Merge mozilla-central to fx-team
authorBlair McBride <bmcbride@mozilla.com>
Thu, 08 Dec 2011 13:57:41 +1300
changeset 82261 6785d3003414c46f93e3d79096bbe2de07772075
parent 82260 cc69fe7c9f265ffe93256f83c5e142b740b9fa23 (current diff)
parent 82256 7ab478082ca72615083636938a23486490d029ad (diff)
child 82263 ebe8aa6a1f353d295c9f87372b7f3687e9e4c745
child 82367 cab4a629450e8bcca2780114cba326acac2ba421
child 83054 550bbef53f76baf93f6ef22f78e8d190b39e3976
push id3935
push userbmo@edmorley.co.uk
push dateThu, 08 Dec 2011 15:16:45 +0000
treeherdermozilla-inbound@00b0798600a6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone11.0a1
first release with
nightly linux32
6785d3003414 / 11.0a1 / 20111208031134 / files
nightly linux64
6785d3003414 / 11.0a1 / 20111208031134 / files
nightly mac
6785d3003414 / 11.0a1 / 20111208031134 / files
nightly win32
6785d3003414 / 11.0a1 / 20111208031134 / files
nightly win64
6785d3003414 / 11.0a1 / 20111208031134 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to fx-team
content/base/public/nsIDOMGCParticipant.h
dom/telephony/Radio.cpp
dom/telephony/Radio.h
dom/telephony/worker-component/Makefile.in
dom/telephony/worker-component/nsIRadioInterface.idl
dom/telephony/worker-component/nsITelephonyWorker.idl
dom/telephony/worker-component/nsTelephonyWorker.js
dom/telephony/worker-component/nsTelephonyWorker.manifest
dom/telephony/worker-component/ril_consts.js
dom/telephony/worker-component/ril_worker.js
js/src/jit-test/tests/basic/arith.js
js/src/jit-test/tests/basic/bug489098.js
js/src/jit-test/tests/basic/jitstatsArchFlags.js
js/src/jit-test/tests/basic/testArrayIn.js
js/src/jit-test/tests/basic/testBreak.js
js/src/jit-test/tests/basic/testCallNull.js
js/src/jit-test/tests/basic/testContinueWithLabel2.js
js/src/jit-test/tests/basic/testHOTLOOPCorrectness.js
js/src/jit-test/tests/basic/testInitMethod.js
js/src/jit-test/tests/basic/testMethodInitDeref.js
js/src/jit-test/tests/basic/testMethodInitUneval.js
js/src/jit-test/tests/basic/testMethodOverride.js
js/src/jit-test/tests/basic/testNewDate.js
js/src/jit-test/tests/basic/testRUNLOOPCorrectness.js
js/src/jit-test/tests/basic/testRegExpLiteral.js
js/src/jit-test/tests/basic/testSetMethod.js
js/src/jit-test/tests/basic/testSideExitInConstructor.js
js/src/jit-test/tests/basic/testStringPropIncrement.js
js/src/jit-test/tests/basic/wrap-primitive-this.js
js/src/jit-test/tests/jaeger/bug580884-2.js
testing/mozbase/manifestdestiny/README.txt
testing/mozbase/manifestdestiny/manifestparser.py
testing/mozbase/mozhttpd/mozhttpd.py
testing/mozbase/mozinfo/mozinfo.py
testing/mozbase/mozinstall/mozinstall.py
xpcom/analysis/final.js
xpcom/tests/static-checker/TestFinal.cpp
xpcom/tests/static-checker/TestFinalFunction.cpp
xpcom/tests/static-checker/TestFinalGrandparentFunction.cpp
xpcom/tests/static-checker/TestFinalTemplate.cpp
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1537,41 +1537,29 @@ nsAccessible::State()
     // XXX: Perhaps we will be able to make this less hacky if we support
     // extended states in nsARIAMap, e.g. derive COLLAPSED from
     // EXPANDABLE && !EXPANDED.
     state &= ~states::COLLAPSED;
   }
 
   if (!(state & states::UNAVAILABLE)) {
     state |= states::ENABLED | states::SENSITIVE;
+
+    // If the object is a current item of container widget then mark it as
+    // ACTIVE. This allows screen reader virtual buffer modes to know which
+    // descendant is the current one that would get focus if the user navigates
+    // to the container widget.
+    nsAccessible* widget = ContainerWidget();
+    if (widget && widget->CurrentItem() == this)
+      state |= states::ACTIVE;
   }
 
   if ((state & states::COLLAPSED) || (state & states::EXPANDED))
     state |= states::EXPANDABLE;
 
-  if (mRoleMapEntry) {
-    // If an object has an ancestor with the activedescendant property
-    // pointing at it, we mark it as ACTIVE even if it's not currently focused.
-    // This allows screen reader virtual buffer modes to know which descendant
-    // is the current one that would get focus if the user navigates to the container widget.
-    nsAutoString id;
-    if (nsCoreUtils::GetID(mContent, id)) {
-      nsIContent *ancestorContent = mContent;
-      nsAutoString activeID;
-      while ((ancestorContent = ancestorContent->GetParent()) != nsnull) {
-        if (ancestorContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant, activeID)) {
-          if (id == activeID) {
-            state |= states::ACTIVE;
-          }
-          break;
-        }
-      }
-    }
-  }
-
   // For some reasons DOM node may have not a frame. We tract such accessibles
   // as invisible.
   nsIFrame *frame = GetFrame();
   if (!frame)
     return state;
 
   const nsStyleDisplay* display = frame->GetStyleDisplay();
   if (display && display->mOpacity == 1.0f &&
@@ -2950,25 +2938,28 @@ nsAccessible::CurrentItem()
 }
 
 nsAccessible*
 nsAccessible::ContainerWidget() const
 {
   nsIAtom* idAttribute = mContent->GetIDAttributeName();
   if (idAttribute) {
     if (mContent->HasAttr(kNameSpaceID_None, idAttribute)) {
-      nsAccessible* parent = Parent();
-      do {
+      for (nsAccessible* parent = Parent(); parent; parent = parent->Parent()) {
         nsIContent* parentContent = parent->GetContent();
         if (parentContent &&
             parentContent->HasAttr(kNameSpaceID_None,
                                    nsGkAtoms::aria_activedescendant)) {
           return parent;
         }
-      } while ((parent = parent->Parent()));
+
+        // Don't cross DOM document boundaries.
+        if (parent->IsDocumentNode())
+          break;
+      }
     }
   }
   return nsnull;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible protected methods
 
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -298,26 +298,24 @@ nsTextEquivUtils::AppendFromValue(nsAcce
   }
 
   //XXX: is it necessary to care the accessible is not a document?
   if (aAccessible->IsDocumentNode())
     return NS_ERROR_UNEXPECTED;
 
   nsIContent *content = aAccessible->GetContent();
 
-  nsCOMPtr<nsIContent> parent = content->GetParent();
-  PRInt32 indexOf = parent->IndexOf(content);
-
-  for (PRInt32 i = indexOf - 1; i >= 0; i--) {
+  for (nsIContent* childContent = content->GetPreviousSibling(); childContent;
+       childContent = childContent->GetPreviousSibling()) {
     // check for preceding text...
-    if (!parent->GetChildAt(i)->TextIsOnlyWhitespace()) {
-      PRUint32 childCount = parent->GetChildCount();
-      for (PRUint32 j = indexOf + 1; j < childCount; j++) {
+    if (!childContent->TextIsOnlyWhitespace()) {
+      for (nsIContent* siblingContent = content->GetNextSibling(); siblingContent;
+           siblingContent = siblingContent->GetNextSibling()) {
         // .. and subsequent text
-        if (!parent->GetChildAt(j)->TextIsOnlyWhitespace()) {
+        if (!siblingContent->TextIsOnlyWhitespace()) {
           nsresult rv = aAccessible->GetValue(text);
           NS_ENSURE_SUCCESS(rv, rv);
 
           return AppendString(aString, text) ?
             NS_OK : NS_OK_NO_NAME_CLAUSE_HANDLED;
           break;
         }
       }
@@ -327,20 +325,18 @@ nsTextEquivUtils::AppendFromValue(nsAcce
 
   return NS_OK_NO_NAME_CLAUSE_HANDLED;
 }
 
 nsresult
 nsTextEquivUtils::AppendFromDOMChildren(nsIContent *aContent,
                                         nsAString *aString)
 {
-  PRUint32 childCount = aContent->GetChildCount();
-  for (PRUint32 childIdx = 0; childIdx < childCount; childIdx++) {
-    nsCOMPtr<nsIContent> childContent = aContent->GetChildAt(childIdx);
-
+  for (nsIContent* childContent = aContent->GetFirstChild(); childContent;
+       childContent = childContent->GetNextSibling()) {
     nsresult rv = AppendFromDOMNode(childContent, aString);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 nsresult
--- a/accessible/src/html/nsHTMLFormControlAccessible.cpp
+++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp
@@ -715,21 +715,21 @@ nsHTMLGroupboxAccessible::
 }
 
 PRUint32
 nsHTMLGroupboxAccessible::NativeRole()
 {
   return nsIAccessibleRole::ROLE_GROUPING;
 }
 
-nsIContent* nsHTMLGroupboxAccessible::GetLegend()
+nsIContent*
+nsHTMLGroupboxAccessible::GetLegend()
 {
-  nsresult count = 0;
-  nsIContent *legendContent = nsnull;
-  while ((legendContent = mContent->GetChildAt(count++)) != nsnull) {
+  for (nsIContent* legendContent = mContent->GetFirstChild(); legendContent;
+       legendContent = legendContent->GetNextSibling()) {
     if (legendContent->NodeInfo()->Equals(nsGkAtoms::legend,
                                           mContent->GetNameSpaceID())) {
       // Either XHTML namespace or no namespace
       return legendContent;
     }
   }
 
   return nsnull;
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -166,19 +166,18 @@ 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);
+  for (nsIContent* childContent = aParentContent->GetFirstChild(); childContent;
+       childContent = childContent->GetNextSibling()) {
     if (!childContent->IsHTML()) {
       continue;
     }
 
     nsCOMPtr<nsIAtom> tag = childContent->Tag();
     if (tag == nsGkAtoms::option ||
         tag == nsGkAtoms::optgroup) {
 
@@ -225,17 +224,17 @@ nsHTMLSelectOptionAccessible::GetNameInt
   // CASE #1 -- great majority of the cases
   // find the label attribute - this is what the W3C says we should use
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
   if (!aName.IsEmpty())
     return NS_OK;
 
   // CASE #2 -- no label parameter, get the first child, 
   // use it if it is a text node
-  nsIContent *text = mContent->GetChildAt(0);
+  nsIContent* text = mContent->GetFirstChild();
   if (!text)
     return NS_OK;
 
   if (text->IsNodeOfType(nsINode::eTEXT)) {
     nsAutoString txtValue;
     nsresult rv = nsTextEquivUtils::
       AppendTextEquivFromTextContent(text, &txtValue);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -340,24 +339,22 @@ nsHTMLSelectOptionAccessible::GetLevelIn
 
   return level;
 }
 
 void
 nsHTMLSelectOptionAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                                          PRInt32 *aSetSize)
 {
-  nsIContent *parentContent = mContent->GetParent();
-
   PRInt32 posInSet = 0, setSize = 0;
   bool isContentFound = false;
 
-  PRUint32 childCount = parentContent->GetChildCount();
-  for (PRUint32 childIdx = 0; childIdx < childCount; childIdx++) {
-    nsIContent *childContent = parentContent->GetChildAt(childIdx);
+  nsIContent* parentContent = mContent->GetParent();
+  for (nsIContent* childContent = parentContent->GetFirstChild(); childContent;
+       childContent = childContent->GetNextSibling()) {
     if (childContent->NodeInfo()->Equals(mContent->NodeInfo())) {
       if (!isContentFound) {
         if (childContent == mContent)
           isContentFound = true;
 
         posInSet++;
       }
       setSize++;
@@ -784,17 +781,17 @@ void nsHTMLComboboxListAccessible::GetBo
     return;
 
   if (0 == (comboAcc->State() & states::COLLAPSED)) {
     nsHTMLSelectListAccessible::GetBoundsRect(aBounds, aBoundingFrame);
     return;
   }
 
   // Get the first option.
-  nsIContent* content = mContent->GetChildAt(0);
+  nsIContent* content = mContent->GetFirstChild();
   if (!content) {
     return;
   }
   nsIFrame* frame = content->GetPrimaryFrame();
   if (!frame) {
     *aBoundingFrame = nsnull;
     return;
   }
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -401,38 +401,35 @@ nsHTMLTableHeaderCellAccessible::NativeR
     case 0:
       return nsIAccessibleRole::ROLE_COLUMNHEADER;
     case 1:
       return nsIAccessibleRole::ROLE_ROWHEADER;
   }
 
   // Assume it's columnheader if there are headers in siblings, oterwise
   // rowheader.
-  nsIContent *parent = mContent->GetParent();
-  if (!parent) {
+  nsIContent* parentContent = mContent->GetParent();
+  if (!parentContent) {
     NS_ERROR("Deattached content on alive accessible?");
     return nsIAccessibleRole::ROLE_NOTHING;
   }
 
-  PRInt32 indexInParent = parent->IndexOf(mContent);
-
-  for (PRInt32 idx = indexInParent - 1; idx >= 0; idx--) {
-    nsIContent* sibling = parent->GetChildAt(idx);
-    if (sibling && sibling->IsElement()) {
-      if (nsCoreUtils::IsHTMLTableHeader(sibling))
+  for (nsIContent* siblingContent = mContent->GetPreviousSibling(); siblingContent;
+       siblingContent = siblingContent->GetPreviousSibling()) {
+    if (siblingContent->IsElement()) {
+      if (nsCoreUtils::IsHTMLTableHeader(siblingContent))
         return nsIAccessibleRole::ROLE_COLUMNHEADER;
       return nsIAccessibleRole::ROLE_ROWHEADER;
     }
   }
 
-  PRInt32 childCount = parent->GetChildCount();
-  for (PRInt32 idx = indexInParent + 1; idx < childCount; idx++) {
-    nsIContent* sibling = parent->GetChildAt(idx);
-    if (sibling && sibling->IsElement()) {
-      if (nsCoreUtils::IsHTMLTableHeader(sibling))
+  for (nsIContent* siblingContent = mContent->GetNextSibling(); siblingContent;
+       siblingContent = siblingContent->GetNextSibling()) {
+    if (siblingContent->IsElement()) {
+      if (nsCoreUtils::IsHTMLTableHeader(siblingContent))
         return nsIAccessibleRole::ROLE_COLUMNHEADER;
       return nsIAccessibleRole::ROLE_ROWHEADER;
     }
   }
 
   // No elements in siblings what means the table has one column only. Therefore
   // it should be column header.
   return nsIAccessibleRole::ROLE_COLUMNHEADER;
--- a/accessible/src/xul/nsXULListboxAccessible.cpp
+++ b/accessible/src/xul/nsXULListboxAccessible.cpp
@@ -251,34 +251,29 @@ nsXULListboxAccessible::GetColumnCount(P
 {
   NS_ENSURE_ARG_POINTER(aColumnsCout);
   *aColumnsCout = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsIContent* headContent = nsnull;
-
-  PRUint32 count = mContent->GetChildCount();
-  for (PRUint32 index = 0; index < count; ++index) {
-    nsIContent* childContent = mContent->GetChildAt(index);
+  for (nsIContent* childContent = mContent->GetFirstChild(); childContent;
+       childContent = childContent->GetNextSibling()) {
     if (childContent->NodeInfo()->Equals(nsGkAtoms::listcols,
                                          kNameSpaceID_XUL)) {
       headContent = childContent;
     }
   }
-
   if (!headContent)
     return NS_OK;
 
   PRUint32 columnCount = 0;
-
-  count = headContent->GetChildCount();
-  for (PRUint32 index = 0; index < count; ++index) {
-    nsIContent* childContent = headContent->GetChildAt(index);
+  for (nsIContent* childContent = headContent->GetFirstChild(); childContent;
+       childContent = childContent->GetNextSibling()) {
     if (childContent->NodeInfo()->Equals(nsGkAtoms::listcol,
                                          kNameSpaceID_XUL)) {
       columnCount++;
     }
   }
 
   *aColumnsCout = columnCount;
   return NS_OK;
@@ -952,21 +947,21 @@ nsXULListitemAccessible::Description(nsS
 
 /**
   * If there is a Listcell as a child ( not anonymous ) use it, otherwise
   *   default to getting the name from GetXULName
   */
 nsresult
 nsXULListitemAccessible::GetNameInternal(nsAString& aName)
 {
-  nsIContent* child = mContent->GetChildAt(0);
-  if (child) {
-    if (child->NodeInfo()->Equals(nsGkAtoms::listcell,
-                                  kNameSpaceID_XUL)) {
-      child->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
+  nsIContent* childContent = mContent->GetFirstChild();
+  if (childContent) {
+    if (childContent->NodeInfo()->Equals(nsGkAtoms::listcell,
+                                         kNameSpaceID_XUL)) {
+      childContent->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
       return NS_OK;
     }
   }
   return GetXULName(aName);
 }
 
 PRUint32
 nsXULListitemAccessible::NativeRole()
--- a/accessible/tests/mochitest/states/test_aria.html
+++ b/accessible/tests/mochitest/states/test_aria.html
@@ -92,16 +92,20 @@
       // aria-checked
       testStates("aria_checked_checkbox", STATE_CHECKED);
       testStates("aria_mixed_checkbox", STATE_MIXED);
 
       // test disabled group and all its descendants to see if they are
       // disabled, too. See bug 429285.
       testAriaDisabledTree("group");
 
+      // active state caused by aria-activedescendant
+      testStates("as_item1", 0, EXT_STATE_ACTIVE);
+      testStates("as_item2", 0, 0, 0, EXT_STATE_ACTIVE);
+
       // universal ARIA properties inherited from file input control
       var fileTextField = getAccessible("fileinput").firstChild;
       testStates(fileTextField,
                  STATE_BUSY | STATE_UNAVAILABLE | STATE_REQUIRED | STATE_HASPOPUP | STATE_INVALID);
       var fileBrowseButton = getAccessible("fileinput").lastChild;
       testStates(fileBrowseButton,
                  STATE_BUSY | STATE_UNAVAILABLE | STATE_REQUIRED | STATE_HASPOPUP | STATE_INVALID);
 
@@ -179,16 +183,21 @@
      title="aria-orientation should be applied to separator and slider roles">
     Mozilla Bug 681674
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=699017"
      title="File input control should be propogate states to descendants">
     Mozilla Bug 699017
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=689847"
+     title="Expose active state on current item of selectable widgets">
+    Mozilla Bug 689847
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div id="textbox_autocomplete_inline" role="textbox" aria-autocomplete="inline"></div>
   <div id="textbox_autocomplete_list" role="textbox" aria-autocomplete="list"></div>
   <div id="textbox_autocomplete_both" role="textbox" aria-autocomplete="both"></div>
@@ -224,16 +233,23 @@
       <div role="option" id="item1">Item 1</div>
       <div role="option" id="item2">Item 2</div>
       <div role="option" id="item3">Item 3</div>
       <div role="option" id="item4">Item 4</div>
     </div>
     <div role="slider" tabindex="0">A slider</div>
   </div>
 
+  <!-- Test active state -->
+  <div id="as_listbox" tabindex="0" role="listbox"
+       aria-activedescendant="as_item1">
+    <div role="option" id="as_item1">Item 1</div>
+    <div role="option" id="as_item2">Item 2</div>
+  </div>
+
   <!-- universal ARIA properties should be inherited by text field of file input -->
   <input type="file" id="fileinput"
          aria-busy="true"
          aria-disabled="true"
          aria-required="true"
          aria-haspopup="true"
          aria-invalid="true">
 
--- a/accessible/tests/mochitest/states/test_selects.html
+++ b/accessible/tests/mochitest/states/test_selects.html
@@ -20,30 +20,34 @@
       testStates(combobox,
                  STATE_HASPOPUP | STATE_COLLAPSED | STATE_FOCUSABLE, 0,
                  STATE_FOCUSED, 0);
 
       var comboboxList = combobox.firstChild;
       testStates(comboboxList, 0, 0, STATE_FOCUSABLE, 0);
 
       var opt1 = comboboxList.firstChild;
-      testStates(opt1, STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE, 0,
-                 STATE_FOCUSED, 0);
+      testStates(opt1, STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE,
+                 EXT_STATE_ACTIVE, STATE_FOCUSED, 0);
 
       var opt2 = comboboxList.lastChild;
       testStates(opt2, STATE_SELECTABLE | STATE_FOCUSABLE, 0, STATE_SELECTED, 0,
-                 STATE_FOCUSED, 0);
+                 STATE_FOCUSED, EXT_STATE_ACTIVE);
 
       // listbox
       var listbox = getAccessible("listbox");
       testStates(listbox, STATE_FOCUSABLE, 0,
-                 STATE_HASPOPUP | STATE_COLLAPSED | STATE_FOCUSED, 0);
+                 STATE_HASPOPUP | STATE_COLLAPSED | STATE_FOCUSED);
 
-      testStates(listbox.firstChild, STATE_SELECTABLE, 0,
-                 STATE_SELECTED | STATE_FOCUSED | STATE_FOCUSED, 0);
+      testStates(listbox.firstChild, STATE_SELECTABLE, EXT_STATE_ACTIVE,
+                 STATE_SELECTED | STATE_FOCUSED | STATE_FOCUSED);
+
+      testStates(listbox.lastChild, STATE_SELECTABLE, 0,
+                 STATE_SELECTED | STATE_FOCUSED | STATE_FOCUSED,
+                 0, 0, EXT_STATE_ACTIVE);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
@@ -55,16 +59,21 @@
      title="mochitest for selects and lists">
     Mozilla Bug 443889
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=640716"
      title="mochitest for selects and lists">
     Mozilla Bug 640716
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=689847"
+     title="Expose active state on current item of selectable widgets">
+    Mozilla Bug 689847
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <select id="combobox">
     <option>item 1</option>
     <option>item 2</option>
copy from mobile/xul/LICENSE
copy to b2g/LICENSE
copy from mobile/xul/Makefile.in
copy to b2g/Makefile.in
--- a/mobile/xul/Makefile.in
+++ b/b2g/Makefile.in
@@ -10,49 +10,39 @@
 # 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.
 #
 # The Initial Developer of the Original Code is
 # the Mozilla Foundation <http://www.mozilla.org/>.
-# Portions created by the Initial Developer are Copyright (C) 2007
+# Portions created by the Initial Developer are Copyright (C) 2011
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
-#   Mark Finkle <mfinkle@mozilla.com>
-#   Joel Maher <jmaher@mozilla.com>
+#   Chris Jones <jones.chris.g@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      = ../..
+DEPTH      = ..
 topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-DIRS = chrome locales components modules themes/core app
-
-ifndef LIBXUL_SDK
-PARALLEL_DIRS += $(DEPTH)/xulrunner/tools/redit
-endif
+DIRS = chrome locales app
 
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/testing/testsuite-targets.mk
-
-package-mobile-tests:
-	$(MAKE) stage-mochitest DIST_BIN=$(DEPTH)/$(DIST)/bin/xulrunner
-	$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
-	@(cd $(PKG_STAGE) && tar $(TAR_CREATE_FLAGS) - *) | bzip2 -f > $(DIST)/$(PKG_PATH)$(TEST_PACKAGE)
copy from mobile/xul/app/Makefile.in
copy to b2g/app/Makefile.in
--- a/mobile/xul/app/Makefile.in
+++ b/b2g/app/Makefile.in
@@ -10,99 +10,100 @@
 # 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.
 #
 # The Initial Developer of the Original Code is
 # the Mozilla Foundation <http://www.mozilla.org/>.
-# Portions created by the Initial Developer are Copyright (C) 2007
+# Portions created by the Initial Developer are Copyright (C) 2011
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
-#   Mark Finkle <mfinkle@mozilla.com>
+#   Chris Jones <jones.chris.g@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     = ../../..
+DEPTH     = ../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-DIRS = profile/extensions
-
-PREF_JS_EXPORTS = $(srcdir)/mobile.js
+PREF_JS_EXPORTS = $(srcdir)/b2g.js
 
 ifndef LIBXUL_SDK
-ifneq (Android,$(OS_TARGET))
 PROGRAM=$(MOZ_APP_NAME)$(BIN_SUFFIX)
 
 CPPSRCS = nsBrowserApp.cpp
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
 LOCAL_INCLUDES += -I$(DEPTH)/build
 
 DEFINES += -DXPCOM_GLUE
 STL_FLAGS=
 
+LIBS += $(JEMALLOC_LIBS)
+
 LIBS += \
   $(EXTRA_DSO_LIBS) \
   $(XPCOM_STANDALONE_GLUE_LDOPTS) \
   $(NULL)
 
-ifeq ($(MOZ_PLATFORM_MAEMO),6)
-LIBS += \
-  $(LIBXUL_DIST)/../widget/src/qt/faststartupqt/$(LIB_PREFIX)faststartupqt.$(LIB_SUFFIX) \
-  $(MOZ_QT_LIBS) \
-  $(NULL)
-LOCAL_INCLUDES += -I$(topsrcdir)/widget/src/qt/faststartupqt $(TK_CFLAGS)
-endif
-
 ifeq ($(OS_ARCH),WINNT)
 OS_LIBS += $(call EXPAND_LIBNAME,version)
 endif
 
 ifdef _MSC_VER
 # Always enter a Windows program through wmain, whether or not we're
 # a console application.
 WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
 endif
-endif
 endif #LIBXUL_SDK
 
-# Make sure the standalone glue doesn't try to get libxpcom.so from mobile/app.
+# Make sure the standalone glue doesn't try to get libxpcom.so from b2g/app.
 NSDISTMODE = copy
 
 include $(topsrcdir)/config/rules.mk
 
-APP_ICON = mobile
+APP_ICON = b2g
 
 DEFINES += \
   -DAPP_NAME=$(MOZ_APP_NAME) \
   -DAPP_VERSION=$(MOZ_APP_VERSION) \
   -DMOZ_UPDATER=$(MOZ_UPDATER) \
   $(NULL)
 
+# strip a trailing slash from the repo URL because it's not always present,
+# and we want to construct a working URL in buildconfig.html
+# make+shell+sed = awful
+_dollar=$$
+SOURCE_REPO := $(shell cd $(srcdir)/.. && hg showconfig paths.default 2>/dev/null | head -n1 | sed -e "s/^ssh:/http:/" -e "s/\/$(_dollar)//" )
+# extra sanity check for old versions of hg
+# that don't support showconfig
+ifeq (http,$(patsubst http%,http,$(SOURCE_REPO)))
+DEFINES += -DMOZ_SOURCE_REPO="$(SOURCE_REPO)"
+endif
+
 ifeq ($(OS_ARCH),WINNT)
 REDIT_PATH = $(LIBXUL_DIST)/bin
 endif
 
 APP_BINARY = $(MOZ_APP_NAME)$(BIN_SUFFIX)
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 
@@ -126,17 +127,17 @@ else
 APPFILES = MacOS
 endif
 
 libs repackage::
 	mkdir -p $(DIST)/$(APP_NAME).app/Contents/MacOS
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents $(DIST)/$(APP_NAME).app --exclude English.lproj
 	mkdir -p $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
-	sed -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" -e "s/%APP_BINARY%/$(APP_BINARY)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(DIST)/$(APP_NAME).app/Contents/Info.plist
+	sed -e "s/%MOZ_APP_VERSION%/$(MOZ_APP_VERSION)/" -e "s/%MOZ_APP_NAME%/$(MOZ_APP_NAME)/" -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" -e "s/%APP_BINARY%/$(APP_BINARY)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(DIST)/$(APP_NAME).app/Contents/Info.plist
 	sed -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj/InfoPlist.strings
 	rsync -a $(DIST)/bin/ $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
 	$(RM) $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/mangle $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/shlibsign
 ifdef LIBXUL_SDK
 	cp $(LIBXUL_DIST)/bin/xulrunner$(BIN_SUFFIX) $(DIST)/$(APP_NAME).app/Contents/MacOS/$(APP_BINARY)
 	rsync -a --exclude nsinstall --copy-unsafe-links $(LIBXUL_DIST)/XUL.framework $(DIST)/$(APP_NAME).app/Contents/Frameworks
 else
 	rm -f $(DIST)/$(APP_NAME).app/Contents/MacOS/$(PROGRAM)
@@ -152,21 +153,16 @@ ifdef LIBXUL_SDK
 endif
 ifndef SKIP_COPY_XULRUNNER
 ifdef LIBXUL_SDK
 	$(NSINSTALL) -D $(DIST)/bin/xulrunner
 	(cd $(LIBXUL_SDK)/bin && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DIST)/bin/xulrunner && tar -xf -)
 endif
 endif # SKIP_COPY_XULRUNNER
 
-ifeq ($(MOZ_PLATFORM_MAEMO),6)
-	$(NSINSTALL) -D $(DIST)/bin/res/drawable
-	cp $(srcdir)/maemo/* $(DIST)/bin/res/drawable/
-	cp $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/favicon32.png $(DIST)/bin/res/drawable/
-endif
 	$(NSINSTALL) -D $(DIST)/bin/chrome/icons/default
 
 ifeq ($(OS_ARCH),WINNT)
 	cp $(srcdir)/$(APP_ICON).ico $(DIST)/bin/chrome/icons/default/$(APP_ICON).ico
 	$(REDIT_PATH)/redit$(HOST_BIN_SUFFIX) $(DIST)/bin/$(APP_BINARY) $(srcdir)/$(APP_ICON).ico
 endif
 
 endif
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..38312abac42830818edef700470cf1c59b25bb81
GIT binary patch
literal 4286
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
new file mode 100644
--- /dev/null
+++ b/b2g/app/b2g.js
@@ -0,0 +1,395 @@
+/* ***** 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 Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Matt Brubeck <mbrubeck@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 ***** */
+
+#filter substitution
+
+pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.xul");
+pref("general.useragent.compatMode.firefox", true);
+pref("browser.chromeURL", "chrome://browser/content/");
+#ifdef MOZ_OFFICIAL_BRANDING
+pref("browser.homescreenURL", "file:///system/home/homescreen.html");
+#else
+pref("browser.homescreenURL", "file:///data/local/homescreen.html,file:///system/home/homescreen.html");
+#endif
+
+// Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
+pref("browser.viewport.scaleRatio", -1);
+
+/* allow scrollbars to float above chrome ui */
+pref("ui.scrollbarsCanOverlapContent", 1);
+
+/* cache prefs */
+pref("browser.cache.disk.enable", false);
+pref("browser.cache.disk.capacity", 0); // kilobytes
+pref("browser.cache.disk.smart_size.enabled", false);
+pref("browser.cache.disk.smart_size.first_run", false);
+
+pref("browser.cache.memory.enable", true);
+pref("browser.cache.memory.capacity", 1024); // kilobytes
+
+/* image cache prefs */
+pref("image.cache.size", 1048576); // bytes
+
+/* offline cache prefs */
+pref("browser.offline-apps.notify", true);
+pref("browser.cache.offline.enable", true);
+pref("browser.cache.offline.capacity", 5120); // kilobytes
+pref("offline-apps.quota.max", 2048); // kilobytes
+pref("offline-apps.quota.warn", 1024); // kilobytes
+
+/* protocol warning prefs */
+pref("network.protocol-handler.warn-external.tel", false);
+pref("network.protocol-handler.warn-external.mailto", false);
+pref("network.protocol-handler.warn-external.vnd.youtube", false);
+
+/* http prefs */
+pref("network.http.pipelining", true);
+pref("network.http.pipelining.ssl", true);
+pref("network.http.proxy.pipelining", true);
+pref("network.http.pipelining.maxrequests" , 6);
+pref("network.http.keep-alive.timeout", 600);
+pref("network.http.max-connections", 6);
+pref("network.http.max-connections-per-server", 4);
+pref("network.http.max-persistent-connections-per-server", 4);
+pref("network.http.max-persistent-connections-per-proxy", 4);
+
+// See bug 545869 for details on why these are set the way they are
+pref("network.buffer.cache.count", 24);
+pref("network.buffer.cache.size",  16384);
+
+/* session history */
+pref("browser.sessionhistory.max_total_viewers", 1);
+pref("browser.sessionhistory.max_entries", 50);
+
+/* session store */
+pref("browser.sessionstore.resume_session_once", false);
+pref("browser.sessionstore.resume_from_crash", true);
+pref("browser.sessionstore.resume_from_crash_timeout", 60); // minutes
+pref("browser.sessionstore.interval", 10000); // milliseconds
+pref("browser.sessionstore.max_tabs_undo", 1);
+
+/* these should help performance */
+pref("mozilla.widget.force-24bpp", true);
+pref("mozilla.widget.use-buffer-pixmap", true);
+pref("mozilla.widget.disable-native-theme", true);
+pref("layout.reflow.synthMouseMove", false);
+
+/* download manager (don't show the window or alert) */
+pref("browser.download.useDownloadDir", true);
+pref("browser.download.folderList", 1); // Default to ~/Downloads
+pref("browser.download.manager.showAlertOnComplete", false);
+pref("browser.download.manager.showAlertInterval", 2000);
+pref("browser.download.manager.retention", 2);
+pref("browser.download.manager.showWhenStarting", false);
+pref("browser.download.manager.closeWhenDone", true);
+pref("browser.download.manager.openDelay", 0);
+pref("browser.download.manager.focusWhenStarting", false);
+pref("browser.download.manager.flashCount", 2);
+pref("browser.download.manager.displayedHistoryDays", 7);
+
+/* download alerts (disabled above) */
+pref("alerts.slideIncrement", 1);
+pref("alerts.slideIncrementTime", 10);
+pref("alerts.totalOpenTime", 6000);
+pref("alerts.height", 50);
+
+/* download helper */
+pref("browser.helperApps.deleteTempFileOnExit", false);
+
+/* password manager */
+pref("signon.rememberSignons", true);
+pref("signon.expireMasterPassword", false);
+pref("signon.SignonFileName", "signons.txt");
+
+/* autocomplete */
+pref("browser.formfill.enable", true);
+
+/* spellcheck */
+pref("layout.spellcheckDefault", 0);
+
+/* block popups by default, and notify the user about blocked popups */
+pref("dom.disable_open_during_load", true);
+pref("privacy.popups.showBrowserMessage", true);
+
+pref("keyword.enabled", true);
+pref("keyword.URL", "http://www.google.com/m?ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q=");
+
+pref("accessibility.typeaheadfind", false);
+pref("accessibility.typeaheadfind.timeout", 5000);
+pref("accessibility.typeaheadfind.flashBar", 1);
+pref("accessibility.typeaheadfind.linksonly", false);
+pref("accessibility.typeaheadfind.casesensitive", 0);
+
+// pointer to the default engine name
+pref("browser.search.defaultenginename", "chrome://browser/locale/region.properties");
+
+// SSL error page behaviour
+pref("browser.ssl_override_behavior", 2);
+pref("browser.xul.error_pages.expert_bad_cert", false);
+
+// disable logging for the search service by default
+pref("browser.search.log", false);
+
+// disable updating
+pref("browser.search.update", false);
+pref("browser.search.update.log", false);
+pref("browser.search.updateinterval", 6);
+
+// enable search suggestions by default
+pref("browser.search.suggest.enabled", true);
+
+// tell the search service that we don't really expose the "current engine"
+pref("browser.search.noCurrentEngine", true);
+
+// enable xul error pages
+pref("browser.xul.error_pages.enabled", true);
+
+// disable color management
+pref("gfx.color_management.mode", 0);
+
+// don't allow JS to move and resize existing windows
+pref("dom.disable_window_move_resize", true);
+
+// prevent click image resizing for nsImageDocument
+pref("browser.enable_click_image_resizing", false);
+
+// controls which bits of private data to clear. by default we clear them all.
+pref("privacy.item.cache", true);
+pref("privacy.item.cookies", true);
+pref("privacy.item.offlineApps", true);
+pref("privacy.item.history", true);
+pref("privacy.item.formdata", true);
+pref("privacy.item.downloads", true);
+pref("privacy.item.passwords", true);
+pref("privacy.item.sessions", true);
+pref("privacy.item.geolocation", true);
+pref("privacy.item.siteSettings", true);
+pref("privacy.item.syncAccount", true);
+
+// URL to the Learn More link XXX this is the firefox one.  Bug 495578 fixes this.
+pref("browser.geolocation.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/geolocation/");
+
+// base url for the wifi geolocation network provider
+pref("geo.wifi.uri", "https://maps.googleapis.com/maps/api/browserlocation/json");
+
+// enable geo
+pref("geo.enabled", true);
+
+// content sink control -- controls responsiveness during page load
+// see https://bugzilla.mozilla.org/show_bug.cgi?id=481566#c9
+pref("content.sink.enable_perf_mode",  2); // 0 - switch, 1 - interactive, 2 - perf
+pref("content.sink.pending_event_mode", 0);
+pref("content.sink.perf_deflect_count", 1000000);
+pref("content.sink.perf_parse_time", 50000000);
+
+pref("javascript.options.mem.high_water_mark", 32);
+
+// Maximum scripts runtime before showing an alert
+pref("dom.max_chrome_script_run_time", 0); // disable slow script dialog for chrome
+pref("dom.max_script_run_time", 20);
+
+// plugins
+pref("plugin.disable", true);
+pref("dom.ipc.plugins.enabled", true);
+
+// product URLs
+// The breakpad report server to link to in about:crashes
+pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
+pref("app.releaseNotesURL", "http://www.mozilla.com/%LOCALE%/b2g/%VERSION%/releasenotes/");
+pref("app.support.baseURL", "http://support.mozilla.com/b2g");
+pref("app.feedbackURL", "http://input.mozilla.com/feedback/");
+pref("app.privacyURL", "http://www.mozilla.com/%LOCALE%/m/privacy.html");
+pref("app.creditsURL", "http://www.mozilla.org/credits/");
+pref("app.featuresURL", "http://www.mozilla.com/%LOCALE%/b2g/features/");
+pref("app.faqURL", "http://www.mozilla.com/%LOCALE%/b2g/faq/");
+
+// Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
+pref("security.alternate_certificate_error_page", "certerror");
+
+pref("security.warn_viewing_mixed", false); // Warning is disabled.  See Bug 616712.
+
+// Override some named colors to avoid inverse OS themes
+pref("ui.-moz-dialog", "#efebe7");
+pref("ui.-moz-dialogtext", "#101010");
+pref("ui.-moz-field", "#fff");
+pref("ui.-moz-fieldtext", "#1a1a1a");
+pref("ui.-moz-buttonhoverface", "#f3f0ed");
+pref("ui.-moz-buttonhovertext", "#101010");
+pref("ui.-moz-combobox", "#fff");
+pref("ui.-moz-comboboxtext", "#101010");
+pref("ui.buttonface", "#ece7e2");
+pref("ui.buttonhighlight", "#fff");
+pref("ui.buttonshadow", "#aea194");
+pref("ui.buttontext", "#101010");
+pref("ui.captiontext", "#101010");
+pref("ui.graytext", "#b1a598");
+pref("ui.highlight", "#fad184");
+pref("ui.highlighttext", "#1a1a1a");
+pref("ui.infobackground", "#f5f5b5");
+pref("ui.infotext", "#000");
+pref("ui.menu", "#f7f5f3");
+pref("ui.menutext", "#101010");
+pref("ui.threeddarkshadow", "#000");
+pref("ui.threedface", "#ece7e2");
+pref("ui.threedhighlight", "#fff");
+pref("ui.threedlightshadow", "#ece7e2");
+pref("ui.threedshadow", "#aea194");
+pref("ui.window", "#efebe7");
+pref("ui.windowtext", "#101010");
+pref("ui.windowframe", "#efebe7");
+
+// replace newlines with spaces on paste into single-line text boxes
+pref("editor.singleLine.pasteNewlines", 2);
+
+// threshold where a tap becomes a drag, in 1/240" reference pixels
+// The names of the preferences are to be in sync with nsEventStateManager.cpp
+pref("ui.dragThresholdX", 25);
+pref("ui.dragThresholdY", 25);
+
+// Layers Acceleration
+pref("layers.acceleration.disabled", false);
+
+// Web Notifications
+pref("notification.feature.enabled", true);
+
+// IndexedDB
+pref("indexedDB.feature.enabled", true);
+pref("dom.indexedDB.warningQuota", 5);
+
+// prevent video elements from preloading too much data
+pref("media.preload.default", 1); // default to preload none
+pref("media.preload.auto", 2);    // preload metadata if preload=auto
+
+//  0: don't show fullscreen keyboard
+//  1: always show fullscreen keyboard
+// -1: show fullscreen keyboard based on threshold pref
+pref("widget.ime.android.landscape_fullscreen", -1);
+pref("widget.ime.android.fullscreen_threshold", 250); // in hundreths of inches
+
+// optimize images memory usage
+pref("image.mem.decodeondraw", true);
+pref("content.image.allow_locking", false);
+pref("image.mem.min_discard_timeout_ms", 10000);
+
+// enable touch events interfaces
+pref("dom.w3c_touch_events.enabled", true);
+pref("dom.w3c_touch_events.safetyX", 0); // escape borders in units of 1/240"
+pref("dom.w3c_touch_events.safetyY", 120); // escape borders in units of 1/240"
+
+#ifdef MOZ_SAFE_BROWSING
+// Safe browsing does nothing unless this pref is set
+pref("browser.safebrowsing.enabled", true);
+
+// Prevent loading of pages identified as malware
+pref("browser.safebrowsing.malware.enabled", true);
+
+// Non-enhanced mode (local url lists) URL list to check for updates
+pref("browser.safebrowsing.provider.0.updateURL", "http://safebrowsing.clients.google.com/safebrowsing/downloads?client={moz:client}&appver={moz:version}&pver=2.2");
+
+pref("browser.safebrowsing.dataProvider", 0);
+
+// Does the provider name need to be localizable?
+pref("browser.safebrowsing.provider.0.name", "Google");
+pref("browser.safebrowsing.provider.0.keyURL", "https://sb-ssl.google.com/safebrowsing/newkey?client={moz:client}&appver={moz:version}&pver=2.2");
+pref("browser.safebrowsing.provider.0.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/report?");
+pref("browser.safebrowsing.provider.0.gethashURL", "http://safebrowsing.clients.google.com/safebrowsing/gethash?client={moz:client}&appver={moz:version}&pver=2.2");
+
+// HTML report pages
+pref("browser.safebrowsing.provider.0.reportGenericURL", "http://{moz:locale}.phish-generic.mozilla.com/?hl={moz:locale}");
+pref("browser.safebrowsing.provider.0.reportErrorURL", "http://{moz:locale}.phish-error.mozilla.com/?hl={moz:locale}");
+pref("browser.safebrowsing.provider.0.reportPhishURL", "http://{moz:locale}.phish-report.mozilla.com/?hl={moz:locale}");
+pref("browser.safebrowsing.provider.0.reportMalwareURL", "http://{moz:locale}.malware-report.mozilla.com/?hl={moz:locale}");
+pref("browser.safebrowsing.provider.0.reportMalwareErrorURL", "http://{moz:locale}.malware-error.mozilla.com/?hl={moz:locale}");
+
+// FAQ URLs
+pref("browser.safebrowsing.warning.infoURL", "http://www.mozilla.com/%LOCALE%/%APP%/phishing-protection/");
+pref("browser.geolocation.warning.infoURL", "http://www.mozilla.com/%LOCALE%/%APP%/geolocation/");
+
+// Name of the about: page contributed by safebrowsing to handle display of error
+// pages on phishing/malware hits.  (bug 399233)
+pref("urlclassifier.alternate_error_page", "blocked");
+
+// The number of random entries to send with a gethash request.
+pref("urlclassifier.gethashnoise", 4);
+
+// The list of tables that use the gethash request to confirm partial results.
+pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
+
+// If an urlclassifier table has not been updated in this number of seconds,
+// a gethash request will be forced to check that the result is still in
+// the database.
+pref("urlclassifier.confirm-age", 2700);
+
+// Maximum size of the sqlite3 cache during an update, in bytes
+pref("urlclassifier.updatecachemax", 4194304);
+
+// URL for checking the reason for a malware warning.
+pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
+#endif
+
+// True if this is the first time we are showing about:firstrun
+pref("browser.firstrun.show.uidiscovery", true);
+pref("browser.firstrun.show.localepicker", true);
+
+// initiated by a user
+pref("content.ime.strict_policy", true);
+
+// True if you always want dump() to work
+//
+// On Android, you also need to do the following for the output
+// to show up in logcat:
+//
+// $ adb shell stop
+// $ adb shell setprop log.redirect-stdio true
+// $ adb shell start
+pref("browser.dom.window.dump.enabled", false);
+
+
+
+// Temporarily relax file:// origin checks so that we can use <img>s
+// from other dirs as webgl textures and more.  Remove me when we have
+// installable apps or wifi support.
+pref("security.fileuri.strict_origin_policy", false);
+
+// Temporarily force-enable GL compositing.  This is default-disabled
+// deep within the bowels of the widgetry system.  Remove me when GL
+// compositing isn't default disabled in widget/src/android.
+pref("layers.acceleration.force-enabled", true);
+
+// screen.enabled and screen.brightness properties.
+pref("dom.screenEnabledProperty.enabled", true);
+pref("dom.screenBrightnessProperty.enabled", true);
copy from mobile/xul/app/macbuild/Contents/Info.plist.in
copy to b2g/app/macbuild/Contents/Info.plist.in
--- a/mobile/xul/app/macbuild/Contents/Info.plist.in
+++ b/b2g/app/macbuild/Contents/Info.plist.in
@@ -24,17 +24,17 @@
 				<string>HTML</string>
 			</array>
 			<key>CFBundleTypeRole</key>
 			<string>Viewer</string>
 		</dict>
 		<dict>
 			<key>CFBundleTypeExtensions</key>
 			<array>
-			    <string>text</string>
+			  <string>text</string>
 				<string>txt</string>
 				<string>js</string>
 				<string>log</string>
 				<string>css</string>
 				<string>xul</string>
 				<string>rdf</string>
 			</array>
 			<key>CFBundleTypeIconFile</key>
@@ -67,25 +67,25 @@
 				<string>JPEG</string>
 				<string>PNGf</string>
 			</array>
 			<key>CFBundleTypeRole</key>
 			<string>Viewer</string>
 		</dict>
 	</array>
 	<key>CFBundleExecutable</key>
-	<string>fennec</string>
+	<string>%MOZ_APP_NAME%</string>
 	<key>CFBundleGetInfoString</key>
 	<string>%APP_NAME% %APP_VERSION%</string>
 	<key>CFBundleIconFile</key>
-	<string>fennec</string>
+	<string>%MOZ_APP_NAME%</string>
 	<key>CFBundleIdentifier</key>
-	<string>org.mozilla.fennec</string>
+	<string>org.mozilla.b2g</string>
 	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
+	<string>%MOZ_APP_VERSION%</string>
 	<key>CFBundleName</key>
 	<string>%APP_NAME%</string>
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
 	<string>%APP_VERSION%</string>
 	<key>CFBundleSignature</key>
 	<string>MOZB</string>
copy from mobile/xul/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
copy to b2g/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
copy from mobile/xul/app/nsBrowserApp.cpp
copy to b2g/app/nsBrowserApp.cpp
--- a/mobile/xul/app/nsBrowserApp.cpp
+++ b/b2g/app/nsBrowserApp.cpp
@@ -64,23 +64,16 @@
 #define snprintf _snprintf
 #define strcasecmp _stricmp
 #endif
 #include "BinaryPath.h"
 
 #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
 
 #include "mozilla/Telemetry.h"
-#if MOZ_PLATFORM_MAEMO == 6
-#include "nsFastStartupQt.h"
-// this used by nsQAppInstance, but defined only in nsAppRunner
-// FastStartupQt using gArgc/v so we need to define it here
-int    gArgc;
-char **gArgv;
-#endif
 
 static void Output(const char *fmt, ... )
 {
   va_list ap;
   va_start(ap, fmt);
 
 #if defined(XP_WIN) && !MOZ_WINCONSOLE
   PRUnichar msg[2048];
@@ -206,35 +199,16 @@ static int do_main(const char *exePath, 
       return 255;
     }
     result = XRE_main(argc, argv, &sAppData);
   }
 
   return result;
 }
 
-#if MOZ_PLATFORM_MAEMO == 6
-static bool
-GeckoPreLoader(const char* execPath)
-{
-  nsresult rv = XPCOMGlueStartup(execPath);
-  if (NS_FAILED(rv)) {
-    Output("Couldn't load XPCOM.\n");
-    return false;
-  }
-
-  rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
-  if (NS_FAILED(rv)) {
-    Output("Couldn't load XRE functions.\n");
-    return false;
-  }
-  return true;
-}
-#endif
-
 int main(int argc, char* argv[])
 {
   char exePath[MAXPATHLEN];
 
   nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
   if (NS_FAILED(rv)) {
     Output("Couldn't calculate the application directory.\n");
     return 255;
@@ -259,34 +233,30 @@ int main(int argc, char* argv[])
   IO_COUNTERS ioCounters;
   gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
   if (gotCounters && !ioCounters.ReadOperationCount)
 #endif
   {
       XPCOMGlueEnablePreload();
   }
 
-#if MOZ_PLATFORM_MAEMO == 6
-  nsFastStartup startup;
-  startup.CreateFastStartup(argc, argv, exePath, GeckoPreLoader);
-#else
+
   rv = XPCOMGlueStartup(exePath);
   if (NS_FAILED(rv)) {
     Output("Couldn't load XPCOM.\n");
     return 255;
   }
   // Reset exePath so that it is the directory name and not the xpcom dll name
   *lastSlash = 0;
 
   rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
   if (NS_FAILED(rv)) {
     Output("Couldn't load XRE functions.\n");
     return 255;
   }
-#endif
 
 #ifdef XRE_HAS_DLL_BLOCKLIST
   XRE_SetupDllBlocklist();
 #endif
 
   if (gotCounters) {
 #if defined(XP_WIN)
     XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS,
copy from mobile/xul/branding/official/Makefile.in
copy to b2g/branding/official/Makefile.in
--- a/mobile/xul/branding/official/Makefile.in
+++ b/b2g/branding/official/Makefile.in
@@ -29,17 +29,17 @@
 # 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 = ../../../..
+DEPTH = ../../..
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 DIRS = \
 	content \
copy from mobile/xul/branding/official/android-resources.mn
copy to b2g/branding/official/android-resources.mn
--- a/mobile/xul/branding/official/android-resources.mn
+++ b/b2g/branding/official/android-resources.mn
@@ -1,6 +1,1 @@
-mobile/xul/app/android/drawable/alertaddons.png
-mobile/xul/app/android/drawable/alertdownloads.png
-mobile/xul/branding/official/content/splash.png
-mobile/xul/branding/official/content/splash_v9.9.png
-mobile/xul/branding/official/content/splash_v8.9.png
-mobile/xul/branding/official/content/favicon32.png
+b2g/branding/official/content/splash.png
copy from mobile/xul/branding/official/configure.sh
copy to b2g/branding/official/configure.sh
--- a/mobile/xul/branding/official/configure.sh
+++ b/b2g/branding/official/configure.sh
@@ -1,3 +1,3 @@
-MOZ_APP_DISPLAYNAME=Firefox
-ANDROID_PACKAGE_NAME=org.mozilla.firefox
+MOZ_APP_DISPLAYNAME=B2G
+ANDROID_PACKAGE_NAME=org.mozilla.b2g
 MOZ_UPDATER=
copy from mobile/xul/branding/official/content/Makefile.in
copy to b2g/branding/official/content/Makefile.in
--- a/mobile/xul/branding/official/content/Makefile.in
+++ b/b2g/branding/official/content/Makefile.in
@@ -1,25 +1,12 @@
 # Branding Makefile
 #  - jars chrome artwork
 
-DEPTH = ../../../../..
+DEPTH = ../../../..
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 include $(topsrcdir)/config/rules.mk
 
-LINUX_BRANDING_FILES = \
-	fennec_26x26.png \
-	fennec_40x40.png \
-	fennec_48x48.png \
-	fennec_72x72.png \
-	fennec_scalable.png \
-	fennec_maemo_icon26.txt \
-	$(NULL)
-
-export::
-	$(NSINSTALL) -D $(DIST)/branding
-	cp $(addprefix $(srcdir)/, $(LINUX_BRANDING_FILES)) $(DIST)/branding/
-	$(NSINSTALL) -D $(DIST)/install
copy from mobile/xul/branding/official/content/about.png
copy to b2g/branding/official/content/about.png
copy from mobile/xul/branding/official/content/favicon32.png
copy to b2g/branding/official/content/favicon32.png
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b7513c2e4689ae656c99a0e79ae266a5931594e3
GIT binary patch
literal 5302
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
IM6N<$g8mX-d;kCd
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c8bee8fca98d4e57315f1198594ff31d48caefad
GIT binary patch
literal 8267
zc$@)CAhh3!P)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^03Y*7L_t(|+U=WrwB1#8?>}p;-(x?|`{d;PBq0fb
z@GyX=Akb1khrN2MmFm@6+goj|UWR(Fqt@%VUa8_$>#J3(#fr6hwbd4>tqO`(K|lh8
zKms8lAtxuvdGB-f-oMvcYu-P8J28muMWnsGWAr!18o$Tc`~3EtYtHYS^SkDPf5D@^
z=CY^#-OBRk@vm{He~p(^mR~r4($7VQ&xUZjpw}tUqoN3uFzdw~ww?Av%I9}_m)|O#
z=?OS00M!*2lN|Zp|6dBIFF$A05&kFLSpAEJzOz+rU}<yBD#9iG46YhuWJy1RBmF28
zkrJvXqOm$h=N34AbehL^J<`g?$M;O$^3Csu;lhpi+`|t5R99b0^7wcDZ7HC>?lL-$
zeVaNUtDnD(p!RkZ4ZXZFbQ<+#BP_jOt!#PDX=>YwA+{_VW@)6U0=3@v6JTlYdeM8v
zGtYjj*?BaT-49Htdp~+3>5)CVL^^MElY9R$TYN03t-6@*;qU#wS3rH;<#ZmqmHO)E
zoF-=AtE%s`Esa{u3~pJ+$n!SIr59~gJ5~*$MH8b~6~Lkw8cI<&KmI=+0Kud13Y>sd
z!hy_j)4?hE&R^c6j^BGs<mlZCcH+J_q{r|2i)YFL%+nRTn1778In)S7&i+%WuKu&i
z;EE-~t5>Lz3wEfpu0Ed^JpW9!Y@oqHt`H9m1$A8xQ3@-iphfR&d)HPV_vMHJgNmza
zNpzgwyDDNP4J-3%<x9HN%~w}NepGai9;>Xp1iNtPUq%7hXP(bHUb;!W`z!mO@VuCR
zjM}=(cldDh5gO~xZ8RbV*KB2Q(+;(1+ZY!;djnbK2*hEXXIo9tFd&q|dIUl6z2T7Z
zc~1c+6eC`kEff#!n&gMy*r~qst`~Co<}Rr#Ry?q{_I0RwH%=b>VV<<*=_)|~lfvI{
zG4X3|1Dk*7#IxGk%K@mayZm|^F26%nmxlF9E`6(>P5;u(EE|hC<Lq_J&vfW^Q~ETV
z*)$X$awimC$VITeye>Qx9;_Fvl+UaeaxdggNUUdF#k1q`v)Opfud(r$|BT};;l}sA
zMjra?4!QKwv)<RPUwOx;RxTMBf7^3j4zTZCXFhWnkp1~{&%o>5(JNo6RP@JOQMsS*
zExYQ|J{Wwhj;d0vDAm7gJAGrD2_oTHSDa3Bq(WFx1Yy9I&4Ua@5aphV11*9Ev;xJC
zCrx^HP6QDsL?{Gu0jHsBh21kL^YbY;y!8`Y_p&N)di}E?n~>{1b4b18ld}hYFm%iM
z`o{d7+dsMIU5~tF6`S6F_~|Rae(HQ|T4*ZGJtX<2cp!hHdezR4Mr*G6b8CiQ9T=oi
zjZ|}ZEqzPYP^phnX;#_#+_gm20No#B`a;gV`FhS+xSQa>Zn`gj2lndUB`69Mpp@#p
zUP=Iz5)8cvnLs9jMKRsAEEbNV^9j~#_U)bH`(M1354~uDSHHFi4D;}=2`;`?$&Cj-
zqQ)+X-ha+#$KMKY@Cz5Q_L|$Do&{td-?7Ec<`22VQjdys+h4A^YtO>)#X3f!FjS5H
zJ_bhC6E_D4Ys1v~2U&U63jAP$7k=|vwmfzVRo^1WbB?~~jpVQYBcj4#6ev{r;-371
z0177_E0FpUCsHT0GRvOhZHmI<QrN$LfyrslzHfYw_rLfcum7!i(4&kmY-h(S9+LMy
z`~h|DFAm&2aMjvZt$xY(_C9?Kn3(%OG1JB#o2NC|seJjY`!61#Bfiiobpg2=q7b2z
zdFH#qY_4&~#(Bf1F5=AHe}xx|ug5%m;fvY-x(}13p4<tUD}B5Wu)YL6D~jBEatEmw
zQt#Q{N@x`h8z|Du(d}9m7E<E0#T$3DdHz-B^E)4{aQBbuFteYPmAg6gwX@ZG$6hY&
zJ(D}8zc#aH{FaNK1#sXmcKqxXF#9_z#4qN!#S9e|*eT1TGrTppl>ho1&*rg^z*O*2
zAM<L6uT7rLFMR7-vfSVUMQuQ+H8g+n>vwYA*{cb>P*sZ9Xf$9-AV8sT-s45c9oRrP
zG?#K<CZQH8+FeVxYe_qn?qb2=-AB+nzsX%U|2DVZf1Jy%{vgNh2<Uf~VA&ED!i%_M
z>*skN_sNELoUS?#-(TB){ao@hDPZDded{CC{=A)&%@%Z&XYhi4D#I~>IMR;Bx)`E5
zrdlUx_S3rW0LKqbQ-~(6E0zpryl3!@tbNP77><Ql38B)&MiDCrlt$^&1*{heDMR7i
zM;6GP#}<wvcch6Wx1Ox+NEa<dS8-(T;|w19I^VzPmCQ`H`0AIwz;9l0oHPrmtX#=m
z6KnX`B{%T;3%i{Do@X80`M!TRZPf*<+~(hX=&9uaZ(6}QN!z}9dZwW04_NiWF?3`|
zrXB4mM>1cKcM|gU0(pC$WNwbRqa6yXFp;7@U|0yNeEvCq#P&0W5a;PlH=<Mtc1j^i
zQ9uv$AXiXW&tltRolxYS!a<P<*`mXHMc%gPsKz4)6ZYTvbzb%>UC!OHo@}N|F*k+l
zB&^-wd8oO8oge-Ou6*0`2eeKeJ^i<K?Rv@>FgfSl_%TbkGUl`wEhU}ubPhYRi2|E=
za0VnqT!dtrWI6+_2qK8<nxJlQ3mMH7gJfQjqbNj?i6Rq71rmg|2;JU&CMD<%^vA4R
zT4&S7L4qhC?>OwDqdHh+{qvTw^rB@*+F`}kwS4BbCXeqv2%S5KH?Bd~H<C@wlRh%R
z+h5n=$b}bj_{;ZF9UZ#y+JC~@f9k_O4S4RhORE34{e>gUKb}&|6xfd7wMVo;qzqeV
z1zJ%QP*_1Ljj1RqO~cH-1;)eExa+fbQ*BfTfk>C5?jf*(at`TbhGjzJPbNi~lx~sb
zj?{uxnoh@)=AJw;9Qw{qjy<p!wd*Dh-L(|uJ23QYTHn13*O{bmO&|A6Rr$)>ek9j@
zWxLw_x&5yXipfu$^^Paz2f?W~-A|rP?YHmas^1w|(Z3>M;YdPyG{q+tr$7@SwgfCu
z3Q+=Dqku2~Wk3fC9YE>=M(20)8!xRg_lqwk4nT{iRT<;Xl`kOLvX$zZ4LED@A~-L-
zh#(ZMOoDPJ<W7-U$O})F2w4h6>IwS#s5T-F>5c4uxXGD=JE3wr&2zSM{HDj~L{%=_
zP;mdRZdGA(P8!R`uGsYIdp_}$EMV^4D~?gPvAKP1Tx#)ML1GXa;5p&Ps%HU!(WQ$A
z1|2HmhUU<oHmXxFG6c;SL<vSiY=n7gT(xTjZ`!$sY%#}qkMjaSuU7CvVxcHJSuUi7
zkfok1Riuf~I&_R^*>Was`4)2r4siA0z1;Aj)!5d<m{oP!yEWa%L;CuUQCR}ABIn4r
zqWRS?{rccf${IXb_*HM$E*o1sUf_}fpM$d=9R;}DB0&JXVn&=QEkFbURVK8e5G%b@
zN08j3jVE;qRW}rijt!Td&hqFSCg!0#mEuM4fa_I6Uch<5^^{$Bg|(U@Q#}6nx6z%S
z!8EE2o_`?=<Kx_TYt9X!$4)ImMX0YeEbIwzqr=$r2wKHxGe7XtCOi1C;45)i5vjoc
zH#_gecD=$WycJYz@To?OLR|S{g>u#fLHV+%R}Q=utT)v9LfWl@%Gxzl&fJWdoW$<h
z&FH)S5WDI5%)aSvrXQOkh$6f%b3yNVuHYQjg0*EN$a29tO)@h}(wYYaW@rR!BI408
zoHN{ePnXT)6f+s|QcZ2SL)X^fgB)ELf=KhD-(>l-KF!2WRlwjMj5GhgR-LUEq>*;K
za#?|GTO<OdBAobgcD<CvOD~24h=7vvR%_5Epl^AVjn{sR+UAwSOGiOK6_echx!ZZg
zfB9>cKKDWj2QG7XFZf>i>%34{u-$^iqtnEzS7UunmgS_@;VUu4+%(1E!*mWD!21Gf
zOS%1?BWyf3KqfQ7Mo4367d<?TolJ0x3L{;7H98yeiGR`sl+u47olNCUaA{ekp$y`B
zwVSAu7$EXv1W`(rpVbN#MyM#DQZvZhQQEieCL9RZD;3`M$z$AnY=n(xZDaZNtrX7S
zG7nM~LEZ~qYbNh{kgVN7yoZTNRHKO=9m59^^>Z#@`Ws&@^Jo$B+(BO-`}RIW^?X>E
zwG^{Ls1{JmBgh@1El5K5@n-9ucdQsa?|<%^dQu)R^`9$Ro8SeuPva5~g@VWcrYuu+
zse}_}j5;}#R_MTBq7V}W=rAOx)+iqSJpEz9hrhYNwzsy~z2rGuaLo(ZaMh)ReS>t`
z1xe~iGDn(0R%o)sQ(dzP2?B~DC!Lw0ee@_<nqsY|vu`hm0`bgDO!9%>I)mkP&Hlq0
ztt~~jpqR?>ZI4n89oBH|45d9qC%D3P?2S*dfX*jQ$46YCj%C{Ch<K%3*F&Y3v3ZZu
z8rOAD(I~AD14@^|tI!a{0VWPGQAF6NVyYFw{+Qptd7KX(zL;&-oWtOnRm5>fAqv~g
zDPdE}Tw;EX#m5d)S+Nu^pvT6@?mdb#3OhH4)e-shaqRpo${56ZWO0FsefRP88!q8B
zFZ~vhKxOqB(!G0#R$0&;RMaFtFoX9b`J&$FlI*faKEC3tO|L()>!bzLU-vM6(!RhM
za8}_mK?1>{K`FePsNEIX7*wD!fkqpRjtoI1z|<nbMunhWL3@pfB7&&OvLz8CXK$gl
zVi|d1X?GIR#e^iuNYbo#E?As6O13b^+(Ubq+qH|<uKOv(<GLx<TDtr9;1=dkVTiXD
zu?`)@+_UR(wr}3WAHHQP$!tzzV}pFb;uanF4oV7q(V*7nEBnXemjzKJa#pW@5(em|
z*``x}KytO-bsZ7~C0}KFW-maf!3fG|lqqN4R6?qKRZKM^s7BP5^r7Q`(1Q&%7o2WM
zegt_tMJquYg+rHN@{}w@4UeGGjN<6AvQ{W8t|)NM;=S$RjNsD@yhBi^Ky&EuJhUF;
ziYpeF`c^=_l2BW*8p-zq8Imqw8vV59=hRJeOU<QKkF%{6Pf~!h@>Ozv*=81RJrZiX
z^_Xf1UJy|bl`mCBVJZd_2h7fT_UxX<#39p1x`bYFVCxyQm#*iUXQ!-aW^^ZK$Ty6l
zy(<-`)e{vUg6M!`atfPt@t(3ob{4!xL`swQzKlZNBjQlnu&^)#;Q(s>7`1gx?8G>Y
zO^Wov07&qK$LMJuK3rv%km`sfDI|V^0%qR30UfBcn0ENW;Ywpiyv8fgstkK7Q0PFR
zLWLJN@X#WUJlMr~!6-!|g84Y+-A7-DpAbHH%QSDjdYZ61OWy93eBg<!QK?fnK|oT1
zRi}~ey&v0MK!q`4Z5avVgy4dBS0-4_Ar4%Uf+?``9qOC<DGs-h_9F4-24o3R6p$y}
zd$6Al5rf;HeTSQWf&zx$wx5NMY(2NVw}mVTQ0hdkSGv9wK+MV6GofN)Jm<i}DPgE-
zM2bMcfU(>W4$(aOO!^uzw%g{$ZqD%P2%lM;l9OSRlhl~tML;P;glNN7%*+(J*+=L8
zyUK)1e3>JQN2CmYc#Dz(mkZ=A#MSZBi%6Q`5+NRqkk%}c<pfeNaUfz~Nhq3QDo^Yq
zPjUe}pO2=k0#nh5)@5QMf|hc%Mx)SyMuiIN;mF~f&?qXg5E>!SLKMPfXNUZW1%iN}
zZ{Q^P>GJI4%$JJ&i84gwBtNJd13eBwBSnEoPk5wsiQe$mp#y;;!xtLK8o16ed<H5k
zaEm!EDX3R+zV?GUuX@{vYK=b#QR6O{eqtWb-oH?h!Xi#6vXX=lG~RiX(&Z<6g-^HR
z@tLI-3-v10VyM?OI)V$=w%Cv!WU(vQEXSoeF3WI5fiDVNZt+Ed&&%O*TaF&+`J%uk
zNjU*p<6VLH0`V5H_GAPQ>v2g!6a&dTo)A?XrfB7e7H}P0CqW8FXV%ldNqGBfZ>KZ9
zaL4)YKA1nr0<z<2D22r<5${n++fr=?cof={Ij(4hR^SRxWE?@Ls8$q#fyj6Q4PDdZ
zTWhZ4g;W27J!U<9CP9=r#qSkbX%YewSHb0FDy*?Yp`sC$w7Hub$Ii{5f}jM+(j@Uc
z7jQ~pTLq_YE?_prXEEVGh;2C<Yhvu8#dQmO=4jiH?|*PF+3hLmwEeT6nhN{ePdLv3
zt@L`2qdV)U4g_Tc&_7Q6MS(F;t!N?zv4OZM1PEb3S;3hKUmtrX*SB864V^1#QzJGx
z4uium#4In1f51!n@8-NEGc=YCa<sCVzdN>;58SbpX;;NePoT8M+oE(0@jdewL_FQ2
zbG-UW$NIq(d%TUP0@Xf1&=(?E=`OBYf_l?il05~T1(7_L2YxCa@bE7+|3f~}{WU*O
zeW|Z&#&;(y*%+Z?gAO&yfT<dSNKs^tsYhD`R)}JVE2?CCDxPTFD7q1W*3?vrErh>G
z&gVPbGZ`>#F0bt3>iSNKuuf7LLN}V|(Gh~tVQOnv5;h&@ykUg#%6g2?$@l&cw8r}r
z;3qgIWP6V=^}QCy4;*7zo)E9AQtKCz$-H#i2=e0@;3(#E5HE96zB~Rvv8uTwn7iQ9
z-6vYW@WtzHe(c5vcDMyg)QIq|On$^E2vlhRUJ$Q|Y5{!%A=1vN)D!`pI960*m>XXp
zUN%6b5s-#eRN(lJ&7HioaaYOwh+@t)kpiSM3o}#bgOAeH5&GHZQ$1%RH~;oNHh*jx
zad!fO7@v1bEAS5I1Y0<kpVnq%V3J0o%j|wf;|!0_96l|O+~GQc&n#$9GFcGTQM2Rz
zz%SgC&q4k~7udNyX5{U=?A_agZ`=9e_p2)_WL-;VPSY6Gc+n^i$}5x?l+x5kt9Wwa
z&=Y7)7=sEl6)gAMxya@-YxE6;1hFAEAzlKMDGg3}SB5qqOCfDJv~6?GU+hHP{3!qX
z_?ak`L2Vd!{7?yc;_+T^&f}AeH@#v8l9aUNab1h42!7Urv$(`kq-Es5I&8O8Tzkg9
z=cf`P=iZ+Ikf;6;6RE5-ok#INpcdvVwZWhaO_89SMp;1>o}dvCP$%qk&<1>HKx-QP
z3b&AQ$9Ehn*2avj3}_Angt12J(u!^7$r49r!9pjeqbj`o@XMKPY=+qiQS1qIg3TSa
zoAipmG9mI_Vdh%=(zzY{v?E)v#7i~O%CL#U7oMVH@wtF5qm^<_T9Yz=#m(*ucU%+l
z>@O5Qoe#)6YCNn-mQLkS|MEKf?r$-=3fhw?jj@P0@MRin6<&jB)^LG>Btt2U1cpK>
zo_ATuSHIF>;!(%+L_n=+s8q`WN-06CBhs+4k#haaIeam>3_mnR94M5e_{>w#;|FYt
zU=W*^tZVKW>YHZkSeNcJ*hNeKs*rrHC>L1^OR?b4M!*Qku>x<cnxEnQz!QXj(z?K<
z<4%g4_W>%IDY^dHX@?FJvy)|xAYS7N!CApsu$3yVS;q$kheC|OM25?+Y)}+Jh$YB#
z=w_%+LYSsF9q@o1;_`hj=5xtaxV|C8mhnGNQi?32$Q;fJJ|04{6#6%SXlNz;!8Ma)
zhkG-g<!Du47jj%$kj<3&g-r{5ZpkJsMK>Us*s}1?a)Kw0!@_kd74OU!ZCI}d96y?I
z=6OvXy`#n0stB8TOjL4zD1}nsq6i;`7;iy5xoG-F1737Z#7n=lhP8Q%MOEc64IWNb
zAaN5{X+onPOoU_wB_XE3R1lv*>oC|1;vrbF9nwYUTf>=+`*`E?r<gh%5U*WNzkZZ#
z#(@`<2(D|9TtGwKc7z)4c<d}WJ#wr6uPrjStTnv&kmr?sYO9XIZLN;OI>9<c?x0A7
z#z4S{MLnfTrbwM&h{6B@14iS~=s4g7+q-;x-&Ss)-_BHJ1HL|jH2NW`mQgsJ0~NsZ
z!%!r!?{B~xIQm1F+Ybwes8>euE=LZ{aMPQ<OFWfQyYNDanWMON3)}JFN|4N^9Nv4B
zhWcW`A3wO3E%Qz_F5iC3r+%>ewtrRuH_i+Hu+mUiITD2YW|ARdw3?pH85|0kI+n3)
zbyPCIT0NnnQ>vHVD}~Y}ks>HUCH&qwk5jL<Nb-!~aFL>|$-G7|uy_m(d=)xJVg4Yf
z2-=UA-YJ?T^$v&Lvzwc~+vQKLxt|OBCXo$m35IKA`wwHMvyxM^B|DwXS`diD^LGyp
z@!36>%deiBs5NhS-A7+_*1A0(|JwJT+Vc3<mYcs;QSg#u^A@KS&UuO)1_nbmZL1?%
z2ttL46(%fKgiNT>rc9lcDHWv3>K79T6(h`cHNSh?TE2VibbPHJObCa*3OeW&L;~W_
z#<OMAa_4(GWCs)S#eyXBG`B9LvZ5asG->@{7g{S&f~i-q?TmD$Ac_P#@7Z$eoB3k(
zb6om`H}f~Y{*mA}9z5cn(#p`^E;D#1{ngkUpXvIj>y7H>wp<hRiqkjO7#s~j`H~Ba
z%HMAyjWLu}qXBKy$r?bb9^{HA_i)?cI(HoI<AGxZ)15A@Zo!g<W%G#ethJUaHwlfw
zf)zo*)Od!D0|r;cm}V76g!78dqel@1^(~tyCdWw*cd-uoV#j%3dMz(IV}cKUBxdGF
z<vn9pfARN!<|e5xkLvdaTD^IuEBH8Ip;KU#!dhX+`Tayyg~t<B0(1x_039mK3F5>k
zN^dBa&{VHEsti4rTHt6@6`}SR?Qp%7<gOQjsO$+?oN<KBfa+j`!eP8e)ngWqb;y%~
z%2<=?#x=C>evot?25X)V?p#lJ?n<tE=RWdX)z-pfw5o{LEiV7nzyH}gMZYqtzbmNc
z9qWp6fhNrzfzmkfTy)VuS*L3VD;g7(CLe?v6@W3NC7@3zLVDC{Nw+8^Xd?v1BMP+g
zXyqwVN7^n|pG-v&hUJ2b2_c9CS2*U6ru1(croMg|-9uB%-E|xk^lgj?FI&R0zKras
zXL5gj>FPHx-uATG<UT)asCZe^h}C0LIcmD=DJTU}N`v#9dtQSm1kpkmmy4sufIfi-
zK?#^A-2va@LIm*mqR095@(L#qR05PT;1U9((V<{M2qT3}aypASqvwqft?DN^R**k_
zoG5nmpHU?miSR8a$|;p)T-*Pe*$*B0*Z?cuF#q&>g@2=_*1fFH?3+k1^O?{Uk4Dj~
z1|;2_^UiG$#u}6mL<$`#g0LsFR%oqIri`9iNiT$!UBbE-i*)P>0tH$qT9C9s8%hi5
zxt7aP!iHjS%OEZYuvtJ*cf@KItu=WU0;7nVhT9*s*Is^o`$Nx2ukgJE^UFo<KC`M{
z(e+B4l#wn?9rcD`{BTZaps#6gwzp0wB?WGDDY!Ur1-*KnURGJ&`$F)kP;@-$JmiT2
zQ8-uj83&<I?H8(J6)MdTn}916x~eITPh#5&mjEbf_Gz_e%D>>EceX$Gw{NQR#XF0i
zyIWk9lqmYwL-i{!?higQm5W|<f*3`SJL(lpnmC5~4Qo%UQK^>A6WTx+Yl2vp7NJW5
z)aQcqnj-WG@>Rf#Lg~^vOdwS25Z4qzwYMf|OEy~9BXlDoJ3fVpG&)jJuPK!VYVY+o
z*;jt}`}ut**#2jtUETmyU<9bI)@tL22lN;7$V5lxEY(J!vfQD(N2{_gU~Fl`stq-a
zDFMrbLJ(<!iXw~*Is_dEp*aDJCHN^_cASVPFoG*QC#h-G<0Jxu)0V8&C8#LknwMH7
zR-d`gzW=Q^+fPY}v(vyLrxyM{hYM&R?Co(FYzf6TQ@*h+)Tf^{5G-vKUbLX1YS1Hh
zJvJAnj%Il4Y4!)i^$489r4FC>NKNPPd5_^0=`DUx7Fvare{%})sz-@I-YF;$RB9P9
zmV4V{#N%V?+YgN1`i5^G{}9j*WI)<GyJrLgdJ2ev2&koCZb|)}4eN(4><`uik<v-x
zB#g8Q0*$po6lu~#n3>2(S~*cABB}-i;VJBrbCgX24!lP>-)k5yF+_QV7mxFff}HyD
zf^G+H-M5zO9=(#SGX<l|RqGYse(=91j<6?qr#I4*doi8?3<!ZHFa!((1Hd3KHlW#X
z-H>_p#%9o*&aC7Xg;sbcc<ZUwG;uW`G-Ypmq#gC4fNH-Xj5T3Yk{wC}l*g-5C*BL*
zc!CCmk>E1T`+syUcSe_R?aJHamsUQi9$A#B7ytF*TT&}6U;&uzjX9wEOex@mrNliG
z8|*1zu!jr7z>=5L)N_ArSf4-A2=!cIrEse3oN*o{o-kC@s+yo;%A^QKpac^LQ2;tB
z%Y9-{p+;8}VMU=MFcGN8Pz?3ShI+0Ze`t{#?vig^|A70eQv{#+3E_($_pm%Odxip_
za*8Dk^n@Sj-S-2dZ|>7q{_@7!3KOcJ+sg0?kx(nG1eX>do*>jz>V_axghtTHp^QLS
z60kv}(G?L>4OBc3Q|qrFI*=oe+Vs=koZkEK3HRk5&~<v}nV#VDJ>j#bBK*_YG<Cuf
z>OkKq)^I{0eL%gb82N>U+3~uK&1bD!Ut?h*B~=lF10hBW^T%7*tRSiz3Bo{)F0WD_
zt`XF9xdiWpG!+gW&fK0yI^Dm2tiAWHdHc|j#P7?X)e~~|l(Eo5{mxUJ`JZRknCV$V
zwWo+?Px$`cX!f2*z`)fp+b%n;Z>yW=EV;Ae9$7V73C>zpT|U|fnq#4^b+dx6{Al*j
zo{WQ_ob%#xA$<s@=E@nJ>It0ocG)dZD&fRfJZ0A1&m#QKvu#fIzN>rTG42W8=qaJz
zQ&6S%H-Op*teGx<bP7Z@7+wma%VX8pS;)SwXQ3yI?Fp2hB6tUA_r_xHeB!hIsQ});
z#KuW=$_RV29`^*Vo^n1BLWADt%qj1-y;;+}8FW3tPmHW5Xwn;L&&=(~{Wkx`w$7fg
zj1#UB^sd8GuJtMJRz0Cl%%b$}ZEqC4=fxBDS^oR+@5eK8{2ypgiU*47lQ94Q002ov
JPDHLkV1lvM5PJXs
copy from mobile/xul/branding/official/content/jar.mn
copy to b2g/branding/official/content/jar.mn
copy from mobile/xul/branding/official/content/logo.png
copy to b2g/branding/official/content/logo.png
copy from mobile/xul/branding/official/content/logoWordmark.png
copy to b2g/branding/official/content/logoWordmark.png
copy from mobile/xul/branding/official/content/splash.png
copy to b2g/branding/official/content/splash.png
copy from mobile/xul/branding/official/locales/Makefile.in
copy to b2g/branding/official/locales/Makefile.in
--- a/mobile/xul/branding/official/locales/Makefile.in
+++ b/b2g/branding/official/locales/Makefile.in
@@ -29,19 +29,19 @@
 # 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          = ../../../../..
+DEPTH          = ../../../..
 topsrcdir      = @top_srcdir@
 srcdir         = @srcdir@
 VPATH          = @srcdir@
-relativesrcdir = mobile/branding/official/locales
+relativesrcdir = b2g/branding/official/locales
 
 include $(DEPTH)/config/autoconf.mk
 
 DEFINES += -DAB_CD=$(AB_CD)
 
 include $(topsrcdir)/config/rules.mk
copy from mobile/xul/branding/official/locales/en-US/brand.dtd
copy to b2g/branding/official/locales/en-US/brand.dtd
--- a/mobile/xul/branding/official/locales/en-US/brand.dtd
+++ b/b2g/branding/official/locales/en-US/brand.dtd
@@ -1,4 +1,4 @@
-<!ENTITY  brandShortName  "Firefox">
-<!ENTITY  brandFullName   "Mozilla Firefox">
+<!ENTITY  brandShortName  "B2G">
+<!ENTITY  brandFullName   "Mozilla B2G">
 <!ENTITY  vendorShortName "Mozilla">
-<!ENTITY  logoTrademark   "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
+<!ENTITY  logoTrademark   "B2G and the B2G logos are trademarks of the Mozilla Foundation.">
copy from mobile/xul/branding/official/locales/en-US/brand.properties
copy to b2g/branding/official/locales/en-US/brand.properties
--- a/mobile/xul/branding/official/locales/en-US/brand.properties
+++ b/b2g/branding/official/locales/en-US/brand.properties
@@ -1,2 +1,2 @@
-brandShortName=Firefox
-brandFullName=Mozilla Firefox
+brandShortName=B2G
+brandFullName=Mozilla B2G
copy from mobile/xul/branding/official/locales/jar.mn
copy to b2g/branding/official/locales/jar.mn
copy from mobile/xul/branding/unofficial/Makefile.in
copy to b2g/branding/unofficial/Makefile.in
--- a/mobile/xul/branding/unofficial/Makefile.in
+++ b/b2g/branding/unofficial/Makefile.in
@@ -29,17 +29,17 @@
 # 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 = ../../../..
+DEPTH = ../../..
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 DIRS = \
 	content \
copy from mobile/xul/branding/unofficial/android-resources.mn
copy to b2g/branding/unofficial/android-resources.mn
--- a/mobile/xul/branding/unofficial/android-resources.mn
+++ b/b2g/branding/unofficial/android-resources.mn
@@ -1,6 +1,1 @@
-mobile/xul/app/android/drawable/alertaddons.png
-mobile/xul/app/android/drawable/alertdownloads.png
-mobile/xul/branding/unofficial/content/splash.png
-mobile/xul/branding/unofficial/content/splash_v9.9.png
-mobile/xul/branding/unofficial/content/splash_v8.9.png
-mobile/xul/branding/unofficial/content/favicon32.png
+b2g/branding/unofficial/content/splash.png
copy from mobile/xul/branding/unofficial/configure.sh
copy to b2g/branding/unofficial/configure.sh
--- a/mobile/xul/branding/unofficial/configure.sh
+++ b/b2g/branding/unofficial/configure.sh
@@ -1,3 +1,3 @@
-ANDROID_PACKAGE_NAME=org.mozilla.fennec_`echo $USER`
-MOZ_APP_DISPLAYNAME=Fennec
+ANDROID_PACKAGE_NAME=org.mozilla.b2g_`echo $USER`
+MOZ_APP_DISPLAYNAME=B2G
 MOZ_UPDATER=
copy from mobile/xul/branding/unofficial/content/Makefile.in
copy to b2g/branding/unofficial/content/Makefile.in
--- a/mobile/xul/branding/unofficial/content/Makefile.in
+++ b/b2g/branding/unofficial/content/Makefile.in
@@ -1,25 +1,11 @@
 # Branding Makefile
 #  - jars chrome artwork
 
-DEPTH = ../../../../..
+DEPTH = ../../../..
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 include $(topsrcdir)/config/rules.mk
-
-LINUX_BRANDING_FILES = \
-	fennec_26x26.png \
-	fennec_40x40.png \
-	fennec_48x48.png \
-	fennec_72x72.png \
-	fennec_scalable.png \
-	fennec_maemo_icon26.txt \
-	$(NULL)
-
-export::
-	$(NSINSTALL) -D $(DIST)/branding
-	cp $(addprefix $(srcdir)/, $(LINUX_BRANDING_FILES)) $(DIST)/branding/
-	$(NSINSTALL) -D $(DIST)/install
copy from mobile/xul/branding/unofficial/content/about.png
copy to b2g/branding/unofficial/content/about.png
copy from mobile/xul/branding/unofficial/content/favicon32.png
copy to b2g/branding/unofficial/content/favicon32.png
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3ae248c857d7010eee72e3f20f5a8fbaeed4f196
GIT binary patch
literal 4053
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
Hu0mjfcGdKw
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fe980153be29d7d4d01066de16a0fd28ae0e223c
GIT binary patch
literal 5897
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
copy from mobile/xul/branding/unofficial/content/jar.mn
copy to b2g/branding/unofficial/content/jar.mn
copy from mobile/xul/branding/unofficial/content/logo.png
copy to b2g/branding/unofficial/content/logo.png
copy from mobile/xul/branding/unofficial/content/logoWordmark.png
copy to b2g/branding/unofficial/content/logoWordmark.png
copy from mobile/xul/branding/unofficial/content/splash.png
copy to b2g/branding/unofficial/content/splash.png
copy from mobile/xul/branding/unofficial/locales/Makefile.in
copy to b2g/branding/unofficial/locales/Makefile.in
--- a/mobile/xul/branding/unofficial/locales/Makefile.in
+++ b/b2g/branding/unofficial/locales/Makefile.in
@@ -30,19 +30,19 @@
 # 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          = ../../../../..
+DEPTH          = ../../../..
 topsrcdir      = @top_srcdir@
 srcdir         = @srcdir@
 VPATH          = @srcdir@
-relativesrcdir = mobile/branding/unofficial/locales
+relativesrcdir = b2g/branding/unofficial/locales
 
 include $(DEPTH)/config/autoconf.mk
 
 DEFINES += -DAB_CD=$(AB_CD)
 
 include $(topsrcdir)/config/rules.mk
copy from mobile/xul/branding/unofficial/locales/en-US/brand.dtd
copy to b2g/branding/unofficial/locales/en-US/brand.dtd
--- a/mobile/xul/branding/unofficial/locales/en-US/brand.dtd
+++ b/b2g/branding/unofficial/locales/en-US/brand.dtd
@@ -1,4 +1,4 @@
-<!ENTITY  brandShortName  "Fennec">
-<!ENTITY  brandFullName   "Mozilla Fennec">
+<!ENTITY  brandShortName  "B2G">
+<!ENTITY  brandFullName   "Mozilla B2G">
 <!ENTITY  vendorShortName "Mozilla">
 <!ENTITY  logoTrademark   "">
copy from mobile/xul/branding/unofficial/locales/en-US/brand.properties
copy to b2g/branding/unofficial/locales/en-US/brand.properties
--- a/mobile/xul/branding/unofficial/locales/en-US/brand.properties
+++ b/b2g/branding/unofficial/locales/en-US/brand.properties
@@ -1,2 +1,2 @@
-brandShortName=Fennec
-brandFullName=Mozilla Fennec
+brandShortName=B2G
+brandFullName=Mozilla B2G
copy from mobile/xul/branding/unofficial/locales/jar.mn
copy to b2g/branding/unofficial/locales/jar.mn
copy from mobile/xul/build.mk
copy to b2g/build.mk
--- a/mobile/xul/build.mk
+++ b/b2g/build.mk
@@ -31,19 +31,16 @@
 # 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 LIBXUL_SDK
-# Needed for building our components as part of libxul
-APP_LIBXUL_DIRS += mobile/xul/components/build
-
 include $(topsrcdir)/toolkit/toolkit-tiers.mk
 else
 ifdef ENABLE_TESTS
 tier_testharness_dirs += \
   testing/mochitest \
   $(NULL)
 endif
 endif
@@ -55,43 +52,37 @@ tier_app_dirs += extensions
 endif
 
 ifdef MOZ_SERVICES_SYNC
 tier_app_dirs += services
 endif
 
 tier_app_dirs += \
   $(MOZ_BRANDING_DIRECTORY) \
-  mobile/xul \
+  b2g \
   $(NULL)
 
 
 installer: 
-	@$(MAKE) -C mobile/xul/installer installer
+	@$(MAKE) -C b2g/installer installer
 
 package:
-	@$(MAKE) -C mobile/xul/installer
+	@$(MAKE) -C b2g/installer
 
 install::
-	@echo "Mobile can't be installed directly."
+	@echo "B2G can't be installed directly."
 	@exit 1
 
-deb: package
-	@$(MAKE) -C mobile/xul/installer deb
-
 upload::
-	@$(MAKE) -C mobile/xul/installer upload
+	@$(MAKE) -C b2g/installer upload
 
 ifdef ENABLE_TESTS
 # Implemented in testing/testsuite-targets.mk
 
 mochitest-browser-chrome:
 	$(RUN_MOCHITEST) --browser-chrome
 	$(CHECK_TEST_ERROR)
 
 mochitest:: mochitest-browser-chrome
 
 .PHONY: mochitest-browser-chrome
 endif
 
-ifeq ($(OS_TARGET),Linux)
-deb: installer
-endif
copy from mobile/xul/chrome/Makefile.in
copy to b2g/chrome/Makefile.in
--- a/mobile/xul/chrome/Makefile.in
+++ b/b2g/chrome/Makefile.in
@@ -30,26 +30,21 @@
 # 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     = ../../..
+DEPTH     = ../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 DEFINES += -DAB_CD=$(MOZ_UI_LOCALE) \
            -DPACKAGE=browser \
            -DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
            $(NULL)
 
-
-ifdef ENABLE_TESTS
-DIRS += tests
-endif
-
 include $(topsrcdir)/config/rules.mk
copy from mobile/xul/chrome/content/commandUtil.js
copy to b2g/chrome/content/commandUtil.js
--- a/mobile/xul/chrome/content/commandUtil.js
+++ b/b2g/chrome/content/commandUtil.js
@@ -34,164 +34,164 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 
 /**
  * Command Updater
  */
-var CommandUpdater = {
+let CommandUpdater = {
   /**
    * Gets a controller that can handle a particular command.
-   * @param   command
-   *          A command to locate a controller for, preferring controllers that
-   *          show the command as enabled.
-   * @returns In this order of precedence:
+   * @param {string} command
+   *        A command to locate a controller for, preferring controllers that
+   *        show the command as enabled.
+   * @return {object} In this order of precedence:
    *            - the first controller supporting the specified command
    *              associated with the focused element that advertises the
-   *              command as ENABLED
+   *              command as ENABLED.
    *            - the first controller supporting the specified command
    *              associated with the global window that advertises the
-   *              command as ENABLED
+   *              command as ENABLED.
    *            - the first controller supporting the specified command
-   *              associated with the focused element
+   *              associated with the focused element.
    *            - the first controller supporting the specified command
-   *              associated with the global window
+   *              associated with the global window.
    */
   _getControllerForCommand: function(command) {
     try {
-      var controller = top.document.commandDispatcher.getControllerForCommand(command);
+      let commandDispatcher = top.document.commandDispatcher;
+      let controller = commandDispatcher.getControllerForCommand(command);
       if (controller && controller.isCommandEnabled(command))
         return controller;
     }
-    catch(e) {
-    }
-    var controllerCount = window.controllers.getControllerCount();
-    for (var i = 0; i < controllerCount; ++i) {
-      var current = window.controllers.getControllerAt(i);
+    catch (e) { }
+
+    let controllerCount = window.controllers.getControllerCount();
+    for (let i = 0; i < controllerCount; ++i) {
+      let current = window.controllers.getControllerAt(i);
       try {
-        if (current.supportsCommand(command) && current.isCommandEnabled(command))
+        if (current.supportsCommand(command) &&
+            current.isCommandEnabled(command))
           return current;
       }
-      catch (e) {
-      }
+      catch (e) { }
     }
     return controller || window.controllers.getControllerForCommand(command);
   },
 
   /**
    * Updates the state of a XUL <command> element for the specified command
    * depending on its state.
-   * @param   command
-   *          The name of the command to update the XUL <command> element for
+   * @param {string} command
+   *        The name of the command to update the XUL <command> element for.
    */
   updateCommand: function(command) {
-    var enabled = false;
+    let enabled = false;
     try {
-      var controller = this._getControllerForCommand(command);
+      let controller = this._getControllerForCommand(command);
       if (controller) {
         enabled = controller.isCommandEnabled(command);
       }
     }
-    catch(ex) { }
+    catch (ex) { }
 
     this.enableCommand(command, enabled);
   },
 
   /**
    * Updates the state of a XUL <command> element for the specified command
    * depending on its state.
-   * @param   command
-   *          The name of the command to update the XUL <command> element for
+   * @param {string} command
+   *        The name of the command to update the XUL <command> element for.
    */
   updateCommands: function(_commands) {
-    var commands = _commands.split(",");
-    for (var command in commands) {
+    let commands = _commands.split(',');
+    for (let command in commands) {
       this.updateCommand(commands[command]);
     }
   },
 
   /**
    * Enables or disables a XUL <command> element.
-   * @param   command
-   *          The name of the command to enable or disable
-   * @param   enabled
+   * @param {string} command
+   *          The name of the command to enable or disable.
+   * @param {bool} enabled
    *          true if the command should be enabled, false otherwise.
    */
   enableCommand: function(command, enabled) {
-    var element = document.getElementById(command);
+    let element = document.getElementById(command);
     if (!element)
       return;
+
     if (enabled)
-      element.removeAttribute("disabled");
+      element.removeAttribute('disabled');
     else
-      element.setAttribute("disabled", "true");
+      element.setAttribute('disabled', 'true');
   },
 
   /**
    * Performs the action associated with a specified command using the most
    * relevant controller.
-   * @param   command
+   * @param {string} command
    *          The command to perform.
    */
   doCommand: function(command) {
-    var controller = this._getControllerForCommand(command);
+    let controller = this._getControllerForCommand(command);
     if (!controller)
       return;
     controller.doCommand(command);
   },
 
   /**
    * Changes the label attribute for the specified command.
-   * @param   command
+   * @param {string} command
    *          The command to update.
-   * @param   labelAttribute
+   * @param {string} labelAttribute
    *          The label value to use.
    */
   setMenuValue: function(command, labelAttribute) {
-    var commandNode = top.document.getElementById(command);
-    if (commandNode)
-    {
-      var label = commandNode.getAttribute(labelAttribute);
-      if ( label )
+    let commandNode = top.document.getElementById(command);
+    if (commandNode) {
+      let label = commandNode.getAttribute(labelAttribute);
+      if (label)
         commandNode.setAttribute('label', label);
     }
   },
 
   /**
    * Changes the accesskey attribute for the specified command.
-   * @param   command
+   * @param {string} command
    *          The command to update.
-   * @param   valueAttribute
+   * @param {string} valueAttribute
    *          The value attribute to use.
    */
   setAccessKey: function(command, valueAttribute) {
-    var commandNode = top.document.getElementById(command);
-    if (commandNode)
-    {
-      var value = commandNode.getAttribute(valueAttribute);
-      if ( value )
+    let commandNode = top.document.getElementById(command);
+    if (commandNode) {
+      let value = commandNode.getAttribute(valueAttribute);
+      if (value)
         commandNode.setAttribute('accesskey', value);
     }
   },
 
   /**
    * Inform all the controllers attached to a node that an event has occurred
-   * (e.g. the tree controllers need to be informed of blur events so that they can change some of the
-   * menu items back to their default values)
-   * @param   node
-   *          The node receiving the event
-   * @param   event
+   * (e.g. the tree controllers need to be informed of blur events so that they
+   * can change some of the menu items back to their default values)
+   * @param  {node} node
+   *          The node receiving the event.
+   * @param  {event} event
    *          The event.
    */
   onEvent: function(node, event) {
-    var numControllers = node.controllers.getControllerCount();
-    var controller;
+    let numControllers = node.controllers.getControllerCount();
+    let controller;
 
-    for ( var controllerIndex = 0; controllerIndex < numControllers; controllerIndex++ )
-    {
-      controller = node.controllers.getControllerAt(controllerIndex);
-      if ( controller )
+    for (let i = 0; i < numControllers; i++) {
+      controller = node.controllers.getControllerAt(i);
+      if (controller)
         controller.onEvent(event);
     }
   }
 };
+
copy from mobile/xul/chrome/content/netError.xhtml
copy to b2g/chrome/content/netError.xhtml
--- a/mobile/xul/chrome/content/netError.xhtml
+++ b/b2g/chrome/content/netError.xhtml
@@ -313,17 +313,16 @@
         <h1 id="et_fileNotFound">&fileNotFound.title;</h1>
         <h1 id="et_malformedURI">&malformedURI.title;</h1>
         <h1 id="et_protocolNotFound">&protocolNotFound.title;</h1>
         <h1 id="et_connectionFailure">&connectionFailure.title;</h1>
         <h1 id="et_netTimeout">&netTimeout.title;</h1>
         <h1 id="et_redirectLoop">&redirectLoop.title;</h1>
         <h1 id="et_unknownSocketType">&unknownSocketType.title;</h1>
         <h1 id="et_netReset">&netReset.title;</h1>
-        <h1 id="et_notCached">&notCached.title;</h1>
         <h1 id="et_netOffline">&netOffline.title;</h1>
         <h1 id="et_netInterrupt">&netInterrupt.title;</h1>
         <h1 id="et_deniedPortAccess">&deniedPortAccess.title;</h1>
         <h1 id="et_proxyResolveFailure">&proxyResolveFailure.title;</h1>
         <h1 id="et_proxyConnectFailure">&proxyConnectFailure.title;</h1>
         <h1 id="et_contentEncodingError">&contentEncodingError.title;</h1>
         <h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
@@ -338,17 +337,16 @@
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_malformedURI">&malformedURI.longDesc;</div>
         <div id="ed_protocolNotFound">&protocolNotFound.longDesc;</div>
         <div id="ed_connectionFailure">&connectionFailure.longDesc;</div>
         <div id="ed_netTimeout">&netTimeout.longDesc;</div>
         <div id="ed_redirectLoop">&redirectLoop.longDesc;</div>
         <div id="ed_unknownSocketType">&unknownSocketType.longDesc;</div>
         <div id="ed_netReset">&netReset.longDesc;</div>
-        <div id="ed_notCached">&notCached.longDesc;</div>
         <div id="ed_netOffline">&netOffline.longDesc2;</div>
         <div id="ed_netInterrupt">&netInterrupt.longDesc;</div>
         <div id="ed_deniedPortAccess">&deniedPortAccess.longDesc;</div>
         <div id="ed_proxyResolveFailure">&proxyResolveFailure.longDesc2;</div>
         <div id="ed_proxyConnectFailure">&proxyConnectFailure.longDesc;</div>
         <div id="ed_contentEncodingError">&contentEncodingError.longDesc;</div>
         <div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
         <div id="ed_nssFailure2">&nssFailure2.longDesc;</div>
new file mode 100644
--- /dev/null
+++ b/b2g/chrome/content/shell.js
@@ -0,0 +1,220 @@
+/* ***** 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 B2G.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const CC = Components.Constructor;
+
+Cu.import('resource://gre/modules/Services.jsm');
+
+const LocalFile = CC('@mozilla.org/file/local;1',
+                     'nsILocalFile',
+                     'initWithPath');
+var shell = {
+  get home() {
+    delete this.home;
+    return this.home = document.getElementById('homescreen');
+  },
+
+  get homeSrc() {
+    try {
+      let homeSrc = Cc['@mozilla.org/process/environment;1']
+                      .getService(Ci.nsIEnvironment)
+                      .get('B2G_HOMESCREEN');
+      if (homeSrc)
+        return homeSrc;
+    } catch (e) {}
+
+    let urls = Services.prefs.getCharPref('browser.homescreenURL').split(',');
+    for (let i = 0; i < urls.length; i++) {
+      let url = urls[i];
+      if (url.substring(0, 7) != 'file://')
+        return url;
+
+      let file = new LocalFile(url.substring(7, url.length));
+      if (file.exists())
+        return url;
+    }
+    return null;
+  },
+
+  start: function shell_init() {
+    window.controllers.appendController(this);
+    window.addEventListener('keypress', this);
+    this.home.addEventListener('load', this, true);
+
+    let ioService = Cc['@mozilla.org/network/io-service;1']
+                      .getService(Ci.nsIIOService2);
+    ioService.offline = false;
+
+    let browser = this.home;
+    browser.homePage = this.homeSrc;
+    browser.goHome();
+  },
+
+  stop: function shell_stop() {
+    window.controllers.removeController(this);
+    window.removeEventListener('keypress', this);
+  },
+
+  supportsCommand: function shell_supportsCommand(cmd) {
+    let isSupported = false;
+    switch (cmd) {
+      case 'cmd_close':
+        isSupported = true;
+        break;
+      default:
+        isSupported = false;
+        break;
+    }
+    return isSupported;
+  },
+
+  isCommandEnabled: function shell_isCommandEnabled(cmd) {
+    return true;
+  },
+
+  doCommand: function shell_doCommand(cmd) {
+    switch (cmd) {
+      case 'cmd_close':
+        this.sendEvent(this.home.contentWindow, 'appclose');
+        break;
+    }
+  },
+
+  handleEvent: function shell_handleEvent(evt) {
+    switch (evt.type) {
+      case 'keypress':
+        switch (evt.keyCode) {
+          case evt.DOM_VK_HOME:
+            this.sendEvent(this.home.contentWindow, 'home');
+            break;
+          case evt.DOM_VK_SLEEP:
+            screen.mozEnabled = !screen.mozEnabled;
+            break;
+          case evt.DOM_VK_ESCAPE:
+            if (evt.getPreventDefault())
+              return;
+            this.doCommand('cmd_close');
+            break;
+        }
+        break;
+      case 'load':
+        this.home.removeEventListener('load', this, true);
+        this.sendEvent(window, 'ContentStart');
+        break;
+    }
+  },
+  sendEvent: function shell_sendEvent(content, type, details) {
+    let event = content.document.createEvent('CustomEvent');
+    event.initCustomEvent(type, true, true, details ? details : {});
+    content.dispatchEvent(event);
+  }
+};
+
+(function VirtualKeyboardManager() {
+  let activeElement = null;
+  let isKeyboardOpened = false;
+
+  let constructor = {
+    handleEvent: function vkm_handleEvent(evt) {
+      let contentWindow = shell.home.contentWindow.wrappedJSObject;
+
+      switch (evt.type) {
+        case 'ContentStart':
+          contentWindow.navigator.mozKeyboard = new MozKeyboard();
+          break;
+        case 'keypress':
+          if (evt.keyCode != evt.DOM_VK_ESCAPE || !isKeyboardOpened)
+            return;
+
+          shell.sendEvent(contentWindow, 'hideime');
+          isKeyboardOpened = false;
+
+          evt.preventDefault();
+          evt.stopPropagation();
+          break;
+        case 'mousedown':
+          if (evt.target != activeElement || isKeyboardOpened)
+            return;
+
+          let type = activeElement.type;
+          shell.sendEvent(contentWindow, 'showime', { type: type });
+          isKeyboardOpened = true;
+          break;
+      }
+    },
+    observe: function vkm_observe(subject, topic, data) {
+      let contentWindow = shell.home.contentWindow;
+
+      let shouldOpen = parseInt(data);
+      if (shouldOpen && !isKeyboardOpened) {
+        activeElement = Cc['@mozilla.org/focus-manager;1']
+                          .getService(Ci.nsIFocusManager)
+                          .focusedElement;
+        if (!activeElement)
+          return;
+
+        let type = activeElement.type;
+        shell.sendEvent(contentWindow, 'showime', { type: type });
+      } else if (!shouldOpen && isKeyboardOpened) {
+        shell.sendEvent(contentWindow, 'hideime');
+      }
+      isKeyboardOpened = shouldOpen;
+    }
+  };
+
+  Services.obs.addObserver(constructor, "ime-enabled-state-changed", false);
+  ['ContentStart', 'keypress', 'mousedown'].forEach(function vkm_events(type) {
+    window.addEventListener(type, constructor, true);
+  });
+})();
+
+
+function MozKeyboard() {
+}
+
+MozKeyboard.prototype = {
+  sendKey: function mozKeyboardSendKey(keyCode) {
+    var utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                      .getInterface(Ci.nsIDOMWindowUtils);
+    ['keydown', 'keypress', 'keyup'].forEach(function sendKeyEvents(type) {
+      utils.sendKeyEvent(type, keyCode, keyCode, null);
+    });
+  }
+};
+
new file mode 100644
--- /dev/null
+++ b/b2g/chrome/content/shell.xul
@@ -0,0 +1,60 @@
+<?xml version="1.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 Mozilla Mobile Browser.
+   -
+   - The Initial Developer of the Original Code is
+   - Mozilla Corporation.
+   - Portions created by the Initial Developer are Copyright (C) 2011
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -   Chris Jones <jones.chris.g@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 LGPL or the GPL. 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 ***** -->
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        id="shell"
+        width="480" height="800"
+#ifdef ANDROID
+        sizemode="fullscreen"
+#endif
+        style="background: black; overflow: hidden;"
+        onload="shell.start();"
+        onunload="shell.stop();">
+
+  <script type="application/javascript" src="chrome://browser/content/commandUtil.js"/>
+  <script type="application/javascript" src="chrome://browser/content/shell.js"/>
+  <script type="application/javascript" src="chrome://browser/content/touch.js"/>
+
+  <commandset id="mainCommandSet">
+    <command id="cmd_close" oncommand="CommandUpdater.doCommand(this.id);"/>
+  </commandset>
+
+  <browser id="homescreen" type="content-primary" flex="1" style="overflow: hidden;"/>
+</window>
+
new file mode 100644
--- /dev/null
+++ b/b2g/chrome/content/touch.js
@@ -0,0 +1,240 @@
+/* ***** 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 B2G.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+(function touchEventHandler() {
+  let debugging = false;
+  function debug(str) {
+    if (debugging)
+      dump(str + '\n');
+  };
+
+  let contextMenuTimeout = 0;
+
+  // This guard is used to not re-enter the events processing loop for
+  // self dispatched events
+  let ignoreEvents = false;
+
+  // During a 'touchstart' and the first 'touchmove' mouse events can be
+  // prevented for the current touch sequence.
+  let canPreventMouseEvents = false;
+
+  // Used to track the first mousemove and to cancel click dispatc if it's not
+  // true.
+  let isNewTouchAction = false;
+
+  // If this is set to true all mouse events will be cancelled by calling
+  // both evt.preventDefault() and evt.stopPropagation().
+  // This will not prevent a contextmenu event to be fired.
+  // This can be turned on if canPreventMouseEvents is true and the consumer
+  // application call evt.preventDefault();
+  let preventMouseEvents = false;
+
+  let TouchEventHandler = {
+    events: ['mousedown', 'mousemove', 'mouseup', 'click', 'unload'],
+    start: function teh_start() {
+      this.events.forEach((function(evt) {
+        shell.home.addEventListener(evt, this, true);
+      }).bind(this));
+    },
+    stop: function teh_stop() {
+      this.events.forEach((function(evt) {
+        shell.home.removeEventListener(evt, this, true);
+      }).bind(this));
+    },
+    handleEvent: function teh_handleEvent(evt) {
+      if (evt.button || ignoreEvents)
+        return;
+
+      let eventTarget = this.target;
+      let type = '';
+      switch (evt.type) {
+        case 'mousedown':
+          debug('mousedown:');
+
+          this.target = evt.target;
+          this.timestamp = evt.timeStamp;
+          evt.target.setCapture(false);
+
+          preventMouseEvents = false;
+          canPreventMouseEvents = true;
+          isNewTouchAction = true;
+
+          contextMenuTimeout =
+            this.sendContextMenu(evt.target, evt.pageX, evt.pageY, 2000);
+          this.startX = evt.pageX;
+          this.startY = evt.pageY;
+          type = 'touchstart';
+          break;
+
+        case 'mousemove':
+          if (!eventTarget)
+            return;
+
+          // On device a mousemove event if fired right after the mousedown
+          // because of the size of the finger, so let's ignore what happens
+          // below 5ms
+          if (evt.timeStamp - this.timestamp < 30)
+            break;
+
+          if (isNewTouchAction) {
+            canPreventMouseEvents = true;
+            isNewTouchAction = false;
+          }
+
+          if (Math.abs(this.startX - evt.pageX) > 15 ||
+              Math.abs(this.startY - evt.pageY) > 15)
+            window.clearTimeout(contextMenuTimeout);
+          type = 'touchmove';
+          break;
+
+        case 'mouseup':
+          if (!eventTarget)
+            return;
+          debug('mouseup:');
+
+          window.clearTimeout(contextMenuTimeout);
+          eventTarget.ownerDocument.releaseCapture();
+          this.target = null;
+          type = 'touchend';
+          break;
+
+        case 'unload':
+          if (!eventTarget)
+            return;
+
+          window.clearTimeout(contextMenuTimeout);
+          eventTarget.ownerDocument.releaseCapture();
+          this.target = null;
+          TouchEventHandler.stop();
+          return;
+
+        case 'click':
+          if (!isNewTouchAction) {
+            debug('click: cancel');
+
+            evt.preventDefault();
+            evt.stopPropagation();
+          } else {
+            // Mouse events has been cancelled so dispatch a sequence
+            // of events to where touchend has been fired
+            if (preventMouseEvents) {
+              let target = evt.target;
+              ignoreEvents = true;
+              try {
+                this.fireMouseEvent('mousemove', evt);
+                this.fireMouseEvent('mousedown', evt);
+                this.fireMouseEvent('mouseup', evt);
+              } catch (e) {
+                alert(e);
+              }
+              evt.preventDefault();
+              evt.stopPropagation();
+              ignoreEvents = false;
+            }
+
+            debug('click: fire');
+          }
+          return;
+      }
+
+      let target = eventTarget || this.target;
+      if (target && type) {
+        let touchEvent = this.sendTouchEvent(evt, target, type);
+        if (touchEvent.getPreventDefault() && canPreventMouseEvents)
+          preventMouseEvents = true;
+      }
+
+      if (preventMouseEvents) {
+        evt.preventDefault();
+        evt.stopPropagation();
+
+        if (type != 'touchmove')
+          debug('cancelled (fire ' + type + ')');
+      }
+    },
+    fireMouseEvent: function teh_fireMouseEvent(type, evt)  {
+      debug(type + ': fire');
+
+      let content = evt.target.ownerDocument.defaultView;
+      var utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
+                         .getInterface(Ci.nsIDOMWindowUtils);
+      utils.sendMouseEvent(type, evt.pageX, evt.pageY, 0, 1, 0, true);
+    },
+    sendContextMenu: function teh_sendContextMenu(target, x, y, delay) {
+      let doc = target.ownerDocument;
+      let evt = doc.createEvent('MouseEvent');
+      evt.initMouseEvent('contextmenu', true, true, doc.defaultView,
+                         0, x, y, x, y, false, false, false, false,
+                         0, null);
+
+      let timeout = window.setTimeout((function contextMenu() {
+        debug('fire context-menu');
+
+        target.dispatchEvent(evt);
+        if (!evt.getPreventDefault())
+          return;
+
+        doc.releaseCapture();
+        this.target = null;
+
+        isNewTouchAction = false;
+      }).bind(this), delay);
+      return timeout;
+    },
+    sendTouchEvent: function teh_sendTouchEvent(evt, target, name) {
+      let touchEvent = document.createEvent('touchevent');
+      let point = document.createTouch(window, target, 0,
+                                     evt.pageX, evt.pageY,
+                                     evt.screenX, evt.screenY,
+                                     evt.clientX, evt.clientY,
+                                     1, 1, 0, 0);
+      let touches = document.createTouchList(point);
+      let targetTouches = touches;
+      let changedTouches = touches;
+      touchEvent.initTouchEvent(name, true, true, window, 0,
+                                false, false, false, false,
+                                touches, targetTouches, changedTouches);
+      target.dispatchEvent(touchEvent);
+      return touchEvent;
+    }
+  };
+
+  window.addEventListener('ContentStart', function touchStart(evt) {
+    window.removeEventListener('ContentStart', touchStart);
+    TouchEventHandler.start();
+  });
+})();
+
copy from mobile/xul/chrome/jar.mn
copy to b2g/chrome/jar.mn
--- a/mobile/xul/chrome/jar.mn
+++ b/b2g/chrome/jar.mn
@@ -1,89 +1,13 @@
 #filter substitution
 
 chrome.jar:
+% content branding %content/branding/
 % content browser %content/
 
-* content/about.xhtml                  (content/about.xhtml)
-  content/config.xul                   (content/config.xul)
-  content/config.js                    (content/config.js)
-  content/aboutCertError.xhtml         (content/aboutCertError.xhtml)
-  content/aboutHome.xhtml              (content/aboutHome.xhtml)
-  content/localePicker.xul             (content/localePicker.xul)
-  content/localePicker.js              (content/localePicker.js)
-* content/aboutRights.xhtml            (content/aboutRights.xhtml)
-  content/blockedSite.xhtml            (content/blockedSite.xhtml)
-  content/languages.properties         (content/languages.properties)
-* content/browser.xul                  (content/browser.xul)
-* content/browser.js                   (content/browser.js)
-* content/browser-ui.js                (content/browser-ui.js)
-* content/browser-scripts.js           (content/browser-scripts.js)
-* content/common-ui.js                 (content/common-ui.js)
-* content/AlertsHelper.js              (content/AlertsHelper.js)
-  content/AppMenu.js                   (content/AppMenu.js)
-* content/AwesomePanel.js              (content/AwesomePanel.js)
-  content/BookmarkHelper.js            (content/BookmarkHelper.js)
-  content/BookmarkPopup.js             (content/BookmarkPopup.js)
-  content/CharsetMenu.js               (content/CharsetMenu.js)
-  content/ContentPopupHelper.js        (content/ContentPopupHelper.js)
-* content/ContextCommands.js           (content/ContextCommands.js)
-  content/IndexedDB.js                 (content/IndexedDB.js)
-  content/MenuListHelperUI.js          (content/MenuListHelperUI.js)
-  content/OfflineApps.js               (content/OfflineApps.js)
-* content/PageActions.js               (content/PageActions.js)
-  content/SelectHelperUI.js            (content/SelectHelperUI.js)
-  content/SelectionHelper.js           (content/SelectionHelper.js)
-  content/SharingUI.js                 (content/SharingUI.js)
-  content/TabletSidebar.js             (content/TabletSidebar.js)
-  content/TabsPopup.js                 (content/TabsPopup.js)
-  content/MasterPasswordUI.js          (content/MasterPasswordUI.js)
-* content/content.js                   (content/content.js)
-  content/commandUtil.js               (content/commandUtil.js)
-* content/bindings.xml                 (content/bindings.xml)
-  content/tabs.xml                     (content/tabs.xml)
-  content/bindings/checkbox.xml        (content/bindings/checkbox.xml)
-* content/bindings/browser.xml         (content/bindings/browser.xml)
-  content/bindings/browser.js          (content/bindings/browser.js)
-  content/notification.xml             (content/notification.xml)
-  content/bindings/extensions.xml      (content/bindings/extensions.xml)
-  content/bindings/downloads.xml       (content/bindings/downloads.xml)
-  content/bindings/console.xml         (content/bindings/console.xml)
-  content/bindings/dialog.xml          (content/bindings/dialog.xml)
-  content/bindings/pageaction.xml      (content/bindings/pageaction.xml)
-  content/bindings/arrowbox.xml        (content/bindings/arrowbox.xml)
-  content/browser.css                  (content/browser.css)
-  content/cursor.css                   (content/cursor.css)
-% content branding %content/branding/
-  content/sanitize.js                  (content/sanitize.js)
-* content/input.js                     (content/input.js)
-* content/Util.js                      (content/Util.js)
-  content/forms.js                     (content/forms.js)
-* content/preferences.js               (content/preferences.js)
-  content/exceptions.js                (content/exceptions.js)
-* content/extensions.js                (content/extensions.js)
-* content/downloads.js                 (content/downloads.js)
-  content/console.js                   (content/console.js)
-  content/prompt/alert.xul             (content/prompt/alert.xul)
-  content/prompt/confirm.xul           (content/prompt/confirm.xul)
-  content/prompt/prompt.xul            (content/prompt/prompt.xul)
-  content/prompt/promptPassword.xul    (content/prompt/promptPassword.xul)
-  content/prompt/select.xul            (content/prompt/select.xul)
-  content/prompt/prompt.js             (content/prompt/prompt.js)
-  content/share.xul                    (content/share.xul)
-  content/webapps.xul                  (content/webapps.xul)
-  content/WebappsUI.js                 (content/WebappsUI.js)
-  content/masterPassword.xul           (content/masterPassword.xul)
-  content/removeMasterPassword.xul     (content/removeMasterPassword.xul)
-  content/AnimatedZoom.js              (content/AnimatedZoom.js)
-#ifdef MOZ_SERVICES_SYNC
-  content/sync.js                      (content/sync.js)
-#endif
-  content/LoginManagerChild.js         (content/LoginManagerChild.js)
-  content/fullscreen-video.js          (content/fullscreen-video.js)
-  content/fullscreen-video.xhtml       (content/fullscreen-video.xhtml)
-  content/netError.xhtml               (content/netError.xhtml)
-  content/CapturePickerUI.js           (content/CapturePickerUI.js)
-  content/CaptureDialog.js             (content/CaptureDialog.js)
-  content/CaptureDialog.xul            (content/CaptureDialog.xul)
-  
-% override chrome://global/content/config.xul chrome://browser/content/config.xul
+* content/shell.xul                     (content/shell.xul)
+  content/shell.js                      (content/shell.js)
+  content/touch.js                      (content/touch.js)
+  content/commandUtil.js                (content/commandUtil.js)
+
 % override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml
+  content/netError.xhtml                (content/netError.xhtml)
copy from mobile/xul/confvars.sh
copy to b2g/confvars.sh
--- a/mobile/xul/confvars.sh
+++ b/b2g/confvars.sh
@@ -30,44 +30,40 @@
 # 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 *****
 
-MOZ_APP_BASENAME=Fennec
+MOZ_APP_BASENAME=B2G
 MOZ_APP_VENDOR=Mozilla
 
 MOZ_APP_VERSION=11.0a1
 
-MOZ_BRANDING_DIRECTORY=mobile/xul/branding/unofficial
-MOZ_OFFICIAL_BRANDING_DIRECTORY=mobile/xul/branding/official
+MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial
+MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
 # MOZ_APP_DISPLAYNAME is set by branding/configure.sh
 
 MOZ_SAFE_BROWSING=
-MOZ_SERVICES_SYNC=1
+MOZ_SERVICES_SYNC=
 
 MOZ_DISABLE_DOMCRYPTO=1
+MOZ_APP_STATIC_INI=1
+
+if test "$OS_TARGET" = "Android"; then
+MOZ_CAPTURE=1
+MOZ_RAW=1
+fi
+
+# use custom widget for html:select
+MOZ_USE_NATIVE_POPUP_WINDOWS=1
 
 if test "$LIBXUL_SDK"; then
 MOZ_XULRUNNER=1
 else
 MOZ_XULRUNNER=
 MOZ_PLACES=1
 fi
 
-if test "$OS_TARGET" = "Android"; then
-MOZ_CAPTURE=1
-MOZ_RAW=1
-fi
-
-# Needed for building our components as part of libxul
-MOZ_APP_COMPONENT_LIBS="browsercomps"
-MOZ_APP_COMPONENT_INCLUDE=nsBrowserComponents.h
-
-# use custom widget for html:select
-MOZ_USE_NATIVE_POPUP_WINDOWS=1
-
-MOZ_APP_ID={a23983c0-fd0e-11dc-95ff-0800200c9a66}
+MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
 MOZ_EXTENSION_MANAGER=1
-MOZ_APP_STATIC_INI=1
copy from mobile/xul/installer/Makefile.in
copy to b2g/installer/Makefile.in
--- a/mobile/xul/installer/Makefile.in
+++ b/b2g/installer/Makefile.in
@@ -31,41 +31,35 @@
 # 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     = ../../..
+DEPTH     = ../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
-
-# overwrite mobile-l10n.js with a matchOS=true one for multi-locale builds
-ifeq ($(AB_CD),multi)
-PREF_JS_EXPORTS = $(srcdir)/mobile-l10n.js
-endif
-
 include $(topsrcdir)/config/rules.mk
 
 MOZ_PKG_REMOVALS = $(srcdir)/removed-files.in
 
 MOZ_PKG_MANIFEST_P = $(srcdir)/package-manifest.in
 
 MOZ_NONLOCALIZED_PKG_LIST = \
 	xpcom \
 	browser \
-	mobile \
+	b2g \
 	$(NULL)
 
-MOZ_LOCALIZED_PKG_LIST = $(AB_CD) multilocale
+MOZ_LOCALIZED_PKG_LIST = $(AB_CD)
 
 DEFINES += \
 	-DAB_CD=$(AB_CD) \
 	-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
 	-DPREF_DIR=$(PREF_DIR) \
 	$(NULL)
 
 ifeq ($(MOZ_CHROME_FILE_FORMAT),jar)
@@ -93,24 +87,16 @@ else
 # Every other platform just winds up in dist/bin
 BINPATH = bin
 endif
 DEFINES += -DBINPATH=$(BINPATH)
 
 ifdef MOZ_PKG_MANIFEST_P
 $(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P) FORCE
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $< > $@
-ifdef MOZ_CHROME_MULTILOCALE
-	printf "\n[multilocale]\n" >> $@
-	for LOCALE in en-US $(MOZ_CHROME_MULTILOCALE) ;\
-	do \
-	  printf "$(BINPATH)/chrome/$$LOCALE$(JAREXT)\n" >> $@; \
-	  printf "$(BINPATH)/chrome/$$LOCALE.manifest\n" >> $@; \
-	done
-endif
 
 GARBAGE += $(MOZ_PKG_MANIFEST)
 endif
 
 ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
 PACKAGE_XULRUNNER =
 UNPACKAGE =
 else
@@ -124,134 +110,17 @@ else
 MOZ_GRE_PKG_DIR=$(MOZ_PKG_DIR)
 endif
 
 package-xulrunner:
 ifdef LIBXUL_SDK
 ifndef SYSTEM_LIBXUL
 	@echo "Packaging xulrunner..."
 	@rm -rf $(LIBXUL_DIST)/xulrunner*
-	@$(MAKE) -C $(LIBXUL_DIST)/.. package || echo "Perhaps you're trying to package a prebuilt SDK. See 'https://wiki.mozilla.org/Mobile/Build/Fennec#Build' for more information."
+	@$(MAKE) -C $(LIBXUL_DIST)/.. package || echo "Perhaps you're trying to package a prebuilt SDK. See 'https://wiki.mozilla.org/B2G' for more information."
 	@cd $(DIST)/$(MOZ_PKG_DIR); $(UNMAKE_PACKAGE)
 	@echo "Removing unpackaged files... (the ones xulrunner/installer keeps)"
 	@cd $(DIST)/$(MOZ_PKG_DIR)/xulrunner; rm -rf $(NO_PKG_FILES)
 else
 	@echo "Using system xulrunner..."
 endif
 endif
 
-ifeq ($(OS_TARGET),Linux)
-GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
-GRE_BUILDID = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build BuildID)
-ABS_OBJDIR=`cd $(DEPTH); pwd`
-ABS_TOPSRCDIR=$(shell cd $(topsrcdir); pwd)
-BASE64_ICON = dist/branding/fennec_maemo_icon26.txt
-MOZ_DEB_TIMESTAMP = "$(shell date  +"%a, %d  %b %Y %T %z" )"
-
-DEB_PKG_VERSION = $(shell echo $(MOZ_APP_VERSION) | $(PERL) -pe 's/pre/~$(GRE_BUILDID)/; s/^([0-9.]+)([a-z][0-9]+)/$$1~$$2/')
-
-DEB_BUILD_ARCH = $(shell dpkg-architecture -qDEB_BUILD_ARCH)
-# package name should match mobile/installer/debian/changelog.in
-DEB_PKG_NAME = $(MOZ_PKG_APPNAME)_$(DEB_PKG_VERSION)_$(DEB_BUILD_ARCH).deb
-
-DEFINES += \
-	-DGRE_MILESTONE=$(GRE_MILESTONE) \
-	-DGRE_BUILDID=$(GRE_BUILDID) \
-	-Dinstalldir=$(installdir) \
-	-DMOZ_APP_DISPLAYNAME="$(MOZ_APP_DISPLAYNAME)" \
-	-DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
-	-DABS_OBJDIR=$(ABS_OBJDIR) \
-	-DBASE64_ICON=$(BASE64_ICON) \
-	-DMOZ_DEB_TIMESTAMP=$(MOZ_DEB_TIMESTAMP) \
-	-DDEB_PKG_VERSION=$(DEB_PKG_VERSION) \
-	$(NULL)
-
-DEBDESTDIR=debian/$(MOZ_APP_NAME)
-
-PP_DEB_FILES =	debian/control \
-		debian/changelog \
-		debian/$(MOZ_APP_NAME).desktop \
-		debian/$(MOZ_APP_NAME).links \
-		debian/$(MOZ_APP_NAME).service \
-		debian/compat \
-		debian/files \
-		debian/menu \
-		debian/fennec.preinst \
-		debian/fennec.prerm \
-		debian/fennec.postinst \
-		$(NULL)
-
-ifeq ($(MOZ_PLATFORM_MAEMO),6)
-PP_DEB_FILES += debian/fennec.aegis \
-		debian/backup \
-		debian/restore \
-		debian/fennec.conf \
-		debian/fennec-cud.sh \
-		debian/fennec-rfs.sh \
-		 debian/fennec.policy \
-                $(NULL)
-endif
-
-$(PP_DEB_FILES):
-	@$(EXIT_ON_ERROR) \
-	for f in $(PP_DEB_FILES); do \
-           src=$(srcdir)/debian/`basename $$f`.in; \
-	   echo $$src ">" $$f ;\
-           $(RM) -f $$f; \
-           mkdir -p debian;  \
-           $(PYTHON) $(topsrcdir)/config/Preprocessor.py \
-             $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $$src > $$f; \
-         done
-
-deb: $(PP_DEB_FILES) $(DIST)/branding/$(MOZ_APP_NAME)_scalable.png \
-	$(DIST)/branding/$(MOZ_APP_NAME)_26x26.png \
-	$(DIST)/branding/$(MOZ_APP_NAME)_40x40.png
-	rm -rf $(DEBDESTDIR)/$(installdir)/*
-	$(NSINSTALL) -D $(DEBDESTDIR)/$(installdir)
-	cp -pRL $(DIST)/$(MOZ_APP_NAME)/* $(DEBDESTDIR)/$(installdir)
-ifeq ($(MOZ_PLATFORM_MAEMO),6)
-	$(NSINSTALL)  debian/$(MOZ_APP_NAME).desktop $(DEBDESTDIR)/usr/share/applications/
-	$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/dbus-1/services/
-	cp debian/$(MOZ_APP_NAME).service $(DEBDESTDIR)/usr/share/dbus-1/services/org.mozilla.$(MOZ_APP_NAME).service
-	$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/themes/blanco/meegotouch/icons/
-	cp $(DIST)/branding/$(MOZ_APP_NAME)_scalable.png $(DEBDESTDIR)/usr/share/themes/blanco/meegotouch/icons/$(MOZ_APP_NAME).png
-	$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/backup-framework/applications
-	$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/$(MOZ_APP_NAME)
-	$(NSINSTALL) -D $(DEBDESTDIR)/etc/osso-cud-scripts
-	$(NSINSTALL) -D $(DEBDESTDIR)/etc/osso-rfs-scripts
-	$(NSINSTALL) -m 755 debian/backup  $(DEBDESTDIR)/usr/share/$(MOZ_APP_NAME)/
-	$(NSINSTALL) -m 755 debian/restore $(DEBDESTDIR)/usr/share/$(MOZ_APP_NAME)/
-	cp debian/$(MOZ_APP_NAME).conf $(DEBDESTDIR)/usr/share/backup-framework/applications/$(MOZ_APP_NAME).conf
-	cp debian/$(MOZ_APP_NAME)-cud.sh $(DEBDESTDIR)/etc/osso-cud-scripts/$(MOZ_APP_NAME)-cud.sh
-	cp debian/$(MOZ_APP_NAME)-rfs.sh $(DEBDESTDIR)/etc/osso-rfs-scripts/$(MOZ_APP_NAME)-rfs.sh
-	$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/policy/etc/syspart.conf.d
-	cp debian/$(MOZ_APP_NAME).policy $(DEBDESTDIR)/usr/share/policy/etc/syspart.conf.d/$(MOZ_APP_NAME)
-else
-	$(NSINSTALL)  debian/$(MOZ_APP_NAME).desktop $(DEBDESTDIR)/usr/share/applications/hildon/
-	$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/dbus-1/services/
-	cp debian/$(MOZ_APP_NAME).service $(DEBDESTDIR)/usr/share/dbus-1/services/org.mozilla.$(MOZ_APP_NAME).service
-	$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/icons/hicolor/scalable/hildon/
-	cp $(DIST)/branding/$(MOZ_APP_NAME)_scalable.png $(DEBDESTDIR)/usr/share/icons/hicolor/scalable/hildon/$(MOZ_APP_NAME).png
-	$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/icons/hicolor/26x26/hildon/
-	cp $(DIST)/branding/$(MOZ_APP_NAME)_26x26.png $(DEBDESTDIR)/usr/share/icons/hicolor/26x26/hildon/$(MOZ_APP_NAME).png
-	$(NSINSTALL) -D $(DEBDESTDIR)/usr/share/icons/hicolor/40x40/hildon/
-	cp $(DIST)/branding/$(MOZ_APP_NAME)_40x40.png $(DEBDESTDIR)/usr/share/icons/hicolor/40x40/hildon/$(MOZ_APP_NAME).png
-endif
-	fakeroot dh_link; fakeroot dh_fixperms; fakeroot dh_installdeb; fakeroot dh_shlibdeps; fakeroot dh_gencontrol; fakeroot dh_md5sums; fakeroot dh_builddeb;
-
-# a defined CONTENTMANAGER implicitly means MOZ_PLATFORM_MAEMO is equals 6
-# in case you use CONTENTMANGER you need to sign your package to gain tracker access.
-ifeq ($(MOZ_PLATFORM_MAEMO),6)
-	if test -e "/usr/bin/aegis-deb-add"; then \
-	   fakeroot aegis-deb-add -control $(DEBDESTDIR)/DEBIAN/control .. debian/fennec.aegis=_aegis; \
-	else \
-	   echo aegis-builder not found, security signing failed!; \
-	fi
-endif
-
-	echo $(DEB_PKG_NAME) > $(DIST)/deb_name.txt
-
-installer: deb
-	@echo Installer DEB created!
-
-# relative to $(DIST)
-UPLOAD_EXTRA_FILES += ../mobile/$(DEB_PKG_NAME) deb_name.txt
-endif
copy from mobile/xul/installer/package-manifest.in
copy to b2g/installer/package-manifest.in
--- a/mobile/xul/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -1,9 +1,9 @@
-; Package file for the Fennec build. 
+; Package file for the B2G build. 
 ;
 ; File format:
 ;
 ; [] designates a toplevel component. Example: [xpcom]
 ; - in front of a file specifies it to be removed from the destination
 ; * wildcard support to recursively copy the entire directory
 ; ; file comment
 ;
@@ -16,17 +16,17 @@
 @APPNAME@/Contents/PkgInfo
 @APPNAME@/Contents/Plug-Ins/
 @APPNAME@/Contents/Resources/
 #endif
 
 [@AB_CD@]
 @BINPATH@/chrome/@AB_CD@@JAREXT@
 @BINPATH@/chrome/@AB_CD@.manifest
-@BINPATH@/@PREF_DIR@/mobile-l10n.js
+@BINPATH@/@PREF_DIR@/b2g-l10n.js
 @BINPATH@/searchplugins/*
 @BINPATH@/defaults/profile/bookmarks.html
 @BINPATH@/defaults/profile/localstore.rdf
 @BINPATH@/defaults/profile/mimeTypes.rdf
 @BINPATH@/defaults/profile/chrome/*
 #ifdef MOZ_UPDATER
 @BINPATH@/update.locale
 @BINPATH@/updater.ini
@@ -42,63 +42,57 @@
 #ifndef MOZ_STATIC_JS
 @BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@
 #endif
 @BINPATH@/@DLL_PREFIX@plc4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@xpcom@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@
-@BINPATH@/@DLL_PREFIX@mozutils@DLL_SUFFIX@
 #ifdef XP_MACOSX
 @BINPATH@/XUL
 #else
 @BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
 #endif
 #ifdef XP_MACOSX
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/
 #else
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@
 #endif
 #ifdef XP_WIN32
+#ifndef MOZ_MEMORY
 #if _MSC_VER == 1400
 @BINPATH@/Microsoft.VC80.CRT.manifest
 @BINPATH@/msvcm80.dll
 @BINPATH@/msvcp80.dll
 @BINPATH@/msvcr80.dll
 #elif _MSC_VER == 1500
 @BINPATH@/Microsoft.VC90.CRT.manifest
 @BINPATH@/msvcm90.dll
 @BINPATH@/msvcp90.dll
 @BINPATH@/msvcr90.dll
 #elif _MSC_VER == 1600
 @BINPATH@/msvcp100.dll
 @BINPATH@/msvcr100.dll
-#elif _MSC_VER == 1700
-@BINPATH@/msvcp110.dll
-@BINPATH@/msvcr110.dll
 #endif
-
+#else
+@BINPATH@/mozcrt19.dll
+@BINPATH@/mozcpp19.dll
 #endif
-
+#endif
 #ifdef ANDROID
 @BINPATH@/AndroidManifest.xml
 @BINPATH@/resources.arsc
-@BINPATH@/package-name.txt
 @BINPATH@/classes.dex
 @BINPATH@/@DLL_PREFIX@mozutils@DLL_SUFFIX@
 @BINPATH@/res/drawable
 @BINPATH@/res/drawable-hdpi
 @BINPATH@/res/layout
 #endif
 
-#ifdef MOZ_PLATFORM_MAEMO
-@BINPATH@/res/drawable
-#endif
-
 [browser]
 ; [Base Browser Files]
 #ifndef XP_UNIX
 @BINPATH@/@MOZ_APP_NAME@.exe
 #else
 @BINPATH@/@MOZ_APP_NAME@-bin
 @BINPATH@/@MOZ_APP_NAME@
 #endif
@@ -148,33 +142,32 @@
 @BINPATH@/components/content_xtf.xpt
 @BINPATH@/components/cookie.xpt
 @BINPATH@/components/directory.xpt
 @BINPATH@/components/docshell.xpt
 @BINPATH@/components/dom.xpt
 @BINPATH@/components/dom_base.xpt
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/dom_telephony.xpt
-@BINPATH@/components/dom_telephony_worker.xpt
+@BINPATH@/components/dom_system_b2g.xpt
 #endif
 @BINPATH@/components/dom_battery.xpt
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_geolocation.xpt
 @BINPATH@/components/dom_notification.xpt
 @BINPATH@/components/dom_html.xpt
 @BINPATH@/components/dom_indexeddb.xpt
 @BINPATH@/components/dom_offline.xpt
 @BINPATH@/components/dom_json.xpt
 @BINPATH@/components/dom_range.xpt
 @BINPATH@/components/dom_sidebar.xpt
 @BINPATH@/components/dom_storage.xpt
-@BINPATH@/components/dom_sms.xpt
 @BINPATH@/components/dom_stylesheets.xpt
 @BINPATH@/components/dom_threads.xpt
 @BINPATH@/components/dom_traversal.xpt
 @BINPATH@/components/dom_views.xpt
 @BINPATH@/components/dom_xbl.xpt
 @BINPATH@/components/dom_xpath.xpt
 @BINPATH@/components/dom_xul.xpt
 @BINPATH@/components/dom_loadsave.xpt
@@ -248,16 +241,19 @@
 @BINPATH@/components/storage.xpt
 @BINPATH@/components/telemetry.xpt
 @BINPATH@/components/toolkitprofile.xpt
 #ifdef MOZ_ENABLE_XREMOTE
 @BINPATH@/components/toolkitremote.xpt
 #endif
 @BINPATH@/components/txtsvc.xpt
 @BINPATH@/components/txmgr.xpt
+#ifdef MOZ_USE_NATIVE_UCONV
+@BINPATH@/components/ucnative.xpt
+#endif
 @BINPATH@/components/uconv.xpt
 @BINPATH@/components/unicharutil.xpt
 #ifdef MOZ_UPDATER
 @BINPATH@/components/update.xpt
 #endif
 @BINPATH@/components/uriloader.xpt
 @BINPATH@/components/urlformatter.xpt
 @BINPATH@/components/webBrowser_core.xpt
@@ -280,16 +276,17 @@
 @BINPATH@/components/xpcom_threads.xpt
 @BINPATH@/components/xpcom_xpti.xpt
 @BINPATH@/components/xpconnect.xpt
 @BINPATH@/components/xulapp.xpt
 @BINPATH@/components/xul.xpt
 @BINPATH@/components/xuldoc.xpt
 @BINPATH@/components/xultmpl.xpt
 @BINPATH@/components/zipwriter.xpt
+@BINPATH@/components/webapps.xpt
 
 ; JavaScript components
 @BINPATH@/components/ConsoleAPI.manifest
 @BINPATH@/components/ConsoleAPI.js
 @BINPATH@/components/FeedProcessor.manifest
 @BINPATH@/components/FeedProcessor.js
 @BINPATH@/components/BrowserFeeds.manifest
 @BINPATH@/components/FeedConverter.js
@@ -303,16 +300,18 @@
 @BINPATH@/components/nsSetDefaultBrowser.manifest
 @BINPATH@/components/nsSetDefaultBrowser.js
 @BINPATH@/components/BrowserPlaces.manifest
 @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
 @BINPATH@/components/nsLoginInfo.js
 @BINPATH@/components/nsLoginManager.js
 @BINPATH@/components/nsLoginManagerPrompter.js
 @BINPATH@/components/storage-Legacy.js
 @BINPATH@/components/storage-mozStorage.js
 @BINPATH@/components/crypto-SDR.js
 @BINPATH@/components/jsconsole-clhandler.manifest
@@ -387,22 +386,16 @@
 @BINPATH@/components/contentSecurityPolicy.manifest
 @BINPATH@/components/contentSecurityPolicy.js
 @BINPATH@/components/contentAreaDropListener.manifest
 @BINPATH@/components/contentAreaDropListener.js
 @BINPATH@/components/messageWakeupService.js
 @BINPATH@/components/messageWakeupService.manifest
 @BINPATH@/components/nsFilePicker.js
 @BINPATH@/components/nsFilePicker.manifest
-#ifdef MOZ_B2G_RIL
-@BINPATH@/components/nsTelephonyWorker.manifest
-@BINPATH@/components/nsTelephonyWorker.js
-@BINPATH@/components/Telephony.manifest
-@BINPATH@/components/Telephony.js
-#endif
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts_s.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
 @BINPATH@/components/nsINIProcessor.manifest
 @BINPATH@/components/nsINIProcessor.js
@@ -465,18 +458,17 @@
 #ifndef XP_MACOSX
 @BINPATH@/icons/*.xpm
 @BINPATH@/icons/*.png
 #endif
 #endif
 
 ; [Default Preferences]
 ; All the pref files must be part of base to prevent migration bugs
-@BINPATH@/@PREF_DIR@/mobile.js
-@BINPATH@/@PREF_DIR@/mobile-branding.js
+@BINPATH@/@PREF_DIR@/b2g.js
 @BINPATH@/@PREF_DIR@/channel-prefs.js
 #ifdef MOZ_SERVICES_SYNC
 @BINPATH@/@PREF_DIR@/services-sync.js
 #endif
 @BINPATH@/greprefs.js
 @BINPATH@/defaults/autoconfig/platform.js
 @BINPATH@/defaults/autoconfig/prefcalls.js
 @BINPATH@/defaults/profile/prefs.js
@@ -516,17 +508,19 @@
 @BINPATH@/res/entityTables/*
 #ifdef XP_MACOSX
 @BINPATH@/res/MainMenu.nib/
 #endif
 
 ; svg
 @BINPATH@/res/svg.css
 @BINPATH@/components/dom_svg.xpt
+#ifdef MOZ_SMIL
 @BINPATH@/components/dom_smil.xpt
+#endif
 
 ; [Personal Security Manager]
 ;
 @BINPATH@/@DLL_PREFIX@nssckbi@DLL_SUFFIX@
 @BINPATH@/components/pipboot.xpt
 @BINPATH@/components/pipnss.xpt
 @BINPATH@/components/pippki.xpt
 @BINPATH@/@DLL_PREFIX@nss3@DLL_SUFFIX@
@@ -590,42 +584,12 @@ bin/libfreebl_32int64_3.so
 bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
 #endif
 
 ; [OS/2]
 #ifdef XP_OS2
 @BINPATH@/MozSounds.cmd
 #endif
 
-[mobile]
+[b2g]
 @BINPATH@/chrome/icons/
 @BINPATH@/chrome/chrome@JAREXT@
 @BINPATH@/chrome/chrome.manifest
-@BINPATH@/components/AboutRedirector.js
-@BINPATH@/components/AddonUpdateService.js
-@BINPATH@/components/AlertsService.js
-@BINPATH@/components/AutoCompleteCache.js
-@BINPATH@/components/BlocklistPrompt.js
-@BINPATH@/components/BrowserCLH.js
-@BINPATH@/components/BrowserStartup.js
-@BINPATH@/components/ContentDispatchChooser.js
-@BINPATH@/components/ContentPermissionPrompt.js
-@BINPATH@/components/DirectoryProvider.js
-@BINPATH@/components/DownloadManagerUI.js
-@BINPATH@/components/FormAutoComplete.js
-@BINPATH@/components/HelperAppDialog.js
-@BINPATH@/components/LoginManager.js
-@BINPATH@/components/LoginManagerPrompter.js
-@BINPATH@/components/MobileComponents.manifest
-@BINPATH@/components/MobileComponents.xpt
-@BINPATH@/components/PromptService.js
-@BINPATH@/components/SessionStore.js
-@BINPATH@/components/Sidebar.js
-#ifdef MOZ_SAFE_BROWSING
-@BINPATH@/components/SafeBrowsing.js
-#endif
-#ifdef MOZ_UPDATER
-@BINPATH@/components/UpdatePrompt.js
-#endif
-@BINPATH@/components/XPIDialogService.js
-@BINPATH@/components/CapturePicker.js
-@BINPATH@/components/browsercomps.xpt
-@BINPATH@/extensions/feedback@mobile.mozilla.org.xpi
copy from mobile/xul/installer/removed-files.in
copy to b2g/installer/removed-files.in
--- a/mobile/xul/installer/removed-files.in
+++ b/b2g/installer/removed-files.in
@@ -1,30 +1,1 @@
-update.locale
 README.txt
-components/nsTryToClose.js
-#if MOZ_UPDATE_CHANNEL != beta
-extensions/feedback@mobile.mozilla.org.xpi
-#endif
-#ifdef XP_WIN
-  #if _MSC_VER != 1400
-    @BINPATH@/Microsoft.VC80.CRT.manifest
-    @BINPATH@/msvcm80.dll
-    @BINPATH@/msvcp80.dll
-    @BINPATH@/msvcr80.dll
-  #endif
-  #if _MSC_VER != 1500
-    @BINPATH@/Microsoft.VC90.CRT.manifest
-    @BINPATH@/msvcm90.dll
-    @BINPATH@/msvcp90.dll
-    @BINPATH@/msvcr90.dll
-  #endif
-  #if _MSC_VER != 1600
-    @BINPATH@/msvcp100.dll
-    @BINPATH@/msvcr100.dll
-  #endif
-  #if _MSC_VER != 1700
-    @BINPATH@/msvcp110.dll
-    @BINPATH@/msvcr110.dll
-  #endif
-  mozcrt19.dll
-  mozcpp19.dll
-#endif
copy from mobile/xul/locales/Makefile.in
copy to b2g/locales/Makefile.in
--- a/mobile/xul/locales/Makefile.in
+++ b/b2g/locales/Makefile.in
@@ -1,249 +1,227 @@
+# vim:set ts=8 sw=8 sts=8 noet:
 # ***** 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.
+# The Original Code is the Mozilla Browser code.
 #
 # The Initial Developer of the Original Code is
-# the Mozilla Foundation <http://www.mozilla.org/>.
-# Portions created by the Initial Developer are Copyright (C) 2007
+# Benjamin Smedberg <bsmedberg@covad.net>
+# Portions created by the Initial Developer are Copyright (C) 2004
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
-#   Mark Finkle <mfinkle@mozilla.com>
-#   Axel Hecht <l10n@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 *****
 
-DEPTH     = ../../..
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-relativesrcdir = mobile/xul/locales
+DEPTH		= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir = b2g/locales
 
 include $(DEPTH)/config/autoconf.mk
+
 include $(topsrcdir)/config/config.mk
 
 ifdef LOCALE_MERGEDIR
-vpath book%.inc $(LOCALE_MERGEDIR)/mobile/profile
-endif
-vpath book%.inc $(LOCALE_SRCDIR)/profile
-ifdef LOCALE_MERGEDIR
-vpath book%.inc @srcdir@/en-US/profile
-endif
-
-ifdef LOCALE_MERGEDIR
-vpath crashreporter%.ini $(LOCALE_MERGEDIR)/mobile/crashreporter
+vpath crashreporter%.ini $(LOCALE_MERGEDIR)/b2g/crashreporter
 endif
 vpath crashreporter%.ini $(LOCALE_SRCDIR)/crashreporter
 ifdef LOCALE_MERGEDIR
 vpath crashreporter%.ini @srcdir@/en-US/crashreporter
 endif
 
+
 SUBMAKEFILES += \
-        $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/Makefile \
-        $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales/Makefile \
-        $(NULL)
+	$(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/Makefile \
+	$(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales/Makefile \
+	$(NULL)
+
+# This makefile uses variable overrides from the libs-% target to
+# build non-default locales to non-default dist/ locations. Be aware!
 
-MOZ_LANGPACK_EID=langpack-$(AB_CD)@firefox-mobile.mozilla.org
-PREF_JS_EXPORTS = $(firstword $(wildcard $(LOCALE_SRCDIR)/mobile-l10n.js) \
-                       @srcdir@/en-US/mobile-l10n.js )
+PWD := $(CURDIR)
 
-# Shouldn't := DEB_BUILD_ARCH despite the $(shell ) as deb isn't everywhere
-DEB_BUILD_ARCH = $(shell dpkg-architecture -qDEB_BUILD_ARCH)
-DATASTAGE = $(CURDIR)/data-stage
+# These are defaulted to be compatible with the files the wget-en-US target
+# pulls. You may override them if you provide your own files. You _must_
+# override them when MOZ_PKG_PRETTYNAMES is defined - the defaults will not
+# work in that case.
+ZIP_IN ?= $(_ABS_DIST)/$(PACKAGE)
+WIN32_INSTALLER_IN ?= $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
+RETRIEVE_WINDOWS_INSTALLER = 1
 
-SEARCH_PLUGINS = $(shell cat \
-  $(firstword $(wildcard $(LOCALE_SRCDIR)/searchplugins/list.txt) \
-       @srcdir@/en-US/searchplugins/list.txt ) )
+MOZ_LANGPACK_EID=langpack-$(AB_CD)@b2g.mozilla.org
 
-tmp-search.jar.mn::
-	printf "$(AB_CD).jar:" > $@
-	printf "$(foreach plugin,$(SEARCH_PLUGINS),$(subst __PLUGIN_SUBST__,$(plugin), \n locale/$(AB_CD)/browser/searchplugins/__PLUGIN_SUBST__.xml (__PLUGIN_SUBST__.xml)))" >>  $@
-	@echo   >> $@
+PREF_JS_EXPORTS = $(call MERGE_FILE,b2g-l10n.js)
 
-searchplugins: tmp-search.jar.mn
-	$(PYTHON) $(MOZILLA_DIR)/config/JarMaker.py \
-          $(QUIET) -j $(FINAL_TARGET)/chrome \
-          -s $(topsrcdir)/$(relativesrcdir)/en-US/searchplugins \
-          -s $(LOCALE_SRCDIR)/searchplugins \
-          $(MAKE_JARS_FLAGS) tmp-search.jar.mn
+ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
+MOZ_PKG_MAC_DSSTORE=$(_ABS_DIST)/branding/dsstore
+MOZ_PKG_MAC_BACKGROUND=$(_ABS_DIST)/branding/background.png
+MOZ_PKG_MAC_ICON=$(_ABS_DIST)/branding/disk.icns
+MOZ_PKG_MAC_EXTRA=--symlink "/Applications:/ "
+endif
 
-export:: searchplugins
-
-GARBAGE += tmp-search.jar.mn
+ifeq (WINNT,$(OS_ARCH))
+UNINSTALLER_PACKAGE_HOOK = $(RM) -r $(STAGEDIST)/uninstall; \
+    $(NSINSTALL) -D $(STAGEDIST)/uninstall; \
+    cp ../installer/windows/l10ngen/helper.exe $(STAGEDIST)/uninstall; \
+    $(RM) $(_ABS_DIST)/l10n-stage/setup.exe; \
+    cp ../installer/windows/l10ngen/setup.exe $(_ABS_DIST)/l10n-stage; \
+    $(NULL)
+endif
 
 include $(topsrcdir)/config/rules.mk
 
 include $(topsrcdir)/toolkit/locales/l10n.mk
 
-clobber-zip:
-	$(RM) $(STAGEDIST)/chrome/$(AB_CD).jar \
-	  $(STAGEDIST)/chrome/$(AB_CD).manifest \
-	  $(STAGEDIST)/defaults/preferences/mobile-l10n.js
-	$(RM) -r $(STAGEDIST)/dictionaries \
-	  $(STAGEDIST)/hyphenation \
-	  $(STAGEDIST)/defaults/profile \
-	  $(STAGEDIST)/chrome/$(AB_CD)
+$(STAGEDIST): $(DIST)/branding
+
+$(DIST)/branding:
+	$(NSINSTALL) -D $@
+
+libs::
+	@if test -f "$(LOCALE_SRCDIR)/existing-profile-defaults.js"; then \
+	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
+	    $(LOCALE_SRCDIR)/existing-profile-defaults.js > $(FINAL_TARGET)/defaults/existing-profile-defaults.js; \
+	fi
+install::
+	@if test -f "$(LOCALE_SRCDIR)/existing-profile-defaults.js"; then \
+	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
+	    $(LOCALE_SRCDIR)/existing-profile-defaults.js > $(DESTDIR)$(mozappdir)/defaults/existing-profile-defaults.js; \
+	fi
+
+NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD))
 
 libs-%:
 	$(NSINSTALL) -D $(DIST)/install
 	@$(MAKE) -C ../../toolkit/locales libs-$* BOTH_MANIFESTS=1
 	@$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
+	@$(MAKE) -C ../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
 	@$(MAKE) -C ../../intl/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
-	@$(MAKE) -B bookmarks.json AB_CD=$*
-	@$(MAKE) -B searchplugins AB_CD=$* XPI_NAME=locale-$*
-	@$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=defaults/preferences BOTH_MANIFESTS=1
+	@$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR) BOTH_MANIFESTS=1
 	@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
 
-# Tailored target to just add the chrome processing for multi-locale builds
-chrome-%:
-	@$(MAKE) -C $(DEPTH)/toolkit/locales chrome-$*
-	@$(MAKE) -C $(DEPTH)/services/sync/locales chrome AB_CD=$*
-	@$(MAKE) -B bookmarks.json AB_CD=$*
-	@$(MAKE) -B searchplugins AB_CD=$*
-	@$(MAKE) chrome AB_CD=$*
-	@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales chrome AB_CD=$*
-ifeq ($(OS_TARGET),Android)
-	@$(MAKE) -C $(DEPTH)/embedding/android chrome AB_CD=$*
+
+repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
+repackage-win32-installer: $(call ESCAPE_SPACE,$(WIN32_INSTALLER_IN)) $(SUBMAKEFILES) libs-$(AB_CD)
+	@echo "Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT)."
+	$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export
+	$(MAKE) -C ../installer/windows CONFIG_DIR=l10ngen l10ngen/setup.exe l10ngen/7zSD.sfx
+	$(MAKE) repackage-zip \
+	  AB_CD=$(AB_CD) \
+	  MOZ_PKG_FORMAT=SFX7Z \
+	  ZIP_IN="$(WIN32_INSTALLER_IN)" \
+	  ZIP_OUT="$(WIN32_INSTALLER_OUT)" \
+	  SFX_HEADER="$(PWD)/../installer/windows/l10ngen/7zSD.sfx \
+	              $(topsrcdir)/b2g/installer/windows/app.tag"
+
+ifeq (WINNT,$(OS_ARCH))
+repackage-win32-installer-%:
+	@$(MAKE) repackage-win32-installer AB_CD=$* WIN32_INSTALLER_IN="$(WIN32_INSTALLER_IN)"
+else
+repackage-win32-installer-%: ;
 endif
 
-# This is a generic target that will make a langpack and repack tarball
-# builds. It is called from the tinderbox scripts. Alter it with caution.
 
-installers-%: clobber-% langpack-% repackage-zip-%
+clobber-zip:
+	$(RM) $(STAGEDIST)/chrome/$(AB_CD).jar \
+	  $(STAGEDIST)/chrome/$(AB_CD).manifest \
+	  $(STAGEDIST)/defaults/pref/b2g-l10n.js
+	  $(STAGEDIST)/dictionaries \
+	  $(STAGEDIST)/hyphenation \
+	  $(STAGEDIST)/defaults/profile \
+	  $(STAGEDIST)/chrome/$(AB_CD)
+
+
+langpack: langpack-$(AB_CD)
+
+# This is a generic target that will make a langpack, repack ZIP (+tarball)
+# builds, and repack an installer if applicable. It is called from the
+# tinderbox scripts. Alter it with caution.
+
+installers-%: clobber-% langpack-% repackage-win32-installer-% repackage-zip-%
 	@echo "repackaging done"
 
-NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD))
-
-bookmarks.json: bookmarks.inc generic/profile/bookmarks.json.in
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
-	  -I $< \
-	  -DAB_CD=$(NO_JA_JP_MAC_AB_CD) \
-	  $(srcdir)/generic/profile/bookmarks.json.in \
-	  > $@
-
-export:: bookmarks.json
-
 ifdef MOZ_UPDATER
-ifdef LOCALE_MERGEDIR
-UPDATER_INI := $(firstword $(wildcard $(LOCALE_MERGEDIR)/updater/updater.ini) \
-       $(wildcard $(LOCALE_SRCDIR)/updater/updater.ini) \
-       $(srcdir)/en-US/updater/updater.ini )
+libs:: $(call MERGE_FILE,updater/updater.ini)
+ifeq ($(OS_ARCH),WINNT)
+	cat $< $(srcdir)/../installer/windows/nsis/updater_append.ini | \
+	  sed -e "s/^InfoText=/Info=/" -e "s/^TitleText=/Title=/" | \
+	  sed -e "s/%MOZ_APP_DISPLAYNAME%/$(MOZ_APP_DISPLAYNAME)/" > \
+	  $(FINAL_TARGET)/updater.ini
 else
-UPDATER_INI := $(addprefix $(LOCALE_SRCDIR)/,updater/updater.ini)
-endif
-libs:: $(UPDATER_INI)
 	cat $< | \
 	  sed -e "s/^InfoText=/Info=/" -e "s/^TitleText=/Title=/" | \
 	  sed -e "s/%MOZ_APP_DISPLAYNAME%/$(MOZ_APP_DISPLAYNAME)/" > \
 	  $(FINAL_TARGET)/updater.ini
 endif
+endif
 
 ifdef MOZ_CRASHREPORTER
 libs:: crashreporter-override.ini
 	$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
 endif
 
-# When we unpack fennec on MacOS X the platform.ini and application.ini are in slightly
+# When we unpack b2g on MacOS X the platform.ini and application.ini are in slightly
 # different locations that on all other platforms
 ifeq (Darwin, $(OS_ARCH))
 ifdef LIBXUL_SDK
 GECKO_PLATFORM_INI_PATH="$(STAGEDIST)/../Frameworks/XUL.framework/Versions/$(MOZILLA_VERSION)/platform.ini"
 else
 GECKO_PLATFORM_INI_PATH="$(STAGEDIST)/platform.ini"
 endif
-FENNEC_APPLICATION_INI_PATH="$(STAGEDIST)/application.ini"
+B2G_APPLICATION_INI_PATH="$(STAGEDIST)/application.ini"
 else
 ifdef LIBXUL_SDK
 GECKO_PLATFORM_INI_PATH="$(STAGEDIST)/xulrunner/platform.ini"
 else
 GECKO_PLATFORM_INI_PATH="$(STAGEDIST)/platform.ini"
 endif
-FENNEC_APPLICATION_INI_PATH="$(STAGEDIST)/application.ini"
+B2G_APPLICATION_INI_PATH="$(STAGEDIST)/application.ini"
 endif
 
+
 ident:
 	@printf "gecko_revision "
 	@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(GECKO_PLATFORM_INI_PATH) Build SourceStamp
-	@printf "fennec_revision "
-	@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(FENNEC_APPLICATION_INI_PATH) App SourceStamp
+	@printf "b2g_revision "
+	@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(B2G_APPLICATION_INI_PATH) App SourceStamp
 	@printf "buildid "
-	@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(FENNEC_APPLICATION_INI_PATH) App BuildID
-
-# special targets just to do the debian single locale packages
-wget-DEB_PKG_NAME:
-ifndef WGET
-	$(error Wget not installed)
-endif
-ifndef EN_US_BINARY_URL
-	$(error EN_US_BINARY_URL not defined)
-endif
-	@$(WGET) -q -O - $(EN_US_BINARY_URL)/deb_name.txt
-
-wget-deb:
-ifndef WGET
-	$(error Wget not installed)
-endif
-ifndef EN_US_BINARY_URL
-	$(error EN_US_BINARY_URL not defined)
-endif
-ifndef DEB_PKG_NAME
-	$(error DEB_PKG_NAME not defined)
-endif
-	$(WGET) -nv -N  $(EN_US_BINARY_URL)/$(DEB_PKG_NAME)
-
-$(DATASTAGE): $(DEB_PKG_NAME)
-	$(RM) -rf $(DATASTAGE)
-	$(NSINSTALL) -D $(DATASTAGE)/DEBIAN
-	ar -p $(DEB_PKG_NAME) data.tar.gz | $(TAR) -zx -C $(DATASTAGE)
-	$(MAKE) clobber-zip AB_CD=en-US STAGEDIST=$(DATASTAGE)/$(installdir)
-	ar -p $(DEB_PKG_NAME) control.tar.gz | $(TAR) -zx -C $(DATASTAGE)/DEBIAN
-# XXX hack around multi-locale deb right now
-	$(RM) $(DATASTAGE)/$(installdir)/chrome/??.*
-	$(RM) $(DATASTAGE)/$(installdir)/chrome/??-??.*
-
-repackage-deb: $(DATASTAGE)
-	$(RM) -rf $(AB_CD)
-	$(NSINSTALL) -D $(AB_CD)/tmp
-	cd $(DIST)/xpi-stage/locale-$(AB_CD) && \
-	  $(TAR) --exclude=install.rdf --exclude=chrome.manifest --exclude=crashreporter.app $(TAR_CREATE_FLAGS) - * | ( cd $(DATASTAGE)/$(installdir) && $(TAR) -xf - )
-	cd $(DATASTAGE) && $(TAR) $(TAR_CREATE_FLAGS) - * | (cd $(CURDIR)/$(AB_CD)/tmp && $(TAR) -xf - )
-	$(MAKE) clobber-zip STAGEDIST=$(DATASTAGE)/$(installdir)
-	cd $(AB_CD) && dpkg-deb -b tmp $(DEB_PKG_NAME)
-	$(RM) -rf $(AB_CD)/tmp
-
-deb-%: AB_CD=$*
-deb-%: clobber-% langpack-%
-ifndef DEB_PKG_NAME
-	$(error DEB_PKG_NAME not defined)
-endif
-	@$(MAKE) repackage-deb AB_CD=$(AB_CD) DEB_PKG_NAME=$(DEB_PKG_NAME)
+	@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(B2G_APPLICATION_INI_PATH) App BuildID
 
 merge-%:
 ifdef LOCALE_MERGEDIR
 	$(RM) -rf $(LOCALE_MERGEDIR)
 	MACOSX_DEPLOYMENT_TARGET= compare-locales -m $(LOCALE_MERGEDIR) $(srcdir)/l10n.ini $(L10NBASEDIR) $*
 endif
 	@echo
+
+# test target, depends on make package
+# try to repack x-test, with just toolkit/defines.inc being there
+l10n-check::
+	$(RM) -rf x-test
+	$(NSINSTALL) -D x-test/toolkit
+	echo "#define MOZ_LANG_TITLE Just testing" > x-test/toolkit/defines.inc
+	$(MAKE) installers-x-test L10NBASEDIR="$(PWD)" LOCALE_MERGEDIR="$(PWD)/mergedir"
copy from mobile/xul/locales/all-locales
copy to b2g/locales/all-locales
new file mode 100644
--- /dev/null
+++ b/b2g/locales/en-US/b2g-l10n.js
@@ -0,0 +1,39 @@
+# ***** 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 Firefox browser.
+#
+# The Initial Developer of the Original Code is
+# Benjamin Smedberg <bsmedberg@covad.net>
+# Portions created by the Initial Developer are Copyright (C) 2004
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#filter substitution
+
+pref("general.useragent.locale", "@AB_CD@");
copy from mobile/xul/locales/en-US/chrome/about.dtd
copy to b2g/locales/en-US/chrome/about.dtd
copy from mobile/xul/locales/en-US/chrome/aboutCertError.dtd
copy to b2g/locales/en-US/chrome/aboutCertError.dtd
copy from mobile/xul/locales/en-US/chrome/notification.dtd
copy to b2g/locales/en-US/chrome/notification.dtd
copy from mobile/xul/locales/en-US/chrome/overrides/appstrings.properties
copy to b2g/locales/en-US/chrome/overrides/appstrings.properties
copy from mobile/xul/locales/en-US/chrome/overrides/netError.dtd
copy to b2g/locales/en-US/chrome/overrides/netError.dtd
copy from mobile/xul/locales/en-US/chrome/overrides/passwordmgr.properties
copy to b2g/locales/en-US/chrome/overrides/passwordmgr.properties
copy from mobile/xul/locales/en-US/chrome/phishing.dtd
copy to b2g/locales/en-US/chrome/phishing.dtd
copy from mobile/xul/locales/en-US/chrome/webapps.dtd
copy to b2g/locales/en-US/chrome/webapps.dtd
copy from mobile/xul/locales/en-US/crashreporter/crashreporter-override.ini
copy to b2g/locales/en-US/crashreporter/crashreporter-override.ini
--- a/mobile/xul/locales/en-US/crashreporter/crashreporter-override.ini
+++ b/b2g/locales/en-US/crashreporter/crashreporter-override.ini
@@ -1,10 +1,10 @@
 # This file is in the UTF-8 encoding
 [Strings]
 # LOCALIZATION NOTE (CrashReporterProductErrorText2): %s is replaced with another string containing detailed information.
-CrashReporterProductErrorText2=Firefox has crashed. Unfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s
-CrashReporterDescriptionText2=Firefox has crashed. Your tabs will be listed on the Firefox Start page when you restart.\n\nPlease help us fix the problem!
+CrashReporterProductErrorText2=B2G has crashed. Unfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s
+CrashReporterDescriptionText2=B2G has crashed. Your tabs will be listed on the B2G Start page when you restart.\n\nPlease help us fix the problem!
 # LOCALIZATION NOTE (CheckSendReport): The %s is replaced with the vendor name.
 CheckSendReport=Send %s a crash report
 CheckIncludeURL=Include the page address
-Quit2=Quit Firefox
-Restart=Restart Firefox
+Quit2=Quit B2G
+Restart=Restart B2G
copy from mobile/xul/locales/en-US/defines.inc
copy to b2g/locales/en-US/defines.inc
copy from mobile/xul/locales/en-US/installer/setup.ini
copy to b2g/locales/en-US/installer/setup.ini
copy from mobile/xul/locales/en-US/updater/updater.ini
copy to b2g/locales/en-US/updater/updater.ini
copy from mobile/xul/locales/filter.py
copy to b2g/locales/filter.py
--- a/mobile/xul/locales/filter.py
+++ b/b2g/locales/filter.py
@@ -33,28 +33,32 @@
 # 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 *****
 
 
 def test(mod, path, entity = None):
   import re
-  # ignore anything but mobile, which is our local repo checkout name
+  # ignore anything but b2g, which is our local repo checkout name
   if mod not in ("netwerk", "dom", "toolkit", "security/manager",
                  "services/sync", "embedding/android",
-                 "mobile/xul"):
+                 "b2g"):
     return False
 
-  if mod != "mobile/xul":
-    # we only have exceptions for mobile
+  # Ignore Lorentz strings, at least temporarily
+  if mod == "toolkit" and path == "chrome/mozapps/plugins/plugins.dtd":
+    if entity.startswith('reloadPlugin.'): return False
+    if entity.startswith('report.'): return False
+
+  if mod != "b2g":
+    # we only have exceptions for b2g
     return True
   if not entity:
-    return not (re.match(r"searchplugins\/.+\.xml", path) or
-                re.match(r"mobile-l10n.js", path) or
+    return not (re.match(r"b2g-l10n.js", path) or
                 re.match(r"defines.inc", path))
   if path == "defines.inc":
     return entity != "MOZ_LANGPACK_CONTRIBUTORS"
 
   if path != "chrome/region.properties":
     # only region.properties exceptions remain, compare all others
     return True
   
copy from mobile/xul/locales/generic/install.rdf
copy to b2g/locales/generic/install.rdf
--- a/mobile/xul/locales/generic/install.rdf
+++ b/b2g/locales/generic/install.rdf
@@ -48,15 +48,15 @@
                em:type="8"
                em:creator="@MOZ_LANGPACK_CREATOR@">
 #ifdef MOZ_LANGPACK_CONTRIBUTORS
     @MOZ_LANGPACK_CONTRIBUTORS@
 #endif
 
     <em:targetApplication>
       <Description>
-        <em:id>{a23983c0-fd0e-11dc-95ff-0800200c9a66}</em:id>
+        <em:id>{3c2e2abc-06d4-11e1-ac3b-374f68613e61}</em:id>
         <em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
         <em:maxVersion>@MOZ_APP_VERSION@</em:maxVersion>
       </Description>
     </em:targetApplication>
   </Description>
 </RDF>
copy from mobile/xul/locales/jar.mn
copy to b2g/locales/jar.mn
--- a/mobile/xul/locales/jar.mn
+++ b/b2g/locales/jar.mn
@@ -1,31 +1,12 @@
 #filter substitution
 
 @AB_CD@.jar:
 % locale browser @AB_CD@ %locale/@AB_CD@/browser/
   locale/@AB_CD@/browser/about.dtd                (%chrome/about.dtd)
   locale/@AB_CD@/browser/aboutCertError.dtd       (%chrome/aboutCertError.dtd)
-  locale/@AB_CD@/browser/aboutHome.dtd            (%chrome/aboutHome.dtd)
-  locale/@AB_CD@/browser/browser.dtd              (%chrome/browser.dtd)
-  locale/@AB_CD@/browser/browser.properties       (%chrome/browser.properties)
-  locale/@AB_CD@/browser/config.dtd               (%chrome/config.dtd)
-  locale/@AB_CD@/browser/localepicker.properties  (%chrome/localepicker.properties)
-  locale/@AB_CD@/browser/region.properties        (%chrome/region.properties)
-  locale/@AB_CD@/browser/preferences.dtd          (%chrome/preferences.dtd)
-  locale/@AB_CD@/browser/checkbox.dtd             (%chrome/checkbox.dtd)
   locale/@AB_CD@/browser/notification.dtd         (%chrome/notification.dtd)
-  locale/@AB_CD@/browser/sync.dtd                 (%chrome/sync.dtd)
-  locale/@AB_CD@/browser/sync.properties          (%chrome/sync.properties)
-  locale/@AB_CD@/browser/prompt.dtd               (%chrome/prompt.dtd)
   locale/@AB_CD@/browser/webapps.dtd              (%chrome/webapps.dtd)
-  locale/@AB_CD@/browser/feedback.dtd             (%chrome/feedback.dtd)
   locale/@AB_CD@/browser/phishing.dtd             (%chrome/phishing.dtd)
-  locale/@AB_CD@/browser/bookmarks.json           (bookmarks.json)
-  locale/@AB_CD@/browser/searchplugins/list.txt   (%searchplugins/list.txt)
 
-# Fennec-specific overrides of generic strings
 * locale/@AB_CD@/browser/netError.dtd             (%chrome/overrides/netError.dtd)
 % override chrome://global/locale/netError.dtd    chrome://browser/locale/netError.dtd
-* locale/@AB_CD@/browser/appstrings.properties    (%chrome/overrides/appstrings.properties)
-% override chrome://global/locale/appstrings.properties chrome://browser/locale/appstrings.properties
-* locale/@AB_CD@/browser/passwordmgr.properties    (%chrome/overrides/passwordmgr.properties)
-% override chrome://passwordmgr/locale/passwordmgr.properties chrome://browser/locale/passwordmgr.properties
copy from mobile/xul/locales/l10n.ini
copy to b2g/locales/l10n.ini
--- a/mobile/xul/locales/l10n.ini
+++ b/b2g/locales/l10n.ini
@@ -1,11 +1,10 @@
 [general]
-depth = ../../..
-all = mobile/xul/locales/all-locales
+depth = ../..
+all = b2g/locales/all-locales
 
 [compare]
-dirs = mobile/xul
+dirs = b2g
 
 [includes]
 toolkit = toolkit/locales/l10n.ini
 services_sync = services/sync/locales/l10n.ini
-embedding_android = embedding/android/locales/l10n.ini
copy from mobile/xul/makefiles.sh
copy to b2g/makefiles.sh
--- a/mobile/xul/makefiles.sh
+++ b/b2g/makefiles.sh
@@ -10,49 +10,44 @@
 # 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.
 #
 # The Initial Developer of the Original Code is
 # the Mozilla Foundation <http://www.mozilla.org/>.
-# Portions created by the Initial Developer are Copyright (C) 2007
+# Portions created by the Initial Developer are Copyright (C) 2011
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
-#   Mark Finkle <mfinkle@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 *****
 
 add_makefiles "
-mobile/xul/app/Makefile
-mobile/xul/app/profile/extensions/Makefile
+netwerk/locales/Makefile
+dom/locales/Makefile
+toolkit/locales/Makefile
+security/manager/locales/Makefile
+b2g/app/Makefile
 $MOZ_BRANDING_DIRECTORY/Makefile
-$MOZ_BRANDING_DIRECTORY/content/Makefile
-$MOZ_BRANDING_DIRECTORY/locales/Makefile
-mobile/xul/chrome/Makefile
-mobile/xul/components/Makefile
-mobile/xul/components/build/Makefile
-mobile/xul/modules/Makefile
-mobile/xul/installer/Makefile
-mobile/xul/locales/Makefile
-mobile/xul/Makefile
-mobile/xul/themes/core/Makefile
-"
+b2g/chrome/Makefile
+b2g/installer/Makefile
+b2g/locales/Makefile
+b2g/Makefile"
 
-if [ "$ENABLE_TESTS" ]; then
-  add_makefiles "
-    mobile/xul/chrome/tests/Makefile
-  "
+if test -n "$MOZ_UPDATE_PACKAGING"; then
+   add_makefiles "
+     tools/update-packaging/Makefile
+   "
 fi
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -274,17 +274,21 @@
 
     <menupopup id="contentAreaContextMenu" pagemenu="start"
                onpopupshowing="if (event.target != this)
                                  return true;
                                gContextMenu = new nsContextMenu(this, gBrowser, event.shiftKey);
                                if (gContextMenu.shouldDisplay)
                                  updateEditUIVisibility();
                                return gContextMenu.shouldDisplay;"
-               onpopuphiding="if (event.target == this) { gContextMenu = null; updateEditUIVisibility(); }">
+               onpopuphiding="if (event.target != this)
+                                return;
+                              gContextMenu.hiding();
+                              gContextMenu = null;
+                              updateEditUIVisibility();">
 #include browser-context.inc
     </menupopup>
 
     <menupopup id="placesContext"/>
 
     <panel id="notification-popup"
            type="arrow"
            footertype="promobox"
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -92,16 +92,22 @@ nsContextMenu.prototype = {
     } catch (e) { }
     this.isTextSelected = this.isTextSelection();
     this.isContentSelected = this.isContentSelection();
 
     // Initialize (disable/remove) menu items.
     this.initItems();
   },
 
+  hiding: function CM_hiding() {
+    InlineSpellCheckerUI.clearSuggestionsFromMenu();
+    InlineSpellCheckerUI.clearDictionaryListFromMenu();
+    InlineSpellCheckerUI.uninit();
+  },
+
   initItems: function CM_initItems() {
     this.initPageMenuSeparator();
     this.initOpenItems();
     this.initNavigationItems();
     this.initViewItems();
     this.initMiscItems();
     this.initSpellingItems();
     this.initSaveItems();
@@ -483,26 +489,16 @@ nsContextMenu.prototype = {
     this.onMathML          = false;
     this.inFrame           = false;
     this.inSyntheticDoc    = false;
     this.hasBGImage        = false;
     this.bgImageURL        = "";
     this.onEditableArea    = false;
     this.isDesignMode      = false;
 
-    // Clear any old spellchecking items from the menu, this used to
-    // be in the menu hiding code but wasn't getting called in all
-    // situations. Here, we can ensure it gets cleaned up any time the
-    // menu is shown. Note: must be before uninit because that clears the
-    // internal vars
-    InlineSpellCheckerUI.clearSuggestionsFromMenu();
-    InlineSpellCheckerUI.clearDictionaryListFromMenu();
-
-    InlineSpellCheckerUI.uninit();
-
     // Remember the node that was clicked.
     this.target = aNode;
 
     // Check if we are in a synthetic document (stand alone image, video, etc.).
     this.inSyntheticDoc =  this.target.ownerDocument.mozSyntheticDocument;
     // First, do checks for nodes that never have children.
     if (this.target.nodeType == Node.ELEMENT_NODE) {
       // See if the user clicked on an image.
--- a/browser/base/content/web-panels.xul
+++ b/browser/base/content/web-panels.xul
@@ -82,18 +82,20 @@
     <tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
     <menupopup id="contentAreaContextMenu" pagemenu="start"
                onpopupshowing="if (event.target != this)
                                  return true;
                                gContextMenu = new nsContextMenu(this, getPanelBrowser(), event.shiftKey);
                                if (gContextMenu.shouldDisplay)
                                  document.popupNode = this.triggerNode;
                                return gContextMenu.shouldDisplay;"
-               onpopuphiding="if (event.target == this)
-                                gContextMenu = null;">
+               onpopuphiding="if (event.target != this)
+                                return;
+                              gContextMenu.hiding();
+                              gContextMenu = null;">
 #include browser-context.inc
     </menupopup>
   </popupset>
 
   <commandset id="editMenuCommands"/> 
   <browser id="web-panels-browser" persist="cachedurl" type="content" flex="1"
            context="contentAreaContextMenu" tooltip="aHTMLTooltip"
            onclick="return window.parent.contentAreaClick(event, true);"/>
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -133,17 +133,17 @@
 @BINPATH@/components/cookie.xpt
 @BINPATH@/components/directory.xpt
 @BINPATH@/components/docshell.xpt
 @BINPATH@/components/dom.xpt
 @BINPATH@/components/dom_apps.xpt
 @BINPATH@/components/dom_base.xpt
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/dom_telephony.xpt
-@BINPATH@/components/dom_telephony_worker.xpt
+@BINPATH@/components/dom_system_b2g.xpt
 #endif
 @BINPATH@/components/dom_battery.xpt
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_geolocation.xpt
 @BINPATH@/components/dom_notification.xpt
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -65,17 +65,17 @@ components/nsExtensionManager.js
 components/nsInterfaceInfoToIDL.js
 components/nsScriptableIO.js
 components/nsUrlClassifierTable.js
 components/nsXmlRpcClient.js
 components/pluginGlue.js
 components/sidebar.xpt
 #ifdef MOZ_B2G_RIL
 components/dom_telephony.xpt
-components/dom_telephony_worker.xpt
+components/dom_system_b2g.xpt
 #endif
 components/WeaveCrypto.js
 components/WeaveCrypto.manifest
 components/xmlextras.xpt
 components/xpcom.xpt
 components/xpti.dat
 components/xptitemp.dat
 components/nsMicrosummaryService.js
@@ -1137,17 +1137,17 @@ xpicleanup@BIN_SUFFIX@
   components/cookie.xpt
   components/crashreporter.xpt
   components/directory.xpt
   components/docshell.xpt
   components/dom.xpt
   components/dom_base.xpt
 #ifdef MOZ_B2G_RIL
   components/dom_telephony.xpt
-  components/dom_telephony_worker.xpt
+  components/dom_system_b2g.xpt
 #endif
   components/dom_canvas.xpt
   components/dom_core.xpt
   components/dom_css.xpt
   components/dom_events.xpt
   components/dom_geolocation.xpt
   components/dom_html.xpt
   components/dom_json.xpt
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -129,16 +129,25 @@ public:
    */
   void UpdateState(bool aNotify);
   
   /**
    * Method to update mState with link state information.  This does not notify.
    */
   void UpdateLinkState(nsEventStates aState);
 
+  /**
+   * Returns true if this element is either a full-screen element or an
+   * ancestor of the full-screen element.
+   */
+  bool IsFullScreenAncestor() const {
+    return mState.HasAtLeastOneOfStates(NS_EVENT_STATE_FULL_SCREEN_ANCESTOR |
+                                        NS_EVENT_STATE_FULL_SCREEN);
+  }
+
 protected:
   /**
    * Method to get the _intrinsic_ content state of this element.  This is the
    * state that is independent of the element's presentation.  To get the full
    * content state, use State().  See nsEventStates.h for
    * the possible bits that could be set here.
    */
   virtual nsEventStates IntrinsicState() const;
deleted file mode 100644
--- a/content/base/public/nsIDOMGCParticipant.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998-1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef nsIDOMGCParticipant_h_
-#define nsIDOMGCParticipant_h_
-
-#include "nsISupports.h"
-
-template<class E> class nsCOMArray;
-
-// 0e2a5a8d-28fd-4a5c-8bf1-5b0067ff3286
-#define NS_IDOMGCPARTICIPANT_IID \
-{ 0x0e2a5a8d, 0x28fd, 0x4a5c, \
-  {0x8b, 0xf1, 0x5b, 0x00, 0x67, 0xff, 0x32, 0x86} }
-
-/**
- * DOM GC Participants are objects that expose information about
- * reachability in the native object graphs to help prevent script ->
- * native -> script cyclical reference from causing leaks due to the
- * creation of garbage collection roots and native/script boundaries.
- *
- * Some implementations of nsIDOMGCParticipant may be responsible for
- * enforcing the requirement that callers of
- * |nsDOMClassInfo::PreserveWrapper| must call
- * |nsDOMClassInfo::ReleaseWrapper| before the nsIDOMGCParticipant
- * argument to the former is destroyed.
- */
-class nsIDOMGCParticipant : public nsISupports
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMGCPARTICIPANT_IID)
-
-  /**
-   * Get a reference node for what is known to be a strongly connected
-   * component of nsIDOMGCParticipants.  For example, DOM trees are
-   * strongly connected, so can return the root node to greatly reduce
-   * the number of nodes on which we need to run graph algorithms.
-   *
-   * Note that it's acceptable for nodes in a single strongly connected
-   * component to return different values for GetSCCIndex, as long as
-   * those two values claim that they're reachable from each other in
-   * AppendReachableList.
-   */
-  virtual nsIDOMGCParticipant* GetSCCIndex() = 0;
-
-  /**
-   * Append the list of nsIDOMGCPartipants reachable from this one via
-   * C++ getters exposed to script that return a different result from
-   * |GetSCCIndex|.  The caller is responsible for taking the transitive
-   * closure of |AppendReachableList|.
-   *
-   * This will only be called on objects that are returned by GetSCCIndex.
-   *
-   * null pointers may be appended; they will be ignored by the caller.
-   */
-  virtual void AppendReachableList(nsCOMArray<nsIDOMGCParticipant>& aArray) = 0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMGCParticipant, NS_IDOMGCPARTICIPANT_IID)
-
-#endif // !defined(nsIDOMGCParticipant_h_)
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -119,18 +119,19 @@ class Loader;
 
 namespace dom {
 class Link;
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID \
-{ 0x3b78f6, 0x6dc5, 0x44c6, \
-  { 0xbc, 0x28, 0x60, 0x2a, 0xb2, 0x4f, 0xfb, 0x7b } }
+{ 0x283ec27d, 0x5b23, 0x49b2, \
+  { 0x94, 0xd9, 0x9, 0xb5, 0xdb, 0x45, 0x30, 0x73 } }
+
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 // Enum for requesting a particular type of document when creating a doc
 enum DocumentFlavor {
   DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
   DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
@@ -747,31 +748,41 @@ public:
    * contains the element which requested DOM full-screen mode if the
    * requestee is in a subdocument. Note this element must be *in*
    * this document.
    */
   virtual Element* GetFullScreenElement() = 0;
 
   /**
    * Asynchronously requests that the document make aElement the full-screen
-   * element, and move into full-screen mode.
+   * element, and move into full-screen mode. The current full-screen element
+   * (if any) is pushed onto the full-screen element stack, and it can be
+   * returned to full-screen status by calling RestorePreviousFullScreenState().
    */
   virtual void AsyncRequestFullScreen(Element* aElement) = 0;
 
   /**
-   * Requests that the document, and all documents in its hierarchy exit
-   * from DOM full-screen mode.
+   * Restores the previous full-screen element to full-screen status. If there
+   * is no former full-screen element, this exits full-screen, moving the
+   * top-level browser window out of full-screen mode.
    */
-  virtual void CancelFullScreen() = 0;
+  virtual void RestorePreviousFullScreenState() = 0;
 
   /**
    * Returns true if this document is in full-screen mode.
    */
   virtual bool IsFullScreenDoc() = 0;
 
+  /**
+   * Exits all documents from DOM full-screen mode, and moves the top-level
+   * browser window out of full-screen mode. If aRunAsync is true, this runs
+   * asynchronously.
+   */
+  static void ExitFullScreen(bool aRunAsync);
+
   //----------------------------------------------------------------------
 
   // Document notification API's
 
   /**
    * Add a new observer of document change notifications. Whenever
    * content is changed, appended, inserted or removed the observers are
    * informed.  An observer that is already observing the document must
@@ -1513,17 +1524,19 @@ public:
    * Lookup an image element using its associated ID, which is usually provided
    * by |-moz-element()|. Similar to GetElementById, with the difference that
    * elements set using mozSetImageElement have higher priority.
    * @param aId the ID associated the element we want to lookup
    * @return the element associated with |aId|
    */
   virtual Element* LookupImageElement(const nsAString& aElementId) = 0;
 
-  void ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback);
+  nsresult ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback,
+                                        PRInt32 *aHandle);
+  void CancelFrameRequestCallback(PRInt32 aHandle);
 
   typedef nsTArray< nsCOMPtr<nsIFrameRequestCallback> > FrameRequestCallbackList;
   /**
    * Put this document's frame request callbacks into the provided
    * list, and forget about them.
    */
   void TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks);
 
@@ -1794,23 +1807,52 @@ protected:
   PRUint32 mEventsSuppressed;
 
   /**
    * The number number of external scripts (ones with the src attribute) that
    * have this document as their owner and that are being evaluated right now.
    */
   PRUint32 mExternalScriptsBeingEvaluated;
 
+  /**
+   * The current frame request callback handle
+   */
+  PRInt32 mFrameRequestCallbackCounter;
+
   // Weak reference to mScriptGlobalObject QI:d to nsPIDOMWindow,
   // updated on every set of mSecriptGlobalObject.
   nsPIDOMWindow *mWindow;
 
   nsCOMPtr<nsIDocumentEncoder> mCachedEncoder;
 
-  FrameRequestCallbackList mFrameRequestCallbacks;
+  struct FrameRequest {
+    FrameRequest(nsIFrameRequestCallback* aCallback,
+                 PRInt32 aHandle) :
+      mCallback(aCallback),
+      mHandle(aHandle)
+    {}
+
+    // Conversion operator so that we can append these to a
+    // FrameRequestCallbackList
+    operator nsIFrameRequestCallback* const () const { return mCallback; }
+
+    // Comparator operators to allow RemoveElementSorted with an
+    // integer argument on arrays of FrameRequest
+    bool operator==(PRInt32 aHandle) const {
+      return mHandle == aHandle;
+    }
+    bool operator<(PRInt32 aHandle) const {
+      return mHandle < aHandle;
+    }
+    
+    nsCOMPtr<nsIFrameRequestCallback> mCallback;
+    PRInt32 mHandle;
+  };
+
+  nsTArray<FrameRequest> mFrameRequestCallbacks;
 
   // This object allows us to evict ourself from the back/forward cache.  The
   // pointer is non-null iff we're currently in the bfcache.
   nsIBFCacheEntry *mBFCacheEntry;
 
   // Our base target.
   nsString mBaseTarget;
 
--- a/content/base/public/nsIEventSource.idl
+++ b/content/base/public/nsIEventSource.idl
@@ -46,27 +46,32 @@
 
 #include "nsISupports.idl"
 
 interface nsIDOMEventListener;
 interface nsIPrincipal;
 interface nsIScriptContext;
 interface nsPIDOMWindow;
 
-[scriptable, uuid(755e2d2d-a836-4539-83f4-16b51156341f)]
+[scriptable, uuid(a3d3181e-47c1-4f2e-b2c7-94775a86f5c5)]
 interface nsIEventSource : nsISupports
 {
   readonly attribute DOMString url;
 
   // ready state
   const unsigned short CONNECTING = 0;
   const unsigned short OPEN = 1;
   const unsigned short CLOSED = 2;
   readonly attribute long readyState;
 
+  // if true then cross-site Access-Control requests are made using credentials
+  // such as cookies and authorization headers. Never affects same-site
+  // requests.
+  readonly attribute boolean withCredentials;
+
   // event handler attributes
   attribute nsIDOMEventListener onopen;
   attribute nsIDOMEventListener onmessage;
   attribute nsIDOMEventListener onerror;
 
   /**
    * Close the connection, if any, and set the readyState attribute to CLOSED.
    * If the connection is already closed, the method does nothing.
@@ -78,14 +83,19 @@ interface nsIEventSource : nsISupports
    * context, and owner window that should be used.
    *
    * @param principal The principal to use for the request. This must not be
    *                  null.
    * @param scriptContext The script context to use for the request. May be
    *                      null.
    * @param ownerWindow The associated window for the request. May be null.
    * @param url The EventSource's url. This must not be empty.
+   * @param withCredentials When set to true attempts to make cross-site
+   *                        Access-Control requests with credentials such as
+   *                        cookies and authorization headers. Never affects
+   *                        same-site requests.
    */
   [noscript] void init(in nsIPrincipal principal,
                        in nsIScriptContext scriptContext,
                        in nsPIDOMWindow ownerWindow,
-                       in DOMString url);
+                       in DOMString url,
+                       in boolean withCredentials);
 };
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1533,17 +1533,16 @@ nsDOMImplementation::CreateHTMLDocument(
 // ==================================================================
 
   // NOTE! nsDocument::operator new() zeroes out all members, so don't
   // bother initializing members to 0.
 
 nsDocument::nsDocument(const char* aContentType)
   : nsIDocument()
   , mAnimatingImages(true)
-  , mIsFullScreen(false)
   , mVisibilityState(eHidden)
 {
   SetContentTypeInternal(nsDependentCString(aContentType));
   
 #ifdef PR_LOGGING
   if (!gDocumentLeakPRLog)
     gDocumentLeakPRLog = PR_NewLogModule("DocumentLeak");
 
@@ -1868,17 +1867,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLayoutHistoryState)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnloadBlocker)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstBaseNodeWithHref)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDOMImplementation)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mImageMaps,
                                                        nsIDOMNodeList)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOriginalDocument)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCachedEncoder)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFullScreenElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mStateObjectCached)
 
   // Traverse all our nsCOMArrays.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mStyleSheets)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mCatalogSheets)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mPreloadingImages)
 
   for (PRUint32 i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) {
@@ -1923,17 +1921,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mXPathEvaluatorTearoff)
   tmp->mCachedRootElement = nsnull; // Avoid a dangling pointer
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDisplayDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstBaseNodeWithHref)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDOMImplementation)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mImageMaps)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOriginalDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCachedEncoder)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFullScreenElement)
 
   tmp->mParentDocument = nsnull;
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mPreloadingImages)
 
   
   if (tmp->mBoxObjectTable) {
    tmp->mBoxObjectTable->EnumerateRead(ClearAllBoxObjects, nsnull);
@@ -7299,31 +7296,16 @@ nsDocument::OnPageShow(bool aPersisted,
 static bool
 NotifyPageHide(nsIDocument* aDocument, void* aData)
 {
   const bool* aPersistedPtr = static_cast<const bool*>(aData);
   aDocument->OnPageHide(*aPersistedPtr, nsnull);
   return true;
 }
 
-static bool
-SetFullScreenState(nsIDocument* aDoc, Element* aElement, bool aIsFullScreen);
-
-static void
-SetWindowFullScreen(nsIDocument* aDoc, bool aValue);
-
-static bool
-ResetFullScreen(nsIDocument* aDocument, void* aData) {
-  if (aDocument->IsFullScreenDoc()) {
-    ::SetFullScreenState(aDocument, nsnull, false);
-    aDocument->EnumerateSubDocuments(ResetFullScreen, nsnull);
-  }
-  return true;
-}
-
 void
 nsDocument::OnPageHide(bool aPersisted,
                        nsIDOMEventTarget* aDispatchStartTarget)
 {
   // Send out notifications that our <link> elements are detached,
   // but only if this is not a full unload.
   Element* root = GetRootElement();
   if (aPersisted && root) {
@@ -7368,33 +7350,25 @@ nsDocument::OnPageHide(bool aPersisted,
   
   EnumerateExternalResources(NotifyPageHide, &aPersisted);
   EnumerateFreezableElements(NotifyActivityChanged, nsnull);
 
   if (IsFullScreenDoc()) {
     // A full-screen doc has been hidden. We need to ensure we exit
     // full-screen, i.e. remove full-screen state from all full-screen
     // documents, and exit the top-level window from full-screen mode.
-    // Unfortunately by the time a doc is hidden, it has been removed
-    // from the doc tree, so we can't just call CancelFullScreen()...
-
-    // So firstly reset full-screen state in *this* document. OnPageHide()
-    // is called in every hidden document, so doing this ensures all hidden
-    // documents have their state reset.
-    ::SetFullScreenState(this, nsnull, false);
-
-    // Next walk the document tree of still visible documents, and reset
-    // their full-screen state. We then move the top-level window out
-    // of full-screen mode.
-    nsCOMPtr<nsIDocument> fullScreenRoot(do_QueryReferent(sFullScreenRootDoc));
-    if (fullScreenRoot) {
-      fullScreenRoot->EnumerateSubDocuments(ResetFullScreen, nsnull);
-      SetWindowFullScreen(fullScreenRoot, false);
-      sFullScreenRootDoc = nsnull;
-    }
+    // By the time a doc is hidden, it has been removed from the doc tree,
+    // so nsIDocument::ExitFullScreen() won't be able to traverse to this
+    // document to reset its state, so reset full-screen state in *this*
+    // document. OnPageHide() is called in every hidden document, so doing
+    // this ensures all hidden documents have their full-screen state reset.
+    ClearFullScreenStack();
+
+    // Next reset full-screen state in all visible documents in the doctree.
+    nsIDocument::ExitFullScreen(false);
   }
 }
 
 void
 nsDocument::WillDispatchMutationEvent(nsINode* aTarget)
 {
   NS_ASSERTION(mSubtreeModifiedDepth != 0 ||
                mSubtreeModifiedTargets.Count() == 0,
@@ -8062,25 +8036,48 @@ nsIDocument::CreateStaticClone(nsISuppor
         }
       }
     }
   }
   mCreatingStaticClone = false;
   return clonedDoc.forget();
 }
 
-void
-nsIDocument::ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback)
-{
+nsresult
+nsIDocument::ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback,
+                                          PRInt32 *aHandle)
+{
+  if (mFrameRequestCallbackCounter == PR_INT32_MAX) {
+    // Can't increment without overflowing; bail out
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+  PRInt32 newHandle = ++mFrameRequestCallbackCounter;
+
   bool alreadyRegistered = !mFrameRequestCallbacks.IsEmpty();
-  if (mFrameRequestCallbacks.AppendElement(aCallback) &&
-      !alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
+  FrameRequest *request =
+    mFrameRequestCallbacks.AppendElement(FrameRequest(aCallback, newHandle));
+  NS_ASSERTION(request, "This is supposed to be infallible!");
+  if (!alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
     mPresShell->GetPresContext()->RefreshDriver()->
       ScheduleFrameRequestCallbacks(this);
   }
+
+  *aHandle = newHandle;
+  return NS_OK;
+}
+
+void
+nsIDocument::CancelFrameRequestCallback(PRInt32 aHandle)
+{
+  // mFrameRequestCallbacks is stored sorted by handle
+  mFrameRequestCallbacks.RemoveElementSorted(aHandle);
+
+  // Not going to worry about unscheduling our refresh driver
+  // callback.  It'll just be a no-op when it happens, if we have no
+  // more frame request callbacks.
 }
 
 nsresult
 nsDocument::GetStateObject(nsIVariant** aState)
 {
   // Get the document's current state object. This is the object backing both
   // history.state and popStateEvent.state.
   //
@@ -8440,53 +8437,23 @@ DispatchFullScreenChange(nsIDocument* aT
   nsRefPtr<nsPLDOMEvent> e =
     new nsPLDOMEvent(aTarget,
                      NS_LITERAL_STRING("mozfullscreenchange"),
                      true,
                      false);
   e->PostDOMEvent();
 }
 
-bool
-nsDocument::SetFullScreenState(Element* aElement, bool aIsFullScreen)
-{
-  if (mFullScreenElement) {
-    // Reset the ancestor and full-screen styles on the outgoing full-screen
-    // element in the current document.
-    nsEventStateManager::SetFullScreenState(mFullScreenElement, false);
-    mFullScreenElement = nsnull;
-  }
-  if (aElement) {
-    nsEventStateManager::SetFullScreenState(aElement, aIsFullScreen);
-  }
-  mFullScreenElement = aElement;
-
-  if (mIsFullScreen == aIsFullScreen) {
-    return false;
-  }
-  mIsFullScreen = aIsFullScreen;
-  return true;
-}
-
-// Wrapper for the nsIDocument -> nsDocument cast required to call
-// nsDocument::SetFullScreenState().
-static bool
-SetFullScreenState(nsIDocument* aDoc, Element* aElement, bool aIsFullScreen)
-{
-  return static_cast<nsDocument*>(aDoc)->
-    SetFullScreenState(aElement, aIsFullScreen);
-}
-
 NS_IMETHODIMP
 nsDocument::MozCancelFullScreen()
 {
   if (!nsContentUtils::IsRequestFullScreenAllowed()) {
     return NS_OK;
   }
-  CancelFullScreen();
+  RestorePreviousFullScreenState();
   return NS_OK;
 }
 
 // Runnable to set window full-screen mode. Used as a script runner
 // to ensure we only call nsGlobalWindow::SetFullScreen() when it's safe to 
 // run script. nsGlobalWindow::SetFullScreen() dispatches a synchronous event
 // (handled in chome code) which is unsafe to run if this is called in
 // nsGenericElement::UnbindFromTree().
@@ -8509,52 +8476,149 @@ private:
 };
 
 static void
 SetWindowFullScreen(nsIDocument* aDoc, bool aValue)
 {
   nsContentUtils::AddScriptRunner(new nsSetWindowFullScreen(aDoc, aValue));
 }
 
-void
-nsDocument::CancelFullScreen()
+class nsCallExitFullScreen : public nsRunnable {
+public:
+  NS_IMETHOD Run()
+  {
+    nsDocument::ExitFullScreen();
+    return NS_OK;
+  }
+};
+
+/* static */
+void
+nsIDocument::ExitFullScreen(bool aRunAsync)
+{
+  if (aRunAsync) {
+    NS_DispatchToCurrentThread(new nsCallExitFullScreen());
+    return;
+  }
+  nsDocument::ExitFullScreen();
+}
+
+static bool
+ResetFullScreen(nsIDocument* aDocument, void* aData) {
+  if (aDocument->IsFullScreenDoc()) {
+    static_cast<nsDocument*>(aDocument)->ClearFullScreenStack();
+    NS_ASSERTION(!aDocument->IsFullScreenDoc(), "Should reset full-screen");
+    nsTArray<nsIDocument*>* changed = reinterpret_cast<nsTArray<nsIDocument*>*>(aData);
+    changed->AppendElement(aDocument);
+    aDocument->EnumerateSubDocuments(ResetFullScreen, aData);
+  }
+  return true;
+}
+
+/* static */
+void
+nsDocument::ExitFullScreen()
+{
+  // Clear full-screen stacks in all descendant documents.
+  nsCOMPtr<nsIDocument> root(do_QueryReferent(sFullScreenRootDoc));
+  if (!root) {
+    // Not in full-screen mode.
+    return;
+  }
+  NS_ASSERTION(root->IsFullScreenDoc(),
+    "Full-screen root should be a full-screen doc...");
+
+  // Stores a list of documents to which we must dispatch "mozfullscreenchange".
+  // We're required by the spec to dispatch the events in leaf-to-root
+  // order when exiting full-screen, but we traverse the doctree in a
+  // root-to-leaf order, so we save references to the documents we must
+  // dispatch to so that we dispatch in the specified order.
+  nsAutoTArray<nsIDocument*, 8> changed;
+
+  // Walk the tree of full-screen documents, and reset their full-screen state.
+  ResetFullScreen(root, static_cast<void*>(&changed));
+
+  // Dispatch "mozfullscreenchange" events. Note this loop is in reverse
+  // order so that the events for the leaf document arrives before the root
+  // document, as required by the spec.
+  for (PRUint32 i = 0; i < changed.Length(); ++i) {
+    DispatchFullScreenChange(changed[changed.Length() - i - 1]);
+  }
+
+  // Reset global state. Do this before we move the window out of full-screen
+  // mode, as that calls nsGlobalWindow::SetFullScreen() which calls back into
+  // nsIDocument::ExitFullScreen().
+  sFullScreenRootDoc = nsnull;
+  sFullScreenDoc = nsnull;
+
+  // Move the top-level window out of full-screen mode.
+  SetWindowFullScreen(root, false);
+}
+
+void
+nsDocument::RestorePreviousFullScreenState()
 {
   NS_ASSERTION(!IsFullScreenDoc() || sFullScreenDoc != nsnull,
                "Should have a full-screen doc when full-screen!");
 
   if (!IsFullScreenDoc() || !GetWindow() || !sFullScreenDoc) {
     return;
   }
 
-  // Reset full-screen state in all full-screen documents.
-  nsCOMPtr<nsIDocument> doc(do_QueryReferent(sFullScreenDoc));
-  while (doc != nsnull) {
-    if (::SetFullScreenState(doc, nsnull, false)) {
-      DispatchFullScreenChange(doc);
-    }
+  // Clear full-screen stacks in all descendant documents, bottom up.
+  nsCOMPtr<nsIDocument> fullScreenDoc(do_QueryReferent(sFullScreenDoc));
+  nsIDocument* doc = fullScreenDoc;
+  while (doc != this) {
+    NS_ASSERTION(doc->IsFullScreenDoc(), "Should be full-screen doc");
+    static_cast<nsDocument*>(doc)->ClearFullScreenStack();
+    DispatchFullScreenChange(doc);
     doc = doc->GetParentDocument();
   }
-  sFullScreenDoc = nsnull;
-  sFullScreenRootDoc = nsnull;
-
-  // Move the window out of full-screen mode.
-  SetWindowFullScreen(this, false);
-
-  return;
+
+  // Roll-back full-screen state to previous full-screen element.
+  NS_ASSERTION(doc == this, "Must have reached this doc.");
+  while (doc != nsnull) {
+    static_cast<nsDocument*>(doc)->FullScreenStackPop();
+    DispatchFullScreenChange(doc);
+    if (static_cast<nsDocument*>(doc)->mFullScreenStack.IsEmpty()) {
+      // Full-screen stack in document is empty. Go back up to the parent
+      // document. We'll pop the containing element off its stack, and use
+      // its next full-screen element as the full-screen element.
+      doc = doc->GetParentDocument();
+    } else {
+      // Else we popped the top of the stack, and there's still another
+      // element in there, so that will become the full-screen element.
+      sFullScreenDoc = do_GetWeakReference(doc);
+      break;
+    }
+  }
+
+  if (doc == nsnull) {
+    // We moved all documents out of full-screen mode, reset global full-screen
+    // state and move the top-level window out of full-screen mode.
+    DebugOnly< nsCOMPtr<nsIDocument> > root(do_QueryReferent(sFullScreenRootDoc));
+    NS_ASSERTION(!root->IsFullScreenDoc(), "Should have cleared all docs' stacks");
+    sFullScreenDoc = nsnull;
+    sFullScreenRootDoc = nsnull;
+    SetWindowFullScreen(this, false);
+  }
 }
 
 bool
 nsDocument::IsFullScreenDoc()
 {
-  return mIsFullScreen;
+  return GetFullScreenElement() != nsnull;
 }
 
 static nsIDocument*
 GetCommonAncestor(nsIDocument* aDoc1, nsIDocument* aDoc2)
 {
+  if (!aDoc1 || !aDoc2) {
+    return nsnull;
+  }
   nsIDocument* doc1 = aDoc1;
   nsIDocument* doc2 = aDoc2;
 
   nsAutoTArray<nsIDocument*, 30> parents1, parents2;
   do {
     parents1.AppendElement(doc1);
     doc1 = doc1->GetParentDocument();
   } while (doc1);
@@ -8629,21 +8693,108 @@ LogFullScreenDenied(bool aLogFailure, co
                                   aMessage,
                                   nsnull, 0, nsnull,
                                   EmptyString(), 0, 0,
                                   nsIScriptError::warningFlag,
                                   "DOM", aDoc);
 }
 
 void
+nsDocument::ClearFullScreenStack()
+{
+  if (mFullScreenStack.IsEmpty()) {
+    return;
+  }
+  // The top element in the full-screen stack will have full-screen
+  // style bits set on it and its ancestors. Remove the style bits.
+  // Note the non-top elements won't have the style bits set.
+  Element* top = FullScreenStackTop();
+  NS_ASSERTION(top, "Should have a top when full-screen stack isn't empty");
+  if (top) {
+    nsEventStateManager::SetFullScreenState(top, false);
+  }
+  mFullScreenStack.Clear();
+}
+
+bool
+nsDocument::FullScreenStackPush(Element* aElement)
+{
+  NS_ASSERTION(aElement, "Must pass non-null to FullScreenStackPush()");
+  Element* top = FullScreenStackTop();
+  if (top == aElement || !aElement) {
+    return false;
+  }
+  if (top) {
+    // We're pushing a new element onto the full-screen stack, so we must
+    // remove the ancestor and full-screen styles from the former top of the
+    // stack.
+    nsEventStateManager::SetFullScreenState(top, false);
+  }
+  nsEventStateManager::SetFullScreenState(aElement, true);
+  mFullScreenStack.AppendElement(do_GetWeakReference(aElement));
+  NS_ASSERTION(GetFullScreenElement() == aElement, "Should match");
+  return true;
+}
+
+void
+nsDocument::FullScreenStackPop()
+{
+  if (mFullScreenStack.IsEmpty()) {
+    return;
+  }
+
+  // Remove styles from existing top element.
+  Element* top = FullScreenStackTop();
+  nsEventStateManager::SetFullScreenState(top, false);
+
+  // Remove top element. Note the remaining top element in the stack
+  // will not have full-screen style bits set, so we will need to restore
+  // them on the new top element before returning.
+  PRUint32 last = mFullScreenStack.Length() - 1;
+  mFullScreenStack.RemoveElementAt(last);
+
+  // Pop from the stack null elements (references to elements which have
+  // been GC'd since they were added to the stack) and elements which are
+  // no longer in this document.
+  while (!mFullScreenStack.IsEmpty()) {
+    Element* element = FullScreenStackTop();
+    if (!element || !element->IsInDoc() || element->OwnerDoc() != this) {
+      NS_ASSERTION(!element->IsFullScreenAncestor(),
+                   "Should have already removed full-screen styles");
+      PRUint32 last = mFullScreenStack.Length() - 1;
+      mFullScreenStack.RemoveElementAt(last);
+    } else {
+      // The top element of the stack is now an in-doc element. Apply the
+      // full-screen styles and return.
+      nsEventStateManager::SetFullScreenState(element, true);
+      break;
+    }
+  }
+}
+
+Element*
+nsDocument::FullScreenStackTop()
+{
+  if (mFullScreenStack.IsEmpty()) {
+    return nsnull;
+  }
+  PRUint32 last = mFullScreenStack.Length() - 1;
+  nsCOMPtr<Element> element(do_QueryReferent(mFullScreenStack[last]));
+  NS_ASSERTION(element, "Should have full-screen element!");
+  NS_ASSERTION(element->IsInDoc(), "Full-screen element should be in doc");
+  NS_ASSERTION(element->OwnerDoc() == this, "Full-screen element should be in this doc");
+  return element;
+}
+
+void
 nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
 {
   NS_ASSERTION(aElement,
     "Must pass non-null element to nsDocument::RequestFullScreen");
-  if (!aElement) {
+  if (!aElement || aElement == GetFullScreenElement()) {
     return;
   }
   if (!aElement->IsInDoc()) {
     LogFullScreenDenied(true, "FullScreenDeniedNotInDocument", this);
     return;
   }
   if (aElement->OwnerDoc() != this) {
     LogFullScreenDenied(true, "FullScreenDeniedMovedDocument", this);
@@ -8652,75 +8803,104 @@ nsDocument::RequestFullScreen(Element* a
   if (!GetWindow()) {
     LogFullScreenDenied(true, "FullScreenDeniedLostWindow", this);
     return;
   }
   if (!IsFullScreenEnabled(aWasCallerChrome, true)) {
     // IsFullScreenEnabled calls LogFullScreenDenied, no need to log.
     return;
   }
-
-  // Turn off full-screen state in all documents which were previously
-  // full-screen but which shouldn't be after this request is granted.
-  // Note commonAncestor will be null when in a separate browser window
-  // to the requesting document.
-  nsIDocument* commonAncestor = nsnull;
+  if (GetFullScreenElement() &&
+      !nsContentUtils::ContentIsDescendantOf(aElement, GetFullScreenElement())) {
+    // If this document is full-screen, only grant full-screen requests from 
+    // a descendent of the current full-screen element.
+    LogFullScreenDenied(true, "FullScreenDeniedNotDescendant", this);
+    return;
+  }
+
+  // Stores a list of documents which we must dispatch "mozfullscreenchange"
+  // too. We're required by the spec to dispatch the events in root-to-leaf
+  // order, but we traverse the doctree in a leaf-to-root order, so we save
+  // references to the documents we must dispatch to so that we get the order
+  // as specified.
+  nsAutoTArray<nsIDocument*, 8> changed;
+
+  // If another top-level window is full-screen. Exit it from full-screen.
   nsCOMPtr<nsIDocument> fullScreenDoc(do_QueryReferent(sFullScreenDoc));
-  if (fullScreenDoc) {
-    commonAncestor = GetCommonAncestor(fullScreenDoc, this);
-  }
-  nsIDocument* doc = fullScreenDoc;
-  while (doc != commonAncestor) {
-    if (::SetFullScreenState(doc, nsnull, false)) {
-      DispatchFullScreenChange(doc);
-    }
-    doc = doc->GetParentDocument();
-  }
-  if (!commonAncestor && fullScreenDoc) {
-    // Other doc is in another browser window. Move it out of full-screen.
-    // Note that nsGlobalWindow::SetFullScreen() proxies to the root window
-    // in its hierarchy, and does not operate on the a per-nsIDOMWindow basis.
-    SetWindowFullScreen(fullScreenDoc, false);
+  nsIDocument* commonAncestor = GetCommonAncestor(fullScreenDoc, this);
+  if (fullScreenDoc && !commonAncestor) {
+    // A document which doesn't have a common ancestor is full-screen, this
+    // must be in a separate browser window. Fully exit full-screen, to move
+    // the other browser window/doctree out of full-screen.
+    nsIDocument::ExitFullScreen(false);
   }
 
   // Remember the root document, so that if a full-screen document is hidden
   // we can reset full-screen state in the remaining visible full-screen documents.
   sFullScreenRootDoc = do_GetWeakReference(nsContentUtils::GetRootDocument(this));
 
   // Set the full-screen element. This sets the full-screen style on the
   // element, and the full-screen-ancestor styles on ancestors of the element
   // in this document.
-  if (SetFullScreenState(aElement, true)) {
-    DispatchFullScreenChange(aElement->OwnerDoc());
-  }
-
+  DebugOnly<bool> x = FullScreenStackPush(aElement);
+  NS_ASSERTION(x, "Full-screen state of requesting doc should always change!");
+  changed.AppendElement(this);
+  
   // Propagate up the document hierarchy, setting the full-screen element as
   // the element's container in ancestor documents. This also sets the
   // appropriate css styles as well. Note we don't propagate down the
   // document hierarchy, the full-screen element (or its container) is not
   // visible there.  
   nsIDocument* child = this;
   nsIDocument* parent;
   while ((parent = child->GetParentDocument())) {
     Element* element = parent->FindContentForSubDocument(child)->AsElement();
-    if (::SetFullScreenState(parent, element, true)) {
-      DispatchFullScreenChange(element->OwnerDoc());
-    }
-    child = parent;
-  }
+    if (static_cast<nsDocument*>(parent)->FullScreenStackPush(element)) {
+      changed.AppendElement(parent);
+      child = parent;
+    } else {
+      NS_ASSERTION(!commonAncestor || child == commonAncestor,
+                   "Should finish loop at common ancestor (or null)");
+      // We've reached either the root, or a point in the doctree where the
+      // new full-screen element container is the same as the previous
+      // full-screen element's container. No more changes need to be made
+      // to the full-screen stacks of documents further up the tree.
+      break;
+    }
+  }
+
+  // Dispatch "mozfullscreenchange" events. Note this loop is in reverse
+  // order so that the events for the root document arrives before the leaf
+  // document, as required by the spec.
+  for (PRUint32 i = 0; i < changed.Length(); ++i) {
+    DispatchFullScreenChange(changed[changed.Length() - i - 1]);
+  }
+
+  // Remember this is the requesting full-screen document.
+  sFullScreenDoc = do_GetWeakReference(static_cast<nsIDocument*>(this));
 
   // Make the window full-screen. Note we must make the state changes above
   // before making the window full-screen, as then the document reports as
   // being in full-screen mode when the chrome "fullscreen" event fires,
   // enabling chrome to distinguish between browser and dom full-screen
-  // modes.
+  // modes. Also note that nsGlobalWindow::SetFullScreen() (which
+  // SetWindowFullScreen() calls) proxies to the root window in its hierarchy,
+  // and does not operate on the a per-nsIDOMWindow basis.
   SetWindowFullScreen(this, true);
 
-  // Remember this is the requesting full-screen document.
-  sFullScreenDoc = do_GetWeakReference(static_cast<nsIDocument*>(this));
+#ifdef DEBUG
+  NS_ASSERTION(GetFullScreenElement() == aElement,
+               "Full-screen element should be the requested element!");
+  NS_ASSERTION(IsFullScreenDoc(), "Should be full-screen doc");
+  nsCOMPtr<nsIDOMHTMLElement> fse;
+  GetMozFullScreenElement(getter_AddRefs(fse));
+  nsCOMPtr<nsIContent> c(do_QueryInterface(fse));
+  NS_ASSERTION(c->AsElement() == aElement,
+    "GetMozFullScreenElement should match GetFullScreenElement()");
+#endif
 }
 
 NS_IMETHODIMP
 nsDocument::GetMozFullScreenElement(nsIDOMHTMLElement **aFullScreenElement)
 {
   NS_ENSURE_ARG_POINTER(aFullScreenElement);
   *aFullScreenElement = nsnull;
   if (IsFullScreenDoc()) {
@@ -8729,17 +8909,20 @@ nsDocument::GetMozFullScreenElement(nsID
     CallQueryInterface(GetFullScreenElement(), aFullScreenElement);
   }
   return NS_OK;
 }
 
 Element*
 nsDocument::GetFullScreenElement()
 {
-  return mFullScreenElement;
+  Element* element = FullScreenStackTop();
+  NS_ASSERTION(!element || element->IsFullScreenAncestor(),
+    "Should have full-screen styles applied!");
+  return element;
 }
 
 NS_IMETHODIMP
 nsDocument::GetMozFullScreen(bool *aFullScreen)
 {
   NS_ENSURE_ARG_POINTER(aFullScreen);
   *aFullScreen = IsFullScreenDoc();
   return NS_OK;
@@ -8748,16 +8931,36 @@ nsDocument::GetMozFullScreen(bool *aFull
 NS_IMETHODIMP
 nsDocument::GetMozFullScreenEnabled(bool *aFullScreen)
 {
   NS_ENSURE_ARG_POINTER(aFullScreen);
   *aFullScreen = IsFullScreenEnabled(nsContentUtils::IsCallerChrome(), false);
   return NS_OK;
 }
 
+static bool
+HasFullScreenSubDocument(nsIDocument* aDoc, void* aData)
+{
+  if (aDoc->IsFullScreenDoc()) {
+    // This subdocument is full-screen. Set result and return false to
+    // stop iteration.
+    *static_cast<bool*>(aData) = true;
+    return false;
+  }
+  return true;
+}
+
+static bool
+HasFullScreenSubDocument(nsIDocument* aDoc)
+{
+  bool result = false;
+  aDoc->EnumerateSubDocuments(&HasFullScreenSubDocument, static_cast<void*>(&result));
+  return result;
+}
+
 bool
 nsDocument::IsFullScreenEnabled(bool aCallerIsChrome, bool aLogFailure)
 {
   if (nsContentUtils::IsFullScreenApiEnabled() && aCallerIsChrome) {
     // Chrome code can always use the full-screen API, provided it's not
     // explicitly disabled. Note IsCallerChrome() returns true when running
     // in an nsRunnable, so don't use GetMozFullScreenEnabled() from an
     // nsRunnable!
@@ -8771,16 +8974,20 @@ nsDocument::IsFullScreenEnabled(bool aCa
   if (nsContentUtils::HasPluginWithUncontrolledEventDispatch(this)) {
     LogFullScreenDenied(aLogFailure, "FullScreenDeniedPlugins", this);
     return false;
   }
   if (!IsVisible()) {
     LogFullScreenDenied(aLogFailure, "FullScreenDeniedHidden", this);
     return false;
   }
+  if (HasFullScreenSubDocument(this)) {
+    LogFullScreenDenied(aLogFailure, "FullScreenDeniedSubDocFullScreen", this);
+    return false;
+  }
 
   // Ensure that all ancestor <iframe> elements have the mozallowfullscreen
   // boolean attribute set.
   nsINode* node = static_cast<nsINode*>(this);
   do {
     nsIContent* content = static_cast<nsIContent*>(node);
     if (content->IsHTML(nsGkAtoms::iframe) &&
         !content->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen)) {
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -953,29 +953,43 @@ public:
 
   bool HasAudioAvailableListeners()
   {
     return mHasAudioAvailableListener;
   }
 
   virtual Element* GetFullScreenElement();
   virtual void AsyncRequestFullScreen(Element* aElement);
-  virtual void CancelFullScreen();
+  virtual void RestorePreviousFullScreenState();
   virtual bool IsFullScreenDoc();
+  static void ExitFullScreen();
 
   // This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
   // to move document into full-screen mode if allowed. aWasCallerChrome
   // should be true when nsIDocument::AsyncRequestFullScreen() was called
   // by chrome code.
   void RequestFullScreen(Element* aElement, bool aWasCallerChrome);
 
-  // Returns true if making this change results in a change in the full-screen
-  // state of this document.
-  bool SetFullScreenState(Element* aElement, bool aIsFullScreen);
- 
+  // Removes all elements from the full-screen stack, removing full-scren
+  // styles from the top element in the stack.
+  void ClearFullScreenStack();
+
+  // Pushes aElement onto the full-screen stack, and removes full-screen styles
+  // from the former full-screen stack top, and its ancestors, and applies the
+  // styles to aElement. aElement becomes the new "full-screen element".
+  bool FullScreenStackPush(Element* aElement);
+
+  // Remove the top element from the full-screen stack. Removes the full-screen
+  // styles from the former top element, and applies them to the new top
+  // element, if there is one.
+  void FullScreenStackPop();
+
+  // Returns the top element from the full-screen stack.
+  Element* FullScreenStackTop();
+
   // This method may fire a DOM event; if it does so it will happen
   // synchronously.
   void UpdateVisibilityState();
   // Posts an event to call UpdateVisibilityState
   virtual void PostVisibilityUpdateEvent();
 
 protected:
   friend class nsNodeUtils;
@@ -1105,16 +1119,21 @@ protected:
 
   // The root document of the doctree containing the document which requested
   // full-screen. This root document will also be in full-screen state, as will
   // all the descendents down to the document which requested full-screen. This
   // reference allows us to reset full-screen state on all documents when a
   // document is hidden/navigation occurs.
   static nsWeakPtr sFullScreenRootDoc;
 
+  // Stack of full-screen elements. When we request full-screen we push the
+  // full-screen element onto this stack, and when we cancel full-screen we
+  // pop one off this stack, restoring the previous full-screen state
+  nsTArray<nsWeakPtr> mFullScreenStack;
+
   nsRefPtr<nsEventListenerManager> mListenerManager;
   nsCOMPtr<nsIDOMStyleSheetList> mDOMStyleSheets;
   nsRefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
   nsRefPtr<nsScriptLoader> mScriptLoader;
   nsDocHeaderData* mHeaderData;
   /* mIdentifierMap works as follows for IDs:
    * 1) Attribute changes affect the table immediately (removing and adding
    *    entries as needed).
@@ -1124,19 +1143,16 @@ protected:
    */
   nsTHashtable<nsIdentifierMapEntry> mIdentifierMap;
 
   nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
 
   // Recorded time of change to 'loading' state.
   mozilla::TimeStamp mLoadingTimeStamp;
 
-  // The current full-screen element of this document.
-  nsCOMPtr<Element> mFullScreenElement;
-
   // True if the document has been detached from its content viewer.
   bool mIsGoingAway:1;
   // True if the document is being destroyed.
   bool mInDestructor:1;
 
   // True if this document has ever had an HTML or SVG <title> element
   // bound to it
   bool mMayHaveTitleElement:1;
--- a/content/base/src/nsEventSource.cpp
+++ b/content/base/src/nsEventSource.cpp
@@ -57,16 +57,17 @@
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIScriptError.h"
 #include "nsICharsetConverterManager.h"
 #include "nsIChannelPolicy.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsContentUtils.h"
 #include "mozilla/Preferences.h"
 #include "xpcpublic.h"
+#include "nsCrossSiteListenerProxy.h"
 
 using namespace mozilla;
 
 #define REPLACEMENT_CHAR     (PRUnichar)0xFFFD
 #define BOM_CHAR             (PRUnichar)0xFEFF
 #define SPACE_CHAR           (PRUnichar)0x0020
 #define CR_CHAR              (PRUnichar)0x000D
 #define LF_CHAR              (PRUnichar)0x000A
@@ -80,16 +81,17 @@ using namespace mozilla;
 #define DEFAULT_RECONNECTION_TIME_VALUE   5000
 #define MAX_RECONNECTION_TIME_VALUE       PR_IntervalToMilliseconds(DELAY_INTERVAL_LIMIT)
 
 nsEventSource::nsEventSource() :
   mStatus(PARSE_STATE_OFF),
   mFrozen(false),
   mErrorLoadOnRedirect(false),
   mGoingToDispatchAllMessages(false),
+  mWithCredentials(false),
   mLastConvertionResult(NS_OK),
   mReadyState(nsIEventSource::CONNECTING),
   mScriptLine(0),
   mInnerWindowID(0)
 {
 }
 
 nsEventSource::~nsEventSource()
@@ -160,16 +162,24 @@ nsEventSource::GetUrl(nsAString& aURL)
 NS_IMETHODIMP
 nsEventSource::GetReadyState(PRInt32 *aReadyState)
 {
   NS_ENSURE_ARG_POINTER(aReadyState);
   *aReadyState = mReadyState;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsEventSource::GetWithCredentials(bool *aWithCredentials)
+{
+  NS_ENSURE_ARG_POINTER(aWithCredentials);
+  *aWithCredentials = mWithCredentials;
+  return NS_OK;
+}
+
 #define NS_EVENTSRC_IMPL_DOMEVENTLISTENER(_eventlistenername, _eventlistener)  \
   NS_IMETHODIMP                                                                \
   nsEventSource::GetOn##_eventlistenername(nsIDOMEventListener * *aListener)   \
   {                                                                            \
     return GetInnerEventListener(_eventlistener, aListener);                   \
   }                                                                            \
                                                                                \
   NS_IMETHODIMP                                                                \
@@ -225,26 +235,28 @@ nsEventSource::Close()
 
 /**
  * This Init method should only be called by C++ consumers.
  */
 NS_IMETHODIMP
 nsEventSource::Init(nsIPrincipal* aPrincipal,
                     nsIScriptContext* aScriptContext,
                     nsPIDOMWindow* aOwnerWindow,
-                    const nsAString& aURL)
+                    const nsAString& aURL,
+                    bool aWithCredentials)
 {
   NS_ENSURE_ARG(aPrincipal);
 
   if (mReadyState != nsIEventSource::CONNECTING || !PrefEnabled()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   mPrincipal = aPrincipal;
   mScriptContext = aScriptContext;
+  mWithCredentials = aWithCredentials;
   if (aOwnerWindow) {
     mOwner = aOwnerWindow->IsOuterWindow() ?
       aOwnerWindow->GetCurrentInnerWindow() : aOwnerWindow;
   } else {
     mOwner = nsnull;
   }
 
   nsCOMPtr<nsIJSContextStack> stack =
@@ -285,18 +297,18 @@ nsEventSource::Init(nsIPrincipal* aPrinc
 
   rv = os->AddObserver(this, DOM_WINDOW_DESTROYED_TOPIC, true);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = os->AddObserver(this, DOM_WINDOW_FROZEN_TOPIC, true);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = os->AddObserver(this, DOM_WINDOW_THAWED_TOPIC, true);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsXPIDLCString origin;
-  rv = mPrincipal->GetOrigin(getter_Copies(origin));
+  nsAutoString origin;
+  rv = nsContentUtils::GetUTFOrigin(srcURI, origin);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCAutoString spec;
   rv = srcURI->GetSpec(spec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mOriginalURL = NS_ConvertUTF8toUTF16(spec);
   mSrc = srcURI;
@@ -371,17 +383,41 @@ nsEventSource::Initialize(nsISupports* a
   NS_ENSURE_STATE(scriptContext);
 
   nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
     do_QueryInterface(aOwner);
   NS_ENSURE_STATE(scriptPrincipal);
   nsCOMPtr<nsIPrincipal> principal = scriptPrincipal->GetPrincipal();
   NS_ENSURE_STATE(principal);
 
-  return Init(principal, scriptContext, ownerWindow, urlParam);
+  bool withCredentialsParam = false;
+  if (aArgc >= 2) {
+    NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(aArgv[1]), NS_ERROR_INVALID_ARG);
+
+    JSObject *obj = JSVAL_TO_OBJECT(aArgv[1]);
+    NS_ASSERTION(obj, "obj shouldn't be null!!");
+
+    JSBool hasProperty = JS_FALSE;
+    NS_ENSURE_TRUE(JS_HasProperty(aContext, obj, "withCredentials",
+                                  &hasProperty), NS_ERROR_FAILURE);
+
+    if (hasProperty) {
+      jsval withCredentialsVal;
+      NS_ENSURE_TRUE(JS_GetProperty(aContext, obj, "withCredentials",
+                                    &withCredentialsVal), NS_ERROR_FAILURE);
+
+      JSBool withCredentials = JS_FALSE;
+      NS_ENSURE_TRUE(JS_ValueToBoolean(aContext, withCredentialsVal,
+                                       &withCredentials), NS_ERROR_FAILURE);
+      withCredentialsParam = !!withCredentials;
+    }
+  }
+
+  return Init(principal, scriptContext, ownerWindow,
+              urlParam, withCredentialsParam);
 }
 
 //-----------------------------------------------------------------------------
 // nsEventSource::nsIObserver
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsEventSource::Observe(nsISupports* aSubject,
@@ -881,18 +917,23 @@ nsEventSource::InitChannelAndRequestEven
   NS_ENSURE_SUCCESS(rv, rv);
 
   mHttpChannel = do_QueryInterface(channel);
   NS_ENSURE_TRUE(mHttpChannel, NS_ERROR_NO_INTERFACE);
 
   rv = SetupHttpChannel();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsCOMPtr<nsIStreamListener> listener =
+    new nsCORSListenerProxy(this, mPrincipal, mHttpChannel,
+                            mWithCredentials, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   // Start reading from the channel
-  return mHttpChannel->AsyncOpen(this, nsnull);
+  return mHttpChannel->AsyncOpen(listener, nsnull);
 }
 
 void
 nsEventSource::AnnounceConnection()
 {
   if (mReadyState == nsIEventSource::CLOSED) {
     return;
   }
@@ -1168,26 +1209,23 @@ nsEventSource::FailConnection()
 
 bool
 nsEventSource::CheckCanRequestSrc(nsIURI* aSrc)
 {
   if (mReadyState == nsIEventSource::CLOSED) {
     return false;
   }
 
-  bool isSameOrigin = false;
   bool isValidURI = false;
   bool isValidContentLoadPolicy = false;
   bool isValidProtocol = false;
 
   nsCOMPtr<nsIURI> srcToTest = aSrc ? aSrc : mSrc.get();
   NS_ENSURE_TRUE(srcToTest, false);
 
-  isSameOrigin = NS_SUCCEEDED(mPrincipal->CheckMayLoad(srcToTest, false));
-
   PRUint32 aCheckURIFlags =
     nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL |
     nsIScriptSecurityManager::DISALLOW_SCRIPT;
 
   nsresult rv = nsContentUtils::GetSecurityManager()->
     CheckLoadURIWithPrincipal(mPrincipal,
                               srcToTest,
                               aCheckURIFlags);
@@ -1217,18 +1255,17 @@ nsEventSource::CheckCanRequestSrc(nsIURI
   nsCAutoString targetURIScheme;
   rv = srcToTest->GetScheme(targetURIScheme);
   if (NS_SUCCEEDED(rv)) {
     // We only have the http support for now
     isValidProtocol = targetURIScheme.EqualsLiteral("http") ||
                       targetURIScheme.EqualsLiteral("https");
   }
 
-  return isSameOrigin && isValidURI && isValidContentLoadPolicy &&
-         isValidProtocol;
+  return isValidURI && isValidContentLoadPolicy && isValidProtocol;
 }
 
 // static
 void
 nsEventSource::TimerCallback(nsITimer* aTimer, void* aClosure)
 {
   nsRefPtr<nsEventSource> thisObject = static_cast<nsEventSource*>(aClosure);
 
@@ -1382,17 +1419,17 @@ nsEventSource::DispatchAllMessageEvents(
       NS_WARNING("Failed to create the message event!!!");
       return;
     }
 
     nsCOMPtr<nsIDOMMessageEvent> messageEvent = do_QueryInterface(event);
     rv = messageEvent->InitMessageEvent(message->mEventName,
                                         false, false,
                                         jsData,
-                                        NS_ConvertUTF8toUTF16(mOrigin),
+                                        mOrigin,
                                         message->mLastEventID, nsnull);
     if (NS_FAILED(rv)) {
       NS_WARNING("Failed to init the message event!!!");
       return;
     }
 
     nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
     privateEvent->SetTrusted(true);
--- a/content/base/src/nsEventSource.h
+++ b/content/base/src/nsEventSource.h
@@ -210,16 +210,17 @@ protected:
     PARSE_STATE_FIELD_VALUE,
     PARSE_STATE_BEGIN_OF_LINE
   };
   ParserStatus mStatus;
 
   bool mFrozen;
   bool mErrorLoadOnRedirect;
   bool mGoingToDispatchAllMessages;
+  bool mWithCredentials;
 
   // used while reading the input streams
   nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder;
   nsresult mLastConvertionResult;
   nsString mLastFieldName;
   nsString mLastFieldValue;
 
   nsRefPtr<nsDOMEventListenerWrapper> mOnOpenListener;
@@ -238,17 +239,17 @@ protected:
   nsCOMPtr<nsIHttpChannel> mHttpChannel;
 
   nsCOMPtr<nsITimer> mTimer;
 
   PRInt32 mReadyState;
   nsString mOriginalURL;
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
-  nsCString mOrigin;
+  nsString mOrigin;
 
   PRUint32 mRedirectFlags;
   nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
   nsCOMPtr<nsIChannel> mNewRedirectChannel;
 
   // Event Source owner information:
   // - the script file name
   // - source code line number where the Event Source object was constructed.
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -3062,45 +3062,38 @@ nsGenericElement::BindToTree(nsIDocument
   NS_POSTCONDITION(aDocument == GetCurrentDoc(), "Bound to wrong document");
   NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
   NS_POSTCONDITION(aBindingParent == GetBindingParent(),
                    "Bound to wrong binding parent");
 
   return NS_OK;
 }
 
-static bool
-IsFullScreenAncestor(Element* aElement)
-{
-  nsEventStates state = aElement->State();
-  return state.HasAtLeastOneOfStates(NS_EVENT_STATE_FULL_SCREEN_ANCESTOR |
-                                     NS_EVENT_STATE_FULL_SCREEN);
-}
-
 void
 nsGenericElement::UnbindFromTree(bool aDeep, bool aNullParent)
 {
   NS_PRECONDITION(aDeep || (!GetCurrentDoc() && !GetBindingParent()),
                   "Shallow unbind won't clear document and binding parent on "
                   "kids!");
   // Make sure to unbind this node before doing the kids
   nsIDocument *document =
     HasFlag(NODE_FORCE_XBL_BINDINGS) ? OwnerDoc() : GetCurrentDoc();
 
   if (aNullParent) {
-    if (IsFullScreenAncestor(this)) {
+    if (IsFullScreenAncestor()) {
       // The element being removed is an ancestor of the full-screen element,
       // exit full-screen state.
       nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
                                       "RemovedFullScreenElement",
                                       nsnull, 0, nsnull,
                                       EmptyString(), 0, 0,
                                       nsIScriptError::warningFlag,
-                                      "DOM", OwnerDoc());      
-      OwnerDoc()->CancelFullScreen();
+                                      "DOM", OwnerDoc());
+      // Fully exit full-screen.
+      nsIDocument::ExitFullScreen(false);
     }
     if (GetParent()) {
       NS_RELEASE(mParent);
     } else {
       mParent = nsnull;
     }
     SetParentIsContent(false);
   }
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -489,32 +489,34 @@ include $(topsrcdir)/config/rules.mk
 		badContentType.eventsource \
 		badContentType.eventsource^headers^ \
 		badEventFieldName.eventsource \
 		badEventFieldName.eventsource^headers^ \
 		badHTTPResponseCode.eventsource \
 		badHTTPResponseCode.eventsource^headers^ \
 		badMessageEvent.eventsource \
 		badMessageEvent.eventsource^headers^ \
+		file_restrictedEventSource.sjs \
 		forRemoval.resource \
 		forRemoval.resource^headers^ \
 		accesscontrol.resource \
 		accesscontrol.resource^headers^ \
 		invalid_accesscontrol.resource \
 		invalid_accesscontrol.resource^headers^ \
 		test_xhr_progressevents.html \
 		progressserver.sjs \
 		somedatas.resource \
 		somedatas.resource^headers^ \
 		delayedServerEvents.sjs \
 		test_html_in_xhr.html \
 		file_html_in_xhr.html \
 		file_html_in_xhr2.html \
 		file_html_in_xhr3.html \
 		file_html_in_xhr.sjs \
+		test_bug647518.html \
 		test_bug664916.html \
 		test_bug666604.html \
 		test_bug675121.html \
 		file_bug675121.sjs \
 		test_bug675166.html \
 		test_bug682554.html \
 		test_bug682592.html \
 		bug682592-subframe.html \
--- a/content/base/test/accesscontrol.resource^headers^
+++ b/content/base/test/accesscontrol.resource^headers^
@@ -1,4 +1,5 @@
-Access-Control-Allow-Origin: http://localhost:8888
+Access-Control-Allow-Origin: http://mochi.test:8888
+Access-Control-Allow-Credentials: true
 Content-Type: text/event-stream
 Cache-Control: no-cache, must-revalidate
 
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_restrictedEventSource.sjs
@@ -0,0 +1,50 @@
+function handleRequest(request, response)
+{
+  if ((request.queryString == "test=user1_xhr" &&
+       request.hasHeader("Authorization") &&
+       request.getHeader("Authorization") == "Basic dXNlciAxOnBhc3N3b3JkIDE=") ||
+      (request.queryString == "test=user1_evtsrc" &&
+       request.hasHeader("Authorization") &&
+       request.getHeader("Authorization") == "Basic dXNlciAxOnBhc3N3b3JkIDE=" &&
+       request.hasHeader("Cookie") &&
+       request.getHeader("Cookie") == "test=5c")) {
+    response.setStatusLine(null, 200, "OK");
+    response.setHeader("Content-Type", "text/event-stream", false);
+    response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false);
+    response.setHeader("Access-Control-Allow-Credentials", "true", false);
+    response.setHeader("Cache-Control", "no-cache, must-revalidate", false);
+    if (request.queryString == "test=user1_xhr") {
+      response.setHeader("Set-Cookie", "test=5c", false);
+    }
+    response.write("event: message\ndata: 1\n\n");
+  } else if ((request.queryString == "test=user2_xhr" &&
+              request.hasHeader("Authorization") &&
+              request.getHeader("Authorization") == "Basic dXNlciAyOnBhc3N3b3JkIDI=") ||
+             (request.queryString == "test=user2_evtsrc" &&
+              request.hasHeader("Authorization") &&
+              request.getHeader("Authorization") == "Basic dXNlciAyOnBhc3N3b3JkIDI=" &&
+              request.hasHeader("Cookie") &&
+              request.getHeader("Cookie") == "test=5d")) {
+    response.setStatusLine(null, 200, "OK");
+    response.setHeader("Content-Type", "text/event-stream", false);
+    response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false);
+    response.setHeader("Access-Control-Allow-Credentials", "true", false);
+    response.setHeader("Cache-Control", "no-cache, must-revalidate", false);
+    if (request.queryString == "test=user2_xhr") {
+      response.setHeader("Set-Cookie", "test=5d", false);
+    }
+    response.write("event: message\ndata: 1\n\n");
+  } else if (request.queryString == "test=user1_xhr" ||
+             request.queryString == "test=user2_xhr") {
+    response.setStatusLine(null, 401, "Unauthorized");
+    response.setHeader("WWW-Authenticate", "basic realm=\"restricted\"", false);
+    response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false);
+    response.setHeader("Access-Control-Allow-Credentials", "true", false);
+    response.write("Unauthorized");
+  } else {
+    response.setStatusLine(null, 403, "Forbidden");
+    response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false);
+    response.setHeader("Access-Control-Allow-Credentials", "true", false);
+    response.write("Forbidden");
+  }
+}
\ No newline at end of file
--- a/content/base/test/test_bug338583.html
+++ b/content/base/test/test_bug338583.html
@@ -27,34 +27,56 @@ https://bugzilla.mozilla.org/show_bug.cg
 //   3) possible invalid eventsources
 //   4) the close method when the object is just been used
 //   5) access-control
 //   6) the data parameter
 //   7) delayed server responses
 
 // --
 
+  var gTestsHaveFinished = [];
+
+  function setTestHasFinished(test_id)
+  {
+    if (gTestsHaveFinished[test_id]) {
+      return;
+    }
+
+    gTestsHaveFinished[test_id] = true;
+    for (var i=0; i < gTestsHaveFinished.length; ++i) {
+      if (!gTestsHaveFinished[i]) {
+        return;
+      }
+    }
+
+    SimpleTest.finish();
+  }
+
   function runAllTests() {
-    // these tests run asynchronously
-    doTest1();    // this will take 8000 ms
-    doTest2();    // this will take 5000 ms
-    doTest3();    // this will take 1500 ms
-    doTest3_b();  // this will take 1500 ms
-    doTest3_c();  // this will take 1500 ms
-    doTest3_d();  // this will take 1500 ms
-    doTest3_e();  // this will take 1500 ms
-    doTest3_f();  // this will take 1500 ms
-    doTest3_g();  // this will take 1500 ms
-    doTest3_h();  // this will take 1500 ms
-    doTest4();    // this will take 3000 ms
-    doTest4_b();  // this will take 3000 ms
-    doTest5();    // this will take 3000 ms
-    doTest5_b();  // this will take 3000 ms
-    doTest6();    // this will take 2500 ms
-    doTest7();    // this will take 8000 ms
+    // these tests run asynchronously, and they will take 8000 ms
+    var all_tests = [
+      doTest1, doTest1_e, doTest2, doTest3, doTest3_b, doTest3_c, doTest3_d,
+      doTest3_e, doTest3_f, doTest3_g, doTest3_h, doTest4, doTest4_b,
+      doTest5, doTest5_b, doTest5_c, doTest5_e, doTest6, doTest7
+    ];
+
+    for (var test_id=0; test_id < all_tests.length; ++test_id) {
+      gTestsHaveFinished[test_id] = false;
+      var fn = all_tests[test_id];
+      fn(test_id);
+    }
+
+    setTimeout(function() {
+      for (var test_id=0; test_id < all_tests.length; ++test_id) {
+        if (!gTestsHaveFinished[test_id]) {
+          ok(false, "Test " + test_id + " took too long");
+          setTestHasFinished(test_id);
+        }
+      }
+    }, 60000 * stress_factor); // all tests together are supposed to take less than 1 minute
   }
 
   function fn_onmessage(e) {
     if (e.currentTarget == e.target && e.target.hits != null)
       e.target.hits['fn_onmessage']++;
   }
 
   function fn_event_listener_message(e) {
@@ -65,24 +87,26 @@ https://bugzilla.mozilla.org/show_bug.cg
   function fn_other_event_name(e) {
     if (e.currentTarget == e.target && e.target.hits != null)
       e.target.hits['fn_other_event_name']++;
   }
 
   var domBranch;
   var oldPrefVal;
 
-  var gEventSourceObj1 = null;
+  var gEventSourceObj1 = null, gEventSourceObj1_e;
   var gEventSourceObj2 = null;
   var gEventSourceObj3_a = null, gEventSourceObj3_b = null,
       gEventSourceObj3_c = null, gEventSourceObj3_d = null,
       gEventSourceObj3_e = null, gEventSourceObj3_f = null,
       gEventSourceObj3_g = null, gEventSourceObj3_h = null;
   var gEventSourceObj4_a = null, gEventSourceObj4_b = null;
-  var gEventSourceObj5_a = null, gEventSourceObj5_b = null;
+  var gEventSourceObj5_a = null, gEventSourceObj5_b = null,
+      gEventSourceObj5_c = null, gEventSourceObj5_d = null,
+      gEventSourceObj5_e = null, gEventSourceObj5_f = null;
   var gEventSourceObj6 = null;
   var gEventSourceObj7 = null;
   var stress_factor;  // used in the setTimeouts in order to help
                       // the test when running in slow machines
 
   function hasBeenHitFor1And2(obj, min) {
     if (obj.hits['fn_onmessage'] < min ||
         obj.hits['fn_event_listener_message'] < min ||
@@ -91,205 +115,227 @@ https://bugzilla.mozilla.org/show_bug.cg
     return true;
   }
 
 // in order to test (1):
 //   a) if the EventSource constructor parameter is equal to its url attribute
 //   b) let its fn_onmessage, fn_event_listener_message, and fn_other_event_name functions listeners be hit four times each
 //   c) the close method (we expect readyState == CLOSED)
 //   d) the close method (we expect no message events anymore)
+//   e) if the ctor throws an exception when the second parameter is null
 
-  function doTest1() {
+  function doTest1(test_id) {
     gEventSourceObj1 = new EventSource("eventsource.resource");
     ok(gEventSourceObj1.url == "http://mochi.test:8888/tests/content/base/test/eventsource.resource", "Test 1.a failed.");
     ok(gEventSourceObj1.readyState == 0 || gEventSourceObj1.readyState == 1, "Test 1.a failed.");
 
-    doTest1_b();
+    doTest1_b(test_id);
   }
 
-  function doTest1_b() {
+  function doTest1_b(test_id) {
     gEventSourceObj1.hits = [];
     gEventSourceObj1.hits['fn_onmessage'] = 0;
     gEventSourceObj1.onmessage = fn_onmessage;
     gEventSourceObj1.hits['fn_event_listener_message'] = 0;
     gEventSourceObj1.addEventListener('message', fn_event_listener_message, true);
     gEventSourceObj1.hits['fn_other_event_name'] = 0;
     gEventSourceObj1.addEventListener('other_event_name', fn_other_event_name, true);
 
     // the eventsources.res always use a retry of 0.5 second, so for four hits a timeout of 6 seconds is enough
     setTimeout(function(){
       bhits = hasBeenHitFor1And2(gEventSourceObj1, 4);
       ok(bhits, "Test 1.b failed.");
 
-      doTest1_c();
+      doTest1_c(test_id);
     }, parseInt(6000*stress_factor));
   }
 
-  function doTest1_c() {
+  function doTest1_c(test_id) {
     gEventSourceObj1.close();
     ok(gEventSourceObj1.readyState == 2, "Test 1.c failed.");
 
-    doTest1_d();
+    doTest1_d(test_id);
   }
 
-  function doTest1_d() {
+  function doTest1_d(test_id) {
     gEventSourceObj1.hits['fn_onmessage'] = 0;
     gEventSourceObj1.hits['fn_event_listener_message'] = 0;
     gEventSourceObj1.hits['fn_other_event_name'] = 0;
 
     setTimeout(function(){
       bhits = hasBeenHitFor1And2(gEventSourceObj1, 1);
       ok(!bhits, "Test 1.d failed.");
       gEventSourceObj1.close();
+      setTestHasFinished(test_id);
     }, parseInt(2000*stress_factor));
   }
 
+  function doTest1_e(test_id) {
+    try {
+      gEventSourceObj1_e = new EventSource("eventsource.resource", null);
+      ok(false, "Test 1.e failed");
+      gEventSourceObj1_e.close();
+    } catch (e) {
+      ok(true, "Test 1.e failed");
+    }
+    setTestHasFinished(test_id);
+  }
+
 // in order to test (2)
 //   a) set a eventsource that give the dom events messages
 //   b) expect trusted events
 
-  function doTest2() {
+  function doTest2(test_id) {
     var func = function(e) {
       ok(e.isTrusted, "Test 2 failed");
       gEventSourceObj2.close();
     };
 
     gEventSourceObj2 = new EventSource("eventsource.resource");
     gEventSourceObj2.onmessage = func;
 
-    setTimeout(function(){  // just to clean...
+    setTimeout(function() {  // just to clean...
       gEventSourceObj2.close();
+      setTestHasFinished(test_id);
     }, parseInt(5000*stress_factor));
   }
 
 // in order to test (3)
 //   a) XSite domain error test
 //   b) protocol file:// test
 //   c) protocol javascript: test
 //   d) wrong Content-Type test
 //   e) bad http response code test
 //   f) message eventsource without a data test
 //   g) eventsource with invalid NCName char in the event field test
 //   h) DNS error
 
-  function doTest3() {
+  function doTest3(test_id) {
     gEventSourceObj3_a = new EventSource("http://example.org/tests/content/base/test/eventsource.resource");
 
     gEventSourceObj3_a.onmessage = fn_onmessage;
     gEventSourceObj3_a.hits = [];
     gEventSourceObj3_a.hits['fn_onmessage'] = 0;
 
     setTimeout(function() {
       ok(gEventSourceObj3_a.hits['fn_onmessage'] == 0, "Test 3.a failed");
       gEventSourceObj3_a.close();
+      setTestHasFinished(test_id);
     }, parseInt(1500*stress_factor));
   }
 
-  function doTest3_b() {
+  function doTest3_b(test_id) {
     var xhr = new XMLHttpRequest;
     xhr.open("GET", "/dynamic/getMyDirectory.sjs", false);
     xhr.send();
     var basePath = xhr.responseText;
 
     gEventSourceObj3_b = new EventSource("file://" + basePath + "eventsource.resource");
 
     gEventSourceObj3_b.onmessage = fn_onmessage;
     gEventSourceObj3_b.hits = [];
     gEventSourceObj3_b.hits['fn_onmessage'] = 0;
 
     setTimeout(function() {
       ok(gEventSourceObj3_b.hits['fn_onmessage'] == 0, "Test 3.b failed");
       gEventSourceObj3_b.close();
+      setTestHasFinished(test_id);
     }, parseInt(1500*stress_factor));
   }
 
   function jsEvtSource()
   {
     return "event: message\n" +
            "data: 1\n\n";
   }
 
-  function doTest3_c() {
+  function doTest3_c(test_id) {
     gEventSourceObj3_c = new EventSource("javascript: return jsEvtSource()");
 
     gEventSourceObj3_c.onmessage = fn_onmessage;
     gEventSourceObj3_c.hits = [];
     gEventSourceObj3_c.hits['fn_onmessage'] = 0;
 
     setTimeout(function() {
       ok(gEventSourceObj3_c.hits['fn_onmessage'] == 0, "Test 3.c failed");
       gEventSourceObj3_c.close();
+      setTestHasFinished(test_id);
     }, parseInt(1500*stress_factor));
   }
 
-  function doTest3_d() {
+  function doTest3_d(test_id) {
     gEventSourceObj3_d = new EventSource("badContentType.eventsource");
 
     gEventSourceObj3_d.onmessage = fn_onmessage;
     gEventSourceObj3_d.hits = [];
     gEventSourceObj3_d.hits['fn_onmessage'] = 0;
 
     setTimeout(function() {
       ok(gEventSourceObj3_d.hits['fn_onmessage'] == 0, "Test 3.d failed");
       gEventSourceObj3_d.close();
+      setTestHasFinished(test_id);
     }, parseInt(1500*stress_factor));
   }
 
-  function doTest3_e() {
+  function doTest3_e(test_id) {
     gEventSourceObj3_e = new EventSource("badHTTPResponseCode.eventsource");
 
     gEventSourceObj3_e.onmessage = fn_onmessage;
     gEventSourceObj3_e.hits = [];
     gEventSourceObj3_e.hits['fn_onmessage'] = 0;
 
     setTimeout(function() {
       ok(gEventSourceObj3_e.hits['fn_onmessage'] == 0, "Test 3.e failed");
       gEventSourceObj3_e.close();
+      setTestHasFinished(test_id);
     }, parseInt(1500*stress_factor));
   }
 
-  function doTest3_f() {
+  function doTest3_f(test_id) {
     gEventSourceObj3_f = new EventSource("badMessageEvent.eventsource");
 
     gEventSourceObj3_f.onmessage = fn_onmessage;
     gEventSourceObj3_f.hits = [];
     gEventSourceObj3_f.hits['fn_onmessage'] = 0;
 
     setTimeout(function() {
       ok(gEventSourceObj3_f.hits['fn_onmessage'] == 0, "Test 3.f failed");
       gEventSourceObj3_f.close();
+      setTestHasFinished(test_id);
     }, parseInt(1500*stress_factor));
   }
 
   function fnInvalidNCName() {
     fnInvalidNCName.hits++;
   }
 
-  function doTest3_g() {
+  function doTest3_g(test_id) {
     gEventSourceObj3_g = new EventSource("badEventFieldName.eventsource");
 
     fnInvalidNCName.hits = 0;
     gEventSourceObj3_g.addEventListener('message event', fnInvalidNCName, true);
 
     setTimeout(function() {
       ok(fnInvalidNCName.hits != 0, "Test 3.g failed");
       gEventSourceObj3_g.close();
+      setTestHasFinished(test_id);
     }, parseInt(1500*stress_factor));
   }
 
-  function doTest3_h() {
+  function doTest3_h(test_id) {
     gEventSourceObj3_h = new EventSource("http://hdfskjghsbg.jtiyoejowe.dafsgbhjab.com");
 
     gEventSourceObj3_h.onmessage = fn_onmessage;
     gEventSourceObj3_h.hits = [];
     gEventSourceObj3_h.hits['fn_onmessage'] = 0;
 
     setTimeout(function() {
       ok(gEventSourceObj3_h.hits['fn_onmessage'] == 0, "Test 3.h failed");
       gEventSourceObj3_h.close();
+      setTestHasFinished(test_id);
     }, parseInt(1500*stress_factor));
   }
 
 // in order to test (4)
 //   a) close the object when it is in use, which is being processed and that is expected
 //      to dispatch more eventlisteners
 //   b) remove an eventlistener in use
 
@@ -304,72 +350,186 @@ https://bugzilla.mozilla.org/show_bug.cg
   function fn_onmessage4_b(e)
   {
     if (e.data > gEventSourceObj4_b.lastData)
       gEventSourceObj4_b.lastData = e.data;
     if (e.data == 2)
       gEventSourceObj4_b.removeEventListener('message', fn_onmessage4_b, true);
   }
 
-  function doTest4() {
+  function doTest4(test_id) {
     gEventSourceObj4_a = new EventSource("forRemoval.resource");
     gEventSourceObj4_a.lastData = 0;
     gEventSourceObj4_a.onmessage = fn_onmessage4_a;
 
     setTimeout(function() {
       ok(gEventSourceObj4_a.lastData == 2, "Test 4.a failed");
       gEventSourceObj4_a.close();
+      setTestHasFinished(test_id);
     }, parseInt(3000*stress_factor));
   }
 
-  function doTest4_b()
+  function doTest4_b(test_id)
   {
     gEventSourceObj4_b = new EventSource("forRemoval.resource");
     gEventSourceObj4_b.lastData = 0;
     gEventSourceObj4_b.addEventListener('message', fn_onmessage4_b, true);
 
     setTimeout(function() {
       ok(gEventSourceObj4_b.lastData == 2, "Test 4.b failed");
       gEventSourceObj4_b.close();
+      setTestHasFinished(test_id);
     }, parseInt(3000*stress_factor));
   }
 
 // in order to test (5)
-//   a) valid access-control xsite request (but must fail)
+//   a) valid access-control xsite request
 //   b) invalid access-control xsite request
+//   c) valid access-control xsite request on a restricted page with credentials
+//   d) valid access-control xsite request on a restricted page without credentials
+//   e) valid access-control xsite request on a restricted page when the parameter withCredentials is a getter 
+//   f) valid access-control xsite request on a restricted page when the parameter withCredentials is missing 
 
-  function doTest5()
+  function doTest5(test_id)
   {
     gEventSourceObj5_a = new EventSource("http://example.org/tests/content/base/test/accesscontrol.resource");
 
     gEventSourceObj5_a.onmessage = fn_onmessage;
     gEventSourceObj5_a.hits = [];
     gEventSourceObj5_a.hits['fn_onmessage'] = 0;
 
     setTimeout(function() {
-      ok(gEventSourceObj5_a.hits['fn_onmessage'] == 0, "Test 5.a failed");
+      ok(gEventSourceObj5_a.hits['fn_onmessage'] != 0, "Test 5.a failed");
       gEventSourceObj5_a.close();
+      setTestHasFinished(test_id);
     }, parseInt(3000*stress_factor));
   }
 
-  function doTest5_b()
+  function doTest5_b(test_id)
   {
     gEventSourceObj5_b = new EventSource("http://example.org/tests/content/base/test/invalid_accesscontrol.resource");
 
     gEventSourceObj5_b.onmessage = fn_onmessage;
     gEventSourceObj5_b.hits = [];
     gEventSourceObj5_b.hits['fn_onmessage'] = 0;
 
     setTimeout(function() {
       ok(gEventSourceObj5_b.hits['fn_onmessage'] == 0, "Test 5.b failed");
       gEventSourceObj5_b.close();
+      setTestHasFinished(test_id);
+    }, parseInt(3000*stress_factor));
+  }
+
+  function doTest5_c(test_id)
+  {
+    // credentials using the auth cache and cookies
+    var xhr = SpecialPowers.createSystemXHR();
+    xhr.withCredentials = true;
+    // also, test mixed mode UI
+    xhr.open("GET", "https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_xhr", false, "user 1", "password 1");
+    xhr.send();
+    ok(xhr.status == 200, "Failed to set credentials in test 5.c");
+
+    gEventSourceObj5_c = new EventSource("https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc",
+                                         { withCredentials: true } );
+    ok(gEventSourceObj5_c.withCredentials, "Wrong withCredentials in test 5.c");
+
+    gEventSourceObj5_c.onmessage = function(e) {
+      ok(e.origin == "https://example.com", "Wrong Origin in test 5.c");
+      fn_onmessage(e);
+    };
+    gEventSourceObj5_c.hits = [];
+    gEventSourceObj5_c.hits['fn_onmessage'] = 0;
+
+    setTimeout(function() {
+      ok(gEventSourceObj5_c.hits['fn_onmessage'] > 0, "Test 5.c failed");
+      gEventSourceObj5_c.close();
+      doTest5_d(test_id);
     }, parseInt(3000*stress_factor));
   }
 
-  function doTest6()
+  function doTest5_d(test_id)
+  {
+    var xhr = SpecialPowers.createSystemXHR();
+    xhr.withCredentials = true;
+    xhr.open("GET", "https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_xhr", false, "user 2", "password 2");
+    xhr.send();
+    ok(xhr.status == 200, "Failed to set credentials in test 5.d");
+
+    gEventSourceObj5_d = new EventSource("https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc");
+    ok(!gEventSourceObj5_d.withCredentials, "Wrong withCredentials in test 5.d");
+
+    gEventSourceObj5_d.onmessage = function(e) {
+      ok(e.origin == "https://example.com", "Wrong Origin in test 5.d");
+      fn_onmessage(e);
+    };
+    gEventSourceObj5_d.hits = [];
+    gEventSourceObj5_d.hits['fn_onmessage'] = 0;
+
+    setTimeout(function() {
+      ok(gEventSourceObj5_d.hits['fn_onmessage'] == 0, "Test 5.d failed");
+      gEventSourceObj5_d.close();
+      setTestHasFinished(test_id);
+    }, parseInt(3000*stress_factor));
+  }
+
+  function doTest5_e(test_id)
+  {
+    // credentials using the auth cache and cookies
+    var xhr = SpecialPowers.createSystemXHR();
+    xhr.withCredentials = true;
+    xhr.open("GET", "http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_xhr", false, "user 1", "password 1");
+    xhr.send();
+    ok(xhr.status == 200, "Failed to set credentials in test 5.e");
+
+    gEventSourceObj5_e = new EventSource("http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc",
+                                         { get withCredentials() { return true; } } );
+    ok(gEventSourceObj5_e.withCredentials, "Wrong withCredentials in test 5.e");
+
+    gEventSourceObj5_e.onmessage = function(e) {
+      ok(e.origin == "http://example.org", "Wrong Origin in test 5.e");
+      fn_onmessage(e);
+    };
+    gEventSourceObj5_e.hits = [];
+    gEventSourceObj5_e.hits['fn_onmessage'] = 0;
+
+    setTimeout(function() {
+      ok(gEventSourceObj5_e.hits['fn_onmessage'] > 0, "Test 5.e failed");
+      gEventSourceObj5_e.close();
+      doTest5_f(test_id);
+    }, parseInt(5000*stress_factor));
+  }
+
+  function doTest5_f(test_id)
+  {
+    var xhr = SpecialPowers.createSystemXHR();
+    xhr.withCredentials = true;
+    xhr.open("GET", "http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_xhr", false, "user 2", "password 2");
+    xhr.send();
+    ok(xhr.status == 200, "Failed to set credentials in test 5.f");
+
+    gEventSourceObj5_f = new EventSource("http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc",
+                                         { });
+    ok(!gEventSourceObj5_f.withCredentials, "Wrong withCredentials in test 5.f");
+
+    gEventSourceObj5_f.onmessage = function(e) {
+      ok(e.origin == "http://example.org", "Wrong Origin in test 5.f");
+      fn_onmessage(e);
+    };
+    gEventSourceObj5_f.hits = [];
+    gEventSourceObj5_f.hits['fn_onmessage'] = 0;
+
+    setTimeout(function() {
+      ok(gEventSourceObj5_f.hits['fn_onmessage'] == 0, "Test 5.f failed");
+      gEventSourceObj5_f.close();
+      setTestHasFinished(test_id);
+    }, parseInt(3000*stress_factor));
+  }
+
+  function doTest6(test_id)
   {
     gEventSourceObj6 = new EventSource("somedatas.resource");
     var fn_somedata = function(e) {
       if (fn_somedata.expected == 0) {
         ok(e.data == "123456789\n123456789123456789\n123456789123456789123456789123456789\n 123456789123456789123456789123456789123456789123456789123456789123456789\nçãá\"\'@`~Ý Ḿyyyy",
           "Test 6.a failed");
       } else if (fn_somedata.expected == 1) {
         ok(e.data == " :xxabcdefghij\nçãá\"\'@`~Ý Ḿyyyy : zz",
@@ -382,20 +542,21 @@ https://bugzilla.mozilla.org/show_bug.cg
       }
       fn_somedata.expected++;
     }
     fn_somedata.expected = 0;
     gEventSourceObj6.onmessage = fn_somedata;
 
     setTimeout(function() {
       gEventSourceObj6.close();
+      setTestHasFinished(test_id);
     }, parseInt(2500*stress_factor));
   }
 
-  function doTest7()
+  function doTest7(test_id)
   {
     gEventSourceObj7 = new EventSource("delayedServerEvents.sjs");
     gEventSourceObj7.msg_received = [];
     gEventSourceObj7.onmessage = function(e)
     {
       e.target.msg_received.push(e.data);
     }
     
@@ -403,21 +564,21 @@ https://bugzilla.mozilla.org/show_bug.cg
       gEventSourceObj7.close();
       
       ok(gEventSourceObj7.msg_received[0] == "" &&
          gEventSourceObj7.msg_received[1] == "delayed1" &&
          gEventSourceObj7.msg_received[2] == "delayed2", "Test 7 failed");
 
       SpecialPowers.setBoolPref("dom.server-events.enabled", oldPrefVal);
       document.getElementById('waitSpan').innerHTML = '';
-      SimpleTest.finish();
+      setTestHasFinished(test_id);
     }, parseInt(8000*stress_factor));
   }
 
-  function doTest()
+  function doTest(test_id)
   {
     oldPrefVal = SpecialPowers.getBoolPref("dom.server-events.enabled");
     SpecialPowers.setBoolPref("dom.server-events.enabled", true);
 
     // we get a good stress_factor by testing 10 setTimeouts and some float
     // arithmetic taking my machine as stress_factor==1 (time=589)
 
     var begin_time = (new Date()).getTime();
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug647518.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=647518
+-->
+<head>
+  <title>Test for Bug 647518</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=647518">Mozilla Bug 647518</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 647518 **/
+SimpleTest.waitForExplicitFinish();
+var counter = 3;
+
+var called = false;
+var handle1 = window.mozRequestAnimationFrame(function() {
+  called = true;
+});
+ok(handle1 > 0, "Should get back a nonzero handle");
+
+function checker() {
+  --counter;
+  if (counter == 0) {
+    is(called, false, "Canceled callback should not have been called");
+    SimpleTest.finish();
+  } else {
+    window.mozRequestAnimationFrame(checker);
+  }
+}
+window.mozRequestAnimationFrame(checker);
+window.mozCancelRequestAnimationFrame(handle1);
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -217,17 +217,18 @@ public:
                    "CurrentTarget should be null!");
     }
     return NS_OK;
   }
 
   /**
    * Copies mItemFlags and mItemData to aVisitor and calls PostHandleEvent.
    */
-  nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
+  nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor,
+                           nsCxPusher* aPusher);
 
   static PRUint32 MaxEtciCount() { return sMaxEtciCount; }
 
   static void ResetMaxEtciCount()
   {
     NS_ASSERTION(!sCurrentEtciCount, "Wrong time to call ResetMaxEtciCount()!");
     sMaxEtciCount = 0;
   }
@@ -277,18 +278,20 @@ nsEventTargetChainItem::PreHandleEvent(n
   SetWantsWillHandleEvent(aVisitor.mWantsWillHandleEvent);
   SetMayHaveListenerManager(aVisitor.mMayHaveListenerManager);
   mItemFlags = aVisitor.mItemFlags;
   mItemData = aVisitor.mItemData;
   return rv;
 }
 
 nsresult
-nsEventTargetChainItem::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
+nsEventTargetChainItem::PostHandleEvent(nsEventChainPostVisitor& aVisitor,
+                                        nsCxPusher* aPusher)
 {
+  aPusher->Pop();
   aVisitor.mItemFlags = mItemFlags;
   aVisitor.mItemData = mItemData;
   mTarget->PostHandleEvent(aVisitor);
   return NS_OK;
 }
 
 nsresult
 nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor, PRUint32 aFlags,
@@ -339,17 +342,17 @@ nsEventTargetChainItem::HandleEventTarge
     //       event listeners should not be fired. But it breaks at least
     //       <xul:dialog>'s buttons. Bug 235441.
     item->HandleEvent(aVisitor, aFlags,
                       aMayHaveNewListenerManagers ||
                       createdELMs != nsEventListenerManager::sCreatedCount,
                       aPusher);
   }
   if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) {
-    item->PostHandleEvent(aVisitor);
+    item->PostHandleEvent(aVisitor, aPusher);
   }
 
   // Bubble
   aVisitor.mEvent->flags &= ~NS_EVENT_FLAG_CAPTURE;
   item = item->mParent;
   while (item) {
     nsIDOMEventTarget* newTarget = item->GetNewTarget();
     if (newTarget) {
@@ -362,17 +365,17 @@ nsEventTargetChainItem::HandleEventTarge
       if ((!(aVisitor.mEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH) ||
            item->ForceContentDispatch()) &&
           !(aVisitor.mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH)) {
         item->HandleEvent(aVisitor, aFlags & NS_EVENT_BUBBLE_MASK,
                           createdELMs != nsEventListenerManager::sCreatedCount,
                           aPusher);
       }
       if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) {
-        item->PostHandleEvent(aVisitor);
+        item->PostHandleEvent(aVisitor, aPusher);
       }
     }
     item = item->mParent;
   }
   aVisitor.mEvent->flags &= ~NS_EVENT_FLAG_BUBBLE;
 
   if (!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT)) {
     // Dispatch to the system event group.  Make sure to clear the
@@ -381,16 +384,17 @@ nsEventTargetChainItem::HandleEventTarge
       ~(NS_EVENT_FLAG_STOP_DISPATCH | NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY);
 
     // Setting back the original target of the event.
     aVisitor.mEvent->target = aVisitor.mEvent->originalTarget;
 
     // Special handling if PresShell (or some other caller)
     // used a callback object.
     if (aCallback) {
+      aPusher->Pop();
       aCallback->HandleEvent(aVisitor);
     }
 
     // Retarget for system event group (which does the default handling too).
     // Setting back the target which was used also for default event group.
     aVisitor.mEvent->target = firstTarget;
     HandleEventTargetChain(aVisitor, aFlags | NS_EVENT_FLAG_SYSTEM_EVENT,
                            aCallback,
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -292,18 +292,17 @@ nsHTMLSharedObjectElement::BindToTree(ns
 
 #ifndef XP_MACOSX
   if (aDocument &&
       aDocument->IsFullScreenDoc() &&
       nsContentUtils::HasPluginWithUncontrolledEventDispatch(this)) {
     // This content contains a windowed plugin for which we don't control
     // event dispatch, and we're in full-screen mode. Exit full-screen mode
     // to prevent phishing attacks.
-    NS_DispatchToCurrentThread(
-      NS_NewRunnableMethod(aDocument, &nsIDocument::CancelFullScreen));
+    nsIDocument::ExitFullScreen(true);
     nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
                                     "AddedWindowedPluginWhileFullScreen",
                                     nsnull, 0, nsnull,
                                     EmptyString(), 0, 0,
                                     nsIScriptError::warningFlag,
                                     "DOM", aDocument);           
   }
 #endif
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -287,16 +287,17 @@ include $(topsrcdir)/config/rules.mk
 		test_fullscreen-api.html \
 		file_fullscreen-plugins.html \
 		file_fullscreen-denied.html \
 		file_fullscreen-denied-inner.html \
 		file_fullscreen-hidden.html \
 		file_fullscreen-navigation.html \
 		file_fullscreen-esc-exit.html \
 		file_fullscreen-esc-exit-inner.html \
+		file_fullscreen-rollback.html \
 		test_li_attributes_reflection.html \
 		test_ol_attributes_reflection.html \
 		test_bug651956.html \
 		test_bug694503.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
--- a/content/html/content/test/file_fullscreen-api-keys.html
+++ b/content/html/content/test/file_fullscreen-api-keys.html
@@ -23,21 +23,21 @@ Test that restricted key pressed drop do
 
 // List of key codes which should exit full-screen mode.
 var keyList = [
   { code: "VK_ESCAPE", suppressed: true},
   { code: "VK_F11",    suppressed: false},
 ];
 
 function ok(condition, msg) {
-  opener.ok(condition, msg);
+  opener.ok(condition, "[keys] " + msg);
 }
 
 function is(a, b, msg) {
-  opener.is(a, b, msg);
+  opener.is(a, b, "[keys] " + msg);
 }
 
 var gKeyTestIndex = 0;
 var gKeyName;
 var gKeyCode;
 var gKeySuppressed;
 var gKeyReceived = false;
 
--- a/content/html/content/test/file_fullscreen-api.html
+++ b/content/html/content/test/file_fullscreen-api.html
@@ -17,21 +17,21 @@ Test DOM full-screen API.
   </style>
 </head>
 <body onload="start();">
 <script type="application/javascript">
 
 /** Test for Bug 545812 **/
 
 function ok(condition, msg) {
-  opener.ok(condition, msg);
+  opener.ok(condition, "[fullscreen] " + msg);
 }
 
 function is(a, b, msg) {
-  opener.is(a, b, msg);
+  opener.is(a, b, "[fullscreen] " + msg);
 }
 
 /*
 <html>
   <body onload='document.body.mozRequestFullScreen();'>
   <iframe id='inner-frame'></iframe>
   </body>
 </html>
@@ -59,151 +59,151 @@ function setRequireTrustedContext(value)
 
 function fullScreenElement() {
   return document.getElementById('full-screen-element');
 }
 
 function fullScreenChange(event) {
   switch (fullScreenChangeCount) {
     case 0: {
-      ok(document.mozFullScreen, "Should be in full-screen mode (first time)");
-      is(event.target, document, "Event target should be full-screen document #1");
-      is(document.mozFullScreenElement, fullScreenElement(),
-         "Full-screen element should be div element.");
-      ok(document.mozFullScreenElement.mozMatchesSelector(":-moz-full-screen"),
-         "FSE should match :-moz-full-screen");
+      ok(document.mozFullScreen, "1. Should be in full-screen mode (first time)");
+      is(event.target, document, "2. Event target should be full-screen document #1");
+      is(document.mozFullScreenElement, fullScreenElement(), "3. Full-screen element should be div element.");
+      ok(document.mozFullScreenElement.mozMatchesSelector(":-moz-full-screen"), "4. FSE should match :-moz-full-screen");
       var fse = fullScreenElement();
       fse.parentNode.removeChild(fse);
-      is(document.mozFullScreenElement, null,
-         "Full-screen element should be null after removing.");
-      ok(!document.mozFullScreen, "Should have left full-screen mode when we remove full-screen element");
+      is(document.mozFullScreenElement, null, "5. Full-screen element should be null after removing.");
+      ok(!document.mozFullScreen, "6. Should have left full-screen mode when we remove full-screen element");
       document.body.appendChild(fse);
-      ok(!document.mozFullScreen, "Should not return to full-screen mode when re-adding former FSE");
-      is(document.mozFullScreenElement, null,
-         "Full-screen element should still be null after re-adding former FSE.");
+      ok(!document.mozFullScreen, "7. Should not return to full-screen mode when re-adding former FSE");
+      is(document.mozFullScreenElement, null, "8. Full-screen element should still be null after re-adding former FSE.");
       break;
     }
     case 1: {
-      ok(!document.mozFullScreen, "Should have left full-screen mode (first time)");
-      is(event.target, document, "Event target should be full-screen document #2");
-      is(document.mozFullScreenElement, null, "Full-screen element should be null.");
+      ok(!document.mozFullScreen, "9. Should have left full-screen mode (first time)");
+      is(event.target, document, "10. Event target should be full-screen document #2");
+      is(document.mozFullScreenElement, null, "11. Full-screen element should be null.");
       iframe = document.createElement("iframe");
       iframe.mozAllowFullScreen = true;
       document.body.appendChild(iframe);
       iframe.src = iframeContents;
       break;
     }
     case 2: {
-      ok(document.mozFullScreen, "Should be back in full-screen mode (second time)");
-      is(event.target, document, "Event target should be full-screen document #3");
-      is(document.mozFullScreenElement, iframe,
-        "Full-screen element should be iframe element.");
- 
-      SimpleTest.waitForFocus(function() {
-        ok(document.mozFullScreen, "Should still be full-screen mode before focus.");
-        SpecialPowers.focus(window);
-        ok(document.mozFullScreen, "Should still be full-screen mode after focus.");
-        
-        var fse = fullScreenElement();
-        fse.mozRequestFullScreen();
-
-        // RequestFullScreen() is async, continue after it completes.
-        setTimeout(function() {
-          ok(document.mozFullScreen, "Should still be full-screen mode after re-requesting.");
-          is(document.mozFullScreenElement, fse, "Full-screen element should have switched to requestee.");
-          var _innerFrame = iframe.contentDocument.getElementById("inner-frame");
-          _innerFrame.contentDocument.body.appendChild(fse);
-          ok(!document.mozFullScreen, "Should exit full-screen after transplanting FSE");
-          is(document.mozFullScreenElement, null, "Full-screen element transplanted, should be null.");
-          is(iframe.contentDocument.mozFullScreenElement, null, "Full-screen element in outer frame should be null.");
-          is(_innerFrame.contentDocument.mozFullScreenElement, null, "Full-screen element in inner frame should be null.");
-          ok(!iframe.contentDocument.mozFullScreen, "Outer frame should not acquire full-screen status.");
-          ok(!_innerFrame.contentDocument.mozFullScreen, "Inner frame should not acquire full-screen status.");
-          
-          document.body.appendChild(fse);
-        }, 0);
-      }, 0);
+      ok(document.mozFullScreen, "12. Should be back in full-screen mode (second time)");
+      is(event.target, document, "13. Event target should be full-screen document #3");
+      is(document.mozFullScreenElement, iframe, "14. Full-screen element should be iframe element.");
+      is(iframe.contentDocument.mozFullScreenElement, iframe.contentDocument.body, "15. Full-screen element in subframe should be body");
+      
+      // The iframe's body is full-screen. Cancel full-screen in the subdocument to return
+      // the full-screen element to the previous full-screen element. This causes
+      // a fullscreenchange event.
+      document.mozCancelFullScreen();
       break;
     }
     case 3: {
-      ok(!document.mozFullScreen, "Should be back in non-full-screen mode (second time)");
-      is(event.target, document, "Event target should be full-screen document #4");
-      is(document.mozFullScreenElement, null, "Full-screen element should be null.");
+      ok(!document.mozFullScreen, "16. Should have left full-screen when removing FSE ancestor.");
+      is(document.mozFullScreenElement, null, "17. Full-screen element should have rolled back.");
+      is(iframe.contentDocument.mozFullScreenElement, null, "18. Full-screen element in subframe should be null");
+      
+      fullScreenElement().mozRequestFullScreen();
+      break;
+    }
+    case 4: {
+      ok(document.mozFullScreen, "19. Should be back in full-screen mode (second time)");
+      is(event.target, document, "20. Event target should be full-screen document #3");
+      is(document.mozFullScreenElement, fullScreenElement(), "21. Full-screen element should be div.");
+      
+      // Transplant the FSE into subdoc. Should exit full-screen.
+      var _innerFrame = iframe.contentDocument.getElementById("inner-frame");
+      var fse = fullScreenElement();
+      _innerFrame.contentDocument.body.appendChild(fse);
+      ok(!document.mozFullScreen, "22. Should exit full-screen after transplanting FSE");
+      is(document.mozFullScreenElement, null, "23. Full-screen element transplanted, should be null.");
+      is(iframe.contentDocument.mozFullScreenElement, null, "24. Full-screen element in outer frame should be null.");
+      is(_innerFrame.contentDocument.mozFullScreenElement, null, "25. Full-screen element in inner frame should be null.");
+      ok(!iframe.contentDocument.mozFullScreen, "26. Outer frame should not acquire full-screen status.");
+      ok(!_innerFrame.contentDocument.mozFullScreen, "27. Inner frame should not acquire full-screen status.");
+      
+      document.body.appendChild(fse);
+      break;
+    }
+    case 5: {
+      ok(!document.mozFullScreen, "28. Should be back in non-full-screen mode (second time)");
+      is(event.target, document, "29. Event target should be full-screen document #4");
+      is(document.mozFullScreenElement, null, "30. Full-screen element should be null.");
       document.body.removeChild(iframe);
       iframe = null;
 
       // Do a request out of document. It should be denied.
       // Continue test in the following mozfullscreenerror handler.
       outOfDocElement = document.createElement("div");
       var f =
       function(e) {
         document.removeEventListener("mozfullscreenerror", f, false);
-        ok(!document.mozFullScreen, "Requests for full-screen from not-in-doc elements should fail.");
+        ok(!document.mozFullScreen, "31. Requests for full-screen from not-in-doc elements should fail.");
         fullScreenErrorRun = true;
 
         container = document.createElement("div");
         inDocElement = document.createElement("div");
         container.appendChild(inDocElement);
         fullScreenElement().appendChild(container);
         
         inDocElement.mozRequestFullScreen();
       };
       document.addEventListener("mozfullscreenerror", f, false);
       outOfDocElement.mozRequestFullScreen();
 
       break;
     }
-    case 4: {
-      ok(document.mozFullScreen, "Should still be in full-screen mode (third time)");
-      is(event.target, document, "Event target should be full-screen document #5");
-      ok(fullScreenErrorRun, "Should have run fullscreenerror handler from previous case.");
-      is(document.mozFullScreenElement, inDocElement,
-        "FSE should be inDocElement.");
+    case 6: {
+      ok(document.mozFullScreen, "32. Should still be in full-screen mode (third time)");
+      is(event.target, document, "33. Event target should be full-screen document #5");
+      ok(fullScreenErrorRun, "34. Should have run fullscreenerror handler from previous case.");
+      is(document.mozFullScreenElement, inDocElement, "35. FSE should be inDocElement.");
 
       var n = container;
       do {
         ok(n.mozMatchesSelector(":-moz-full-screen-ancestor"), "Ancestor " + n + " should match :-moz-full-screen-ancestor")
         n = n.parentNode;
       } while (n && n.mozMatchesSelector);
         
       // Remove full-screen ancestor element from document, verify it stops being reported as current FSE.
       container.parentNode.removeChild(container);
-      ok(!document.mozFullScreen,
-         "Should exit full-screen mode after removing full-screen element ancestor from document");
-      is(document.mozFullScreenElement, null,
-        "Should not have a full-screen element again.");
+      ok(!document.mozFullScreen, "36. Should exit full-screen mode after removing full-screen element ancestor from document");
+      is(document.mozFullScreenElement, null, "37. Should not have a full-screen element again.");
       break;
     }
-    case 5: {
-      ok(!document.mozFullScreen, "Should be back in non-full-screen mode (third time)");
+    case 7: {
+      ok(!document.mozFullScreen, "38. Should be back in non-full-screen mode (third time)");
       setRequireTrustedContext(true);
       fullscreendenied = false;
       fullScreenElement().mozRequestFullScreen();
 
       setTimeout(
         function() {
           ok(fullscreendenied, "Request for fullscreen should have been denied because calling context isn't trusted");
           ok(!document.mozFullScreen, "Should still be in normal mode, because calling context isn't trusted.");
           button = document.createElement("button");
           button.onclick = function(){fullScreenElement().mozRequestFullScreen();}
           fullScreenElement().appendChild(button);
           sendMouseClick(button);
         }, 0);
       break;
     }
-    case 6: {
+    case 8: {
       ok(document.mozFullScreen, "Moved to full-screen after mouse click");
       document.mozCancelFullScreen();
       ok(document.mozFullScreen, "Should still be in full-screen mode, because calling context isn't trusted.");
       setRequireTrustedContext(false);
       document.mozCancelFullScreen();
       ok(!document.mozFullScreen, "Should have left full-screen mode.");
       break;
     }
-    case 7: {
+    case 9: {
       ok(!document.mozFullScreen, "Should have left full-screen mode (last time).");
 
       SpecialPowers.setBoolPref("full-screen-api.enabled", false);
       is(document.mozFullScreenEnabled, false, "document.mozFullScreenEnabled should be false if full-screen-api.enabled is false");
       fullscreendenied = false;
       fullScreenElement().mozRequestFullScreen();
       setTimeout(
         function() {
--- a/content/html/content/test/file_fullscreen-denied.html
+++ b/content/html/content/test/file_fullscreen-denied.html
@@ -17,21 +17,21 @@ Test DOM full-screen API.
 </head>
 <body onload="run();">
 
 <script type="application/javascript">
 
 /** Test for Bug 545812 **/
 
 function ok(condition, msg) {
-  opener.ok(condition, msg);
+  opener.ok(condition, "[denied] " + msg);
 }
 
 function is(a, b, msg) {
-  opener.is(a, b, msg);
+  opener.is(a, b, "[denied] " + msg);
 }
 
 var fullscreendenied = false;
 
 document.addEventListener("mozfullscreenerror", function(){fullscreendenied=true;}, false);
 
 var gotFullScreenChange = false;
 
--- a/content/html/content/test/file_fullscreen-esc-exit.html
+++ b/content/html/content/test/file_fullscreen-esc-exit.html
@@ -16,29 +16,30 @@ exit DOM full-screen mode.
   }
   </style>
 </head>
 <body onload="startTest();">
 
 <script type="application/javascript">
 
 function ok(condition, msg) {
-  opener.ok(condition, msg);
+  opener.ok(condition, "[esc-exit] " + msg);
 }
 
 function is(a, b, msg) {
-  opener.is(a, b, msg);
+  opener.is(a, b, "[esc-exit] " + msg);
 }
 
 function finish() {
   opener.nextTest();
 }
 
 function fullscreenchange1(event) {
   ok(document.mozFullScreen, "Should have entered full-screen mode");
+  is(document.mozFullScreenElement, document.body, "FSE should be doc");
   document.removeEventListener("mozfullscreenchange", fullscreenchange1, false);
   document.addEventListener("mozfullscreenchange", fullscreenchange2, false);
   ok(!document.getElementById("subdoc").contentWindow.escKeySent, "Should not yet have sent ESC key press.");
   document.getElementById("subdoc").contentWindow.startTest();
 }
 
 function fullscreenchange2(event) {
   document.removeEventListener("mozfullscreenchange", fullscreenchange2, false);
--- a/content/html/content/test/file_fullscreen-hidden.html
+++ b/content/html/content/test/file_fullscreen-hidden.html
@@ -29,22 +29,23 @@ function boom()
 {
   frameWin = document.getElementById("f").contentWindow;
   e1 = frameWin.document.documentElement;
   frameWin.location = "data:text/html,<body text=blue onload='parent.b2()'>2";
 }
 
 function b2()
 {
-  try { e1.mozRequestFullScreen(); } catch(e) { opener.ok(false, "Should not enter full-screen"); }
+  try { e1.mozRequestFullScreen(); } catch(e) { opener.ok(false, "[hidden] Should not enter full-screen"); }
   setTimeout(done, 0);
 }
 
 function done() {
-  opener.ok(!document.mozFullScreen, "Should not have entered full-screen mode in hidden document.");
-  opener.ok(!e1.ownerDocument.mozFullScreen, "Requesting owner should not have entered full-screen mode.");
+  opener.ok(!document.mozFullScreen, "[hidden] Should not have entered full-screen mode in hidden document.");
+  opener.ok(!e1.ownerDocument.mozFullScreen, "[hidden] Requesting owner should not have entered full-screen mode.");
   opener.nextTest();
 }
 
 </script>
 </pre>
 </body>
+
 </html>
--- a/content/html/content/test/file_fullscreen-navigation.html
+++ b/content/html/content/test/file_fullscreen-navigation.html
@@ -29,23 +29,23 @@ var prevTrusted;
 
 function boom()
 {
   frameWin = document.getElementById("f").contentWindow;
   e1 = frameWin.document.body;
   e1.mozRequestFullScreen();
   setTimeout(
     function() {
-      opener.ok(document.mozFullScreen, "Request should be granted");
+      opener.ok(document.mozFullScreen, "[navigation] Request should be granted");
       frameWin.location = "data:text/html,<body text=blue onload='parent.b2()'>2";
     }, 0);
 }
 
 function b2()
 {
-  opener.ok(!document.mozFullScreen, "Should have left full-screen due to navigation.");
+  opener.ok(!document.mozFullScreen, "[navigation] Should have left full-screen due to navigation.");
   opener.nextTest();
 }
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/html/content/test/file_fullscreen-plugins.html
+++ b/content/html/content/test/file_fullscreen-plugins.html
@@ -38,21 +38,21 @@ Test plugins with DOM full-screen API:
 
 <iframe id="subdoc-plugin" src="data:text/html;charset=utf-8,<html><body><embed id%3D'windowed-plugin' type%3D'application%2Fx-test' style%3D'width%3A200px%3Bheight%3A100px%3B' wmode%3D'window'><%2Fembed><%2Fbody><%2Fhtml>%0D%0A"></iframe>
 
 <script type="application/javascript">
 
 /** Test for Bug 545812 **/
 
 function ok(condition, msg) {
-  opener.ok(condition, msg);
+  opener.ok(condition, "[plugins] " + msg);
 }
 
 function is(a, b, msg) {
-  opener.is(a, b, msg);
+  opener.is(a, b, "[plugins] " + msg);
 }
 
 const isMacOs = navigator.appVersion.indexOf("Macintosh") != -1;
 
 document.addEventListener("mozfullscreenchange", isMacOs ? macFullScreenChange : fullScreenChange, false);
 
 var windowedPlugin = null;
 
@@ -139,16 +139,17 @@ function macFullScreenChange(event) {
   }
   fullScreenChangeCount++;
 }
 
 function fullScreenChange(event) {
   switch (fullScreenChangeCount) {
     case 0: {
       ok(document.mozFullScreen, "Request for full-screen with document containing windowless plugin should be granted");
+      is(document.mozFullScreenElement, document.body, "FSE should be body.");
       // Add windowed plugin to document, should cause full-screen mode to exit.
       document.body.appendChild(windowedPlugin);
       break;
     }
     case 1: {
       ok(!document.mozFullScreen, "Should have left full-screen mode after re-adding windowed plugin to document");
       windowedPlugin.parentNode.removeChild(windowedPlugin);
       document.body.mozRequestFullScreen();
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_fullscreen-rollback.html
@@ -0,0 +1,130 @@
+ <!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=700764
+
+Verifies that cancelFullScreen() rolls back to have the previous full-screen
+element full-screen.
+
+Tests:
+* Request full-screen in doc.
+* Request full-screen in doc on element not descended from full-screen element. Request should be denied.
+* Request full-screen in subdoc.
+* Cancel full-screen in subdoc, doc should be full-screen.
+* Request full-screen in subdoc.
+* Removing FSE should fully-exit full-screen.
+
+
+-->
+<head>
+  <title>Test for Bug 700764</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<body onload="start();">
+
+<div id="fse">
+  <div id="fse-inner">
+    <iframe id="subdoc" mozallowfullscreen src="data:text/html,<html><body bgcolor='black'></body></html>"></iframe>
+  </div>
+</div>
+
+<div id="non-fse"></div>
+
+<script type="application/javascript">
+
+/** Test for Bug 700764 **/
+
+function ok(condition, msg) {
+  opener.ok(condition, "[rollback] " + msg);
+}
+
+function is(a, b, msg) {
+  opener.is(a, b, "[rollback] " + msg);
+}
+
+function addListener(type, f) {
+  document.addEventListener("mozfullscreen" + type, f, false);
+}
+
+function removeListener(type, f) {
+  document.removeEventListener("mozfullscreen" + type, f, false);
+}
+
+function e(id) {
+  return document.getElementById(id);
+}
+
+function start() {
+  SimpleTest.waitForFocus(
+    function() {
+      addListener("change", change1);
+      e("fse").mozRequestFullScreen();
+    }
+  );
+}
+
+function change1() {
+  removeListener("change", change1);
+  addListener("error", error1);
+  is(document.mozFullScreenElement, e("fse"), "Body should be FSE");
+  
+  // Request full-screen from element not descendent from current FSE.
+  e("non-fse").mozRequestFullScreen();
+}
+
+function error1() {
+  removeListener("error", error1);
+  addListener("change", change2);
+  is(document.mozFullScreenElement, e("fse"), "FSE should not change");
+  var iframe = e("subdoc");
+  iframe.contentDocument.body.mozRequestFullScreen();
+}
+
+function change2() {
+  removeListener("change", change2);
+  var iframe = e("subdoc");
+  is(document.mozFullScreenElement, iframe, "Subdoc container should be FSE.");
+  is(iframe.contentDocument.mozFullScreenElement, iframe.contentDocument.body, "Subdoc body should be FSE in subdoc");
+  addListener("change", change3);
+  iframe.contentDocument.mozCancelFullScreen();  
+}
+
+function change3() {
+  removeListener("change", change3);
+  is(document.mozFullScreenElement, e("fse"), "FSE should rollback to FSE.");
+  addListener("change", change4);
+  document.mozCancelFullScreen();
+}
+
+function change4() {
+  removeListener("change", change4);
+  is(document.mozFullScreenElement, null, "Should have left full-screen entirely");
+  addListener("change", change5);
+  e("fse").mozRequestFullScreen();
+}
+
+function change5() {
+  removeListener("change", change5);
+  addListener("change", change6);
+  is(document.mozFullScreenElement, e("fse"), "FSE should be e('fse')");
+  e("fse-inner").mozRequestFullScreen();
+}
+
+function change6() {
+  removeListener("change", change6);
+  addListener("change", change7);
+  var element = e('fse-inner');
+  is(document.mozFullScreenElement, element, "FSE should be e('fse-inner')");
+  element.parentNode.removeChild(element);
+}
+
+function change7() {
+  removeListener("change", change7);
+  is(document.mozFullScreenElement, null, "Should have fully exited full-screen mode when removed FSE from doc");
+  opener.nextTest();
+}
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/content/test/test_fullscreen-api.html
+++ b/content/html/content/test/test_fullscreen-api.html
@@ -31,16 +31,17 @@ SpecialPowers.setBoolPref("full-screen-a
 // to write.
 var prevTrusted = SpecialPowers.getBoolPref("full-screen-api.allow-trusted-requests-only");
 SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
 
 // Run the tests which go full-screen in new windows, as mochitests normally
 // run in an iframe, which by default will not have the mozallowfullscreen
 // attribute set, so full-screen won't work.
 var gTestWindows = [
+  "file_fullscreen-rollback.html",
   "file_fullscreen-esc-exit.html",
   "file_fullscreen-denied.html",
   "file_fullscreen-api.html",
   "file_fullscreen-api-keys.html",
   "file_fullscreen-plugins.html",
   "file_fullscreen-hidden.html",
   "file_fullscreen-navigation.html"
 ];
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -3869,30 +3869,44 @@ nsGlobalWindow::GetMozPaintCount(PRUint6
   if (!presShell)
     return NS_OK;
 
   *aResult = presShell->GetPaintCount();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback)
-{
-  FORWARD_TO_INNER(MozRequestAnimationFrame, (aCallback),
+nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback,
+                                         PRInt32 *aHandle)
+{
+  FORWARD_TO_INNER(MozRequestAnimationFrame, (aCallback, aHandle),
                    NS_ERROR_NOT_INITIALIZED);
 
   if (!mDoc) {
     return NS_OK;
   }
 
   if (!aCallback) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
   }
 
-  mDoc->ScheduleFrameRequestCallback(aCallback);
+  return mDoc->ScheduleFrameRequestCallback(aCallback, aHandle);
+}
+
+NS_IMETHODIMP
+nsGlobalWindow::MozCancelRequestAnimationFrame(PRInt32 aHandle)
+{
+  FORWARD_TO_INNER(MozCancelRequestAnimationFrame, (aHandle),
+                   NS_ERROR_NOT_INITIALIZED);
+
+  if (!mDoc) {
+    return NS_OK;
+  }
+
+  mDoc->CancelFrameRequestCallback(aHandle);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetMozAnimationStartTime(PRInt64 *aTime)
 {
   FORWARD_TO_INNER(GetMozAnimationStartTime, (aTime), NS_ERROR_NOT_INITIALIZED);
 
@@ -4419,22 +4433,22 @@ nsGlobalWindow::SetFullScreen(bool aFull
   // Set this before so if widget sends an event indicating its
   // gone full screen, the state trap above works.
   mFullScreen = aFullScreen;
 
   nsCOMPtr<nsIWidget> widget = GetMainWidget();
   if (widget)
     widget->MakeFullScreen(aFullScreen);
 
-  if (!mFullScreen && mDocument) {
-    // Notify the document that we've left full-screen mode. This is so that
-    // if we're in full-screen mode and the user exits full-screen mode with
-    // the browser full-screen mode toggle keyboard-shortcut, we detect that
-    // and leave DOM API full-screen mode too.
-    mDocument->MozCancelFullScreen();
+  if (!mFullScreen) {
+    // Force exit from DOM full-screen mode. This is so that if we're in
+    // DOM full-screen mode and the user exits full-screen mode with
+    // the browser full-screen mode toggle keyboard-shortcut, we'll detect
+    // that and leave DOM API full-screen mode too.
+    nsIDocument::ExitFullScreen(false);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetFullScreen(bool* aFullScreen)
 {
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -1104,18 +1104,18 @@ IDBObjectStore::AddOrPut(const jsval& aV
   PRUint64 offset;
 
   nsresult rv =
     GetAddInfo(aCx, aValue, keyval, cloneBuffer, key, updateInfo, &offset);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  // Put requires a key.
-  if (aOverwrite && key.IsUnset()) {
+  // Put requires a key, unless this is an autoIncrementing objectStore.
+  if (aOverwrite && !mAutoIncrement && key.IsUnset()) {
     return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
   }
 
   nsRefPtr<IDBRequest> request = GenerateRequest(this);
   NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   nsRefPtr<AddHelper> helper =
     new AddHelper(mTransaction, request, this, cloneBuffer, key, aOverwrite,
@@ -1788,17 +1788,17 @@ AddHelper::DoDatabaseWork(mozIStorageCon
     }
 
     if (NS_FAILED(rv)) {
       return NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR;
     }
   }
 
   // If we are supposed to generate a key, get the new id.
-  if (autoIncrement && !mOverwrite) {
+  if (autoIncrement && !mayOverwrite) {
 #ifdef DEBUG
     PRInt64 oldKey = unsetKey ? 0 : mKey.ToInteger();
 #endif
 
     PRInt64 newIntKey;
     rv = aConnection->GetLastInsertRowID(&newIntKey);
     NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
--- a/dom/indexedDB/test/test_key_requirements.html
+++ b/dom/indexedDB/test/test_key_requirements.html
@@ -56,28 +56,28 @@
       request.onerror = errorHandler;
       request.onsuccess = grabEventAndContinueHandler;
       event = yield;
 
       is(event.target.result, key2, "put gave the same key back");
 
       try {
         objectStore.put({});
-        ok(false, "put with no key should throw!");
+        ok(true, "put with no key should not throw with autoIncrement!");
       }
       catch (e) {
-        ok(true, "put with no key threw");
+        ok(false, "put with no key threw with autoIncrement");
       }
 
       try {
         objectStore.put({});
-        ok(false, "put with no key should throw!");
+        ok(true, "put with no key should not throw with autoIncrement!");
       }
       catch (e) {
-        ok(true, "put with no key threw");
+        ok(false, "put with no key threw with autoIncrement");
       }
 
       try {
         objectStore.delete();
         ok(false, "remove with no key should throw!");
       }
       catch (e) {
         ok(true, "remove with no key threw");
@@ -242,28 +242,28 @@
       request.onerror = errorHandler;
       request.onsuccess = grabEventAndContinueHandler;
       event = yield;
 
       is(event.target.result, key2, "put gave the same key back");
 
       try {
         objectStore.put({});
-        ok(false, "put with no key should throw!");
+        ok(true, "put with no key should not throw with autoIncrement!");
       }
       catch (e) {
-        ok(true, "put with no key threw");
+        ok(false, "put with no key threw with autoIncrement");
       }
 
       try {
         objectStore.put({});
-        ok(false, "put with no key should throw!");
+        ok(true, "put with no key should not throw with autoIncrement!");
       }
       catch (e) {
-        ok(true, "put with no key threw");
+        ok(false, "put with no key threw with autoIncrement");
       }
 
       try {
         objectStore.delete();
         ok(false, "remove with no key should throw!");
       }
       catch (e) {
         ok(true, "remove with no key threw");
--- a/dom/indexedDB/test/test_put_get_values_autoIncrement.html
+++ b/dom/indexedDB/test/test_put_get_values_autoIncrement.html
@@ -24,28 +24,28 @@
       request.onupgradeneeded = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
 
       let objectStore = db.createObjectStore(objectStoreName,
                                              { autoIncrement: 1 });
 
-      request = objectStore.add(testString.value);
+      request = objectStore.put(testString.value);
       request.onerror = errorHandler;
       request.onsuccess = function(event) {
         testString.key = event.target.result;
         request = objectStore.get(testString.key);
         request.onerror = errorHandler;
         request.onsuccess = function(event) {
           is(event.target.result, testString.value, "Got the right value");
         };
       };
 
-      request = objectStore.add(testInt.value);
+      request = objectStore.put(testInt.value);
       request.onerror = errorHandler;
       request.onsuccess = function(event) {
         testInt.key = event.target.result;
         request = objectStore.get(testInt.key);
         request.onerror = errorHandler;
         request.onsuccess = function(event) {
           is(event.target.result, testInt.value, "Got the right value");
           finishTest();
--- a/dom/interfaces/base/nsIDOMWindow.idl
+++ b/dom/interfaces/base/nsIDOMWindow.idl
@@ -65,17 +65,17 @@ interface nsIDOMMozURLProperty : nsISupp
  * The nsIDOMWindow interface is the primary interface for a DOM
  * window object. It represents a single window object that may
  * contain child windows if the document in the window contains a
  * HTML frameset document or if the document contains iframe elements.
  *
  * @see <http://www.whatwg.org/html/#window>
  */
 
-[scriptable, uuid(8f577294-d572-4473-94b1-d2c5a74a2a74)]
+[scriptable, uuid(973e7219-40d5-4f94-b78d-53c2a0b8a13c)]
 interface nsIDOMWindow : nsISupports
 {
   // the current browsing context
   readonly attribute nsIDOMWindow                       window;
 
   /* [replaceable] self */
   readonly attribute nsIDOMWindow                       self;
 
@@ -412,20 +412,25 @@ interface nsIDOMWindow : nsISupports
    */
   readonly attribute unsigned long long mozPaintCount;
 
   /**
    * Request a refresh of this browser window.
    *
    * @see <http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/RequestAnimationFrame/Overview.html>
    */
-  void
+  long
     mozRequestAnimationFrame(in nsIFrameRequestCallback aCallback);
 
   /**
+   * Cancel a refresh callback.
+   */
+  void mozCancelRequestAnimationFrame(in long aHandle);
+
+  /**
    * The current animation start time in milliseconds since the epoch.
    */
   readonly attribute long long mozAnimationStartTime;
 
   /**
    * @see <http://dev.w3.org/2006/webapi/FileAPI/#creating-revoking>
    */
   readonly attribute nsIDOMMozURLProperty URL;
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -118,13 +118,15 @@ GlobalStorageWarning=Use of globalStorag
 FullScreenDeniedDisabled=Request for full-screen was denied because full-screen API is disabled by user preference.
 FullScreenDeniedPlugins=Request for full-screen was denied because a document on this page contains a windowed plugin.
 FullScreenDeniedHidden=Request for full-screen was denied because the document is no longer visible.
 FullScreenDeniedIframeDisallowed=Request for full-screen was denied because at least one of the document's containing iframes does not have a "mozallowfullscreen" attribute.
 FullScreenDeniedNotInputDriven=Request for full-screen was denied because Element.mozRequestFullScreen() was not called from inside a short running user-generated event handler.
 FullScreenDeniedNotInDocument=Request for full-screen was denied because requesting element is no longer in its document.
 FullScreenDeniedMovedDocument=Request for full-screen was denied because requesting element has moved document.
 FullScreenDeniedLostWindow=Request for full-screen was denied because we no longer have a window.
+FullScreenDeniedSubDocFullScreen=Request for full-screen was denied because a subdocument of the document requesting full-screen is already full-screen.
+FullScreenDeniedNotDescendant=Request for full-screen was denied because requesting element is not a descendant of the current full-screen element.
 RemovedFullScreenElement=Exited full-screen because full-screen element was removed from document.
 AddedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was added to document.
 HTMLMultipartXHRWarning=HTML parsing in XMLHttpRequest is not supported for multipart responses.
 HTMLSyncXHRWarning=HTML parsing in XMLHttpRequest is not supported in the synchronous mode.
 InvalidRedirectChannelWarning=Unable to redirect to %S because the channel doesn't implement nsIWritablePropertyBag2.
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -3308,18 +3308,17 @@ NS_IMETHODIMP nsPluginInstanceOwner::Cre
 
   if (mObjectFrame) {
     if (!mWidget) {
       bool windowless = false;
       mInstance->IsWindowless(&windowless);
       nsIDocument *doc = mContent ? mContent->OwnerDoc() : nsnull;
 #ifndef XP_MACOSX
       if (!windowless && doc && doc->IsFullScreenDoc()) {
-        NS_DispatchToCurrentThread(
-          NS_NewRunnableMethod(doc, &nsIDocument::CancelFullScreen));
+        nsIDocument::ExitFullScreen(true);
       }
 #endif
       // always create widgets in Twips, not pixels
       nsPresContext* context = mObjectFrame->PresContext();
       rv = mObjectFrame->CreateWidget(context->DevPixelsToAppUnits(mPluginWindow->width),
                                       context->DevPixelsToAppUnits(mPluginWindow->height),
                                       windowless);
       if (NS_OK == rv) {
--- a/dom/system/Makefile.in
+++ b/dom/system/Makefile.in
@@ -56,16 +56,20 @@ endif
 ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
 DIRS = cocoa
 endif
 
 ifneq (,$(filter android,$(MOZ_WIDGET_TOOLKIT)))
 DIRS = android
 endif
 
+ifdef MOZ_B2G_RIL #{
+DIRS += b2g
+endif #}
+
 CPPSRCS     = \
   nsDeviceMotion.cpp \
   $(NULL)
 
 # We fire the nsDOMDeviceAcceleration
 LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
 
 # On Systems that have build in geolocation providers,
rename from dom/telephony/worker-component/Makefile.in
rename to dom/system/b2g/Makefile.in
--- a/dom/telephony/worker-component/Makefile.in
+++ b/dom/system/b2g/Makefile.in
@@ -1,62 +1,65 @@
-#
 # ***** 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 Original Code is Telephony.
 #
 # The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
+#   The Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2011
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
+#   Ben Turner <bent.mozilla@gmail.com> (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 *****
 
-DEPTH		= ../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
+DEPTH            = ../../..
+topsrcdir        = @top_srcdir@
+srcdir           = @srcdir@
+VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-EXTRA_COMPONENTS = \
-  nsTelephonyWorker.manifest \
-  nsTelephonyWorker.js \
+MODULE           = dom
+LIBRARY_NAME     = domsystemb2g_s
+XPIDL_MODULE     = dom_system_b2g
+LIBXUL_LIBRARY   = 1
+FORCE_STATIC_LIB = 1
+
+include $(topsrcdir)/dom/dom-config.mk
+
+CPPSRCS = \
+  RadioManager.cpp \
   $(NULL)
 
-EXTRA_JS_MODULES = \
-  ril_consts.js \
-  ril_worker.js \
-  $(NULL)
+XPIDLSRCS = nsIRadioWorker.idl
 
-XPIDL_MODULE = dom_telephony_worker
-XPIDLSRCS = \
-  nsITelephonyWorker.idl \
-  nsIRadioInterface.idl \
+LOCAL_INCLUDES = \
+  -I$(topsrcdir)/dom/base \
+  -I$(topsrcdir)/dom/telephony \
+  -I$(topsrcdir)/content/events/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
-
rename from dom/telephony/Radio.cpp
rename to dom/system/b2g/RadioManager.cpp
--- a/dom/telephony/Radio.cpp
+++ b/dom/system/b2g/RadioManager.cpp
@@ -32,24 +32,25 @@
  * 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 "Radio.h"
-#include "nsITelephonyWorker.h"
+#include "RadioManager.h"
+#include "nsIRadioWorker.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "nsIJSContextStack.h"
 #include "nsIObserverService.h"
 #include "mozilla/dom/workers/Workers.h"
 #include "jstypedarray.h"
+#include "nsTelephonyWorker.h"
 
 #include "nsThreadUtils.h"
 
 #if defined(MOZ_WIDGET_GONK)
 #include <android/log.h>
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
 #else
 #define LOG(args...)  printf(args);
@@ -63,17 +64,17 @@ static NS_DEFINE_CID(kTelephonyWorkerCID
 // Topic we listen to for shutdown.
 #define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change"
 
 USING_TELEPHONY_NAMESPACE
 
 namespace {
 
 // Doesn't carry a reference, we're owned by services.
-Radio* gInstance = nsnull;
+RadioManager* gInstance = nsnull;
 
 class ConnectWorkerToRIL : public WorkerTask {
 public:
   virtual bool RunTask(JSContext *aCx);
 };
 
 JSBool
 PostToRIL(JSContext *cx, uintN argc, jsval *vp)
@@ -82,17 +83,17 @@ PostToRIL(JSContext *cx, uintN argc, jsv
 
   if (argc != 1) {
     JS_ReportError(cx, "Expecting a single argument with the RIL message");
     return false;
   }
 
   jsval v = JS_ARGV(cx, vp)[0];
 
-  nsAutoPtr<RilMessage> rm(new RilMessage());
+  nsAutoPtr<RilRawData> rm(new RilRawData());
   JSAutoByteString abs;
   void *data;
   size_t size;
   if (JSVAL_IS_STRING(v)) {
     JSString *str = JSVAL_TO_STRING(v);
     if (!abs.encode(cx, str)) {
       return false;
     }
@@ -117,26 +118,26 @@ PostToRIL(JSContext *cx, uintN argc, jsv
     size = JS_GetTypedArrayByteLength(obj);
     data = JS_GetTypedArrayData(obj);
   } else {
     JS_ReportError(cx,
                    "Incorrect argument. Expecting a string or a typed array");
     return false;
   }
 
-  if (size > RilMessage::DATA_SIZE) {
+  if (size > RilRawData::MAX_DATA_SIZE) {
     JS_ReportError(cx, "Passed-in data is too large");
     return false;
   }
 
   rm->mSize = size;
   memcpy(rm->mData, data, size);
 
-  RilMessage *tosend = rm.forget();
-  JS_ALWAYS_TRUE(SendRilMessage(&tosend));
+  RilRawData *tosend = rm.forget();
+  JS_ALWAYS_TRUE(SendRilRawData(&tosend));
   return true;
 }
 
 bool
 ConnectWorkerToRIL::RunTask(JSContext *aCx)
 {
   // Set up the postRILMessage on the function for worker -> RIL thread
   // communication.
@@ -146,32 +147,32 @@ ConnectWorkerToRIL::RunTask(JSContext *a
 
   return JS_DefineFunction(aCx, workerGlobal, "postRILMessage", PostToRIL, 1, 0);
 }
 
 class RILReceiver : public RilConsumer
 {
   class DispatchRILEvent : public WorkerTask {
   public:
-    DispatchRILEvent(RilMessage *aMessage)
+    DispatchRILEvent(RilRawData *aMessage)
       : mMessage(aMessage)
     { }
 
     virtual bool RunTask(JSContext *aCx);
 
   private:
-    nsAutoPtr<RilMessage> mMessage;
+    nsAutoPtr<RilRawData> mMessage;
   };
 
 public:
   RILReceiver(WorkerCrossThreadDispatcher *aDispatcher)
     : mDispatcher(aDispatcher)
   { }
 
-  virtual void MessageReceived(RilMessage *aMessage) {
+  virtual void MessageReceived(RilRawData *aMessage) {
     nsRefPtr<DispatchRILEvent> dre(new DispatchRILEvent(aMessage));
     mDispatcher->PostTask(dre);
   }
 
 private:
   nsRefPtr<WorkerCrossThreadDispatcher> mDispatcher;
 };
 
@@ -189,52 +190,50 @@ RILReceiver::DispatchRILEvent::RunTask(J
   memcpy(JS_GetTypedArrayData(array), mMessage->mData, mMessage->mSize);
   jsval argv[] = { OBJECT_TO_JSVAL(array) };
   return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv),
                              argv, argv);
 }
 
 } // anonymous namespace
 
-Radio::Radio()
+RadioManager::RadioManager()
   : mShutdown(false)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!gInstance, "There should only be one instance!");
 }
 
-Radio::~Radio()
+RadioManager::~RadioManager()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!gInstance || gInstance == this,
                "There should only be one instance!");
   gInstance = nsnull;
 }
 
 nsresult
-Radio::Init()
+RadioManager::Init()
 {
   NS_ASSERTION(NS_IsMainThread(), "We can only initialize on the main thread");
 
   nsCOMPtr<nsIObserverService> obs =
     do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
   if (!obs) {
     NS_WARNING("Failed to get observer service!");
     return NS_ERROR_FAILURE;
   }
 
   nsresult rv = obs->AddObserver(this, PROFILE_BEFORE_CHANGE_TOPIC, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // The telephony worker component is a hack that gives us a global object for
   // our own functions and makes creating the worker possible.
-  nsCOMPtr<nsITelephonyWorker> worker(do_CreateInstance(kTelephonyWorkerCID));
-  if (!worker) {
-    return NS_ERROR_FAILURE;
-  }
+  nsCOMPtr<nsIRadioWorker> worker(do_CreateInstance(kTelephonyWorkerCID));
+  NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
 
   jsval workerval;
   rv = worker->GetWorker(&workerval);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ASSERTION(!JSVAL_IS_PRIMITIVE(workerval), "bad worker value");
 
   JSContext *cx;
   rv = nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&cx);
@@ -261,73 +260,73 @@ Radio::Init()
   if (!wctd->PostTask(connection)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   // Now that we're set up, connect ourselves to the RIL thread.
   mozilla::RefPtr<RILReceiver> receiver = new RILReceiver(wctd);
   StartRil(receiver);
 
-  mRadioInterface = do_QueryInterface(worker);
-  NS_ENSURE_TRUE(mRadioInterface, NS_ERROR_FAILURE);
+  mTelephone = do_QueryInterface(worker);
+  NS_ENSURE_TRUE(mTelephone, NS_ERROR_FAILURE);
 
   return NS_OK;
 }
 
 void
-Radio::Shutdown()
+RadioManager::Shutdown()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   StopRil();
-  mRadioInterface = nsnull;
+  mTelephone = nsnull;
 
   mShutdown = true;
 }
 
 // static
-already_AddRefed<Radio>
-Radio::FactoryCreate()
+already_AddRefed<RadioManager>
+RadioManager::FactoryCreate()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  nsRefPtr<Radio> instance(gInstance);
+  nsRefPtr<RadioManager> instance(gInstance);
 
   if (!instance) {
-    instance = new Radio();
+    instance = new RadioManager();
     if (NS_FAILED(instance->Init())) {
       return nsnull;
     }
 
     gInstance = instance;
   }
 
   return instance.forget();
 }
 
 // static
-already_AddRefed<nsIRadioInterface>
-Radio::GetRadioInterface()
+already_AddRefed<nsITelephone>
+RadioManager::GetTelephone()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (gInstance) {
-    nsCOMPtr<nsIRadioInterface> retval = gInstance->mRadioInterface;
+    nsCOMPtr<nsITelephone> retval = gInstance->mTelephone;
     return retval.forget();
   }
 
   return nsnull;
 }
 
 
-NS_IMPL_ISUPPORTS1(Radio, nsIObserver)
+NS_IMPL_ISUPPORTS1(RadioManager, nsIObserver)
 
 NS_IMETHODIMP
-Radio::Observe(nsISupports* aSubject, const char* aTopic,
-               const PRUnichar* aData)
+RadioManager::Observe(nsISupports* aSubject, const char* aTopic,
+                      const PRUnichar* aData)
 {
   if (!strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC)) {
     Shutdown();
 
     nsCOMPtr<nsIObserverService> obs =
       do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
     if (obs) {
       if (NS_FAILED(obs->RemoveObserver(this, aTopic))) {
rename from dom/telephony/Radio.h
rename to dom/system/b2g/RadioManager.h
--- a/dom/telephony/Radio.h
+++ b/dom/system/b2g/RadioManager.h
@@ -43,17 +43,17 @@
 #include "jsapi.h"
 #include "nsComponentManagerUtils.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsServiceManagerUtils.h"
 
 #include "nsIObserver.h"
 #include "mozilla/ipc/Ril.h"
-#include "nsIRadioInterface.h"
+#include "nsITelephone.h"
 
 #define TELEPHONYRADIO_CONTRACTID "@mozilla.org/telephony/radio;1"
 #define TELEPHONYRADIOINTERFACE_CONTRACTID "@mozilla.org/telephony/radio-interface;1"
 
 #define BEGIN_TELEPHONY_NAMESPACE \
   namespace mozilla { namespace dom { namespace telephony {
 #define END_TELEPHONY_NAMESPACE \
   } /* namespace telephony */ } /* namespace dom */ } /* namespace mozilla */
@@ -68,34 +68,34 @@
 #define TELEPHONYRADIOINTERFACE_CID \
   {0xd66e7ece, 0x41b1, 0x4608, {0x82, 0x80, 0x72, 0x50, 0xa6, 0x44, 0xe6, 0x6f}}
 
 
 class nsIXPConnectJSObjectHolder;
 
 BEGIN_TELEPHONY_NAMESPACE
 
-class Radio : public nsIObserver
+class RadioManager : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   nsresult Init();
   void Shutdown();
 
-  static already_AddRefed<Radio>
+  static already_AddRefed<RadioManager>
   FactoryCreate();
 
-  static already_AddRefed<nsIRadioInterface>
-  GetRadioInterface();
+  static already_AddRefed<nsITelephone>
+  GetTelephone();
 
 protected:
-  Radio();
-  ~Radio();
+  RadioManager();
+  ~RadioManager();
 
-  nsCOMPtr<nsIRadioInterface> mRadioInterface;
+  nsCOMPtr<nsITelephone> mTelephone;
   bool mShutdown;
 };
 
 END_TELEPHONY_NAMESPACE
 
 #endif // mozilla_dom_telephony_radio_h__
new file mode 100644
--- /dev/null
+++ b/dom/system/b2g/nsIRadioWorker.idl
@@ -0,0 +1,43 @@
+/* ***** 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 Telephony.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ben Turner <bent.mozilla@gmail.com> (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 ***** */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(8f031451-ac25-4816-a09e-a075bb704e63)]
+interface nsIRadioWorker : nsISupports {
+    readonly attribute jsval worker;
+};
--- a/dom/telephony/Makefile.in
+++ b/dom/telephony/Makefile.in
@@ -37,36 +37,35 @@
 
 DEPTH            = ../..
 topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
+MODULE           = dom
 LIBRARY_NAME     = domtelephony_s
 XPIDL_MODULE     = dom_telephony
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/dom/dom-config.mk
 
-CPPSRCS = \
-  Radio.cpp \
-  $(NULL)
-
-LOCAL_INCLUDES = \
-  -I$(topsrcdir)/dom/base \
-  -I$(topsrcdir)/content/events/src \
-  $(NULL)
-
 XPIDLSRCS = \
   mozIDOMTelephony.idl \
+  nsITelephone.idl \
   $(NULL)
 
 EXTRA_COMPONENTS = \
   Telephony.manifest \
   Telephony.js \
+  nsTelephonyWorker.manifest \
+  nsTelephonyWorker.js \
   $(NULL)
 
-DIRS += worker-component
+EXTRA_JS_MODULES = \
+  ril_consts.js \
+  ril_worker.js \
+  $(NULL)
 
 include $(topsrcdir)/config/rules.mk
+
--- a/dom/telephony/Telephony.js
+++ b/dom/telephony/Telephony.js
@@ -41,16 +41,41 @@ Cu.import("resource://gre/modules/XPCOMU
 
 const TELEPHONY_CID = Components.ID("{37e248d2-02ff-469b-bb31-eef5a4a4bee3}");
 const TELEPHONY_CONTRACTID = "@mozilla.org/telephony;1";
 
 const TELEPHONY_CALL_CID = Components.ID("{6b9b3daf-e5ea-460b-89a5-641ee20dd577}");
 const TELEPHONY_CALL_CONTRACTID = "@mozilla.org/telephony-call;1";
 
 
+const DOM_RADIOSTATE_UNAVAILABLE   = "unavailable";
+const DOM_RADIOSTATE_OFF           = "off";
+const DOM_RADIOSTATE_READY         = "ready";
+
+const DOM_CARDSTATE_UNAVAILABLE    = "unavailable";
+const DOM_CARDSTATE_ABSENT         = "absent";
+const DOM_CARDSTATE_PIN_REQUIRED   = "pin_required";
+const DOM_CARDSTATE_PUK_REQUIRED   = "puk_required";
+const DOM_CARDSTATE_NETWORK_LOCKED = "network_locked";
+const DOM_CARDSTATE_NOT_READY      = "not_ready";
+const DOM_CARDSTATE_READY          = "ready";
+
+const DOM_CALL_READYSTATE_DIALING        = "dialing";
+const DOM_CALL_READYSTATE_RINGING        = "ringing";
+const DOM_CALL_READYSTATE_BUSY           = "busy";
+const DOM_CALL_READYSTATE_CONNECTING     = "connecting";
+const DOM_CALL_READYSTATE_CONNECTED      = "connected";
+const DOM_CALL_READYSTATE_DISCONNECTING  = "disconnecting";
+const DOM_CALL_READYSTATE_DISCONNECTED   = "disconnected";
+const DOM_CALL_READYSTATE_INCOMING       = "incoming";
+const DOM_CALL_READYSTATE_HOLDING        = "holding";
+const DOM_CALL_READYSTATE_HELD           = "held";
+
+const CALLINDEX_TEMPORARY_DIALING = -1;
+
 /**
  * Define an event listener slot on an object, e.g.
  * 
  *   obj.onerror = function () {...}
  * 
  * will register the function as an event handler for the "error" event
  * if the "error" slot was defined on 'obj' or its prototype.
  */
@@ -105,93 +130,84 @@ EventTarget.prototype = {
        return;
      }
   },
 
   dispatchEvent: function dispatchEvent(event) {
     //TODO this does not deal with bubbling, defaultPrevented, canceling, etc.
     //TODO disallow re-dispatch of the same event if it's already being
     // dispatched (recursion).
+    if (!this._listeners) {
+      return;
+    }
     let handlerList = this._listeners[event.type];
     if (!handlerList) {
       return;
     }
     event.target = this;
 
     // We need to worry about event handler mutations during the event firing.
     // The correct behaviour is to *not* call any listeners that are added
     // during the firing and to *not* call any listeners that are removed
     // during the firing. To address this, we make a copy of the listener list
     // before dispatching and then double-check that each handler is still
     // registered before firing it.
     let handlers = handlerList.slice();
     handlers.forEach(function (handler) {
-      if (handerList.indexOf(handler) == -1) {
+      if (handlerList.indexOf(handler) == -1) {
         return;
       }
       switch (typeof handler) {
         case "function":
           handler(event);
           break;
         case "object":
           handler.handleEvent(event);
           break;
       }
     });
   }
 };
 
-const DOM_RADIOSTATE_UNAVAILABLE = "unavailable";
-const DOM_RADIOSTATE_OFF         = "off";
-const DOM_RADIOSTATE_READY       = "ready";
-   
-const DOM_CARDSTATE_UNAVAILABLE    = "unavailable";
-const DOM_CARDSTATE_ABSENT         = "absent";
-const DOM_CARDSTATE_PIN_REQUIRED   = "pin_required";
-const DOM_CARDSTATE_PUK_REQUIRED   = "puk_required";
-const DOM_CARDSTATE_NETWORK_LOCKED = "network_locked";
-const DOM_CARDSTATE_NOT_READY      = "not_ready";
-const DOM_CARDSTATE_READY          = "ready";
-
 /**
- * Callback object that Telephony registers with nsIRadioInterface.
+ * Callback object that Telephony registers with nsITelephone.
  * Telephony can't use itself because that might overload event handler
  * attributes ('onfoobar').
  */
-function TelephonyRadioCallback(telephony) {
+function TelephoneCallback(telephony) {
   this.telephony = telephony;
 }
-TelephonyRadioCallback.prototype = {
+TelephoneCallback.prototype = {
 
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioCallback]),
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephoneCallback]),
 
-  // nsIRadioCallback
+  // nsITelephoneCallback
 
-  onsignalstrengthchange: function onsignalstrengthchange(signalStrength) {
-    this.telephony.signalStrength = signalStrength;
+  onsignalstrengthchange: function onsignalstrengthchange(event) {
+    this.telephony.signalStrength = event.signalStrength;
     this.telephony._dispatchEventByType("signalstrengthchange");
   },
 
-  onoperatorchange: function onoperatorchange(operator) {
-    this.telephony.operator = operator;
+  onoperatorchange: function onoperatorchange(event) {
+    this.telephony.operator = event.operator;
     this.telephony._dispatchEventByType("operatorchange");
   },
 
-  onradiostatechange: function onradiostatechange(radioState) {
-    this.telephony.radioState = radioState;
+  onradiostatechange: function onradiostatechange(event) {
+    this.telephony.radioState = event.radioState;
     this.telephony._dispatchEventByType("radiostatechange");
   },
 
-  oncardstatechange: function oncardstatechange(cardState) {
-    this.telephony.cardState = cardState;
+  oncardstatechange: function oncardstatechange(event) {
+    this.telephony.cardState = event.cardState;
     this.telephony._dispatchEventByType("cardstatechange");
   },
 
-  oncallstatechange: function oncallstatechange(callState) {
-    this.telephony._processCallState(callState);
+  oncallstatechange: function oncallstatechange(event) {
+    this.telephony._processCallState(event);
   },
 
 };
 
 /**
  * The navigator.mozTelephony object.
  */
 function Telephony() {}
@@ -209,105 +225,202 @@ Telephony.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMTelephony,
                                          Ci.nsIDOMEventTarget,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
 
   // nsIDOMGlobalPropertyInitializer
 
   init: function init(window) {
     this.window = window;
-    this.radioInterface = Cc["@mozilla.org/telephony/radio-interface;1"]
-                            .createInstance(Ci.nsIRadioInterface);
-    this.radioCallback = new TelephonyRadioCallback(this);
+    this.telephone = Cc["@mozilla.org/telephony/radio-interface;1"]
+                       .createInstance(Ci.nsITelephone);
+    this.telephoneCallback = new TelephoneCallback(this);
+    //TODO switch to method suggested by bz in bug 707507
     window.addEventListener("unload", function onunload(event) {
-      this.radioInterface.unregisterCallback(this.radioCallback);
-      this.radioCallback = null;
+      this.telephone.unregisterCallback(this.telephoneCallback);
+      this.telephoneCallback = null;
       this.window = null;
     }.bind(this));
-    this.radioInterface.registerCallback(this.radioCallback);
+    this.telephone.registerCallback(this.telephoneCallback);
+    this.callsByIndex = {};
     this.liveCalls = [];
 
-    let initialState = this.radioInterface.initialState;
-    this.operator        = initialState.operator;
-    this.radioState      = initialState.radioState;
-    this.cardState       = initialState.cardState;
-    this.signalStrength  = initialState.signalStrength;
-    this._processCallState(initialState.callState);
+    // Populate existing state.
+    let currentState = this.telephone.currentState;
+    let states = currentState.currentCalls;
+    for (let i = 0; i < states.length; i++) {
+      let state = states[i];
+      let call = new TelephonyCall(this.telephone, state.callIndex);
+      call.readyState = state.callState;
+      call.number = state.number;
+      this.liveCalls.push(call);
+      this.callsByIndex[state.callIndex] = call;
+    }
+
+    this.operator        = currentState.operator;
+    this.radioState      = currentState.radioState;
+    this.cardState       = currentState.cardState;
+    this.signalStrength  = currentState.signalStrength;
   },
 
   _dispatchEventByType: function _dispatchEventByType(type) {
     let event = this.window.document.createEvent("Event");
     event.initEvent(type, false, false);
     //event.isTrusted = true;
     this.dispatchEvent(event);
   },
 
-  _processCallState: function _processCallState(callState) {
-    //TODO
+  _dispatchCallEvent: function _dispatchCallEvent(call, type, target) {
+    let event = this.window.document.createEvent("Event");
+    event.initEvent(type, false, false);
+    event.call = call; //XXX this is probably not going to work
+    //event.isTrusted = true;
+    target = target || call;
+    target.dispatchEvent(event);    
   },
 
+  _processCallState: function _processCallState(state) {
+    // If the call is dialing, chances are good that we just kicked that off
+    // so there's a call object without a callIndex. Let's fix that.
+    if (state.callState == DOM_CALL_READYSTATE_DIALING) {
+      let call = this.callsByIndex[CALLINDEX_TEMPORARY_DIALING];
+      if (call) {
+        call.callIndex = state.callIndex;
+        delete this.callsByIndex[CALLINDEX_TEMPORARY_DIALING];
+        this.callsByIndex[call.callIndex] = call;
+        // Nothing else to do, since the initial call state will already be
+        // DOM_CALL_READYSTATE_DIALING, so there's no event to dispatch.
+        return;
+      }
+    }
+
+    // If there is an existing call object, update state and dispatch event
+    // on it.
+    let call = this.callsByIndex[state.callIndex];
+    if (call) {
+      if (call.readyState == state.callState) {
+        // No change in ready state, don't dispatch an event.
+        return;
+      }
+      if (state.readyState == DOM_CALL_READYSTATE_DISCONNECTED) {
+        let index = this.liveCalls.indexOf(call);
+        if (index != -1) {
+          this.liveCalls.splice(index, 1);
+        }
+        delete this.callsByIndex[call.callIndex];
+      }
+      call.readyState = state.callState;
+      this._dispatchCallEvent(call, "readystatechange");
+      this._dispatchCallEvent(call, state.callState);
+      return;
+    }
+
+    // There's no call object yet, so let's create a new one, except when
+    // the state notified means that the call is over.
+    if (state.readyState == DOM_CALL_READYSTATE_DISCONNECTED) {
+      return;
+    }
+    call = new TelephonyCall(this.telephone, state.callIndex);
+    call.number = state.number;
+    call.readyState = state.callState;
+    this.callsByIndex[state.callIndex] = call;
+    this.liveCalls.push(call);
+
+    let target;
+    if (call.readyState == DOM_CALL_READYSTATE_INCOMING) {
+      target = this;
+    } else {
+      target = call;
+      this._dispatchCallEvent(call, "readystatechange");
+    }
+    this._dispatchCallEvent(call, state.callState, target);
+  },
+
+  callsByIndex: null,
+
   // mozIDOMTelephony
 
   liveCalls: null,
 
   dial: function dial(number) {
-    this.radioInterface.dial(number);
-    return new TelephonyCall(number, DOM_CALL_READYSTATE_DIALING);
+    this.telephone.dial(number);
+
+    // We don't know ahead of time what callIndex the call is going to have
+    // so let's assign a temp value for now and sort it out on the first
+    // 'callstatechange' event.
+    //TODO ensure there isn't already an outgoing call
+    let callIndex = CALLINDEX_TEMPORARY_DIALING;
+    let call = new TelephonyCall(this.telephone, callIndex);
+    call.readyState = DOM_CALL_READYSTATE_DIALING;
+    call.number = number;
+    this.callsByIndex[callIndex] = call;
+    this.liveCalls.push(call);
+    return call;
   },
 
   // Additional stuff that's useful.
 
   signalStrength: null,
   operator: null,
   radioState: DOM_RADIOSTATE_UNAVAILABLE,
   cardState: DOM_CARDSTATE_UNAVAILABLE,
 
 };
+defineEventListenerSlot(Telephony.prototype, DOM_CALL_READYSTATE_INCOMING);
+//XXX philikon's additions
 defineEventListenerSlot(Telephony.prototype, "radiostatechange");
 defineEventListenerSlot(Telephony.prototype, "cardstatechange");
 defineEventListenerSlot(Telephony.prototype, "signalstrengthchange");
 defineEventListenerSlot(Telephony.prototype, "operatorchange");
-defineEventListenerSlot(Telephony.prototype, "incoming");
 
 
-const DOM_CALL_READYSTATE_DIALING   = "dialing";
-const DOM_CALL_READYSTATE_DOM_CALLING   = "calling";
-const DOM_CALL_READYSTATE_INCOMING  = "incoming";
-const DOM_CALL_READYSTATE_CONNECTED = "connected";
-const DOM_CALL_READYSTATE_CLOSED    = "closed";
-const DOM_CALL_READYSTATE_BUSY      = "busy";
-
-function TelephonyCall(number, initialState) {
-  this.number = number;
-  this.readyState = initialState;
+function TelephonyCall(telephone, callIndex) {
+  this.telephone = telephone;
+  this.callIndex = callIndex;
 }
 TelephonyCall.prototype = {
 
   __proto__: EventTarget.prototype,
 
   classID: TELEPHONY_CALL_CID,
   classInfo: XPCOMUtils.generateCI({classID: TELEPHONY_CALL_CID,
                                     contractID: TELEPHONY_CALL_CONTRACTID,
                                     interfaces: [Ci.mozIDOMTelephonyCall,
                                                  Ci.nsIDOMEventTarget],
                                     flags: Ci.nsIClassInfo.DOM_OBJECT,
                                     classDescription: "TelephonyCall"}),
   QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMTelephonyCall,
                                          Ci.nsIDOMEventTarget]),
 
+
+  callIndex: null,
+
+  // mozIDOMTelephonyCall
+
   number: null,
   readyState: null,
 
   answer: function answer() {
-    //TODO
+    if (this.readyState != DOM_CALL_READYSTATE_INCOMING) {
+      throw "Can only answer an incoming call!";
+    }
+    this.telephone.answerCall();
   },
 
   disconnect: function disconnect() {
-    //TODO
+    if (this.readyState == DOM_CALL_READYSTATE_INCOMING) {
+      this.telephone.rejectCall();
+    } else {
+      this.telephone.hangUp(this.callIndex);
+    }
   },
 
 };
-defineEventListenerSlot(TelephonyCall.prototype, "connect");
-defineEventListenerSlot(TelephonyCall.prototype, "disconnect");
-defineEventListenerSlot(TelephonyCall.prototype, "busy");
+defineEventListenerSlot(TelephonyCall.prototype, "readystatechange");
+defineEventListenerSlot(TelephonyCall.prototype, DOM_CALL_READYSTATE_RINGING);
+defineEventListenerSlot(TelephonyCall.prototype, DOM_CALL_READYSTATE_BUSY);
+defineEventListenerSlot(TelephonyCall.prototype, DOM_CALL_READYSTATE_CONNECTING);
+defineEventListenerSlot(TelephonyCall.prototype, DOM_CALL_READYSTATE_CONNECTED);
+defineEventListenerSlot(TelephonyCall.prototype, DOM_CALL_READYSTATE_DISCONNECTING);
+defineEventListenerSlot(TelephonyCall.prototype, DOM_CALL_READYSTATE_DISCONNECTED);
 
 
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([Telephony]);
--- a/dom/telephony/mozIDOMTelephony.idl
+++ b/dom/telephony/mozIDOMTelephony.idl
@@ -31,16 +31,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEventTarget.idl"
+#include "nsIDOMEvent.idl"
 interface nsIDOMEventListener;
 interface mozIDOMTelephonyCall;
 
 [scriptable, uuid(24371c72-1631-477d-b26e-f14db369bc22)]
 interface mozIDOMTelephony : nsIDOMEventTarget {
 
   readonly attribute jsval liveCalls;
   mozIDOMTelephonyCall dial(in DOMString number);
@@ -69,8 +70,13 @@ interface mozIDOMTelephonyCall : nsIDOME
   attribute nsIDOMEventListener onreadystatechange;
   attribute nsIDOMEventListener onringing;
   attribute nsIDOMEventListener onbusy;
   attribute nsIDOMEventListener onconnecting;
   attribute nsIDOMEventListener onconnected;
   attribute nsIDOMEventListener ondisconnecting;
   attribute nsIDOMEventListener ondisconnected;
 };
+
+[scriptable, uuid(c8c42b0c-a0dd-4702-9425-a7a80b2075c3)]
+interface mozIDOMTelephonyCallEvent : nsIDOMEvent {
+  readonly attribute mozIDOMTelephonyCall call;
+};
rename from dom/telephony/worker-component/nsIRadioInterface.idl
rename to dom/telephony/nsITelephone.idl
--- a/dom/telephony/worker-component/nsIRadioInterface.idl
+++ b/dom/telephony/nsITelephone.idl
@@ -32,30 +32,32 @@
  * 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"
 
-[scriptable, uuid(e21cdf40-c511-442b-8c7d-aa75471b0423)]
-interface nsIRadioCallback : nsISupports {
-  void oncallstatechange(in jsval callState);
+[scriptable, uuid(9b7e3a01-9c45-4af3-81bb-1bf08a842226)]
+interface nsITelephoneCallback : nsISupports {
+  void oncallstatechange(in jsval event);
 
   //XXX philikon's additions
-  void onoperatorchange(in jsval operatorInfo);
-  void onradiostatechange(in jsval radioState);
-  void oncardstatechange(in jsval cardState);
-  void onsignalstrengthchange(in jsval signalStrength);
+  void onoperatorchange(in jsval event);
+  void onradiostatechange(in jsval event);
+  void oncardstatechange(in jsval event);
+  void onsignalstrengthchange(in jsval event);
 };
 
-[scriptable, uuid(dda49485-5887-49bb-ba0b-10c5d116eb64)]
-interface nsIRadioInterface : nsISupports {
+[scriptable, uuid(3d3deb80-fa5e-4e05-9153-91ee614f67d5)]
+interface nsITelephone : nsISupports {
 
-  readonly attribute jsval initialState;
+  readonly attribute jsval currentState;
 
   void dial(in DOMString number);
-  void hangup(in long callIndex);
+  void hangUp(in long callIndex);
+  void answerCall();
+  void rejectCall();
 
-  void registerCallback(in nsIRadioCallback callback);
-  void unregisterCallback(in nsIRadioCallback callback);
+  void registerCallback(in nsITelephoneCallback callback);
+  void unregisterCallback(in nsITelephoneCallback callback);
 };
new file mode 100644
--- /dev/null
+++ b/dom/telephony/nsTelephonyWorker.h
@@ -0,0 +1,40 @@
+/* ***** 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 Telephony.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ben Turner <bent.mozilla@gmail.com> (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 ***** */
+
+#define NS_TELEPHONYWORKER_CID \
+    { 0x2d831c8d, 0x6017, 0x435b, \
+      { 0xa8, 0x0c, 0xe5, 0xd4, 0x22, 0x81, 0x0c, 0xea } }
rename from dom/telephony/worker-component/nsTelephonyWorker.js
rename to dom/telephony/nsTelephonyWorker.js
--- a/dom/telephony/worker-component/nsTelephonyWorker.js
+++ b/dom/telephony/nsTelephonyWorker.js
@@ -40,36 +40,43 @@ const {classes: Cc, interfaces: Ci, util
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const DEBUG = true; // set to false to suppress debug messages
 
 const TELEPHONYWORKER_CONTRACTID = "@mozilla.org/telephony/worker;1";
 const TELEPHONYWORKER_CID        = Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}");
 
+const DOM_CALL_READYSTATE_DISCONNECTED = "disconnected";
 
 function nsTelephonyWorker() {
   this.worker = new ChromeWorker("resource://gre/modules/ril_worker.js");
   this.worker.onerror = this.onerror.bind(this);
   this.worker.onmessage = this.onmessage.bind(this);
 
   this._callbacks = [];
-  this.initialState = {};
+  this.currentState = {
+    signalStrength: null,
+    operator:       null,
+    radioState:     null,
+    cardState:      null,
+    currentCalls:   {}
+  };
 }
 nsTelephonyWorker.prototype = {
 
   classID:   TELEPHONYWORKER_CID,
   classInfo: XPCOMUtils.generateCI({classID: TELEPHONYWORKER_CID,
                                     contractID: TELEPHONYWORKER_CONTRACTID,
                                     classDescription: "TelephonyWorker",
-                                    interfaces: [Ci.nsITelephonyWorker,
-                                                 Ci.nsIRadioInterface]}),
+                                    interfaces: [Ci.nsIRadioWorker,
+                                                 Ci.nsITelephone]}),
 
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyWorker,
-                                         Ci.nsIRadioInterface]),
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioWorker,
+                                         Ci.nsITelephone]),
 
   onerror: function onerror(event) {
     // It is very important to call preventDefault on the event here.
     // If an exception is thrown on the worker, it bubbles out to the
     // component that created it. If that component doesn't have an
     // onerror handler, the worker will try to call the error reporter
     // on the context it was created on. However, That doesn't work
     // for component contexts and can result in crashes. This onerror
@@ -81,61 +88,78 @@ nsTelephonyWorker.prototype = {
           event.lineno + ": " + event.message + "\n");
   },
 
   onmessage: function onmessage(event) {
     let message = event.data;
     debug("Received message: " + JSON.stringify(message));
     let value;
     switch (message.type) {
+      case "callstatechange":
       case "signalstrengthchange":
-        this.initialState.signalStrength = message.signalStrength;
-        value = message.signalStrength;
+        this.currentState.signalStrength = message.signalStrength;
         break;
       case "operatorchange":
-        this.initialState.operator = message.operator;
-        value = message.operator;
+        this.currentState.operator = message.operator;
         break;
-      case "onradiostatechange":
-        this.initialState.radioState = message.radioState;
-        value = message.radioState;
+      case "radiostatechange":
+        this.currentState.radioState = message.radioState;
         break;
       case "cardstatechange":
-        this.initialState.cardState = message.cardState;
-        value = message.cardState;
+        this.currentState.cardState = message.cardState;
         break;
       case "callstatechange":
-        this.initialState.callState = message.callState;
-        value = message.callState;
+        // Reuse the message object as the value here since there's more to
+        // the call state than just the callState integer.
+        if (message.callState == DOM_CALL_READYSTATE_DISCONNECTED) {
+          delete this.currentState.callState[message.callIndex];
+        } else {
+          this.currentState.callState[value.callIndex] = message;
+        }
         break;
       default:
         // Got some message from the RIL worker that we don't know about.
+        return;
     }
+    let methodname = "on" + message.type;
     this._callbacks.forEach(function (callback) {
       let method = callback[methodname];
       if (typeof method != "function") {
         return;
       }
-      method.call(callback, value);
+      method.call(callback, message);
     });
   },
 
-  // nsITelephonWorker
+  // nsIRadioWorker
 
   worker: null,
 
-  // nsIRadioInterface
+  // nsITelephone
 
-  initialState: null,
+  currentState: null,
 
   dial: function dial(number) {
     debug("Dialing " + number);
     this.worker.postMessage({type: "dial", number: number});
   },
 
+  hangUp: function hangUp(callIndex) {
+    debug("Hanging up call no. " + callIndex);
+    this.worker.postMessage({type: "hangUp", callIndex: callIndex});
+  },
+
+  answerCall: function answerCall() {
+    this.worker.postMessage({type: "answerCall"});
+  },
+
+  rejectCall: function rejectCall() {
+    this.worker.postMessage({type: "rejectCall"});
+  },
+
   _callbacks: null,
 
   registerCallback: function registerCallback(callback) {
     this._callbacks.push(callback);
   },
 
   unregisterCallback: function unregisterCallback(callback) {
     let index = this._callbacks.indexOf(callback);
rename from dom/telephony/worker-component/nsTelephonyWorker.manifest
rename to dom/telephony/nsTelephonyWorker.manifest
rename from dom/telephony/worker-component/ril_consts.js
rename to dom/telephony/ril_consts.js
--- a/dom/telephony/worker-component/ril_consts.js
+++ b/dom/telephony/ril_consts.js
@@ -31,29 +31,16 @@
  * 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 ***** */
 
-const CARD_MAX_APPS = 8;
-
-const RADIO_STATE_OFF = 0;
-const RADIO_STATE_UNAVAILABLE = 1;
-const RADIO_STATE_SIM_NOT_READY = 2;
-const RADIO_STATE_SIM_LOCKED_OR_ABSENT = 3;
-const RADIO_STATE_SIM_READY = 4;
-const RADIO_STATE_RUIM_NOT_READY = 5;
-const RADIO_STATE_RUIM_READY = 6;
-const RADIO_STATE_RUIM_LOCKED_OR_ABSENT = 7;
-const RADIO_STATE_NV_NOT_READY = 8;
-const RADIO_STATE_NV_READY = 9;
-
 const REQUEST_GET_SIM_STATUS = 1;
 const REQUEST_ENTER_SIM_PIN = 2;
 const REQUEST_ENTER_SIM_PUK = 3;
 const REQUEST_ENTER_SIM_PIN2 = 4;
 const REQUEST_ENTER_SIM_PUK2 = 5;
 const REQUEST_CHANGE_SIM_PIN = 6;
 const REQUEST_CHANGE_SIM_PIN2 = 7;
 const REQUEST_ENTER_NETWORK_DEPERSONALIZATION = 8;
@@ -149,16 +136,19 @@ const REQUEST_CDMA_WRITE_SMS_TO_RUIM = 9
 const REQUEST_CDMA_DELETE_SMS_ON_RUIM = 97;
 const REQUEST_DEVICE_IDENTITY = 98;
 const REQUEST_EXIT_EMERGENCY_CALLBACK_MODE = 99;
 const REQUEST_GET_SMSC_ADDRESS = 100;
 const REQUEST_SET_SMSC_ADDRESS = 101;
 const REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
 const REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
 
+const RESPONSE_TYPE_SOLICITED = 0;
+const RESPONSE_TYPE_UNSOLICITED = 1;
+
 const UNSOLICITED_RESPONSE_BASE = 1000;
 const UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED = 1000;
 const UNSOLICITED_RESPONSE_CALL_STATE_CHANGED = 1001;
 const UNSOLICITED_RESPONSE_NETWORK_STATE_CHANGED = 1002;
 const UNSOLICITED_RESPONSE_NEW_SMS = 1003;
 const UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT = 1004;
 const UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM = 1005;
 const UNSOLICITED_ON_USSD = 1006;
@@ -182,8 +172,72 @@ const UNSOLICITED_RESTRICTED_STATE_CHANG
 const UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE = 1024;
 const UNSOLICITED_CDMA_CALL_WAITING = 1025;
 const UNSOLICITED_CDMA_OTA_PROVISION_STATUS = 1026;
 const UNSOLICITED_CDMA_INFO_REC = 1027;
 const UNSOLICITED_OEM_HOOK_RAW = 1028;
 const UNSOLICITED_RINGBACK_TONE = 1029;
 const UNSOLICITED_RESEND_INCALL_MUTE = 1030;
 
+const RADIO_STATE_OFF = 0;
+const RADIO_STATE_UNAVAILABLE = 1;
+const RADIO_STATE_SIM_NOT_READY = 2;
+const RADIO_STATE_SIM_LOCKED_OR_ABSENT = 3;
+const RADIO_STATE_SIM_READY = 4;
+const RADIO_STATE_RUIM_NOT_READY = 5;
+const RADIO_STATE_RUIM_READY = 6;
+const RADIO_STATE_RUIM_LOCKED_OR_ABSENT = 7;
+const RADIO_STATE_NV_NOT_READY = 8;
+const RADIO_STATE_NV_READY = 9;
+
+const CARD_MAX_APPS = 8;
+
+const CALL_STATE_ACTIVE = 0;
+const CALL_STATE_HOLDING = 1;
+const CALL_STATE_DIALING = 2;
+const CALL_STATE_ALERTING = 3;
+const CALL_STATE_INCOMING = 4;
+const CALL_STATE_WAITING = 5;
+
+const TOA_INTERNATIONAL = 0x91;
+const TOA_UNKNOWN = 0x81;
+
+const CALL_PRESENTATION_ALLOWED = 0;
+const CALL_PRESENTATION_RESTRICTED = 1;
+const CALL_PRESENTATION_UNKNOWN = 2;
+const CALL_PRESENTATION_PAYPHONE = 3;
+
+
+/**
+ * DOM constants
+ */
+
+const DOM_RADIOSTATE_UNAVAILABLE   = "unavailable";
+const DOM_RADIOSTATE_OFF           = "off";
+const DOM_RADIOSTATE_READY         = "ready";
+
+const DOM_CARDSTATE_UNAVAILABLE    = "unavailable";
+const DOM_CARDSTATE_ABSENT         = "absent";
+const DOM_CARDSTATE_PIN_REQUIRED   = "pin_required";
+const DOM_CARDSTATE_PUK_REQUIRED   = "puk_required";
+const DOM_CARDSTATE_NETWORK_LOCKED = "network_locked";
+const DOM_CARDSTATE_NOT_READY      = "not_ready";
+const DOM_CARDSTATE_READY          = "ready";
+
+const DOM_CALL_READYSTATE_DIALING        = "dialing";
+const DOM_CALL_READYSTATE_RINGING        = "ringing";
+const DOM_CALL_READYSTATE_BUSY           = "busy";
+const DOM_CALL_READYSTATE_CONNECTING     = "connecting";
+const DOM_CALL_READYSTATE_CONNECTED      = "connected";
+const DOM_CALL_READYSTATE_DISCONNECTING  = "disconnecting";
+const DOM_CALL_READYSTATE_DISCONNECTED   = "disconnected";
+const DOM_CALL_READYSTATE_INCOMING       = "incoming";
+const DOM_CALL_READYSTATE_HOLDING        = "holding";
+const DOM_CALL_READYSTATE_HELD           = "held";
+
+const RIL_TO_DOM_CALL_STATE = [
+  DOM_CALL_READYSTATE_CONNECTED, // CALL_READYSTATE_ACTIVE
+  DOM_CALL_READYSTATE_HELD,      // CALL_READYSTATE_HOLDING
+  DOM_CALL_READYSTATE_DIALING,   // CALL_READYSTATE_DIALING
+  DOM_CALL_READYSTATE_RINGING,   // CALL_READYSTATE_ALERTING
+  DOM_CALL_READYSTATE_INCOMING,  // CALL_READYSTATE_INCOMING
+  DOM_CALL_READYSTATE_HELD       // CALL_READYSTATE_WAITING (XXX is this right?)
+];
rename from dom/telephony/worker-component/ril_worker.js
rename to dom/telephony/ril_worker.js
--- a/dom/telephony/worker-component/ril_worker.js
+++ b/dom/telephony/ril_worker.js
@@ -66,19 +66,16 @@ importScripts("ril_consts.js");
 const DEBUG = true;
 
 const INT32_MAX   = 2147483647;
 const UINT8_SIZE  = 1;
 const UINT16_SIZE = 2;
 const UINT32_SIZE = 4;
 const PARCEL_SIZE_SIZE = UINT32_SIZE;
 
-const RESPONSE_TYPE_SOLICITED = 0;
-const RESPONSE_TYPE_UNSOLICITED = 1;
-
 /**
  * This object contains helpers buffering incoming data & deconstructing it
  * into parcels as well as buffering outgoing data & constructing parcels.
  * For that it maintains two buffers and corresponding uint8 views, indexes.
  *
  * The incoming buffer is a circular buffer where we store incoming data.
  * As soon as a complete parcel is received, it is processed right away, so
  * the buffer only needs to be large enough to hold one parcel.
@@ -429,34 +426,36 @@ let Buf = {
   },
 
   /**
    * Process one parcel.
    */
 
   processParcel: function processParcel() {
     let response_type = this.readUint32();
-    let length = this.readIncoming - 2 * UINT32_SIZE;
+    let length = this.readIncoming - UINT32_SIZE;
 
     let request_type;
     if (response_type == RESPONSE_TYPE_SOLICITED) {
       let token = this.readUint32();
       let error = this.readUint32();
+      length -= 2 * UINT32_SIZE;
       request_type = this.tokenRequestMap[token];
       if (error) {
         //TODO
         debug("Received error " + error + " for solicited parcel type " +
               request_type);
         return;
       }
       debug("Solicited response for request type " + request_type +
             ", token " + token);
       delete this.tokenRequestMap[token];
     } else if (response_type == RESPONSE_TYPE_UNSOLICITED) {
       request_type = this.readUint32();
+      length -= UINT32_SIZE;
       debug("Unsolicited response for request type " + request_type);
     } else {
       debug("Unknown response type: " + response_type);
       return;
     }
 
     RIL.handleParcel(request_type, length);
   },
@@ -621,16 +620,43 @@ let RIL = {
     Buf.writeUint32(uusInfo || 0);
 	// TODO Why do we need this extra 0? It was put it in to make this
 	// match the format of the binary message.
 	Buf.writeUint32(0);
     Buf.sendParcel();
   },
 
   /**
+   * Hang up the phone.
+   *
+   * @param index
+   *        Call index (1-based) as reported by REQUEST_GET_CURRENT_CALLS.
+   */
+  hangUp: function hangUp(index) {
+    Buf.newParcel(REQUEST_HANGUP);
+    Buf.writeUint32(1);
+    Buf.writeUint32(index);
+    Buf.sendParcel();
+  },
+
+  /**
+   * Answer an incoming call.
+   */
+  answerCall: function answerCall() {
+    Buf.simpleRequest(REQUEST_ANSWER);
+  },
+
+  /**
+   * Reject an incoming call.
+   */
+  rejectCall: function rejectCall() {
+    Buf.simpleRequest(REQUEST_UDUB);
+  },
+
+  /**
    * Send an SMS.
    *
    * @param smscPDU
    *        String containing the SMSC PDU in hex format.
    * @param pdu
    *        String containing the PDU in hex format.
    */
   sendSMS: function sendSMS(smscPDU, pdu) {
@@ -693,67 +719,83 @@ RIL[REQUEST_ENTER_SIM_PIN] = function RE
   Phone.onEnterICCPIN(response);
 };
 RIL[REQUEST_ENTER_SIM_PUK] = null;
 RIL[REQUEST_ENTER_SIM_PIN2] = null;
 RIL[REQUEST_ENTER_SIM_PUK2] = null;
 RIL[REQUEST_CHANGE_SIM_PIN] = null;
 RIL[REQUEST_CHANGE_SIM_PIN2] = null;
 RIL[REQUEST_ENTER_NETWORK_DEPERSONALIZATION] = null;
-RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS() {
-  let calls = [];
-  let calls_length = Buf.readUint32();
+RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length) {
+  let calls_length = 0;
+  // The RIL won't even send us the length integer if there are no active calls.
+  // So only read this integer if the parcel actually has it.
+  if (length) {
+    calls_length = Buf.readUint32();
+  }
+  if (!calls_length) {
+    Phone.onCurrentCalls(null);
+    return;
+  }
 
+  let calls = {};
   for (let i = 0; i < calls_length; i++) {
-    let dc = {
-      state:              Buf.readUint32(), // CALLSTATE_* constants
-      index:              Buf.readUint32(),
+    let call = {
+      state:              Buf.readUint32(), // CALL_STATE_*
+      index:              Buf.readUint32(), // GSM index (1-based)
       toa:                Buf.readUint32(),
       isMpty:             Boolean(Buf.readUint32()),
       isMT:               Boolean(Buf.readUint32()),
       als:                Buf.readUint32(),
       isVoice:            Boolean(Buf.readUint32()),
       isVoicePrivacy:     Boolean(Buf.readUint32()),
       somethingOrOther:   Buf.readUint32(), //XXX TODO whatziz? not in ril.h, but it's in the output...
       number:             Buf.readString(), //TODO munge with TOA
-      numberPresentation: Buf.readUint32(), // Connection.PRESENTATION XXX TODO
+      numberPresentation: Buf.readUint32(), // CALL_PRESENTATION_*
       name:               Buf.readString(),
       namePresentation:   Buf.readUint32(),
       uusInfo:            null
     };
     let uusInfoPresent = Buf.readUint32();
     if (uusInfoPresent == 1) {
-      dc.uusInfo = {
+      call.uusInfo = {
         type:     Buf.readUint32(),
         dcs:      Buf.readUint32(),
         userData: null //XXX TODO byte array?!?
       };
     }
-    calls.push(dc);
+    calls[call.index] = call;
   }
-
   Phone.onCurrentCalls(calls);
 };
-RIL[REQUEST_DIAL] = null;
+RIL[REQUEST_DIAL] = function REQUEST_DIAL(length) {
+  Phone.onDial();
+};
 RIL[REQUEST_GET_IMSI] = function REQUEST_GET_IMSI(length) {
-  let imsi = Buf.readString(length);
+  let imsi = Buf.readString();
   Phone.onIMSI(imsi);
 };
-RIL[REQUEST_HANGUP] = null;
+RIL[REQUEST_HANGUP] = function REQUEST_HANGUP(length) {
+  Phone.onHangUp();
+};
 RIL[REQUEST_HANGUP_WAITING_OR_BACKGROUND] = null;
 RIL[REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = null;
 RIL[REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = null;
 RIL[REQUEST_SWITCH_HOLDING_AND_ACTIVE] = null;
 RIL[REQUEST_CONFERENCE] = null;
-RIL[REQUEST_UDUB] = null;
+RIL[REQUEST_UDUB] = function REQUEST_UDUB(length) {
+  Phone.onRejectCall();
+};
 RIL[REQUEST_LAST_CALL_FAIL_CAUSE] = null;
 RIL[REQUEST_SIGNAL_STRENGTH] = function REQUEST_SIGNAL_STRENGTH() {
   let strength = {
     // Valid values are (0-31, 99) as defined in TS 27.007 8.5.
-    gsmSignalStrength: Buf.readUint32(),
+    // For some reason we're getting int32s like [99, 4, 0, 0] and [99, 3, 0, 0]
+    // here, so let's strip of anything beyond the first byte.
+    gsmSignalStrength: Buf.readUint32() & 0xff,
     // GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5.
     gsmBitErrorRate:   Buf.readUint32(),
     // The CDMA RSSI value.
     cdmaDBM:           Buf.readUint32(),
     // The CDMA EC/IO.
     cdmaECIO:          Buf.readUint32(),
     // The EVDO RSSI value.
     evdoDBM:           Buf.readUint32(),
@@ -799,17 +841,19 @@ RIL[REQUEST_SMS_ACKNOWLEDGE] = null;
 RIL[REQUEST_GET_IMEI] = function REQUEST_GET_IMEI() {
   let imei = Buf.readString();
   Phone.onIMEI(imei);
 };
 RIL[REQUEST_GET_IMEISV] = function REQUEST_GET_IMEISV() {
   let imeiSV = Buf.readString();
   Phone.onIMEISV(imeiSV);
 };
-RIL[REQUEST_ANSWER] = null;
+RIL[REQUEST_ANSWER] = function REQUEST_ANSWER(length) {
+  Phone.onAnswerCall();
+};
 RIL[REQUEST_DEACTIVATE_DATA_CALL] = null;
 RIL[REQUEST_QUERY_FACILITY_LOCK] = null;
 RIL[REQUEST_SET_FACILITY_LOCK] = null;
 RIL[REQUEST_CHANGE_BARRING_PASSWORD] = null;
 RIL[REQUEST_QUERY_NETWORK_SELECTION_MODE] = function REQUEST_QUERY_NETWORK_SELECTION_MODE() {
   let response = Buf.readUint32List();
   Phone.onNetworkSelectionMode(response);
 };
@@ -896,17 +940,25 @@ RIL[UNSOLICITED_SIGNAL_STRENGTH] = funct
 RIL[UNSOLICITED_DATA_CALL_LIST_CHANGED] = null;
 RIL[UNSOLICITED_SUPP_SVC_NOTIFICATION] = null;
 RIL[UNSOLICITED_STK_SESSION_END] = null;
 RIL[UNSOLICITED_STK_PROACTIVE_COMMAND] = null;
 RIL[UNSOLICITED_STK_EVENT_NOTIFY] = null;
 RIL[UNSOLICITED_STK_CALL_SETUP] = null;
 RIL[UNSOLICITED_SIM_SMS_STORAGE_FULL] = null;
 RIL[UNSOLICITED_SIM_REFRESH] = null;
-RIL[UNSOLICITED_CALL_RING] = null;
+RIL[UNSOLICITED_CALL_RING] = function UNSOLICITED_CALL_RING() {
+  let info = {
+    isPresent:  Buf.readUint32(),
+    signalType: Buf.readUint32(),
+    alertPitch: Buf.readUint32(),
+    signal:     Buf.readUint32()
+  };
+  Phone.onCallRing(info);
+};
 RIL[UNSOLICITED_RESPONSE_SIM_STATUS_CHANGED] = null;
 RIL[UNSOLICITED_RESPONSE_CDMA_NEW_SMS] = null;
 RIL[UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS] = null;
 RIL[UNSOLICITED_CDMA_RUIM_SMS_STORAGE_FULL] = null;
 RIL[UNSOLICITED_RESTRICTED_STATE_CHANGED] = null;
 RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE] = null;
 RIL[UNSOLICITED_CDMA_CALL_WAITING] = null;
 RIL[UNSOLICITED_CDMA_OTA_PROVISION_STATUS] = null;
@@ -956,17 +1008,17 @@ let Phone = {
   /**
    * ICC card status
    */
   iccStatus: null,
 
   /**
    * Active calls
    */
-  calls: null,
+  currentCalls: {},
 
   /**
    * Handlers for messages from the RIL. They all begin with on* and are called
    * from RIL object.
    */
 
   onRadioStateChanged: function onRadioStateChanged(newState) {
     debug("Radio state changed from " + this.radioState + " to " + newState);
@@ -996,78 +1048,131 @@ let Phone = {
       }
       if (cdma) {
         RIL.getDeviceIdentity();
       }
       Buf.simpleRequest(REQUEST_BASEBAND_VERSION);
       RIL.setScreenState(true);
       this.sendDOMMessage({
         type: "radiostatechange",
-        radioState: (newState == RADIO_STATE_OFF) ? "off" : "ready"
+        radioState: (newState == RADIO_STATE_OFF) ?
+                     DOM_RADIOSTATE_OFF : DOM_RADIOSTATE_READY
       });
 
       //XXX TODO For now, just turn the radio on if it's off. for the real
       // deal we probably want to do the opposite: start with a known state
       // when we boot up and let the UI layer control the radio power.
       if (newState == RADIO_STATE_OFF) {
         RIL.setRadioPower(true);
       }
     }
 
     if (newState == RADIO_STATE_UNAVAILABLE) {
       // The radio is no longer available, we need to deal with any
       // remaining pending requests.
       //TODO do that
 
       this.sendDOMMessage({type: "radiostatechange",
-                           radioState: "unavailable"});
+                           radioState: DOM_RADIOSTATE_UNAVAILABLE});
     }
 
     if (newState == RADIO_STATE_SIM_READY  ||
         newState == RADIO_STATE_RUIM_READY ||
         newState == RADIO_STATE_NV_READY) {
       // The ICC card has become available. Get all the things.
       RIL.getICCStatus();
       this.requestNetworkInfo();
       RIL.getSignalStrength();
       this.sendDOMMessage({type: "cardstatechange",
-                           cardState: "ready"});
+                           cardState: DOM_CARDSTATE_READY});
     }
     if (newState == RADIO_STATE_SIM_LOCKED_OR_ABSENT  ||
         newState == RADIO_STATE_RUIM_LOCKED_OR_ABSENT) {
       RIL.getICCStatus();
       this.sendDOMMessage({type: "cardstatechange",
-                           cardState: "unavailable"});
+                           cardState: DOM_CARDSTATE_UNAVAILABLE});
     }
 
     let wasOn = this.radioState != RADIO_STATE_OFF &&
                 this.radioState != RADIO_STATE_UNAVAILABLE;
     let isOn = newState != RADIO_STATE_OFF &&
                newState != RADIO_STATE_UNAVAILABLE;
     if (!wasOn && isOn) {
       //TODO
     }
     if (wasOn && !isOn) {
       //TODO
     }
 
     this.radioState = newState;
   },
 
-  onCurrentCalls: function onCurrentCalls(calls) {
-    debug("onCurrentCalls");
-    debug(calls);
-    //TODO 
-    this.sendDOMMessage({type: "callstatechange", callState: calls});
+  onCurrentCalls: function onCurrentCalls(newCalls) {
+    // Go through the calls we currently have on file and see if any of them
+    // changed state. Remove them from the newCalls map as we deal with them
+    // so that only new calls remain in the map after we're done.
+    for each (let currentCall in this.currentCalls) {
+      let callIndex = currentCall.index;
+      let newCall;
+      if (newCalls) {
+        newCall = newCalls[callIndex];
+        delete newCalls[callIndex];
+      }
+
+      if (!newCall) {
+        // Call is no longer reported by the radio. Send disconnected
+        // state change.
+        this.sendDOMMessage({type:      "callstatechange",
+                             callState:  DOM_CALL_READYSTATE_DISCONNECTED,
+                             callIndex:  callIndex,
+                             number:     currentCall.number,
+                             name:       currentCall.name});
+        delete this.currentCalls[currentCall];
+        continue;
+      }
+
+      if (newCall.state == currentCall.state) {
+        continue;
+      }
+
+      this._handleChangedCallState(newCall);
+    }
+
+    // Go through any remaining calls that are new to us.
+    for each (let newCall in newCalls) {
+      if (newCall.isVoice) {
+        this._handleChangedCallState(newCall);
+      }
+    }
+  },
+
+  _handleChangedCallState: function handleChangedCallState(newCall) {
+    // Format international numbers appropriately.
+    if (newCall.number &&
+        newCall.toa == TOA_INTERNATIONAL &&
+        newCall.number[0] != "+") {
+      newCall.number = "+" + newCall.number;
+    }
+    this.currentCalls[newCall.index] = newCall;
+    this.sendDOMMessage({type:      "callstatechange",
+                         callState: RIL_TO_DOM_CALL_STATE[newCall.state],
+                         callIndex: newCall.index,
+                         number:    newCall.number,
+                         name:      newCall.name});
   },
 
   onCallStateChanged: function onCallStateChanged() {
     RIL.getCurrentCalls();
   },
 
+  onCallRing: function onCallRing(info) {
+    debug("onCallRing " + JSON.stringify(info)); //DEBUG
+    RIL.getCurrentCalls();
+  },
+
   onNetworkStateChanged: function onNetworkStateChanged() {
     debug("Network state changed, re-requesting phone state.");
     this.requestNetworkInfo();
   },
 
   onICCStatus: function onICCStatus(iccStatus) {
     debug("SIM card state is " + iccStatus.cardState);
     debug("Universal PIN state is " + iccStatus.universalPINState);
@@ -1126,16 +1231,28 @@ let Phone = {
   },
 
   onSignalStrength: function onSignalStrength(strength) {
     debug("Signal strength " + JSON.stringify(strength));
     this.sendDOMMessage({type: "signalstrengthchange",
                          signalStrength: strength});
   },
 
+  onDial: function onDial() {
+  },
+
+  onHangUp: function onHangUp() {
+  },
+
+  onAnswerCall: function onAnswerCall() {
+  },
+
+  onRejectCall: function onRejectCall() {
+  },
+
   onSendSMS: function onSendSMS(messageRef, ackPDU, errorCode) {
     //TODO
   },
 
 
   /**
    * Outgoing requests to the RIL. These can be triggered from the
    * main thread via messages that look like this:
@@ -1166,16 +1283,42 @@ let Phone = {
    * @param number
    *        String containing the number to dial.
    */
   dial: function dial(options) {
     RIL.dial(options.number, 0, 0);
   },
 
   /**
+   * Hang up a call.
+   *
+   * @param callIndex
+   *        Call index of the call to hang up.
+   */
+  hangUp: function hangUp(options) {
+    //TODO need to check whether call is holding/waiting/background
+    // and then use REQUEST_HANGUP_WAITING_OR_BACKGROUND
+    RIL.hangUp(options.callIndex);
+  },
+
+  /**
+   * Answer an incoming call.
+   */
+  answerCall: function answerCall() {
+    RIL.answerCall();
+  },
+
+  /**
+   * Reject an incoming call.
+   */
+  rejectCall: function rejectCall() {
+    RIL.rejectCall();
+  },
+
+  /**
    * Send an SMS.
    *
    * @param number
    *        String containing the recipient number.
    * @param message
    *        String containing the message text.
    */
   sendSMS: function sendSMS(options) {
deleted file mode 100644
--- a/dom/telephony/worker-component/nsITelephonyWorker.idl
+++ /dev/null
@@ -1,51 +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 Telephony.
- *
- * The Initial Developer of the Original Code is
- *   The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Ben Turner <bent.mozilla@gmail.com> (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 ***** */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(8f031451-ac25-4816-a09e-a075bb704e63)]
-interface nsITelephonyWorker : nsISupports {
-    readonly attribute jsval worker;
-};
-
-%{ C++
-
-#define NS_TELEPHONYWORKER_CID \
-    { 0x2d831c8d, 0x6017, 0x435b, \
-      { 0xa8, 0x0c, 0xe5, 0xd4, 0x22, 0x81, 0x0c, 0xea } }
-
-%}
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -279,16 +279,17 @@ GLContextCGL::ResizeOffscreen(const gfxI
                                    textureMaxMipMapLevel:0
                                    pixelsWide:aNewSize.width
                                    pixelsHigh:aNewSize.height];
         if (!pb) {
             return false;
         }
 
         if (!ResizeOffscreenFBO(aNewSize, false)) {
+            [pb release];
             return false;
         }
 
         [mPBuffer release];
         mPBuffer = pb;
 
         mOffscreenSize = aNewSize;
         mOffscreenActualSize = aNewSize;
--- a/ipc/Makefile.in
+++ b/ipc/Makefile.in
@@ -38,11 +38,15 @@ DEPTH = ..
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 DIRS += chromium glue ipdl testshell
 
+ifdef MOZ_B2G_RIL #{
+DIRS += ril
+endif #}
+
 TOOL_DIRS = app
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/ipc/ril/Makefile.in
@@ -0,0 +1,65 @@
+# ***** 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 IPC.
+#
+# The Initial Developer of the Original Code is
+#   The Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Chris Jones <jones.chris.g@gmail.com>
+#   Kyle Machulis <kyle@nonpolynomial.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 = ipc
+LIBRARY_NAME = mozril_s
+FORCE_STATIC_LIB = 1
+LIBXUL_LIBRARY = 1
+EXPORT_LIBRARY = 1
+
+EXPORTS_NAMESPACES = mozilla/ipc
+
+EXPORTS_mozilla/ipc = \
+  Ril.h \
+  $(NULL)
+
+CPPSRCS += \
+  Ril.cpp \
+  $(NULL)
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/ipc/ril/Ril.cpp
@@ -0,0 +1,359 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=8 et ft=cpp: */
+/* ***** 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 Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *   Kyle Machulis <kyle@nonpolynomial.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 <fcntl.h>
+#include <unistd.h>
+
+#include <queue>
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/select.h>
+#include <sys/types.h>
+
+#include "base/eintr_wrapper.h"
+#include "base/message_loop.h"
+#include "mozilla/FileUtils.h"
+#include "mozilla/Monitor.h"
+#include "mozilla/Util.h"
+#include "nsAutoPtr.h"
+#include "nsIThread.h"
+#include "nsXULAppAPI.h"
+#include "Ril.h"
+
+#if defined(MOZ_WIDGET_GONK)
+#include <android/log.h>
+#define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
+#else
+#define LOG(args...)  printf(args);
+#endif
+
+using namespace base;
+using namespace std;
+
+namespace mozilla {
+namespace ipc {
+
+struct RilClient : public RefCounted<RilClient>,
+                   public MessageLoopForIO::Watcher
+
+{
+    typedef queue<RilRawData*> RilRawDataQueue;
+
+    RilClient() : mSocket(-1)
+                , mMutex("RilClient.mMutex")
+                , mBlockedOnWrite(false)
+                , mCurrentRilRawData(NULL)
+    { }
+    virtual ~RilClient() { }
+
+    bool OpenSocket();
+
+    virtual void OnFileCanReadWithoutBlocking(int fd);
+    virtual void OnFileCanWriteWithoutBlocking(int fd);
+
+    ScopedClose mSocket;
+    MessageLoopForIO::FileDescriptorWatcher mReadWatcher;
+    MessageLoopForIO::FileDescriptorWatcher mWriteWatcher;
+    nsAutoPtr<RilRawData> mIncoming;
+    Mutex mMutex;
+    RilRawDataQueue mOutgoingQ;
+    bool mBlockedOnWrite;
+    MessageLoopForIO* mIOLoop;
+    nsAutoPtr<RilRawData> mCurrentRilRawData;
+    size_t mCurrentWriteOffset;
+};
+
+static RefPtr<RilClient> sClient;
+static RefPtr<RilConsumer> sConsumer;
+
+//-----------------------------------------------------------------------------
+// This code runs on the IO thread.
+//
+
+class RilWriteTask : public Task {
+    virtual void Run();
+};
+
+void RilWriteTask::Run() {
+    sClient->OnFileCanWriteWithoutBlocking(sClient->mSocket.mFd);
+}
+
+static void
+ConnectToRil(Monitor* aMonitor, bool* aSuccess)
+{
+    MOZ_ASSERT(!sClient);
+
+    sClient = new RilClient();
+    if (!(*aSuccess = sClient->OpenSocket())) {
+        sClient = nsnull;
+    }
+
+    {
+        MonitorAutoLock lock(*aMonitor);
+        lock.Notify();
+    }
+    // aMonitor may have gone out of scope by now, don't touch it
+}
+
+bool
+RilClient::OpenSocket()
+{
+#if defined(MOZ_WIDGET_GONK)
+    // Using a network socket to test basic functionality
+    // before we see how this works on the phone.
+    struct sockaddr_un addr;
+    socklen_t alen;
+    size_t namelen;
+    int err;
+    memset(&addr, 0, sizeof(addr));
+    strcpy(addr.sun_path, "/dev/socket/rilb2g");
+    addr.sun_family = AF_LOCAL;
+    mSocket.mFd = socket(AF_LOCAL, SOCK_STREAM, 0);
+    alen = strlen("/dev/socket/rilb2g") + offsetof(struct sockaddr_un, sun_path) + 1;
+#else
+    struct hostent *hp;
+    struct sockaddr_in addr;
+    socklen_t alen;
+
+    hp = gethostbyname("localhost");
+    if (hp == 0) return -1;
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family = hp->h_addrtype;
+    addr.sin_port = htons(6200);
+    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+    mSocket.mFd = socket(hp->h_addrtype, SOCK_STREAM, 0);
+    alen = sizeof(addr);
+#endif
+
+    if (mSocket.mFd < 0) {
+        LOG("Cannot create socket for RIL!\n");
+        return -1;
+    }
+
+    if (connect(mSocket.mFd, (struct sockaddr *) &addr, alen) < 0) {
+        LOG("Cannot open socket for RIL!\n");
+        close(mSocket.mFd);
+        return false;
+    }
+    LOG("Socket open for RIL\n");
+
+    // Set close-on-exec bit.
+    int flags = fcntl(mSocket.mFd, F_GETFD);
+    if (-1 == flags) {
+        return false;
+    }
+
+    flags |= FD_CLOEXEC;
+    if (-1 == fcntl(mSocket.mFd, F_SETFD, flags)) {
+        return false;
+    }
+
+    // Select non-blocking IO.
+    if (-1 == fcntl(mSocket.mFd, F_SETFL, O_NONBLOCK)) {
+        return false;
+    }
+    mIOLoop = MessageLoopForIO::current();
+    if (!mIOLoop->WatchFileDescriptor(mSocket.mFd,
+                                      true,
+                                      MessageLoopForIO::WATCH_READ,
+                                      &mReadWatcher,
+                                      this)) {
+        return false;
+    }
+    return true;
+}
+
+void
+RilClient::OnFileCanReadWithoutBlocking(int fd)
+{
+    // Keep reading data until either
+    //
+    //   - mIncoming is completely read
+    //     If so, sConsumer->MessageReceived(mIncoming.forget())
+    //
+    //   - mIncoming isn't completely read, but there's no more
+    //     data available on the socket
+    //     If so, break;
+
+    MOZ_ASSERT(fd == mSocket.mFd);
+    while (true) {
+        if (!mIncoming) {
+            mIncoming = new RilRawData();
+            int ret = read(fd, mIncoming->mData, 1024);
+            if (ret <= 0) {
+                LOG("Cannot read from network, error %d\n", ret);
+                return;
+            }
+            mIncoming->mSize = ret;
+            sConsumer->MessageReceived(mIncoming.forget());
+            if (ret < 1024) {
+                return;
+            }
+        }
+    }
+}
+
+void
+RilClient::OnFileCanWriteWithoutBlocking(int fd)
+{
+    // Try to write the bytes of mCurrentRilRawData.  If all were written, continue.
+    //
+    // Otherwise, save the byte position of the next byte to write
+    // within mCurrentRilRawData, and request another write when the
+    // system won't block.
+    //
+
+    MOZ_ASSERT(fd == mSocket.mFd);
+
+    while (!mOutgoingQ.empty() || mCurrentRilRawData != NULL) {
+        if(!mCurrentRilRawData) {
+            mCurrentRilRawData = mOutgoingQ.front();
+            mOutgoingQ.pop();
+            mCurrentWriteOffset = 0;
+        }
+        const uint8_t *toWrite;
+
+        toWrite = mCurrentRilRawData->mData;
+ 
+        while (mCurrentWriteOffset < mCurrentRilRawData->mSize) {
+            ssize_t write_amount = mCurrentRilRawData->mSize - mCurrentWriteOffset;
+            ssize_t written;
+            written = write (fd, toWrite + mCurrentWriteOffset,
+                             write_amount);
+            if(written > 0) {
+                mCurrentWriteOffset += written;
+            }
+            if (written != write_amount) {
+                break;
+            }
+        }
+
+        if(mCurrentWriteOffset != mCurrentRilRawData->mSize) {
+            MessageLoopForIO::current()->WatchFileDescriptor(
+                fd,
+                false,
+                MessageLoopForIO::WATCH_WRITE,
+                &mWriteWatcher,
+                this);
+            return;
+        }
+        mCurrentRilRawData = NULL;
+    }
+}
+
+
+static void
+DisconnectFromRil(Monitor* aMonitor)
+{
+    // XXX This might "strand" messages in the outgoing queue.  We'll
+    // assume that's OK for now.
+    sClient = nsnull;
+    {
+        MonitorAutoLock lock(*aMonitor);
+        lock.Notify();
+    }
+}
+
+//-----------------------------------------------------------------------------
+// This code runs on any thread.
+//
+
+bool
+StartRil(RilConsumer* aConsumer)
+{
+    MOZ_ASSERT(aConsumer);
+    sConsumer = aConsumer;
+
+    Monitor monitor("StartRil.monitor");
+    bool success;
+    {
+        MonitorAutoLock lock(monitor);
+
+        XRE_GetIOMessageLoop()->PostTask(
+            FROM_HERE,
+            NewRunnableFunction(ConnectToRil, &monitor, &success));
+
+        lock.Wait();
+    }
+
+    return success;
+}
+
+bool
+SendRilRawData(RilRawData** aMessage)
+{
+    if (!sClient) {
+        return false;
+    }
+
+    RilRawData *msg = *aMessage;
+    *aMessage = nsnull;
+
+    {
+        MutexAutoLock lock(sClient->mMutex);
+        sClient->mOutgoingQ.push(msg);
+    }
+    sClient->mIOLoop->PostTask(FROM_HERE, new RilWriteTask());
+
+    return true;
+}
+
+void
+StopRil()
+{
+    Monitor monitor("StopRil.monitor");
+    {
+        MonitorAutoLock lock(monitor);
+
+        XRE_GetIOMessageLoop()->PostTask(
+            FROM_HERE,
+            NewRunnableFunction(DisconnectFromRil, &monitor));
+
+        lock.Wait();
+    }
+
+    sConsumer = nsnull;
+}
+
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/ril/Ril.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp: */
+/* ***** 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 Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *   Kyle Machulis <kyle@nonpolynomial.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 ***** */
+
+#ifndef mozilla_ipc_Ril_h
+#define mozilla_ipc_Ril_h 1
+
+#include "mozilla/RefPtr.h"
+
+namespace base {
+class MessageLoop;
+}
+
+class nsIThread;
+
+namespace mozilla {
+namespace ipc {
+
+
+/*
+ * Represents raw data going to or coming from the RIL socket. Can
+ * actually contain multiple RIL parcels in the data block, and may
+ * also contain incomplete parcels on the front or back. Actual parcel
+ * construction is handled in the worker thread.
+ */
+struct RilRawData
+{
+    static const size_t MAX_DATA_SIZE = 1024;
+    uint8_t mData[MAX_DATA_SIZE];
+
+    // Number of octets in mData.
+    size_t mSize;
+};
+
+class RilConsumer : public RefCounted<RilConsumer>
+{
+public:
+    virtual ~RilConsumer() { }
+    virtual void MessageReceived(RilRawData* aMessage) { }
+};
+
+bool StartRil(RilConsumer* aConsumer);
+
+bool SendRilRawData(RilRawData** aMessage);
+
+void StopRil();
+
+} // namespace ipc
+} // namepsace mozilla
+
+#endif // mozilla_ipc_Ril_h
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -251,27 +251,27 @@ CompileRegExpObject(JSContext *cx, RegEx
         return true;
     }
 
     JSLinearString *sourceStr;
     if (sourceValue.isUndefined()) {
         sourceStr = cx->runtime->emptyString;
     } else {
         /* Coerce to string and compile. */
-        JSString *str = js_ValueToString(cx, sourceValue);
+        JSString *str = ToString(cx, sourceValue);
         if (!str)
             return false;
         sourceStr = str->ensureLinear(cx);
         if (!sourceStr)
             return false;
     }
 
     RegExpFlag flags = RegExpFlag(0);
     if (argc > 1 && !argv[1].isUndefined()) {
-        JSString *flagStr = js_ValueToString(cx, argv[1]);
+        JSString *flagStr = ToString(cx, argv[1]);
         if (!flagStr)
             return false;
         argv[1].setString(flagStr);
         if (!ParseRegExpFlags(cx, flagStr, &flags))
             return false;
     }
 
     JSLinearString *escapedSourceStr = EscapeNakedForwardSlashes(cx, sourceStr);
@@ -523,17 +523,17 @@ ExecuteRegExp(JSContext *cx, Native nati
     } else {
         if (!matcher.reset(reobj))
             return false;
     }
 
     RegExpStatics *res = cx->regExpStatics();
 
     /* Step 2. */
-    JSString *input = js_ValueToString(cx, (args.length() > 0) ? args[0] : UndefinedValue());
+    JSString *input = ToString(cx, (args.length() > 0) ? args[0] : UndefinedValue());
     if (!input)<