Merge mozilla-central to tracemonkey.
authorRobert Sayre <sayrer@gmail.com>
Sun, 02 Aug 2009 15:27:09 -0700
changeset 31076 0c0ad985df66e97164cfc0af4385501858bc1fe0
parent 31075 e3d2c39d5aa4ef34ae38a18ca504af994c1ccfd0 (current diff)
parent 31026 990d01d872830a9dc0226db833fc16ded050611a (diff)
child 31077 e8588659c14b57ef35d04794f8b5bd4e916d616c
push idunknown
push userunknown
push dateunknown
milestone1.9.2a1pre
Merge mozilla-central to tracemonkey.
configure.in
embedding/qa/Makefile.in
embedding/qa/jstests/ComponentListTest.txt
embedding/qa/jstests/EmbedSmokeTest.txt
embedding/qa/jstests/accessibility/html/htmlanchor.html
embedding/qa/jstests/accessibility/html/htmlanchortext.html
embedding/qa/jstests/accessibility/html/htmlbutton.html
embedding/qa/jstests/accessibility/html/htmlbuttontext.html
embedding/qa/jstests/accessibility/html/htmlcheckboxchecked.html
embedding/qa/jstests/accessibility/html/htmlcheckboxunchecked.html
embedding/qa/jstests/accessibility/html/htmlfieldsetwithlegend.html
embedding/qa/jstests/accessibility/html/htmlfieldsetwithoutlegend.html
embedding/qa/jstests/accessibility/html/htmlradiobuttonchecked.html
embedding/qa/jstests/accessibility/html/htmlradiobuttonunchecked.html
embedding/qa/jstests/accessibility/html/htmlselect.html
embedding/qa/jstests/accessibility/html/htmlselectoption.html
embedding/qa/jstests/accessibility/html/htmltable.html
embedding/qa/jstests/accessibility/html/htmltablecaption.html
embedding/qa/jstests/accessibility/html/htmltablecaptiontext.html
embedding/qa/jstests/accessibility/html/htmltablecell.html
embedding/qa/jstests/accessibility/html/htmltablecelltext.html
embedding/qa/jstests/accessibility/html/htmltablerow.html
embedding/qa/jstests/accessibility/html/htmltextarea.html
embedding/qa/jstests/accessibility/xul/xularrowscrollbox.xul
embedding/qa/jstests/accessibility/xul/xulbox.xul
embedding/qa/jstests/accessibility/xul/xulbutton.xul
embedding/qa/jstests/accessibility/xul/xulcheckboxchecked.xul
embedding/qa/jstests/accessibility/xul/xulcheckboxunchecked.xul
embedding/qa/jstests/accessibility/xul/xuldeck.xul
embedding/qa/jstests/accessibility/xul/xuldescription.xul
embedding/qa/jstests/accessibility/xul/xulgrid.xul
embedding/qa/jstests/accessibility/xul/xulgroupbox.xul
embedding/qa/jstests/accessibility/xul/xulimage.xul
embedding/qa/jstests/accessibility/xul/xullabel.xul
embedding/qa/jstests/accessibility/xul/xullistbox.xul
embedding/qa/jstests/accessibility/xul/xullistitem.xul
embedding/qa/jstests/accessibility/xul/xulmenubar.xul
embedding/qa/jstests/accessibility/xul/xulmenuitem.xul
embedding/qa/jstests/accessibility/xul/xulmenulist.xul
embedding/qa/jstests/accessibility/xul/xulprogressmeter.xul
embedding/qa/jstests/accessibility/xul/xulradiobuttonchecked.xul
embedding/qa/jstests/accessibility/xul/xulradiobuttonunchecked.xul
embedding/qa/jstests/accessibility/xul/xulradiogroup.xul
embedding/qa/jstests/accessibility/xul/xulscrollbar.xul
embedding/qa/jstests/accessibility/xul/xulstack.xul
embedding/qa/jstests/accessibility/xul/xultab.xul
embedding/qa/jstests/accessibility/xul/xultabbox.xul
embedding/qa/jstests/accessibility/xul/xultabpanel.xul
embedding/qa/jstests/accessibility/xul/xultabpanels.xul
embedding/qa/jstests/accessibility/xul/xultabs.xul
embedding/qa/jstests/accessibility/xul/xultextbox.xul
embedding/qa/jstests/accessibility/xul/xultoolbar.xul
embedding/qa/jstests/accessibility/xul/xultoolbox.xul
embedding/qa/jstests/accessibility/xul/xultree.xul
embedding/qa/jstests/accessibility/xul/xultreecol.xul
embedding/qa/jstests/accessibility/xul/xultreecols.xul
embedding/qa/jstests/accessibility/xul/xultreeitem.xul
embedding/qa/jstests/bridge.js
embedding/qa/jstests/content/nsISelection.html
embedding/qa/jstests/dom/nsIDOMWindow.html
embedding/qa/jstests/networking/nsIFileProtocolHandler.html
embedding/qa/jstests/networking/nsIFileProtocolHandler.js
embedding/qa/jstests/networking/nsIIOService.html
embedding/qa/jstests/networking/nsIIOService.js
embedding/qa/jstests/networking/nsIProtocolHandler.html
embedding/qa/jstests/networking/nsIProtocolHandler.js
embedding/qa/jstests/networking/nsIURI.html
embedding/qa/jstests/networking/nsIURI.js
embedding/qa/jstests/nsIDocCharsetTest.txt
embedding/qa/jstests/nsIPrefBranchTest.txt
embedding/qa/jstests/nsIPromptTest.txt
embedding/qa/jstests/nsIURITest.txt
embedding/qa/jstests/nsIURLTest.txt
embedding/qa/jstests/nsIWebBrowserPersistTest1.txt
embedding/qa/jstests/nsIWebBrowserPersistTest2.txt
embedding/qa/jstests/nsIWebBrowserPersistTest3.txt
embedding/qa/jstests/plugins.txt
embedding/qa/jstests/profile/nsiprofile.html
embedding/qa/jstests/sHistory/NsISHistoryTestCase1.html
embedding/qa/jstests/sHistory/NsISHistoryTestCase1.txt
embedding/qa/jstests/sHistory/SHListenerTest.html
embedding/qa/jstests/sHistory/loadHistoryPage.html
embedding/qa/jstests/sHistory/nsISHListenerTestLib.js
embedding/qa/jstests/sHistory/nsISHistoryTestLib.js
embedding/qa/jstests/webNav/nsIWebNavTestCase1.html
embedding/qa/jstests/webNav/nsIWebNavTestCase1.txt
embedding/qa/jstests/webNav/nsIWebNavTestLib.js
embedding/qa/jstests/xpcom/nsILocalFile.html
embedding/qa/jstests/xpcom/nsIProperties.html
embedding/qa/mozembed/Makefile.in
embedding/qa/mozembed/makefile.win
embedding/qa/mozembed/public/Makefile.in
embedding/qa/mozembed/public/makefile.win
embedding/qa/mozembed/public/nsIQABrowserChrome.idl
embedding/qa/mozembed/public/nsIQABrowserUIGlue.idl
embedding/qa/mozembed/public/nsIQABrowserView.idl
embedding/qa/mozembed/src/Makefile.in
embedding/qa/mozembed/src/SMALL.ICO
embedding/qa/mozembed/src/StdAfx.cpp
embedding/qa/mozembed/src/StdAfx.h
embedding/qa/mozembed/src/makefile.win
embedding/qa/mozembed/src/mozEmbed.ICO
embedding/qa/mozembed/src/mozEmbed.cpp
embedding/qa/mozembed/src/mozEmbed.h
embedding/qa/mozembed/src/mozEmbed.rc
embedding/qa/mozembed/src/nsQABrowserCID.h
embedding/qa/mozembed/src/nsQABrowserChrome.cpp
embedding/qa/mozembed/src/nsQABrowserChrome.h
embedding/qa/mozembed/src/nsQABrowserModule.cpp
embedding/qa/mozembed/src/nsQABrowserUIGlue.h
embedding/qa/mozembed/src/nsQABrowserView.cpp
embedding/qa/mozembed/src/nsQABrowserView.h
embedding/qa/mozembed/src/nsQAWindowCreator.cpp
embedding/qa/mozembed/src/nsQAWindowCreator.h
embedding/qa/mozembed/src/resource.h
embedding/qa/testembed/BrowserFrameGlue.cpp
embedding/qa/testembed/BrowserFrm.cpp
embedding/qa/testembed/BrowserFrm.h
embedding/qa/testembed/BrowserImpl.cpp
embedding/qa/testembed/BrowserImpl.h
embedding/qa/testembed/BrowserImplCtxMenuLstnr.cpp
embedding/qa/testembed/BrowserImplHistoryLstnr.cpp
embedding/qa/testembed/BrowserImplPrompt.cpp
embedding/qa/testembed/BrowserImplWebPrgrsLstnr.cpp
embedding/qa/testembed/BrowserToolTip.cpp
embedding/qa/testembed/BrowserToolTip.h
embedding/qa/testembed/BrowserView.cpp
embedding/qa/testembed/BrowserView.cpp.mod
embedding/qa/testembed/BrowserView.h
embedding/qa/testembed/Dialogs.cpp
embedding/qa/testembed/Dialogs.h
embedding/qa/testembed/DomWindow.cpp
embedding/qa/testembed/DomWindow.h
embedding/qa/testembed/IBrowserFrameGlue.h
embedding/qa/testembed/Makefile.in
embedding/qa/testembed/MostRecentUrls.cpp
embedding/qa/testembed/MostRecentUrls.h
embedding/qa/testembed/Preferences.cpp
embedding/qa/testembed/Preferences.h
embedding/qa/testembed/PrintProgressDialog.cpp
embedding/qa/testembed/PrintProgressDialog.h
embedding/qa/testembed/ProfileMgr.cpp
embedding/qa/testembed/ProfileMgr.h
embedding/qa/testembed/ProfilesDlg.cpp
embedding/qa/testembed/ProfilesDlg.h
embedding/qa/testembed/QaFindDlg.cpp
embedding/qa/testembed/QaFindDlg.h
embedding/qa/testembed/QaUtils.cpp
embedding/qa/testembed/QaUtils.h
embedding/qa/testembed/README.TXT
embedding/qa/testembed/Selection.cpp
embedding/qa/testembed/Selection.h
embedding/qa/testembed/StdAfx.cpp
embedding/qa/testembed/StdAfx.h
embedding/qa/testembed/TestEmbed.cpp
embedding/qa/testembed/TestEmbed.h
embedding/qa/testembed/Tests.cpp
embedding/qa/testembed/Tests.h
embedding/qa/testembed/UrlDialog.cpp
embedding/qa/testembed/UrlDialog.h
embedding/qa/testembed/WebProgDlg.cpp
embedding/qa/testembed/WebProgDlg.h
embedding/qa/testembed/components/Dialogs.cpp
embedding/qa/testembed/components/Dialogs.h
embedding/qa/testembed/components/Dialogs.rc
embedding/qa/testembed/components/Makefile.in
embedding/qa/testembed/components/PromptService.cpp
embedding/qa/testembed/components/PromptService.h
embedding/qa/testembed/components/resource.h
embedding/qa/testembed/components/stdafx.h
embedding/qa/testembed/nsICmdParams.cpp
embedding/qa/testembed/nsICmdParams.h
embedding/qa/testembed/nsICommandMgr.cpp
embedding/qa/testembed/nsICommandMgr.h
embedding/qa/testembed/nsIEditSession.cpp
embedding/qa/testembed/nsIEditSession.h
embedding/qa/testembed/nsIFile.cpp
embedding/qa/testembed/nsIFile.h
embedding/qa/testembed/nsIObserServ.cpp
embedding/qa/testembed/nsIObserServ.h
embedding/qa/testembed/nsIWebBrow.cpp
embedding/qa/testembed/nsIWebBrow.h
embedding/qa/testembed/nsIWebBrowFind.cpp
embedding/qa/testembed/nsIWebBrowFind.h
embedding/qa/testembed/nsIWebNav.cpp
embedding/qa/testembed/nsIWebNav.h
embedding/qa/testembed/nsIWebProg.cpp
embedding/qa/testembed/nsIWebProg.h
embedding/qa/testembed/nsIclipboardcmd.cpp
embedding/qa/testembed/nsIclipboardcmd.h
embedding/qa/testembed/nsProfile.cpp
embedding/qa/testembed/nsProfile.h
embedding/qa/testembed/nsiDirServ.cpp
embedding/qa/testembed/nsiDirServ.h
embedding/qa/testembed/nsiHistory.cpp
embedding/qa/testembed/nsiHistory.h
embedding/qa/testembed/nsichanneltests.cpp
embedding/qa/testembed/nsichanneltests.h
embedding/qa/testembed/nsihttpchanneltests.cpp
embedding/qa/testembed/nsihttpchanneltests.h
embedding/qa/testembed/nsirequest.cpp
embedding/qa/testembed/nsirequest.h
embedding/qa/testembed/res/Toolbar.bmp
embedding/qa/testembed/res/testembed.ico
embedding/qa/testembed/res/testembed.rc2
embedding/qa/testembed/res/toolbar1.bmp
embedding/qa/testembed/resource.h
embedding/qa/testembed/testembed.aps
embedding/qa/testembed/testembed.dsp
embedding/qa/testembed/testembed.dsw
embedding/qa/testembed/testembed.htm
embedding/qa/testembed/testembed.rc
embedding/qa/testembed/winEmbedFileLocProvider.cpp
embedding/qa/testembed/winEmbedFileLocProvider.h
embedding/tests/os2Embed/Makefile.in
embedding/tests/os2Embed/SMALL.ICO
embedding/tests/os2Embed/WebBrowserChrome.cpp
embedding/tests/os2Embed/WebBrowserChrome.h
embedding/tests/os2Embed/WindowCreator.cpp
embedding/tests/os2Embed/WindowCreator.h
embedding/tests/os2Embed/os2Embed.ICO
embedding/tests/os2Embed/os2Embed.cpp
embedding/tests/os2Embed/os2Embed.h
embedding/tests/os2Embed/os2Embed.rc
embedding/tests/os2Embed/resource.h
extensions/python/xpcom/doc/advanced.html
extensions/python/xpcom/doc/architecture.html
extensions/python/xpcom/doc/configure.html
extensions/python/xpcom/doc/credits.html
extensions/python/xpcom/doc/tutorial.html
extensions/python/xpcom/readme.html
jpeg/jpegOS2.def
js/src/Makefile.in
modules/libpr0n/decoders/xbm/Makefile.in
modules/libpr0n/decoders/xbm/nsXBMDecoder.cpp
modules/libpr0n/decoders/xbm/nsXBMDecoder.h
modules/libpref/src/init/all.js
security/coreconf/OpenVMS.mk
security/coreconf/OpenVMSV7.1-2.mk
toolkit/components/places/src/nsNavHistoryAutoComplete.cpp
xulrunner/app/document-os2.ico
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -35,17 +35,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsAccessNode.h"
 #include "nsIAccessible.h"
 #include "nsAccessibilityAtoms.h"
 #include "nsHashtable.h"
-#include "nsIAccessibilityService.h"
+#include "nsAccessibilityService.h"
 #include "nsIAccessibleDocument.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocument.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsIDOMCSSPrimitiveValue.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
@@ -77,37 +77,29 @@
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 nsIStringBundle *nsAccessNode::gStringBundle = 0;
 nsIStringBundle *nsAccessNode::gKeyStringBundle = 0;
 nsITimer *nsAccessNode::gDoCommandTimer = 0;
 nsIDOMNode *nsAccessNode::gLastFocusedNode = 0;
+#ifdef DEBUG
 PRBool nsAccessNode::gIsAccessibilityActive = PR_FALSE;
-PRBool nsAccessNode::gIsShuttingDownApp = PR_FALSE;
+#endif
 PRBool nsAccessNode::gIsCacheDisabled = PR_FALSE;
 PRBool nsAccessNode::gIsFormFillEnabled = PR_FALSE;
 nsAccessNodeHashtable nsAccessNode::gGlobalDocAccessibleCache;
 
 nsApplicationAccessibleWrap *nsAccessNode::gApplicationAccessible = nsnull;
 
-nsIAccessibilityService *nsAccessNode::sAccService = nsnull;
-nsIAccessibilityService *nsAccessNode::GetAccService()
+nsIAccessibilityService*
+nsAccessNode::GetAccService()
 {
-  if (!gIsAccessibilityActive)
-    return nsnull;
-
-  if (!sAccService) {
-    nsresult rv = CallGetService("@mozilla.org/accessibilityService;1",
-                                 &sAccService);
-    NS_ASSERTION(NS_SUCCEEDED(rv), "No accessibility service");
-  }
-
-  return sAccService;
+  return nsAccessibilityService::GetAccessibilityService();
 }
 
 /*
  * Class nsAccessNode
  */
  
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible. nsISupports
@@ -240,19 +232,17 @@ NS_IMETHODIMP nsAccessNode::GetOwnerWind
   if (!docAccessible)
     return NS_ERROR_FAILURE; // This node or doc accessible is shut down
   return docAccessible->GetWindowHandle(aWindow);
 }
 
 already_AddRefed<nsApplicationAccessibleWrap>
 nsAccessNode::GetApplicationAccessible()
 {
-  if (!gIsAccessibilityActive) {
-    return nsnull;
-  }
+  NS_ASSERTION(gIsAccessibilityActive, "Accessibility wasn't initialized!");
 
   if (!gApplicationAccessible) {
     nsApplicationAccessibleWrap::PreCreate();
 
     gApplicationAccessible = new nsApplicationAccessibleWrap();
     if (!gApplicationAccessible)
       return nsnull;
 
@@ -268,19 +258,18 @@ nsAccessNode::GetApplicationAccessible()
   }
 
   NS_ADDREF(gApplicationAccessible);   // Addref because we're a getter
   return gApplicationAccessible;
 }
 
 void nsAccessNode::InitXPAccessibility()
 {
-  if (gIsAccessibilityActive) {
-    return;
-  }
+  NS_ASSERTION(!gIsAccessibilityActive,
+               "Accessibility was initialized already!");
 
   nsCOMPtr<nsIStringBundleService> stringBundleService =
     do_GetService(NS_STRINGBUNDLE_CONTRACTID);
   if (stringBundleService) {
     // Static variables are released in ShutdownAllXPAccessibility();
     stringBundleService->CreateBundle(ACCESSIBLE_BUNDLE_URL, 
                                       &gStringBundle);
     stringBundleService->CreateBundle(PLATFORM_KEYS_BUNDLE_URL, 
@@ -292,60 +281,60 @@ void nsAccessNode::InitXPAccessibility()
   gGlobalDocAccessibleCache.Init(4);
 
   nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
   if (prefBranch) {
     prefBranch->GetBoolPref("accessibility.disablecache", &gIsCacheDisabled);
     prefBranch->GetBoolPref("browser.formfill.enable", &gIsFormFillEnabled);
   }
 
+#ifdef DEBUG
   gIsAccessibilityActive = PR_TRUE;
-  NotifyA11yInitOrShutdown();
+#endif
+  NotifyA11yInitOrShutdown(PR_TRUE);
 }
 
-void nsAccessNode::NotifyA11yInitOrShutdown()
+void nsAccessNode::NotifyA11yInitOrShutdown(PRBool aIsInit)
 {
   nsCOMPtr<nsIObserverService> obsService =
     do_GetService("@mozilla.org/observer-service;1");
   NS_ASSERTION(obsService, "No observer service to notify of a11y init/shutdown");
   if (obsService) {
     static const PRUnichar kInitIndicator[] = { '1', 0 };
     static const PRUnichar kShutdownIndicator[] = { '0', 0 }; 
     obsService->NotifyObservers(nsnull, "a11y-init-or-shutdown",
-                                gIsAccessibilityActive ? kInitIndicator  : kShutdownIndicator);
+                                aIsInit ? kInitIndicator  : kShutdownIndicator);
   }
 }
 
 void nsAccessNode::ShutdownXPAccessibility()
 {
   // Called by nsAccessibilityService::Shutdown()
   // which happens when xpcom is shutting down
   // at exit of program
 
-  if (!gIsAccessibilityActive) {
-    return;
-  }
-  gIsShuttingDownApp = PR_TRUE;
+  NS_ASSERTION(gIsAccessibilityActive, "Accessibility was shutdown already!");
 
   NS_IF_RELEASE(gStringBundle);
   NS_IF_RELEASE(gKeyStringBundle);
   NS_IF_RELEASE(gDoCommandTimer);
   NS_IF_RELEASE(gLastFocusedNode);
-  NS_IF_RELEASE(sAccService);
 
   nsApplicationAccessibleWrap::Unload();
   ClearCache(gGlobalDocAccessibleCache);
 
   // Release gApplicationAccessible after everything else is shutdown
   // so we don't accidently create it again while tearing down root accessibles
   NS_IF_RELEASE(gApplicationAccessible);
   gApplicationAccessible = nsnull;  
 
+#ifdef DEBUG
   gIsAccessibilityActive = PR_FALSE;
-  NotifyA11yInitOrShutdown();
+#endif
+  NotifyA11yInitOrShutdown(PR_FALSE);
 }
 
 PRBool
 nsAccessNode::IsDefunct()
 {
   if (!mDOMNode)
     return PR_TRUE;
 
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -169,31 +169,31 @@ protected:
 
 #ifdef DEBUG_A11Y
     PRBool mIsInitialized;
 #endif
 
     /**
      * Notify global nsIObserver's that a11y is getting init'd or shutdown
      */
-    static void NotifyA11yInitOrShutdown();
+    static void NotifyA11yInitOrShutdown(PRBool aIsInit);
 
     // Static data, we do our own refcounting for our static data
     static nsIStringBundle *gStringBundle;
     static nsIStringBundle *gKeyStringBundle;
     static nsITimer *gDoCommandTimer;
+#ifdef DEBUG
     static PRBool gIsAccessibilityActive;
-    static PRBool gIsShuttingDownApp;
+#endif
     static PRBool gIsCacheDisabled;
     static PRBool gIsFormFillEnabled;
 
     static nsAccessNodeHashtable gGlobalDocAccessibleCache;
 
 private:
-  static nsIAccessibilityService *sAccService;
   static nsApplicationAccessibleWrap *gApplicationAccessible;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessNode,
                               NS_ACCESSNODE_IMPL_CID)
 
 #endif
 
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -108,86 +108,104 @@
 
 #ifdef MOZ_ACCESSIBILITY_ATK
 #include "nsAppRootAccessible.h"
 #else
 #include "nsApplicationAccessibleWrap.h"
 #endif
 
 nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nsnull;
+PRBool nsAccessibilityService::gIsShutdown = PR_TRUE;
 
 /**
   * nsAccessibilityService
   */
 
 nsAccessibilityService::nsAccessibilityService()
 {
+  // Add observers.
   nsCOMPtr<nsIObserverService> observerService = 
     do_GetService("@mozilla.org/observer-service;1");
   if (!observerService)
     return;
 
   observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
   nsCOMPtr<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
   if (progress) {
     progress->AddProgressListener(static_cast<nsIWebProgressListener*>(this),
                                   nsIWebProgress::NOTIFY_STATE_DOCUMENT |
                                   nsIWebProgress::NOTIFY_LOCATION);
   }
+
+  // Initialize accessibility.
   nsAccessNodeWrap::InitAccessibility();
 }
 
 nsAccessibilityService::~nsAccessibilityService()
 {
-  nsAccessibilityService::gAccessibilityService = nsnull;
-  nsAccessNodeWrap::ShutdownAccessibility();
+  NS_ASSERTION(gIsShutdown, "Accessibility wasn't shutdown!");
+  gAccessibilityService = nsnull;
 }
 
 NS_IMPL_THREADSAFE_ISUPPORTS5(nsAccessibilityService, nsIAccessibilityService, nsIAccessibleRetrieval,
                               nsIObserver, nsIWebProgressListener, nsISupportsWeakReference)
 
 // nsIObserver
 
 NS_IMETHODIMP
 nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
                          const PRUnichar *aData)
 {
   if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
+
+    // Remove observers.
     nsCOMPtr<nsIObserverService> observerService = 
       do_GetService("@mozilla.org/observer-service;1");
     if (observerService) {
       observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
     }
     nsCOMPtr<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
     if (progress)
       progress->RemoveProgressListener(static_cast<nsIWebProgressListener*>(this));
-    nsAccessNodeWrap::ShutdownAccessibility();
-    // Cancel and release load timers
+
+    // Cancel and release load timers.
     while (mLoadTimers.Count() > 0 ) {
       nsCOMPtr<nsITimer> timer = mLoadTimers.ObjectAt(0);
       void *closure = nsnull;
       timer->GetClosure(&closure);
       if (closure) {
         nsIWebProgress *webProgress = static_cast<nsIWebProgress*>(closure);
         NS_RELEASE(webProgress);  // Release nsIWebProgress for timer
       }
       timer->Cancel();
       mLoadTimers.RemoveObjectAt(0);
     }
+
+    // Application is going to be closed, shutdown accessibility and mark
+    // accessibility service as shutdown to prevent calls of its methods.
+    // Don't null accessibility service static member at this point to be safe
+    // if someone will try to operate with it.
+
+    NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
+
+    gIsShutdown = PR_TRUE;
+    nsAccessNodeWrap::ShutdownAccessibility();
   }
+
   return NS_OK;
 }
 
 // nsIWebProgressListener
 NS_IMETHODIMP nsAccessibilityService::OnStateChange(nsIWebProgress *aWebProgress,
   nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
 {
   NS_ASSERTION(aStateFlags & STATE_IS_DOCUMENT, "Other notifications excluded");
 
-  if (!aWebProgress || 0 == (aStateFlags & (STATE_START | STATE_STOP))) {
+  if (gIsShutdown || !aWebProgress ||
+      (aStateFlags & (STATE_START | STATE_STOP)) == 0) {
     return NS_OK;
   }
   
   nsCAutoString name;
   aRequest->GetName(name);
   if (name.EqualsLiteral("about:blank"))
     return NS_OK;
 
@@ -255,33 +273,36 @@ NS_IMETHODIMP
 nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
                                             nsIAccessible *aTarget)
 {
   return nsAccUtils::FireAccEvent(aEvent, aTarget);
 }
 
 void nsAccessibilityService::StartLoadCallback(nsITimer *aTimer, void *aClosure)
 {
-  nsIAccessibilityService *accService = nsAccessNode::GetAccService();
-  if (accService)
-    accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START);
+  if (gAccessibilityService)
+    gAccessibilityService->
+      ProcessDocLoadEvent(aTimer, aClosure,
+                          nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START);
 }
 
 void nsAccessibilityService::EndLoadCallback(nsITimer *aTimer, void *aClosure)
 {
-  nsIAccessibilityService *accService = nsAccessNode::GetAccService();
-  if (accService)
-    accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
+  if (gAccessibilityService)
+    gAccessibilityService->
+      ProcessDocLoadEvent(aTimer, aClosure,
+                          nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
 }
 
 void nsAccessibilityService::FailedLoadCallback(nsITimer *aTimer, void *aClosure)
 {
-  nsIAccessibilityService *accService = nsAccessNode::GetAccService();
-  if (accService)
-    accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
+  if (gAccessibilityService)
+    gAccessibilityService->
+      ProcessDocLoadEvent(aTimer, aClosure,
+                          nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
 }
 
 /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
 NS_IMETHODIMP nsAccessibilityService::OnProgressChange(nsIWebProgress *aWebProgress,
   nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress,
   PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
 {
   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
@@ -1310,17 +1331,17 @@ NS_IMETHODIMP nsAccessibilityService::Ge
                                                     nsIWeakReference *aWeakShell,
                                                     nsIFrame **aFrameHint,
                                                     PRBool *aIsHidden,
                                                     nsIAccessible **aAccessible)
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
   NS_ENSURE_ARG_POINTER(aFrameHint);
   *aAccessible = nsnull;
-  if (!aPresShell || !aWeakShell) {
+  if (!aPresShell || !aWeakShell || gIsShutdown) {
     return NS_ERROR_FAILURE;
   }
 
   NS_ASSERTION(aNode, "GetAccessible() called with no node.");
 
   *aIsHidden = PR_FALSE;
 
 #ifdef DEBUG_A11Y
@@ -2051,32 +2072,38 @@ NS_IMETHODIMP nsAccessibilityService::In
 }
 
 //////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////
 
 nsresult 
 nsAccessibilityService::GetAccessibilityService(nsIAccessibilityService** aResult)
 {
-  NS_PRECONDITION(aResult != nsnull, "null ptr");
-  if (! aResult)
-      return NS_ERROR_NULL_POINTER;
+  NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
+  *aResult = nsnull;
 
-  *aResult = nsnull;
-  if (!nsAccessibilityService::gAccessibilityService) {
+  if (!gAccessibilityService) {
     gAccessibilityService = new nsAccessibilityService();
-    if (!gAccessibilityService ) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+    NS_ENSURE_TRUE(gAccessibilityService, NS_ERROR_OUT_OF_MEMORY);
+
+    gIsShutdown = PR_FALSE;
   }
-  *aResult = nsAccessibilityService::gAccessibilityService;
-  NS_ADDREF(*aResult);
+
+  NS_ADDREF(*aResult = gAccessibilityService);
   return NS_OK;
 }
 
+nsIAccessibilityService*
+nsAccessibilityService::GetAccessibilityService()
+{
+  NS_ASSERTION(!gIsShutdown,
+               "Going to deal with shutdown accessibility service!");
+  return gAccessibilityService;
+}
+
 nsresult
 NS_GetAccessibilityService(nsIAccessibilityService** aResult)
 {
   return nsAccessibilityService::GetAccessibilityService(aResult);
 }
 
 nsresult
 nsAccessibilityService::GetAccessibleForDeckChildren(nsIDOMNode *aNode, nsIAccessible** aAccessible)
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -79,16 +79,26 @@ public:
   static nsresult GetShellFromNode(nsIDOMNode *aNode,
                                    nsIWeakReference **weakShell);
 
   /**
    * Return accessibility service (static instance of this class).
    */
   static nsresult GetAccessibilityService(nsIAccessibilityService** aResult);
 
+  /**
+   * Return cached accessibility service.
+   */
+  static nsIAccessibilityService* GetAccessibilityService();
+
+  /**
+   * Indicates whether accessibility service was shutdown.
+   */
+  static PRBool gIsShutdown;
+
 private:
   /**
    * Return presentation shell, DOM node for the given frame.
    *
    * @param aFrame - the given frame
    * @param aShell [out] - presentation shell for DOM node associated with the
    *                 given frame
    * @param aContent [out] - DOM node associated with the given frame
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -34,17 +34,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 "nsRootAccessible.h"
 #include "nsAccessibilityAtoms.h"
 #include "nsAccessibleEventData.h"
-#include "nsIAccessibilityService.h"
+#include "nsAccessibilityService.h"
 #include "nsIMutableArray.h"
 #include "nsICommandManager.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocument.h"
 #include "nsIDOMAttr.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
@@ -665,17 +665,17 @@ nsDocAccessible::Shutdown()
       if (!mInFlushPendingEvents)
         NS_RELEASE_THIS();
     }
   }
 
   // Remove from the cache after other parts of Shutdown(), so that Shutdown() procedures
   // can find the doc or root accessible in the cache if they need it.
   // We don't do this during ShutdownAccessibility() because that is already clearing the cache
-  if (!gIsShuttingDownApp)
+  if (!nsAccessibilityService::gIsShutdown)
     gGlobalDocAccessibleCache.Remove(static_cast<void*>(kungFuDeathGripDoc));
 
   return NS_OK;
 }
 
 void nsDocAccessible::ShutdownChildDocuments(nsIDocShellTreeItem *aStart)
 {
   nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(aStart));
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -331,31 +331,43 @@ nsTextEquivUtils::AppendFromValue(nsIAcc
   if (aAccessible != gInitiatorAcc) {
     nsresult rv = aAccessible->GetValue(text);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return AppendString(aString, text) ?
       NS_OK : NS_OK_NO_NAME_CLAUSE_HANDLED;
   }
 
-  nsCOMPtr<nsIAccessible> nextSibling;
-  aAccessible->GetNextSibling(getter_AddRefs(nextSibling));
-  if (nextSibling) {
-    nsCOMPtr<nsIAccessible> parent;
-    aAccessible->GetParent(getter_AddRefs(parent));
-    if (parent) {
-      nsCOMPtr<nsIAccessible> firstChild;
-      parent->GetFirstChild(getter_AddRefs(firstChild));
-      if (firstChild && firstChild != aAccessible) {
-        nsresult rv = aAccessible->GetValue(text);
-        NS_ENSURE_SUCCESS(rv, rv);
+  nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(aAccessible);
+  nsCOMPtr<nsIDOMNode> node;
+  acc->GetDOMNode(getter_AddRefs(node));
+  NS_ENSURE_STATE(node);
+
+  nsCOMPtr<nsIContent> content(do_QueryInterface(node));
+  NS_ENSURE_STATE(content);
+
+  nsCOMPtr<nsIContent> parent = content->GetParent();
+  PRInt32 indexOf = parent->IndexOf(content);
 
-        return AppendString(aString, text) ?
-          NS_OK : NS_OK_NO_NAME_CLAUSE_HANDLED;
+  for (PRInt32 i = indexOf - 1; i >= 0; i--) {
+    // check for preceding text...
+    if (!parent->GetChildAt(i)->TextIsOnlyWhitespace()) {
+      PRUint32 childCount = parent->GetChildCount();
+      for (PRUint32 j = indexOf + 1; j < childCount; j++) {
+        // .. and subsequent text
+        if (!parent->GetChildAt(j)->TextIsOnlyWhitespace()) {
+          nsresult rv = aAccessible->GetValue(text);
+          NS_ENSURE_SUCCESS(rv, rv);
+
+          return AppendString(aString, text) ?
+            NS_OK : NS_OK_NO_NAME_CLAUSE_HANDLED;
+          break;
+        }
       }
+      break;
     }
   }
 
   return NS_OK_NO_NAME_CLAUSE_HANDLED;
 }
 
 nsresult
 nsTextEquivUtils::AppendFromDOMChildren(nsIContent *aContent,
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -588,19 +588,18 @@ nsAccessNodeWrap::get_localInterface(
   *localInterface = static_cast<nsIAccessNode*>(this);
   NS_ADDREF_THIS();
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
  
 void nsAccessNodeWrap::InitAccessibility()
 {
-  if (gIsAccessibilityActive) {
-    return;
-  }
+  NS_ASSERTION(!gIsAccessibilityActive,
+               "Accessibility was initialized already!");
 
   nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
   if (prefBranch) {
     prefBranch->GetBoolPref("accessibility.disableenumvariant", &gIsEnumVariantSupportDisabled);
   }
 
   if (!gmUserLib) {
     gmUserLib =::LoadLibraryW(L"USER32.DLL");
@@ -618,19 +617,17 @@ void nsAccessNodeWrap::InitAccessibility
   nsAccessNode::InitXPAccessibility();
 }
 
 void nsAccessNodeWrap::ShutdownAccessibility()
 {
   NS_IF_RELEASE(gTextEvent);
   ::DestroyCaret();
 
-  if (!gIsAccessibilityActive) {
-    return;
-  }
+  NS_ASSERTION(gIsAccessibilityActive, "Accessibility was shutdown already!");
 
   nsAccessNode::ShutdownXPAccessibility();
 }
 
 int nsAccessNodeWrap::FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo)
 {
   if (aCode == EXCEPTION_ACCESS_VIOLATION) {
 #ifdef MOZ_CRASHREPORTER
--- a/accessible/tests/mochitest/test_name.html
+++ b/accessible/tests/mochitest/test_name.html
@@ -134,40 +134,46 @@
       // If nothing is left. Let's try title attribute.
       testName("btn_title", "title");
 
       //////////////////////////////////////////////////////////////////////////
       // textarea name
 
       // textarea's name should have the value, which initially is specified by
       // a text child.
-      testName("textareawithchild", "Story: Foo");
+      testName("textareawithchild", "Story Foo is ended.");
 
       // new textarea name should reflect the value change. 
       var elem = document.getElementById("textareawithchild");
       elem.value = "Bar";
 
-      testName("textareawithchild", "Story: Bar");
+      testName("textareawithchild", "Story Bar is ended.");
 
       /////////////////////////////////////////////////////////////////////////
       // label with nested combobox (test for 'f' item of name computation guide)
 
       testName("comboinstart", "One day(s).");
       testName("combo3", "day(s).");
 
+      testName("textboxinstart", "Two days.");
+      testName("textbox1", "days.");
+
       testName("comboinmiddle", "Subscribe to ATOM feed.");
       testName("combo4", "Subscribe to ATOM feed.");
 
       testName("comboinmiddle2", "Play the Haliluya sound when new mail arrives");
       testName("combo5", "Play the Haliluya sound when new mail arrives");
       testName("checkbox", "Play the Haliluya sound when new mail arrives");
 
       testName("comboinend", "This day was sunny");
       testName("combo6", "This day was");
 
+      testName("textboxinend", "This day was sunny");
+      testName("textbox2", "This day was");
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addLoadEvent(doTest);
   </script>
 
 </head>
@@ -340,30 +346,38 @@
     </div>
   </div>
 
   <!-- name from title attribute -->
   <span id="btn_title" role="group" title="title">15</span>
 
   <!-- A textarea nested in a label with a text child (bug #453371). -->
   <form>
-    <label>Story: 
+    <label>Story
       <textarea id="textareawithchild" name="name">Foo</textarea>
+      is ended.
     </label>
   </form>
 
   <!-- a label with a nested control in the start, middle and end -->
   <form>
+    <!-- at the start (without and with whitespaces) -->
     <label id="comboinstart"><select id="combo3">
         <option>One</option>
         <option>Two</option>
       </select>
       day(s).
     </label>
 
+    <label id="textboxinstart">
+      <input id="textbox1" value="Two">
+      days.
+    </label>
+
+    <!-- in the middle -->
     <label id="comboinmiddle">
       Subscribe to
       <select id="combo4" name="occupation">
         <option>ATOM</option>
         <option>RSS</option>
       </select>
       feed.
     </label>
@@ -372,18 +386,24 @@
       <select id="combo5">
         <option>Haliluya</option>
         <option>Hurra</option>
       </select>
       sound when new mail arrives
     </label>
     <input id="checkbox" type="checkbox" />
 
+    <!-- at the end (without and with whitespaces) -->
     <label id="comboinend">
       This day was
       <select id="combo6" name="occupation">
         <option>sunny</option>
         <option>rainy</option>
       </select></label>
+
+    <label id="textboxinend">
+      This day was
+      <input id="textbox2" value="sunny">
+    </label>
   </form>
 
 </body>
 </html>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -880,16 +880,19 @@ pref("content.sink.perf_deflect_count", 
 pref("content.sink.interactive_parse_time", 5000); /* default 3000 */
 pref("content.sink.perf_parse_time", 150000); /* default 360000 */
 pref("content.sink.pending_event_mode", 0); /* default 1 */
 pref("content.sink.event_probe_rate", 1); /* default 1 */
 pref("content.sink.interactive_time", 750000); /* default 750000 */
 pref("content.sink.initial_perf_time", 500000); /* default 2000000 */
 pref("content.sink.enable_perf_mode", 0); /* default 0; 0 == switch, 1 == stay interactive, 2 == stay perf */
 
+// Write sessionstore.js less often
+pref("browser.sessionstore.interval", 60000);
+
 #endif /* WINCE */
 
 // Whether to use a panel that looks like an OS X sheet for customization
 #ifdef XP_MACOSX
 pref("toolbar.customization.usesheet", true);
 #else
 pref("toolbar.customization.usesheet", false);
 #endif
--- a/browser/base/content/browser-context.inc
+++ b/browser/base/content/browser-context.inc
@@ -162,23 +162,21 @@
                 oncommand="gContextMenu.sendMedia();"/>
       <menuitem id="context-sendaudio"
                 label="&sendAudioCmd.label;"
                 accesskey="&sendAudioCmd.accesskey;"
                 oncommand="gContextMenu.sendMedia();"/>
       <menuitem id="context-back"
                 label="&backCmd.label;"
                 accesskey="&backCmd.accesskey;"
-                chromedir="&locale.dir;"
                 command="Browser:BackOrBackDuplicate"
                 onclick="checkForMiddleClick(this, event);"/>
       <menuitem id="context-forward"
                 label="&forwardCmd.label;"
                 accesskey="&forwardCmd.accesskey;"
-                chromedir="&locale.dir;"
                 command="Browser:ForwardOrForwardDuplicate"
                 onclick="checkForMiddleClick(this, event);"/>
       <menuitem id="context-reload"
                 label="&reloadCmd.label;"
                 accesskey="&reloadCmd.accesskey;"
                 command="Browser:ReloadOrDuplicate"
                 onclick="checkForMiddleClick(this, event);"/>
       <menuitem id="context-stop"
--- a/browser/base/content/browser-doctype.inc
+++ b/browser/base/content/browser-doctype.inc
@@ -1,15 +1,13 @@
 <!DOCTYPE window [
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
 %brandDTD;
 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
 %browserDTD;
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
-%globalDTD;
 <!ENTITY % globalRegionDTD SYSTEM "chrome://global-region/locale/region.dtd">
 %globalRegionDTD;
 <!ENTITY % charsetDTD SYSTEM "chrome://global/locale/charsetOverlay.dtd" >
 %charsetDTD;
 <!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd" >
 %textcontextDTD;
 <!ENTITY % customizeToolbarDTD SYSTEM "chrome://global/locale/customizeToolbar.dtd">
   %customizeToolbarDTD;
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -434,17 +434,17 @@
                           key="key_viewSource"
                           command="View:PageSource"/>
 #ifndef XP_MACOSX
                 <menuitem id="fullScreenItem"
                           accesskey="&fullScreenCmd.accesskey;"
                           label="&fullScreenCmd.label;"
                           key="key_fullScreen"
                           type="checkbox"
-                          command="View:FullScreen"/>
+                          observes="View:FullScreen"/>
 #endif
                 <menuitem id="menu_showAllTabs"
                           hidden="true"
                           accesskey="&showAllTabsCmd.accesskey;"
                           label="&showAllTabsCmd.label;"
                           command="Browser:ShowAllTabs"
                           key="key_showAllTabs"/>
                 <menuseparator hidden="true" id="documentDirection-separator"/>
@@ -469,27 +469,25 @@
                          tooltip="btTooltip">
                 <menuitem id="historyMenuBack"
                           label="&backCmd.label;"
 #ifdef XP_MACOSX
                           key="goBackKb2"
 #else
                           key="goBackKb"
 #endif
-                          chromedir="&locale.dir;"
                           command="Browser:BackOrBackDuplicate"
                           onclick="checkForMiddleClick(this, event);"/>
                 <menuitem id="historyMenuForward"
                           label="&forwardCmd.label;"
 #ifdef XP_MACOSX
                           key="goForwardKb2"
 #else
                           key="goForwardKb"
 #endif
-                          chromedir="&locale.dir;"
                           command="Browser:ForwardOrForwardDuplicate"
                           onclick="checkForMiddleClick(this, event);"/>
                 <menuitem id="historyMenuHome"
                           label="&historyHomeCmd.label;"
                           oncommand="BrowserGoHome(event);"
                           onclick="checkForMiddleClick(this, event);"
                           key="goHome"/>
                 <menuitem id="menu_showAllHistory"
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -427,19 +427,17 @@ var PlacesCommandHook = {
 
     // dock the panel to the star icon when possible, otherwise dock
     // it to the content area
     if (aBrowser.contentWindow == window.content) {
       var starIcon = aBrowser.ownerDocument.getElementById("star-button");
       if (starIcon && isElementVisible(starIcon)) {
         // Make sure the bookmark properties dialog hangs toward the middle of
         // the location bar in RTL builds
-        var position = "after_end";
-        if (gURLBar.getAttribute("chromedir") == "rtl")
-          position = "after_start";
+        var position = (getComputedStyle(gNavToolbox, "").direction == "rtl") ? 'after_start' : 'after_end';
         if (aShowEditUI)
           StarUI.showEditBookmarkPopup(itemId, starIcon, position);
 #ifdef ADVANCED_STARRING_UI
         else
           StarUI.showPageBookmarkedNotification(itemId, starIcon, position);
 #endif
         return;
       }
@@ -519,20 +517,17 @@ var PlacesCommandHook = {
    * @param     url
    *            The nsIURI of the page the feed was attached to
    * @title     title
    *            The title of the feed. Optional.
    * @subtitle  subtitle
    *            A short description of the feed. Optional.
    */
   addLiveBookmark: function PCH_addLiveBookmark(url, feedTitle, feedSubtitle) {
-    var ios = 
-        Cc["@mozilla.org/network/io-service;1"].
-        getService(Ci.nsIIOService);
-    var feedURI = ios.newURI(url, null, null);
+    var feedURI = makeURI(url);
     
     var doc = gBrowser.contentDocument;
     var title = (arguments.length > 1) ? feedTitle : doc.title;
  
     var description;
     if (arguments.length > 2)
       description = feedSubtitle;
     else
--- a/browser/base/content/browser-textZoom.js
+++ b/browser/base/content/browser-textZoom.js
@@ -261,18 +261,29 @@ var FullZoom = {
       // the global preference has changed.
       if (!this._cps.hasPref(gBrowser.currentURI, this.name))
         this._applyPrefToSetting();
     }
   },
 
   // location change observer
 
-  onLocationChange: function FullZoom_onLocationChange(aURI, aBrowser) {
-    if (!aURI)
+  /**
+   * Called when the location of a tab changes.
+   * When that happens, we need to update the current zoom level if appropriate.
+   *
+   * @param aURI
+   *        A URI object representing the new location.
+   * @param aIsTabSwitch
+   *        Whether this location change has happened because of a tab switch.
+   * @param aBrowser
+   *        (optional) browser object displaying the document
+   */
+  onLocationChange: function FullZoom_onLocationChange(aURI, aIsTabSwitch, aBrowser) {
+    if (!aURI || (aIsTabSwitch && !this.siteSpecific))
       return;
     this._applyPrefToSetting(this._cps.getPref(aURI, this.name), aBrowser);
   },
 
   // update state of zoom type menu item
 
   updateMenu: function FullZoom_updateMenu() {
     var menuItem = document.getElementById("toggle_zoom");
@@ -297,21 +308,16 @@ var FullZoom = {
     if (typeof this.globalValue != "undefined")
       ZoomManager.zoom = this.globalValue;
     else
       ZoomManager.reset();
 
     this._removePref();
   },
 
-  setSettingValue: function FullZoom_setSettingValue() {
-    var value = this._cps.getPref(gBrowser.currentURI, this.name);
-    this._applyPrefToSetting(value);
-  },
-
   /**
    * Set the zoom level for the current tab.
    *
    * Per nsPresContext::setFullZoom, we can set the zoom to its current value
    * without significant impact on performance, as the setting is only applied
    * if it differs from the current setting.  In fact getting the zoom and then
    * checking ourselves if it differs costs more.
    * 
@@ -324,22 +330,23 @@ var FullZoom = {
    *
    * So when we apply new zoom values to the browser, we simply set the zoom.
    * We don't check first to see if the new value is the same as the current
    * one.
    **/
   _applyPrefToSetting: function FullZoom__applyPrefToSetting(aValue, aBrowser) {
     var browser = aBrowser || gBrowser.selectedBrowser;
 
-    if (!this.siteSpecific || gInPrintPreviewMode ||
-        browser.contentDocument instanceof Ci.nsIImageDocument)
-      return;
+    var resetZoom = (!this.siteSpecific || gInPrintPreviewMode ||
+                     browser.contentDocument instanceof Ci.nsIImageDocument);
 
     try {
-      if (typeof aValue != "undefined")
+      if (resetZoom)
+        ZoomManager.setZoomForBrowser(browser, 1);
+      else if (typeof aValue != "undefined")
         ZoomManager.setZoomForBrowser(browser, this._ensureValid(aValue));
       else if (typeof this.globalValue != "undefined")
         ZoomManager.setZoomForBrowser(browser, this.globalValue);
       else
         ZoomManager.setZoomForBrowser(browser, 1);
     }
     catch(ex) {}
   },
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -40,17 +40,17 @@ toolbarpaletteitem[place="palette"] > to
   display: none;
 }
 
 #feed-button > .button-box > .box-inherit > .button-text,
 #feed-button > .button-box > .button-menu-dropmarker {
   display: none;
 }
 
-#feed-menu[chromedir="rtl"] > menuitem {
+#feed-menu:-moz-locale-dir(rtl) > menuitem {
   direction: rtl;
 }
 
 #urlbar[pageproxystate="invalid"] > #urlbar-icons > :not(#go-button) ,
 #urlbar[pageproxystate="valid"] > #urlbar-icons > #go-button ,
 #urlbar[isempty="true"] > #urlbar-icons > #go-button {
   visibility: collapse;
 }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -41,16 +41,17 @@
 #   Michael Ventnor <m.ventnor@gmail.com>
 #   Simon Bünzli <zeniko@gmail.com>
 #   Johnathan Nightingale <johnath@mozilla.com>
 #   Ehsan Akhgari <ehsan.akhgari@gmail.com>
 #   Dão Gottwald <dao@mozilla.com>
 #   Thomas K. Dyas <tdyas@zecador.org>
 #   Edward Lee <edward.lee@engineering.uiuc.edu>
 #   Paul O’Shannessy <paul@oshannessy.com>
+#   Nils Maier <maierman@web.de>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -1834,28 +1835,61 @@ function delayedOpenWindow(chrome, flags
 
 /* Required because the tab needs time to set up its content viewers and get the load of
    the URI kicked off before becoming the active content area. */
 function delayedOpenTab(aUrl, aReferrer, aCharset, aPostData, aAllowThirdPartyFixup)
 {
   gBrowser.loadOneTab(aUrl, aReferrer, aCharset, aPostData, false, aAllowThirdPartyFixup);
 }
 
+var gLastOpenDirectory = {
+  _lastDir: null,
+  get path() {
+    if (!this._lastDir || !this._lastDir.exists()) {
+      try {
+        this._lastDir = gPrefService.getComplexValue("browser.open.lastDir",
+                                                     Ci.nsILocalFile);
+        if (!this._lastDir.exists())
+          this._lastDir = null;
+      }
+      catch(e) {}
+    }
+    return this._lastDir;
+  },
+  set path(val) {
+    if (!val || !val.exists() || !val.isDirectory())
+      return;
+    this._lastDir = val.clone();
+
+    // Don't save the last open directory pref inside the Private Browsing mode
+    if (!gPrivateBrowsingUI.privateBrowsingEnabled)
+      gPrefService.setComplexValue("browser.open.lastDir", Ci.nsILocalFile,
+                                   this._lastDir);
+  },
+  reset: function() {
+    this._lastDir = null;
+  }
+};
+
 function BrowserOpenFileWindow()
 {
   // Get filepicker component.
   try {
     const nsIFilePicker = Components.interfaces.nsIFilePicker;
     var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
     fp.init(window, gNavigatorBundle.getString("openFile"), nsIFilePicker.modeOpen);
     fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText | nsIFilePicker.filterImages |
                      nsIFilePicker.filterXML | nsIFilePicker.filterHTML);
-
-    if (fp.show() == nsIFilePicker.returnOK)
+    fp.displayDirectory = gLastOpenDirectory.path;
+
+    if (fp.show() == nsIFilePicker.returnOK) {
+      if (fp.file && fp.file.exists())
+        gLastOpenDirectory.path = fp.file.parent.QueryInterface(Ci.nsILocalFile);
       openTopWin(fp.fileURL.spec);
+    }
   } catch (ex) {
   }
 }
 
 function BrowserCloseTabOrWindow() {
 #ifdef XP_MACOSX
   // If we're not a browser window, just close the window
   if (window.location.href != getBrowserURL()) {
@@ -2552,17 +2586,16 @@ function onEnterPrintPreview()
   gInPrintPreviewMode = true;
   toggleAffectedChrome(true);
 }
 
 function onExitPrintPreview()
 {
   // restore chrome to original state
   gInPrintPreviewMode = false;
-  FullZoom.setSettingValue();
   toggleAffectedChrome(false);
 }
 
 function getPPBrowser()
 {
   return gBrowser;
 }
 
@@ -2655,20 +2688,19 @@ var browserDragAndDrop = {
     }
 
     // For shortcuts, we want to check for the file type last, so that the
     // url pointed to in one of the url types is found first before the file
     // type, which points to the actual file.
     var file = dt.mozGetDataAt("application/x-moz-file", 0);
     if (file) {
       var name = file instanceof Ci.nsIFile ? file.leafName : "";
-      var ioService = Cc["@mozilla.org/network/io-service;1"]
-                                .getService(Ci.nsIIOService);
-      var fileHandler = ioService.getProtocolHandler("file")
-                                 .QueryInterface(Ci.nsIFileProtocolHandler);
+      var fileHandler = ContentAreaUtils.ioService
+                                        .getProtocolHandler("file")
+                                        .QueryInterface(Ci.nsIFileProtocolHandler);
       return [fileHandler.getURLSpecFromFile(file), name];
     }
 
     return [ , ];
   },
 
   dragOver : function (aEvent, statusString)
   {
@@ -2884,19 +2916,17 @@ const DOMLinkHandler = {
           }
           break;
         case "icon":
           if (!iconAdded) {
             if (!gPrefService.getBoolPref("browser.chrome.site_icons"))
               break;
 
             var targetDoc = link.ownerDocument;
-            var ios = Cc["@mozilla.org/network/io-service;1"].
-                      getService(Ci.nsIIOService);
-            var uri = ios.newURI(link.href, targetDoc.characterSet, null);
+            var uri = makeURI(link.href, targetDoc.characterSet);
 
             if (gBrowser.isFailedIcon(uri))
               break;
 
             // Verify that the load of this icon is legal.
             // error pages can load their favicon, to be on the safe side,
             // only allow chrome:// favicons
             const aboutNeterr = /^about:neterror\?/;
@@ -3469,17 +3499,17 @@ function updateEditUIVisibility()
 var FullScreen =
 {
   _XULNS: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
   toggle: function()
   {
     // show/hide all menubars, toolbars, and statusbars (except the full screen toolbar)
     this.showXULChrome("toolbar", window.fullScreen);
     this.showXULChrome("statusbar", window.fullScreen);
-    document.getElementById("fullScreenItem").setAttribute("checked", !window.fullScreen);
+    document.getElementById("View:FullScreen").setAttribute("checked", !window.fullScreen);
 
     var fullScrToggler = document.getElementById("fullscr-toggler");
     if (!window.fullScreen) {
       // Add a tiny toolbar to receive mouseover and dragenter events, and provide affordance.
       // This will help simulate the "collapse" metaphor while also requiring less code and
       // events than raw listening of mouse coords.
       if (!fullScrToggler) {
         fullScrToggler = document.createElement("toolbar");
@@ -4226,17 +4256,17 @@ var XULBrowserWindow = {
       // properties anyways, though.
     }
     gIdentityHandler.checkIdentity(this._state, locationObj);
   },
 
   // simulate all change notifications after switching tabs
   onUpdateCurrentBrowser: function (aStateFlags, aStatus, aMessage, aTotalProgress) {
     if (FullZoom.updateBackgroundTabs)
-      FullZoom.onLocationChange(gBrowser.currentURI);
+      FullZoom.onLocationChange(gBrowser.currentURI, true);
     var nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
     var loadingDone = aStateFlags & nsIWebProgressListener.STATE_STOP;
     // use a pseudo-object instead of a (potentially non-existing) channel for getting
     // a correct error message - and make sure that the UI is always either in
     // loading (STATE_START) or done (STATE_STOP) mode
     this.onStateChange(
       gBrowser.webProgress,
       { URI: gBrowser.currentURI },
@@ -4293,17 +4323,17 @@ var TabsProgressListener = {
   },
 
   onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
   },
 
   onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI) {
     // Filter out any sub-frame loads
     if (aBrowser.contentWindow == aWebProgress.DOMWindow)
-      FullZoom.onLocationChange(aLocationURI, aBrowser);
+      FullZoom.onLocationChange(aLocationURI, false, aBrowser);
   },
   
   onStatusChange: function (aBrowser, aWebProgress, aRequest, aStatus, aMessage) {
   },
 
   onRefreshAttempted: function (aBrowser, aWebProgress, aURI, aDelay, aSameURI) {
     if (gPrefService.getBoolPref("accessibility.blockautorefresh")) {
       let brandBundle = document.getElementById("bundle_brand");
@@ -4417,40 +4447,34 @@ nsBrowserAccess.prototype =
         var newTab = win.gBrowser.loadOneTab("about:blank", null, null, null, loadInBackground, false);
         newWindow = win.gBrowser.getBrowserForTab(newTab).docShell
                                 .QueryInterface(Ci.nsIInterfaceRequestor)
                                 .getInterface(Ci.nsIDOMWindow);
         try {
           if (aURI) {
             if (aOpener) {
               location = aOpener.location;
-              referrer =
-                      Components.classes["@mozilla.org/network/io-service;1"]
-                                .getService(Components.interfaces.nsIIOService)
-                                .newURI(location, null, null);
+              referrer = makeURI(location);
             }
             newWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                      .getInterface(Ci.nsIWebNavigation)
                      .loadURI(aURI.spec, loadflags, referrer, null, null);
           }
           if (needToFocusWin || (!loadInBackground && isExternal))
             newWindow.focus();
         } catch(e) {
         }
         break;
       default : // OPEN_CURRENTWINDOW or an illegal value
         try {
           if (aOpener) {
             newWindow = aOpener.top;
             if (aURI) {
               location = aOpener.location;
-              referrer =
-                      Components.classes["@mozilla.org/network/io-service;1"]
-                                .getService(Components.interfaces.nsIIOService)
-                                .newURI(location, null, null);
+              referrer = makeURI(location);
 
               newWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(nsIWebNavigation)
                        .loadURI(aURI.spec, loadflags, referrer, null, null);
             }
           } else {
             newWindow = gBrowser.selectedBrowser.docShell
                                 .QueryInterface(Ci.nsIInterfaceRequestor)
@@ -5413,21 +5437,18 @@ var OfflineApps = {
   },
 
   _getManifestURI: function(aWindow) {
     if (!aWindow.document.documentElement) return null;
     var attr = aWindow.document.documentElement.getAttribute("manifest");
     if (!attr) return null;
 
     try {
-      var ios = Cc["@mozilla.org/network/io-service;1"].
-                getService(Ci.nsIIOService);
-
-      var contentURI = ios.newURI(aWindow.location.href, null, null);
-      return ios.newURI(attr, aWindow.document.characterSet, contentURI);
+      var contentURI = makeURI(aWindow.location.href, null, null);
+      return makeURI(attr, aWindow.document.characterSet, contentURI);
     } catch (e) {
       return null;
     }
   },
 
   // A cache update isn't tied to a specific window.  Try to find
   // the best browser in which to warn the user about space usage
   _getBrowserForCacheUpdate: function(aCacheUpdate) {
@@ -5618,36 +5639,31 @@ var OfflineApps = {
   _startFetching: function(aDocument) {
     if (!aDocument.documentElement)
       return;
 
     var manifest = aDocument.documentElement.getAttribute("manifest");
     if (!manifest)
       return;
 
-    var ios = Cc["@mozilla.org/network/io-service;1"].
-              getService(Ci.nsIIOService);
-
-    var manifestURI = ios.newURI(manifest, aDocument.characterSet,
-                                 aDocument.documentURIObject);
+    var manifestURI = makeURI(manifest, aDocument.characterSet,
+                              aDocument.documentURIObject);
 
     var updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"].
                         getService(Ci.nsIOfflineCacheUpdateService);
     updateService.scheduleUpdate(manifestURI, aDocument.documentURIObject);
   },
 
   /////////////////////////////////////////////////////////////////////////////
   // nsIObserver
   observe: function (aSubject, aTopic, aState)
   {
     if (aTopic == "dom-storage-warn-quota-exceeded") {
       if (aSubject) {
-        var uri = Cc["@mozilla.org/network/io-service;1"].
-                  getService(Ci.nsIIOService).
-                  newURI(aSubject.location.href, null, null);
+        var uri = makeURI(aSubject.location.href);
 
         if (OfflineApps._checkUsage(uri)) {
           var browserWindow =
             this._getBrowserWindowForContentWindow(aSubject);
           var browser = this._getBrowserForContentWindow(browserWindow,
                                                          aSubject);
           OfflineApps._warnUsage(browser, uri);
         }
@@ -5663,54 +5679,89 @@ var OfflineApps = {
         }
       }
     }
   }
 };
 
 function WindowIsClosing()
 {
-  var cn = gBrowser.tabContainer.childNodes;
-  var numtabs = cn.length;
-  var reallyClose = 
-    closeWindow(false,
-                function () {
-                  return gBrowser.warnAboutClosingTabs(true);
-                });
-
+  var reallyClose = closeWindow(false, warnAboutClosingWindow);
   if (!reallyClose)
     return false;
 
-  for (var i = 0; reallyClose && i < numtabs; ++i) {
-    var ds = gBrowser.getBrowserForTab(cn[i]).docShell;
+  var numBrowsers = gBrowser.browsers.length;
+  for (let i = 0; reallyClose && i < numBrowsers; ++i) {
+    let ds = gBrowser.browsers[i].docShell;
 
     if (ds.contentViewer && !ds.contentViewer.permitUnload())
       reallyClose = false;
   }
 
   return reallyClose;
 }
 
+/**
+ * Checks if this is the last full *browser* window around. If it is, this will
+ * be communicated like quitting. Otherwise, we warn about closing multiple tabs.
+ * @returns true if closing can proceed, false if it got cancelled.
+ */
+function warnAboutClosingWindow() {
+  // Popups aren't considered full browser windows.
+  if (!toolbar.visible)
+    return gBrowser.warnAboutClosingTabs(true);
+
+  // Figure out if there's at least one other browser window around.
+  let foundOtherBrowserWindow = false;
+  let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
+  let e = wm.getEnumerator("navigator:browser");
+  while (e.hasMoreElements() && !foundOtherBrowserWindow) {
+    let win = e.getNext();
+    if (win != window && win.toolbar.visible)
+      foundOtherBrowserWindow = true;
+  }
+  if (foundOtherBrowserWindow)
+    return gBrowser.warnAboutClosingTabs(true);
+
+  let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+
+  let closingCanceled = Cc["@mozilla.org/supports-PRBool;1"].
+                        createInstance(Ci.nsISupportsPRBool);
+  os.notifyObservers(closingCanceled,
+                                   "browser-lastwindow-close-requested", null);
+  if (closingCanceled.data)
+    return false;
+
+  os.notifyObservers(null, "browser-lastwindow-close-granted", null);
+
+#ifdef XP_MACOSX
+  // OS X doesn't quit the application when the last window is closed, but keeps
+  // the session alive. Hence don't prompt users to save tabs, but warn about
+  // closing multiple tabs.
+  return gBrowser.warnAboutClosingTabs(true);
+#else
+  return true;
+#endif
+}
+
 var MailIntegration = {
   sendLinkForWindow: function (aWindow) {
     this.sendMessage(aWindow.location.href,
                      aWindow.document.title);
   },
 
   sendMessage: function (aBody, aSubject) {
     // generate a mailto url based on the url and the url's title
     var mailtoUrl = "mailto:";
     if (aBody) {
       mailtoUrl += "?body=" + encodeURIComponent(aBody);
       mailtoUrl += "&subject=" + encodeURIComponent(aSubject);
     }
 
-    var ioService = Components.classes["@mozilla.org/network/io-service;1"]
-                              .getService(Components.interfaces.nsIIOService);
-    var uri = ioService.newURI(mailtoUrl, null, null);
+    var uri = makeURI(mailtoUrl);
 
     // now pass this uri to the operating system
     this._launchExternalUrl(uri);
   },
 
   // a generic method which can be used to pass arbitrary urls to the operating
   // system.
   // aURL --> a nsIURI which represents the url to launch
@@ -6642,19 +6693,17 @@ var gIdentityHandler = {
     this._identityPopup.popupBoxObject
         .setConsumeRollupEvent(Ci.nsIPopupBoxObject.ROLLUP_CONSUME);
     
     // Update the popup strings
     this.setPopupMessages(this._identityBox.className);
     
     // Make sure the identity popup hangs toward the middle of the location bar
     // in RTL builds
-    var position = 'after_start';
-    if (gURLBar.getAttribute("chromedir") == "rtl")
-      position = 'after_end';
+    var position = (getComputedStyle(gNavToolbox, "").direction == "rtl") ? 'after_end' : 'after_start';
 
     // Add the "open" attribute to the identity box for styling
     this._identityBox.setAttribute("open", "true");
     var self = this;
     this._identityPopup.addEventListener("popuphidden", function (e) {
       e.currentTarget.removeEventListener("popuphidden", arguments.callee, false);
       self._identityBox.removeAttribute("open");
     }, false);
@@ -6669,26 +6718,29 @@ let DownloadMonitorPanel = {
   //// DownloadMonitorPanel Member Variables
 
   _panel: null,
   _activeStr: null,
   _pausedStr: null,
   _lastTime: Infinity,
   _listening: false,
 
+  get DownloadUtils() {
+    delete this.DownloadUtils;
+    Cu.import("resource://gre/modules/DownloadUtils.jsm", this);
+    return this.DownloadUtils;
+  },
+
   //////////////////////////////////////////////////////////////////////////////
   //// DownloadMonitorPanel Public Methods
 
   /**
    * Initialize the status panel and member variables
    */
   init: function DMP_init() {
-    // Load the modules to help display strings
-    Cu.import("resource://gre/modules/DownloadUtils.jsm");
-
     // Initialize "private" member variables
     this._panel = document.getElementById("download-monitor");
 
     // Cache the status strings
     this._activeStr = gNavigatorBundle.getString("activeDownloads");
     this._pausedStr = gNavigatorBundle.getString("pausedDownloads");
 
     gDownloadMgr.addListener(this);
@@ -6697,20 +6749,27 @@ let DownloadMonitorPanel = {
     this.updateStatus();
   },
 
   uninit: function DMP_uninit() {
     if (this._listening)
       gDownloadMgr.removeListener(this);
   },
 
+  inited: function DMP_inited() {
+    return this._panel != null;
+  },
+
   /**
    * Update status based on the number of active and paused downloads
    */
   updateStatus: function DMP_updateStatus() {
+    if (!this.inited())
+      return;
+
     let numActive = gDownloadMgr.activeDownloadCount;
 
     // Hide the panel and reset the "last time" if there's no downloads
     if (numActive == 0) {
       this._panel.hidden = true;
       this._lastTime = Infinity;
 
       return;
@@ -6730,17 +6789,18 @@ let DownloadMonitorPanel = {
           maxTime = -1;
       }
       else if (dl.state == gDownloadMgr.DOWNLOAD_PAUSED)
         numPaused++;
     }
 
     // Get the remaining time string and last sec for time estimation
     let timeLeft;
-    [timeLeft, this._lastTime] = DownloadUtils.getTimeLeft(maxTime, this._lastTime);
+    [timeLeft, this._lastTime] =
+      this.DownloadUtils.getTimeLeft(maxTime, this._lastTime);
 
     // Figure out how many downloads are currently downloading
     let numDls = numActive - numPaused;
     let status = this._activeStr;
 
     // If all downloads are paused, show the paused message instead
     if (numDls == 0) {
       numDls = numPaused;
@@ -6907,16 +6967,20 @@ let gPrivateBrowsingUI = {
       // Adjust the window's title
       let docElement = document.documentElement;
       docElement.setAttribute("title",
         docElement.getAttribute("title_privatebrowsing"));
       docElement.setAttribute("titlemodifier",
         docElement.getAttribute("titlemodifier_privatebrowsing"));
       docElement.setAttribute("browsingmode", "private");
     }
+
+    setTimeout(function () {
+      DownloadMonitorPanel.updateStatus();
+    }, 0);
   },
 
   onExitPrivateBrowsing: function PBUI_onExitPrivateBrowsing() {
     if (BrowserSearch.searchBar)
       BrowserSearch.searchBar.textbox.reset();
 
     document.getElementById("menu_import").removeAttribute("disabled");
 
@@ -6941,16 +7005,22 @@ let gPrivateBrowsingUI = {
 
     // Enable the menu item in after exiting the auto-start mode
     document.getElementById("privateBrowsingItem")
             .removeAttribute("disabled");
     document.getElementById("Tools:PrivateBrowsing")
             .removeAttribute("disabled");
 
     this._privateBrowsingAutoStarted = false;
+
+    gLastOpenDirectory.reset();
+
+    setTimeout(function () {
+      DownloadMonitorPanel.updateStatus();
+    }, 0);
   },
 
   _setPBMenuTitle: function PBUI__setPBMenuTitle(aMode) {
     let pbMenuItem = document.getElementById("privateBrowsingItem");
     pbMenuItem.setAttribute("label", pbMenuItem.getAttribute(aMode + "label"));
     pbMenuItem.setAttribute("accesskey", pbMenuItem.getAttribute(aMode + "accesskey"));
   },
 
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -99,27 +99,26 @@
 <script type="application/javascript" src="chrome://browser/content/places/editBookmarkOverlay.js"/>
 
 # All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the 
 # browser-sets.inc file for sharing with hiddenWindow.xul.
 #include browser-sets.inc
 
   <popupset id="mainPopupSet">
     <menupopup id="backForwardMenu"
-               chromedir="&locale.dir;"
                onpopupshowing="return FillHistoryMenu(event.target);"
                oncommand="gotoHistoryIndex(event);"
                onclick="checkForMiddleClick(this, event);"/>
     <tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
 
     <!-- for search and content formfill/pw manager -->
-    <panel type="autocomplete" chromedir="&locale.dir;" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
+    <panel type="autocomplete" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
 
     <!-- for url bar autocomplete -->
-    <panel type="autocomplete-richlistbox" chromedir="&locale.dir;" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
+    <panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
 
     <panel id="editBookmarkPanel"
            orient="vertical"
            ignorekeys="true"
            hidden="true"
            onpopupshown="StarUI.panelShown(event);"
            aria-labelledby="editBookmarkPanelTitle">
       <row id="editBookmarkPanelHeader" align="center" hidden="true">
@@ -200,18 +199,17 @@
 #include browser-context.inc
     </popup>
 
     <popup id="placesContext"/>
 
     <!-- Popup for site identity information -->
     <panel id="identity-popup" position="after_start" hidden="true" noautofocus="true"
            onpopupshown="document.getElementById('identity-popup-more-info-button').focus();"
-           level="top"
-           chromedir="&locale.dir;">
+           level="top">
       <hbox id="identity-popup-container" align="top">
         <image id="identity-popup-icon"/>
         <vbox id="identity-popup-content-box">
           <label id="identity-popup-connectedToLabel" value="&identity.connectedTo;"/>
           <label id="identity-popup-connectedToLabel2"
                  value="&identity.unverifiedsite2;"/>
           <description id="identity-popup-content-host"/>
           <label id="identity-popup-runByLabel" value="&identity.runBy;"/>
@@ -313,36 +311,33 @@
       </toolbaritem>
     </toolbar>
 
     <toolbarpalette id="BrowserToolbarPalette">
 
       <toolbaritem id="unified-back-forward-button" class="chromeclass-toolbar-additional"
                    context="backForwardMenu">
         <toolbarbutton id="back-button" class="toolbarbutton-1"
-                       chromedir="&locale.dir;"
                        label="&backCmd.label;"
                        command="Browser:BackOrBackDuplicate"
                        onclick="checkForMiddleClick(this, event);"
                        tooltiptext="&backButton.tooltip;"/>
         <toolbarbutton id="forward-button" class="toolbarbutton-1"
-                       chromedir="&locale.dir;"
                        label="&forwardCmd.label;"
                        command="Browser:ForwardOrForwardDuplicate"
                        onclick="checkForMiddleClick(this, event);"
                        tooltiptext="&forwardButton.tooltip;"/>
-        <toolbarbutton id="back-forward-dropmarker" type="menu" chromedir="&locale.dir;"
+        <toolbarbutton id="back-forward-dropmarker" type="menu"
                        disabled="true" tooltiptext="&backForwardMenu.tooltip;"
                        onbroadcast="if (this.disabled) this.disabled =
                                       document.getElementById('Browser:Back').hasAttribute('disabled') &amp;&amp;
                                       document.getElementById('Browser:Forward').hasAttribute('disabled');">
           <!-- bug 415444: event.stopPropagation is here for the cloned version of
                this menupopup -->
           <menupopup context=""
-                     chromedir="&locale.dir;"
                      position="after_start"
                      onpopupshowing="return FillHistoryMenu(event.target);"
                      oncommand="gotoHistoryIndex(event); event.stopPropagation();"
                      onclick="checkForMiddleClick(this, event);"/>
           <observes element="Browser:Back" attribute="disabled"/>
           <observes element="Browser:Forward" attribute="disabled"/>
         </toolbarbutton>
       </toolbaritem>
@@ -369,41 +364,40 @@
 
       <toolbaritem id="urlbar-container" align="center" flex="400" persist="width"
                    title="&locationItem.title;" class="chromeclass-location">
         <textbox id="urlbar" flex="1"
                  bookmarkhistoryemptytext="&urlbar.bookmarkhistory.emptyText;"
                  bookmarkemptytext="&urlbar.bookmark.emptyText;"
                  historyemptytext="&urlbar.history.emptyText;"
                  noneemptytext="&urlbar.none.emptyText;"
-                 chromedir="&locale.dir;"
                  type="autocomplete"
                  autocompletesearch="history"
                  autocompletepopup="PopupAutoCompleteRichResult"
                  completeselectedindex="true"
                  tabscrolling="true"
                  showcommentcolumn="true"
                  showimagecolumn="true"
                  enablehistory="true"
                  maxrows="6"
+                 timeout="75"
                  newlines="stripsurroundingwhitespace"
                  oninput="gBrowser.userTypedValue = this.value;"
                  ontextentered="this.handleCommand(param);"
                  ontextreverted="return this.handleRevert();"
                  pageproxystate="invalid"
                  onsearchbegin="LocationBarHelpers._searchBegin();"
                  onsearchcomplete="LocationBarHelpers._searchComplete();"
                  onfocus="document.getElementById('identity-box').style.MozUserFocus= 'normal'"
                  onblur="setTimeout(function() document.getElementById('identity-box').style.MozUserFocus = '', 0);">
           <!-- Use onclick instead of normal popup= syntax since the popup
                code fires onmousedown, and hence eats our favicon drag events.
                We only add the identity-box button to the tab order when the location bar
                has focus, otherwise pressing F6 focuses it instead of the location bar -->
           <box id="identity-box" role="button"
-               chromedir="&locale.dir;"
                onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
                onkeypress="gIdentityHandler.handleIdentityButtonEvent(event);">
             <hbox align="center">
               <stack id="page-proxy-stack"
                      onclick="PageProxyClickHandler(event);">
                 <image id="urlbar-throbber" busy="false"/>
                 <image id="page-proxy-favicon" validate="never"
                        pageproxystate="invalid"
@@ -413,43 +407,40 @@
               <label id="identity-icon-label" crop="center" flex="1"/>
             </hbox>
           </box>
           <hbox id="urlbar-icons">
             <button type="menu"
                     style="-moz-user-focus: none"
                     class="plain urlbar-icon"
                     id="feed-button"
-                    chromedir="&locale.dir;"
                     collapsed="true"
                     tooltiptext="&feedButton.tooltip;"
                     onclick="return FeedHandler.onFeedButtonClick(event);">
               <menupopup position="after_end"
                          id="feed-menu"
-                         chromedir="&locale.dir;"
                          onpopupshowing="return FeedHandler.buildFeedList(this);"
                          oncommand="return FeedHandler.subscribeToFeed(null, event);"
                          onclick="checkForMiddleClick(this, event);"/>
             </button>
             <image id="star-button"
                    class="urlbar-icon"
                    onclick="PlacesStarButton.onClick(event);"/>
             <image id="go-button"
-                   chromedir="&locale.dir;"
                    class="urlbar-icon"
                    tooltiptext="&goEndCap.tooltip;"
                    onclick="gURLBar.handleCommand(event);"/>
           </hbox>
         </textbox>
       </toolbaritem>
 
       <toolbaritem id="search-container" title="&searchItem.title;"
                    align="center" class="chromeclass-toolbar-additional"
                    flex="100" persist="width">
-        <searchbar id="searchbar" flex="1" chromedir="&locale.dir;"/>
+        <searchbar id="searchbar" flex="1"/>
       </toolbaritem>
 
       <toolbarbutton id="print-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      label="&printButton.label;" command="cmd_print"
                      tooltiptext="&printButton.tooltip;"/>
 
       <toolbaritem id="navigator-throbber" title="&throbberItem.title;" align="center" pack="center"
                    mousethrough="always">
@@ -515,17 +506,23 @@
                        label="&copyCmd.label;"
                        command="cmd_copy"
                        tooltiptext="&copyButton.tooltip;"/>
 
         <toolbarbutton id="paste-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                        label="&pasteCmd.label;"
                        command="cmd_paste"
                        tooltiptext="&pasteButton.tooltip;"/>
-
+#ifndef XP_MACOSX
+        <toolbarbutton id="fullscreen-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
+                       observes="View:FullScreen"
+                       type="checkbox"
+                       label="&fullScreenCmd.label;"
+                       tooltiptext="&fullScreenButton.tooltip;"/>
+#endif
     </toolbarpalette>
 
     <toolbar id="nav-bar" class="toolbar-primary chromeclass-toolbar"
              toolbarname="&navbarCmd.label;" accesskey="&navbarCmd.accesskey;"
              fullscreentoolbar="true" mode="icons"
 #ifdef WINCE
              iconsize="small" defaulticonsize="small"
 #else
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -1177,20 +1177,18 @@ nsContextMenu.prototype = {
       // for example, HTML case also throws if empty
       throw "Empty href";
     }
 
     return makeURLAbsolute(this.link.baseURI, href);
   },
   
   getLinkURI: function() {
-    var ioService = Cc["@mozilla.org/network/io-service;1"].
-                    getService(Ci.nsIIOService);
     try {
-      return ioService.newURI(this.linkURL, null, null);
+      return makeURI(this.linkURL);
     }
     catch (ex) {
      // e.g. empty URL string
     }
 
     return null;
   },
   
--- a/browser/base/content/openLocation.xul
+++ b/browser/base/content/openLocation.xul
@@ -74,17 +74,17 @@
                   class="uri-element"
                   oninput="doEnabling();"/>
         <button label="&chooseFile.label;" oncommand="onChooseFile();"/>
       </hbox>
       <hbox align="center">
         <label value="&openWhere.label;"/>
         <menulist id="openWhereList">
           <menupopup>
-            <menuitem value="0" id="currentWindow" label="&topWindow.label;"/>
+            <menuitem value="0" id="currentWindow" label="&topTab.label;"/>
             <menuitem value="1" label="&newWindow.label;"/>
             <menuitem value="3" label="&newTab.label;"/>
           </menupopup>
         </menulist>
         <spacer flex="1"/>
       </hbox>
     </vbox>
   </hbox> 
--- a/browser/base/content/pageinfo/pageInfo.xul
+++ b/browser/base/content/pageinfo/pageInfo.xul
@@ -43,18 +43,16 @@
 # ***** END LICENSE BLOCK *****
 
 <?xml-stylesheet href="chrome://browser/content/pageinfo/pageInfo.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/pageInfo.css" type="text/css"?>
 
 <!DOCTYPE window [
   <!ENTITY % pageInfoDTD SYSTEM "chrome://browser/locale/pageInfo.dtd">
   %pageInfoDTD;
-  <!ENTITY % global SYSTEM "chrome://global/locale/global.dtd">
-  %global;
 ]>
 
 #ifdef XP_MACOSX
 <?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
 #endif
 
 <window id="main-window"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
@@ -112,18 +110,17 @@
   </keyset>
 
   <menupopup id="picontext">
     <menuitem id="menu_selectall" label="&selectall.label;" command="cmd_selectall" accesskey="&selectall.accesskey;"/>
     <menuitem id="menu_copy"      label="&copy.label;"      command="cmd_copy"      accesskey="&copy.accesskey;"/>
   </menupopup>
 
   <windowdragbox id="topBar" class="viewGroupWrapper">
-    <radiogroup id="viewGroup" class="chromeclass-toolbar" orient="horizontal"
-                chromedir="&locale.dir;">
+    <radiogroup id="viewGroup" class="chromeclass-toolbar" orient="horizontal">
       <radio id="generalTab"  label="&generalTab;"  accesskey="&generalTab.accesskey;"
            oncommand="showTab('general');"/>
       <radio id="mediaTab"    label="&mediaTab;"    accesskey="&mediaTab.accesskey;"
            oncommand="showTab('media'); ensureSelection(gImageView)" hidden="true"/>
       <radio id="feedTab"     label="&feedTab;"     accesskey="&feedTab.accesskey;"
            oncommand="showTab('feed');" hidden="true"/>
       <radio id="permTab"     label="&permTab;"     accesskey="&permTab.accesskey;"
            oncommand="showTab('perm');"/>
--- a/browser/base/content/safeMode.js
+++ b/browser/base/content/safeMode.js
@@ -106,17 +106,17 @@ function restoreDefaultSearchEngines() {
 
   searchService.restoreDefaultEngines();
 }
 
 function onOK() {
   try {
     if (document.getElementById("resetUserPrefs").checked)
       clearAllPrefs();
-    if (document.getElementById("resetBookmarks").checked)
+    if (document.getElementById("deleteBookmarks").checked)
       restoreDefaultBookmarks();
     if (document.getElementById("resetToolbars").checked)
       deleteLocalstore();
     if (document.getElementById("disableAddons").checked)
       disableAddons();
     if (document.getElementById("restoreSearch").checked)
       restoreDefaultSearchEngines();
   } catch(e) {
@@ -134,13 +134,13 @@ function onCancel() {
 function onLoad() {
   document.getElementById("tasks")
           .addEventListener("CheckboxStateChange", UpdateOKButtonState, false);
 }
 
 function UpdateOKButtonState() {
   document.documentElement.getButton("accept").disabled = 
     !document.getElementById("resetUserPrefs").checked &&
-    !document.getElementById("resetBookmarks").checked &&
+    !document.getElementById("deleteBookmarks").checked &&
     !document.getElementById("resetToolbars").checked &&
     !document.getElementById("disableAddons").checked &&
     !document.getElementById("restoreSearch").checked;
 }
--- a/browser/base/content/safeMode.xul
+++ b/browser/base/content/safeMode.xul
@@ -74,15 +74,15 @@
   <description>&safeModeDescription.label;</description>
 
   <separator class="thin"/>
 
   <label value="&safeModeDescription2.label;"/>
   <vbox id="tasks">
     <checkbox id="disableAddons"  label="&disableAddons.label;"  accesskey="&disableAddons.accesskey;"/>
     <checkbox id="resetToolbars"  label="&resetToolbars.label;"  accesskey="&resetToolbars.accesskey;"/>
-    <checkbox id="resetBookmarks" label="&resetBookmarks.label;" accesskey="&resetBookmarks.accesskey;"/>
+    <checkbox id="deleteBookmarks" label="&deleteBookmarks.label;" accesskey="&deleteBookmarks.accesskey;"/>
     <checkbox id="resetUserPrefs" label="&resetUserPrefs.label;" accesskey="&resetUserPrefs.accesskey;"/>
     <checkbox id="restoreSearch"  label="&restoreSearch.label;"  accesskey="&restoreSearch.accesskey;"/>
   </vbox>
      
   <separator class="thin"/>
 </dialog>
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -45,35 +45,33 @@
    - 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 ***** -->
 
 <!DOCTYPE bindings [
 <!ENTITY % tabBrowserDTD SYSTEM "chrome://browser/locale/tabbrowser.dtd" >
 %tabBrowserDTD;
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
-%globalDTD;
 ]>
 
 <bindings id="tabBrowserBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
           xmlns:xbl="http://www.mozilla.org/xbl">
 
   <binding id="tabbrowser">
     <resources>
       <stylesheet src="chrome://browser/content/tabbrowser.css"/>
     </resources>
 
     <content>
       <xul:stringbundle anonid="tbstringbundle" src="chrome://browser/locale/tabbrowser.properties"/>
       <xul:tabbox anonid="tabbox" flex="1" eventnode="document" xbl:inherits="handleCtrlPageUpDown"
                   onselect="if (!('updateCurrentBrowser' in this.parentNode) || event.target.localName != 'tabpanels') return; this.parentNode.updateCurrentBrowser();">
-        <xul:hbox class="tab-drop-indicator-bar" collapsed="true" chromedir="&locale.dir;"
+        <xul:hbox class="tab-drop-indicator-bar" collapsed="true"
                   ondragover="this.parentNode.parentNode._onDragOver(event);"
                   ondragleave="this.parentNode.parentNode._onDragLeave(event);"
                   ondrop="this.parentNode.parentNode._onDrop(event);">
           <xul:hbox class="tab-drop-indicator" mousethrough="always"/>
         </xul:hbox>
         <xul:hbox class="tabbrowser-strip" collapsed="true" tooltip="_child" context="_child"
                   anonid="strip"
                   ondragstart="this.parentNode.parentNode._onDragStart(event);"
@@ -617,27 +615,23 @@
       </method>
 
       <method name="setIcon">
         <parameter name="aTab"/>
         <parameter name="aURI"/>
         <body>
           <![CDATA[
             var browser = this.getBrowserForTab(aTab);
-            browser.mIconURL = aURI;
-
-            if (aURI) {
-              if (!(aURI instanceof Components.interfaces.nsIURI)) {
-                var ios = Components.classes["@mozilla.org/network/io-service;1"]
-                                    .getService(Components.interfaces.nsIIOService);
-                aURI = ios.newURI(aURI, null, null);
-              }
-              if (this.mFaviconService)
-                this.mFaviconService.setAndLoadFaviconForPage(browser.currentURI,
-                                                              aURI, false);
+            browser.mIconURL = aURI instanceof Ci.nsIURI ? aURI.spec : aURI;
+
+            if (aURI && this.mFaviconService) {
+              if (!(aURI instanceof Ci.nsIURI))
+                aURI = makeURI(aURI);
+              this.mFaviconService.setAndLoadFaviconForPage(browser.currentURI,
+                                                            aURI, false);
             }
 
             this.updateIcon(aTab);
 
             if (browser == this.mCurrentBrowser) {
               for (let i = 0; i < this.mProgressListeners.length; i++) {
                 let p = this.mProgressListeners[i];
                 if ('onLinkIconAvailable' in p)
@@ -701,17 +695,17 @@
                     return;
 
                   var req = browser.contentDocument.imageRequest;
                   if (!req || !req.image ||
                       req.image.width > sz ||
                       req.image.height > sz)
                     return;
 
-                  this.setIcon(aTab, browser.currentURI.spec);
+                  this.setIcon(aTab, browser.currentURI);
                 } catch (e) { }
               }
             }
             // Use documentURIObject in the check for shouldLoadFavIcon so that we
             // do the right thing with about:-style error pages.  Bug 453442
             else if (this.shouldLoadFavIcon(browser.contentDocument.documentURIObject)) {
               var url = browser.currentURI.prePath + "/favicon.ico";
               if (!this.isFailedIcon(url))
@@ -720,24 +714,21 @@
           ]]>
         </body>
       </method>
 
       <method name="isFailedIcon">
         <parameter name="aURI"/>
         <body>
           <![CDATA[
-            if (!(aURI instanceof Components.interfaces.nsIURI)) {
-              var ios = Components.classes["@mozilla.org/network/io-service;1"]
-                                  .getService(Components.interfaces.nsIIOService);
-              aURI = ios.newURI(aURI, null, null);
+            if (this.mFaviconService) {
+              if (!(aURI instanceof Ci.nsIURI))
+                aURI = makeURI(aURI);
+              return this.mFaviconService.isFailedFavicon(aURI);
             }
-
-            if (this.mFaviconService)
-              return this.mFaviconService.isFailedFavicon(aURI);
             return null;
           ]]>
         </body>
       </method>
 
       <method name="updateTitlebar">
         <body>
           <![CDATA[
@@ -2814,35 +2805,33 @@
     <content>
       <xul:toolbarbutton class="scrollbutton-up" collapsed="true"
                          xbl:inherits="orient"
                          anonid="scrollbutton-up"
                          onclick="_distanceScroll(event);"
                          onmousedown="_startScroll(-1);"
                          onmouseover="_continueScroll(-1);"
                          onmouseup="_stopScroll();"
-                         onmouseout="_pauseScroll();"
-                         chromedir="&locale.dir;"/>
+                         onmouseout="_pauseScroll();"/>
       <xul:scrollbox xbl:inherits="orient,align,pack,dir" flex="1" anonid="scrollbox">
         <children/>
       </xul:scrollbox>
       <xul:stack align="center" pack="end" class="scrollbutton-down-stack">
         <xul:hbox flex="1" class="scrollbutton-down-box" 
                            collapsed="true" anonid="down-box"/>
         <xul:hbox flex="1" class="scrollbutton-down-box-animate" 
                            collapsed="true" anonid="down-box-animate"/>
         <xul:toolbarbutton class="scrollbutton-down" collapsed="true"
                            xbl:inherits="orient"
                            anonid="scrollbutton-down"
                            onclick="_distanceScroll(event);"
                            onmousedown="_startScroll(1);"
                            onmouseover="_continueScroll(1);"
                            onmouseup="_stopScroll();"
-                           onmouseout="_pauseScroll();"
-                           chromedir="&locale.dir;"/>
+                           onmouseout="_pauseScroll();"/>
       </xul:stack>
     </content>
 #endif
   </binding>
 
   <binding id="tabbrowser-tabs"
            extends="chrome://global/content/bindings/tabbox.xml#tabs">
     <content>
@@ -2853,45 +2842,45 @@
         </xul:vbox>
         <xul:hbox xbl:inherits="overflow" class="tabs-container">
 #ifdef XP_MACOSX
           <xul:stack>
             <xul:spacer class="tabs-left"/>
           </xul:stack>
 #endif
           <xul:arrowscrollbox anonid="arrowscrollbox" orient="horizontal" flex="1"
-                              style="min-width: 1px;" chromedir="&locale.dir;"
+                              style="min-width: 1px;"
 #ifndef XP_MACOSX
                               clicktoscroll="true"
 #endif
                               class="tabbrowser-arrowscrollbox">
 # This is a hack to circumvent bug 472020, otherwise the tabs show up on the
 # right of the newtab button.
             <children includes="tab"/>
 # This is to ensure anything extensions put here will go before the newtab
 # button, necessary due to the previous hack.
             <children/>
             <xul:toolbarbutton class="tabs-newtab-button"
-                               command="cmd_newNavigatorTab" chromedir="&locale.dir;"
+                               command="cmd_newNavigatorTab"
                                tooltiptext="&newTabButton.tooltip;"/>
           </xul:arrowscrollbox>
           <xul:toolbarbutton class="tabs-newtab-button" anonid="newtab-button"
-                             command="cmd_newNavigatorTab" chromedir="&locale.dir;"
+                             command="cmd_newNavigatorTab"
                              tooltiptext="&newTabButton.tooltip;"/>
-          <xul:stack align="center" pack="end" chromedir="&locale.dir;">
+          <xul:stack align="center" pack="end">
             <xul:hbox flex="1" class="tabs-alltabs-box-animate" anonid="alltabs-box-animate"/>
             <xul:toolbarbutton class="tabs-alltabs-button" anonid="alltabs-button"
                                type="menu"
                                tooltiptext="&listAllTabs.label;">
              <xul:menupopup class="tabs-alltabs-popup" anonid="alltabs-popup"
                             position="after_end"/>
             </xul:toolbarbutton>
           </xul:stack>
           <xul:toolbarbutton anonid="tabs-closebutton"
-                             class="close-button tabs-closebutton" chromedir="&locale.dir;"/>
+                             class="close-button tabs-closebutton"/>
         </xul:hbox>
       </xul:stack>
     </content>
     <implementation implements="nsITimerCallback, nsIDOMEventListener">
       <constructor>
         <![CDATA[
           var pb2 =
               Components.classes['@mozilla.org/preferences-service;1'].
@@ -3237,18 +3226,17 @@
         // for the one-close-button case
         event.stopPropagation();
       </handler>
     </handlers>
   </binding>
 
   <binding id="tabbrowser-tab" display="xul:hbox"
            extends="chrome://global/content/bindings/tabbox.xml#tab">
-    <content chromedir="&locale.dir;"
-             closetabtext="&closeTab.label;">
+    <content closetabtext="&closeTab.label;">
       <xul:image xbl:inherits="validate,src=image" class="tab-icon-image"/>
       <xul:label flex="1" xbl:inherits="value=label,crop,accesskey" class="tab-text"/>
       <xul:toolbarbutton anonid="close-button" tabindex="-1" class="tab-close-button"/>
     </content>
 
     <implementation>
       <field name="mOverCloseButton">false</field>
       <field name="mCorrespondingMenuitem">null</field>
--- a/browser/base/content/test/browser_bug386835.js
+++ b/browser/base/content/test/browser_bug386835.js
@@ -1,12 +1,14 @@
 var gTestPage = "http://example.org/browser/browser/base/content/test/dummy_page.html";
 var gTestImage = "http://example.org/browser/browser/base/content/test/moz.png";
 var gTab1, gTab2, gTab3;
 var gLevel;
+const kBack = 0;
+const kForward = 1;
 
 function test() {
   waitForExplicitFinish();
 
   gTab1 = gBrowser.addTab(gTestPage);
   gTab2 = gBrowser.addTab();
   gTab3 = gBrowser.addTab();
   gBrowser.selectedTab = gTab1;
@@ -48,20 +50,84 @@ function thirdPageLoaded() {
   load(gTab1, gTestImage, imageLoaded);
 }
 
 function imageLoaded() {
   zoomTest(gTab1, 1, "Zoom should be 1 when image was loaded in the background");
   gBrowser.selectedTab = gTab1;
   zoomTest(gTab1, 1, "Zoom should still be 1 when tab with image is selected");
 
-  finishTest();
+  executeSoon(imageZoomSwitch);
+}
+
+function imageZoomSwitch() {
+  navigate(kBack, function() {
+    navigate(kForward, function() {
+      zoomTest(gTab1, 1, "Tab 1 should not be zoomed when an image loads");
+      gBrowser.selectedTab = gTab2;
+      zoomTest(gTab1, 1, "Tab 1 should still not be zoomed when deselected");
+
+      // Mac OS X does not support print preview, so skip those tests
+      let isOSX = ("nsILocalFileMac" in Components.interfaces);
+      if (isOSX)
+        finishTest();
+      else
+        runPrintPreviewTests();
+    });
+  });
+}
+
+function runPrintPreviewTests() {
+  // test print preview on image document
+  testPrintPreview(gTab1, function() {
+    // test print preview on HTML document
+    testPrintPreview(gTab2, function() {
+      // test print preview on image document with siteSpecific set to false
+      gPrefService.setBoolPref("browser.zoom.siteSpecific", false);
+      testPrintPreview(gTab1, function() {
+        // test print preview of HTML document with siteSpecific set to false
+        testPrintPreview(gTab2, function() {
+          gPrefService.clearUserPref("browser.zoom.siteSpecific");
+          finishTest();
+        });
+      });
+    });
+  });
+}
+
+function testPrintPreview(aTab, aCallback) {
+  gBrowser.selectedTab = aTab;
+  FullZoom.enlarge();
+  let level = ZoomManager.zoom;
+
+  function onEnterPP() {
+    toggleAffectedChromeOrig.apply(null, arguments);
+
+    function onExitPP() {
+      toggleAffectedChromeOrig.apply(null, arguments);
+      toggleAffectedChrome = toggleAffectedChromeOrig;
+
+      zoomTest(aTab, level, "Toggling print preview mode should not affect zoom level");
+
+      FullZoom.reset();
+      aCallback();
+    }
+    toggleAffectedChrome = onExitPP;
+    PrintUtils.exitPrintPreview();
+  }
+  let toggleAffectedChromeOrig = toggleAffectedChrome;
+  toggleAffectedChrome = onEnterPP;
+
+  let printPreview = new Function(document.getElementById("cmd_printPreview")
+                                          .getAttribute("oncommand"));
+  executeSoon(printPreview);
 }
 
 function finishTest() {
+  gBrowser.selectedTab = gTab1;
   FullZoom.reset();
   gBrowser.removeTab(gTab1);
   FullZoom.reset();
   gBrowser.removeTab(gTab2);
   FullZoom.reset();
   gBrowser.removeTab(gTab3);
   finish();
 }
@@ -72,8 +138,19 @@ function zoomTest(tab, val, msg) {
 
 function load(tab, url, cb) {
   tab.linkedBrowser.addEventListener("load", function (event) {
     event.currentTarget.removeEventListener("load", arguments.callee, true);
     cb();
   }, true);
   tab.linkedBrowser.loadURI(url);
 }
+
+function navigate(direction, cb) {
+  gBrowser.addEventListener("pageshow", function(event) {
+    gBrowser.removeEventListener("pageshow", arguments.callee, true);
+    setTimeout(cb, 0);
+  }, true);
+  if (direction == kBack)
+    gBrowser.goBack();
+  else if (direction == kForward)
+    gBrowser.goForward();
+}
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -278,20 +278,18 @@
         <body><![CDATA[
           var val = this.value.substring(this.selectionStart, this.selectionEnd);
 
           // If the entire value is selected and it's a valid non-javascript,
           // non-data URI, encode it.
           if (val == this.value &&
               this.getAttribute("pageproxystate") == "valid") {
             let uri;
-            let ioService = Cc["@mozilla.org/network/io-service;1"]
-                              .getService(Ci.nsIIOService);
             try {
-              uri = ioService.newURI(val, null, null);
+              uri = makeURI(val);
             } catch (e) {}
 
             if (uri && !uri.schemeIs("javascript") && !uri.schemeIs("data")) {
               val = uri.spec;
 
               // Parentheses are known to confuse third-party applications (bug 458565).
               val = val.replace(/[()]/g, function (c) escape(c));
             }
@@ -382,20 +380,17 @@
         ]]></body>
       </method>
 
       <property name="textValue"
                 onget="return this.value;">
         <setter>
           <![CDATA[
           try {
-            let uri = Cc["@mozilla.org/network/io-service;1"].
-                      getService(Ci.nsIIOService).
-                      newURI(val, null, null);
-            val = losslessDecodeURI(uri);
+            val = losslessDecodeURI(makeURI(val));
           } catch (ex) { }
           this.value = val;
 
           // Completing a result should simulate the user typing the result, so
           // fire an input event.
           let evt = document.createEvent("UIEvents");
           evt.initUIEvent("input", true, false, window, 0);
           this.mIgnoreInput = true;
--- a/browser/base/content/web-panels.xul
+++ b/browser/base/content/web-panels.xul
@@ -42,18 +42,16 @@
 <?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
 <?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
 
 <!DOCTYPE page [
 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
 %browserDTD;
 <!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd">
 %textcontextDTD;
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
-%globalDTD;
 ]>
 
 <page id="webpanels-window"
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         onload="load()" onunload="unload()">
   <script type="application/x-javascript" src="chrome://global/content/contentAreaUtils.js"/>
   <script type="application/x-javascript" src="chrome://browser/content/browser.js"/>
--- a/browser/components/microsummaries/src/nsMicrosummaryService.js
+++ b/browser/components/microsummaries/src/nsMicrosummaryService.js
@@ -2050,17 +2050,17 @@ MicrosummaryResource.prototype = {
     // its charset in the bookmarks datastore the last time the user visited it,
     // then specify the charset in the channel so XMLHttpRequest loads
     // the resource correctly.
     try {
       var resolver = Cc["@mozilla.org/embeddor.implemented/bookmark-charset-resolver;1"].
                      getService(Ci.nsICharsetResolver);
       if (resolver) {
         var charset = resolver.requestCharset(null, request.channel, {}, {});
-        if (charset != "");
+        if (charset != "")
           request.channel.contentCharset = charset;
       }
     }
     catch(ex) {}
 
     request.send(null);
   },
 
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -904,17 +904,16 @@ var Module = {
     registerType("text/plain");
     registerType("image/gif");
     registerType("image/jpeg");
     registerType("image/jpg");
     registerType("image/png");
     registerType("image/bmp");
     registerType("image/x-icon");
     registerType("image/vnd.microsoft.icon");
-    registerType("image/x-xbitmap");
     registerType("application/http-index-format");
 
     var catMan = Components.classes["@mozilla.org/categorymanager;1"]
                            .getService(nsICategoryManager);
 
     catMan.addCategoryEntry("command-line-handler",
                             "m-browser",
                             bch_contractID, true, true);
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -20,16 +20,17 @@
 #
 # Contributor(s):
 #   Giorgio Maone <g.maone@informaction.com>
 #   Seth Spitzer <sspitzer@mozilla.com>
 #   Asaf Romano <mano@mozilla.com>
 #   Marco Bonardo <mak77@bonardo.net>
 #   Dietrich Ayala <dietrich@mozilla.com>
 #   Ehsan Akhgari <ehsan.akhgari@gmail.com>
+#   Nils Maier <maierman@web.de>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -97,16 +98,22 @@ function BrowserGlue() {
     delete this._observerService;
     return this._observerService = Cc['@mozilla.org/observer-service;1'].
                                    getService(Ci.nsIObserverService);
   });
 
   this._init();
 }
 
+#ifndef XP_MACOSX
+# OS X has the concept of zero-window sessions and therefore ignores the
+# browser-lastwindow-close-* topics.
+#define OBSERVE_LASTWINDOW_CLOSE_TOPICS 1
+#endif
+
 BrowserGlue.prototype = {
   
   _saveSession: false,
 
   _setPrefToSaveSession: function()
   {
     this._prefs.setBoolPref("browser.sessionstore.resume_session_once", true);
 
@@ -146,16 +153,27 @@ BrowserGlue.prototype = {
         if (this._saveSession) {
           this._setPrefToSaveSession();
         }
         // Everything that uses Places during shutdown should be here, since
         // on quit-application Places database connection will be closed
         // and history synchronization could fail.
         this._onProfileShutdown();
         break;
+#ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
+      case "browser-lastwindow-close-requested":
+        // The application is not actually quitting, but the last full browser
+        // window is about to be closed.
+        this._onQuitRequest(subject, "lastwindow");
+        break;
+      case "browser-lastwindow-close-granted":
+        if (this._saveSession)
+          this._setPrefToSaveSession();
+        break;
+#endif
       case "session-save":
         this._setPrefToSaveSession();
         subject.QueryInterface(Ci.nsISupportsPRBool);
         subject.data = true;
         break;
       case "places-init-complete":
         this._initPlaces();
         this._observerService.removeObserver(this, "places-init-complete");
@@ -184,32 +202,40 @@ BrowserGlue.prototype = {
     const osvr = this._observerService;
     osvr.addObserver(this, "xpcom-shutdown", false);
     osvr.addObserver(this, "prefservice:after-app-defaults", false);
     osvr.addObserver(this, "final-ui-startup", false);
     osvr.addObserver(this, "sessionstore-windows-restored", false);
     osvr.addObserver(this, "browser:purge-session-history", false);
     osvr.addObserver(this, "quit-application-requested", false);
     osvr.addObserver(this, "quit-application-granted", false);
+#ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
+    osvr.addObserver(this, "browser-lastwindow-close-requested", false);
+    osvr.addObserver(this, "browser-lastwindow-close-granted", false);
+#endif
     osvr.addObserver(this, "session-save", false);
     osvr.addObserver(this, "places-init-complete", false);
     osvr.addObserver(this, "places-database-locked", false);
   },
 
   // cleanup (called on application shutdown)
   _dispose: function() 
   {
     // observer removal 
     const osvr = this._observerService;
     osvr.removeObserver(this, "xpcom-shutdown");
     osvr.removeObserver(this, "prefservice:after-app-defaults");
     osvr.removeObserver(this, "final-ui-startup");
     osvr.removeObserver(this, "sessionstore-windows-restored");
     osvr.removeObserver(this, "browser:purge-session-history");
     osvr.removeObserver(this, "quit-application-requested");
+#ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
+    osvr.removeObserver(this, "browser-lastwindow-close-requested");
+    osvr.removeObserver(this, "browser-lastwindow-close-granted");
+#endif
     osvr.removeObserver(this, "quit-application-granted");
     osvr.removeObserver(this, "session-save");
   },
 
   _onAppDefaults: function()
   {
     // apply distribution customizations (prefs)
     // other customizations are applied in _onProfileStartup()
@@ -333,17 +359,16 @@ BrowserGlue.prototype = {
 
     // Never show a prompt inside the private browsing mode
     var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
                             getService(Ci.nsIPrivateBrowsingService).
                             privateBrowsingEnabled;
     if (!showPrompt || inPrivateBrowsing)
       return false;
 
-    var buttonChoice = 0;
     var quitBundle = this._bundleService.createBundle("chrome://browser/locale/quitDialog.properties");
     var brandBundle = this._bundleService.createBundle("chrome://branding/locale/brand.properties");
 
     var appName = brandBundle.GetStringFromName("brandShortName");
     var quitDialogTitle = quitBundle.formatStringFromName(aQuitType + "DialogTitle",
                                                           [appName], 1);
 
     var message;
@@ -372,19 +397,21 @@ BrowserGlue.prototype = {
     if (aQuitType == "restart")
       button0Title = quitBundle.GetStringFromName("restartTitle");
     else {
       flags += promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
       button0Title = quitBundle.GetStringFromName("saveTitle");
       button2Title = quitBundle.GetStringFromName("quitTitle");
     }
 
-    buttonChoice = promptService.confirmEx(null, quitDialogTitle, message,
-                                 flags, button0Title, button1Title, button2Title,
-                                 neverAskText, neverAsk);
+    var mostRecentBrowserWindow = wm.getMostRecentWindow("navigator:browser");
+    var buttonChoice =
+      promptService.confirmEx(mostRecentBrowserWindow, quitDialogTitle, message,
+                              flags, button0Title, button1Title, button2Title,
+                              neverAskText, neverAsk);
 
     switch (buttonChoice) {
     case 2: // Quit
       if (neverAsk.value)
         this._prefs.setBoolPref("browser.tabs.warnOnClose", false);
       break;
     case 1: // Cancel
       aCancelQuit.QueryInterface(Ci.nsISupportsPRBool);
@@ -1085,27 +1112,29 @@ GeolocationPrompt.prototype = {
     var notification = notificationBox.getNotificationWithValue("geolocation");
     if (!notification) {
       var bundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
       var browserBundle = bundleService.createBundle("chrome://browser/locale/browser.properties");
 
       var buttons = [{
               label: browserBundle.GetStringFromName("geolocation.shareLocation"),
               accessKey: browserBundle.GetStringFromName("geolocation.shareLocation.accesskey"),
-              callback: function(notification) {                  
-                  if (notification.getElementsByClassName("rememberChoice")[0].checked)
+              callback: function(notification) {
+                  var elements = notification.getElementsByClassName("rememberChoice");
+                  if (elements.length && elements[0].checked)
                       setPagePermission(request.requestingURI, true);
                   request.allow(); 
               },
           },
           {
               label: browserBundle.GetStringFromName("geolocation.dontShareLocation"),
               accessKey: browserBundle.GetStringFromName("geolocation.dontShareLocation.accesskey"),
               callback: function(notification) {
-                  if (notification.getElementsByClassName("rememberChoice")[0].checked)
+                  var elements = notification.getElementsByClassName("rememberChoice");
+                  if (elements.length && elements[0].checked)
                       setPagePermission(request.requestingURI, false);
                   request.cancel();
               },
           }];
       
       var message = browserBundle.formatStringFromName("geolocation.siteWantsToKnow",
                                                        [request.requestingURI.host], 1);      
 
@@ -1116,21 +1145,27 @@ GeolocationPrompt.prototype = {
                                                       buttons);
 
       // For whatever reason, if we do this immediately
       // (eg, without the setTimeout), the "link"
       // element does not show up in the notification
       // bar.
       function geolocation_hacks_to_notification () {
 
-        var checkbox = newBar.ownerDocument.createElementNS(XULNS, "checkbox");
-        checkbox.className = "rememberChoice";
-        checkbox.setAttribute("label", browserBundle.GetStringFromName("geolocation.remember"));
-        checkbox.setAttribute("accesskey", browserBundle.GetStringFromName("geolocation.remember.accesskey"));
-        newBar.appendChild(checkbox);
+        // Never show a remember checkbox inside the private browsing mode
+        var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
+                                getService(Ci.nsIPrivateBrowsingService).
+                                privateBrowsingEnabled;
+        if (!inPrivateBrowsing) {
+          var checkbox = newBar.ownerDocument.createElementNS(XULNS, "checkbox");
+          checkbox.className = "rememberChoice";
+          checkbox.setAttribute("label", browserBundle.GetStringFromName("geolocation.remember"));
+          checkbox.setAttribute("accesskey", browserBundle.GetStringFromName("geolocation.remember.accesskey"));
+          newBar.appendChild(checkbox);
+        }
 
         var link = newBar.ownerDocument.createElementNS(XULNS, "label");
         link.className = "text-link";
         link.setAttribute("value", browserBundle.GetStringFromName("geolocation.learnMore"));
 
         var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
         link.href = formatter.formatURLPref("browser.geolocation.warning.infoURL");
 
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -149,17 +149,17 @@ PlacesController.prototype = {
     case "cmd_paste":
     case "placesCmd_paste":
       return this._canInsert(true) && this._isClipboardDataPasteable();
     case "cmd_selectAll":
       if (this._view.selType != "single") {
         var result = this._view.getResult();
         if (result) {
           var container = asContainer(result.root);
-          if (container.containerOpen && container.childCount > 0);
+          if (container.containerOpen && container.childCount > 0)
             return true;
         }
       }
       return false;
     case "placesCmd_open":
     case "placesCmd_open:window":
     case "placesCmd_open:tab":
       var selectedNode = this._view.selectedNode;
--- a/browser/components/places/content/places.xml
+++ b/browser/components/places/content/places.xml
@@ -1,15 +1,10 @@
 <?xml version="1.0"?>
 
-<!DOCTYPE bindings [
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
-%globalDTD;
-]>
-
 <bindings id="placesBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:xbl="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   
   <binding id="command-button" extends="chrome://global/content/bindings/button.xml#button">
     <implementation>
--- a/browser/components/places/content/places.xul
+++ b/browser/components/places/content/places.xul
@@ -57,18 +57,16 @@
 <?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
 #endif
 
 <!DOCTYPE window [
 <!ENTITY % placesDTD SYSTEM "chrome://browser/locale/places/places.dtd">
 %placesDTD;
 <!ENTITY % editMenuOverlayDTD SYSTEM "chrome://global/locale/editMenuOverlay.dtd">
 %editMenuOverlayDTD;
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
-%globalDTD;
 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
 %browserDTD;
 ]>
 
 <window id="places"
         title="&places.library.title;" 
         windowtype="Places:Organizer" 
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
@@ -182,34 +180,32 @@
   <popupset id="placesPopupset">
     <popup id="placesContext"/>
     <popup id="placesColumnsContext"
            onpopupshowing="ViewMenu.fillWithColumns(event, null, null, 'checkbox', null);"
            oncommand="ViewMenu.showHideColumn(event.target); event.stopPropagation();"/>
   </popupset>
 
   <toolbox id="placesToolbox">
-    <toolbar class="chromeclass-toolbar" id="placesToolbar" align="center" chromedir="&locale.dir;">
+    <toolbar class="chromeclass-toolbar" id="placesToolbar" align="center">
       <toolbarbutton id="back-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      command="OrganizerCommand:Back"
                      tooltiptext="&backButton.tooltip;"
-                     chromedir="&locale.dir;"
                      disabled="true"/>
 
       <toolbarbutton id="forward-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      command="OrganizerCommand:Forward"
                      tooltiptext="&forwardButton.tooltip;"
-                     chromedir="&locale.dir;"
                      disabled="true"/>
 
 #ifdef XP_MACOSX
         <toolbarbutton type="menu" class="tabbable"
               onpopupshowing="document.getElementById('placeContent').focus()"
 #else
-      <menubar id="placesMenu" chromedir="&locale.dir;">
+      <menubar id="placesMenu">
         <menu accesskey="&organize.accesskey;" class="menu-iconic"
 #endif
               id="organizeButton" label="&organize.label;">
           <menupopup id="organizeButtonPopup">
             <menuitem id="newbookmark"
                       command="placesCmd_new:bookmark"
                       label="&cmd.new_bookmark.label;"
                       accesskey="&cmd.new_bookmark.accesskey;"/>
--- a/browser/components/places/content/toolbar.xml
+++ b/browser/components/places/content/toolbar.xml
@@ -36,18 +36,16 @@
 # 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 ***** 
 
 
 <!DOCTYPE bindings [
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" >
-%globalDTD;
 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
 %browserDTD;
 ]>
 
 <bindings id="placesToolbarBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:xbl="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
@@ -75,17 +73,16 @@
       <xul:hbox mousethrough="always"
                 flex="1"
                 pack="end">
         <xul:toolbarbutton type="menu"
                            class="chevron"
                            mousethrough="never"
                            collapsed="true"
                            tooltiptext="&bookmarksToolbarChevron.tooltip;"
-                           chromedir="&locale.dir;"
                            onpopupshowing="chevronPopupShowing(event);">
           <xul:menupopup anonid="chevronPopup"
                          xbl:inherits="tooltip"
 #ifndef XP_MACOSX
                          context="placesContext"
 #endif
           />
         </xul:toolbarbutton>
--- a/browser/components/places/tests/browser/Makefile.in
+++ b/browser/components/places/tests/browser/Makefile.in
@@ -57,12 +57,13 @@ include $(topsrcdir)/config/rules.mk
 	browser_history_sidebar_search.js \
 	browser_bookmarksProperties.js \
 	browser_forgetthissite_single.js \
 	browser_library_left_pane_commands.js \
 	browser_drag_bookmarks_on_toolbar.js \
 	browser_library_middleclick.js \
 	browser_library_views_liveupdate.js \
 	browser_views_liveupdate.js \
+	browser_sidebarpanels_click.js \
 	$(NULL)
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/browser/browser_sidebarpanels_click.js
@@ -0,0 +1,206 @@
+/* ***** 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 Places test code.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that the items in the bookmarks and history sidebar
+// panels are clickable in both LTR and RTL modes.
+
+function test() {
+  const BOOKMARKS_SIDEBAR_ID = "viewBookmarksSidebar";
+  const BOOKMARKS_SIDEBAR_TREE_ID = "bookmarks-view";
+  const HISTORY_SIDEBAR_ID = "viewHistorySidebar";
+  const HISTORY_SIDEBAR_TREE_ID = "historyTree";
+
+  // Initialization.
+  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+           getService(Ci.nsIWindowWatcher);
+  let bs = PlacesUtils.bookmarks;
+  let hs = PlacesUtils.history;
+  let sidebarBox = document.getElementById("sidebar-box");
+  let sidebar = document.getElementById("sidebar");
+  waitForExplicitFinish();
+
+  // If a sidebar is already open, close it.
+  if (!sidebarBox.hidden) {
+    info("Unexpected sidebar found - a previous test failed to cleanup correctly");
+    toggleSidebar();
+  }
+
+  const TEST_URL = "javascript:alert(\"test\");";
+
+  let tests = [];
+  tests.push({
+    _itemID: null,
+    init: function() {
+      // Add a bookmark to the Unfiled Bookmarks folder.
+      this._itemID = bs.insertBookmark(bs.unfiledBookmarksFolder,
+                                       PlacesUtils._uri(TEST_URL),
+                                       bs.DEFAULT_INDEX, "test");
+    },
+    prepare: function() {
+    },
+    selectNode: function(tree) {
+      tree.selectItems([this._itemID]);
+    },
+    cleanup: function() {
+      bs.removeFolderChildren(bs.unfiledBookmarksFolder);
+    },
+    sidebarName: BOOKMARKS_SIDEBAR_ID,
+    treeName: BOOKMARKS_SIDEBAR_TREE_ID,
+    desc: "Bookmarks sidebar test"
+  });
+
+  tests.push({
+    init: function() {
+      // Add a history entry.
+      this.cleanup();
+      hs.addVisit(PlacesUtils._uri(TEST_URL), Date.now() * 1000,
+                  null, hs.TRANSITION_TYPED, false, 0);
+    },
+    prepare: function() {
+      sidebar.contentDocument.getElementById("byvisited").doCommand();
+    },
+    selectNode: function(tree) {
+      tree.selectNode(tree.view.nodeForTreeIndex(0));
+      is(tree.selectedNode.uri, TEST_URL, "The correct visit has been selected");
+      is(tree.selectedNode.itemId, -1, "The selected node is not bookmarked");
+    },
+    cleanup: function() {
+      hs.QueryInterface(Ci.nsIBrowserHistory)
+        .removeAllPages();
+    },
+    sidebarName: HISTORY_SIDEBAR_ID,
+    treeName: HISTORY_SIDEBAR_TREE_ID,
+    desc: "History sidebar test"
+  });
+
+  let currentTest;
+
+  function testPlacesPanel(preFunc, postFunc) {
+    currentTest.init();
+
+    sidebar.addEventListener("load", function() {
+      sidebar.removeEventListener("load", arguments.callee, true);
+
+      let doc = sidebar.contentDocument;
+      let tree = doc.getElementById(currentTest.treeName);
+      let tbo = tree.treeBoxObject;
+
+      executeSoon(function() {
+        currentTest.prepare();
+        if (preFunc)
+          preFunc();
+
+        let observer = {
+          observe: function(aSubject, aTopic, aData) {
+            if (aTopic === "domwindowopened") {
+              ww.unregisterNotification(this);
+              let alertDialog = aSubject.QueryInterface(Ci.nsIDOMWindow);
+              alertDialog.addEventListener("load", function() {
+                alertDialog.removeEventListener("load", arguments.callee, false);
+                info("alert dialog observed as expected");
+                executeSoon(function() {
+                  alertDialog.close();
+                  toggleSidebar(currentTest.sidebarName);
+                  currentTest.cleanup();
+                  postFunc();
+                });
+              }, false);
+            }
+          }
+        };
+        ww.registerNotification(observer);
+
+        // Select the inserted places item.
+        currentTest.selectNode(tree);
+        is(tbo.view.selection.count, 1,
+           "The test node should be successfully selected");
+        // Get its row ID.
+        let min = {}, max = {};
+        tbo.view.selection.getRangeAt(0, min, max);
+        let rowID = min.value;
+        tbo.ensureRowIsVisible(rowID);
+
+        // Calculate the click coordinates.
+        let x = {}, y = {}, width = {}, height = {};
+        tbo.getCoordsForCellItem(rowID, tree.columns[0], "text",
+                                 x, y, width, height);
+        x = x.value + width.value / 2;
+        y = y.value + height.value / 2;
+        // Simulate the click.
+        EventUtils.synthesizeMouse(tree.body, x, y, {}, doc.defaultView);
+        // Now, wait for the domwindowopened observer to catch the alert dialog.
+        // If something goes wrong, the test will time out at this stage.
+        // Note that for the history sidebar, the URL itself is not opened,
+        // and Places will show the load-js-data-url-error prompt as an alert
+        // box, which means that the click actually worked, so it's good enough
+        // for the purpose of this test.
+      });
+    }, true);
+    toggleSidebar(currentTest.sidebarName);
+  }
+
+  function changeSidebarDirection(aDirection) {
+    document.getElementById("sidebar")
+            .contentDocument
+            .documentElement
+            .style.direction = aDirection;
+  }
+
+  function runNextTest() {
+    if (tests.length == 0)
+      finish();
+    else {
+      currentTest = tests.shift();
+      testPlacesPanel(function() {
+        changeSidebarDirection("ltr");
+        info("Running " + currentTest.desc + " in LTR mode");
+      }, function() {
+        executeSoon(function() {
+          testPlacesPanel(function() {
+            // Run the test in RTL mode.
+            changeSidebarDirection("rtl");
+            info("Running " + currentTest.desc + " in RTL mode");
+          }, function() {
+            executeSoon(runNextTest);
+          });
+        });
+      });
+    }
+  }
+
+  runNextTest();
+}
--- a/browser/components/places/tests/perf/Makefile.in
+++ b/browser/components/places/tests/perf/Makefile.in
@@ -40,25 +40,26 @@ topsrcdir      = @top_srcdir@
 srcdir         = @srcdir@
 VPATH          = @srcdir@
 relativesrcdir = browser/components/places/tests/perf
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _CHROME_FILES = \
-  perf_large_delete.xul \
-  $(NULL)
+	perf_large_delete.xul \
+	$(NULL)
 
+# XXX disabled tests, not working properly yet
+#  browser_ui_history_menu.js
+#  browser_ui_locationbar.js
+# XXX disabled tests, random failures
+#  browser_ui_bookmarks_sidebar.js
 _BROWSER_TEST_FILES = \
-  browser_ui_000_data.js\
-  browser_ui_bookmarks_sidebar.js\
-  browser_ui_history_sidebar.js\
-  $(NULL)
-# XXX disabled tests, not working properly yet
-#  browser_ui_history_menu.js\
-#  browser_ui_locationbar.js\
+	browser_ui_000_data.js \
+	browser_ui_history_sidebar.js \
+	$(NULL)
 
 libs:: $(_CHROME_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
--- a/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js
+++ b/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js
@@ -62,19 +62,24 @@ var observer = {
       tm.mainThread.dispatch({
         run: function() {
           continue_test();
         }
       }, Ci.nsIThread.DISPATCH_NORMAL);
     }
   }
 };
-os.addObserver(observer, NS_PLACES_INIT_COMPLETE_TOPIC, false);
 
 function run_test() {
+  // XXX bug 507199
+  // This test is temporarily disabled!
+  return;
+
+  os.addObserver(observer, NS_PLACES_INIT_COMPLETE_TOPIC, false);
+
   // Create bookmarks.html in the profile.
   create_bookmarks_html("bookmarks.glue.html");
   // Remove JSON backup from profile.
   remove_all_JSON_backups();
 
   // Remove current database file.
   var db = gProfD.clone();
   db.append("places.sqlite");
--- a/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js
+++ b/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js
@@ -62,19 +62,24 @@ var observer = {
       tm.mainThread.dispatch({
         run: function() {
           continue_test();
         }
       }, Ci.nsIThread.DISPATCH_NORMAL);
     }
   }
 };
-os.addObserver(observer, NS_PLACES_INIT_COMPLETE_TOPIC, false);
 
 function run_test() {
+  // XXX bug 507199
+  // This test is temporarily disabled!
+  return;
+
+  os.addObserver(observer, NS_PLACES_INIT_COMPLETE_TOPIC, false);
+
   // Remove bookmarks.html from profile.
   remove_bookmarks_html();
   // Remove JSON backup from profile.
   remove_all_JSON_backups();
 
   // Remove current database file.
   var db = gProfD.clone();
   db.append("places.sqlite");
--- a/browser/components/preferences/advanced.js
+++ b/browser/components/preferences/advanced.js
@@ -51,19 +51,18 @@ var gAdvancedPane = {
     this._inited = true;
     var advancedPrefs = document.getElementById("advancedPrefs");
 
     var extraArgs = window.arguments[1];
     if (extraArgs && extraArgs["advancedTab"]){
       advancedPrefs.selectedTab = document.getElementById(extraArgs["advancedTab"]);
     } else {
       var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex");
-      if (preference.value === null)
-        return;
-      advancedPrefs.selectedIndex = preference.value;
+      if (preference.value !== null)
+        advancedPrefs.selectedIndex = preference.value;
     }
 
 #ifdef MOZ_UPDATER
     this.updateAppUpdateItems();
     this.updateAutoItems();
     this.updateModeItems();
 #endif
     this.updateOfflineApps();
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
@@ -118,16 +118,19 @@ PrivateBrowsingService.prototype = {
   _alreadyChangingMode: false,
 
   // Whether we're entering the private browsing mode at application startup
   _autoStart: false,
 
   // Whether the private browsing mode has been started automatically
   _autoStarted: false,
 
+  // List of view source window URIs for restoring later
+  _viewSrcURLs: [],
+
   // XPCOM registration
   classDescription: "PrivateBrowsing Service",
   contractID: "@mozilla.org/privatebrowsing;1",
   classID: Components.ID("{c31f4883-839b-45f6-82ad-a6a9bc5ad599}"),
   _xpcom_categories: [
     { category: "app-startup", service: true }
   ],
 
@@ -172,16 +175,32 @@ PrivateBrowsingService.prototype = {
             this._savedBrowserState = ss.getBrowserState();
           else // no open browser windows, just restore a blank state on exit
             this._savedBrowserState = blankState;
         }
       }
 
       this._closePageInfoWindows();
 
+      // save view-source windows URIs and close them
+      let viewSrcWindowsEnum = Cc["@mozilla.org/appshell/window-mediator;1"].
+                               getService(Ci.nsIWindowMediator).
+                               getEnumerator("navigator:view-source");
+      while (viewSrcWindowsEnum.hasMoreElements()) {
+        let win = viewSrcWindowsEnum.getNext();
+        if (this._inPrivateBrowsing) {
+          let plainURL = win.getBrowser().currentURI.spec;
+          if (plainURL.indexOf("view-source:") == 0) {
+            plainURL = plainURL.substr(12);
+            this._viewSrcURLs.push(plainURL);
+          }
+        }
+        win.close();
+      }
+
       if (!this._quitting && this._saveSession) {
         let browserWindow = this._getBrowserWindow();
 
         // if there are open browser windows, load a dummy session to get a distinct 
         // separation between private and non-private sessions
         if (browserWindow) {
           // set an empty session to transition from/to pb mode, see bug 476463
           ss.setBrowserState(blankState);
@@ -210,16 +229,38 @@ PrivateBrowsingService.prototype = {
                getService(Ci.nsISessionStore);
       // if we have transitioned out of private browsing mode and the session is
       // to be restored, do it now
       if (!this._inPrivateBrowsing) {
         ss.setBrowserState(this._savedBrowserState);
         this._savedBrowserState = null;
 
         this._closePageInfoWindows();
+
+        // re-open all view-source windows
+        let windowWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+                            getService(Ci.nsIWindowWatcher);
+        this._viewSrcURLs.forEach(function(uri) {
+          let args = Cc["@mozilla.org/supports-array;1"].
+                     createInstance(Ci.nsISupportsArray);
+          let str = Cc["@mozilla.org/supports-string;1"].
+                    createInstance(Ci.nsISupportsString);
+          str.data = uri;
+          args.AppendElement(str);
+          args.AppendElement(null); // charset
+          args.AppendElement(null); // page descriptor
+          args.AppendElement(null); // line number
+          let forcedCharset = Cc["@mozilla.org/supports-PRBool;1"].
+                              createInstance(Ci.nsISupportsPRBool);
+          forcedCharset.data = false;
+          args.AppendElement(forcedCharset);
+          windowWatcher.openWindow(null, "chrome://global/content/viewSource.xul",
+            "_blank", "all,dialog=no", args);
+        });
+        this._viewSrcURLs = [];
       }
       else {
         // otherwise, if we have transitioned into private browsing mode, load
         // about:privatebrowsing
         let privateBrowsingState = {
           "windows": [{
             "tabs": [{
               "entries": [{
--- a/browser/components/privatebrowsing/test/browser/Makefile.in
+++ b/browser/components/privatebrowsing/test/browser/Makefile.in
@@ -40,28 +40,36 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = browser/components/privatebrowsing/test/browser
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_TEST_FILES =  \
-		browser_privatebrowsing_ui.js \
 		browser_console_clear.js \
-		browser_privatebrowsing_theming.js \
-		browser_privatebrowsing_searchbar.js \
+		browser_privatebrowsing_certexceptionsui.js \
+		browser_privatebrowsing_crh.js \
+		browser_privatebrowsing_downloadmonitor.js \
 		browser_privatebrowsing_findbar.js \
-		browser_privatebrowsing_zoom.js \
+		browser_privatebrowsing_forgetthissite.js \
+		browser_privatebrowsing_geoprompt.js \
+		browser_privatebrowsing_geoprompt_page.html \
+		browser_privatebrowsing_import.js \
+		browser_privatebrowsing_opendir.js \
+		browser_privatebrowsing_pageinfo.js \
+		browser_privatebrowsing_popupmode.js \
+		browser_privatebrowsing_searchbar.js \
+		browser_privatebrowsing_sslsite_transition.js \
+		browser_privatebrowsing_theming.js \
 		browser_privatebrowsing_transition.js \
-		browser_privatebrowsing_import.js \
-		browser_privatebrowsing_crh.js \
+		browser_privatebrowsing_ui.js \
+		browser_privatebrowsing_urlbarfocus.js \
+		browser_privatebrowsing_viewsource.js \
 		browser_privatebrowsing_windowtitle.js \
 		browser_privatebrowsing_windowtitle_page.html \
-		browser_privatebrowsing_urlbarfocus.js \
-		browser_privatebrowsing_forgetthissite.js \
-		browser_privatebrowsing_pageinfo.js \
-		browser_privatebrowsing_sslsite_transition.js \
-		browser_privatebrowsing_popupmode.js \
+		browser_privatebrowsing_zoom.js \
+		browser_privatebrowsing_zoomrestore.js \
+		staller.sjs \
 		$(NULL)
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
@@ -0,0 +1,137 @@
+/* ***** 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 Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that certificate exceptions UI behaves correctly
+// inside the private browsing mode, based on whether it's opened from the prefs
+// window or from the SSL error page (see bug 461627).
+
+function test() {
+  // initialization
+  let pb = Cc["@mozilla.org/privatebrowsing;1"].
+           getService(Ci.nsIPrivateBrowsingService);
+  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+           getService(Ci.nsIWindowWatcher);
+
+  const EXCEPTIONS_DLG_URL = 'chrome://pippki/content/exceptionDialog.xul';
+  const EXCEPTIONS_DLG_FEATURES = 'chrome,centerscreen,modal';
+  const INVALID_CERT_LOCATION = 'https://nocert.example.com/';
+  waitForExplicitFinish();
+
+  // enter private browsing mode
+  pb.privateBrowsingEnabled = true;
+
+  let testCheckbox;
+  let obs = {
+      observe: function(aSubject, aTopic, aData) {
+          // unregister ourself
+          ww.unregisterNotification(this);
+
+          let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
+          win.addEventListener("load", function() {
+              win.removeEventListener("load", arguments.callee, false);
+              testCheckbox(win.document.defaultView);
+          }, false);
+      }
+  };
+
+  step1();
+
+  // Test the certificate exceptions dialog as it is invoked from about:certerror
+  function step1() {
+    ww.registerNotification(obs);
+    let params = {
+      exceptionAdded : false,
+      location: INVALID_CERT_LOCATION,
+      handlePrivateBrowsing : true,
+      prefetchCert: true,
+    };
+    testCheckbox = function(win) {
+      let obsSvc = Cc["@mozilla.org/observer-service;1"].
+                   getService(Ci.nsIObserverService);
+      obsSvc.addObserver({
+        observe: function(aSubject, aTopic, aData) {
+          obsSvc.removeObserver(this, "cert-exception-ui-ready", false);
+          ok(win.gCert, "The certificate information should be available now");
+
+          let checkbox = win.document.getElementById("permanent");
+          ok(checkbox.hasAttribute("disabled"),
+            "the permanent checkbox should be disabled when handling the private browsing mode");
+          ok(!checkbox.hasAttribute("checked"),
+            "the permanent checkbox should not be checked when handling the private browsing mode");
+          win.close();
+          step2();
+        }
+      }, "cert-exception-ui-ready", false);
+    };
+    window.openDialog(EXCEPTIONS_DLG_URL, '', EXCEPTIONS_DLG_FEATURES, params);
+  }
+
+  // Test the certificate excetions dialog as it is invoked from the Preferences dialog
+  function step2() {
+    ww.registerNotification(obs);
+    let params = {
+      exceptionAdded : false,
+      location: INVALID_CERT_LOCATION,
+      prefetchCert: true,
+    };
+    testCheckbox = function(win) {
+      let obsSvc = Cc["@mozilla.org/observer-service;1"].
+                   getService(Ci.nsIObserverService);
+      obsSvc.addObserver({
+        observe: function(aSubject, aTopic, aData) {
+          obsSvc.removeObserver(this, "cert-exception-ui-ready", false);
+          ok(win.gCert, "The certificate information should be available now");
+
+          let checkbox = win.document.getElementById("permanent");
+          ok(!checkbox.hasAttribute("disabled"),
+            "the permanent checkbox should not be disabled when not handling the private browsing mode");
+          ok(checkbox.hasAttribute("checked"),
+            "the permanent checkbox should be checked when not handling the private browsing mode");
+          win.close();
+          cleanup();
+        }
+      }, "cert-exception-ui-ready", false);
+    };
+    window.openDialog(EXCEPTIONS_DLG_URL, '', EXCEPTIONS_DLG_FEATURES, params);
+  }
+
+  function cleanup() {
+    // leave the private browsing mode
+    pb.privateBrowsingEnabled = false;
+    finish();
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadmonitor.js
@@ -0,0 +1,168 @@
+/* ***** 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 Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that the download monitor status bar panel is correctly
+// cleared when switching the private browsing mode on or off.
+
+function test() {
+  // initialization
+  let pb = Cc["@mozilla.org/privatebrowsing;1"].
+           getService(Ci.nsIPrivateBrowsingService);
+  let dm = Cc["@mozilla.org/download-manager;1"].
+           getService(Ci.nsIDownloadManager);
+  if (!gDownloadMgr)
+    gDownloadMgr = dm;
+  let iosvc = Cc["@mozilla.org/network/io-service;1"].
+              getService(Ci.nsIIOService);
+  let panel = document.getElementById("download-monitor");
+  waitForExplicitFinish();
+
+  // Add a new download
+  addDownload(dm, {
+    resultFileName: "pbtest-1",
+    downloadName: "PB Test 1"
+  });
+
+  // Make sure that the download is being displayed in the monitor panel
+  if (!DownloadMonitorPanel.inited())
+    DownloadMonitorPanel.init();
+  else
+    DownloadMonitorPanel.updateStatus();
+  ok(!panel.hidden, "The download panel should be successfully added initially");
+
+  // Enter the private browsing mode
+  pb.privateBrowsingEnabled = true;
+
+  setTimeout(function () {
+    ok(panel.hidden, "The download panel should be hidden when entering the private browsing mode");
+
+    // Add a new download
+    let file = addDownload(dm, {
+      resultFileName: "pbtest-2",
+      downloadName: "PB Test 2"
+    }).targetFile;
+
+    // Update the panel
+    DownloadMonitorPanel.updateStatus();
+
+    // Make sure that the panel is visible
+    ok(!panel.hidden, "The download panel should show up when a new download is added");
+
+    // Exit the private browsing mode
+    pb.privateBrowsingEnabled = false;
+
+    setTimeout(function () {
+      ok(panel.hidden, "The download panel should be hidden when leaving the private browsing mode");
+
+      // cleanup
+      let dls = dm.activeDownloads;
+      while (dls.hasMoreElements()) {
+        let dl = dls.getNext().QueryInterface(Ci.nsIDownload);
+        dm.removeDownload(dl.id);
+        let file = dl.targetFile;
+        if (file.exists())
+          file.remove(false);
+      }
+      if (file.exists())
+        file.remove(false);
+
+      finish();
+    }, 0);
+  }, 0);
+}
+
+/**
+ * Adds a download to the DM, and starts it.
+ * (Copied from toolkit/componentns/downloads/test/unit/head_download_manager.js)
+ * @param aParams (optional): an optional object which contains the function
+ *                            parameters:
+ *                              resultFileName: leaf node for the target file
+ *                              targetFile: nsIFile for the target (overrides resultFileName)
+ *                              sourceURI: the download source URI
+ *                              downloadName: the display name of the download
+ *                              runBeforeStart: a function to run before starting the download
+ */
+function addDownload(dm, aParams)
+{
+  if (!aParams)
+    aParams = {};
+  if (!("resultFileName" in aParams))
+    aParams.resultFileName = "download.result";
+  if (!("targetFile" in aParams)) {
+    let dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+                 getService(Ci.nsIProperties);
+    aParams.targetFile = dirSvc.get("ProfD", Ci.nsIFile);
+    aParams.targetFile.append(aParams.resultFileName);
+  }
+  if (!("sourceURI" in aParams))
+    aParams.sourceURI = "http://localhost:8888/browser/browser/components/privatebrowsing/test/browser/staller.sjs";
+  if (!("downloadName" in aParams))
+    aParams.downloadName = null;
+  if (!("runBeforeStart" in aParams))
+    aParams.runBeforeStart = function () {};
+
+  const nsIWBP = Ci.nsIWebBrowserPersist;
+  let persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
+                .createInstance(Ci.nsIWebBrowserPersist);
+  persist.persistFlags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
+                         nsIWBP.PERSIST_FLAGS_BYPASS_CACHE |
+                         nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
+
+  let dl = dm.addDownload(Ci.nsIDownloadManager.DOWNLOAD_TYPE_DOWNLOAD,
+                          createURI(aParams.sourceURI),
+                          createURI(aParams.targetFile), aParams.downloadName, null,
+                          Math.round(Date.now() * 1000), null, persist);
+
+  // This will throw if it isn't found, and that would mean test failure, so no
+  // try catch block
+  let test = dm.getDownload(dl.id);
+
+  aParams.runBeforeStart.call(undefined, dl);
+
+  persist.progressListener = dl.QueryInterface(Ci.nsIWebProgressListener);
+  persist.saveURI(dl.source, null, null, null, null, dl.targetFile);
+
+  return dl;
+}
+
+function createURI(aObj)
+{
+  let ios = Cc["@mozilla.org/network/io-service;1"].
+            getService(Ci.nsIIOService);
+  return (aObj instanceof Ci.nsIFile) ? ios.newFileURI(aObj) :
+                                        ios.newURI(aObj, null, null);
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
@@ -0,0 +1,96 @@
+/* ***** 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 Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that the geolocation prompt does not show a remember
+// control inside the private browsing mode.
+
+function test() {
+  // initialization
+  let pb = Cc["@mozilla.org/privatebrowsing;1"].
+           getService(Ci.nsIPrivateBrowsingService);
+
+  const testPageURL = "http://localhost:8888/browser/" +
+    "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html";
+  waitForExplicitFinish();
+
+  let pageTab = gBrowser.addTab();
+  gBrowser.selectedTab = pageTab;
+  let pageBrowser = gBrowser.getBrowserForTab(pageTab);
+  pageBrowser.addEventListener("load", function () {
+    pageBrowser.removeEventListener("load", arguments.callee, true);
+
+    setTimeout(function() {
+      // Make sure the notification is correctly displayed with a remember control
+      let notificationBox = gBrowser.getNotificationBox(pageBrowser);
+      let notification = notificationBox.getNotificationWithValue("geolocation");
+      ok(notification, "Notification box should be displaying outside of private browsing mode");
+      is(notification.getElementsByClassName("rememberChoice").length, 1,
+         "The remember control must be displayed outside of private browsing mode");
+      notificationBox.currentNotification.close();
+
+      gBrowser.removeTab(pageTab);
+
+      // enter the private browsing mode
+      pb.privateBrowsingEnabled = true;
+
+      pageTab = gBrowser.addTab();
+      gBrowser.selectedTab = pageTab;
+      pageBrowser = gBrowser.getBrowserForTab(pageTab);
+      pageBrowser.addEventListener("load", function () {
+        pageBrowser.removeEventListener("load", arguments.callee, true);
+
+        setTimeout(function() {
+          // Make sure the notification is correctly displayed without a remember control
+          let notificationBox = gBrowser.getNotificationBox(pageBrowser);
+          let notification = notificationBox.getNotificationWithValue("geolocation");
+          ok(notification, "Notification box should be displaying outside of private browsing mode");
+          is(notification.getElementsByClassName("rememberChoice").length, 0,
+             "The remember control must not be displayed inside of private browsing mode");
+          notificationBox.currentNotification.close();
+
+          gBrowser.removeTab(pageTab);
+
+          // cleanup
+          pb.privateBrowsingEnabled = false;
+          finish();
+        }, 100); // remember control is added in a setTimeout(0) call
+      }, true);
+      pageBrowser.contentWindow.location = testPageURL;
+    }, 100); // remember control is added in a setTimeout(0) call
+  }, true);
+  pageBrowser.contentWindow.location = testPageURL;
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+  <head>
+    <title>Geolocation invoker</title>
+  </head>
+  <body>
+    <script type="text/javascript">
+      navigator.geolocation.getCurrentPosition(function (pos) {
+        // ignore
+      });
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_opendir.js
@@ -0,0 +1,142 @@
+/* ***** 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 Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that the last open directory used inside the private
+// browsing mode is not remembered after leaving that mode.
+
+function test() {
+  // initialization
+  let pb = Cc["@mozilla.org/privatebrowsing;1"].
+           getService(Ci.nsIPrivateBrowsingService);
+  let ds = Cc["@mozilla.org/file/directory_service;1"].
+           getService(Ci.nsIProperties);
+  let dir1 = ds.get("ProfD", Ci.nsIFile);
+  let dir2 = ds.get("TmpD", Ci.nsIFile);
+  let file = dir2.clone();
+  file.append("pbtest.file");
+  file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
+
+  const kPrefName = "browser.open.lastDir";
+
+  function setupCleanSlate() {
+    gLastOpenDirectory.reset();
+    gPrefService.clearUserPref(kPrefName);
+  }
+
+  setupCleanSlate();
+
+  // Test 1: general workflow test
+
+  // initial checks
+  ok(!gLastOpenDirectory.path,
+     "Last open directory path should be initially empty");
+  gLastOpenDirectory.path = dir2;
+  is(gLastOpenDirectory.path.path, dir2.path,
+     "The path should be successfully set");
+  gLastOpenDirectory.path = null;
+  is(gLastOpenDirectory.path.path, dir2.path,
+     "The path should be not change when assigning it to null");
+  gLastOpenDirectory.path = dir1;
+  is(gLastOpenDirectory.path.path, dir1.path,
+     "The path should be successfully outside of the private browsing mode");
+
+  // enter private browsing mode
+  pb.privateBrowsingEnabled = true;
+
+  is(gLastOpenDirectory.path.path, dir1.path,
+     "The path should not change when entering the private browsing mode");
+  gLastOpenDirectory.path = dir2;
+  is(gLastOpenDirectory.path.path, dir2.path,
+     "The path should successfully change inside the private browsing mode");
+
+  // leave private browsing mode
+  pb.privateBrowsingEnabled = false;
+
+  is(gLastOpenDirectory.path.path, dir1.path,
+     "The path should be reset to the same path as before entering the private browsing mode");
+
+  setupCleanSlate();
+
+  // Test 2: the user first tries to open a file inside the private browsing mode
+
+  pb.privateBrowsingEnabled = true;
+  ok(!gLastOpenDirectory.path,
+     "No original path should exist inside the private browsing mode");
+  gLastOpenDirectory.path = dir1;
+  is(gLastOpenDirectory.path.path, dir1.path, 
+     "The path should be successfully set inside the private browsing mode");
+  pb.privateBrowsingEnabled = false;
+  ok(!gLastOpenDirectory.path,
+     "The path set inside the private browsing mode should not leak when leaving that mode");
+
+  setupCleanSlate();
+
+  // Test 3: the last open directory is set from a previous session, it should be used
+  // in normal mode
+
+  gPrefService.setComplexValue(kPrefName, Ci.nsILocalFile, dir1);
+  is(gLastOpenDirectory.path.path, dir1.path,
+     "The pref set from last session should take effect outside the private browsing mode");
+
+  setupCleanSlate();
+
+  // Test 4: the last open directory is set from a previous session, it should be used
+  // in private browsing mode mode
+
+  gPrefService.setComplexValue(kPrefName, Ci.nsILocalFile, dir1);
+  pb.privateBrowsingEnabled = true;
+  is(gLastOpenDirectory.path.path, dir1.path,
+     "The pref set from last session should take effect inside the private browsing mode");
+  pb.privateBrowsingEnabled = false;
+  is(gLastOpenDirectory.path.path, dir1.path,
+     "The pref set from last session should remain in effect after leaving the private browsing mode");
+
+  setupCleanSlate();
+
+  // Test 5: setting the path to a file shouldn't work
+
+  gLastOpenDirectory.path = file;
+  ok(!gLastOpenDirectory.path,
+     "Setting the path to a file shouldn't work when it's originally null");
+  gLastOpenDirectory.path = dir1;
+  gLastOpenDirectory.path = file;
+  is(gLastOpenDirectory.path.path, dir1.path,
+     "Setting the path to a file shouldn't work when it's not originally null");
+
+  // cleanup
+  file.remove(false);
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_viewsource.js
@@ -0,0 +1,197 @@
+/* ***** 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 Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that entering the private browsing mode closes
+// all view source windows, and leaving it restores them
+
+function test() {
+  // initialization
+  let pb = Cc["@mozilla.org/privatebrowsing;1"].
+           getService(Ci.nsIPrivateBrowsingService);
+
+  waitForExplicitFinish();
+
+  let tabAbout = gBrowser.addTab();
+  gBrowser.selectedTab = tabAbout;
+  let aboutBrowser = gBrowser.getBrowserForTab(tabAbout);
+  aboutBrowser.addEventListener("load", function () {
+    aboutBrowser.removeEventListener("load", arguments.callee, true);
+
+    let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+             getService(Ci.nsIWindowWatcher);
+    let observer = {
+      observe: function(aSubject, aTopic, aData) {
+        if (aTopic == "domwindowopened") {
+          ww.unregisterNotification(this);
+
+          let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
+          win.addEventListener("load", function() {
+            win.removeEventListener("load", arguments.callee, false);
+
+            let browser = win.document.defaultView.getBrowser();
+            browser.addEventListener("load", function() {
+              browser.removeEventListener("load", arguments.callee, true);
+              
+              // view source window is loaded, proceed with the rest of the test
+              step1();
+            }, true);
+          }, false);
+        }
+      }
+    };
+    ww.registerNotification(observer);
+
+    openViewSource();
+
+    function openViewSource() {
+      // invoke the View Source command
+      let event = document.createEvent("Events");
+      event.initEvent("command", true, true);
+      document.getElementById("View:PageSource").dispatchEvent(event);
+    }
+
+    function step1() {
+      observer = {
+        observe: function(aSubject, aTopic, aData) {
+          if (aTopic == "domwindowclosed") {
+            ok(true, "Entering the private browsing mode should close the view source window");
+            ww.unregisterNotification(observer);
+
+            step2();
+          }
+          else if (aTopic == "domwindowopened")
+            ok(false, "Entering the private browsing mode should not open any view source window");
+        }
+      };
+      ww.registerNotification(observer);
+
+      gBrowser.addTabsProgressListener({
+        onLocationChange: function() {},
+        onProgressChange: function() {},
+        onSecurityChange: function() {},
+        onStatusChange: function() {},
+        onRefreshAttempted: function() {},
+        onLinkIconAvailable: function() {},
+        onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
+          if (aStateFlags & (Ci.nsIWebProgressListener.STATE_STOP |
+                             Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
+            gBrowser.removeTabsProgressListener(this);
+
+            step3();
+          }
+        }
+      });
+
+      // enter private browsing mode
+      pb.privateBrowsingEnabled = true;
+    }
+
+    let events = 0, step2, step3;
+    step2 = step3 = function() {
+      if (++events == 2)
+        step4();
+    }
+
+    function step4() {
+      observer = {
+        observe: function(aSubject, aTopic, aData) {
+          if (aTopic == "domwindowopened") {
+            ww.unregisterNotification(this);
+
+            let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
+            win.addEventListener("load", function() {
+              win.removeEventListener("load", arguments.callee, false);
+
+              let browser = win.document.defaultView.getBrowser();
+              browser.addEventListener("load", function() {
+                browser.removeEventListener("load", arguments.callee, true);
+                
+                // view source window inside private browsing mode opened
+                step5();
+              }, true);
+            }, false);
+          }
+        }
+      };
+      ww.registerNotification(observer);
+
+      openViewSource();
+    }
+
+    function step5() {
+      let events = 0;
+
+      observer = {
+        observe: function(aSubject, aTopic, aData) {
+          if (aTopic == "domwindowclosed") {
+            ok(true, "Leaving the private browsing mode should close the existing view source window");
+            if (++events == 2)
+              ww.unregisterNotification(observer);
+          }
+          else if (aTopic == "domwindowopened") {
+            ok(true, "Leaving the private browsing mode should restore the previous view source window");
+            if (++events == 2)
+              ww.unregisterNotification(observer);
+
+            let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
+            win.addEventListener("load", function() {
+              win.removeEventListener("load", arguments.callee, false);
+
+              let browser = win.document.defaultView.getBrowser();
+              browser.addEventListener("load", function() {
+                browser.removeEventListener("load", arguments.callee, true);
+                
+                is(browser.currentURI.spec, "view-source:about:",
+                  "The correct view source window should be restored");
+
+                // cleanup
+                win.close();
+                gBrowser.removeTab(gBrowser.selectedTab);
+                finish();
+              }, true);
+            }, false);
+          }
+        }
+      };
+      ww.registerNotification(observer);
+
+      // exit private browsing mode
+      pb.privateBrowsingEnabled = false;
+    }
+  }, true);
+  aboutBrowser.loadURI("about:");
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoomrestore.js
@@ -0,0 +1,137 @@
+/* ***** 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 Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that about:privatebrowsing does not appear zoomed in
+// if there is already a zoom site pref for about:blank (bug 487656).
+
+function test() {
+  // initialization
+  let pb = Cc["@mozilla.org/privatebrowsing;1"].
+           getService(Ci.nsIPrivateBrowsingService);
+  let cps = Cc["@mozilla.org/content-pref/service;1"].
+            getService(Ci.nsIContentPrefService);
+  waitForExplicitFinish();
+
+  let tabBlank = gBrowser.selectedTab;
+  gBrowser.removeAllTabsBut(tabBlank);
+
+  let blankBrowser = gBrowser.getBrowserForTab(tabBlank);
+  blankBrowser.addEventListener("load", function() {
+    blankBrowser.removeEventListener("load", arguments.callee, true);
+
+    // change the zoom on the blank page
+    FullZoom.enlarge();
+    isnot(ZoomManager.zoom, 1, "Zoom level for about:blank should be changed");
+
+    // enter private browsing mode
+    pb.privateBrowsingEnabled = true;
+    let tabAboutPB = gBrowser.selectedTab;
+    let browserAboutPB = gBrowser.getBrowserForTab(tabAboutPB);
+    browserAboutPB.addEventListener("load", function() {
+      browserAboutPB.removeEventListener("load", arguments.callee, true);
+      setTimeout(function() {
+        // make sure the zoom level is set to 1
+        is(ZoomManager.zoom, 1, "Zoom level for about:privatebrowsing should be reset");
+
+        // Mac OS X does not support print preview, so skip those tests
+        let isOSX = ("nsILocalFileMac" in Components.interfaces);
+        if (isOSX) {
+          finishTest();
+          return;
+        }
+
+        // test print preview on HTML document
+        testPrintPreview(browserAboutPB, function() {
+          browserAboutPB.addEventListener("load", function() {
+            browserAboutPB.removeEventListener("load", arguments.callee, true);
+
+            // test print preview on image document
+            testPrintPreview(browserAboutPB, finishTest);
+          }, true);
+          browserAboutPB.loadURI("about:logo");
+        });
+      }, 0);
+    }, true);
+  }, true);
+  blankBrowser.loadURI("about:blank");
+}
+
+function finishTest() {
+  let pb = Cc["@mozilla.org/privatebrowsing;1"].
+           getService(Ci.nsIPrivateBrowsingService);
+  // leave private browsing mode
+  pb.privateBrowsingEnabled = false;
+  let tabBlank = gBrowser.selectedTab;
+  let blankBrowser = gBrowser.getBrowserForTab(tabBlank);
+  blankBrowser.addEventListener("load", function() {
+    blankBrowser.removeEventListener("load", arguments.callee, true);
+
+    executeSoon(function() {
+      // cleanup
+      FullZoom.reset();
+      finish();
+    });
+  }, true);
+}
+
+function testPrintPreview(aBrowser, aCallback) {
+  FullZoom.enlarge();
+  let level = ZoomManager.getZoomForBrowser(aBrowser);
+
+  function onEnterPP(aHide) {
+    toggleAffectedChromeOrig(aHide);
+
+    function onExitPP(aHide) {
+      toggleAffectedChromeOrig(aHide);
+      toggleAffectedChrome = toggleAffectedChromeOrig;
+
+      is(ZoomManager.getZoomForBrowser(aBrowser), level,
+         "Toggling print preview mode should not affect zoom level");
+
+      FullZoom.reset();
+      aCallback();
+    }
+    toggleAffectedChrome = onExitPP;
+    PrintUtils.exitPrintPreview();
+  }
+  let toggleAffectedChromeOrig = toggleAffectedChrome;
+  toggleAffectedChrome = onEnterPP;
+
+  let printPreview = new Function(document.getElementById("cmd_printPreview")
+                                          .getAttribute("oncommand"));
+  executeSoon(printPreview);
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/staller.sjs
@@ -0,0 +1,55 @@
+/* ***** 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 Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This provides the tests with a download URL which never finishes.
+
+function handleRequest(request, response) {
+  response.setStatusLine(request.httpVersion, 200, "OK");
+  response.processAsync();
+
+  function stall() {
+    response.write("stalling...\n");
+  }
+
+  response.setHeader("Content-Type", "text/plain", false);
+  stall();
+
+  const nsITimer = Components.interfaces.nsITimer;
+  var timer = Components.classes["@mozilla.org/timer;1"]
+                        .createInstance(nsITimer);
+  timer.initWithCallback(stall, 500, nsITimer.TYPE_REPEATING_SLACK);
+}
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -40,18 +40,16 @@
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 <!DOCTYPE bindings [
 <!ENTITY % searchBarDTD SYSTEM "chrome://browser/locale/searchbar.dtd" >
 %searchBarDTD;
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
-%globalDTD;
 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
 %browserDTD;
 ]>
 
 <bindings id="SearchBindings"
       xmlns="http://www.mozilla.org/xbl"
       xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
       xmlns:xbl="http://www.mozilla.org/xbl">
@@ -75,33 +73,31 @@
                    timeout="250"
                    maxrows="10"
                    completeselectedindex="true"
                    showcommentcolumn="true"
                    tabscrolling="true"
                    xbl:inherits="disabled,disableautocomplete,searchengine,src,newlines">
         <xul:button class="searchbar-engine-button"
                     type="menu"
-                    anonid="searchbar-engine-button"
-                    chromedir="&locale.dir;">
+                    anonid="searchbar-engine-button">
           <xul:image class="searchbar-engine-image" xbl:inherits="src"/>
           <xul:image class="searchbar-dropmarker-image"/>
           <xul:menupopup class="searchbar-popup"
                          anonid="searchbar-popup">
             <xul:menuseparator/>
             <xul:menuitem class="open-engine-manager"
                           anonid="open-engine-manager"
                           label="&cmd_engineManager.label;"
                           oncommand="openManager(event);"/>
           </xul:menupopup>
         </xul:button>
-        <xul:hbox class="search-go-container" chromedir="&locale.dir;">
+        <xul:hbox class="search-go-container">
           <xul:image class="search-go-button"
                      anonid="search-go-button"
-                     chromedir="&locale.dir;"
                      onclick="handleSearchCommand(event);"
                      tooltiptext="&searchEndCap.label;" />
         </xul:hbox>
       </xul:textbox>
     </content>
 
     <implementation implements="nsIObserver">
 
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -18,16 +18,17 @@
  * Portions created by the Initial Developer are Copyright (C) 2006
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Dietrich Ayala <dietrich@mozilla.com>
  *   Ehsan Akhgari <ehsan.akhgari@gmail.com>
  *   Michael Kraft <morac99-firefox@yahoo.com>
  *   Paul O’Shannessy <paul@oshannessy.com>
+ *   Nils Maier <maierman@web.de>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -69,16 +70,17 @@ const PRIVACY_ENCRYPTED = 1;
 const PRIVACY_FULL = 2;
 
 const NOTIFY_WINDOWS_RESTORED = "sessionstore-windows-restored";
 
 // global notifications observed
 const OBSERVING = [
   "domwindowopened", "domwindowclosed",
   "quit-application-requested", "quit-application-granted",
+  "browser-lastwindow-close-granted",
   "quit-application", "browser:purge-session-history",
   "private-browsing", "browser:purge-domain-data",
   "private-browsing-change-granted"
 ];
 
 /*
 XUL Window properties to (re)store
 Restored in restoreDimensions()
@@ -164,16 +166,21 @@ SessionStoreService.prototype = {
   _recentCrashes: 0,
 
   // whether we are in private browsing mode
   _inPrivateBrowsing: false,
 
   // whether we clearing history on shutdown
   _clearingOnShutdown: false,
 
+#ifndef XP_MACOSX
+  // whether the last window was closed and should be restored
+  _restoreLastWindow: false,
+#endif
+
 /* ........ Global Event Handlers .............. */
 
   /**
    * Initialize the component
    */
   init: function sss_init(aWindow) {
     if (!aWindow || this._loadState == STATE_RUNNING) {
       // make sure that all browser windows which try to initialize
@@ -324,16 +331,25 @@ SessionStoreService.prototype = {
         this._collectWindowData(aWindow);
       });
       this._dirtyWindows = [];
       break;
     case "quit-application-granted":
       // freeze the data at what we've got (ignoring closing windows)
       this._loadState = STATE_QUITTING;
       break;
+#ifndef XP_MACOSX
+    case "browser-lastwindow-close-granted":
+      // last browser window is quitting.
+      // remember to restore the last window when another browser window is openend
+      // do not account for pref(resume_session_once) at this point, as it might be
+      // set by another observer getting this notice after us
+      this._restoreLastWindow = true;
+      break;
+#endif
     case "quit-application":
       if (aData == "restart") {
         this._prefBranch.setBoolPref("sessionstore.resume_session_once", true);
         this._clearingOnShutdown = false;
       }
       this._loadState = STATE_QUITTING; // just to be sure
       this._uninit();
       break;
@@ -563,17 +579,18 @@ SessionStoreService.prototype = {
       // restore a crashed session resp. resume the last session if requested
       if (this._initialState) {
         // make sure that the restored tabs are first in the window
         this._initialState._firstTabs = true;
         this._restoreCount = this._initialState.windows ? this._initialState.windows.length : 0;
         this.restoreWindow(aWindow, this._initialState, this._isCmdLineEmpty(aWindow));
         delete this._initialState;
         
-        // mark ourselves as running
+        // _loadState changed from "stopped" to "running"
+        // force a save operation so that crashes happening during startup are correctly counted
         this.saveState(true);
       }
       else {
         // Nothing to restore, notify observers things are complete.
         var observerService = Cc["@mozilla.org/observer-service;1"].
                               getService(Ci.nsIObserverService);
         observerService.notifyObservers(null, NOTIFY_WINDOWS_RESTORED, "");
         
@@ -581,17 +598,48 @@ SessionStoreService.prototype = {
         this._lastSaveTime -= this._interval;
       }
     }
     // this window was opened by _openWindowWithState
     else if (!this._isWindowLoaded(aWindow)) {
       let followUp = this._statesToRestore[aWindow.__SS_restoreID].windows.length == 1;
       this.restoreWindow(aWindow, this._statesToRestore[aWindow.__SS_restoreID], true, followUp);
     }
-    
+#ifndef XP_MACOSX
+    else if (this._restoreLastWindow && aWindow.toolbar.visible &&
+             this._closedWindows.length && this._doResumeSession() &&
+             !this._inPrivateBrowsing) {
+
+      // default to the most-recently closed window
+      // don't use popup windows
+      let state = null;
+      this._closedWindows = this._closedWindows.filter(function(aWinState) {
+        if (!state && !aWinState.isPopup) {
+          state = aWinState;
+          return false;
+        }
+        return true;
+      });
+      if (state) {
+        delete state.hidden;
+        state = { windows: [state] };
+        this._restoreCount = 1;
+        this.restoreWindow(aWindow, state, this._isCmdLineEmpty(aWindow));
+      }
+      // we actually restored the session just now.
+      this._prefBranch.setBoolPref("sessionstore.resume_session_once", false);
+    }
+    if (this._restoreLastWindow && aWindow.toolbar.visible) {
+      // always reset (if not a popup window)
+      // we don't want to restore a window directly after, for example,
+      // undoCloseWindow was executed.
+      this._restoreLastWindow = false;
+    }
+#endif
+
     var tabbrowser = aWindow.getBrowser();
     var tabpanels = tabbrowser.mPanelContainer;
     
     // add tab change listeners to all already existing tabs
     for (var i = 0; i < tabpanels.childNodes.length; i++) {
       this.onTabAdd(aWindow, tabpanels.childNodes[i], true);
     }
     // notification of tab add/remove/selection
@@ -1541,19 +1589,16 @@ SessionStoreService.prototype = {
   _updateCookies: function sss_updateCookies(aWindows) {
     function addCookieToHash(aHash, aHost, aPath, aName, aCookie) {
       // lazily build up a 3-dimensional hash, with
       // aHost, aPath, and aName as keys
       if (!aHash[aHost])
         aHash[aHost] = {};
       if (!aHash[aHost][aPath])
         aHash[aHost][aPath] = {};
-      if (!aHash[aHost][aPath][aName])
-        aHash[aHost][aPath][aName] = {};
-
       aHash[aHost][aPath][aName] = aCookie;
     }
 
     var cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
     // collect the cookies per window
     for (var i = 0; i < aWindows.length; i++)
       aWindows[i].cookies = [];
 
@@ -1564,24 +1609,19 @@ SessionStoreService.prototype = {
     aWindows.forEach(function(aWindow) {
       for (var host in aWindow._hosts) {
         var list = cm.getCookiesFromHost(host);
         while (list.hasMoreElements()) {
           var cookie = list.getNext().QueryInterface(Ci.nsICookie2);
           if (cookie.isSession && _this._checkPrivacyLevel(cookie.isSecure)) {
             // use the cookie's host, path, and name as keys into a hash,
             // to make sure we serialize each cookie only once
-            var isInHash = false;
-            try {
-              if (jscookies[cookie.host][cookie.path][cookie.name])
-                isInHash = true;
-            } catch (e) {
-              // not in hash yet
-            }
-            if (!isInHash) {
+            if (!(cookie.host in jscookies &&
+                  cookie.path in jscookies[cookie.host] &&
+                  cookie.name in jscookies[cookie.host][cookie.path])) {
               var jscookie = { "host": cookie.host, "value": cookie.value };
               // only add attributes with non-default values (saving a few bits)
               if (cookie.path) jscookie.path = cookie.path;
               if (cookie.name) jscookie.name = cookie.name;
               if (cookie.isSecure) jscookie.secure = true;
               if (cookie.isHttpOnly) jscookie.httponly = true;
               if (cookie.expiry < MAX_EXPIRY) jscookie.expiry = cookie.expiry;
 
--- a/browser/components/sessionstore/test/browser/Makefile.in
+++ b/browser/components/sessionstore/test/browser/Makefile.in
@@ -53,16 +53,17 @@ include $(topsrcdir)/config/rules.mk
 	browser_248970_b.js \
 	browser_248970_b_sample.html \
 	browser_339445.js \
 	browser_339445_sample.html \
 	browser_345898.js \
 	browser_346337.js \
 	browser_346337_sample.html \
 	browser_350525.js \
+	browser_354894.js \
 	browser_367052.js \
 	browser_393716.js \
 	browser_394759.js \
 	browser_394759_privatebrowsing.js \
 	browser_408470.js \
 	browser_408470_sample.html \
 	browser_423132.js \
 	browser_423132_sample.html \
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser/browser_354894.js
@@ -0,0 +1,516 @@
+/* ***** 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 sessionstore test code.
+ *
+ * The Initial Developer of the Original Code is
+ * Nils Maier <maierman@web.de>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Simon Bünzli <zeniko@gmail.com>
+ * Paul O’Shannessy <paul@oshannessy.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 ***** */
+
+/**
+ * Checks that restoring the last browser window in session is actually
+ * working:
+ *  1.1) Open a new browser window
+ *  1.2) Add some tabs
+ *  1.3) Close that window
+ *  1.4) Opening another window
+ *  --> State is restored
+ *
+ *  2.1) Open a new browser window
+ *  2.2) Add some tabs
+ *  2.3) Enter private browsing mode
+ *  2.4) Close the window while still in private browsing mode
+ *  2.5) Opening a new window
+ *  --> State is not restored, because private browsing mode is still active
+ *  2.6) Leaving private browsing mode
+ *  2.7) Open another window
+ *  --> State (that was before entering PBM) is restored
+ *
+ *  3.1) Open a new browser window
+ *  3.2) Add some tabs
+ *  3.4) Open some popups
+ *  3.5) Add another tab to one popup (so that it gets stored) and close it again
+ *  3.5) Close the browser window
+ *  3.6) Open another browser window
+ *  --> State of the closed browser window, but not of the popup, is restored
+ *
+ *  4.1) Open a popup
+ *  4.2) Add another tab to the popup (so that it gets stored) and close it again
+ *  4.3) Open a window
+ *  --> Nothing at all should be restored
+ *
+ *  5.1) Open two browser windows and close them again
+ *  5.2) undoCloseWindow() one
+ *  5.3) Open another browser window
+ *  --> Nothing at all should be restored
+ *
+ * Checks the new notifications are correctly posted and processed, that is
+ * for each successful -requested a -granted is received, but omitted if
+ *  -requested was cnceled
+ * Said notifications are:
+ *  - browser-lastwindow-close-requested
+ *  - browser-lastwindow-close-granted
+ * Tests are:
+ *  6) Cancel closing when first observe a -requested
+ *  --> Window is kept open
+ *  7) Count the number of notifications
+ *  --> count(-requested) == count(-granted) + 1
+ *  --> (The first -requested was canceled, so off-by-one)
+ *  8) (Mac only) Mac version of Test 5 additionally preparing Test 6
+ *
+ * @see https://bugzilla.mozilla.org/show_bug.cgi?id=354894
+ * @note It is implicitly tested that restoring the last window works when
+ * non-browser windows are around. The "Run Tests" window as well as the main
+ * browser window (wherein the test code gets executed) won't be considered
+ * browser windows. To achiveve this said main browser window has it's windowtype
+ * attribute modified so that it's not considered a browser window any longer.
+ * This is crucial, because otherwise there would be two browser windows around,
+ * said main test window and the one opened by the tests, and hence the new
+ * logic wouldn't be executed at all.
+ * @note Mac only tests the new notifications, as restoring the last window is
+ * not enabled on that platform (platform shim; the application is kept running
+ * although there are no windows left)
+ * @note There is a difference when closing a browser window with
+ * BrowserTryToCloseWindow() as opposed to close(). The former will make
+ * nsSessionStore restore a window next time it gets a chance and will post
+ * notifications. The latter won't.
+ */
+function test() {
+  waitForExplicitFinish();
+
+  // Some urls that might be opened in tabs and/or popups
+  // Do not use about:blank:
+  // That one is reserved for special purposes in the tests
+  const TEST_URLS = ["about:mozilla", "about:buildconfig"];
+
+  // Number of -request notifications to except
+  // remember to adjust when adding new tests
+  const NOTIFICATIONS_EXPECTED = 6;
+
+  // Window features of popup windows
+  const POPUP_FEATURES = "toolbar=no,resizable=no,status=no";
+
+  // Window features of browser windows
+  const CHROME_FEATURES = "chrome,all,dialog=no";
+
+  // Store the old window type for cleanup
+  let oldWinType = "";
+  // Store the old tabs.warnOnClose pref so that we may reset it during
+  // cleanup
+  let oldWarnTabsOnClose = gPrefService.getBoolPref("browser.tabs.warnOnClose");
+
+  // Observe these, and also use to count the number of hits
+  let observing = {
+    "browser-lastwindow-close-requested": 0,
+    "browser-lastwindow-close-granted": 0
+  };
+
+  /**
+   * Helper: Will observe and handle the notifications for us
+   */
+  let observer = {
+    hitCount: 0,
+
+    observe: function(aCancel, aTopic, aData) {
+      // count so that we later may compare
+      observing[aTopic]++;
+
+      // handle some tests
+      if (++this.hitCount == 1) {
+        // Test 6
+        aCancel.QueryInterface(Ci.nsISupportsPRBool).data = true;
+      }
+    }
+  };
+  let observerService = Cc["@mozilla.org/observer-service;1"].
+                        getService(Ci.nsIObserverService);
+
+  /**
+   * Helper: Sets prefs as the testsuite requires
+   * @note Will be reset in cleanTestSuite just before finishing the tests
+   */
+  function setPrefs() {
+    gPrefService.setIntPref("browser.startup.page", 3);
+    gPrefService.setBoolPref(
+      "browser.privatebrowsing.keep_current_session",
+      true
+    );
+    gPrefService.setBoolPref("browser.tabs.warnOnClose", false);
+  }
+
+  /**
+   * Helper: Sets up this testsuite
+   */
+  function setupTestsuite(testFn) {
+    // Register our observers
+    for (let o in observing) {
+      observerService.addObserver(observer, o, false);
+    }
+
+    // Make the main test window not count as a browser window any longer
+    oldWinType = document.documentElement.getAttribute("windowtype");
+    document.documentElement.setAttribute("windowtype", "navigator:testrunner");
+  }
+
+  /**
+   * Helper: Cleans up behind the testsuite
+   */
+  function cleanupTestsuite(callback) {
+    // Finally remove observers again
+    for (let o in observing) {
+      observerService.removeObserver(observer, o, false);
+    }
+    // Reset the prefs we touched
+    for each (let pref in [
+      "browser.startup.page",
+      "browser.privatebrowsing.keep_current_session"
+    ]) {
+      if (gPrefService.prefHasUserValue(pref)) {
+        gPrefService.clearUserPref(pref);
+      }
+    }
+    gPrefService.setBoolPref("browser.tabs.warnOnClose", oldWarnTabsOnClose);
+
+    // Reset the window type
+    document.documentElement.setAttribute("windowtype", oldWinType);
+  }
+
+  /**
+   * Helper: sets the prefs and a new window with our test tabs
+   */
+  function setupTestAndRun(testFn) {
+    // Prepare the prefs
+    setPrefs();
+
+    // Prepare a window; open it and add more tabs
+    let newWin = openDialog(location, "_blank", CHROME_FEATURES, "about:config");
+    newWin.addEventListener("load", function(aEvent) {
+      newWin.removeEventListener("load", arguments.callee, false);
+      newWin.gBrowser.addEventListener("load", function(aEvent) {
+        newWin.gBrowser.removeEventListener("load", arguments.callee, true);
+        for each (let url in TEST_URLS) {
+          newWin.gBrowser.addTab(url);
+        }
+
+        executeSoon(function() testFn(newWin));
+      }, true);
+    }, false);
+  }
+
+  /**
+   * Test 1: Normal in-session restore
+   * @note: Non-Mac only
+   */
+  function testOpenCloseNormal(nextFn) {
+    setupTestAndRun(function(newWin) {
+      // Close the window
+      // window.close doesn't push any close events,
+      // so use BrowserTryToCloseWindow
+      newWin.BrowserTryToCloseWindow();
+
+      // The first request to close is denied by our observer (Test 6)
+      ok(!newWin.closed, "First close request was denied");
+      if (!newWin.closed) {
+        newWin.BrowserTryToCloseWindow();
+        ok(newWin.closed, "Second close request was granted");
+      }
+
+      // Open a new window
+      // The previously closed window should be restored
+      newWin = openDialog(location, "_blank", CHROME_FEATURES);
+      newWin.addEventListener("load", function() {
+        executeSoon(function() {
+          is(newWin.gBrowser.browsers.length, TEST_URLS.length + 1,
+             "Restored window in-session with otherpopup windows around");
+
+          // Cleanup
+          newWin.close();
+
+          // Next please
+          executeSoon(nextFn);
+        });
+      }, true);
+    });
+  }
+
+  /**
+   * Test 2: PrivateBrowsing in-session restore
+   * @note: Non-Mac only
+   */
+  function testOpenClosePrivateBrowsing(nextFn) {
+    setupTestAndRun(function(newWin) {
+      let pb = Cc["@mozilla.org/privatebrowsing;1"].
+               getService(Ci.nsIPrivateBrowsingService);
+
+      // Close the window
+      newWin.BrowserTryToCloseWindow();
+
+      // Enter private browsing mode
+      pb.privateBrowsingEnabled = true;
+
+      // Open a new window.
+      // The previously closed window should NOT be restored
+      newWin = openDialog(location, "_blank", CHROME_FEATURES);
+      newWin.addEventListener("load", function() {
+        executeSoon(function() {
+          is(newWin.gBrowser.browsers.length, 1,
+             "Did not restore in private browing mode");
+
+          // Cleanup
+          newWin.BrowserTryToCloseWindow();
+
+          // Exit private browsing mode again
+          pb.privateBrowsingEnabled = false;
+
+          newWin = openDialog(location, "_blank", CHROME_FEATURES);
+          newWin.addEventListener("load", function() {
+            executeSoon(function() {
+              is(newWin.gBrowser.browsers.length, TEST_URLS.length + 1,
+                 "Restored after leaving private browsing again");
+
+              newWin.close();
+
+              // Next please
+              executeSoon(nextFn);
+            });
+          }, true);
+        });
+      }, true);
+    });
+  }
+
+  /**
+   * Test 3: Open some popup windows to check those aren't restored, but
+   *         the browser window is
+   * @note: Non-Mac only
+   */
+  function testOpenCloseWindowAndPopup(nextFn) {
+    setupTestAndRun(function(newWin) {
+      // open some popups
+      let popup = openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[0]);
+      let popup2 = openDialog(location, "popup2", POPUP_FEATURES, TEST_URLS[1]);
+      popup2.addEventListener("load", function() {
+        popup2.removeEventListener("load", arguments.callee, false);
+        popup2.gBrowser.addEventListener("load", function() {
+          popup2.gBrowser.removeEventListener("load", arguments.callee, true);
+          popup2.gBrowser.addTab(TEST_URLS[0]);
+          // close the window
+          newWin.BrowserTryToCloseWindow();
+
+          // Close the popup window
+          // The test is successful when not this popup window is restored
+          // but instead newWin
+          popup2.close();
+
+          // open a new window the previously closed window should be restored to
+          newWin = openDialog(location, "_blank", CHROME_FEATURES);
+          newWin.addEventListener("load", function() {
+            executeSoon(function() {
+              is(newWin.gBrowser.browsers.length, TEST_URLS.length + 1,
+                 "Restored window and associated tabs in session");
+
+              // Cleanup
+              newWin.close();
+              popup.close();
+
+              // Next please
+              executeSoon(nextFn);
+            });
+          }, true);
+        }, true);
+      }, false);
+    });
+  }
+
+  /**
+   * Test 4: Open some popup window to check it isn't restored.
+   *         Instead nothing at all should be restored
+   * @note: Non-Mac only
+   */
+  function testOpenCloseOnlyPopup(nextFn) {
+    // prepare the prefs
+    setPrefs();
+
+    // This will cause nsSessionStore to restore a window the next time it
+    // gets a chance.
+    let popup = openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
+    popup.addEventListener("load", function() {
+      is(popup.gBrowser.browsers.length, 1,
+         "Did not restore the popup window (1)");
+      popup.BrowserTryToCloseWindow();
+
+      // Real tests
+      popup = openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
+      popup.addEventListener("load", function() {
+        popup.removeEventListener("load", arguments.callee, false);
+        popup.gBrowser.addEventListener("load", function() {
+          popup.gBrowser.removeEventListener("load", arguments.callee, true);
+          popup.gBrowser.addTab(TEST_URLS[0]);
+
+          is(popup.gBrowser.browsers.length, 2,
+             "Did not restore to the popup window (2)");
+
+          // Close the popup window
+          // The test is successful when not this popup window is restored
+          // but instead a new window is opened without restoring anything
+          popup.close();
+
+          let newWin = openDialog(location, "_blank", CHROME_FEATURES, "about:blank");
+          newWin.addEventListener("load", function() {
+            newWin.removeEventListener("load", arguments.callee, true);
+            executeSoon(function() {
+              isnot(newWin.gBrowser.browsers.length, 2,
+                    "Did not restore the popup window");
+              is(TEST_URLS.indexOf(newWin.gBrowser.browsers[0].currentURI.spec), -1,
+                 "Did not restore the popup window (2)");
+
+              // Cleanup
+              newWin.close();
+
+              // Next please
+              executeSoon(nextFn);
+            });
+          }, true);
+        }, true);
+      }, false);
+    }, true);
+  }
+
+    /**
+   * Test 5: Open some windows and do undoCloseWindow. This should prevent any
+   *         restoring later in the test
+   * @note: Non-Mac only
+   */
+  function testOpenCloseRestoreFromPopup(nextFn) {
+    setupTestAndRun(function(newWin) {
+      setupTestAndRun(function(newWin2) {
+        newWin.BrowserTryToCloseWindow();
+        newWin2.BrowserTryToCloseWindow();
+
+        newWin = undoCloseWindow(0);
+
+        newWin2 = openDialog(location, "_blank", CHROME_FEATURES);
+        newWin2.addEventListener("load", function() {
+          newWin2.removeEventListener("load", arguments.callee, true);
+          executeSoon(function() {
+            is(newWin2.gBrowser.browsers.length, 1,
+               "Did not restore, as undoCloseWindow() was last called");
+            is(TEST_URLS.indexOf(newWin2.gBrowser.browsers[0].currentURI.spec), -1,
+               "Did not restore, as undoCloseWindow() was last called (2)");
+
+            // Cleanup
+            newWin.close();
+            newWin2.close();
+
+            // Next please
+            executeSoon(nextFn);
+          });
+        }, true);
+      });
+    });
+  }
+
+  /**
+   * Test 7: Check whether the right number of notifications was received during
+   *         the tests
+   */
+  function testNotificationCount(nextFn) {
+    is(observing["browser-lastwindow-close-requested"], NOTIFICATIONS_EXPECTED,
+       "browser-lastwindow-close-requested notifications observed");
+
+    // -request must be one more as we cancel the first one we hit,
+    // and hence won't produce a corresponding -grant
+    // @see observer.observe
+    is(observing["browser-lastwindow-close-requested"],
+       observing["browser-lastwindow-close-granted"] + 1,
+       "Notification count for -request and -grant matches");
+
+    executeSoon(nextFn);
+  }
+
+  /**
+   * Test 8: Test if closing can be denied on Mac
+   *         Futhermore prepares the testNotificationCount test (Test 6)
+   * @note: Mac only
+   */
+  function testMacNotifications(nextFn, iteration) {
+    iteration = iteration || 1;
+    setupTestAndRun(function(newWin) {
+      // close the window
+      // window.close doesn't push any close events,
+      // so use BrowserTryToCloseWindow
+      newWin.BrowserTryToCloseWindow();
+      if (iteration == 1) {
+        ok(!newWin.closed, "First close attempt denied");
+        if (!newWin.closed) {
+          newWin.BrowserTryToCloseWindow();
+          ok(newWin.closed, "Second close attempt granted");
+        }
+      }
+
+      if (iteration < NOTIFICATIONS_EXPECTED - 1) {
+        executeSoon(function() testMacNotifications(nextFn, ++iteration));
+      }
+      else {
+        executeSoon(nextFn);
+      }
+    });
+  }
+
+  // Execution starts here
+
+  setupTestsuite();
+  if (navigator.platform.match(/Mac/)) {
+    // Mac tests
+    testMacNotifications(
+      function() testNotificationCount(
+        function() cleanupTestsuite() + finish()
+      )
+    );
+  }
+  else {
+    // Non-Mac Tests
+    testOpenCloseNormal(
+      function() testOpenClosePrivateBrowsing(
+        function() testOpenCloseWindowAndPopup(
+          function() testOpenCloseOnlyPopup(
+            function() testOpenCloseRestoreFromPopup (
+              function() testNotificationCount(
+                function() cleanupTestsuite() + finish()
+              )
+            )
+          )
+        )
+      )
+    );
+  }
+}
--- a/browser/components/sessionstore/test/browser/browser_490040.js
+++ b/browser/components/sessionstore/test/browser/browser_490040.js
@@ -33,61 +33,79 @@
  * 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 ***** */
 
 function test() {
   /** Test for Bug 490040 **/
 
-  let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-  let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+  let ss = Cc["@mozilla.org/browser/sessionstore;1"].
+           getService(Ci.nsISessionStore);
+  let os = Cc["@mozilla.org/observer-service;1"].
+           getService(Ci.nsIObserverService);
+  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+           getService(Ci.nsIWindowWatcher);
 
   waitForExplicitFinish();
 
-  function testWithState(aState, aCallback) {
-    // ensure we can store the window if need be
+  function testWithState(aState) {
+    // Ensure we can store the window if needed.
     let curClosedWindowCount = ss.getClosedWindowCount();
-    gPrefService.setIntPref("browser.sessionstore.max_windows_undo", curClosedWindowCount + 1);
+    gPrefService.setIntPref("browser.sessionstore.max_windows_undo",
+                            curClosedWindowCount + 1);
 
-    let theWin = openDialog(location, "_blank", "chrome,all,dialog=no");
-    theWin.addEventListener("load", function(aEvent) {
-      theWin.removeEventListener("load", arguments.callee, true);
-
-      ss.setWindowState(theWin, JSON.stringify(aState.windowState), true);
+    let windowObserver = {
+      observe: function(aSubject, aTopic, aData) {
+        let theWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
 
-      let observer = {
-        QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
-                                               Ci.nsISupportsWeakReference]),
-        observe: function(aSubject, aTopic, aData) {
-          let _this = this;
-          // use executeSoon to ensure this happens after SS observer
-          executeSoon(function() {
-            is(ss.getClosedWindowCount(), curClosedWindowCount + (aState.shouldBeAdded ? 1 : 0),
-               "That window should " + (aState.shouldBeAdded ? "" : "not ") + "be restorable");
-            os.removeObserver(_this, "domwindowclosed");
-            executeSoon(aCallback);
-          });
+        switch(aTopic) {
+          case "domwindowopened":
+            theWin.addEventListener("load", function () {
+              theWin.removeEventListener("load", arguments.callee, false);
+              executeSoon(function() {
+                // Close the window as soon as the first tab loads, or
+                // immediately if there are no tabs.
+                if (aState.windowState.windows[0].tabs[0].entries.length) {
+                  theWin.gBrowser.addEventListener("load", function() {
+                    theWin.gBrowser.removeEventListener("load",
+                                                        arguments.callee, true);
+                    theWin.close();
+                  }, true);
+                } else {
+                  executeSoon(function() {
+                    theWin.close();
+                  });
+                }
+                ss.setWindowState(theWin, JSON.stringify(aState.windowState),
+                                  true);
+              });
+            }, false);
+            break;
+
+          case "domwindowclosed":
+            ww.unregisterNotification(this);
+            // Use executeSoon to ensure this happens after SS observer.
+            executeSoon(function() {
+              is(ss.getClosedWindowCount(),
+                 curClosedWindowCount + (aState.shouldBeAdded ? 1 : 0),
+                 "That window should " + (aState.shouldBeAdded ? "" : "not ") +
+                 "be restorable");
+              executeSoon(runNextTest);
+            });
+            break;
         }
-      };
-      os.addObserver(observer, "domwindowclosed", true);
-
-      // Close the window as soon as the first tab loads, or immediately if
-      // there are no tabs.
-      if (aState.windowState.windows[0].tabs[0].entries.length) {
-        theWin.gBrowser.addEventListener("load", function() {
-          theWin.gBrowser.removeEventListener("load", arguments.callee, true);
-          theWin.close();
-        }, true);
-      } else {
-        executeSoon(function() {
-          theWin.close();
-        });
       }
-    }, true);
+    }
+    ww.registerNotification(windowObserver);
+    ww.openWindow(null,
+                  location,
+                  "_blank",
+                  "chrome,all,dialog=no",
+                  null);
   }
 
   // Only windows with open tabs are restorable. Windows where a lone tab is
   // detached may have _closedTabs, but is left with just an empty tab.
   let states = [
     {
       shouldBeAdded: true,
       windowState: {
@@ -123,20 +141,21 @@ function test() {
           tabs: [{ entries: [] }],
           _closedTabs: [],
           extData: { keyname: "pi != " + Math.random() }
         }]
       }
     }
   ];
 
-  testWithState(states[0], function() {
-    testWithState(states[1], function() {
-      testWithState(states[2], function() {
-        testWithState(states[3], function() {
-          gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
-          finish();
-        });
-      });
-    });
-  });
+  function runNextTest() {
+    if (states.length) {
+      let state = states.shift();
+      testWithState(state);
+    }
+    else {
+      gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
+      finish();
+    }
+  }
+  runNextTest();
 }
 
--- a/browser/components/shell/content/setDesktopBackground.xul
+++ b/browser/components/shell/content/setDesktopBackground.xul
@@ -72,17 +72,19 @@
     <hbox align="center">
       <label value="&position.label;"/>
       <menulist id="menuPosition"
                 label="&position.label;" 
                 oncommand="gSetBackground.updatePosition();">
         <menupopup>
           <menuitem label="&center.label;"  value="CENTER"/>
           <menuitem label="&tile.label;"    value="TILE"/>
+#ifndef WINCE
           <menuitem label="&stretch.label;" value="STRETCH"/>
+#endif
         </menupopup>
       </menulist>
       <spacer flex="1"/>
       <label value="&color.label;"/>
       <colorpicker id="desktopColor"
                    type="button" 
                    onchange="gSetBackground.updateColor(this.color);"/> 
     </hbox>
--- a/browser/components/shell/src/nsWindowsShellService.cpp
+++ b/browser/components/shell/src/nsWindowsShellService.cpp
@@ -21,16 +21,17 @@
  * Contributor(s):
  *  Ben Goodger    <ben@mozilla.org>       (Clients, Mail, New Default Browser)
  *  Joe Hewitt     <hewitt@netscape.com>   (Set Background)
  *  Blake Ross     <blake@cs.stanford.edu> (Desktop Color, DDE support)
  *  Jungshik Shin  <jshin@mailaps.org>     (I18N)
  *  Robert Strong  <robert.bugzilla@gmail.com>
  *  Asaf Romano    <mano@mozilla.com>
  *  Ryan Jones     <sciguyryan@gmail.com>
+ *  Paul O'Shannessy <paul@oshannessy.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
@@ -210,19 +211,21 @@ typedef struct {
   char* valueName;
   char* valueData;
 } SETTING;
 
 #ifndef WINCE
 #define APP_REG_NAME L"Firefox"
 #define CLS_HTML "FirefoxHTML"
 #define CLS_URL "FirefoxURL"
+#define CPL_DESKTOP L"\\Control Panel\\Desktop"
 #define VAL_OPEN "\"%APPPATH%\" -requestPending -osint -url \"%1\""
 #define VAL_FILE_ICON "%APPPATH%,1"
 #else
+#define CPL_DESKTOP L"\\ControlPanel\\Desktop"
 #define VAL_OPEN "\"%APPPATH%\" -osint -url \"%1\""
 #define VAL_FILE_ICON "%APPPATH%,-2"
 #endif
 
 #define DI "\\DefaultIcon"
 #define SOP "\\shell\\open\\command"
 
 
@@ -651,22 +654,22 @@ nsWindowsShellService::SetDesktopBackgro
   // write the bitmap to a file in the profile directory
   rv = WriteBitmap(file, container);
 
   // if the file was written successfully, set it as the system wallpaper
   if (NS_SUCCEEDED(rv)) {
      PRBool result = PR_FALSE;
      DWORD  dwDisp = 0;
      HKEY   key;
-     // Try to create/open a subkey under HKLM.
-     DWORD res = ::RegCreateKeyExW(HKEY_CURRENT_USER,
-                                   L"Control Panel\\Desktop",
+     // Try to create/open a subkey under HKCU.
+     DWORD res = ::RegCreateKeyExW(HKEY_CURRENT_USER, CPL_DESKTOP,
                                    0, NULL, REG_OPTION_NON_VOLATILE,
                                    KEY_WRITE, NULL, &key, &dwDisp);
     if (REG_SUCCEEDED(res)) {
+#ifndef WINCE
       PRUnichar tile[2], style[2];
       switch (aPosition) {
         case BACKGROUND_TILE:
           tile[0] = '1';
           style[0] = '1';
           break;
         case BACKGROUND_CENTER:
           tile[0] = '0';
@@ -683,18 +686,35 @@ nsWindowsShellService::SetDesktopBackgro
       // The size is always 3 unicode characters.
       PRInt32 size = 3 * sizeof(PRUnichar);
       ::RegSetValueExW(key, L"TileWallpaper",
                        0, REG_SZ, (const BYTE *)tile, size);
       ::RegSetValueExW(key, L"WallpaperStyle",
                        0, REG_SZ, (const BYTE *)style, size);
       ::SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (PVOID)path.get(),
                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
+#else
+      DWORD tile = (aPosition == BACKGROUND_TILE);
+      ::RegSetValueExW(key, L"Tile",
+                       0, REG_DWORD, (const BYTE *)&tile, sizeof(DWORD));
+      // On WinCE SPI_SETDESKWALLPAPER isn't available, so set the registry
+      // entry ourselves and then broadcast UI change
+      PRInt32 size = (path.Length() + 1) * sizeof(PRUnichar);
+      ::RegSetValueExW(key, L"Wallpaper",
+                       0, REG_SZ, (const BYTE *)path.get(), size);
+      ::SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, NULL, 0);
+#endif
+
       // Close the key we opened.
       ::RegCloseKey(key);
+
+#ifdef WINCE
+      // Ensure that the writes are flushed in case of hard reboot
+      ::RegFlushKey(HKEY_CURRENT_USER);
+#endif
     }
   }
   return rv;
 }
 
 NS_IMETHODIMP
 nsWindowsShellService::OpenApplication(PRInt32 aApplication)
 {
@@ -810,20 +830,23 @@ nsWindowsShellService::SetDesktopBackgro
   int aParameters[2] = { COLOR_BACKGROUND, COLOR_DESKTOP };
   BYTE r = (aColor >> 16);
   BYTE g = (aColor << 16) >> 24;
   BYTE b = (aColor << 24) >> 24;
   COLORREF colors[2] = { RGB(r,g,b), RGB(r,g,b) };
 
   ::SetSysColors(sizeof(aParameters) / sizeof(int), aParameters, colors);
 
+  // SetSysColors is persisting across sessions on Windows CE, so no need to
+  // write to registry
+#ifndef WINCE
   PRBool result = PR_FALSE;
   DWORD  dwDisp = 0;
   HKEY   key;
-  // Try to create/open a subkey under HKLM.
+  // Try to create/open a subkey under HKCU.
   DWORD rv = ::RegCreateKeyExW(HKEY_CURRENT_USER,
                                L"Control Panel\\Colors", 0, NULL,
                                REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
                                &key, &dwDisp);
 
   if (REG_SUCCEEDED(rv)) {
     char rgb[12];
     sprintf((char*)rgb, "%u %u %u\0", r, g, b);
@@ -831,16 +854,17 @@ nsWindowsShellService::SetDesktopBackgro
 
     ::RegSetValueExW(key, L"Background",
                      0, REG_SZ, (const BYTE *)backColor.get(),
                      (backColor.Length() + 1) * sizeof(PRUnichar));
   }
   
   // Close the key we opened.
   ::RegCloseKey(key);
+#endif
   return NS_OK;
 }
 
 #ifndef WINCE
 NS_IMETHODIMP
 nsWindowsShellService::GetUnreadMailCount(PRUint32* aCount)
 {
   *aCount = 0;
--- a/browser/installer/unix/packages-static
+++ b/browser/installer/unix/packages-static
@@ -232,16 +232,17 @@ bin/components/sessionstore.xpt
 bin/components/nsURLFormatter.js
 bin/components/urlformatter.xpt
 bin/components/libbrowserdirprovider.so
 bin/components/libbrowsercomps.so
 bin/components/txEXSLTRegExFunctions.js
 bin/components/nsLivemarkService.js
 bin/components/nsTaggingService.js
 bin/components/nsPlacesDBFlush.js
+bin/components/nsPlacesAutoComplete.js
 bin/components/nsDefaultCLH.js
 bin/components/nsContentPrefService.js
 bin/components/nsContentDispatchChooser.js
 bin/components/nsHandlerService.js
 bin/components/nsWebHandlerApp.js
 bin/components/libdbusservice.so
 bin/components/aboutRights.js
 bin/components/aboutRobots.js
--- a/browser/installer/windows/packages-static
+++ b/browser/installer/windows/packages-static
@@ -239,16 +239,17 @@ bin\components\sessionstore.xpt
 bin\components\nsURLFormatter.js
 bin\components\urlformatter.xpt
 bin\components\browserdirprovider.dll
 bin\components\brwsrcmp.dll
 bin\components\txEXSLTRegExFunctions.js
 bin\components\nsLivemarkService.js
 bin\components\nsTaggingService.js
 bin\components\nsPlacesDBFlush.js
+bin\components\nsPlacesAutoComplete.js
 bin\components\nsDefaultCLH.js
 bin\components\nsContentPrefService.js
 bin\components\nsContentDispatchChooser.js
 bin\components\nsHandlerService.js
 bin\components\nsWebHandlerApp.js
 bin\components\aboutRights.js
 bin\components\aboutRobots.js
 bin\components\aboutCertError.js
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -365,16 +365,17 @@ you can use these alternative items. Oth
 
 <!ENTITY newTabButton.tooltip           "Open a new tab">
 <!ENTITY newWindowButton.tooltip        "Open a new window">
 <!ENTITY sidebarCloseButton.tooltip     "Close sidebar">
 
 <!ENTITY cutButton.tooltip              "Cut">
 <!ENTITY copyButton.tooltip             "Copy">
 <!ENTITY pasteButton.tooltip            "Paste">
+<!ENTITY fullScreenButton.tooltip       "Display the window in full screen">
 
 <!ENTITY quitApplicationCmdWin.label       "Exit"> 
 <!ENTITY quitApplicationCmdWin.accesskey   "x">
 <!ENTITY goBackCmd.commandKey "[">
 <!ENTITY goForwardCmd.commandKey "]">
 <!ENTITY quitApplicationCmd.label       "Quit"> 
 <!ENTITY quitApplicationCmd.accesskey   "Q">
 <!ENTITY quitApplicationCmdMac.label    "Quit &brandShortName;">
--- a/browser/locales/en-US/chrome/browser/openLocation.dtd
+++ b/browser/locales/en-US/chrome/browser/openLocation.dtd
@@ -1,10 +1,10 @@
 <!-- extracted from content/openLocation.xul -->
 
 <!ENTITY enter.label "Enter the web location (URL), or specify the local file you would like to open:">  
 <!ENTITY chooseFile.label "Choose File…">
 <!ENTITY newWindow.label "New Window">
 <!ENTITY newTab.label "New Tab">
-<!ENTITY topWindow.label "Current Window">
+<!ENTITY topTab.label "Current Tab">
 <!ENTITY caption.label "Open Web Location">
 <!ENTITY openWhere.label "Open in:">
 <!ENTITY openBtn.label "Open">
--- a/browser/locales/en-US/chrome/browser/safeMode.dtd
+++ b/browser/locales/en-US/chrome/browser/safeMode.dtd
@@ -43,18 +43,18 @@
 <!ENTITY safeModeDescription2.label   "You can make some or all of these changes permanent:">
 
 <!ENTITY disableAddons.label          "Disable all add-ons">
 <!ENTITY disableAddons.accesskey      "D">
 
 <!ENTITY resetToolbars.label          "Reset toolbars and controls">
 <!ENTITY resetToolbars.accesskey      "R">
 
-<!ENTITY resetBookmarks.label         "Reset bookmarks to &brandShortName; defaults">
-<!ENTITY resetBookmarks.accesskey     "b">
+<!ENTITY deleteBookmarks.label        "Delete all bookmarks except for backups">
+<!ENTITY deleteBookmarks.accesskey    "b">
 
 <!ENTITY resetUserPrefs.label         "Reset all user preferences to &brandShortName; defaults">
 <!ENTITY resetUserPrefs.accesskey     "p">
 
 <!ENTITY restoreSearch.label          "Restore default search engines">
 <!ENTITY restoreSearch.accesskey      "s">
 
 <!ENTITY changeAndRestartButton.label "Make Changes and Restart">
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -396,43 +396,43 @@ menuitem:not([type]) {
   list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu");
 }
 
 #historyMenuBack[disabled],
 #context-back[disabled] {
   list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu&state=disabled");
 }
 
-#historyMenuBack[chromedir="rtl"],
-#context-back[chromedir="rtl"] {
+#historyMenuBack:-moz-locale-dir(rtl),
+#context-back:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu");
 }
 
-#historyMenuBack[disabled][chromedir="rtl"],
-#context-back[disabled][chromedir="rtl"] {
+#historyMenuBack[disabled]:-moz-locale-dir(rtl),
+#context-back[disabled]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu&state=disabled");
 }
 
 #historyMenuForward,
 #context-forward {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu");
 }
 
 #historyMenuForward[disabled],
 #context-forward[disabled] {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu&state=disabled");
 }
 
-#historyMenuForward[chromedir="rtl"],
-#context-forward[chromedir="rtl"] {
+#historyMenuForward:-moz-locale-dir(rtl),
+#context-forward:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu");
 }
 
-#historyMenuForward[disabled][chromedir="rtl"],
-#context-forward[disabled][chromedir="rtl"] {
+#historyMenuForward[disabled]:-moz-locale-dir(rtl),
+#context-forward[disabled]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu&state=disabled");
 }
 
 #historyMenuHome {
   list-style-image: url("moz-icon://stock/gtk-home?size=menu");
 }
 
 #menu_showAllHistory {
@@ -517,34 +517,34 @@ toolbar[mode="full"] .toolbarbutton-menu
 /* 24px primary toolbar buttons */
 #back-button {
   list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar");
 }
 #back-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar&state=disabled");
 }
 
-#back-button[chromedir="rtl"] {
+#back-button:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar");
 }
-#back-button[disabled="true"][chromedir="rtl"] {
+#back-button[disabled="true"]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar&state=disabled");
 }
 
 #forward-button {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar");
 }
 #forward-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar&state=disabled");
 }
 
-#forward-button[chromedir="rtl"] {
+#forward-button:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar");
 }
-#forward-button[disabled="true"][chromedir="rtl"] {
+#forward-button[disabled="true"]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar&state=disabled");
 }
 
 #reload-button {
   list-style-image: url("moz-icon://stock/gtk-refresh?size=toolbar");
 }
 #reload-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-refresh?size=toolbar&state=disabled");
@@ -622,16 +622,20 @@ toolbar[mode="full"] .toolbarbutton-menu
 
 #paste-button {
   list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar");
 }
 #paste-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar&state=disabled");
 }
 
+#fullscreen-button {
+  list-style-image: url("moz-icon://stock/gtk-fullscreen?size=toolbar");
+}
+
 /* 16px primary toolbar buttons */
 toolbar[iconsize="small"] .toolbarbutton-1 {
   -moz-box-orient: vertical;
   min-width: 0;
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
 }
 
 toolbar[iconsize="small"] .toolbarbutton-1[type="menu-button"] {
@@ -643,43 +647,43 @@ toolbar[iconsize="small"] #back-button {
 }
 .unified-nav-back[_moz-menuactive] {
   list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu") !important;
 }
 toolbar[iconsize="small"] #back-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu&state=disabled");
 }
 
-toolbar[iconsize="small"] #back-button[chromedir="rtl"] {
+toolbar[iconsize="small"] #back-button:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu");
 }
-menupopup[chromedir="rtl"] > .unified-nav-back[_moz-menuactive] {
+menupopup:-moz-locale-dir(rtl) > .unified-nav-back[_moz-menuactive] {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu") !important;
 }
-toolbar[iconsize="small"] #back-button[disabled="true"][chromedir="rtl"] {
+toolbar[iconsize="small"] #back-button[disabled="true"]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu&state=disabled");
 }
 
 toolbar[iconsize="small"] #forward-button {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu");
 }
 .unified-nav-forward[_moz-menuactive] {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu") !important;
 }
 toolbar[iconsize="small"] #forward-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu&state=disabled");
 }
 
-toolbar[iconsize="small"] #forward-button[chromedir="rtl"] {
+toolbar[iconsize="small"] #forward-button:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu");
 }
-menupopup[chromedir="rtl"] > .unified-nav-forward[_moz-menuactive] {
+menupopup:-moz-locale-dir(rtl) > .unified-nav-forward[_moz-menuactive] {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu") !important;
 }
-toolbar[iconsize="small"] #forward-button[disabled="true"][chromedir="rtl"] {
+toolbar[iconsize="small"] #forward-button[disabled="true"]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu&state=disabled");
 }
 
 toolbar[iconsize="small"] #stop-button {
   list-style-image: url("moz-icon://stock/gtk-stop?size=menu");
 }
 toolbar[iconsize="small"] #stop-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-stop?size=menu&state=disabled");
@@ -759,16 +763,20 @@ toolbar[iconsize="small"] #copy-button[d
 
 toolbar[iconsize="small"] #paste-button {
   list-style-image: url("moz-icon://stock/gtk-paste?size=menu");
 }
 toolbar[iconsize="small"] #paste-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-paste?size=menu&state=disabled");
 }
 
+toolbar[iconsize="small"] #fullscreen-button {
+  list-style-image: url("moz-icon://stock/gtk-fullscreen?size=menu");
+}
+
 /* Fullscreen window controls */
 #window-controls {
   -moz-box-align: start;
   padding: 0;
   border-left: 2px solid;
   -moz-border-left-colors: ThreeDHighlight ThreeDShadow;
 }
 
@@ -828,17 +836,17 @@ toolbar[iconsize="small"] #paste-button[
   display: none;
 }
 
 #PopupAutoComplete,
 #PopupAutoCompleteRichResult {
   direction: ltr !important;
 }
 
-#PopupAutoComplete[chromedir="rtl"] > tree > treerows {
+#PopupAutoComplete:-moz-locale-dir(rtl) > tree > treerows {
   direction: rtl;
 }
 
 #PopupAutoComplete .autocomplete-treebody {
   direction: ltr;
 }
 
 /* Favicon */
@@ -870,17 +878,17 @@ toolbar[iconsize="small"] #paste-button[
 
 /* Identity indicator */
 #identity-box {
   background-color: -moz-dialog;
   color: -moz-dialogtext;
   -moz-border-end: 1px solid ThreeDShadow;
 }
 
-#identity-box[chromedir="rtl"] {
+#identity-box:-moz-locale-dir(rtl) {
   -moz-border-start: 1px solid ThreeDShadow;
 }
 
 #identity-box:focus {
   outline: 1px dotted -moz-DialogText;
 }
 
 #identity-box:hover > hbox {
@@ -1333,17 +1341,17 @@ tabpanels {
   list-style-image: url("chrome://global/skin/icons/loading_16.png");
   -moz-margin-end: 4px;
 }
 
 toolbarbutton.chevron {
   list-style-image: url("chrome://global/skin/toolbar/chevron.gif") !important;
 }
 
-toolbarbutton.chevron[chromedir="rtl"] {
+toolbarbutton.chevron:-moz-locale-dir(rtl) {
   list-style-image: url("chrome://global/skin/toolbar/chevron-rtl.gif") !important;
 }
 
 toolbarbutton.chevron > .toolbarbutton-text,
 toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
--- a/browser/themes/gnomestripe/browser/places/organizer.css
+++ b/browser/themes/gnomestripe/browser/places/organizer.css
@@ -8,36 +8,36 @@
 
 #back-button {
   list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar");
 }
 #back-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar&state=disabled");
 }
 
-#back-button[chromedir="rtl"] {
+#back-button:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar");
 }
-#back-button[disabled="true"][chromedir="rtl"] {
+#back-button[disabled="true"]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar&state=disabled");
 }
 
 /* forward button */
 
 #forward-button {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar");
 }
 #forward-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar&state=disabled");
 }
 
-#forward-button[chromedir="rtl"] {
+#forward-button:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar");
 }
-#forward-button[disabled="true"][chromedir="rtl"] {
+#forward-button[disabled="true"]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar&state=disabled");
 }
 
 /* Menu */
 #placesMenu {
   -moz-appearance: none;
   border: none;
 }
--- a/browser/themes/gnomestripe/browser/searchbar.css
+++ b/browser/themes/gnomestripe/browser/searchbar.css
@@ -68,17 +68,17 @@
 }
 
 .search-go-button {
   padding: 1px;
   list-style-image: url("chrome://global/skin/icons/Search-glass.png");
   cursor: pointer;
 }
 
-.search-go-button[chromedir="rtl"] {
+.search-go-button:-moz-locale-dir(rtl) {
   -moz-transform: scaleX(-1);
 }
 
 menuitem[cmd="cmd_clearhistory"] {
   list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
 }
 
 menuitem[cmd="cmd_clearhistory"][disabled] {
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -119,22 +119,22 @@ toolbarbutton.bookmark-item {
   color: #222;
   border: none !important;
 }
 
 toolbarbutton.bookmark-item[type=menu] > .toolbarbutton-menu-dropmarker {
   -moz-padding-end: 7px;
 }
 
-toolbarbutton.bookmark-item[type=menu][chromedir="rtl"] > .toolbarbutton-menu-dropmarker {
+toolbarbutton.bookmark-item[type=menu]:-moz-locale-dir(rtl) > .toolbarbutton-menu-dropmarker {
   -moz-padding-start: 4px;
   -moz-padding-end: 2px;
 }
 
-toolbarbutton.bookmark-item[chromedir="rtl"] {
+toolbarbutton.bookmark-item:-moz-locale-dir(rtl) {
   -moz-padding-start: 0px;
   -moz-padding-end: 7px;
 }
 
 .bookmark-item[container] {
   list-style-image: url("chrome://global/skin/tree/folder.png");
 }
 
@@ -145,17 +145,17 @@ toolbarbutton.bookmark-item[chromedir="r
 toolbarbutton.bookmark-item > .toolbarbutton-text {
   margin: 0;
 }
 
 toolbarbutton.bookmark-item:not([container]) > .toolbarbutton-text {
   -moz-padding-end: 7px;
 }
 
-toolbarbutton.bookmark-item[chromedir="rtl"] > .toolbarbutton-text {
+toolbarbutton.bookmark-item:-moz-locale-dir(rtl) > .toolbarbutton-text {
   -moz-padding-end: 0;
   -moz-padding-start: 7px;
 }
 
 toolbarbutton.bookmark-item:hover {
   background: url("chrome://global/skin/toolbar/toolbarbutton-customhover-left.png") no-repeat left center;
 }
 
@@ -165,45 +165,45 @@ toolbarbutton.bookmark-item[open="true"]
 }
 
 toolbarbutton.bookmark-item:not([container]):hover > .toolbarbutton-text,
 toolbarbutton.bookmark-item[container]:not([open]):hover > .toolbarbutton-menu-dropmarker {
   background: url("chrome://global/skin/toolbar/toolbarbutton-customhover-right.png") no-repeat right top;
 }
 
 toolbarbutton.bookmark-item[container]:hover > .toolbarbutton-text,
-toolbarbutton.bookmark-item[container][chromedir="rtl"]:not([open]):hover > .toolbarbutton-menu-dropmarker,
+toolbarbutton.bookmark-item[container]:-moz-locale-dir(rtl):not([open]):hover > .toolbarbutton-menu-dropmarker,
 #home-button.bookmark-item:hover > .toolbarbutton-icon,
-#home-button.bookmark-item[chromedir="rtl"]:hover > .toolbarbutton-text {
+#home-button.bookmark-item:-moz-locale-dir(rtl):hover > .toolbarbutton-text {
   background: url("chrome://global/skin/toolbar/toolbarbutton-customhover-mid.png") repeat-x;
 }
 
-#home-button.bookmark-item:hover[chromedir="rtl"] > .toolbarbutton-icon,
-toolbarbutton.bookmark-item[chromedir="rtl"]:hover > .toolbarbutton-text {
+#home-button.bookmark-item:hover:-moz-locale-dir(rtl) > .toolbarbutton-icon,
+toolbarbutton.bookmark-item:-moz-locale-dir(rtl):hover > .toolbarbutton-text {
   background: url("chrome://global/skin/toolbar/toolbarbutton-customhover-right.png") no-repeat right top;
 }
 
 toolbarbutton.bookmark-item:not([container]):hover:active > .toolbarbutton-text,
 toolbarbutton.bookmark-item[open] > .toolbarbutton-menu-dropmarker,
 toolbarbutton.bookmark-item[container]:hover:active > .toolbarbutton-menu-dropmarker {
   background: url("chrome://browser/skin/bookmark-open-right.png") no-repeat right top;
 }
 
 toolbarbutton.bookmark-item[container]:hover:active > .toolbarbutton-text,
 toolbarbutton.bookmark-item[container][open="true"] > .toolbarbutton-text,
 #home-button.bookmark-item:hover:active > .toolbarbutton-icon,
-toolbarbutton.bookmark-item[container][chromedir="rtl"]:hover:active > .toolbarbutton-menu-dropmarker,
-toolbarbutton.bookmark-item[container][chromedir="rtl"][open="true"] > .toolbarbutton-menu-dropmarker,
-#home-button.bookmark-item:hover:active[chromedir="rtl"] > .toolbarbutton-text {
+toolbarbutton.bookmark-item[container]:-moz-locale-dir(rtl):hover:active > .toolbarbutton-menu-dropmarker,
+toolbarbutton.bookmark-item[container]:-moz-locale-dir(rtl)[open="true"] > .toolbarbutton-menu-dropmarker,
+#home-button.bookmark-item:hover:active:-moz-locale-dir(rtl) > .toolbarbutton-text {
   background: url("chrome://browser/skin/bookmark-open-mid.png") repeat-x !important;
 }
 
-toolbarbutton.bookmark-item[chromedir="rtl"][container]:hover:active > .toolbarbutton-text,
-toolbarbutton.bookmark-item[chromedir="rtl"][container][open] > .toolbarbutton-text,
-#home-button.bookmark-item[chromedir="rtl"]:hover:active > .toolbarbutton-icon {
+toolbarbutton.bookmark-item:-moz-locale-dir(rtl)[container]:hover:active > .toolbarbutton-text,
+toolbarbutton.bookmark-item:-moz-locale-dir(rtl)[container][open] > .toolbarbutton-text,
+#home-button.bookmark-item:-moz-locale-dir(rtl):hover:active > .toolbarbutton-icon {
   background: url("chrome://browser/skin/bookmark-open-right.png") no-repeat right top !important;
 }
 
 toolbarbutton.bookmark-item-microsummarized {
   max-width: 20em;
 }
 
 .bookmark-item > .toolbarbutton-icon {
@@ -285,18 +285,18 @@ toolbarbutton.bookmark-item-microsummari
 
 .toolbarbutton-1,
 #back-forward-dropmarker {
   min-width: 0px;
   list-style-image: url("chrome://browser/skin/Toolbar.png");
   -moz-box-orient: vertical;
 }
 
-.toolbarbutton-1[chromedir="rtl"],
-#back-forward-dropmarker[chromedir="rtl"] {
+.toolbarbutton-1:-moz-locale-dir(rtl),
+#back-forward-dropmarker:-moz-locale-dir(rtl) {
   list-style-image: url("chrome://browser/skin/Toolbar-rtl.png");
 }
 
 toolbar[mode="text"] .toolbarbutton-1,
 toolbar[mode="text"] .toolbarbutton-menubutton-button {
   -moz-box-orient: horizontal;
 }
 
@@ -370,82 +370,82 @@ toolbar[mode="icons"] #forward-button .t
 toolbar[mode="icons"] #unified-back-forward-button > #back-button {
   -moz-image-region: rect(0px, 535px, 33px, 504px);
   -moz-margin-end: 0;
   -moz-padding-end: 0;
   border-left: none;
   border-right: none;
 }
 
-toolbar[mode="icons"] #unified-back-forward-button > #back-button[chromedir="rtl"] {
+toolbar[mode="icons"] #unified-back-forward-button > #back-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px, 571px, 33px, 540px);
 }
 
 toolbar[mode="icons"] #unified-back-forward-button > #back-button[disabled="true"] {
  -moz-image-region: rect(33px, 535px, 66px, 504px);
 }
 
-toolbar[mode="icons"] #unified-back-forward-button > #back-button[disabled="true"][chromedir="rtl"] {
+toolbar[mode="icons"] #unified-back-forward-button > #back-button[disabled="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(33px, 571px, 66px, 540px);
 }
 
 toolbar[mode="icons"] #unified-back-forward-button > #back-button:hover:active:not([disabled]),
 toolbar[mode="icons"] #unified-back-forward-button > #back-button[open="true"] {
   -moz-image-region: rect(66px, 535px, 99px, 504px);
 }
 
-toolbar[mode="icons"] #unified-back-forward-button > #back-button:hover:active[chromedir="rtl"]:not([disabled]),
-toolbar[mode="icons"] #unified-back-forward-button > #back-button[open="true"][chromedir="rtl"] {
+toolbar[mode="icons"] #unified-back-forward-button > #back-button:hover:active:-moz-locale-dir(rtl):not([disabled]),
+toolbar[mode="icons"] #unified-back-forward-button > #back-button[open="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(66px, 571px, 99px, 540px);
 }
 
 toolbar[mode="icons"] #unified-back-forward-button > #forward-button {
   -moz-image-region: rect(0px, 560px, 33px, 535px);
   -moz-margin-start: 0;
   -moz-margin-end: 0;
   -moz-padding-start: 0;
   -moz-padding-end: 0;
   border-left: none;
   border-right: none;
 }
 
-toolbar[mode="icons"] #unified-back-forward-button > #forward-button[chromedir="rtl"] {
+toolbar[mode="icons"] #unified-back-forward-button > #forward-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px, 540px, 33px, 514px);
 }
 
 toolbar[mode="icons"] #unified-back-forward-button > #forward-button[disabled="true"] {
  -moz-image-region: rect(33px, 560px, 66px, 535px);
 }
 
-toolbar[mode="icons"] #unified-back-forward-button > #forward-button[disabled="true"][chromedir="rtl"] {
+toolbar[mode="icons"] #unified-back-forward-button > #forward-button[disabled="true"]:-moz-locale-dir(rtl) {
  -moz-image-region: rect(33px, 540px, 66px, 514px);
 }
 
 toolbar[mode="icons"] #unified-back-forward-button > #forward-button:hover:active:not([disabled]),
 toolbar[mode="icons"] #unified-back-forward-button > #forward-button[open="true"] {
   -moz-image-region: rect(99px, 560px, 132px, 530px);
   -moz-margin-start: -5px;
 }
 
-toolbar[mode="icons"] #unified-back-forward-button > #forward-button[chromedir="rtl"]:hover:active:not([disabled]),
-toolbar[mode="icons"] #unified-back-forward-button > #forward-button[open="true"][chromedir="rtl"] {
+toolbar[mode="icons"] #unified-back-forward-button > #forward-button:-moz-locale-dir(rtl):hover:active:not([disabled]),
+toolbar[mode="icons"] #unified-back-forward-button > #forward-button[open="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(99px, 545px, 132px, 514px);
 }
 
 #back-forward-dropmarker {
   -moz-image-region: rect(0px, 571px, 33px, 560px);
   -moz-margin-start: 0;
   -moz-margin-end: 3px;
   -moz-padding-start: 0;
   -moz-padding-end: 1px;
   border-left: none;
   border-right: none;
 }
 
-#back-forward-dropmarker[chromedir="rtl"] {
+#back-forward-dropmarker:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px, 514px, 33px, 504px);
 }
 
 toolbar[mode="icons"] #back-forward-dropmarker > image {
   display: -moz-box;
   margin: 0;
   padding: 0;
 }
@@ -453,131 +453,131 @@ toolbar[mode="icons"] #back-forward-drop
 toolbar[mode="icons"] #back-forward-dropmarker > dropmarker {
   display: none;
 }
 
 #back-forward-dropmarker[disabled="true"] {
  -moz-image-region: rect(33px, 571px, 66px, 560px);
 }
 
-#back-forward-dropmarker[disabled="true"][chromedir="rtl"] {
+#back-forward-dropmarker[disabled="true"]:-moz-locale-dir(rtl) {
  -moz-image-region: rect(33px, 514px, 66px, 504px);
 }
 
 #back-forward-dropmarker:hover:active:not([disabled]),
 #back-forward-dropmarker[open="true"] {
   -moz-image-region: rect(66px, 571px, 99px, 560px);
 }
 
-#back-forward-dropmarker[chromedir="rtl"]:hover:active:not([disabled]),
-#back-forward-dropmarker[open="true"][chromedir="rtl"] {
+#back-forward-dropmarker:-moz-locale-dir(rtl):hover:active:not([disabled]),
+#back-forward-dropmarker[open="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(66px, 514px, 99px, 504px);
 }
 
 .unified-nav-back[_moz-menuactive],
-menupopup[chromedir="rtl"] > .unified-nav-forward[_moz-menuactive] {
+menupopup:-moz-locale-dir(rtl) > .unified-nav-forward[_moz-menuactive] {
   list-style-image: url("chrome://browser/skin/menu-back.png") !important;
 }
 
 .unified-nav-forward[_moz-menuactive],
-menupopup[chromedir="rtl"] > .unified-nav-back[_moz-menuactive] {
+menupopup:-moz-locale-dir(rtl) > .unified-nav-back[_moz-menuactive] {
   list-style-image: url("chrome://browser/skin/menu-forward.png") !important;
 }
 
 
 /* ----- SMALL BACK BUTTON, PAIRED----- */	
 
 toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button {
   -moz-image-region: rect(0px, 605px, 23px, 571px);
   -moz-margin-end: 0;
   -moz-padding-end: 0;
   border-left: none;
   border-right: none;
 }
 
-toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button[chromedir="rtl"] {
+toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px, 648px, 23px, 614px);
 }
 
 toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button[disabled="true"] {
   -moz-image-region: rect(23px, 605px, 46px, 571px);
 }
 
-toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button[disabled="true"][chromedir="rtl"] {
+toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button[disabled="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(23px, 648px, 46px, 614px);
 }
 
 toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button:hover:active:not([disabled]),
 toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button[open="true"] {
   -moz-image-region: rect(46px, 605px, 69px, 571px);
 }
 
-toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button[chromedir="rtl"]:hover:active:not([disabled]),
-toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button[open="true"][chromedir="rtl"] {
+toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button:-moz-locale-dir(rtl):hover:active:not([disabled]),
+toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #back-button[open="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(46px, 648px, 69px, 614px);
 }
 
 /* ----- SMALL FORWARD BUTTON, PAIRED ----- */	
 
 toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button {
   -moz-image-region: rect(0px, 638px, 23px, 605px);
   -moz-margin-start: 0;
   -moz-padding-start: 0;
   border-left: none;
   border-right: none;
 }
 
-toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button[chromedir="rtl"] {
+toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px, 614px, 23px, 580px);
 }
 
 toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button[disabled="true"] {
  -moz-image-region: rect(23px, 638px, 46px, 605px);
 }
 
-toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button[disabled="true"][chromedir="rtl"] {
+toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button[disabled="true"]:-moz-locale-dir(rtl) {
  -moz-image-region: rect(23px, 614px, 46px, 580px);
 }
 
 toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button:hover:active:not([disabled]),
 toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button[open="true"] {
   -moz-image-region: rect(46px, 638px, 69px, 605px);
   -moz-margin-start: 0;
 }
 
-toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button[chromedir="rtl"]:hover:active:not([disabled]),
-toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button[open="true"][chromedir="rtl"] {
+toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button:-moz-locale-dir(rtl):hover:active:not([disabled]),
+toolbar[mode="icons"][iconsize="small"] #unified-back-forward-button > #forward-button[open="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(46px, 614px, 69px, 580px);
 }
 
 /* ----- SMALL BACK/FORWARD DROPMARKER ----- */	
 
 toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker {
   -moz-image-region: rect(0px, 648px, 23px, 638px);
 }
 
-toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker[chromedir="rtl"] {
+toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px, 580px, 23px, 571px);
 }
 
 toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker[disabled="true"] {
  -moz-image-region: rect(23px, 648px, 46px, 638px);
 }
 
-toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker[disabled="true"][chromedir="rtl"] {
+toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker[disabled="true"]:-moz-locale-dir(rtl) {
  -moz-image-region: rect(23px, 580px, 46px, 571px);
 }
 
 toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker:hover:active:not([disabled]),
 toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker[open="true"] {
   -moz-image-region: rect(46px, 648px, 69px, 638px);
 }
 
-toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker[chromedir="rtl"]:hover:active:not([disabled]),
-toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker[open="true"][chromedir="rtl"] {
+toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker:-moz-locale-dir(rtl):hover:active:not([disabled]),
+toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarker[open="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(46px, 580px, 69px, 571px);
 }
 
 /* ----- DEFAULT RELOAD BUTTON ----- */	
 
 #reload-button {
   -moz-image-region: rect(0px, 108px, 23px, 72px);
 }
@@ -1456,17 +1456,17 @@ sidebarheader > .tabs-closebutton > .too
 #wrapper-navigator-throbber > #navigator-throbber {
   list-style-image: url("chrome://global/skin/icons/notloading_16.png");
 }
 
 toolbarbutton.chevron {
   list-style-image: url("chrome://global/skin/icons/chevron.png") !important;
 }
 
-toolbarbutton.chevron[chromedir="rtl"] {
+toolbarbutton.chevron:-moz-locale-dir(rtl) {
   list-style-image: url("chrome://global/skin/icons/chevron-rtl.png") !important;
 }
 
 
 toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
@@ -1658,25 +1658,25 @@ tabbrowser > tabbox > tabpanels {
 .tabbrowser-arrowscrollbox > .scrollbutton-up,
 .tabbrowser-arrowscrollbox > .scrollbutton-down-stack > .scrollbutton-down {
   -moz-image-region: rect(0, 11px, 17px, 0);
   margin: 0;
   padding: 0 1px;
   border: none;
 }
 
-.tabbrowser-arrowscrollbox > .scrollbutton-up[chromedir="ltr"],
-.tabbrowser-arrowscrollbox > .scrollbutton-down-stack > .scrollbutton-down[chromedir="rtl"] {
+.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(ltr),
+.tabbrowser-arrowscrollbox > .scrollbutton-down-stack > .scrollbutton-down:-moz-locale-dir(rtl) {
   border-right: 2px solid;
   -moz-border-right-colors: rgba(0,0,0,0.25) rgba(255,255,255,0.15);
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
 }
 
-.tabbrowser-arrowscrollbox > .scrollbutton-down-stack > .scrollbutton-down[chromedir="ltr"],
-.tabbrowser-arrowscrollbox > .scrollbutton-up[chromedir="rtl"] {
+.tabbrowser-arrowscrollbox > .scrollbutton-down-stack > .scrollbutton-down:-moz-locale-dir(ltr),
+.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl) {
   border-left: 2px solid;
   -moz-border-left-colors: rgba(0,0,0,0.25) rgba(255,255,255,0.15);
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-right.png");
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-up:hover,
 .tabbrowser-arrowscrollbox > .scrollbutton-down-stack > .scrollbutton-down:hover {
   -moz-image-region: rect(0, 22px, 17px, 11px);
--- a/browser/themes/pinstripe/browser/places/organizer.css
+++ b/browser/themes/pinstripe/browser/places/organizer.css
@@ -91,37 +91,37 @@
 #back-button {
   -moz-image-region: rect(0px, 34px, 23px, 0px);
   -moz-margin-end: 0;
   -moz-padding-end: 0;
   border-left: none;
   border-right: none;
 }
 
-#back-button[chromedir="rtl"] {
+#back-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px, 67px, 23px, 34px);
 }
 
 #back-button[disabled="true"] {
  -moz-image-region: rect(23px, 34px, 46px, 0px) !important;
 }
 
-#back-button[disabled="true"][chromedir="rtl"] {
+#back-button[disabled="true"]:-moz-locale-dir(rtl) {
  -moz-image-region: rect(23px, 67px, 46px, 34px) !important;
 }
 
 #back-button:hover:active,
 #back-button[buttondown="true"],
 #back-button[open="true"] {
   -moz-image-region: rect(46px, 34px, 69px, 0px);
 }
 
-#back-button:hover:active[chromedir="rtl"],
-#back-button[buttondown="true"][chromedir="rtl"],
-#back-button[open="true"][chromedir="rtl"] {
+#back-button:hover:active:-moz-locale-dir(rtl),
+#back-button[buttondown="true"]:-moz-locale-dir(rtl),
+#back-button[open="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(46px, 67px, 69px, 34px);
 }
 
 #back-button > .toolbarbutton-text,
 #forward-button > .toolbarbutton-text {
   display: none;
 }
 
@@ -131,53 +131,53 @@
   -moz-image-region: rect(0px, 67px, 23px, 34px);
   -moz-margin-start: 0;
   -moz-margin-end: 8px;
   -moz-padding-start: 0;
   border-left: none;
   border-right: none;
 }
 
-#forward-button[chromedir="rtl"] {
+#forward-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px, 34px, 23px, 0px);
 }
 
 #forward-button[disabled="true"] {
   -moz-image-region: rect(23px, 67px, 46px, 34px) !important;
 }
 
-#forward-button[disabled="true"][chromedir="rtl"] {
+#forward-button[disabled="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(23px, 34px, 46px, 0px) !important;
 }
 
 #forward-button:hover:active,
 #forward-button[buttondown="true"],
 #forward-button[open="true"] {
   -moz-image-region: rect(46px, 67px, 69px, 34px);
 }
 
-#forward-button:hover:active[chromedir="rtl"],
-#forward-button[buttondown="true"][chromedir="rtl"],
-#forward-button[open="true"][chromedir="rtl"] {
+#forward-button:hover:active:-moz-locale-dir(rtl),
+#forward-button[buttondown="true"]:-moz-locale-dir(rtl),
+#forward-button[open="true"]:-moz-locale-dir(rtl) {
   -moz-image-region: rect(46px, 34px, 69px, 0px);
 }
 
 #placesToolbar > toolbarbutton[type="menu"] {
   -moz-margin-start: 5px;
   -moz-padding-end: 10px;
   background: url("chrome://browser/skin/places/menubutton-end.png") right center no-repeat;
 }
 #placesToolbar > toolbarbutton[type="menu"][open="true"] {
   background: url("chrome://browser/skin/places/menubutton-end-pressed.png") right center no-repeat;
 }
 
-#placesToolbar[chromedir="rtl"] > toolbarbutton[type="menu"] {
+#placesToolbar:-moz-locale-dir(rtl) > toolbarbutton[type="menu"] {
   background: url("chrome://browser/skin/places/menubutton-end-rtl.png") left center no-repeat;
 }
-#placesToolbar[chromedir="rtl"] > toolbarbutton[type="menu"][open="true"] {
+#placesToolbar:-moz-locale-dir(rtl) > toolbarbutton[type="menu"][open="true"] {
   background: url("chrome://browser/skin/places/menubutton-end-pressed-rtl.png") left center no-repeat;
 }
 
 #placesToolbar > toolbarbutton[type="menu"] > menupopup {
   -moz-margin-start: 2px;
   margin-top: -4px;
 }
 
@@ -187,20 +187,20 @@
   -moz-padding-start: 10px;
   -moz-padding-end: 4px;
   height: 23px;
 }
 #placesToolbar > toolbarbutton[type="menu"][open="true"] > .toolbarbutton-icon {
   background: url("chrome://browser/skin/places/menubutton-start-pressed.png") left center no-repeat;
 }
 
-#placesToolbar[chromedir="rtl"] > toolbarbutton[type="menu"] > .toolbarbutton-icon {
+#placesToolbar:-moz-locale-dir(rtl) > toolbarbutton[type="menu"] > .toolbarbutton-icon {
   background: url("chrome://browser/skin/places/menubutton-start-rtl.png") right center no-repeat;
 }
-#placesToolbar[chromedir="rtl"] > toolbarbutton[type="menu"][open="true"] > .toolbarbutton-icon {
+#placesToolbar:-moz-locale-dir(rtl) > toolbarbutton[type="menu"][open="true"] > .toolbarbutton-icon {
   background: url("chrome://browser/skin/places/menubutton-start-pressed-rtl.png") right center no-repeat;
 }
 
 #placesToolbar > toolbarbutton[type="menu"] > .toolbarbutton-text {
   display:  none;
 }
 
 #placesToolbar > toolbarbutton[type="menu"] > .toolbarbutton-menu-dropmarker {
--- a/browser/themes/pinstripe/browser/searchbar.css
+++ b/browser/themes/pinstripe/browser/searchbar.css
@@ -40,63 +40,63 @@
   min-width: 45px;
   border: 0;
   -moz-box-align: center;
   margin: 0;
   -moz-margin-start: -45px;
   padding: 0;
 }
 
-.searchbar-engine-button[chromedir="rtl"] {
+.searchbar-engine-button:-moz-locale-dir(rtl) {
   background-image: url("chrome://browser/skin/urlbar/startcap-rtl.png");
 }
 
 .searchbar-textbox[focused="true"] > .searchbar-engine-button {
   background-image: url("chrome://browser/skin/urlbar/startcap-focused.png");
 }
 
-.searchbar-textbox[focused="true"] > .searchbar-engine-button[chromedir="rtl"] {
+.searchbar-textbox[focused="true"] > .searchbar-engine-button:-moz-locale-dir(rtl) {
   background-image: url("chrome://browser/skin/urlbar/startcap-focused-rtl.png");
 }
 
 .searchbar-textbox[focused="true"] > .searchbar-engine-button:-moz-system-metric(mac-graphite-theme) {
   background-image: url("chrome://browser/skin/urlbar/startcap-focused-graphite.png");
 }
 
-.searchbar-textbox[focused="true"] > .searchbar-engine-button[chromedir="rtl"]:-moz-system-metric(mac-graphite-theme) {
+.searchbar-textbox[focused="true"] > .searchbar-engine-button:-moz-locale-dir(rtl):-moz-system-metric(mac-graphite-theme) {
   background-image: url("chrome://browser/skin/urlbar/startcap-focused-graphite-rtl.png");
 }
 
 .searchbar-engine-button:hover:active,
 .searchbar-engine-button[open="true"] {
   background-image: url("chrome://browser/skin/urlbar/startcap-active.png") !important;
 }
 
-.searchbar-engine-button:hover:active[chromedir="rtl"],
-.searchbar-engine-button[open="true"][chromedir="rtl"] {
+.searchbar-engine-button:hover:active:-moz-locale-dir(rtl),
+.searchbar-engine-button[open="true"]:-moz-locale-dir(rtl) {
   background-image: url("chrome://browser/skin/urlbar/startcap-active-rtl.png") !important;
 }
 
 .searchbar-textbox[focused="true"] > .searchbar-engine-button:active,
 .searchbar-textbox[focused="true"] > .searchbar-engine-button[open="true"] {
   background-image: url("chrome://browser/skin/urlbar/startcap-active-focused.png") !important;
 }
 
-.searchbar-textbox[focused="true"] > .searchbar-engine-button[chromedir="rtl"]:active,
-.searchbar-textbox[focused="true"] > .searchbar-engine-button[open="true"][chromedir="rtl"] {
+.searchbar-textbox[focused="true"] > .searchbar-engine-button:-moz-locale-dir(rtl):active,
+.searchbar-textbox[focused="true"] > .searchbar-engine-button[open="true"]:-moz-locale-dir(rtl) {
   background-image: url("chrome://browser/skin/urlbar/startcap-active-focused-rtl.png") !important;
 }
 
 .searchbar-textbox[focused="true"] > .searchbar-engine-button:active:-moz-system-metric(mac-graphite-theme),
 .searchbar-textbox[focused="true"] > .searchbar-engine-button[open="true"]:-moz-system-metric(mac-graphite-theme) {
   background-image: url("chrome://browser/skin/urlbar/startcap-active-focused-graphite.png") !important;
 }
 
-.searchbar-textbox[focused="true"] > .searchbar-engine-button[chromedir="rtl"]:active:-moz-system-metric(mac-graphite-theme),
-.searchbar-textbox[focused="true"] > .searchbar-engine-button[open="true"][chromedir="rtl"]:-moz-system-metric(mac-graphite-theme) {
+.searchbar-textbox[focused="true"] > .searchbar-engine-button:-moz-locale-dir(rtl):active:-moz-system-metric(mac-graphite-theme),
+.searchbar-textbox[focused="true"] > .searchbar-engine-button[open="true"]:-moz-locale-dir(rtl):-moz-system-metric(mac-graphite-theme) {
   background-image: url("chrome://browser/skin/urlbar/startcap-active-focused-graphite-rtl.png") !important;
 }
 
 .searchbar-engine-button > .button-box {
   -moz-appearance: none;
   padding: 0;
   -moz-padding-end: 3px;
   border: 0;
@@ -113,33 +113,33 @@
 }
 
 .search-go-container {
   -moz-box-align: center;
   background: url("chrome://browser/skin/urlbar/endcap.png") no-repeat right top;
   -moz-padding-end: 5px;
 }
 
-.search-go-container[chromedir="rtl"] {
+.search-go-container:-moz-locale-dir(rtl) {
   background-image: url("chrome://browser/skin/urlbar/endcap-rtl.png");
 }
 
 .searchbar-textbox[focused="true"] > .search-go-container {
   background-image: url("chrome://browser/skin/urlbar/endcap-focused.png");
 }
 
-.searchbar-textbox[focused="true"] > .search-go-container[chromedir="rtl"] {
+.searchbar-textbox[focused="true"] > .search-go-container:-moz-locale-dir(rtl) {
   background: url("chrome://browser/skin/urlbar/endcap-focused-rtl.png") no-repeat left top;
 }
 
 .searchbar-textbox[focused="true"] > .search-go-container:-moz-system-metric(mac-graphite-theme) {
   background-image: url("chrome://browser/skin/urlbar/endcap-focused-graphite.png");
 }
 
-.searchbar-textbox[focused="true"] > .search-go-container[chromedir="rtl"]:-moz-system-metric(mac-graphite-theme) {
+.searchbar-textbox[focused="true"] > .search-go-container:-moz-locale-dir(rtl):-moz-system-metric(mac-graphite-theme) {
   background-image: url("chrome://browser/skin/urlbar/endcap-focused-graphite-rtl.png");
 }
 
 .search-go-button {
   padding: 1px;
   list-style-image: url("chrome://browser/skin/Search.png");
   margin: 0;
   padding: 0;
--- a/browser/themes/winstripe/browser/browser-aero.css
+++ b/browser/themes/winstripe/browser/browser-aero.css
@@ -13,30 +13,30 @@
 /* ::::: Location Bar AutoComplete Styling ::::: */
 
 .ac-url-text:-moz-system-metric(windows-default-theme) {
   color: -moz-nativehyperlinktext;
 }
 
 /* ::::: Identity Indicator Styling ::::: */
 
-#urlbar[chromedir="ltr"]:-moz-system-metric(windows-default-theme) {
+#urlbar:-moz-locale-dir(ltr):-moz-system-metric(windows-default-theme) {
   -moz-margin-start: 9px;
 }
 
-#identity-box[chromedir="ltr"]:-moz-system-metric(windows-default-theme) {
+#identity-box:-moz-locale-dir(ltr):-moz-system-metric(windows-default-theme) {
   -moz-margin-start: -7px;
 }
 
-#identity-box[chromedir="ltr"]:-moz-system-metric(windows-default-theme) {
+#identity-box:-moz-locale-dir(ltr):-moz-system-metric(windows-default-theme) {
   -moz-border-radius: 11px 0 2px 11px / 15px 0 2px 15px;
 }
 
-/* Match #identity-box[chromedir="ltr"]'s -moz-margin-start */
-#identity-popup[chromedir="ltr"]:-moz-system-metric(windows-default-theme) {
+/* Match #identity-box:-moz-locale-dir(ltr)'s -moz-margin-start */
+#identity-popup:-moz-locale-dir(ltr):-moz-system-metric(windows-default-theme) {
   -moz-margin-start: 7px;
 }
 
 /* Bug 413060, comment 16: Vista Aero is a special case where we use a
    tooltip appearance for the address bar popup panels */
 #identity-popup:-moz-system-metric(windows-default-theme),
 #editBookmarkPanel:-moz-system-metric(windows-default-theme) {
   -moz-appearance: tooltip;
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -243,26 +243,26 @@ toolbar[iconsize="large"][mode="icons"] 
   -moz-image-region: rect(68px 396px 102px 360px);
 }
 toolbar[iconsize="large"][mode="icons"] #back-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(102px 396px 136px 360px);
 }
 
 /* unified back button with keyhole icons, RTL version */
 
-toolbar[iconsize="large"][mode="icons"] #back-button[chromedir="rtl"] {
+toolbar[iconsize="large"][mode="icons"] #back-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px 516px 34px 480px);
 }
-toolbar[iconsize="large"][mode="icons"] #back-button[chromedir="rtl"]:not([disabled="true"]):hover {
+toolbar[iconsize="large"][mode="icons"] #back-button:-moz-locale-dir(rtl):not([disabled="true"]):hover {
   -moz-image-region: rect(34px 516px 68px 480px);
 }
-toolbar[iconsize="large"][mode="icons"] #back-button[chromedir="rtl"][disabled="true"] {
+toolbar[iconsize="large"][mode="icons"] #back-button:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(68px 516px 102px 480px);
 }
-toolbar[iconsize="large"][mode="icons"] #back-button[chromedir="rtl"]:not([disabled="true"]):hover:active {
+toolbar[iconsize="large"][mode="icons"] #back-button:-moz-locale-dir(rtl):not([disabled="true"]):hover:active {
   -moz-image-region: rect(102px 516px 136px 480px);
 }
 
 /* unified forward button with keyhole icons */
 
 toolbar[mode="icons"] #forward-button {
   -moz-appearance: none;
   padding: 0;
@@ -279,26 +279,26 @@ toolbar[iconsize="large"][mode="icons"] 
   -moz-image-region: rect(71px 422px 99px 396px);
 }
 toolbar[iconsize="large"][mode="icons"] #forward-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(105px 422px 133px 396px);
 }
 
 /* unified forward button with keyhole icons, RTL version */
 
-toolbar[iconsize="large"][mode="icons"] #forward-button[chromedir="rtl"] {
+toolbar[iconsize="large"][mode="icons"] #forward-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(3px 480px 31px 454px);
 }
-toolbar[iconsize="large"][mode="icons"] #forward-button[chromedir="rtl"]:not([disabled="true"]):hover {
+toolbar[iconsize="large"][mode="icons"] #forward-button:-moz-locale-dir(rtl):not([disabled="true"]):hover {
   -moz-image-region: rect(37px 480px 65px 454px);
 }
-toolbar[iconsize="large"][mode="icons"] #forward-button[chromedir="rtl"][disabled="true"] {
+toolbar[iconsize="large"][mode="icons"] #forward-button:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(71px 480px 99px 454px);
 }
-toolbar[iconsize="large"][mode="icons"] #forward-button[chromedir="rtl"]:not([disabled="true"]):hover:active {
+toolbar[iconsize="large"][mode="icons"] #forward-button:-moz-locale-dir(rtl):not([disabled="true"]):hover:active {
   -moz-image-region: rect(105px 480px 133px 454px);
 }
 
 /* dropmarker for unified back and forward buttons with keyhole icons */
 
 toolbar[mode="icons"] #back-forward-dropmarker {
   -moz-appearance: none;
   padding: 0;
@@ -326,26 +326,26 @@ toolbar[iconsize="large"][mode="icons"] 
   -moz-image-region: rect(71px 438px 99px 422px);
 }
 toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker:not([disabled="true"]):hover:active {
   -moz-image-region: rect(105px 438px 133px 422px);
 }
 
 /* unified dropmarker with keyhole icons, RTL version */
 
-toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker[chromedir="rtl"] {
+toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker:-moz-locale-dir(rtl) {
   -moz-image-region: rect(3px 454px 31px 438px);
 }
-toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker[chromedir="rtl"]:not([disabled="true"]):hover {
+toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker:-moz-locale-dir(rtl):not([disabled="true"]):hover {
   -moz-image-region: rect(37px 454px 65px 438px);
 }
-toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker[chromedir="rtl"][disabled="true"] {
+toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(71px 454px 99px 438px);
 }
-toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker[chromedir="rtl"]:not([disabled="true"]):hover:active {
+toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker:-moz-locale-dir(rtl):not([disabled="true"]):hover:active {
   -moz-image-region: rect(105px 454px 133px 438px);
 }
 
 /* ::::: unified back and forward buttons, small icons mode ::::: */
 
 toolbar[iconsize="small"][mode="icons"] #back-button > .toolbarbutton-icon,
 toolbar[iconsize="small"][mode="icons"] #forward-button > .toolbarbutton-icon {
   -moz-padding-end: 0;
@@ -363,26 +363,26 @@ toolbar[iconsize="small"][mode="icons"] 
   -moz-image-region: rect(48px 264px 72px 240px);
 }
 toolbar[iconsize="small"][mode="icons"] #back-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(72px 264px 96px 240px);
 }
 
 /* unified back button with keyhole icons, small icons mode, RTL version */
 
-toolbar[iconsize="small"][mode="icons"] #back-button[chromedir="rtl"] {
+toolbar[iconsize="small"][mode="icons"] #back-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px 362px 24px 338px);
 }
-toolbar[iconsize="small"][mode="icons"] #back-button[chromedir="rtl"]:not([disabled="true"]):hover {
+toolbar[iconsize="small"][mode="icons"] #back-button:-moz-locale-dir(rtl):not([disabled="true"]):hover {
   -moz-image-region: rect(24px 362px 48px 338px);
 }
-toolbar[iconsize="small"][mode="icons"] #back-button[chromedir="rtl"][disabled="true"] {
+toolbar[iconsize="small"][mode="icons"] #back-button:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(48px 362px 72px 338px);
 }
-toolbar[iconsize="small"][mode="icons"] #back-button[chromedir="rtl"]:not([disabled="true"]):hover:active {
+toolbar[iconsize="small"][mode="icons"] #back-button:-moz-locale-dir(rtl):not([disabled="true"]):hover:active {
   -moz-image-region: rect(72px 362px 96px 338px);
 }
 
 /* unified forward button with keyhole icons, small icons mode */
 
 toolbar[iconsize="small"][mode="icons"] #forward-button {
   -moz-image-region: rect(0px 288px 24px 264px);
 }
@@ -393,26 +393,26 @@ toolbar[iconsize="small"][mode="icons"] 
   -moz-image-region: rect(48px 288px 72px 264px);
 }
 toolbar[iconsize="small"][mode="icons"] #forward-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(72px 288px 96px 264px);
 }
 
 /* unified forward button with keyhole icons, small icons mode, RTL version */
 
-toolbar[iconsize="small"][mode="icons"] #forward-button[chromedir="rtl"] {
+toolbar[iconsize="small"][mode="icons"] #forward-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px 338px 24px 314px);
 }
-toolbar[iconsize="small"][mode="icons"] #forward-button[chromedir="rtl"]:not([disabled="true"]):hover {
+toolbar[iconsize="small"][mode="icons"] #forward-button:-moz-locale-dir(rtl):not([disabled="true"]):hover {
   -moz-image-region: rect(24px 338px 48px 314px);
 }
-toolbar[iconsize="small"][mode="icons"] #forward-button[chromedir="rtl"][disabled="true"] {
+toolbar[iconsize="small"][mode="icons"] #forward-button:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(48px 338px 72px 314px);
 }
-toolbar[iconsize="small"][mode="icons"] #forward-button[chromedir="rtl"]:not([disabled="true"]):hover:active {
+toolbar[iconsize="small"][mode="icons"] #forward-button:-moz-locale-dir(rtl):not([disabled="true"]):hover:active {
   -moz-image-region: rect(72px 338px 96px 314px);
 }
 
 /* dropmarker for unified back and forward buttons with keyhole icons, small icons mode */
 
 toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker {
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
   -moz-image-region: rect(0px 301px 24px 288px);
@@ -424,26 +424,26 @@ toolbar[iconsize="small"][mode="icons"] 
   -moz-image-region: rect(48px 301px 72px 288px);
 }
 toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker:not([disabled="true"]):hover:active {
   -moz-image-region: rect(72px 301px 96px 288px);
 }
 
 /* unified dropmarker with keyhole icons, small icons mode, RTL version */
 
-toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker[chromedir="rtl"] {
+toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px 314px 24px 301px);
 }
-toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker[chromedir="rtl"]:not([disabled="true"]):hover {
+toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker:-moz-locale-dir(rtl):not([disabled="true"]):hover {
   -moz-image-region: rect(24px 314px 48px 301px);
 }
-toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker[chromedir="rtl"][disabled="true"] {
+toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(48px 314px 72px 301px);
 }
-toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker[chromedir="rtl"]:not([disabled="true"]):hover:active {
+toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker:-moz-locale-dir(rtl):not([disabled="true"]):hover:active {
   -moz-image-region: rect(72px 314px 96px 301px);
 }
 
 /* ::::: 24px primary toolbar buttons ::::: */
 
 /* back button */
 
 #back-button {
@@ -455,27 +455,27 @@ toolbar[iconsize="small"][mode="icons"] 
 }
 #back-button[disabled="true"] {
   -moz-image-region: rect(48px 24px 72px 0px);
 }
 #back-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(96px 24px 120px 0px);
 }
 
-#back-button[chromedir="rtl"] {
+#back-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px 48px 24px 24px);
 }
-#back-button[chromedir="rtl"]:not([disabled="true"]):hover,
-#back-button[chromedir="rtl"][buttonover="true"] {
+#back-button:-moz-locale-dir(rtl):not([disabled="true"]):hover,
+#back-button:-moz-locale-dir(rtl)[buttonover="true"] {
   -moz-image-region: rect(24px 48px 48px 24px);
 }
-#back-button[chromedir="rtl"][disabled="true"] {
+#back-button:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(48px 48px 72px 24px);
 }
-#back-button[chromedir="rtl"]:not([disabled="true"]):hover:active {
+#back-button:-moz-locale-dir(rtl):not([disabled="true"]):hover:active {
   -moz-image-region: rect(96px 48px 120px 24px);
 }
 
 /* forward button */
 
 #forward-button {
   -moz-image-region: rect(0px 48px 24px 24px);
 }
@@ -485,27 +485,27 @@ toolbar[iconsize="small"][mode="icons"] 
 }
 #forward-button[disabled="true"] {
   -moz-image-region: rect(48px 48px 72px 24px);
 }
 #forward-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(96px 48px 120px 24px);
 }
 
-#forward-button[chromedir="rtl"] {
+#forward-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px 24px 24px 0px); 
 }
-#forward-button[chromedir="rtl"]:not([disabled="true"]):hover,
-#forward-button[chromedir="rtl"][buttonover="true"] {
+#forward-button:-moz-locale-dir(rtl):not([disabled="true"]):hover,
+#forward-button:-moz-locale-dir(rtl)[buttonover="true"] {
   -moz-image-region: rect(24px 24px 48px 0px);
 }
-#forward-button[chromedir="rtl"][disabled="true"] {
+#forward-button:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(48px 24px 72px 0px);
 }
-#forward-button[chromedir="rtl"]:not([disabled="true"]):hover:active {
+#forward-button:-moz-locale-dir(rtl):not([disabled="true"]):hover:active {
   -moz-image-region: rect(96px 24px 120px 0px);
 }
 
 /* stop button */
 
 #stop-button {
   -moz-image-region: rect(0px 72px 24px 48px);
 }
@@ -691,16 +691,28 @@ toolbar:not([iconsize="small"]) #new-win
 }
 #paste-button[disabled="true"] {
   -moz-image-region: rect(48px 336px 72px 312px);
 }
 #paste-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(96px 336px 120px 312px);
 }
 
+/* fullscreen button */
+
+#fullscreen-button {
+  -moz-image-region: rect(0px 360px 24px 336px);
+}
+#fullscreen-button:hover {
+  -moz-image-region: rect(24px 360px 48px 336px);
+}
+#fullscreen-button:hover:active {
+  -moz-image-region: rect(96px 360px 120px 336px);
+}
+
 /* ::::: 16px primary toolbar buttons ::::: */
 
 toolbar[iconsize="small"] .toolbarbutton-1 {
   -moz-box-orient: vertical;
   min-width: 0;
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
 }
 
@@ -722,31 +734,31 @@ toolbar[iconsize="small"] #back-button[b
 }
 toolbar[iconsize="small"] #back-button[disabled="true"] {
   -moz-image-region: rect(32px 16px 48px 0px);
 }
 toolbar[iconsize="small"] #back-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 16px 80px 0px);
 }
 
-toolbar[iconsize="small"] #back-button[chromedir="rtl"] {
+toolbar[iconsize="small"] #back-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px 32px 16px 16px);
 }
-toolbar[iconsize="small"] #back-button[chromedir="rtl"]:not([disabled="true"]):hover,
-toolbar[iconsize="small"] #back-button[chromedir="rtl"][buttonover="true"] {
+toolbar[iconsize="small"] #back-button:-moz-locale-dir(rtl):not([disabled="true"]):hover,
+toolbar[iconsize="small"] #back-button:-moz-locale-dir(rtl)[buttonover="true"] {
   -moz-image-region: rect(16px 32px 32px 16px);
 }
-toolbar[iconsize="small"] #back-button[chromedir="rtl"][disabled="true"] {
+toolbar[iconsize="small"] #back-button:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(32px 32px 48px 16px);
 }
-toolbar[iconsize="small"] #back-button[chromedir="rtl"]:not([disabled="true"]):hover:active {
+toolbar[iconsize="small"] #back-button:-moz-locale-dir(rtl):not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 32px 80px 16px);
 }
 .unified-nav-back[_moz-menuactive],
-menupopup[chromedir="rtl"] > .unified-nav-forward[_moz-menuactive] {
+menupopup:-moz-locale-dir(rtl) > .unified-nav-forward[_moz-menuactive] {
   list-style-image: url("chrome://browser/skin/menu-back.png") !important;
 }
 
 /* forward button */
 
 toolbar[iconsize="small"] #forward-button > .toolbarbutton-icon {
   -moz-padding-end: 1px;
 }
@@ -759,31 +771,31 @@ toolbar[iconsize="small"] #forward-butto
 }
 toolbar[iconsize="small"] #forward-button[disabled="true"] {
   -moz-image-region: rect(32px 32px 48px 16px);
 }
 toolbar[iconsize="small"] #forward-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 32px 80px 16px);
 }
 
-toolbar[iconsize="small"] #forward-button[chromedir="rtl"] {
+toolbar[iconsize="small"] #forward-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px 16px 16px 0px);
 }
-toolbar[iconsize="small"] #forward-button[chromedir="rtl"]:not([disabled="true"]):hover,
-toolbar[iconsize="small"] #forward-button[chromedir="rtl"][buttonover="true"] {
+toolbar[iconsize="small"] #forward-button:-moz-locale-dir(rtl):not([disabled="true"]):hover,
+toolbar[iconsize="small"] #forward-button:-moz-locale-dir(rtl)[buttonover="true"] {
   -moz-image-region: rect(16px 16px 32px 0px);
 }
-toolbar[iconsize="small"] #forward-button[chromedir="rtl"][disabled="true"] {
+toolbar[iconsize="small"] #forward-button:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(32px 16px 48px 0px);
 }
-toolbar[iconsize="small"] #forward-button[chromedir="rtl"]:not([disabled="true"]):hover:active {
+toolbar[iconsize="small"] #forward-button:-moz-locale-dir(rtl):not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 16px 80px 0px);
 }
 .unified-nav-forward[_moz-menuactive],
-menupopup[chromedir="rtl"] > .unified-nav-back[_moz-menuactive] {
+menupopup:-moz-locale-dir(rtl) > .unified-nav-back[_moz-menuactive] {
   list-style-image: url("chrome://browser/skin/menu-forward.png") !important;
 }
 
 /* stop button */
 
 toolbar[iconsize="small"] #stop-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
@@ -1003,16 +1015,31 @@ toolbar[iconsize="small"] #paste-button:
 }
 toolbar[iconsize="small"] #paste-button[disabled="true"] {
   -moz-image-region: rect(32px 224px 48px 208px);
 }
 toolbar[iconsize="small"] #paste-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 224px 80px 208px);
 }
 
+/* fullscreen button */
+
+toolbar[iconsize="small"] #fullscreen-button > .toolbarbutton-icon {
+  padding-left: 1px;
+}
+toolbar[iconsize="small"] #fullscreen-button {
+  -moz-image-region: rect(0px 240px 16px 224px);
+}
+toolbar[iconsize="small"] #fullscreen-button:hover {
+  -moz-image-region: rect(16px 240px 32px 224px);
+}
+toolbar[iconsize="small"] #fullscreen-button:hover:active {
+  -moz-image-region: rect(64px 240px 80px 224px);
+}
+
 /* ::::: fullscreen window controls ::::: */
 
 #minimize-button,
 #restore-button,
 #close-button {
   list-style-image: url("chrome://global/skin/icons/windowControls.png");
   padding: 0;
 }
@@ -1096,17 +1123,17 @@ toolbar[iconsize="small"] #paste-button:
 #urlbar .autocomplete-textbox-container {
   direction: ltr;
 }
 
 #PopupAutoComplete {
   direction: ltr !important;
 }
 
-#PopupAutoComplete[chromedir="rtl"] > tree > treerows {
+#PopupAutoComplete:-moz-locale-dir(rtl) > tree > treerows {
   direction: rtl;
 }
 
 #PopupAutoComplete .autocomplete-treebody {
   direction: ltr;
 }
 
 #PopupAutoCompleteRichResult {
@@ -1503,17 +1530,17 @@ tabpanels {
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-up {
   border-left-style: none;
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
   -moz-border-radius-topright: 2px;
 }
 
-.tabbrowser-arrowscrollbox > .scrollbutton-up[chromedir="rtl"] {
+.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl) {
   border-left-style: solid;
   border-right-style: none;
   -moz-border-radius-topleft: 2px;
   -moz-border-radius-topright: 0px;
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-right.png");
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-down,
@@ -1522,26 +1549,26 @@ tabpanels {
   border-right-style: none;
   -moz-border-radius-topleft: 2px;
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-down {
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-right.png");
 }
 
-.tabbrowser-arrowscrollbox > .scrollbutton-down[chromedir="rtl"],
-.tabs-container > .tabs-newtab-button[chromedir="rtl"],
-.tabs-container > stack[chromedir="rtl"] > .tabs-alltabs-button {
+.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(rtl),
+.tabs-container > .tabs-newtab-button:-moz-locale-dir(rtl),
+.tabs-container > stack:-moz-locale-dir(rtl) > .tabs-alltabs-button {
   border-left-style: none;
   border-right-style: solid;
   -moz-border-radius-topleft: 0px;
   -moz-border-radius-topright: 2px;
 }
 
-.tabbrowser-arrowscrollbox > .scrollbutton-down[chromedir="rtl"] {
+.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(rtl) {
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
 }
 
 .tabs-newtab-button {
   list-style-image: url(chrome://browser/skin/tabbrowser/newtab.png);
   -moz-image-region: rect(0, 18px, 18px, 0);
 }
 
@@ -1587,17 +1614,17 @@ tabpanels {
   margin-top: 2px;
   margin-bottom: 4px;
   width: 18px !important;
   background-image: url("chrome://browser/skin/tabbrowser/alltabs-box-overflow-end-bkgnd-animate.png");
   background-repeat: no-repeat;
   opacity: 0.0;
 }
 
-stack[chromedir="rtl"] > hbox > .tabs-alltabs-box-animate {
+stack:-moz-locale-dir(rtl) > hbox > .tabs-alltabs-box-animate {
   background-image: url("chrome://browser/skin/tabbrowser/alltabs-box-overflow-start-bkgnd-animate.png");
 }
 
 /* All tabs menupopup */
 .alltabs-item > .menu-iconic-left > .menu-iconic-icon {
   list-style-image: url("chrome://global/skin/icons/folder-item.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
@@ -1638,34 +1665,34 @@ stack[chromedir="rtl"] > hbox > .tabs-al
   margin: 3px 0px 3px;
   padding: 4px 2px 2px;
   background: -moz-dialog url("chrome://browser/skin/tabbrowser/tab-active-bkgnd.png") repeat-x;
   border-left: 1px solid threedshadow;
   border-top: 1px solid threedshadow;
   -moz-border-radius-topleft: 2px;
 }
 
-.tabs-container > .tabs-closebutton[chromedir="rtl"] {
+.tabs-container > .tabs-closebutton:-moz-locale-dir(rtl) {
   border-left: none;
   border-right: 1px solid threedshadow;
   -moz-border-radius-topleft: 0px;
   -moz-border-radius-topright: 2px;
 }
 
 #sidebar-box .tabs-closebutton {
   list-style-image: url("chrome://global/skin/icons/closeSidebar.png");
   margin-bottom: 0px !important;
   padding: 0px 2px 0px 2px !important;
 }
 
 toolbarbutton.chevron {
   list-style-image: url("chrome://global/skin/toolbar/chevron.gif") !important;
 }
 
-toolbarbutton.chevron[chromedir="rtl"] {
+toolbarbutton.chevron:-moz-locale-dir(rtl) {
   list-style-image: url("chrome://global/skin/toolbar/chevron-rtl.gif") !important;
 }
 
 toolbarbutton.chevron > .toolbarbutton-text,
 toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
@@ -1707,23 +1734,23 @@ toolbar[mode="text"] > #window-controls 
 }
 
 #urlbar > .autocomplete-history-dropmarker:hover:active,
 #urlbar > .autocomplete-history-dropmarker[open="true"] {
   background-position: 0 -120px !important;
   -moz-image-region: rect(0, 26px, 11px, 13px);
 }
 
-#urlbar[chromedir="ltr"] > .autocomplete-history-dropmarker {
+#urlbar:-moz-locale-dir(ltr) > .autocomplete-history-dropmarker {
   border-left: 1px solid;
   -moz-border-left-colors: transparent;
 }
 
-#urlbar[chromedir="ltr"] > .autocomplete-history-dropmarker:hover ,
-#urlbar[chromedir="ltr"] > .autocomplete-history-dropmarker[open="true"] {
+#urlbar:-moz-locale-dir(ltr) > .autocomplete-history-dropmarker:hover ,
+#urlbar:-moz-locale-dir(ltr) > .autocomplete-history-dropmarker[open="true"] {
   -moz-border-left-colors: ButtonShadow;
 }
 
 /* Feed icon */
 #feed-button,
 #feed-button > .button-box,
 #feed-button:hover:active > .button-box {
   padding: 0px;
@@ -1797,36 +1824,36 @@ toolbarbutton.bookmark-item[dragover="tr
   height: 2px;
   -moz-margin-end: -4em;
   background-color: Highlight;
 }
 
 /* ::::: Identity Indicator Styling ::::: */
 /* Location bar visuals*/
 
-#urlbar[chromedir="ltr"]:-moz-system-metric(windows-default-theme) {
+#urlbar:-moz-locale-dir(ltr):-moz-system-metric(windows-default-theme) {
   -moz-margin-start: 6px;
 }
 
 #urlbar > .autocomplete-textbox-container {
   -moz-box-align: stretch;
 }
 
 #identity-box {
   background: -moz-dialog url(navbar-textbox-buttons.png) repeat-x;
   color: -moz-dialogText;
   border: 1px none ThreeDShadow;
   -moz-border-end-style: solid;
   -moz-box-shadow: 1px 1px 0 rgba(255,255,255,.3) inset,
                    0 -1px 0 rgba(255,255,255,.2) inset;
 }
-#identity-box[chromedir="rtl"] {
+#identity-box:-moz-locale-dir(ltr) {
   -moz-border-start-style: solid;
 }
-#identity-box[chromedir="ltr"]:-moz-system-metric(windows-default-theme) {
+#identity-box:-moz-locale-dir(ltr):-moz-system-metric(windows-default-theme) {
   -moz-border-radius: 6px 0 2px 6px / 15px 0 2px 15px;
   margin: -1px 0;
   -moz-margin-start: -4px;
   -moz-padding-start: 2px;
   border-style: solid;
   -moz-border-end-color: rgba(0,0,0,.05);
 }
 
@@ -1975,17 +2002,17 @@ toolbarbutton.bookmark-item[dragover="tr
 
 /* Popup Bounding Box */
 #identity-popup {
   -moz-appearance: menupopup;
   color: MenuText;
 }
 
 /* Bug 413060, comment 14: Match #identity-box's -moz-margin-start, less 1px */
-#identity-popup[chromedir="ltr"]:-moz-system-metric(windows-default-theme) {
+#identity-popup:-moz-locale-dir(ltr):-moz-system-metric(windows-default-theme) {
   -moz-margin-start: 3px;
 }
 
 #identity-popup-container {
   background-image: none;
   min-width: 280px;
   padding: 9px;
 }
--- a/browser/themes/winstripe/browser/places/organizer.css
+++ b/browser/themes/winstripe/browser/places/organizer.css
@@ -15,46 +15,46 @@
 
 #placesToolbar > toolbarbutton > image,
 #placesToolbar > toolbarbutton > label {
   margin: 0;
   padding: 0;
 }
 
 #back-button,
-#forward-button[chromedir="rtl"] {  
+#forward-button:-moz-locale-dir(rtl) {  
   -moz-image-region: rect(0px, 24px, 24px, 0px);
 }
 #back-button:not([disabled="true"]):hover,
-#forward-button:not([disabled="true"]):hover[chromedir="rtl"] {
+#forward-button:not([disabled="true"]):hover:-moz-locale-dir(rtl) {
   -moz-image-region: rect(24px, 24px, 48px, 0px);
 }
 #back-button[disabled="true"],
-#forward-button[chromedir="rtl"][disabled="true"] {
+#forward-button:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(48px, 24px, 72px, 0px) !important;
 }
 #back-button:not([disabled="true"]):hover:active,
-#forward-button:not([disabled="true"]):hover:active[chromedir="rtl"] {
+#forward-button:not([disabled="true"]):hover:active:-moz-locale-dir(rtl) {
   -moz-image-region: rect(72px, 24px, 96px, 0px);
 }
 
 #forward-button,
-#back-button[chromedir="rtl"] {
+#back-button:-moz-locale-dir(rtl) {
   -moz-image-region: rect(0px, 48px, 24px, 24px);
 }
 #forward-button:not([disabled="true"]):hover,
-#back-button:not([disabled="true"]):hover[chromedir="rtl"] {
+#back-button:not([disabled="true"]):hover:-moz-locale-dir(rtl) {
   -moz-image-region: rect(24px, 48px, 48px, 24px);
 }
 #forward-button[disabled="true"],
-#back-button[chromedir="rtl"][disabled="true"] {
+#back-button:-moz-locale-dir(rtl)[disabled="true"] {
   -moz-image-region: rect(48px, 48px, 72px, 24px) !important;
 }
 #forward-button:not([disabled="true"]):hover:active,
-#back-button:not([disabled="true"]):hover:active[chromedir="rtl"] {
+#back-button:not([disabled="true"]):hover:active:-moz-locale-dir(rtl) {
   -moz-image-region: rect(72px, 48px, 96px, 24px);
 }
 
 /* Menu */
 #placesMenu {
   -moz-margin-start: 8px;
   -moz-appearance: none;
   border: none;
@@ -89,17 +89,17 @@
   padding-bottom: 1px;
 }
 
 #placesMenu > menu > label {
   -moz-padding-end: 8px;
   background: url(chrome://global/skin/arrow/arrow-dn.gif) right center no-repeat;
 }
 
-#placesMenu[chromedir="rtl"] > menu > label {
+#placesMenu:-moz-locale-dir(rtl) > menu > label {
   background-position: left center;
 }
 
 /* organize button */
 #organizeButton {
   list-style-image: url("chrome://browser/skin/places/organize.png");
 }
 
--- a/browser/themes/winstripe/browser/searchbar.css
+++ b/browser/themes/winstripe/browser/searchbar.css
@@ -40,17 +40,17 @@
   border: 0 solid;
   -moz-border-end-width: 1px;
   -moz-border-right-colors: ThreeDShadow;
   -moz-border-left-colors: ThreeDShadow;
   -moz-box-shadow: 1px 1px 0 rgba(255,255,255,.4) inset,
                    0 -1px 0 rgba(255,255,255,.4) inset;
 }
 
-.searchbar-engine-button:-moz-system-metric(windows-default-theme)[chromedir="ltr"] {
+.searchbar-engine-button:-moz-system-metric(windows-default-theme):-moz-locale-dir(ltr) {
   -moz-border-right-colors: rgba(0,0,0,.05);
 }
 
 .searchbar-engine-button:hover {
   background-position: 0 -60px;
 }
 
 .searchbar-engine-button[open="true"] {
@@ -63,17 +63,17 @@
   padding: 0;
   border: 0;
 }
 
 .searchbar-engine-button[addengines="true"]:not([open="true"]) > .button-box {
   background: transparent url(chrome://browser/skin/Search-addengines.png) no-repeat right center;
 }
 
-.searchbar-engine-button[addengines="true"][chromedir="rtl"] > .button-box {
+.searchbar-engine-button[addengines="true"]:-moz-locale-dir(rtl) > .button-box {
   background-position: left center;
 }
 
 .searchbar-dropmarker-image {
   list-style-image: url(mainwindow-dropdown-arrow.png);
   -moz-image-region: rect(0, 13px, 11px, 0);
 }
 
@@ -89,17 +89,17 @@
 }
 
 .search-go-button {
   padding: 2px;
   list-style-image: url("chrome://global/skin/icons/Search-glass.png");
   -moz-image-region: rect(0px 16px 16px 0px);
 }
 
-.search-go-button[chromedir="rtl"] {
+.search-go-button:-moz-locale-dir(rtl) {
   -moz-transform: scaleX(-1);
 }
 
 .search-go-button:hover {
   -moz-image-region: rect(0px 32px 16px 16px);
 }
 
 .search-go-button:hover:active {
--- a/build/autoconf/nspr.m4
+++ b/build/autoconf/nspr.m4
@@ -1,15 +1,27 @@
 # -*- tab-width: 4; -*-
 # Configure paths for NSPR
 # Public domain - Chris Seawood <cls@seawood.org> 2001-04-05
 # Based upon gtk.m4 (also PD) by Owen Taylor
 
 dnl AM_PATH_NSPR([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
 dnl Test for NSPR, and define NSPR_CFLAGS and NSPR_LIBS
+dnl
+dnl If the nspr-config script is available, use it to find the
+dnl appropriate CFLAGS and LIBS, and to check for the required
+dnl version, and run ACTION-IF-FOUND.
+dnl
+dnl Otherwise, if NO_NSPR_CONFIG_SYSTEM_VERSION is set, we use it,
+dnl NO_NSPR_CONFIG_SYSTEM_CFLAGS, and NO_NSPR_CONFIG_SYSTEM_LIBS to
+dnl provide default values, and run ACTION-IF-FOUND.  (Some systems
+dnl ship NSPR without nspr-config, but can glean the appropriate flags
+dnl and version.)
+dnl
+dnl Otherwise, run ACTION-IF-NOT-FOUND.
 AC_DEFUN([AM_PATH_NSPR],
 [dnl
 
 AC_ARG_WITH(nspr-prefix,
 	[  --with-nspr-prefix=PFX  Prefix where NSPR is installed],
 	nspr_config_prefix="$withval",
 	nspr_config_prefix="")
 
@@ -33,27 +45,34 @@ AC_ARG_WITH(nspr-exec-prefix,
 	fi
 
 	unset ac_cv_path_NSPR_CONFIG
 	AC_PATH_PROG(NSPR_CONFIG, nspr-config, no)
 	min_nspr_version=ifelse([$1], ,4.0.0,$1)
 	AC_MSG_CHECKING(for NSPR - version >= $min_nspr_version)
 
 	no_nspr=""
-	if test "$NSPR_CONFIG" = "no"; then
-		no_nspr="yes"
-	else
+	if test "$NSPR_CONFIG" != "no"; then
 		NSPR_CFLAGS=`$NSPR_CONFIG $nspr_config_args --cflags`
 		NSPR_LIBS=`$NSPR_CONFIG $nspr_config_args --libs`
+		NSPR_VERSION_STRING=`$NSPR_CONFIG $nspr_config_args --version`	
+	elif test -n "${NO_NSPR_CONFIG_SYSTEM_VERSION}"; then
+	    NSPR_CFLAGS="${NO_NSPR_CONFIG_SYSTEM_CFLAGS}"
+		NSPR_LIBS="${NO_NSPR_CONFIG_SYSTEM_LDFLAGS}"
+		NSPR_VERSION_STRING="$NO_NSPR_CONFIG_SYSTEM_VERSION"
+	else
+	    no_nspr="yes"
+	fi
 
-		nspr_config_major_version=`$NSPR_CONFIG $nspr_config_args --version | \
+	if test -z "$no_nspr"; then
+		nspr_config_major_version=`echo $NSPR_VERSION_STRING | \
 			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
-		nspr_config_minor_version=`$NSPR_CONFIG $nspr_config_args --version | \
+		nspr_config_minor_version=`echo $NSPR_VERSION_STRING | \
 			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
-		nspr_config_micro_version=`$NSPR_CONFIG $nspr_config_args --version | \
+		nspr_config_micro_version=`echo $NSPR_VERSION_STRING | \
 			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
 		min_nspr_major_version=`echo $min_nspr_version | \
 			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
 		min_nspr_minor_version=`echo $min_nspr_version | \
 			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
 		min_nspr_micro_version=`echo $min_nspr_version | \
 			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
 		if test "$nspr_config_major_version" -ne "$min_nspr_major_version"; then
new file mode 100644
--- /dev/null
+++ b/build/pgo/certs/bug483440-attack2b.ca
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICKDCCAZGgAwIBAgIFAIyjFPowDQYJKoZIhvcNAQEFBQAwKDEXMBUGA1UEAwwO
+KgB3d3cubXlDQS5vcmcxDTALBgNVBAMTBG15Q0EwHhcNMDkwMzE0MTg0NzU2WhcN
+MTkwMzE0MTg0NzU2WjBhMRMwEQYDVQQKEwpCYWRndXkgSW5jMRcwFQYDVQQDEw53
+d3cuYmFkZ3V5LmNvbTEZMBcGA1UECxMQSGFja2luZyBEaXZpc2lvbjEWMBQGBFUE
+gAMTDHd3dy5iYW5rLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2YvL
+GgmF0OTLBKz0nYTvR+DlnZai7b2MqAIM9IUEpMfqzJPNYCsXziYXgHtr/do9ppJP
+BhDjeyIGEOSpgBqdkWItxlLopUHnf8VKwnDPPj4KkNyXuTLm60X/ph+/zrjTw+kU
+m+/kVYstgGMuTIoTuu7loxCqqeVlAgc5lzTpUhkCAwEAAaMlMCMwDAYDVR0TAQH/
+BAIwADATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQAKHl1G
+vaXftj5QPK3eIT6Q3fWuGKR39grlg5GL/WocPanYycOlm9zvT1Hx95cY6msIXSKp
+xycndJ02ODX35DDgolV6VHUsM9yoagk+eqs5kCqW2qiv3moIshL0yWVhuCobMA+E
+D3wHFCPqVU+igRdCrEQDxZHoFOR4J/DKHfGANg==
+-----END CERTIFICATE-----
new file mode 100644
--- /dev/null
+++ b/build/pgo/certs/bug483440-attack7.ca
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICljCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBkDERMA8GBPMlBAMTB2F0
+dGFjazcxEDAOBgOABAMTB2F0dGFjazYxEzARBgZVBP///38TB2F0dGFjazUxEjAQ
+BgVVBAOBgRMHYXR0YWNrNDEUMBIGB1UEgICAgIATB2F0dGFjazMxFDASBgdVBJCA
+gIABEwdhdHRhY2syMRQwEgYHVQSIgICAARMHYXR0YWNrMTAeFw0wOTA0MTMxNDAw
+MzdaFw0yOTA0MTMxNDAwMzdaMIGQMREwDwYE8yUEAxMHYXR0YWNrNzEQMA4GA4AE
+AxMHYXR0YWNrNjETMBEGBlUE////fxMHYXR0YWNrNTESMBAGBVUEA4GBEwdhdHRh
+Y2s0MRQwEgYHVQSAgICAgBMHYXR0YWNrMzEUMBIGB1UEkICAgAETB2F0dGFjazIx
+FDASBgdVBIiAgIABEwdhdHRhY2sxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQC77fQ1wrywBnVmr8XO0/78/qFOz+sjnMlpBvLx5UImittgMNSgEqNulRDbO0qG
+K4tlFF2sNsS7aOun6Cq7yl2+a8mIljmjzs+iwCLOEAkQTOM4RsdCosJVy/fjwmH1
+xI0uXt5cPkA0FM7B/IZSzWSC+2gY1+u1AhRJ35bXDhu92wIDAQABMA0GCSqGSIb3
+DQEBBQUAA4GBAFZitQjsQJ1+XsxKchBefilaHsi4oncc05P29IXcRbHI8wK2vNk8
+kkG2c6M4a4Rx1R4C3n99NwXH4vyNUbA9FuMSAdjaS3TW3zm8lKNCuIWGuI2Vvefy
++wNcCfb8B4AuP8pZOqqKsspgiBAE1EPPErnb7nMVLCnf+ts9ARXLBZTi
+-----END CERTIFICATE-----
new file mode 100644
--- /dev/null
+++ b/build/pgo/certs/bug483440-pk10oflo.ca
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICMTCCAZqgAwIBAgIFAIyjFTAwDQYJKoZIhvcNAQEFBQAwKDEXMBUGA1UEAwwO
+KgB3d3cubXlDQS5vcmcxDTALBgNVBAMTBG15Q0EwHhcNMDkwMzE0MTg0ODI0WhcN
+MTkwMzE0MTg0ODI0WjBqMRMwEQYDVQQKEwpCYWRndXkgSW5jMRcwFQYDVQQDEw53
+d3cuYmFkZ3V5LmNvbTEZMBcGA1UECxMQSGFja2luZyBEaXZpc2lvbjEfMB0GDVUE
+goCAgICAgICAgAMTDHd3dy5iYW5rLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+gYkCgYEA2YvLGgmF0OTLBKz0nYTvR+DlnZai7b2MqAIM9IUEpMfqzJPNYCsXziYX
+gHtr/do9ppJPBhDjeyIGEOSpgBqdkWItxlLopUHnf8VKwnDPPj4KkNyXuTLm60X/
+ph+/zrjTw+kUm+/kVYstgGMuTIoTuu7loxCqqeVlAgc5lzTpUhkCAwEAAaMlMCMw
+DAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUF
+AAOBgQBr+ekYoADBm6kbHBR1oc/6O9ZciRsTbxIAl3xjA3kNEeiUXXSoe+1dlt3Z
+7D6EaQztqR8usCW728J3vi8p/XxociK3r4aq0Sxu29gp21N1V/Um8y3ssI+Yt9Im
+oHlo5ikUXra5PtGAwi4FymrU5dWlHxYk1PlNP5nsvxdElPZnZA==
+-----END CERTIFICATE-----
index a6e25b9d59c8e758dbce88ed703609da8009d919..ed2a828a379d203dcf83e134b1a52f583c0e4fef
GIT binary patch
literal 65536
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
e00000000000000000000000000001>*Z%>EvZMt7
index 6238f5da9e5c67c28c4fe8a31441645e57b02941..5309a0e32bf0eb696b431a0186a18fcbfd5186ff
GIT binary patch
literal 57344
zc%1CqV~j0bz~K9~ZQHha+O}=mwr$%wZQHhS+B|K$d)~=B^I<agKFLk)%sZ3xFR5fB
zsoG!uSyiiQZ2&M-0{{R3AOHZ61pokq|9A-i0{{RB@ZUB7i2vAt|9J!c&-P#6gZ#%v
z`d>d!vGq9s_-}yz`3@A|e=`Wc|J_IY@#DvjA3uKl`0?Y%j~_q&?*azk4?h7T36l(o
z0;vlo4W<h=4~-3(1+fOI4q6E04^#;B{o}`fB47YO0ER%I-wYIB&{Uz~q0g{@Fra|I
z445D&NaHaR@`d?}Gm+<{CwE7!vl2MsK!AWCfk6IwZ8N%ukycG%LnRS1_yE|B0Y)r#
znrIUAKrUaye6$WOphw8CF`4KgE$iF^*0FR_A%Cz*6kQnz(XYsi_@v-xg61{YuvVY&
zlBYNk$BUS1($<h-M&v>OgO|RS&VNa;RasI}b&}}K>U1eBfas<^+aP1cx!!Y}_I^Jj
z<==vmK~CVAW%rB86DZCKt;z<O4ZA_DNSrjOYFzH8aWX?zGG7B3(@5zX*9paX%PyP>
zAjk8WUFrxBYt<65vUNmK$sKX;QUo7^^mp>yL2vDFB$;2QNOZKK+1!frB9~$u$u=~S
z(e28N;drnpKpxtASn7G7S#m@a5!LTHtPiPg*6XDsG0<}xQ#jVfuUEf@(sUKfYyV<&
z9b1679(fH?uVnnw6Qj4&M(?RITr5p`U@3fun0NpaW#F*_e|L*iP=2R7nj-c9jL+BC
zz`31FF=+`h>a5~F;(ZK=2|^GR98I61v+;*nD4g4fvDAm8Tykl^eSKvlECu*NMD44F
zNi~GhmtpCQAKz&>4{t4sNy)!=@bz=_+nPRsmkm#?l;~D~J~XuLs6Itp_0n&fJJaPN
zH8OE1gg_B`#iMW-qWKxqm8!PHu8vV_+2#;=z~k~RWLvyfn#bgTou#)8nO6nDfkhf`
zfRO|$th(VaIfMHl<fs)2M~r9})l@@rty-LzH2>)n9|aUG@rY0b_V13QPRF5l#e<6S
zr5yK5ut5LY!b22mlHr6BPpiBUb-C`1-o)v{Io`MOJ=VFQ48QIuG5LY_qV-)wi0iH-
zmfG@l+2xMHx6@3f&#rh)a!%6AGZMT#)30B^iHPB-4Gwg76&RQe-$g6CPVvgosoX>N
z%dv!q;1@@FfDysuaOte8-iG}^RXI^cUJtT850QW$$>w#<KJojqvleMF5=|fATTr$+
zS<Xfn0q2&zh|%kL3UoNN<2WY3@Po%Fxw!gPU7JW{N~5WIJMgE2@Qpop#lKjQ!jFii
zK6knjAbaKG*F;IRxywwi6HIM|fC1nPUCdY*nK>CajZ7S!|KAb{pOdZS70&a09*!qg
z(C4(mv-*bkCm}(uu}`)y#qer9-F&!fI~GWU_hxpCD9xHuOD<Ht5D-dgFSlvl6caHt
z;3xil%H9k7-}&DCQ}9UYuUq`9Ij<jWQUB8JG(S0RM)#2h!2Kw^+V;L`ISSVJKL<9Y
zYsbsMRG0eG{};`El*6a%(w|;7(AADOvB*mrtn7T+8yvB9!TGkFu4<?aKU($x`yva!
zB~JNull{0g8-`{f6MCGP8*S8wBN|~kuo6#+^;1^$nI}F-gbMB~;`K47uw9ZSw4|ye
zod&6|)x4J>H@#BlXcSL07fENR!*rsFu$rW5kB=pJAOC!OO1UR6R3=%L(U|F05ur`6
zXfp>LdM#`kIjP^Q*63;4#9JbsUqmYgU}ANa0-yh6I6wRN0=Qf{n+J6r!VEn_SepW=
zxOT0%54dpFG@T9C^Gb+t9b_^4Dc*o_LI}CmOJ(3gF$ZK=fwEBO9((~grG{NUbY<($
z{2nWwX1D?=sDVsNJ8PMW;g;(_Ux5lr$a>6VJ`vuG3v0A}I_6U`tPKg*_;{^aaGFoj
zHP>YHg3?ni4My^O*1nxlOc;C_k@g47!p3FzO`qm)UUSLw%kanBn`CMPK}I@X<rGU_
z(7R$;d0y)I`vNXlqGvAGe#EJ3Urs35ZJre5yS*G1I9%K$cxo5gFeH_98rPh@R()G~
z58JtQpz_TYh{8UDB5c?QswK20h7t{^qJ%~Cz(P_RIf5MTwy!A}?gFZ1qcI~_&11ct
zpy(uwpoSrcM#E=7bi0At6y0ypaN_U<{^<L(hCO#B*?O4rr!icz*`~p({P7$uDHM+C
z)a2|#t2I#F1M;V$-iH%Z-`7-ok0|H|#_6UA{J2Ercb&d1F~7SHX9kC+TkSEh^nyrn
zB5-5!!Wh<i+8j}IRwg~$Cihq4@?jY&{v?oc`ekaQ>kGm-?iO{ED+yi}(*V)2##Vab
zU^Ayzx?P-oH|{<AbshI>utxQu;Ym2x)mTkIdIOw}n<V?$X93+ruClW4SFEXCx~*1a
zbwa)yya82<jHj!74ncAW5*<U&53r^WRnYV6CV>8fM&jBS*w%{u9N|egdx(0q;`aQ>
zkg!g*a%dfCUD2k@Njcv;AOFbt4_j=x=il73>Ch3V=b`PW=4LkkQVrX6WYaS%_}MkE
zH^|GQHN}<V_rgEbl->eJ!Rdl|26VOgbCWECFHVHVWx`Nv436`WE{~3O8nvJ*tP1GD
z?)Vp3YiK*`V`QlT{#q155RwPhzjw0m1!fBOe)9)VX7MPl@D#BjSy$mQ<@yZZn6b7w
zPGt%zR1(|_V&)Ug^d_DBH4RN)W`pb`toiVyn3?>S!^CG7;cW2%h7A<Aln=FQIPjQS
zy{Fd00V#fI8y|znm%R~7uT{r*mJZSIPXj@`BWYGiBM{ngH!C7x;8l|PS?^zVl-_5%
zo~*i?s++8joR}37ZE<D~p|EC@gbB1pw1y5D8N!ifeljgnXJwd0Jj3z^u5X&oj>~(}
z5!h$T8qxbv8`3qrpcsD1XhcC8y3k0Zkzzrz9_i>C;y$N*Uu06P$K72V<3(gzPDIkZ
z#Rl&1=G)wtsrgi-fJ4|#d4&(_D^XH7w?o6OO@w3$JjfTXzWjJz-HvC)_;l>L;Jdjm
za5j#|;q41%@ciU($Hy8o&d0SSOeK9ep{iH5x3qQsy`<cLq0fZvhSG7kbOPEgM@CcU
zKUVaub>~rOcG{oZqn$oLgVQE|7X+C3Wyh^!XNJjP!~HK04CjI&uXK(G;?LP{|3n9d
z%7+Jg)j1f&MUlF<_fYyTA?=PNq8}*Fq=+)1BS`lGKE>@=6gUK-nx`OShmpT|g5nW`
zlnHML8E=0?-$QmPIxc<m^2IWZsV=fZD9qv`B%OLf(B_jvrB5|PI$M4YQv<Kml*llS
zz`{UP!54GNNfw12F^|1W&J9FMy-#(T8E(Sk8|TbbdxJ=bqzhXzv0}7st(S1}tAKN|
z#<|di4Ee)uQ^b}n)8pTFmEWo#o@Mq}1ydx7(a&;9(<AwSApni1*KiW1Uh)hmc~_Se
zP*|fTv}I~vBHOV}21ZzNDJKGbriuOOmrlF1LkdHlzJ`6^7lc_5qwVxB$B{c|2P0-&
z7SVJ<LmLd_;)M+mF>{(8vh6DKiDzlKsReJ&TNITPF>+vlfExw%JI8bRRVPB=2UqYo
z!u&7Q)Zs^DtaAe_M3HSKwg-h`V)!6x{ZkEehGy+n%3wAMO8)Uq=WOSu`Yp}?Y%QK!
zcX7Oz>&o)-z$y%z)`i*#{ee}MOMOisn+18UD-obhamlurr{nS*0KOT)m7$#SjGr=q
z<1wvbxFxF0;@JL+9=8Q(fBy^DOYc(5t2Jd7u^GJs*E7WH5Q`#cj7K;|I^{XBW~7F-
zB8@Dq%KAq@sU~qpcrrHOctId1#yuS|uDv+dI;QI#Gb)&B^@PA8NNW`yJZZwfD-olG
zm*QvM$?(MfM-`8`XM(M$M~X(T>J2f5KyoYAFgi~LVy24Dy<#w@exO)p$rE#>&2I1M
zYG*Z`#>(wx_FfZg=_5K8Cx7{MX?-W#LIZl4d8x7hTQ(|vQoI$ZS9Lnu;5G{58+0po
zD`(j7aIB=@sbWoeZMnyZMG#qvge3Hc=CzuVH5>O+u1}<M;wKuT&>``hCKUdM5b<3z
zht5DAU4{W;9suJD5UAC`nK-AxwQZja%#}ag#Uk#dGqb`xsjY|`NPG&x1RsIH&E+u$
z;Q1p{=+OA;K*do1(<tK3!F=_^%{5@T+dJggNJZ$4o*TUk|73Y%SQ5w5&XpQ?ez}ou
zGCfE*b)hgS(lG_uyZm1h&U6)pjg@^)iSv(XsO@93kA5j~F>Coz<o-FdX3x&0bwNYj
zB}$Fzbax@Z5J}$Jt_6IOQF}>@jDYGOo9Es(dzAbX=?Em@6)k4>H2-^gYRs}kZ5)U4
zx`s+oa{<e6Vvxapb5?f+PovL1#Sgd#AbGCIPDKorn2X_gf@?Siu#L*gtq4e+D?Lz1
zkEn|Ncy;E2vsX|E%4OZGez;TA^lVVkzq&k^ru=VLuRtUlNhz38=%1V`yh)1snf$nU
zQ9;pSkZI=iYkbuhE74h6wVegJ48OMT)l+A;e@~t-O5d*Lm5q3loPQRu#q7(n$s#bm
z+{DMnvL)PG-YO1S;U69LBr{=OmLyU4Qd>Nlav*Z-*xmtd`Vz~jj9^(BXr=i*D9hg~
zYn^S>{%-Fa*j*u$C6T6t`X8?Uw?Qd@0Wkmo;D9NB|FdT%e*E}9$G?m&P3*EAwq72R
zO5Y9`z~^=KpUN;t|BNondpXbz*fzBQ9&32gG^2!B+9lv6sNQkc-?C6Q+L@QRG{n4G
zL2ly8ft|tL8sMg&@Wi?njMFSDa3Fi(FLIKWSInu))+TP+0NOz0VP=6*oTxFLn>ood
zIrVENNb%(EyJUsZW#_H73)&tUVZF-T>)-;M6Y*J@zW&$r)|wU;*V(>Mi$+XyzwlIj
zQ#~->*bp#RhW+(pC3C^TnCq=#N`uXTgKv(<d9gDJyqW&WUT{e=1~!+GG9DTs-RLKd
zSyCC3#WuD}m0X9K)0v=;p>Gkl-r~r?c<XW<4G3mF7Ng(hi)=NZhy^r>KpVNHcy+VO
zGgBj|=7GV+2146*BGtumAW>sU+nunSz&!fn(32_YyKA{>A<wO2IG>)=8?Pzf947-@
zq-GJ(EYw^KNrmmtU%I_Dhwb}mK|Vz$$F1IV<&ul9w|kwSDlWq{xr}nzF_zA=o%<Wy
zgqq5w*T2pWC{3~|y8%uloV=LQSG|w3{Dq|6y*I*{mQN#inov?_&<5yYRzOML7alZK
zJx3$L>MA<;b?Km;KNSWwun+TqG-Y;jVCDqWK=+|e@wQ0H%qIqslS>6~W*tb#oq7ep
zWBhJD1)c&wh76Xw75E_UDRk>q6KT;f0>g2v^1yU<?DZ6`e`@4Z&ETys2#GK6vHS<d
zprgx4;6!;+YV?=+2@%}GD1-L=30$jd9LWg@HC-7N3SAU(CFWLikT5(S!0#ae273t(
zOap}g$pwX_U)xyG2U!%L_Zwbtj@RDpT+>X?Ga8%bSE0Y@Z@wzw3VyLJ3n01RBhsc;
z?yCKT1m56*d?6i!7q?$;iXETXj5_bed3_cs+UAv~n-Kpvx+52QpnWq0v*qvG;)8YK
z65P`2R=E{~YJsL|Jb66XK5IDcf(Jp8(MxGKosQzgh$9GV0u$e2uy#V}{(G*(fAfhM
zvI=wF!{(^TK$rRYaKbCYPQ8`#^gP8xKI69`s_5AS&*c1(o9we=^2qD10XHMVqLV@I
zx7!vj^)J<!H7pX#1lkPtxwch#UDQ95nPO@DQ%&UP%I=Nib_KZw?Xy}_#9Zf>l3wfj
zxQ7HPrxGo;z+WuSx?pvs1V7w)u||NRY?Vk%c(@9Q)8$zimsQd{6n`<r4;PVcm7T-T
zKDmug|5cDJB`HF5P<s*Io4gl<zgJ(GZKu%afw9d92*L*R;P3~%-om?SYK$WCyn5G;
z>V1ckN?UBYv0IQ-L65`MGMp8yZD?H<U+wcuw~HJPf4w-zvGjl6tVq^Zj50H)S2%6k
zL>EWy+g<D<!$6b$a_mjHgnU+rDl|J(ES+&2?&NgL&T)K&AYtoL&~4w{@UomgSe>op
zL{?2oqymPbyU+g(CwiTN_eQIayJR>_*@!7Aw>gBqDwp7?bnF%BEgJm<{+Gd}yYZ+z
zju3#W=<rE%ut4eU_3vCP2FC{Fs=GSJp$!z!N5(>+bYE4U2>G4Lj7vS|H(;hKGb~Y(
z7&;8;3`|4cpf4Ih(&S@ri<pG2y95sC#H2Mf1BzcD;fEu7Lu2UFEZjsg1YL~Q^9|KH
zVb{fdq)3t{R=qPbJZ}b+!X4Xp5iTYu+u_9b9Bi#0*xmtg3N2E6)%}|hpJrBV!lY(m
z?g^Ig6$FI1ki7(0Z}^|GY;`>B!z<=EM@;ue0HABSmmp{0u>^l^AZ945;M_}7E=hk5
zm+t}y3HkQ+KAnL}px((aAuU^#Kiq00n{GUn!ZstLjHF0tFA9axX5#zrzGp30SHc*a
zrFxkuzrGM`wwvmR|L_KtMO@V11o3+VO`oJaZ%w`kiIc1uGniB7yHnZQ*~%>tKK=IX
z+I)#EBCdCHNPS#Z5@dwkU|`?RFrCp3nf4ncM>8k&LZ%`rnh`lwz*N;!k?B7=VZY}6
zF60tHDCmZ}tkl@Zj;^?)q%E@M5wqi%dTp=geqSV&3yLQ0E+>s0N<_nE#zWiC1JTYX
z#3@Ma)rz7;LD(qOIHI5S7VPO5!_8NWS1x<MjC9r&<2ig{QQ+Q$z3d~fZlkaC+}BGQ
zmaxM1A?SnkZpKu_p*U@-uhGl+mul8Y&QYg}qoE1&M(^6Hn)#sRfcO5XhJ?)K6^Yp)
ze)#NC{B`H^wo3&sYt*AgBWO+2jC_Eh+x|B1j3l60k60;`kv5~3w<<C<Z>ykj(u-jq
z!|3@m7#!?RPToN`^09`y{3FR$BQUwTdb~AyGq)FL=L-d{zc^Pd&MK0-uTw&=HV>A3
zfUYOQ5R+x%a%>ceQiTN70rU{&R{TJaBHq+W<Esw(b~l3=aYhrVB{;JooyL1u$X~Il
zBmlyE<@!X?PI$_aKRm|Y`p=bFRKS<VFa4$P+1gk;K(;Ii(oJOh{3ey`ltM@^?p!ia
z6f!wHkGVnC$^2vlUpb=S*f^fbawA&t7IaEr=Bd!co#NXdiA_SQhF%=ATJ+}8BXJxB
zcc;d#5ea}7>Z>vW=Pbw8OG<_uTzUK<Dw9T-JKrX?&&NH$Wvbwoh@=t$tQFNu37dmN
zSH-2fEQY6(Q+60L*>A-ZYR$v9m(x!D--Cuo-wXVzyMID&SjkGIpoL(O94#<_^+4TI
za4cLFrHF{?Cl>Y0m>g7}PR|Enm(pPfP2TQYNUOQMxW)vDvg^RLeH;dIKY=i@bZfl8
zf9aZF%n>Zpa_8DG;^6ID*#?iAGw$MEBmx4EOY@}9*-$8raY2A(y18zYMKLAq{XIVH
z332h<b5<<~Uf!RO0&NS)1!cp|MfFDdD0adpfb-4uV+7D{5$JPQOn8tT@tYe5-mD+_
zg>Hv)V7UW{^<gIJ6Hi!O>rBE8;q+i5{uJfw$x(n?JCNu`!9laf*M1!z0Zy%OTJvWx
z@(WaYpeGd~+qE%fIS&L72%RGL&L6@#+4&?Gi%*<_B0%Uk1pXRbVYK`<nD8?*cII)y
zb&iUYDs7@p@cqI2c@v8rcl#Mc#a4uPkn>9Jj_QUahntT$f}C@!FDn?i6Nm1bDxdnX
zZKA=<Dw^$B9Ss4HXNB{tdWLvU?ObZ?c?+gyUg0-n+59j<bSm<<cg9w6#1j5O5Slp}
z+-D7-f!_4AL)NkM(e%TnLhcJo?{+9OgR>9Wf*tBbI_JMs<Boe*8`9;<Ld)rw^#{j@
z9-CBy^Pg&PSsN^zz2JN~P#Z$Xv-M@X!T9H>m@MIU4}?QuG{<q$6l#!8X4N-cJcf39
z&IwG?H-8goQg0;q7CT-ARR_FXt#BUb`$I>zDR0;~K56Z~F#_Kf4=A{LOWz8LV05o(
z{kD2$ULR8V$YOFJjE-vhDtWojJh9oSni1L3+=E52xB7mC6rrPY;Y^L9oD7x`TfGF~
zu6)ADT`h=8SGHNmrxrd>HC|pEF%#;#t%*oDiCF*D$U(^8p5oE`xQzlsXC=m)60~kN
zH}>5TuplDpYQc4|$LQ82vhL8N!RW<S;xU$;E<bERq5C20ZfCv}YPMJm{L5r+xw6`J
z@|eH-x7$XCx+tbM*O~;<0rw1HGY}HpwWv2cc8aeQ^|{n210b9g*?P9uVd0XSx-zuy
z7G<&9X>lVwhOpuQF}mM}*-3o_t0G)~>t_<SenY3f*9W-LNpEJPS{0E`IVi?WpB&($
z#NQUd3L%o9H)7wpr%iNUlR4VDK7#g0MPPTl1BGe~ENUp>{xSz+ub@8ci0y&i&%JHp
zD5AInN&PzJT6J##Givcu19(5noB<W~U-+ozEQ8Ul#S=@W*`gcoG1s{I1<Ieeun>l*
zoAeFXT}c{N64QPYIRJ<WCcb8mta#$s!3f$I*0$b{Zw@xtIn@zD(^#cg>_z;lI8b6s
z)08TSvBCI#ui~NZlH6`#BS=ICcR`}F>8ea<Dkcta!PLZ#e6uK_(`g*)49`o|6VP#(
zJ5h^xuvIn4VJy-Dq~jG&>akq4UjfPyg7MJGqJ9iT`|Y2tERu0pA`yTWlWd|@f;J?r
z8-R=rN}r?9u8c?oRQH$XGXNhwf1hQ&+bYJ6&h2zy^JM9_D5sW28XhHiy$Skv;5B}E
zdf%BhP}-6k=`c*iV0!f?$4xDrygMqL)4UO^%#Wd$)!7{yH_E4GHPAXLgZ9w`pKtCY
z94cl1(fw;lzd)@$Xj>HZdz4^lx`>g{WAz?&dpt663oqM<(Ul$awkn_p2Xn!s==DGQ
z_U?}#KYsl9@#DvjA3uKl`0?X^x&Qh3|Nrb?^y9~mA3y%@_is<l1i8vgnbrF1V|v*L
zFGtOiUx=>$b5BMST*up;O=}n2Q`^?LUHTZ-JpM}os~)re?IS7LL7)zI#gC34o<IH2
zGs=0o1*k?@6cL5PK9J%2Fb`%D204*$K~0Yh%kxvRTl#klt^e1%^aSLNf};<K*uz_Z
z-rKn-*b5$*=KxfU0hfofH(dtW{e$GNzf&h-!&Q7Yfp&nzaQC{0P+5NdL2E{;g!#^0
zipk@Lc_v|fzQcRl4!e$f7k%D?SZaIn5d-^RnF=1S^Q$NR2Scj-hhtgGQalESdxnT}
z4(*(bq%uD~fx?GG*{J^}6u`(CK^tO9_cZ+g#uA<d%7}QKPtE5A8Z@s#F4~u2W4X$0
zn^PNmRi;z6>9Iiz@Fv+-O40xfyKnD!A8`uAxDolF+oY-%M3_%-_sAei&);b$BZnZ+
z5{1!7FX2SSt7%K+Rn2B!kZL%gW`5a1)hNMP1n+B988h@Qx<3Wpjq;Jo`+1}nvw7CT
zT~8+%iU8?EeW-G;E7onL00>{ZrDldFfpup1t}i@smYY35&rDthrb{M4A`-#_9G4*)
zPdX2yuf-6*^?_A9_x68%-!D8-H-*wQW6y^3tfT3iYGB_LS$hYZtW}50=|{u34qE?q
zk!}5x*hBU;mrsMmNIYj)!OF^?`LX2LcVa<>{gR<J4|_EQXYF-v=WJ+Wzkf_GzW9m?
z%*=v2$71rF)F6=&vy<PM1^N7%F1*6!_@4U5CVb0^Wpv5|IxpGB0h)TB`*g9v2{TD`
zDVHKVY08HZ!U`Yw^U6leN*0yjny1w5wEDL?rr8ZvrrC#Lhb~PEzW~Dc<+WiR#S6+A
zzn;7Q#8ffFhVRLqmC~C@+Jw^%wQy)aCUei@vCP$#Qww$q&=qcY63A-ZAj)}p3(e#W
z93JO(+7(I8*El14lW&1xJj+W_z(omVWnH&(evYryJI1v|eNxnNvD~)rf#FCV9a^JD
zhQ#uifXXUv%^6Z1$B9-5CQy?aOiNj1(t#{_HW-VwTSxqWgI}L89dIiB#p#T#VQF>J
zzf_~sO`z-Jrf0d2rA#mon#Tr(TO#>SHA`-wq%ZRaREf`gLd>8Y7K5S}U*@IQwn$7x
zPhQ48Mv4VK2Mz*H-*RL6FtC1&(=E;4IF#^5D3BP}@|&-PS*V<u1c9E#a$oyZP*+eT
zdpaT?v*FwjKq%*T*~r#p%_wJd21HIM@b6Gk6x?Fzj9SLMEe}Wj@G{WzSeIwhl44+#
zd=`!-xd{Ow^QLIdxuQ*(Fm)UW^x59%u;tH56yLg)iUlgx#g;Z?RuuSrW!E)x2#{>g
zLb~@4k!E@!BJY1faP!XO5wkI}na$FL-)N{itgUq)t9DAI85lm|gzYoR60t6H$ne;}
z3{YN0K@>e1dq;@$I;vprR|zU?TfsajSAdm)@972^tPmve;V_irW$Mmw*OWlR8T$n=
zZfGipIH?;Fgs`gJafrYip-Tn#i7j*+%6f`T5FQC*i-J&!fj)hg>+u@kGj`@mO`sB9
z80Z0BZn<tkDrJSb#SzmRY!-dKg<%g({EK({^JN=tFm$<qnZHn8DlAokKxIwY(EFd>
zXmj0KjBHF^h#Cbj3B}C$MAhTo9L?!WQB#N|h)!=Cmewwvs#b|MhUgNfVUaPM0l(^X
zCC`Hui}3y&<JCvYNSJp!<>_DM7Amja^q$Aa0gyuLQQBo$t9(J4tk$S5u|scQl%%|c
z?1J*?a2E#AXfmn`*;BqP`tQ6w@ZmruXNt68azHz|4ZmMSa}|otzA<HM1%13c76?!p
zbyk?~IjuSNH&3s`>rGG|)YY}vbsf1^P%AT4-VZXiKJePh=E7ephHzRmW39W0uEspU
z2GdYnVjLMG&}#MK?C2bW`lvBcdqXVyU#m$Y68R#ujsnjmnCbLt)OExaXkXn&MNC}4
zoXXG5)R_8JP1H@7w-yXqxTA?)WDG^uc~0aM6Kv<}Q;)iN8tUzAFb7<t?=p@$@dSSr
zx}g?-9Gz^Wtm_9j3n%g7jvmxcXV38i-l<6*rcO9FoX_}pE9X=CoSDI5>B{uQD{@xO
z<*W#9VjWRw@Z#9(b^c2=uMtZ)McPxTamW0w7R7DlXSX}B|5USK&JkW&N{yV!x>x;t
zDF=cHvM0O-3@YQBI$#>88gE5Byqi+nMHSza42s4|*T-W(dmSYu!=#IwKx=?06Rc}7
zz%nZF3@9x&@r_GIv2%`UkAqL%7D7xpHS0{zq8;zS^F~*T=GFr*R;N89fGQs9BM!Zo
z7^Td$jQ9rhxH-FK;|}XsX#=>sCK_31GRZ`%JdhKU!f<<nJn55*OJIe#0hpw5FQr{`
z41Xzje{44+rXO46k7X(XLMG;WZES$yRF=61Qi)XnzEMNP@cZ|Ko5}k_cNo8yS`W88
zC$xa{_rh@OAgJ+mM5B-{c3M*&$zh@R-2*CPLB>Xjeq(fw`Mi{Jgj2hvBHfu!*>!Qo
z@X4;7VXn`3bkG4JQ;6KAZU>1ZZ7jOo{NED&s_3LYTHF!APEXhwBku_N1LEF&_h3tT
z>4Go(0VM2bE2(L=`L*f!sc-xOe4=bL;!bhcN-}6BOw)NY^u1olAPY3a@Jfq9C3}Y)
zQTV_(-h?=-Pz+ZAwm!(&V(>MEIyep+zut?OjKrjPpzf4cLUKqb!#Zc+Xa!^M(755_
zN2g{<RG;9*JUJB7U5#6`(S1+&oMd%g=NpSK<>MC7_oXn}YV5CC)ry0rN7co??hU^b
zeix%}x;tAbo;05IQoG9k!O}I54~t9hqGB!8oh-REufVR~l)|2*6~naYMPzn22q#IJ
zTE}OQ*M_ojH^`6>4*2s#=@8XcFuWiIV+Yv6>|tBX%5Y%7x5x;vsP7$Vk5`;PRF{A}
z3<C_e4I@afLJ?)J%78e25!|rkiLN9PFQ3-i&t684`09F{RiN)$)_`Np^q8f1pAhWs
zT(2kH<4Cmh%F{paDJs}#79Q6g4>h3rY26VlDwHJz!@uG4rZh=BTL<rFR!9;f#|0AM
z-bZAtZQN4eVV0p6R=GrOT41UJqQH59OK9ridTPB_xZU#JymjJBlQK!H$Xp8MXW-0n
zZvD8AYe$oaUe*jXeCMJ=uc7B3yhsM0&1A<72Ji^K2X6ph1w#$v0%-*40{P$9|960{
zf&OQoKmPdf<HwKxul~<i|8ESqtrcyaoNc>l8LFhqps}8X%UBL8E%G7+v~>Tx!QCOZ
zyDi<k_*%Q&P}?=PG2RJ%9byY0*8))1wY5azCK_dE$fy2^du;aomuJ^&)5X$<!4)~n
zjYm@o-iXj4*twk#b&Ea0Q<KMKbNl47H2xER4p~zSNS!wJLXWITP$&B-$(7#Znj9?U
zuyXjlK4`2G<Lu58Mk6mnbK_cAB~ITXF(aRaV330mBTpoZ#?3yLkX33Hl8C4;GS*!)
zSOXwivL|5$kMC6h{yvP!x+R670^~ekjrc;x?PDtyHGB)T(o|Kwq~|0b&v&ceUuI9h
zM|+XI!y6`$nc=o^W?CeOl7g#?j}%7f=<&W3EbiSAz$_N=e7kdS7{iu@(jv%cxwT29
zFqYlhH9`K+k_wTSnx!F~{F~G!Z7_kV=BD1n87omStar#f6#M!#0LIS~{k<31AE*7#
zBwg)WHGz4Bss3S?7c6XK>QzP<hF4y=AA@Us=5vd8z49-uU<eTrp^B4@D*R0Sm4_0!
z%CVzKIQ;xbX}e?Bm~y1G^_$5(tL;-1BCxEBkQ)uL0$>jVjWKUg`FuB|2Fy3l>FXZu
z*K@>GV0V>2@|YWJ=gsUsOUu7VfQCp62}y^~Ik%ID2=3(#PkA8E&<w%iEz)`WtF4z$
zCfq~vlN8^fM^m??x!=FAhnfu`^jzg9nGaW@tsI@#%}a?ygx+v*&2rxXq#^sCC2X~a
z3r2oVd^i)AL7u*orNl=ut{Wvcqks(F79P1_oBFGVagY#Qa$9h+k0+<;y)hp-tP{LZ
zM?-@!&HZ5r%6sq>i+&e+svjCy@sfAiy?+6Z2}W}QjQ^TNhoTO03cx%`NQj~tf-bG6
zAiw64g#vEw3#vB_`3-%OH<q8=Am@5FaYIlCq7YS_d>-}?6;&CBPwN=;FBcTfj*k$l
zX8@GbOYhU>K)njBT~-DERD-7z0;Rytbi?BpOoQ}D7`Vd?d=ABEVgYovk$OM12|l0R
zit#UdP8jfsSsL-OW4m&F>fOo7RfPCP`Df4Kq;)AR*%qc=v}VDmLHO!3Zm0b7WXMVE
zB@5=81nX^r@PK})%1oIDc9sAcjx86hI@#oKNZ(r<BXYJ4GQXJsNOw$GLL5@*OS)~@
zmXk-$l>!DdPZ=?`N2!(_{Cb*xxk7Z$T^seBFxY#gp111Z#(KdPbSGr1pB<!Vl|phP
z)Mh~!f;5jGo}jFhC600qvsB2wv_<;UCS>Q1c^U226b>h#dHE09%VaHfh2#Q#6OGLz
z$~l0YetRSq%EP`os;_j{oP~gkuen|NJN1{0<(U_B5jHUhrVsYz;jKE(DXM#n$aF%N
z<@Hu8yo}39N3NgjVd6U+j%&iC^PO`-E!7gWo#AKlao8x@kG!gZXIApvoy`fi@Ot1;
zN($dgxoxCVm(KeDoQ(O@3h!_6wxX-&s`yIie(13x@2Lp1j^-?qGt~>N=>A?mVCi}Y
zDoBx+D?7R_S{=zuO=FhoGHFKrd*aPxVqYT*AZts=qyOb#Ug};j1>8C|pPr;Ud2ti-
zTo%t!B{<B_+f27MgYhf7sfdT)Nnr<~0{VP<RF^(5X`sC|^}<F}!mpn8jij0#|B_ir
z$bdZyI_pvBbf@%+6-po*|9gs1DHhz!QTDS!OhN{7TTdWeu|8b#bRyi5!~}_4h4ta!
zl~2W7$nY`$Q1o#K5~Z2S7YVIv495|M#JN95)iLgtXQ6}1Z(LF=efxW0q!*}o^w8cg
z?bo*B2gVCi+0dO0Hq9s!_+q)#b&jzcf?3K~eL5poK$r8=j@+4jD{V1HV&3qhda&+B
zS=d7Vn1feW4}Zu@Hm;R>4NUP?Jp){^q_7%Iz^y1otSQ>Gw4M<pf%Vt#W(lFmFTKzn
za5RxwGlH)XH(qWP)V|sn>GS-Nncu*chb>^Tw|lz5v#4TCF@BfXWSOfa&4CK|9jb_l
zOww%wnoE!0n)%g1gS{1b>~?~MJ$JY_N>of@L}286b7g|GBE&m5A6q#B&H(3kr4pm=
z)uv=`#7XxSg6_4;uQNfP|Lb~0W)CY{#_gT0S#*U3H$haFUoN^5CD5@sDnw-ICkUq)
zagOittGbZ?9WhcR_i2xsCWs2T6zjlq%PZfAJqMb~4O-F5)r4|C4<!Yrbi+BmPpVCy
zt@0~2Dqpi)88vy_krB;w=BRz^B7OxkSD4r6WeHa9&oU8%V%_nLSG=7Y*EcaitvV=G
zf`gO|W&&!UH^5A;PWd!U!KqYD5mgaylmxOPuH`FHFgoz_ZCU1Pf)@*@&-Sm5;5L;b
z<7Bp{MN(>UprMuw&=R)V>gE;!WrpB;Ecu<x{8HiSW$N#_b^(gp51<Mw_n1RXK7CBQ
zHkVll*Thc)^IkBp?`7f6^oiY#qYVO4$Fe>C_w;9!-|aLoB!;tvyqK8DNNcbZHBOg+
z3cqXsq!6p}PW;HTJfSFMOiRw65N+(XoChdMbEj413yT3xf;OIBm&(a6%0V@IJ_Sf!
zFu!Io>1}<>v{P)hmjjXzYA0;DcU~io)NbsPHO2xO5LNPm;m&)E;;Iil1Yh#~+nHRI
zMj^zWJtQhd#ti92FgA8!p$_U9mMQS8BU*)=?QC?`wCFm(N&+#eGU;S+mG9q@cIw~e
z6jRWum?t$(0>QL&NR^&uc2czR3Og54-(DVB#s?F4e6CHW1U!nYclHqDrYSxJZ=*u`
zhjxzWnDBv%Z?vNP<gxvc1){PzNN@2ANeo+6c~kxh#^oN%V^{)9y_%?3KS4FQh{tw!
zr1>kekU8BbvZAsVSWc^~<XYUXyjFy^<D9E9&0@FTqDer5XYMV|a3@pVnJgwM7bt$y
zj43@i8Ed9kzv1ucLvt-b*?70tA<!G}Q_;$yyJ!{T(~?SFhba}OuBzV&$-hjjBx}lu
zp5^}P&)vKk?6Itv3RL%_M^n$?Z5D?px1=Z1@wb8{!B?ccB~dV;vWD}>)sNA{5mFQb
zPIcK3t>8QyKX>{Q>@pB*)DapT7MmT9JDn^e%d}*~tD6o48A3p+TAh7WZ)R<0Xkbn2
zWMJ+5Kd=7>`e*(BfA$&dk01Z%__sBge2^n#XOaX68Hi7ZKx|ylHZT8uC9~NHlPFq>
z+pJEs9NKQd0+!iJ=v(iGOpK!Zy^2{}HE<2@${2{WOwqDBFi@^}121wm%;gM>L5xTo
zg{#6dif$SJ17k=Plqq$FUMeYS14cxw-TG5Rk7C&D@T^r%l{`k%35q}@RkgfjL<}TO
zDM3<+YoEsIXY~TZnIZ2dJbHK8y1Xty%OD^rUnzJd@zYbNd1#?L962@!0`6I?v@qJb
zcdcyF9ixTftbvd`9DD9Q?!IXm&kYr&Sa5XaUDF~rL=B0c-I1e<QOWx0q{;zd08)dM
z5g*)P4f0*K@5BqO0UZ<ib&2+XYfa%$&G1TaqPPa0+-;5z>ZMZcDcW{@ddVNkd)LL+
zKrlX%KlT(YlXk@_{WHdY#_J=#VlY)%_xkB9w$&ly_jRIBdxf`=JhdQBS<w^|Zkh;|
zOH@82r=9@ihs5K8R{2Yu^H|M2d8s8|@Jx<By+mMJr1cprIUj?tJb^&~vG6mw2-?sy
z!c#955G3mm?DvmNvEa~0Lb4F{mcTKOiG#$)z{6J(OD=}w>I^8%duN86fdighg!^(A
z*Hxe$W}YY3ah{N_hMgqgtW1Zs#BWO&Hxv=UgfuK}{ZZYq4lbbgR=0E=QeCLYu^;M_
zMiZBuTW%)}vO1*~-7<?B;f*b1@w{GR;?^knQ6A)DW<54Lox~Sd&L<6HxJblyMf}+D
z0l#v6{>=50Uq1dG5wpJqiKgI-EOPw%Kp7>0Hzl+|3cu2S7^xee`)iON7@@I9V80s1
z`3>)PG`#`5_HsY>;FOLV{`qMe(>%%+;O@fn_jE>)3*4#GAf}(*-<?7z8*bE|mG4i2
zUP}5HHDEM);Zop&^rOk|G-r@8ed4;K)(D8v24uz7Aq6NX27Z;NdY-tbq1~0KtkWiz
zkdi3^9HRpI-<M?`zymbEd7yPpVfEF!ELWj@a~zt56D{zXWeQVg`HiTLY1PD{k#uBq
zWS%Ul%~>EH5-QHCX^oZHp;cpXuFBzlg?>%t0^!H9T0$oOQVr&E<G$T6@p@O)#>9*j
zZ2D6hfA&Asw8-AU`UfFxw&T06gC(MSqI?f$V))=R45_4DcBOpI#e*d|G>Q8#l>;eH
z+?T|+xo1s!cL6F%vpLTWyL-34WIc;+<fND6Us<9O&i@_AayRL(0H<%mQ4dukJyte^
z2Tn-me&vuKz*@tL9ZEQw!9SzA4<%4l1RSU%`HkRQN?5@vN$1IX_Gv*UN&78QyYvMV
zVx@axSKaa(WCSQ9&wKK<DUja{B(p9s*H{F65g8QegbCT)K`ch)OYVBi7gk+P5`&aF
zma3au>tw2t7J`I7#IGMswXAz;{`V+Pdsdwh8Rv!yL+P!N=<cIzWc2p@Hx(7@L|_r^
zYXRzSl5x@$Bnif*mW|}UX^ejooTkk0&PG;zKLdWTY~V4~pA|`Wj+d))dWhCy_?&cC
zo7<mK*CI<Js|6%B5<lM+ER?GEQ<Ut2Da%_}y<BlnZ>d^Fx2gxwxD@i0;`-(9*=fnH
zM3iEf9Qnimvs7frl1sPW^g;lsYVjq#^zcY7^pjV%NEmvs>7=_Uq4hJk*x6-fhqtU!
zV_;j61bx+_4pC$P2=*6mTRjacci3$BC7!G<vVOP~6(gsB)2B^dMNW*CI%v5C0L&gP
zmc4p1XX1~rRDSBkgeN+FLe)U!Pfd5Y)bIC?hS)k<B8a*?PLr{m5;6mh$j9uFVUT$i
zj4GC2M?;xAm4)4%_kjpSxUP!l$UYu5I$Ws{ry2EbKV_Lv1(|8D<tj3oHqw8NW#na%
z-t^Ni4+z)*piLRdJbBU}v_R4W4D!ar5q(M?JFpK{-PD$3^N%kiM-(q}rE_tv<@3I9
zxsy58N$lAUOjm0x7Q7(DS&6}h0%t`nRSv9I5UPRpBA~S~uzAIOQ0M(6-AfX2>#aui
z1F46aC-g<dgp6!OA|>`Ep$H=aFvJRJ8on0Bsi6zs0A!ZPkLKvMgHa_tGtvKpXDlDw
zO|Hc0KdPZL;|%*?^Z5<2pJab9h6UR<LV!NPL;xe3=$p(={}vWvw_nmtYE!RxRq-#?
z+%~$;A}@cKQ4(&YwcBnN&Wf;;{!`6m%<N$B$p=?NEFpXE!AWhBF*j#j2Q5C)O1|}r
zo^$pyQGuuTCFA;mL;zPUQ#1?|TqNm9EijmvzA{iTCucCUqVZolzIoFSvpM(juDm||
z%#H78T@iY=HGA7F9e?e8dR|qg@u`iSVpN<ck1RRcS9IKNQd{OozZmci1_A^Q@2$gw
zgd+4j#++1_;)$#S)O(7yGi(EH>nhM++6D0@yV8Q5F<WWstUa!C2zhYVScA44=FnoU
zolsPM_&ghJg-q?Bu9{cGDDCHzXh)sFrOXvxHg1S^)e@(X797j;*n`%K-oz=?WU!?Q
zD(ToP7+;w{BqO`a@zY~gERRBs>H8qY7X6E8R>w##V!s=2_7!|Xe7Zv8^lgu;cXA!@
zS#t<Z!(`bcqo8=T&p3g>-YI#b&?0@4fniiT;TJ2yrWYTpXITz`HRJ>4nEz~l>y;or
zkbg<>S)CVimk$u==XRDcsyi<rCG4!f3065uydOkMB_O2$(@JnLQz|@Zf)#|PjLn0h
zFd0NFdLrv8A3<2nVu#RFCRziobmF3CjH1qOw0?t;lDEv$l7c>8{3QnZB^neYw8dk9
zZA3AOZ(*&KyaNIcyswNj%1KCwX3dy2pCfHo9{({Bn>vCZtqOLE$)K-)sUyf09w~>j
zvlpcCy_}VpVp3)%exxpCvz#F50|a6Jq%mj<93STsvLl8lcof9dqWLVa-%EDGIl|tN
z2RV^Rz@pm3q7RMYmb$WHERpj25S5;al~sH6dJwiFn>5TR%VmL?)ciV(XUH*WcwCSv
zb&H=U=1vq!p;IX9>ewI$MqHD)z`F)XrZ76{V*p%oVG(v^sOuG`n6C>hj7<L*f-L0S
zv;2~=T!7ap+Q+_{O^QXej*7Icy}67<ibjlJ<g$RJ(9mCS%y<icj!9~_#%K+2%c$ud
z^gRl5*NlsTS1abkZS^38@uR;nt)zTO&KAkC#*D>|HE)HFyM2_I3&m(K3jK1mhXO%I
znwz`!ar76&3rVYX|58ntiMUWgM;?-IiAVSK^RME4-U9i5s>#{vP>ON^;0h#GR#gFt
z^Qyf8^0t``f2oO#SJo}vwL%PPH9dY%XhKZfn(^>;_X9NcunWQ*BTm(m7ns|8^R6He
z*6St4bM%^r#=Zlq99;DbwY4eO(H~jlJgZmF+%R7Pi4)(xT{w`MlOCQI;1Mv6rCeG>
z|Ly+*`=-9>Q+MoB+#sSEXx5dR+bi($(p{pQf5jW4ei9QL^oBRz!#kd%J=e@I!i6-v
zGDg3A7|q2cj}n?HwF0Jabx41{%_fv~OE_2SwJ{9M-~1AIK$pDB%Qk=yM*himuxr_^
zpP=Ns@A2I^OJ8UJmW?9SJdnZwJJ1TjiHnk89vzvfF@H2GPYv%7VqOB5P*kh+FqLnJ
zAmlzzQPt{IAETN}4OP(Mw-ZMIf4faAVg$;gBD_LiddkMSN{B1lGpy6!i7kcDBVaB_
zo6{X`XewGucnFjM?&o>WzmI3^=(&N~Wi+C<N(~od?8eZlnRfB;*QhlC73Hjd_Kg5Z
z)hc-yD^lBd=kOyK+Jlon(h844)pub`STKF|^BaiQjVcU62?SvY)B3($+a4X|;B`W|
zc~})BUX6+<3qohBQu62u3~1N@_x@|(smlbLWviwIN~vR94;c6_mfPm`WA1ZfY>hM8
z<fr4wY4PUAbc{AxSO7m70b)dI)>tKNnsMWLM;X9s`L<WngIjLv;KK!w_!-$sF`pEz
zw>Q^Q=v%ZRm5eL|Ay!h@>M@u@##-Z!CQ#+TVBZKE;Jq%D3o02ihI%dH9GP`ek|(Y%
zVUMdLM8b!V)L)(9;f}$_-L222Q#M1vMM1M9VPvp?aeBr!1FoVGLp&7rlMD%EkFGz0
zKBvo0(|61bUg3P<3Y0(-im<4;AqTTCckj$)VS=!=75-4)nWTSEK-E1Y!J{QxJ9%Xz
z)Qa%HN_&2F+mm&hmN3%n^44FC`-78$<<GkBu4O<z<31U%-~NfEzESBIEA&C=wL*Cx
z6*NVB575+S7<CP~lrLpg`m%}vXL{Hic!2(Yxc-Oux&Ht0<A3xoqYJW=PB?Y4iXUG~
zInA~%YX1S&eCj`=3x@SZ>OL3Q4DR1S(8U*X^8ghXIcC{+y+uAcpN{-U>#>={i<*XU
zLzKu+igD!fTUzn~(P7RRXcMu@VvfcV+N+Cf;T?|BCr%hc#DxWLqJe3ebW3ymKH%$Q
z+4pcg>wr5GkSiR>W)9d$p|v@6Q4Cr2YOaH#Xp6|whe93%yl{`z_2TGBbcqGdFSRx?
zx#_<?!?klMFuIfr6jN(J#VL}zb%Ho1VEJq_n}H<TC3huqCd-oPnEGxUlS578s`5}?
z;p%Sp9Xh>io%PpA<vi+6N$D={xeRa26}lQ%MCnM2cfIMWu}s}<7aT8Dn@9rvs2lx7
z7YgfqN*Ghvp^e`X?o!}ByOW!N)PpLI&$&0d{JQpqG1(C&TAD{P_@<Faiq_w|eI<|d
z2n*21Z@r)xQxZh@DFN^N%Cnu}f;0<(pbH-!M*{=_etQQKleWPvMrpD<dGUi=VLRTo
zMX&>%CQfH=@9gC24HMl?GVtKo35G7+3{+zRC;2w6#G!5ijxz-5dicskNmlz=BD<D`
zT}2e}+EFR0e{DZH^Y3j`vN`Ycn649;vR;^s1@hMiKkT<Xs{uYF!Dc&W65}Cw19b)*
z+2z!n87BvVk0qkv3Qd1kN#K%w`mc57y6XZPJ1)oa>N+eNU_<jcoAPCeSi=8K>@XP5
z1{7s$K6E9Tj-^}r<#mO6_TF|W_+T=kWq7C;dxq!&4tWquQ>^#!{?H573JoySVwg5*
zoKi^Y)0q?ARLMAIWKEBkqfm13rmScKsL%6fnS1D&Tqi_yHR>}@bo_v^FVgH*AxjP5
z9W<j8AOr!<fG&x|NK#%^E}5wx*cnI=@{z7Ef@z^Xt=cHsSaS?wK7q`%sT51Bng!vm
z(iy}__g*gdktn!F&j=73!P8cUb%~{xPS*!*Do%6><xir|rUHOoM4hL^lV-aw^A`3L
z+9SVfeQ^`;^AraMLUE;k*<a#(RM0S%@UClYsIHp;<Rv+L`Y9i$8$JUX>v0LfK6V-P
zJNAF6reRGZlDSW(c2vciTx|hNIk!{wzyE8dT^I#sSzT4DrQQ<0wFMZMdaB@cA+P@i
z5b+A{f%aoiwR6j?Ux$Ag`W1jKnd3^++;-l=^#NBz*>8E;okS+%UwF%QuH<>4u@LA5
zlm^9#jN((#ns&hf^Qp8Re6g}qeyYKriVk%&`-sE}9d-aJ>M)wbZ8qdsH!@{>un-t$
z{!N;QiZ<!sacm~5wFzW<G==Aef>gTT`dqZAVt$OipPN*0`v%Dz@Mvo8jtj`A=kfw7
zmL3du`sl}E>1S#Lgsotj&50vI;soAfkhu5=1+aIo9xzvb?aI7>$=d5JU9K+)OREfy
z%`m+0y039DX8?_R)WW;LY%+K}*Lk5I7+TF|<+h67m?Je}8cbF+K5a!<$Jjqf4Af$L
z^0t~TRAWm_OHvj?yMyce-~DOiqMwzr)tU8;n_SG?=adR(N<73^Hc9MlA_(``14iW-
zI@5}mK&JD__JJ0nFloB829qE?4vInp3)J376&7;Oz*fu-(Wab5wvNMTfSLA?vRCY)
zfi9ifGS*CxP;?VYVX5YmtY(vQirpZOsav{<3G6L+B~F<ZvTLlaJhsrsAy;|>y?>uT
zKdjv2fdC8ZW%BV4CY=><8kNziM3T%hlk#8}A~*`%LH2*YTLj6I;LM&PfA&Kxtx+S~
zKaW5=&s}g}uQG5JwA_HetD-gLxL7x9teG_tNTh5G;#<<%P5IF4^JE{xiyzuj**Xy@
za2vSN#cP@UH9y2p7h6WD(LZ6|-9GgPwcUnnqQ&NT<h;QNGyU_DqKmJmsn|gK4C)qs
z5Id+DL(Dm`-;uc}NOu1i=Pff!y7qS!?oGw!%YO@`vwDm%-LR}|*j)#zuCGB#`8g01
z2*P65sTSl2TtU|qW0#xxQWJG7XRQcI*x~M6SLF;^2SO~ZpWr|R_HJQ018Zk>nx3yb
z{WuJRU1>2}l3R7G-MFf^jXV<+{~pOwg8B;}l7oemqXt5u^bpJrAYNFf;8VUGE4z!>
zJXP^t2Bzl1%FwwtS#T=2=x46^XRi5YuKEARxn_3Gv0VqXXU4pv;(VyiU)D8u7BT-+
zGYR08I&yZ~cyQ+@PRGHe{ZO!-m$^P@Gwbp80<TAATG;?%2e{3q4<SEzUZ#HP6J~YP
zs4@P`akJSTFxM=SnU)fOD;zrF)+loUwFiBdE2NP;MB;z4D^?t9w0%sKE`kS~C*i9X
zj&uFE{oocXY4z;l2{l9rQAx%9Sexpb(lRmE&`qV`-&DY97Rjqnl1>ePw^py;#`SgL
z`j&DP%fvNkWL~rO#)tlXXjMB`{0QO>y;Hgd;ytT!Gp2>~d0WX)0?7Z~)_=h4o%7oV
zKiQ}j0hIyWTo$-;@sB84Qei2d@Srf0I~=R*Z%e`~RMTrDM74oS@XRJ~3!i5UM=F`7
zgm5uoDJD`=dFX{y;_n-$dVuEZc|NyS`~x*L>~goyqW{v~JO75l##_F1yKCFFZQHhO
z+qP}nwrzLUySCe1xAV(;CX<=D@5#x%$xUYZ`5#uk&&rdvmLDsjh>jNh4v)R_FUiUT
zOTj7~oPAfCv#UVag?MYFkr|Hml^OyoH3!xd>I~PHQT>cn6RQ-wAV$KP1Xnloi&=Uc
zY<2}tgV475Iz8)H^!>`%;$zY)oT+0ub%2?Q{A;$>AjhuG{Uq-)=eZi?J?04)7(rn1
zHM&!|g`8(E$BwABUkXX^k_GAufMRJf{@_d+kNXFKrp0DpHmXO!q59y(_bIC$#LrJ2
ziGVw62?9lBj#tWI2pEfCq_Vj){6r3J6v;+bnW6|znE|Plfmvh5Fw|dF!4rU!B+*|$
zTpl->dc-K0CrXUz3kd5k(yR0*To2VNCcG$dXs1a<;W@LT;$B2fVYVqY2Dz$E?Qixf
zx}Ve7RiJu!VLm%2Sq=^Wr4Yb7t$0#2(e|l-K_rAgi*Y=O=E-fTNn)0cpl;Wx|Hg)_
zzJ+9O-J-8~D}zY0-PRmAkD?f2!S<U3Rfo<Ehi^sTWBxj*2Pr~b2s#CJOulS;_`;3I
zop&2pBpZG2nFyt!>4h8m^Ywa%dtCH@i1#kr;59><>Yrd{mET+PO=papwApKY{2~*n
zjc#ff&6zgsN$&@(UtyO}VJ^L~G>)yXg+{7=bixPs(CmO=p7uoEysV!-)B^Fp_<zJ7
z@BhOO{}camT@oRn9@De{(%^HO8|UO09m<0~o&UKm-C?m|oGz-I0NaZe_GAVt<#s75
zPtI=06tuI-qa(GuFvo}23M0RHAWtp7f2||KEx2y>=t2$Op0`kLq?=2hgPLoquPaxX
z2q<@*qgW3$5BT^p5I($XW6Qu-0@Iq*pMEA&F<(e9A6U+aFjDJvnR$i*$dC=8+fz7v
z)k4|#u8Ivt*o69a!o>0HaC}*j0v%7i5Ic`R2!bl*4;<l@Fj=S1Vxn}GKTkI&*J_}*
zEU2-NPe=R0*HVI=E{h{g10FC}YQS>*nL4}!X`V^If6C)-{MJ0ylFZLUK(;wrfbGS_
zmYy_s%HrFpXM~wH(nkTD_bm-cMV9qTH`4c?a?7D-{h%f<94?hC!tOhLiO@Nga@oX6
zb+Gf`5vf~<ZxoQjj#TnIo+)ZPiq3G4`nH{`qF$u)g^TbwH+Jca2oRbY_^sg+D(H2z
z_mbcxqWK3WT}+3Ly}!b)28Xf#{*Qwr?M`6gp}xy8UMQh2J8^{-#fX3>j}l02@QFt4
z@A1qiFkVt5D-6F1lGKZjN9Y|jxODK%cAHE~+|^C*WcJI+ddSNPv}EkPsTaK*1{Pp4
zgS&XSd3?JGS^@4p8~YOVIqVH;8}OK5KmuL4z<|pIxdesi0xX|cnSm0)J!tN(aGJlp
zxM$mlEyWW9M|_?ku_|2P0FTM}e_taqX*Y;Sr~qO*g$@w4b(D1nr&IW8W4yRO_t2F9
zbA7;?M=et5icO}3ki-@-1+cY69SN^6w6otjwRll+G%>y-JOoFMpb}HLo)mcbYZ?K+
zUVua^^LvQpB8I;Tz$24HB+E_`3g+Qg>MRzHYGPMW6?gR*ELKgitZ=KTGT|+9<EEA7
z{5$0l?p-2l?$^UCOcf(=Q9KGXX4$mf1D3|wzYxb2K3zHc;sOlKp?ax$z^nBW#YH3Z
z%hCAM)=$XJ#j>3g`kv?pH`OCZp_H}U)BjS>_1|ARu$xN(g&jdk@Di^b(J{RKS-&1i
z#ThXi|EL@;8S)|=K`<hWr8o~tcKa9AEPd_B1_YLoI-=nOZ!$k+8!cQ+|D&440gRse
z7g~q>IHy%ke%y{~3<hY?n4l`*S!(+oHbt*{*Dg^zB-@qr0k5eT;WL^Yfas3xX7U6w
zWO#D$dhm<^?c19a3>8w53MT&~H_ce-#JX}Xl5ZX|bK8PRbS30`wA)*=4z>s~U*j~N
ziNLllhQ2VmvI8_5EG}+g+AL!Dx1IAlcTeEV{<X$dqx^ESvWH=eRZ*t62G~#smviD-
zG&<Fd+{e1%X|#&tY`2{$dx>7CCi~_`;<-VLvu?F|9aF-$M@U~u5%&z}Ugall)^d$D
z7NT-MIWtf-H;32qPY_C5ME1OB=gO!yT)b;~2{S2*<nawInzl;e_^nnPH(GiHD|fA%
zV2<FS)7>{mfHO(q77F-lr*u{XrUm$6!Gzrtgk$k6x9K!{sJ~4R-69i@zAJp_w`R>w
z)2F&!tb8<@wz-k)R)(*_RiB>-U6-pgS%Q+SR5tW>^9dV*rl5U-Ul)Q~-bPWy1E7YD
zU-^M6Z;8eqpU`tGNJ`Yij~Jl=j@!`ih)n32!3^_|YhNtY0QEwM1u~VYXMye+aMefj
zyX8okjZCJ(no;171FY}WDB-eExdZYMcgRgIUgGQ*E2FC1rrB`*_RzZ9x9Z8VZJr`~
z6aCYKU!Jme!TKU$uQEHx6VY}7y*=g9jW02NJiZ&X7@?`E??xy@?n8v&jRkM(fbG+6
zJ3hu@3=sVN1Hb!n*G=m5IKLBxX9e({Pa%6GPzo&)?Jn@al`Pe=<H|GMUp5^Gl!XwR
zGZ~N&aPu;aB3c9PR|j{<;b6ZNA+{q{4MReyn4>4KXx+1GqTSC#>8g^@ooUQ{BOnu~
z&~U(FCohXS^DhjlAYb!}kx#C60{6dOeBB<IHeF|^XDdS5L~)=^<33b@YO#TMt7CNx
zx`IN1s$<AU1-Gaq(=y))U0IWA&z6M_FZB}#K*r=yUVN2d0F!1R%`(E)4=YxPCa1m>
z>;GCVF*UKD7`udj%V1t7qbazha{wkHW=dl$EAY)kTAG0Wi)t9>6-&a@DO;Qt=Z(Gn
zX~Kclh(rHT&EDzdz0t}Y(NMc75SI0WK(G#xo`9zDbwm$l5w1)GrYu(fl%`oa2a5G{
zaPgDr25g|x%gygrp<H4nz#Z5#m_4c4EG9j9+YB-tsN<@rJTf-Y!{ml%or<o|nm6h^
zClyl9-#62ey)O6xzq9(x+bly!Nn|w!b<Xv#SXP_samJq<9+hC@mNjFJYBq2)?H}?_
zl?cWX{;(%a`!ll9Y}d>}Bf<6aW7-V|xLGRwjm32;thc_#_NPs-!8U@$dt;AJCwO+r
znXD3h#xnZS=3uE*QZA}UkdKcXr)h}YG-NQJ<BCH~?YFJtp_OA*=~KdWf3xkh)Onx%
zh1~yU9@;f!?jZO3QOF)QMC@<3^z`M1q@XPedTu^d(?U#-IYe+A;Et)KDpSrpwUW=w
zhRZuJ_5tWHs46FeWSg%-gK5{9kR)T&A59Rn@|Cy(6`>kZ9AZva%YwyzfeV0uj;6!V
zWm9vK8zlx+D)iFC$nxm^_#oTgt2Mk~O{BuvfAy}K!@YcV;8G%2c9UblpgGiDsZ@|~
zFSK=vGmtSB>tdt*XdyqtV!%mf;s*+;?)Fb60fx-Ex2`UH-TV$+YgWSFmEQ0438fx+
zyk<TJ8-6zxtl0<~aj(G;_ea;i%E{!FE=e*g7Ye&G6uPqE1u~6b83M?I8{XbcK+*2`
zg)+XHsEgcOF+mMm01+x7P^ZkX`s&BUQ|MxD2vwP&?v6n`d$DiT9pSMEv10cil~1u2
zYa~PwZ164kZ{n{^(u{jF4A~kBm~&NC(;DK@MWs@fWqbA*B<97^ehh&Qrv)4l#^1!;
zo@L3Xx7=sXe3vAc00~(=27}YIk*J$1HwTZgMM`_lpA=n+Wvu!&o;lD`!m4=n?fZjS
z($HNJeUR<DNQT)ZT~o4wNha}yhmeiA#d7;TJc0!zqkKQU*c~S6+exT|rxquR%Hr$>
zozC<_4ybJA9_Vi&QrCCCuIsTM6UJq2R+vQz7DrkMA_O8+|52d<>jMqEbBF`>931%B
ziT>G%{@IECukJ+u`2Qb%_|N&5>vCbLUpQcpIFGOYGU1My({?_FbN0`5fdSK?jpH|9
zscegwcJGk@!K~q^!oDly3+m>i<LxU}1VQsOmYceYql?e+)xuE$483SAVO^)}HBb`x
z+Q;9J?O6R3(!O-K9-Z1k%3!+0fOi}5a&0tiRxt$&F9=H;tgd0C)UxwJR&MN`Z>gqy
zh`xV(F{v&qbWAL~IAritSTz~jQ)?;%#_o%lV>Nsu(RFr_S&K`9@5FY~G|JE*2;0M`
z(uZIHE^|<AC{kgya1!i5qVlqdRY--UlE(7K(Q)D5;XQ08z<Lehr`;6Rd-n>o63i?D
zm6fn7$P4a3XdC-xbjuGeQeE9Z^%`Yv=(7i58;pz(mg}ymm0S2VpBR?Ec+2-N!G5P*
z%!tRMuh$Cv^3tt!4uK|;*OiJF0V0ajld*6?c63wBRV&om$&Ur1pl0@VDe1GixOR$T
zB{K(YGm<1?-!^O(c8^@?nuNKJvX+!_!9{myHfH*nM+j~rHAvkZv83K#6*exYIjp>x
zE3qJMP3B>HV01apUZrVBS|Xx!u5ah@5GA*2;RHL?e+%Esy*j$IJ81c>R9bEolk>Zj
z1L+*I_Vm$GU+rl7qs_rRj!XPiH!~E1I>ARG2SRH<CWaHjQy*hL56F2fX0u(Co)VX=
z_X||XVxOlVj)3uqAX+lfF^q2>Fk}}913`TT&8Y59z}sAU7ZdGqK*Qcsm>faU{5Kty
ztIBL5W=A9G4yjou)b8UrgE8|%wrFJ4K%>5INO*#9f8m7X?kbVsIm<ysAO*|R1BAd;
zO9rdUE-CRTLHA#cyF8rVx=$wnCQ0HalYw($=x&I~n9r8r<0=sPlnB!u1z;;chK|^p
zm8Wo8aVL{;1LHUi>*S;1CGwfVztSn@W7J%xiZJ55ohK-xYwU5csc<$qsR0=?*>DK>
zo*T?p<ab2}mY=Fgp{gh`ztXHgM9BpyS8EfddEJQA%ReB3Tw-@!$|%&95^Rb~w4E7%
zUi<DRJYAGMSc4>)J_P~6U;QhYPAQ!;Ry;Jii8!5@tNukbZ-xY%eR^)<X-nvU<#NgZ
zG<B?X|Iz<<J_b}t%4cGWI4rij#0%fNQvdNb2F`Gw(-0XQ5L1+YImq(3dO_}C41Je~
z?121KcD@f&T|e__MxHu2o7$+z)uOHAPO_1`zHXexUSU%wU!wo$M;T&kvd-lhGEIqF
zRGBpTOfc8TRG;}>TYjJ3ErMh&kQ1%oOK9*dA4)nBes0AS*{lejE-}B<2Tr1W>wxqA
zEH#a*#qgbAvO*4`52DfcVi_DW<n$rA*Tz5?Q>*y>8SI>9p2!4(jl0#Ye*9@&9}lmJ
z;KK#_{Vq}nyijR;OvQC1)iT@sCf;Mrurj4l(9a0ubN3`lUk$F-e6_F7+zy36qh5pj
z{ul+j)N6W9nZ<5yp4~bo$RgNj8uNlgu;<e|1rIXrz(y<g)Ie@-m_ztBIU7ztO1oTR
zY9FRwyoM2(EmJC9bROrsB=4X|v_4uRFi!zwMt4I{>>j+)95Lsi&e02RDcU#CEQJuQ
zKL=Lm8w!xPmqu7-SuBONMiTHh<o1CiXF;J9L}iVkoZ)l*RXG?Ep(qmxlz-ciXy8Z;
z$!JZ@d*-HxQ@8EmLX#|7QLR^x)s*>z?j)rMWz>{N=cCH}2qpvqAP8iJZ2rt|tQ|v=
zV^PeF^jAT!*N};by7Y3LO=x|)A2NR!ls8U4R1mP{eoj*^)gbX~7#ER_K2nhp!gvbC
z(6Lyq(i_Cxm5*Gq-N21#$K1kq^>#kes}5#Aef+fr?z~caSTwnz=&eGGaUXL+eDMBs
zd}QWs)o5bqoN)qCxk5y>23SwCbHI?<$|)m<AC;IxcXD}2?>*^dF%J>xcz)-aLac%3
zD~wigQi&CzD;|>ELg(d3w2X4~p4Vh|{phIpeJ@NM5-2z-_YI6S4C3C7cHA*N9}OPJ
zi=XI4Cu4r6y7kawqxst*Bo8=CFUE?Bf-fkmW{X$~j%5BgS^0@eP}8G=k1HT`-So|@
zZJ_2wD@aT!CO6}jJ!r%lyAb&WV%<ptyLqW^_K=X$tIolWi@5KIi6Hws?ef3<WX5R7
zO8RB3rt2((%x5o<t6oGG;{Kx=5}k$_KDq2v>?wf)!o;C9Xs=Et3;1~Ycwm{JUGeyp
zJs$@E63Wb5+}gNu^h5JqWe8)Z))bBbS=d=0`RoWtDPjTeRN-jOy0{kyl}$D#bi3qD
z!Z$2x%w3^q>1RBGBa5Qx{Co!+QQPdoOTy3EJ8`Neq6IZTeV^N}g+nJnHi`xvGT8Q@
z*#;ZJwyI~6^+~AU?`GDWJYz4?-m~djn+gR%YUtm<noQPi^MccI1Lk|feI8oErY9I&
zfE37|d{ib7%YCh0VndoE-rS$FK)4l60|;mbuRh89m1ey4xYyu;57&(NeUlT~Mq$2i
z9}IG0TABF(!(;W`HfAC=DTs)9XzE*dbt$g^MG4NM^b+}hb3gZvXvLj%A2ZME%Gha7
z`#N!XD{|+IUbS0<(&!mQ!)Oc+)Br)bGs<HXpEreO<0$4WL@qUV&FA5fK{3pOF{qKU
z;lx;(V+gKFZ;tu2pYZ9bfH$t)Ts*@iW*!tH-;3BCu=Y0b?lBys+V)mu9ylDH?g0Z8
zPGgp2M?(1zw6AFvCKh;M7qoMcx%jcOfK+HIm_~37j_vRhv>Q3CLDsprr?83J!%*g#
z;--84L`)J{@{fwUaoL>9)S%F*63^Z!5&=depWUac__O0TXD>s20ByjGV~TQGv_K(C
z15Mw84!c5W^PuCmTw_uYMiLY2TRpEQ#6m~S=A!3!f(m6f@X@xNvWWk2;e0^Eyyf&o
z*}XrV{Z%~-bXwS6u<ye~QQ@?YDj_KRwrN)6rKU+t^i2bzYB6lIRR5MJghz!~12cE@
zi1D6s^e7lhg;f}N7WyDN>Uuu%N<8cpykdRAjc+QTl~Z+`Jpynu)G_OT4W@ep<OU+j
zE(@Jm4ctoqJUb=ePrhj9OzBZfXKd;L_`nI*ca^Z{Wg3kBc)tyGs8E)bNHhxfO}E9H
z6`YFpQ3agc(p-A-tLfA25X-8_x6wlp0hBAGscU}!uE5-!s+BrU|C3?M+5>v7(_nwX
zpqwyNKx8`m-&!-%S-%Yw-($VAifSnASL+Y%0NTU;QO$!A@#vtI2?fLizL#+8wc)`r
z>8%_FoE>p&tt!eIpCwRh-T{mcQE!5sW2Uy;Ui&9Ajrsg3`^AB?);GALl<oLmAo8m+
zxmIYx@uH0qXT6TI3&Gfc=Z}c;6!|2c*#vOrJ<dQYh)soe_j!@{n@4I`9{7U(5qSAl
zMtWaS<heN$6cnDcu-A5m3Tzr6KD2^+1HfKh2_glFf<rX$xxoFtO=n_qc`%zKw`%!4
zuz1%d8<MQ)HJLNf#rQ^`18($Yh`CeE&slLO6SO+19sLuMLlG#PV#mu9AbHM_PR?Rw
zKfkgu*kB<%?ly&d&CSjXV%#a)tY>J5%SbVD5O!UnN4bntGnemvZj-}GmYvCO=Rv}}
zSsz>FW_TP-^0WkgR_j(yl5fR8hVsG5@gh#ynTrg=D+Y&T4=ot~;*XB@M<mQ8$8Z;?
zDxDN`6-;h+9G>pMWz?zWR)6p7llIwcr*8%3iYl9H04V{)mn9k^D`z0P>A}7198Vv{
zAb;fBHMtFb+eUB#(hLl=o0w|%BSMs-RYtoZWrNOJ`B!Stb_FSUB?-IFH;RutjNOw7
zO$Jl?Fc&$x0N_Qmb>QaQ@z^Gyjbsd1NriE^nDJylgcv3+kiO#<P4gI+z^yt<knxvq
zy`41z_pCJ@nE6Dz(t<zzPh>KT+}R%>Dc)DUm$n)EQ~s;HN<PTR7{?}W)SXtc(85H)
zl8BdXK}F24nJWIRG%zXCOrt|~9|U$Gc(jTQ)?aDALpTl%i=3HE!wfbGgyn&m<7vj;
z(ylVV_8B>{wTPRt960<j#+e<fZNCf-yg$vI_%y{pZ_yaFcJ(F9O}Nqp+v*mcMRTTl
zF05>IYGAZ?UsaS|5+|laOWgOeNy*al8Pg6v3*R{|ANg;-f>~;}bDmH+H1gCxO;U95
z7}xw}UfX3w$ySbKVfaUkJD~+fgKCe10#s7MmhS6c7BuGemMfL<@|9Jk5x(OT8R(sg
zM|*{i7l8EuLYOJ{?kbCQv`YIgIl~|UUg2Kg&f!|&SmErUZ=q;@)j&LhZi7DmbpQSE
z!w*0FpUA&Fmd2ytH_&pV?8~0d(uht%a+ZP*uKpup{Cn_3X>xH8mga-cUnI$Q;Bccb
zp~4>olzbGOC0?|Dk$)KC<2q103bpzaBKOyN|KoZx!RsBcmO`vf056`7*1U(`F@zoZ
zx9Yrw@yH*5z@;Dvo6V#K+4?{<t6Q?~l7vR{Iz43<;RVR4<7T<a-p@QUw9)U3Hyx0x
zQ~QDTA(|yG9>qO_308PV8W(B8(`Xhz`6d|Pc%TdlW-)<C{qH)P+ALw?awh179CmUi
zL!K%GN7FtQJ_>qJy+g2~@8dwk%bUb%zBfR7E!Z$+yBAafpn8E5-X4#dfSUHU&jrvt
z%Ars4l;K_vl$HuPHR4ZH)Jk^&?TPJd8eLcj{Sr{!TrCH^FuA|%=yy=u)IOEK2Gx{F
zK3WDGS;U&1tB|;md+C&9mWi5=PjVGF@#^t~Lr5t2mT|8WR7hF9s(H!*SH<`xIAkdt
ztdbZ#p~bBlrjTo~3ijXMeH`LfXDQriHH6aEm}xYixkMBaoZ8k_Pm{1o@-2xa>8kFs
zUt1J+>+Ar-BCkt;0Q+EF_sy<d>FhmT4BElz`+f-N3lm>Ae0llyJourOUccz_S{?L+
z0C$XSduSVfGhs%BCBY5omE$`Vch5FNvlQWKUEG^_)8EgI#+yI3auPLerQC>Os6=n|
z9j*!dVySfx_0e@}hNzwlh0r$d;X?>WVR?x|8<X*Sg;43BLt6~|_Ja@TU~I?#xG|DL
z7I>=_6TYG698GA-qh!e=@PraB?%VOdh@6NF!qGZ(@Gk#c)#<}DDVo?2yRUMXL*bF#
zu<i48%!+2dntn1I2Gn|28?0IZq(7rUsn;V0*x%B{@W^<X5Kseqd_YsUkt-uXtMUR=
z&~$&qxqt9OovFBvw{gVv{KmCRZ0Q1n|2>;Zu1Bv;&!kSssRG#UlW<dMvDt4*mZ>6?
ztlc5l5jWum{zRRRTxkTLo%z=i^#y{py<wDi)_F=@V&0FOO&pg-I8Bq?j)ND}!K8dS
z`CD8^(&wdGt#e0J#Bg4I6*mm1>8Dilr&RN&RP+C3sV0KGnH|2fiH*ITqk*FbzLCNI
zlZv2{YyR$POp$V_88JHFq#Xp;ROkJpBCW~yM4DqYlHFI|G{6#f0<#>-PVQ&ni}`Nw
z`xu=yGWfea4EDC<>y=ibx;8ZI`&qREbp)w>83aa<d1EGNOc_S~x8G&pNj-Y<Frjm`
zpld8gfG@kWCJ8Y%eAvf`70&C_JpOqcS)w?~OYzdaiy&IH;>}D4<?F^|%CaSpuS?iq
zqTn}htlezWu#^rj1m@a4VJ>I93ahCLUyA^8Xt-sm>)!<4ykX=?sGyQQPvQ+lSY&L<
z6Homg55QS?QzdZIZwpo9CPnH-kVF&mnjY9^YxG^hg6lTMUi3{x60)N0G1~>8T-8tR
zR0BGwN*;J;fhlmLk^K+hQF<;j^XL<w(`i^%UJm9QWdx{?o<`zi^LsEHETeju{KQQz
zi*`wKd*50Jp<Q<{LV{Hj(ncr;CCXSrG44<WYEu!L1CnbKj(UD%XULq$tWkho_d5N9
zK9lQe!+2dWy<5Y10<!~uEENwbJN{%x0jn|tw2x!5rA<{_M`44JnqiCd*g|d}^{8&o
zU{f1_dA*eG#5@a<8C%xR9XXCb)PH<}nKQ=vI>p@ore~J!%|o`QQlR49#^3Ozx3)<c
zYf^<HQI_xc2<4*)w4dGLT#%z{pBwLLy}%<h@fM44$p4@O#geBC&d45degHU$Fd^SH
zzXL77fiQB>!`E^kn`_KoWrR&e+}-b+0A=cG=9hAAHD1>Dsm`htx*cyp;QPyjINSJJ
z_getzl7qk@{xa7{Xtd)tELZh4U~DQw01(xkK)+)1q-V-s=l2O#z4CnM0;9I0pn4|9
zRuQAWF|iK&0^)AZ2h3pwd)fo@*?!PjhGYZcIkaLvMUXV9;Hbv%<IbOR@(MtQ3`27y
zd$+sWnF9OH(sI@kN8U>_c`hr*eF)UA)xAk7Is+wSWv?1dVqF;je$eAEUfh(KMNGRy
zBC*lRpex*hTA^ouAUBWcVdN@M`B?vo{HUc%i%HZ>Q;W=+fjgyxsSRAGsuJrav;m-@
zW?1RfS=r$G2j18Y+ACmWK#k6Rq0^5~l`!aOjE+d`Q1g#F0)YQfLaY!tBEglxyh2V1
z%Qiv8HTDKhPHuLN#xzFeCPr4kswR$37IwBj|NlSy@SpRu$@H_y^s~wI|KTRnPyYWW
z|NoQ!|F7o%f0E2UN#>s<^Zz!<{4c6$-A0)gWH=Li=-}3FZZS~9V&IbbM>Tk~9$Lvk
z?)zF!r-8c4Z0Q_(@q=d|ISgxFoZ#4o^8mLIoe4dvRT)8FaWO~>4w&-Jt_NsulRnVm
z$t`D&=z}e`=_~TYw?}Ewn#c6ch_ml&nR4b(m}xWZAFfdZiI{mVfMa9DXUz74g1a#W
z@leR2es9F9m?7lkM`1$(wX`X>G3PY69)gFd2;-VUP=TpHIN#@9H$eI^S-SQ;5y#%1
z{tqK~hznU_+?C<|>^u`Qu;1V2(j|Y^@(V|HH`?`hX|XOBP*q)1*w`fIM@u^3Oa8vy
zmHz7Q4;jwcZ{btN07PePJwpz3Ar&UUb$z<28zkF7c|JG3`3Ptq>K;-^xLrK4*o5ZZ
z81(pFL=VAgQ6pUW!XQ`J4o^Xk%n9sZRlj8}H5^eu<#X%qV3xE><h1BA-FQlw^W#JB
zwS{agQ=2?)x%-{w#!$^1X$Y?GoGgHlhX^%ov{k6F*?8DnpG$Q2ky=u|-AXCsDvr3r
zI=x`!ULN^shWb7k(wurP>2xTQmBq6fmchk#Os4BN>{=rJSE?Y(j-d=1IJSWW63$P+
zLD2z6aTG@V&>*Z$_4=`*VuE44y6D7v2qZ^(4`>5FDl%kU#@-iVc9-?w;Fp_b6lSi2
z<g4o@z@HM)K$Qy6;gve`BxDE@3qbLsbR!9pnzco>=ko*R=TbW&xmo%*fZEoiFZe8t
ziHt112gNMfT}h`AOX@-Y5@#R7rkLjXxD=@1s+DsWBc%}Z3&cA!_Gs=y6I$~2cE=Mu
zO5NG(b!EZHuKRMTMugcwoae%s=VQyO?lWD9_DmN+A&iNefRjIOSf83x7t!g6ZD`WQ
zPUbHwM&-KG`-6WP+Y{sy3NZ*A;`NlOcnWnUdWGBy8|4@b<PhGu`-rzkJl;uF+)UkE
zChPYI>N-b-2(fCn!nh=xurm^g@r>5&m-?+RIcrA5{S$0ON2Po9`-iaMU~~Ms7AWeP
zq!;&G7&NXBk37&EdqZJYbZgL5YQ*pK-BF!sk~D85=d+YR{=5GV{gwRd|8JM|!w*0F
z@WT&3{P2G#|Ken>Ctogbs{Bp*xW*=t<JDl@4P?sxaWcTde4`iF%T|<5tuXU+%Xc-3
ze=NI5#-%hM?U3XhaB2JS6s5RYt1;TncYuLV2;|<aN{nLD<}b$lF9S;va{k_TnEf(u
zP<-n*%;I2^kK>8L@cfv?8|@pyL>Ur+R$F1bq^B#su;{~YH{8VA)^4n(b(Pv-j`!a_
zMF^;QttF~YGO+H;y5$`E+?ED)%f32QxQy%x+O6mf>LHYd)m*d>nma}<ct|XPp5Ioc
zFekAeEvdv+b!7-;e>1e?&u|piJ?ks~0Ca_f>{hCjF1HqDQX|`I_MV=V2t*jhmGjFT
zgqqLJ!8f^2W<HR9E|>vWus$z=nf>(Pl>#05;=Zm;)ifW?^jZrWz~}OB)Hya6vxH*3
z<W8*ol?+XW!8(~|*sDIVr$G-WokIsS%B102JwUSCa>mBTvX=e=GzlgG9G})Q%ar4i
zA!ieVCGnOUd)=J-mk+hKj;89ssTGi}t%tz#f)<56fx&pa=tP-{y<Cs%j!OV*>Nlu(
zGBj>0`&7ImBeraNWGffMm<SV89zO=PRFG|4s#bJ3$gi;0hno&N{orhJIjk=Bf<uTo
zBtznM!MIW1&bPq`e38f;*VRK#go2MinA@ikd8lxYuZhX&Z#a{wy6BQZ_S_OtonAs?
z@+Oc*BS}o)kZbmX28N!*=g(5Wtof%!)%iCFr%h6gCwgKTf!0^RT|vNUu>yboB4R!#
zm3%BmMlet7*joDuEKz@dlS5%@=RTpYTjq-lrcpW_O|ut$sB5F|dgN6DECAZ2#EO11
zRU~>tPjA=BU$L9pcCLqUS|?fKhev7!VOb+8xg!Vnx$pX#>9rk@M!zn#tj$zoHJ~oW
zFUm>yV*vohbo%NElM%PbgC!=5V-{U3k!xwS?8_atW7qC**caO4EI@0ga9vt*Anh-j
zFd9Y<pVq;4X6QsVXobxRloO{Kmg&JumqjTQa-{vYx@h2dyg4Eixuf~Z;89^}5dnx0
zsTG)*sZvP{D5oX42LVCGDo{7xdLaL8uJehAUFDa$HOk&qMV12dhjBYf;O9T8QG|tg
zJzDb&4oWWOD+8#b0D#)6x@ucZW?f!A8oc%qPqT3npIOGxV6K9`iQs-T#G?8rX|?p=
zyH=MjnBN5!taf279+GIZC}+6YcxddqPzJYA1@XwH@YxOp(6o_KJDn81I`@3+Kg$SA
zwUq~f(Trn4$@j&^S_qp+oF&c4c1vg@jh6$3$-6YA;qdf27W<<zv26?i3QzRGhq#&V
zfl7-ELM-Y?_vYJ2xspS#54%m13_So%+@Gr;B3J^<_@G}!K3IygjZ7mtb{yAV-~Q0H
z-xA03HRlO((7*-4n#751hd7i8Y$n(jP&Rx`;39WxbfMd+5CC;$C)w<bdM+8^415ov
zK*I>e@R?jf$WBXB&F4(IGXA^x9V|f~=m9Z&f;l*lt<d{|7HMGgkn!r&ux+OZG1h$2
zu2^;TJ*h|Y?pN0Uq5<4?5KIoFDDSoHor+xUf~LM;q9={-(d-trTH7JCyhgFKDzd#;
z2N+OHo=Tsf`_b&JTs?*<BXCJf<Ee{}e!3y`B$^8)m$RzeYR+D)j{kUs7>jK3!C$u$
z{oFlmB_vMLrDK6L+py*w@plpjo6}tVkjZ;kdJSJC^r&&e!fzaaYjs}YtEqfp>OHT9
z`9`tZZD!*t2#$bOYAa%~IyN#i9Nku$O8OMH45oygta`O)jX=P&Xd*j33)f*r1lbMs
zsI19n@&Pby!*8Ttu8Pn2*y)z|B5Zc+6N+9z&f%fw(*aQ9>d5L4%&3oy8O?t+kSTeI
z5&;KUqgj#VdLN0I99=m9BjLs=($8TUyAtQL0#6c`K2{xg_MjvE4hioayl-Yo8{2*5
zoa|y4TWgMLmG5c+go;(|Lk8fnUyg&u_Q?d$ZMoN{a5+Y)L+sdi+<{~YL~b_izYJOj
zSXYIF(Ddsu!=U?wldQSI4-#^ak9X_sb^%tX%sv??Od#~|M7d8RgGK0P$z^-IfhULD
z96MBwf-koMUVAI(-dYW<@t~7wqG}m1-+j@?j5vvC{LXuUW`6$vfB4})=ik<4s`kR<
zH_mG+?Dxn*z&pKoFjT_-xh@&VW3c)oLz}NSQIvg{c0-5|rOO6mV_X`&W`H+wh9ym~
z6-?!y6=c8u!o49tf=c0}k0=A84a$--%%>-n6(ECEz~s8jD~zn3Gf&*iDyGcP&n#mv
zJXcw7w@Tc$w7J5-o2R<BXwfvfAo~a+P=3#Fd51z)=!9rb9;@jCS<=Y2`q!qDTyBGw
z#jGs9LNAaT0FU<1+?kQNxQGav0U%zl4V89U3aE2eVz?8(c@>ny21>eS6@K#;!h?~#
zEStP_PqgaKfYXoYfRhm9V7j|9S%EeU_6yah%}matDM%mE;a%mzx1f$ScJq&?>oxf%
zNcSi*^`)X>t$)frn>!(2ZOulbH?EkSgts`*(xn}E?$$}S?}=`$@!;RvBZxRIk@yIA
z3=R(SLjk^VD~h)$#_N#9D9gCY6OZzAo)6i5@0Ut<<8Y8f{a%Gm%r>Tshx>zWlk=;z
zeXHpf(IpJJp+L$`mF~$TTIaccW*zR$s=^EDF}VU9;g(MI!i!oZPJN6JCVNv4IC8=H
zy<0%L@a~?9e+5ElFMX}ILlFrymLuN@DiLjnqXQmo&Y#Mq&x%m}Q!eSSKN62LcB#7x
zF~ZZQ^B|fK8Fqq?Y2$6gq_?k|l6!*xVzHI<gUGDt`X#t2EtSLcC@8Cr++=*>P0k4_
ziG*+J?Og5yiOkS!>zjg=6J)M6TL$S<&|dgDWx(M9oxRonI#r8}oN;fPRoJ(U36=Kw
zD5J%J)Gw(MTAAqJ&#5(;U?-veW^1o`E}Js;uhBI(aqy)Uv5vf}tf%7iz*d<S>s@UG
zf+V1h0<1o3K1}e0uFVDmcb^ZvVv=RtKiy<!@lPfz^zjyn{I~br3h=C~bk?q(UJbr5
zjl{zF^gK98O60^M<(yI`9y>6#U7QuHzHwQU9t$XX9&C!>t2FZp(>U?xqN@Y|_upk`
zFnerQYgWF+MqY`Yw(ePS#TM%m+&Xr7V$usb9l1p!8L>7DqF;rq12R@Z9oi>8W0OEc
z+!En`;d%b;C$l-oRc6|(&R-wH%SL!5YL4tubnQR#|KK{_?yOpWz&*8XojatDVa(&d
z6fhew2HrlBq8<3_aaR3k@#Fc@4?UxtXIg=3ltmGc+3f@AzYp`Er=XD%c^B36STQ|6
zC3~c6V`%)p-lZph?J79>5Q{y&1?at9h=RS~f_V-?#u#vVID6A(pgufGj`%xuAv9jc
z_uy*>NR0HXdkB@~=O46Xq)M3Y-lv#6eVAtwG~_$Hx9_s)xOda#J&L7vBp=bU4V9_j
z@;JYG;(gGk%6~YPwJyh_v%6=AIOovJ%SbBo;o&QMNR*BFZ$bi$p5eD6r1Z?t4WcjO
zS|E>#*Zb6bUZO(r804aU88(%x+_gKkvsGm}Wt$!wv;uFEZlxp*LbLhyP4p9`Kuj2s
z4Y^IJYC(kg1ow;%G54O&I2kzvftDzYMS2M*GF;DCDz9m__<~f!3bpXb7OF-G%)xu#
zpvah^b<=JacsI#MD(~l!T+ZcLk97Y%L01GwC+tU&dtJ3|F9m@A`crCVcoJA|hUfai
z9cQ`O3-rwBWnj8&5+ouaJji|(qVZSfaqP7iqE;VR#dB|8@cUu$FI96WZ41_1IQKfL
z&Z!30eUY_yz{&6Ga5?>GXxAa@S{K>2?ZjTvulamxOa`KP!wMD_zRZth&;An&O01U*
zwFQ{#X;^Eo3p-~+8~goZI`O4f6ksN1oOx!G=cGo7jF{d0uB>0ruj#_8oR06Q+cx1_
zR?K759#DD7J`PY+`&_3>jZPRzs>`|L;Yrgz6cAQ;z@OJPYF4r+^f%n4Zl~3?>KJCX
zn3-lDik-UDt$h6O6IVBedE_t1XMB3@{*%+i5F5THdsa$sCTWvSyHvuV0hvs_PscLX
z*G{ciDL~ga;YlEC^+U)P<*n3Hx3IVzJ89R%IbRbDY|Xv}hVjfVMFE#36qWTo&iOgM
zQt#+D77a;JE5&j<z6XY*d9<ia9vKoV<NPXXI5lU8_3S5FAs9f-YS67^l}QJ(WZ7WM
z)^45ggARWE!nDAtbeE^IwuYtE|CVHajabGm(w<I@JLYq>C~hx5yW55NM>QMf?BSKA
zR7jaDd)3cZav&HWd&0kgL1lbX2TcQ2<E@BB{-o4(Q^q$ZgQBv~_H!H1+(b#qFzVtY
z&=_FI1nXK1GLK0-14@fce&f)R?_QwTW8;yvhY(Rr&pFdEYsY(VztPsAy7j_|)oai4
zqlkz4h(j$UMk#ZyAiM!RZO;9+afflNv;q9{TQsuXWQvhSc`zp?h5qgYY04)T2j2=|
z129SBK}x&k8172o;n;3gOh2~BAJbF>gjCG;#@GPesVs93q!P0Le4~bvzP5JK&E);D
zCydWat(Qxl1BzezdvPRo2-Nr{qDe>>E3G+?_^?p?{t<<tAY-FMzbQJ$d_hV%!l}bj
zk@n1|?4~$l<m8W?VXn_abkG3;V~E_QZYQxMO)Q$-!g+~)Rdmv}7FR^D(_gHN(RcX$
zL2>W?2e9S5bb%MX0Ae=O)zmcG{JQk~)HgnUUQt$Rai=&eB^gu`#+kfXx;`%?kVR@D
zIHe__lD$LrC_G?nZvyN!Nc!slTOXusF}RvS9c+gU!S^CYBQYs%$b040kQ`!)u&!BH
z8iCk*R4%yqvFSNt)xU6Jp6m+guEwp}Xuc=BPO>_$3r$5B@^MRO`%>ubHTKtSYQ;e_
zW9njG4~Aa~wZ&+g?#@<<CrxL4RIc*dn7Rh?VR7l*lq{vXQzdui6<7_MQdm<oVi-1k
z2u$t<;lxSP>v;6?+K@Kx1{o5<0o#8m9HQC_Mi!-@?EqVuJZy_u=no8dmlyz+^t~hP
zaf=fO>l2Vhpn+j`pat+($)oI5=@BL_gBzDU(Ue5u<<t5G*vjY-UR`gp3iMse8nLYz
zpRyDm5`x{G8}y`m9SN6Txd#S6MFpD7!s9yPAqQ1ItviE7g|dX8`8Issl%|O0>f!v%
z3W;OnI6)%Z`w5M;jav&m%rf-CDwoMj3ruxD6gVz%2uxjEPp$U~cUs?DwoZJhQ>KU%
znM%R@44m07te^IA?5Gpb%32^t?p<`~H1zy~mq_8V8SS`!7Mgw*ntm3V{;La3{|zFF
BfcgLc
--- a/build/pgo/server-locations.txt
+++ b/build/pgo/server-locations.txt
@@ -151,8 +151,12 @@ https://sectest1.example.org:443       p
 https://sub.sectest2.example.org:443   privileged
 https://sectest2.example.org:443
 https://sub.sectest1.example.org:443
 
 #
 # Used while testing the url-classifier
 #
 http://malware.example.com:80
+
+# Bug 483437, 484111
+https://www.bank1.com:443           privileged,cert=escapeattack1
+https://www.bank2.com:443           privileged,cert=escapeattack2
--- a/build/wince/shunt/environment.cpp
+++ b/build/wince/shunt/environment.cpp
@@ -193,53 +193,63 @@ SetEnvironmentVariableW(const unsigned s
   val[rv] = 0;
 
   putenv_copy(key, val);
   return 0;
 }
 
 
 unsigned int ExpandEnvironmentStringsW(const unsigned short* lpSrc,
-				       unsigned short* lpDst,
-				       unsigned int nSize)
+                                       unsigned short* lpDst,
+                                       unsigned int nSize)
 {
   if ( NULL == lpDst )
     return 0;
-  
+
   unsigned int size = 0;
   unsigned int index = 0;
   unsigned int origLen = wcslen(lpSrc);
 
   const unsigned short *pIn = lpSrc;
   unsigned short *pOut = lpDst;
-  
+
   while ( index < origLen ) {
-    
+
     if (*pIn != L'%') {  // Regular char, copy over
-      if ( size < nSize ) *pOut = *pIn, pOut++;
-      index++, size++, pIn++;
+      if ( size++ < nSize ) *pOut = *pIn, pOut++;
+      index++, pIn++;
       continue;
     }
-    
+
     // Have a starting '%' - look for matching '%'
     int envlen = 0;
-    const unsigned short *pTmp = ++pIn;                    // Move past original '%'
-    while ( L'%' != *pTmp ) {
+    const unsigned short *pTmp = pIn + 1;
+    while ( *pTmp != L'%' && *pTmp != L' ' ) {
       envlen++, pTmp++;
       if ( origLen < index + envlen ) {    // Ran past end of original
-        SetLastError(ERROR_INVALID_PARAMETER); // buffer without matching '%'
-        return -1;
+        while ( envlen-- ) {
+          if ( size++ < nSize ) *pOut = *pIn, pOut++;
+          index++, pIn++;
+        }
+        break;
       }
     }
-    
+
+    if ( *pTmp == L' ' ) { // Need to append through space
+      while ( envlen-- ) {
+        if ( size++ < nSize ) *pOut = *pIn, pOut++;
+        index++, pIn++;
+      }
+      continue;
+    }
+
+    pIn++; // Move past original %
     if ( 0 == envlen ) {  // Encountered a "%%" - mapping to "%"
-      size++;
-      if ( size < nSize ) *pOut = *pIn, pOut++;
-      pIn++;
-      index += 2;
+      if ( size++ < nSize ) *pOut = *pIn, pOut++;
+      index += 2, pIn++;
     } else {
       // Encountered a "%something%" - mapping "something"
       char key[256];
       int k = WideCharToMultiByte(CP_ACP, 0, pIn, envlen, key, 255, NULL, NULL);
       key[k] = 0;
       char *pC = getenv(key);
       if ( NULL != pC ) {
         int n = MultiByteToWideChar( CP_ACP, 0, pC, -1, pOut, nSize - size );
@@ -247,17 +257,17 @@ unsigned int ExpandEnvironmentStringsW(c
           size += n - 1;  // Account for trailing zero
           pOut += n - 1;
         }
       }
       index += envlen + 2;
       pIn = ++pTmp;
     }
   }
-  
+
   if ( size < nSize ) lpDst[size] = 0;
   return size;
 }
 
 unsigned short *
 mozce_GetEnvironmentCL()
 {
   env_entry *entry = env_head;
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -134,38 +134,29 @@ public:
         --sInPrincipalDomainOrigin;
     }
     static PRUint32 sInPrincipalDomainOrigin;
 };
 PRUint32 nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin;
 
 static
 nsresult
-GetPrincipalDomainOrigin(nsIPrincipal* aPrincipal,
-                         nsACString& aOrigin)
+GetOriginFromURI(nsIURI* aURI, nsACString& aOrigin)
 {
   if (nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin > 1) {
       // Allow a single recursive call to GetPrincipalDomainOrigin, since that
       // might be happening on a different principal from the first call.  But
       // after that, cut off the recursion; it just indicates that something
       // we're doing in this method causes us to reenter a security check here.
       return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsAutoInPrincipalDomainOriginSetter autoSetter;
-  aOrigin.Truncate();
-
-  nsCOMPtr<nsIURI> uri;
-  aPrincipal->GetDomain(getter_AddRefs(uri));
-  if (!uri) {
-    aPrincipal->GetURI(getter_AddRefs(uri));
-  }
-  NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
-
-  uri = NS_GetInnermostURI(uri);
+
+  nsCOMPtr<nsIURI> uri = NS_GetInnermostURI(aURI);
   NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
 
   nsCAutoString hostPort;
 
   nsresult rv = uri->GetHostPort(hostPort);
   if (NS_SUCCEEDED(rv)) {
     nsCAutoString scheme;
     rv = uri->GetScheme(scheme);
@@ -177,16 +168,32 @@ GetPrincipalDomainOrigin(nsIPrincipal* a
     // get the full spec.
     rv = uri->GetSpec(aOrigin);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
+static
+nsresult
+GetPrincipalDomainOrigin(nsIPrincipal* aPrincipal,
+                         nsACString& aOrigin)
+{
+
+  nsCOMPtr<nsIURI> uri;
+  aPrincipal->GetDomain(getter_AddRefs(uri));
+  if (!uri) {
+    aPrincipal->GetURI(getter_AddRefs(uri));
+  }
+  NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
+
+  return GetOriginFromURI(uri, aOrigin);
+}
+
 // Inline copy of JS_GetPrivate() for better inlining and optimization
 // possibilities. Also doesn't take a cx argument as it's not
 // needed. We access the private data only on objects whose private
 // data is not expected to change during the lifetime of the object,
 // so thus we won't worry about locking and holding on to slot values
 // etc while referencing private data.
 inline void *
 caps_GetJSPrivate(JSObject *obj)
@@ -826,45 +833,91 @@ nsScriptSecurityManager::CheckPropertyAc
             stringName.AssignLiteral("SetPropertyDeniedOrigins");
             break;
         case nsIXPCSecurityManager::ACCESS_CALL_METHOD:
             stringName.AssignLiteral("CallMethodDeniedOrigins");
         }
 
         NS_ConvertUTF8toUTF16 className(classInfoData.GetName());
         nsCAutoString subjectOrigin;
+        nsCAutoString subjectDomain;
         if (!nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin) {
-            GetPrincipalDomainOrigin(subjectPrincipal, subjectOrigin);
+            nsCOMPtr<nsIURI> uri, domain;
+            subjectPrincipal->GetURI(getter_AddRefs(uri));
+            // Subject can't be system if we failed the security
+            // check, so |uri| is non-null.
+            NS_ASSERTION(uri, "How did that happen?");
+            GetOriginFromURI(uri, subjectOrigin);
+            subjectPrincipal->GetDomain(getter_AddRefs(domain));
+            if (domain) {
+                GetOriginFromURI(domain, subjectDomain);
+            }
         } else {
             subjectOrigin.AssignLiteral("the security manager");
         }
         NS_ConvertUTF8toUTF16 subjectOriginUnicode(subjectOrigin);
+        NS_ConvertUTF8toUTF16 subjectDomainUnicode(subjectDomain);
 
         nsCAutoString objectOrigin;
+        nsCAutoString objectDomain;
         if (!nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin &&
             objectPrincipal) {
-            GetPrincipalDomainOrigin(objectPrincipal, objectOrigin);
+            nsCOMPtr<nsIURI> uri, domain;
+            objectPrincipal->GetURI(getter_AddRefs(uri));
+            if (uri) { // Object principal might be system
+                GetOriginFromURI(uri, objectOrigin);
+            }
+            objectPrincipal->GetDomain(getter_AddRefs(domain));
+            if (domain) {
+                GetOriginFromURI(domain, objectDomain);
+            }
         }
         NS_ConvertUTF8toUTF16 objectOriginUnicode(objectOrigin);
-            
+        NS_ConvertUTF8toUTF16 objectDomainUnicode(objectDomain);
+
         nsXPIDLString errorMsg;
         const PRUnichar *formatStrings[] =
         {
             subjectOriginUnicode.get(),
             className.get(),
             JSValIDToString(cx, aProperty),
-            objectOriginUnicode.get()
+            objectOriginUnicode.get(),
+            subjectDomainUnicode.get(),
+            objectDomainUnicode.get()
         };
 
         PRUint32 length = NS_ARRAY_LENGTH(formatStrings);
 
+        // XXXbz Our localization system is stupid and can't handle not showing
+        // some strings that get passed in.  Which means that we have to get
+        // our length precisely right: it has to be exactly the number of
+        // strings our format string wants.  This means we'll have to move
+        // strings in the array as needed, sadly...
         if (nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin ||
             !objectPrincipal) {
             stringName.AppendLiteral("OnlySubject");
-            --length;
+            length -= 3;
+        } else {
+            // default to a length that doesn't include the domains, then
+            // increase it as needed.
+            length -= 2;
+            if (!subjectDomainUnicode.IsEmpty()) {
+                stringName.AppendLiteral("SubjectDomain");
+                length += 1;
+            }
+            if (!objectDomainUnicode.IsEmpty()) {
+                stringName.AppendLiteral("ObjectDomain");
+                length += 1;
+                if (length != NS_ARRAY_LENGTH(formatStrings)) {
+                    // We have an object domain but not a subject domain.
+                    // Scoot our string over one slot.  See the XXX comment
+                    // above for why we need to do this.
+                    formatStrings[length-1] = formatStrings[length];
+                }
+            }
         }
         
         // We need to keep our existing failure rv and not override it
         // with a likely success code from the following string bundle
         // call in order to throw the correct security exception later.
         nsresult rv2 = sStrBundle->FormatStringFromName(stringName.get(),
                                                         formatStrings,
                                                         length,
@@ -2858,17 +2911,17 @@ nsScriptSecurityManager::CanCreateWrappe
                                           const nsIID &aIID,
                                           nsISupports *aObj,
                                           nsIClassInfo *aClassInfo,
                                           void **aPolicy)
 {
 #ifdef DEBUG_CAPS_CanCreateWrapper
     char* iidStr = aIID.ToString();
     printf("### CanCreateWrapper(%s) ", iidStr);
-    nsCRT::free(iidStr);
+    NS_Free(iidStr);
 #endif
 // XXX Special case for nsIXPCException ?
     ClassInfoData objClassInfo = ClassInfoData(aClassInfo, nsnull);
     if (objClassInfo.IsDOMClass())
     {
 #ifdef DEBUG_CAPS_CanCreateWrapper
         printf("DOM class - GRANTED.\n");
 #endif
@@ -2987,17 +3040,17 @@ nsScriptSecurityManager::CheckComponentP
 
 NS_IMETHODIMP
 nsScriptSecurityManager::CanCreateInstance(JSContext *cx,
                                            const nsCID &aCID)
 {
 #ifdef DEBUG_CAPS_CanCreateInstance
     char* cidStr = aCID.ToString();
     printf("### CanCreateInstance(%s) ", cidStr);
-    nsCRT::free(cidStr);
+    NS_Free(cidStr);
 #endif
 
     nsresult rv = CheckXPCPermissions(nsnull, nsnull, nsnull, nsnull);
     if (NS_FAILED(rv))
 #ifdef XPC_IDISPATCH_SUPPORT
     {
         rv = CheckComponentPermissions(cx, aCID);
     }
@@ -3024,17 +3077,17 @@ nsScriptSecurityManager::CanCreateInstan
 
 NS_IMETHODIMP
 nsScriptSecurityManager::CanGetService(JSContext *cx,
                                        const nsCID &aCID)
 {
 #ifdef DEBUG_CAPS_CanGetService
     char* cidStr = aCID.ToString();
     printf("### CanGetService(%s) ", cidStr);
-    nsCRT::free(cidStr);
+    NS_Free(cidStr);
 #endif
 
     nsresult rv = CheckXPCPermissions(nsnull, nsnull, nsnull, nsnull);
     if (NS_FAILED(rv))
     {
         //-- Access denied, report an error
         nsCAutoString errorMsg("Permission denied to get service. CID=");
         char cidStr[NSID_LENGTH];
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -174,28 +174,28 @@ xpcshell-tests:
 # 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=$(SOLO_FILE) \
+          --test-path=$(SOLO_FILE) \
           --interactive \
           $(DIST)/bin/xpcshell \
           $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(MODULE)/$(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=$(SOLO_FILE) \
+          --test-path=$(SOLO_FILE) \
           $(DIST)/bin/xpcshell \
           $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(MODULE)/$(dir))
 
 endif # XPCSHELL_TESTS
 
 ifdef CPP_UNIT_TESTS
 
 # Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
--- a/configure.in
+++ b/configure.in
@@ -1380,16 +1380,22 @@ hppa* | parisc)
 
 sun4u | sparc*)
     CPU_ARCH=sparc
     ;;
 
 x86_64 | ia64)
     CPU_ARCH="$OS_TEST"
     ;;
+
+arm)
+    if test "$OS_TARGET" == "WINCE"; then
+        CPU_ARCH="$OS_TEST"
+    fi
+    ;;
 esac
 
 if test -z "$OS_TARGET"; then
     OS_TARGET=$OS_ARCH
 fi
 OS_CONFIG="${OS_TARGET}${OS_RELEASE}"
 
 dnl ========================================================
@@ -2003,17 +2009,17 @@ case "$target" in
     ;;
     mips*)
         MOZ_DEBUG_FLAGS="-g" # We want inlining
     ;;
     esac
     ;;
 
 *-wince*)
-
+    TARGET_COMPILER_ABI=msvc
     MOZ_TOOLS_DIR=`echo $MOZ_TOOLS`
     AR_LIST="$AR -list"
     AR_EXTRACT="$AR -extract"
     AR_DELETE="$AR d"
     AR_FLAGS='-OUT:"$@"'
 
     if test "$AS_BIN"; then
         AS="$AS_BIN"
@@ -4503,17 +4509,17 @@ MOZ_ARG_HEADER(Application)
 BUILD_STATIC_LIBS=
 ENABLE_TESTS=1
 MOZ_ACTIVEX_SCRIPTING_SUPPORT=
 MOZ_BRANDING_DIRECTORY=
 MOZ_DBGRINFO_MODULES=
 MOZ_ENABLE_CANVAS=1
 MOZ_ENABLE_CANVAS3D=
 MOZ_FEEDS=1
-MOZ_IMG_DECODERS_DEFAULT="png gif jpeg bmp xbm icon"
+MOZ_IMG_DECODERS_DEFAULT="png gif jpeg bmp icon"
 MOZ_IMG_ENCODERS_DEFAULT="png jpeg"
 MOZ_JAVAXPCOM=
 MOZ_JSDEBUGGER=1
 MOZ_JSLOADER=1
 MOZ_MATHML=1
 MOZ_MORK=1
 MOZ_MORKREADER=
 MOZ_AUTH_EXTENSION=1
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -100,18 +100,18 @@ class nsBindingManager;
 class nsIDOMNodeList;
 class mozAutoSubtreeModified;
 struct JSObject;
 class nsFrameLoader;
 class nsIBoxObject;
 
 // IID for the nsIDocument interface
 #define NS_IDOCUMENT_IID      \
-  { 0x46003091, 0x7f99, 0x420f, \
-  { 0x95, 0xbc, 0x28, 0xd7, 0xd5, 0x01, 0x5a, 0x41 } }
+{ 0xe0ca6723, 0x1efa, 0x4819, \
+  { 0x84, 0xbb, 0xfa, 0x48, 0x39, 0xe8, 0xef, 0x19 } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 //----------------------------------------------------------------------
 
 // Document interface.  This is implemented by all document objects in
 // Gecko.
@@ -1151,16 +1151,25 @@ public:
 
   /**
    * Called by nsParser to preload images. Can be removed and code moved
    * to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
    * parser-module is linked with gklayout-module.
    */
   virtual void MaybePreLoadImage(nsIURI* uri) = 0;
 
+  /**
+   * Returns true if the locale used for the document specifies a direction of
+   * right to left. For chrome documents, this comes from the chrome registry.
+   * This is used to determine the current state for the :-moz-locale-dir pseudoclass
+   * so once can know whether a document is expected to be rendered left-to-right
+   * or right-to-left.
+   */
+  virtual PRBool IsDocumentRightToLeft() { return PR_FALSE; }
+
 protected:
   ~nsIDocument()
   {
     // XXX The cleanup of mNodeInfoManager (calling DropDocumentReference and
     //     releasing it) happens in the nsDocument destructor. We'd prefer to
     //     do it here but nsNodeInfoManager is a concrete class that we don't
     //     want to expose to users of the nsIDocument API outside of Gecko.
   }
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -160,16 +160,17 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsCPrefetchService.h"
 #include "nsIChromeRegistry.h"
 #include "nsIMIMEHeaderParam.h"
 #include "nsIDOMXULCommandEvent.h"
 #include "nsIDOMAbstractView.h"
 #include "nsIDOMDragEvent.h"
 #include "nsDOMDataTransfer.h"
 #include "nsHtml5Module.h"
+#include "nsPresContext.h"
 
 #ifdef IBMBIDI
 #include "nsIBidiKeyboard.h"
 #endif
 #include "nsCycleCollectionParticipant.h"
 
 // for ReportToConsole
 #include "nsIStringBundle.h"
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -129,16 +129,17 @@
 #include "nsIView.h"
 #include "nsIViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsIScrollableView.h"
 #include "nsIScrollableViewProvider.h"
 #include "nsXBLInsertionPoint.h"
 #include "nsICSSStyleRule.h" /* For nsCSSSelectorList */
 #include "nsCSSRuleProcessor.h"
+#include "nsRuleProcessorData.h"
 
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
 #endif /* MOZ_XUL */
 
 #ifdef ACCESSIBILITY
 #include "nsIAccessibilityService.h"
 #include "nsIAccessibleEvent.h"
@@ -3204,25 +3205,20 @@ nsGenericElement::doInsertChildAt(nsICon
 
   rv = aKid->BindToTree(aDocument, aParent, nsnull, PR_TRUE);
   if (NS_FAILED(rv)) {
     aChildArray.RemoveChildAt(aIndex);
     aKid->UnbindFromTree();
     return rv;
   }
 
-  // The kid may have removed its parent from the document, so recheck that
-  // that's still in the document before proceeding.  Also, the kid may have
-  // just removed itself, in which case we don't really want to fire
-  // ContentAppended or a mutation event.
-  // XXXbz What if the kid just moved us in the document?  Scripts suck.  We
-  // really need to stop running them while we're in the middle of modifying
-  // the DOM....
-
-  if (aNotify && aKid->GetNodeParent() == container) {
+  NS_ASSERTION(aKid->GetNodeParent() == container,
+               "Did we run script inappropriately?");
+
+  if (aNotify) {
     // Note that we always want to call ContentInserted when things are added
     // as kids to documents
     if (aParent && isAppend) {
       nsNodeUtils::ContentAppended(aParent, aIndex);
     } else {
       nsNodeUtils::ContentInserted(container, aKid, aIndex);
     }
 
@@ -3725,17 +3721,17 @@ nsGenericElement::doReplaceOrInsertBefor
       NS_ENSURE_SUCCESS(rv, rv);
 
       NS_ASSERTION(adoptedKid == aNewChild, "Uh, adopt node changed nodes?");
     }
   }
 
   // We want an update batch when we expect several mutations to be performed,
   // which is when we're replacing a node, or when we're inserting a fragment.
-  mozAutoDocConditionalContentUpdateBatch(aDocument,
+  mozAutoDocConditionalContentUpdateBatch batch(aDocument,
     aReplace || nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE);
 
   // If we're replacing
   if (aReplace) {
     // Getting (and addrefing) the following child here is sort of wasteful
     // in the common case, but really, it's not that expensive. Get over it.
     refContent = container->GetChildAt(insPos + 1);
 
@@ -3763,16 +3759,22 @@ nsGenericElement::doReplaceOrInsertBefor
   /*
    * Check if we're inserting a document fragment. If we are, we need
    * to remove the children of the document fragment and add them
    * individually (i.e. we don't add the actual document fragment).
    */
   if (nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
     PRUint32 count = newContent->GetChildCount();
 
+    if (!count) {
+      returnVal.swap(*aReturn);
+
+      return NS_OK;
+    }
+
     // Copy the children into a separate array to avoid having to deal with
     // mutations to the fragment while we're inserting.
     nsCOMArray<nsIContent> fragChildren;
     if (!fragChildren.SetCapacity(count)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     PRUint32 i;
     for (i = 0; i < count; i++) {
@@ -3788,59 +3790,92 @@ nsGenericElement::doReplaceOrInsertBefor
       // We don't need to update i if someone mutates the DOM. The only thing
       // that'd happen is that the resulting child list might be unexpected,
       // but we should never crash since RemoveChildAt is out-of-bounds safe.
       nsMutationGuard guard;
       newContent->RemoveChildAt(--i, PR_TRUE);
       mutated = mutated || guard.Mutated(1);
     }
 
-    // Iterate through the fragment's children, and insert them in the new
-    // parent
-    for (i = 0; i < count; ++i) {
-      // Get the n:th child from the array.
-      nsIContent* childContent = fragChildren[i];
-
-      // If we've had any unexpeted mutations so far we need to recheck that
-      // the child can still be inserted.
-      if (mutated) {
-        // We really only need to update insPos if we *just* got an unexpected
-        // mutation as opposed to 3 insertions ago. But this is an edgecase so
-        // no need to over optimize.
-        insPos = refContent ? container->IndexOf(refContent) :
-                              container->GetChildCount();
-        if (insPos < 0) {
-          // Someone seriously messed up the childlist. We have no idea
-          // where to insert the remaining children, so just bail.
-          return NS_ERROR_DOM_NOT_FOUND_ERR;
-        }
+    // If we've had any unexpeted mutations so far we need to recheck that
+    // the child can still be inserted.
+    if (mutated) {
+      for (i = 0; i < count; ++i) {
+        // Get the n:th child from the array.
+        nsIContent* childContent = fragChildren[i];
 
         nsCOMPtr<nsIDOMNode> tmpNode = do_QueryInterface(childContent);
         PRUint16 tmpType = 0;
         tmpNode->GetNodeType(&tmpType);
 
         if (childContent->GetNodeParent() ||
             !IsAllowedAsChild(childContent, tmpType, aParent, aDocument, PR_FALSE,
                               refContent)) {
           return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
         }
       }
 
-      nsMutationGuard guard;
+      insPos = refContent ? container->IndexOf(refContent) :
+                            container->GetChildCount();
+      if (insPos < 0) {
+        // Someone seriously messed up the childlist. We have no idea
+        // where to insert the remaining children, so just bail.
+        return NS_ERROR_DOM_NOT_FOUND_ERR;
+      }
+    }
+
+    PRBool appending = aParent && (insPos == container->GetChildCount());
+    PRBool firstInsPos = insPos;
+
+    // Iterate through the fragment's children, and insert them in the new
+    // parent
+    for (i = 0; i < count; ++i, ++insPos) {
+      nsIContent* childContent = fragChildren[i];
 
       // XXXbz how come no reparenting here?  That seems odd...
       // Insert the child.
-      res = container->InsertChildAt(childContent, insPos, PR_TRUE);
-      NS_ENSURE_SUCCESS(res, res);
-
-      // Check to see if any evil mutation events mucked around with the
-      // child list.
-      mutated = mutated || guard.Mutated(1);
-      
-      ++insPos;
+      res = container->InsertChildAt(childContent, insPos, PR_FALSE);
+      if (NS_FAILED(res)) {
+        // Make sure to notify on any children that we did succeed to insert
+        if (appending && i != 0) {
+          nsNodeUtils::ContentAppended(aParent, firstInsPos);
+        }
+        return res;
+      }
+
+      if (!appending) {
+        nsNodeUtils::ContentInserted(container, childContent, insPos);
+      }
+    }
+
+    // Notify
+    if (appending) {
+      nsNodeUtils::ContentAppended(aParent, firstInsPos);
+    }
+
+    // Fire mutation events. Optimize for the case when there are no listeners
+    nsIDocument* doc = container->GetOwnerDoc();
+    nsPIDOMWindow* window = nsnull;
+    if (doc && (window = doc->GetInnerWindow()) &&
+        window->HasMutationListeners(NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
+
+      for (i = 0; i < count; ++i, ++insPos) {
+        nsIContent* childContent = fragChildren[i];
+
+        if (nsContentUtils::HasMutationListeners(childContent,
+              NS_EVENT_BITS_MUTATION_NODEINSERTED, container)) {
+          mozAutoRemovableBlockerRemover blockerRemover;
+
+          nsMutationEvent mutation(PR_TRUE, NS_MUTATION_NODEINSERTED);
+          mutation.mRelatedNode = do_QueryInterface(container);
+
+          mozAutoSubtreeModified subtree(container->GetOwnerDoc(), container);
+          nsEventDispatcher::Dispatch(childContent, nsnull, &mutation);
+        }
+      }
     }
   }
   else {
     // Not inserting a fragment but rather a single node.
 
     if (newContent->IsRootOfAnonymousSubtree()) {
       // This is anonymous content.  Don't allow its insertion
       // anywhere, since it might have UnbindFromTree calls coming
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -498,16 +498,17 @@ GK_ATOM(listcol, "listcol")
 GK_ATOM(listcols, "listcols")
 GK_ATOM(listener, "listener")
 GK_ATOM(listhead, "listhead")
 GK_ATOM(listheader, "listheader")
 GK_ATOM(listing, "listing")
 GK_ATOM(listitem, "listitem")
 GK_ATOM(listrows, "listrows")
 GK_ATOM(load, "load")
+GK_ATOM(localedir, "localedir")
 GK_ATOM(localName, "local-name")
 GK_ATOM(longdesc, "longdesc")
 #ifdef MOZ_MEDIA
 GK_ATOM(loopend, "loopend")
 GK_ATOM(loopstart, "loopstart")
 #endif
 GK_ATOM(lowerFirst, "lower-first")
 GK_ATOM(lowest, "lowest")
--- a/content/canvas/test/Makefile.in
+++ b/content/canvas/test/Makefile.in
@@ -40,666 +40,17 @@ DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = content/canvas/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 _TEST_FILES_0 = \
-	test_fallback.basic.html \
-	test_fallback.multiple.html \
-	test_fallback.nested.html \
-	test_type.name.html \
-	test_type.exists.html \
-	test_type.delete.html \
-	test_type.prototype.html \
-	test_type.replace.html \
-	test_type.extend.html \
-	test_size.attributes.html \
-	test_size.attributes.type.get.html \
-	test_size.attributes.type.set.html \
-	test_size.attributes.default.html \
-	test_size.attributes.reflect.1.html \
-	test_size.attributes.reflect.2.html \
-	test_size.attributes.removed.html \
-	test_size.attributes.parse.whitespace.html \
-	test_size.attributes.parse.nonnumber.html \
-	test_size.attributes.parse.zero.html \
-	test_size.attributes.parse.negative.html \
-	test_size.attributes.parse.zerosuffix.html \
-	test_size.attributes.parse.floatsuffix.html \
-	test_size.attributes.parse.badsuffix.html \
-	test_size.attributes.parse.percentsuffix.html \
-	test_size.attributes.setAttribute.whitespace.html \
-	test_size.attributes.setAttribute.nonnumber.html \
-	test_size.attributes.setAttribute.zero.html \
-	test_size.attributes.setAttribute.negative.html \
-	test_size.attributes.setAttribute.zerosuffix.html \
-	test_size.attributes.setAttribute.floatsuffix.html \
-	test_size.attributes.setAttribute.badsuffix.html \
-	test_size.attributes.setAttribute.percentsuffix.html \
-	test_size.attributes.style.html \
-	test_initial.colour.html \
-	test_initial.reset.different.html \
-	test_initial.reset.same.html \
-	test_initial.reset.path.html \
-	test_initial.reset.clip.html \
-	test_initial.reset.transform.html \
-	test_initial.reset.gradient.html \
-	test_initial.reset.pattern.html \
-	test_context.emptystring.html \
-	test_context.unrecognised.badname.html \
-	test_context.unrecognised.badsuffix.html \
-	test_context.unrecognised.nullsuffix.html \
-	test_context.unrecognised.unicode.html \
-	test_context.casesensitive.html \
-	test_context.arguments.missing.html \
-	test_context.arguments.extra.html \
-	test_toDataURL.default.html \
-	test_toDataURL.png.html \
-	test_toDataURL.unrecognised.html \
-	test_toDataURL.lowercase.html \
-	test_toDataURL.arguments.1.html \
-	test_toDataURL.arguments.2.html \
-	test_toDataURL.arguments.3.html \
-	test_toDataURL.nocontext.html \
-	test_toDataURL.zerosize.html \
-	test_toDataURL.primarycolours.html \
-	test_toDataURL.complexcolours.html \
-	test_2d.getcontext.exists.html \
-	test_2d.type.exists.html \
-	test_2d.type.delete.html \
-	test_2d.type.prototype.html \
-	test_2d.type.replace.html \
-	test_2d.type.extend.html \
-	test_2d.getcontext.unique.html \
-	test_2d.getcontext.shared.html \
-	test_2d.voidreturn.html \
-	test_2d.missingargs.html \
-	test_2d.scaled.html \
-	test_2d.canvas.reference.html \
-	test_2d.canvas.readonly.html \
-	test_2d.state.saverestore.strokeStyle.html \
-	test_2d.state.saverestore.fillStyle.html \
-	test_2d.state.saverestore.globalAlpha.html \
-	test_2d.state.saverestore.lineWidth.html \
-	test_2d.state.saverestore.lineCap.html \
-	test_2d.state.saverestore.lineJoin.html \
-	test_2d.state.saverestore.miterLimit.html \
-	test_2d.state.saverestore.shadowOffsetX.html \
-	test_2d.state.saverestore.shadowOffsetY.html \
-	test_2d.state.saverestore.shadowBlur.html \
-	test_2d.state.saverestore.shadowColor.html \
-	test_2d.state.saverestore.globalCompositeOperation.html \
-	test_initial.reset.2dstate.html \
-	test_2d.state.saverestore.transformation.html \
-	test_2d.state.saverestore.clip.html \
-	test_2d.state.saverestore.path.html \
-	test_2d.state.saverestore.bitmap.html \
-	test_2d.state.saverestore.stack.html \
-	test_2d.state.saverestore.stackdepth.html \
-	test_2d.state.saverestore.underflow.html \
-	test_2d.transformation.order.html \
-	test_2d.transformation.scale.basic.html \
-	test_2d.transformation.scale.zero.html \
-	test_2d.transformation.scale.negative.html \
-	test_2d.transformation.scale.large.html \
-	test_2d.transformation.scale.nonfinite.html \
-	test_2d.transformation.scale.multiple.html \
-	$(NULL)
-
-_TEST_FILES_1 = \
-	test_2d.transformation.rotate.zero.html \
-	test_2d.transformation.rotate.radians.html \
-	test_2d.transformation.rotate.direction.html \
-	test_2d.transformation.rotate.wrap.html \
-	test_2d.transformation.rotate.wrapnegative.html \
-	test_2d.transformation.rotate.nonfinite.html \
-	test_2d.transformation.translate.basic.html \
-	test_2d.transformation.translate.nonfinite.html \
-	test_2d.transformation.transform.identity.html \
-	test_2d.transformation.transform.skewed.html \
-	test_2d.transformation.transform.multiply.html \
-	test_2d.transformation.transform.nonfinite.html \
-	test_2d.transformation.setTransform.skewed.html \
-	test_2d.transformation.setTransform.multiple.html \
-	test_2d.transformation.setTransform.nonfinite.html \
-	test_2d.composite.globalAlpha.range.html \
-	test_2d.composite.globalAlpha.invalid.html \
-	test_2d.composite.globalAlpha.default.html \
-	test_2d.composite.globalAlpha.fill.html \
-	test_2d.composite.globalAlpha.image.html \
-	test_2d.composite.globalAlpha.canvas.html \
-	test_2d.composite.globalAlpha.imagepattern.html \
-	test_2d.composite.globalAlpha.canvaspattern.html \
-	test_2d.composite.solid.source-over.html \
-	test_2d.composite.solid.destination-over.html \
-	test_2d.composite.solid.source-in.html \
-	test_2d.composite.solid.destination-in.html \
-	test_2d.composite.solid.source-out.html \
-	test_2d.composite.solid.destination-out.html \
-	test_2d.composite.solid.source-atop.html \
-	test_2d.composite.solid.destination-atop.html \
-	test_2d.composite.solid.copy.html \
-	test_2d.composite.transparent.source-over.html \
-	test_2d.composite.transparent.destination-over.html \
-	test_2d.composite.transparent.source-in.html \
-	test_2d.composite.transparent.destination-in.html \
-	test_2d.composite.transparent.source-out.html \
-	test_2d.composite.transparent.destination-out.html \
-	test_2d.composite.transparent.source-atop.html \
-	test_2d.composite.transparent.destination-atop.html \
-	test_2d.composite.transparent.copy.html \
-	test_2d.composite.image.source-over.html \
-	test_2d.composite.image.destination-over.html \
-	test_2d.composite.image.destination-out.html \
-	test_2d.composite.image.source-atop.html \
-	test_2d.composite.image.copy.html \
-	test_2d.composite.canvas.source-over.html \
-	test_2d.composite.canvas.destination-over.html \
-	test_2d.composite.canvas.destination-out.html \
-	test_2d.composite.canvas.source-atop.html \
-	test_2d.composite.canvas.copy.html \
-	test_2d.composite.uncovered.fill.copy.html \
-	test_2d.composite.uncovered.image.copy.html \
-	test_2d.composite.uncovered.pattern.copy.html \
-	test_2d.composite.clip.source-over.html \
-	test_2d.composite.clip.destination-over.html \
-	test_2d.composite.clip.source-in.html \