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 idunknown
push userunknown
push dateunknown
bugs568691
milestone2.0b2pre
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
+nsFrameLoader::ShowRemoteFrame(nsIFrameFrame* frame, nsIView* view)
+{
+  NS_ASSERTION(mRemoteFrame, "ShowRemote only makes sense on remote frames.");
+
+  if (!mChildProcess) {
+    TryNewProcess();
+  }
+
+  if (!mChildProcess) {
+    NS_ERROR("Couldn't create child process.");
+    return false;
+  }
+
+  nsIWidget* w = view->GetWidget();
+  if (!w) {
+    NS_ERROR("Our view doesn't have a widget. Totally stuffed!");
+    return false;
+  }
+
+  nsIntSize size = GetSubDocumentSize(frame->GetFrame());
+
+#ifdef XP_WIN
+  HWND parentwin =
+    static_cast<HWND>(w->GetNativeData(NS_NATIVE_WINDOW));
+
+  mChildProcess->SendcreateWidget(parentwin);
+#elif defined(MOZ_WIDGET_GTK2)
+  GdkWindow* parent_win =
+    static_cast<GdkWindow*>(w->GetNativeData(NS_NATIVE_WINDOW));
+
+  gpointer user_data = nsnull;
+  gdk_window_get_user_data(parent_win, &user_data);
+
+  MozContainer* parentMozContainer = MOZ_CONTAINER(user_data);
+  GtkContainer* container = GTK_CONTAINER(parentMozContainer);