Merge mozilla-central, including the Electrolysis changes, into the branch for bug 568691.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Thu, 01 Jul 2010 11:55:57 -0400
changeset 47092 e90cbf73a8be1a3803ffb1c907388b3c8dfde8bf
parent 47091 ea142ed538fc02e587a18c8db4655f36cec8e54e (current diff)
parent 46969 d9253109fd884143e362b2f23b02281e6d0944b5 (diff)
child 47093 2ad039920033d9fe2960153a79584b2e8c02a3ef
push id14223
push userbsmedberg@mozilla.com
push dateThu, 01 Jul 2010 18:30:48 +0000
treeherdermozilla-central@836fd3f8feba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs568691
milestone2.0b2pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central, including the Electrolysis changes, into the branch for bug 568691.
.hgtags
browser/components/places/public/Makefile.in
browser/components/places/public/nsIPlacesTransactionsService.idl
browser/components/places/src/BrowserPlaces.manifest
browser/components/places/src/Makefile.in
browser/components/places/src/nsPlacesTransactionsService.js
browser/installer/package-manifest.in
browser/installer/removed-files.in
browser/themes/gnomestripe/browser/Geo.png
browser/themes/pinstripe/browser/Geo.png
browser/themes/winstripe/browser/Geo-aero.png
browser/themes/winstripe/browser/Geo.png
chrome/src/Makefile.in
chrome/src/nsChromeRegistry.cpp
chrome/src/nsChromeRegistry.h
chrome/src/nsChromeRegistryChrome.cpp
chrome/src/nsChromeRegistryChrome.h
chrome/src/nsChromeRegistryContent.cpp
chrome/src/nsChromeRegistryContent.h
content/base/public/Makefile.in
content/base/src/Makefile.in
content/base/src/nsContentUtils.cpp
dom/src/geolocation/Makefile.in
dom/src/geolocation/NetworkGeolocationProvider.js
embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
extensions/cookie/nsCookieModule.cpp
js/src/xpconnect/shell/xpcshell.cpp
layout/build/nsLayoutModule.cpp
layout/style/nsCSSRuleProcessor.cpp
modules/plugin/base/src/nsPluginHost.cpp
netwerk/base/src/Makefile.in
netwerk/build/nsNetModule.cpp
testing/xpcshell/head.js
toolkit/components/places/src/Makefile.in
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/library/dlldeps-xul.cpp
toolkit/library/libxul-config.mk
toolkit/mozapps/extensions/amWebInstallListener.js
toolkit/toolkit-tiers.mk
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsEmbedFunctions.cpp
xpcom/build/nsXPComInit.cpp
xpcom/build/nsXULAppAPI.h
xpcom/components/ManifestParser.cpp
xpcom/components/ModuleUtils.h
xpcom/glue/nsClassHashtable.h
xpcom/glue/nsInterfaceHashtable.h
--- a/.hgtags
+++ b/.hgtags
@@ -30,14 +30,25 @@ 8a601ed6bc4c7b3d1e35aa9e81f257512d984bd5
 d7d64f68423b68a671f623f123e90057ebc49dac UPDATE_PACKAGING_R7
 fb32f6e1859c07846a01b4478a7b1678019e0b45 UPDATE_PACKAGING_R7
 f817a4378f32b1ad0a7c4b5a9949586dba816da5 FENNEC_M11
 5c1e7c779b6edc8ff912001990edc579f80597f4 FENNEC_B1
 fe9cc55b8db7f56f7e68a246acba363743854979 UPDATE_PACKAGING_R8
 6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-r15462
 6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-latest
 376b78fc72230aaf2ca4e279a8f4ef1efd4a1d9f GECKO_1_9_2_BASE
+941ad9d7d079246481f365c3cfbfc75a5bbefc94 last-mozilla-central
+2bae3bbf866e7de2a4b2377e7c2f52cc9ac14a22 last-mozilla-central
+2bae3bbf866e7de2a4b2377e7c2f52cc9ac14a22 last-mozilla-central
+65c1582465efe99899189519fccaf7b2826fcb2e last-mozilla-central
+65c1582465efe99899189519fccaf7b2826fcb2e last-mozilla-central
+27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
+27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
+a732c6d3c078f80635255c78bfaadffa5828a8a5 last-mozilla-central
+a732c6d3c078f80635255c78bfaadffa5828a8a5 last-mozilla-central
+925595f3c08634cc42e33158ea6858bb55623ef7 last-mozilla-central
+dba2abb7db57078c5a4810884834d3056a5d56c2 last-mozilla-central
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R9
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R10
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R11
 0327e126ea245112c0aa7283fee154e084866fb5 bsmedberg-static-xpcom-registration-base
 0327e126ea245112c0aa7283fee154e084866fb5 bsmedberg-static-xpcom-registration-base
 2f83edbbeef0de7dd901411d270da61106c8afae bsmedberg-static-xpcom-registration-base
--- a/accessible/public/nsIAccessibleRetrieval.idl
+++ b/accessible/public/nsIAccessibleRetrieval.idl
@@ -51,57 +51,33 @@ interface nsIDOMDOMStringList;
  * An interface for in-process accessibility clients
  * wishing to get an nsIAccessible or nsIAccessNode for
  * a given DOM node.
  * More documentation at:
  *   http://www.mozilla.org/projects/ui/accessibility
  *
  * @status UNDER_REVIEW
  */
-[scriptable, uuid(420f0f49-27c1-4ac1-b509-5aba4353909b)]
+[scriptable, uuid(310ce77d-c92b-4761-82e8-77e1a728e8d4)]
 interface nsIAccessibleRetrieval : nsISupports
 {
   /**
    * Return application accessible.
    */
   nsIAccessible getApplicationAccessible();
 
   /**
    * Return an nsIAccessible for a DOM node in pres shell 0.
    * Create a new accessible of the appropriate type if necessary,
    * or use one from the accessibility cache if it already exists.
    * @param aNode The DOM node to get an accessible for.
    * @return The nsIAccessible for the given DOM node.
    */
   nsIAccessible getAccessibleFor(in nsIDOMNode aNode);
 
-  /**
-   * The same like getAccessibleFor method except it returns accessible only if
-   * it is attached, i.e. accessible is certified to be a descendent of the root
-   * accessible.
-   *
-   * @param aNode - the DOM node to get an accessible for.
-   *
-   * @return - the accessible for the given DOM node.
-   */
-  nsIAccessible getAttachedAccessibleFor(in nsIDOMNode aNode);
-
-  /**
-   * Return an DOM node that is relevant to attached accesible check. This
-   * node is either from bindings chain if given node is anonymous and owner
-   * binding denies accessible in anonymous content or given node (it's not
-   * important whether it is accessible or not). This method doesn't create
-   * accessible object for returned node.
-   *
-   * @param aNode - the DOM node to get relevant content node.
-   *
-   * @return - the DOM node for parent attached accessible
-   */
-  nsIDOMNode getRelevantContentNodeFor(in nsIDOMNode aNode);
-
    /**
     * Returns accessible role as a string.
     *
     * @param aRole - the accessible role constants.
     */
   AString getStringRole(in unsigned long aRole);
 
    /**
--- a/accessible/src/base/nsAccTreeWalker.cpp
+++ b/accessible/src/base/nsAccTreeWalker.cpp
@@ -108,18 +108,18 @@ nsAccTreeWalker::GetNextChildInternal(PR
     mState->childList->GetLength(&length);
 
   while (mState->childIdx < length) {
     nsIContent* childNode = mState->childList->GetNodeAt(mState->childIdx);
     mState->childIdx++;
 
     PRBool isHidden = PR_FALSE;
     nsRefPtr<nsAccessible> accessible =
-      GetAccService()->GetAccessible(childNode, presShell, mWeakShell,
-                                     &isHidden);
+      GetAccService()->GetOrCreateAccessible(childNode, presShell, mWeakShell,
+                                             &isHidden);
 
     if (accessible)
       return accessible.forget();
 
     // Walk down into subtree to find accessibles.
     if (!isHidden) {
       if (!PushState(childNode))
         break;
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -522,41 +522,38 @@ nsAccUtils::GetTextAccessibleFromSelecti
     return nsnull;
 
   PRInt32 focusOffset = 0;
   aSelection->GetFocusOffset(&focusOffset);
 
   nsCOMPtr<nsINode> focusNode(do_QueryInterface(focusDOMNode));
   nsCOMPtr<nsINode> resultNode =
     nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
+  nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(resultNode));
 
   // Get text accessible containing the result node.
-  while (resultNode) {
-    // Make sure to get the correct starting node for selection events inside
-    // XBL content trees.
-    resultNode = GetAccService()->GetRelevantContentNodeFor(resultNode);
-    if (!resultNode->IsNodeOfType(nsINode::eTEXT)) {
-      nsAccessible *accessible = GetAccService()->GetAccessible(resultNode);
-      if (accessible) {
-        nsHyperTextAccessible *textAcc = nsnull;
-        CallQueryInterface(accessible, &textAcc);
-        if (textAcc) {
-          if (aNode)
-            NS_ADDREF(*aNode = resultNode);
-
-          return textAcc;
-        }
-      }
-    }
-
-    resultNode = resultNode->GetNodeParent();
+  nsAccessible* accessible =
+    GetAccService()->GetAccessibleOrContainer(resultNode, weakShell);
+  if (!accessible) {
+    NS_NOTREACHED("No nsIAccessibleText for selection change event!");
+    return nsnull;
   }
 
-  NS_NOTREACHED("No nsIAccessibleText for selection change event!");
+  do {
+    nsHyperTextAccessible* textAcc = nsnull;
+    CallQueryInterface(accessible, &textAcc);
+    if (textAcc) {
+      if (aNode)
+        NS_ADDREF(*aNode = accessible->GetNode());
 
+      return textAcc;
+    }
+  } while (accessible = accessible->GetParent());
+
+  NS_NOTREACHED("We must reach document accessible implementing nsIAccessibleText!");
   return nsnull;
 }
 
 nsresult
 nsAccUtils::ConvertToScreenCoords(PRInt32 aX, PRInt32 aY,
                                   PRUint32 aCoordinateType,
                                   nsAccessNode *aAccessNode,
                                   nsIntPoint *aCoords)
@@ -629,17 +626,18 @@ nsAccUtils::GetScreenCoordsForWindow(nsA
 {
   return nsCoreUtils::GetScreenCoordsForWindow(aAccessNode->GetNode());
 }
 
 nsIntPoint
 nsAccUtils::GetScreenCoordsForParent(nsAccessNode *aAccessNode)
 {
   nsAccessible *parent =
-    GetAccService()->GetContainerAccessible(aAccessNode->GetNode(), PR_TRUE);
+    GetAccService()->GetContainerAccessible(aAccessNode->GetNode(),
+                                            aAccessNode->GetWeakShell());
   if (!parent)
     return nsIntPoint(0, 0);
 
   nsIFrame *parentFrame = parent->GetFrame();
   if (!parentFrame)
     return nsIntPoint(0, 0);
 
   nsIntRect parentRect = parentFrame->GetScreenRectExternal();
@@ -810,22 +808,16 @@ nsAccUtils::MustPrune(nsIAccessible *aAc
     role == nsIAccessibleRole::ROLE_PASSWORD_TEXT ||
     role == nsIAccessibleRole::ROLE_TOGGLE_BUTTON ||
     role == nsIAccessibleRole::ROLE_GRAPHIC ||
     role == nsIAccessibleRole::ROLE_SLIDER ||
     role == nsIAccessibleRole::ROLE_PROGRESSBAR ||
     role == nsIAccessibleRole::ROLE_SEPARATOR;
 }
 
-PRBool
-nsAccUtils::IsNodeRelevant(nsINode *aNode)
-{
-  return aNode == GetAccService()->GetRelevantContentNodeFor(aNode);
-}
-
 nsresult
 nsAccUtils::GetHeaderCellsFor(nsIAccessibleTable *aTable,
                               nsIAccessibleTableCell *aCell,
                               PRInt32 aRowOrColHeaderCells, nsIArray **aCells)
 {
   nsresult rv = NS_OK;
   nsCOMPtr<nsIMutableArray> cells = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -406,22 +406,16 @@ public:
 
   /**
    * Return true if the given accessible can't have children. Used when exposing
    * to platform accessibility APIs, should the children be pruned off?
    */
   static PRBool MustPrune(nsIAccessible *aAccessible);
 
   /**
-   * Return true if the given node can be accessible and attached to
-   * the document's accessible tree.
-   */
-  static PRBool IsNodeRelevant(nsINode *aNode);
-
-  /**
    * Search hint enum constants. Used by GetHeaderCellsFor() method.
    */
   enum {
     // search for row header cells, left direction
     eRowHeaderCells,
     // search for column header cells, top direction
     eColumnHeaderCells
   };
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -171,16 +171,21 @@ public:
     return GetNode() && GetNode()->IsNodeOfType(nsINode::eDOCUMENT);
   }
 
   /**
    * Return the corresponding press shell for this accessible.
    */
   already_AddRefed<nsIPresShell> GetPresShell();
 
+  /**
+   * Return presentation shell for the accessible.
+   */
+  nsIWeakReference* GetWeakShell() const { return mWeakShell; }
+
 protected:
     nsPresContext* GetPresContext();
 
     void LastRelease();
 
   nsCOMPtr<nsIContent> mContent;
   nsCOMPtr<nsIWeakReference> mWeakShell;
 
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -143,40 +143,28 @@ nsAccessibilityService::Observe(nsISuppo
 // nsIAccessibilityService
 void
 nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent *aTarget)
 {
   nsIDocument *document = aTarget->GetCurrentDoc();
   if (!document)
     return;
 
-  nsINode *targetNode = aTarget;
-  nsAccessible *targetAcc = GetAccessible(targetNode);
-
-  // Getting the targetAcc above will have ensured accessible doc creation.
-  // XXX Bug 561683
-  nsDocAccessible *docAccessible = GetDocAccessible(document);
-  if (!docAccessible)
+  // If the jump target is not accessible then fire an event for nearest
+  // accessible in parent chain.
+  nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(aTarget));
+  nsAccessible* targetAcc = GetAccessibleOrContainer(aTarget, weakShell);
+  if (!targetAcc)
     return;
 
-  // If the jump target is not accessible then fire an event for nearest
-  // accessible in parent chain.
-  if (!targetAcc) {
-    targetAcc = GetContainerAccessible(targetNode, PR_TRUE);
-    targetNode = targetAcc->GetNode();
-  }
-
-  NS_ASSERTION(targetNode,
-      "No accessible in parent chain!? Expect at least a document accessible.");
-  if (!targetNode)
-    return;
+  nsINode* targetNode = targetAcc->GetNode();
 
   // XXX note in rare cases the node could go away before we flush the queue,
   // for example if the node becomes inaccessible, or is removed from the DOM.
-  docAccessible->
+  GetDocAccessible(document)->
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
                                targetNode);
 }
 
 // nsIAccessibilityService
 nsresult
 nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
                                             nsIAccessible *aTarget)
@@ -509,41 +497,16 @@ nsAccessibilityService::GetAccessibleFor
   NS_ENSURE_ARG_POINTER(aAccessible);
 
   nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
   NS_IF_ADDREF(*aAccessible = GetAccessible(node));
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::GetAttachedAccessibleFor(nsIDOMNode *aDOMNode,
-                                                 nsIAccessible **aAccessible)
-{
-  NS_ENSURE_ARG(aDOMNode);
-  NS_ENSURE_ARG_POINTER(aAccessible);
-
-  nsCOMPtr<nsINode> node(do_QueryInterface(aDOMNode));
-  NS_IF_ADDREF(*aAccessible = GetAttachedAccessibleFor(node));
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode *aNode,
-                                                  nsIDOMNode **aRelevantNode)
-{
-  NS_ENSURE_ARG(aNode);
-  NS_ENSURE_ARG_POINTER(aRelevantNode);
-
-  nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
-  nsINode *relevantNode = GetRelevantContentNodeFor(node);
-  CallQueryInterface(relevantNode, aRelevantNode);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsAccessibilityService::GetStringRole(PRUint32 aRole, nsAString& aString)
 {
   if ( aRole >= NS_ARRAY_LENGTH(kRoleNames)) {
     aString.AssignLiteral("unknown");
     return NS_OK;
   }
 
   CopyUTF8toUTF16(kRoleNames[aRole], aString);
@@ -725,98 +688,57 @@ nsAccessibilityService::GetAccessibleFro
 nsAccessible*
 nsAccessibilityService::GetAccessibleInShell(nsINode* aNode,
                                              nsIPresShell* aPresShell)
 {
   if (!aNode || !aPresShell)
     return nsnull;
 
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
-  nsRefPtr<nsAccessible> accessible =
-    GetAccessible(aNode, aPresShell, weakShell);
-  return accessible;
+  return GetAccessibleByRule(aNode, weakShell, eGetAccForNode);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService public
 
-nsAccessible *
-nsAccessibilityService::GetAccessible(nsINode *aNode)
+nsAccessible*
+nsAccessibilityService::GetAccessible(nsINode* aNode)
 {
-  if (!aNode)
-    return nsnull;
-
-  nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
-  if (!presShell)
-    return nsnull;
-
-  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
-  nsRefPtr<nsAccessible> accessible = GetAccessible(aNode, presShell,
-                                                    weakShell);
-  return accessible;
+  if (aNode) {
+    nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(aNode));
+    if (weakShell)
+      return GetAccessibleByRule(aNode, weakShell, eGetAccForNode);
+  }
+  return nsnull;
 }
 
-nsAccessible *
-nsAccessibilityService::GetAccessibleInWeakShell(nsINode *aNode,
-                                                 nsIWeakReference *aWeakShell) 
-{
-  if (!aNode || !aWeakShell)
-    return nsnull;
-
-  nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
-  nsRefPtr<nsAccessible> accessible = GetAccessible(aNode, presShell,
-                                                    aWeakShell);
-  return accessible;
-}
-
-nsAccessible *
-nsAccessibilityService::GetContainerAccessible(nsINode *aNode,
-                                               PRBool aCanCreate)
+nsAccessible*
+nsAccessibilityService::GetCachedContainerAccessible(nsINode* aNode)
 {
   if (!aNode)
     return nsnull;
 
   nsIDocument *document = aNode->GetCurrentDoc();
   if (!document)
     return nsnull;
 
   nsIPresShell *presShell = document->GetShell();
   if (!presShell)
     return nsnull;
 
   nsINode *currNode = aNode;
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
 
   nsAccessible *accessible = nsnull;
-  while (!accessible && (currNode = currNode->GetNodeParent())) {
-    currNode = GetAccService()->GetRelevantContentNodeFor(currNode);
-
-    if (aCanCreate) {
-      accessible = GetAccService()->GetAccessibleInWeakShell(currNode,
-                                                             weakShell);
-
-    } else {
-      // Only return cached accessible, don't create anything.
-      accessible = GetCachedAccessible(currNode, weakShell);
-    }
-  }
+  while ((currNode = currNode->GetNodeParent()) &&
+         !(accessible = GetCachedAccessible(currNode, weakShell)));
 
   return accessible;
 }
 
-nsAccessible *
-nsAccessibilityService::GetAttachedAccessibleFor(nsINode *aNode)
-{
-  nsINode *relevantNode = GetRelevantContentNodeFor(aNode);
-  if (relevantNode != aNode)
-    return nsnull;
-
-  return GetAccessible(relevantNode);
-}
-
 PRBool
 nsAccessibilityService::InitAccessible(nsAccessible *aAccessible,
                                        nsRoleMapEntry *aRoleMapEntry)
 {
   if (!aAccessible)
     return PR_FALSE;
 
   // Add to cache an accessible, etc.
@@ -858,20 +780,20 @@ static PRBool HasRelatedContent(nsIConte
       return PR_TRUE;
     }
   }
 
   return PR_FALSE;
 }
 
 already_AddRefed<nsAccessible>
-nsAccessibilityService::GetAccessible(nsINode *aNode,
-                                      nsIPresShell *aPresShell,
-                                      nsIWeakReference *aWeakShell,
-                                      PRBool *aIsHidden)
+nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
+                                              nsIPresShell* aPresShell,
+                                              nsIWeakReference* aWeakShell,
+                                              PRBool* aIsHidden)
 {
   if (!aPresShell || !aWeakShell || !aNode || gIsShutdown)
     return nsnull;
 
   if (aIsHidden)
     *aIsHidden = PR_FALSE;
 
   // Check to see if we already have an accessible for this node in the cache.
@@ -1239,81 +1161,83 @@ nsAccessibilityService::HasUniversalAria
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_invalid) ||
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_label) ||
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_labelledby) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_live) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_owns) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_relevant);
 }
 
-nsINode *
-nsAccessibilityService::GetRelevantContentNodeFor(nsINode *aNode)
+nsAccessible*
+nsAccessibilityService::GetAccessibleByRule(nsINode* aNode,
+                                            nsIWeakReference* aWeakShell,
+                                            EWhatAccToGet aWhatToGet)
 {
-  // The method returns node that is relevant for attached accessible check.
-  // Sometimes element that is XBL widget hasn't accessible children in
-  // anonymous content. This method check whether given node can be accessible
-  // by looking through all nested bindings that given node is anonymous for. If
-  // there is XBL widget that deniedes to be accessible for given node then the
-  // method returns that XBL widget otherwise it returns given node.
-
-  // For example, the algorithm allows us to handle following cases:
-  // 1. xul:dialog element has buttons (like 'ok' and 'cancel') in anonymous
-  // content. When node is dialog's button then we dialog's button since button
-  // of xul:dialog is accessible anonymous node.
-  // 2. xul:texbox has html:input in anonymous content. When given node is
-  // html:input elmement then we return xul:textbox since xul:textbox doesn't
-  // allow accessible nodes in anonymous content.
-  // 3. xforms:input that is hosted in xul document contains xul:textbox
-  // element. When given node is html:input or xul:textbox then we return
-  // xforms:input element since xforms:input hasn't accessible anonymous
-  // children.
-
-  if (!aNode)
+  if (!aNode || !aWeakShell)
     return nsnull;
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
-  if (content) {
-    // Build stack of binding parents so we can walk it in reverse.
-    nsIContent *bindingParent;
-    nsCOMArray<nsIContent> bindingsStack;
+  nsAccessible* cachedAcc = GetCachedAccessible(aNode, aWeakShell);
+  if (cachedAcc) {
+    if (aWhatToGet & eGetAccForNode)
+      return cachedAcc;
 
-    for (bindingParent = content->GetBindingParent(); bindingParent != nsnull &&
-         bindingParent != bindingParent->GetBindingParent();
-         bindingParent = bindingParent->GetBindingParent()) {
-      bindingsStack.AppendObject(bindingParent);
-    }
+    // XXX: while nsAccessible::GetParent() tries to repair broken tree and
+    // may not return cached parent then we use GetAccessibleOrContainer().
+    return GetAccessibleByRule(aNode->GetNodeParent(), aWeakShell,
+                               eGetAccForNodeOrContainer);
+  }
 
-    PRInt32 bindingsCount = bindingsStack.Count();
-    for (PRInt32 index = bindingsCount - 1; index >= 0 ; index--) {
-      bindingParent = bindingsStack[index];
+  // Go up looking for the nearest accessible container stored in cache.
+  nsTArray<nsINode*> nodes;
+  nsINode* node = aNode;
+  while ((node = node->GetNodeParent()) &&
+         !(cachedAcc = GetCachedAccessible(node, aWeakShell)))
+    nodes.AppendElement(node);
 
-      // Try to get an accessible by type since XBL widget can be accessible
-      // only if it implements nsIAccessibleProvider interface.
-      nsCOMPtr<nsIWeakReference> weakShell =
-        nsCoreUtils::GetWeakShellFor(bindingParent);
+  // Node is not in accessible document.
+  if (!cachedAcc)
+    return nsnull;
 
-      // XXX: it's a hack we should try the cache before, otherwise to cache
-      // the accessible.
-      nsRefPtr<nsAccessible> accessible =
-        CreateAccessibleByType(bindingParent, weakShell);
-
-      if (accessible) {
-        if (!accessible->GetAllowsAnonChildAccessibles())
-          return bindingParent;
+  // If children of the cached accessible weren't initialized then go down to
+  // the given node and create accessible tree.
+  nsAccessible* containerAcc = cachedAcc;
+  if (!cachedAcc->AreChildrenCached()) {
+    cachedAcc->EnsureChildren();
+    for (PRInt32 idx = nodes.Length() - 1; idx >= 0; idx--) {
+      cachedAcc = GetCachedAccessible(nodes[idx], aWeakShell);
+      if (cachedAcc) {
+        cachedAcc->EnsureChildren();
+        containerAcc = cachedAcc;
       }
     }
   }
 
-  return aNode;
+  // If the given node is accessible then it should be cached at this point.
+  // Exception is an area element because area and imagemap nodes aren't in
+  // the same parent chain.
+  cachedAcc = GetCachedAccessible(aNode, aWeakShell);
+  if (!cachedAcc && aNode->IsElement()) {
+    nsIFrame* frame = aNode->AsElement()->GetPrimaryFrame();
+    if (frame && frame->GetContent() != aNode)
+      cachedAcc = GetAreaAccessible(frame, aNode, aWeakShell, &containerAcc);
+  }
+
+  if ((aWhatToGet & eGetAccForNode) && cachedAcc)
+    return cachedAcc;
+  else if (aWhatToGet & eGetAccForContainer)
+    return containerAcc;
+
+  return nsnull;
 }
 
 nsAccessible*
-nsAccessibilityService::GetAreaAccessible(nsIFrame *aImageFrame,
-                                          nsINode *aAreaNode,
-                                          nsIWeakReference *aWeakShell)
+nsAccessibilityService::GetAreaAccessible(nsIFrame* aImageFrame,
+                                          nsINode* aAreaNode,
+                                          nsIWeakReference* aWeakShell,
+                                          nsAccessible** aImageAccessible)
 {
   // Check if frame is an image frame, and content is <area>.
   nsIImageFrame *imageFrame = do_QueryFrame(aImageFrame);
   if (!imageFrame)
     return nsnull;
 
   nsCOMPtr<nsIDOMHTMLAreaElement> areaElmt = do_QueryInterface(aAreaNode);
   if (!areaElmt)
@@ -1326,16 +1250,19 @@ nsAccessibilityService::GetAreaAccessibl
   if (!imageAcc) {
     imageAcc = CreateHTMLImageAccessible(aImageFrame->GetContent(),
                                          aImageFrame->PresContext()->PresShell());
 
     if (!InitAccessible(imageAcc, nsnull))
       return nsnull;
   }
 
+  if (aImageAccessible)
+    *aImageAccessible = imageAcc;
+
   // Make sure <area> accessible children of the image map are cached so
   // that they should be available in global cache.
   imageAcc->EnsureChildren();
 
   return GetCachedAccessible(aAreaNode, aWeakShell);
 }
 
 already_AddRefed<nsAccessible>
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -122,76 +122,72 @@ public:
   // nsAccessibiltiyService
 
   /**
    * Return true if accessibility service has been shutdown.
    */
   static PRBool IsShutdown() { return gIsShutdown; }
 
   /**
-   * Return an accessible for the given DOM node.
+   * Return an accessible for the given DOM node from the cache or create new
+   * one.
    *
    * @param  aNode       [in] the given node
    * @param  aPresShell  [in] the pres shell of the node
    * @param  aWeakShell  [in] the weak shell for the pres shell
    * @param  aIsHidden   [out, optional] indicates whether the node's frame is
    *                       hidden
    */
   already_AddRefed<nsAccessible>
-    GetAccessible(nsINode *aNode, nsIPresShell *aPresShell,
-                  nsIWeakReference *aWeakShell, PRBool *aIsHidden = nsnull);
+    GetOrCreateAccessible(nsINode* aNode, nsIPresShell* aPresShell,
+                          nsIWeakReference* aWeakShell,
+                          PRBool* aIsHidden = nsnull);
 
   /**
    * Return an accessible for the given DOM node.
    */
-  nsAccessible *GetAccessible(nsINode *aNode);
+  nsAccessible* GetAccessible(nsINode* aNode);
 
   /**
-   * Return an accessible for a DOM node in the given pres shell.
-   * 
-   * @param aNode       [in] the given node.
-   * @param aPresShell  [in] the presentation shell of the given node.
+   * Return an accessible for a DOM node in the given presshell.
+   *
+   * @param aNode       [in] the given node
+   * @param aWeakShell  [in] the presentation shell for the given node
    */
-  nsAccessible *GetAccessibleInWeakShell(nsINode *aNode,
-                                         nsIWeakReference *aPresShell);
-
-  /**
-   * Return the first accessible parent of a DOM node.
-   *
-   * @param aDOMNode    [in] the DOM node to get an accessible for
-   * @param aCanCreate  [in] specifies if accessible can be created if it didn't
-   *                     exist
-   */
-  nsAccessible *GetContainerAccessible(nsINode *aNode, PRBool aCanCreate);
+  inline nsAccessible* GetAccessibleInWeakShell(nsINode* aNode,
+                                                nsIWeakReference* aWeakShell)
+  {
+    return GetAccessibleByRule(aNode, aWeakShell, eGetAccForNode);
+  }
 
   /**
-   * The same as getAccessibleFor method except it returns accessible only if
-   * it is attached, i.e. accessible is certified to be a descendant of the root
-   * accessible.
-   *
-   * XXX: this method must go away once we'll implement correct accessible tree.
-   *
-   * @param  aNode  [in] the DOM node to get an accessible for
-   * @return         the accessible for the given DOM node
+   * Return an accessible for the given DOM node or container accessible if
+   * the node is not accessible.
    */
-  nsAccessible *GetAttachedAccessibleFor(nsINode *aNode);
+  inline nsAccessible* GetAccessibleOrContainer(nsINode* aNode,
+                                                nsIWeakReference* aWeakShell)
+  {
+    return GetAccessibleByRule(aNode, aWeakShell, eGetAccForNodeOrContainer);
+  }
 
   /**
-   * Return an DOM node that is relevant to attached accessible check. This
-   * node is either from bindings chain if given node is anonymous and owner
-   * binding denies accessible in anonymous content or given node (it's not
-   * important whether it is accessible or not). This method doesn't create
-   * accessible object for returned node.
+   * Return a container accessible for the given DOM node.
+   */
+  inline nsAccessible* GetContainerAccessible(nsINode* aNode,
+                                              nsIWeakReference* aWeakShell)
+  {
+    return GetAccessibleByRule(aNode, aWeakShell, eGetAccForContainer);
+  }
+
+  /**
+   * Return the first cached accessible parent of a DOM node.
    *
-   * XXX: this method must go away once we'll implement correct accessible tree.
-   *
-   * @param  aNode  [in] the DOM node to get relevant content node
-   * @return         the DOM node for parent attached accessible
+   * @param aDOMNode    [in] the DOM node to get an accessible for
    */
-  nsINode *GetRelevantContentNodeFor(nsINode *aNode);
+  nsAccessible* GetCachedContainerAccessible(nsINode *aNode);
 
   /**
    * Initialize an accessible and cache it. The method should be called for
    * every created accessible.
    *
    * @param  aAccessible    [in] accessible to initialize.
    * @param  aRoleMapEntry  [in] the role map entry role the ARIA role or nsnull
    *                          if none
@@ -226,21 +222,40 @@ private:
    */
   PRBool Init();
 
   /**
    * Shutdowns accessibility service.
    */
   void Shutdown();
 
+  enum EWhatAccToGet {
+    eGetAccForNode = 0x1,
+    eGetAccForContainer = 0x2,
+    eGetAccForNodeOrContainer = eGetAccForNode | eGetAccForContainer
+  };
+
+  /**
+   * Return accessible or accessible container for the given node in presshell.
+   */
+  nsAccessible* GetAccessibleByRule(nsINode* aNode,
+                                    nsIWeakReference* aWeakShell,
+                                    EWhatAccToGet aWhatToGet);
+
   /**
    * Return accessible for HTML area element associated with an image map.
+   *
+   * @param  aImageFrame       [in] image frame
+   * @param  aAreaNode         [in] area node
+   * @param  aWeakShell        [in] presshell of image frame
+   * @param  aImageAccessible  [out, optional] image accessible, isn't addrefed
    */
   nsAccessible* GetAreaAccessible(nsIFrame* aImageFrame, nsINode* aAreaNode,
-                                  nsIWeakReference* aWeakShell);
+                                  nsIWeakReference* aWeakShell,
+                                  nsAccessible** aImageAccessible = nsnull);
 
   /**
    * Create accessible for the element implementing nsIAccessibleProvider
    * interface.
    */
   already_AddRefed<nsAccessible>
     CreateAccessibleByType(nsIContent* aContent, nsIWeakReference* aWeakShell);
 
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -808,26 +808,23 @@ nsAccessible::GetChildAtPoint(PRInt32 aX
   nsIFrame *foundFrame = presShell->GetFrameForPoint(frame, offset);
 
   nsIContent* content = nsnull;
   if (!foundFrame || !(content = foundFrame->GetContent())) {
     NS_IF_ADDREF(*aChild = fallbackAnswer);
     return NS_OK;
   }
 
-  nsINode *relevantNode = GetAccService()->GetRelevantContentNodeFor(content);
-  nsAccessible *accessible = GetAccService()->GetAccessible(relevantNode);
+  // Get accessible for the node with the point or the first accessible in
+  // the DOM parent chain.
+  nsAccessible* accessible =
+   GetAccService()->GetAccessibleOrContainer(content, mWeakShell);
   if (!accessible) {
-    // No accessible for the node with the point, so find the first
-    // accessible in the DOM parent chain
-    accessible = GetAccService()->GetContainerAccessible(relevantNode, PR_TRUE);
-    if (!accessible) {
-      NS_IF_ADDREF(*aChild = fallbackAnswer);
-      return NS_OK;
-    }
+    NS_IF_ADDREF(*aChild = fallbackAnswer);
+    return NS_OK;
   }
 
   if (accessible == this) {
     // Manually walk through accessible children and see if the are within this
     // point. Skip offscreen or invisible accessibles. This takes care of cases
     // where layout won't walk into things for us, such as image map areas and
     // sub documents (XXX: subdocuments should be handled by methods of
     // nsOuterDocAccessibles).
@@ -1237,18 +1234,16 @@ nsAccessible::GetXULName(nsAString& aLab
 
   return nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
 }
 
 nsresult
 nsAccessible::HandleAccEvent(nsAccEvent *aEvent)
 {
   NS_ENSURE_ARG_POINTER(aEvent);
-  NS_ENSURE_TRUE(nsAccUtils::IsNodeRelevant(aEvent->GetNode()),
-                 NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIObserverService> obsService =
     mozilla::services::GetObserverService();
   NS_ENSURE_TRUE(obsService, NS_ERROR_FAILURE);
 
   return obsService->NotifyObservers(aEvent, NS_ACCESSIBLE_EVENT_TOPIC, nsnull);
 }
 
@@ -2670,32 +2665,17 @@ nsAccessible::Init()
     GetAccService()->GetDocAccessible(mContent->GetOwnerDoc());
   NS_ASSERTION(docAcc, "Cannot cache new nsAccessible!");
   if (!docAcc)
     return PR_FALSE;
 
   void *uniqueID = nsnull;
   GetUniqueID(&uniqueID);
 
-  if (!docAcc->CacheAccessible(uniqueID, this))
-    return PR_FALSE;
-
-  // Make sure an ancestor in real content is cached so that
-  // nsDocAccessible::RefreshNodes() can find the anonymous subtree to release
-  // when the root node goes away. /Specific examples of where this is used:
-  // <input type="file"> and <xul:findbar>.
-  // XXX: remove this once we create correct accessible tree.
-  if (mContent && mContent->IsInAnonymousSubtree()) {
-    nsAccessible *parent = GetAccService()->GetContainerAccessible(mContent,
-                                                                   PR_TRUE);
-    if (parent)
-      parent->EnsureChildren();
-  }
-
-  return PR_TRUE;
+  return docAcc->CacheAccessible(uniqueID, this);
 }
 
 void
 nsAccessible::Shutdown()
 {
   // Invalidate the child count and pointers to other accessibles, also make
   // sure none of its children point to this parent
   InvalidateChildren();
@@ -2774,41 +2754,43 @@ nsAccessible::InvalidateChildren()
 
   mChildren.Clear();
   mAreChildrenInitialized = PR_FALSE;
 }
 
 nsAccessible*
 nsAccessible::GetParent()
 {
+  if (mParent)
+    return mParent;
+
   if (IsDefunct())
     return nsnull;
 
-  if (mParent)
-    return mParent;
+  // XXX: mParent can be null randomly because supposedly we get layout
+  // notification and invalidate parent-child relations, this accessible stays
+  // unattached. This should gone after bug 572951. Other reason is bug 574588
+  // since CacheChildren() implementation calls nsAccessible::GetRole() what
+  // can need to get a parent and we are here as result.
+  NS_WARNING("Bad accessible tree!");
 
 #ifdef DEBUG
   nsDocAccessible *docAccessible = GetDocAccessible();
   NS_ASSERTION(docAccessible, "No document accessible for valid accessible!");
 #endif
 
-  nsAccessible *parent = GetAccService()->GetContainerAccessible(mContent,
-                                                                 PR_TRUE);
+  nsAccessible* parent = GetAccService()->GetContainerAccessible(mContent,
+                                                                 mWeakShell);
   NS_ASSERTION(parent, "No accessible parent for valid accessible!");
   if (!parent)
     return nsnull;
 
-#ifdef DEBUG
-  NS_ASSERTION(!parent->IsDefunct(), "Defunct parent!");
-
+  // Repair parent-child relations.
   parent->EnsureChildren();
-  if (parent != mParent)
-    NS_WARNING("Bad accessible tree!");
-#endif
-
+  NS_ASSERTION(parent == mParent, "Wrong children repair!");
   return parent;
 }
 
 nsAccessible*
 nsAccessible::GetChildAt(PRUint32 aIndex)
 {
   if (EnsureChildren())
     return nsnull;
@@ -2840,35 +2822,16 @@ nsAccessible::GetIndexOf(nsIAccessible *
 
 PRInt32
 nsAccessible::GetIndexInParent()
 {
   nsAccessible *parent = GetParent();
   return parent ? parent->GetIndexOf(this) : -1;
 }
 
-nsAccessible*
-nsAccessible::GetCachedParent()
-{
-  if (IsDefunct())
-    return nsnull;
-
-  return mParent;
-}
-
-nsAccessible*
-nsAccessible::GetCachedFirstChild()
-{
-  if (IsDefunct())
-    return nsnull;
-
-  return mChildren.SafeElementAt(0, nsnull);
-}
-
-
 #ifdef DEBUG
 PRBool
 nsAccessible::IsInCache()
 {
   nsDocAccessible *docAccessible =
     GetAccService()->GetDocAccessible(mContent->GetOwnerDoc());
   if (!docAccessible)
     return nsnull;
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -230,17 +230,17 @@ public:
   virtual PRBool RemoveChild(nsAccessible *aAccessible) { return PR_FALSE; }
 
   //////////////////////////////////////////////////////////////////////////////
   // Accessible tree traverse methods
 
   /**
    * Return parent accessible.
    */
-  virtual nsAccessible* GetParent();
+  nsAccessible* GetParent();
 
   /**
    * Return child accessible at the given index.
    */
   virtual nsAccessible* GetChildAt(PRUint32 aIndex);
 
   /**
    * Return child accessible count.
@@ -258,24 +258,23 @@ public:
   PRInt32 GetIndexInParent();
 
   /**
    * Return true if accessible has children;
    */
   PRBool HasChildren() { return !!GetChildAt(0); }
 
   /**
-   * Return parent accessible only if cached.
+   * Return cached accessible of parent-child relatives.
    */
-  nsAccessible* GetCachedParent();
+  nsAccessible* GetCachedParent() const { return mParent; }
+  nsAccessible* GetCachedFirstChild() const
+    { return mChildren.SafeElementAt(0, nsnull); }
 
-  /**
-   * Return first child accessible only if cached.
-   */
-  nsAccessible* GetCachedFirstChild();
+  PRBool AreChildrenCached() const { return mAreChildrenInitialized; }
 
 #ifdef DEBUG
   /**
    * Return true if the access node is cached.
    */
   PRBool IsInCache();
 #endif
 
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -400,22 +400,16 @@ nsApplicationAccessible::GetStateInterna
   }
 
   if (aExtraState)
     *aExtraState = 0;
 
   return NS_OK;
 }
 
-nsAccessible*
-nsApplicationAccessible::GetParent()
-{
-  return nsnull;
-}
-
 void
 nsApplicationAccessible::InvalidateChildren()
 {
   // Do nothing because application children are kept updated by AppendChild()
   // and RemoveChild() method calls.
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/base/nsApplicationAccessible.h
+++ b/accessible/src/base/nsApplicationAccessible.h
@@ -108,17 +108,16 @@ public:
   virtual PRBool IsDefunct();
   virtual PRBool Init();
   virtual void Shutdown();
 
   // nsAccessible
   virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
-  virtual nsAccessible* GetParent();
 
   virtual void InvalidateChildren();
   virtual PRBool AppendChild(nsAccessible* aChild);
   virtual PRBool RemoveChild(nsAccessible* aChild);
 
 protected:
 
   // nsAccessible
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -950,18 +950,16 @@ nsDocAccessible::AttributeChangedImpl(ns
     return; // Still loading, ignore setting of initial attributes
 
   nsCOMPtr<nsIPresShell> shell = GetPresShell();
   if (!shell) {
     return; // Document has been shut down
   }
 
   NS_ASSERTION(aContent, "No node for attr modified");
-  if (!aContent || !nsAccUtils::IsNodeRelevant(aContent))
-    return;
 
   // Universal boolean properties that don't require a role. Fire the state
   // change when disabled or aria-disabled attribute is set.
   if (aAttribute == nsAccessibilityAtoms::disabled ||
       aAttribute == nsAccessibilityAtoms::aria_disabled) {
 
     // Note. Checking the XUL or HTML namespace would not seem to gain us
     // anything, because disabled attribute really is going to mean the same
@@ -1267,22 +1265,16 @@ void
 nsDocAccessible::ParentChainChanged(nsIContent *aContent)
 {
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible
 
-nsAccessible*
-nsDocAccessible::GetParent()
-{
-  return IsDefunct() ? nsnull : mParent.get();
-}
-
 #ifdef DEBUG_ACCDOCMGR
 nsresult
 nsDocAccessible::HandleAccEvent(nsAccEvent *aAccEvent)
 {
   NS_LOG_ACCDOCLOAD_HANDLEEVENT(aAccEvent)
 
   return nsHyperTextAccessible::HandleAccEvent(aAccEvent);
 
@@ -1508,26 +1500,27 @@ nsDocAccessible::ProcessPendingEvent(nsA
         return;
       }
       gLastFocusedFrameType = newFrameType;
     }
   }
 
   if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
 
-    nsAccessible *containerAccessible = nsnull;
-    if (accessible)
+    nsAccessible* containerAccessible = nsnull;
+    if (accessible) {
       containerAccessible = accessible->GetParent();
+    } else {
+      nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(node));
+      containerAccessible = GetAccService()->GetContainerAccessible(node,
+                                                                    weakShell);
+    }
 
-    if (!containerAccessible) {
-      containerAccessible = GetAccService()->GetContainerAccessible(node,
-                                                                    PR_TRUE);
-      if (!containerAccessible)
-        containerAccessible = this;
-    }
+    if (!containerAccessible)
+      containerAccessible = this;
 
     if (isAsync) {
       // For asynch show, delayed invalidatation of parent's children
       containerAccessible->InvalidateChildren();
 
       // Some show events in the subtree may have been removed to 
       // avoid firing redundant events. But, we still need to make sure any
       // accessibles parenting those shown nodes lose their child references.
@@ -1764,17 +1757,17 @@ nsDocAccessible::InvalidateCacheSubtree(
     nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
     NS_ENSURE_TRUE(esm,);
 
     if (!esm->IsHandlingUserInputExternal()) {
       // Changes during page load, but not caused by user input
       // Just invalidate accessible hierarchy and return,
       // otherwise the page load time slows down way too much
       nsAccessible *containerAccessible =
-        GetAccService()->GetContainerAccessible(childNode, PR_FALSE);
+        GetAccService()->GetCachedContainerAccessible(childNode);
       if (!containerAccessible) {
         containerAccessible = this;
       }
 
       containerAccessible->InvalidateChildren();
       return;
     }     
     // else: user input, so we must fall through and for full handling,
@@ -1800,17 +1793,17 @@ nsDocAccessible::InvalidateCacheSubtree(
     printf("[Create %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
   else if (aChangeType == nsIAccessibilityService::NODE_REMOVE)
     printf("[Destroy  %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
   else if (aChangeType == nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE)
     printf("[Type change %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
 #endif
 
   nsAccessible *containerAccessible =
-    GetAccService()->GetContainerAccessible(childNode, PR_TRUE);
+    GetAccService()->GetCachedContainerAccessible(childNode);
   if (!containerAccessible) {
     containerAccessible = this;
   }
 
   if (!isShowing) {
     // Fire EVENT_HIDE.
     if (isHiding) {
       if (aChild) {
@@ -1945,17 +1938,17 @@ nsDocAccessible::FireShowHideEvents(nsIN
 
   nsAccessible *accessible = nsnull;
   if (!aAvoidOnThisNode) {
     if (aEventType == nsIAccessibleEvent::EVENT_HIDE) {
       // Don't allow creation for accessibles when nodes going away
       accessible = GetCachedAccessible(aNode);
     } else {
       // Allow creation of new accessibles for show events
-      accessible = GetAccService()->GetAttachedAccessibleFor(aNode);
+      accessible = GetAccService()->GetAccessible(aNode);
     }
   }
 
   if (accessible) {
     // Found an accessible, so fire the show/hide on it and don't look further
     // into this subtree.
     nsRefPtr<nsAccEvent> event =
       new nsAccEvent(aEventType, accessible, aIsAsyncChange, aIsFromUserInput,
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -108,17 +108,16 @@ public:
   virtual nsINode* GetNode() const { return mDocument; }
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
 
   virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
-  virtual nsAccessible* GetParent();
 
 #ifdef DEBUG_ACCDOCMGR
   virtual nsresult HandleAccEvent(nsAccEvent *aAccEvent);
 #endif
 
   // nsIAccessibleText
   NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
 
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -453,109 +453,77 @@ nsRootAccessible::FireAccessibleFocusEve
 }
 
 void
 nsRootAccessible::FireCurrentFocusEvent()
 {
   if (IsDefunct())
     return;
 
+  // Simulate a focus event so that we can reuse code that fires focus for
+  // container children like treeitems.
   nsCOMPtr<nsINode> focusedNode = GetCurrentFocus();
   if (!focusedNode) {
     return; // No current focus
   }
 
-  // Simulate a focus event so that we can reuse code that fires focus for container children like treeitems
   nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(mDocument);
   if (docEvent) {
     nsCOMPtr<nsIDOMEvent> event;
     if (NS_SUCCEEDED(docEvent->CreateEvent(NS_LITERAL_STRING("Events"),
                                            getter_AddRefs(event))) &&
         NS_SUCCEEDED(event->InitEvent(NS_LITERAL_STRING("focus"), PR_TRUE, PR_TRUE))) {
-      // Get the target node we really want for the event.
 
-      nsINode *targetNode =
-        GetAccService()->GetRelevantContentNodeFor(focusedNode);
-      if (targetNode) {
-        // If the focused element is document element or HTML body element
-        // then simulate the focus event for the document.
-        nsINode *document = targetNode->GetOwnerDoc();
-        if (targetNode == nsCoreUtils::GetRoleContent(document)) {
-          HandleEventWithTarget(event, document);
-          return;
-        }
-
-        // Otherwise simulate the focus event for currently focused node.
-        nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
-        nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(focusedNode));
-        privateEvent->SetTarget(target);
-        HandleEventWithTarget(event, targetNode);
-      }
+      nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
+      nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(focusedNode));
+      privateEvent->SetTarget(target);
+      HandleEvent(event);
     }
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIDOMEventListener
 
-NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
+NS_IMETHODIMP
+nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
 {
-  // Turn DOM events in accessibility events
-  // Get info about event and target
-  nsCOMPtr<nsIDOMNode> targetNode;
-  GetTargetNode(aEvent, getter_AddRefs(targetNode));
-  if (!targetNode)
-    return NS_ERROR_FAILURE;
+  nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
+  NS_ENSURE_STATE(nsevent);
 
-  nsCOMPtr<nsINode> node(do_QueryInterface(targetNode));
-  return HandleEventWithTarget(aEvent, node);
-}
-
+  nsCOMPtr<nsIDOMEventTarget> domEventTarget;
+  nsevent->GetOriginalTarget(getter_AddRefs(domEventTarget));
+  nsCOMPtr<nsINode> origTarget(do_QueryInterface(domEventTarget));
+  NS_ENSURE_STATE(origTarget);
 
-// nsRootAccessible protected member
-nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
-                                                 nsINode* aTargetNode)
-{
   nsAutoString eventType;
   aEvent->GetType(eventType);
-  nsAutoString localName;
-  nsCOMPtr<nsIContent> targetContent(do_QueryInterface(aTargetNode));
-  if (targetContent)
-    targetContent->NodeInfo()->GetName(localName);
-#ifdef MOZ_XUL
-  PRBool isTree = localName.EqualsLiteral("tree");
-#endif
-#ifdef DEBUG_A11Y
-  // Very useful for debugging, please leave this here.
-  if (eventType.EqualsLiteral("AlertActive")) {
-    printf("\ndebugging %s events for %s", NS_ConvertUTF16toUTF8(eventType).get(), NS_ConvertUTF16toUTF8(localName).get());
-  }
-  if (localName.LowerCaseEqualsLiteral("textbox")) {
-    printf("\ndebugging %s events for %s", NS_ConvertUTF16toUTF8(eventType).get(), NS_ConvertUTF16toUTF8(localName).get());
-  }
-#endif
-
-  nsAccessibilityService *accService = GetAccService();
-  NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIWeakReference> weakShell =
-    nsCoreUtils::GetWeakShellFor(aTargetNode);
+    nsCoreUtils::GetWeakShellFor(origTarget);
   if (!weakShell)
     return NS_OK;
 
-  nsAccessible *accessible =
-    accService->GetAccessibleInWeakShell(aTargetNode, weakShell);
+  nsAccessible* accessible =
+    GetAccService()->GetAccessibleOrContainer(origTarget, weakShell);
 
   if (eventType.EqualsLiteral("popuphiding"))
-    return HandlePopupHidingEvent(aTargetNode, accessible);
+    return HandlePopupHidingEvent(origTarget, accessible);
 
   if (!accessible)
     return NS_OK;
 
+  nsINode* targetNode = accessible->GetNode();
+  nsIContent* targetContent = targetNode->IsElement() ?
+    targetNode->AsElement() : nsnull;
 #ifdef MOZ_XUL
+  PRBool isTree = targetContent ?
+    targetContent->NodeInfo()->Equals(nsAccessibilityAtoms::tree,
+                                      kNameSpaceID_XUL) : PR_FALSE;
+
   if (isTree) {
     nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
     NS_ASSERTION(treeAcc,
                  "Accessible for xul:tree isn't nsXULTreeAccessible.");
 
     if (treeAcc) {
       if (eventType.EqualsLiteral("TreeViewChanged")) {
         treeAcc->TreeViewChanged();
@@ -582,17 +550,17 @@ nsresult nsRootAccessible::HandleEventWi
                         nsIAccessibleStates::STATE_SELECTED)) != 0;
 
     nsRefPtr<nsAccEvent> accEvent =
       new nsAccStateChangeEvent(accessible, nsIAccessibleStates::STATE_CHECKED,
                                 PR_FALSE, isEnabled);
     nsEventShell::FireEvent(accEvent);
 
     if (isEnabled)
-      FireAccessibleFocusEvent(accessible, aTargetNode, aEvent);
+      FireAccessibleFocusEvent(accessible, targetNode, aEvent);
 
     return NS_OK;
   }
 
   if (eventType.EqualsLiteral("CheckboxStateChange")) {
     PRUint32 state = nsAccUtils::State(accessible);
 
     PRBool isEnabled = !!(state & nsIAccessibleStates::STATE_CHECKED);
@@ -606,17 +574,17 @@ nsresult nsRootAccessible::HandleEventWi
     return NS_OK;
   }
 
   nsAccessible *treeItemAccessible = nsnull;
 #ifdef MOZ_XUL
   // If it's a tree element, need the currently selected item
   if (isTree) {
     nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelect =
-      do_QueryInterface(aTargetNode);
+      do_QueryInterface(targetNode);
     if (multiSelect) {
       PRInt32 treeIndex = -1;
       multiSelect->GetCurrentIndex(&treeIndex);
       if (treeIndex >= 0) {
         nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
         if (treeAcc) {
           treeItemAccessible = treeAcc->GetTreeItemAccessible(treeIndex);
           if (treeItemAccessible)
@@ -636,19 +604,19 @@ nsresult nsRootAccessible::HandleEventWi
       new nsAccStateChangeEvent(accessible, nsIAccessibleStates::STATE_EXPANDED,
                                 PR_FALSE, isEnabled);
     nsEventShell::FireEvent(accEvent);
     return NS_OK;
   }
 
   if (treeItemAccessible && eventType.EqualsLiteral("select")) {
     // If multiselect tree, we should fire selectionadd or selection removed
-    if (gLastFocusedNode == aTargetNode) {
+    if (gLastFocusedNode == targetNode) {
       nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSel =
-        do_QueryInterface(aTargetNode);
+        do_QueryInterface(targetNode);
       nsAutoString selType;
       multiSel->GetSelType(selType);
       if (selType.IsEmpty() || !selType.EqualsLiteral("single")) {
         // XXX: We need to fire EVENT_SELECTION_ADD and EVENT_SELECTION_REMOVE
         // for each tree item. Perhaps each tree item will need to cache its
         // selection state and fire an event after a DOM "select" event when
         // that state changes. nsXULTreeAccessible::UpdateTreeSelection();
         nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
@@ -659,47 +627,46 @@ nsresult nsRootAccessible::HandleEventWi
       nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION,
                               treeItemAccessible);
       return NS_OK;
     }
   }
   else
 #endif
   if (eventType.EqualsLiteral("focus")) {
-    if (aTargetNode == mDocument && mDocument != gLastFocusedNode) {
+    if (targetNode == mDocument && mDocument != gLastFocusedNode) {
       // Got focus event for the window, we will make sure that an accessible
       // focus event for initial focus is fired. We do this on a short timer
       // because the initial focus may not have been set yet.
       NS_DISPATCH_RUNNABLEMETHOD(FireCurrentFocusEvent, this)
     }
 
     // Keep a reference to the target node. We might want to change
     // it to the individual radio button or selected item, and send
     // the focus event to that.
-    nsCOMPtr<nsINode> focusedItem(aTargetNode);
-
+    nsCOMPtr<nsINode> focusedItem = targetNode;
     if (!treeItemAccessible) {
       nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
-        do_QueryInterface(aTargetNode);
+        do_QueryInterface(targetNode);
       if (selectControl) {
         nsCOMPtr<nsIDOMXULMenuListElement> menuList =
-          do_QueryInterface(aTargetNode);
+          do_QueryInterface(targetNode);
         if (!menuList) {
           // Don't do this for menu lists, the items only get focused
           // when the list is open, based on DOMMenuitemActive events
           nsCOMPtr<nsIDOMXULSelectControlItemElement> selectedItem;
           selectControl->GetSelectedItem(getter_AddRefs(selectedItem));
           if (selectedItem)
             focusedItem = do_QueryInterface(selectedItem);
 
           if (!focusedItem)
             return NS_OK;
 
-          accessible = accService->GetAccessibleInWeakShell(focusedItem,
-                                                            weakShell);
+          accessible = GetAccService()->GetAccessibleInWeakShell(focusedItem,
+                                                                 weakShell);
           if (!accessible)
             return NS_OK;
         }
       }
     }
     FireAccessibleFocusEvent(accessible, focusedItem, aEvent);
   }
   else if (eventType.EqualsLiteral("blur")) {
@@ -751,83 +718,57 @@ nsresult nsRootAccessible::HandleEventWi
           if (nsAccUtils::Role(containerParent) != nsIAccessibleRole::ROLE_COMBOBOX) {
             return NS_OK;
           }
         }
       }
     }
     if (!fireFocus) {
       nsCOMPtr<nsINode> realFocusedNode = GetCurrentFocus();
-      nsCOMPtr<nsIContent> realFocusedContent = do_QueryInterface(realFocusedNode);
-      nsCOMPtr<nsIContent> targetContent = do_QueryInterface(aTargetNode);
-      nsIContent *containerContent = targetContent;
+      nsIContent* realFocusedContent = realFocusedNode->AsElement();
+      nsIContent* containerContent = targetContent;
       while (containerContent) {
         nsCOMPtr<nsIDOMXULPopupElement> popup = do_QueryInterface(containerContent);
         if (popup || containerContent == realFocusedContent) { 
           // If we're inside the focus or a popup we can fire focus events
           // for the changed active item
           fireFocus = PR_TRUE;
           break;
         }
         containerContent = containerContent->GetParent();
       }
     }
     if (fireFocus) {
       // Always asynch, always from user input.
-      FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE,
+      FireAccessibleFocusEvent(accessible, targetNode, aEvent, PR_TRUE,
                                PR_TRUE, eFromUserInput);
     }
   }
   else if (eventType.EqualsLiteral("DOMMenuBarActive")) {  // Always asynch, always from user input
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_START,
                             accessible, PR_TRUE, eFromUserInput);
   }
   else if (eventType.EqualsLiteral("DOMMenuBarInactive")) {  // Always asynch, always from user input
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_END,
                             accessible, PR_TRUE, eFromUserInput);
     FireCurrentFocusEvent();
   }
   else if (eventType.EqualsLiteral("ValueChange")) {
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
-                               aTargetNode, nsAccEvent::eRemoveDupes);
+                               targetNode, nsAccEvent::eRemoveDupes);
   }
 #ifdef DEBUG
   else if (eventType.EqualsLiteral("mouseover")) {
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START,
                             accessible);
   }
 #endif
   return NS_OK;
 }
 
-void nsRootAccessible::GetTargetNode(nsIDOMEvent *aEvent, nsIDOMNode **aTargetNode)
-{
-  *aTargetNode = nsnull;
-
-  nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
-
-  if (!nsevent)
-    return;
-
-  nsCOMPtr<nsIDOMEventTarget> domEventTarget;
-  nsevent->GetOriginalTarget(getter_AddRefs(domEventTarget));
-  nsCOMPtr<nsIDOMNode> eventTarget(do_QueryInterface(domEventTarget));
-  if (!eventTarget)
-    return;
-
-  nsIAccessibilityService* accService = GetAccService();
-  if (accService) {
-    nsresult rv = accService->GetRelevantContentNodeFor(eventTarget,
-                                                        aTargetNode);
-    if (NS_SUCCEEDED(rv) && *aTargetNode)
-      return;
-  }
-
-  NS_ADDREF(*aTargetNode = eventTarget);
-}
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode
 
 PRBool
 nsRootAccessible::Init()
 {
   nsApplicationAccessible *applicationAcc = GetApplicationAccessible();
@@ -928,27 +869,16 @@ nsRootAccessible::GetRelationByType(PRUi
     nsDocAccessible *accDoc = nsAccUtils::GetDocAccessibleFor(contentTreeItem);
     return nsRelUtils::AddTarget(aRelationType, aRelation, accDoc);
   }
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccessible
-
-nsAccessible*
-nsRootAccessible::GetParent()
-{
-  // Parent has been set in nsApplicationAccesible::AppendChild() when root
-  // accessible was initialized.
-  return mParent;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // Protected members
 
 nsresult
 nsRootAccessible::HandlePopupShownEvent(nsAccessible *aAccessible)
 {
   PRUint32 role = nsAccUtils::Role(aAccessible);
 
   if (role == nsIAccessibleRole::ROLE_MENUPOPUP) {
--- a/accessible/src/base/nsRootAccessible.h
+++ b/accessible/src/base/nsRootAccessible.h
@@ -82,17 +82,16 @@ public:
 
   // nsAccessNode
   virtual PRBool Init();
   virtual void Shutdown();
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
-  virtual nsAccessible* GetParent();
 
   // nsRootAccessible
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
 
   /**
    * Fire an accessible focus event for the current focusAccssible
    * and attach a new selection listener, if necessary.
    *
@@ -121,29 +120,22 @@ public:
 
 protected:
   NS_DECL_RUNNABLEMETHOD(nsRootAccessible, FireCurrentFocusEvent)
 
     nsresult AddEventListeners();
     nsresult RemoveEventListeners();
 
   /**
-   * Process DOM events.
-   */
-  nsresult HandleEventWithTarget(nsIDOMEvent* aEvent, nsINode* aTargetNode);
-
-    static void GetTargetNode(nsIDOMEvent *aEvent, nsIDOMNode **aTargetNode);
-
-  /**
-   * Process "popupshown" event. Used by HandleEventWithTarget().
+   * Process "popupshown" event. Used by HandleEvent().
    */
 
   nsresult HandlePopupShownEvent(nsAccessible *aAccessible);
   /*
-   * Process "popuphiding" event. Used by HandleEventWithTarget().
+   * Process "popuphiding" event. Used by HandleEvent().
    */
   nsresult HandlePopupHidingEvent(nsINode *aNode, nsAccessible *aAccessible);
 
 #ifdef MOZ_XUL
     nsresult HandleTreeRowCountChangedEvent(nsIDOMEvent *aEvent,
                                             nsXULTreeAccessible *aAccessible);
     nsresult HandleTreeInvalidatedEvent(nsIDOMEvent *aEvent,
                                         nsXULTreeAccessible *aAccessible);
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -366,30 +366,32 @@ nsHTMLSelectListAccessible::CacheChildre
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLSelectListAccessible protected
 
 void
 nsHTMLSelectListAccessible::CacheOptSiblings(nsIContent *aParentContent)
 {
+  nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
   PRUint32 numChildren = aParentContent->GetChildCount();
   for (PRUint32 count = 0; count < numChildren; count ++) {
     nsIContent *childContent = aParentContent->GetChildAt(count);
     if (!childContent->IsHTML()) {
       continue;
     }
 
     nsCOMPtr<nsIAtom> tag = childContent->Tag();
     if (tag == nsAccessibilityAtoms::option ||
         tag == nsAccessibilityAtoms::optgroup) {
 
       // Get an accessible for option or optgroup and cache it.
-      nsAccessible *accessible =
-        GetAccService()->GetAccessibleInWeakShell(childContent, mWeakShell);
+      nsRefPtr<nsAccessible> accessible =
+        GetAccService()->GetOrCreateAccessible(childContent, presShell,
+                                               mWeakShell);
       if (accessible) {
         mChildren.AppendElement(accessible);
         accessible->SetParent(this);
       }
 
       // Deep down into optgroup element.
       if (tag == nsAccessibilityAtoms::optgroup)
         CacheOptSiblings(childContent);
@@ -927,21 +929,29 @@ nsHTMLComboboxAccessible::CacheChildren(
     return;
 
   if (!mListAccessible) {
     mListAccessible = 
       new nsHTMLComboboxListAccessible(mParent, mContent, mWeakShell);
     if (!mListAccessible)
       return;
 
-    mListAccessible->Init();
+    // Initialize and put into cache.
+    if (!mListAccessible->Init()) {
+      mListAccessible->Shutdown();
+      return;
+    }
   }
 
   mChildren.AppendElement(mListAccessible);
   mListAccessible->SetParent(this);
+
+  // Cache combobox option accessibles so that we build complete accessible tree
+  // for combobox.
+  mListAccessible->EnsureChildren();
 }
 
 void
 nsHTMLComboboxAccessible::Shutdown()
 {
   nsAccessibleWrap::Shutdown();
 
   if (mListAccessible) {
@@ -1166,15 +1176,8 @@ void nsHTMLComboboxListAccessible::GetBo
   if (!frame) {
     *aBoundingFrame = nsnull;
     return;
   }
 
   *aBoundingFrame = frame->GetParent();
   aBounds = (*aBoundingFrame)->GetRect();
 }
-
-// nsHTMLComboboxListAccessible. nsAccessible public mehtod
-nsAccessible*
-nsHTMLComboboxListAccessible::GetParent()
-{
-  return mParent;
-}
--- a/accessible/src/html/nsHTMLSelectAccessible.h
+++ b/accessible/src/html/nsHTMLSelectAccessible.h
@@ -271,12 +271,11 @@ public:
   NS_IMETHOD GetUniqueID(void **aUniqueID);
 
   // nsAccessNode
   virtual nsIFrame* GetFrame();
 
   // nsAccessible
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
-  virtual nsAccessible* GetParent();
 };
 
 #endif
--- a/accessible/src/html/nsHTMLTextAccessible.cpp
+++ b/accessible/src/html/nsHTMLTextAccessible.cpp
@@ -342,22 +342,16 @@ nsHTMLListBulletAccessible::AppendTextTo
   PRUint32 maxLength = mBulletText.Length() - aStartOffset;
   if (aLength > maxLength) {
     aLength = maxLength;
   }
   aText += Substring(mBulletText, aStartOffset, aLength);
   return NS_OK;
 }
 
-nsAccessible*
-nsHTMLListBulletAccessible::GetParent()
-{
-  return mParent;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLListAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHTMLListAccessible::
   nsHTMLListAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsHyperTextAccessibleWrap(aContent, aShell)
 {
--- a/accessible/src/html/nsHTMLTextAccessible.h
+++ b/accessible/src/html/nsHTMLTextAccessible.h
@@ -124,18 +124,16 @@ public:
   virtual void Shutdown();
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
                                 PRUint32 aLength);
 
-  virtual nsAccessible* GetParent();
-
 protected:
   // XXX: Ideally we'd get the bullet text directly from the bullet frame via
   // nsBulletFrame::GetListItemText(), but we'd need an interface for getting
   // text from contentless anonymous frames. Perhaps something like
   // nsIAnonymousFrame::GetText() ? However, in practice storing the bullet text
   // here should not be a problem if we invalidate the right parts of
   // the accessibility cache when mutation events occur.
   nsString mBulletText;
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1676,17 +1676,17 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
   if (!childID)
     return NS_OK; // Can't fire an event without a child ID
 
   // See if we're in a scrollable area with its own window
   nsAccessible *newAccessible = nsnull;
   if (eventType == nsIAccessibleEvent::EVENT_HIDE) {
     // Don't use frame from current accessible when we're hiding that
     // accessible.
-    newAccessible = accessible->GetParent();
+    newAccessible = accessible->GetCachedParent();
   } else {
     newAccessible = accessible;
   }
 
   HWND hWnd = GetHWNDFor(newAccessible);
   NS_ENSURE_TRUE(hWnd, NS_ERROR_FAILURE);
 
   // Gecko uses two windows for every scrollable area. One window contains
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -113,27 +113,30 @@ nsXFormsAccessible::CacheSelectChildren(
     container = do_QueryInterface(mContent);
 
   nsCOMPtr<nsIDOMNodeList> children;
   sXFormsService->GetSelectChildrenFor(container, getter_AddRefs(children));
 
   if (!children)
     return;
 
+  nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
+
   PRUint32 length = 0;
   children->GetLength(&length);
 
   for (PRUint32 index = 0; index < length; index++) {
     nsCOMPtr<nsIDOMNode> DOMChild;
     children->Item(index, getter_AddRefs(DOMChild));
     if (!DOMChild)
       continue;
 
     nsCOMPtr<nsIContent> child(do_QueryInterface(DOMChild));
-    nsAccessible *accessible = GetAccService()->GetAttachedAccessibleFor(child);
+    nsRefPtr<nsAccessible> accessible =
+      GetAccService()->GetOrCreateAccessible(child, presShell, mWeakShell);
     if (!accessible)
       continue;
 
     mChildren.AppendElement(accessible);
     accessible->SetParent(this);
   }
 }
 
--- a/accessible/src/xul/nsXULColorPickerAccessible.cpp
+++ b/accessible/src/xul/nsXULColorPickerAccessible.cpp
@@ -161,16 +161,18 @@ nsXULColorPickerAccessible::GetRoleInter
 
 void
 nsXULColorPickerAccessible::CacheChildren()
 {
   nsAccTreeWalker walker(mWeakShell, mContent, PR_TRUE);
 
   nsRefPtr<nsAccessible> child;
   while ((child = walker.GetNextChild())) {
+    // XXX: do not call nsAccessible::GetRole() while accessible not in tree
+    // (bug 574588).
     PRUint32 role = nsAccUtils::Role(child);
 
     // Get an accessbile for menupopup or panel elements.
     if (role == nsIAccessibleRole::ROLE_ALERT) {
       mChildren.AppendElement(child);
       child->SetParent(this);
 
       return;
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -207,16 +207,18 @@ nsXULButtonAccessible::CacheChildren()
 
   nsRefPtr<nsAccessible> menupopupAccessible;
   nsRefPtr<nsAccessible> buttonAccessible;
 
   nsAccTreeWalker walker(mWeakShell, mContent, PR_TRUE);
 
   nsRefPtr<nsAccessible> child;
   while ((child = walker.GetNextChild())) {
+    // XXX: do not call nsAccessible::GetRole() while accessible not in tree
+    // (bug 574588).
     PRUint32 role = nsAccUtils::Role(child);
 
     if (role == nsIAccessibleRole::ROLE_MENUPOPUP) {
       // Get an accessbile for menupopup or panel elements.
       menupopupAccessible.swap(child);
 
     } else if (isMenuButton && role == nsIAccessibleRole::ROLE_PUSHBUTTON) {
       // Button type="menu-button" contains a real button. Get an accessible
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -1035,22 +1035,16 @@ nsXULTreeItemAccessibleBase::GetStateInt
   mTree->GetFirstVisibleRow(&firstVisibleRow);
   mTree->GetLastVisibleRow(&lastVisibleRow);
   if (mRow < firstVisibleRow || mRow > lastVisibleRow)
     *aState |= nsIAccessibleStates::STATE_INVISIBLE;
 
   return NS_OK;
 }
 
-nsAccessible*
-nsXULTreeItemAccessibleBase::GetParent()
-{
-  return IsDefunct() ? nsnull : mParent.get();
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessibleBase: nsAccessible protected methods
 
 void
 nsXULTreeItemAccessibleBase::DispatchClickEvent(nsIContent *aContent,
                                                 PRUint32 aActionIndex)
 {
   if (IsDefunct())
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -194,17 +194,16 @@ public:
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsAccessNode
   virtual PRBool IsDefunct();
   virtual void Shutdown();
 
   // nsAccessible
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
-  virtual nsAccessible* GetParent();
 
   // nsXULTreeItemAccessibleBase
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID)
 
   /**
    * Return row index associated with the accessible.
    */
   PRInt32 GetRowIndex() const { return mRow; }
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -1197,22 +1197,16 @@ nsXULTreeGridCellAccessible::GetStateInt
     mTreeView->GetCellValue(mRow, mColumn, checked);
     if (checked.EqualsIgnoreCase("true"))
       *aStates |= nsIAccessibleStates::STATE_CHECKED;
   }
 
   return NS_OK;
 }
 
-nsAccessible*
-nsXULTreeGridCellAccessible::GetParent()
-{
-  return IsDefunct() ? nsnull : mParent.get();
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridCellAccessible: public implementation
 
 PRInt32
 nsXULTreeGridCellAccessible::GetColumnIndex() const
 {
   PRInt32 index = 0;
   nsCOMPtr<nsITreeColumn> column = mColumn;
--- a/accessible/src/xul/nsXULTreeGridAccessible.h
+++ b/accessible/src/xul/nsXULTreeGridAccessible.h
@@ -157,18 +157,16 @@ public:
   virtual PRBool IsDefunct();
   virtual PRBool Init();
 
   // nsAccessible
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 
-  virtual nsAccessible* GetParent();
-
   // nsXULTreeGridCellAccessible
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID)
 
   /**
    * Return index of the column.
    */
   PRInt32 GetColumnIndex() const;
 
--- a/accessible/tests/mochitest/events/test_docload.html
+++ b/accessible/tests/mochitest/events/test_docload.html
@@ -122,16 +122,21 @@
     {
       // Get application root accessible.
       var docAcc = getAccessible(document);
       while (docAcc) {
         this.mRootAcc = docAcc;
         try {
           docAcc = docAcc.parent;
         } catch (e) {
+          // XXX: it may randomaly fail on propertypage accessible of browser's
+          // tabbbrowser if nsIAccessible::parent returns cached parent only.
+          // This should gone after bug 572951.
+          // Error: failed | Can't get parent for [ 'panel1277435313424' ,
+          // role: propertypage]
           ok(false, "Can't get parent for " + prettyName(docAcc));
           throw e;
         }
       }
 
       this.eventSeq = [
         new invokerChecker(EVENT_REORDER, this.mRootAcc)
       ];
--- a/accessible/tests/mochitest/events/test_text.html
+++ b/accessible/tests/mochitest/events/test_text.html
@@ -56,16 +56,17 @@
      */
     function removeChildSpan(aID)
     {
       this.__proto__ = new textRemoveInvoker(aID, 0, 5, "33322");
 
       this.invoke = function removeChildSpan_invoke()
       {
         // remove HTML span, a first child of the node
+        ensureAccessibleTree(this.DOMNode);
         this.DOMNode.removeChild(this.DOMNode.firstChild);
       }
 
       this.getID = function removeChildSpan_getID()
       {
         return "Remove inaccessible span containing accessible nodes" + prettyName(aID);
       }
     }
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/setup.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/setup.js
@@ -57,17 +57,17 @@ const POPUP_REMINDER_INTERVAL = "extensi
 const ALWAYS_SUBMIT_DATA = "extensions.testpilot.alwaysSubmitData";
 const LOG_FILE_NAME = "TestPilotErrorLog.log";
 
 let TestPilotSetup = {
   didReminderAfterStartup: false,
   startupComplete: false,
   _shortTimer: null,
   _longTimer: null,
-  _remoteExperimentLoader: null,
+  _remoteExperimentLoader: null, // TODO make this a lazy initializer too?
   taskList: [],
   version: "",
 
   // Lazy initializers:
   __application: null,
   get _application() {
     if (this.__application == null) {
       this.__application = Cc["@mozilla.org/fuel/application;1"]
@@ -367,20 +367,26 @@ let TestPilotSetup = {
     // exists.  No excuse to ever be running two copies of the same task.
     this.taskList.push(testPilotTask);
   },
 
   _showNotification: function TPS__showNotification(task, fragile, text, title,
                                                     iconClass, showSubmit,
 						    showAlwaysSubmitCheckbox,
                                                     linkText, linkUrl,
-						    isExtensionUpdate) {
+						    isExtensionUpdate,
+                                                    onCloseCallback) {
+    /* TODO: Refactor the arguments of this function, it's getting really
+     * unweildly.... maybe pass in an object, or even make a notification an
+     * object that you create and then call .show() on. */
+
     // If there are multiple windows, show notifications in the frontmost
     // window.
-    let doc = this._getFrontBrowserWindow().document;
+    let window = this._getFrontBrowserWindow();
+    let doc = window.document;
     let popup = doc.getElementById("pilot-notification-popup");
 
     let anchor;
     if (this._isFfx4BetaVersion()) {
       /* If we're in the Ffx4Beta version, popups come down from feedback
        * button, but if we're in the standalone extension version, they
        * come up from status bar icon. */
       anchor = doc.getElementById("feedback-menu-button");
@@ -417,24 +423,24 @@ let TestPilotSetup = {
     alwaysSubmitCheckbox.setAttribute("hidden", !showAlwaysSubmitCheckbox);
     if (showSubmit) {
       if (isExtensionUpdate) {
         submitBtn.setAttribute("label",
 	  this._stringBundle.GetStringFromName(
 	    "testpilot.notification.update"));
 	submitBtn.onclick = function() {
           this._extensionUpdater.check(EXTENSION_ID);
-          self._hideNotification();
+          self._hideNotification(window, onCloseCallback);
 	};
       } else {
         submitBtn.setAttribute("label",
 	  this._stringBundle.GetStringFromName("testpilot.submit"));
         // Functionality for submit button:
         submitBtn.onclick = function() {
-          self._hideNotification();
+          self._hideNotification(window, onCloseCallback);
           if (showAlwaysSubmitCheckbox && alwaysSubmitCheckbox.checked) {
             self._prefs.setValue(ALWAYS_SUBMIT_DATA, true);
           }
           task.upload( function(success) {
             if (success) {
               self._showNotification(
 		task, true,
                 self._stringBundle.GetStringFromName(
@@ -459,46 +465,52 @@ let TestPilotSetup = {
       link.setAttribute("class", "notification-link");
       link.onclick = function(event) {
         if (event.button == 0) {
 	  if (task) {
             task.loadPage();
 	  } else {
             self._openChromeless(linkUrl);
 	  }
-          self._hideNotification();
+          self._hideNotification(window, onCloseCallback);
         }
       };
       link.setAttribute("hidden", false);
     } else {
       link.setAttribute("hidden", true);
     }
 
     closeBtn.onclick = function() {
-      self._hideNotification();
+      self._hideNotification(window, onCloseCallback);
     };
 
     // Show the popup:
     popup.hidden = false;
     popup.setAttribute("open", "true");
     popup.openPopup( anchor, "after_end");
   },
 
   _openChromeless: function TPS__openChromeless(url) {
     let window = this._getFrontBrowserWindow();
     window.TestPilotWindowUtils.openChromeless(url);
   },
 
-  _hideNotification: function TPS__hideNotification() {
-    let window = this._getFrontBrowserWindow();
+  _hideNotification: function TPS__hideNotification(window, onCloseCallback) {
+    /* Note - we take window as an argument instead of just using the frontmost
+     * window because the window order might have changed since the notification
+     * appeared and we want to be sure we close the notification in the same
+     * window as we opened it in! */
     let popup = window.document.getElementById("pilot-notification-popup");
     popup.hidden = true;
     popup.setAttribute("open", "false");
     popup.removeAttribute("tpisextensionupdate");
     popup.hidePopup();
+    if (onCloseCallback) {
+      onCloseCallback();
+    }
   },
 
   _isShowingUpdateNotification : function() {
     let window = this._getFrontBrowserWindow();
     let popup = window.document.getElementById("pilot-notification-popup");
 
     return popup.hasAttribute("tpisextensionupdate");
   },
@@ -538,36 +550,38 @@ let TestPilotSetup = {
       }
     }
 
     // If there's no finished test, next highest priority is new tests that
     // are starting...
     if (this._prefs.getValue(POPUP_SHOW_ON_NEW, false)) {
       for (i = 0; i < this.taskList.length; i++) {
         task = this.taskList[i];
-        if (task.status == TaskConstants.STATUS_STARTING ||
+        if (task.status == TaskConstants.STATUS_PENDING ||
             task.status == TaskConstants.STATUS_NEW) {
           if (task.taskType == TaskConstants.TYPE_EXPERIMENT) {
 	    this._showNotification(
-	      task, true,
+	      task, false,
 	      this._stringBundle.formatStringFromName(
 		"testpilot.notification.newTestPilotStudy.message",
 		[task.title], 1),
 	      this._stringBundle.GetStringFromName(
 		"testpilot.notification.newTestPilotStudy"),
 	      "new-study", false, false,
 	      this._stringBundle.GetStringFromName("testpilot.moreInfo"),
-	      task.defaultUrl);
-            // Having shown the notification, update task status so that this
-            // notification won't be shown again.
-            task.changeStatus(TaskConstants.STATUS_IN_PROGRESS, true);
+	      task.defaultUrl, false, function() {
+                /* on close callback (Bug 575767) -- when the "new study
+                 * starting" popup is dismissed, then the study can start. */
+                task.changeStatus(TaskConstants.STATUS_IN_PROGRESS, true);
+                TestPilotSetup.reloadRemoteExperiments();
+              });
             return;
           } else if (task.taskType == TaskConstants.TYPE_SURVEY) {
 	    this._showNotification(
-	      task, true,
+	      task, false,
 	      this._stringBundle.formatStringFromName(
 		"testpilot.notification.newTestPilotSurvey.message",
 		[task.title], 1),
               this._stringBundle.GetStringFromName(
 		"testpilot.notification.newTestPilotSurvey"),
 	      "new-study", false, false,
 	      this._stringBundle.GetStringFromName("testpilot.moreInfo"),
 	      task.defaultUrl);
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/tasks.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/tasks.js
@@ -198,16 +198,17 @@ var TestPilotTask = {
 
   onWindowClosed: function TestPilotTask_onWindowClosed(window) {
   },
 
   onUrlLoad: function TestPilotTask_onUrlLoad(url) {
   },
 
   onDetailPageOpened: function TestPilotTask_onDetailPageOpened(){
+    // TODO fold this into loadPage()?
   },
 
   checkDate: function TestPilotTask_checkDate() {
   },
 
   changeStatus: function TPS_changeStatus(newStatus, suppressNotification) {
     // TODO we always suppress notifications except when new status is
     // "finished"; maybe remove that argument and only fire notification
@@ -439,24 +440,19 @@ TestPilotExperiment.prototype = {
       break;
     }
     if (!waitForData) {
       callback(content);
     }
   },
 
   experimentIsRunning: function TestPilotExperiment_isRunning() {
-    if (this._optInRequired) {
-      return (this._status == TaskConstants.STATUS_STARTING ||
-              this._status == TaskConstants.STATUS_IN_PROGRESS);
-    } else {
-      // Tests that don't require extra opt-in should start running even
-      // if you haven't seen them yet.
-      return (this._status < TaskConstants.STATUS_FINISHED);
-    }
+    // bug 575767
+    return (this._status == TaskConstants.STATUS_STARTING ||
+            this._status == TaskConstants.STATUS_IN_PROGRESS);
   },
 
   // Pass events along to handlers:
   onNewWindow: function TestPilotExperiment_onNewWindow(window) {
     this._logger.trace("Experiment.onNewWindow called.");
     if (this.experimentIsRunning()) {
       this._handlers.onNewWindow(window);
     }
@@ -594,21 +590,33 @@ TestPilotExperiment.prototype = {
         numTimesRun++;
         this._logger.trace("Test recurring... incrementing " + RECUR_TIMES_PREF_PREFIX + this._id + " to " + numTimesRun);
         Application.prefs.setValue( RECUR_TIMES_PREF_PREFIX + this._id,
                                     numTimesRun );
         this._logger.trace("Incremented it.");
       }
     }
 
-    // No-opt-in required tests skip PENDING and go straight to STARTING.
+    // If the notify-on-new-study pref is turned off, and the test doesn't
+    // require opt-in, then it can jump straight ahead to STARTING.
     if (!this._optInRequired &&
-        this._status < TaskConstants.STATUS_STARTING &&
+        !Application.prefs.getValue("extensions.testpilot.popup.showOnNewStudy",
+                                    false) &&
+        (this._status == TaskConstants.STATUS_NEW ||
+         this._status == TaskConstants.STATUS_PENDING)) {
+      this._logger.info("Skipping pending and going straight to starting.");
+      this.changeStatus(TaskConstants.STATUS_STARTING, true);
+    }
+
+    // If a study is STARTING, and we're in the right date range,
+    // then start it, and move it to IN_PROGRESS.
+    if ( this._status == TaskConstants.STATUS_STARTING &&
         currentDate >= this._startDate &&
         currentDate <= this._endDate) {
+      this._logger.info("Study now starting.");
       let uuidGenerator =
         Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
       let uuid = uuidGenerator.generateUUID().toString();
       // remove the brackets from the generated UUID
       if (uuid.indexOf("{") == 0) {
         uuid = uuid.substring(1, (uuid.length - 1));
       }
       // clear the data before starting.
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -247,26 +247,22 @@ window[chromehidden~="toolbar"] toolbar:
 #identity-popup-content-box.unknownIdentity > #identity-popup-content-host ,
 #identity-popup-content-box.unknownIdentity > #identity-popup-content-owner ,
 #identity-popup-content-box.verifiedIdentity > #identity-popup-connectedToLabel2 ,
 #identity-popup-content-box.verifiedDomain > #identity-popup-connectedToLabel2 {
   display: none;
 }
 
 /*  Full Screen UI */
+
 #fullscr-toggler {
-  display: none;
-  min-height: 1px;
   height: 1px;
   background: black;
-  border-style: none;
-  -moz-appearance: none;
 }
 
-#navigator-toolbox[inFullscreen="true"] > #fullscr-toggler,
 #nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-icon {
   display: -moz-box;
 }
 
 #nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-text {
   display: none;
 }
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3513,22 +3513,20 @@ var FullScreen =
     document.getElementById("View:FullScreen").setAttribute("checked", !window.fullScreen);
 
     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.
       let fullScrToggler = document.getElementById("fullscr-toggler");
       if (!fullScrToggler) {
-        fullScrToggler = document.createElement("toolbar");
+        fullScrToggler = document.createElement("hbox");
         fullScrToggler.id = "fullscr-toggler";
-        fullScrToggler.setAttribute("customizable", "false");
-        fullScrToggler.setAttribute("moz-collapsed", "true");
-        var navBar = document.getElementById("nav-bar");
-        navBar.parentNode.insertBefore(fullScrToggler, navBar);
+        fullScrToggler.collapsed = true;
+        gNavToolbox.parentNode.insertBefore(fullScrToggler, gNavToolbox.nextSibling);
       }
       fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
       fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
 
       if (gPrefService.getBoolPref("browser.fullscreen.autohide"))
         gBrowser.mPanelContainer.addEventListener("mousemove",
                                                   this._collapseCallback, false);
 
@@ -3719,22 +3717,21 @@ var FullScreen =
       gBrowser.mPanelContainer.addEventListener("mousemove",
                                                 this._collapseCallback, false);
     }
     else {
       gBrowser.mPanelContainer.removeEventListener("mousemove",
                                                    this._collapseCallback, false);
     }
 
-    var allFSToolbars = document.getElementsByTagNameNS(this._XULNS, "toolbar");
-    for (var i = 0; i < allFSToolbars.length; i++) {
-      if (allFSToolbars[i].getAttribute("fullscreentoolbar") == "true")
-        allFSToolbars[i].setAttribute("moz-collapsed", !aShow);
-    }
-    document.getElementById("fullscr-toggler").setAttribute("moz-collapsed", aShow);
+    // Hiding/collapsing the toolbox interferes with the tab bar's scrollbox,
+    // so we just move it off-screen instead. See bug 430687.
+    gNavToolbox.style.marginTop = aShow ? "" : -gNavToolbox.clientHeight + "px";
+
+    document.getElementById("fullscr-toggler").collapsed = aShow;
     this._isChromeCollapsed = !aShow;
     if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 2)
       this._shouldAnimate = true;
   },
 
   showXULChrome: function(aTag, aShow)
   {
     var els = document.getElementsByTagNameNS(this._XULNS, aTag);
--- a/browser/base/content/safeMode.js
+++ b/browser/base/content/safeMode.js
@@ -16,32 +16,34 @@
 #
 # The Initial Developer of the Original Code is
 # Mike Connor.
 # Portions created by the Initial Developer are Copyright (C) 2005
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Mike Connor <mconnor@steelgryphon.com>
-#   Asaf Romano <mozilla.mano@sent.com>
+#   Asaf Romano <mano@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
 # 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 *****
 
+Components.utils.import("resource://gre/modules/AddonManager.jsm");
+
 function restartApp() {
   var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
                              .getService(Components.interfaces.nsIAppStartup);
   appStartup.quit(appStartup.eForceQuit | appStartup.eRestart);
 }
 
 function clearAllPrefs() {
   var prefService = Components.classes["@mozilla.org/preferences-service;1"]
@@ -73,37 +75,31 @@ function deleteLocalstore() {
   var directoryService =  Components.classes[nsIDirectoryServiceContractID]
                                     .getService(nsIProperties);
   var localstoreFile = directoryService.get("LStoreS", Components.interfaces.nsIFile);
   if (localstoreFile.exists())
     localstoreFile.remove(false);
 }
 
 function disableAddons() {
-  // Disable addons
-  const nsIUpdateItem = Components.interfaces.nsIUpdateItem;
-  var em = Components.classes["@mozilla.org/extensions/manager;1"]
-                     .getService(Components.interfaces.nsIExtensionManager);
-  var type = nsIUpdateItem.TYPE_EXTENSION + nsIUpdateItem.TYPE_LOCALE;
-  var items = em.getItemList(type);
-  for (var i = 0; i < items.length; ++i)
-    em.disableItem(items[i].id);
-
-  // Select the default theme
-  var prefB = Components.classes["@mozilla.org/preferences-service;1"]
-                        .getService(Components.interfaces.nsIPrefBranch);
-  if (prefB.prefHasUserValue("general.skins.selectedSkin"))
-    prefB.clearUserPref("general.skins.selectedSkin");
-
-  // Disable plugins
-  var phs = Components.classes["@mozilla.org/plugin/host;1"]
-                      .getService(Components.interfaces.nsIPluginHost);
-  var plugins = phs.getPluginTags();
-  for (i = 0; i < plugins.length; ++i)
-    plugins[i].disabled = true;
+  AddonManager.getAllAddons(function(aAddons) {
+    aAddons.forEach(function(aAddon) {
+      if (aAddon.type == "theme") {
+        // Setting userDisabled to false on the default theme activates it,
+        // disables all other themes and deactivates the applied persona, if
+        // any.
+        const DEFAULT_THEME_ID = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
+        if (aAddon.id == DEFAULT_THEME_ID)
+          aAddon.userDisabled = false;
+      }
+      else {
+        aAddon.userDisabled = true;
+      }
+    });
+  });
 }
 
 function restoreDefaultSearchEngines() {
   var searchService = Components.classes["@mozilla.org/browser/search-service;1"]
                                 .getService(Components.interfaces.nsIBrowserSearchService);
 
   searchService.restoreDefaultEngines();
 }
--- a/browser/components/places/Makefile.in
+++ b/browser/components/places/Makefile.in
@@ -38,17 +38,17 @@
 
 DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-DIRS = public src
+DIRS = src
 
 ifdef ENABLE_TESTS
 	DIRS += tests
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += -I$(topsrcdir)/browser/components/
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -490,17 +490,25 @@ PlacesViewBase.prototype = {
     // nothing to be done when the title changes.
     if (elt == this._rootElt)
       return;
 
     // Here we need the <menu>.
     if (elt.localName == "menupopup")
       elt = elt.parentNode;
 
-    elt.label = aNewTitle || PlacesUIUtils.getBestTitle(aPlacesNode);
+    if (!aNewTitle && elt.localName != "toolbarbutton") {
+      // Many users consider toolbars as shortcuts containers, so explicitly
+      // allow empty labels on toolbarbuttons.  For any other element try to be
+      // smarter, guessing a title from the uri.
+      elt.label = PlacesUIUtils.getBestTitle(aPlacesNode);
+    }
+    else {
+      elt.label = aNewTitle;
+    }
   },
 
   nodeRemoved:
   function PVB_nodeRemoved(aParentPlacesNode, aPlacesNode, aIndex) {
     let parentElt = aParentPlacesNode._DOMElement;
     let elt = aPlacesNode._DOMElement;
 
     if (!parentElt)
deleted file mode 100644
--- a/browser/components/places/public/Makefile.in
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# ***** 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 code.
-#
-# The Initial Developer of the Original Code is
-# Google Inc.
-# Portions created by the Initial Developer are Copyright (C) 2005
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Brett Wilson <brettw@gmail.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH = ../../../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = browserplaces
-XPIDL_MODULE = browserplaces
-
-XPIDLSRCS  = nsIPlacesTransactionsService.idl \
-             $(NULL)
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/browser/components/places/public/nsIPlacesTransactionsService.idl
+++ /dev/null
@@ -1,381 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Places.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation
- *
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Sungjoon Steve Won <stevewon@gmail.com> (Original Author)
- *   Asaf Romano <mano@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsISupports.idl"
-#include "nsITransactionManager.idl"
-
-interface nsIVariant;
-interface nsIURI;
-interface nsIMicrosummary;
-interface nsITransaction;
-
-/**
- * nsIPlacesTransactionService is a service designed to handle
- * nsITransactions that correspond to changes in Places. It is here as a
- * service so that we can keep the transactions around without holding onto
- * the global scope of a js window.
- *
- * NOTE: If you are interacting directly with the Places back-end, and you
- *       need to transactionalize a large amount of changes, look at
- *       nsINavBookmarksService.runInBatchMode.
- */
-
-[scriptable, uuid(32eee5da-2bc7-4d18-8a54-a8ff0dec4d2a)]
-interface nsIPlacesTransactionsService : nsITransactionManager
-{
-  /**
-   * Transaction for performing several Places Transactions in a single batch. 
-   * 
-   * @param aName
-   *        title of the aggregate transactions
-   * @param aTransactions
-   *        an array of transactions to perform
-   * @returns nsITransaction object
-   */
-  nsITransaction aggregateTransactions(in AString aName,
-                                       in nsIVariant aTransactions);
-
-  /**
-   * Transaction for creating a new folder item.
-   *
-   * @param aName
-   *        the name of the new folder
-   * @param aContainerId
-   *        the identifier of the folder in which the new folder should be
-   *        added.
-   * @param [optional] aIndex
-   *        the index of the item in aContainer, pass -1 or nothing to create
-   *        the item at the end of aContainer.
-   * @param [optional] aAnnotations
-   *        the annotations to set for the new folder.
-   * @param [optional] aChildItemsTransactions
-   *        array of transactions for items to be created under the new folder.
-   * @returns nsITransaction object
-   */
-  nsITransaction createFolder(in AString aName, in long long aContainerId,
-                              [optional] in long long aIndex,
-                              [optional] in nsIVariant aAnnotations,
-                              [optional] in nsIVariant aChildItemsTransactions);
-
-  /**
-   * Transaction for creating a new bookmark item
-   *
-   * @param aURI
-   *        the uri of the new bookmark (nsIURI)
-   * @param aContainerId
-   *        the identifier of the folder in which the bookmark should be added.
-   * @param [optional] aIndex
-   *        the index of the item in aContainer, pass -1 or nothing to create
-   *        the item at the end of aContainer.
-   * @param [optional] aTitle
-   *        the title of the new bookmark.
-   * @param [optional] aKeyword
-   *        the keyword of the new bookmark.
-   * @param [optional] aAnnotations
-   *        the annotations to set for the new bookmark.
-   * @param [optional] aChildTransactions
-   *        child transactions to commit after creating the bookmark. Prefer
-   *        using any of the arguments above if possible. In general, a child
-   *        transations should be used only if the change it does has to be
-   *        reverted manually when removing the bookmark item.
-   *        a child transaction must support setting its bookmark-item
-   *        identifier via an "id" js setter.
-   * @returns nsITransaction object
-   */
-  nsITransaction createItem(in nsIURI aURI, in long long aContainerId,
-                            [optional] in long long aIndex,
-                            [optional] in AString aTitle,
-                            [optional] in AString aKeyword,
-                            [optional] in nsIVariant aAnnotations,
-                            [optional] in nsIVariant aChildTransactions);
-
-  /**
-   * Transaction for creating a new separator item
-   *
-   * @param aContainerId
-   *        the identifier of the folder in which the separator should be
-   *        added.
-   * @param [optional] aIndex
-   *        the index of the item in aContainer, pass -1 or nothing to create
-   *        the separator at the end of aContainer.
-   * @returns nsITransaction object
-   */
-  nsITransaction createSeparator(in long long aContainerId,
-                                 [optional] in long long aIndex);
-
-  /**
-   * Transaction for creating a new live-bookmark item.
-   *
-   * @see nsILivemarksService::createLivemark for documentation regarding the
-   * first three arguments.
-   *
-   * @param aContainerId
-   *        the identifier of the folder in which the live-bookmark should be
-   *        added.
-   * @param [optional]  aIndex
-   *        the index of the item in aContainer, pass -1 or nothing to create
-   *        the item at the end of aContainer.
-   * @param [optional] aAnnotations
-   *        the annotations to set for the new live-bookmark.
-   * @returns nsITransaction object
-   */
-  nsITransaction createLivemark(in nsIURI aFeedURI,
-                                in nsIURI aSiteURI,
-                                in AString aName,
-                                in long long aContainerId,
-                                [optional] in long long aIndex,
-                                [optional] in nsIVariant aAnnotations);
-
-  /**
-   * Transaction for moving an Item.
-   *
-   * @param aItemId
-   *        the id of the item to move
-   * @param aNewContainerId
-   *        id of the new container to move to
-   * @param aNewIndex
-   *        index of the new position to move to
-   * @returns nsITransaction object
-   */
-  nsITransaction moveItem(in long long aItemId,
-                          in long long aNewContainerId,
-                          in long long aNewIndex);
-
-  /**
-   * Transaction for removing an Item
-   *
-   * @param aItemId
-   *        id of the item to remove
-   * @returns nsITransaction object
-   */
-  nsITransaction removeItem(in long long aItemId);
-
-  /**
-   * Transaction for editting a bookmark's title.
-   *
-   * @param aItemId
-   *        id of the item to edit
-   * @param aNewTitle
-   *        new title for the item to edit
-   * @returns nsITransaction object
-   */
-  nsITransaction editItemTitle(in long long aItemId, in AString aNewTitle);
-
-  /**
-   * Transaction for editing a bookmark's uri.
-   *
-   * @param aBookmarkId
-   *        id of the bookmark to edit
-   * @param aNewURI
-   *        new uri for the bookmark
-   * @returns nsITransaction object
-   */
-  nsITransaction editBookmarkURI(in long long aBookmarkId, in nsIURI aNewURI);
-
-  /**
-   * Transaction for setting/unsetting an item annotation
-   *
-   * @param aItemId
-   *        id of the item where to set annotation
-   * @param aAnnotationObject
-   *        Object representing an annotation, containing the following
-   *        properties: name, flags, expires, type, mimeType (only used for
-   *        binary annotations), value.
-   *        If value is null the annotation will be removed
-   * @returns nsITransaction object
-   */
-  nsITransaction setItemAnnotation(in nsIVariant aItemId,
-                                   in nsIVariant aAnnotationObject);
-
-  /**
-   * Transaction for setting/unsetting a page annotation
-   *
-   * @param aURI
-   *        URI of the page where to set annotation
-   * @param aAnnotationObject
-   *        Object representing an annotation, containing the following
-   *        properties: name, flags, expires, type, mimeType (only used for
-   *        binary annotations), value.
-   *        If value is null the annotation will be removed
-   * @returns nsITransaction object
-   */
-  nsITransaction setPageAnnotation(in nsIURI aURI,
-                                   in nsIVariant aAnnotationObject);
-
-  /**
-   * Transaction for setting/unsetting Load-in-sidebar annotation
-   *
-   * @param aBookmarkId
-   *        id of the bookmark where to set Load-in-sidebar annotation
-   * @param aLoadInSidebar
-   *        boolean value
-   * @returns nsITransaction object
-   */
-  nsITransaction setLoadInSidebar(in long long aBookmarkId,
-                                  in boolean aLoadInSidebar);
-
-  /**
-   * Transaction for editing a the description of a bookmark or a folder
-   * 
-   * @param aItemId
-   *        id of the item to edit
-   * @param aDescription
-   *        new description
-   * @returns nsITransaction object
-   */
-  nsITransaction editItemDescription(in long long aItemId,
-                                     in AString aDescription);
-
-  /**
-   * Transaction for editing a bookmark's keyword.
-   *
-   * @param aBookmarkId
-   *        id of the bookmark to edit
-   * @param aNewKeyword
-   *        new keyword for the bookmark
-   * @returns nsITransaction object
-   */
-  nsITransaction editBookmarkKeyword(in long long aBookmarkId,
-                                     in AString aNewKeyword);
-
-  /**
-   * Transaction for editing the post data associated with a bookmark.
-   *
-   * @param aBookmarkId
-   *        id of the bookmark to edit
-   * @param aPostData
-   *        post data
-   * @returns nsITransaction object
-   */
-  nsITransaction editBookmarkPostData(in long long aBookmarkId,
-                                      in AString aPostData);
-
-  /**
-   * Transaction for editing a live bookmark's site URI.
-   *
-   * @param aLivemarkId
-   *        id of the livemark
-   * @param aURI
-   *        new site uri
-   * @returns nsITransaction object
-   */
-  nsITransaction editLivemarkSiteURI(in long long aLivemarkId, in nsIURI aURI);
-
-  /**
-   * Transaction for editting a live bookmark's feed URI.
-   *
-   * @param aLivemarkId
-   *        id of the livemark
-   * @param aURI
-   *        new feed uri
-   * @returns nsITransaction object
-   */
-  nsITransaction editLivemarkFeedURI(in long long aLivemarkId, in nsIURI aURI);
-
-  /**
-   * Transaction for editing a bookmark's microsummary.
-   *
-   * @param aBookmarkId
-   *        id of the bookmark to edit
-   * @param aNewMicrosummary
-   *        new microsummary for the bookmark
-   * @returns nsITransaction object
-   */
-  nsITransaction editBookmarkMicrosummary(in long long aBookmarkId,
-                                          in nsIMicrosummary aNewMicrosummary);
-
-  /**
-   * Transaction for editing an item's date added property.
-   *
-   * @param aItemId
-   *        id of the item to edit
-   * @param aNewDateAdded
-   *        new date added for the item 
-   * @returns nsITransaction object
-   */
-  nsITransaction editItemDateAdded(in long long aItemId,
-                                   in PRTime aNewDateAdded);
-
-  /**
-   * Transaction for editing an item's last modified time.
-   *
-   * @param aItemId
-   *        id of the item to edit
-   * @param aNewLastModified
-   *        new last modified date for the item 
-   * @returns nsITransaction object
-   */
-  nsITransaction editItemLastModified(in long long aItemId,
-                                      in PRTime aNewLastModified);
-
-  /**
-   * Transaction for sorting a folder by name
-   *
-   * @param aFolderId
-   *        id of the folder to sort
-   * @returns nsITransaction object
-   */
-  nsITransaction sortFolderByName(in long long aFolderId);
-
-  /**
-   * Transaction for tagging a URL with the given set of tags. Current tags set
-   * for the URL persist. It's the caller's job to check whether or not aURI
-   * was already tagged by any of the tags in aTags, undoing this tags
-   * transaction removes them all from aURL!
-   *
-   * @param aURI
-   *        the URL to tag.
-   * @param aTags
-   *        Array of tags to set for the given URL.
-   */
-  nsITransaction tagURI(in nsIURI aURI, in nsIVariant aTags);
-
-  /**
-   * Transaction for removing tags from a URL. It's the caller's job to check
-   * whether or not aURI isn't tagged by any of the tags in aTags, undoing this
-   * tags transaction adds them all to aURL!
-   *
-   * @param aURI
-   *        the URL to un-tag.
-   * @param aTags
-   *        Array of tags to unset. pass null to remove all tags from the given
-   *        url.
-   */
-  nsITransaction untagURI(in nsIURI aURI, in nsIVariant aTags);
-};
--- a/browser/components/places/src/BrowserPlaces.manifest
+++ b/browser/components/places/src/BrowserPlaces.manifest
@@ -1,4 +1,2 @@
-component {c0844a84-5a12-4808-80a8-809cb002bb4f} nsPlacesTransactionsService.js
-contract @mozilla.org/browser/placesTransactionsService;1 {c0844a84-5a12-4808-80a8-809cb002bb4f}
 component {6bcb9bde-9018-4443-a071-c32653469597} PlacesProtocolHandler.js
 contract @mozilla.org/network/protocol;1?name=place {6bcb9bde-9018-4443-a071-c32653469597}
--- a/browser/components/places/src/Makefile.in
+++ b/browser/components/places/src/Makefile.in
@@ -41,17 +41,16 @@ DEPTH = ../../../..
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 EXTRA_COMPONENTS = \
   BrowserPlaces.manifest \
-  nsPlacesTransactionsService.js \
   PlacesProtocolHandler.js \
   $(NULL)
 
 EXTRA_JS_MODULES = \
   PlacesUIUtils.jsm \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/components/places/src/PlacesUIUtils.jsm
+++ b/browser/components/places/src/PlacesUIUtils.jsm
@@ -67,38 +67,38 @@ var PlacesUIUtils = {
 
   /**
    * Makes a URI from a spec, and do fixup
    * @param   aSpec
    *          The string spec of the URI
    * @returns A URI object for the spec.
    */
   createFixedURI: function PUIU_createFixedURI(aSpec) {
-    return this.URIFixup.createFixupURI(aSpec, 0);
+    return URIFixup.createFixupURI(aSpec, 0);
   },
 
   /**
    * Wraps a string in a nsISupportsString wrapper
    * @param   aString
    *          The string to wrap
    * @returns A nsISupportsString object containing a string.
    */
   _wrapString: function PUIU__wrapString(aString) {
     var s = Cc["@mozilla.org/supports-string;1"].
             createInstance(Ci.nsISupportsString);
     s.data = aString;
     return s;
   },
 
   getFormattedString: function PUIU_getFormattedString(key, params) {
-    return this._bundle.formatStringFromName(key, params, params.length);
+    return bundle.formatStringFromName(key, params, params.length);
   },
 
   getString: function PUIU_getString(key) {
-    return this._bundle.GetStringFromName(key);
+    return bundle.GetStringFromName(key);
   },
 
   /**
    * Get a transaction for copying a uri item from one container to another
    * as a bookmark.
    * @param   aData
    *          JSON object of dropped or pasted item properties
    * @param   aContainer
@@ -655,17 +655,17 @@ var PlacesUIUtils = {
     return ("performed" in aInfo && aInfo.performed);
   },
 
   _getTopBrowserWin: function PUIU__getTopBrowserWin() {
     return Services.wm.getMostRecentWindow("navigator:browser");
   },
 
   _getCurrentActiveWin: function PUIU__getCurrentActiveWin() {
-    return this.fm.activeWindow;
+    return focusManager.activeWindow;
   },
 
   /**
    * Returns the closet ancestor places view for the given DOM node
    * @param aNode
    *        a DOM node
    * @return the closet ancestor places view if exists, null otherwsie.
    */
@@ -1216,17 +1216,17 @@ var PlacesUIUtils = {
    *
    * @param aItemId id of a container
    * @returns the name of the query, or empty string if not a left-pane query
    */
   getLeftPaneQueryNameFromId: function PUIU_getLeftPaneQueryNameFromId(aItemId) {
     var queryName = "";
     // If the let pane hasn't been built, use the annotation service
     // directly, to avoid building the left pane too early.
-    if (this.__lookupGetter__("leftPaneFolderId")) {
+    if (Object.getOwnPropertyDescriptor(this, "leftPaneFolderId").value === undefined) {
       try {
         queryName = PlacesUtils.annotations.
                                 getItemAnnotation(aItemId, this.ORGANIZER_QUERY_ANNO);
       }
       catch (ex) {
         // doesn't have the annotation
         queryName = "";
       }
@@ -1235,48 +1235,214 @@ var PlacesUIUtils = {
       // If the left pane has already been built, use the name->id map
       // cached in PlacesUIUtils.
       for (let [name, id] in Iterator(this.leftPaneQueries)) {
         if (aItemId == id)
           queryName = name;
       }
     }
     return queryName; 
-  },
-
+  }
 };
 
 XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "RDF",
                                    "@mozilla.org/rdf/rdf-service;1",
                                    "nsIRDFService");
 
 XPCOMUtils.defineLazyGetter(PlacesUIUtils, "localStore", function() {
   return PlacesUIUtils.RDF.GetDataSource("rdf:local-store");
 });
 
-XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "ptm",
-                                   "@mozilla.org/browser/placesTransactionsService;1",
-                                   "nsIPlacesTransactionsService");
-
-XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "URIFixup",
-                                   "@mozilla.org/docshell/urifixup;1",
-                                   "nsIURIFixup");
-
 XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ellipsis", function() {
   return Services.prefs.getComplexValue("intl.ellipsis",
                                         Ci.nsIPrefLocalizedString).data;
 });
 
 XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "privateBrowsing",
                                    "@mozilla.org/privatebrowsing;1",
                                    "nsIPrivateBrowsingService");
 
-XPCOMUtils.defineLazyGetter(PlacesUIUtils, "_bundle", function() {
+XPCOMUtils.defineLazyServiceGetter(this, "URIFixup",
+                                   "@mozilla.org/docshell/urifixup;1",
+                                   "nsIURIFixup");
+
+XPCOMUtils.defineLazyGetter(this, "bundle", function() {
   const PLACES_STRING_BUNDLE_URI =
     "chrome://browser/locale/places/places.properties";
   return Cc["@mozilla.org/intl/stringbundle;1"].
          getService(Ci.nsIStringBundleService).
          createBundle(PLACES_STRING_BUNDLE_URI);
 });
 
-XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "fm",
+XPCOMUtils.defineLazyServiceGetter(this, "focusManager",
                                    "@mozilla.org/focus-manager;1",
                                    "nsIFocusManager");
+
+/**
+ * This is a compatibility shim for old PUIU.ptm users.
+ *
+ * If you're looking for transactions and writing new code using them, directly
+ * use the transactions objects exported by the PlacesUtils.jsm module.
+ *
+ * This object will be removed once enough users are converted to the new API.
+ */
+XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ptm", function() {
+  // Ensure PlacesUtils is imported in scope.
+  PlacesUtils;
+
+  return {
+    aggregateTransactions: function(aName, aTransactions)
+      new PlacesAggregatedTransaction(aName, aTransactions),
+
+    createFolder: function(aName, aContainer, aIndex, aAnnotations,
+                           aChildItemsTransactions)
+      new PlacesCreateFolderTransaction(aName, aContainer, aIndex, aAnnotations,
+                                        aChildItemsTransactions),
+
+    createItem: function(aURI, aContainer, aIndex, aTitle, aKeyword,
+                         aAnnotations, aChildTransactions)
+      new PlacesCreateBookmarkTransaction(aURI, aContainer, aIndex, aTitle,
+                                          aKeyword, aAnnotations,
+                                          aChildTransactions),
+
+    createSeparator: function(aContainer, aIndex)
+      new PlacesCreateSeparatorTransaction(aContainer, aIndex),
+
+    createLivemark: function(aFeedURI, aSiteURI, aName, aContainer, aIndex,
+                             aAnnotations)
+      new PlacesCreateLivemarkTransaction(aFeedURI, aSiteURI, aName, aContainer,
+                                          aIndex, aAnnotations),
+
+    moveItem: function(aItemId, aNewContainer, aNewIndex)
+      new PlacesMoveItemTransaction(aItemId, aNewContainer, aNewIndex),
+
+    removeItem: function(aItemId)
+      new PlacesRemoveItemTransaction(aItemId),
+
+    editItemTitle: function(aItemId, aNewTitle)
+      new PlacesEditItemTitleTransaction(aItemId, aNewTitle),
+
+    editBookmarkURI: function(aItemId, aNewURI)
+      new PlacesEditBookmarkURITransaction(aItemId, aNewURI),
+
+    setItemAnnotation: function(aItemId, aAnnotationObject)
+      new PlacesSetItemAnnotationTransaction(aItemId, aAnnotationObject),
+
+    setPageAnnotation: function(aURI, aAnnotationObject)
+      new PlacesSetPageAnnotationTransaction(aURI, aAnnotationObject),
+
+    editBookmarkKeyword: function(aItemId, aNewKeyword)
+      new PlacesEditBookmarkKeywordTransaction(aItemId, aNewKeyword),
+
+    editBookmarkPostData: function(aItemId, aPostData)
+      new PlacesEditBookmarkPostDataTransaction(aItemId, aPostData),
+
+    editLivemarkSiteURI: function(aLivemarkId, aSiteURI)
+      new PlacesEditLivemarkSiteURITransaction(aLivemarkId, aSiteURI),
+
+    editLivemarkFeedURI: function(aLivemarkId, aFeedURI)
+      new PlacesEditLivemarkFeedURITransaction(aLivemarkId, aFeedURI),
+
+    editBookmarkMicrosummary: function(aItemId, aNewMicrosummary)
+      new PlacesEditBookmarkMicrosummaryTransaction(aItemId, aNewMicrosummary),
+
+    editItemDateAdded: function(aItemId, aNewDateAdded)
+      new PlacesEditItemDateAddedTransaction(aItemId, aNewDateAdded),
+
+    editItemLastModified: function(aItemId, aNewLastModified)
+      new PlacesEditItemLastModifiedTransaction(aItemId, aNewLastModified),
+
+    sortFolderByName: function(aFolderId)
+      new PlacesSortFolderByNameTransaction(aFolderId),
+
+    tagURI: function(aURI, aTags)
+      new PlacesTagURITransaction(aURI, aTags),
+
+    untagURI: function(aURI, aTags)
+      new PlacesUntagURITransaction(aURI, aTags),
+
+    /**
+     * Transaction for setting/unsetting Load-in-sidebar annotation.
+     *
+     * @param aBookmarkId
+     *        id of the bookmark where to set Load-in-sidebar annotation.
+     * @param aLoadInSidebar
+     *        boolean value.
+     * @returns nsITransaction object.
+     */
+    setLoadInSidebar: function(aItemId, aLoadInSidebar)
+    {
+      let annoObj = { name: PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO,
+                      type: Ci.nsIAnnotationService.TYPE_INT32,
+                      flags: 0,
+                      value: aLoadInSidebar,
+                      expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+      return new PlacesSetItemAnnotationTransaction(aItemId, annoObj);
+    },
+
+   /**
+    * Transaction for editing a the description of a bookmark or a folder.
+    * 
+    * @param aItemId
+    *        id of the item to edit.
+    * @param aDescription
+    *        new description.
+    * @returns nsITransaction object.
+    */
+    editItemDescription: function(aItemId, aDescription)
+    {
+      let annoObj = { name: PlacesUIUtils.DESCRIPTION_ANNO,
+                      type: Ci.nsIAnnotationService.TYPE_STRING,
+                      flags: 0,
+                      value: aDescription,
+                      expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+      return new PlacesSetItemAnnotationTransaction(aItemId, annoObj);
+    },
+
+    ////////////////////////////////////////////////////////////////////////////
+    //// nsITransactionManager forwarders.
+
+    beginBatch: function()
+      PlacesUtils.transactionManager.beginBatch(),
+
+    endBatch: function()
+      PlacesUtils.transactionManager.endBatch(),
+
+    doTransaction: function(txn)
+      PlacesUtils.transactionManager.doTransaction(txn),
+
+    undoTransaction: function()
+      PlacesUtils.transactionManager.undoTransaction(),
+
+    redoTransaction: function()
+      PlacesUtils.transactionManager.redoTransaction(),
+
+    get numberOfUndoItems()
+      PlacesUtils.transactionManager.numberOfUndoItems,
+    get numberOfRedoItems()
+      PlacesUtils.transactionManager.numberOfRedoItems,
+    get maxTransactionCount()
+      PlacesUtils.transactionManager.maxTransactionCount,
+    set maxTransactionCount(val)
+      PlacesUtils.transactionManager.maxTransactionCount = val,
+
+    clear: function()
+      PlacesUtils.transactionManager.clear(),
+
+    peekUndoStack: function()
+      PlacesUtils.transactionManager.peekUndoStack(),
+
+    peekRedoStack: function()
+      PlacesUtils.transactionManager.peekRedoStack(),
+
+    getUndoStack: function()
+      PlacesUtils.transactionManager.getUndoStack(),
+
+    getRedoStack: function()
+      PlacesUtils.transactionManager.getRedoStack(),
+
+    AddListener: function(aListener)
+      PlacesUtils.transactionManager.AddListener(aListener),
+
+    RemoveListener: function(aListener)
+      PlacesUtils.transactionManager.RemoveListener(aListener)
+  }
+});
deleted file mode 100644
--- a/browser/components/places/src/nsPlacesTransactionsService.js
+++ /dev/null
@@ -1,1187 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Places Command Controller.
- *
- * The Initial Developer of the Original Code is Google Inc.
- *
- * Portions created by the Initial Developer are Copyright (C) 2005
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Sungjoon Steve Won <stevewon@gmail.com> (Original Author)
- *   Asaf Romano <mano@mozilla.com>
- *   Marco Bonarco <mak77@bonardo.net>
- *
- * 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 ***** */
-
-let Ci = Components.interfaces;
-let Cc = Components.classes;
-let Cr = Components.results;
-let Cu = Components.utils;
-
-const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
-const DESCRIPTION_ANNO = "bookmarkProperties/description";
-
-const CLASS_ID = Components.ID("c0844a84-5a12-4808-80a8-809cb002bb4f");
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "Services", function() {
-  Cu.import("resource://gre/modules/Services.jsm");
-  return Services;
-});
-
-XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
-  Cu.import("resource://gre/modules/PlacesUtils.jsm");
-  return PlacesUtils;
-});
-
-// The minimum amount of transactions we should tell our observers to begin
-// batching (rather than letting them do incremental drawing).
-const MIN_TRANSACTIONS_FOR_BATCH = 5;
-
-function placesTransactionsService() {
-  Services.obs.addObserver(this, PlacesUtils.TOPIC_SHUTDOWN, false);
-  this.mTransactionManager = Cc["@mozilla.org/transactionmanager;1"].
-                             createInstance(Ci.nsITransactionManager);
-}
-
-placesTransactionsService.prototype = {
-  classID: CLASS_ID,
-
-  QueryInterface: XPCOMUtils.generateQI([
-    Ci.nsIPlacesTransactionsService,
-    Ci.nsITransactionManager,
-    Ci.nsIObserver,
-  ]),
-
-  // nsIObserver
-  observe: function PlacesTxn_observe(aSubject, aTopic, aData) {
-    if (aTopic == PlacesUtils.TOPIC_SHUTDOWN) {
-      Services.obs.removeObserver(this, PlacesUtils.TOPIC_SHUTDOWN);
-      delete this.mTransactionManager;
-    }
-  },
-
-  aggregateTransactions:
-  function placesTxn_aggregateTransactions(aName, aTransactions) {
-    return new placesAggregateTransactions(aName, aTransactions);
-  },
-
-  createFolder:
-  function placesTxn_createFolder(aName, aContainer, aIndex,
-                                  aAnnotations, aChildItemsTransactions) {
-     return new placesCreateFolderTransactions(aName, aContainer, aIndex,
-                                               aAnnotations, aChildItemsTransactions);
-  },
-
-  createItem:
-  function placesTxn_createItem(aURI, aContainer, aIndex, aTitle,
-                                aKeyword, aAnnotations, aChildTransactions) {
-    return new placesCreateItemTransactions(aURI, aContainer, aIndex, aTitle,
-                                            aKeyword, aAnnotations, aChildTransactions);
-  },
-
-  createSeparator:
-  function placesTxn_createSeparator(aContainer, aIndex) {
-    return new placesCreateSeparatorTransactions(aContainer, aIndex);
-  },
-
-  createLivemark:
-  function placesTxn_createLivemark(aFeedURI, aSiteURI, aName,
-                                    aContainer, aIndex, aAnnotations) {
-    return new placesCreateLivemarkTransactions(aFeedURI, aSiteURI, aName,
-                                                aContainer, aIndex, aAnnotations);
-  },
-
-  moveItem:
-  function placesTxn_moveItem(aItemId, aNewContainer, aNewIndex) {
-    return new placesMoveItemTransactions(aItemId, aNewContainer, aNewIndex);
-  },
-
-  removeItem:
-  function placesTxn_removeItem(aItemId) {
-    if (aItemId == PlacesUtils.tagsFolderId ||
-        aItemId == PlacesUtils.placesRootId ||
-        aItemId == PlacesUtils.bookmarksMenuFolderId ||
-        aItemId == PlacesUtils.toolbarFolderId)
-      throw Cr.NS_ERROR_INVALID_ARG;
-
-    // if the item lives within a tag container, use the tagging transactions
-    var parent = PlacesUtils.bookmarks.getFolderIdForItem(aItemId);
-    var grandparent = PlacesUtils.bookmarks.getFolderIdForItem(parent);
-    if (grandparent == PlacesUtils.tagsFolderId) {
-      var uri = PlacesUtils.bookmarks.getBookmarkURI(aItemId);
-      return this.untagURI(uri, [parent]);
-    }
-    
-    // if the item is a livemark container we will not save its children and
-    // will use createLivemark to undo.
-    if (PlacesUtils.itemIsLivemark(aItemId))
-      return new placesRemoveLivemarkTransaction(aItemId);
-
-    return new placesRemoveItemTransaction(aItemId);
-  },
-
-  editItemTitle:
-  function placesTxn_editItemTitle(aItemId, aNewTitle) {
-    return new placesEditItemTitleTransactions(aItemId, aNewTitle);
-  },
-
-  editBookmarkURI:
-  function placesTxn_editBookmarkURI(aItemId, aNewURI) {
-    return new placesEditBookmarkURITransactions(aItemId, aNewURI);
-  },
-
-  setItemAnnotation:
-  function placesTxn_setItemAnnotation(aItemId, aAnnotationObject) {
-    return new placesSetItemAnnotationTransactions(aItemId, aAnnotationObject);
-  },
-
-  setPageAnnotation:
-  function placesTxn_setPageAnnotation(aURI, aAnnotationObject) {
-    return new placesSetPageAnnotationTransactions(aURI, aAnnotationObject);
-  },
-
-  setLoadInSidebar:
-  function placesTxn_setLoadInSidebar(aItemId, aLoadInSidebar) {
-    var annoObj = { name: LOAD_IN_SIDEBAR_ANNO,
-                    type: Ci.nsIAnnotationService.TYPE_INT32,
-                    flags: 0,
-                    value: aLoadInSidebar,
-                    expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
-    return this.setItemAnnotation(aItemId, annoObj);
-  },
-
-  editItemDescription:
-  function placesTxn_editItemDescription(aItemId, aDescription) {
-    var annoObj = { name: DESCRIPTION_ANNO,
-                    type: Ci.nsIAnnotationService.TYPE_STRING,
-                    flags: 0,
-                    value: aDescription,
-                    expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
-    return this.setItemAnnotation(aItemId, annoObj);
-  },
-
-  editBookmarkKeyword:
-  function placesTxn_editBookmarkKeyword(aItemId, aNewKeyword) {
-    return new placesEditBookmarkKeywordTransactions(aItemId, aNewKeyword);
-  },
-
-  editBookmarkPostData:
-  function placesTxn_editBookmarkPostdata(aItemId, aPostData) {
-    return new placesEditBookmarkPostDataTransactions(aItemId, aPostData);
-  },
-
-  editLivemarkSiteURI:
-  function placesTxn_editLivemarkSiteURI(aLivemarkId, aSiteURI) {
-    return new placesEditLivemarkSiteURITransactions(aLivemarkId, aSiteURI);
-  },
-
-  editLivemarkFeedURI:
-  function placesTxn_editLivemarkFeedURI(aLivemarkId, aFeedURI) {
-    return new placesEditLivemarkFeedURITransactions(aLivemarkId, aFeedURI);
-  },
-
-  editBookmarkMicrosummary:
-  function placesTxn_editBookmarkMicrosummary(aItemId, aNewMicrosummary) {
-    return new placesEditBookmarkMicrosummaryTransactions(aItemId, aNewMicrosummary);
-  },
-
-  editItemDateAdded:
-  function placesTxn_editItemDateAdded(aItemId, aNewDateAdded) {
-    return new placesEditItemDateAddedTransaction(aItemId, aNewDateAdded);
-  },
-
-  editItemLastModified:
-  function placesTxn_editItemLastModified(aItemId, aNewLastModified) {
-    return new placesEditItemLastModifiedTransaction(aItemId, aNewLastModified);
-  },
-
-  sortFolderByName:
-  function placesTxn_sortFolderByName(aFolderId) {
-    return new placesSortFolderByNameTransactions(aFolderId);
-  },
-
-  tagURI:
-  function placesTxn_tagURI(aURI, aTags) {
-    return new placesTagURITransaction(aURI, aTags);
-  },
-
-  untagURI:
-  function placesTxn_untagURI(aURI, aTags) {
-    return new placesUntagURITransaction(aURI, aTags);
-  },
-
-  // Update commands in the undo group of the active window
-  // commands in inactive windows will are updated on-focus
-  _updateCommands: function placesTxn__updateCommands() {
-    var win = Services.wm.getMostRecentWindow(null);
-    if (win)
-      win.updateCommands("undo");
-  },
-
-  // nsITransactionManager
-  beginBatch: function() {
-    this.mTransactionManager.beginBatch();
-
-    // A no-op transaction is pushed to the stack, in order to make safe and
-    // easy to implement "Undo" an unknown number of transactions (including 0),
-    // "above" beginBatch and endBatch. Otherwise,implementing Undo that way
-    // head to dataloss: for example, if no changes were done in the
-    // edit-item panel, the last transaction on the undo stack would be the
-    // initial createItem transaction, or even worse, the batched editing of
-    // some other item.
-    // DO NOT MOVE this to the window scope, that would leak (bug 490068)! 
-    this.doTransaction({ doTransaction: function() { },
-                         undoTransaction: function() { },
-                         redoTransaction: function() { },
-                         isTransient: false,
-                         merge: function() { return false; } });
-  },
-
-  endBatch: function() this.mTransactionManager.endBatch(),
-
-  doTransaction: function placesTxn_doTransaction(txn) {
-    this.mTransactionManager.doTransaction(txn);
-    this._updateCommands();
-  },
-
-  undoTransaction: function placesTxn_undoTransaction() {
-    this.mTransactionManager.undoTransaction();
-    this._updateCommands();
-  },
-
-  redoTransaction: function placesTxn_redoTransaction() {
-    this.mTransactionManager.redoTransaction();
-    this._updateCommands();
-  },
-
-  clear: function() this.mTransactionManager.clear(),
-
-  get numberOfUndoItems() {
-    return this.mTransactionManager.numberOfUndoItems;
-  },
-
-  get numberOfRedoItems() {
-    return this.mTransactionManager.numberOfRedoItems;
-  },
-
-  get maxTransactionCount() {
-    return this.mTransactionManager.maxTransactionCount;
-  },
-  set maxTransactionCount(val) {
-    return this.mTransactionManager.maxTransactionCount = val;
-  },
-
-  peekUndoStack: function() this.mTransactionManager.peekUndoStack(),
-  peekRedoStack: function() this.mTransactionManager.peekRedoStack(),
-  getUndoStack: function() this.mTransactionManager.getUndoStack(),
-  getRedoStack: function() this.mTransactionManager.getRedoStack(),
-  AddListener: function(l) this.mTransactionManager.AddListener(l),
-  RemoveListener: function(l) this.mTransactionManager.RemoveListener(l)
-};
-
-/**
- * Method and utility stubs for Places Edit Transactions
- */
-function placesBaseTransaction() {
-}
-
-placesBaseTransaction.prototype = {
-  // for child-transactions
-  get wrappedJSObject() {
-    return this;
-  },
-
-  // nsITransaction
-  redoTransaction: function PBT_redoTransaction() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  get isTransient() {
-    return false;
-  },
-
-  merge: function mergeFunc(transaction) {
-    return false;
-  },
-
-  // nsISupports
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsITransaction]),
-};
-
-function placesAggregateTransactions(name, transactions) {
-  this._transactions = transactions;
-  this._name = name;
-  this.container = -1;
-  this.redoTransaction = this.doTransaction;
-
-  // Check child transactions number.  We will batch if we have more than
-  // MIN_TRANSACTIONS_FOR_BATCH total number of transactions.
-  var countTransactions = function(aTransactions, aTxnCount) {
-    for (let i = 0;
-         i < aTransactions.length && aTxnCount < MIN_TRANSACTIONS_FOR_BATCH;
-         i++, aTxnCount++) {
-      let txn = aTransactions[i].wrappedJSObject;
-      if (txn && txn.childTransactions && txn.childTransactions.length)
-        aTxnCount = countTransactions(txn.childTransactions, aTxnCount);
-    }
-    return aTxnCount;
-  }
-
-  var txnCount = countTransactions(transactions, 0);
-  this._useBatch = txnCount >= MIN_TRANSACTIONS_FOR_BATCH;
-}
-
-placesAggregateTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PAT_doTransaction() {
-    if (this._useBatch) {
-      var callback = {
-        _self: this,
-        runBatched: function() {
-          this._self.commit(false);
-        }
-      };
-      PlacesUtils.bookmarks.runInBatchMode(callback, null);
-    }
-    else
-      this.commit(false);
-  },
-
-  undoTransaction: function PAT_undoTransaction() {
-    if (this._useBatch) {
-      var callback = {
-        _self: this,
-        runBatched: function() {
-          this._self.commit(true);
-        }
-      };
-      PlacesUtils.bookmarks.runInBatchMode(callback, null);
-    }
-    else
-      this.commit(true);
-  },
-
-  commit: function PAT_commit(aUndo) {
-    // Use a copy of the transactions array, so we won't reverse the original
-    // one on undoing.
-    var transactions = this._transactions.slice(0);
-    if (aUndo)
-      transactions.reverse();
-    for (var i = 0; i < transactions.length; i++) {
-      var txn = transactions[i];
-      if (this.container > -1) 
-        txn.wrappedJSObject.container = this.container;
-      if (aUndo)
-        txn.undoTransaction();
-      else
-        txn.doTransaction();
-    }
-  }
-};
-
-function placesCreateFolderTransactions(aName, aContainer, aIndex,
-                                        aAnnotations,
-                                        aChildItemsTransactions) {
-  this._name = aName;
-  this._container = aContainer;
-  this._index = typeof(aIndex) == "number" ? aIndex : -1;
-  this._annotations = aAnnotations;
-  this._id = null;
-  this.childTransactions = aChildItemsTransactions || [];
-  this.redoTransaction = this.doTransaction;
-}
-
-placesCreateFolderTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  // childItemsTransaction support
-  get container() { return this._container; },
-  set container(val) { return this._container = val; },
-
-  doTransaction: function PCFT_doTransaction() {
-    this._id = PlacesUtils.bookmarks.createFolder(this._container, 
-                                                  this._name, this._index);
-    if (this._annotations && this._annotations.length > 0)
-      PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
-
-    if (this.childTransactions.length) {
-      // Set the new container id into child transactions.
-      for (var i = 0; i < this.childTransactions.length; ++i) {
-        this.childTransactions[i].wrappedJSObject.container = this._id;
-      }
-
-      let aggregateTxn = new placesAggregateTransactions("Create folder childTxn",
-                                                         this.childTransactions);
-      aggregateTxn.doTransaction();
-    }
-
-    if (this._GUID)
-      PlacesUtils.bookmarks.setItemGUID(this._id, this._GUID);
-  },
-
-  undoTransaction: function PCFT_undoTransaction() {
-    if (this.childTransactions.length) {
-      let aggregateTxn = new placesAggregateTransactions("Create folder childTxn",
-                                                         this.childTransactions);
-      aggregateTxn.undoTransaction();
-    }
-
-    // If a GUID exists for this item, preserve it before removing the item.
-    if (PlacesUtils.annotations.itemHasAnnotation(this._id, PlacesUtils.GUID_ANNO))
-      this._GUID = PlacesUtils.bookmarks.getItemGUID(this._id);
-
-    // Remove item only after all child transactions have been reverted.
-    PlacesUtils.bookmarks.removeItem(this._id);
-  }
-};
-
-function placesCreateItemTransactions(aURI, aContainer, aIndex, aTitle,
-                                      aKeyword, aAnnotations,
-                                      aChildTransactions) {
-  this._uri = aURI;
-  this._container = aContainer;
-  this._index = typeof(aIndex) == "number" ? aIndex : -1;
-  this._title = aTitle;
-  this._keyword = aKeyword;
-  this._annotations = aAnnotations;
-  this.childTransactions = aChildTransactions || [];
-  this.redoTransaction = this.doTransaction;
-}
-
-placesCreateItemTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  // childItemsTransactions support for the create-folder transaction
-  get container() { return this._container; },
-  set container(val) { return this._container = val; },
-
-  doTransaction: function PCIT_doTransaction() {
-    this._id = PlacesUtils.bookmarks.insertBookmark(this.container, this._uri,
-                                                    this._index, this._title);
-    if (this._keyword)
-      PlacesUtils.bookmarks.setKeywordForBookmark(this._id, this._keyword);
-    if (this._annotations && this._annotations.length > 0)
-      PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
- 
-    if (this.childTransactions.length) {
-      // Set the new item id into child transactions.
-      for (var i = 0; i < this.childTransactions.length; ++i) {
-        this.childTransactions[i].wrappedJSObject.id = this._id;
-      }
-      let aggregateTxn = new placesAggregateTransactions("Create item childTxn",
-                                                         this.childTransactions);
-      aggregateTxn.doTransaction();
-    }
-    if (this._GUID)
-      PlacesUtils.bookmarks.setItemGUID(this._id, this._GUID);
-  },
-
-  undoTransaction: function PCIT_undoTransaction() {
-    if (this.childTransactions.length) {
-      // Undo transactions should always be done in reverse order.
-      let aggregateTxn = new placesAggregateTransactions("Create item childTxn",
-                                                         this.childTransactions);
-      aggregateTxn.undoTransaction();
-    }
-
-    // If a GUID exists for this item, preserve it before removing the item.
-    if (PlacesUtils.annotations.itemHasAnnotation(this._id, PlacesUtils.GUID_ANNO))
-      this._GUID = PlacesUtils.bookmarks.getItemGUID(this._id);
-
-    // Remove item only after all child transactions have been reverted.
-    PlacesUtils.bookmarks.removeItem(this._id);
-  }
-};
-
-function placesCreateSeparatorTransactions(aContainer, aIndex) {
-  this._container = aContainer;
-  this._index = typeof(aIndex) == "number" ? aIndex : -1;
-  this._id = null;
-  this.redoTransaction = this.doTransaction;
-}
-
-placesCreateSeparatorTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  // childItemsTransaction support
-  get container() { return this._container; },
-  set container(val) { return this._container = val; },
-
-  doTransaction: function PCST_doTransaction() {
-    this._id = PlacesUtils.bookmarks
-                          .insertSeparator(this.container, this._index);
-    if (this._GUID)
-      PlacesUtils.bookmarks.setItemGUID(this._id, this._GUID);
-  },
-
-  undoTransaction: function PCST_undoTransaction() {
-    // If a GUID exists for this item, preserve it before removing the item.
-    if (PlacesUtils.annotations.itemHasAnnotation(this._id, PlacesUtils.GUID_ANNO))
-      this._GUID = PlacesUtils.bookmarks.getItemGUID(this._id);
-
-    PlacesUtils.bookmarks.removeItem(this._id);
-  }
-};
-
-function placesCreateLivemarkTransactions(aFeedURI, aSiteURI, aName,
-                                          aContainer, aIndex,
-                                          aAnnotations) {
-  this.redoTransaction = this.doTransaction;
-  this._feedURI = aFeedURI;
-  this._siteURI = aSiteURI;
-  this._name = aName;
-  this._container = aContainer;
-  this._index = typeof(aIndex) == "number" ? aIndex : -1;
-  this._annotations = aAnnotations;
-}
-
-placesCreateLivemarkTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  // childItemsTransaction support
-  get container() { return this._container; },
-  set container(val) { return this._container = val; },
-
-  doTransaction: function PCLT_doTransaction() {
-    this._id = PlacesUtils.livemarks.createLivemark(this._container, this._name,
-                                                    this._siteURI, this._feedURI,
-                                                    this._index);
-    if (this._annotations && this._annotations.length > 0)
-      PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
-    if (this._GUID)
-      PlacesUtils.bookmarks.setItemGUID(this._id, this._GUID);
-  },
-
-  undoTransaction: function PCLT_undoTransaction() {
-    // If a GUID exists for this item, preserve it before removing the item.
-    if (PlacesUtils.annotations.itemHasAnnotation(this._id, PlacesUtils.GUID_ANNO))
-      this._GUID = PlacesUtils.bookmarks.getItemGUID(this._id);
-
-    PlacesUtils.bookmarks.removeItem(this._id);
-  }
-};
-
-function placesRemoveLivemarkTransaction(aFolderId) {
-  this.redoTransaction = this.doTransaction;
-  this._id = aFolderId;
-  this._title = PlacesUtils.bookmarks.getItemTitle(this._id);
-  this._container = PlacesUtils.bookmarks.getFolderIdForItem(this._id);
-  var annos = PlacesUtils.getAnnotationsForItem(this._id);
-  // Exclude livemark service annotations, those will be recreated automatically
-  var annosToExclude = ["livemark/feedURI",
-                        "livemark/siteURI",
-                        "livemark/expiration",
-                        "livemark/loadfailed",
-                        "livemark/loading"];
-  this._annotations = annos.filter(function(aValue, aIndex, aArray) {
-      return annosToExclude.indexOf(aValue.name) == -1;
-    });
-  this._feedURI = PlacesUtils.livemarks.getFeedURI(this._id);
-  this._siteURI = PlacesUtils.livemarks.getSiteURI(this._id);
-  this._dateAdded = PlacesUtils.bookmarks.getItemDateAdded(this._id);
-  this._lastModified = PlacesUtils.bookmarks.getItemLastModified(this._id);
-}
-
-placesRemoveLivemarkTransaction.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PRLT_doTransaction() {
-    this._index = PlacesUtils.bookmarks.getItemIndex(this._id);
-    PlacesUtils.bookmarks.removeItem(this._id);
-  },
-
-  undoTransaction: function PRLT_undoTransaction() {
-    this._id = PlacesUtils.livemarks.createLivemark(this._container,
-                                                    this._title,
-                                                    this._siteURI,
-                                                    this._feedURI,
-                                                    this._index);
-    PlacesUtils.bookmarks.setItemDateAdded(this._id, this._dateAdded);
-    PlacesUtils.bookmarks.setItemLastModified(this._id, this._lastModified);
-    // Restore annotations
-    PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
-  }
-};
-
-function placesMoveItemTransactions(aItemId, aNewContainer, aNewIndex) {
-  this._id = aItemId;
-  this._oldContainer = PlacesUtils.bookmarks.getFolderIdForItem(this._id);
-  this._newContainer = aNewContainer;
-  this._newIndex = aNewIndex;
-  this.redoTransaction = this.doTransaction;
-}
-
-placesMoveItemTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PMIT_doTransaction() {
-    this._oldIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
-    PlacesUtils.bookmarks.moveItem(this._id, this._newContainer, this._newIndex);
-    this._undoIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
-  },
-
-  undoTransaction: function PMIT_undoTransaction() {
-    // moving down in the same container takes in count removal of the item
-    // so to revert positions we must move to oldIndex + 1
-    if (this._newContainer == this._oldContainer &&
-        this._oldIndex > this._undoIndex)
-      PlacesUtils.bookmarks.moveItem(this._id, this._oldContainer, this._oldIndex + 1);
-    else
-      PlacesUtils.bookmarks.moveItem(this._id, this._oldContainer, this._oldIndex);
-  }
-};
-
-function placesRemoveItemTransaction(aItemId) {
-  this.redoTransaction = this.doTransaction;
-  this._id = aItemId;
-  this._itemType = PlacesUtils.bookmarks.getItemType(this._id);
-  if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
-    this.childTransactions = this._getFolderContentsTransactions();
-    // Remove this folder itself.
-    let txn = PlacesUtils.bookmarks.getRemoveFolderTransaction(this._id);
-    this.childTransactions.push(txn);
-  }
-  else if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) {
-    this._uri = PlacesUtils.bookmarks.getBookmarkURI(this._id);
-    this._keyword = PlacesUtils.bookmarks.getKeywordForBookmark(this._id);
-  }
-
-  if (this._itemType != Ci.nsINavBookmarksService.TYPE_SEPARATOR)
-    this._title = PlacesUtils.bookmarks.getItemTitle(this._id);
-
-  this._oldContainer = PlacesUtils.bookmarks.getFolderIdForItem(this._id);
-  this._annotations = PlacesUtils.getAnnotationsForItem(this._id);
-  this._dateAdded = PlacesUtils.bookmarks.getItemDateAdded(this._id);
-  this._lastModified = PlacesUtils.bookmarks.getItemLastModified(this._id);
-}
-
-placesRemoveItemTransaction.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PRIT_doTransaction() {
-    this._oldIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
-
-    if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
-      let aggregateTxn = new placesAggregateTransactions("Remove item childTxn",
-                                                         this.childTransactions);
-      aggregateTxn.doTransaction();
-    }
-    else {
-      PlacesUtils.bookmarks.removeItem(this._id);
-      if (this._uri) {
-        // if this was the last bookmark (excluding tag-items and livemark
-        // children, see getMostRecentBookmarkForURI) for the bookmark's url,
-        // remove the url from tag containers as well.
-        if (PlacesUtils.getMostRecentBookmarkForURI(this._uri) == -1) {
-          this._tags = PlacesUtils.tagging.getTagsForURI(this._uri);
-          PlacesUtils.tagging.untagURI(this._uri, this._tags);
-        }
-      }
-    }
-  },
-
-  undoTransaction: function PRIT_undoTransaction() {
-    if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) {
-      this._id = PlacesUtils.bookmarks.insertBookmark(this._oldContainer,
-                                                      this._uri,
-                                                      this._oldIndex,
-                                                      this._title);
-      if (this._tags && this._tags.length > 0)
-        PlacesUtils.tagging.tagURI(this._uri, this._tags);
-      if (this._keyword)
-        PlacesUtils.bookmarks.setKeywordForBookmark(this._id, this._keyword);
-    }
-    else if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
-      let aggregateTxn = new placesAggregateTransactions("Remove item childTxn",
-                                                         this.childTransactions);
-      aggregateTxn.undoTransaction();
-    }
-    else // TYPE_SEPARATOR
-      this._id = PlacesUtils.bookmarks.insertSeparator(this._oldContainer, this._oldIndex);
-
-    if (this._annotations.length > 0)
-      PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
-
-    PlacesUtils.bookmarks.setItemDateAdded(this._id, this._dateAdded);
-    PlacesUtils.bookmarks.setItemLastModified(this._id, this._lastModified);
-  },
-
-  /**
-  * Returns a flat, ordered list of transactions for a depth-first recreation
-  * of items within this folder.
-  */
-  _getFolderContentsTransactions:
-  function PRIT__getFolderContentsTransactions() {
-    var transactions = [];
-    var contents =
-      PlacesUtils.getFolderContents(this._id, false, false).root;
-    for (var i = 0; i < contents.childCount; ++i) {
-      let txn = new placesRemoveItemTransaction(contents.getChild(i).itemId);
-      transactions.push(txn);
-    }
-    contents.containerOpen = false;
-    // Reverse transactions to preserve parent-child relationship.
-    return transactions.reverse();
-  }
-};
-
-function placesEditItemTitleTransactions(id, newTitle) {
-  this._id = id;
-  this._newTitle = newTitle;
-  this._oldTitle = "";
-  this.redoTransaction = this.doTransaction;
-}
-
-placesEditItemTitleTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PEITT_doTransaction() {
-    this._oldTitle = PlacesUtils.bookmarks.getItemTitle(this._id);
-    PlacesUtils.bookmarks.setItemTitle(this._id, this._newTitle);
-  },
-
-  undoTransaction: function PEITT_undoTransaction() {
-    PlacesUtils.bookmarks.setItemTitle(this._id, this._oldTitle);
-  }
-};
-
-function placesEditBookmarkURITransactions(aBookmarkId, aNewURI) {
-  this._id = aBookmarkId;
-  this._newURI = aNewURI;
-  this.redoTransaction = this.doTransaction;
-}
-
-placesEditBookmarkURITransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PEBUT_doTransaction() {
-    this._oldURI = PlacesUtils.bookmarks.getBookmarkURI(this._id);
-    PlacesUtils.bookmarks.changeBookmarkURI(this._id, this._newURI);
-    // move tags from old URI to new URI
-    this._tags = PlacesUtils.tagging.getTagsForURI(this._oldURI);
-    if (this._tags.length != 0) {
-      // only untag the old URI if this is the only bookmark
-      if (PlacesUtils.getBookmarksForURI(this._oldURI, {}).length == 0)
-        PlacesUtils.tagging.untagURI(this._oldURI, this._tags);
-      PlacesUtils.tagging.tagURI(this._newURI, this._tags);
-    }
-  },
-
-  undoTransaction: function PEBUT_undoTransaction() {
-    PlacesUtils.bookmarks.changeBookmarkURI(this._id, this._oldURI);
-    // move tags from new URI to old URI 
-    if (this._tags.length != 0) {
-      // only untag the new URI if this is the only bookmark
-      if (PlacesUtils.getBookmarksForURI(this._newURI, {}).length == 0)
-        PlacesUtils.tagging.untagURI(this._newURI, this._tags);
-      PlacesUtils.tagging.tagURI(this._oldURI, this._tags);
-    }
-  }
-};
-
-function placesSetItemAnnotationTransactions(aItemId, aAnnotationObject) {
-  this.id = aItemId;
-  this._anno = aAnnotationObject;
-  // create an empty old anno
-  this._oldAnno = { name: this._anno.name,
-                    type: Ci.nsIAnnotationService.TYPE_STRING,
-                    flags: 0,
-                    value: null,
-                    expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
-  this.redoTransaction = this.doTransaction;
-}
-
-placesSetItemAnnotationTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PSIAT_doTransaction() {
-    // Since this can be used as a child transaction this.id will be known
-    // only at this point, after the external caller has set it.
-    if (PlacesUtils.annotations.itemHasAnnotation(this.id, this._anno.name)) {
-      // Save the old annotation if it is set.
-      var flags = {}, expires = {}, mimeType = {}, type = {};
-      PlacesUtils.annotations.getItemAnnotationInfo(this.id, this._anno.name,
-                                                    flags, expires, mimeType,
-                                                    type);
-      this._oldAnno.flags = flags.value;
-      this._oldAnno.expires = expires.value;
-      this._oldAnno.mimeType = mimeType.value;
-      this._oldAnno.type = type.value;
-      this._oldAnno.value = PlacesUtils.annotations
-                                       .getItemAnnotation(this.id,
-                                                          this._anno.name);
-    }
-
-    PlacesUtils.setAnnotationsForItem(this.id, [this._anno]);
-  },
-
-  undoTransaction: function PSIAT_undoTransaction() {
-    PlacesUtils.setAnnotationsForItem(this.id, [this._oldAnno]);
-  }
-};
-
-function placesSetPageAnnotationTransactions(aURI, aAnnotationObject) {
-  this._uri = aURI;
-  this._anno = aAnnotationObject;
-  // create an empty old anno
-  this._oldAnno = { name: this._anno.name,
-                    type: Ci.nsIAnnotationService.TYPE_STRING,
-                    flags: 0,
-                    value: null,
-                    expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
-
-  if (PlacesUtils.annotations.pageHasAnnotation(this._uri, this._anno.name)) {
-    // fill the old anno if it is set
-    var flags = {}, expires = {}, mimeType = {}, type = {};
-    PlacesUtils.annotations.getPageAnnotationInfo(this._uri, this._anno.name,
-                                                  flags, expires, mimeType, type);
-    this._oldAnno.flags = flags.value;
-    this._oldAnno.expires = expires.value;
-    this._oldAnno.mimeType = mimeType.value;
-    this._oldAnno.type = type.value;
-    this._oldAnno.value = PlacesUtils.annotations
-                                     .getPageAnnotation(this._uri, this._anno.name);
-  }
-
-  this.redoTransaction = this.doTransaction;
-}
-
-placesSetPageAnnotationTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PSPAT_doTransaction() {
-    PlacesUtils.setAnnotationsForURI(this._uri, [this._anno]);
-  },
-
-  undoTransaction: function PSPAT_undoTransaction() {
-    PlacesUtils.setAnnotationsForURI(this._uri, [this._oldAnno]);
-  }
-};
-
-function placesEditBookmarkKeywordTransactions(id, newKeyword) {
-  this.id = id;
-  this._newKeyword = newKeyword;
-  this._oldKeyword = "";
-  this.redoTransaction = this.doTransaction;
-}
-
-placesEditBookmarkKeywordTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PEBKT_doTransaction() {
-    this._oldKeyword = PlacesUtils.bookmarks.getKeywordForBookmark(this.id);
-    PlacesUtils.bookmarks.setKeywordForBookmark(this.id, this._newKeyword);
-  },
-
-  undoTransaction: function PEBKT_undoTransaction() {
-    PlacesUtils.bookmarks.setKeywordForBookmark(this.id, this._oldKeyword);
-  }
-};
-
-function placesEditBookmarkPostDataTransactions(aItemId, aPostData) {
-  this.id = aItemId;
-  this._newPostData = aPostData;
-  this._oldPostData = null;
-  this.redoTransaction = this.doTransaction;
-}
-
-placesEditBookmarkPostDataTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PEUPDT_doTransaction() {
-    this._oldPostData = PlacesUtils.getPostDataForBookmark(this.id);
-    PlacesUtils.setPostDataForBookmark(this.id, this._newPostData);
-  },
-
-  undoTransaction: function PEUPDT_undoTransaction() {
-    PlacesUtils.setPostDataForBookmark(this.id, this._oldPostData);
-  }
-};
-
-function placesEditLivemarkSiteURITransactions(folderId, uri) {
-  this._folderId = folderId;
-  this._newURI = uri;
-  this._oldURI = null;
-  this.redoTransaction = this.doTransaction;
-}
-
-placesEditLivemarkSiteURITransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PELSUT_doTransaction() {
-    this._oldURI = PlacesUtils.livemarks.getSiteURI(this._folderId);
-    PlacesUtils.livemarks.setSiteURI(this._folderId, this._newURI);
-  },
-
-  undoTransaction: function PELSUT_undoTransaction() {
-    PlacesUtils.livemarks.setSiteURI(this._folderId, this._oldURI);
-  }
-};
-
-function placesEditLivemarkFeedURITransactions(folderId, uri) {
-  this._folderId = folderId;
-  this._newURI = uri;
-  this._oldURI = null;
-  this.redoTransaction = this.doTransaction;
-}
-
-placesEditLivemarkFeedURITransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PELFUT_doTransaction() {
-    this._oldURI = PlacesUtils.livemarks.getFeedURI(this._folderId);
-    PlacesUtils.livemarks.setFeedURI(this._folderId, this._newURI);
-    PlacesUtils.livemarks.reloadLivemarkFolder(this._folderId);
-  },
-
-  undoTransaction: function PELFUT_undoTransaction() {
-    PlacesUtils.livemarks.setFeedURI(this._folderId, this._oldURI);
-    PlacesUtils.livemarks.reloadLivemarkFolder(this._folderId);
-  }
-};
-
-function placesEditBookmarkMicrosummaryTransactions(aItemId, newMicrosummary) {
-  this.id = aItemId;
-  this._mss = Cc["@mozilla.org/microsummary/service;1"].
-              getService(Ci.nsIMicrosummaryService);
-  this._newMicrosummary = newMicrosummary;
-  this._oldMicrosummary = null;
-  this.redoTransaction = this.doTransaction;
-}
-
-placesEditBookmarkMicrosummaryTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PEBMT_doTransaction() {
-    this._oldMicrosummary = this._mss.getMicrosummary(this.id);
-    if (this._newMicrosummary)
-      this._mss.setMicrosummary(this.id, this._newMicrosummary);
-    else
-      this._mss.removeMicrosummary(this.id);
-  },
-
-  undoTransaction: function PEBMT_undoTransaction() {
-    if (this._oldMicrosummary)
-      this._mss.setMicrosummary(this.id, this._oldMicrosummary);
-    else
-      this._mss.removeMicrosummary(this.id);
-  }
-};
-
-function placesEditItemDateAddedTransaction(id, newDateAdded) {
-  this.id = id;
-  this._newDateAdded = newDateAdded;
-  this._oldDateAdded = null;
-  this.redoTransaction = this.doTransaction;
-}
-
-placesEditItemDateAddedTransaction.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  // to support folders as well
-  get container() { return this.id; },
-  set container(val) { return this.id = val; },
-
-  doTransaction: function PEIDA_doTransaction() {
-    this._oldDateAdded = PlacesUtils.bookmarks.getItemDateAdded(this.id);
-    PlacesUtils.bookmarks.setItemDateAdded(this.id, this._newDateAdded);
-  },
-
-  undoTransaction: function PEIDA_undoTransaction() {
-    PlacesUtils.bookmarks.setItemDateAdded(this.id, this._oldDateAdded);
-  }
-};
-
-function placesEditItemLastModifiedTransaction(id, newLastModified) {
-  this.id = id;
-  this._newLastModified = newLastModified;
-  this._oldLastModified = null;
-  this.redoTransaction = this.doTransaction;
-}
-
-placesEditItemLastModifiedTransaction.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  // to support folders as well
-  get container() { return this.id; },
-  set container(val) { return this.id = val; },
-
-  doTransaction: function PEILM_doTransaction() {
-    this._oldLastModified = PlacesUtils.bookmarks.getItemLastModified(this.id);
-    PlacesUtils.bookmarks.setItemLastModified(this.id, this._newLastModified);
-  },
-
-  undoTransaction: function PEILM_undoTransaction() {
-    PlacesUtils.bookmarks.setItemLastModified(this.id, this._oldLastModified);
-  }
-};
-
-function placesSortFolderByNameTransactions(aFolderId) {
-  this._folderId = aFolderId;
-  this._oldOrder = null,
-  this.redoTransaction = this.doTransaction;
-}
-
-placesSortFolderByNameTransactions.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PSSFBN_doTransaction() {
-    this._oldOrder = [];
-
-    var contents =
-      PlacesUtils.getFolderContents(this._folderId, false, false).root;
-    var count = contents.childCount;
-
-    // sort between separators
-    var newOrder = []; 
-    var preSep = []; // temporary array for sorting each group of items
-    var sortingMethod =
-      function (a, b) {
-        if (PlacesUtils.nodeIsContainer(a) && !PlacesUtils.nodeIsContainer(b))
-          return -1;
-        if (!PlacesUtils.nodeIsContainer(a) && PlacesUtils.nodeIsContainer(b))
-          return 1;
-        return a.title.localeCompare(b.title);
-      };
-
-    for (var i = 0; i < count; ++i) {
-      var item = contents.getChild(i);
-      this._oldOrder[item.itemId] = i;
-      if (PlacesUtils.nodeIsSeparator(item)) {
-        if (preSep.length > 0) {
-          preSep.sort(sortingMethod);
-          newOrder = newOrder.concat(preSep);
-          preSep.splice(0);
-        }
-        newOrder.push(item);
-      }
-      else
-        preSep.push(item);
-    }
-    contents.containerOpen = false;
-
-    if (preSep.length > 0) {
-      preSep.sort(sortingMethod);
-      newOrder = newOrder.concat(preSep);
-    }
-
-    // set the nex indexes
-    var callback = {
-      runBatched: function() {
-        for (var i = 0; i < newOrder.length; ++i) {
-          PlacesUtils.bookmarks.setItemIndex(newOrder[i].itemId, i);
-        }
-      }
-    };
-    PlacesUtils.bookmarks.runInBatchMode(callback, null);
-  },
-
-  undoTransaction: function PSSFBN_undoTransaction() {
-    var callback = {
-      _self: this,
-      runBatched: function() {
-        for (item in this._self._oldOrder)
-          PlacesUtils.bookmarks.setItemIndex(item, this._self._oldOrder[item]);
-      }
-    };
-    PlacesUtils.bookmarks.runInBatchMode(callback, null);
-  }
-};
-
-function placesTagURITransaction(aURI, aTags) {
-  this._uri = aURI;
-  this._tags = aTags;
-  this._unfiledItemId = -1;
-  this.redoTransaction = this.doTransaction;
-}
-
-placesTagURITransaction.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PTU_doTransaction() {
-    if (PlacesUtils.getMostRecentBookmarkForURI(this._uri) == -1) {
-      // Force an unfiled bookmark first
-      this._unfiledItemId =
-        PlacesUtils.bookmarks
-                   .insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
-                                   this._uri,
-                                   PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                   PlacesUtils.history.getPageTitle(this._uri));
-      if (this._GUID)
-        PlacesUtils.bookmarks.setItemGUID(this._unfiledItemId, this._GUID);
-    }
-    PlacesUtils.tagging.tagURI(this._uri, this._tags);
-  },
-
-  undoTransaction: function PTU_undoTransaction() {
-    if (this._unfiledItemId != -1) {
-      // If a GUID exists for this item, preserve it before removing the item.
-      if (PlacesUtils.annotations.itemHasAnnotation(this._unfiledItemId, PlacesUtils.GUID_ANNO)) {
-        this._GUID = PlacesUtils.bookmarks.getItemGUID(this._unfiledItemId);
-      }
-      PlacesUtils.bookmarks.removeItem(this._unfiledItemId);
-      this._unfiledItemId = -1;
-    }
-    PlacesUtils.tagging.untagURI(this._uri, this._tags);
-  }
-};
-
-function placesUntagURITransaction(aURI, aTags) {
-  this._uri = aURI;
-  if (aTags) {    
-    // Within this transaction, we cannot rely on tags given by itemId
-    // since the tag containers may be gone after we call untagURI.
-    // Thus, we convert each tag given by its itemId to name.
-    this._tags = aTags;
-    for (var i=0; i < aTags.length; i++) {
-      if (typeof(this._tags[i]) == "number")
-        this._tags[i] = PlacesUtils.bookmarks.getItemTitle(this._tags[i]);
-    }
-  }
-  else
-    this._tags = PlacesUtils.tagging.getTagsForURI(this._uri);
-
-  this.redoTransaction = this.doTransaction;
-}
-
-placesUntagURITransaction.prototype = {
-  __proto__: placesBaseTransaction.prototype,
-
-  doTransaction: function PUTU_doTransaction() {
-    PlacesUtils.tagging.untagURI(this._uri, this._tags);
-  },
-
-  undoTransaction: function PUTU_undoTransaction() {
-    PlacesUtils.tagging.tagURI(this._uri, this._tags);
-  }
-};
-
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([placesTransactionsService]);
--- a/browser/components/places/tests/browser/browser_views_liveupdate.js
+++ b/browser/components/places/tests/browser/browser_views_liveupdate.js
@@ -99,17 +99,17 @@ function startTest() {
                              bs.DEFAULT_INDEX,
                              "bm1");
   bs.setItemTitle(id, "bm1_edited");
   addedBookmarks.push(id);
   id = bs.insertBookmark(bs.bookmarksMenuFolder,
                          PlacesUtils._uri("place:"),
                          bs.DEFAULT_INDEX,
                          "bm2");
-  bs.setItemTitle(id, "bm2_edited");
+  bs.setItemTitle(id, "");
   addedBookmarks.push(id);
   id = bs.insertSeparator(bs.bookmarksMenuFolder, bs.DEFAULT_INDEX);
   addedBookmarks.push(id);
   id = bs.createFolder(bs.bookmarksMenuFolder,
                        "bmf",
                        bs.DEFAULT_INDEX);
   bs.setItemTitle(id, "bmf_edited");
   addedBookmarks.push(id);
@@ -130,17 +130,17 @@ function startTest() {
   bs.setItemTitle(id, "tb1_edited");
   addedBookmarks.push(id);
   // Test live update of title.
   bs.setItemTitle(id, "tb1_edited");
   id = bs.insertBookmark(bs.toolbarFolder,
                          PlacesUtils._uri("place:"),
                          bs.DEFAULT_INDEX,
                          "tb2");
-  bs.setItemTitle(id, "tb2_edited");
+  bs.setItemTitle(id, "");
   addedBookmarks.push(id);
   id = bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
   addedBookmarks.push(id);
   id = bs.createFolder(bs.toolbarFolder,
                        "tbf",
                        bs.DEFAULT_INDEX);
   bs.setItemTitle(id, "tbf_edited");
   addedBookmarks.push(id);
@@ -280,19 +280,23 @@ var bookmarksObserver = {
 
     // Check that item has been moved in the correct position.
     let validator = function(aElementOrTreeIndex) {
       if (typeof(aElementOrTreeIndex) == "number") {
         var sidebar = document.getElementById("sidebar");
         var tree = sidebar.contentDocument.getElementById("bookmarks-view");
         let cellText = tree.view.getCellText(aElementOrTreeIndex,
                                              tree.columns.getColumnAt(0));
+        if (!aNewValue)
+          return cellText == PlacesUIUtils.getBestTitle(tree.view.nodeForTreeIndex(aElementOrTreeIndex));
         return cellText == aNewValue;
       }
       else {
+        if (!aNewValue && aElementOrTreeIndex.localName != "toolbarbutton")
+          return aElementOrTreeIndex.label == PlacesUIUtils.getBestTitle(aElementOrTreeIndex._placesNode);
         return aElementOrTreeIndex.label == aNewValue;
       }
     };
 
     for (var i = 0; i < views.length; i++) {
       var [node, index, valid] = searchItemInView(aItemId, views[i], validator);
       isnot(node, null, "Found changed Places node in " + views[i]);
       is(node.title, aNewValue, "Node has correct title: " + aNewValue);
--- a/browser/components/places/tests/unit/test_placesTxn.js
+++ b/browser/components/places/tests/unit/test_placesTxn.js
@@ -33,60 +33,22 @@
  * 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 ***** */
 
-// Get bookmark service
-try {
-  var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
-} catch(ex) {
-  do_throw("Could not get nav-bookmarks-service\n");
-}
-
-// Get livemark service
-try {
-  var lmsvc = Cc["@mozilla.org/browser/livemark-service;2"].getService(Ci.nsILivemarkService);
-} catch(ex) {
-  do_throw("Could not get livemark-service\n");
-} 
-
-// Get microsummary service
-try {
-  var mss = Cc["@mozilla.org/microsummary/service;1"].getService(Ci.nsIMicrosummaryService);
-} catch(ex) {
-  do_throw("Could not get microsummary-service\n");
-} 
-
-// Get Places Transaction Manager Service
-try {
-  var ptSvc = Cc["@mozilla.org/browser/placesTransactionsService;1"].
-              getService(Ci.nsIPlacesTransactionsService);
-} catch(ex) {
-  do_throw("Could not get Places Transactions Service\n");
-}
-
-// Get tagging service
-try {
-  var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
-                getService(Ci.nsITaggingService);
-} catch(ex) {
-  do_throw("Could not get tagging service\n");
-}
-
-// Get annotations service
-try {
-  var annosvc = Cc["@mozilla.org/browser/annotation-service;1"].
-                getService(Ci.nsIAnnotationService);
-} catch(ex) {
-  do_throw("Could not get annotations service\n");
-}
+var bmsvc = PlacesUtils.bookmarks;
+var lmsvc = PlacesUtils.livemarks;
+var mss = PlacesUtils.microsummaries;
+var ptSvc = PlacesUIUtils.ptm;
+var tagssvc = PlacesUtils.tagging;
+var annosvc = PlacesUtils.annotations;
 
 // create and add bookmarks observer
 var observer = {
   onBeginUpdateBatch: function() {
     this._beginUpdateBatch = true;
   },
   onEndUpdateBatch: function() {
     this._endUpdateBatch = true;
@@ -138,19 +100,18 @@ bmsvc.addObserver(observer, false);
 var bmStartIndex = 0;
 
 // main
 function run_test() {
   // get bookmarks root index
   var root = bmsvc.bookmarksMenuFolder;
 
   //Test creating a folder with a description
-  const DESCRIPTION_ANNO = "bookmarkProperties/description";
   const TEST_DESCRIPTION = "this is my test description";
-  var annos = [{ name: DESCRIPTION_ANNO,
+  var annos = [{ name: PlacesUIUtils.DESCRIPTION_ANNO,
                  type: annosvc.TYPE_STRING,
                 flags: 0,
                 value: TEST_DESCRIPTION,
               expires: annosvc.EXPIRE_NEVER }];
   var txn1 = ptSvc.createFolder("Testing folder", root, bmStartIndex, annos);
   ptSvc.doTransaction(txn1);
 
   // This checks that calling undoTransaction on an "empty batch" doesn't
@@ -160,17 +121,17 @@ function run_test() {
   ptSvc.undoTransaction();
 
   var folderId = observer._itemAddedId;
   do_check_eq(bmsvc.getItemTitle(folderId), "Testing folder");
   do_check_eq(observer._itemAddedIndex, bmStartIndex);
   do_check_eq(observer._itemAddedParent, root);
   do_check_eq(observer._itemAddedId, folderId);
   do_check_eq(TEST_DESCRIPTION, 
-              annosvc.getItemAnnotation(folderId, DESCRIPTION_ANNO));
+              annosvc.getItemAnnotation(folderId, PlacesUIUtils.DESCRIPTION_ANNO));
 
   txn1.undoTransaction();
   do_check_eq(observer._itemRemovedId, folderId);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, bmStartIndex);
   txn1.redoTransaction();
   do_check_eq(observer._itemAddedIndex, bmStartIndex);
   do_check_eq(observer._itemAddedParent, root);
@@ -410,21 +371,21 @@ function run_test() {
   do_check_eq(observer._itemChangedId, bkmk1Id);
   do_check_eq(observer._itemChangedProperty, "uri");
   do_check_eq(observer._itemChangedValue, "http://newuri.com/");
   txn9.undoTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
   do_check_eq(observer._itemChangedProperty, "uri");
   do_check_eq(observer._itemChangedValue, "http://www.example3.com/");
   
-  // Test edit item description
+  // Test edit description transaction.
   var txn10 = ptSvc.editItemDescription(bkmk1Id, "Description1");
   txn10.doTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
-  do_check_eq(observer._itemChangedProperty, "bookmarkProperties/description");
+  do_check_eq(observer._itemChangedProperty, PlacesUIUtils.DESCRIPTION_ANNO);
 
   // Testing edit keyword
   var txn11 = ptSvc.editBookmarkKeyword(bkmk1Id, "kw1");
   txn11.doTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
   do_check_eq(observer._itemChangedProperty, "keyword");
   do_check_eq(observer._itemChangedValue, "kw1"); 
   txn11.undoTransaction();
@@ -505,26 +466,25 @@ function run_test() {
   do_check_true(lmsvc.isLivemark(lvmkId));
   do_check_eq(lmsvc.getSiteURI(lvmkId).spec, "http://siteuri.com/");
   do_check_eq(lmsvc.getFeedURI(lvmkId).spec, "http://feeduri.com/");
   do_check_eq(annosvc.getItemAnnotation(lvmkId, "livemark/testAnno"), "testAnno");
   txn15.redoTransaction();
   do_check_false(lmsvc.isLivemark(lvmkId));
   do_check_eq(observer._itemRemovedId, lvmkId);
 
-  // Test setLoadInSidebar
-  const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
+  // Test LoadInSidebar transaction.
   var txn16 = ptSvc.setLoadInSidebar(bkmk1Id, true);
   txn16.doTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
-  do_check_eq(observer._itemChangedProperty, LOAD_IN_SIDEBAR_ANNO);
+  do_check_eq(observer._itemChangedProperty, PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO);
   do_check_eq(observer._itemChanged_isAnnotationProperty, true);
   txn16.undoTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
-  do_check_eq(observer._itemChangedProperty, LOAD_IN_SIDEBAR_ANNO);
+  do_check_eq(observer._itemChangedProperty, PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO);
   do_check_eq(observer._itemChanged_isAnnotationProperty, true);
 
   // Test generic item annotation
   var itemAnnoObj = { name: "testAnno/testInt",
                       type: Ci.nsIAnnotationService.TYPE_INT32,
                       flags: 0,
                       value: 123,
                       expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
--- a/browser/components/places/tests/unit/test_txnGUIDs.js
+++ b/browser/components/places/tests/unit/test_txnGUIDs.js
@@ -1,89 +1,87 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *  vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Marco Bonardo <mak77@bonardo.net>
- *
- * 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 ***** */
-
-/**
- * This test will ensure any transactions service that is going to create
- * a new item, won't replace the GUID when undoing and redoing the action.
- */
-var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-            getService(Ci.nsINavBookmarksService);
-var txnsvc = Cc["@mozilla.org/browser/placesTransactionsService;1"].
-             getService(Ci.nsIPlacesTransactionsService);
-
-function test_GUID_persistance(aTxn) {
-  aTxn.doTransaction();
-  var itemId = bmsvc.getIdForItemAt(bmsvc.unfiledBookmarksFolder, 0);
-  var GUID = bmsvc.getItemGUID(itemId);
-  aTxn.undoTransaction();
-  aTxn.redoTransaction();
-  do_check_eq(GUID, bmsvc.getItemGUID(itemId));
-  aTxn.undoTransaction();
-}
-
-function run_test() {
-  // Create folder.
-  var createFolderTxn = txnsvc.createFolder("Test folder",
-                                            bmsvc.unfiledBookmarksFolder,
-                                            bmsvc.DEFAULT_INDEX);
-  test_GUID_persistance(createFolderTxn);
-
-  // Create bookmark.
-  var createBookmarkTxn = txnsvc.createItem(uri("http://www.example.com"),
-                                            bmsvc.unfiledBookmarksFolder,
-                                            bmsvc.DEFAULT_INDEX,
-                                            "Test bookmark");
-  test_GUID_persistance(createBookmarkTxn);
-
-  // Create separator.
-  var createSeparatorTxn = txnsvc.createSeparator(bmsvc.unfiledBookmarksFolder,
-                                                  bmsvc.DEFAULT_INDEX);
-  test_GUID_persistance(createFolderTxn);
-
-  // Create livemark.
-  var createLivemarkTxn = txnsvc.createLivemark(uri("http://feeduri.com"),
-                                               uri("http://siteuri.com"),
-                                               "Test livemark",
-                                               bmsvc.unfiledBookmarksFolder,
-                                               bmsvc.DEFAULT_INDEX);
-  test_GUID_persistance(createLivemarkTxn);
-
-  // Tag URI.
-  var tagURITxn = txnsvc.tagURI(uri("http://www.example.com"), ["foo"]);
-  test_GUID_persistance(tagURITxn);
-}
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *  vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Marco Bonardo <mak77@bonardo.net>
+ *
+ * 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 ***** */
+
+/**
+ * This test will ensure any transactions service that is going to create
+ * a new item, won't replace the GUID when undoing and redoing the action.
+ */
+var bmsvc = PlacesUtils.bookmarks;
+var txnsvc = PlacesUIUtils.ptm;
+
+function test_GUID_persistance(aTxn) {
+  aTxn.doTransaction();
+  var itemId = bmsvc.getIdForItemAt(bmsvc.unfiledBookmarksFolder, 0);
+  var GUID = bmsvc.getItemGUID(itemId);
+  aTxn.undoTransaction();
+  aTxn.redoTransaction();
+  do_check_eq(GUID, bmsvc.getItemGUID(itemId));
+  aTxn.undoTransaction();
+}
+
+function run_test() {
+  // Create folder.
+  var createFolderTxn = txnsvc.createFolder("Test folder",
+                                            bmsvc.unfiledBookmarksFolder,
+                                            bmsvc.DEFAULT_INDEX);
+  test_GUID_persistance(createFolderTxn);
+
+  // Create bookmark.
+  var createBookmarkTxn = txnsvc.createItem(uri("http://www.example.com"),
+                                            bmsvc.unfiledBookmarksFolder,
+                                            bmsvc.DEFAULT_INDEX,
+                                            "Test bookmark");
+  test_GUID_persistance(createBookmarkTxn);
+
+  // Create separator.
+  var createSeparatorTxn = txnsvc.createSeparator(bmsvc.unfiledBookmarksFolder,
+                                                  bmsvc.DEFAULT_INDEX);
+  test_GUID_persistance(createFolderTxn);
+
+  // Create livemark.
+  var createLivemarkTxn = txnsvc.createLivemark(uri("http://feeduri.com"),
+                                               uri("http://siteuri.com"),
+                                               "Test livemark",
+                                               bmsvc.unfiledBookmarksFolder,
+                                               bmsvc.DEFAULT_INDEX);
+  test_GUID_persistance(createLivemarkTxn);
+
+  // Tag URI.
+  var tagURITxn = txnsvc.tagURI(uri("http://www.example.com"), ["foo"]);
+  test_GUID_persistance(tagURITxn);
+}
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -114,17 +114,16 @@
 #endif
 @BINPATH@/components/accessibility.xpt
 #endif
 @BINPATH@/components/appshell.xpt
 @BINPATH@/components/appstartup.xpt
 @BINPATH@/components/autocomplete.xpt
 @BINPATH@/components/autoconfig.xpt
 @BINPATH@/components/browsercompsbase.xpt
-@BINPATH@/components/browserplaces.xpt
 @BINPATH@/components/browser-feeds.xpt
 @BINPATH@/components/caps.xpt
 @BINPATH@/components/chardet.xpt
 @BINPATH@/components/chrome.xpt
 @BINPATH@/components/commandhandler.xpt
 @BINPATH@/components/commandlines.xpt
 @BINPATH@/components/composer.xpt
 @BINPATH@/components/content_base.xpt
@@ -275,17 +274,16 @@
 @BINPATH@/components/WebContentConverter.js
 @BINPATH@/components/BrowserComponents.manifest
 @BINPATH@/components/nsBrowserContentHandler.js
 @BINPATH@/components/nsBrowserGlue.js
 @BINPATH@/components/nsSetDefaultBrowser.manifest
 @BINPATH@/components/nsSetDefaultBrowser.js
 @BINPATH@/components/nsMicrosummaryService.js
 @BINPATH@/components/BrowserPlaces.manifest
-@BINPATH@/components/nsPlacesTransactionsService.js
 @BINPATH@/components/nsPrivateBrowsingService.manifest
 @BINPATH@/components/nsPrivateBrowsingService.js
 @BINPATH@/components/toolkitsearch.manifest
 @BINPATH@/components/nsSearchService.js
 @BINPATH@/components/nsSearchSuggestions.js
 @BINPATH@/components/nsTryToClose.manifest
 @BINPATH@/components/nsTryToClose.js
 @BINPATH@/components/passwordmgr.manifest
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -550,17 +550,16 @@ xpicleanup@BIN_SUFFIX@
   ../Resources/firefox-bin.rsrc
   components/accessibility.xpt
   components/alerts.xpt
   components/appshell.xpt
   components/appstartup.xpt
   components/autoconfig.xpt
   components/browser-feeds.xpt
   components/browsercompsbase.xpt
-  components/browserplaces.xpt
   components/browsersearch.xpt
   components/caps.xpt
   components/chardet.xpt
   components/chrome.xpt
   components/commandhandler.xpt
   components/commandlines.xpt
   components/composer.xpt
   components/content.xpt
@@ -856,8 +855,10 @@ extensions/inspector@mozilla.org/install
 extensions/inspector@mozilla.org/components/inspector-cmdline.js
 extensions/inspector@mozilla.org/chrome.manifest
 extensions/inspector@mozilla.org/chrome/inspector.jar
 extensions/inspector@mozilla.org/defaults/preferences/inspector.js
 extensions/inspector@mozilla.org/platform/WINNT/chrome/icons/default/winInspectorMain.ico
 extensions/inspector@mozilla.org/components/inspector.xpt
 extensions/inspector@mozilla.org/components/@DLL_PREFIX@inspector@DLL_SUFFIX@
 extensions/inspector@mozilla.org/chrome/icons/default/winInspectorMain.ico
+components/nsPlacesTransactionsService.js
+components/browserplaces.xpt
deleted file mode 100644
index 8503bc31498fab300e93acdf732dc91d03c7f3b7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
index 0000000000000000000000000000000000000000..082b177811eb58303ee74b744e924adaf7223ade
GIT binary patch
literal 606
zc$@)V0-^nhP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0006dNkl<ZILn2T
z-)mBF7{(6>yNDu!h-y^WT4$vu1#K<dtOkxvn`sG~UUboqMYteyQF<{qGz&5hoQiJx
zN!w^aFcv6X8H28jF=7yO(Z3J`gMsk$J_nW4k?7)s&-1*``{j7_s{l~Ube(^y3I(Am
z)aq30nQHC-Wz>+K5Z2@RXH32Oh6m-J2Gq<rW2fbS&Y;#Nl*TekxIMdy@h4w!dSc%A
zG;7Y-VV67213Cf^wNUB<l5bbxODsTqMHuP3_6CHS8E5RUE52YHU>~~g5^57KzT(V{
zIf%|T9#1qqOg_&}{CSmmO*pLV^JTTc<a-2Cix6EAY>frc%wY01Vfk!&5x!dsoE4Nk
z15@9_Gi5k06d~GUealv)<8?+fgr-aEuPN=`)JACL6TI<R^h7m?H?S@?^4^$cbc2~P
z{V!#wXL4gW^%1>SUgCg13-Jcl0~&c}AcvDzUt#F(68&#w$BCOi`s4Gk`!W#y->)DY
zuYGVDp6he$uPNJ)$8~3<2=|x{(G{Wj5=AqE$=ifwcl0qFkw=_q%C=+UE}_<Q`8Ay9
zauD788Aa2><nxYT4&Bn_4tI^g)+3kny#r~uW6y9jl!f?;FtV#J2|~?`Gj`Y&uQmUP
zTO1eLgwpQ*Npyt^=#CcQ@~6?^zh^+rj5BuF<xb0G+I%RM5Z2pI-NF9h9Mo{pfSMU+
s?ELdKl1&FkRiPlP2&l7C&swhYA1K2vaguu^HUIzs07*qoM6N<$f{UggX8-^I
new file mode 100644
index 0000000000000000000000000000000000000000..6e09ab9c32d021d9f1f4c937943b31be08cb87c8
GIT binary patch
literal 8056
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
GLSTZxlG)Ax
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -980,26 +980,26 @@ toolbar[iconsize="small"] #fullscreen-bu
 
 .popup-notification-icon {
   width: 64px;
   height: 64px;
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
-  list-style-image: url(chrome://browser/skin/Geo.png);
+  list-style-image: url(chrome://browser/skin/Geolocation-64.png);
 }
 
 /* Notification icon box */
 #notification-popup-box {
   margin: 0 3px;
 }
 
 #geo-notification-icon {
-  list-style-image: url(chrome://browser/skin/Geo.png);
+  list-style-image: url(chrome://browser/skin/Geolocation-16.png);
   width: 16px;
   height: 16px;
 }
 
 /* Feed icon */
 #feed-button,
 #feed-button > .button-box,
 #feed-button:hover:active > .button-box {
--- a/browser/themes/gnomestripe/browser/jar.mn
+++ b/browser/themes/gnomestripe/browser/jar.mn
@@ -5,17 +5,18 @@ browser.jar:
 * skin/classic/browser/aboutPrivateBrowsing.css             (aboutPrivateBrowsing.css)
 * skin/classic/browser/aboutSessionRestore.css        (aboutSessionRestore.css)
   skin/classic/browser/aboutSessionRestore-window-icon.png
   skin/classic/browser/aboutCertError.css             (aboutCertError.css)
   skin/classic/browser/actionicon-tab.png
 * skin/classic/browser/browser.css                    (browser.css)
 * skin/classic/browser/engineManager.css              (engineManager.css)
   skin/classic/browser/fullscreen-video.css
-  skin/classic/browser/Geo.png
+  skin/classic/browser/Geolocation-16.png
+  skin/classic/browser/Geolocation-64.png
   skin/classic/browser/Go-arrow.png
   skin/classic/browser/identity.png
   skin/classic/browser/Info.png
   skin/classic/browser/KUI-close.png
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
 * skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
deleted file mode 100644
index 566a8ae74d6c94305b125883d9592fc292b6e9bf..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
index 0000000000000000000000000000000000000000..a40cc1bb9ab74689fc3b7fdcffb3c9258387e4f4
GIT binary patch
literal 416
zc$@*C0bl-!P)<h;3K|Lk000e1NJLTq000mG000mO1ONa4wfZ;e0004JNkl<ZC{t}w
z%WA?<6g(>z^&JtTCTjCA(s=QKfd<962)2Stzr_Ct1o932071x41cZVhbn6EM3V{oO
z=|W?>D6=@joZ&ne0^RUr6ueSYPRnU2DtJ#urr%3(FC-1LAwxzR4G2kb|1jipl~6>7
z_X5SyV?9=!UeMtpDq%hcB9P!qP_N1u1X3^RCkUjB)vE--15uU9X`id?Hc&Y}A8t%#
zeJ-cf7i#(g41(+=xh@MC9|Q)P9;p`wZIOw8p)DAcGnsq}gSVo3Sk<ytRjVIck&#Sc
z#x&t`SSgFNP<$9fO*^t^md-KxChKbj+x~BbZLeUR$qJSj`I%Vj)WnRB{3T{SjhT~9
zxpaS1I!GUP#-@Ckjv0ZRU<LEqVjvJZvl9r^V&-)P#|IH;mUBY~L*DguXCBXEebM!Y
z+<_a;a*wdqdpEIR;~j5!g$*}Z|AuvgYizvjX@?!Qr;X=6;{E{z2IkOF7ucEr0000<
KMNUMnLSTaTC#<6Y
new file mode 100644
index 0000000000000000000000000000000000000000..099b9c76f355237c3ae163f5c17845bb2cf36c6c
GIT binary patch
literal 8490
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
Y57q13Is`|s(f|Me07*qoM6N<$g6Am5R{#J2
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -1805,47 +1805,47 @@ toolbarbutton.chevron > .toolbarbutton-m
 #identity-popup,
 #notification-popup {
   -moz-appearance: none;
   -moz-window-shadow: none;
   background-color: transparent;
   margin-top: -3px;
   margin-left: -23px;
   min-width: 280px;
-  -moz-border-image: url(chrome://browser/skin/hud-panel.png) 26 18 22 50 / 26px 18px 22px 50px repeat; 
+  -moz-border-image: url(chrome://browser/skin/hud-panel.png) 26 18 22 50 / 26px 18px 22px 50px repeat;
 }
 
 #notification-popup {
   margin-top: -1px;
   margin-left: -27px;
 }
 
 #notification-popup-box {
   margin: 0 3px;
 }
 
 #geo-notification-icon {
-  list-style-image: url(chrome://browser/skin/Geo.png);
+  list-style-image: url(chrome://browser/skin/Geolocation-16.png);
   width: 16px;
   height: 16px;
   margin: 0 2px;
 }
 
 .popup-notification-description {
   color: #fff;
 }
 
 .popup-notification-icon {
   width: 64px;
   height: 64px;
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
-  list-style-image: url(chrome://browser/skin/Geo.png);
+  list-style-image: url(chrome://browser/skin/Geolocation-64.png);
 }
 
 #identity-popup-container,
 #identity-popup-notification-container {
   margin: 4px 3px 2px -30px;
   color: #fff;
 }
 
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -5,17 +5,18 @@ browser.jar:
 * skin/classic/browser/aboutSessionRestore.css              (aboutSessionRestore.css)
   skin/classic/browser/aboutSessionRestore-window-icon.png
   skin/classic/browser/aboutCertError.css                   (aboutCertError.css)
   skin/classic/browser/actionicon-tab.png
 * skin/classic/browser/browser.css                          (browser.css)
 * skin/classic/browser/engineManager.css                    (engineManager.css)
   skin/classic/browser/feed-icons.png
   skin/classic/browser/fullscreen-video.css
-  skin/classic/browser/Geo.png
+  skin/classic/browser/Geolocation-16.png
+  skin/classic/browser/Geolocation-64.png
   skin/classic/browser/Go-arrow.png
   skin/classic/browser/home.png
   skin/classic/browser/hud-panel.png
   skin/classic/browser/hud-style-button-middle-background.png
   skin/classic/browser/hud-style-check-box-checked.png
   skin/classic/browser/hud-style-check-box-empty.png
   skin/classic/browser/hud-style-dropmarker-double-arrows.png
   skin/classic/browser/hud-style-expander-closed.png
deleted file mode 100644
index d81f056341e85dbede3ca5b02d35c2469969dde0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 9ae4c5a25748e66d9298b971b9fdbc5a45bf4669..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
index 0000000000000000000000000000000000000000..d710e7336dbc445d36ee4868257d9139c50f8919
GIT binary patch
literal 704
zc$@*i0zdtUP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0007qNkl<ZILl-B
z|NlP&G6n(_AZ}z}VBf~TC3F{zL2R%Xg9?UvG|d^TyrMV66*O<F=$hRyuyMNt!XP$C
z3?v6qgJA#=umSNhQ8~3cidu%(BotJeWK=XQjI5ncfiQ>-5(CMB)PU52^dKA1ETy7*
zTUpEKsECw;Hq3MtZKJ(PS_V5{d|^p>Z6!^^qad|FJq=L344R^{YPU5FEw2el$Y~-w
zPgqiJv9N^P0%S2kaam1uL-VV`QYs)r)Ict2(loZZC9SB@j2=Lo{G!4fe4+yA;!+Cg
z&1(7<HyIdM8W=>Rl=hk0xm_2QQZz$Xhzkpd$(k8iIbY|OklW3mqGNKy)j#s8j+y-p
zUJ;p{3=FI*85kH9u|%&T(8gt4LXtZ)jjXTQdj?-t(9plYplxh@(?2p9C=hr{)6jgo
zu(bS2Mos}t12}jU`Nd?Hs_U3+w|4fq;Sn5tSxv|E3WJ7$`2o+s=v&&xmd3<-K||Nn
z*vUKOhO)NdZU$*Z^;So(pnGy^+AWy23dk_9^NXX4ODkzM+qih&5tmhNVi1&&*R*!=
zzGrIZexHR;SPNMpzl8j9UNPC(sD|=u8Cp5tHM4WO!zV1I2^Lh-Hf(bXh<vDHVSk>5
zR}^lDslC@RLtEDaaLt^2TIxpD=N!C3?klS6G{aM(n4B`3p{3n2&%l@`macwJfa$(n
zQOnpmJgwkXNMi0y8C5+CVHu@16FZMbPQIa!bc`*R0aGO#MrP7Awaj$&kGSt0k?=eu
zDerlHUH9YM+Rn#;@tIHEf?}RJcn9CrG&IY^nHxb^%g92-*vhflGbCznL{j#%@T9C~
m?g0^d49)GE)D289vNHgKsnY3}7pKGk0000<MNUMnLSTYaut7oq
new file mode 100644
index 0000000000000000000000000000000000000000..1bd46ba5e146737f93c1ec1dfb1c80a6e203a59a
GIT binary patch
literal 8424
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
KMNUMnLSTaD2x3+M
--- a/browser/themes/winstripe/browser/browser-aero.css
+++ b/browser/themes/winstripe/browser/browser-aero.css
@@ -24,16 +24,20 @@
     background: transparent;
   }
 
   /* the new titlebar requires this, or content will be clipped at the top of the screen. */
   #main-window[sizemode="maximized"][chromemargin^="0,"] {
     margin-top: 8px;
   }
 
+  #main-window[sizemode="normal"][chromemargin^="0,"] {
+    margin-top: 2px;
+  }
+
   #main-window:not(:-moz-lwtheme)[inFullscreen="true"] {
     -moz-appearance: none;
     background-color: #556;
   }
 
   #toolbar-menubar:not(:-moz-lwtheme),
   #navigator-toolbox[tabsontop="true"] > #TabsToolbar:not(:-moz-lwtheme),
   #navigator-toolbox:not([tabsontop="true"]) > #nav-bar:not(:-moz-lwtheme),
@@ -48,17 +52,17 @@
     border-right: 1px solid ThreeDShadow;
   }
 
   /* Make the window draggable by glassed toolbars (bug 555081) */
   #toolbar-menubar:not([autohide="true"]),
   #navigator-toolbox[tabsontop="true"] > #TabsToolbar,
   #navigator-toolbox:not([tabsontop="true"]) > #nav-bar,
   #navigator-toolbox:not([tabsontop="true"]) > #nav-bar + #customToolbars + #PersonalToolbar[collapsed="true"] + #TabsToolbar:last-child,
-  #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#fullscr-toggler):-moz-lwtheme {
+  #navigator-toolbox > toolbar:not(#toolbar-menubar):-moz-lwtheme {
     -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
   }
 
   #browser:not(:-moz-lwtheme),
   #browser-bottombox:not(:-moz-lwtheme) {
     background-color: -moz-dialog;
   }
 
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -1598,26 +1598,26 @@ toolbarbutton.bookmark-item[dragover="tr
 
 .popup-notification-icon {
   width: 64px;
   height: 64px;
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
-  list-style-image: url(chrome://browser/skin/Geo.png);
+  list-style-image: url(chrome://browser/skin/Geolocation-64.png);
 }
 
 /* Notification icon box */
 #notification-popup-box {
   margin: 0 3px;
 }
 
 #geo-notification-icon {
-  list-style-image: url(chrome://browser/skin/Geo.png);
+  list-style-image: url(chrome://browser/skin/Geolocation-16.png);
   width: 16px;
   height: 16px;
 }
 
 #identity-popup-container {
   min-width: 280px;
   padding: 9px;
 }
--- a/browser/themes/winstripe/browser/jar.mn
+++ b/browser/themes/winstripe/browser/jar.mn
@@ -8,17 +8,18 @@ browser.jar:
 *       skin/classic/browser/aboutSessionRestore.css                 (aboutSessionRestore.css)
         skin/classic/browser/aboutSessionRestore-window-icon.png     (aboutSessionRestore-window-icon.png)
         skin/classic/browser/aboutCertError.css                      (aboutCertError.css)
         skin/classic/browser/actionicon-tab.png
         skin/classic/browser/appmenu-dropmarker.png
 *       skin/classic/browser/browser.css                             (browser.css)
 *       skin/classic/browser/engineManager.css                       (engineManager.css)
         skin/classic/browser/fullscreen-video.css
-        skin/classic/browser/Geo.png                                 (Geo.png)
+        skin/classic/browser/Geolocation-16.png
+        skin/classic/browser/Geolocation-64.png
         skin/classic/browser/Info.png                                (Info.png)
         skin/classic/browser/identity.png                            (identity.png)
         skin/classic/browser/keyhole-forward-mask.svg
         skin/classic/browser/KUI-background.png
         skin/classic/browser/KUI-close.png
         skin/classic/browser/mainwindow-dropdown-arrow.png
         skin/classic/browser/pageInfo.css
         skin/classic/browser/pageInfo.png                            (pageInfo.png)
@@ -93,17 +94,18 @@ browser.jar:
 *       skin/classic/aero/browser/aboutSessionRestore.css            (aboutSessionRestore.css)
         skin/classic/aero/browser/aboutSessionRestore-window-icon.png (aboutSessionRestore-window-icon-aero.png)
         skin/classic/aero/browser/aboutCertError.css                 (aboutCertError.css)
         skin/classic/aero/browser/actionicon-tab.png                 (actionicon-tab.png)
         skin/classic/aero/browser/appmenu-dropmarker.png
 *       skin/classic/aero/browser/browser.css                        (browser-aero.css)
 *       skin/classic/aero/browser/engineManager.css                  (engineManager.css)
         skin/classic/aero/browser/fullscreen-video.css
-        skin/classic/aero/browser/Geo.png                            (Geo-aero.png)
+        skin/classic/aero/browser/Geolocation-16.png
+        skin/classic/aero/browser/Geolocation-64.png
         skin/classic/aero/browser/Info.png                           (Info-aero.png)
         skin/classic/aero/browser/identity.png                       (identity-aero.png)
         skin/classic/aero/browser/keyhole-forward-mask.svg
         skin/classic/aero/browser/KUI-background.png
         skin/classic/aero/browser/KUI-close.png
         skin/classic/aero/browser/mainwindow-dropdown-arrow.png      (mainwindow-dropdown-arrow-aero.png)
         skin/classic/aero/browser/pageInfo.css
         skin/classic/aero/browser/pageInfo.png                       (pageInfo-aero.png)
--- a/chrome/src/Makefile.in
+++ b/chrome/src/Makefile.in
@@ -42,37 +42,54 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE          = chrome
 LIBRARY_NAME    = chrome_s
 LIBXUL_LIBRARY  = 1
 FORCE_STATIC_LIB = 1
 
+EXPORTS_NAMESPACES = mozilla/chrome
+
+EXPORTS_mozilla/chrome = \
+		RegistryMessageUtils.h \
+		$(NULL)
 
 CPPSRCS		= \
 		nsChromeRegistry.cpp \
+		nsChromeRegistryChrome.cpp \
 		nsChromeProtocolHandler.cpp \
 		$(NULL)
 
+ifdef MOZ_IPC
+CPPSRCS += nsChromeRegistryContent.cpp
+endif
+
 EXTRA_DSO_LDOPTS = \
                 $(MOZ_UNICHARUTIL_LIBS) \
                 $(MOZ_COMPONENT_LIBS) \
                 $(NULL)
 
 ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
 EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS)
 endif
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 EXTRA_DSO_LDOPTS += $(TK_LIBS)
 endif
 
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
+LOCAL_INCLUDES += \
+		-I$(topsrcdir)/netwerk/protocol/res \
+		-I$(topsrcdir)/netwerk/base/src \
+		$(NULL)
+
 ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
 CXXFLAGS          += $(MOZ_GTK2_CFLAGS)
 endif
 
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/xpcom/components \
   -I$(DEPTH)/xpcom \
   $(NULL)
new file mode 100644
--- /dev/null
+++ b/chrome/src/RegistryMessageUtils.h
@@ -0,0 +1,208 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Josh Matthews <josh@joshmatthews.net> (Initial Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_RegistryMessageUtils_h
+#define mozilla_RegistryMessageUtils_h
+
+#include "IPC/IPCMessageUtils.h"
+#include "nsStringGlue.h"
+
+struct SerializedURI
+{
+  nsCString spec;
+  nsCString charset;
+};
+
+struct ChromePackage
+{
+  nsCString package;
+  SerializedURI contentBaseURI;
+  SerializedURI localeBaseURI;
+  SerializedURI skinBaseURI;
+  PRUint32 flags;
+};
+
+struct ResourceMapping
+{
+  nsCString resource;
+  SerializedURI resolvedURI;
+};
+
+struct OverrideMapping
+{
+  SerializedURI originalURI;
+  SerializedURI overrideURI;
+};
+
+namespace IPC {
+
+template<>
+struct ParamTraits<SerializedURI>
+{
+  typedef SerializedURI paramType;
+
+  static void Write(Message* aMsg, const paramType& aParam)
+  {
+    WriteParam(aMsg, aParam.spec);
+    WriteParam(aMsg, aParam.charset);
+  }
+
+  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  {
+    nsCString spec, charset;
+    if (ReadParam(aMsg, aIter, &spec) &&
+        ReadParam(aMsg, aIter, &charset)) {
+      aResult->spec = spec;
+      aResult->charset = charset;
+      return true;
+    }
+    return false;
+  }
+};
+  
+template <>
+struct ParamTraits<ChromePackage>
+{
+  typedef ChromePackage paramType;
+  
+  static void Write(Message* aMsg, const paramType& aParam)
+  {
+    WriteParam(aMsg, aParam.package);
+    WriteParam(aMsg, aParam.contentBaseURI);
+    WriteParam(aMsg, aParam.localeBaseURI);
+    WriteParam(aMsg, aParam.skinBaseURI);
+    WriteParam(aMsg, aParam.flags);
+  }
+  
+  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  {
+    nsCString package;
+    SerializedURI contentBaseURI, localeBaseURI, skinBaseURI;
+    PRUint32 flags;
+    
+    if (ReadParam(aMsg, aIter, &package) &&
+        ReadParam(aMsg, aIter, &contentBaseURI) &&
+        ReadParam(aMsg, aIter, &localeBaseURI) &&
+        ReadParam(aMsg, aIter, &skinBaseURI) &&
+        ReadParam(aMsg, aIter, &flags)) {
+      aResult->package = package;
+      aResult->contentBaseURI = contentBaseURI;
+      aResult->localeBaseURI = localeBaseURI;
+      aResult->skinBaseURI = skinBaseURI;
+      aResult->flags = flags;
+      return true;
+    }
+    return false;
+  }
+
+  static void Log(const paramType& aParam, std::wstring* aLog)
+  {
+    aLog->append(StringPrintf(L"[%s, %s, %s, %s, %u]", aParam.package.get(),
+                             aParam.contentBaseURI.spec.get(),
+                             aParam.localeBaseURI.spec.get(),
+                             aParam.skinBaseURI.spec.get(), aParam.flags));
+  }
+};
+
+template <>
+struct ParamTraits<ResourceMapping>
+{
+  typedef ResourceMapping paramType;
+  
+  static void Write(Message* aMsg, const paramType& aParam)
+  {
+    WriteParam(aMsg, aParam.resource);
+    WriteParam(aMsg, aParam.resolvedURI);
+  }
+  
+  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  {
+    nsCString resource;
+    SerializedURI resolvedURI;
+    
+    if (ReadParam(aMsg, aIter, &resource) &&
+        ReadParam(aMsg, aIter, &resolvedURI)) {
+      aResult->resource = resource;
+      aResult->resolvedURI = resolvedURI;
+      return true;
+    }
+    return false;
+  }
+
+  static void Log(const paramType& aParam, std::wstring* aLog)
+  {
+    aLog->append(StringPrintf(L"[%s, %s, %u]", aParam.resource.get(),
+                             aParam.resolvedURI.spec.get()));
+  }
+};
+
+template <>
+struct ParamTraits<OverrideMapping>
+{
+  typedef OverrideMapping paramType;
+  
+  static void Write(Message* aMsg, const paramType& aParam)
+  {
+    WriteParam(aMsg, aParam.originalURI);
+    WriteParam(aMsg, aParam.overrideURI);
+  }
+  
+  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  {
+    SerializedURI originalURI;
+    SerializedURI overrideURI;
+    
+    if (ReadParam(aMsg, aIter, &originalURI) &&
+        ReadParam(aMsg, aIter, &overrideURI)) {
+      aResult->originalURI = originalURI;
+      aResult->overrideURI = overrideURI;
+      return true;
+    }
+    return false;
+  }
+
+  static void Log(const paramType& aParam, std::wstring* aLog)
+  {
+    aLog->append(StringPrintf(L"[%s, %s, %u]", aParam.originalURI.spec.get(),
+                             aParam.overrideURI.spec.get()));
+  }
+};
+
+}
+
+#endif // RegistryMessageUtils_h
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -35,106 +35,57 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsChromeRegistry.h"
+#include "nsChromeRegistryChrome.h"
+#ifdef MOZ_IPC
+#include "nsChromeRegistryContent.h"
+#endif
 
 #include <string.h>
 
 #include "prio.h"
 #include "prprf.h"
-#if defined(XP_WIN)
-#include <windows.h>
-#elif defined(XP_MACOSX)
-#include <CoreServices/CoreServices.h>
-#elif defined(MOZ_WIDGET_GTK2)
-#include <gtk/gtk.h>
-#endif
 
-#include "nsAppDirectoryServiceDefs.h"
-#include "nsArrayEnumerator.h"
-#include "nsComponentManager.h"
-#include "nsStringEnumerator.h"
-#include "nsEnumeratorUtils.h"
 #include "nsCOMPtr.h"
 #include "nsDOMError.h"
 #include "nsEscape.h"
-#include "nsInt64.h"
 #include "nsLayoutCID.h"
-#include "nsNetCID.h"
 #include "nsNetUtil.h"
-#include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
-#include "nsWidgetsCID.h"
-#include "nsXPCOMCIDInternal.h"
-#include "nsXPIDLString.h"
-#include "nsXULAppAPI.h"
-#include "nsTextFormatter.h"
-#include "nsZipArchive.h"
 
-#include "nsIAtom.h"
-#include "nsICommandLine.h"
 #include "nsCSSStyleSheet.h"
 #include "nsIConsoleService.h"
-#include "nsIDirectoryService.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDocShell.h"
-#include "nsIDocumentObserver.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMLocation.h"
 #include "nsIDOMWindowCollection.h"
 #include "nsIDOMWindowInternal.h"
-#include "nsIFileChannel.h"
-#include "nsIFileURL.h"
 #include "nsIIOService.h"
 #include "nsIJARProtocolHandler.h"
-#include "nsIJARURI.h"
-#include "nsILocalFile.h"
-#include "nsILocaleService.h"
-#include "nsILookAndFeel.h"
 #include "nsIObserverService.h"
-#include "nsIPrefService.h"
-#include "nsIPrefBranch.h"
-#include "nsIPrefBranch2.h"
 #include "nsIPresShell.h"
 #include "nsIProtocolHandler.h"
-#include "nsIResProtocolHandler.h"
 #include "nsIScriptError.h"
-#include "nsIServiceManager.h"
-#include "nsISimpleEnumerator.h"
-#include "nsIStyleSheet.h"
-#include "nsISupportsArray.h"
-#include "nsIVersionComparator.h"
 #include "nsIWindowMediator.h"
-#include "nsIXPConnect.h"
-#include "nsIXULAppInfo.h"
-#include "nsIXULRuntime.h"
-
-#include "mozilla/Omnijar.h"
-
-#define UILOCALE_CMD_LINE_ARG "UILocale"
-
-#define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
-#define SELECTED_LOCALE_PREF "general.useragent.locale"
-#define SELECTED_SKIN_PREF   "general.skins.selectedSkin"
-
-static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
 
 nsChromeRegistry* nsChromeRegistry::gChromeRegistry;
 
 ////////////////////////////////////////////////////////////////////////////////
 
-static void
-LogMessage(const char* aMsg, ...)
+void
+nsChromeRegistry::LogMessage(const char* aMsg, ...)
 {
   nsCOMPtr<nsIConsoleService> console 
     (do_GetService(NS_CONSOLESERVICE_CONTRACTID));
   if (!console)
     return;
 
   va_list args;
   va_start(args, aMsg);
@@ -142,19 +93,19 @@ LogMessage(const char* aMsg, ...)
   va_end(args);
   if (!formatted)
     return;
 
   console->LogStringMessage(NS_ConvertUTF8toUTF16(formatted).get());
   PR_smprintf_free(formatted);
 }
 
-static void
-LogMessageWithContext(nsIURI* aURL, PRUint32 aLineNumber, PRUint32 flags,
-                      const char* aMsg, ...)
+void
+nsChromeRegistry::LogMessageWithContext(nsIURI* aURL, PRUint32 aLineNumber, PRUint32 flags,
+                                        const char* aMsg, ...)
 {
   nsresult rv;
 
   nsCOMPtr<nsIConsoleService> console 
     (do_GetService(NS_CONSOLESERVICE_CONTRACTID));
 
   nsCOMPtr<nsIScriptError> error
     (do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
@@ -179,252 +130,18 @@ LogMessageWithContext(nsIURI* aURL, PRUi
   PR_smprintf_free(formatted);
 
   if (NS_FAILED(rv))
     return;
 
   console->LogMessage(error);
 }
 
-// We use a "best-fit" algorithm for matching locales and themes. 
-// 1) the exact selected locale/theme
-// 2) (locales only) same language, different country
-//    e.g. en-GB is the selected locale, only en-US is available
-// 3) any available locale/theme
-
-/**
- * Match the language-part of two lang-COUNTRY codes, hopefully but
- * not guaranteed to be in the form ab-CD or abz-CD. "ab" should also
- * work, any other garbage-in will produce undefined results as long
- * as it does not crash.
- */
-static PRBool
-LanguagesMatch(const nsACString& a, const nsACString& b)
-{
-  if (a.Length() < 2 || b.Length() < 2)
-    return PR_FALSE;
-
-  nsACString::const_iterator as, ae, bs, be;
-  a.BeginReading(as);
-  a.EndReading(ae);
-  b.BeginReading(bs);
-  b.EndReading(be);
-
-  while (*as == *bs) {
-    if (*as == '-')
-      return PR_TRUE;
- 
-    ++as; ++bs;
-
-    // reached the end
-    if (as == ae && bs == be)
-      return PR_TRUE;
-
-    // "a" is short
-    if (as == ae)
-      return (*bs == '-');
-
-    // "b" is short
-    if (bs == be)
-      return (*as == '-');
-  }
-
-  return PR_FALSE;
-}
-
-static PRBool
-CanLoadResource(nsIURI* aResourceURI)
-{
-  PRBool isLocalResource = PR_FALSE;
-  (void)NS_URIChainHasFlags(aResourceURI,
-                            nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
-                            &isLocalResource);
-  return isLocalResource;
-}
-
-nsChromeRegistry::ProviderEntry*
-nsChromeRegistry::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
-{
-  PRInt32 i = mArray.Count();
-  if (!i)
-    return nsnull;
-
-  ProviderEntry* found = nsnull;  // Only set if we find a partial-match locale
-  ProviderEntry* entry;
-
-  while (i--) {
-    entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
-    if (aPreferred.Equals(entry->provider))
-      return entry;
-
-    if (aType != LOCALE)
-      continue;
-
-    if (LanguagesMatch(aPreferred, entry->provider)) {
-      found = entry;
-      continue;
-    }
-
-    if (!found && entry->provider.EqualsLiteral("en-US"))
-      found = entry;
-  }
-
-  if (!found && aType != EXACT)
-    return entry;
-
-  return found;
-}
-
-nsIURI*
-nsChromeRegistry::nsProviderArray::GetBase(const nsACString& aPreferred, MatchType aType)
-{
-  ProviderEntry* provider = GetProvider(aPreferred, aType);
-
-  if (!provider)
-    return nsnull;
-
-  return provider->baseURI;
-}
-
-const nsACString&
-nsChromeRegistry::nsProviderArray::GetSelected(const nsACString& aPreferred, MatchType aType)
-{
-  ProviderEntry* entry = GetProvider(aPreferred, aType);
-
-  if (entry)
-    return entry->provider;
-
-  return EmptyCString();
-}
-
-void
-nsChromeRegistry::nsProviderArray::SetBase(const nsACString& aProvider, nsIURI* aBaseURL)
-{
-  ProviderEntry* provider = GetProvider(aProvider, EXACT);
-
-  if (provider) {
-    provider->baseURI = aBaseURL;
-    return;
-  }
-
-  // no existing entries, add a new one
-  provider = new ProviderEntry(aProvider, aBaseURL);
-  if (!provider)
-    return; // It's safe to silently fail on OOM
-
-  mArray.AppendElement(provider);
-}
-
-void
-nsChromeRegistry::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
-{
-  PRInt32 i = mArray.Count();
-  while (i--) {
-    ProviderEntry *entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
-    a->AppendElement(entry->provider);
-  }
-}
-
-void
-nsChromeRegistry::nsProviderArray::Clear()
-{
-  PRInt32 i = mArray.Count();
-  while (i--) {
-    ProviderEntry* entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
-    delete entry;
-  }
-
-  mArray.Clear();
-}
-
-nsChromeRegistry::PackageEntry::PackageEntry(const nsACString& aPackage) :
-  package(aPackage), flags(0)
-{
-}
-
-PLHashNumber
-nsChromeRegistry::HashKey(PLDHashTable *table, const void *key)
-{
-  const nsACString& str = *reinterpret_cast<const nsACString*>(key);
-  return HashString(str);
-}
-
-PRBool
-nsChromeRegistry::MatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
-                           const void *key)
-{
-  const nsACString& str = *reinterpret_cast<const nsACString*>(key);
-  const PackageEntry* pentry = static_cast<const PackageEntry*>(entry);
-  return str.Equals(pentry->package);
-}
-
-void
-nsChromeRegistry::ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
-{
-  PackageEntry* pentry = static_cast<PackageEntry*>(entry);
-  pentry->~PackageEntry();
-}
-
-PRBool
-nsChromeRegistry::InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
-                            const void *key)
-{
-  const nsACString& str = *reinterpret_cast<const nsACString*>(key);
-
-  new (entry) PackageEntry(str);
-  return PR_TRUE;
-}
-
-const PLDHashTableOps
-nsChromeRegistry::kTableOps = {
-  PL_DHashAllocTable,
-  PL_DHashFreeTable,
-  HashKey,
-  MatchKey,
-  PL_DHashMoveEntryStub,
-  ClearEntry,
-  PL_DHashFinalizeStub,
-  InitEntry
-};
-
-void
-nsChromeRegistry::OverlayListEntry::AddURI(nsIURI* aURI)
-{
-  PRInt32 i = mArray.Count();
-  while (i--) {
-    PRBool equals;
-    if (NS_SUCCEEDED(aURI->Equals(mArray[i], &equals)) && equals)
-        return;
-  }
-
-  mArray.AppendObject(aURI);
-}
-
-void
-nsChromeRegistry::OverlayListHash::Add(nsIURI* aBase, nsIURI* aOverlay)
-{
-  OverlayListEntry* entry = mTable.PutEntry(aBase);
-  if (entry)
-    entry->AddURI(aOverlay);
-}
-
-const nsCOMArray<nsIURI>*
-nsChromeRegistry::OverlayListHash::GetArray(nsIURI* aBase)
-{
-  OverlayListEntry* entry = mTable.GetEntry(aBase);
-  if (!entry)
-    return nsnull;
-
-  return &entry->mArray;
-}
-
 nsChromeRegistry::~nsChromeRegistry()
 {
-  if (mPackagesHash.ops)
-    PL_DHashTableFinish(&mPackagesHash);
   gChromeRegistry = nsnull;
 }
 
 NS_INTERFACE_MAP_BEGIN(nsChromeRegistry)
   NS_INTERFACE_MAP_ENTRY(nsIChromeRegistry)
   NS_INTERFACE_MAP_ENTRY(nsIXULChromeRegistry)
   NS_INTERFACE_MAP_ENTRY(nsIToolkitChromeRegistry)
 #ifdef MOZ_XUL
@@ -436,135 +153,56 @@ NS_INTERFACE_MAP_BEGIN(nsChromeRegistry)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsChromeRegistry)
 NS_IMPL_RELEASE(nsChromeRegistry)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChromeRegistry methods:
 
-static nsresult
-getUILangCountry(nsACString& aUILang)
+already_AddRefed<nsIChromeRegistry>
+nsChromeRegistry::GetService()
 {
-  nsresult rv;
-
-  nsCOMPtr<nsILocaleService> localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString uiLang;
-  rv = localeService->GetLocaleComponentForUserAgent(uiLang);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  CopyUTF16toUTF8(uiLang, aUILang);
-  return NS_OK;
+  if (!nsChromeRegistry::gChromeRegistry)
+  {
+    // We don't actually want this ref, we just want the service to
+    // initialize if it hasn't already.
+    nsCOMPtr<nsIChromeRegistry> reg(
+        do_GetService(NS_CHROMEREGISTRY_CONTRACTID));
+    if (!gChromeRegistry)
+      return NULL;
+  }
+  NS_IF_ADDREF(gChromeRegistry);
+  return gChromeRegistry;
 }
 
 nsresult
 nsChromeRegistry::Init()
 {
-  nsresult rv;
-
   // Check to see if necko and the JAR protocol handler are registered yet
   // if not, somebody is doing work during XPCOM registration that they
   // shouldn't be doing. See bug 292549, where JS components are trying
   // to call Components.utils.import("chrome:///") early in registration
   NS_ASSERTION(nsCOMPtr<nsIIOService>(mozilla::services::GetIOService()),
                "I/O service not registered or available early enough?");
 
-  if (!PL_DHashTableInit(&mPackagesHash, &kTableOps,
-                         nsnull, sizeof(PackageEntry), 16))
+  if (!mOverrideTable.Init())
     return NS_ERROR_FAILURE;
 
-  if (!mOverlayHash.Init() ||
-      !mStyleHash.Init() ||
-      !mOverrideTable.Init())
-    return NS_ERROR_FAILURE;
-
-  mSelectedLocale = NS_LITERAL_CSTRING("en-US");
-  mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0");
-
   // This initialization process is fairly complicated and may cause reentrant
   // getservice calls to resolve chrome URIs (especially locale files). We
   // don't want that, so we inform the protocol handler about our existence
   // before we are actually fully initialized.
   gChromeRegistry = this;
 
-  PRBool safeMode = PR_FALSE;
-  nsCOMPtr<nsIXULRuntime> xulrun (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
-  if (xulrun)
-    xulrun->GetInSafeMode(&safeMode);
-  
-  nsCOMPtr<nsIPrefService> prefserv (do_GetService(NS_PREFSERVICE_CONTRACTID));
-  nsCOMPtr<nsIPrefBranch> prefs;
-
-  if (safeMode)
-    prefserv->GetDefaultBranch(nsnull, getter_AddRefs(prefs));
-  else
-    prefs = do_QueryInterface(prefserv);
-
-  if (!prefs) {
-    NS_WARNING("Could not get pref service!");
-  }
-  else {
-    nsXPIDLCString provider;
-    rv = prefs->GetCharPref(SELECTED_SKIN_PREF, getter_Copies(provider));
-    if (NS_SUCCEEDED(rv))
-      mSelectedSkin = provider;
-
-    SelectLocaleFromPref(prefs);
-
-    nsCOMPtr<nsIPrefBranch2> prefs2 (do_QueryInterface(prefs));
-    if (prefs2) {
-      rv = prefs2->AddObserver(MATCH_OS_LOCALE_PREF, this, PR_TRUE);
-      rv = prefs2->AddObserver(SELECTED_LOCALE_PREF, this, PR_TRUE);
-      rv = prefs2->AddObserver(SELECTED_SKIN_PREF, this, PR_TRUE);
-    }
-  }
-
-  nsCOMPtr<nsIObserverService> obsService =
-    mozilla::services::GetObserverService();
-  if (obsService) {
-    obsService->AddObserver(this, "command-line-startup", PR_TRUE);
-    obsService->AddObserver(this, "profile-initial-state", PR_TRUE);
-  }
-
   mInitialized = PR_TRUE;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsChromeRegistry::CheckForOSAccessibility()
-{
-  nsresult rv;
-
-  nsCOMPtr<nsILookAndFeel> lookAndFeel (do_GetService(kLookAndFeelCID));
-  if (lookAndFeel) {
-    PRInt32 useAccessibilityTheme = 0;
-
-    rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_UseAccessibilityTheme,
-                                useAccessibilityTheme);
-
-    if (NS_SUCCEEDED(rv) && useAccessibilityTheme) {
-      /* Set the skin to classic and remove pref observers */
-      if (!mSelectedSkin.EqualsLiteral("classic/1.0")) {
-        mSelectedSkin.AssignLiteral("classic/1.0");
-        RefreshSkins();
-      }
-
-      nsCOMPtr<nsIPrefBranch2> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
-      if (prefs) {
-        prefs->RemoveObserver(SELECTED_SKIN_PREF, this);
-      }
-    }
-  }
-
-  return NS_OK;
-}
-
 nsresult
 nsChromeRegistry::GetProviderAndPath(nsIURL* aChromeURL,
                                      nsACString& aProvider, nsACString& aPath)
 {
   nsresult rv;
 
 #ifdef DEBUG
   PRBool isChrome;
@@ -686,157 +324,44 @@ nsChromeRegistry::ConvertChromeURL(nsIUR
 
   nsCAutoString package, provider, path;
   rv = chromeURL->GetHostPort(package);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = GetProviderAndPath(chromeURL, provider, path);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PackageEntry* entry =
-    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
-                                                    & (nsACString&) package,
-                                                    PL_DHASH_LOOKUP));
+  nsIURI* baseURI;
+  rv = GetBaseURIFromPackage(package, provider, path, &baseURI);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  if (PL_DHASH_ENTRY_IS_FREE(entry)) {
-    if (!mInitialized)
-      return NS_ERROR_NOT_INITIALIZED;
+  PRUint32 flags;
+  rv = GetFlagsFromPackage(package, &flags);
+  if (NS_FAILED(rv))
+    return rv;
 
-    LogMessage("No chrome package registered for chrome://%s/%s/%s",
-               package.get(), provider.get(), path.get());
-
-    return NS_ERROR_FAILURE;
-  }
-
-  if (entry->flags & PackageEntry::PLATFORM_PACKAGE) {
+  if (flags & PLATFORM_PACKAGE) {
 #if defined(XP_WIN) || defined(XP_OS2)
     path.Insert("win/", 0);
 #elif defined(XP_MACOSX)
     path.Insert("mac/", 0);
 #else
     path.Insert("unix/", 0);
 #endif
   }
 
-  nsIURI* baseURI = nsnull;
-  if (provider.EqualsLiteral("locale")) {
-    baseURI = entry->locales.GetBase(mSelectedLocale, nsProviderArray::LOCALE);
-  }
-  else if (provider.EqualsLiteral("skin")) {
-    baseURI = entry->skins.GetBase(mSelectedSkin, nsProviderArray::ANY);
-  }
-  else if (provider.EqualsLiteral("content")) {
-    baseURI = entry->baseURI;
-  }
-
   if (!baseURI) {
     LogMessage("No chrome package registered for chrome://%s/%s/%s",
                package.get(), provider.get(), path.get());
     return NS_ERROR_FAILURE;
   }
 
   return NS_NewURI(aResult, path, nsnull, baseURI);
 }
 
-nsresult
-nsChromeRegistry::GetSelectedLocale(const nsACString& aPackage, nsACString& aLocale)
-{
-  PackageEntry* entry =
-    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
-                                                       & aPackage,
-                                                       PL_DHASH_LOOKUP));
-
-  if (PL_DHASH_ENTRY_IS_FREE(entry))
-    return NS_ERROR_FAILURE;
-
-  aLocale = entry->locales.GetSelected(mSelectedLocale, nsProviderArray::LOCALE);
-  if (aLocale.IsEmpty())
-    return NS_ERROR_FAILURE;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsChromeRegistry::IsLocaleRTL(const nsACString& package, PRBool *aResult)
-{
-  *aResult = PR_FALSE;
-
-  nsCAutoString locale;
-  GetSelectedLocale(package, locale);
-  if (locale.Length() < 2)
-    return NS_OK;
-
-  // first check the intl.uidirection.<locale> preference, and if that is not
-  // set, check the same preference but with just the first two characters of
-  // the locale. If that isn't set, default to left-to-right.
-  nsCAutoString prefString = NS_LITERAL_CSTRING("intl.uidirection.") + locale;
-  nsCOMPtr<nsIPrefBranch> prefBranch (do_GetService(NS_PREFSERVICE_CONTRACTID));
-  if (!prefBranch)
-    return NS_OK;
-  
-  nsXPIDLCString dir;
-  prefBranch->GetCharPref(prefString.get(), getter_Copies(dir));
-  if (dir.IsEmpty()) {
-    PRInt32 hyphen = prefString.FindChar('-');
-    if (hyphen >= 1) {
-      nsCAutoString shortPref(Substring(prefString, 0, hyphen));
-      prefBranch->GetCharPref(shortPref.get(), getter_Copies(dir));
-    }
-  }
-  *aResult = dir.EqualsLiteral("rtl");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsChromeRegistry::GetLocalesForPackage(const nsACString& aPackage,
-                                       nsIUTF8StringEnumerator* *aResult)
-{
-  nsTArray<nsCString> *a = new nsTArray<nsCString>;
-  if (!a)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  PackageEntry* entry =
-    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
-                                                       & aPackage,
-                                                       PL_DHASH_LOOKUP));
-
-  if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
-    entry->locales.EnumerateToArray(a);
-  }
-
-  nsresult rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
-  if (NS_FAILED(rv))
-    delete a;
-
-  return rv;
-}
-
-#ifdef MOZ_XUL
-NS_IMETHODIMP
-nsChromeRegistry::GetStyleOverlays(nsIURI *aChromeURL,
-                                   nsISimpleEnumerator **aResult)
-{
-  const nsCOMArray<nsIURI>* parray = mStyleHash.GetArray(aChromeURL);
-  if (!parray)
-    return NS_NewEmptyEnumerator(aResult);
-
-  return NS_NewArrayEnumerator(aResult, *parray);
-}
-
-NS_IMETHODIMP
-nsChromeRegistry::GetXULOverlays(nsIURI *aChromeURL, nsISimpleEnumerator **aResult)
-{
-  const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(aChromeURL);
-  if (!parray)
-    return NS_NewEmptyEnumerator(aResult);
-
-  return NS_NewArrayEnumerator(aResult, *parray);
-}
-#endif // MOZ_XUL
-
 ////////////////////////////////////////////////////////////////////////
 
 // theme stuff
 
 
 static void FlushSkinBindingsForWindow(nsIDOMWindowInternal* aWindow)
 {
   // Get the DOM document.
@@ -1115,84 +640,22 @@ nsChromeRegistry::AllowContentToAccess(n
     NS_ERROR("Chrome URL doesn't implement nsIURL.");
     return NS_ERROR_UNEXPECTED;
   }
 
   nsCAutoString package;
   rv = url->GetHostPort(package);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PackageEntry *entry =
-    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
-                                                    & (nsACString&) package,
-                                                    PL_DHASH_LOOKUP));
-
-  if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
-    *aResult = !!(entry->flags & PackageEntry::CONTENT_ACCESSIBLE);
-  }
-  return NS_OK;
-}
-
-static PLDHashOperator
-RemoveAll(PLDHashTable *table, PLDHashEntryHdr *entry, PRUint32 number, void *arg)
-{
-  return (PLDHashOperator) (PL_DHASH_NEXT | PL_DHASH_REMOVE);
-}
-
-#ifdef MOZ_OMNIJAR
-nsresult
-nsChromeRegistry::CheckOmnijarChrome()
-{
-  nsresult rv;
-
-  nsZipArchive* jarReader = mozilla::OmnijarReader();
-  // just proceed normally if there is no omnijar
-  if (!jarReader)
-    return NS_OK;
-
-  nsZipItem* manifest = jarReader->GetItem("chrome/chrome.manifest");
-  NS_ENSURE_TRUE(manifest, NS_ERROR_NOT_AVAILABLE);
+  PRUint32 flags;
+  rv = GetFlagsFromPackage(package, &flags);
 
-  nsCAutoString omniJarSpec;
-  rv = NS_GetURLSpecFromActualFile(mozilla::OmnijarPath(), omniJarSpec);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  PRUint32 len = manifest->RealSize();
-  nsAutoArrayPtr<PRUint8> outbuf(new PRUint8[len]);
-  NS_ENSURE_TRUE(outbuf, NS_ERROR_OUT_OF_MEMORY);
-
-  nsZipCursor cursor(manifest, jarReader, outbuf, len);
-  PRUint32 readlen;
-  PRUint8* buf = cursor.Read(&readlen);
-  NS_ENSURE_TRUE(buf, NS_ERROR_FILE_CORRUPTED);
-
-  nsAutoString jarString(NS_LITERAL_STRING("jar:"));
-  AppendUTF8toUTF16(omniJarSpec, jarString);
-  jarString += NS_LITERAL_STRING("!/chrome/chrome.manifest"); 
-
-  nsCOMPtr<nsIURI> manifestURI;
-  rv = NS_NewURI(getter_AddRefs(manifestURI), jarString);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = ProcessManifestBuffer((char *)buf, readlen, manifestURI, PR_FALSE);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return rv;
-}
-#endif /* MOZ_OMNIJAR */
-
-NS_IMETHODIMP
-nsChromeRegistry::CheckForNewChrome()
-{
-  PL_DHashTableEnumerate(&mPackagesHash, RemoveAll, nsnull);
-  mOverlayHash.Clear();
-  mStyleHash.Clear();
-  mOverrideTable.Clear();
-
-  nsComponentManagerImpl::gComponentManager->RereadChromeManifests();
+  if (NS_SUCCEEDED(rv)) {
+    *aResult = !!(flags & CONTENT_ACCESSIBLE);
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP_(PRBool)
 nsChromeRegistry::WrappersEnabled(nsIURI *aURI)
 {
   nsCOMPtr<nsIURL> chromeURL (do_QueryInterface(aURI));
   if (!chromeURL)
@@ -1203,377 +666,34 @@ nsChromeRegistry::WrappersEnabled(nsIURI
   if (NS_FAILED(rv) || !isChrome)
     return PR_FALSE;
 
   nsCAutoString package;
   rv = chromeURL->GetHostPort(package);
   if (NS_FAILED(rv))
     return PR_FALSE;
 
-  PackageEntry* entry =
-    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
-                                                    & (nsACString&) package,
-                                                    PL_DHASH_LOOKUP));
-
-  return PL_DHASH_ENTRY_IS_LIVE(entry);
-}
-
-nsresult
-nsChromeRegistry::SelectLocaleFromPref(nsIPrefBranch* prefs)
-{
-  nsresult rv;
-  PRBool matchOSLocale = PR_FALSE, userLocaleOverride = PR_FALSE;
-  prefs->PrefHasUserValue(SELECTED_LOCALE_PREF, &userLocaleOverride);
-  rv = prefs->GetBoolPref(MATCH_OS_LOCALE_PREF, &matchOSLocale);
-
-  if (NS_SUCCEEDED(rv) && matchOSLocale && !userLocaleOverride) {
-    // compute lang and region code only when needed!
-    nsCAutoString uiLocale;
-    rv = getUILangCountry(uiLocale);
-    if (NS_SUCCEEDED(rv))
-      mSelectedLocale = uiLocale;
-  }
-  else {
-    nsXPIDLCString provider;
-    rv = prefs->GetCharPref(SELECTED_LOCALE_PREF, getter_Copies(provider));
-    if (NS_SUCCEEDED(rv)) {
-      mSelectedLocale = provider;
-    }
-  }
-
-  return rv;
-}
-
-NS_IMETHODIMP nsChromeRegistry::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
-{
-  nsresult rv = NS_OK;
-
-  if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
-    nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
-    NS_ASSERTION(prefs, "Bad observer call!");
-
-    NS_ConvertUTF16toUTF8 pref(someData);
-
-    if (pref.EqualsLiteral(MATCH_OS_LOCALE_PREF) ||
-        pref.EqualsLiteral(SELECTED_LOCALE_PREF)) {
-      rv = SelectLocaleFromPref(prefs);
-      if (NS_SUCCEEDED(rv) && mProfileLoaded)
-        FlushAllCaches();
-    }
-    else if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
-      nsXPIDLCString provider;
-      rv = prefs->GetCharPref(pref.get(), getter_Copies(provider));
-      if (NS_FAILED(rv)) {
-        NS_ERROR("Couldn't get new locale pref!");
-        return rv;
-      }
-
-      mSelectedSkin = provider;
-      RefreshSkins();
-    } else {
-      NS_ERROR("Unexpected pref!");
-    }
-  }
-  else if (!strcmp("command-line-startup", aTopic)) {
-    nsCOMPtr<nsICommandLine> cmdLine (do_QueryInterface(aSubject));
-    if (cmdLine) {
-      nsAutoString uiLocale;
-      rv = cmdLine->HandleFlagWithParam(NS_LITERAL_STRING(UILOCALE_CMD_LINE_ARG),
-                                        PR_FALSE, uiLocale);
-      if (NS_SUCCEEDED(rv) && !uiLocale.IsEmpty()) {
-        CopyUTF16toUTF8(uiLocale, mSelectedLocale);
-        nsCOMPtr<nsIPrefBranch2> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
-        if (prefs) {
-          prefs->RemoveObserver(SELECTED_LOCALE_PREF, this);
-        }
-      }
-    }
-  }
-  else if (!strcmp("profile-initial-state", aTopic)) {
-    mProfileLoaded = PR_TRUE;
-  }
-  else {
-    NS_ERROR("Unexpected observer topic!");
-  }
-
-  return rv;
-}
-
-nsIURI*
-nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
-{
-  if (!mManifestURI) {
-    nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
-    if (!io) {
-      NS_WARNING("No IO service trying to process chrome manifests");
-      return NULL;
-    }
-
-    io->NewFileURI(mFile, getter_AddRefs(mManifestURI));
-  }
-  return mManifestURI;
-}
-
-nsIXPConnect*
-nsChromeRegistry::ManifestProcessingContext::GetXPConnect()
-{
-  if (!mXPConnect)
-    mXPConnect = do_GetService("@mozilla.org/js/xpc/XPConnect;1");
-
-  return mXPConnect;
-}
-
-already_AddRefed<nsIURI>
-nsChromeRegistry::ManifestProcessingContext::ResolveURI(const char* uri)
-{
-  nsIURI* baseuri = GetManifestURI();
-  if (!baseuri)
-    return NULL;
-
-  nsCOMPtr<nsIURI> resolved;
-  nsresult rv = NS_NewURI(getter_AddRefs(resolved), uri, baseuri);
-  if (NS_FAILED(rv))
-    return NULL;
-
-  return resolved.forget();
-}
-
-static void
-EnsureLowerCase(char *aBuf)
-{
-  for (; *aBuf; ++aBuf) {
-    char ch = *aBuf;
-    if (ch >= 'A' && ch <= 'Z')
-      *aBuf = ch + 'a' - 'A';
-  }
-}
-
-void
-nsChromeRegistry::ManifestContent(ManifestProcessingContext& cx, int lineno,
-                                  char *const * argv, bool platform, bool contentaccessible)
-{
-  char* package = argv[0];
-  char* uri = argv[1];
-
-  EnsureLowerCase(package);
-
-  nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
-  if (!resolved) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, unable to create URI '%s'.", uri);
-    return;
-  }
-
-  if (!CanLoadResource(resolved)) {
-    LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, cannot register non-local URI '%s' as content.",
-                          uri);
-    return;
-  }
-
-  PackageEntry* entry =
-    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
-                                                    & (const nsACString&) nsDependentCString(package),
-                                                    PL_DHASH_ADD));
-  if (!entry)
-    return;
-
-  entry->baseURI = resolved;
-
-  if (platform)
-    entry->flags |= PackageEntry::PLATFORM_PACKAGE;
-  if (contentaccessible)
-    entry->flags |= PackageEntry::CONTENT_ACCESSIBLE;
-  if (cx.GetXPConnect()) {
-    nsCAutoString urlp("chrome://");
-    urlp.Append(package);
-    urlp.Append('/');
-
-    cx.GetXPConnect()->FlagSystemFilenamePrefix(urlp.get(), true);
-  }
+  PRUint32 flags;
+  rv = GetFlagsFromPackage(package, &flags);
+  return NS_SUCCEEDED(rv) && (flags & XPCNATIVEWRAPPERS);
 }
 
-void
-nsChromeRegistry::ManifestLocale(ManifestProcessingContext& cx, int lineno,
-                                 char *const * argv, bool platform, bool contentaccessible)
-{
-  char* package = argv[0];
-  char* provider = argv[1];
-  char* uri = argv[2];
-
-  EnsureLowerCase(package);
-
-  nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
-  if (!resolved) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, unable to create URI '%s'.", uri);
-    return;
-  }
-
-  if (!CanLoadResource(resolved)) {
-    LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, cannot register non-local URI '%s' as content.",
-                          uri);
-    return;
-  }
-
-  PackageEntry* entry =
-    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
-                                                    & (const nsACString&) nsDependentCString(package),
-                                                    PL_DHASH_ADD));
-  if (!entry)
-    return;
-
-  entry->locales.SetBase(nsDependentCString(provider), resolved);
-}
-
-void
-nsChromeRegistry::ManifestSkin(ManifestProcessingContext& cx, int lineno,
-                               char *const * argv, bool platform, bool contentaccessible)
+already_AddRefed<nsChromeRegistry>
+nsChromeRegistry::GetSingleton()
 {
-  char* package = argv[0];
-  char* provider = argv[1];
-  char* uri = argv[2];
-
-  EnsureLowerCase(package);
-
-  nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
-  if (!resolved) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, unable to create URI '%s'.", uri);
-    return;
-  }
-
-  if (!CanLoadResource(resolved)) {
-    LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, cannot register non-local URI '%s' as content.",
-                          uri);
-    return;
-  }
-
-  PackageEntry* entry =
-    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
-                                                    & (const nsACString&) nsDependentCString(package),
-                                                    PL_DHASH_ADD));
-  if (!entry)
-    return;
-
-  entry->skins.SetBase(nsDependentCString(provider), resolved);
-}
-
-void
-nsChromeRegistry::ManifestOverlay(ManifestProcessingContext& cx, int lineno,
-                                  char *const * argv, bool platform, bool contentaccessible)
-{
-  char* base = argv[0];
-  char* overlay = argv[1];
-
-  nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
-  nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
-  if (!baseuri || !overlayuri) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, unable to create URI.");
-    return;
-  }
-
-  if (!CanLoadResource(overlayuri)) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "Cannot register non-local URI '%s' as an overlay.", overlay);
-    return;
+  if (gChromeRegistry) {
+    NS_ADDREF(gChromeRegistry);
+    return gChromeRegistry;
   }
 
-  mOverlayHash.Add(baseuri, overlayuri);
-}
-
-void
-nsChromeRegistry::ManifestStyle(ManifestProcessingContext& cx, int lineno,
-                                char *const * argv, bool platform, bool contentaccessible)
-{
-  char* base = argv[0];
-  char* overlay = argv[1];
-
-  nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
-  nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
-  if (!baseuri || !overlayuri) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, unable to create URI.");
-    return;
-  }
-
-  if (!CanLoadResource(overlayuri)) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "Cannot register non-local URI '%s' as a style overlay.", overlay);
-    return;
-  }
+  nsRefPtr<nsChromeRegistry> cr;
+#ifdef MOZ_IPC
+  if (GeckoProcessType_Content == XRE_GetProcessType())
+    cr = new nsChromeRegistryContent();
+  else
+#endif
+    cr = new nsChromeRegistryChrome();
 
-  mStyleHash.Add(baseuri, overlayuri);
-}
-
-void
-nsChromeRegistry::ManifestOverride(ManifestProcessingContext& cx, int lineno,
-                                   char *const * argv, bool platform, bool contentaccessible)
-{
-  char* chrome = argv[0];
-  char* resolved = argv[1];
+  if (NS_FAILED(cr->Init()))
+    return NULL;
 
-  nsCOMPtr<nsIURI> chromeuri = cx.ResolveURI(chrome);
-  nsCOMPtr<nsIURI> resolveduri = cx.ResolveURI(resolved);
-  if (!chromeuri || !resolveduri) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, unable to create URI.");
-    return;
-  }
-
-  if (!CanLoadResource(resolveduri)) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "Cannot register non-local URI '%s' for an override.", resolved);
-    return;
-  }
-  mOverrideTable.Put(chromeuri, resolveduri);
+  return cr.forget();
 }
-
-void
-nsChromeRegistry::ManifestResource(ManifestProcessingContext& cx, int lineno,
-                                   char *const * argv, bool platform, bool contentaccessible)
-{
-  char* package = argv[0];
-  char* uri = argv[1];
-
-  EnsureLowerCase(package);
-  nsDependentCString host(package);
-
-  nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
-  if (!io) {
-    NS_WARNING("No IO service trying to process chrome manifests");
-    return;
-  }
-
-  nsCOMPtr<nsIProtocolHandler> ph;
-  nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
-  if (NS_FAILED(rv))
-    return;
-  
-  nsCOMPtr<nsIResProtocolHandler> rph = do_QueryInterface(ph);
-
-  PRBool exists = PR_FALSE;
-  rv = rph->HasSubstitution(host, &exists);
-  if (exists) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "Duplicate resource declaration for '%s' ignored.", package);
-    return;
-  }
-
-  nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
-  if (!resolved) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "During chrome registration, unable to create URI '%s'.", uri);
-    return;
-  }
-
-  if (!CanLoadResource(resolved)) {
-    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
-                          "Warning: cannot register non-local URI '%s' as a resource.",
-                          uri);
-    return;
-  }
-
-  rph->SetSubstitution(host, resolved);
-}
--- a/chrome/src/nsChromeRegistry.h
+++ b/chrome/src/nsChromeRegistry.h
@@ -32,107 +32,111 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#ifndef nsChromeRegistry_h
+#define nsChromeRegistry_h
+
 #include "nsIChromeRegistry.h"
 #include "nsIToolkitChromeRegistry.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
+#include "nsIPrefBranch.h"
 
 #ifdef MOZ_XUL
 #include "nsIXULOverlayProvider.h"
 #endif
 
 #include "pldhash.h"
 
 #include "nsCOMArray.h"
 #include "nsString.h"
 #include "nsTHashtable.h"
 #include "nsURIHashKey.h"
-#include "nsVoidArray.h"
-#include "nsTArray.h"
 #include "nsInterfaceHashtable.h"
 #include "nsXULAppAPI.h"
 #include "nsIResProtocolHandler.h"
 #include "nsIXPConnect.h"
 
-struct PRFileDesc;
-class nsIAtom;
 class nsIDOMWindowInternal;
-class nsILocalFile;
-class nsIPrefBranch;
-class nsIRDFDataSource;
-class nsIRDFResource;
-class nsIRDFService;
-class nsISimpleEnumerator;
 class nsIURL;
 
+// The chrome registry is actually split between nsChromeRegistryChrome and
+// nsChromeRegistryContent. The work/data that is common to both resides in
+// the shared nsChromeRegistry implementation, with operations that only make
+// sense for one side erroring out in the other.
+
 // for component registration
 // {47049e42-1d87-482a-984d-56ae185e367a}
 #define NS_CHROMEREGISTRY_CID \
 { 0x47049e42, 0x1d87, 0x482a, { 0x98, 0x4d, 0x56, 0xae, 0x18, 0x5e, 0x36, 0x7a } }
 
 class nsChromeRegistry : public nsIToolkitChromeRegistry,
 #ifdef MOZ_XUL
                          public nsIXULOverlayProvider,
 #endif
                          public nsIObserver,
                          public nsSupportsWeakReference
 {
 public:
   NS_DECL_ISUPPORTS
 
-  // nsIChromeRegistry methods:
-  NS_DECL_NSICHROMEREGISTRY
-  NS_DECL_NSIXULCHROMEREGISTRY
-  NS_DECL_NSITOOLKITCHROMEREGISTRY
+  // nsIXULChromeRegistry methods:
+  NS_IMETHOD ReloadChrome();
+  NS_IMETHOD RefreshSkins();
+  NS_IMETHOD AllowScriptsForPackage(nsIURI* url,
+                                    PRBool* _retval NS_OUTPARAM);
+  NS_IMETHOD AllowContentToAccess(nsIURI* url,
+                                  PRBool* _retval NS_OUTPARAM);
 
-#ifdef MOZ_XUL
-  NS_DECL_NSIXULOVERLAYPROVIDER
-#endif
-
-  NS_DECL_NSIOBSERVER
+  // nsIChromeRegistry methods:
+  NS_IMETHOD_(PRBool) WrappersEnabled(nsIURI *aURI);
+  NS_IMETHOD ConvertChromeURL(nsIURI* aChromeURI, nsIURI* *aResult);
 
   // nsChromeRegistry methods:
-  nsChromeRegistry() : mInitialized(PR_FALSE), mProfileLoaded(PR_FALSE) {
-    mPackagesHash.ops = nsnull;
-  }
-  ~nsChromeRegistry();
+  nsChromeRegistry() : mInitialized(PR_FALSE) { }
+  virtual ~nsChromeRegistry();
 
-  nsresult Init();
+  virtual nsresult Init();
+
+  static already_AddRefed<nsIChromeRegistry> GetService();
 
   static nsChromeRegistry* gChromeRegistry;
 
   static nsresult Canonify(nsIURL* aChromeURL);
 
 protected:
-  nsresult GetDynamicInfo(nsIURI *aChromeURL, PRBool aIsOverlay, nsISimpleEnumerator **aResult);
-
-  nsresult LoadInstallDataSource();
-  nsresult LoadProfileDataSource();
-
   void FlushSkinCaches();
   void FlushAllCaches();
 
-private:
+  static void LogMessage(const char* aMsg, ...);
+  static void LogMessageWithContext(nsIURI* aURL, PRUint32 aLineNumber, PRUint32 flags,
+                                    const char* aMsg, ...);
+
+  virtual nsresult GetBaseURIFromPackage(const nsCString& aPackage,
+                                         const nsCString& aProvider,
+                                         const nsCString& aPath,
+                                         nsIURI* *aResult) = 0;
+  virtual nsresult GetFlagsFromPackage(const nsCString& aPackage,
+                                       PRUint32* aFlags) = 0;
+
   nsresult SelectLocaleFromPref(nsIPrefBranch* prefs);
-#ifdef MOZ_OMNIJAR
-  nsresult CheckOmnijarChrome();
-#endif
 
   static nsresult RefreshWindow(nsIDOMWindowInternal* aWindow);
   static nsresult GetProviderAndPath(nsIURL* aChromeURL,
                                      nsACString& aProvider, nsACString& aPath);
 
 public:
+  static already_AddRefed<nsChromeRegistry> GetSingleton();
+
   struct ManifestProcessingContext
   {
     ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile)
       : mType(aType)
       , mFile(aFile)
     { }
     ~ManifestProcessingContext()
     { }
@@ -143,144 +147,52 @@ public:
     already_AddRefed<nsIURI> ResolveURI(const char* uri);
 
     NSLocationType mType;
     nsCOMPtr<nsILocalFile> mFile;
     nsCOMPtr<nsIURI> mManifestURI;
     nsCOMPtr<nsIXPConnect> mXPConnect;
   };
 
-  void ManifestContent(ManifestProcessingContext& cx, int lineno,
-                       char *const * argv, bool platform, bool contentaccessible);
-  void ManifestLocale(ManifestProcessingContext& cx, int lineno,
-                      char *const * argv, bool platform, bool contentaccessible);
-  void ManifestSkin(ManifestProcessingContext& cx, int lineno,
-                    char *const * argv, bool platform, bool contentaccessible);
-  void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
-                       char *const * argv, bool platform, bool contentaccessible);
-  void ManifestStyle(ManifestProcessingContext& cx, int lineno,
-                     char *const * argv, bool platform, bool contentaccessible);
-  void ManifestOverride(ManifestProcessingContext& cx, int lineno,
-                        char *const * argv, bool platform, bool contentaccessible);
-  void ManifestResource(ManifestProcessingContext& cx, int lineno,
-                        char *const * argv, bool platform, bool contentaccessible);
-
-public:
-  struct ProviderEntry
-  {
-    ProviderEntry(const nsACString& aProvider, nsIURI* aBase) :
-      provider(aProvider),
-      baseURI(aBase) { }
-
-    nsCString        provider;
-    nsCOMPtr<nsIURI> baseURI;
-  };
+  virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
+                               char *const * argv, bool platform,
+                               bool contentaccessible) = 0;
+  virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
+                              char *const * argv, bool platform,
+                              bool contentaccessible) = 0;
+  virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
+                            char *const * argv, bool platform,
+                            bool contentaccessible) = 0;
+  virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
+                               char *const * argv, bool platform,
+                               bool contentaccessible) = 0;
+  virtual void ManifestStyle(ManifestProcessingContext& cx, int lineno,
+                             char *const * argv, bool platform,
+                             bool contentaccessible) = 0;
+  virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
+                                char *const * argv, bool platform,
+                                bool contentaccessible) = 0;
+  virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
+                                char *const * argv, bool platform,
+                                bool contentaccessible) = 0;
 
-  class nsProviderArray
-  {
-  public:
-    nsProviderArray() :
-      mArray(1) { }
-    ~nsProviderArray()
-      { Clear(); }
+  // Available flags
+  enum {
+    // This is a "platform" package (e.g. chrome://global-platform/).
+    // Appends one of win/ unix/ mac/ to the base URI.
+    PLATFORM_PACKAGE = 1 << 0,
 
-    // When looking up locales and skins, the "selected" locale is not always
-    // available. This enum identifies what kind of match is desired/found.
-    enum MatchType {
-      EXACT = 0,
-      LOCALE = 1, // "en-GB" is selected, we found "en-US"
-      ANY = 2
-    };
+    // This package should use the new XPCNativeWrappers to separate
+    // content from chrome. This flag is currently unused (because we call
+    // into xpconnect at registration time).
+    XPCNATIVEWRAPPERS = 1 << 1,
 
-    nsIURI* GetBase(const nsACString& aPreferred, MatchType aType);
-    const nsACString& GetSelected(const nsACString& aPreferred, MatchType aType);
-    void    SetBase(const nsACString& aProvider, nsIURI* base);
-    void    EnumerateToArray(nsTArray<nsCString> *a);
-    void    Clear();
-
-  private:
-    ProviderEntry* GetProvider(const nsACString& aPreferred, MatchType aType);
-
-    nsVoidArray mArray;
+    // Content script may access files in this package
+    CONTENT_ACCESSIBLE = 1 << 2
   };
 
-  struct PackageEntry : public PLDHashEntryHdr
-  {
-    PackageEntry(const nsACString& package);
-    ~PackageEntry() { }
-
-    // Available flags
-    enum {
-      // This is a "platform" package (e.g. chrome://global-platform/).
-      // Appends one of win/ unix/ mac/ to the base URI.
-      PLATFORM_PACKAGE = 1 << 0,
-
-      // Content script may access files in this package
-      CONTENT_ACCESSIBLE = 1 << 1
-    };
-
-    nsCString        package;
-    nsCOMPtr<nsIURI> baseURI;
-    PRUint32         flags;
-    nsProviderArray  locales;
-    nsProviderArray  skins;
-  };
-
-private:
-  static PLDHashNumber HashKey(PLDHashTable *table, const void *key);
-  static PRBool        MatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
-                                const void *key);
-  static void          ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry);
-  static PRBool        InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
-                                 const void *key);
-
-  static const PLDHashTableOps kTableOps;
-
-public:
-  class OverlayListEntry : public nsURIHashKey
-  {
-  public:
-    typedef nsURIHashKey::KeyType        KeyType;
-    typedef nsURIHashKey::KeyTypePointer KeyTypePointer;
-
-    OverlayListEntry(KeyTypePointer aKey) : nsURIHashKey(aKey) { }
-    OverlayListEntry(OverlayListEntry& toCopy) : nsURIHashKey(toCopy),
-                                                 mArray(toCopy.mArray) { }
-    ~OverlayListEntry() { }
-
-    void AddURI(nsIURI* aURI);
-
-    nsCOMArray<nsIURI> mArray;
-  };
-
-  class OverlayListHash
-  {
-  public:
-    OverlayListHash() { }
-    ~OverlayListHash() { }
-
-    PRBool Init() { return mTable.Init(); }
-    void Add(nsIURI* aBase, nsIURI* aOverlay);
-    void Clear() { mTable.Clear(); }
-    const nsCOMArray<nsIURI>* GetArray(nsIURI* aBase);
-
-  private:
-    nsTHashtable<OverlayListEntry> mTable;
-  };
-
-private:
   PRBool mInitialized;
-  PRBool mProfileLoaded;
-
-  // Hash of package names ("global") to PackageEntry objects
-  PLDHashTable mPackagesHash;
-
-  // Hashes on the file to be overlaid (chrome://browser/content/browser.xul)
-  // to a list of overlays/stylesheets
-  OverlayListHash mOverlayHash;
-  OverlayListHash mStyleHash;
 
   // "Override" table (chrome URI string -> real URI)
   nsInterfaceHashtable<nsURIHashKey, nsIURI> mOverrideTable;
+};
 
-  nsCString mSelectedLocale;
-  nsCString mSelectedSkin;
-};
+#endif // nsChromeRegistry_h
new file mode 100644
--- /dev/null
+++ b/chrome/src/nsChromeRegistryChrome.cpp
@@ -0,0 +1,1109 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Josh Matthews <josh@joshmatthews.net> (Initial Developer)
+ *
+ * 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 ***** */
+
+#ifdef MOZ_IPC
+#include "mozilla/dom/PContentProcessParent.h"
+#include "RegistryMessageUtils.h"
+#include "nsResProtocolHandler.h"
+#endif
+
+#include "nsChromeRegistryChrome.h"
+
+#if defined(XP_WIN)
+#include <windows.h>
+#elif defined(XP_MACOSX)
+#include <CoreServices/CoreServices.h>
+#elif defined(MOZ_WIDGET_GTK2)
+#include <gtk/gtk.h>
+#endif
+
+#include "nsArrayEnumerator.h"
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsComponentManager.h"
+#include "nsEnumeratorUtils.h"
+#include "nsNetUtil.h"
+#include "nsStringEnumerator.h"
+#include "nsTextFormatter.h"
+#include "nsUnicharUtils.h"
+#include "nsWidgetsCID.h"
+#include "nsXPCOMCIDInternal.h"
+#include "nsZipArchive.h"
+
+#include "nsICommandLine.h"
+#include "nsILocaleService.h"
+#include "nsILocalFile.h"
+#include "nsILookAndFeel.h"
+#include "nsIObserverService.h"
+#include "nsIPrefBranch2.h"
+#include "nsIPrefService.h"
+#include "nsIResProtocolHandler.h"
+#include "nsIScriptError.h"
+#include "nsIVersionComparator.h"
+#include "nsIXPConnect.h"
+#include "nsIXULAppInfo.h"
+#include "nsIXULRuntime.h"
+
+#include "mozilla/Omnijar.h"
+
+#define UILOCALE_CMD_LINE_ARG "UILocale"
+
+#define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
+#define SELECTED_LOCALE_PREF "general.useragent.locale"
+#define SELECTED_SKIN_PREF   "general.skins.selectedSkin"
+
+static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
+
+static PLDHashOperator
+RemoveAll(PLDHashTable *table, PLDHashEntryHdr *entry, PRUint32 number, void *arg)
+{
+  return (PLDHashOperator) (PL_DHASH_NEXT | PL_DHASH_REMOVE);
+}
+
+// We use a "best-fit" algorithm for matching locales and themes. 
+// 1) the exact selected locale/theme
+// 2) (locales only) same language, different country
+//    e.g. en-GB is the selected locale, only en-US is available
+// 3) any available locale/theme
+
+/**
+ * Match the language-part of two lang-COUNTRY codes, hopefully but
+ * not guaranteed to be in the form ab-CD or abz-CD. "ab" should also
+ * work, any other garbage-in will produce undefined results as long
+ * as it does not crash.
+ */
+static PRBool
+LanguagesMatch(const nsACString& a, const nsACString& b)
+{
+  if (a.Length() < 2 || b.Length() < 2)
+    return PR_FALSE;
+
+  nsACString::const_iterator as, ae, bs, be;
+  a.BeginReading(as);
+  a.EndReading(ae);
+  b.BeginReading(bs);
+  b.EndReading(be);
+
+  while (*as == *bs) {
+    if (*as == '-')
+      return PR_TRUE;
+ 
+    ++as; ++bs;
+
+    // reached the end
+    if (as == ae && bs == be)
+      return PR_TRUE;
+
+    // "a" is short
+    if (as == ae)
+      return (*bs == '-');
+
+    // "b" is short
+    if (bs == be)
+      return (*as == '-');
+  }
+
+  return PR_FALSE;
+}
+
+nsChromeRegistryChrome::nsChromeRegistryChrome()
+  : mProfileLoaded(PR_FALSE)
+{
+  mPackagesHash.ops = nsnull;
+}
+
+nsChromeRegistryChrome::~nsChromeRegistryChrome()
+{
+  if (mPackagesHash.ops)
+    PL_DHashTableFinish(&mPackagesHash);
+}
+
+nsresult
+nsChromeRegistryChrome::Init()
+{
+  nsresult rv = nsChromeRegistry::Init();
+  if (NS_FAILED(rv))
+    return rv;
+
+  if (!mOverlayHash.Init() ||
+      !mStyleHash.Init())
+    return NS_ERROR_FAILURE;
+  
+  mSelectedLocale = NS_LITERAL_CSTRING("en-US");
+  mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0");
+
+  if (!PL_DHashTableInit(&mPackagesHash, &kTableOps,
+                         nsnull, sizeof(PackageEntry), 16))
+    return NS_ERROR_FAILURE;
+
+  PRBool safeMode = PR_FALSE;
+  nsCOMPtr<nsIXULRuntime> xulrun (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
+  if (xulrun)
+    xulrun->GetInSafeMode(&safeMode);
+  
+  nsCOMPtr<nsIPrefService> prefserv (do_GetService(NS_PREFSERVICE_CONTRACTID));
+  nsCOMPtr<nsIPrefBranch> prefs;
+
+  if (safeMode)
+    prefserv->GetDefaultBranch(nsnull, getter_AddRefs(prefs));
+  else
+    prefs = do_QueryInterface(prefserv);
+
+  if (!prefs) {
+    NS_WARNING("Could not get pref service!");
+  }
+  else {
+    nsXPIDLCString provider;
+    rv = prefs->GetCharPref(SELECTED_SKIN_PREF, getter_Copies(provider));
+    if (NS_SUCCEEDED(rv))
+      mSelectedSkin = provider;
+
+    SelectLocaleFromPref(prefs);
+
+    nsCOMPtr<nsIPrefBranch2> prefs2 (do_QueryInterface(prefs));
+    if (prefs2) {
+      rv = prefs2->AddObserver(MATCH_OS_LOCALE_PREF, this, PR_TRUE);
+      rv = prefs2->AddObserver(SELECTED_LOCALE_PREF, this, PR_TRUE);
+      rv = prefs2->AddObserver(SELECTED_SKIN_PREF, this, PR_TRUE);
+    }
+  }
+
+  nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
+  if (obsService) {
+    obsService->AddObserver(this, "command-line-startup", PR_TRUE);
+    obsService->AddObserver(this, "profile-initial-state", PR_TRUE);
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsChromeRegistryChrome::CheckForOSAccessibility()
+{
+  nsresult rv;
+
+  nsCOMPtr<nsILookAndFeel> lookAndFeel (do_GetService(kLookAndFeelCID));
+  if (lookAndFeel) {
+    PRInt32 useAccessibilityTheme = 0;
+
+    rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_UseAccessibilityTheme,
+                                useAccessibilityTheme);
+
+    if (NS_SUCCEEDED(rv) && useAccessibilityTheme) {
+      /* Set the skin to classic and remove pref observers */
+      if (!mSelectedSkin.EqualsLiteral("classic/1.0")) {
+        mSelectedSkin.AssignLiteral("classic/1.0");
+        RefreshSkins();
+      }
+
+      nsCOMPtr<nsIPrefBranch2> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
+      if (prefs) {
+        prefs->RemoveObserver(SELECTED_SKIN_PREF, this);
+      }
+    }
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsChromeRegistryChrome::GetLocalesForPackage(const nsACString& aPackage,
+                                       nsIUTF8StringEnumerator* *aResult)
+{
+  nsTArray<nsCString> *a = new nsTArray<nsCString>;
+  if (!a)
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  PackageEntry* entry =
+      static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
+                                                      & aPackage,
+                                                      PL_DHASH_LOOKUP));
+
+  if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
+    entry->locales.EnumerateToArray(a);
+  }
+
+  nsresult rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
+  if (NS_FAILED(rv))
+    delete a;
+
+  return rv;
+}
+
+static nsresult
+getUILangCountry(nsACString& aUILang)
+{
+  nsresult rv;
+
+  nsCOMPtr<nsILocaleService> localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoString uiLang;
+  rv = localeService->GetLocaleComponentForUserAgent(uiLang);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  CopyUTF16toUTF8(uiLang, aUILang);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsChromeRegistryChrome::IsLocaleRTL(const nsACString& package, PRBool *aResult)
+{
+  *aResult = PR_FALSE;
+
+  nsCAutoString locale;
+  GetSelectedLocale(package, locale);
+  if (locale.Length() < 2)
+    return NS_OK;
+
+  // first check the intl.uidirection.<locale> preference, and if that is not
+  // set, check the same preference but with just the first two characters of
+  // the locale. If that isn't set, default to left-to-right.
+  nsCAutoString prefString = NS_LITERAL_CSTRING("intl.uidirection.") + locale;
+  nsCOMPtr<nsIPrefBranch> prefBranch (do_GetService(NS_PREFSERVICE_CONTRACTID));
+  if (!prefBranch)
+    return NS_OK;
+  
+  nsXPIDLCString dir;
+  prefBranch->GetCharPref(prefString.get(), getter_Copies(dir));
+  if (dir.IsEmpty()) {
+    PRInt32 hyphen = prefString.FindChar('-');
+    if (hyphen >= 1) {
+      nsCAutoString shortPref(Substring(prefString, 0, hyphen));
+      prefBranch->GetCharPref(shortPref.get(), getter_Copies(dir));
+    }
+  }
+  *aResult = dir.EqualsLiteral("rtl");
+  return NS_OK;
+}
+
+nsresult
+nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage,
+                                          nsACString& aLocale)
+{
+  PackageEntry* entry =
+      static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
+                                                      & aPackage,
+                                                      PL_DHASH_LOOKUP));
+
+  if (PL_DHASH_ENTRY_IS_FREE(entry))
+    return NS_ERROR_FAILURE;
+
+  aLocale = entry->locales.GetSelected(mSelectedLocale, nsProviderArray::LOCALE);
+  if (aLocale.IsEmpty())
+    return NS_ERROR_FAILURE;
+
+  return NS_OK;
+}
+
+nsresult
+nsChromeRegistryChrome::SelectLocaleFromPref(nsIPrefBranch* prefs)
+{
+  nsresult rv;
+  PRBool matchOSLocale = PR_FALSE, userLocaleOverride = PR_FALSE;
+  prefs->PrefHasUserValue(SELECTED_LOCALE_PREF, &userLocaleOverride);
+  rv = prefs->GetBoolPref(MATCH_OS_LOCALE_PREF, &matchOSLocale);
+
+  if (NS_SUCCEEDED(rv) && matchOSLocale && !userLocaleOverride) {
+    // compute lang and region code only when needed!
+    nsCAutoString uiLocale;
+    rv = getUILangCountry(uiLocale);
+    if (NS_SUCCEEDED(rv))
+      mSelectedLocale = uiLocale;
+  }
+  else {
+    nsXPIDLCString provider;
+    rv = prefs->GetCharPref(SELECTED_LOCALE_PREF, getter_Copies(provider));
+    if (NS_SUCCEEDED(rv)) {
+      mSelectedLocale = provider;
+    }
+  }
+
+  return rv;
+}
+
+NS_IMETHODIMP
+nsChromeRegistryChrome::Observe(nsISupports *aSubject, const char *aTopic,
+                                const PRUnichar *someData)
+{
+  nsresult rv = NS_OK;
+
+  if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
+    nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
+    NS_ASSERTION(prefs, "Bad observer call!");
+
+    NS_ConvertUTF16toUTF8 pref(someData);
+
+    if (pref.EqualsLiteral(MATCH_OS_LOCALE_PREF) ||
+        pref.EqualsLiteral(SELECTED_LOCALE_PREF)) {
+      rv = SelectLocaleFromPref(prefs);
+      if (NS_SUCCEEDED(rv) && mProfileLoaded)
+        FlushAllCaches();
+    }
+    else if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
+      nsXPIDLCString provider;
+      rv = prefs->GetCharPref(pref.get(), getter_Copies(provider));
+      if (NS_FAILED(rv)) {
+        NS_ERROR("Couldn't get new locale pref!");
+        return rv;
+      }
+
+      mSelectedSkin = provider;
+      RefreshSkins();
+    } else {
+      NS_ERROR("Unexpected pref!");
+    }
+  }
+  else if (!strcmp("command-line-startup", aTopic)) {
+    nsCOMPtr<nsICommandLine> cmdLine (do_QueryInterface(aSubject));
+    if (cmdLine) {
+      nsAutoString uiLocale;
+      rv = cmdLine->HandleFlagWithParam(NS_LITERAL_STRING(UILOCALE_CMD_LINE_ARG),
+                                        PR_FALSE, uiLocale);
+      if (NS_SUCCEEDED(rv) && !uiLocale.IsEmpty()) {
+        CopyUTF16toUTF8(uiLocale, mSelectedLocale);
+        nsCOMPtr<nsIPrefBranch2> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
+        if (prefs) {
+          prefs->RemoveObserver(SELECTED_LOCALE_PREF, this);
+        }
+      }
+    }
+  }
+  else if (!strcmp("profile-initial-state", aTopic)) {
+    mProfileLoaded = PR_TRUE;
+  }
+  else {
+    NS_ERROR("Unexpected observer topic!");
+  }
+
+  return rv;
+}
+
+#ifdef MOZ_OMNIJAR
+nsresult
+nsChromeRegistryChrome::CheckOmnijarChrome()
+{
+  nsresult rv;
+
+  nsZipArchive* jarReader = mozilla::OmnijarReader();
+  // just proceed normally if there is no omnijar
+  if (!jarReader)
+    return NS_OK;
+
+  nsZipItem* manifest = jarReader->GetItem("chrome/chrome.manifest");
+  NS_ENSURE_TRUE(manifest, NS_ERROR_NOT_AVAILABLE);
+
+  nsCAutoString omniJarSpec;
+  rv = NS_GetURLSpecFromActualFile(mozilla::OmnijarPath(), omniJarSpec);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRUint32 len = manifest->RealSize();
+  nsAutoArrayPtr<PRUint8> outbuf(new PRUint8[len]);
+  NS_ENSURE_TRUE(outbuf, NS_ERROR_OUT_OF_MEMORY);
+
+  nsZipCursor cursor(manifest, jarReader, outbuf, len);
+  PRUint32 readlen;
+  PRUint8* buf = cursor.Read(&readlen);
+  NS_ENSURE_TRUE(buf, NS_ERROR_FILE_CORRUPTED);
+
+  nsAutoString jarString(NS_LITERAL_STRING("jar:"));
+  AppendUTF8toUTF16(omniJarSpec, jarString);
+  jarString += NS_LITERAL_STRING("!/chrome/chrome.manifest"); 
+
+  nsCOMPtr<nsIURI> manifestURI;
+  rv = NS_NewURI(getter_AddRefs(manifestURI), jarString);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = ProcessManifestBuffer((char *)buf, readlen, manifestURI, PR_FALSE);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return rv;
+}
+#endif /* MOZ_OMNIJAR */
+
+NS_IMETHODIMP
+nsChromeRegistryChrome::CheckForNewChrome()
+{
+  PL_DHashTableEnumerate(&mPackagesHash, RemoveAll, nsnull);
+  mOverlayHash.Clear();
+  mStyleHash.Clear();
+  mOverrideTable.Clear();
+
+  nsComponentManagerImpl::gComponentManager->RereadChromeManifests();
+  return NS_OK;
+}
+
+#ifdef MOZ_IPC
+static void
+SerializeURI(nsIURI* aURI,
+             SerializedURI& aSerializedURI)
+{
+  if (!aURI)
+    return;
+
+  aURI->GetSpec(aSerializedURI.spec);
+  aURI->GetOriginCharset(aSerializedURI.charset);
+}
+
+static PLDHashOperator
+EnumerateOverride(nsIURI* aURIKey,
+                  nsIURI* aURI,
+                  void* aArg)
+{
+  nsTArray<OverrideMapping>* overrides =
+      static_cast<nsTArray<OverrideMapping>*>(aArg);
+
+  SerializedURI chromeURI, overrideURI;
+
+  SerializeURI(aURIKey, chromeURI);
+  SerializeURI(aURI, overrideURI);
+        
+  OverrideMapping override = {
+    chromeURI, overrideURI
+  };
+  overrides->AppendElement(override);
+  return (PLDHashOperator)PL_DHASH_NEXT;
+}
+
+struct EnumerationArgs
+{
+  nsTArray<ChromePackage>& packages;
+  const nsCString& selectedLocale;
+  const nsCString& selectedSkin;
+};
+
+void
+nsChromeRegistryChrome::SendRegisteredChrome(
+    mozilla::dom::PContentProcessParent* aParent)
+{
+  nsTArray<ChromePackage> packages;
+  nsTArray<ResourceMapping> resources;
+  nsTArray<OverrideMapping> overrides;
+
+  EnumerationArgs args = {
+    packages, mSelectedLocale, mSelectedSkin
+  };
+  PL_DHashTableEnumerate(&mPackagesHash, CollectPackages, &args);
+
+  nsCOMPtr<nsIIOService> io (do_GetIOService());
+  NS_ENSURE_TRUE(io, );
+
+  nsCOMPtr<nsIProtocolHandler> ph;
+  nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
+  NS_ENSURE_SUCCESS(rv, );
+
+  //FIXME: Some substitutions are set up lazily and might not exist yet
+  nsCOMPtr<nsIResProtocolHandler> irph (do_QueryInterface(ph));
+  nsResProtocolHandler* rph = static_cast<nsResProtocolHandler*>(irph.get());
+  rph->CollectSubstitutions(resources);
+
+  mOverrideTable.EnumerateRead(&EnumerateOverride, &overrides);
+
+  bool success = aParent->SendRegisterChrome(packages, resources, overrides);
+  NS_ENSURE_TRUE(success, );
+}
+
+PLDHashOperator
+nsChromeRegistryChrome::CollectPackages(PLDHashTable *table,
+                                  PLDHashEntryHdr *entry,
+                                  PRUint32 number,
+                                  void *arg)
+{
+  EnumerationArgs* args = static_cast<EnumerationArgs*>(arg);
+  PackageEntry* package = static_cast<PackageEntry*>(entry);
+
+  SerializedURI contentURI, localeURI, skinURI;
+
+  SerializeURI(package->baseURI, contentURI);
+  SerializeURI(package->locales.GetBase(args->selectedLocale,
+                                        nsProviderArray::LOCALE), localeURI);
+  SerializeURI(package->skins.GetBase(args->selectedSkin, nsProviderArray::ANY),
+               skinURI);
+  
+  ChromePackage chromePackage = {
+    package->package,
+    contentURI,
+    localeURI,
+    skinURI,
+    package->flags
+  };
+  args->packages.AppendElement(chromePackage);
+  return (PLDHashOperator)PL_DHASH_NEXT;
+}
+#endif
+
+static PRBool
+CanLoadResource(nsIURI* aResourceURI)
+{
+  PRBool isLocalResource = PR_FALSE;
+  (void)NS_URIChainHasFlags(aResourceURI,
+                            nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
+                            &isLocalResource);
+  return isLocalResource;
+}
+
+nsresult
+nsChromeRegistryChrome::GetBaseURIFromPackage(const nsCString& aPackage,
+                                              const nsCString& aProvider,
+                                              const nsCString& aPath,
+                                              nsIURI* *aResult)
+{
+  PackageEntry* entry =
+      static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
+                                                      &aPackage,
+                                                      PL_DHASH_LOOKUP));
+
+  if (PL_DHASH_ENTRY_IS_FREE(entry)) {
+    if (!mInitialized)
+      return NS_ERROR_NOT_INITIALIZED;
+
+    LogMessage("No chrome package registered for chrome://%s/%s/%s",
+               aPackage.get(), aProvider.get(), aPath.get());
+
+    return NS_ERROR_FAILURE;
+  }
+
+  *aResult = nsnull;
+  if (aProvider.EqualsLiteral("locale")) {
+    *aResult = entry->locales.GetBase(mSelectedLocale, nsProviderArray::LOCALE);
+  }
+  else if (aProvider.EqualsLiteral("skin")) {
+    *aResult = entry->skins.GetBase(mSelectedSkin, nsProviderArray::ANY);
+  }
+  else if (aProvider.EqualsLiteral("content")) {
+    *aResult = entry->baseURI;
+  }
+  return NS_OK;
+}
+
+nsresult
+nsChromeRegistryChrome::GetFlagsFromPackage(const nsCString& aPackage,
+                                            PRUint32* aFlags)
+{
+  PackageEntry* entry =
+      static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
+                                                      & (nsACString&) aPackage,
+                                                      PL_DHASH_LOOKUP));
+  if (PL_DHASH_ENTRY_IS_FREE(entry))
+    return NS_ERROR_NOT_AVAILABLE;
+
+  *aFlags = entry->flags;
+  return NS_OK;
+}
+
+PLHashNumber
+nsChromeRegistryChrome::HashKey(PLDHashTable *table, const void *key)
+{
+  const nsACString& str = *reinterpret_cast<const nsACString*>(key);
+  return HashString(str);
+}
+
+PRBool
+nsChromeRegistryChrome::MatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
+                           const void *key)
+{
+  const nsACString& str = *reinterpret_cast<const nsACString*>(key);
+  const PackageEntry* pentry = static_cast<const PackageEntry*>(entry);
+  return str.Equals(pentry->package);
+}
+
+void
+nsChromeRegistryChrome::ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
+{
+  PackageEntry* pentry = static_cast<PackageEntry*>(entry);
+  pentry->~PackageEntry();
+}
+
+PRBool
+nsChromeRegistryChrome::InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
+                            const void *key)
+{
+  const nsACString& str = *reinterpret_cast<const nsACString*>(key);
+
+  new (entry) PackageEntry(str);
+  return PR_TRUE;
+}
+
+const PLDHashTableOps
+nsChromeRegistryChrome::kTableOps = {
+  PL_DHashAllocTable,
+  PL_DHashFreeTable,
+  HashKey,
+  MatchKey,
+  PL_DHashMoveEntryStub,
+  ClearEntry,
+  PL_DHashFinalizeStub,
+  InitEntry
+};
+
+nsChromeRegistryChrome::ProviderEntry*
+nsChromeRegistryChrome::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
+{
+  PRInt32 i = mArray.Count();
+  if (!i)
+    return nsnull;
+
+  ProviderEntry* found = nsnull;  // Only set if we find a partial-match locale
+  ProviderEntry* entry;
+
+  while (i--) {
+    entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
+    if (aPreferred.Equals(entry->provider))
+      return entry;
+
+    if (aType != LOCALE)
+      continue;
+
+    if (LanguagesMatch(aPreferred, entry->provider)) {
+      found = entry;
+      continue;
+    }
+
+    if (!found && entry->provider.EqualsLiteral("en-US"))
+      found = entry;
+  }
+
+  if (!found && aType != EXACT)
+    return entry;
+
+  return found;
+}
+
+nsIURI*
+nsChromeRegistryChrome::nsProviderArray::GetBase(const nsACString& aPreferred, MatchType aType)
+{
+  ProviderEntry* provider = GetProvider(aPreferred, aType);
+
+  if (!provider)
+    return nsnull;
+
+  return provider->baseURI;
+}
+
+const nsACString&
+nsChromeRegistryChrome::nsProviderArray::GetSelected(const nsACString& aPreferred, MatchType aType)
+{
+  ProviderEntry* entry = GetProvider(aPreferred, aType);
+
+  if (entry)
+    return entry->provider;
+
+  return EmptyCString();
+}
+
+void
+nsChromeRegistryChrome::nsProviderArray::SetBase(const nsACString& aProvider, nsIURI* aBaseURL)
+{
+  ProviderEntry* provider = GetProvider(aProvider, EXACT);
+
+  if (provider) {
+    provider->baseURI = aBaseURL;
+    return;
+  }
+
+  // no existing entries, add a new one
+  provider = new ProviderEntry(aProvider, aBaseURL);
+  if (!provider)
+    return; // It's safe to silently fail on OOM
+
+  mArray.AppendElement(provider);
+}
+
+void
+nsChromeRegistryChrome::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
+{
+  PRInt32 i = mArray.Count();
+  while (i--) {
+    ProviderEntry *entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
+    a->AppendElement(entry->provider);
+  }
+}
+
+void
+nsChromeRegistryChrome::nsProviderArray::Clear()
+{
+  PRInt32 i = mArray.Count();
+  while (i--) {
+    ProviderEntry* entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
+    delete entry;
+  }
+
+  mArray.Clear();
+}
+
+void
+nsChromeRegistryChrome::OverlayListEntry::AddURI(nsIURI* aURI)
+{
+  PRInt32 i = mArray.Count();
+  while (i--) {
+    PRBool equals;
+    if (NS_SUCCEEDED(aURI->Equals(mArray[i], &equals)) && equals)
+      return;
+  }
+
+  mArray.AppendObject(aURI);
+}
+
+void
+nsChromeRegistryChrome::OverlayListHash::Add(nsIURI* aBase, nsIURI* aOverlay)
+{
+  OverlayListEntry* entry = mTable.PutEntry(aBase);
+  if (entry)
+    entry->AddURI(aOverlay);
+}
+
+const nsCOMArray<nsIURI>*
+nsChromeRegistryChrome::OverlayListHash::GetArray(nsIURI* aBase)
+{
+  OverlayListEntry* entry = mTable.GetEntry(aBase);
+  if (!entry)
+    return nsnull;
+
+  return &entry->mArray;
+}
+
+#ifdef MOZ_XUL
+NS_IMETHODIMP
+nsChromeRegistryChrome::GetStyleOverlays(nsIURI *aChromeURL,
+                                         nsISimpleEnumerator **aResult)
+{
+  const nsCOMArray<nsIURI>* parray = mStyleHash.GetArray(aChromeURL);
+  if (!parray)
+    return NS_NewEmptyEnumerator(aResult);
+
+  return NS_NewArrayEnumerator(aResult, *parray);
+}
+
+NS_IMETHODIMP
+nsChromeRegistryChrome::GetXULOverlays(nsIURI *aChromeURL,
+                                       nsISimpleEnumerator **aResult)
+{
+  const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(aChromeURL);
+  if (!parray)
+    return NS_NewEmptyEnumerator(aResult);
+
+  return NS_NewArrayEnumerator(aResult, *parray);
+}
+#endif // MOZ_XUL
+
+nsIURI*
+nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
+{
+  if (!mManifestURI) {
+    nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
+    if (!io) {
+      NS_WARNING("No IO service trying to process chrome manifests");
+      return NULL;
+    }
+
+    io->NewFileURI(mFile, getter_AddRefs(mManifestURI));
+  }
+  return mManifestURI;
+}
+
+nsIXPConnect*
+nsChromeRegistry::ManifestProcessingContext::GetXPConnect()
+{
+  if (!mXPConnect)
+    mXPConnect = do_GetService("@mozilla.org/js/xpc/XPConnect;1");
+
+  return mXPConnect;
+}
+
+already_AddRefed<nsIURI>
+nsChromeRegistry::ManifestProcessingContext::ResolveURI(const char* uri)
+{
+  nsIURI* baseuri = GetManifestURI();
+  if (!baseuri)
+    return NULL;
+
+  nsCOMPtr<nsIURI> resolved;
+  nsresult rv = NS_NewURI(getter_AddRefs(resolved), uri, baseuri);
+  if (NS_FAILED(rv))
+    return NULL;
+
+  return resolved.forget();
+}
+
+static void
+EnsureLowerCase(char *aBuf)
+{
+  for (; *aBuf; ++aBuf) {
+    char ch = *aBuf;
+    if (ch >= 'A' && ch <= 'Z')
+      *aBuf = ch + 'a' - 'A';
+  }
+}
+
+void
+nsChromeRegistryChrome::ManifestContent(ManifestProcessingContext& cx, int lineno,
+                                        char *const * argv, bool platform,
+                                        bool contentaccessible)
+{
+  char* package = argv[0];
+  char* uri = argv[1];
+
+  EnsureLowerCase(package);
+
+  nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
+  if (!resolved) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "During chrome registration, unable to create URI '%s'.", uri);
+    return;
+  }
+
+  if (!CanLoadResource(resolved)) {
+    LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
+                          "During chrome registration, cannot register non-local URI '%s' as content.",
+                          uri);
+    return;
+  }
+
+  PackageEntry* entry =
+    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
+                                                    & (const nsACString&) nsDependentCString(package),
+                                                    PL_DHASH_ADD));
+  if (!entry)
+    return;
+
+  entry->baseURI = resolved;
+
+  if (platform)
+    entry->flags |= PLATFORM_PACKAGE;
+  if (contentaccessible)
+    entry->flags |= CONTENT_ACCESSIBLE;
+  if (cx.GetXPConnect()) {
+    nsCAutoString urlp("chrome://");
+    urlp.Append(package);
+    urlp.Append('/');
+
+    cx.GetXPConnect()->FlagSystemFilenamePrefix(urlp.get(), true);
+  }
+}
+
+void
+nsChromeRegistryChrome::ManifestLocale(ManifestProcessingContext& cx, int lineno,
+                                       char *const * argv, bool platform,
+                                       bool contentaccessible)
+{
+  char* package = argv[0];
+  char* provider = argv[1];
+  char* uri = argv[2];
+
+  EnsureLowerCase(package);
+
+  nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
+  if (!resolved) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "During chrome registration, unable to create URI '%s'.", uri);
+    return;
+  }
+
+  if (!CanLoadResource(resolved)) {
+    LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
+                          "During chrome registration, cannot register non-local URI '%s' as content.",
+                          uri);
+    return;
+  }
+
+  PackageEntry* entry =
+    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
+                                                    & (const nsACString&) nsDependentCString(package),
+                                                    PL_DHASH_ADD));
+  if (!entry)
+    return;
+
+  entry->locales.SetBase(nsDependentCString(provider), resolved);
+}
+
+void
+nsChromeRegistryChrome::ManifestSkin(ManifestProcessingContext& cx, int lineno,
+                                     char *const * argv, bool platform,
+                                     bool contentaccessible)
+{
+  char* package = argv[0];
+  char* provider = argv[1];
+  char* uri = argv[2];
+
+  EnsureLowerCase(package);
+
+  nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
+  if (!resolved) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "During chrome registration, unable to create URI '%s'.", uri);
+    return;
+  }
+
+  if (!CanLoadResource(resolved)) {
+    LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
+                          "During chrome registration, cannot register non-local URI '%s' as content.",
+                          uri);
+    return;
+  }
+
+  PackageEntry* entry =
+    static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
+                                                    & (const nsACString&) nsDependentCString(package),
+                                                    PL_DHASH_ADD));
+  if (!entry)
+    return;
+
+  entry->skins.SetBase(nsDependentCString(provider), resolved);
+}
+
+void
+nsChromeRegistryChrome::ManifestOverlay(ManifestProcessingContext& cx, int lineno,
+                                        char *const * argv, bool platform,
+                                        bool contentaccessible)
+{
+  char* base = argv[0];
+  char* overlay = argv[1];
+
+  nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
+  nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
+  if (!baseuri || !overlayuri) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "During chrome registration, unable to create URI.");
+    return;
+  }
+
+  if (!CanLoadResource(overlayuri)) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "Cannot register non-local URI '%s' as an overlay.", overlay);
+    return;
+  }
+
+  mOverlayHash.Add(baseuri, overlayuri);
+}
+
+void
+nsChromeRegistryChrome::ManifestStyle(ManifestProcessingContext& cx, int lineno,
+                                      char *const * argv, bool platform,
+                                      bool contentaccessible)
+{
+  char* base = argv[0];
+  char* overlay = argv[1];
+
+  nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
+  nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
+  if (!baseuri || !overlayuri) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "During chrome registration, unable to create URI.");
+    return;
+  }
+
+  if (!CanLoadResource(overlayuri)) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "Cannot register non-local URI '%s' as a style overlay.", overlay);
+    return;
+  }
+
+  mStyleHash.Add(baseuri, overlayuri);
+}
+
+void
+nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext& cx, int lineno,
+                                         char *const * argv, bool platform,
+                                         bool contentaccessible)
+{
+  char* chrome = argv[0];
+  char* resolved = argv[1];
+
+  nsCOMPtr<nsIURI> chromeuri = cx.ResolveURI(chrome);
+  nsCOMPtr<nsIURI> resolveduri = cx.ResolveURI(resolved);
+  if (!chromeuri || !resolveduri) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "During chrome registration, unable to create URI.");
+    return;
+  }
+
+  if (!CanLoadResource(resolveduri)) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "Cannot register non-local URI '%s' for an override.", resolved);
+    return;
+  }
+  mOverrideTable.Put(chromeuri, resolveduri);
+}
+
+void
+nsChromeRegistryChrome::ManifestResource(ManifestProcessingContext& cx, int lineno,
+                                         char *const * argv, bool platform,
+                                         bool contentaccessible)
+{
+  char* package = argv[0];
+  char* uri = argv[1];
+
+  EnsureLowerCase(package);
+  nsDependentCString host(package);
+
+  nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
+  if (!io) {
+    NS_WARNING("No IO service trying to process chrome manifests");
+    return;
+  }
+
+  nsCOMPtr<nsIProtocolHandler> ph;
+  nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
+  if (NS_FAILED(rv))
+    return;
+  
+  nsCOMPtr<nsIResProtocolHandler> rph = do_QueryInterface(ph);
+
+  PRBool exists = PR_FALSE;
+  rv = rph->HasSubstitution(host, &exists);
+  if (exists) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "Duplicate resource declaration for '%s' ignored.", package);
+    return;
+  }
+
+  nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
+  if (!resolved) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "During chrome registration, unable to create URI '%s'.", uri);
+    return;
+  }
+
+  if (!CanLoadResource(resolved)) {
+    LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+                          "Warning: cannot register non-local URI '%s' as a resource.",
+                          uri);
+    return;
+  }
+
+  rph->SetSubstitution(host, resolved);
+}
new file mode 100644
--- /dev/null
+++ b/chrome/src/nsChromeRegistryChrome.h
@@ -0,0 +1,223 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Josh Matthews <josh@joshmatthews.net> (Initial Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsChromeRegistryChrome_h
+#define nsChromeRegistryChrome_h
+
+#include "nsChromeRegistry.h"
+
+namespace mozilla {
+namespace dom {
+class PContentProcessParent;
+}
+}
+
+class nsIPrefBranch;
+
+class nsChromeRegistryChrome : public nsChromeRegistry
+{
+ public:
+  nsChromeRegistryChrome();
+  ~nsChromeRegistryChrome();
+
+  NS_OVERRIDE nsresult Init();
+
+  NS_OVERRIDE NS_IMETHOD CheckForNewChrome();
+  NS_OVERRIDE NS_IMETHOD CheckForOSAccessibility();
+  NS_OVERRIDE NS_IMETHOD GetLocalesForPackage(const nsACString& aPackage,
+                                              nsIUTF8StringEnumerator* *aResult);
+  NS_OVERRIDE NS_IMETHOD IsLocaleRTL(const nsACString& package,
+                                     PRBool *aResult);
+  NS_OVERRIDE NS_IMETHOD GetSelectedLocale(const nsACString& aPackage,
+                                           nsACString& aLocale);
+  NS_OVERRIDE NS_IMETHOD Observe(nsISupports *aSubject, const char *aTopic,
+                                 const PRUnichar *someData);
+
+#ifdef MOZ_XUL
+  NS_OVERRIDE NS_IMETHOD GetXULOverlays(nsIURI *aURI,
+                                        nsISimpleEnumerator **_retval);
+  NS_OVERRIDE NS_IMETHOD GetStyleOverlays(nsIURI *aURI,
+                                          nsISimpleEnumerator **_retval);
+#endif
+  
+#ifdef MOZ_IPC
+  void SendRegisteredChrome(mozilla::dom::PContentProcessParent* aChild);
+#endif
+
+ private:
+#ifdef MOZ_IPC
+  static PLDHashOperator CollectPackages(PLDHashTable *table,
+                                         PLDHashEntryHdr *entry,
+                                         PRUint32 number, void *arg);
+#endif
+
+  nsresult SelectLocaleFromPref(nsIPrefBranch* prefs);
+  NS_OVERRIDE nsresult GetBaseURIFromPackage(const nsCString& aPackage,
+                                             const nsCString& aProvider,
+                                             const nsCString& aPath,
+                                             nsIURI* *aResult);
+  NS_OVERRIDE nsresult GetFlagsFromPackage(const nsCString& aPackage,
+                                           PRUint32* aFlags);
+
+  static const PLDHashTableOps kTableOps;
+  static PLDHashNumber HashKey(PLDHashTable *table, const void *key);
+  static PRBool        MatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
+                                const void *key);
+  static void          ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry);
+  static PRBool        InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
+                                 const void *key);
+
+  struct ProviderEntry
+  {
+    ProviderEntry(const nsACString& aProvider, nsIURI* aBase) :
+    provider(aProvider),
+    baseURI(aBase) { }
+
+    nsCString        provider;
+    nsCOMPtr<nsIURI> baseURI;
+  };
+
+  class nsProviderArray
+  {
+   public:
+    nsProviderArray() :
+    mArray(1) { }
+    ~nsProviderArray()
+    { Clear(); }
+
+    // When looking up locales and skins, the "selected" locale is not always
+    // available. This enum identifies what kind of match is desired/found.
+    enum MatchType {
+      EXACT = 0,
+      LOCALE = 1, // "en-GB" is selected, we found "en-US"
+      ANY = 2
+    };
+
+    nsIURI* GetBase(const nsACString& aPreferred, MatchType aType);
+    const nsACString& GetSelected(const nsACString& aPreferred, MatchType aType);
+    void    SetBase(const nsACString& aProvider, nsIURI* base);
+    void    EnumerateToArray(nsTArray<nsCString> *a);
+    void    Clear();
+
+   private:
+    ProviderEntry* GetProvider(const nsACString& aPreferred, MatchType aType);
+
+    nsVoidArray mArray;
+  };
+
+  struct PackageEntry : public PLDHashEntryHdr
+  {
+    PackageEntry(const nsACString& package)
+    : package(package), flags(0) { }
+    ~PackageEntry() { }
+
+    nsCString        package;
+    nsCOMPtr<nsIURI> baseURI;
+    PRUint32         flags;
+    nsProviderArray  locales;
+    nsProviderArray  skins;
+  };
+
+  class OverlayListEntry : public nsURIHashKey
+  {
+   public:
+    typedef nsURIHashKey::KeyType        KeyType;
+    typedef nsURIHashKey::KeyTypePointer KeyTypePointer;
+
+    OverlayListEntry(KeyTypePointer aKey) : nsURIHashKey(aKey) { }
+    OverlayListEntry(OverlayListEntry& toCopy) : nsURIHashKey(toCopy),
+                                                 mArray(toCopy.mArray) { }
+    ~OverlayListEntry() { }
+
+    void AddURI(nsIURI* aURI);
+
+    nsCOMArray<nsIURI> mArray;
+  };
+
+  class OverlayListHash
+  {
+   public:
+    OverlayListHash() { }
+    ~OverlayListHash() { }
+
+    PRBool Init() { return mTable.Init(); }
+    void Add(nsIURI* aBase, nsIURI* aOverlay);
+    void Clear() { mTable.Clear(); }
+    const nsCOMArray<nsIURI>* GetArray(nsIURI* aBase);
+
+   private:
+    nsTHashtable<OverlayListEntry> mTable;
+  };
+
+  // Hashes on the file to be overlaid (chrome://browser/content/browser.xul)
+  // to a list of overlays/stylesheets
+  OverlayListHash mOverlayHash;
+  OverlayListHash mStyleHash;
+
+  PRBool mProfileLoaded;
+  
+  nsCString mSelectedLocale;
+  nsCString mSelectedSkin;
+
+  // Hash of package names ("global") to PackageEntry objects
+  PLDHashTable mPackagesHash;
+
+  virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
+                               char *const * argv, bool platform,
+                               bool contentaccessible);
+  virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
+                              char *const * argv, bool platform,
+                              bool contentaccessible);
+  virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
+                            char *const * argv, bool platform,
+                            bool contentaccessible);
+  virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
+                               char *const * argv, bool platform,
+                               bool contentaccessible);
+  virtual void ManifestStyle(ManifestProcessingContext& cx, int lineno,
+                             char *const * argv, bool platform,
+                             bool contentaccessible);
+  virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
+                                char *const * argv, bool platform,
+                                bool contentaccessible);
+  virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
+                                char *const * argv, bool platform,
+                                bool contentaccessible);
+};
+
+#endif // nsChromeRegistryChrome_h
new file mode 100644
--- /dev/null
+++ b/chrome/src/nsChromeRegistryContent.cpp
@@ -0,0 +1,331 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Josh Matthews <josh@joshmatthews.net> (Initial Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "RegistryMessageUtils.h"
+#include "nsChromeRegistry.h"
+#include "nsChromeRegistryContent.h"
+#include "nsString.h"
+#include "nsNetUtil.h"
+#include "nsResProtocolHandler.h"
+
+nsChromeRegistryContent::nsChromeRegistryContent()
+{
+  mPackagesHash.Init();
+}
+
+void
+nsChromeRegistryContent::RegisterRemoteChrome(
+    const nsTArray<ChromePackage>& aPackages,
+    const nsTArray<ResourceMapping>& aResources,
+    const nsTArray<OverrideMapping>& aOverrides)
+{
+  for (PRUint32 i = aPackages.Length(); i > 0; ) {
+    --i;
+    RegisterPackage(aPackages[i]);
+  }
+
+  for (PRUint32 i = aResources.Length(); i > 0; ) {
+    --i;
+    RegisterResource(aResources[i]);
+  }
+
+  for (PRUint32 i = aOverrides.Length(); i > 0; ) {
+    --i;
+    RegisterOverride(aOverrides[i]);
+  }
+}
+
+void
+nsChromeRegistryContent::RegisterPackage(const ChromePackage& aPackage)
+{
+  nsCOMPtr<nsIIOService> io (do_GetIOService());
+  if (!io)
+    return;
+
+  nsCOMPtr<nsIURI> content, locale, skin;
+
+  if (aPackage.contentBaseURI.spec.Length()) {
+    nsresult rv = NS_NewURI(getter_AddRefs(content),
+                            aPackage.contentBaseURI.spec,
+                            aPackage.contentBaseURI.charset.get(),
+                            nsnull, io);
+    if (NS_FAILED(rv))
+      return;
+  }
+  if (aPackage.localeBaseURI.spec.Length()) {
+    nsresult rv = NS_NewURI(getter_AddRefs(locale),
+                            aPackage.localeBaseURI.spec,
+                            aPackage.localeBaseURI.charset.get(),
+                            nsnull, io);
+    if (NS_FAILED(rv))
+      return;
+  }
+  if (aPackage.skinBaseURI.spec.Length()) {
+    nsCOMPtr<nsIURI> skinBaseURI;
+    nsresult rv = NS_NewURI(getter_AddRefs(skin),
+                            aPackage.skinBaseURI.spec,
+                            aPackage.skinBaseURI.charset.get(),
+                            nsnull, io);
+    if (NS_FAILED(rv))
+      return;
+  }
+
+  PackageEntry* entry = new PackageEntry;
+  entry->flags = aPackage.flags;
+  entry->contentBaseURI = content;
+  entry->localeBaseURI = locale;
+  entry->skinBaseURI = skin;
+
+  nsresult rv = mPackagesHash.Put(aPackage.package, entry);
+  if (NS_FAILED(rv))
+    return;
+}
+
+void
+nsChromeRegistryContent::RegisterResource(const ResourceMapping& aResource)
+{
+  nsCOMPtr<nsIIOService> io (do_GetIOService());
+  if (!io)
+    return;
+
+  nsCOMPtr<nsIProtocolHandler> ph;
+  nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
+  if (NS_FAILED(rv))
+    return;
+  
+  nsCOMPtr<nsIResProtocolHandler> rph (do_QueryInterface(ph));
+  if (!rph)
+    return;
+
+  nsCOMPtr<nsIURI> resolvedURI;
+  if (aResource.resolvedURI.spec.Length()) {
+    nsresult rv = NS_NewURI(getter_AddRefs(resolvedURI),
+                            aResource.resolvedURI.spec,
+                            aResource.resolvedURI.charset.get(),
+                            nsnull, io);                 
+    if (NS_FAILED(rv))
+      return;
+  }
+
+  rv = rph->SetSubstitution(aResource.resource, resolvedURI);
+  if (NS_FAILED(rv))
+    return;
+}
+
+void
+nsChromeRegistryContent::RegisterOverride(const OverrideMapping& aOverride)
+{
+  nsCOMPtr<nsIIOService> io (do_GetIOService());
+  if (!io)
+    return;
+
+  nsCOMPtr<nsIURI> chromeURI, overrideURI;
+  nsresult rv = NS_NewURI(getter_AddRefs(chromeURI),
+                          aOverride.originalURI.spec,
+                          aOverride.originalURI.charset.get(),
+                          nsnull, io);
+  if (NS_FAILED(rv))
+    return;
+
+  rv = NS_NewURI(getter_AddRefs(overrideURI), aOverride.overrideURI.spec,
+                 aOverride.overrideURI.charset.get(), nsnull, io);
+  if (NS_FAILED(rv))
+    return;
+  
+  mOverrideTable.Put(chromeURI, overrideURI);
+}
+
+nsresult
+nsChromeRegistryContent::GetBaseURIFromPackage(const nsCString& aPackage,
+                                               const nsCString& aProvider,
+                                               const nsCString& aPath,
+                                               nsIURI* *aResult)
+{
+  PackageEntry* entry;
+  if (!mPackagesHash.Get(aPackage, &entry)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  *aResult = nsnull;
+  if (aProvider.EqualsLiteral("locale")) {
+    *aResult = entry->localeBaseURI;
+  }
+  else if (aProvider.EqualsLiteral("skin")) {
+    *aResult = entry->skinBaseURI;
+  }
+  else if (aProvider.EqualsLiteral("content")) {
+    *aResult = entry->contentBaseURI;
+  }
+  return NS_OK;
+}
+
+nsresult
+nsChromeRegistryContent::GetFlagsFromPackage(const nsCString& aPackage,
+                                             PRUint32* aFlags)
+{
+  PackageEntry* entry;
+  if (!mPackagesHash.Get(aPackage, &entry)) {
+    return NS_ERROR_FAILURE;
+  }
+  *aFlags = entry->flags;
+  return NS_OK;
+}
+
+// All functions following only make sense in chrome, and therefore assert
+
+#define CONTENT_NOTREACHED() \
+  NS_NOTREACHED("Content should not be calling this")
+
+#define CONTENT_NOT_IMPLEMENTED() \
+  CONTENT_NOTREACHED();           \
+  return NS_ERROR_NOT_IMPLEMENTED;
+
+NS_IMETHODIMP
+nsChromeRegistryContent::GetLocalesForPackage(const nsACString& aPackage,
+                                              nsIUTF8StringEnumerator* *aResult)
+{
+  CONTENT_NOT_IMPLEMENTED();
+}
+
+NS_IMETHODIMP
+nsChromeRegistryContent::CheckForOSAccessibility()
+{
+  CONTENT_NOT_IMPLEMENTED();
+}
+
+NS_IMETHODIMP
+nsChromeRegistryContent::CheckForNewChrome()
+{
+  CONTENT_NOT_IMPLEMENTED();
+}
+
+NS_IMETHODIMP
+nsChromeRegistryContent::IsLocaleRTL(const nsACString& package,
+                                     PRBool *aResult)
+{
+  CONTENT_NOT_IMPLEMENTED();
+}
+
+NS_IMETHODIMP
+nsChromeRegistryContent::GetSelectedLocale(const nsACString& aPackage,
+                                           nsACString& aLocale)
+{
+  CONTENT_NOT_IMPLEMENTED();
+}
+  
+NS_IMETHODIMP
+nsChromeRegistryContent::Observe(nsISupports* aSubject, const char* aTopic,
+                                 const PRUnichar* aData)
+{
+  CONTENT_NOT_IMPLEMENTED();
+}
+
+NS_IMETHODIMP
+nsChromeRegistryContent::GetStyleOverlays(nsIURI *aChromeURL,
+                                          nsISimpleEnumerator **aResult)
+{
+  CONTENT_NOT_IMPLEMENTED();
+}
+
+NS_IMETHODIMP
+nsChromeRegistryContent::GetXULOverlays(nsIURI *aChromeURL,
+                                        nsISimpleEnumerator **aResult)
+{
+  CONTENT_NOT_IMPLEMENTED();
+}
+
+void
+nsChromeRegistryContent::ManifestContent(ManifestProcessingContext& cx,
+                                         int lineno, char *const * argv,
+                                         bool platform, bool contentaccessible)
+{
+  CONTENT_NOTREACHED();
+}
+
+void
+nsChromeRegistryContent::ManifestLocale(ManifestProcessingContext& cx,
+                                        int lineno,
+                                        char *const * argv, bool platform,
+                                        bool contentaccessible)
+{
+  CONTENT_NOTREACHED();
+}
+
+void
+nsChromeRegistryContent::ManifestSkin(ManifestProcessingContext& cx,
+                                      int lineno,
+                                      char *const * argv, bool platform,
+                                      bool contentaccessible)
+{
+  CONTENT_NOTREACHED();
+}
+
+void
+nsChromeRegistryContent::ManifestOverlay(ManifestProcessingContext& cx, int lineno,
+                                         char *const * argv, bool platform,
+                                         bool contentaccessible)
+{
+  CONTENT_NOTREACHED();
+}
+
+void
+nsChromeRegistryContent::ManifestStyle(ManifestProcessingContext& cx,
+                                       int lineno,
+                                       char *const * argv, bool platform,
+                                       bool contentaccessible)
+{
+  CONTENT_NOTREACHED();
+}
+
+void
+nsChromeRegistryContent::ManifestOverride(ManifestProcessingContext& cx,
+                                          int lineno,
+                                          char *const * argv, bool platform,
+                                          bool contentaccessible)
+{
+  CONTENT_NOTREACHED();
+}
+
+void
+nsChromeRegistryContent::ManifestResource(ManifestProcessingContext& cx,
+                                          int lineno,
+                                          char *const * argv, bool platform,
+                                          bool contentaccessible)
+{
+  CONTENT_NOTREACHED();
+}
new file mode 100644
--- /dev/null
+++ b/chrome/src/nsChromeRegistryContent.h
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Josh Matthews <josh@joshmatthews.net> (Initial Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsChromeRegistryContent_h
+#define nsChromeRegistryContent_h
+
+#include "nsChromeRegistry.h"
+#include "nsTArray.h"
+#include "nsClassHashtable.h"
+
+class nsCString;
+struct ChromePackage;
+struct ResourceMapping;
+struct OverrideMapping;
+
+class nsChromeRegistryContent : public nsChromeRegistry
+{
+ public:
+  nsChromeRegistryContent();
+  
+  void RegisterRemoteChrome(const nsTArray<ChromePackage>& aPackages,
+                            const nsTArray<ResourceMapping>& aResources,
+                            const nsTArray<OverrideMapping>& aOverrides);
+
+  NS_OVERRIDE NS_IMETHOD GetLocalesForPackage(const nsACString& aPackage,
+                                              nsIUTF8StringEnumerator* *aResult);
+  NS_OVERRIDE NS_IMETHOD CheckForNewChrome();
+  NS_OVERRIDE NS_IMETHOD CheckForOSAccessibility();
+  NS_OVERRIDE NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
+                                 const PRUnichar* aData);
+  NS_OVERRIDE NS_IMETHOD IsLocaleRTL(const nsACString& package,
+                                     PRBool *aResult);
+  NS_OVERRIDE NS_IMETHOD GetSelectedLocale(const nsACString& aPackage,
+                                           nsACString& aLocale);
+  NS_OVERRIDE NS_IMETHOD GetStyleOverlays(nsIURI *aChromeURL,
+                                          nsISimpleEnumerator **aResult);
+  NS_OVERRIDE NS_IMETHOD GetXULOverlays(nsIURI *aChromeURL,
+                                        nsISimpleEnumerator **aResult);
+
+ private:
+  struct PackageEntry
+  {
+    PackageEntry() : flags(0) { }
+    ~PackageEntry() { }
+
+    nsCOMPtr<nsIURI> contentBaseURI;
+    nsCOMPtr<nsIURI> localeBaseURI;
+    nsCOMPtr<nsIURI> skinBaseURI;
+    PRUint32         flags;
+  };
+  
+  void RegisterPackage(const ChromePackage& aPackage);
+  void RegisterResource(const ResourceMapping& aResource);
+  void RegisterOverride(const OverrideMapping& aOverride);
+
+  NS_OVERRIDE nsresult GetBaseURIFromPackage(const nsCString& aPackage,
+                                 const nsCString& aProvider,
+                                 const nsCString& aPath,
+                                 nsIURI* *aResult);
+  NS_OVERRIDE nsresult GetFlagsFromPackage(const nsCString& aPackage, PRUint32* aFlags);
+
+  nsClassHashtable<nsCStringHashKey, PackageEntry> mPackagesHash;
+
+  virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
+                               char *const * argv, bool platform,
+                               bool contentaccessible);
+  virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
+                              char *const * argv, bool platform,
+                              bool contentaccessible);
+  virtual void ManifestSkin(ManifestProcessingContext& cx, int lineno,
+                            char *const * argv, bool platform,
+                            bool contentaccessible);
+  virtual void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
+                               char *const * argv, bool platform,
+                               bool contentaccessible);
+  virtual void ManifestStyle(ManifestProcessingContext& cx, int lineno,
+                             char *const * argv, bool platform,
+                             bool contentaccessible);
+  virtual void ManifestOverride(ManifestProcessingContext& cx, int lineno,
+                                char *const * argv, bool platform,
+                                bool contentaccessible);
+  virtual void ManifestResource(ManifestProcessingContext& cx, int lineno,
+                                char *const * argv, bool platform,
+                                bool contentaccessible);
+};
+
+#endif // nsChromeRegistryContent_h
--- a/chrome/test/Makefile.in
+++ b/chrome/test/Makefile.in
@@ -41,10 +41,16 @@ srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = test_chrome
 
 XPCSHELL_TESTS = unit \
                  $(NULL)
+ifdef MOZ_IPC
+# FIXME/bug 575918: out-of-process xpcshell is broken on OS X
+ifneq ($(OS_ARCH),Darwin)
+XPCSHELL_TESTS += unit_ipc
+endif
+endif
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/chrome/test/unit/data/test_resolve_uris.manifest
@@ -0,0 +1,5 @@
+resource foo resource://foo/foo-resource/
+content foo resource://foo/foo-content/
+locale foo foo resource://foo/foo-locale/
+skin foo foo resource://foo/foo-skin/
+override chrome://good-package/content/override-me.xul resource://foo/foo-override/override-me.xul
new file mode 100644
--- /dev/null
+++ b/chrome/test/unit/test_resolve_uris.js
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Chrome Registration Test Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Josh Matthews <josh@joshmatthews.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// head_crtestutils.js doesn't get included in the child by default
+if (typeof registerManifests === "undefined") {
+  load("../unit/head_crtestutils.js");
+}
+
+let manifests = [
+    do_get_file("../unit/data/test_resolve_uris.manifest"),
+];
+registerManifests(manifests);
+
+function do_run_test()
+{
+  let cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
+           getService(Ci.nsIChromeRegistry);
+
+  var runtime = Components.classes["@mozilla.org/xre/app-info;1"]
+                .getService(Components.interfaces.nsIXULRuntime);
+  if (runtime.processType ==
+      Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
+    cr.checkForNewChrome();
+  }
+
+  // See if our various things were able to register
+  let registrationTypes = [
+      "content",
+      "locale",
+      "skin",
+      "override",
+      "resource",
+  ];
+
+  for (let j = 0; j < registrationTypes.length; j++) {
+    let type = registrationTypes[j];
+    dump("Testing type '" + type + "'\n");
+    let expectedURI = "resource://foo/foo-" + type + "/";
+    let sourceURI = "chrome://foo/" + type + "/";
+    switch (type) {
+      case "content":
+        expectedURI += "foo.xul";
+        break;
+      case "locale":
+        expectedURI += "foo.dtd";
+        break;
+      case "skin":
+        expectedURI += "foo.css";
+        break;
+      case "override":
+        sourceURI = "chrome://good-package/content/override-me.xul";
+        expectedURI += "override-me.xul";
+        break;
+      case "resource":
+        sourceURI = "resource://foo/";
+        break;
+    };
+    try {
+      let ios = Cc["@mozilla.org/network/io-service;1"].
+                getService(Ci.nsIIOService);
+      sourceURI = ios.newURI(sourceURI, null, null);
+      let uri;
+      if (type == "resource") {
+        // resources go about a slightly different way than everything else
+        let rph = ios.getProtocolHandler("resource").
+            QueryInterface(Ci.nsIResProtocolHandler);
+        uri = rph.resolveURI(sourceURI);
+      }
+      else {
+        uri = cr.convertChromeURL(sourceURI).spec;
+      }
+      
+      do_check_eq(expectedURI, uri);
+    }
+    catch (e) {
+      dump(e + "\n");
+      do_throw("Should have registered a handler for type '" +
+               type + "'\n");
+    }
+  }
+}
+
+if (typeof run_test === "undefined") {
+  run_test = function() {
+    do_run_test();
+  };
+}
new file mode 100644
--- /dev/null
+++ b/chrome/test/unit_ipc/test_resolve_uris_ipc.js
@@ -0,0 +1,9 @@
+//
+// Run test script in content process instead of chrome (xpcshell's default)
+//
+
+function run_test() {
+  load("../unit/test_resolve_uris.js");
+  do_run_test();
+  run_test_in_child("../unit/test_resolve_uris.js");
+}
--- a/configure.in
+++ b/configure.in
@@ -4980,17 +4980,16 @@ esac
 case "${target}" in
     arm-android-eabi)
         NSS_DISABLE_DBM=1
         USE_ARM_KUSER=1
         MOZ_INSTALLER=
         MOZ_CRASHREPORTER=
         NS_PRINTING=
         NECKO_WIFI=
-        MOZ_PLUGINS=
         MOZ_THUMB2=1
         MOZ_THEME_FASTSTRIPE=1
         MOZ_TREE_FREETYPE=1
         MOZ_MEMORY=1
         ;;
 esac
 
 MOZ_ARG_ENABLE_STRING(application,
@@ -5695,17 +5694,17 @@ MOZ_ARG_DISABLE_BOOL(jsd,
     MOZ_JSDEBUGGER=,
     MOZ_JSDEBUGGER=1)
 
 
 dnl ========================================================
 dnl = Disable IPC support for tabs and plugins
 dnl ========================================================
 case "${target}" in
-*-wince*|*-android*)
+*-wince*)
     MOZ_IPC=
     ;;
 esac
 
 MOZ_ARG_DISABLE_BOOL(ipc,
 [  --disable-ipc           Disable IPC supports for tabs and plugins],
     MOZ_IPC=,
     MOZ_IPC=1)
--- a/content/base/public/nsIFrameLoader.idl
+++ b/content/base/public/nsIFrameLoader.idl
@@ -36,27 +36,35 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 
 interface nsIDocShell;
 interface nsIURI;
+interface nsIWebProgress;
+interface nsIFrame;
 interface nsIChromeFrameMessageManager;
+interface nsIVariant;
 
-[scriptable, uuid(3b256c12-20e1-4fd3-8edb-b9c793919f15)]
+[scriptable, uuid(65d2c9e2-852c-48cf-a95d-9b82f1273c15)]
 interface nsIFrameLoader : nsISupports
 {
   /**
    * Get the docshell from the frame loader.
    */
   readonly attribute nsIDocShell docShell;
 
   /**
+   * Get the nsIWebProgress from the frame loader, allowing listener registration.
+   */
+  readonly attribute nsIWebProgress webProgress;
+
+  /**
    * Start loading the frame. This method figures out what to load
    * from the owner content in the frame loader.
    */
   void loadFrame();
 
   /**
    * Loads the specified URI in this frame. Behaves identically to loadFrame,
    * except that this method allows specifying the URI to load.
@@ -71,23 +79,64 @@ interface nsIFrameLoader : nsISupports
 
   /**
    * Find out whether the loader's frame is at too great a depth in
    * the frame tree.  This can be used to decide what operations may
    * or may not be allowed on the loader's docshell.
    */
   readonly attribute boolean depthTooGreat;
 
+  /**
+   * Updates the position and size of the subdocument loaded by this frameloader.
+   *
+   *  @param aIFrame The nsIFrame for the content node that owns this frameloader
+   */
+  [noscript] void updatePositionAndSize(in nsIFrame aIFrame);
+
+  /**
+   * Activate remote frame.
+   * Throws an exception with non-remote frames.
+   */
+  void activateRemoteFrame();
+
+  /**
+   * @see nsIDOMWindowUtils sendMouseEvent.
+   */
+  void sendCrossProcessMouseEvent(in AString aType,
+                                  in float aX,
+                                  in float aY,
+                                  in long aButton,
+                                  in long aClickCount,
+                                  in long aModifiers,
+                                  [optional] in boolean aIgnoreRootScrollFrame);
+
+  /**
+   * Activate event forwarding from client (remote frame) to parent.
+   */
+  void activateFrameEvent(in AString aType, in boolean capture);
+
   // Note, when frameloaders are swapped, also messageManagers are swapped.
   readonly attribute nsIChromeFrameMessageManager messageManager;
+
+  /**
+   * @see nsIDOMWindowUtils sendKeyEvent.
+   */
+  void sendCrossProcessKeyEvent(in AString aType,
+                                in long aKeyCode,
+                                in long aCharCode,
+                                in long aModifiers,
+                                [optional] in boolean aPreventDefault);
+
+  attribute boolean delayRemoteDialogs;
+
 };
 
 native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
 
-[scriptable, uuid(8f3b12a0-35ae-4e0d-9152-8e0d7e49d446)]
+[scriptable, uuid(5879040e-83e9-40e3-b2bb-5ddf43b76e47)]
 interface nsIFrameLoaderOwner : nsISupports
 {
   /**
    * The frame loader owned by this nsIFrameLoaderOwner
    */
   readonly attribute nsIFrameLoader frameLoader;
   [noscript, notxpcom] alreadyAddRefed_nsFrameLoader GetFrameLoader();
 
--- a/content/base/public/nsIFrameMessageManager.idl
+++ b/content/base/public/nsIFrameMessageManager.idl
@@ -47,17 +47,17 @@ interface nsIFrameMessageListener : nsIS
   /**
    * This is for JS only.
    * receiveMessage is called with one parameter, which has the following
    * properties:
    *   {
    *     name:    %message name%,
    *     sync:    %true or false%.
    *     json:    %json object or null%,
-   *     objects: %array of cpow or null, always null if sync is false%
+   *     objects: %array of handles or null, always null if sync is false%
    *   }
    * @note objects property isn't implemented yet.
    *
    * if the message is synchronous, possible return value is sent back
    * as JSON.
    *
    * When the listener is called, 'this' value is the target of the message.
    */
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -164,28 +164,33 @@ EXTRA_COMPONENTS = \
 		contentAreaDropListener.js \
 		contentAreaDropListener.manifest \
 		$(NULL)
 
 EXTRA_JS_MODULES = \
 		CSPUtils.jsm \
 		$(NULL)
 
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 INCLUDES	+= \
 		-I$(srcdir)/../../events/src \
 		-I$(srcdir)/../../xml/content/src \
 		-I$(srcdir)/../../../layout/xul/base/src \
 		-I$(srcdir)/../../xul/content/src \
 		-I$(srcdir)/../../html/content/src \
 		-I$(srcdir)/../../base/src \
 		-I$(srcdir)/../../xbl/src \
 		-I$(srcdir)/../../../layout/generic \
 		-I$(srcdir)/../../../layout/style \
 		-I$(srcdir)/../../../dom/base \
 		-I$(srcdir)/../../xml/document/src \
 		-I$(topsrcdir)/xpcom/io \
+		-I$(topsrcdir)/dom/ipc \
 		-I$(topsrcdir)/js/src/xpconnect/src \
 		-I$(topsrcdir)/caps/include \
 		$(NULL)
 
+CXXFLAGS += $(TK_CFLAGS)
+
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -84,16 +84,17 @@
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMEventGroup.h"
 #include "nsIDOMCDATASection.h"
 #include "nsIDOMProcessingInstruction.h"
 #include "nsDOMString.h"
 #include "nsNodeUtils.h"
 #include "nsLayoutUtils.h" // for GetFrameForPoint
 #include "nsIFrame.h"
+#include "nsITabChild.h"
 
 #include "nsRange.h"
 #include "nsIDOMText.h"
 #include "nsIDOMComment.h"
 #include "nsDOMDocumentType.h"
 #include "nsNodeIterator.h"
 #include "nsTreeWalker.h"
 
@@ -1079,17 +1080,18 @@ IMPL_SHIM(nsIApplicationCacheContainer)
     }                                                                      \
   PR_END_MACRO
 
 NS_IMETHODIMP
 nsExternalResourceMap::LoadgroupCallbacks::GetInterface(const nsIID & aIID,
                                                         void **aSink)
 {
   if (mCallbacks &&
-      (IID_IS(nsIPrompt) || IID_IS(nsIAuthPrompt) || IID_IS(nsIAuthPrompt2))) {
+      (IID_IS(nsIPrompt) || IID_IS(nsIAuthPrompt) || IID_IS(nsIAuthPrompt2) ||
+       IID_IS(nsITabChild))) {
     return mCallbacks->GetInterface(aIID, aSink);
   }
 
   *aSink = nsnull;
 
   TRY_SHIM(nsILoadContext);
   TRY_SHIM(nsIProgressEventSink);
   TRY_SHIM(nsIChannelEventSink);
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -18,16 +18,17 @@
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1998
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Johnny Stenback <jst@netscape.com> (original author)
  *   Boris Zbarsky <bzbarsky@mit.edu>
+ *   Frederic Plourde <frederic.plourde@polymtl.ca>
  *
  * 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
@@ -38,64 +39,100 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Class for managing loading of a subframe (creation of the docshell,
  * handling of loads in it, recursion-checking).
  */
 
+#ifdef MOZ_WIDGET_QT
+#include <QtGui/QX11EmbedWidget>
+#include <QGraphicsWidget>
+#include <QGraphicsProxyWidget>
+#endif
+
+#ifdef MOZ_IPC
+#  include "base/basictypes.h"
+#endif
+
+#include "prenv.h"
+
 #include "nsIDOMHTMLIFrameElement.h"
 #include "nsIDOMHTMLFrameElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIPresShell.h"
 #include "nsIContent.h"
 #include "nsIContentViewer.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebNavigation.h"
+#include "nsIWebProgress.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeNode.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocShellLoadInfo.h"
 #include "nsIBaseWindow.h"
 #include "nsContentUtils.h"
+#include "nsIXPConnect.h"
+#include "nsIJSContextStack.h"
 #include "nsUnicharUtils.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIScrollable.h"
 #include "nsFrameLoader.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIFrame.h"
 #include "nsIFrameFrame.h"
 #include "nsDOMError.h"
 #include "nsGUIEvent.h"
 #include "nsEventDispatcher.h"
 #include "nsISHistory.h"
 #include "nsISHistoryInternal.h"
 #include "nsIDOMNSHTMLDocument.h"
+
+#include "nsLayoutUtils.h"
 #include "nsIView.h"
 #include "nsPLDOMEvent.h"
 
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 
 #include "nsGkAtoms.h"
 #include "nsINameSpaceManager.h"
 
 #include "nsThreadUtils.h"
 #include "nsIContentViewer.h"
+#include "nsIView.h"
+
 #include "nsIDOMChromeWindow.h"
 #include "nsInProcessTabChildGlobal.h"
 #include "mozilla/AutoRestore.h"
 
+#ifdef MOZ_WIDGET_GTK2
+#include "mozcontainer.h"
+
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+#endif
+
+#ifdef MOZ_IPC
+#include "ContentProcessParent.h"
+#include "TabParent.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+#endif
+
+#include "jsapi.h"
+
 class nsAsyncDocShellDestroyer : public nsRunnable
 {
 public:
   nsAsyncDocShellDestroyer(nsIDocShell* aDocShell)
     : mDocShell(aDocShell)
   {
   }
 
@@ -252,21 +289,44 @@ nsFrameLoader::ReallyStartLoading()
   
   return rv;
 }
 
 nsresult
 nsFrameLoader::ReallyStartLoadingInternal()
 {
   NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInDoc());
+
+  nsresult rv = MaybeCreateDocShell();
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+#ifdef MOZ_IPC
+  if (mRemoteFrame) {
+    if (!mChildProcess) {
+      TryNewProcess();
+    }
+
+    if (!mChildProcess) {
+      NS_WARNING("Couldn't create child process for iframe.");
+      return NS_ERROR_FAILURE;
+    }
+
+    // FIXME get error codes from child
+    mChildProcess->LoadURL(mURIToLoad);
+    return NS_OK;
+  }
+#endif
+
+  NS_ASSERTION(mDocShell,
+               "MaybeCreateDocShell succeeded with a null mDocShell");
+
   // Just to be safe, recheck uri.
-  nsresult rv = CheckURILoad(mURIToLoad);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = EnsureDocShell();
+  rv = CheckURILoad(mURIToLoad);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
   mDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
   NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
 
   // We'll use our principal, not that of the document loaded inside us.  This
   // is very important; needed to prevent XSS attacks on documents loaded in
@@ -317,38 +377,84 @@ nsFrameLoader::CheckURILoad(nsIURI* aURI
   nsresult rv =
     secMan->CheckLoadURIWithPrincipal(principal, aURI,
                                       nsIScriptSecurityManager::STANDARD);
   if (NS_FAILED(rv)) {
     return rv; // We're not
   }
 
   // Bail out if this is an infinite recursion scenario
+  rv = MaybeCreateDocShell();
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+#ifdef MOZ_IPC
+  if (mRemoteFrame) {
+    return NS_OK;
+  }
+#endif
   return CheckForRecursiveLoad(aURI);
 }
 
 NS_IMETHODIMP
 nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
 {
   *aDocShell = nsnull;
 
   // If we have an owner, make sure we have a docshell and return
   // that. If not, we're most likely in the middle of being torn down,
   // then we just return null.
   if (mOwnerContent) {
-    nsresult rv = EnsureDocShell();
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsresult rv = MaybeCreateDocShell();
+    if (NS_FAILED(rv))
+      return rv;
+#ifdef MOZ_IPC
+    if (mRemoteFrame) {
+      NS_WARNING("No docshells for remote frames!");
+      return NS_ERROR_NOT_AVAILABLE;
+    }
+#endif
+    NS_ASSERTION(mDocShell,
+                 "MaybeCreateDocShell succeeded, but null mDocShell");
   }
 
   *aDocShell = mDocShell;
   NS_IF_ADDREF(*aDocShell);
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsFrameLoader::GetWebProgress(nsIWebProgress **aWebProgress)
+{
+  nsresult rv;
+  *aWebProgress = nsnull;
+#ifdef MOZ_IPC
+  if (mRemoteFrame) {
+    if (!mChildProcess) {
+      TryNewProcess();
+    }
+    if (!mChildProcess) {
+      return NS_ERROR_UNEXPECTED;
+    }
+    *aWebProgress = mChildProcess;
+    NS_ADDREF(*aWebProgress);
+    return NS_OK;
+  }
+#endif
+
+  nsCOMPtr<nsIDocShell> shell;
+  rv = GetDocShell(getter_AddRefs(shell));
+  if (NS_SUCCEEDED(rv)) {
+    nsCOMPtr<nsIWebProgress> progress(do_QueryInterface(shell));
+    progress.swap(*aWebProgress);
+  }
+  return rv;
+}
+
 void
 nsFrameLoader::Finalize()
 {
   nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
   if (base_win) {
     base_win->Destroy();
   }
   mDocShell = nsnull;
@@ -542,73 +648,87 @@ nsFrameLoader::Show(PRInt32 marginWidth,
     return PR_FALSE;
   }
   // Reset mInShow if we exit early.
   AutoResetInShow resetInShow(this);
   mInShow = PR_TRUE;
 
   nsContentType contentType;
 
-  nsresult rv = EnsureDocShell();
+  nsresult rv = MaybeCreateDocShell();
   if (NS_FAILED(rv)) {
     return PR_FALSE;
   }
 
-  if (!mDocShell)
-    return PR_FALSE;
-
-  nsCOMPtr<nsIPresShell> presShell;
-  mDocShell->GetPresShell(getter_AddRefs(presShell));
-  if (presShell)
-    return PR_TRUE;
+#ifdef MOZ_IPC
+  if (mRemoteFrame) {
+    contentType = eContentTypeUI;
+  }
+  else
+#endif
+  {
+    if (!mDocShell)
+      return false;
+    nsCOMPtr<nsIPresShell> presShell;
+    mDocShell->GetPresShell(getter_AddRefs(presShell));
+    if (presShell)
+      return true;
 
-  mDocShell->SetMarginWidth(marginWidth);
-  mDocShell->SetMarginHeight(marginHeight);
+    mDocShell->SetMarginWidth(marginWidth);
+    mDocShell->SetMarginHeight(marginHeight);
 
-  nsCOMPtr<nsIScrollable> sc = do_QueryInterface(mDocShell);
-  if (sc) {
-    sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
-                                       scrollbarPrefX);
-    sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
-                                       scrollbarPrefY);
-  }
+    nsCOMPtr<nsIScrollable> sc = do_QueryInterface(mDocShell);
+    if (sc) {
+      sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
+                                         scrollbarPrefX);
+      sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
+                                         scrollbarPrefY);
+    }
 
 
-  nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
-  NS_ASSERTION(treeItem,
-               "Found a nsIDocShell that isn't a nsIDocShellTreeItem.");
+    nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
+    NS_ASSERTION(treeItem,
+                 "Found a nsIDocShell that isn't a nsIDocShellTreeItem.");
 
-  PRInt32 itemType;
-  treeItem->GetItemType(&itemType);
+    PRInt32 itemType;
+    treeItem->GetItemType(&itemType);
 
-  if (itemType == nsIDocShellTreeItem::typeChrome)
-    contentType = eContentTypeUI;
-  else {
-    nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
-    treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
-    contentType = sameTypeParent ? eContentTypeContentFrame : eContentTypeContent;
+    if (itemType == nsIDocShellTreeItem::typeChrome)
+      contentType = eContentTypeUI;
+    else {
+      nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
+      treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
+      contentType = sameTypeParent ? eContentTypeContentFrame : eContentTypeContent;
+    }
   }
 
   nsIView* view = frame->CreateViewAndWidget(contentType);
   if (!view)
     return PR_FALSE;
 
+#ifdef MOZ_IPC
+  if (mRemoteFrame) {
+    return ShowRemoteFrame(frame, view);
+  }
+#endif
+
   nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mDocShell);
   NS_ASSERTION(baseWindow, "Found a nsIDocShell that isn't a nsIBaseWindow.");
   baseWindow->InitWindow(nsnull, view->GetWidget(), 0, 0, 10, 10);
   // This is kinda whacky, this "Create()" call doesn't really
   // create anything, one starts to wonder why this was named
   // "Create"...
   baseWindow->Create();
   baseWindow->SetVisibility(PR_TRUE);
 
   // Trigger editor re-initialization if midas is turned on in the
   // sub-document. This shouldn't be necessary, but given the way our
   // editor works, it is. See
   // https://bugzilla.mozilla.org/show_bug.cgi?id=284245
+  nsCOMPtr<nsIPresShell> presShell;
   mDocShell->GetPresShell(getter_AddRefs(presShell));
   if (presShell) {
     nsCOMPtr<nsIDOMNSHTMLDocument> doc =
       do_QueryInterface(presShell->GetDocument());
 
     if (doc) {
       nsAutoString designMode;
       doc->GetDesignMode(designMode);
@@ -624,16 +744,104 @@ nsFrameLoader::Show(PRInt32 marginWidth,
   if (mHideCalled) {
     mHideCalled = PR_FALSE;
     Hide();
     return PR_FALSE;
   }
   return PR_TRUE;
 }
 
+#ifdef MOZ_IPC
+bool