Merge latest green mozilla-central to services-central.
authorNick Alexander <nalexander@mozilla.com>
Tue, 16 Jul 2013 08:31:31 -0700
changeset 138617 5f79304fcefe891a964f2d03212db895a405ba13
parent 138616 4e0a9e8a698c760a5cc1de3a711d695e497508f1 (current diff)
parent 138615 60e5fd5a379caaf2cb6dd42e701cc98a78797ded (diff)
child 138700 457c3ad5254ec17de0af109b856c89b529989923
child 138841 45c529ffbe90a63266ff67e0c746f54a2378d66a
push id24963
push usernalexander@mozilla.com
push dateTue, 16 Jul 2013 15:32:24 +0000
treeherdermozilla-central@5f79304fcefe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge latest green mozilla-central to services-central.
browser/metro/base/content/bindings/autocomplete.xml
build/stlport/stl/config/_android.h.in
mobile/android/base/resources/layout/awesomebar_suggestion_item.xml
mobile/android/base/resources/layout/awesomebar_suggestion_row.xml
--- a/CLOBBER
+++ b/CLOBBER
@@ -12,9 +12,9 @@
 #          O               O
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
-Bug 870407 - move CMMSRCS to mozbuild
+Bug 870180 - CPOWs
--- a/accessible/src/base/nsAccessiblePivot.cpp
+++ b/accessible/src/base/nsAccessiblePivot.cpp
@@ -411,37 +411,60 @@ nsAccessiblePivot::MovePivotInternal(Acc
   mPosition = aPosition;
   int32_t oldStart = mStartOffset, oldEnd = mEndOffset;
   mStartOffset = mEndOffset = -1;
 
   return NotifyOfPivotChange(oldPosition, oldStart, oldEnd, aReason);
 }
 
 Accessible*
+nsAccessiblePivot::AdjustStartPosition(Accessible* aAccessible,
+                                       RuleCache& aCache,
+                                       uint16_t* aFilterResult,
+                                       nsresult* aResult)
+{
+  Accessible* matched = aAccessible;
+  *aResult = aCache.ApplyFilter(aAccessible, aFilterResult);
+
+  if (aAccessible != mRoot && aAccessible != mModalRoot) {
+    for (Accessible* temp = aAccessible->Parent();
+         temp && temp != mRoot && temp != mModalRoot; temp = temp->Parent()) {
+      uint16_t filtered = nsIAccessibleTraversalRule::FILTER_IGNORE;
+      *aResult = aCache.ApplyFilter(temp, &filtered);
+      NS_ENSURE_SUCCESS(*aResult, nullptr);
+      if (filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE) {
+        *aFilterResult = filtered;
+        matched = temp;
+      }
+    }
+  }
+
+  return matched;
+}
+
+Accessible*
 nsAccessiblePivot::SearchBackward(Accessible* aAccessible,
                                   nsIAccessibleTraversalRule* aRule,
                                   bool aSearchCurrent,
                                   nsresult* aResult)
 {
   *aResult = NS_OK;
 
   // Initial position could be unset, in that case return null.
   if (!aAccessible)
     return nullptr;
 
   RuleCache cache(aRule);
-  Accessible* accessible = aAccessible;
-
   uint16_t filtered = nsIAccessibleTraversalRule::FILTER_IGNORE;
+  Accessible* accessible = AdjustStartPosition(aAccessible, cache,
+                                               &filtered, aResult);
+  NS_ENSURE_SUCCESS(*aResult, nullptr);
 
-  if (aSearchCurrent) {
-    *aResult = cache.ApplyFilter(accessible, &filtered);
-    NS_ENSURE_SUCCESS(*aResult, nullptr);
-    if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
-      return accessible;
+  if (aSearchCurrent && (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)) {
+    return accessible;
   }
 
   Accessible* root = GetActiveRoot();
   while (accessible != root) {
     Accessible* parent = accessible->Parent();
     int32_t idxInParent = accessible->IndexInParent();
     while (idxInParent > 0) {
       if (!(accessible = parent->GetChildAt(--idxInParent)))
@@ -487,17 +510,17 @@ nsAccessiblePivot::SearchForward(Accessi
 
   // Initial position could be not set, in that case begin search from root.
   Accessible* root = GetActiveRoot();
   Accessible* accessible = (!aAccessible) ? root : aAccessible;
 
   RuleCache cache(aRule);
 
   uint16_t filtered = nsIAccessibleTraversalRule::FILTER_IGNORE;
-  *aResult = cache.ApplyFilter(accessible, &filtered);
+  accessible = AdjustStartPosition(accessible, cache, &filtered, aResult);
   NS_ENSURE_SUCCESS(*aResult, nullptr);
   if (aSearchCurrent && (filtered & nsIAccessibleTraversalRule::FILTER_MATCH))
     return accessible;
 
   while (true) {
     Accessible* firstChild = nullptr;
     while (!(filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE) &&
            (firstChild = accessible->FirstChild())) {
--- a/accessible/src/base/nsAccessiblePivot.h
+++ b/accessible/src/base/nsAccessiblePivot.h
@@ -11,16 +11,17 @@
 
 #include "Accessible-inl.h"
 #include "nsAutoPtr.h"
 #include "nsTObserverArray.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Attributes.h"
 
 class nsIAccessibleTraversalRule;
+class RuleCache;
 
 /**
  * Class represents an accessible pivot.
  */
 class nsAccessiblePivot MOZ_FINAL : public nsIAccessiblePivot
 {
 public:
   typedef mozilla::a11y::Accessible Accessible;
@@ -86,16 +87,28 @@ private:
   }
 
   /*
    * Update the pivot, and notify observers. Return true if it moved.
    */
   bool MovePivotInternal(Accessible* aPosition, PivotMoveReason aReason);
 
   /*
+   * Get initial node we should start a search from with a given rule.
+   *
+   * When we do a move operation from one position to another,
+   * the initial position can be inside of a subtree that is ignored by
+   * the given rule. We need to step out of the ignored subtree and start
+   * the search from there.
+   *
+   */
+  Accessible* AdjustStartPosition(Accessible* aAccessible, RuleCache& aCache,
+                                  uint16_t* aFilterResult, nsresult* aResult);
+
+  /*
    * The root accessible.
    */
   nsRefPtr<Accessible> mRoot;
 
   /*
    * The temporary modal root accessible.
    */
   nsRefPtr<Accessible> mModalRoot;
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -1125,17 +1125,19 @@ HyperTextAccessible::GetTextAtOffset(int
       if (IsEmptyLastLineOffset(offset)) {
         *aStartOffset = *aEndOffset = offset;
         return NS_OK;
       }
 
       if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
         offset = AdjustCaretOffset(offset);
 
-      // Home key, arrow down and if not on last line then home key.
+      // Start offset is begin of the current line (as the home key was
+      // pressed). End offset is begin of the next line if any (arrow down and
+      // home keys), otherwise end of the current line (arrow down only).
       *aStartOffset = FindLineBoundary(offset, eDirPrevious, eSelectBeginLine);
       *aEndOffset = FindLineBoundary(offset, eDirNext, eSelectLine);
       int32_t tmpOffset = FindLineBoundary(*aEndOffset, eDirPrevious, eSelectBeginLine);
       if (tmpOffset != *aStartOffset)
         *aEndOffset = tmpOffset;
 
       return GetText(*aStartOffset, *aEndOffset, aText);
     }
@@ -1149,18 +1151,20 @@ HyperTextAccessible::GetTextAtOffset(int
         *aEndOffset = offset;
         aText.AssignLiteral("\n");
         return NS_OK;
       }
 
       if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
         offset = AdjustCaretOffset(offset);
 
-      // In contrast to word end boundary we follow the spec here. End key,
-      // then up arrow and if not on first line then end key.
+      // In contrast to word end boundary we follow the spec here.
+      // End offset is end of the current line (as the end key was pressed).
+      // Start offset is end of the previous line if any (up arrow and end keys),
+      // otherwise 0 offset (up arrow only).
       *aEndOffset = FindLineBoundary(offset, eDirNext, eSelectEndLine);
       int32_t tmpOffset = FindLineBoundary(offset, eDirPrevious, eSelectLine);
       *aStartOffset = FindLineBoundary(tmpOffset, eDirNext, eSelectEndLine);
       if (*aStartOffset == *aEndOffset)
         *aStartOffset = 0;
 
       return GetText(*aStartOffset, *aEndOffset, aText);
     }
@@ -1211,17 +1215,51 @@ HyperTextAccessible::GetTextAfterOffset(
         if (*aStartOffset != offset) {
           *aStartOffset = *aEndOffset;
           *aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eEndWord);
         }
       }
       return GetText(*aStartOffset, *aEndOffset, aText);
 
     case BOUNDARY_LINE_START:
+      if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
+        offset = AdjustCaretOffset(offset);
+
+      // Down arrow, home key, down arrow, home key.
+      *aStartOffset = FindLineBoundary(offset, eDirNext, eSelectLine);
+      if (*aStartOffset != CharacterCount()) {
+        *aStartOffset = FindLineBoundary(*aStartOffset, eDirPrevious, eSelectBeginLine);
+        *aEndOffset = FindLineBoundary(*aStartOffset, eDirNext, eSelectLine);
+        if (*aEndOffset != CharacterCount())
+          *aEndOffset = FindLineBoundary(*aEndOffset, eDirPrevious, eSelectBeginLine);
+      } else {
+        *aEndOffset = CharacterCount();
+      }
+      return GetText(*aStartOffset, *aEndOffset, aText);
+
     case BOUNDARY_LINE_END:
+      if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
+        offset = AdjustCaretOffset(offset);
+
+      // Empty last line doesn't have own frame (a previous line contains '\n'
+      // character instead) thus we can't operate on last line separately
+      // from the previous line.
+      if (IsEmptyLastLineOffset(offset)) {
+        *aStartOffset = *aEndOffset = offset;
+        return NS_OK;
+      }
+
+      // End key, down arrow, end key.
+      *aStartOffset = FindLineBoundary(offset, eDirNext, eSelectEndLine);
+      *aEndOffset = FindLineBoundary(*aStartOffset, eDirNext, eSelectLine);
+      if (*aEndOffset != CharacterCount())
+        *aEndOffset = FindLineBoundary(*aEndOffset, eDirNext, eSelectEndLine);
+
+      return GetText(*aStartOffset, *aEndOffset, aText);
+
     case BOUNDARY_ATTRIBUTE_RANGE:
       return GetTextHelper(eGetAfter, aBoundaryType, aOffset,
                            aStartOffset, aEndOffset, aText);
 
     default:
       return NS_ERROR_INVALID_ARG;
   }
 }
--- a/accessible/src/jsat/OutputGenerator.jsm
+++ b/accessible/src/jsat/OutputGenerator.jsm
@@ -574,17 +574,17 @@ this.UtteranceGenerator = {
   },
 
   _getListUtterance: function _getListUtterance(aAccessible, aRoleStr, aFlags, aItemCount) {
     let desc = [];
     let roleStr = this._getLocalizedRole(aRoleStr);
     if (roleStr) {
       desc.push(roleStr);
     }
-    desc.push(this._getPluralFormString('listItemCount', aItemCount));
+    desc.push(this._getPluralFormString('listItemsCount', aItemCount));
     let utterance = [desc.join(' ')];
 
     this._addName(utterance, aAccessible, aFlags);
     this._addLandmark(utterance, aAccessible);
 
     return utterance;
   }
 };
--- a/accessible/src/windows/ia2/Makefile.in
+++ b/accessible/src/windows/ia2/Makefile.in
@@ -12,17 +12,16 @@ include $(DEPTH)/config/autoconf.mk
 LIBRARY_NAME = accessibility_toolkit_ia2_s
 EXPORT_LIBRARY = 1
 LIBXUL_LIBRARY = 1
 
 # The midl generated code include Windows headers which defines min and max
 # macros which conflicts with std::min/max.  Suppress the macros:
 OS_CXXFLAGS += -DNOMINMAX
 
-include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES += \
   -I$(srcdir) \
   -I$(srcdir)/../msaa \
   -I$(srcdir)/../../base \
   -I$(srcdir)/../../generic \
   -I$(srcdir)/../../html \
--- a/accessible/src/windows/sdn/Makefile.in
+++ b/accessible/src/windows/sdn/Makefile.in
@@ -11,17 +11,16 @@ include $(DEPTH)/config/autoconf.mk
 
 LIBRARY_NAME = accessibility_toolkit_sdn_s
 EXPORT_LIBRARY = 1
 LIBXUL_LIBRARY = 1
 # The midl generated code include Windows headers which defines min and max
 # macros which conflicts with std::min/max.  Suppress the macros:
 OS_CXXFLAGS += -DNOMINMAX
 
-include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES += \
   -I$(srcdir) \
   -I$(srcdir)/../msaa \
   -I$(srcdir)/../../base \
   -I$(srcdir)/../../generic \
   -I$(srcdir)/../../html \
--- a/accessible/src/windows/uia/Makefile.in
+++ b/accessible/src/windows/uia/Makefile.in
@@ -11,17 +11,16 @@ include $(DEPTH)/config/autoconf.mk
 
 LIBRARY_NAME = accessibility_toolkit_uia_s
 EXPORT_LIBRARY = ..
 LIBXUL_LIBRARY = 1
 # The midl generated code include Windows headers which defines min and max
 # macros which conflicts with std::min/max.  Suppress the macros:
 OS_CXXFLAGS += -DNOMINMAX
 
-include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES += \
   -I$(srcdir) \
   -I$(srcdir)/../msaa \
   -I$(srcdir)/../../base \
   -I$(srcdir)/../../generic \
   -I$(srcdir)/../../html \
--- a/accessible/tests/mochitest/pivot.js
+++ b/accessible/tests/mochitest/pivot.js
@@ -71,32 +71,42 @@ var ObjectTraversalRule =
 
 /**
  * A checker for virtual cursor changed events.
  */
 function VCChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets, aPivotMoveMethod)
 {
   this.__proto__ = new invokerChecker(EVENT_VIRTUALCURSOR_CHANGED, aDocAcc);
 
+  this.match = function VCChangedChecker_check(aEvent)
+  {
+    var event = null;
+    try {
+      event = aEvent.QueryInterface(nsIAccessibleVirtualCursorChangeEvent);
+    } catch (e) {
+      return false;
+    }
+
+    var expectedReason = VCChangedChecker.methodReasonMap[aPivotMoveMethod] ||
+      nsIAccessiblePivot.REASON_NONE;
+
+    return event.reason == expectedReason;
+  };
+
   this.check = function VCChangedChecker_check(aEvent)
   {
     SimpleTest.info("VCChangedChecker_check");
 
     var event = null;
     try {
       event = aEvent.QueryInterface(nsIAccessibleVirtualCursorChangeEvent);
     } catch (e) {
       SimpleTest.ok(false, "Does not support correct interface: " + e);
     }
 
-    SimpleTest.is(
-      event.reason,
-      VCChangedChecker.methodReasonMap[aPivotMoveMethod],
-      'wrong move reason');
-
     var position = aDocAcc.virtualCursor.position;
     var idMatches = position && position.DOMNode.id == aIdOrNameOrAcc;
     var nameMatches = position && position.name == aIdOrNameOrAcc;
     var accMatches = position == aIdOrNameOrAcc;
 
     SimpleTest.ok(idMatches || nameMatches || accMatches, "id or name matches",
                   "expecting " + aIdOrNameOrAcc + ", got '" +
                   prettyName(position));
@@ -191,19 +201,24 @@ function setVCRangeInvoker(aDocAcc, aTex
  */
 function setVCPosInvoker(aDocAcc, aPivotMoveMethod, aRule, aIdOrNameOrAcc)
 {
   var expectMove = (aIdOrNameOrAcc != false);
   this.invoke = function virtualCursorChangedInvoker_invoke()
   {
     VCChangedChecker.
       storePreviousPosAndOffset(aDocAcc.virtualCursor);
-    var moved = aDocAcc.virtualCursor[aPivotMoveMethod](aRule);
-    SimpleTest.ok((expectMove && moved) || (!expectMove && !moved),
-                  "moved pivot");
+    if (aPivotMoveMethod && aRule) {
+      var moved = aDocAcc.virtualCursor[aPivotMoveMethod](aRule);
+      SimpleTest.is(!!moved, !!expectMove,
+                    "moved pivot with " + aPivotMoveMethod +
+                    " to " + aIdOrNameOrAcc);
+    } else {
+      aDocAcc.virtualCursor.position = getAccessible(aIdOrNameOrAcc);
+    }
   };
 
   this.getID = function setVCPosInvoker_getID()
   {
     return "Do " + (expectMove ? "" : "no-op ") + aPivotMoveMethod;
   };
 
   if (expectMove) {
@@ -442,16 +457,16 @@ function removeVCRootInvoker(aRootNode)
   ];
 }
 
 /**
  * A debug utility for writing proper sequences for queueTraversalSequence.
  */
 function dumpTraversalSequence(aPivot, aRule)
 {
-  var sequence = []
+  var sequence = [];
   if (aPivot.moveFirst(aRule)) {
     do {
       sequence.push("'" + prettyName(aPivot.position) + "'");
     } while (aPivot.moveNext(aRule))
   }
   SimpleTest.info("\n[" + sequence.join(", ") + "]\n");
 }
--- a/accessible/tests/mochitest/pivot/doc_virtualcursor.html
+++ b/accessible/tests/mochitest/pivot/doc_virtualcursor.html
@@ -10,17 +10,17 @@
   <p id="paragraph-1">
     Lorem ipsum <strong>dolor</strong> sit amet. Integer vitae urna
     leo, id <a href="#">semper</a> nulla.
   </p>
   <h2 id="heading-2-2" aria-hidden="undefined">Second Section Title</h2>
   <p id="paragraph-2" aria-hidden="">
     Sed accumsan luctus lacus, vitae mollis arcu tristique vulputate.</p>
   <p id="paragraph-3" aria-hidden="true">
-    Maybe it was the other <i>George Michael</i>.
+    <a href="#" id="hidden-link">Maybe</a> it was the other <i>George Michael</i>.
     You know, the <a href="#">singer-songwriter</a>.
   </p>
   <iframe
      src="data:text/html,<html><body>An <i>embedded</i> document.</body></html>">
   </iframe>
   <div id="hide-me">Hide me</div>
   <p id="links" aria-hidden="false">
     <a href="http://mozilla.org" title="Link 1 title">Link 1</a>
--- a/accessible/tests/mochitest/pivot/test_virtualcursor.html
+++ b/accessible/tests/mochitest/pivot/test_virtualcursor.html
@@ -90,16 +90,22 @@
         gQueue, docAcc, ObjectTraversalRule,
         getAccessible(doc.getElementById('paragraph-1')),
         ['Lorem ipsum ', 'dolor', ' sit amet. Integer vitae urna leo, id ',
          'semper', ' nulla. ']);
 
       gQueue.push(new setModalRootInvoker(docAcc, docAcc.parent,
                                           NS_ERROR_INVALID_ARG));
 
+      // Put cursor in an ignored subtree
+      gQueue.push(new setVCPosInvoker(docAcc, null, null,
+                                      getAccessible(doc.getElementById("hidden-link"))));
+      // Next item shoud be outside of that subtree
+      gQueue.push(new setVCPosInvoker(docAcc, "moveNext", ObjectTraversalRule, "An "));
+
       gQueue.invoke();
     }
 
     SimpleTest.waitForExplicitFinish();
     addLoadEvent(function () {
       /* We open a new browser because we need to test with a top-level content
          document. */
       openBrowserWindow(
--- a/accessible/tests/mochitest/text/test_atcaretoffset.html
+++ b/accessible/tests/mochitest/text/test_atcaretoffset.html
@@ -39,17 +39,17 @@
       this.__proto__ = new synthFocus("textarea");
 
       this.finalCheck = function moveToLastLineEnd_finalCheck()
       {
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "", 15, 15,
                             ["textarea"]);
 
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "", 15, 15,
-                            "textarea", kOk, kTodo, kTodo);
+                            [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "words", 10, 15,
                          [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
                          [ "textarea" ]);
 
         testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
@@ -67,20 +67,20 @@
 
     function moveToLastLineStart()
     {
       this.__proto__ = new moveToLineStart("textarea", 10);
 
       this.finalCheck = function moveToLastLineStart_finalCheck()
       {
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "", 15, 15,
-                            "textarea", kTodo, kTodo, kOk);
+                            [ "textarea" ]);
 
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "", 15, 15,
-                            "textarea", kTodo, kTodo, kOk);
+                            [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "words", 10, 15,
                          [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
                          [ "textarea" ]);
 
         testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
@@ -99,20 +99,20 @@
     function moveToMiddleLineStart()
     {
       this.__proto__ = new synthUpKey("textarea",
                                       new caretMoveChecker(6, "textarea"));
 
       this.finalCheck = function moveToMiddleLineStart_finalCheck()
       {
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "words", 10, 15,
-                            "textarea", kTodo, kTodo, kTodo);
+                            [ "textarea" ]);
 
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
-                            "textarea", kTodo, kTodo, kTodo);
+                            [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
                          [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
                          [ "textarea" ]);
 
         testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "aword\n", 0, 6,
@@ -130,20 +130,20 @@
 
     function moveToMiddleLineEnd()
     {
       this.__proto__ = new moveToLineEnd("textarea", 10);
 
       this.finalCheck = function moveToMiddleLineEnd_finalCheck()
       {
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "words", 10, 15,
-                            "textarea", kTodo, kTodo, kTodo);
+                            [ "textarea" ]);
 
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
-                            "textarea", kTodo, kTodo, kOk);
+                            [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
                          [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
                          [ "textarea" ]);
 
         testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "aword\n", 0, 6,
@@ -161,20 +161,20 @@
 
     function moveToFirstLineStart()
     {
       this.__proto__ = new moveToTextStart("textarea");
 
       this.finalCheck = function moveToFirstLineStart_finalCheck()
       {
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
-                            "textarea", kTodo, kTodo, kTodo);
+                            [ "textarea" ]);
 
-        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "aword", 0, 5,
-                            "textarea", kOk, kOk, kOk);
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
+                            [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "aword\n", 0, 6,
                          [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "aword", 0, 5,
                          [ "textarea" ]);
 
         testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "", 0, 0,
@@ -192,20 +192,20 @@
 
     function moveToFirstLineEnd()
     {
       this.__proto__ = new moveToLineEnd("textarea", 5);
 
       this.finalCheck = function moveToFirstLineStart_finalCheck()
       {
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
-                            "textarea", kTodo, kTodo, kTodo);
+                            [ "textarea" ]);
 
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
-                            "textarea", kTodo, kTodo, kTodo);
+                            [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "aword\n", 0, 6,
                          [ "textarea" ]);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "aword", 0, 5,
                          [ "textarea" ]);
 
         testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "", 0, 0,
@@ -219,18 +219,16 @@
       {
         return "move to first line end";
       }
     }
 
     var gQueue = null;
     function doTest()
     {
-      SimpleTest.expectAssertions(1);
-
       gQueue = new eventQueue();
       gQueue.push(new moveToLastLineEnd());
       gQueue.push(new moveToLastLineStart());
       gQueue.push(new moveToMiddleLineStart());
       gQueue.push(new moveToMiddleLineEnd());
       gQueue.push(new moveToFirstLineStart());
       gQueue.push(new moveToFirstLineEnd());
       gQueue.invoke(); // will call SimpleTest.finish();
--- a/accessible/tests/mochitest/text/test_multiline.html
+++ b/accessible/tests/mochitest/text/test_multiline.html
@@ -11,102 +11,45 @@
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
 
     function doTest()
     {
-      SimpleTest.expectAssertions(5);
-
       // __o__n__e__w__o__r__d__\n
       //  0  1  2  3  4  5  6  7
       // __\n
       //  8
       // __t__w__o__ __w__o__r__d__s__\n
       //  9 10 11 12 13 14 15 16 17 18
 
       ////////////////////////////////////////////////////////////////////////
       // getText
 
       var IDs = ["div", "divbr", "editable", "editablebr", "textarea"];
 
       ////////////////////////////////////////////////////////////////////////
       // getTextAfterOffset
 
       // BOUNDARY_LINE_START
-      testTextAfterOffset(0, BOUNDARY_LINE_START, "\n", 8, 9,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(7, BOUNDARY_LINE_START, "\n", 8, 9,
-                          "div", kOk, kTodo, kTodo,
-                          "divbr", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
-                          "editablebr", kOk, kTodo, kTodo,
-                          "textarea", kOk, kTodo, kTodo);
-      testTextAfterOffset(8, BOUNDARY_LINE_START, "two words\n", 9, 19,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(9, BOUNDARY_LINE_START, "", 19, 19,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(19, BOUNDARY_LINE_START, "", 19, 19,
-                          "div", kOk, kOk, kTodo,
-                          "divbr", kOk, kOk, kTodo,
-                          "editable", kOk, kOk, kTodo,
-                          "editablebr", kOk, kOk, kTodo,
-                          "textarea", kOk, kOk, kTodo);
+      testTextAfterOffset(0, BOUNDARY_LINE_START, "\n", 8, 9, IDs);
+      testTextAfterOffset(7, BOUNDARY_LINE_START, "\n", 8, 9, IDs);
+      testTextAfterOffset(8, BOUNDARY_LINE_START, "two words\n", 9, 19, IDs);
+      testTextAfterOffset(9, BOUNDARY_LINE_START, "", 19, 19, IDs);
+      testTextAfterOffset(19, BOUNDARY_LINE_START, "", 19, 19, IDs);
 
       // BOUNDARY_LINE_END
-      testTextAfterOffset(0, BOUNDARY_LINE_END, "\n", 7, 8,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(7, BOUNDARY_LINE_END, "\n", 7, 8,
-                          "div", kOk, kOk, kOk,
-                          "divbr", kOk, kOk, kOk,
-                          "editable", kOk, kOk, kOk,
-                          "editablebr", kOk, kOk, kOk,
-                          "textarea", kOk, kOk, kOk);
-      testTextAfterOffset(8, BOUNDARY_LINE_END, "\ntwo words", 8, 18,
-                          "div", kOk, kOk, kOk,
-                          "divbr", kOk, kOk, kOk,
-                          "editable", kOk, kOk, kOk,
-                          "editablebr", kOk, kOk, kOk,
-                          "textarea", kOk, kOk, kOk);
-      testTextAfterOffset(9, BOUNDARY_LINE_END, "\n", 18, 19,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
-      testTextAfterOffset(18, BOUNDARY_LINE_END, "\n", 18, 19,
-                          "div", kOk, kOk, kOk,
-                          "divbr", kOk, kOk, kOk,
-                          "editable", kOk, kOk, kOk,
-                          "editablebr", kOk, kOk, kOk,
-                          "textarea", kOk, kOk, kOk);
-      testTextAfterOffset(19, BOUNDARY_LINE_END, "", 19, 19,
-                          "div", kOk, kTodo, kTodo,
-                          "divbr", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
-                          "editablebr", kOk, kTodo, kTodo,
-                          "textarea", kOk, kTodo, kTodo);
+      testTextAfterOffset(0, BOUNDARY_LINE_END, "\n", 7, 8, IDs);
+      testTextAfterOffset(7, BOUNDARY_LINE_END, "\n", 7, 8, IDs);
+      testTextAfterOffset(8, BOUNDARY_LINE_END, "\ntwo words", 8, 18, IDs);
+      testTextAfterOffset(9, BOUNDARY_LINE_END, "\n", 18, 19, IDs);
+      testTextAfterOffset(18, BOUNDARY_LINE_END, "\n", 18, 19, IDs);
+      testTextAfterOffset(19, BOUNDARY_LINE_END, "", 19, 19, IDs);
 
       ////////////////////////////////////////////////////////////////////////
       // getTextBeforeOffset
 
       // BOUNDARY_LINE_START
       testTextBeforeOffset(0, BOUNDARY_LINE_START, "", 0, 0, IDs);
       testTextBeforeOffset(8, BOUNDARY_LINE_START, "oneword\n", 0, 8, IDs);
       testTextBeforeOffset(9, BOUNDARY_LINE_START, "\n", 8, 9, IDs);
@@ -161,16 +104,21 @@
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=853340">
     Bug 853340
   </a>
   <a target="_blank"
      title="getTextBeforeOffset for word boundaries: evolving"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=855732">
     Bug 855732
   </a>
+  <a target="_blank"
+     title=" getTextAfterOffset for line boundary on new rails"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=882292">
+    Bug 882292
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
 
   <div id="div">oneword
 
 two words
 </div>
--- a/accessible/tests/mochitest/text/test_singleline.html
+++ b/accessible/tests/mochitest/text/test_singleline.html
@@ -6,76 +6,38 @@
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
-    if (navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(0, 4);
-    } else {
-      SimpleTest.expectAssertions(4);
-    }
-
     function doTest()
     {
       // __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
       //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
 
       ////////////////////////////////////////////////////////////////////////
       // getTextAfterOffset
 
       var IDs = [ "input", "div", "editable", "textarea" ];
       var regularIDs = [ "input", "div", "editable" ];
 
       // BOUNDARY_LINE_START
-      testTextAfterOffset(0, BOUNDARY_LINE_START, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(1, BOUNDARY_LINE_START, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(14, BOUNDARY_LINE_START, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(15, BOUNDARY_LINE_START, "", 15, 15,
-                          "input", kOk, kOk, kOk,
-                          "div", kOk, kOk, kOk,
-                          "editable", kOk, kOk, kOk,
-                          "textarea", kOk, kOk, kOk);
+      testTextAfterOffset(0, BOUNDARY_LINE_START, "", 15, 15, IDs);
+      testTextAfterOffset(1, BOUNDARY_LINE_START, "", 15, 15, IDs);
+      testTextAfterOffset(14, BOUNDARY_LINE_START, "", 15, 15, IDs);
+      testTextAfterOffset(15, BOUNDARY_LINE_START, "", 15, 15, IDs);
 
       // BOUNDARY_LINE_END
-      testTextAfterOffset(0, BOUNDARY_LINE_END, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(1, BOUNDARY_LINE_END, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(14, BOUNDARY_LINE_END, "", 15, 15,
-                          "input", kTodo, kTodo, kOk,
-                          "div", kTodo, kTodo, kOk,
-                          "editable", kTodo, kTodo, kOk,
-                          "textarea", kTodo, kTodo, kOk);
-      testTextAfterOffset(15, BOUNDARY_LINE_END, "", 15, 15,
-                          "input", kOk, kTodo, kTodo,
-                          "div", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
-                          "textarea", kOk, kTodo, kTodo);
+      testTextAfterOffset(0, BOUNDARY_LINE_END, "", 15, 15, IDs);
+      testTextAfterOffset(1, BOUNDARY_LINE_END, "", 15, 15, IDs);
+      testTextAfterOffset(14, BOUNDARY_LINE_END, "", 15, 15, IDs);
+      testTextAfterOffset(15, BOUNDARY_LINE_END, "", 15, 15, IDs);
 
       ////////////////////////////////////////////////////////////////////////
       // getTextBeforeOffset
 
       var IDs = [ "input", "div", "editable", "textarea" ];
 
       // BOUNDARY_LINE_START
       testTextBeforeOffset(0, BOUNDARY_LINE_START, "", 0, 0, IDs);
@@ -126,16 +88,21 @@
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=853340">
     Bug 853340
   </a>
   <a target="_blank"
      title="getTextBeforeOffset for word boundaries: evolving"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=855732">
     Bug 855732
   </a>
+  <a target="_blank"
+     title=" getTextAfterOffset for line boundary on new rails"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=882292">
+    Bug 882292
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <input id="input" value="hello my friend"/>
   <div id="div">hello my friend</div>
   <div id="editable" contenteditable="true">hello my friend</div>
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -554,20 +554,23 @@ pref("dom.experimental_forms", true);
 pref("gfx.gralloc.enabled", false);
 
 // XXXX REMOVE FOR PRODUCTION. Turns on GC and CC logging
 pref("javascript.options.mem.log", false);
 
 // Increase mark slice time from 10ms to 30ms
 pref("javascript.options.mem.gc_incremental_slice_ms", 30);
 
-pref("javascript.options.mem.gc_high_frequency_heap_growth_max", 150);
+// Increase time to get more high frequency GC on benchmarks from 1000ms to 1500ms
+pref("javascript.options.mem.gc_high_frequency_time_limit_ms", 1500);
+
+pref("javascript.options.mem.gc_high_frequency_heap_growth_max", 300);
 pref("javascript.options.mem.gc_high_frequency_heap_growth_min", 120);
 pref("javascript.options.mem.gc_high_frequency_high_limit_mb", 40);
-pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 10);
+pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 0);
 pref("javascript.options.mem.gc_low_frequency_heap_growth", 120);
 pref("javascript.options.mem.high_water_mark", 6);
 pref("javascript.options.mem.gc_allocation_threshold_mb", 1);
 pref("javascript.options.mem.gc_decommit_threshold_mb", 1);
 
 // Show/Hide scrollbars when active/inactive
 pref("ui.showHideScrollbars", 1);
 
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "d717e2e751a6bb1303499bde6be9dbd88b275e30", 
+    "revision": "37d94f0bacee10e768aca70b2ea6acab378ebed5", 
     "repo_path": "/integration/gaia-central"
 }
--- a/browser/Makefile.in
+++ b/browser/Makefile.in
@@ -2,22 +2,23 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
-include $(topsrcdir)/config/config.mk
-
 include $(topsrcdir)/config/rules.mk
 
 ifdef MAKENSISU
 
 # For Windows build the uninstaller during the application build since the
 # uninstaller is included with the application for mar file generation.
 libs::
 	$(MAKE) -C installer/windows uninstaller
 ifdef MOZ_MAINTENANCE_SERVICE
 	$(MAKE) -C installer/windows maintenanceservice_installer
 endif
 endif
+
+check::
+	$(PYTHON) $(topsrcdir)/build/compare-mozconfig/compare-mozconfigs-wrapper.py
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3663,20 +3663,18 @@ var XULBrowserWindow = {
   get isImage () {
     delete this.isImage;
     return this.isImage = document.getElementById("isImage");
   },
 
   init: function () {
     this.throbberElement = document.getElementById("navigator-throbber");
 
-    // Initialize the security button's state and tooltip text.  Remember to reset
-    // _hostChanged, otherwise onSecurityChange will short circuit.
+    // Initialize the security button's state and tooltip text.
     var securityUI = gBrowser.securityUI;
-    this._hostChanged = true;
     this.onSecurityChange(null, null, securityUI.state);
   },
 
   destroy: function () {
     // XXXjag to avoid leaks :-/, see bug 60729
     delete this.throbberElement;
     delete this.stopCommand;
     delete this.reloadCommand;
@@ -3857,17 +3855,16 @@ var XULBrowserWindow = {
         this.stopCommand.setAttribute("disabled", "true");
         CombinedStopReload.switchToReload(aRequest instanceof Ci.nsIRequest);
       }
     }
   },
 
   onLocationChange: function (aWebProgress, aRequest, aLocationURI, aFlags) {
     var location = aLocationURI ? aLocationURI.spec : "";
-    this._hostChanged = true;
 
     // Hide the form invalid popup.
     if (gFormSubmitObserver.panel) {
       gFormSubmitObserver.panel.hidePopup();
     }
 
     let pageTooltip = document.getElementById("aHTMLTooltip");
     let tooltipNode = pageTooltip.triggerNode;
@@ -3999,47 +3996,28 @@ var XULBrowserWindow = {
 
   onStatusChange: function (aWebProgress, aRequest, aStatus, aMessage) {
     this.status = aMessage;
     this.updateStatusField();
   },
 
   // Properties used to cache security state used to update the UI
   _state: null,
-  _hostChanged: false, // onLocationChange will flip this bit
+  _lastLocation: null,
 
   onSecurityChange: function (aWebProgress, aRequest, aState) {
     // Don't need to do anything if the data we use to update the UI hasn't
     // changed
+    let uri = gBrowser.currentURI;
+    let spec = uri.spec;
     if (this._state == aState &&
-        !this._hostChanged) {
-#ifdef DEBUG
-      try {
-        var contentHost = gBrowser.contentWindow.location.host;
-        if (this._host !== undefined && this._host != contentHost) {
-            Components.utils.reportError(
-              "ASSERTION: browser.js host is inconsistent. Content window has " +
-              "<" + contentHost + "> but cached host is <" + this._host + ">.\n"
-            );
-        }
-      } catch (ex) {}
-#endif
+        this._lastLocation == spec)
       return;
-    }
     this._state = aState;
-
-#ifdef DEBUG
-    try {
-      this._host = gBrowser.contentWindow.location.host;
-    } catch(ex) {
-      this._host = null;
-    }
-#endif
-
-    this._hostChanged = false;
+    this._lastLocation = spec;
 
     // aState is defined as a bitmask that may be extended in the future.
     // We filter out any unknown bits before testing for known values.
     const wpl = Components.interfaces.nsIWebProgressListener;
     const wpl_security_bits = wpl.STATE_IS_SECURE |
                               wpl.STATE_IS_BROKEN |
                               wpl.STATE_IS_INSECURE;
     var level;
@@ -4058,17 +4036,16 @@ var XULBrowserWindow = {
       // anymore, but still set it for third-party themes.
       if (gURLBar)
         gURLBar.setAttribute("level", level);
     } else {
       if (gURLBar)
         gURLBar.removeAttribute("level");
     }
 
-    let uri = gBrowser.currentURI;
     try {
       uri = Services.uriFixup.createExposableURI(uri);
     } catch (e) {}
     gIdentityHandler.checkIdentity(this._state, uri);
   },
 
   // simulate all change notifications after switching tabs
   onUpdateCurrentBrowser: function XWB_onUpdateCurrentBrowser(aStateFlags, aStatus, aMessage, aTotalProgress) {
--- a/browser/base/content/test/browser_CTP_drag_drop.js
+++ b/browser/base/content/test/browser_CTP_drag_drop.js
@@ -82,17 +82,17 @@ function part7() {
   ok(PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser), "Should have a click-to-play notification in the tab in the new window");
   ok(!PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser), "Should not have a click-to-play notification in the old window now");
 
   let plugin = gNewWindow.gBrowser.selectedBrowser.contentDocument.getElementById("test");
   let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
   ok(!objLoadingContent.activated, "plugin should not be activated");
 
   EventUtils.synthesizeMouseAtCenter(plugin, {}, gNewWindow.gBrowser.selectedBrowser.contentWindow);
-  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser).dismissed;
+  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser).dismissed && gNewWindow.PopupNotifications.panel.firstChild;
   waitForCondition(condition, part8, "waited too long for plugin to activate");
 }
 
 function part8() {
   // Click the activate button on doorhanger to make sure it works
   gNewWindow.PopupNotifications.panel.firstChild._primaryButton.click();
 
   let plugin = gNewWindow.gBrowser.selectedBrowser.contentDocument.getElementById("test");
--- a/browser/base/content/test/browser_bug882977.js
+++ b/browser/base/content/test/browser_bug882977.js
@@ -29,12 +29,11 @@ function test() {
       browser.removeEventListener("load", onLoad, true);
       checkIdentityMode(win);
     }, true);
   });
 }
 
 function checkIdentityMode(win) {
   let identityMode = win.document.getElementById("identity-box").className;
-  is(identityMode, "unknownIdentity", "Identity should be chromeUI but is currently " +
-                                      "shown as unknownIdentity for new windows.");
+  is(identityMode, "chromeUI", "Identity state should be chromeUI for about:home in a new window");
   finish();
 }
--- a/browser/base/content/test/social/browser_addons.js
+++ b/browser/base/content/test/social/browser_addons.js
@@ -15,17 +15,18 @@ let manifest = { // builtin provider
   workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
   iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
 };
 let manifest2 = { // used for testing install
   name: "provider 2",
   origin: "https://test1.example.com",
   sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html",
   workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js",
-  iconURL: "https://test1.example.com/browser/browser/base/content/test/moz.png"
+  iconURL: "https://test1.example.com/browser/browser/base/content/test/moz.png",
+  version: 1
 };
 
 function test() {
   waitForExplicitFinish();
 
   let prefname = getManifestPrefname(manifest);
   setBuiltinManifestPref(prefname, manifest);
   // ensure that manifest2 is NOT showing as builtin
@@ -274,10 +275,54 @@ var tests = {
       Social.installProvider(doc, manifest2, function(addonManifest) {
         Services.prefs.clearUserPref("social.directories");
         SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
           Social.uninstallProvider(addonManifest.origin);
           gBrowser.removeTab(tab);
         });
       });
     });
+  },
+  testUpgradeProviderFromWorker: function(next) {
+    // add the provider, change the pref, add it again. The provider at that
+    // point should be upgraded
+    let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
+    addTab(activationURL, function(tab) {
+      let doc = tab.linkedBrowser.contentDocument;
+      let installFrom = doc.nodePrincipal.origin;
+      Services.prefs.setCharPref("social.whitelist", installFrom);
+      Social.installProvider(doc, manifest2, function(addonManifest) {
+        SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
+          Social.enabled = true;
+          checkSocialUI();
+          is(Social.provider.manifest.version, 1, "manifest version is 1")
+          // watch for the provider-update and tell the worker to update
+          SocialService.registerProviderListener(function providerListener(topic, data) {
+            if (topic != "provider-update")
+              return;
+            SocialService.unregisterProviderListener(providerListener);
+            observeProviderSet(function() {
+              Services.prefs.clearUserPref("social.whitelist");
+              executeSoon(function() {
+                is(Social.provider.manifest.version, 2, "manifest version is 2");
+                Social.uninstallProvider(addonManifest.origin);
+                gBrowser.removeTab(tab);
+                next();
+              })
+            });
+          });
+          let port = Social.provider.getWorkerPort();
+          port.postMessage({topic: "worker.update", data: true});
+        });
+      });
+    });
   }
 }
+
+
+function observeProviderSet(cb) {
+  Services.obs.addObserver(function providerSet(subject, topic, data) {
+    Services.obs.removeObserver(providerSet, "social:provider-set");
+    info("social:provider-set observer was notified");
+    // executeSoon to let the browser UI observers run first
+    executeSoon(cb);
+  }, "social:provider-set", false);
+}
\ No newline at end of file
--- a/browser/base/content/test/social/social_activate.html
+++ b/browser/base/content/test/social/social_activate.html
@@ -15,17 +15,17 @@ var data = {
   "sidebarURL": "/browser/browser/base/content/test/social/social_sidebar.html",
   "workerURL": "/browser/browser/base/content/test/social/social_worker.js",
 
   // should be available for display purposes
   "description": "A short paragraph about this provider",
   "author": "Shane Caraveo, Mozilla",
 
   // optional
-  "version": "1.0"
+  "version": 1
 }
 
 function activate(node) {
   node.setAttribute("data-service", JSON.stringify(data));
   var event = new CustomEvent("ActivateSocialFeature");
   node.dispatchEvent(event);
 }
 
--- a/browser/base/content/test/social/social_worker.js
+++ b/browser/base/content/test/social/social_worker.js
@@ -132,11 +132,18 @@ onconnect = function(e) {
         break;
       case "test-isVisible-response":
         testPort.postMessage({topic: "got-isVisible-response", result: event.data.result});
         break;
       case "share-data-message":
         if (testPort)
           testPort.postMessage({topic:"got-share-data-message", result: event.data.result});
         break;
+      case "worker.update":
+        apiPort.postMessage({topic: 'social.manifest-get'});
+        break;
+      case "social.manifest":
+        event.data.data.version = 2;
+        apiPort.postMessage({topic: 'social.manifest-set', data: event.data.data});
+        break;
     }
   }
 }
index afce613e2fd2d6dedb69c453ea978d9aeb7692ef..28f13894ed2873e7f2bbc76a31dea75b61c81956
GIT binary patch
literal 1800
zc$@(U2lx1iP)<h;3K|Lk000e1NJLTq001xm000mO1^@s6P_F#3000KhNkl<Zc-o!T
zdr*^S76$MSt5B6~D*}R6*HY370ufjRkr0tU0$RBQFx(+rloeM&<t9+17z0)y;99wP
z*+rOzT3xDc>#VI7iaJn55t-_Mc!63LXOZf1vBSI1alSAahOs;Q$8Wxq_c>=KCnoZ8
z{W%N%S0=EOXAB%`{)l7MoGv<>0s1fp3@6o_|DM&(vtlRTUdC#T7QX6hOW@jqxJh`e
z2L>=7mVhPCVxZF1@lm0j%R{w|b6>H;htx+iTzAI1QyGH_Zow$89a<nAQb7Z+78p4)
zn^3I>`s4Kii_xmLOGnD*cHw-CpzegW(du_pkUvuSy9$268O;GRIiNTH2Fx3*@e;Ks
znb%(pozvSapEXWU_go7%?CMBfe4-;|@v$G`=YP&GXu#dvX`xFFL%@E+CD4G;pvFY|
z<_-RRWN{2$4+DFhr)3LTo*pu*cy>%+PP6=*H*HT}mi@Kg+!tSMoXuY6n~-@OO-i%R
zyGvX?;F^-Gwd61XjCUD?-~;Wzrq~Tj@2f3o0sY4s>loA%z({YQ;L6XH_L9CsHsQSm
zf=)Wq^{{B!C&-qutD!UKlfSatHoHOg&IB;>WuV#ZdxzZrbR&1=-ZOqCJ#?n)^41TJ
zA#>)=#ySuacm`|=IV^?4(`1>H(bwQnrTG2!k5>)@({)Gf9Mx0iYTJ?TbYg1Osd7@^
zEpoA9txALL>h+?do@OtqJQgrr7m|c&w+^oJIu#~3KQ%iWzx*#(b6s4xzlN?MdBAx2
za2Iy+nGqa@CSW?QQAVHs_j_bTmv%`RY1t#wTuzntv}DOXMmD?SQ}2b%8Pen5rAe<*
zuJv82^u`^H_q(huetu23UEKlKC5)i{TZzYeeRYw-&+sp^=z584`O!e@vwxOZc2cf&
zNc#Sdw?A8N&uRQTNjosO2Y-M!fzu&|Gw=^+0tUC}M+|fRzBQ!tbYcj@^M3Q*V6O)!
z0!-*Pq5U7}+pJB#joTDoH71381K0T8E@X!EW6Tp<_hhd6faQv;`u~~hwfRY7m>tfI
zVHOxQrn+w{l-XTXd)fZ5&%>sZdNI?B%z{(-tS6(uKnx+^2HI>U6vI8Z4xPYYj9<X8
zMwu`M>_SGg{LJ>)&5g-QZ=BD>8P{_>cy4`STt#hM!u{H~_zpaOq+S^37qHynXfwXu
z!G@j9l4VpW-SUpbiz9GOnch#0;bw&!old8&7WQYjuINr%BYa4`n0ZOFT&BdIi~@r=
zcns&@4a)du1H6Pj_#PPiqFtaoEM*K>UE;P~72zpARY&i*`17ftw~*=e)+pxS^_R$B
zB70I5ncPaf@Lan<yq*1coUJ`O9KEhA(a~{mx0_Sz@V81!WHSfON13Lrb!tM-ugIPz
zyR7V@-UOk;2+eZa-4vu97#sw~Q-U_11&`n%<nZ}T?N_LDQ+8)@U=BMHky%bpQmsti
zflMD}^*1O?OM<fdp|2t;;{fHDxkIz`6^eCS-4kN9ie-9>Pt%hWC?ti*jNq-Ii%RDx
zq4U3@A=lUaB;}a7PqSQ{a|Fo)26thAufGO;2!uD`2K2!LK3DMz=oc&Ui}E)XFqNOW
zXP<AuAl2%C{g>_@k1{?Gs0z7N9&5VaUwwO@ulfl*ro2dzUrMv|CR2SRb-sc%Y?H01
zPj2NpM0Lz6@%1O?qiqw`xW_y=6D154x^)LF7d;KO5e-njOD3tOzt~)uLo6|cXTabK
z7~<;y&;xgfff8VRuPML4j4#sDEwf~0!+T_9Z0|=U=d-*^U)7%~3L~FikQ<gp?)NPU
zElAGyFRG+->ZKX}I$?0JMByeAtbO5WA!gxDk``~i&Iw+hI(8-gy@PQZ|CkrLL6hj=
z)kx>mOEWaf`P**MlEVZr7=UwN4pL}?2Yfcc_j0sA%DQTL>Z^h@F{mei?ewS`OqW$$
zJeQlc;$T>jVz+1I&0UhJ$CObI_41#-_Wm<3C&V|~b&1CWFn0^dkiWgOwe@I3Wbu}O
zJ>J%y_ap+z0A<uey);9!oVQhyu0R+DHXS~bYx`+|t)kk=t3<9}xiZPE_7|M7=}?yI
zUmiofG(!ulTqNbRSBdms{~YHf(*NL$O^33KP5#-`OEWafc?fn)Weh6lfN^*Z*WnY&
zbbD!mxYeh~<YlfVWuHZ|<Yeh)*M_cmms2m{#TM6w4xANJMm^L^Gqix6xeuAV%w5n#
zh(g7F^)8khdRHv;`E|u2pAlEVhVHPnesz>l5A|y2IFZH9{~Ik3wW?9qwAX3A)~8Ij
qmlm*EutDo}*J-MaK%aVaXZ{Nf!<PwAe958!0000<MNUMnLSTZx2ZDtF
index 531ff5dec0cd353a41a0c7799bcefcc47fbcd8d8..ff0e6cad2daf18e83e0350d514272b3e56b0231b
GIT binary patch
literal 4802
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
index afce613e2fd2d6dedb69c453ea978d9aeb7692ef..feba1607a9bb7fa8a5be6f335cdeb32fc3e70636
GIT binary patch
literal 1624
zc$@)P2B-OnP)<h;3K|Lk000e1NJLTq001xm000mO1^@s6P_F#30000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU%`bk7VR7l6w)_G7>RU8L!NkvDU```gD
z6*UE?%+cIRO_Xylpa`ysxTOZ<Zix;^qCPeemB)@2OJbpdq8Q~sD2bT44TLC*0fM05
z!ZIRAvN-SbJ&)sq6y%@&$(hgG^Um*k@SJ<^x%c+y@gM)2n@HaQUFZh`xPH9voo>eJ
zKp!xGVK9<oZ8`rNI&YnTf%8Q}@PpgX#N~hwt9A3A>srM;F%b{l4I>AO?vU`pW{rbI
z`REH`wXP<CzMh~zHMD$&@y65y`N~se!m_v)2JO-zo6f~g2`Qh>GA!Hq<iAR@gF2vH
zc*ZhaojK{yT}KjHP!F^V^(@2Bvd(LhSD3n7Qp%PdZ4~T(q@9s1iEU&VmVILp1{+iC
zKn;|;1mj>dL_r<zXBoTK7N9GI7dn#QTs2UQki2V_5#?5v5oOcG(1K&=tLHT}%d#;Y
z7O!u*EnO)rI;;lD7_NxRo8XtfWy0P(hk=fXsj|gK8hK64viwT4odkn5Nk;Gt=xgkF
zoj`4eewJ0dy63GTADEJWoO+-gNg)NRQSU2-{WTB2pLVF#TSeX<`D(vR2`HW+TM*SK
z%#WZQy|*FR1@(77aJ{rqwlJ#xRX@v4Ru!AGE7`UHhXfy>oG%oCi}va`Bn*SKkOWOU
z=lAODi-9>o#6OENV&JV%qWZHGM^83+cBw7G3r9&ow_U`5>{Mi$+j2Q!d_TyCIG&0Z
z=7duQ?UVWoBPxeFC4Pt6K=uF_v+KIq@C|1}6ia`&F3dgH!g9tA2?=boYbI#8A~pwb
z*<y>~W9ZxQ7Qt`Ac|ao1-sTJFNA_LMCw|u`j`u7=@@HAcR2lL6oSorblIo_7MNsZS
z(LYNi?!S@Dvv>H@X_$Ooc&T6=fO{hJ;aK-8>!s-GkI-)jy`lez^+_v7Z_jWU`bGS4
z#p0-|EQ>K^Y;4;E?W3E30)gdVuARJnbT0^oLdb@Eo^9p}7(n)1ZU$-*c*{;Ykhxwu
zkY&Rr&g#}NPx^~~*CL7UA0?0rg)9p#{1H1+u-exmSo+a1ZW-<))|~b+U3X>`ujyDs
zR}UOyADyT_JD@^t8&o2<3B1p;7}LtewoP(DcoR@q0~L@AJ$bDsoPt)UgeyGTpk07x
zdNWXI?=@HAb@7qted&VD(Psji!0aQ{{qXxN>aD0fCSDntEDO)I3m{%Cg1IL(aXJyM
zXW?68WE+@iee5~gBfTtRY88q(!IuSdua~IR8d&?^VOg2z{i1yVwyGSU5Xg^=llCgu
zs(Ql%xDOt@eoK1`Dbw=F?sHW1N{?hmM)LW6E5FBk+r&Oq5as!YP$_z6s5BX6T7mW!
zlDtZVX*=lP&%%CUM`rlvNBsHAOPF=EVXB_FvRaQQtB2Z09A|Zmxz~ORS?%!w3Pn)G
z+vh+R7DHdS36)UJ>+PFZnHEIclPTGmQcB!YYBcR#sTs2mKQR<{pIdGnRiPj|f6YVv
zF;uWR#<XwZ1tIamC)=pL*^WxtRM$GzHk3TGtq#|WRm}8tw1|8(PCjF2iQcDfwR+RO
zsbY2G`N17FG1;wvXF%Z$)baKr&;bb?A%yp{Z2MzWb#o+fOR5Jd?l_x5+<w-yCFS|m
zb51l3ki60tNFHh1#GNV8te<7s7{1B-O!m$+mreS*QJAoqDn#W~*`zI+_K2ksZnh^|
zM!fHMY?H}~??VUM?E8iFvn(5<eT-@rF>SjYsDVNiB*P%EhAb%OHI{kvMYb!|k+_^z
z10^nrHKJS6g_*&5<0X&ZmJ!!8w}@+EMO*E(nq}X3ku8f<3S-x*fy%~jtTQrm%QRCJ
ztRD4c+%EZK=VHByo2yujWmxuKFEZ^SCOa>NdZ1lkwXQ!U+>@Qi){_lDyU>74*Pjwg
z4tdDNIQ=b*cA%YMHPa>EcK#`$UBtvqhTsRe&;rjP8}_hTw;yx+GfhO7#4zG~;ttso
z*9whj=b|r|)w=zd^S&{|*wQ0GK5lK9FlyyX*@vrM$j7fMF}CuEXSKI}%>5rfr~d(2
WVxXp!azq>e0000<MNUMnLSTZ|8Wx!V
index 531ff5dec0cd353a41a0c7799bcefcc47fbcd8d8..9b2d6bc66f21ff97506d6f09497049c5af18e4ab
GIT binary patch
literal 4283
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
index a39e493c1eb1eaacc6b40c32fb6eebe683021b3f..feba1607a9bb7fa8a5be6f335cdeb32fc3e70636
GIT binary patch
literal 1624
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
WVxXp!azq>e0000<MNUMnLSTZ|8Wx!V
index 794d54ecae5277de16d1b9ae6f030c7d7b0678f7..9b2d6bc66f21ff97506d6f09497049c5af18e4ab
GIT binary patch
literal 4283
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
--- a/browser/components/places/tests/chrome/test_bug631374_tags_selector_scroll.xul
+++ b/browser/components/places/tests/chrome/test_bug631374_tags_selector_scroll.xul
@@ -113,25 +113,30 @@
 
           // Doing this backwords tests more interesting paths.
           for (let i = tags.length - 1; i >= 0 ; i -= 2) {
             tagsSelector.selectedIndex = i;
             let listItem = tagsSelector.selectedItem;
             SimpleTest.isnot(listItem, null, "Valid listItem found");
 
             tagsSelector.ensureElementIsVisible(listItem);
-            let visibleIndex = tagsSelector.getIndexOfFirstVisibleRow();
+            let firstVisibleTag = tags[tagsSelector.getIndexOfFirstVisibleRow()];
 
             SimpleTest.ok(listItem.checked, "Item is checked " + i);
             let selectedTag = listItem.label;
 
             // Uncheck the tag.
             listItem.checked = false;
-            SimpleTest.is(tagsSelector.getIndexOfFirstVisibleRow(),
-                          Math.max(visibleIndex -1, 0),
+
+            // Ensure the first visible tag is still visible in the list.
+            let firstVisibleIndex = tagsSelector.getIndexOfFirstVisibleRow();
+            let lastVisibleIndex = firstVisibleIndex + tagsSelector.getNumberOfVisibleRows() -1;
+            let expectedTagIndex = tags.indexOf(firstVisibleTag);
+            SimpleTest.ok(expectedTagIndex >= firstVisibleIndex &&
+                          expectedTagIndex <= lastVisibleIndex,
                           "Scroll position is correct");
 
             // The listbox is rebuilt, so we have to get the new element.
             let newItem = tagsSelector.selectedItem;
             SimpleTest.isnot(newItem, null, "Valid new listItem found");
             SimpleTest.ok(newItem.checked, "New listItem is checked " + i);
             SimpleTest.is(tagsSelector.selectedItem.label,
                           tags[Math.min(i + 1, tags.length - 2)],
new file mode 100644
--- /dev/null
+++ b/browser/config/mozconfigs/whitelist
@@ -0,0 +1,90 @@
+# 'nightly' contains things that are in nightly mozconfigs and allowed to be missing from release builds.
+# Other keys in whitelist contain things are in that branches mozconfigs and allowed to be missing from nightly builds.
+whitelist = {
+    'release': {},
+    'nightly': {},
+    }
+
+all_platforms = ['win32', 'linux32', 'linux64', 'macosx-universal']
+
+for platform in all_platforms:
+    whitelist['nightly'][platform] = [
+        'ac_add_options --enable-update-channel=nightly',
+        'ac_add_options --enable-profiling',
+        'mk_add_options CLIENT_PY_ARGS="--hg-options=\'--verbose --time\' --hgtool=../tools/buildfarm/utils/hgtool.py --skip-chatzilla --skip-comm --skip-inspector --skip-venkman --tinderbox-print"'
+    ]
+
+for platform in ['linux32', 'linux64', 'macosx-universal']:
+    whitelist['nightly'][platform] += [
+        'ac_add_options --enable-codesighs',
+        'mk_add_options MOZ_MAKE_FLAGS="-j4"',
+    ]
+
+for platform in ['linux32', 'linux64', 'macosx-universal', 'win32']:
+    whitelist['nightly'][platform] += ['ac_add_options --enable-signmar']
+    whitelist['nightly'][platform] += ['ac_add_options --enable-js-diagnostics']
+
+whitelist['nightly']['linux32'] += [
+    'CXX=$REAL_CXX',
+    'CXX="ccache $REAL_CXX"',
+    'CC="ccache $REAL_CC"',
+    'mk_add_options PROFILE_GEN_SCRIPT=@TOPSRCDIR@/build/profile_pageloader.pl',
+    'ac_add_options --with-ccache=/usr/bin/ccache',
+    'export MOZILLA_OFFICIAL=1',
+    'export MOZ_TELEMETRY_REPORTING=1',
+    "mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'",
+    'STRIP_FLAGS="--strip-debug"',
+    'ac_add_options --disable-elf-hack # --enable-elf-hack conflicts with --enable-profiling',
+]
+
+whitelist['nightly']['linux64'] += [
+    'export MOZILLA_OFFICIAL=1',
+    'export MOZ_TELEMETRY_REPORTING=1',
+    "mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'",
+    'STRIP_FLAGS="--strip-debug"',
+    'ac_add_options --with-ccache=/usr/bin/ccache',
+    'ac_add_options --disable-elf-hack # --enable-elf-hack conflicts with --enable-profiling',
+]
+
+whitelist['nightly']['macosx-universal'] += [
+    'ac_add_options --with-macbundlename-prefix=Firefox',
+    'mk_add_options MOZ_MAKE_FLAGS="-j12"',
+    'ac_add_options --with-ccache',
+    'ac_add_options --disable-install-strip',
+    'ac_add_options --enable-instruments',
+    'ac_add_options --enable-dtrace',
+]
+
+whitelist['nightly']['win32'] += [
+    '. $topsrcdir/configs/mozilla2/win32/include/choose-make-flags',
+    'mk_add_options MOZ_MAKE_FLAGS=-j1',
+    'if test "$IS_NIGHTLY" != ""; then',
+    'ac_add_options --disable-auto-deps',
+    'fi',
+    'ac_add_options --enable-metro',
+]
+
+for platform in all_platforms:
+    whitelist['release'][platform] = [
+        'ac_add_options --enable-update-channel=release',
+        'ac_add_options --enable-official-branding',
+        'mk_add_options MOZ_MAKE_FLAGS="-j4"',
+        'export BUILDING_RELEASE=1',
+    ]
+whitelist['release']['win32'] += ['mk_add_options MOZ_PGO=1']
+whitelist['release']['linux32'] += [
+    'export MOZILLA_OFFICIAL=1',
+    'export MOZ_TELEMETRY_REPORTING=1',
+    'mk_add_options MOZ_PGO=1',
+    "mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'",
+]
+whitelist['release']['linux64'] += [
+    'export MOZILLA_OFFICIAL=1',
+    'export MOZ_TELEMETRY_REPORTING=1',
+    'mk_add_options MOZ_PGO=1',
+    "mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'",
+]
+
+if __name__ == '__main__':
+    import pprint
+    pprint.pprint(whitelist)
--- a/browser/devtools/Makefile.in
+++ b/browser/devtools/Makefile.in
@@ -2,14 +2,12 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
-include $(topsrcdir)/config/config.mk
-
 include $(topsrcdir)/config/rules.mk
 
 libs::
 	$(NSINSTALL) $(srcdir)/main.js $(FINAL_TARGET)/modules/devtools
--- a/browser/devtools/styleeditor/StyleEditorDebuggee.jsm
+++ b/browser/devtools/styleeditor/StyleEditorDebuggee.jsm
@@ -223,16 +223,22 @@ let StyleSheet = function(form, debuggee
   this._onSourceLoad = this._onSourceLoad.bind(this);
   this._onPropertyChange = this._onPropertyChange.bind(this);
   this._onStyleApplied = this._onStyleApplied.bind(this);
 
   this._client.addListener("sourceLoad", this._onSourceLoad);
   this._client.addListener("propertyChange", this._onPropertyChange);
   this._client.addListener("styleApplied", this._onStyleApplied);
 
+  // Backwards compatibility
+  this._client.addListener("sourceLoad-" + this._actor, this._onSourceLoad);
+  this._client.addListener("propertyChange-" + this._actor, this._onPropertyChange);
+  this._client.addListener("styleApplied-" + this._actor, this._onStyleApplied);
+
+
   // set initial property values
   for (let attr in form) {
     this[attr] = form[attr];
   }
 }
 
 StyleSheet.prototype = {
   /**
@@ -319,10 +325,14 @@ StyleSheet.prototype = {
 
   /**
    * Clean up and remove event listeners
    */
   destroy: function() {
     this._client.removeListener("sourceLoad", this._onSourceLoad);
     this._client.removeListener("propertyChange", this._onPropertyChange);
     this._client.removeListener("styleApplied", this._onStyleApplied);
+
+    this._client.removeListener("sourceLoad-" + this._actor, this._onSourceLoad);
+    this._client.removeListener("propertyChange-" + this._actor, this._onPropertyChange);
+    this._client.removeListener("styleApplied-" + this._actor, this._onStyleApplied);
   }
 }
--- a/browser/metro/Makefile.in
+++ b/browser/metro/Makefile.in
@@ -3,17 +3,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH     = ../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/config.mk
 
 include $(topsrcdir)/config/rules.mk
 
 #########################################
 # application.ini
 
 ifdef MOZILLA_OFFICIAL
 DEFINES += -DMOZILLA_OFFICIAL
--- a/browser/metro/base/content/ContextCommands.js
+++ b/browser/metro/base/content/ContextCommands.js
@@ -156,17 +156,17 @@ var ContextCommands = {
     aRichListItem.setAttribute("searchString", "");
     BrowserUI.newTab(defaultURI, Browser.selectedTab);
   },
 
   // Link specific
 
   openLinkInNewTab: function cc_openLinkInNewTab() {
     Browser.addTab(ContextMenuUI.popupState.linkURL, false, Browser.selectedTab);
-    ContextUI.peekTabs();
+    ContextUI.peekTabs(kOpenInNewTabAnimationDelayMsec);
   },
 
   copyLink: function cc_copyLink() {
     this.clipboard.copyString(ContextMenuUI.popupState.linkURL,
                               this.docRef);
   },
 
   bookmarkLink: function cc_bookmarkLink() {
--- a/browser/metro/base/content/ContextUI.js
+++ b/browser/metro/base/content/ContextUI.js
@@ -5,22 +5,16 @@
 // Fired when any context ui is displayed
 const kContextUIShowEvent = "MozContextUIShow";
 // Fired when any context ui is dismissed
 const kContextUIDismissEvent = "MozContextUIDismiss";
 // Fired when the tabtray is displayed
 const kContextUITabsShowEvent = "MozContextUITabsShow";
 // add more as needed...
 
-// delay for ContextUI's dismissTabsWithDelay
-const kHideContextAndTrayDelayMsec = 3000;
-
-// delay when showing the tab bar briefly as a new tab opens
-const kNewTabAnimationDelayMsec = 1000;
-
 /*
  * Manages context UI (navbar, tabbar, appbar) and track visibility. Also
  * tracks events that summon and hide the context UI.
  */
 var ContextUI = {
   _expandable: true,
   _hidingId: 0,
 
@@ -155,63 +149,46 @@ var ContextUI = {
     }
 
     return dismissed;
   },
 
   /*
    * Briefly show the tab bar and then hide it. Fires context ui events.
    */
-  peekTabs: function peekTabs() {
-    if (this.tabbarVisible) {
-      setTimeout(function () {
-        ContextUI.dismissTabsWithDelay(kNewTabAnimationDelayMsec);
-      }, 0);
-    } else {
-      BrowserUI.setOnTabAnimationEnd(function () {
-        ContextUI.dismissTabsWithDelay(kNewTabAnimationDelayMsec);
-      });
+  peekTabs: function peekTabs(aDelay) {
+    if (!this.tabbarVisible)
       this.displayTabs();
-    }
+
+    ContextUI.dismissTabsWithDelay(aDelay);
   },
 
   /*
    * Dismiss tab bar after a delay. Fires context ui events.
    */
   dismissTabsWithDelay: function (aDelay) {
-    aDelay = aDelay || kHideContextAndTrayDelayMsec;
+    aDelay = aDelay || kNewTabAnimationDelayMsec;
     this._clearDelayedTimeout();
     this._hidingId = setTimeout(function () {
         ContextUI.dismissTabs();
       }, aDelay);
   },
 
-  // Cancel any pending delayed dismiss
-  cancelDismiss: function cancelDismiss() {
-    this._clearDelayedTimeout();
-  },
-
   // Display the nav bar
   displayNavbar: function () {
     this._clearDelayedTimeout();
     Elements.navbar.show();
   },
 
   // Display the tab tray
   displayTabs: function () {
     this._clearDelayedTimeout();
     this._setIsExpanded(true);
   },
 
-  // Display the app bar
-  displayContextAppbar: function () {
-    this._clearDelayedTimeout();
-    Elements.contextappbar.show();
-  },
-
   // Dismiss the navbar if visible.
   dismissNavbar: function dismissNavbar() {
     Elements.navbar.dismiss();
   },
 
   // Dismiss the tabstray if visible.
   dismissTabs: function dimissTabs() {
     this._clearDelayedTimeout();
@@ -307,25 +284,19 @@ var ContextUI = {
         break;
       case "KeyboardChanged":
         this.dismissTabs();
         break;
       case "mousedown":
         if (aEvent.button == 0 && this.isVisible)
           this.dismiss();
         break;
-      case 'URLChanged':
-        this.dismissTabs();
-        break;
-      case 'TabSelect':
-        this.dismissTabs();
-        break;
 
-      case 'ToolPanelShown':
-      case 'ToolPanelHidden':
+      case "ToolPanelShown":
+      case "ToolPanelHidden":
       case "touchstart":
       case "AlertActive":
         this.dismiss();
         break;
     }
   },
 
   _fire: function (name) {
--- a/browser/metro/base/content/WebProgress.js
+++ b/browser/metro/base/content/WebProgress.js
@@ -79,18 +79,20 @@ const WebProgress = {
       identityBox.className = aTab._identityState;
     }
   },
 
   _locationChange: function _locationChange(aJson, aTab) {
     let spec = aJson.location;
     let location = spec.split("#")[0]; // Ignore fragment identifier changes.
 
-    if (aTab == Browser.selectedTab)
+    if (aTab == Browser.selectedTab) {
       BrowserUI.updateURI();
+      BrowserUI.update();
+    }
 
     let locationHasChanged = (location != aTab.browser.lastLocation);
     if (locationHasChanged) {
       Browser.getNotificationBox(aTab.browser).removeTransientNotifications();
       aTab.resetZoomLevel();
       aTab.browser.lastLocation = location;
       aTab.browser.userTypedValue = "";
       aTab.browser.appIcon = { href: null, size:-1 };
@@ -118,32 +120,25 @@ const WebProgress = {
       aTab.scrolledAreaChanged(true);
       aTab.updateThumbnailSource();
     });
   },
 
   _networkStart: function _networkStart(aJson, aTab) {
     aTab.startLoading();
 
-    if (aTab == Browser.selectedTab) {
+    if (aTab == Browser.selectedTab)
       BrowserUI.update(TOOLBARSTATE_LOADING);
-
-      // We should at least show something in the URLBar until
-      // the load has progressed further along
-      if (aTab.browser.currentURI.spec == "about:blank")
-        BrowserUI.updateURI({ captionOnly: true });
-    }
   },
 
   _networkStop: function _networkStop(aJson, aTab) {
     aTab.endLoading();
 
-    if (aTab == Browser.selectedTab) {
+    if (aTab == Browser.selectedTab)
       BrowserUI.update(TOOLBARSTATE_LOADED);
-    }
   },
 
   _windowStart: function _windowStart(aJson, aTab) {
     this._progressStart(aJson, aTab);
   },
 
   _windowStop: function _windowStop(aJson, aTab) {
     this._progressStop(aJson, aTab);
@@ -157,17 +152,17 @@ const WebProgress = {
 
     this._progressActive = true;
 
     // display the track
     Elements.progressContainer.removeAttribute("collapsed");
 
     // 'Whoosh' in
     this._progressCount = kProgressMarginStart;
-    Elements.progress.style.width = this._progressCount + "%"; 
+    Elements.progress.style.width = this._progressCount + "%";
     Elements.progress.removeAttribute("fade");
 
     // Create a pulse timer to keep things moving even if we don't
     // collect any state changes.
     setTimeout(function() {
       WebProgress._progressStepTimer();
     }, kHeartbeatDuration, this);
   },
@@ -199,26 +194,26 @@ const WebProgress = {
     setTimeout(function() {
       WebProgress._progressStepTimer();
     }, kHeartbeatDuration, this);
   },
 
   _progressStop: function _progressStop(aJson, aTab) {
     this._progressActive = false;
     // 'Whoosh out' and fade
-    Elements.progress.style.width = "100%"; 
+    Elements.progress.style.width = "100%";
     Elements.progress.setAttribute("fade", true);
   },
 
   _progressTransEnd: function _progressTransEnd(data) {
     if (!Elements.progress.hasAttribute("fade"))
       return;
     // Close out fade finished, reset
     if (data.propertyName == "opacity") {
-      Elements.progress.style.width = "0px"; 
+      Elements.progress.style.width = "0px";
       Elements.progressContainer.setAttribute("collapsed", true);
     }
   },
 
   _onTabSelect: function(aEvent) {
     let identityBox = document.getElementById("identity-box-inner");
     let tab = Browser.getTabFromChrome(aEvent.originalTarget);
     identityBox.className = tab._identityState || "";
--- a/browser/metro/base/content/appbar.js
+++ b/browser/metro/base/content/appbar.js
@@ -110,17 +110,17 @@ var Appbar = {
                                      null, null);
         if (uri.schemeIs('http') || uri.schemeIs('https')) {
           typesArray.push("view-on-desktop");
         }
       } catch(ex) {
       }
 
       var x = this.menuButton.getBoundingClientRect().left;
-      var y = Elements.navbar.getBoundingClientRect().top;
+      var y = Elements.toolbar.getBoundingClientRect().top;
       ContextMenuUI.showContextMenu({
         json: {
           types: typesArray,
           string: '',
           xPos: x,
           yPos: y,
           leftAligned: true,
           bottomAligned: true
--- a/browser/metro/base/content/bindings/grid.xml
+++ b/browser/metro/base/content/bindings/grid.xml
@@ -81,22 +81,30 @@
               this._fireOnSelectionChange();
             }
           ]]>
         </body>
       </method>
 
       <method name="handleItemClick">
         <parameter name="aItem"/>
+        <parameter name="aEvent"/>
         <body>
           <![CDATA[
             if(!this.isBound)
               return;
-            if (this.controller)
-              this.controller.handleItemClick(aItem);
+
+            if ("single" == this.getAttribute("seltype")) {
+              // we'll republish this as a selectionchange event on the grid
+              aEvent.stopPropagation();
+              this.selectItem(aItem);
+            }
+
+	    if (this.controller && this.controller.handleItemClick)
+              this.controller.handleItemClick(aItem, aEvent);
           ]]>
         </body>
       </method>
 
       <method name="handleItemContextMenu">
         <parameter name="aItem"/>
         <parameter name="aEvent"/>
         <body>
rename from browser/metro/base/content/bindings/autocomplete.xml
rename to browser/metro/base/content/bindings/urlbar.xml
--- a/browser/metro/base/content/bindings/autocomplete.xml
+++ b/browser/metro/base/content/bindings/urlbar.xml
@@ -9,294 +9,639 @@
 %browserDTD;
 ]>
 
 <bindings
     xmlns="http://www.mozilla.org/xbl"
     xmlns:xbl="http://www.mozilla.org/xbl"
     xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
-  <binding id="autocomplete" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete">
-    <implementation>
+  <binding id="urlbar" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete">
+    <implementation implements="nsIObserver">
       <constructor>
-          <![CDATA[
-            this.minResultsForPopup = 0;
-            this.popup._input = this;
-          ]]>
+        <![CDATA[
+          this._mayFormat = Services.prefs.getBoolPref("browser.urlbar.formatting.enabled");
+          this._mayTrimURLs = Services.prefs.getBoolPref("browser.urlbar.trimURLs");
+          this._maySelectAll = Services.prefs.getBoolPref("browser.urlbar.doubleClickSelectsAll");
+
+          Services.prefs.addObserver("browser.urlbar.formatting.enabled", this, false);
+          Services.prefs.addObserver("browser.urlbar.trimURLs", this, false);
+          Services.prefs.addObserver("browser.urlbar.doubleClickSelectsAll", this, false);
+
+          this.inputField.controllers.insertControllerAt(0, this._copyCutValueController);
+
+          this.minResultsForPopup = 0;
+          this.popup._input = this;
+        ]]>
       </constructor>
 
+      <destructor>
+        <![CDATA[
+          Services.prefs.removeObserver("browser.urlbar.formatting.enabled", this);
+          Services.prefs.removeObserver("browser.urlbar.trimURLs", this);
+          Services.prefs.removeObserver("browser.urlbar.doubleClickSelectsAll", this);
+        ]]>
+      </destructor>
+
+      <field name="_mayFormat"/>
+      <field name="_mayTrimURLs"/>
+      <field name="_maySelectAll"/>
+      <field name="_lastKnownGoodURL"/>
+
       <method name="openPopup">
         <body>
           <![CDATA[
             this.popup.openAutocompletePopup(this, null);
           ]]>
         </body>
       </method>
 
       <method name="closePopup">
         <body>
           <![CDATA[
             this.popup.closePopup(this, null);
           ]]>
         </body>
       </method>
 
+      <!-- URI Display: Domain Highlighting -->
+
+      <method name="_clearFormatting">
+        <body>
+          <![CDATA[
+            if (!this._mayFormat)
+              return;
+
+            let controller = this.editor.selectionController;
+            let selection = controller.getSelection(controller.SELECTION_URLSECONDARY);
+            selection.removeAllRanges();
+          ]]>
+        </body>
+      </method>
+
       <method name="formatValue">
         <body>
           <![CDATA[
-            BrowserUI.formatURI();
+            if (!this._mayFormat || this.isEditing)
+              return;
+
+            let controller = this.editor.selectionController;
+            let selection = controller.getSelection(controller.SELECTION_URLSECONDARY);
+            selection.removeAllRanges();
+
+            let textNode = this.editor.rootElement.firstChild;
+            let value = textNode.textContent;
+
+            let protocol = value.match(/^[a-z\d.+\-]+:(?=[^\d])/);
+            if (protocol &&
+                ["http:", "https:", "ftp:"].indexOf(protocol[0]) == -1)
+              return;
+            let matchedURL = value.match(/^((?:[a-z]+:\/\/)?(?:[^\/]+@)?)(.+?)(?::\d+)?(?:\/|$)/);
+            if (!matchedURL)
+              return;
+
+            let [, preDomain, domain] = matchedURL;
+            let baseDomain = domain;
+            let subDomain = "";
+            // getBaseDomainFromHost doesn't recognize IPv6 literals in brackets as IPs (bug 667159)
+            if (domain[0] != "[") {
+              try {
+                baseDomain = Services.eTLD.getBaseDomainFromHost(domain);
+                if (!domain.endsWith(baseDomain)) {
+                  // getBaseDomainFromHost converts its resultant to ACE.
+                  let IDNService = Cc["@mozilla.org/network/idn-service;1"]
+                                   .getService(Ci.nsIIDNService);
+                  baseDomain = IDNService.convertACEtoUTF8(baseDomain);
+                }
+              } catch (e) {}
+            }
+            if (baseDomain != domain) {
+              subDomain = domain.slice(0, -baseDomain.length);
+            }
+
+            let rangeLength = preDomain.length + subDomain.length;
+            if (rangeLength) {
+              let range = document.createRange();
+              range.setStart(textNode, 0);
+              range.setEnd(textNode, rangeLength);
+              selection.addRange(range);
+            }
+
+            let startRest = preDomain.length + domain.length;
+            if (startRest < value.length) {
+              let range = document.createRange();
+              range.setStart(textNode, startRest);
+              range.setEnd(textNode, value.length);
+              selection.addRange(range);
+            }
+          ]]>
+        </body>
+      </method>
+
+      <!-- URI Display: Scheme and Trailing Slash Triming -->
+
+      <method name="_trimURL">
+        <parameter name="aURL"/>
+        <body>
+          <![CDATA[
+            // This function must not modify the given URL such that calling
+            // nsIURIFixup::createFixupURI with the rfdesult will produce a different URI.
+            return aURL /* remove single trailing slash for http/https/ftp URLs */
+               .replace(/^((?:http|https|ftp):\/\/[^/]+)\/$/, "$1")
+                /* remove http:// unless the host starts with "ftp\d*\." or contains "@" */
+               .replace(/^http:\/\/((?!ftp\d*\.)[^\/@]+(?:\/|$))/, "$1");
+          ]]>
+        </body>
+      </method>
+
+      <method name="_getSelectedValueForClipboard">
+        <body>
+          <![CDATA[
+            // Grab the actual input field's value, not our value, which could include moz-action:
+            let inputVal = this.inputField.value;
+            let selectedVal = inputVal.substring(this.selectionStart, this.electionEnd);
+
+            // If the selection doesn't start at the beginning or doesn't span the full domain or
+            // the URL bar is modified, nothing else to do here.
+            if (this.selectionStart > 0 || this.valueIsTyped)
+              return selectedVal;
+
+            // The selection doesn't span the full domain if it doesn't contain a slash and is
+            // followed by some character other than a slash.
+            if (!selectedVal.contains("/")) {
+              let remainder = inputVal.replace(selectedVal, "");
+              if (remainder != "" && remainder[0] != "/")
+                return selectedVal;
+            }
+
+            let uriFixup = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup);
+
+            let uri;
+            try {
+              uri = uriFixup.createFixupURI(inputVal, Ci.nsIURIFixup.FIXUP_FLAG_USE_UTF8);
+            } catch (e) {}
+            if (!uri)
+              return selectedVal;
+
+            // Only copy exposable URIs
+            try {
+              uri = uriFixup.createExposableURI(uri);
+            } catch (ex) {}
+
+            // If the entire URL is selected, just use the actual loaded URI.
+            if (inputVal == selectedVal) {
+              // ... but only if  isn't a javascript: or data: URI, since those
+              // are hard to read when encoded
+              if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) {
+                // Parentheses are known to confuse third-party applications (bug 458565).
+                selectedVal = uri.spec.replace(/[()]/g, function (c) escape(c));
+              }
+
+              return selectedVal;
+            }
+
+            // Just the beginning of the URL is selected, check for a trimmed value
+            let spec = uri.spec;
+            let trimmedSpec = this._trimURL(spec);
+            if (spec != trimmedSpec) {
+              // Prepend the portion that trimURL removed from the beginning.
+              // This assumes trimURL will only truncate the URL at
+              // the beginning or end (or both).
+              let trimmedSegments = spec.split(trimmedSpec);
+              selectedVal = trimmedSegments[0] + selectedVal;
+            }
+
+            return selectedVal;
           ]]>
         </body>
       </method>
 
+      <field name="_copyCutValueController">
+        <![CDATA[
+          ({
+            urlbar: this,
+            doCommand: function(aCommand) {
+              let urlbar = this.urlbar;
+              let val = urlbar._getSelectedValueForClipboard();
+              if (!val)
+                return;
+
+              if (aCommand == "cmd_cut" && this.isCommandEnabled(aCommand)) {
+                let start = urlbar.selectionStart;
+                let end = urlbar.selectionEnd;
+                urlbar.inputField.value = urlbar.inputField.value.substring(0, start) +
+                                          urlbar.inputField.value.substring(end);
+                urlbar.selectionStart = urlbar.selectionEnd = start;
+              }
+
+              Cc["@mozilla.org/widget/clipboardhelper;1"]
+                .getService(Ci.nsIClipboardHelper)
+                .copyString(val, document);
+            },
+
+            supportsCommand: function(aCommand) {
+              switch (aCommand) {
+                case "cmd_copy":
+                case "cmd_cut":
+                  return true;
+              }
+              return false;
+            },
+
+            isCommandEnabled: function(aCommand) {
+              let urlbar = this.urlbar;
+              return this.supportsCommand(aCommand) &&
+                     (aCommand != "cmd_cut" || !urlbar.readOnly) &&
+                     urlbar.selectionStart < urlbar.selectionEnd;
+            },
+
+            onEvent: function(aEventName) {}
+          })
+        ]]>
+      </field>
+
       <method name="trimValue">
         <parameter name="aURL"/>
-        <body><![CDATA[
-          return BrowserUI.trimURL(aURL);
-        ]]></body>
+        <body>
+          <![CDATA[
+            return (this._mayTrimURLs) ? this._trimURL(aURL) : aURL;
+          ]]>
+        </body>
+      </method>
+
+      <!-- URI Editing -->
+
+      <property name="isEditing" readonly="true">
+        <getter>
+          <![CDATA[
+            return Elements.urlbarState.getAttribute("mode") == "edit";
+          ]]>
+        </getter>
+      </property>
+
+      <method name="beginEditing">
+        <parameter name="aShouldDismiss"/>
+        <body>
+          <![CDATA[
+            if (this.isEditing)
+              return;
+
+            Elements.urlbarState.setAttribute("mode", "edit");
+            this._lastKnownGoodURL = this.value;
+
+            if (!this.focused)
+              this.focus();
+
+            this._clearFormatting();
+            this.select();
+
+            if (aShouldDismiss)
+              ContextUI.dismissTabs();
+          ]]>
+        </body>
+      </method>
+
+      <method name="endEditing">
+        <parameter name="aShouldRevert"/>
+        <body>
+          <![CDATA[
+            if (!this.isEditing)
+              return;
+
+            Elements.urlbarState.setAttribute("mode", "view");
+            this.closePopup();
+            this.formatValue();
+
+            if (this.focused)
+              this.blur();
+
+            if (aShouldRevert)
+              this.value = this._lastKnownGoodURL;
+          ]]>
+        </body>
+      </method>
+
+      <!-- URI Submission -->
+
+      <method name="_canonizeURL">
+        <parameter name="aURL"/>
+        <parameter name="aTriggeringEvent"/>
+        <body>
+          <![CDATA[
+            if (!aURL)
+              return "";
+
+            // Only add the suffix when the URL bar value isn't already "URL-like",
+            // and only if we get a keyboard event, to match user expectations.
+            if (/^\s*[^.:\/\s]+(?:\/.*|\s*)$/i.test(aURL)) {
+              let accel = aTriggeringEvent.ctrlKey;
+              let shift = aTriggeringEvent.shiftKey;
+              let suffix = "";
+
+              switch (true) {
+                case (accel && shift):
+                  suffix = ".org/";
+                  break;
+                case (shift):
+                  suffix = ".net/";
+                  break;
+                case (accel):
+                  try {
+                    suffix = gPrefService.getCharPref("browser.fixup.alternate.suffix");
+                    if (suffix.charAt(suffix.length - 1) != "/")
+                      suffix += "/";
+                  } catch(e) {
+                    suffix = ".com/";
+                  }
+                  break;
+              }
+
+              if (suffix) {
+                // trim leading/trailing spaces (bug 233205)
+                aURL = aURL.trim();
+
+                // Tack www. and suffix on.  If user has appended directories, insert
+                // suffix before them (bug 279035).  Be careful not to get two slashes.
+                let firstSlash = aURL.indexOf("/");
+                if (firstSlash >= 0) {
+                  aURL = aURL.substring(0, firstSlash) + suffix + aURL.substring(firstSlash + 1);
+                } else {
+                  aURL = aURL + suffix;
+                }
+                aURL = "http://www." + aURL;
+              }
+            }
+
+            return aURL;
+          ]]>
+        </body>
+      </method>
+
+      <method name="submitURL">
+        <parameter name="aEvent"/>
+        <body>
+          <![CDATA[
+            // If the address was typed in by a user, tidy it up
+            if (aEvent instanceof KeyEvent)
+              this.value = this._canonizeURL(this.value, aEvent);
+
+            this.endEditing();
+            BrowserUI.goToURI(this.value);
+
+            return true;
+          ]]>
+        </body>
+      </method>
+
+      <method name="submitSearch">
+        <parameter name="anEngineName"/>
+        <body>
+          <![CDATA[
+            this.endEditing();
+            BrowserUI.doOpenSearch(anEngineName);
+
+            return true;
+          ]]>
+        </body>
+      </method>
+
+      <!-- nsIObserver -->
+
+      <method name="observe">
+        <parameter name="aSubject"/>
+        <parameter name="aTopic"/>
+        <parameter name="aData"/>
+        <body>
+          <![CDATA[
+            if (aTopic != "nsPref:changed")
+              return;
+
+            switch (aData) {
+              case "browser.urlbar.formatting.enabled":
+                this._mayFormat = Services.prefs.getBoolPref(aData);
+                break;
+              case "browser.urlbar.trimURLs":
+                this._mayTrimURLs = Services.prefs.getBoolPref(aData);
+                break;
+              case "browser.urlbar.doubleClickSelectsAll":
+                this._maySelectAll = Services.prefs.getBoolPref(aData);
+                break;
+            }
+          ]]>
+        </body>
       </method>
     </implementation>
 
     <handlers>
-      <handler event="click" phase="capturing">
+      <!-- Entering editing mode -->
+
+      <handler event="input" phase="capturing">
         <![CDATA[
-        // If the urlbar is not already focused, focus it and select the contents.
-        if (Elements.urlbarState.getAttribute("mode") != "edit") {
-          BrowserUI._editURI(true);
-        }
+          // Ensures that paste-and-go actually brings the URL bar into editing mode
+          // and displays the half-height autocomplete popup.
+          this.beginEditing();
+          this.openPopup();
         ]]>
       </handler>
 
+      <handler event="click" phase="capturing">
+        <![CDATA[
+          this.beginEditing(true);
+        ]]>
+      </handler>
+
+      <!-- Editing mode behaviors -->
+
       <handler event="dblclick" phase="capturing">
         <![CDATA[
-          let selectAll = Services.prefs.getBoolPref("browser.urlbar.doubleClickSelectsAll");
-          if (selectAll)
-            this.select();
+            if (this._maySelectAll) this.select();
         ]]>
       </handler>
 
       <handler event="contextmenu" phase="capturing">
         <![CDATA[
           let box = this.inputField.parentNode;
           box.showContextMenu(this, event, true);
         ]]>
       </handler>
 
+      <!-- Leaving editing mode -->
+
+      <handler event="blur" phase="capturing">
+        <![CDATA[
+          this.endEditing();
+        ]]>
+      </handler>
+
       <handler event="keypress" phase="capturing" keycode="VK_RETURN">
         <![CDATA[
-          event.preventDefault();
-          event.stopPropagation();
+          if (this.popup.submitSelected())
+            return;
 
-          this.popup.handleCompletion();
+          if (this.submitURL(event))
+            return;
         ]]>
       </handler>
     </handlers>
   </binding>
 
-  <binding id="autocomplete-popup">
+  <binding id="urlbar-autocomplete">
     <content orient="horizontal">
-      <xul:vbox id="results-vbox" class="meta-section viewable-height" flex="1">
+      <xul:vbox id="results-vbox" flex="1">
         <xul:label class="meta-section-title" value="&autocompleteResultsHeader.label;"/>
-        <richgrid id="results-richgrid" deferlayout="true" anonid="results" seltype="single" flex="1"/>
+        <richgrid id="results-richgrid" rows="3" deferlayout="true" anonid="results" seltype="single" flex="1"/>
       </xul:vbox>
 
-      <xul:vbox id="searches-vbox" class="meta-section viewable-height" flex="1">
+      <xul:vbox id="searches-vbox" flex="1">
         <xul:label class="meta-section-title" value="&autocompleteSearchesHeader.label;"/>
-        <richgrid id="searches-richgrid" deferlayout="true" anonid="searches" seltype="single" flex="1"/>
+        <richgrid id="searches-richgrid" rows="3" deferlayout="true" anonid="searches" seltype="single" flex="1"/>
       </xul:vbox>
     </content>
 
     <implementation implements="nsIAutoCompletePopup, nsIObserver">
       <constructor>
         <![CDATA[
+          this.hidden = true;
+
           Services.obs.addObserver(this, "browser-search-engine-modified", false);
-          this.updateSearchEngines();
+
           this._results.controller = this;
           this._searches.controller = this;
         ]]>
       </constructor>
 
       <destructor>
         <![CDATA[
           Services.obs.removeObserver(this, "browser-search-engine-modified");
         ]]>
       </destructor>
 
-      <method name="handleItemClick">
-        <parameter name="aItem"/>
-        <body>
-          <![CDATA[
-            if (aItem.control == this._searches) {
-              let engineName = aItem.getAttribute("value");
-              BrowserUI.doOpenSearch(engineName);
-            } else {
-              let url = aItem.getAttribute("value");
-              Browser.loadURI(url);
-            }
-          ]]>
-        </body>
-      </method>
-
-    <!-- nsIAutocompleteInput -->
+      <!-- nsIAutocompleteInput -->
 
       <field name="_input">null</field>
-      <field name="_popupOpen">false</field>
 
+      <property name="input" readonly="true" onget="return this._input;"/>
+      <property name="matchCount" readonly="true" onget="return this.input.controller.matchCount;"/>
+      <property name="popupOpen" readonly="true" onget="return !this.hidden"/>
       <property name="overrideValue" readonly="true" onget="return null;"/>
 
       <property name="selectedItem">
         <getter>
           <![CDATA[
             return this._isGridBound(this._results) ? this._results.selectedItem : null;
           ]]>
         </getter>
         <setter>
           <![CDATA[
             return this._isGridBound(this._results) ? this._results.selectedItem : null;
           ]]>
         </setter>
       </property>
+
       <property name="selectedIndex">
         <getter>
           <![CDATA[
             return this._isGridBound(this._results) ? this._results.selectedIndex : -1;
           ]]>
         </getter>
         <setter>
           <![CDATA[
             return this._isGridBound(this._results) ? this._results.selectedIndex : -1;
           ]]>
         </setter>
       </property>
 
-      <property name="input" readonly="true" onget="return this._input;"/>
-      <property name="popupOpen" readonly="true" onget="return this._popupOpen;"/>
-      <property name="_matchCount" readonly="true" onget="return this.input.controller.matchCount;"/>
-
       <method name="openAutocompletePopup">
         <parameter name="aInput"/>
         <parameter name="aElement"/>
         <body>
           <![CDATA[
-            if (this._popupOpen)
+            if (this.popupOpen)
               return;
 
             ContextUI.dismissContextAppbar();
 
             this._input = aInput;
-            this._popupOpen = true;
             this._grid = this._results;
 
             this.clearSelection();
             this.invalidate();
 
             this._results.arrangeItemsNow();
             this._searches.arrangeItemsNow();
 
-            this._fire("autocompletestart");
-          ]]>
-        </body>
-      </method>
-
-      <method name="gridBoundCallback">
-        <body>
-          <![CDATA[
-            this.updateResults();
+            this.hidden = false;
           ]]>
         </body>
       </method>
 
       <method name="closePopup">
         <body>
           <![CDATA[
-            if (!this._popupOpen)
+            if (!this.popupOpen)
               return;
 
             this.input.controller.stopSearch();
-            this._popupOpen = false;
-            this._fire("autocompleteend");
+            this.hidden = true;
+          ]]>
+        </body>
+      </method>
+
+      <!-- Updating grid content -->
+
+      <field name="_grid">null</field>
+      <field name="_results" readonly="true">document.getAnonymousElementByAttribute(this, 'anonid', 'results');</field>
+      <field name="_searches" readonly="true">document.getAnonymousElementByAttribute(this, 'anonid', 'searches');</field>
+
+      <property name="_otherGrid" readonly="true">
+        <getter>
+          <![CDATA[
+            if (this._grid == null)
+              return null;
+
+            return (this._grid == this._results) ? this._searches : this._results;
+          ]]>
+        </getter>
+      </property>
+
+      <method name="_isGridBound">
+        <parameter name="aGrid"/>
+        <body>
+          <![CDATA[
+            return aGrid && aGrid.isBound;
           ]]>
         </body>
       </method>
 
       <method name="invalidate">
         <body>
           <![CDATA[
-            if (!this._popupOpen)
+            if (!this.popupOpen)
               return;
 
             this.updateResults();
             this.updateSearchEngineSubtitles();
           ]]>
         </body>
       </method>
 
-      <method name="selectBy">
-        <parameter name="aReverse"/>
-        <parameter name="aPage"/>
-        <body>
-          <![CDATA[
-            let handleOnSelect = this._handleOnSelect;
-            this._handleOnSelect = false;
-
-            // TODO <jwilde>: Pressing page up/down should jump between rows,
-            //                not just items in the grid
-
-            // Move between grids if we're at the edge of one
-            if ((this._grid.isSelectionAtEnd && !aReverse) ||
-                (this._grid.isSelectionAtStart && aReverse)) {
-              let index = aReverse ? this._otherGrid.itemCount - 1 : 0;
-              this._otherGrid.selectedIndex = index;
-            } else {
-              this._grid.offsetSelection(aReverse ? -1 : 1);
-            }
-
-            this._handleOnSelect = handleOnSelect;
-          ]]>
-        </body>
-      </method>
-
-    <!-- nsIObserver -->
-
-      <method name="observe">
-        <parameter name="aSubject"/>
-        <parameter name="aTopic"/>
-        <parameter name="aData"/>
-        <body>
-          <![CDATA[
-            if (aTopic != "browser-search-engine-modified")
-              return;
-
-            switch (aData) {
-              case "engine-added":
-              case "engine-removed":
-              case "engine-changed":
-                this.updateSearchEngines();
-                break;
-              case "engine-current":
-                // Not relevant
-                break;
-            }
-          ]]>
-        </body>
-      </method>
-
-    <!-- Interface for updating various components of the popup. -->
+      <!-- Updating grid content: results -->
 
       <method name="updateResults">
         <body>
           <![CDATA[
             if (!this._isGridBound(this._results))
               return;
+
             if (!this.input)
               return;
 
             let controller = this.input.controller;
-            let lastMatch = this._matchCount - 1;
-            let iterCount = Math.max(this._results.itemCount, this._matchCount);
+            let lastMatch = this.matchCount - 1;
+            let iterCount = Math.max(this._results.itemCount, this.matchCount);
 
             // Swap out existing items for new search hit results
             for (let i = 0; i < iterCount; i++) {
               if (i > lastMatch) {
                 let lastItem = this._results.itemCount - 1;
                 this._results.removeItemAt(lastItem, true);
                 continue;
               }
@@ -317,23 +662,29 @@
               item.setAttribute("iconURI", iconURI);
             }
 
             this._results.arrangeItems();
           ]]>
         </body>
       </method>
 
-      <method name="updateSearchEngines">
-        <body><![CDATA[
-          Services.search.init(this._onSearchServiceInit.bind(this));
-        ]]></body>
+      <!-- Updating grid content: search engines -->
+
+      <field name="_engines">[]</field>
+
+      <method name="_initSearchEngines">
+        <body>
+          <![CDATA[
+            Services.search.init(this.updateSearchEngineGrid.bind(this));
+          ]]>
+        </body>
       </method>
 
-      <method name="_onSearchServiceInit">
+      <method name="updateSearchEngineGrid">
         <body>
           <![CDATA[
             if (!this._isGridBound(this._searches))
               return;
 
             this._engines = Services.search.getVisibleEngines();
 
             while (this._searches.itemCount > 0)
@@ -366,31 +717,34 @@
               let item = this._searches.getItemAtIndex(i);
               item.setAttribute("label", label);
               item.refresh && item.refresh();
             }
           ]]>
         </body>
       </method>
 
-    <!-- Interface for handling actions across grids -->
+      <!-- Selecting results -->
 
-      <method name="handleCompletion">
+      <method name="selectBy">
+        <parameter name="aReverse"/>
+        <parameter name="aPage"/>
         <body>
           <![CDATA[
-            if (this._grid == this._results) {
-              this.input.controller.handleEnter(false);
+            if (!this._isGridBound(this._results) ||
+                !this._isGridBound(this._searches))
               return;
-            }
 
-            if (this._grid == this._searches) {
-              let engine = this._engines[this._grid.selectedIndex];
-              BrowserUI.doOpenSearch(engine.name);
-              this.closePopup();
-              return;
+            // Move between grids if we're at the edge of one.
+            if ((this._grid.isSelectionAtEnd && !aReverse) ||
+                (this._grid.isSelectionAtStart && aReverse)) {
+              let index = !aReverse ? 0 : this._otherGrid.itemCount - 1;
+              this._otherGrid.selectedIndex = index;
+            } else {
+              this._grid.offsetSelection(aReverse ? -1 : 1);
             }
           ]]>
         </body>
       </method>
 
       <method name="clearSelection">
         <body>
           <![CDATA[
@@ -398,76 +752,87 @@
               this._results.clearSelection();
 
             if (this._isGridBound(this._searches))
               this._searches.clearSelection();
           ]]>
         </body>
       </method>
 
-    <!-- Helpers -->
-
-      <field name="_engines">[]</field>
-      <field name="_handleOnSelect">true</field>
-      <field name="_grid">null</field>
-
-      <property name="_results" readonly="true" onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'results');"/>
-      <property name="_searches" readonly="true" onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'searches');"/>
+      <!-- Submitting selected results -->
 
-      <property name="_otherGrid" readonly="true">
-        <getter>
-          <![CDATA[
-            return (this._grid == this._results) ? this._searches : this._results;
-          ]]>
-        </getter>
-      </property>
-
-      <method name="_isGridBound">
-        <parameter name="aGrid"/>
+      <method name="submitSelected">
         <body>
           <![CDATA[
-            return aGrid && aGrid.itemCount != undefined;
+            if (this._isGridBound(this._results) &&
+                this._results.selectedIndex >= 0) {
+              let url = this.input.controller.getValueAt(this._results.selectedIndex);
+              this.input.value = url;
+              return this.input.submitURL();
+            }
+
+            if (this._isGridBound(this._searches) &&
+                this._searches.selectedIndex >= 0) {
+              let engine = this._engines[this._searches.selectedIndex];
+              return this.input.submitSearch(engine.name);
+            }
+
+            return false;
           ]]>
         </body>
       </method>
 
-      <method name="_fire">
-        <parameter name="aName"/>
+      <method name="handleItemClick">
+        <parameter name="aItem"/>
+        <parameter name="aEvent"/>
         <body>
           <![CDATA[
-            let event = document.createEvent("Events");
-            event.initEvent(aName, true, false);
-            this.dispatchEvent(event);
+            this.submitSelected();
+          ]]>
+        </body>
+      </method>
+
+      <!-- nsIObserver -->
+
+      <method name="observe">
+        <parameter name="aSubject"/>
+        <parameter name="aTopic"/>
+        <parameter name="aData"/>
+        <body>
+          <![CDATA[
+            switch (aTopic) {
+              case "browser-search-engine-modified":
+                this.updateSearchEngineGrid();
+                break;
+            }
           ]]>
         </body>
       </method>
     </implementation>
 
     <handlers>
+      <handler event="contentgenerated">
+        <![CDATA[
+          let grid = event.originalTarget;
+
+          if (grid == this._searches)
+            this._initSearchEngines();
+
+          if (grid == this._results)
+            this.updateResults();
+        ]]>
+      </handler>
+
       <handler event="select">
         <![CDATA[
           let grid = event.originalTarget;
+
+          // If a selection was made on a different grid,
+          // remove selection from the current grid.
           if (grid != this._grid) {
-            if (this._grid.clearSelection)
-              this._grid.clearSelection();
-            this._grid = grid;
+            this._grid.clearSelection();
+            this._grid = this._otherGrid;
           }
-
-          if (this._handleOnSelect && this._results.selectedItem) {
-            BrowserUI.goToURI(
-              this._results.selectedItem.getAttribute("value"));
-            this.closePopup();
-          } else if (this._handleOnSelect) {
-            this.handleCompletion();
-          }
-        ]]>
-      </handler>
-
-      <handler event="contentgenerated">
-        <![CDATA[
-          let grid = event.originalTarget;
-          if (grid == this._searches)
-            this.updateSearchEngines();
         ]]>
       </handler>
     </handlers>
   </binding>
 </bindings>
--- a/browser/metro/base/content/browser-ui.js
+++ b/browser/metro/base/content/browser-ui.js
@@ -1,12 +1,13 @@
 // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
 
 Cu.import("resource://gre/modules/PageThumbs.jsm");
 Cu.import("resource://gre/modules/devtools/dbg-server.jsm")
 
 /**
  * Constants
  */
 
@@ -17,16 +18,23 @@ const TOOLBARSTATE_LOADED   = 2;
 
 // Page for which the start UI is shown
 const kStartOverlayURI = "about:start";
 
 // Devtools Messages
 const debugServerStateChanged = "devtools.debugger.remote-enabled";
 const debugServerPortChanged = "devtools.debugger.remote-port";
 
+// delay when showing the tab bar briefly after a new (empty) tab opens
+const kNewTabAnimationDelayMsec = 1000;
+// delay when showing the tab bar after opening a link on a new tab
+const kOpenInNewTabAnimationDelayMsec = 3000;
+// delay before closing tab bar after selecting another tab
+const kSelectTabAnimationDelayMsec = 500;
+
 /**
  * Cache of commonly used elements.
  */
 
 let Elements = {};
 [
   ["contentShowing",     "bcast_contentShowing"],
   ["urlbarState",        "bcast_urlbarState"],
@@ -69,19 +77,20 @@ var Strings = {};
   });
 });
 
 var BrowserUI = {
   get _edit() { return document.getElementById("urlbar-edit"); },
   get _back() { return document.getElementById("cmd_back"); },
   get _forward() { return document.getElementById("cmd_forward"); },
 
-  lastKnownGoodURL: "", //used when the user wants to escape unfinished url entry
+  lastKnownGoodURL: "", // used when the user wants to escape unfinished url entry
+  ready: false, // used for tests to determine when delayed initialization is done
+
   init: function() {
-
     // start the debugger now so we can use it on the startup code as well
     if (Services.prefs.getBoolPref(debugServerStateChanged)) {
       this.runDebugServer();
     }
     Services.prefs.addObserver(debugServerStateChanged, this, false);
     Services.prefs.addObserver(debugServerPortChanged, this, false);
 
     // listen content messages
@@ -95,58 +104,55 @@ var BrowserUI = {
 
     // listening escape to dismiss dialog on VK_ESCAPE
     window.addEventListener("keypress", this, true);
 
     window.addEventListener("MozPrecisePointer", this, true);
     window.addEventListener("MozImprecisePointer", this, true);
 
     Services.prefs.addObserver("browser.cache.disk_cache_ssl", this, false);
-    Services.prefs.addObserver("browser.urlbar.formatting.enabled", this, false);
-    Services.prefs.addObserver("browser.urlbar.trimURLs", this, false);
     Services.obs.addObserver(this, "metro_viewstate_changed", false);
-    
-    this._edit.inputField.controllers.insertControllerAt(0, this._copyCutURIController);
 
     // Init core UI modules
     ContextUI.init();
     StartUI.init();
     PanelUI.init();
     FlyoutPanelsUI.init();
     PageThumbs.init();
     SettingsCharm.init();
     NavButtonSlider.init();
 
     // show the right toolbars, awesomescreen, etc for the os viewstate
     BrowserUI._adjustDOMforViewState();
 
     // We can delay some initialization until after startup.  We wait until
     // the first page is shown, then dispatch a UIReadyDelayed event.
-    messageManager.addMessageListener("pageshow", function() {
+    messageManager.addMessageListener("pageshow", function onPageShow() {
       if (getBrowser().currentURI.spec == "about:blank")
         return;
 
-      messageManager.removeMessageListener("pageshow", arguments.callee, true);
+      messageManager.removeMessageListener("pageshow", onPageShow);
 
       setTimeout(function() {
         let event = document.createEvent("Events");
         event.initEvent("UIReadyDelayed", true, false);
         window.dispatchEvent(event);
+        BrowserUI.ready = true;
       }, 0);
     });
 
     // Only load IndexedDB.js when we actually need it. A general fix will happen in bug 647079.
     messageManager.addMessageListener("IndexedDB:Prompt", function(aMessage) {
       return IndexedDB.receiveMessage(aMessage);
     });
 
     // Delay the panel UI and Sync initialization
-    window.addEventListener("UIReadyDelayed", function(aEvent) {
+    window.addEventListener("UIReadyDelayed", function delayedInit(aEvent) {
       Util.dumpLn("* delay load started...");
-      window.removeEventListener(aEvent.type, arguments.callee, false);
+      window.removeEventListener("UIReadyDelayed",  delayedInit, false);
 
       // Login Manager and Form History initialization
       Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
       Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
 
       messageManager.addMessageListener("Browser:MozApplicationManifest", OfflineApps);
 
       try {
@@ -286,20 +292,32 @@ var BrowserUI = {
 #endif
   },
 
 
   /*********************************
    * Navigation
    */
 
+  /* Updates the overall state of the toolbar, but not the URL bar. */
   update: function(aState) {
+    let uri = this.getDisplayURI(Browser.selectedBrowser);
+    StartUI.update(uri);
+
+    this._updateButtons();
     this._updateToolbar();
   },
 
+  /* Updates the URL bar. */
+  updateURI: function(aOptions) {
+    let uri = this.getDisplayURI(Browser.selectedBrowser);
+    let cleanURI = Util.isURLEmpty(uri) ? "" : uri;
+    this._edit.value = cleanURI;
+  },
+
   getDisplayURI: function(browser) {
     let uri = browser.currentURI;
     let spec = uri.spec;
 
     try {
       spec = gURIFixup.createExposableURI(uri).spec;
     } catch (ex) {}
 
@@ -308,183 +326,77 @@ var BrowserUI = {
       let textToSubURI = Cc["@mozilla.org/intl/texttosuburi;1"].
                          getService(Ci.nsITextToSubURI);
       spec = textToSubURI.unEscapeNonAsciiURI(charset, spec);
     } catch (ex) {}
 
     return spec;
   },
 
-  /**
-    * Some prefs that have consequences in both Metro and Desktop such as
-    * app-update prefs, are automatically pulled from Desktop here.
-    */
-  _pullDesktopControlledPrefs: function() {
-    function pullDesktopControlledPrefType(prefType, prefFunc) {
-      try {
-        registry.create(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
-                      "Software\\Mozilla\\Firefox\\Metro\\Prefs\\" + prefType,
-                      Ci.nsIWindowsRegKey.ACCESS_ALL);
-        for (let i = 0; i < registry.valueCount; i++) {
-          let prefName = registry.getValueName(i);
-          let prefValue = registry.readStringValue(prefName);
-          if (prefType == Ci.nsIPrefBranch.PREF_BOOL) {
-            prefValue = prefValue == "true";
-          }
-          Services.prefs[prefFunc](prefName, prefValue);
-        }
-      } catch (ex) {
-        Util.dumpLn("Could not pull for prefType " + prefType + ": " + ex);
-      } finally {
-        registry.close();
-      }
-    }
-    let registry = Cc["@mozilla.org/windows-registry-key;1"].
-                   createInstance(Ci.nsIWindowsRegKey);
-    pullDesktopControlledPrefType(Ci.nsIPrefBranch.PREF_INT, "setIntPref");
-    pullDesktopControlledPrefType(Ci.nsIPrefBranch.PREF_BOOL, "setBoolPref");
-    pullDesktopControlledPrefType(Ci.nsIPrefBranch.PREF_STRING, "setCharPref");
-  },
-
-  /* Set the location to the current content */
-  updateURI: function(aOptions) {
-    aOptions = aOptions || {};
-
-    let uri = this.getDisplayURI(Browser.selectedBrowser);
-    let cleanURI = Util.isURLEmpty(uri) ? "" : uri;
-    this._setURI(cleanURI);
-
-    if ("captionOnly" in aOptions && aOptions.captionOnly)
-      return;
-
-    StartUI.update(uri);
-    this._updateButtons();
-    this._updateToolbar();
-  },
-
   goToURI: function(aURI) {
     aURI = aURI || this._edit.value;
     if (!aURI)
       return;
 
+    this._edit.value = aURI;
+
     // Make sure we're online before attempting to load
     Util.forceOnline();
 
     BrowserUI.showContent(aURI);
-    content.focus();
-    this._setURI(aURI);
+    Browser.selectedBrowser.focus();
 
     Task.spawn(function() {
       let postData = {};
       aURI = yield Browser.getShortcutOrURI(aURI, postData);
       Browser.loadURI(aURI, { flags: Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP, postData: postData });
 
       // Delay doing the fixup so the raw URI is passed to loadURIWithFlags
       // and the proper third-party fixup can be done
       let fixupFlags = Ci.nsIURIFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
       let uri = gURIFixup.createFixupURI(aURI, fixupFlags);
       gHistSvc.markPageAsTyped(uri);
 
       BrowserUI._titleChanged(Browser.selectedBrowser);
     });
   },
 
-  handleUrlbarEnter: function handleUrlbarEnter(aEvent) {
-    let url = this._edit.value;
-    if (aEvent instanceof KeyEvent)
-      url = this._canonizeURL(url, aEvent);
-    this.goToURI(url);
-  },
-
-  _canonizeURL: function _canonizeURL(aUrl, aTriggeringEvent) {
-    if (!aUrl)
-      return "";
-
-    // Only add the suffix when the URL bar value isn't already "URL-like",
-    // and only if we get a keyboard event, to match user expectations.
-    if (/^\s*[^.:\/\s]+(?:\/.*|\s*)$/i.test(aUrl)) {
-      let accel = aTriggeringEvent.ctrlKey;
-      let shift = aTriggeringEvent.shiftKey;
-      let suffix = "";
-
-      switch (true) {
-        case (accel && shift):
-          suffix = ".org/";
-          break;
-        case (shift):
-          suffix = ".net/";
-          break;
-        case (accel):
-          try {
-            suffix = gPrefService.getCharPref("browser.fixup.alternate.suffix");
-            if (suffix.charAt(suffix.length - 1) != "/")
-              suffix += "/";
-          } catch(e) {
-            suffix = ".com/";
-          }
-          break;
-      }
-
-      if (suffix) {
-        // trim leading/trailing spaces (bug 233205)
-        aUrl = aUrl.trim();
-
-        // Tack www. and suffix on.  If user has appended directories, insert
-        // suffix before them (bug 279035).  Be careful not to get two slashes.
-        let firstSlash = aUrl.indexOf("/");
-        if (firstSlash >= 0) {
-          aUrl = aUrl.substring(0, firstSlash) + suffix + aUrl.substring(firstSlash + 1);
-        } else {
-          aUrl = aUrl + suffix;
-        }
-        aUrl = "http://www." + aUrl;
-      }
-    }
-    return aUrl;
-  },
-
   doOpenSearch: function doOpenSearch(aName) {
     // save the current value of the urlbar
     let searchValue = this._edit.value;
+    let engine = Services.search.getEngineByName(aName);
+    let submission = engine.getSubmission(searchValue, null);
+
+    this._edit.value = submission.uri.spec;
 
     // Make sure we're online before attempting to load
     Util.forceOnline();
+
     BrowserUI.showContent();
+    Browser.selectedBrowser.focus();
 
-    let engine = Services.search.getEngineByName(aName);
-    let submission = engine.getSubmission(searchValue, null);
-    Browser.loadURI(submission.uri.spec, { postData: submission.postData });
+    Task.spawn(function () {
+      Browser.loadURI(submission.uri.spec, { postData: submission.postData });
 
-    // loadURI may open a new tab, so get the selectedBrowser afterward.
-    Browser.selectedBrowser.userTypedValue = submission.uri.spec;
-    this._titleChanged(Browser.selectedBrowser);
+      // loadURI may open a new tab, so get the selectedBrowser afterward.
+      Browser.selectedBrowser.userTypedValue = submission.uri.spec;
+      BrowserUI._titleChanged(Browser.selectedBrowser);
+    });
   },
 
   /*********************************
    * Tab management
    */
 
   newTab: function newTab(aURI, aOwner) {
     aURI = aURI || kStartOverlayURI;
     let tab = Browser.addTab(aURI, true, aOwner);
-    ContextUI.peekTabs();
     return tab;
   },
 
-  newOrSelectTab: function newOrSelectTab(aURI, aOwner) {
-    let tabs = Browser.tabs;
-    for (let i = 0; i < tabs.length; i++) {
-      if (tabs[i].browser.currentURI.spec == aURI) {
-        Browser.selectedTab = tabs[i];
-        return;
-      }
-    }
-    this.newTab(aURI, aOwner);
-  },
-
   setOnTabAnimationEnd: function setOnTabAnimationEnd(aCallback) {
     Elements.tabs.addEventListener("animationend", function onAnimationEnd() {
       Elements.tabs.removeEventListener("animationend", onAnimationEnd);
       aCallback();
     });
   },
 
   closeTab: function closeTab(aTab) {
@@ -497,19 +409,19 @@ var BrowserUI = {
     tabToClose.chromeTab.setAttribute("closing", "true");
 
     let wasCollapsed = !ContextUI.tabbarVisible;
     if (wasCollapsed) {
       ContextUI.displayTabs();
     }
 
     this.setOnTabAnimationEnd(function() {
-	    Browser.closeTab(tabToClose, { forceClose: true } );
-        if (wasCollapsed)
-          ContextUI.dismissTabsWithDelay(kNewTabAnimationDelayMsec);
+      Browser.closeTab(tabToClose, { forceClose: true } );
+      if (wasCollapsed)
+        ContextUI.dismissTabsWithDelay(kNewTabAnimationDelayMsec);
     });
   },
 
   /**
     * Re-open a closed tab.
     * @param aIndex
     *        The index of the tab (via nsSessionStore.getClosedTabData)
     * @returns a reference to the reopened tab.
@@ -541,17 +453,17 @@ var BrowserUI = {
   },
 
   selectTab: function selectTab(aTab) {
     Browser.selectedTab = aTab;
   },
 
   selectTabAndDismiss: function selectTabAndDismiss(aTab) {
     this.selectTab(aTab);
-    ContextUI.dismissTabs();
+    ContextUI.dismissTabsWithDelay(kSelectTabAnimationDelayMsec);
   },
 
   selectTabAtIndex: function selectTabAtIndex(aIndex) {
     // count backwards for aIndex < 0
     if (aIndex < 0)
       aIndex += Browser._tabs.length;
 
     if (aIndex >= 0 && aIndex < Browser._tabs.length)
@@ -616,37 +528,31 @@ var BrowserUI = {
 
   observe: function BrowserUI_observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case "nsPref:changed":
         switch (aData) {
           case "browser.cache.disk_cache_ssl":
             this._sslDiskCacheEnabled = Services.prefs.getBoolPref(aData);
             break;
-          case "browser.urlbar.formatting.enabled":
-            this._formattingEnabled = Services.prefs.getBoolPref(aData);
-            break;
-          case "browser.urlbar.trimURLs":
-            this._mayTrimURLs = Services.prefs.getBoolPref(aData);
-            break;
           case debugServerStateChanged:
             if (Services.prefs.getBoolPref(aData)) {
               this.runDebugServer();
             } else {
               this.stopDebugServer();
             }
             break;
           case debugServerPortChanged:
             this.changeDebugPort(Services.prefs.getIntPref(aData));
             break;
         }
         break;
       case "metro_viewstate_changed":
         this._adjustDOMforViewState();
-        let autocomplete = document.getElementById("start-autocomplete");
+        let autocomplete = document.getElementById("urlbar-autocomplete");
         if (aData == "snapped") {
           FlyoutPanelsUI.hide();
           // Order matters (need grids to get dimensions, etc), now
           // let snapped grid know to refresh/redraw
           Services.obs.notifyObservers(null, "metro_viewstate_dom_snapped", null);
           autocomplete.setAttribute("orient", "vertical");
         }
         else {
@@ -655,16 +561,47 @@ var BrowserUI = {
         break;
     }
   },
 
   /*********************************
    * Internal utils
    */
 
+  /**
+  * Some prefs that have consequences in both Metro and Desktop such as
+  * app-update prefs, are automatically pulled from Desktop here.
+  */
+  _pullDesktopControlledPrefs: function() {
+    function pullDesktopControlledPrefType(prefType, prefFunc) {
+      try {
+        registry.create(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
+                      "Software\\Mozilla\\Firefox\\Metro\\Prefs\\" + prefType,
+                      Ci.nsIWindowsRegKey.ACCESS_ALL);
+        for (let i = 0; i < registry.valueCount; i++) {
+          let prefName = registry.getValueName(i);
+          let prefValue = registry.readStringValue(prefName);
+          if (prefType == Ci.nsIPrefBranch.PREF_BOOL) {
+            prefValue = prefValue == "true";
+          }
+          Services.prefs[prefFunc](prefName, prefValue);
+        }
+      } catch (ex) {
+        Util.dumpLn("Could not pull for prefType " + prefType + ": " + ex);
+      } finally {
+        registry.close();
+      }
+    }
+    let registry = Cc["@mozilla.org/windows-registry-key;1"].
+                   createInstance(Ci.nsIWindowsRegKey);
+    pullDesktopControlledPrefType(Ci.nsIPrefBranch.PREF_INT, "setIntPref");
+    pullDesktopControlledPrefType(Ci.nsIPrefBranch.PREF_BOOL, "setBoolPref");
+    pullDesktopControlledPrefType(Ci.nsIPrefBranch.PREF_STRING, "setCharPref");
+  },
+
   _adjustDOMforViewState: function() {
     if (MetroUtils.immersive) {
       let currViewState = "";
       switch (MetroUtils.snappedState) {
         case Ci.nsIWinMetroUtils.fullScreenLandscape:
           currViewState = "landscape";
           break;
         case Ci.nsIWinMetroUtils.fullScreenPortrait:
@@ -722,214 +659,16 @@ var BrowserUI = {
     let isLoading = Browser.selectedTab.isLoading();
 
     if (isLoading && mode != "loading")
       Elements.urlbarState.setAttribute("mode", "loading");
     else if (!isLoading && mode != "edit")
       Elements.urlbarState.setAttribute("mode", "view");
   },
 
-  _trimURL: function _trimURL(aURL) {
-    // This function must not modify the given URL such that calling
-    // nsIURIFixup::createFixupURI with the result will produce a different URI.
-    return aURL /* remove single trailing slash for http/https/ftp URLs */
-               .replace(/^((?:http|https|ftp):\/\/[^/]+)\/$/, "$1")
-                /* remove http:// unless the host starts with "ftp\d*\." or contains "@" */
-               .replace(/^http:\/\/((?!ftp\d*\.)[^\/@]+(?:\/|$))/, "$1");
-  },
-
-  trimURL: function trimURL(aURL) {
-    return this.mayTrimURLs ? this._trimURL(aURL) : aURL;
-  },
-
-  _setURI: function _setURI(aURL) {
-    this._edit.value = aURL;
-    this.lastKnownGoodURL = aURL;
-  },
-
-  _getSelectedURIForClipboard: function _getSelectedURIForClipboard() {
-    // Grab the actual input field's value, not our value, which could include moz-action:
-    let inputVal = this._edit.inputField.value;
-    let selectedVal = inputVal.substring(this._edit.selectionStart, this._edit.electionEnd);
-
-    // If the selection doesn't start at the beginning or doesn't span the full domain or
-    // the URL bar is modified, nothing else to do here.
-    if (this._edit.selectionStart > 0 || this._edit.valueIsTyped)
-      return selectedVal;
-    // The selection doesn't span the full domain if it doesn't contain a slash and is
-    // followed by some character other than a slash.
-    if (!selectedVal.contains("/")) {
-      let remainder = inputVal.replace(selectedVal, "");
-      if (remainder != "" && remainder[0] != "/")
-        return selectedVal;
-    }
-
-    let uriFixup = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup);
-
-    let uri;
-    try {
-      uri = uriFixup.createFixupURI(inputVal, Ci.nsIURIFixup.FIXUP_FLAG_USE_UTF8);
-    } catch (e) {}
-    if (!uri)
-      return selectedVal;
-
-    // Only copy exposable URIs
-    try {
-      uri = uriFixup.createExposableURI(uri);
-    } catch (ex) {}
-
-    // If the entire URL is selected, just use the actual loaded URI.
-    if (inputVal == selectedVal) {
-      // ... but only if  isn't a javascript: or data: URI, since those
-      // are hard to read when encoded
-      if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) {
-        // Parentheses are known to confuse third-party applications (bug 458565).
-        selectedVal = uri.spec.replace(/[()]/g, function (c) escape(c));
-      }
-
-      return selectedVal;
-    }
-
-    // Just the beginning of the URL is selected, check for a trimmed value
-    let spec = uri.spec;
-    let trimmedSpec = this.trimURL(spec);
-    if (spec != trimmedSpec) {
-      // Prepend the portion that trimURL removed from the beginning.
-      // This assumes trimURL will only truncate the URL at
-      // the beginning or end (or both).
-      let trimmedSegments = spec.split(trimmedSpec);
-      selectedVal = trimmedSegments[0] + selectedVal;
-    }
-
-    return selectedVal;
-  },
-
-  _copyCutURIController: {
-    doCommand: function(aCommand) {
-      let urlbar = BrowserUI._edit;
-      let val = BrowserUI._getSelectedURIForClipboard();
-      if (!val)
-        return;
-
-      if (aCommand == "cmd_cut" && this.isCommandEnabled(aCommand)) {
-        let start = urlbar.selectionStart;
-        let end = urlbar.selectionEnd;
-        urlbar.inputField.value = urlbar.inputField.value.substring(0, start) +
-                                  urlbar.inputField.value.substring(end);
-        urlbar.selectionStart = urlbar.selectionEnd = start;
-      }
-
-      Cc["@mozilla.org/widget/clipboardhelper;1"]
-        .getService(Ci.nsIClipboardHelper)
-        .copyString(val, document);
-    },
-
-    supportsCommand: function(aCommand) {
-      switch (aCommand) {
-        case "cmd_copy":
-        case "cmd_cut":
-          return true;
-      }
-      return false;
-    },
-
-    isCommandEnabled: function(aCommand) {
-      let urlbar = BrowserUI._edit;
-      return this.supportsCommand(aCommand) &&
-             (aCommand != "cmd_cut" || !urlbar.readOnly) &&
-             urlbar.selectionStart < urlbar.selectionEnd;
-    },
-
-    onEvent: function(aEventName) {}
-  },
-
-  _editURI: function _editURI(aShouldDismiss) {
-    this._edit.focus();
-    this._edit.select();
-
-    Elements.urlbarState.setAttribute("mode", "edit");
-    StartUI.show();
-    if (aShouldDismiss) {
-      ContextUI.dismissTabs();
-    }
-  },
-
-  formatURI: function formatURI() {
-    if (!this.formattingEnabled ||
-        Elements.urlbarState.getAttribute("mode") == "edit")
-      return;
-
-    let controller = this._edit.editor.selectionController;
-    let selection = controller.getSelection(controller.SELECTION_URLSECONDARY);
-    selection.removeAllRanges();
-
-    let textNode = this._edit.editor.rootElement.firstChild;
-    let value = textNode.textContent;
-
-    let protocol = value.match(/^[a-z\d.+\-]+:(?=[^\d])/);
-    if (protocol &&
-        ["http:", "https:", "ftp:"].indexOf(protocol[0]) == -1)
-      return;
-    let matchedURL = value.match(/^((?:[a-z]+:\/\/)?(?:[^\/]+@)?)(.+?)(?::\d+)?(?:\/|$)/);
-    if (!matchedURL)
-      return;
-
-    let [, preDomain, domain] = matchedURL;
-    let baseDomain = domain;
-    let subDomain = "";
-    // getBaseDomainFromHost doesn't recognize IPv6 literals in brackets as IPs (bug 667159)
-    if (domain[0] != "[") {
-      try {
-        baseDomain = Services.eTLD.getBaseDomainFromHost(domain);
-        if (!domain.endsWith(baseDomain)) {
-          // getBaseDomainFromHost converts its resultant to ACE.
-          let IDNService = Cc["@mozilla.org/network/idn-service;1"]
-                           .getService(Ci.nsIIDNService);
-          baseDomain = IDNService.convertACEtoUTF8(baseDomain);
-        }
-      } catch (e) {}
-    }
-    if (baseDomain != domain) {
-      subDomain = domain.slice(0, -baseDomain.length);
-    }
-
-    let rangeLength = preDomain.length + subDomain.length;
-    if (rangeLength) {
-      let range = document.createRange();
-      range.setStart(textNode, 0);
-      range.setEnd(textNode, rangeLength);
-      selection.addRange(range);
-    }
-
-    let startRest = preDomain.length + domain.length;
-    if (startRest < value.length) {
-      let range = document.createRange();
-      range.setStart(textNode, startRest);
-      range.setEnd(textNode, value.length);
-      selection.addRange(range);
-    }
-  },
-
-  _clearURIFormatting: function _clearURIFormatting() {
-    if (!this.formattingEnabled)
-      return;
-
-    let controller = this._edit.editor.selectionController;
-    let selection = controller.getSelection(controller.SELECTION_URLSECONDARY);
-    selection.removeAllRanges();
-  },
-
-  _urlbarBlurred: function _urlbarBlurred() {
-    let state = Elements.urlbarState;
-    if (state.getAttribute("mode") == "edit")
-      state.removeAttribute("mode");
-    this._updateToolbar();
-    this.formatURI();
-  },
-
   _closeOrQuit: function _closeOrQuit() {
     // Close active dialog, if we have one. If not then close the application.
     if (!BrowserUI.isContentShowing()) {
       BrowserUI.showContent();
     } else {
       // Check to see if we should really close the window
       if (Browser.closing()) {
         window.close();
@@ -980,20 +719,17 @@ var BrowserUI = {
 
   // Checks if various different parts of the UI is visible and closes
   // them one at a time.
   handleEscape: function (aEvent) {
     aEvent.stopPropagation();
     aEvent.preventDefault();
 
     if (this._edit.popupOpen) {
-      this._edit.value = this.lastKnownGoodURL;
-      this._edit.closePopup();
-      StartUI.hide();
-      ContextUI.dismiss();
+      this._edit.endEditing(true);
       return;
     }
 
     // Check open popups
     if (DialogUI._popup) {
       DialogUI._hidePopup();
       return;
     }
@@ -1200,34 +936,16 @@ var BrowserUI = {
 
   get sslDiskCacheEnabled() {
     if (this._sslDiskCacheEnabled === null) {
       this._sslDiskCacheEnabled = Services.prefs.getBoolPref("browser.cache.disk_cache_ssl");
     }
     return this._sslDiskCacheEnabled;
   },
 
-  _formattingEnabled: null,
-
-  get formattingEnabled() {
-    if (this._formattingEnabled === null) {
-      this._formattingEnabled = Services.prefs.getBoolPref("browser.urlbar.formatting.enabled");
-    }
-    return this._formattingEnabled;
-  },
-
-  _mayTrimURLs: null,
-
-  get mayTrimURLs() {
-    if (this._mayTrimURLs === null) {
-      this._mayTrimURLs = Services.prefs.getBoolPref("browser.urlbar.trimURLs");
-    }
-    return this._mayTrimURLs;
-  },
-
   supportsCommand : function(cmd) {
     var isSupported = false;
     switch (cmd) {
       case "cmd_back":
       case "cmd_forward":
       case "cmd_reload":
       case "cmd_forceReload":
       case "cmd_stop":
@@ -1297,17 +1015,17 @@ var BrowserUI = {
       case "cmd_go":
         this.goToURI();
         break;
       case "cmd_home":
         this.goToURI(Browser.getHomePage());
         break;
       case "cmd_openLocation":
         ContextUI.displayNavbar();
-        this._editURI(true);
+        this._edit.beginEditing(true);
         break;
       case "cmd_addBookmark":
         ContextUI.displayNavbar();
         Appbar.onStarButton(true);
         break;
       case "cmd_bookmarks":
         PanelUI.show("bookmarks-container");
         break;
@@ -1327,17 +1045,18 @@ var BrowserUI = {
         // Only close one window
         this._closeOrQuit();
         break;
       case "cmd_close":
         this._closeOrQuit();
         break;
       case "cmd_newTab":
         this.newTab();
-        this._editURI(false);
+        this._edit.beginEditing(false);
+        ContextUI.peekTabs(kNewTabAnimationDelayMsec);
         break;
       case "cmd_closeTab":
         this.closeTab();
         break;
       case "cmd_undoCloseTab":
         this.undoCloseTab();
         break;
       case "cmd_sanitize":
@@ -1367,35 +1086,32 @@ var BrowserUI = {
   },
 
   crashReportingPrefChanged: function crashReportingPrefChanged(aState) {
     CrashReporter.submitReports = aState;
   }
 };
 
 var StartUI = {
-  get isVisible() { return this.isStartPageVisible || this.isFiltering; },
+  get isVisible() { return this.isStartPageVisible; },
   get isStartPageVisible() { return Elements.windowState.hasAttribute("startpage"); },
-  get isFiltering() { return Elements.windowState.hasAttribute("filtering"); },
 
   get maxResultsPerSection() {
     return Services.prefs.getIntPref("browser.display.startUI.maxresults");
   },
 
   sections: [
     "TopSitesStartView",
     "TopSitesSnappedView",
     "BookmarksStartView",
     "HistoryStartView",
     "RemoteTabsStartView"
   ],
 
   init: function init() {
-    Elements.startUI.addEventListener("autocompletestart", this, false);
-    Elements.startUI.addEventListener("autocompleteend", this, false);
     Elements.startUI.addEventListener("contextmenu", this, false);
     Elements.startUI.addEventListener("click", this, false);
     Elements.startUI.addEventListener("MozMousePixelScroll", this, false);
 
     this.sections.forEach(function (sectionName) {
       let section = window[sectionName];
       if (section.init)
         section.init();
@@ -1424,44 +1140,24 @@ var StartUI = {
     this.sections.forEach(function (sectionName) {
       let section = window[sectionName];
       if (section.show)
         section.show();
     });
     return true;
   },
 
-  /** Show the autocomplete popup */
-  filter: function filter() {
-    if (this.isFiltering)
-      return;
-
-    BrowserUI._edit.openPopup();
-    Elements.windowState.setAttribute("filtering", "true");
-  },
-
-  /** Hide the autocomplete popup */
-  unfilter: function unfilter() {
-    if (!this.isFiltering)
-      return;
-
-    BrowserUI._edit.closePopup();
-    Elements.windowState.removeAttribute("filtering");
-  },
-
   /** Hide the Firefox start page */
   hide: function hide(aURI) {
     aURI = aURI || Browser.selectedBrowser.currentURI.spec;
     if (!this.isStartPageVisible || this.isStartURI(aURI))
       return false;
 
     Elements.contentShowing.removeAttribute("disabled");
     Elements.windowState.removeAttribute("startpage");
-
-    this.unfilter();
     return true;
   },
 
   /** Is the current tab supposed to show the Firefox start page? */
   isStartURI: function isStartURI(aURI) {
     aURI = aURI || Browser.selectedBrowser.currentURI.spec;
     return aURI == kStartOverlayURI || aURI == "about:home";
   },
@@ -1483,22 +1179,16 @@ var StartUI = {
       // Advanced notice to CAO, so we can shuffle the nav bar in advance
       // of the keyboard transition.
       ContentAreaObserver.navBarWillBlur();
     }
   },
 
   handleEvent: function handleEvent(aEvent) {
     switch (aEvent.type) {
-      case "autocompletestart":
-        this.filter();
-        break;
-      case "autocompleteend":
-        this.unfilter();
-        break;
       case "contextmenu":
         let event = document.createEvent("Events");
         event.initEvent("MozEdgeUICompleted", true, false);
         window.dispatchEvent(event);
         break;
       case "click":
         this.onClick(aEvent);
         break;
--- a/browser/metro/base/content/browser.css
+++ b/browser/metro/base/content/browser.css
@@ -90,21 +90,21 @@ setting[type="menulist"] {
 }
 
 #chrome-selection-overlay,
 #content-selection-overlay {
   -moz-binding: url("chrome://browser/content/bindings/selectionoverlay.xml#selection-binding");
 }
 
 #urlbar-edit {
-  -moz-binding: url("chrome://browser/content/bindings/autocomplete.xml#autocomplete");
+  -moz-binding: url("chrome://browser/content/bindings/urlbar.xml#urlbar");
 }
 
-#start-autocomplete {
-  -moz-binding: url("chrome://browser/content/bindings/autocomplete.xml#autocomplete-popup");
+#urlbar-autocomplete {
+  -moz-binding: url("chrome://browser/content/bindings/urlbar.xml#urlbar-autocomplete");
 }
 
 richgrid {
   -moz-binding: url("chrome://browser/content/bindings/grid.xml#richgrid");
 }
 
 richgriditem {
   -moz-binding: url("chrome://browser/content/bindings/grid.xml#richgrid-item");
--- a/browser/metro/base/content/browser.js
+++ b/browser/metro/base/content/browser.js
@@ -569,16 +569,17 @@ var Browser = {
       tab.active = true;
 
     if (isFirstTab) {
       // Don't waste time at startup updating the whole UI; just display the URL.
       BrowserUI._titleChanged(browser);
     } else {
       // Update all of our UI to reflect the new tab's location
       BrowserUI.updateURI();
+      BrowserUI.update();
 
       let event = document.createEvent("Events");
       event.initEvent("TabSelect", true, false);
       event.lastTab = lastTab;
       tab.chromeTab.dispatchEvent(event);
     }
 
     tab.lastSelected = Date.now();
@@ -1573,17 +1574,17 @@ Tab.prototype = {
   },
 
   _copyHistoryFrom: function _copyHistoryFrom(tab) {
     let otherHistory = tab._browser._webNavigation.sessionHistory;
     let history = this._browser._webNavigation.sessionHistory;
 
     // Ensure that history is initialized
     history.QueryInterface(Ci.nsISHistoryInternal);
-    
+
     for (let i = 0, length = otherHistory.index; i <= length; i++)
       history.addEntry(otherHistory.getEntryAtIndex(i, false), true);
   },
 
   _loadUsingParams: function _loadUsingParams(aBrowser, aURI, aParams) {
     let flags = aParams.flags || Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
     let postData = ("postData" in aParams && aParams.postData) ? aParams.postData.value : null;
     let referrerURI = "referrerURI" in aParams ? aParams.referrerURI : null;
--- a/browser/metro/base/content/browser.xul
+++ b/browser/metro/base/content/browser.xul
@@ -174,17 +174,18 @@
     <key id="key_selectLastTab" oncommand="BrowserUI.selectTabAtIndex(-1);" key="9" modifiers="accel"/>
   </keyset>
 
   <stack id="stack" flex="1">
     <!-- Page Area -->
     <vbox id="page">
       <vbox id="tray" class="tray-toolbar" observes="bcast_windowState" >
         <!-- Tabs -->
-        <hbox id="tabs-container" observes="bcast_windowState">
+        <!-- onclick handler to work around bug 837242 -->
+        <hbox id="tabs-container" observes="bcast_windowState" onclick="void(0);">
           <box id="tabs" flex="1"
                 observes="bcast_preciseInput"
                 onselect="BrowserUI.selectTabAndDismiss(this);"
                 onclosetab="BrowserUI.closeTab(this);"/>
           <vbox id="tabs-controls">
             <toolbarbutton id="newtab-button" command="cmd_newTab" label="&newtab.label;"/>
           </vbox>
         </hbox>
@@ -223,18 +224,16 @@
               <label class="meta-section-title" value="&snappedBookmarksHeader.label;"
                 onclick="PanelUI.show('bookmarks-container');"/>
               <label class="meta-section-title" value="&snappedHistoryHeader.label;"
                 onclick="PanelUI.show('history-container');" inputProcessing="true"/>
               <label id="snappedRemoteTabsLabel" class="meta-section-title" value="&snappedRemoteTabsHeader.label;"
                 onclick="PanelUI.show('remotetabs-container');" inputProcessing="true"/>
             </scrollbox>
           </hbox>
-          <!-- Autocompletion interface -->
-          <box id="start-autocomplete" observes="bcast_windowState"/>
         </hbox>
       </vbox> <!-- end tray -->
 
       <!-- Content viewport -->
       <stack id="content-viewport">
         <deck id="browsers" flex="1" observes="bcast_preciseInput"/>
         <box id="vertical-scroller" class="scroller" orient="vertical" end="0" top="0"/>
         <box id="horizontal-scroller" class="scroller" orient="horizontal" left="0" bottom="0"/>
@@ -251,54 +250,58 @@
               observes="cmd_back"></html:div>
 
     <!-- Navbar -->
     <appbar id="navbar" mousethrough="never" observes="bcast_windowState">
       <hbox id="progress-container" layer="true">
         <hbox id="progress-control" />
       </hbox>
 
-      <!-- Main Toolbar -->
-      <toolbar id="toolbar" observes="bcast_windowState" flex="1">
-        <observes element="bcast_windowState" attribute="*"/>
-        <observes element="bcast_urlbarState" attribute="*"/>
+      <vbox id="toolbar-autocomplete" flex="1">
+        <!-- Autocomplete -->
+        <scrollbox flex="1">
+          <hbox id="urlbar-autocomplete" observes="bcast_windowState"/>
+        </scrollbox>
 
-        <toolbarbutton id="back-button" class="appbar-primary" command="cmd_back"/>
-        <toolbarbutton id="forward-button" class="appbar-primary" command="cmd_forward"/>
+        <!-- Main Toolbar -->
+        <toolbar id="toolbar" observes="bcast_windowState" flex="1">
+          <observes element="bcast_windowState" attribute="*"/>
+          <observes element="bcast_urlbarState" attribute="*"/>
+
+          <toolbarbutton id="back-button" class="appbar-primary" command="cmd_back"/>
+          <toolbarbutton id="forward-button" class="appbar-primary" command="cmd_forward"/>
 
-        <hbox id="urlbar-container" flex="1" observes="bcast_urlbarState">
-          <hbox id="urlbar" flex="1">
-            <box id="identity-box" role="button">
-              <hbox id="identity-box-inner" align="center" mousethrough="always">
-                <image id="identity-icon"/>
-              </hbox>
-            </box>
+          <hbox id="urlbar-container" flex="1" observes="bcast_urlbarState">
+            <hbox id="urlbar" flex="1">
+              <box id="identity-box" role="button">
+                <hbox id="identity-box-inner" align="center" mousethrough="always">
+                  <image id="identity-icon"/>
+                </hbox>
+              </box>
 
-            <textbox id="urlbar-edit"
-                     type="url"
-                     class="uri-element"
-                     autocompletesearch="history"
-                     autocompletepopup="start-autocomplete"
-                     completeselectedindex="true"
-                     placeholder="&urlbar.emptytext;"
-                     flex="1"
-                     onpaste="this.focus();"
-                     ontextentered="BrowserUI.handleUrlbarEnter(param);"
-                     onblur="BrowserUI._urlbarBlurred();"/>
+              <textbox id="urlbar-edit"
+                       type="url"
+                       class="uri-element"
+                       autocompletesearch="history"
+                       autocompletepopup="urlbar-autocomplete"
+                       completeselectedindex="true"
+                       placeholder="&urlbar.emptytext;"
+                       flex="1"/>
+            </hbox>
+
+            <toolbarbutton id="reload-button" oncommand="CommandUpdater.doCommand(event.shiftKey ? 'cmd_forceReload' : 'cmd_reload');"/>
+            <toolbarbutton id="stop-button" command="cmd_stop"/>
           </hbox>
 
-          <toolbarbutton id="reload-button" oncommand="CommandUpdater.doCommand(event.shiftKey ? 'cmd_forceReload' : 'cmd_reload');"/>
-          <toolbarbutton id="stop-button" command="cmd_stop"/>
-        </hbox>
-
-        <toolbarbutton id="download-button" oncommand="Appbar.onDownloadButton()"/>
-        <toolbarbutton id="star-button" class="appbar-primary" type="checkbox" oncommand="Appbar.onStarButton()"/>
-        <toolbarbutton id="pin-button" class="appbar-primary" type="checkbox" oncommand="Appbar.onPinButton()"/>
-        <toolbarbutton id="menu-button" class="appbar-primary" oncommand="Appbar.onMenuButton(event)"/>
-       </toolbar>
+          <toolbarbutton id="download-button" oncommand="Appbar.onDownloadButton()"/>
+          <toolbarbutton id="star-button" class="appbar-primary" type="checkbox" oncommand="Appbar.onStarButton()"/>
+          <toolbarbutton id="pin-button" class="appbar-primary" type="checkbox" oncommand="Appbar.onPinButton()"/>
+          <toolbarbutton id="menu-button" class="appbar-primary" oncommand="Appbar.onMenuButton(event)"/>
+        </toolbar>
+      </vbox>
     </appbar>
 
     <vbox id="panel-container" hidden="true" class="window-width window-height meta" observes="bcast_windowState">
       <hbox id="panel-header">
         <toolbarbutton id="panel-close-button" command="cmd_panel"/>
 
         <menulist id="panel-view-switcher" oncommand="PanelUI.switchPane(this.value);">
           <menupopup>
@@ -348,17 +351,17 @@
     </vbox>
 
     <!-- Find bar -->
     <appbar id="findbar" class="window-width findbar-box" orient="horizontal" pack="start">
       <textbox id="findbar-textbox" class="search-bar findbar-item" oncommand="FindHelperUI.search(this.value)" oninput="FindHelperUI.updateCommands(this.value);" type="search"/>
       <button class="findbar-item previous-button" command="cmd_findPrevious"/>
       <button class="findbar-item next-button" command="cmd_findNext"/>
       <spacer flex="1"/>
-      <button class="findbar-item close-button" command="cmd_findClose"/>
+      <button id="findbar-close" class="findbar-item close-button" command="cmd_findClose"/>
     </appbar>
 
     <!-- Context button bar -->
     <appbar id="contextappbar">
       <toolbar id="contextualactions-tray" flex="1">
         <toolbarbutton id="delete-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('delete')"/>
         <toolbarbutton id="restore-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('restore')"/>
         <toolbarbutton id="pin-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('pin')"/>
--- a/browser/metro/base/content/helperui/MenuUI.js
+++ b/browser/metro/base/content/helperui/MenuUI.js
@@ -333,43 +333,57 @@ var MenuControlUI = {
     this._menuPopup.hide();
   }
 };
 
 function MenuPopup(aPanel, aPopup) {
   this._panel = aPanel;
   this._popup = aPopup;
   this._wantTypeBehind = false;
+  this._willReshowPopup = false;
 
   window.addEventListener('MozAppbarShowing', this, false);
 }
 MenuPopup.prototype = {
   get _visible() { return !this._panel.hidden; },
   get _commands() { return this._popup.childNodes[0]; },
 
   show: function (aPositionOptions) {
-    if (this._visible)
-      return;
+    if (this._visible) {
+      this._willReshowPopup = true;
+      let self = this;
+      this._panel.addEventListener("transitionend", function () {
+        self._show(aPositionOptions);
+        self._panel.removeEventListener("transitionend", arguments.callee);
+      });
+    } else {
+      this._show(aPositionOptions);
+    }
+  },
 
+  _show: function (aPositionOptions) {
     window.addEventListener("keypress", this, true);
     window.addEventListener("mousedown", this, true);
     Elements.stack.addEventListener("PopupChanged", this, false);
     Elements.browsers.addEventListener("PanBegin", this, false);
 
     this._panel.hidden = false;
     this._position(aPositionOptions || {});
 
     let self = this;
     this._panel.addEventListener("transitionend", function () {
       self._panel.removeEventListener("transitionend", arguments.callee);
       self._panel.removeAttribute("showingfrom");
 
+      let eventName = self._willReshowPopup ? "popupmoved" : "popupshown";
       let event = document.createEvent("Events");
-      event.initEvent("popupshown", true, false);
-      document.dispatchEvent(event);
+      event.initEvent(eventName, true, false);
+      self._panel.dispatchEvent(event);
+
+      self._willReshowPopup = false;
     });
 
     let popupFrom = !aPositionOptions.bottomAligned ? "above" : "below";
     this._panel.setAttribute("showingfrom", popupFrom);
 
     // Ensure the panel actually gets shifted before getting animated
     setTimeout(function () {
       self._panel.setAttribute("showing", "true");
@@ -388,19 +402,21 @@ MenuPopup.prototype = {
     let self = this;
     this._panel.addEventListener("transitionend", function () {
       self._panel.removeEventListener("transitionend", arguments.callee);
       self._panel.removeAttribute("hiding");
       self._panel.hidden = true;
       self._popup.style.maxWidth = "none";
       self._popup.style.maxHeight = "none";
 
-      let event = document.createEvent("Events");
-      event.initEvent("popuphidden", true, false);
-      document.dispatchEvent(event);
+      if (!self._willReshowPopup) {
+        let event = document.createEvent("Events");
+        event.initEvent("popuphidden", true, false);
+        self._panel.dispatchEvent(event);
+      }
     });
 
     this._panel.setAttribute("hiding", "true");
     setTimeout(()=>this._panel.removeAttribute("showing"), 0);
   },
 
   _position: function _position(aPositionOptions) {
     let aX = aPositionOptions.xPos;
--- a/browser/metro/base/jar.mn
+++ b/browser/metro/base/jar.mn
@@ -16,17 +16,17 @@ chrome.jar:
   content/bindings/toggleswitch.xml            (content/bindings/toggleswitch.xml)
   content/bindings/browser.xml                 (content/bindings/browser.xml)
   content/bindings/browser.js                  (content/bindings/browser.js)
   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/arrowbox.xml                (content/bindings/arrowbox.xml)
   content/bindings/grid.xml                    (content/bindings/grid.xml)
-  content/bindings/autocomplete.xml            (content/bindings/autocomplete.xml)
+  content/bindings/urlbar.xml                  (content/bindings/urlbar.xml)
   content/bindings/appbar.xml                  (content/bindings/appbar.xml)
   content/bindings/flyoutpanel.xml             (content/bindings/flyoutpanel.xml)
   content/bindings/selectionoverlay.xml        (content/bindings/selectionoverlay.xml)
   content/bindings/cssthrobber.xml             (content/bindings/cssthrobber.xml)
   content/bindings/popup.xml                   (content/bindings/popup.xml)
 
 * content/flyouts/flyoutUI.js                  (content/flyouts/flyoutUI.js)
 * content/flyouts/aboutFlyout.js               (content/flyouts/aboutFlyout.js)
--- a/browser/metro/base/tests/mochitest/Makefile.in
+++ b/browser/metro/base/tests/mochitest/Makefile.in
@@ -7,24 +7,27 @@ topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 BROWSER_TESTS = \
   head.js \
+  browser_urlbar.js \
   browser_bookmarks.js \
   browser_canonizeURL.js \
   browser_context_menu_tests.js \
   browser_context_menu_tests_01.html \
   browser_context_menu_tests_02.html \
   browser_context_menu_tests_03.html \
   browser_context_ui.js \
   browser_downloads.js \
+  browser_findbar.js \
+  browser_findbar.html \
   browser_history.js \
   browser_onscreen_keyboard.js \
   browser_onscreen_keyboard.html \
   browser_prefs_ui.js \
   browser_remotetabs.js \
   browser_tabs.js \
   browser_test.js \
   browser_tiles.js \
@@ -55,16 +58,17 @@ BROWSER_TESTS += \
   $(NULL)
 endif
 
 BROWSER_TEST_RESOURCES = \
   res/image01.png \
   res/textblock01.html \
   res/textinput01.html \
   res/textarea01.html \
+  res/testEngine.xml \
   $(NULL)
 
 libs:: $(BROWSER_TESTS)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/$(relativesrcdir)
 
 libs:: $(BROWSER_TEST_RESOURCES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/$(relativesrcdir)/res
 
--- a/browser/metro/base/tests/mochitest/browser_canonizeURL.js
+++ b/browser/metro/base/tests/mochitest/browser_canonizeURL.js
@@ -11,11 +11,11 @@ function test() {
     ["example", {ctrlKey: true}, "http://www.example.com/"],
     ["example.org", {ctrlKey: true}, "example.org"],
     ["example", {shiftKey: true}, "http://www.example.net/"],
     ["example", {shiftKey: true, ctrlKey: true}, "http://www.example.org/"],
     ["  example  ", {ctrlKey: true}, "http://www.example.com/"],
     [" example/a ", {ctrlKey: true}, "http://www.example.com/a"]
   ];
   for (let [input, modifiers, result] of testcases) {
-    is(BrowserUI._canonizeURL(input, modifiers), result, input + " -> " + result);
+    is(BrowserUI._edit._canonizeURL(input, modifiers), result, input + " -> " + result);
   }
 }
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/tests/mochitest/browser_findbar.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8">
+    <title>Find bar tests</title>
+  </head>
+  <body>
+    <p>Find bar tests</title>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/tests/mochitest/browser_findbar.js
@@ -0,0 +1,56 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+function test() {
+  runTests();
+}
+
+gTests.push({
+  desc: "Access the find bar with the keyboard",
+  run: function() {
+    let tab = yield addTab(chromeRoot + "browser_findbar.html");
+    yield waitForCondition(() => BrowserUI.ready);
+    is(Elements.findbar.isShowing, false, "Find bar is hidden by default");
+
+    EventUtils.synthesizeKey("f", { accelKey: true });
+    yield waitForEvent(Elements.findbar, "transitionend");
+    is(Elements.findbar.isShowing, true, "Show find bar with Ctrl-F");
+
+    let textbox = document.getElementById("findbar-textbox");
+    is(textbox.value, "", "Find bar is empty");
+
+    EventUtils.sendString("bar");
+    is(textbox.value, "bar", "Type 'bar' into find bar");
+
+    EventUtils.synthesizeKey("VK_ESCAPE", { accelKey: true });
+    yield waitForEvent(Elements.findbar, "transitionend");
+    is(Elements.findbar.isShowing, false, "Hide find bar with Esc");
+
+    Browser.closeTab(tab);
+  }
+});
+
+gTests.push({
+  desc: "Show and hide the find bar with mouse",
+  run: function() {
+    let tab = yield addTab(chromeRoot + "browser_findbar.html");
+    yield waitForCondition(() => BrowserUI.ready);
+    is(Elements.findbar.isShowing, false, "Find bar is hidden by default");
+
+    ContextUI.displayNavbar();
+    EventUtils.sendMouseEvent({ type: "click" }, "menu-button");
+    EventUtils.sendMouseEvent({ type: "click" }, "context-findinpage");
+    yield waitForEvent(Elements.findbar, "transitionend");
+    is(Elements.findbar.isShowing, true, "Show find bar with menu item");
+
+    EventUtils.synthesizeMouse(document.getElementById("findbar-close"), 1, 1, {});
+    yield waitForEvent(Elements.findbar, "transitionend");
+    is(Elements.findbar.isShowing, false, "Hide find bar with close button");
+
+    Browser.closeTab(tab);
+  }
+});
--- a/browser/metro/base/tests/mochitest/browser_selection_urlbar.js
+++ b/browser/metro/base/tests/mochitest/browser_selection_urlbar.js
@@ -51,28 +51,51 @@ gTests.push({
     ok(SelectionHelperUI.isCaretUIVisible, "caret ui active");
 
     // to the right
     let xpos = SelectionHelperUI.caretMark.xPos;
     let ypos = SelectionHelperUI.caretMark.yPos + 10;
     var touchdrag = new TouchDragAndHold();
     yield touchdrag.start(gWindow, xpos, ypos, 900, ypos);
     yield waitForCondition(function () {
-      return getTrimmedSelection(edit).toString() == 
+      return getTrimmedSelection(edit).toString() ==
         "mochitests/content/metro/browser/metro/base/tests/mochitest/res/textblock01.html";
     }, kCommonWaitMs, kCommonPollMs);
     touchdrag.end();
     yield waitForMs(100);
 
     ok(SelectionHelperUI.isSelectionUIVisible, "selection ui active");
 
     // taps on the urlbar-edit leak a ClientRect property on the window
     delete window.r;
   },
 });
 
+gTests.push({
+  desc: "bug 887120 - tap & hold to paste into urlbar",
+  run: function bug887120_test() {
+    gWindow = window;
+
+    yield showNavBar();
+    let edit = document.getElementById("urlbar-edit");
+
+    SpecialPowers.clipboardCopyString("mozilla");
+    sendContextMenuClickToElement(window, edit);
+    yield waitForEvent(document, "popupshown");
+
+    ok(ContextMenuUI._menuPopup._visible, "is visible");
+    let paste = document.getElementById("context-paste");
+    ok(!paste.hidden, "paste item is visible");
+
+    sendElementTap(window, paste);
+    ok(edit.popup.popupOpen, "bug: popup should be showing");
+
+    delete window.r;
+  }
+});
+
 function test() {
   if (!isLandscapeMode()) {
     todo(false, "browser_selection_tests need landscape mode to run.");
     return;
   }
   runTests();
 }
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/tests/mochitest/browser_urlbar.js
@@ -0,0 +1,232 @@
+// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var gEdit = null;
+
+/*=============================================================================
+  Search engine mocking utilities
+=============================================================================*/
+
+var gEngine = null;
+
+const kSearchEngineName = "Foo";
+const kSearchEngineURI = chromeRoot + "res/testEngine.xml";
+
+/*
+ * addMockSearchDefault - adds a mock search engine to the top of the engine list.
+ */
+function addMockSearchDefault(aTimeoutMs) {
+  let deferred = Promise.defer();
+  let timeoutMs = aTimeoutMs || kDefaultWait;
+  let timerID = 0;
+
+  function engineAddObserver(aSubject, aTopic, aData) {
+    if (aData != "engine-added")
+      return;
+
+    gEngine = Services.search.getEngineByName(kSearchEngineName);
+    Services.obs.removeObserver(engineAddObserver, "browser-search-engine-modified");
+    clearTimeout(timerID);
+    gEngine.hidden = false;
+    ok(gEngine, "mock engine was added");
+    deferred.resolve();
+  }
+
+  if (gEngine) {
+    deferred.resolve();
+    return deferred.promise;
+  }
+
+  timerID = setTimeout(function ids_canceller() {
+    Services.obs.removeObserver(engineAddObserver, "browser-search-engine-modified");
+    deferred.reject(new Error("search add timeout"));
+  }, timeoutMs);
+
+  Services.obs.addObserver(engineAddObserver, "browser-search-engine-modified", false);
+  Services.search.addEngine(kSearchEngineURI, Ci.nsISearchEngine.DATA_XML,
+                            "data:image/x-icon,%00", false);
+  return deferred.promise;
+}
+
+/*
+ * removeMockSearchDefault - removes mock "Foo" search engine.
+ */
+
+function removeMockSearchDefault(aTimeoutMs) {
+  let deferred = Promise.defer();
+  let timeoutMs = aTimeoutMs || kDefaultWait;
+  let timerID = 0;
+
+  function engineRemoveObserver(aSubject, aTopic, aData) {
+    if (aData != "engine-removed")
+      return;
+
+    clearTimeout(timerID);
+    gEngine = null;
+    Services.obs.removeObserver(engineRemoveObserver, "browser-search-engine-modified");
+    deferred.resolve();
+  }
+
+  if (!gEngine) {
+    deferred.resolve();
+    return deferred.promise;
+  }
+
+  timerID = setTimeout(function ids_canceller() {
+    Services.obs.removeObserver(engineRemoveObserver, "browser-search-engine-modified");
+    deferred.reject(new Error("search remove timeout"));
+  }, timeoutMs);
+
+  Services.obs.addObserver(engineRemoveObserver, "browser-search-engine-modified", false);
+  Services.search.removeEngine(gEngine);
+  return deferred.promise;
+}
+
+/*=============================================================================
+  Test cases
+=============================================================================*/
+
+function test() {
+  runTests();
+}
+
+
+function setUp() {
+  if (!gEdit)
+    gEdit = document.getElementById("urlbar-edit");
+
+  yield addTab("about:start");
+  yield showNavBar();
+  yield waitForCondition(function () {
+    return StartUI.isStartPageVisible;
+  });
+}
+
+function tearDown() {
+  yield removeMockSearchDefault();
+  Browser.closeTab(Browser.selectedTab, { forceClose: true });
+  delete window.r;
+}
+
+gTests.push({
+  desc: "search engines update",
+  setUp: setUp,
+  tearDown: tearDown,
+  run: function testSearchEngine() {
+    // If the XBL hasn't initialized yet, open the popup so that it will.
+    if (gEdit.popup._searches == undefined) {
+      gEdit.openPopup();
+      gEdit.closePopup();
+    }
+
+    let numSearches = gEdit.popup._searches.itemCount;
+    function getEngineItem() {
+      return gEdit.popup._searches.querySelector("richgriditem[value="+kSearchEngineName+"]");
+    }
+
+    yield addMockSearchDefault();
+    ok(gEdit.popup._searches.itemCount == numSearches + 1, "added search engine count");
+    ok(getEngineItem(), "added search engine item");
+
+    yield removeMockSearchDefault();
+    ok(gEdit.popup._searches.itemCount == numSearches, "normal search engine count");
+    ok(!getEngineItem(), "added search engine item");
+  }
+});
+
+gTests.push({
+  desc: "display autocomplete while typing, handle enter",
+  setUp: setUp,
+  tearDown: tearDown,
+  run: function testUrlbarTyping() {
+    sendElementTap(window, gEdit);
+    ok(gEdit.isEditing, "focus urlbar: in editing mode");
+    ok(!gEdit.popup.popupOpen, "focus urlbar: popup not open yet");
+
+    EventUtils.sendString("about:blank", window);
+    let opened = yield waitForCondition(() => gEdit.popup.popupOpen);
+    ok(opened, "type in urlbar: popup opens");
+
+    EventUtils.synthesizeKey("VK_RETURN", {}, window);
+    let closed = yield waitForCondition(() => !gEdit.popup.popupOpen);
+    ok(closed, "hit enter in urlbar: popup closes, page loads");
+    ok(!gEdit.isEditing, "hit enter in urlbar: not in editing mode");
+  }
+});
+
+gTests.push({
+  desc: "display and select a search with keyboard",
+  setUp: setUp,
+  tearDown: tearDown,
+  run: function testSearchKeyboard() {
+    yield addMockSearchDefault();
+
+    sendElementTap(window, gEdit);
+    ok(gEdit.isEditing, "focus urlbar: in editing mode");
+    ok(!gEdit.popup.popupOpen, "focus urlbar: popup not open yet");
+
+    let search = "mozilla";
+    EventUtils.sendString(search, window);
+    yield waitForCondition(() => gEdit.popup.popupOpen);
+
+    // XXX We should probably change the keyboard selection behavior entirely,
+    // given that it makes little to no sense, but that's a job for a later patch.
+
+    EventUtils.synthesizeKey("VK_DOWN", {}, window);
+    is(gEdit.popup.selectedIndex, -1, "key select search: no result selected");
+    is(gEdit.popup._searches.selectedIndex, 0, "key select search: first search selected");
+
+    let engines = Services.search.getVisibleEngines();
+    for (let i = 0, max = engines.length - 1; i < max; i++) {
+      is(gEdit.popup._searches.selectedIndex, i, "key select search: next index");
+      EventUtils.synthesizeKey("VK_DOWN", {}, window);
+    }
+
+    let existingValue = gEdit.value;
+    EventUtils.synthesizeKey("VK_RETURN", {}, window);
+
+    yield waitForCondition(() => gEdit.value != existingValue);
+
+    let closed = yield waitForCondition(() => !gEdit.popup.popupOpen);
+    ok(closed, "hit enter in urlbar: popup closes, page loads");
+    ok(!gEdit.isEditing, "hit enter in urlbar: not in editing mode");
+
+    let searchSubmission = gEngine.getSubmission(search, null);
+    let trimmedSubmission = gEdit.trimValue(searchSubmission.uri.spec);
+    is(gEdit.value, trimmedSubmission, "hit enter in urlbar: search conducted");
+
+    yield removeMockSearchDefault();
+  }
+});
+
+gTests.push({
+  desc: "display and select a search with touch",
+  setUp: setUp,
+  tearDown: tearDown,
+  run: function testUrlbarSearchesTouch() {
+    yield addMockSearchDefault();
+
+    sendElementTap(window, gEdit);
+    ok(gEdit.isEditing, "focus urlbar: in editing mode");
+    ok(!gEdit.popup.popupOpen, "focus urlbar: popup not open yet");
+
+    let search = "mozilla";
+    EventUtils.sendString(search, window);
+    yield waitForCondition(() => gEdit.popup.popupOpen);
+
+    sendElementTap(window, gEdit.popup._searches.lastChild);
+
+    let closed = yield waitForCondition(() => !gEdit.popup.popupOpen);
+    ok(closed, "tap search option: popup closes, page loads");
+    ok(!gEdit.isEditing, "tap search option: not in editing mode");
+
+    let searchSubmission = gEngine.getSubmission(search, null);
+    let trimmedSubmission = gEdit.trimValue(searchSubmission.uri.spec);
+    is(gEdit.value, trimmedSubmission, "tap search option: search conducted");
+  }
+});
+
--- a/browser/metro/base/tests/mochitest/head.js
+++ b/browser/metro/base/tests/mochitest/head.js
@@ -703,18 +703,18 @@ TouchDragAndHold.prototype = {
     this._win = null;
   },
 };
 
 /*=============================================================================
   System utilities
 =============================================================================*/
 
- /*
- * emptyClipboard - clear the windows clipbaord.
+/*
+ * emptyClipboard - clear the windows clipboard.
  */
 function emptyClipboard() {
   Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard)
                                        .emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
 }
 
 /*
  * purgeEventQueue - purges the event queue on the calling thread.
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/tests/mochitest/res/testEngine.xml
@@ -0,0 +1,12 @@
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
+                       xmlns:moz="http://www.mozilla.org/2006/browser/search/">
+  <ShortName>Foo</ShortName>
+  <Description>Foo Search</Description>
+  <InputEncoding>utf-8</InputEncoding>
+  <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
+  <Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/?search">
+    <Param name="test" value="{searchTerms}"/>
+  </Url>
+  <moz:SearchForm>http://mochi.test:8888/browser/browser/components/search/test/</moz:SearchForm>
+  <moz:Alias>fooalias</moz:Alias>
+</OpenSearchDescription>
--- a/browser/metro/modules/Makefile.in
+++ b/browser/metro/modules/Makefile.in
@@ -3,10 +3,9 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH      = @DEPTH@
 topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/config/rules.mk
--- a/browser/metro/theme/browser.css
+++ b/browser/metro/theme/browser.css
@@ -243,17 +243,17 @@ documenttab[selected] .documenttab-selec
   padding: 0px;
   margin-top: -30px;
   margin-left: -18px;
   pointer-events: auto;
 }
 
 /* Toolbar ------------------------------------------------------------------ */
 
-#toolbar {
+#toolbar-autocomplete {
   background-color: @panel_light_color@;
 }
 
 #toolbar > #back-button {
   list-style-image: url(chrome://browser/skin/images/appbar-back.png);
   position: relative;
   z-index: 1;
   transition: opacity @forward_transition_length@ ease-out;
@@ -359,26 +359,26 @@ appbar {
   position: fixed;
   bottom: 0;
   width: 100%;
   transform: translateY(100%);
   transition: transform @metro_animation_duration@ @metro_animation_easing@;
   font-size: 0;
 }
 
-appbar > toolbar {
+appbar toolbar {
   -moz-appearance: none;
   -moz-box-align: center;
   border: 0;
   width: 100%;
   min-height: @toolbar_height@;
   font-size: 1rem;
 }
 
-appbar > toolbar > toolbarbutton {
+appbar toolbar > toolbarbutton {
   border: 0;
   margin: 0 @toolbar_horizontal_spacing@;
   padding: 0;
   /* Don't inherit background-color from toolbarbutton[checked="true"] */
   background-color: transparent;
 }
 
 appbar > toolbar > toolbarbutton[disabled] {
--- a/browser/metro/theme/platform.css
+++ b/browser/metro/theme/platform.css
@@ -189,37 +189,38 @@ menulist {
 }
 
 .menu-popup richlistitem {
   width: 100%;
   min-height: @touch_button_small@;
   min-width: @touch_action_minwidth@; /* keep the button from being too narrow */
   border: 0 none;
   -moz-box-align: center;
+  font-weight: 600;
 }
 
 .menu-popup richlistitem:not([disabled]):hover {
-  background-color: #dedad0;
+  background-color: #ccc;
   color: black;
 }
 
 .menu-popup richlistitem:not([disabled]):active {
-  background-color: @selected_color@ !important;
-  color: black;
+  background-color: black;
+  color: white;
 }
 
 .menu-popup > richlistbox[left-hand="true"] > richlistitem {
   padding-left: 50px;
 }
 
 .menu-popup > richlistbox[left-hand="false"] > richlistitem {
   padding-right: 50px;
 }
 
-/* form select popup */
+/* Additional styles applied to popups for form <select> elements. */
 
 #select-container {
   padding: 0;
   position: absolute;
   background-color: transparent;
 }
 
 #select-commands {
@@ -228,44 +229,44 @@ menulist {
   border: #000 solid @metro_border_thick@;
   display: -moz-box;
   -moz-user-focus: ignore;
   -moz-box-align: stretch;
   width: 100%;
 }
 
 /* listcell element doesn't have flex="1" so we need to force it */
-#select-commands .option-command > listcell {
+.option-command > listcell {
   -moz-box-flex: 1 !important;
 }
 
 .option-command {
   min-height: @touch_button_small@;
   min-width: @touch_action_minwidth@; /* keep the button from being too narrow */
   border: 0 none;
 }
 
 .option-command.selected {
-  background-color: @selected_color@ !important;
-  color: black;
+  background-color: #ff8000;
+  color: white;
 }
 
 .option-command.optgroup {
   font-weight: bold;
   font-style: italic;
   pointer-events: none;
 }
 
 .option-command:not([disabled]):hover {
-  background-color: #dedad0;
+  background-color: #f0f0f0;
   color: black;
 }
 
 .option-command:not([disabled]):active {
-  background-color: @selected_color@ !important;
+  background-color: #d3d3d3;
   color: black;
 }
 
 .select-popup > richlistbox > scrollbox {
   width: 100%;
   overflow-x: hidden !important;
 }
 
--- a/browser/modules/Social.jsm
+++ b/browser/modules/Social.jsm
@@ -157,16 +157,33 @@ this.Social = {
     }.bind(this));
 
     // Register an observer for changes to the provider list
     SocialService.registerProviderListener(function providerListener(topic, data) {
       // An engine change caused by adding/removing a provider should notify
       if (topic == "provider-added" || topic == "provider-removed") {
         this._updateProviderCache(data);
         Services.obs.notifyObservers(null, "social:providers-changed", null);
+        return;
+      }
+      if (topic == "provider-update") {
+        // a provider has self-updated its manifest, we need to update our
+        // cache and possibly reload if it was the current provider.
+        let provider = data;
+        SocialService.getOrderedProviderList(function(providers) {
+          Social._updateProviderCache(providers);
+          Services.obs.notifyObservers(null, "social:providers-changed", null);
+          // if we need a reload, do it now
+          if (provider.enabled) {
+            Social.enabled = false;
+            Services.tm.mainThread.dispatch(function() {
+              Social.enabled = true;
+            }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
+          }
+        });
       }
     }.bind(this));
   },
 
   // Called to update our cache of providers and set the current provider
   _updateProviderCache: function (providers) {
     this.providers = providers;
 
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -86,21 +86,16 @@ toolbarbutton.bookmark-item[open="true"]
   -moz-padding-end: 2px;
 }
 
 .bookmark-item > .toolbarbutton-icon {
   width: 16px;
   height: 16px;
 }
 
-#PlacesToolbarItems > .bookmark-item:not([image]):not([label=""]):not([container]) > .toolbarbutton-icon {
-  display: none;
-}
-
-
 /* Prevent [mode="icons"] from hiding the label */
 .bookmark-item > .toolbarbutton-text {
   display: -moz-box !important;
 }
 
 .bookmark-item > .toolbarbutton-menu-dropmarker {
   display: none;
 }
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -211,21 +211,16 @@ toolbarbutton.bookmark-item > menupopup 
 }
 
 .bookmark-item > .toolbarbutton-icon {
   width: 16px;
   min-height: 16px;
   max-height: 16px;
 }
 
-#PlacesToolbarItems > .bookmark-item:not([image]):not([label=""]):not([container]) > .toolbarbutton-icon {
-  display: none;
-}
-
-
 .bookmark-item > .toolbarbutton-icon[label]:not([label=""]),
 .bookmark-item > .toolbarbutton-icon[type="menu"] {
   -moz-margin-end: 5px;
 }
 
 .bookmark-item[container] {
   list-style-image: url("chrome://global/skin/tree/folder.png");
 }
--- a/browser/themes/shared/identity-block.inc.css
+++ b/browser/themes/shared/identity-block.inc.css
@@ -28,27 +28,27 @@
 %ifdef MOZ_OFFICIAL_BRANDING
   color: rgb(229,115,0);
   background-image: linear-gradient(rgba(229,114,0,0),
                                     rgba(229,114,0,.5) 35%,
                                     rgba(229,114,0,.5) 65%,
                                     rgba(229,114,0,0));
 %else
 %if MOZ_UPDATE_CHANNEL == aurora
-  color: hsl(214,90%,23%);
-  background-image: linear-gradient(hsla(208,99%,37%,0),
-                                    hsla(214,90%,23%,.5) 35%,
-                                    hsla(214,90%,23%,.5) 65%,
-                                    hsla(214,90%,23%,0));
+  color: rgb(51,30,84);
+  background-image: linear-gradient(rgba(51,30,84,0),
+                                    rgba(51,30,84,.5) 35%,
+                                    rgba(51,30,84,.5) 65%,
+                                    rgba(51,30,84,0));
 %else
-  color: hsl(211,33%,32%);
-  background-image: linear-gradient(hsla(211,33%,32%,0),
-                                    hsla(211,33%,32%,.5) 35%,
-                                    hsla(211,33%,32%,.5) 65%,
-                                    hsla(211,33%,32%,0));
+  color: rgb(0,33,71);
+  background-image: linear-gradient(rgba(0,33,71,0),
+                                    rgba(0,33,71,.5) 35%,
+                                    rgba(0,33,71,.5) 65%,
+                                    rgba(0,33,71,0));
 %endif
 %endif
 }
 
 /* page proxy icon */
 
 #page-proxy-favicon {
   width: 16px;
--- a/browser/themes/windows/browser-aero.css
+++ b/browser/themes/windows/browser-aero.css
@@ -85,16 +85,28 @@
     border-color: hsla(210,54%,20%,.35) hsla(210,54%,20%,.37) hsla(210,54%,20%,.4);
   }
 
   #navigator-toolbox[tabsontop=true] #urlbar:not(:-moz-lwtheme)[focused],
   #navigator-toolbox[tabsontop=true] .searchbar-textbox:not(:-moz-lwtheme)[focused] {
     border-color: hsla(206,100%,60%,.65) hsla(206,100%,55%,.65) hsla(206,100%,50%,.65);
   }
 
+  #sidebar-header {
+    -moz-appearance: none;
+    color: black;
+    background-color: #EEF3FA;
+    border-bottom: none;
+    text-shadow: none;
+  }
+
+  #sidebar-title {
+    font-weight: bold;
+  }
+
   .sidebar-splitter {
     border: 0;
     -moz-border-end: 1px solid #A9B7C9;
     min-width: 0;
     width: 3px;
     background-color: transparent;
     -moz-margin-start: -3px;
     position: relative;
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -607,20 +607,16 @@ toolbarbutton.bookmark-item[open="true"]
   -moz-padding-end: 2px;
 }
 
 .bookmark-item:not(#bookmarks-menu-button) > .toolbarbutton-icon {
   width: 16px;
   height: 16px;
 }
 
-#PlacesToolbarItems > .bookmark-item:not([image]):not([label=""]):not([container]) > .toolbarbutton-icon {
-  display: none;
-}
-
 /* Prevent [mode="icons"] from hiding the label */
 .bookmark-item > .toolbarbutton-text {
   display: -moz-box !important;
 }
 
 .bookmark-item > .toolbarbutton-menu-dropmarker {
   display: none;
 }
--- a/browser/themes/windows/places/places-aero.css
+++ b/browser/themes/windows/places/places-aero.css
@@ -10,9 +10,13 @@
   #history-panel {
     background-color: #EEF3FA;
   }
 
   .sidebar-placesTree {
     background-color: transparent;
     border-top: none;
   }
+
+  .sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
+    text-decoration: none;
+  }
 }
--- a/build/autoconf/android.m4
+++ b/build/autoconf/android.m4
@@ -239,37 +239,25 @@ if test "$OS_TARGET" = "Android" -a -z "
             elif test -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/libstdc++.a"; then
                 # android-ndk-r5c, android-ndk-r6, android-ndk-r6b
                 STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include"
                 STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/"
                 STLPORT_LIBS="-lstdc++"
             else
                 AC_MSG_ERROR([Couldn't find path to gnu-libstdc++ in the android ndk])
             fi
-        elif test -e "$android_ndk/sources/cxx-stl/stlport/src/iostream.cpp" ; then
-            if test -e "$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a"; then
-                STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
-            elif test -e "$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a"; then
-                STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
-            else
-                AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
-            fi
-            STLPORT_SOURCES="$android_ndk/sources/cxx-stl/stlport"
-            STLPORT_CPPFLAGS="-I$_objdir/build/stlport -I$android_ndk/sources/cxx-stl/stlport/stlport"
-            STLPORT_LIBS="-lstlport_static -static-libstdc++"
-        elif test "$target" != "arm-android-eabi"; then
-            dnl fail if we're not building with NDKr4
-            AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
+        else
+            STLPORT_CPPFLAGS="-I$_topsrcdir/build/stlport/stlport -I$android_ndk/sources/cxx-stl/system/include"
+            STLPORT_LIBS="$_objdir/build/stlport/libstlport_static.a -static-libstdc++"
         fi
     fi
     CXXFLAGS="$CXXFLAGS $STLPORT_CPPFLAGS"
-    LDFLAGS="$LDFLAGS $STLPORT_LDFLAGS"
-    LIBS="$LIBS $STLPORT_LIBS"
 fi
-AC_SUBST([STLPORT_SOURCES])
+AC_SUBST([MOZ_ANDROID_LIBSTDCXX])
+AC_SUBST([STLPORT_LIBS])
 
 ])
 
 AC_DEFUN([MOZ_ANDROID_SDK],
 [
 
 MOZ_ARG_WITH_STRING(android-sdk,
 [  --with-android-sdk=DIR
new file mode 100644
--- /dev/null
+++ b/build/compare-mozconfig/compare-mozconfigs-wrapper.py
@@ -0,0 +1,53 @@
+#!/usr/bin/python
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import subprocess
+import sys
+from os import path
+from buildconfig import substs
+
+def determine_platform():
+    platform_mapping = {'WINNT': {'x86_64': 'win64',
+                                  'i386': 'win32'},
+                        'Darwin': {'x86_64': 'macosx-universal',
+                                   'i386':'macosx-universal'},
+                        'Linux': {'x86_64': 'linux64',
+                                  'i386': 'linux32'}}
+
+    os_type = substs['OS_TARGET']
+    cpu_type = substs['TARGET_CPU']
+    return platform_mapping.get(os_type, {}).get(cpu_type, None)
+
+def main():
+    """ A wrapper script that calls compare-mozconfig.py
+    based on the platform that the machine is building for"""
+    platform = determine_platform()
+
+    if platform is not None:
+        python_exe = substs['PYTHON']
+        topsrcdir = substs['top_srcdir']
+
+        # construct paths and args for compare-mozconfig
+        browser_dir = path.join(topsrcdir, 'browser')
+        script_path = path.join(topsrcdir, 'build/compare-mozconfig/compare-mozconfigs.py')
+        whitelist_path = path.join(browser_dir, 'config/mozconfigs/whitelist')
+        beta_mozconfig_path = path.join(browser_dir, 'config/mozconfigs', platform, 'beta')
+        release_mozconfig_path = path.join(browser_dir, 'config/mozconfigs', platform, 'release')
+        nightly_mozconfig_path = path.join(browser_dir, 'config/mozconfigs', platform, 'nightly')
+
+        # compare beta vs nightly
+        ret_code = subprocess.call([python_exe, script_path, '--whitelist',
+                                    whitelist_path, '--no-download',
+                                    platform + ',' + beta_mozconfig_path +
+                                    ',' + nightly_mozconfig_path])
+
+        if ret_code > 0:
+            sys.exit(ret_code)
+
+        # compare release vs nightly
+        ret_code = subprocess.call([python_exe, script_path, '--whitelist',
+                                    whitelist_path, '--no-download',
+                                    platform + ',' + release_mozconfig_path +
+                                    ',' + nightly_mozconfig_path])
new file mode 100644
--- /dev/null
+++ b/build/compare-mozconfig/compare-mozconfigs.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+import logging
+import os
+import site
+import sys
+import urllib2
+
+site.addsitedir(os.path.join(os.path.dirname(__file__), "../../lib/python"))
+
+from release.sanity import verify_mozconfigs
+from release.info import readConfig
+from util.hg import make_hg_url
+
+FAILURE_CODE = 1
+SUCCESS_CODE = 0
+
+def get_mozconfig(path, options):
+    """Consumes a path and returns a list of lines from
+    the mozconfig file. If download is required, the path
+    specified should be relative to the root of the hg
+    repository e.g browser/config/mozconfigs/linux32/nightly"""
+    if options.no_download:
+        return open(path, 'r').readlines()
+    else:
+        url = make_hg_url(options.hghost, options.branch, 'http',
+                    options.revision, path)
+        return urllib2.urlopen(url).readlines()
+
+if __name__ == '__main__':
+    from optparse import OptionParser
+    parser = OptionParser()
+
+    parser.add_option('--branch', dest='branch')
+    parser.add_option('--revision', dest='revision')
+    parser.add_option('--hghost', dest='hghost', default='hg.mozilla.org')
+    parser.add_option('--whitelist', dest='whitelist')
+    parser.add_option('--no-download', action='store_true', dest='no_download',
+                      default=False)
+    options, args = parser.parse_args()
+
+    logging.basicConfig(level=logging.INFO)
+
+    missing_args = options.branch is None or options.revision is None
+    if not options.no_download and missing_args:
+        logging.error('Not enough arguments to download mozconfigs')
+        sys.exit(FAILURE_CODE)
+
+    mozconfig_whitelist = readConfig(options.whitelist, ['whitelist'])
+
+    for arg in args:
+        platform, mozconfig_path, nightly_mozconfig_path = arg.split(',')
+
+        mozconfig_lines = get_mozconfig(mozconfig_path, options)
+        nightly_mozconfig_lines = get_mozconfig(nightly_mozconfig_path, options)
+
+        mozconfig_pair = (mozconfig_path, mozconfig_lines)
+        nightly_mozconfig_pair = (nightly_mozconfig_path,
+                                  nightly_mozconfig_lines)
+
+        passed = verify_mozconfigs(mozconfig_pair, nightly_mozconfig_pair,
+                                   platform, mozconfig_whitelist)
+
+        if passed:
+            logging.info('Mozconfig check passed!')
+        else:
+            logging.error('Mozconfig check failed!')
+            sys.exit(FAILURE_CODE)
+    sys.exit(SUCCESS_CODE)
--- a/build/dumbmake-dependencies
+++ b/build/dumbmake-dependencies
@@ -14,18 +14,17 @@ toolkit/library
   widget
   gfx
   toolkit/components/build
     toolkit/components
   security/build
   security/manager
   security/dbm
   security/nss
-  accessible/build
-    accessible
+  accessible
   dom
   content
   layout
   editor
   parser
   js/src
     js/xpconnect
       js/xpconnect/loader
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -126,39 +126,46 @@ def bootstrap(topsrcdir, mozilla_dir=Non
     state_env_dir = os.environ.get('MOZBUILD_STATE_PATH', None)
     if state_env_dir:
         if not os.path.exists(state_env_dir):
             print('Creating global state directory from environment variable: %s'
                 % state_env_dir)
             os.makedirs(state_env_dir, mode=0o770)
             print('Please re-run mach.')
             sys.exit(1)
+        state_dir = state_env_dir
     else:
         if not os.path.exists(state_user_dir):
             print(STATE_DIR_FIRST_RUN.format(userdir=state_user_dir))
             try:
                 for i in range(20, -1, -1):
                     time.sleep(1)
                     sys.stdout.write('%d ' % i)
                     sys.stdout.flush()
             except KeyboardInterrupt:
                 sys.exit(1)
 
             print('\nCreating default state directory: %s' % state_user_dir)
             os.mkdir(state_user_dir)
             print('Please re-run mach.')
             sys.exit(1)
+        state_dir = state_user_dir
 
     try:
         import mach.main
     except ImportError:
         sys.path[0:0] = [os.path.join(mozilla_dir, path) for path in SEARCH_PATHS]
         import mach.main
 
+    def populate_context(context):
+        context.state_dir = state_dir
+
     mach = mach.main.Mach(topsrcdir)
+    mach.populate_context_handler = populate_context
+
     for category, meta in CATEGORIES.items():
         mach.define_category(category, meta['short'], meta['long'],
             meta['priority'])
 
     for path in MACH_MODULES:
         mach.load_commands_from_file(os.path.join(mozilla_dir, path))
 
     return mach
--- a/build/moz.build
+++ b/build/moz.build
@@ -4,17 +4,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 if CONFIG['OS_ARCH'] not in ('WINNT', 'OS2'):
     DIRS += ['unix']
 elif CONFIG['OS_ARCH'] == 'WINNT':
     DIRS += ['win32']
 
-if CONFIG['STLPORT_SOURCES']:
+if CONFIG['OS_TARGET'] == 'Android' and not CONFIG['MOZ_ANDROID_LIBSTDCXX']:
     DIRS += ['stlport']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     TEST_DIRS += [
         'mobile/sutagent/android',
         'mobile/sutagent/android/watcher',
         'mobile/sutagent/android/ffxcp',
         'mobile/sutagent/android/fencp',
new file mode 100644
--- /dev/null
+++ b/build/release/info.py
@@ -0,0 +1,218 @@
+from datetime import datetime
+import os
+from os import path
+import re
+import shutil
+import sys
+from urllib2 import urlopen
+
+from release.paths import makeCandidatesDir
+
+import logging
+log = logging.getLogger(__name__)
+
+# If version has two parts with no trailing specifiers like "rc", we
+# consider it a "final" release for which we only create a _RELEASE tag.
+FINAL_RELEASE_REGEX = "^\d+\.\d+$"
+
+
+class ConfigError(Exception):
+    pass
+
+
+def getBuildID(platform, product, version, buildNumber, nightlyDir='nightly',
+               server='stage.mozilla.org'):
+    infoTxt = makeCandidatesDir(product, version, buildNumber, nightlyDir,
+                                protocol='http', server=server) + \
+        '%s_info.txt' % platform
+    try:
+        buildInfo = urlopen(infoTxt).read()
+    except:
+        log.error("Failed to retrieve %s" % infoTxt)
+        raise
+
+    for line in buildInfo.splitlines():
+        key, value = line.rstrip().split('=', 1)
+        if key == 'buildID':
+            return value
+
+
+def findOldBuildIDs(product, version, buildNumber, platforms,
+                    nightlyDir='nightly', server='stage.mozilla.org'):
+    ids = {}
+    if buildNumber <= 1:
+        return ids
+    for n in range(1, buildNumber):
+        for platform in platforms:
+            if platform not in ids:
+                ids[platform] = []
+            try:
+                id = getBuildID(platform, product, version, n, nightlyDir,
+                                server)
+                ids[platform].append(id)
+            except Exception, e:
+                log.error("Hit exception: %s" % e)
+    return ids
+
+
+def getReleaseConfigName(product, branch, version=None, staging=False):
+    # XXX: Horrible hack for bug 842741. Because Thunderbird release
+    # and esr both build out of esr17 repositories we'll bump the wrong
+    # config for release without this.
+    if product == 'thunderbird' and 'esr17' in branch and version and 'esr' not in version:
+        cfg = 'release-thunderbird-comm-release.py'
+    else:
+        cfg = 'release-%s-%s.py' % (product, branch)
+    if staging:
+        cfg = 'staging_%s' % cfg
+    return cfg
+
+
+def readReleaseConfig(configfile, required=[]):
+    return readConfig(configfile, keys=['releaseConfig'], required=required)
+
+
+def readBranchConfig(dir, localconfig, branch, required=[]):
+    shutil.copy(localconfig, path.join(dir, "localconfig.py"))
+    oldcwd = os.getcwd()
+    os.chdir(dir)
+    sys.path.append(".")
+    try:
+        return readConfig("config.py", keys=['BRANCHES', branch],
+                          required=required)
+    finally:
+        os.chdir(oldcwd)
+        sys.path.remove(".")
+
+
+def readConfig(configfile, keys=[], required=[]):
+    c = {}
+    execfile(configfile, c)
+    for k in keys:
+        c = c[k]
+    items = c.keys()
+    err = False
+    for key in required:
+        if key not in items:
+            err = True
+            log.error("Required item `%s' missing from %s" % (key, c))
+    if err:
+        raise ConfigError("Missing at least one item in config, see above")
+    return c
+
+
+def isFinalRelease(version):
+    return bool(re.match(FINAL_RELEASE_REGEX, version))
+
+
+def getBaseTag(product, version):
+    product = product.upper()
+    version = version.replace('.', '_')
+    return '%s_%s' % (product, version)
+
+
+def getTags(baseTag, buildNumber, buildTag=True):
+    t = ['%s_RELEASE' % baseTag]
+    if buildTag:
+        t.append('%s_BUILD%d' % (baseTag, int(buildNumber)))
+    return t
+
+
+def getRuntimeTag(tag):
+    return "%s_RUNTIME" % tag
+
+
+def getReleaseTag(tag):
+    return "%s_RELEASE" % tag
+
+
+def generateRelbranchName(version, prefix='GECKO'):
+    return '%s%s_%s_RELBRANCH' % (
+        prefix, version.replace('.', ''),
+        datetime.now().strftime('%Y%m%d%H'))
+
+
+def getReleaseName(product, version, buildNumber):
+    return '%s-%s-build%s' % (product.title(), version, str(buildNumber))
+
+
+def getRepoMatchingBranch(branch, sourceRepositories):
+    for sr in sourceRepositories.values():
+        if branch in sr['path']:
+            return sr
+    return None
+
+
+def fileInfo(filepath, product):
+    """Extract information about a release file.  Returns a dictionary with the
+    following keys set:
+    'product', 'version', 'locale', 'platform', 'contents', 'format',
+    'pathstyle'
+
+    'contents' is one of 'complete', 'installer'
+    'format' is one of 'mar' or 'exe'
+    'pathstyle' is either 'short' or 'long', and refers to if files are all in
+        one directory, with the locale as part of the filename ('short' paths,
+        firefox 3.0 style filenames), or if the locale names are part of the
+        directory structure, but not the file name itself ('long' paths,
+        firefox 3.5+ style filenames)
+    """
+    try:
+        # Mozilla 1.9.0 style (aka 'short') paths
+        # e.g. firefox-3.0.12.en-US.win32.complete.mar
+        filename = os.path.basename(filepath)
+        m = re.match("^(%s)-([0-9.]+)\.([-a-zA-Z]+)\.(win32)\.(complete|installer)\.(mar|exe)$" % product, filename)
+        if not m:
+            raise ValueError("Could not parse: %s" % filename)
+        return {'product': m.group(1),
+                'version': m.group(2),
+                'locale': m.group(3),
+                'platform': m.group(4),
+                'contents': m.group(5),
+                'format': m.group(6),
+                'pathstyle': 'short',
+                'leading_path': '',
+                }
+    except:
+        # Mozilla 1.9.1 and on style (aka 'long') paths
+        # e.g. update/win32/en-US/firefox-3.5.1.complete.mar
+        #      win32/en-US/Firefox Setup 3.5.1.exe
+        ret = {'pathstyle': 'long'}
+        if filepath.endswith('.mar'):
+            ret['format'] = 'mar'
+            m = re.search("update/(win32|linux-i686|linux-x86_64|mac|mac64)/([-a-zA-Z]+)/(%s)-(\d+\.\d+(?:\.\d+)?(?:\w+(?:\d+)?)?)\.(complete)\.mar" % product, filepath)
+            if not m:
+                raise ValueError("Could not parse: %s" % filepath)
+            ret['platform'] = m.group(1)
+            ret['locale'] = m.group(2)
+            ret['product'] = m.group(3)
+            ret['version'] = m.group(4)
+            ret['contents'] = m.group(5)
+            ret['leading_path'] = ''
+        elif filepath.endswith('.exe'):
+            ret['format'] = 'exe'
+            ret['contents'] = 'installer'
+            # EUballot builds use a different enough style of path than others
+            # that we can't catch them in the same regexp
+            if filepath.find('win32-EUballot') != -1:
+                ret['platform'] = 'win32'
+                m = re.search("(win32-EUballot/)([-a-zA-Z]+)/((?i)%s) Setup (\d+\.\d+(?:\.\d+)?(?:\w+\d+)?(?:\ \w+\ \d+)?)\.exe" % product, filepath)
+                if not m:
+                    raise ValueError("Could not parse: %s" % filepath)
+                ret['leading_path'] = m.group(1)
+                ret['locale'] = m.group(2)
+                ret['product'] = m.group(3).lower()
+                ret['version'] = m.group(4)
+            else:
+                m = re.search("(partner-repacks/[-a-zA-Z0-9_]+/|)(win32|mac|linux-i686)/([-a-zA-Z]+)/((?i)%s) Setup (\d+\.\d+(?:\.\d+)?(?:\w+(?:\d+)?)?(?:\ \w+\ \d+)?)\.exe" % product, filepath)
+                if not m:
+                    raise ValueError("Could not parse: %s" % filepath)
+                ret['leading_path'] = m.group(1)
+                ret['platform'] = m.group(2)
+                ret['locale'] = m.group(3)
+                ret['product'] = m.group(4).lower()
+                ret['version'] = m.group(5)
+        else:
+            raise ValueError("Unknown filetype for %s" % filepath)
+
+        return ret
new file mode 100644
--- /dev/null
+++ b/build/release/sanity.py
@@ -0,0 +1,124 @@
+import difflib
+import logging
+import re
+import urllib2
+from util.commands import run_cmd, get_output
+from util.hg import get_repo_name, make_hg_url
+from subprocess import CalledProcessError
+
+log = logging.getLogger(__name__)
+
+
+def check_buildbot():
+    """check if buildbot command works"""
+    try:
+        run_cmd(['buildbot', '--version'])
+    except CalledProcessError:
+        log.error("FAIL: buildbot command doesn't work", exc_info=True)
+        raise
+
+
+def find_version(contents, versionNumber):
+    """Given an open readable file-handle look for the occurrence
+       of the version # in the file"""
+    ret = re.search(re.compile(re.escape(versionNumber), re.DOTALL), contents)
+    return ret
+
+
+def locale_diff(locales1, locales2):
+    """ accepts two lists and diffs them both ways, returns any differences
+    found """
+    diff_list = [locale for locale in locales1 if not locale in locales2]
+    diff_list.extend(locale for locale in locales2 if not locale in locales1)
+    return diff_list
+
+
+def get_buildbot_username_param():
+    cmd = ['buildbot', 'sendchange', '--help']
+    output = get_output(cmd)
+    if "-W, --who=" in output:
+        return "--who"
+    else:
+        return "--username"
+
+
+def sendchange(branch, revision, username, master, products):
+    """Send the change to buildbot to kick off the release automation"""
+    if isinstance(products, basestring):
+        products = [products]
+    cmd = [
+        'buildbot',
+        'sendchange',
+        get_buildbot_username_param(),
+        username,
+        '--master',
+        master,
+        '--branch',
+        branch,
+        '-p',
+        'products:%s' % ','.join(products),
+        '-p',
+        'script_repo_revision:%s' % revision,
+        'release_build'
+    ]
+    logging.info("Executing: %s" % cmd)
+    run_cmd(cmd)
+
+
+def verify_mozconfigs(mozconfig_pair, nightly_mozconfig_pair, platform,
+                      mozconfigWhitelist={}):
+    """Compares mozconfig to nightly_mozconfig and compare to an optional
+    whitelist of known differences. mozconfig_pair and nightly_mozconfig_pair
+    are pairs containing the mozconfig's identifier and the list of lines in
+    the mozconfig."""
+
+    # unpack the pairs to get the names, the names are just for
+    # identifying the mozconfigs when logging the error messages
+    mozconfig_name, mozconfig_lines = mozconfig_pair
+    nightly_mozconfig_name, nightly_mozconfig_lines = nightly_mozconfig_pair
+
+    missing_args = mozconfig_lines == [] or nightly_mozconfig_lines == []
+    if missing_args:
+        log.info("Missing mozconfigs to compare for %s" % platform)
+        return False
+
+    success = True
+
+    diffInstance = difflib.Differ()
+    diff_result = diffInstance.compare(mozconfig_lines, nightly_mozconfig_lines)
+    diffList = list(diff_result)
+
+    for line in diffList:
+        clean_line = line[1:].strip()
+        if (line[0] == '-' or line[0] == '+') and len(clean_line) > 1:
+            # skip comment lines
+            if clean_line.startswith('#'):
+                continue
+            # compare to whitelist
+            message = ""
+            if line[0] == '-':
+                if platform in mozconfigWhitelist.get('release', {}):
+                    if clean_line in \
+                            mozconfigWhitelist['release'][platform]:
+                        continue
+            elif line[0] == '+':
+                if platform in mozconfigWhitelist.get('nightly', {}):
+                    if clean_line in \
+                            mozconfigWhitelist['nightly'][platform]:
+                        continue
+                    else:
+                        log.warning("%s not in %s %s!" % (
+                            clean_line, platform,
+                            mozconfigWhitelist['nightly'][platform]))
+            else:
+                log.error("Skipping line %s!" % line)
+                continue
+            message = "found in %s but not in %s: %s"
+            if line[0] == '-':
+                log.error(message % (mozconfig_name,
+                                     nightly_mozconfig_name, clean_line))
+            else:
+                log.error(message % (nightly_mozconfig_name,
+                                     mozconfig_name, clean_line))
+            success = False
+    return success
new file mode 100644
--- /dev/null
+++ b/build/stlport/Android.mk
@@ -0,0 +1,115 @@
+LOCAL_PATH := $(call my-dir)
+
+# Normally, we distribute the NDK with prebuilt binaries of STLport
+# in $LOCAL_PATH/<abi>/. However,
+#
+
+STLPORT_FORCE_REBUILD := $(strip $(STLPORT_FORCE_REBUILD))
+ifndef STLPORT_FORCE_REBUILD
+  ifeq (,$(strip $(wildcard $(LOCAL_PATH)/libs/$(TARGET_ARCH_ABI)/libstlport_static.a)))
+    $(call __ndk_info,WARNING: Rebuilding STLport libraries from sources!)
+    $(call __ndk_info,You might want to use $$NDK/build/tools/build-stlport.sh)
+    $(call __ndk_info,in order to build prebuilt versions to speed up your builds!)
+    STLPORT_FORCE_REBUILD := true
+  endif
+endif
+
+libstlport_path := $(LOCAL_PATH)
+
+libstlport_src_files := \
+        src/dll_main.cpp \
+        src/fstream.cpp \
+        src/strstream.cpp \
+        src/sstream.cpp \
+        src/ios.cpp \
+        src/stdio_streambuf.cpp \
+        src/istream.cpp \
+        src/ostream.cpp \
+        src/iostream.cpp \
+        src/codecvt.cpp \
+        src/collate.cpp \
+        src/ctype.cpp \
+        src/monetary.cpp \
+        src/num_get.cpp \
+        src/num_put.cpp \
+        src/num_get_float.cpp \
+        src/num_put_float.cpp \
+        src/numpunct.cpp \
+        src/time_facets.cpp \
+        src/messages.cpp \
+        src/locale.cpp \
+        src/locale_impl.cpp \
+        src/locale_catalog.cpp \
+        src/facets_byname.cpp \
+        src/complex.cpp \
+        src/complex_io.cpp \
+        src/complex_trig.cpp \
+        src/string.cpp \
+        src/bitset.cpp \
+        src/allocators.cpp \
+        src/c_locale.c \
+        src/cxa.c \
+
+libstlport_cflags := -D_GNU_SOURCE
+libstlport_cppflags := -fuse-cxa-atexit
+libstlport_c_includes := $(libstlport_path)/stlport
+
+#It is much more practical to include the sources of GAbi++ in our builds
+# of STLport. This is similar to what the GNU libstdc++ does (it includes
+# its own copy of libsupc++)
+#
+# This simplifies usage, since you only have to list a single library
+# as a dependency, instead of two, especially when using the standalone
+# toolchain.
+#
+include $(dir $(LOCAL_PATH))/gabi++/sources.mk
+
+libstlport_c_includes += $(libgabi++_c_includes)
+
+ifneq ($(STLPORT_FORCE_REBUILD),true)
+
+$(call ndk_log,Using prebuilt STLport libraries)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := stlport_static
+LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).a
+LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_CPP_FEATURES := rtti
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := stlport_shared
+LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).so
+LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_CPP_FEATURES := rtti
+include $(PREBUILT_SHARED_LIBRARY)
+
+else # STLPORT_FORCE_REBUILD == true
+
+$(call ndk_log,Rebuilding STLport libraries from sources)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := stlport_static
+LOCAL_CPP_EXTENSION := .cpp .cc
+LOCAL_SRC_FILES := $(libstlport_src_files)
+LOCAL_SRC_FILES += $(libgabi++_src_files:%=../gabi++/%)
+LOCAL_CFLAGS := $(libstlport_cflags)
+LOCAL_CPPFLAGS := $(libstlport_cppflags)
+LOCAL_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_CPP_FEATURES := rtti exceptions
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := stlport_shared
+LOCAL_CPP_EXTENSION := .cpp .cc
+LOCAL_SRC_FILES := $(libstlport_src_files)
+LOCAL_SRC_FILES += $(libgabi++_src_files:%=../gabi++/%)
+LOCAL_CFLAGS := $(libstlport_cflags)
+LOCAL_CPPFLAGS := $(libstlport_cppflags)
+LOCAL_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_CPP_FEATURES := rtti exceptions
+include $(BUILD_SHARED_LIBRARY)
+
+endif # STLPORT_FORCE_REBUILD == true
new file mode 100644
--- /dev/null
+++ b/build/stlport/LICENSE
@@ -0,0 +1,27 @@
+Boris Fomitchev grants Licensee a non-exclusive, non-transferable, royalty-free license to use STLport and its documentation without fee.
+
+By downloading, using, or copying STLport or any portion thereof,  Licensee agrees to abide by the intellectual property laws and all other applicable laws of the United States of America, and to all of the terms and conditions of this Agreement.
+
+Licensee shall maintain the following copyright and permission  notices on STLport sources and its documentation unchanged :
+
+Copyright 1999,2000 Boris Fomitchev
+
+This material is provided "as is", with absolutely no warranty expressed or implied. Any use is at your own risk.
+Permission to use or copy this software for any purpose is hereby granted without fee, provided the above notices are retained on all copies. Permission to modify the code and to distribute modified code is granted, provided the above notices are retained, and a notice that the code was modified is included with the above copyright notice.
+The Licensee may distribute binaries compiled with STLport (whether original or modified) without any royalties or restrictions.
+
+The Licensee may distribute original or modified STLport sources, provided that:
+
+The conditions indicated in the above permission notice are met;
+The following copyright notices are retained when present, and conditions provided in accompanying permission notices are met :
+Copyright 1994 Hewlett-Packard Company
+
+Copyright 1996,97 Silicon Graphics Computer Systems, Inc.
+
+Copyright 1997 Moscow Center for SPARC Technology.
+
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Hewlett-Packard Company makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.
+
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Silicon Graphics makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.
+
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Moscow Center for SPARC Technology  makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.
new file mode 100644
--- a/build/stlport/Makefile.in
+++ b/build/stlport/Makefile.in
@@ -12,17 +12,17 @@ include $(DEPTH)/config/autoconf.mk
 MODULES = stlport
 FORCE_STATIC_LIB = 1
 STL_FLAGS =
 
 # Force to build a static library, instead of a fake library, without
 # installing it in dist/lib.
 LIBRARY = $(LIB_PREFIX)$(LIBRARY_NAME).$(LIB_SUFFIX)
 
-VPATH += $(STLPORT_SOURCES)/src
+VPATH += $(srcdir)/src
 
-CSRCS = $(notdir $(wildcard $(STLPORT_SOURCES)/src/*.c))
+CSRCS = $(notdir $(wildcard $(srcdir)/src/*.c))
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES += -D_GNU_SOURCE
 CXXFLAGS += -fuse-cxa-atexit
-INCLUDES += -I$(STLPORT_SOURCES)/stlport
+INCLUDES += -I$(srcdir)/stlport
new file mode 100644
--- /dev/null
+++ b/build/stlport/README
@@ -0,0 +1,69 @@
+STLport for Android
+
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+
+     This feature is currently in beta. In case of issue
+     please contact the android-ndk support forum or
+     file bugs at http://b.android.com
+
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+
+This directory contains a port of STLport for Android, which provides
+a simple STL implementation. Note that it currently does not support
+C++ exceptions and RTTI. Support for wchar_t and locales is probably buggy.
+
+You can either use it as a static or shared library.
+
+1/ The static library is recommended if you will only produce
+   one shared library for your project. All necessary STLport functions
+   will be added to it. This option should also generate smaller
+   overall binaries.
+
+2/ The shared library, is recommended if you want to produce
+   several shared libraries in your project, because it avoids copying the
+   same STLport functions to each one of them, and having different instances
+   of the same global variables (which can easily conflict or result in
+   undefined behaviour).
+
+To use the *static* library, define APP_STL in your Application.mk as follows:
+
+    APP_STL := stlport_static
+
+To use the *shared* library, use "stlport_shared" instead:
+
+    APP_STL := stlport_shared
+
+Note that, in this case, you will need, in your application, to explicitely
+load the 'stlport_shared' library before any library that depends on it.
+For example:
+
+    static {
+        System.loadLibrary("stlport_shared");
+        System.loadLibrary("foo");
+        System.loadLibrary("bar");
+    }
+
+If both libfoo.so and libbar.so depend on STLport.
+
+You can build the STLport unit test program by doing the following:
+
+  cd $NDK
+  tests/run-tests.sh --test=test-stlport
+
+If you have an Android device connected to your machine, this will
+automatically try to run the generated test command. Note that for now
+a few tests are still failing (mostly related to wchar_t and locales).
+
+They should be fixed hopefully by a later release of this library.
+
+The NDK comes with prebuilt binaries for this library to speed up development.
+You can however rebuild them from sources in your own application build by
+defining STLPORT_FORCE_REBUILD to 'true' in your Application.mk as in:
+
+    STLPORT_FORCE_REBUILD := true
+
+
+VERSION INFORMATION: This module is based on STLport version 5.2.0
+
new file mode 100644
--- /dev/null
+++ b/build/stlport/README.android
@@ -0,0 +1,9 @@
+Version: 5.2.1
+
+Changes:
+    * Added _android.h included by _system.h
+    * Do not use linux float functions in num_get_float.cpp as Android does not
+      have them.
+    * _mbstate_t.h cannot define its own mbstate_t as bionic already defines
+      it.
+    * _pair.h needs to define bionic's (sgi's) internal pair header guard.
new file mode 100644
--- /dev/null
+++ b/build/stlport/README.mozilla
@@ -0,0 +1,7 @@
+This copy of STLport was taken from the Android NDK r8e.
+Android specific changes are listed in README.android.
+The libs/ directory containing prebuilt static libraries was removed.
+
+The following patches are applied on top:
+- android-mozilla-config.patch: Adjusts Android-specific configuration
+  to the mozilla codebase use of the STL.
new file mode 100644
--- /dev/null
+++ b/build/stlport/README.original
@@ -0,0 +1,64 @@
+**********************************************************************
+* 	README file for STLport 5.0                                    *
+*                                                                    *
+**********************************************************************
+
+This directory contains the STLport-5.0 release.
+
+What's inside :
+
+README           - this file
+INSTALL          - installation instructions
+
+bin              - installation directory for STLport unit tests;
+                   it may contain more subdirs, if you use
+                   crosscompilation
+build/lib        - build directory for STLport library (if you use
+                   STLport iostreams and/or locale only)
+build/test/unit  - build directory for regression (unit) tests
+build/test/eh    - build directory for exception handling tests
+stlport          - main STLport include directory
+src              - source for iostreams implementation and other parts
+                   that aren't pure template code
+lib              - installation directory for STLport library (if you
+                   use STLport iostreams and/or locale only);
+                   it may contain more subdirs, if you use
+                   crosscompilation
+test/unit        - unit (regression) tests
+test/eh          - exception handling test using STLport iostreams
+etc              - miscellanous files (ChangeLog, TODO, scripts, etc.) 
+
+GETTING STLPORT
+
+To download the latest version of STLport, please be sure to visit
+https://sourceforge.net/project/showfiles.php?group_id=146814
+
+LEGALESE
+
+This software is being distributed under the following terms:
+
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Copyright (c) 1996-1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1997
+ * Moscow Center for SPARC Technology
+ *
+ * Copyright (c) 1999-2003
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted 
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+
+**********************************************************************
new file mode 100644
--- /dev/null
+++ b/build/stlport/android-mozilla-config.patch
@@ -0,0 +1,82 @@
+diff --git a/stlport/stl/config/_android.h b/stlport/stl/config/_android.h
+--- a/stlport/stl/config/_android.h
++++ b/stlport/stl/config/_android.h
+@@ -10,18 +10,18 @@
+ #define _PTHREADS
+ 
+ // Don't have native <cplusplus> headers
+ #define _STLP_HAS_NO_NEW_C_HEADERS 1
+ 
+ // Use unix for streams
+ #define _STLP_USE_UNIX_IO 1
+ 
+-// We do have rtti support now through GAbi++
+-#undef _STLP_NO_RTTI
++// We don't want rtti support
++#define _STLP_NO_RTTI 1
+ 
+ // C library is in the global namespace.
+ #define _STLP_VENDOR_GLOBAL_CSTD 1
+ 
+ // Don't have underlying local support.
+ #undef _STLP_REAL_LOCALE_IMPLEMENTED
+ 
+ // No pthread_spinlock_t in Android
+@@ -32,48 +32,42 @@
+ 
+ // Little endian platform.
+ #define _STLP_LITTLE_ENDIAN 1
+ 
+ // No <exception> headers
+ #undef _STLP_NO_EXCEPTION_HEADER
+ 
+ // No throwing exceptions
+-#undef _STLP_NO_EXCEPTIONS
+-
++#define _STLP_NO_EXCEPTIONS 1
++#define _STLP_NO_EXCEPTION_HEADER 1
+ 
+ // No need to define our own namespace
+ #define _STLP_NO_OWN_NAMESPACE 1
+ 
+ // Use __new_alloc instead of __node_alloc, so we don't need static functions.
+ #define _STLP_USE_SIMPLE_NODE_ALLOC 1
+ 
+ // Don't use extern versions of range errors, so we don't need to
+ // compile as a library.
+ #define _STLP_USE_NO_EXTERN_RANGE_ERRORS 1
+ 
+ // The system math library doesn't have long double variants, e.g
+ // sinl, cosl, etc
+ #define _STLP_NO_VENDOR_MATH_L 1
+ 
+-// Define how to include our native headers.
+-#define _STLP_NATIVE_HEADER(header) <usr/include/header>
+-#define _STLP_NATIVE_C_HEADER(header) <../include/header>
+-#define _STLP_NATIVE_CPP_C_HEADER(header) <../../gabi++/include/header>
+-#define _STLP_NATIVE_CPP_RUNTIME_HEADER(header) <../../gabi++/include/header>
+-#define _STLP_NATIVE_OLD_STREAMS_HEADER(header) <usr/include/header>
+-
+ // Include most of the gcc settings.
+ #include <stl/config/_gcc.h>
+ 
+ // Do not use glibc, Android is missing some things.
+ #undef _STLP_USE_GLIBC
+ 
+ // No exceptions.
+-#undef _STLP_NO_UNCAUGHT_EXCEPT_SUPPORT
+-#undef _STLP_NO_UNEXPECTED_EXCEPT_SUPPORT
++#define _STLP_NO_UNCAUGHT_EXCEPT_SUPPORT 1
++#define _STLP_NO_UNEXPECTED_EXCEPT_SUPPORT 1
+ 
+-#ifndef _ANDROID_NDK_BLAZE_
+-// Android does have include_next but it doesn't work well in our build system.
+-#undef _STLP_HAS_INCLUDE_NEXT
+-#endif
++#define _STLP_HAS_INCLUDE_NEXT 1
++
++// Use operator new instead of stlport own node allocator
++#undef _STLP_USE_NEWALLOC
++#define _STLP_USE_NEWALLOC 1
+ 
+ #endif /* __stl_config__android_h */
--- a/build/stlport/moz.build
+++ b/build/stlport/moz.build
@@ -1,14 +1,12 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-CONFIGURE_SUBST_FILES += ['stl/config/_android.h']
-
 CPP_SOURCES += [
-    '$(notdir $(wildcard $(STLPORT_SOURCES)/src/*.cpp))',
+    '$(notdir $(wildcard $(srcdir)/src/*.cpp))',
 ]
 
 LIBRARY_NAME = 'stlport_static'
 
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/_stdio_file.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#ifndef _STLP_STDIO_FILE_H
+#define _STLP_STDIO_FILE_H
+
+/* This file provides a low-level interface between the internal
+ * representation of struct FILE, from the C stdio library, and
+ * the C++ I/O library. */
+
+#ifndef _STLP_CSTDIO
+#  include <cstdio>
+#endif
+#ifndef _STLP_CSTDDEF
+#  include <cstddef>
+#endif
+
+#if defined (__MSL__)
+#  include <unix.h>  /* get the definition of fileno */
+#endif
+
+_STLP_BEGIN_NAMESPACE
+
+#if defined (_STLP_WCE)
+
+inline int _FILE_fd(const FILE *__f) {
+  /* Check if FILE is one of the three standard streams
+     We do this check first, because invoking _fileno() on one of them
+     causes a terminal window to be created. This also happens if you do
+     any IO on them, but merely retrieving the filedescriptor shouldn't
+     already do that.
+
+     Obviously this is pretty implementation-specific because it requires
+     that indeed the first three FDs are always the same, but that is not
+     only common but almost guaranteed. */
+  for (int __fd = 0; __fd != 3; ++__fd) {
+    if (__f == _getstdfilex(__fd))
+      return __fd;
+  }
+
+  /* Normal files. */
+  return (int)::_fileno((FILE*)__f); 
+}
+
+# elif defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
+
+inline int _FILE_fd(const FILE *__f) { return __f->__file; }
+
+# elif defined (__sun) && defined (_LP64)
+
+inline int _FILE_fd(const FILE *__f) { return (int) __f->__pad[2]; }
+
+#elif defined (__hpux) /* && defined(__hppa) && defined(__HP_aCC)) */ || \
+      defined (__MVS__) || \
+      defined (_STLP_USE_UCLIBC) /* should be before _STLP_USE_GLIBC */
+
+inline int _FILE_fd(const FILE *__f) { return fileno(__CONST_CAST(FILE*, __f)); }
+
+#elif defined (_STLP_USE_GLIBC)
+
+inline int _FILE_fd(const FILE *__f) { return __f->_fileno; }
+
+#elif defined (__BORLANDC__)
+
+inline int _FILE_fd(const FILE *__f) { return __f->fd; }
+
+#elif defined (__MWERKS__)
+
+/* using MWERKS-specific defines here to detect other OS targets
+ * dwa: I'm not sure they provide fileno for all OS's, but this should
+ * work for Win32 and WinCE
+
+ * Hmm, at least for Novell NetWare __dest_os == __mac_os true too..
+ * May be both __dest_os and __mac_os defined and empty?   - ptr */
+#  if __dest_os == __mac_os
+inline int _FILE_fd(const FILE *__f) { return ::fileno(__CONST_CAST(FILE*, __f)); }
+#  else
+inline int _FILE_fd(const FILE *__f) { return ::_fileno(__CONST_CAST(FILE*, __f)); }
+#  endif
+
+#elif defined (__QNXNTO__) || defined (__WATCOMC__) || defined (__EMX__)
+
+inline int _FILE_fd(const FILE *__f) { return __f->_handle; }
+
+#elif defined (__Lynx__)
+
+/* the prototypes are taken from LynxOS patch for STLport 4.0 */
+inline int _FILE_fd(const FILE *__f) { return __f->_fd; }
+
+#else  /* The most common access to file descriptor. */
+
+inline int _FILE_fd(const FILE *__f) { return __f->_file; }
+
+#endif
+
+_STLP_END_NAMESPACE
+
+#endif /* _STLP_STDIO_FILE_H */
+
+/* Local Variables:
+ * mode:C++
+ * End: */
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/acquire_release.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#ifndef ACQUIRE_RELEASE_H
+#define ACQUIRE_RELEASE_H
+
+#include "c_locale.h"
+
+_STLP_BEGIN_NAMESPACE
+_STLP_MOVE_TO_PRIV_NAMESPACE
+
+_Locale_ctype* _STLP_CALL __acquire_ctype(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+_Locale_codecvt* _STLP_CALL __acquire_codecvt(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+_Locale_numeric* _STLP_CALL __acquire_numeric(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+_Locale_collate* _STLP_CALL __acquire_collate(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+_Locale_monetary* _STLP_CALL __acquire_monetary(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+_Locale_time* _STLP_CALL __acquire_time(const char* &name, char *buf, _Locale_name_hint*, int *__err_code);
+_Locale_messages* _STLP_CALL __acquire_messages(const char* &name, char *buf, _Locale_name_hint* hint, int *__err_code);
+
+void _STLP_CALL __release_ctype(_Locale_ctype* cat);
+void _STLP_CALL __release_codecvt(_Locale_codecvt* cat);
+void _STLP_CALL __release_numeric(_Locale_numeric* cat);
+void _STLP_CALL __release_collate(_Locale_collate* cat);
+void _STLP_CALL __release_monetary(_Locale_monetary* cat);
+void _STLP_CALL __release_time(_Locale_time* __time);
+void _STLP_CALL __release_messages(_Locale_messages* cat);
+
+_STLP_MOVE_TO_STD_NAMESPACE
+_STLP_END_NAMESPACE
+
+#endif /* ACQUIRE_RELEASE_H */
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/aligned_buffer.h
@@ -0,0 +1,21 @@
+#ifndef ALIGNED_BUFFER_H
+#define ALIGNED_BUFFER_H
+
+_STLP_BEGIN_NAMESPACE
+// this is for fake initialization
+template<class T>
+union _Stl_aligned_buffer {
+  char buf[sizeof(T)];
+  struct { double a; double b; } padding;
+
+  T* operator&() {
+    return __REINTERPRET_CAST(T*, this);
+  }
+
+  T const* operator&() const {
+    return __REINTERPRET_CAST(T const*, this);
+  }
+};
+_STLP_END_NAMESPACE
+
+#endif
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/allocators.cpp
@@ -0,0 +1,1121 @@
+/*
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1997
+ * Moscow Center for SPARC Technology
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#include "stlport_prefix.h"
+
+#include <memory>
+
+#if defined (__GNUC__) && (defined (__CYGWIN__) || defined (__MINGW32__))
+#  include <malloc.h>
+#endif
+
+#if defined (_STLP_PTHREADS) && !defined (_STLP_NO_THREADS)
+#  include <pthread_alloc>
+#  include <cerrno>
+#endif
+
+#include <stl/_threads.h>
+
+#include "lock_free_slist.h"
+
+#if defined (__WATCOMC__)
+#  pragma warning 13 9
+#  pragma warning 367 9
+#  pragma warning 368 9
+#endif
+
+#if defined (_STLP_SGI_THREADS)
+  // We test whether threads are in use before locking.
+  // Perhaps this should be moved into stl_threads.h, but that
+  // probably makes it harder to avoid the procedure call when
+  // it isn't needed.
+extern "C" {
+  extern int __us_rsthread_malloc;
+}
+#endif
+
+// Specialised debug form of new operator which does not provide "false"
+// memory leaks when run with debug CRT libraries.
+#if defined (_STLP_MSVC) && (_STLP_MSVC >= 1020 && defined (_STLP_DEBUG_ALLOC)) && !defined (_STLP_WCE)
+#  include <crtdbg.h>
+inline char* __stlp_new_chunk(size_t __bytes) {
+  void *__chunk = _STLP_CHECK_NULL_ALLOC(::operator new(__bytes, __FILE__, __LINE__));
+  return __STATIC_CAST(char*, __chunk);
+}
+inline void __stlp_delete_chunck(void* __p) { ::operator delete(__p, __FILE__, __LINE__); }
+#else
+#  ifdef _STLP_NODE_ALLOC_USE_MALLOC
+#    include <cstdlib>
+inline char* __stlp_new_chunk(size_t __bytes) {
+  // do not use _STLP_CHECK_NULL_ALLOC, this macro is dedicated to new operator.
+  void *__chunk = _STLP_VENDOR_CSTD::malloc(__bytes);
+  if (__chunk == 0) {
+    _STLP_THROW_BAD_ALLOC;
+  }
+  return __STATIC_CAST(char*, __chunk);
+}
+inline void __stlp_delete_chunck(void* __p) { _STLP_VENDOR_CSTD::free(__p); }
+#  else
+inline char* __stlp_new_chunk(size_t __bytes)
+{ return __STATIC_CAST(char*, _STLP_STD::__stl_new(__bytes)); }
+inline void __stlp_delete_chunck(void* __p) { _STLP_STD::__stl_delete(__p); }
+#  endif
+#endif
+
+/* This is an additional atomic operations to the ones already defined in
+ * stl/_threads.h, platform should try to support it to improve performance.
+ * __add_atomic_t _STLP_ATOMIC_ADD(volatile __add_atomic_t* __target, __add_atomic_t __val) :
+ * does *__target = *__target + __val and returns the old *__target value */
+typedef long __add_atomic_t;
+typedef unsigned long __uadd_atomic_t;
+
+#if defined (__GNUC__) && defined (__i386__)
+inline long _STLP_atomic_add_gcc_x86(long volatile* p, long addend) {
+  long result;
+  __asm__ __volatile__
+    ("lock; xaddl %1, %0;"
+    :"=m" (*p), "=r" (result)
+    :"m"  (*p), "1"  (addend)
+    :"cc");
+ return result + addend;
+}
+#  define _STLP_ATOMIC_ADD(__dst, __val)  _STLP_atomic_add_gcc_x86(__dst, __val)
+#elif defined (_STLP_WIN32THREADS)
+// The Win32 API function InterlockedExchangeAdd is not available on Windows 95.
+#  if !defined (_STLP_WIN95_LIKE)
+#    if defined (_STLP_NEW_PLATFORM_SDK)
+#      define _STLP_ATOMIC_ADD(__dst, __val) InterlockedExchangeAdd(__dst, __val)
+#    else
+#      define _STLP_ATOMIC_ADD(__dst, __val) InterlockedExchangeAdd(__CONST_CAST(__add_atomic_t*, __dst), __val)
+#    endif
+#  endif
+#endif
+
+#if defined (__OS400__)
+// dums 02/05/2007: is it really necessary ?
+enum { _ALIGN = 16, _ALIGN_SHIFT = 4 };
+#else
+enum { _ALIGN = 2 * sizeof(void*), _ALIGN_SHIFT = 2 + sizeof(void*) / 4 };
+#endif
+
+#define _S_FREELIST_INDEX(__bytes) ((__bytes - size_t(1)) >> (int)_ALIGN_SHIFT)
+
+_STLP_BEGIN_NAMESPACE
+
+// malloc_alloc out-of-memory handling
+static __oom_handler_type __oom_handler = __STATIC_CAST(__oom_handler_type, 0);
+
+#ifdef _STLP_THREADS
+_STLP_mutex __oom_handler_lock;
+#endif
+
+void* _STLP_CALL __malloc_alloc::allocate(size_t __n)
+{
+  void *__result = malloc(__n);
+  if ( 0 == __result ) {
+    __oom_handler_type __my_malloc_handler;
+
+    for (;;) {
+      {
+#ifdef _STLP_THREADS
+        _STLP_auto_lock _l( __oom_handler_lock );
+#endif
+        __my_malloc_handler = __oom_handler;
+      }
+      if ( 0 == __my_malloc_handler) {
+        _STLP_THROW_BAD_ALLOC;
+      }
+      (*__my_malloc_handler)();
+      __result = malloc(__n);
+      if ( __result )
+        return __result;
+    }
+  }
+  return __result;
+}
+
+__oom_handler_type _STLP_CALL __malloc_alloc::set_malloc_handler(__oom_handler_type __f)
+{
+#ifdef _STLP_THREADS
+  _STLP_auto_lock _l( __oom_handler_lock );
+#endif
+  __oom_handler_type __old = __oom_handler;
+  __oom_handler = __f;
+  return __old;
+}
+
+// *******************************************************
+// Default node allocator.
+// With a reasonable compiler, this should be roughly as fast as the
+// original STL class-specific allocators, but with less fragmentation.
+//
+// Important implementation properties:
+// 1. If the client request an object of size > _MAX_BYTES, the resulting
+//    object will be obtained directly from malloc.
+// 2. In all other cases, we allocate an object of size exactly
+//    _S_round_up(requested_size).  Thus the client has enough size
+//    information that we can return the object to the proper free list
+//    without permanently losing part of the object.
+//
+
+#define _STLP_NFREELISTS 16
+
+#if defined (_STLP_LEAKS_PEDANTIC) && defined (_STLP_USE_DYNAMIC_LIB)
+/*
+ * We can only do cleanup of the node allocator memory pool if we are
+ * sure that the STLport library is used as a shared one as it guaranties
+ * the unicity of the node allocator instance. Without that guaranty node
+ * allocator instances might exchange memory blocks making the implementation
+ * of a cleaning process much more complicated.
+ */
+#  define _STLP_DO_CLEAN_NODE_ALLOC
+#endif
+
+/* When STLport is used without multi threaded safety we use the node allocator
+ * implementation with locks as locks becomes no-op. The lock free implementation
+ * always use system specific atomic operations which are slower than 'normal'
+ * ones.
+ */
+#if defined (_STLP_THREADS) && \
+    defined (_STLP_HAS_ATOMIC_FREELIST) && defined (_STLP_ATOMIC_ADD)
+/*
+ * We have an implementation of the atomic freelist (_STLP_atomic_freelist)
+ * for this architecture and compiler.  That means we can use the non-blocking
+ * implementation of the node-allocation engine.*/
+#  define _STLP_USE_LOCK_FREE_IMPLEMENTATION
+#endif
+
+#if !defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+#  if defined (_STLP_THREADS)
+
+class _Node_Alloc_Lock {
+  static _STLP_STATIC_MUTEX& _S_Mutex() {
+    static _STLP_STATIC_MUTEX mutex _STLP_MUTEX_INITIALIZER;
+    return mutex;
+  }
+public:
+  _Node_Alloc_Lock() {
+#    if defined (_STLP_SGI_THREADS)
+    if (__us_rsthread_malloc)
+#    endif
+      _S_Mutex()._M_acquire_lock();
+  }
+
+  ~_Node_Alloc_Lock() {
+#    if defined (_STLP_SGI_THREADS)
+    if (__us_rsthread_malloc)
+#    endif
+      _S_Mutex()._M_release_lock();
+  }
+};
+
+#  else
+
+class _Node_Alloc_Lock {
+public:
+  _Node_Alloc_Lock() { }
+  ~_Node_Alloc_Lock() { }
+};
+
+#  endif
+
+struct _Node_alloc_obj {
+  _Node_alloc_obj * _M_next;
+};
+#endif
+
+class __node_alloc_impl {
+  static inline size_t _STLP_CALL _S_round_up(size_t __bytes)
+  { return (((__bytes) + (size_t)_ALIGN-1) & ~((size_t)_ALIGN - 1)); }
+
+#if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+  typedef _STLP_atomic_freelist::item   _Obj;
+  typedef _STLP_atomic_freelist         _Freelist;
+  typedef _STLP_atomic_freelist         _ChunkList;
+
+  // Header of blocks of memory that have been allocated as part of
+  // a larger chunk but have not yet been chopped up into nodes.
+  struct _FreeBlockHeader : public _STLP_atomic_freelist::item {
+    char* _M_end;     // pointer to end of free memory
+  };
+#else
+  typedef _Node_alloc_obj       _Obj;
+  typedef _Obj* _STLP_VOLATILE  _Freelist;
+  typedef _Obj*                 _ChunkList;
+#endif
+
+private:
+  // Returns an object of size __n, and optionally adds to size __n free list.
+  static _Obj* _S_refill(size_t __n);
+  // Allocates a chunk for nobjs of size __p_size.  nobjs may be reduced
+  // if it is inconvenient to allocate the requested number.
+  static char* _S_chunk_alloc(size_t __p_size, int& __nobjs);
+  // Chunk allocation state.
+  static _Freelist _S_free_list[_STLP_NFREELISTS];
+  // Amount of total allocated memory
+#if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+  static _STLP_VOLATILE __add_atomic_t _S_heap_size;
+#else
+  static size_t _S_heap_size;
+#endif
+
+#if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+  // List of blocks of free memory
+  static _STLP_atomic_freelist  _S_free_mem_blocks;
+#else
+  // Start of the current free memory buffer
+  static char* _S_start_free;
+  // End of the current free memory buffer
+  static char* _S_end_free;
+#endif
+
+#if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+public:
+  // Methods to report alloc/dealloc calls to the counter system.
+#  if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+  typedef _STLP_VOLATILE __stl_atomic_t _AllocCounter;
+#  else
+  typedef __stl_atomic_t _AllocCounter;
+#  endif
+  static _AllocCounter& _STLP_CALL _S_alloc_counter();
+  static void _S_alloc_call();
+  static void _S_dealloc_call();
+
+private:
+  // Free all the allocated chuncks of memory
+  static void _S_chunk_dealloc();
+  // Beginning of the linked list of allocated chunks of memory
+  static _ChunkList _S_chunks;
+#endif /* _STLP_DO_CLEAN_NODE_ALLOC */
+
+public:
+  /* __n must be > 0      */
+  static void* _M_allocate(size_t& __n);
+  /* __p may not be 0 */
+  static void _M_deallocate(void *__p, size_t __n);
+};
+
+#if !defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+void* __node_alloc_impl::_M_allocate(size_t& __n) {
+  __n = _S_round_up(__n);
+  _Obj * _STLP_VOLATILE * __my_free_list = _S_free_list + _S_FREELIST_INDEX(__n);
+  _Obj *__r;
+
+  // Acquire the lock here with a constructor call.
+  // This ensures that it is released in exit or during stack
+  // unwinding.
+  _Node_Alloc_Lock __lock_instance;
+
+  if ( (__r  = *__my_free_list) != 0 ) {
+    *__my_free_list = __r->_M_next;
+  } else {
+    __r = _S_refill(__n);
+  }
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  _S_alloc_call();
+#  endif
+  // lock is released here
+  return __r;
+}
+
+void __node_alloc_impl::_M_deallocate(void *__p, size_t __n) {
+  _Obj * _STLP_VOLATILE * __my_free_list = _S_free_list + _S_FREELIST_INDEX(__n);
+  _Obj * __pobj = __STATIC_CAST(_Obj*, __p);
+
+  // acquire lock
+  _Node_Alloc_Lock __lock_instance;
+  __pobj->_M_next = *__my_free_list;
+  *__my_free_list = __pobj;
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  _S_dealloc_call();
+#  endif
+  // lock is released here
+}
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+#    define _STLP_OFFSET sizeof(_Obj)
+#  else
+#    define _STLP_OFFSET 0
+#  endif
+
+/* We allocate memory in large chunks in order to avoid fragmenting     */
+/* the malloc heap too much.                                            */
+/* We assume that size is properly aligned.                             */
+/* We hold the allocation lock.                                         */
+char* __node_alloc_impl::_S_chunk_alloc(size_t _p_size, int& __nobjs) {
+  char* __result;
+  size_t __total_bytes = _p_size * __nobjs;
+  size_t __bytes_left = _S_end_free - _S_start_free;
+
+  if (__bytes_left > 0) {
+    if (__bytes_left >= __total_bytes) {
+      __result = _S_start_free;
+      _S_start_free += __total_bytes;
+      return __result;
+    }
+
+    if (__bytes_left >= _p_size) {
+      __nobjs = (int)(__bytes_left / _p_size);
+      __total_bytes = _p_size * __nobjs;
+      __result = _S_start_free;
+      _S_start_free += __total_bytes;
+      return __result;
+    }
+
+    // Try to make use of the left-over piece.
+    _Obj* _STLP_VOLATILE* __my_free_list = _S_free_list + _S_FREELIST_INDEX(__bytes_left);
+    __REINTERPRET_CAST(_Obj*, _S_start_free)->_M_next = *__my_free_list;
+    *__my_free_list = __REINTERPRET_CAST(_Obj*, _S_start_free);
+    _S_start_free = _S_end_free = 0;
+  }
+
+  size_t __bytes_to_get = 2 * __total_bytes + _S_round_up(_S_heap_size) + _STLP_OFFSET;
+
+  _STLP_TRY {
+    _S_start_free = __stlp_new_chunk(__bytes_to_get);
+  }
+#if defined (_STLP_USE_EXCEPTIONS)
+  catch (const _STLP_STD::bad_alloc&) {
+    _Obj* _STLP_VOLATILE* __my_free_list;
+    _Obj* __p;
+    // Try to do with what we have.  That can't hurt.
+    // We do not try smaller requests, since that tends
+    // to result in disaster on multi-process machines.
+    for (size_t __i = _p_size; __i <= (size_t)_MAX_BYTES; __i += (size_t)_ALIGN) {
+      __my_free_list = _S_free_list + _S_FREELIST_INDEX(__i);
+      __p = *__my_free_list;
+      if (0 != __p) {
+        *__my_free_list = __p -> _M_next;
+        _S_start_free = __REINTERPRET_CAST(char*, __p);
+        _S_end_free = _S_start_free + __i;
+        return _S_chunk_alloc(_p_size, __nobjs);
+        // Any leftover piece will eventually make it to the
+        // right free list.
+      }
+    }
+    __bytes_to_get = __total_bytes + _STLP_OFFSET;
+    _S_start_free = __stlp_new_chunk(__bytes_to_get);
+  }
+#endif
+
+  _S_heap_size += __bytes_to_get >> 4;
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  __REINTERPRET_CAST(_Obj*, _S_start_free)->_M_next = _S_chunks;
+  _S_chunks = __REINTERPRET_CAST(_Obj*, _S_start_free);
+#  endif
+  _S_end_free = _S_start_free + __bytes_to_get;
+  _S_start_free += _STLP_OFFSET;
+  return _S_chunk_alloc(_p_size, __nobjs);
+}
+
+/* Returns an object of size __n, and optionally adds to size __n free list.*/
+/* We assume that __n is properly aligned.                                  */
+/* We hold the allocation lock.                                             */
+_Node_alloc_obj* __node_alloc_impl::_S_refill(size_t __n) {
+  int __nobjs = 20;
+  char* __chunk = _S_chunk_alloc(__n, __nobjs);
+
+  if (1 == __nobjs) return __REINTERPRET_CAST(_Obj*, __chunk);
+
+  _Obj* _STLP_VOLATILE* __my_free_list = _S_free_list + _S_FREELIST_INDEX(__n);
+  _Obj* __result;
+  _Obj* __current_obj;
+  _Obj* __next_obj;
+
+  /* Build free list in chunk */
+  __result = __REINTERPRET_CAST(_Obj*, __chunk);
+  *__my_free_list = __next_obj = __REINTERPRET_CAST(_Obj*, __chunk + __n);
+  for (--__nobjs; --__nobjs; ) {
+    __current_obj = __next_obj;
+    __next_obj = __REINTERPRET_CAST(_Obj*, __REINTERPRET_CAST(char*, __next_obj) + __n);
+    __current_obj->_M_next = __next_obj;
+  }
+  __next_obj->_M_next = 0;
+  return __result;
+}
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+void __node_alloc_impl::_S_alloc_call()
+{ ++_S_alloc_counter(); }
+
+void __node_alloc_impl::_S_dealloc_call() {
+  __stl_atomic_t &counter = _S_alloc_counter();
+  if (--counter == 0)
+  { _S_chunk_dealloc(); }
+}
+
+/* We deallocate all the memory chunks      */
+void __node_alloc_impl::_S_chunk_dealloc() {
+  _Obj *__pcur = _S_chunks, *__pnext;
+  while (__pcur != 0) {
+    __pnext = __pcur->_M_next;
+    __stlp_delete_chunck(__pcur);
+    __pcur = __pnext;
+  }
+  _S_chunks = 0;
+  _S_start_free = _S_end_free = 0;
+  _S_heap_size = 0;
+  memset(__REINTERPRET_CAST(char*, __CONST_CAST(_Obj**, &_S_free_list[0])), 0, _STLP_NFREELISTS * sizeof(_Obj*));
+}
+#  endif
+
+#else
+
+void* __node_alloc_impl::_M_allocate(size_t& __n) {
+  __n = _S_round_up(__n);
+  _Obj* __r = _S_free_list[_S_FREELIST_INDEX(__n)].pop();
+  if (__r  == 0)
+  { __r = _S_refill(__n); }
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  _S_alloc_call();
+#  endif
+  return __r;
+}
+
+void __node_alloc_impl::_M_deallocate(void *__p, size_t __n) {
+  _S_free_list[_S_FREELIST_INDEX(__n)].push(__STATIC_CAST(_Obj*, __p));
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  _S_dealloc_call();
+#  endif
+}
+
+/* Returns an object of size __n, and optionally adds additional ones to    */
+/* freelist of objects of size __n.                                         */
+/* We assume that __n is properly aligned.                                  */
+__node_alloc_impl::_Obj* __node_alloc_impl::_S_refill(size_t __n) {
+  int __nobjs = 20;
+  char* __chunk = _S_chunk_alloc(__n, __nobjs);
+
+  if (__nobjs <= 1)
+    return __REINTERPRET_CAST(_Obj*, __chunk);
+
+  // Push all new nodes (minus first one) onto freelist
+  _Obj* __result   = __REINTERPRET_CAST(_Obj*, __chunk);
+  _Obj* __cur_item = __result;
+  _Freelist* __my_freelist = _S_free_list + _S_FREELIST_INDEX(__n);
+  for (--__nobjs; __nobjs != 0; --__nobjs) {
+    __cur_item  = __REINTERPRET_CAST(_Obj*, __REINTERPRET_CAST(char*, __cur_item) + __n);
+    __my_freelist->push(__cur_item);
+  }
+  return __result;
+}
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+#    define _STLP_OFFSET _ALIGN
+#  else
+#    define _STLP_OFFSET 0
+#  endif
+
+/* We allocate memory in large chunks in order to avoid fragmenting     */
+/* the malloc heap too much.                                            */
+/* We assume that size is properly aligned.                             */
+char* __node_alloc_impl::_S_chunk_alloc(size_t _p_size, int& __nobjs) {
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  //We are going to add a small memory block to keep all the allocated blocks
+  //address, we need to do so respecting the memory alignment. The following
+  //static assert checks that the reserved block is big enough to store a pointer.
+  _STLP_STATIC_ASSERT(sizeof(_Obj) <= _ALIGN)
+#  endif
+  char*  __result       = 0;
+  __add_atomic_t __total_bytes  = __STATIC_CAST(__add_atomic_t, _p_size) * __nobjs;
+
+  _FreeBlockHeader* __block = __STATIC_CAST(_FreeBlockHeader*, _S_free_mem_blocks.pop());
+  if (__block != 0) {
+    // We checked a block out and can now mess with it with impugnity.
+    // We'll put the remainder back into the list if we're done with it below.
+    char*  __buf_start  = __REINTERPRET_CAST(char*, __block);
+    __add_atomic_t __bytes_left = __block->_M_end - __buf_start;
+
+    if ((__bytes_left < __total_bytes) && (__bytes_left >= __STATIC_CAST(__add_atomic_t, _p_size))) {
+      // There's enough left for at least one object, but not as much as we wanted
+      __result      = __buf_start;
+      __nobjs       = (int)(__bytes_left/_p_size);
+      __total_bytes = __STATIC_CAST(__add_atomic_t, _p_size) * __nobjs;
+      __bytes_left -= __total_bytes;
+      __buf_start  += __total_bytes;
+    }
+    else if (__bytes_left >= __total_bytes) {
+      // The block has enough left to satisfy all that was asked for
+      __result      = __buf_start;
+      __bytes_left -= __total_bytes;
+      __buf_start  += __total_bytes;
+    }
+
+    if (__bytes_left != 0) {
+      // There is still some memory left over in block after we satisfied our request.
+      if ((__result != 0) && (__bytes_left >= (__add_atomic_t)sizeof(_FreeBlockHeader))) {
+        // We were able to allocate at least one object and there is still enough
+        // left to put remainder back into list.
+        _FreeBlockHeader* __newblock = __REINTERPRET_CAST(_FreeBlockHeader*, __buf_start);
+        __newblock->_M_end  = __block->_M_end;
+        _S_free_mem_blocks.push(__newblock);
+      }
+      else {
+        // We were not able to allocate enough for at least one object.
+        // Shove into freelist of nearest (rounded-down!) size.
+        size_t __rounded_down = _S_round_up(__bytes_left + 1) - (size_t)_ALIGN;
+        if (__rounded_down > 0)
+          _S_free_list[_S_FREELIST_INDEX(__rounded_down)].push((_Obj*)__buf_start);
+      }
+    }
+    if (__result != 0)
+      return __result;
+  }
+
+  // We couldn't satisfy it from the list of free blocks, get new memory.
+  __add_atomic_t __bytes_to_get = 2 * __total_bytes +
+                                  __STATIC_CAST(__add_atomic_t,
+                                                _S_round_up(__STATIC_CAST(__uadd_atomic_t, _STLP_ATOMIC_ADD(&_S_heap_size, 0)))) +
+                                  _STLP_OFFSET;
+  _STLP_TRY {
+    __result = __stlp_new_chunk(__bytes_to_get);
+  }
+#if defined (_STLP_USE_EXCEPTIONS)
+  catch (const bad_alloc&) {
+    // Allocation failed; try to canibalize from freelist of a larger object size.
+    for (size_t __i = _p_size; __i <= (size_t)_MAX_BYTES; __i += (size_t)_ALIGN) {
+      _Obj* __p  = _S_free_list[_S_FREELIST_INDEX(__i)].pop();
+      if (0 != __p) {
+        if (__i < sizeof(_FreeBlockHeader)) {
+          // Not enough to put into list of free blocks, divvy it up here.
+          // Use as much as possible for this request and shove remainder into freelist.
+          __nobjs = (int)(__i/_p_size);
+          __total_bytes = __nobjs * __STATIC_CAST(__add_atomic_t, _p_size);
+          size_t __bytes_left = __i - __total_bytes;
+          size_t __rounded_down = _S_round_up(__bytes_left+1) - (size_t)_ALIGN;
+          if (__rounded_down > 0) {
+            _S_free_list[_S_FREELIST_INDEX(__rounded_down)].push(__REINTERPRET_CAST(_Obj*, __REINTERPRET_CAST(char*, __p) + __total_bytes));
+          }
+          return __REINTERPRET_CAST(char*, __p);
+        }
+        else {
+          // Add node to list of available blocks and recursively allocate from it.
+          _FreeBlockHeader* __newblock = (_FreeBlockHeader*)__p;
+          __newblock->_M_end  = __REINTERPRET_CAST(char*, __p) + __i;
+          _S_free_mem_blocks.push(__newblock);
+          return _S_chunk_alloc(_p_size, __nobjs);
+        }
+      }
+    }
+
+    // We were not able to find something in a freelist, try to allocate a smaller amount.
+    __bytes_to_get  = __total_bytes + _STLP_OFFSET;
+    __result = __stlp_new_chunk(__bytes_to_get);
+
+    // This should either throw an exception or remedy the situation.
+    // Thus we assume it succeeded.
+  }
+#endif
+  // Alignment check
+  _STLP_VERBOSE_ASSERT(((__REINTERPRET_CAST(size_t, __result) & __STATIC_CAST(size_t, _ALIGN - 1)) == 0),
+                       _StlMsg_DBA_DELETED_TWICE)
+  _STLP_ATOMIC_ADD(&_S_heap_size, __bytes_to_get >> 4);
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+  // We have to track the allocated memory chunks for release on exit.
+  _S_chunks.push(__REINTERPRET_CAST(_Obj*, __result));
+  __result       += _ALIGN;
+  __bytes_to_get -= _ALIGN;
+#  endif
+
+  if (__bytes_to_get > __total_bytes) {
+    // Push excess memory allocated in this chunk into list of free memory blocks
+    _FreeBlockHeader* __freeblock = __REINTERPRET_CAST(_FreeBlockHeader*, __result + __total_bytes);
+    __freeblock->_M_end  = __result + __bytes_to_get;
+    _S_free_mem_blocks.push(__freeblock);
+  }
+  return __result;
+}
+
+#  if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+void __node_alloc_impl::_S_alloc_call()
+{ _STLP_ATOMIC_INCREMENT(&_S_alloc_counter()); }
+
+void __node_alloc_impl::_S_dealloc_call() {
+  _STLP_VOLATILE __stl_atomic_t *pcounter = &_S_alloc_counter();
+  if (_STLP_ATOMIC_DECREMENT(pcounter) == 0)
+    _S_chunk_dealloc();
+}
+
+/* We deallocate all the memory chunks      */
+void __node_alloc_impl::_S_chunk_dealloc() {
+  // Note: The _Node_alloc_helper class ensures that this function
+  // will only be called when the (shared) library is unloaded or the
+  // process is shutdown.  It's thus not possible that another thread
+  // is currently trying to allocate a node (we're not thread-safe here).
+  //
+
+  // Clear the free blocks and all freelistst.  This makes sure that if
+  // for some reason more memory is allocated again during shutdown
+  // (it'd also be really nasty to leave references to deallocated memory).
+  _S_free_mem_blocks.clear();
+  _S_heap_size      = 0;
+
+  for (size_t __i = 0; __i < _STLP_NFREELISTS; ++__i) {
+    _S_free_list[__i].clear();
+  }
+
+  // Detach list of chunks and free them all
+  _Obj* __chunk = _S_chunks.clear();
+  while (__chunk != 0) {
+    _Obj* __next = __chunk->_M_next;
+    __stlp_delete_chunck(__chunk);
+    __chunk  = __next;
+  }
+}
+#  endif
+
+#endif
+
+#if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+struct __node_alloc_cleaner {
+  ~__node_alloc_cleaner()
+  { __node_alloc_impl::_S_dealloc_call(); }
+};
+
+#  if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+_STLP_VOLATILE __stl_atomic_t& _STLP_CALL
+#  else
+__stl_atomic_t& _STLP_CALL
+#  endif
+__node_alloc_impl::_S_alloc_counter() {
+  static _AllocCounter _S_counter = 1;
+  static __node_alloc_cleaner _S_node_alloc_cleaner;
+  return _S_counter;
+}
+#endif
+
+#if !defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+_Node_alloc_obj * _STLP_VOLATILE
+__node_alloc_impl::_S_free_list[_STLP_NFREELISTS]
+= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+// The 16 zeros are necessary to make version 4.1 of the SunPro
+// compiler happy.  Otherwise it appears to allocate too little
+// space for the array.
+#else
+_STLP_atomic_freelist __node_alloc_impl::_S_free_list[_STLP_NFREELISTS];
+_STLP_atomic_freelist __node_alloc_impl::_S_free_mem_blocks;
+#endif
+
+#if !defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+char *__node_alloc_impl::_S_start_free = 0;
+char *__node_alloc_impl::_S_end_free = 0;
+#endif
+
+#if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+_STLP_VOLATILE __add_atomic_t
+#else
+size_t
+#endif
+__node_alloc_impl::_S_heap_size = 0;
+
+#if defined (_STLP_DO_CLEAN_NODE_ALLOC)
+#  if defined (_STLP_USE_LOCK_FREE_IMPLEMENTATION)
+_STLP_atomic_freelist __node_alloc_impl::_S_chunks;
+#  else
+_Node_alloc_obj* __node_alloc_impl::_S_chunks  = 0;
+#  endif
+#endif
+
+void * _STLP_CALL __node_alloc::_M_allocate(size_t& __n)
+{ return __node_alloc_impl::_M_allocate(__n); }
+
+void _STLP_CALL __node_alloc::_M_deallocate(void *__p, size_t __n)
+{ __node_alloc_impl::_M_deallocate(__p, __n); }
+
+#if defined (_STLP_PTHREADS) && !defined (_STLP_NO_THREADS)
+
+#  define _STLP_DATA_ALIGNMENT 8
+
+_STLP_MOVE_TO_PRIV_NAMESPACE
+
+// *******************************************************
+// __perthread_alloc implementation
+union _Pthread_alloc_obj {
+  union _Pthread_alloc_obj * __free_list_link;
+  char __client_data[_STLP_DATA_ALIGNMENT];    /* The client sees this.    */
+};
+
+// Pthread allocators don't appear to the client to have meaningful
+// instances.  We do in fact need to associate some state with each
+// thread.  That state is represented by _Pthread_alloc_per_thread_state.
+
+struct _Pthread_alloc_per_thread_state {
+  typedef _Pthread_alloc_obj __obj;
+  enum { _S_NFREELISTS = _MAX_BYTES / _STLP_DATA_ALIGNMENT };
+
+  // Free list link for list of available per thread structures.
+  // When one of these becomes available for reuse due to thread
+  // termination, any objects in its free list remain associated
+  // with it.  The whole structure may then be used by a newly
+  // created thread.
+  _Pthread_alloc_per_thread_state() : __next(0)
+  { memset((void *)__CONST_CAST(_Pthread_alloc_obj**, __free_list), 0, (size_t)_S_NFREELISTS * sizeof(__obj *)); }
+  // Returns an object of size __n, and possibly adds to size n free list.
+  void *_M_refill(size_t __n);
+
+  _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS];
+  _Pthread_alloc_per_thread_state *__next;
+  // this data member is only to be used by per_thread_allocator, which returns memory to the originating thread.
+  _STLP_mutex _M_lock;
+};
+
+// Pthread-specific allocator.
+class _Pthread_alloc_impl {
+public: // but only for internal use:
+  typedef _Pthread_alloc_per_thread_state __state_type;
+  typedef char value_type;
+
+  // Allocates a chunk for nobjs of size size.  nobjs may be reduced
+  // if it is inconvenient to allocate the requested number.
+  static char *_S_chunk_alloc(size_t __size, size_t &__nobjs, __state_type*);
+
+  enum {_S_ALIGN = _STLP_DATA_ALIGNMENT};
+
+  static size_t _S_round_up(size_t __bytes)
+  { return (((__bytes) + (int)_S_ALIGN - 1) & ~((int)_S_ALIGN - 1)); }
+  static size_t _S_freelist_index(size_t __bytes)
+  { return (((__bytes) + (int)_S_ALIGN - 1) / (int)_S_ALIGN - 1); }
+
+private:
+  // Chunk allocation state. And other shared state.
+  // Protected by _S_chunk_allocator_lock.
+  static _STLP_STATIC_MUTEX _S_chunk_allocator_lock;
+  static char *_S_start_free;
+  static char *_S_end_free;
+  static size_t _S_heap_size;
+  static __state_type *_S_free_per_thread_states;
+  static pthread_key_t _S_key;
+  static bool _S_key_initialized;
+  // Pthread key under which per thread state is stored.
+  // Allocator instances that are currently unclaimed by any thread.
+  static void _S_destructor(void *instance);
+  // Function to be called on thread exit to reclaim per thread
+  // state.
+  static __state_type *_S_new_per_thread_state();
+public:
+  // Return a recycled or new per thread state.
+  static __state_type *_S_get_per_thread_state();
+private:
+        // ensure that the current thread has an associated
+        // per thread state.
+  class _M_lock;
+  friend class _M_lock;
+  class _M_lock {
+  public:
+    _M_lock () { _S_chunk_allocator_lock._M_acquire_lock(); }
+    ~_M_lock () { _S_chunk_allocator_lock._M_release_lock(); }
+  };
+
+public:
+
+  /* n must be > 0      */
+  static void * allocate(size_t& __n);
+
+  /* p may not be 0 */
+  static void deallocate(void *__p, size_t __n);
+
+  // boris : versions for per_thread_allocator
+  /* n must be > 0      */
+  static void * allocate(size_t& __n, __state_type* __a);
+
+  /* p may not be 0 */
+  static void deallocate(void *__p, size_t __n, __state_type* __a);
+
+  static void * reallocate(void *__p, size_t __old_sz, size_t& __new_sz);
+};
+
+/* Returns an object of size n, and optionally adds to size n free list.*/
+/* We assume that n is properly aligned.                                */
+/* We hold the allocation lock.                                         */
+void *_Pthread_alloc_per_thread_state::_M_refill(size_t __n) {
+  typedef _Pthread_alloc_obj __obj;
+  size_t __nobjs = 128;
+  char * __chunk = _Pthread_alloc_impl::_S_chunk_alloc(__n, __nobjs, this);
+  __obj * volatile * __my_free_list;
+  __obj * __result;
+  __obj * __current_obj, * __next_obj;
+  size_t __i;
+
+  if (1 == __nobjs)  {
+    return __chunk;
+  }
+
+  __my_free_list = __free_list + _Pthread_alloc_impl::_S_freelist_index(__n);
+
+  /* Build free list in chunk */
+  __result = (__obj *)__chunk;
+  *__my_free_list = __next_obj = (__obj *)(__chunk + __n);
+  for (__i = 1; ; ++__i) {
+    __current_obj = __next_obj;
+    __next_obj = (__obj *)((char *)__next_obj + __n);
+    if (__nobjs - 1 == __i) {
+      __current_obj -> __free_list_link = 0;
+      break;
+    } else {
+      __current_obj -> __free_list_link = __next_obj;
+    }
+  }
+  return __result;
+}
+
+void _Pthread_alloc_impl::_S_destructor(void *__instance) {
+  _M_lock __lock_instance;  // Need to acquire lock here.
+  _Pthread_alloc_per_thread_state* __s = (_Pthread_alloc_per_thread_state*)__instance;
+  __s -> __next = _S_free_per_thread_states;
+  _S_free_per_thread_states = __s;
+}
+
+_Pthread_alloc_per_thread_state* _Pthread_alloc_impl::_S_new_per_thread_state() {
+  /* lock already held here.  */
+  if (0 != _S_free_per_thread_states) {
+    _Pthread_alloc_per_thread_state *__result = _S_free_per_thread_states;
+    _S_free_per_thread_states = _S_free_per_thread_states -> __next;
+    return __result;
+  }
+  else {
+    return new _Pthread_alloc_per_thread_state;
+  }
+}
+
+_Pthread_alloc_per_thread_state* _Pthread_alloc_impl::_S_get_per_thread_state() {
+  int __ret_code;
+  __state_type* __result;
+
+  if (_S_key_initialized && (__result = (__state_type*) pthread_getspecific(_S_key)))
+    return __result;
+
+  /*REFERENCED*/
+  _M_lock __lock_instance;  // Need to acquire lock here.
+  if (!_S_key_initialized) {
+    if (pthread_key_create(&_S_key, _S_destructor)) {
+      _STLP_THROW_BAD_ALLOC;  // failed
+    }
+    _S_key_initialized = true;
+  }
+
+  __result = _S_new_per_thread_state();
+  __ret_code = pthread_setspecific(_S_key, __result);
+  if (__ret_code) {
+    if (__ret_code == ENOMEM) {
+      _STLP_THROW_BAD_ALLOC;
+    } else {
+  // EINVAL
+      _STLP_ABORT();
+    }
+  }
+  return __result;
+}
+
+/* We allocate memory in large chunks in order to avoid fragmenting     */
+/* the malloc heap too much.                                            */
+/* We assume that size is properly aligned.                             */
+char *_Pthread_alloc_impl::_S_chunk_alloc(size_t __p_size, size_t &__nobjs, _Pthread_alloc_per_thread_state *__a) {
+  typedef _Pthread_alloc_obj __obj;
+  {
+    char * __result;
+    size_t __total_bytes;
+    size_t __bytes_left;
+    /*REFERENCED*/
+    _M_lock __lock_instance;         // Acquire lock for this routine
+
+    __total_bytes = __p_size * __nobjs;
+    __bytes_left = _S_end_free - _S_start_free;
+    if (__bytes_left >= __total_bytes) {
+      __result = _S_start_free;
+      _S_start_free += __total_bytes;
+      return __result;
+    } else if (__bytes_left >= __p_size) {
+      __nobjs = __bytes_left/__p_size;
+      __total_bytes = __p_size * __nobjs;
+      __result = _S_start_free;
+      _S_start_free += __total_bytes;
+      return __result;
+    } else {
+      size_t __bytes_to_get = 2 * __total_bytes + _S_round_up(_S_heap_size);
+      // Try to make use of the left-over piece.
+      if (__bytes_left > 0) {
+        __obj * volatile * __my_free_list = __a->__free_list + _S_freelist_index(__bytes_left);
+        ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list;
+        *__my_free_list = (__obj *)_S_start_free;
+      }
+#  ifdef _SGI_SOURCE
+      // Try to get memory that's aligned on something like a
+      // cache line boundary, so as to avoid parceling out
+      // parts of the same line to different threads and thus
+      // possibly different processors.
+      {
+        const int __cache_line_size = 128;  // probable upper bound
+        __bytes_to_get &= ~(__cache_line_size-1);
+        _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get);
+        if (0 == _S_start_free) {
+          _S_start_free = (char *)__malloc_alloc::allocate(__bytes_to_get);
+        }
+      }
+#  else  /* !SGI_SOURCE */
+      _S_start_free = (char *)__malloc_alloc::allocate(__bytes_to_get);
+#  endif
+      _S_heap_size += __bytes_to_get >> 4;
+      _S_end_free = _S_start_free + __bytes_to_get;
+    }
+  }
+  // lock is released here
+  return _S_chunk_alloc(__p_size, __nobjs, __a);
+}
+
+
+/* n must be > 0      */
+void *_Pthread_alloc_impl::allocate(size_t& __n) {
+  typedef _Pthread_alloc_obj __obj;
+  __obj * volatile * __my_free_list;
+  __obj * __result;
+  __state_type* __a;
+
+  if (__n > _MAX_BYTES) {
+    return __malloc_alloc::allocate(__n);
+  }
+
+  __n = _S_round_up(__n);
+  __a = _S_get_per_thread_state();
+
+  __my_free_list = __a->__free_list + _S_freelist_index(__n);
+  __result = *__my_free_list;
+  if (__result == 0) {
+    void *__r = __a->_M_refill(__n);
+    return __r;
+  }
+  *__my_free_list = __result->__free_list_link;
+  return __result;
+};
+
+/* p may not be 0 */
+void _Pthread_alloc_impl::deallocate(void *__p, size_t __n) {
+  typedef _Pthread_alloc_obj __obj;
+  __obj *__q = (__obj *)__p;
+  __obj * volatile * __my_free_list;
+  __state_type* __a;
+
+  if (__n > _MAX_BYTES) {
+      __malloc_alloc::deallocate(__p, __n);
+      return;
+  }
+
+  __a = _S_get_per_thread_state();
+
+  __my_free_list = __a->__free_list + _S_freelist_index(__n);
+  __q -> __free_list_link = *__my_free_list;
+  *__my_free_list = __q;
+}
+
+// boris : versions for per_thread_allocator
+/* n must be > 0      */
+void *_Pthread_alloc_impl::allocate(size_t& __n, __state_type* __a) {
+  typedef _Pthread_alloc_obj __obj;
+  __obj * volatile * __my_free_list;
+  __obj * __result;
+
+  if (__n > _MAX_BYTES) {
+    return __malloc_alloc::allocate(__n);
+  }
+  __n = _S_round_up(__n);
+
+  // boris : here, we have to lock per thread state, as we may be getting memory from
+  // different thread pool.
+  _STLP_auto_lock __lock(__a->_M_lock);
+
+  __my_free_list = __a->__free_list + _S_freelist_index(__n);
+  __result = *__my_free_list;
+  if (__result == 0) {
+    void *__r = __a->_M_refill(__n);
+    return __r;
+  }
+  *__my_free_list = __result->__free_list_link;
+  return __result;
+};
+
+/* p may not be 0 */
+void _Pthread_alloc_impl::deallocate(void *__p, size_t __n, __state_type* __a) {
+  typedef _Pthread_alloc_obj __obj;
+  __obj *__q = (__obj *)__p;
+  __obj * volatile * __my_free_list;
+
+  if (__n > _MAX_BYTES) {
+    __malloc_alloc::deallocate(__p, __n);
+    return;
+  }
+
+  // boris : here, we have to lock per thread state, as we may be returning memory from
+  // different thread.
+  _STLP_auto_lock __lock(__a->_M_lock);
+
+  __my_free_list = __a->__free_list + _S_freelist_index(__n);
+  __q -> __free_list_link = *__my_free_list;
+  *__my_free_list = __q;
+}
+
+void *_Pthread_alloc_impl::reallocate(void *__p, size_t __old_sz, size_t& __new_sz) {
+  void * __result;
+  size_t __copy_sz;
+
+  if (__old_sz > _MAX_BYTES && __new_sz > _MAX_BYTES) {
+    return realloc(__p, __new_sz);
+  }
+
+  if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return __p;
+  __result = allocate(__new_sz);
+  __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
+  memcpy(__result, __p, __copy_sz);
+  deallocate(__p, __old_sz);
+  return __result;
+}
+
+_Pthread_alloc_per_thread_state* _Pthread_alloc_impl::_S_free_per_thread_states = 0;
+pthread_key_t _Pthread_alloc_impl::_S_key = 0;
+_STLP_STATIC_MUTEX _Pthread_alloc_impl::_S_chunk_allocator_lock _STLP_MUTEX_INITIALIZER;
+bool _Pthread_alloc_impl::_S_key_initialized = false;
+char *_Pthread_alloc_impl::_S_start_free = 0;
+char *_Pthread_alloc_impl::_S_end_free = 0;
+size_t _Pthread_alloc_impl::_S_heap_size = 0;
+
+void * _STLP_CALL _Pthread_alloc::allocate(size_t& __n)
+{ return _Pthread_alloc_impl::allocate(__n); }
+void _STLP_CALL _Pthread_alloc::deallocate(void *__p, size_t __n)
+{ _Pthread_alloc_impl::deallocate(__p, __n); }
+void * _STLP_CALL _Pthread_alloc::allocate(size_t& __n, __state_type* __a)
+{ return _Pthread_alloc_impl::allocate(__n, __a); }
+void _STLP_CALL _Pthread_alloc::deallocate(void *__p, size_t __n, __state_type* __a)
+{ _Pthread_alloc_impl::deallocate(__p, __n, __a); }
+void * _STLP_CALL _Pthread_alloc::reallocate(void *__p, size_t __old_sz, size_t& __new_sz)
+{ return _Pthread_alloc_impl::reallocate(__p, __old_sz, __new_sz); }
+_Pthread_alloc_per_thread_state* _STLP_CALL _Pthread_alloc::_S_get_per_thread_state()
+{ return _Pthread_alloc_impl::_S_get_per_thread_state(); }
+
+_STLP_MOVE_TO_STD_NAMESPACE
+
+#endif
+
+_STLP_END_NAMESPACE
+
+#undef _S_FREELIST_INDEX
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/bitset.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1998
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#include "stlport_prefix.h"
+
+#include <bitset>
+
+_STLP_BEGIN_NAMESPACE
+
+_STLP_MOVE_TO_PRIV_NAMESPACE
+
+// ------------------------------------------------------------
+// Lookup tables for find and count operations.
+
+size_t _Bs_G::_S_count(const unsigned char *__first,
+                       const unsigned char *__last)
+{
+  static const unsigned char _bit_count[256] = {
+  0, /*   0 */ 1, /*   1 */ 1, /*   2 */ 2, /*   3 */ 1, /*   4 */
+  2, /*   5 */ 2, /*   6 */ 3, /*   7 */ 1, /*   8 */ 2, /*   9 */
+  2, /*  10 */ 3, /*  11 */ 2, /*  12 */ 3, /*  13 */ 3, /*  14 */
+  4, /*  15 */ 1, /*  16 */ 2, /*  17 */ 2, /*  18 */ 3, /*  19 */
+  2, /*  20 */ 3, /*  21 */ 3, /*  22 */ 4, /*  23 */ 2, /*  24 */
+  3, /*  25 */ 3, /*  26 */ 4, /*  27 */ 3, /*  28 */ 4, /*  29 */
+  4, /*  30 */ 5, /*  31 */ 1, /*  32 */ 2, /*  33 */ 2, /*  34 */
+  3, /*  35 */ 2, /*  36 */ 3, /*  37 */ 3, /*  38 */ 4, /*  39 */
+  2, /*  40 */ 3, /*  41 */ 3, /*  42 */ 4, /*  43 */ 3, /*  44 */
+  4, /*  45 */ 4, /*  46 */ 5, /*  47 */ 2, /*  48 */ 3, /*  49 */
+  3, /*  50 */ 4, /*  51 */ 3, /*  52 */ 4, /*  53 */ 4, /*  54 */
+  5, /*  55 */ 3, /*  56 */ 4, /*  57 */ 4, /*  58 */ 5, /*  59 */
+  4, /*  60 */ 5, /*  61 */ 5, /*  62 */ 6, /*  63 */ 1, /*  64 */
+  2, /*  65 */ 2, /*  66 */ 3, /*  67 */ 2, /*  68 */ 3, /*  69 */
+  3, /*  70 */ 4, /*  71 */ 2, /*  72 */ 3, /*  73 */ 3, /*  74 */
+  4, /*  75 */ 3, /*  76 */ 4, /*  77 */ 4, /*  78 */ 5, /*  79 */
+  2, /*  80 */ 3, /*  81 */ 3, /*  82 */ 4, /*  83 */ 3, /*  84 */
+  4, /*  85 */ 4, /*  86 */ 5, /*  87 */ 3, /*  88 */ 4, /*  89 */
+  4, /*  90 */ 5, /*  91 */ 4, /*  92 */ 5, /*  93 */ 5, /*  94 */
+  6, /*  95 */ 2, /*  96 */ 3, /*  97 */ 3, /*  98 */ 4, /*  99 */
+  3, /* 100 */ 4, /* 101 */ 4, /* 102 */ 5, /* 103 */ 3, /* 104 */
+  4, /* 105 */ 4, /* 106 */ 5, /* 107 */ 4, /* 108 */ 5, /* 109 */
+  5, /* 110 */ 6, /* 111 */ 3, /* 112 */ 4, /* 113 */ 4, /* 114 */
+  5, /* 115 */ 4, /* 116 */ 5, /* 117 */ 5, /* 118 */ 6, /* 119 */
+  4, /* 120 */ 5, /* 121 */ 5, /* 122 */ 6, /* 123 */ 5, /* 124 */
+  6, /* 125 */ 6, /* 126 */ 7, /* 127 */ 1, /* 128 */ 2, /* 129 */
+  2, /* 130 */ 3, /* 131 */ 2, /* 132 */ 3, /* 133 */ 3, /* 134 */
+  4, /* 135 */ 2, /* 136 */ 3, /* 137 */ 3, /* 138 */ 4, /* 139 */
+  3, /* 140 */ 4, /* 141 */ 4, /* 142 */ 5, /* 143 */ 2, /* 144 */
+  3, /* 145 */ 3, /* 146 */ 4, /* 147 */ 3, /* 148 */ 4, /* 149 */
+  4, /* 150 */ 5, /* 151 */ 3, /* 152 */ 4, /* 153 */ 4, /* 154 */
+  5, /* 155 */ 4, /* 156 */ 5, /* 157 */ 5, /* 158 */ 6, /* 159 */
+  2, /* 160 */ 3, /* 161 */ 3, /* 162 */ 4, /* 163 */ 3, /* 164 */
+  4, /* 165 */ 4, /* 166 */ 5, /* 167 */ 3, /* 168 */ 4, /* 169 */
+  4, /* 170 */ 5, /* 171 */ 4, /* 172 */ 5, /* 173 */ 5, /* 174 */
+  6, /* 175 */ 3, /* 176 */ 4, /* 177 */ 4, /* 178 */ 5, /* 179 */
+  4, /* 180 */ 5, /* 181 */ 5, /* 182 */ 6, /* 183 */ 4, /* 184 */
+  5, /* 185 */ 5, /* 186 */ 6, /* 187 */ 5, /* 188 */ 6, /* 189 */
+  6, /* 190 */ 7, /* 191 */ 2, /* 192 */ 3, /* 193 */ 3, /* 194 */
+  4, /* 195 */ 3, /* 196 */ 4, /* 197 */ 4, /* 198 */ 5, /* 199 */
+  3, /* 200 */ 4, /* 201 */ 4, /* 202 */ 5, /* 203 */ 4, /* 204 */
+  5, /* 205 */ 5, /* 206 */ 6, /* 207 */ 3, /* 208 */ 4, /* 209 */
+  4, /* 210 */ 5, /* 211 */ 4, /* 212 */ 5, /* 213 */ 5, /* 214 */
+  6, /* 215 */ 4, /* 216 */ 5, /* 217 */ 5, /* 218 */ 6, /* 219 */
+  5, /* 220 */ 6, /* 221 */ 6, /* 222 */ 7, /* 223 */ 3, /* 224 */
+  4, /* 225 */ 4, /* 226 */ 5, /* 227 */ 4, /* 228 */ 5, /* 229 */
+  5, /* 230 */ 6, /* 231 */ 4, /* 232 */ 5, /* 233 */ 5, /* 234 */
+  6, /* 235 */ 5, /* 236 */ 6, /* 237 */ 6, /* 238 */ 7, /* 239 */
+  4, /* 240 */ 5, /* 241 */ 5, /* 242 */ 6, /* 243 */ 5, /* 244 */
+  6, /* 245 */ 6, /* 246 */ 7, /* 247 */ 5, /* 248 */ 6, /* 249 */
+  6, /* 250 */ 7, /* 251 */ 6, /* 252 */ 7, /* 253 */ 7, /* 254 */
+  8  /* 255 */
+  };
+
+  size_t __result(0);
+  while ( __first < __last ) {
+    __result += _bit_count[*(__first++)];
+  }
+  return __result;
+}
+
+unsigned char _Bs_G::_S_first_one(unsigned char __byte)
+{
+  static const unsigned char _first_one[256] = {
+  0, /*   0 */ 0, /*   1 */ 1, /*   2 */ 0, /*   3 */ 2, /*   4 */
+  0, /*   5 */ 1, /*   6 */ 0, /*   7 */ 3, /*   8 */ 0, /*   9 */
+  1, /*  10 */ 0, /*  11 */ 2, /*  12 */ 0, /*  13 */ 1, /*  14 */
+  0, /*  15 */ 4, /*  16 */ 0, /*  17 */ 1, /*  18 */ 0, /*  19 */
+  2, /*  20 */ 0, /*  21 */ 1, /*  22 */ 0, /*  23 */ 3, /*  24 */
+  0, /*  25 */ 1, /*  26 */ 0, /*  27 */ 2, /*  28 */ 0, /*  29 */
+  1, /*  30 */ 0, /*  31 */ 5, /*  32 */ 0, /*  33 */ 1, /*  34 */
+  0, /*  35 */ 2, /*  36 */ 0, /*  37 */ 1, /*  38 */ 0, /*  39 */
+  3, /*  40 */ 0, /*  41 */ 1, /*  42 */ 0, /*  43 */ 2, /*  44 */
+  0, /*  45 */ 1, /*  46 */ 0, /*  47 */ 4, /*  48 */ 0, /*  49 */
+  1, /*  50 */ 0, /*  51 */ 2, /*  52 */ 0, /*  53 */ 1, /*  54 */
+  0, /*  55 */ 3, /*  56 */ 0, /*  57 */ 1, /*  58 */ 0, /*  59 */
+  2, /*  60 */ 0, /*  61 */ 1, /*  62 */ 0, /*  63 */ 6, /*  64 */
+  0, /*  65 */ 1, /*  66 */ 0, /*  67 */ 2, /*  68 */ 0, /*  69 */
+  1, /*  70 */ 0, /*  71 */ 3, /*  72 */ 0, /*  73 */ 1, /*  74 */
+  0, /*  75 */ 2, /*  76 */ 0, /*  77 */ 1, /*  78 */ 0, /*  79 */
+  4, /*  80 */ 0, /*  81 */ 1, /*  82 */ 0, /*  83 */ 2, /*  84 */
+  0, /*  85 */ 1, /*  86 */ 0, /*  87 */ 3, /*  88 */ 0, /*  89 */
+  1, /*  90 */ 0, /*  91 */ 2, /*  92 */ 0, /*  93 */ 1, /*  94 */
+  0, /*  95 */ 5, /*  96 */ 0, /*  97 */ 1, /*  98 */ 0, /*  99 */
+  2, /* 100 */ 0, /* 101 */ 1, /* 102 */ 0, /* 103 */ 3, /* 104 */
+  0, /* 105 */ 1, /* 106 */ 0, /* 107 */ 2, /* 108 */ 0, /* 109 */
+  1, /* 110 */ 0, /* 111 */ 4, /* 112 */ 0, /* 113 */ 1, /* 114 */
+  0, /* 115 */ 2, /* 116 */ 0, /* 117 */ 1, /* 118 */ 0, /* 119 */
+  3, /* 120 */ 0, /* 121 */ 1, /* 122 */ 0, /* 123 */ 2, /* 124 */
+  0, /* 125 */ 1, /* 126 */ 0, /* 127 */ 7, /* 128 */ 0, /* 129 */
+  1, /* 130 */ 0, /* 131 */ 2, /* 132 */ 0, /* 133 */ 1, /* 134 */
+  0, /* 135 */ 3, /* 136 */ 0, /* 137 */ 1, /* 138 */ 0, /* 139 */
+  2, /* 140 */ 0, /* 141 */ 1, /* 142 */ 0, /* 143 */ 4, /* 144 */
+  0, /* 145 */ 1, /* 146 */ 0, /* 147 */ 2, /* 148 */ 0, /* 149 */
+  1, /* 150 */ 0, /* 151 */ 3, /* 152 */ 0, /* 153 */ 1, /* 154 */
+  0, /* 155 */ 2, /* 156 */ 0, /* 157 */ 1, /* 158 */ 0, /* 159 */
+  5, /* 160 */ 0, /* 161 */ 1, /* 162 */ 0, /* 163 */ 2, /* 164 */
+  0, /* 165 */ 1, /* 166 */ 0, /* 167 */ 3, /* 168 */ 0, /* 169 */
+  1, /* 170 */ 0, /* 171 */ 2, /* 172 */ 0, /* 173 */ 1, /* 174 */
+  0, /* 175 */ 4, /* 176 */ 0, /* 177 */ 1, /* 178 */ 0, /* 179 */
+  2, /* 180 */ 0, /* 181 */ 1, /* 182 */ 0, /* 183 */ 3, /* 184 */
+  0, /* 185 */ 1, /* 186 */ 0, /* 187 */ 2, /* 188 */ 0, /* 189 */
+  1, /* 190 */ 0, /* 191 */ 6, /* 192 */ 0, /* 193 */ 1, /* 194 */
+  0, /* 195 */ 2, /* 196 */ 0, /* 197 */ 1, /* 198 */ 0, /* 199 */
+  3, /* 200 */ 0, /* 201 */ 1, /* 202 */ 0, /* 203 */ 2, /* 204 */
+  0, /* 205 */ 1, /* 206 */ 0, /* 207 */ 4, /* 208 */ 0, /* 209 */
+  1, /* 210 */ 0, /* 211 */ 2, /* 212 */ 0, /* 213 */ 1, /* 214 */
+  0, /* 215 */ 3, /* 216 */ 0, /* 217 */ 1, /* 218 */ 0, /* 219 */
+  2, /* 220 */ 0, /* 221 */ 1, /* 222 */ 0, /* 223 */ 5, /* 224 */
+  0, /* 225 */ 1, /* 226 */ 0, /* 227 */ 2, /* 228 */ 0, /* 229 */
+  1, /* 230 */ 0, /* 231 */ 3, /* 232 */ 0, /* 233 */ 1, /* 234 */
+  0, /* 235 */ 2, /* 236 */ 0, /* 237 */ 1, /* 238 */ 0, /* 239 */
+  4, /* 240 */ 0, /* 241 */ 1, /* 242 */ 0, /* 243 */ 2, /* 244 */
+  0, /* 245 */ 1, /* 246 */ 0, /* 247 */ 3, /* 248 */ 0, /* 249 */
+  1, /* 250 */ 0, /* 251 */ 2, /* 252 */ 0, /* 253 */ 1, /* 254 */
+  0, /* 255 */
+  };
+  return _first_one[__byte];
+}
+
+_STLP_MOVE_TO_STD_NAMESPACE
+
+_STLP_END_NAMESPACE
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#include "stlport_prefix.h"
+
+#include "c_locale.h"
+
+#if defined (_STLP_WIN32) && !defined (_STLP_WCE)
+#  include "c_locale_win32/c_locale_win32.c"
+#elif defined (_STLP_USE_GLIBC2_LOCALIZATION)
+#  include "c_locale_glibc/c_locale_glibc2.c" /* glibc 2.2 and newer */
+#else
+#  include "c_locale_dummy/c_locale_dummy.c"
+#endif
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale.h
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+/*
+ * It is impossible to write the C++ locale library in terms of locales
+ * as defined in the C standard.  Instead, we write the C++ locale and I/O
+ * library in terms of a low level C-like interface.  This file defines
+ * that interface.
+ *
+ * The low-level locale interface can't be written portably; there
+ * must be a version of it for each platform that the C++ library
+ * is ported to.  On many systems this interface may be a thin wrapper
+ * for existing functionality.
+ */
+
+#ifndef _STLP_C_LOCALE_IMPL_H
+#define _STLP_C_LOCALE_IMPL_H
+
+#include "stlport_prefix.h"
+
+#include <wchar.h> /* for mbstate_t */
+#include <stl/c_locale.h>
+
+struct _Locale_name_hint;
+
+#if defined (_GNU_SOURCE) && defined (__GLIBC__) && \
+    ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2))
+#  define _STLP_USE_GLIBC2_LOCALIZATION
+#  include <nl_types.h>
+typedef nl_catd nl_catd_type;
+#else
+typedef int nl_catd_type;
+#endif
+
+/*
+ * A number: the maximum length of a simple locale name.
+ * (i.e. a name like like en_US, as opposed to a name like
+ * en_US/de_AT/de_AT/es_MX/en_US/en_US) */
+#define _Locale_MAX_SIMPLE_NAME 256
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Typedefs:
+ */
+typedef unsigned short int _Locale_mask_t;
+
+/* Function called during STLport library load phase. Might contain any
+ * code necessary to the platform localization layer.
+ */
+void _Locale_init(void);
+
+/* Function called during STLport library unload. Might contain any
+ * code necessary to the platform localization layer.
+ */
+void _Locale_final(void);
+
+/* Create a category of the locale with the given name.
+ *
+ * The char* argument is a simple (not a composite) locale name, which may
+ * neither be an empty string nor a null pointer.
+ *
+ * These functions return NULL to indicate failure. Failure reason should be reported
+ * using the __err_code pointer.
+ */
+struct _Locale_ctype* _Locale_ctype_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_codecvt* _Locale_codecvt_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_numeric* _Locale_numeric_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_time* _Locale_time_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_collate* _Locale_collate_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_monetary* _Locale_monetary_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+struct _Locale_messages* _Locale_messages_create(const char *, struct _Locale_name_hint*, int * /* __err_code */);
+
+/* Give error reason on failure of one of the _Locale_*_create functions. Available
+ * reasons are:
+ * 0: No specific error reason has been reported.
+ * 1: No platform support for the given facet.
+ * 2: Unknown locale name
+ * 3: No platform API for localization support.
+ * 4: No more memory
+ */
+#define _STLP_LOC_UNDEFINED 0
+#define _STLP_LOC_UNSUPPORTED_FACET_CATEGORY 1
+#define _STLP_LOC_UNKNOWN_NAME 2
+#define _STLP_LOC_NO_PLATFORM_SUPPORT 3
+#define _STLP_LOC_NO_MEMORY 4
+
+/* Release a category of a locale
+ *
+ * These functions are used to release a category acquired with the
+ * according _Locale_*_create() functions.
+ */
+void _Locale_ctype_destroy(struct _Locale_ctype *);
+void _Locale_codecvt_destroy(struct _Locale_codecvt *);
+void _Locale_numeric_destroy(struct _Locale_numeric *);
+void _Locale_time_destroy(struct _Locale_time *);
+void _Locale_collate_destroy(struct _Locale_collate *);
+void _Locale_monetary_destroy(struct _Locale_monetary *);
+void _Locale_messages_destroy(struct _Locale_messages *);
+
+/*
+ * Returns the name of the user's default locale in each
+ * category, as a null-terminated string.  A NULL value
+ * means the default "C" locale.
+ */
+const char * _Locale_ctype_default(char * __buf);
+const char * _Locale_numeric_default(char * __buf);
+const char * _Locale_time_default(char * __buf);
+const char * _Locale_collate_default(char * __buf);
+const char * _Locale_monetary_default(char * __buf);
+const char * _Locale_messages_default(char * __buf);
+
+/* Retrieve the name of the given category
+ *
+ * __buf points to a buffer that can hold at least _Locale_MAX_SIMPLE_NAME
+ * characters.  These functions store the name, as a null-terminated
+ * string, in __buf. This function can't fail, at worst name is truncated.
+ */
+char const* _Locale_ctype_name(const struct _Locale_ctype *, char* __buf);
+char const* _Locale_codecvt_name(const struct _Locale_codecvt *, char* __buf);
+char const* _Locale_numeric_name(const struct _Locale_numeric *, char* __buf);
+char const* _Locale_time_name(const struct _Locale_time *, char* __buf);
+char const* _Locale_collate_name(const struct _Locale_collate *, char*  __buf);
+char const* _Locale_monetary_name(const struct _Locale_monetary *, char* __buf);
+char const* _Locale_messages_name(const struct _Locale_messages *, char* __buf);
+
+/*
+ * cname is a (possibly composite) locale name---i.e. a name that can
+ * be passed to setlocale. __buf points to an array large enough to
+ * store at least _Locale_MAX_SIMPLE_NAME characters, and each of these
+ * functions extracts the name of a single category, stores it in buf
+ * as a null-terminated string, and returns buf.
+ */
+char const* _Locale_extract_ctype_name(const char *cname, char *__buf,
+                                       struct _Locale_name_hint* __hint, int *__err_code);
+char const* _Locale_extract_numeric_name(const char *cname, char *__buf,
+                                         struct _Locale_name_hint* __hint, int *__err_code);
+char const* _Locale_extract_time_name(const char *cname, char *__buf,
+                                      struct _Locale_name_hint* __hint, int *__err_code);
+char const* _Locale_extract_collate_name(const char *cname, char *__buf,
+                                         struct _Locale_name_hint* __hint, int *__err_code);
+char const* _Locale_extract_monetary_name(const char *cname, char *__buf,
+                                          struct _Locale_name_hint* __hint, int *__err_code);
+char const* _Locale_extract_messages_name(const char *cname, char *__buf,
+                                          struct _Locale_name_hint* __hint, int *__err_code);
+
+/* Functions to improve locale creation process. For some locale API (Win32)
+ * you need to find a locale identification from the name which can be a
+ * rather expensive operation especially if you do so for all facets of a
+ * locale. Those functions can be used to extract from a API dependent facet
+ * struct the information necessary to skip this lookup process for other
+ * facets creation. If not supported those function should return NULL.
+ */
+struct _Locale_name_hint* _Locale_get_ctype_hint(struct _Locale_ctype*);
+struct _Locale_name_hint* _Locale_get_numeric_hint(struct _Locale_numeric*);
+struct _Locale_name_hint* _Locale_get_time_hint(struct _Locale_time*);
+struct _Locale_name_hint* _Locale_get_collate_hint(struct _Locale_collate*);
+struct _Locale_name_hint* _Locale_get_monetary_hint(struct _Locale_monetary*);
+struct _Locale_name_hint* _Locale_get_messages_hint(struct _Locale_messages*);
+
+/*
+ * FUNCTIONS THAT USE CTYPE
+ */
+
+/*
+ * Narrow character functions:
+ */
+
+/*
+ * Returns a pointer to the beginning of the ctype table.  The table is
+ * at least 257 bytes long; if p is the pointer returned by this
+ * function, then p[c] is valid if c is EOF or if p is any value of
+ * type unsigned char.
+ */
+const _Locale_mask_t * _Locale_ctype_table(struct _Locale_ctype *);
+
+/*
+ * c is either EOF, or an unsigned char value.
+ */
+int _Locale_toupper(struct _Locale_ctype *, int /* c */);
+int _Locale_tolower(struct _Locale_ctype *, int /* c */);
+
+
+#ifndef _STLP_NO_WCHAR_T
+/*
+ * Wide character functions:
+ */
+_Locale_mask_t _WLocale_ctype(struct _Locale_ctype *, wint_t, _Locale_mask_t);
+wint_t _WLocale_tolower(struct _Locale_ctype *, wint_t);
+wint_t _WLocale_toupper(struct _Locale_ctype *, wint_t);
+
+/*
+ * Multibyte functions:
+ */
+
+/*
+ * Returns the number of bytes of the longest allowed multibyte
+ * character in the current encoding.
+ */
+int _WLocale_mb_cur_max(struct _Locale_codecvt *);
+
+/*
+ * Returns the number of bytes of the shortest allowed multibyte
+ * character in the current encoding.
+ */
+int _WLocale_mb_cur_min(struct _Locale_codecvt *);
+
+/*
+ * Returns 1 if the current multibyte encoding is stateless
+ * and does not require the use of an mbstate_t value.
+ */
+int _WLocale_is_stateless(struct _Locale_codecvt *);
+
+/*
+ * Almost identical to mbrtowc, from 4.6.5.3.2 of NA1.  The only
+ * important difference is that mbrtowc treats null wide characters
+ * as special, and we don't.  Specifically: examines the characters
+ * in [from, from + n), extracts a single wide character, and stores
+ * it in *to.  Modifies shift_state if appropriate.  The return value,
+ * which is always positive, is the number of characters extracted from
+ * the input sequence.  Return value is (size_t) -1 if there was an
+ * encoding error in the input sequence, and (size_t) -2 if
+ * [from, from + n) is correct but not complete.  None of the pointer
+ * arguments may be null pointers.
+ */
+size_t _WLocale_mbtowc(struct _Locale_codecvt *,
+                       wchar_t * /* to */,
+                       const char * /* from */, size_t /* n */,
+                       mbstate_t *);
+
+/*
+ * Again, very similar to wcrtomb.  The differences are that (1) it
+ * doesn't treat null characters as special; and (2) it stores at most
+ * n characters.  Converts c to a multibyte sequence, stores that
+ * sequence in the array 'to', and returns the length of the sequence.
+ * Modifies shift_state if appropriate.  The return value is (size_t) -1
+ * if c is not a valid wide character, and (size_t) -2 if the length of
+ * the multibyte character sequence is greater than n.
+ */
+size_t _WLocale_wctomb(struct _Locale_codecvt *,
+                       char *, size_t,
+                       const wchar_t,
+                       mbstate_t *);
+
+/*
+ * Inserts whatever characters are necessary to restore st to an
+ * initial shift state.  Sets *next to buf + m, where m is the number
+ * of characters inserted.  (0 <= m <= n.)  Returns m to indicate
+ * success, (size_t) -1 to indicate error, (size_t) -2 to indicate
+ * partial success (more than n characters needed).  For success or partial
+ * success, sets *next to buf + m.
+ */
+size_t _WLocale_unshift(struct _Locale_codecvt *,
+                        mbstate_t *,
+                        char *, size_t, char **);
+#endif
+
+/*
+ * FUNCTIONS THAT USE COLLATE
+ */
+
+/*
+ * Compares the two sequences [s1, s1 + n1) and [s2, s2 + n2).  Neither
+ * sequence is assumed to be null-terminated, and null characters
+ * aren't special.  If the two sequences are the same up through
+ * min(n1, n2), then the sequence that compares less is whichever one
+ * is shorter.
+ */
+int _Locale_strcmp(struct _Locale_collate *,
+                   const char * /* s1 */, size_t /* n1 */,
+                   const char * /* s2 */, size_t /* n2 */);
+#ifndef _STLP_NO_WCHAR_T
+int _WLocale_strcmp(struct _Locale_collate *,
+                    const wchar_t * /* s1 */, size_t /* n1 */,
+                    const wchar_t * /* s2 */, size_t /* n2 */);
+#endif
+
+/*
+ * Creates a transformed version of the string [s2, s2 + n2).  The
+ * string may contain embedded null characters; nulls aren't special.
+ * The transformed string begins at s1, and contains at most n1
+ * characters.  The return value is the length of the transformed
+ * string.  If the return value is greater than n1 then this is an
+ * error condition: it indicates that there wasn't enough space.  In
+ * that case, the contents of [s1, s1 + n1) is unspecified.
+*/
+size_t _Locale_strxfrm(struct _Locale_collate *,
+                       char * /* s1 */, size_t /* n1 */,
+                       const char * /* s2 */, size_t /* n2 */);
+
+#ifndef _STLP_NO_WCHAR_T
+size_t _WLocale_strxfrm(struct _Locale_collate *,
+                        wchar_t * /* s1 */, size_t /* n1 */,
+                        const wchar_t * /* s2 */, size_t /* n2 */);
+#endif
+
+
+/*
+ * FUNCTIONS THAT USE NUMERIC
+ */
+
+/*
+ * Equivalent to the first three fields in struct lconv.  (C standard,
+ * section 7.4.)
+ */
+char _Locale_decimal_point(struct _Locale_numeric *);
+char _Locale_thousands_sep(struct _Locale_numeric *);
+const char * _Locale_grouping(struct _Locale_numeric *);
+
+#ifndef _STLP_NO_WCHAR_T
+wchar_t _WLocale_decimal_point(struct _Locale_numeric *);
+wchar_t _WLocale_thousands_sep(struct _Locale_numeric *);
+#endif
+
+/*
+ * Return "true" and "false" in English locales, and something
+ * appropriate in non-English locales.
+ */
+const char * _Locale_true(struct _Locale_numeric *);
+const char * _Locale_false(struct _Locale_numeric *);
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t * _WLocale_true(struct _Locale_numeric *, wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_false(struct _Locale_numeric *, wchar_t* /* buf */, size_t /* bufSize */);
+#endif
+
+/*
+ * FUNCTIONS THAT USE MONETARY
+ */
+
+/*
+ * Return the obvious fields of struct lconv.
+ */
+const char * _Locale_int_curr_symbol(struct _Locale_monetary *);
+const char * _Locale_currency_symbol(struct _Locale_monetary *);
+char         _Locale_mon_decimal_point(struct _Locale_monetary *);
+char         _Locale_mon_thousands_sep(struct _Locale_monetary *);
+const char * _Locale_mon_grouping(struct _Locale_monetary *);
+const char * _Locale_positive_sign(struct _Locale_monetary *);
+const char * _Locale_negative_sign(struct _Locale_monetary *);
+char         _Locale_int_frac_digits(struct _Locale_monetary *);
+char         _Locale_frac_digits(struct _Locale_monetary *);
+int          _Locale_p_cs_precedes(struct _Locale_monetary *);
+int          _Locale_p_sep_by_space(struct _Locale_monetary *);
+int          _Locale_p_sign_posn(struct _Locale_monetary *);
+int          _Locale_n_cs_precedes(struct _Locale_monetary *);
+int          _Locale_n_sep_by_space(struct _Locale_monetary *);
+int          _Locale_n_sign_posn(struct _Locale_monetary *);
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t * _WLocale_int_curr_symbol(struct _Locale_monetary *, wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_currency_symbol(struct _Locale_monetary *, wchar_t* /* buf */, size_t /* bufSize */);
+wchar_t         _WLocale_mon_decimal_point(struct _Locale_monetary *);
+wchar_t         _WLocale_mon_thousands_sep(struct _Locale_monetary *);
+const wchar_t * _WLocale_positive_sign(struct _Locale_monetary *, wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_negative_sign(struct _Locale_monetary *, wchar_t* /* buf */, size_t /* bufSize */);
+#endif
+
+/*
+ * FUNCTIONS THAT USE TIME
+ */
+
+/*
+ * month is in the range [0, 12).
+ */
+const char * _Locale_full_monthname(struct _Locale_time *, int /* month */);
+const char * _Locale_abbrev_monthname(struct _Locale_time *, int /* month */);
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t * _WLocale_full_monthname(struct _Locale_time *, int /* month */,
+                                        wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_abbrev_monthname(struct _Locale_time *, int /* month */,
+                                          wchar_t* /* buf */, size_t /* bufSize */);
+#endif
+
+/*
+ * day is in the range [0, 7).  Sunday is 0.
+ */
+const char * _Locale_full_dayofweek(struct _Locale_time *, int /* day */);
+const char * _Locale_abbrev_dayofweek(struct _Locale_time *, int /* day */);
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t * _WLocale_full_dayofweek(struct _Locale_time *, int /* day */,
+                                        wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_abbrev_dayofweek(struct _Locale_time *, int /* day */,
+                                          wchar_t* /* buf */, size_t /* bufSize */);
+#endif
+
+const char * _Locale_d_t_fmt(struct _Locale_time *);
+const char * _Locale_d_fmt(struct _Locale_time *);
+const char * _Locale_t_fmt(struct _Locale_time *);
+const char * _Locale_long_d_t_fmt(struct _Locale_time*);
+const char * _Locale_long_d_fmt(struct _Locale_time*);
+
+const char * _Locale_am_str(struct _Locale_time *);
+const char * _Locale_pm_str(struct _Locale_time *);
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t * _WLocale_am_str(struct _Locale_time *,
+                                wchar_t* /* buf */, size_t /* bufSize */);
+const wchar_t * _WLocale_pm_str(struct _Locale_time *,
+                                wchar_t* /* buf */, size_t /* bufSize */);
+#endif
+
+/*
+ * FUNCTIONS THAT USE MESSAGES
+ */
+
+/*
+ * Very similar to catopen, except that it uses the given message
+ * category to determine which catalog to open.
+ */
+nl_catd_type _Locale_catopen(struct _Locale_messages*, const char*);
+
+/* Complementary to _Locale_catopen.
+ * The catalog must be a value that was returned by a previous call
+ * to _Locale_catopen.
+ */
+void _Locale_catclose(struct _Locale_messages*, nl_catd_type);
+
+/*
+ * Returns a string, identified by a set index and a message index,
+ * from an opened message catalog.  Returns the supplied default if
+ * no such string exists.
+ */
+const char * _Locale_catgets(struct _Locale_messages *, nl_catd_type,
+                             int, int,const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STLP_C_LOCALE_IMPL_H */
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale_dummy/c_locale_dummy.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+/* This is a "stub" implementation of the "c_locale.h" interface,
+   intended for operating systems where we have not yet written
+   a real implementation.  A C++ library using this stub implementation
+   is still standard-conforming, since the C++ standard does not require
+   that any locales other than "C" be supported.
+*/
+
+#include <string.h>
+#include <wchar.h>
+#include <ctype.h>
+#include <wctype.h>
+#include <limits.h>
+
+#if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
+#  define _STLP_STRNCPY(D, DS, S, C) strncpy_s(D, DS, S, C)
+#  if !defined (_STLP_NO_WCHAR_T)
+#    define _STLP_WCSNCPY(D, DS, S, C) wcsncpy_s(D, DS, S, C)
+#  endif
+#else
+#  define _STLP_STRNCPY(D, DS, S, C) strncpy(D, S, C)
+#  if !defined (_STLP_NO_WCHAR_T)
+#    define _STLP_WCSNCPY(D, DS, S, C) wcsncpy(D, S, C)
+#  endif
+#endif
+
+static const char *_C_name = "C";
+static const char *_empty_str = "";
+#ifndef _STLP_NO_WCHAR_T
+#if defined(WCHAR_MAX) && WCHAR_MAX == 255
+static const wchar_t *_empty_wstr = "";
+#else
+static const wchar_t *_empty_wstr = L"";
+#endif
+#endif
+
+static _Locale_mask_t ctable[256];
+
+/* Framework functions */
+
+void _Locale_init(void) {
+  /* Ctype table for the ASCII character set. */
+  char c;
+  /* We might never reach 128 when char is signed. */
+  for (c = 0; /* c != 128 */; ++c) {
+    if (isalpha(c)) ctable[(unsigned char)c] |= _Locale_ALPHA;
+    if (iscntrl(c)) ctable[(unsigned char)c] |= _Locale_CNTRL;
+    if (isdigit(c)) ctable[(unsigned char)c] |= _Locale_DIGIT;
+    if (isprint(c)) ctable[(unsigned char)c] |= _Locale_PRINT;
+    if (ispunct(c)) ctable[(unsigned char)c] |= _Locale_PUNCT;
+    if (isspace(c)) ctable[(unsigned char)c] |= _Locale_SPACE;
+    if (isxdigit(c)) ctable[(unsigned char)c] |= _Locale_XDIGIT;
+    if (isupper(c)) ctable[(unsigned char)c] |= _Locale_UPPER;
+    if (islower(c)) ctable[(unsigned char)c] |= _Locale_LOWER;
+    if (c == 127) break;
+  }
+
+  /* ASCII is a 7-bit code, so everything else is non-ASCII. */
+  memset(&(ctable[128]), 0, 128 * sizeof(_Locale_mask_t));
+}
+
+void _Locale_final(void)
+{}
+
+void* _Locale_create(const char* name, int *__err_code) {
+  if (name[0] == 'C' && name[1] == 0)
+  { return (void*)0x1; }
+  *__err_code = _STLP_LOC_NO_PLATFORM_SUPPORT; return 0;
+}
+
+struct _Locale_ctype* _Locale_ctype_create(const char *name,
+                                           struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_ctype*)_Locale_create(name, __err_code); }
+
+struct _Locale_codecvt* _Locale_codecvt_create(const char *name,
+                                               struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_codecvt*)_Locale_create(name, __err_code); }
+
+struct _Locale_numeric* _Locale_numeric_create(const char *name,
+                                               struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_numeric*)_Locale_create(name, __err_code); }
+
+struct _Locale_time* _Locale_time_create(const char *name,
+                                         struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_time*)_Locale_create(name, __err_code); }
+
+struct _Locale_collate* _Locale_collate_create(const char *name,
+                                               struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_collate*)_Locale_create(name, __err_code); }
+
+struct _Locale_monetary* _Locale_monetary_create(const char *name,
+                                                 struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_monetary*)_Locale_create(name, __err_code); }
+
+struct _Locale_messages* _Locale_messages_create(const char *name,
+                                                 struct _Locale_name_hint* hint, int *__err_code)
+{ return (struct _Locale_messages*)_Locale_create(name, __err_code); }
+
+const char *_Locale_ctype_default(char* buf)    { return _C_name; }
+const char *_Locale_numeric_default(char * buf) { return _C_name; }
+const char *_Locale_time_default(char* buf)     { return _C_name; }
+const char *_Locale_collate_default(char* buf)  { return _C_name; }
+const char *_Locale_monetary_default(char* buf) { return _C_name; }
+const char *_Locale_messages_default(char* buf) { return _C_name; }
+
+char const* _Locale_ctype_name(const struct _Locale_ctype *lctype, char* buf)
+{ return _C_name; }
+
+char const* _Locale_codecvt_name(const struct _Locale_codecvt *lcodecvt, char* buf)
+{ return _C_name; }
+
+char const* _Locale_numeric_name(const struct _Locale_numeric *lnum, char* buf)
+{ return _C_name; }
+
+char const* _Locale_time_name(const struct _Locale_time *ltime, char* buf)
+{ return _C_name; }
+
+char const* _Locale_collate_name(const struct _Locale_collate *lcol, char* buf)
+{ return _C_name; }
+
+char const* _Locale_monetary_name(const struct _Locale_monetary *lmon, char* buf)
+{ return _C_name; }
+
+char const* _Locale_messages_name(const struct _Locale_messages *lmes, char* buf)
+{ return _C_name; }
+
+void _Locale_ctype_destroy(struct _Locale_ctype *lctype)     {}
+void _Locale_codecvt_destroy(struct _Locale_codecvt *lcodecvt)   {}
+void _Locale_numeric_destroy(struct _Locale_numeric *lnum)   {}
+void _Locale_time_destroy(struct _Locale_time *ltime)        {}
+void _Locale_collate_destroy(struct _Locale_collate *lcol)   {}
+void _Locale_monetary_destroy(struct _Locale_monetary *lmon) {}
+void _Locale_messages_destroy(struct _Locale_messages *lmes) {}
+
+static char const* _Locale_extract_name(const char* name, int *__err_code) {
+  // When the request is the default locale or the "C" locale we answer "C".
+  if (name[0] == 0 ||
+      (name[0] == 'C' && name[1] == 0))
+  {  return _C_name; }
+  *__err_code = _STLP_LOC_NO_PLATFORM_SUPPORT; return 0;
+}
+
+char const* _Locale_extract_ctype_name(const char *name, char *buf,
+                                       struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+char const* _Locale_extract_numeric_name(const char *name, char *buf,
+                                         struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+char const* _Locale_extract_time_name(const char*name, char *buf,
+                                      struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+char const* _Locale_extract_collate_name(const char *name, char *buf,
+                                         struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+char const* _Locale_extract_monetary_name(const char *name, char *buf,
+                                          struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+char const* _Locale_extract_messages_name(const char *name, char *buf,
+                                          struct _Locale_name_hint* hint, int *__err_code)
+{ return _Locale_extract_name(name, __err_code); }
+
+struct _Locale_name_hint* _Locale_get_ctype_hint(struct _Locale_ctype* ctype)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_numeric_hint(struct _Locale_numeric* numeric)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_time_hint(struct _Locale_time* time)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_collate_hint(struct _Locale_collate* collate)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_monetary_hint(struct _Locale_monetary* monetary)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_messages_hint(struct _Locale_messages* messages)
+{ return 0; }
+
+/* ctype */
+const _Locale_mask_t* _Locale_ctype_table(struct _Locale_ctype* lctype) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lctype)
+  return ctable;
+}
+
+int _Locale_toupper(struct _Locale_ctype*lctype, int c)
+{ return toupper(c); }
+
+int _Locale_tolower(struct _Locale_ctype*lctype, int c)
+{ return tolower(c); }
+
+#ifndef _STLP_NO_WCHAR_T
+_Locale_mask_t _WLocale_ctype(struct _Locale_ctype *lctype, wint_t wc, _Locale_mask_t mask) {
+  _Locale_mask_t ret = 0;
+  if ((mask & _Locale_ALPHA) != 0 && iswalpha(wc))
+    ret |= _Locale_ALPHA;
+
+  if ((mask & _Locale_CNTRL) != 0 && iswcntrl(wc))
+    ret |= _Locale_CNTRL;
+
+  if ((mask & _Locale_DIGIT) != 0 && iswdigit(wc))
+    ret |= _Locale_DIGIT;
+
+  if ((mask & _Locale_PRINT) != 0 && iswprint(wc))
+    ret |= _Locale_PRINT;
+
+  if ((mask & _Locale_PUNCT) != 0 && iswpunct(wc))
+    ret |= _Locale_PUNCT;
+
+  if ((mask & _Locale_SPACE) != 0 && iswspace(wc))
+    ret |= _Locale_SPACE;
+
+  if ((mask & _Locale_XDIGIT) != 0 && iswxdigit(wc))
+    ret |= _Locale_XDIGIT;
+
+  if ((mask & _Locale_UPPER) != 0 && iswupper(wc))
+    ret |= _Locale_UPPER;
+
+  if ((mask & _Locale_LOWER) != 0 && iswlower(wc))
+    ret |= _Locale_LOWER;
+
+  return ret;
+}
+
+wint_t _WLocale_tolower(struct _Locale_ctype *lctype, wint_t wc)
+{ return towlower(wc); }
+
+wint_t _WLocale_toupper(struct _Locale_ctype *lctype, wint_t wc)
+{ return towupper(wc); }
+
+int _WLocale_mb_cur_max (struct _Locale_codecvt *lcodecvt) { return 1; }
+int _WLocale_mb_cur_min (struct _Locale_codecvt *lcodecvt) { return 1; }
+int _WLocale_is_stateless (struct _Locale_codecvt *lcodecvt) { return 1; }
+
+size_t _WLocale_mbtowc(struct _Locale_codecvt *lcodecvt,
+                       wchar_t *to,
+                       const char *from, size_t n,
+                       mbstate_t *st)
+{ *to = *from; return 1; }
+
+size_t _WLocale_wctomb(struct _Locale_codecvt *lcodecvt,
+                       char *to, size_t n,
+                       const wchar_t c,
+                       mbstate_t *st)
+{ *to = (char)c; return 1; }
+
+size_t _WLocale_unshift(struct _Locale_codecvt *lcodecvt,
+                        mbstate_t *st,
+                        char *buf, size_t n, char ** next)
+{ *next = buf; return 0; }
+#endif
+
+/* Collate */
+ int _Locale_strcmp(struct _Locale_collate* lcol,
+                    const char* s1, size_t n1, const char* s2, size_t n2) {
+  int ret = 0;
+  char buf1[64], buf2[64];
+  while (n1 > 0 || n2 > 0) {
+    size_t bufsize1 = n1 < 63 ? n1 : 63;
+    size_t bufsize2 = n2 < 63 ? n2 : 63;
+    _STLP_STRNCPY(buf1, 64, s1, bufsize1); buf1[bufsize1] = 0;
+    _STLP_STRNCPY(buf2, 64, s2, bufsize2); buf2[bufsize2] = 0;
+
+    ret = strcmp(buf1, buf2);
+    if (ret != 0) return ret < 0 ? -1 : 1;
+    s1 += bufsize1; n1 -= bufsize1;
+    s2 += bufsize2; n2 -= bufsize2;
+  }
+  return ret == 0 ? 0 : (ret < 0 ? -1 : 1);
+}
+
+#ifndef _STLP_NO_WCHAR_T
+
+int _WLocale_strcmp(struct _Locale_collate* lcol,
+                    const wchar_t* s1, size_t n1, const wchar_t* s2, size_t n2) {
+  int ret = 0;
+  wchar_t buf1[64], buf2[64];
+  while (n1 > 0 || n2 > 0) {
+    size_t bufsize1 = n1 < 63 ? n1 : 63;
+    size_t bufsize2 = n2 < 63 ? n2 : 63;
+    _STLP_WCSNCPY(buf1, 64, s1, bufsize1); buf1[bufsize1] = 0;
+    _STLP_WCSNCPY(buf2, 64, s2, bufsize2); buf2[bufsize2] = 0;
+
+    ret = wcscmp(buf1, buf2);
+    if (ret != 0) return ret < 0 ? -1 : 1;
+    s1 += bufsize1; n1 -= bufsize1;
+    s2 += bufsize2; n2 -= bufsize2;
+  }
+  return ret == 0 ? 0 : (ret < 0 ? -1 : 1);
+}
+
+#endif
+
+size_t _Locale_strxfrm(struct _Locale_collate* lcol,
+                       char* dest, size_t dest_n,
+                       const char* src, size_t src_n) {
+  if (dest != 0) {
+    _STLP_STRNCPY(dest, dest_n, src, dest_n - 1); dest[dest_n - 1] = 0;
+  }
+  return src_n;
+}
+
+#ifndef _STLP_NO_WCHAR_T
+
+size_t _WLocale_strxfrm(struct _Locale_collate* lcol,
+                        wchar_t* dest, size_t dest_n,
+                        const wchar_t* src, size_t src_n) {
+  if (dest != 0) {
+    _STLP_WCSNCPY(dest, dest_n, src, dest_n - 1); dest[dest_n - 1] = 0;
+  }
+  return src_n;
+}
+
+#endif
+
+/* Numeric */
+
+char _Locale_decimal_point(struct _Locale_numeric* lnum)
+{ return '.'; }
+char _Locale_thousands_sep(struct _Locale_numeric* lnum)
+{ return ','; }
+const char* _Locale_grouping(struct _Locale_numeric * lnum)
+{ return _empty_str; }
+const char * _Locale_true(struct _Locale_numeric * lnum)
+{ return "true"; }
+const char * _Locale_false(struct _Locale_numeric * lnum)
+{ return "false"; }
+
+#ifndef _STLP_NO_WCHAR_T
+wchar_t _WLocale_decimal_point(struct _Locale_numeric* lnum)
+{ return L'.'; }
+wchar_t _WLocale_thousands_sep(struct _Locale_numeric* lnum)
+{ return L','; }
+#if defined(WCHAR_MAX) && WCHAR_MAX == 255
+const wchar_t * _WLocale_true(struct _Locale_numeric* lnum, wchar_t* buf, size_t bufSize)
+{ return "true"; }
+const wchar_t * _WLocale_false(struct _Locale_numeric* lnum, wchar_t* buf, size_t bufSize)
+{ return "false"; }
+#else
+const wchar_t * _WLocale_true(struct _Locale_numeric* lnum, wchar_t* buf, size_t bufSize)
+{ return L"true"; }
+const wchar_t * _WLocale_false(struct _Locale_numeric* lnum, wchar_t* buf, size_t bufSize)
+{ return L"false"; }
+#endif
+#endif
+
+/* Monetary */
+
+const char* _Locale_int_curr_symbol(struct _Locale_monetary * lmon)
+{ return _empty_str; }
+const char* _Locale_currency_symbol(struct _Locale_monetary * lmon)
+{ return _empty_str; }
+char        _Locale_mon_decimal_point(struct _Locale_monetary * lmon)
+{ return '.'; }
+char        _Locale_mon_thousands_sep(struct _Locale_monetary * lmon)
+{ return ','; }
+const char* _Locale_mon_grouping(struct _Locale_monetary * lmon)
+{ return _empty_str; }
+const char* _Locale_positive_sign(struct _Locale_monetary * lmon)
+{ return _empty_str; }
+const char* _Locale_negative_sign(struct _Locale_monetary * lmon)
+{ return _empty_str; }
+char        _Locale_int_frac_digits(struct _Locale_monetary * lmon)
+{ return 0; }
+char        _Locale_frac_digits(struct _Locale_monetary * lmon)
+{ return 0; }
+int         _Locale_p_cs_precedes(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+int         _Locale_p_sep_by_space(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+int         _Locale_p_sign_posn(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+int         _Locale_n_cs_precedes(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+int          _Locale_n_sep_by_space(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+int          _Locale_n_sign_posn(struct _Locale_monetary * lmon)
+{ return CHAR_MAX; }
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t* _WLocale_int_curr_symbol(struct _Locale_monetary * lmon,
+                                        wchar_t* buf, size_t bufSize)
+{ return _empty_wstr; }
+const wchar_t* _WLocale_currency_symbol(struct _Locale_monetary * lmon,
+                                        wchar_t* buf, size_t bufSize)
+{ return _empty_wstr; }
+wchar_t        _WLocale_mon_decimal_point(struct _Locale_monetary * lmon)
+{ return L'.'; }
+wchar_t        _WLocale_mon_thousands_sep(struct _Locale_monetary * lmon)
+{ return L','; }
+const wchar_t* _WLocale_positive_sign(struct _Locale_monetary * lmon,
+                                      wchar_t* buf, size_t bufSize)
+{ return _empty_wstr; }
+const wchar_t* _WLocale_negative_sign(struct _Locale_monetary * lmon,
+                                      wchar_t* buf, size_t bufSize)
+{ return _empty_wstr; }
+#endif
+
+/* Time */
+static const char* full_monthname[] =
+{ "January", "February", "March", "April", "May", "June",
+  "July", "August", "September", "October", "November", "December" };
+const char * _Locale_full_monthname(struct _Locale_time * ltime, int n)
+{ return full_monthname[n]; }
+
+static const char* abbrev_monthname[] =
+{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+const char * _Locale_abbrev_monthname(struct _Locale_time * ltime, int n)
+{ return abbrev_monthname[n]; }
+
+static const char* full_dayname[] =
+{ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
+const char * _Locale_full_dayofweek(struct _Locale_time * ltime, int n)
+{ return full_dayname[n]; }
+
+static const char* abbrev_dayname[] =
+{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+const char * _Locale_abbrev_dayofweek(struct _Locale_time * ltime, int n)
+{ return abbrev_dayname[n]; }
+
+const char* _Locale_d_t_fmt(struct _Locale_time* ltime)
+{ return "%m/%d/%y"; }
+const char* _Locale_d_fmt(struct _Locale_time* ltime)
+{ return "%m/%d/%y"; }
+const char* _Locale_t_fmt(struct _Locale_time* ltime)
+{ return "%H:%M:%S"; }
+const char* _Locale_long_d_t_fmt(struct _Locale_time* ltime)
+{ return _empty_str; }
+const char* _Locale_long_d_fmt(struct _Locale_time* ltime)
+{ return _empty_str; }
+const char* _Locale_am_str(struct _Locale_time* ltime)
+{ return "AM"; }
+const char* _Locale_pm_str(struct _Locale_time* ltime)
+{ return "PM"; }
+
+#ifndef _STLP_NO_WCHAR_T
+#if defined(WCHAR_MAX) && WCHAR_MAX == 255
+static const wchar_t* full_wmonthname[] =
+{ "January", "February", "March", "April", "May", "June",
+  "July", "August", "September", "October", "November", "December" };
+const wchar_t * _WLocale_full_monthname(struct _Locale_time * ltime, int n,
+                                        wchar_t* buf, size_t bufSize)
+{ return full_wmonthname[n]; }
+
+static const wchar_t* abbrev_wmonthname[] =
+{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+const wchar_t * _WLocale_abbrev_monthname(struct _Locale_time * ltime, int n,
+                                          wchar_t* buf, size_t bufSize)
+{ return abbrev_wmonthname[n]; }
+
+static const wchar_t* full_wdayname[] =
+{ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
+const wchar_t * _WLocale_full_dayofweek(struct _Locale_time * ltime, int n,
+                                        wchar_t* buf, size_t bufSize)
+{ return full_wdayname[n]; }
+
+static const wchar_t* abbrev_wdayname[] =
+{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+const wchar_t * _WLocale_abbrev_dayofweek(struct _Locale_time * ltime, int n,
+                                          wchar_t* buf, size_t bufSize)
+{ return abbrev_wdayname[n]; }
+
+const wchar_t* _WLocale_am_str(struct _Locale_time* ltime,
+                               wchar_t* buf, size_t bufSize)
+{ return "AM"; }
+const wchar_t* _WLocale_pm_str(struct _Locale_time* ltime,
+                               wchar_t* buf, size_t bufSize)
+{ return "PM"; }
+#else /* WCHAR_MAX != 255 */
+static const wchar_t* full_wmonthname[] =
+{ L"January", L"February", L"March", L"April", L"May", L"June",
+  L"July", L"August", L"September", L"October", L"November", L"December" };
+const wchar_t * _WLocale_full_monthname(struct _Locale_time * ltime, int n,
+                                        wchar_t* buf, size_t bufSize)
+{ return full_wmonthname[n]; }
+
+static const wchar_t* abbrev_wmonthname[] =
+{ L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun",
+  L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec" };
+const wchar_t * _WLocale_abbrev_monthname(struct _Locale_time * ltime, int n,
+                                          wchar_t* buf, size_t bufSize)
+{ return abbrev_wmonthname[n]; }
+
+static const wchar_t* full_wdayname[] =
+{ L"Sunday", L"Monday", L"Tuesday", L"Wednesday", L"Thursday", L"Friday", L"Saturday" };
+const wchar_t * _WLocale_full_dayofweek(struct _Locale_time * ltime, int n,
+                                        wchar_t* buf, size_t bufSize)
+{ return full_wdayname[n]; }
+
+static const wchar_t* abbrev_wdayname[] =
+{ L"Sun", L"Mon", L"Tue", L"Wed", L"Thu", L"Fri", L"Sat" };
+const wchar_t * _WLocale_abbrev_dayofweek(struct _Locale_time * ltime, int n,
+                                          wchar_t* buf, size_t bufSize)
+{ return abbrev_wdayname[n]; }
+
+const wchar_t* _WLocale_am_str(struct _Locale_time* ltime,
+                               wchar_t* buf, size_t bufSize)
+{ return L"AM"; }
+const wchar_t* _WLocale_pm_str(struct _Locale_time* ltime,
+                               wchar_t* buf, size_t bufSize)
+{ return L"PM"; }
+#endif /* WCHAR_MAX != 255 */
+#endif
+
+/* Messages */
+
+nl_catd_type _Locale_catopen(struct _Locale_messages* lmes, const char* name)
+{ return -1; }
+void _Locale_catclose(struct _Locale_messages* lmes, nl_catd_type cat) {}
+const char* _Locale_catgets(struct _Locale_messages* lmes, nl_catd_type cat,
+                            int setid, int msgid, const char *dfault)
+{ return dfault; }
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale_glibc/c_locale_glibc2.c
@@ -0,0 +1,705 @@
+#include <locale.h>
+#include <langinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wctype.h>
+#include <string.h>
+#include <stdint.h>
+
+static const char *_empty_str = "";
+static const char *_C_name = "C";
+
+static wchar_t* _ToWChar(const char* buf, wchar_t *wbuf, size_t wbufSize) {
+  wchar_t *wcur = wbuf;
+  wchar_t *wend = wbuf + wbufSize - 1;
+  for (; wcur != wend && *buf != 0; ++buf, ++wcur)
+    *wcur = *buf;
+  *wcur = 0;
+  return wbuf;
+}
+
+#if 0
+struct _Locale_ctype
+{
+  locale_t __cloc;
+};
+
+struct _Locale_numeric
+{
+  locale_t __cloc;
+};
+
+struct _Locale_time
+{
+  locale_t __cloc;
+};
+
+struct _Locale_collate
+{
+  locale_t __cloc;
+};
+
+struct _Locale_monetary
+{
+  locale_t __cloc;
+};
+
+struct _Locale_messages
+{
+  locale_t __cloc;
+};
+#endif
+
+void _Locale_init()
+{}
+
+void _Locale_final()
+{}
+
+struct _Locale_ctype *_Locale_ctype_create(const char *nm, struct _Locale_name_hint* hint,
+                                           int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_ctype*)newlocale(LC_CTYPE_MASK, nm, NULL);
+}
+
+struct _Locale_codecvt *_Locale_codecvt_create(const char *nm, struct _Locale_name_hint* hint,
+                                               int *__err_code) {
+  // Glibc do not support multibyte manipulation for the moment, it simply implements "C".
+  if (nm[0] == 'C' && nm[1] == 0)
+  { return (struct _Locale_codecvt*)0x01; }
+  *__err_code = _STLP_LOC_NO_PLATFORM_SUPPORT; return 0;
+}
+
+struct _Locale_numeric *_Locale_numeric_create(const char *nm, struct _Locale_name_hint* hint,
+                                               int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_numeric*)newlocale(LC_NUMERIC_MASK, nm, NULL);
+}
+  
+struct _Locale_time *_Locale_time_create(const char *nm, struct _Locale_name_hint* hint,
+                                         int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_time*)newlocale(LC_TIME_MASK, nm, NULL);
+}
+
+struct _Locale_collate *_Locale_collate_create(const char *nm, struct _Locale_name_hint* hint,
+                                               int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_collate*)newlocale(LC_COLLATE_MASK, nm, NULL);
+}
+
+struct _Locale_monetary *_Locale_monetary_create(const char *nm, struct _Locale_name_hint* hint,
+                                                 int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_monetary*)newlocale(LC_MONETARY_MASK, nm, NULL);
+}
+
+struct _Locale_messages *_Locale_messages_create(const char *nm, struct _Locale_name_hint* hint,
+                                                 int *__err_code) {
+  *__err_code = _STLP_LOC_UNKNOWN_NAME;
+  return (struct _Locale_messages*)newlocale(LC_MESSAGES_MASK, nm, NULL);
+}
+
+/*
+  try to see locale category LC should be used from environment;
+  according POSIX, the order is
+  1. LC_ALL
+  2. category (LC_CTYPE, LC_NUMERIC, ... )
+  3. LANG
+  If set nothing, return "C" (this really implementation-specific).
+*/
+static const char *_Locale_aux_default( const char *LC, char *nm )
+{
+  char *name = getenv( "LC_ALL" );
+
+  if ( name != NULL && *name != 0 ) {
+    return name;
+  }
+  name = getenv( LC );
+  if ( name != NULL && *name != 0 ) {
+    return name;
+  }
+  name = getenv( "LANG" );
+  if ( name != NULL && *name != 0 ) {
+    return name;
+  }
+
+  return _C_name;
+}
+
+const char *_Locale_ctype_default( char *nm )
+{
+  return _Locale_aux_default( "LC_CTYPE", nm );
+}
+
+const char *_Locale_numeric_default( char *nm )
+{
+  return _Locale_aux_default( "LC_NUMERIC", nm );
+}
+
+const char *_Locale_time_default( char *nm )
+{
+  return _Locale_aux_default( "LC_TIME", nm );
+}
+
+const char *_Locale_collate_default( char *nm )
+{
+  return _Locale_aux_default( "LC_COLLATE", nm );
+}
+
+const char *_Locale_monetary_default( char *nm )
+{
+  return _Locale_aux_default( "LC_MONETARY", nm );
+}
+
+const char *_Locale_messages_default( char *nm )
+{
+  return _Locale_aux_default( "LC_MESSAGES", nm );
+}
+
+char const*_Locale_ctype_name( const struct _Locale_ctype *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_CTYPE];
+}
+
+char const*_Locale_codecvt_name( const struct _Locale_codecvt *__loc, char *buf )
+{
+  return _C_name;
+}
+
+char const*_Locale_numeric_name( const struct _Locale_numeric *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_NUMERIC];
+}
+
+char const*_Locale_time_name( const struct _Locale_time *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_TIME];
+}
+
+char const*_Locale_collate_name( const struct _Locale_collate *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_COLLATE];
+}
+
+char const*_Locale_monetary_name( const struct _Locale_monetary *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_MONETARY];
+}
+
+char const*_Locale_messages_name( const struct _Locale_messages *__loc, char *buf )
+{
+  return ((locale_t)__loc)->__names[LC_MESSAGES];
+}
+
+void _Locale_ctype_destroy( struct _Locale_ctype *__loc )
+{ freelocale((locale_t)__loc); }
+
+void _Locale_codecvt_destroy( struct _Locale_codecvt *__loc )
+{}
+
+void _Locale_numeric_destroy( struct _Locale_numeric *__loc )
+{ freelocale((locale_t)__loc); }
+
+void _Locale_time_destroy( struct _Locale_time *__loc )
+{ freelocale((locale_t)__loc); }
+
+void _Locale_collate_destroy( struct _Locale_collate *__loc )
+{ freelocale((locale_t)__loc); }
+
+void _Locale_monetary_destroy( struct _Locale_monetary *__loc )
+{ freelocale((locale_t)__loc); }
+
+void _Locale_messages_destroy( struct _Locale_messages* __loc )
+{ freelocale((locale_t)__loc); }
+
+/*
+ * locale loc expected either locale name indeed (platform-specific)
+ * or string like "LC_CTYPE=LocaleNameForCType;LC_NUMERIC=LocaleNameForNum;"
+ *
+ */
+
+static char const*__Extract_locale_name( const char *loc, const char *category, char *buf )
+{
+  char *expr;
+  size_t len_name;
+
+  if( loc[0]=='L' && loc[1]=='C' && loc[2]=='_') {
+    expr = strstr( (char*)loc, category );
+    if ( expr == NULL )
+      return NULL; /* Category not found. */
+    ++expr;
+    len_name = strcspn( expr, ";" );
+    len_name = len_name >= _Locale_MAX_SIMPLE_NAME ? _Locale_MAX_SIMPLE_NAME - 1 : len_name;
+    strncpy( buf, expr, len_name );
+    buf[len_name] = 0;
+    return buf;
+  }
+  return loc;
+}
+
+char const*_Locale_extract_ctype_name(const char *loc, char *buf,
+                                      struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_CTYPE=", buf ); }
+
+char const*_Locale_extract_numeric_name(const char *loc, char *buf,
+                                        struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_NUMERIC=", buf ); }
+
+char const*_Locale_extract_time_name(const char *loc, char *buf,
+                                     struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_TIME=", buf ); }
+
+char const*_Locale_extract_collate_name(const char *loc, char *buf,
+                                        struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_COLLATE=", buf ); }
+
+char const*_Locale_extract_monetary_name(const char *loc, char *buf,
+                                         struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_MONETARY=", buf ); }
+
+char const*_Locale_extract_messages_name(const char *loc, char *buf,
+                                         struct _Locale_name_hint* hint, int *__err_code)
+{ return __Extract_locale_name( loc, "LC_MESSAGES=", buf ); }
+
+struct _Locale_name_hint* _Locale_get_ctype_hint(struct _Locale_ctype* ctype)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_numeric_hint(struct _Locale_numeric* numeric)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_time_hint(struct _Locale_time* time)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_collate_hint(struct _Locale_collate* collate)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_monetary_hint(struct _Locale_monetary* monetary)
+{ return 0; }
+struct _Locale_name_hint* _Locale_get_messages_hint(struct _Locale_messages* messages)
+{ return 0; }
+
+/* ctype */
+
+const _Locale_mask_t *_Locale_ctype_table( struct _Locale_ctype *__loc )
+{
+  /* return table with masks (upper, lower, alpha, etc.) */
+  _STLP_STATIC_ASSERT( sizeof(_Locale_mask_t) == sizeof(((locale_t)__loc)->__ctype_b[0]) )
+  return ((locale_t)__loc)->__ctype_b;
+}
+
+int _Locale_toupper( struct _Locale_ctype *__loc, int c )
+{ return ((locale_t)__loc)->__ctype_toupper[c]; }
+
+int _Locale_tolower( struct _Locale_ctype *__loc, int c )
+{ return ((locale_t)__loc)->__ctype_tolower[c]; }
+
+#if !defined (_STLP_NO_WCHAR_T)
+_Locale_mask_t _WLocale_ctype( struct _Locale_ctype *__loc, wint_t wc, _Locale_mask_t __mask )
+{
+  _Locale_mask_t ret = 0;
+  if ((__mask & _Locale_ALPHA) != 0 && iswalpha_l(wc, (locale_t)__loc))
+    ret |= _Locale_ALPHA;
+  
+  if ((__mask & _Locale_CNTRL) != 0 && iswcntrl_l(wc, (locale_t)__loc))
+    ret |= _Locale_CNTRL;
+
+  if ((__mask & _Locale_DIGIT) != 0 && iswdigit_l(wc, (locale_t)__loc))
+    ret |= _Locale_DIGIT;
+
+  if ((__mask & _Locale_PRINT) != 0 && iswprint_l(wc, (locale_t)__loc)) 
+    ret |= _Locale_PRINT;
+
+  if ((__mask & _Locale_PUNCT) != 0 && iswpunct_l(wc, (locale_t)__loc))
+    ret |= _Locale_PUNCT;
+
+  if ((__mask & _Locale_SPACE) != 0 && iswspace_l(wc, (locale_t)__loc))
+    ret |= _Locale_SPACE;
+
+  if ((__mask & _Locale_XDIGIT) != 0 && iswxdigit_l(wc, (locale_t)__loc))
+    ret |= _Locale_XDIGIT;
+
+  if ((__mask & _Locale_UPPER) != 0 && iswupper_l(wc, (locale_t)__loc))
+    ret |= _Locale_UPPER;
+
+  if ((__mask & _Locale_LOWER) != 0 && iswlower_l(wc, (locale_t)__loc))
+    ret |= _Locale_LOWER;
+
+  return ret;
+}
+
+wint_t _WLocale_tolower( struct _Locale_ctype *__loc, wint_t c )
+{
+  return towlower_l( c, ((locale_t)__loc) );
+}
+
+wint_t _WLocale_toupper( struct _Locale_ctype *__loc, wint_t c )
+{
+  return towupper_l( c, ((locale_t)__loc) );
+}
+#endif
+
+int _WLocale_mb_cur_max( struct _Locale_codecvt * lcodecvt) { return 1; }
+int _WLocale_mb_cur_min( struct _Locale_codecvt * lcodecvt) { return 1; }
+int _WLocale_is_stateless( struct _Locale_codecvt * lcodecvt) { return 1; }
+
+#if !defined (_STLP_NO_WCHAR_T)
+size_t _WLocale_mbtowc(struct _Locale_codecvt *lcodecvt,
+                       wchar_t *to,
+                       const char *from, size_t n,
+                       mbstate_t *st)
+{ *to = *from; return 1; }
+
+size_t _WLocale_wctomb(struct _Locale_codecvt *lcodecvt,
+                       char *to, size_t n,
+                       const wchar_t c,
+                       mbstate_t *st)
+{ *to = (char)c; return 1; }
+#endif
+
+size_t _WLocale_unshift(struct _Locale_codecvt *lcodecvt,
+                        mbstate_t *st,
+                        char *buf, size_t n, char ** next)
+{ *next = buf; return 0; }
+
+/* Collate */
+int _Locale_strcmp(struct _Locale_collate * __loc,
+                   const char *s1, size_t n1,
+		   const char *s2, size_t n2) {
+  int ret = 0;
+  char buf1[64], buf2[64];
+  while (n1 > 0 || n2 > 0) {
+    size_t bufsize1 = n1 < 63 ? n1 : 63;
+    size_t bufsize2 = n2 < 63 ? n2 : 63;
+    strncpy(buf1, s1, bufsize1); buf1[bufsize1] = 0;
+    strncpy(buf2, s2, bufsize2); buf2[bufsize2] = 0;
+
+    ret = strcoll_l(buf1, buf2, (locale_t)__loc);
+    if (ret != 0) return ret;
+    s1 += bufsize1; n1 -= bufsize1;
+    s2 += bufsize2; n2 -= bufsize2;
+  }
+  return ret;
+}
+
+#if !defined (_STLP_NO_WCHAR_T)
+int _WLocale_strcmp(struct _Locale_collate *__loc,
+                    const wchar_t *s1, size_t n1,
+                    const wchar_t *s2, size_t n2) {
+  int ret = 0;
+  wchar_t buf1[64], buf2[64];
+  while (n1 > 0 || n2 > 0) {
+    size_t bufsize1 = n1 < 63 ? n1 : 63;
+    size_t bufsize2 = n2 < 63 ? n2 : 63;
+    wcsncpy(buf1, s1, bufsize1); buf1[bufsize1] = 0;
+    wcsncpy(buf2, s2, bufsize2); buf2[bufsize2] = 0;
+
+    ret = wcscoll_l(buf1, buf2, (locale_t)__loc);
+    if (ret != 0) return ret;
+    s1 += bufsize1; n1 -= bufsize1;
+    s2 += bufsize2; n2 -= bufsize2;
+  }
+  return ret;
+}
+
+#endif
+
+size_t _Locale_strxfrm(struct _Locale_collate *__loc,
+                       char *dest, size_t dest_n,
+                       const char *src, size_t src_n )
+{
+  const char *real_src;
+  char *buf = NULL;
+  size_t result;
+
+  if (src_n == 0)
+  {
+    if (dest != NULL) dest[0] = 0;
+    return 0;
+  }
+  if (src[src_n] != 0) {
+    buf = malloc(src_n + 1);
+    strncpy(buf, src, src_n);
+    buf[src_n] = 0;
+    real_src = buf;
+  }
+  else
+    real_src = src;
+  result = strxfrm_l(dest, real_src, dest_n, (locale_t)__loc);
+  if (buf != NULL) free(buf);
+  return result;
+}
+
+# ifndef _STLP_NO_WCHAR_T
+
+size_t _WLocale_strxfrm( struct _Locale_collate *__loc,
+                        wchar_t *dest, size_t dest_n,
+                        const wchar_t *src, size_t src_n )
+{
+  const wchar_t *real_src;
+  wchar_t *buf = NULL;
+  size_t result;
+
+  if (src_n == 0)
+  {
+    if (dest != NULL) dest[0] = 0;
+    return 0;
+  }
+  if (src[src_n] != 0) {
+    buf = malloc((src_n + 1) * sizeof(wchar_t));
+    wcsncpy(buf, src, src_n);
+    buf[src_n] = 0;
+    real_src = buf;
+  }
+  else
+    real_src = src;
+  result = wcsxfrm_l(dest, real_src, dest_n, (locale_t)__loc);
+  if (buf != NULL) free(buf);
+  return result;
+}
+
+# endif
+
+/* Numeric */
+
+char _Locale_decimal_point(struct _Locale_numeric *__loc)
+{
+  return *(nl_langinfo_l(RADIXCHAR, (locale_t)__loc));
+}
+
+char _Locale_thousands_sep(struct _Locale_numeric *__loc)
+{
+  return *(nl_langinfo_l(THOUSEP, (locale_t)__loc));
+}
+
+const char* _Locale_grouping(struct _Locale_numeric *__loc)
+{
+  return (_Locale_thousands_sep(__loc) != 0 ) ? (nl_langinfo_l(GROUPING, (locale_t)__loc)) : _empty_str;
+}
+
+const char *_Locale_true(struct _Locale_numeric *__loc)
+{
+  return nl_langinfo_l(YESSTR, (locale_t)__loc);
+}
+
+const char *_Locale_false(struct _Locale_numeric *__loc)
+{
+  return nl_langinfo_l(NOSTR, (locale_t)__loc);
+}
+
+#ifndef _STLP_NO_WCHAR_T
+wchar_t _WLocale_decimal_point(struct _Locale_numeric *__loc)
+{ return (wchar_t)_Locale_decimal_point(__loc); }
+wchar_t _WLocale_thousands_sep(struct _Locale_numeric *__loc)
+{ return (wchar_t)_Locale_thousands_sep(__loc); }
+const wchar_t *_WLocale_true(struct _Locale_numeric *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_true(__loc), buf, bufSize); }
+const wchar_t *_WLocale_false(struct _Locale_numeric *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_false(__loc), buf, bufSize); }
+#endif
+
+/* Monetary */
+
+const char *_Locale_int_curr_symbol(struct _Locale_monetary *__loc)
+{
+  return nl_langinfo_l(INT_CURR_SYMBOL, (locale_t)__loc);
+}
+
+const char *_Locale_currency_symbol(struct _Locale_monetary *__loc)
+{
+  return nl_langinfo_l(CURRENCY_SYMBOL, (locale_t)__loc);
+}
+
+char _Locale_mon_decimal_point(struct _Locale_monetary * __loc)
+{
+  return *(nl_langinfo_l(MON_DECIMAL_POINT,(locale_t)__loc));
+}
+
+char _Locale_mon_thousands_sep(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(MON_THOUSANDS_SEP, (locale_t)__loc));
+}
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t *_WLocale_int_curr_symbol(struct _Locale_monetary *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_int_curr_symbol(__loc), buf, bufSize); }
+const wchar_t *_WLocale_currency_symbol(struct _Locale_monetary *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_currency_symbol(__loc), buf, bufSize); }
+wchar_t _WLocale_mon_decimal_point(struct _Locale_monetary * __loc)
+{ return (wchar_t)_Locale_mon_decimal_point(__loc); }
+wchar_t _WLocale_mon_thousands_sep(struct _Locale_monetary * __loc)
+{ return (wchar_t)_Locale_mon_thousands_sep(__loc); }
+const wchar_t *_WLocale_positive_sign(struct _Locale_monetary *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_positive_sign(__loc), buf, bufSize); }
+const wchar_t *_WLocale_negative_sign(struct _Locale_monetary *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_negative_sign(__loc), buf, bufSize); }
+#endif
+
+const char *_Locale_mon_grouping(struct _Locale_monetary *__loc)
+{
+  return (_Locale_mon_thousands_sep( __loc ) != 0 ) ? nl_langinfo_l(MON_GROUPING, (locale_t)__loc) : _empty_str;
+}
+
+const char *_Locale_positive_sign(struct _Locale_monetary *__loc)
+{
+  return nl_langinfo_l(POSITIVE_SIGN, (locale_t)__loc);
+}
+
+const char *_Locale_negative_sign(struct _Locale_monetary *__loc)
+{
+  return nl_langinfo_l(NEGATIVE_SIGN, (locale_t)__loc);
+}
+
+char _Locale_int_frac_digits(struct _Locale_monetary *__loc)
+{
+  /* We are forced to manually handled the "C" locale for consistency with
+   * the default implementation in STLport. */
+  const char* lname = ((locale_t)__loc)->__names[LC_MONETARY];
+  if (lname[0] == 'C' && lname[1] == 0)
+    return 0;
+  return *(nl_langinfo_l(INT_FRAC_DIGITS, (locale_t)__loc));
+}
+
+char _Locale_frac_digits(struct _Locale_monetary *__loc)
+{
+  /* We are forced to manually handled the "C" locale for consistency with
+   * the default implementation in STLport. */
+  const char* lname = ((locale_t)__loc)->__names[LC_MONETARY];
+  if (lname[0] == 'C' && lname[1] == 0)
+    return 0;
+  return *(nl_langinfo_l(FRAC_DIGITS, (locale_t)__loc));
+}
+
+/* 1 if currency_symbol precedes a positive value, 0 if succeeds */
+int _Locale_p_cs_precedes(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(P_CS_PRECEDES, (locale_t)__loc));
+}
+
+/* 1 if a space separates currency_symbol from a positive value. */
+int _Locale_p_sep_by_space(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(P_SEP_BY_SPACE, (locale_t)__loc));
+}
+
+/*
+ * 0 Parentheses surround the quantity and currency_symbol
+ * 1 The sign string precedes the quantity and currency_symbol
+ * 2 The sign string succeeds the quantity and currency_symbol.
+ * 3 The sign string immediately precedes the currency_symbol.
+ * 4 The sign string immediately succeeds the currency_symbol.
+ */
+int _Locale_p_sign_posn(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(P_SIGN_POSN, (locale_t)__loc));
+}
+
+/* 1 if currency_symbol precedes a negative value, 0 if succeeds */
+int _Locale_n_cs_precedes(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(N_CS_PRECEDES, (locale_t)__loc));
+}
+
+/* 1 if a space separates currency_symbol from a negative value. */
+int _Locale_n_sep_by_space(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(N_SEP_BY_SPACE, (locale_t)__loc));
+}
+
+/*
+ * 0 Parentheses surround the quantity and currency_symbol
+ * 1 The sign string precedes the quantity and currency_symbol
+ * 2 The sign string succeeds the quantity and currency_symbol.
+ * 3 The sign string immediately precedes the currency_symbol.
+ * 4 The sign string immediately succeeds the currency_symbol.
+ */
+int _Locale_n_sign_posn(struct _Locale_monetary *__loc)
+{
+  return *(nl_langinfo_l(N_SIGN_POSN, (locale_t)__loc));
+}
+
+
+/* Time */
+const char *_Locale_full_monthname(struct _Locale_time *__loc, int _m )
+{
+  return nl_langinfo_l(MON_1 + _m, (locale_t)__loc);
+}
+
+const char *_Locale_abbrev_monthname(struct _Locale_time *__loc, int _m )
+{
+  return nl_langinfo_l(ABMON_1 + _m, (locale_t)__loc);
+}
+
+const char *_Locale_full_dayofweek(struct _Locale_time *__loc, int _d )
+{
+  return nl_langinfo_l(DAY_1 + _d, (locale_t)__loc);
+}
+
+const char *_Locale_abbrev_dayofweek(struct _Locale_time *__loc, int _d )
+{
+  return nl_langinfo_l(ABDAY_1 + _d, (locale_t)__loc);
+}
+
+const char *_Locale_d_t_fmt(struct _Locale_time *__loc)
+{
+  return nl_langinfo_l(D_T_FMT, (locale_t)__loc);
+}
+
+const char *_Locale_d_fmt(struct _Locale_time *__loc )
+{
+  return nl_langinfo_l(D_FMT, (locale_t)__loc);
+}
+
+const char *_Locale_t_fmt(struct _Locale_time *__loc )
+{
+  return nl_langinfo_l(T_FMT, (locale_t)__loc);
+}
+
+const char *_Locale_long_d_t_fmt(struct _Locale_time *__loc )
+{
+  return nl_langinfo_l(ERA_D_T_FMT, (locale_t)__loc);
+}
+
+const char *_Locale_long_d_fmt(struct _Locale_time *__loc )
+{
+  return nl_langinfo_l(ERA_D_FMT, (locale_t)__loc);
+}
+
+const char *_Locale_am_str(struct _Locale_time *__loc )
+{
+  return nl_langinfo_l(AM_STR, (locale_t)__loc);
+}
+
+const char *_Locale_pm_str(struct _Locale_time* __loc )
+{
+  return nl_langinfo_l(PM_STR, (locale_t)__loc);
+}
+
+#ifndef _STLP_NO_WCHAR_T
+const wchar_t *_WLocale_full_monthname(struct _Locale_time *__loc, int _m, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_full_monthname(__loc, _m), buf, bufSize); }
+const wchar_t *_WLocale_abbrev_monthname(struct _Locale_time *__loc, int _m, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_abbrev_monthname(__loc, _m), buf, bufSize); }
+const wchar_t *_WLocale_full_dayofweek(struct _Locale_time *__loc, int _d, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_full_dayofweek(__loc, _d), buf, bufSize); }
+const wchar_t *_WLocale_abbrev_dayofweek(struct _Locale_time *__loc, int _d, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_abbrev_dayofweek(__loc, _d), buf, bufSize); }
+const wchar_t *_WLocale_am_str(struct _Locale_time *__loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_am_str(__loc), buf, bufSize); }
+const wchar_t *_WLocale_pm_str(struct _Locale_time* __loc, wchar_t *buf, size_t bufSize)
+{ return _ToWChar(_Locale_pm_str(__loc), buf, bufSize); }
+#endif
+
+/* Messages */
+
+nl_catd_type _Locale_catopen(struct _Locale_messages *__loc, const char *__cat_name )
+{
+  return catopen( __cat_name, NL_CAT_LOCALE );
+}
+
+void _Locale_catclose(struct _Locale_messages *__loc, nl_catd_type __cat )
+{
+  catclose( __cat );
+}
+
+const char *_Locale_catgets(struct _Locale_messages *__loc, nl_catd_type __cat,
+                            int __setid, int __msgid, const char *dfault)
+{
+  return catgets( __cat, __setid, __msgid, dfault );
+}
new file mode 100644
--- /dev/null
+++ b/build/stlport/src/c_locale_win32/c_locale_win32.c
@@ -0,0 +1,1786 @@
+/*
+ * Copyright (c) 1999
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Copyright (c) 1999
+ * Boris Fomitchev
+ *
+ * Written 2000
+ * Anton Lapach
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
+
+#include <limits.h>
+#if defined (_STLP_MSVC) || defined (__ICL)
+#  include <memory.h>
+#endif
+#include <string.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
+#  define _STLP_STRCPY(D, DS, S) strcpy_s(D, DS, S)
+#  define _STLP_STRNCPY(D, DS, S, C) strncpy_s(D, DS, S, C)
+#  define _STLP_STRCAT(D, DS, S) strcat_s(D, DS, S)
+#else
+#  define _STLP_STRCPY(D, DS, S) strcpy(D, S)
+#  define _STLP_STRNCPY(D, DS, S, C) strncpy(D, S, C)
+#  define _STLP_STRCAT(D, DS, S) strcat(D, S)
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* Framework functions */
+/*
+  locale :: "lang[_country[.code_page]]"
+  | ".code_page"
+  | ""
+  | NULL
+
+*/
+
+typedef struct _LOCALECONV {
+  const char* name;
+  const char* abbrev;
+} LOCALECONV;
+
+#define MAX_LANG_LEN        64  /* max language name length */
+#define MAX_CTRY_LEN        64  /* max country name length */
+#define MAX_MODIFIER_LEN    0   /* max modifier name length - n/a */
+#define MAX_LC_LEN          (MAX_LANG_LEN+MAX_CTRY_LEN+MAX_MODIFIER_LEN+3)
+                                /* max entire locale string length */
+#define MAX_CP_LEN          5   /* max code page name length */
+
+#if !defined (LANG_INVARIANT)
+#  define LANG_INVARIANT 0x7f
+#  define _STLP_LANG_INVARIANT_DEFINED
+#endif
+
+#ifndef CP_UTF7
+#  define CP_UTF7 65000
+#endif
+
+#ifndef CP_UTF8
+#  define CP_UTF8 65001
+#endif
+
+#define INVARIANT_LCID MAKELCID(MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT)
+
+static const char *_C_name = "C";
+
+/*  non-NLS language string table */
+static LOCALECONV __rg_language[] = {
+  {"american",                    "ENU"},
+  {"american english",            "ENU"},
+  {"american-english",            "ENU"},
+  {"australian",                  "ENA"},
+  {"belgian",                     "NLB"},
+  {"canadian",                    "ENC"},
+  {"chh",                         "ZHH"},
+  {"chi",                         "ZHI"},
+  {"chinese",                     "CHS"},
+  {"chinese-hongkong",            "ZHH"},
+  {"chinese-simplified",          "CHS"},
+  {"chinese-singapore",           "ZHI"},
+  {"chinese-traditional",         "CHT"},
+  {"dutch-belgian",               "NLB"},
+  {"english-american",            "ENU"},
+  {"english-aus",                 "ENA"},
+  {"english-belize",              "ENL"},
+  {"english-can",                 "ENC"},
+  {"english-caribbean",           "ENB"},
+  {"english-ire",                 "ENI"},
+  {"english-jamaica",             "ENJ"},
+  {"english-nz",                  "ENZ"},
+  {"english-south africa",        "ENS"},
+  {"english-trinidad y tobago",   "ENT"},
+  {"english-uk",                  "ENG"},
+  {"english-us",                  "ENU"},
+  {"english-usa",                 "ENU"},
+  {"french-belgian",              "FRB"},
+  {"french-canadian",             "FRC"},
+  {"french-luxembourg",           "FRL"},
+  {"french-swiss",                "FRS"},
+  {"german-austrian",             "DEA"},
+  {"german-lichtenstein",         "DEC"},
+  {"german-luxembourg",           "DEL"},
+  {"german-swiss",                "DES"},
+  {"irish-english",               "ENI"},
+  {"italian-swiss",               "ITS"},
+  {"norwegian",                   "NOR"},
+  {"norwegian-bokmal",            "NOR"},
+  {"norwegian-nynorsk",           "NON"},
+  {"portuguese-brazilian",        "PTB"},
+  {"spanish-argentina",           "ESS"},
+  {"spanish-bolivia",             "ESB"},
+  {"spanish-chile",               "ESL"},
+  {"spanish-colombia",            "ESO"},
+  {"spanish-costa rica",          "ESC"},
+  {"spanish-dominican republic",  "ESD"},
+  {"spanish-ecuador",             "ESF"},
+  {"spanish-el salvador",         "ESE"},
+  {"spanish-guatemala",           "ESG"},
+  {"spanish-honduras",            "ESH"},
+  {"spanish-mexican",             "ESM"},
+  {"spanish-modern",              "ESN"},
+  {"spanish-nicaragua",           "ESI"},
+  {"spanish-panama",              "ESA"},
+  {"spanish-paraguay",            "ESZ"},
+  {"spanish-peru",                "ESR"},
+  {"spanish-puerto rico",         "ESU"},
+  {"spanish-uruguay",             "ESY"},
+  {"spanish-venezuela",           "ESV"},
+  {"swedish-finland",             "SVF"},
+  {"swiss",                       "DES"},
+  {"uk",                          "ENG"},
+  {"us",                          "ENU"},
+  {"usa",                         "ENU"}
+};
+
+/*  non-NLS country string table */
+static LOCALECONV __rg_country[] = {
+  {"america",                     "USA"},
+  {"britain",                     "GBR"},
+  {"china",                       "CHN"},
+  {"czech",                       "CZE"},
+  {"england",                     "GBR"},
+  {"great britain",               "GBR"},
+  {"holland",                     "NLD"},
+  {"hong-kong",                   "HKG"},
+  {"new-zealand",                 "NZL"},
+  {"nz",                          "NZL"},
+  {"pr china",                    "CHN"},
+  {"pr-china",                    "CHN"},
+  {"puerto-rico",                 "PRI"},
+  {"slovak",                      "SVK"},
+  {"south africa",                "ZAF"},
+  {"south korea",                 "KOR"},
+  {"south-africa",                "ZAF"},
+  {"south-korea",                 "KOR"},
+  {"trinidad & tobago",           "TTO"},
+  {"uk",                          "GBR"},
+  {"united-kingdom",              "GBR"},
+  {"united-states",               "USA"},
+  {"us",                          "USA"},
+};
+
+typedef struct _Locale_name_hint {
+  LCID id;
+} _Locale_lcid_t;
+
+typedef struct _Locale_ctype {
+  _Locale_lcid_t lc;
+  UINT cp;
+  unsigned short ctable[256];
+} _Locale_ctype_t;
+
+typedef struct _Locale_numeric {
+  _Locale_lcid_t lc;
+  char cp[MAX_CP_LEN + 1];
+  char decimal_point[4];
+  char thousands_sep[4];
+  char *grouping;
+} _Locale_numeric_t;
+
+typedef struct _Locale_time {
+  _Locale_lcid_t lc;
+  char cp[MAX_CP_LEN + 1];
+  char *month[12];
+  char *abbrev_month[12];
+  char *dayofweek[7];
+  char *abbrev_dayofweek[7];
+  char *date_time_format;
+  char *long_date_time_format;
+  char *date_format;
+  char *long_date_format;
+  char *time_format;
+  char am[9];
+  char pm[9];
+} _Locale_time_t;
+
+typedef struct _Locale_collate {
+  _Locale_lcid_t lc;
+  char cp[MAX_CP_LEN + 1];
+} _Locale_collate_t;
+
+typedef struct _Locale_monetary {
+  _Locale_lcid_t lc;
+  char cp[MAX_CP_LEN + 1];
+  char decimal_point[4];
+  char thousands_sep[4];
+  char *grouping;
+  char int_curr_symbol[5]; /* 3 + 1 + 1 */
+  char curr_symbol[6];
+  char negative_sign[5];
+  char positive_sign[5];
+  int frac_digits;
+  int int_frac_digits;
+} _Locale_monetary_t;
+
+/* Internal function */
+static void __FixGrouping(char *grouping);
+static const char* __ConvertName(const char* lname, LOCALECONV* ConvTable, int TableSize);
+static int __ParseLocaleString(const char* lname, char* lang, char* ctry, char* page);
+static int __GetLCID(const char* lang, const char* ctry, LCID* lcid);
+static int __GetLCIDFromName(const char* lname, LCID* lcid, char *cp, _Locale_lcid_t *hint);
+static char const* __GetLocaleName(LCID lcid, const char* cp, char* buf);
+static char const* __Extract_locale_name(const char* loc, const char* category, char* buf);
+static char const* __TranslateToSystem(const char* lname, char* buf, _Locale_lcid_t* hint, int *__err_code);
+static void __GetLocaleInfoUsingACP(LCID lcid, const char* cp, LCTYPE lctype, char* buf, int buf_size, wchar_t* wbuf, int wbuf_size);
+static int __intGetACP(LCID lcid);
+static int __intGetOCP(LCID lcid);
+static int __GetDefaultCP(LCID lcid);
+static char* __ConvertToCP(int from_cp, int to_cp, const char *from, size_t size, size_t *ret_buf_size);
+static void my_ltoa(long __x, char* buf);
+
+void my_ltoa(long __x, char* buf) {
+  char rbuf[64];
+  char* ptr = rbuf;
+
+  if (__x == 0)
+    *ptr++ = '0';
+  else {
+    for (; __x != 0; __x /= 10)
+      *ptr++ = (char)(__x % 10) + '0';
+  }
+  while(ptr > rbuf) *buf++ = *--ptr;
+  /* psw */
+  *buf = '\0';
+}
+
+#if defined (__cplusplus)
+_STLP_BEGIN_NAMESPACE
+extern "C" {
+#endif
+
+_Locale_lcid_t* _Locale_get_ctype_hint(_Locale_ctype_t* ltype)
+{ return (ltype != 0) ? &ltype->lc : 0; }
+_Locale_lcid_t* _Locale_get_numeric_hint(_Locale_numeric_t* lnumeric)
+{ return (lnumeric != 0) ? &lnumeric->lc : 0; }
+_Locale_lcid_t* _Locale_get_time_hint(_Locale_time_t* ltime)
+{ return (ltime != 0) ? &ltime->lc : 0; }
+_Locale_lcid_t* _Locale_get_collate_hint(_Locale_collate_t* lcollate)
+{ return (lcollate != 0) ? &lcollate->lc : 0; }
+_Locale_lcid_t* _Locale_get_monetary_hint(_Locale_monetary_t* lmonetary)
+{ return (lmonetary != 0) ? &lmonetary->lc : 0; }
+_Locale_lcid_t* _Locale_get_messages_hint(struct _Locale_messages* lmessages) {
+  _STLP_MARK_PARAMETER_AS_UNUSED(lmessages)
+  return 0;
+}
+
+#define MAP(x, y) if ((mask & x) != 0) ret |= (y)
+unsigned short MapCtypeMask(unsigned short mask) {
+  unsigned short ret = 0;
+  MAP(C1_UPPER, _Locale_UPPER | _Locale_PRINT);
+  MAP(C1_LOWER, _Locale_LOWER | _Locale_PRINT);
+  MAP(C1_DIGIT, _Locale_DIGIT | _Locale_PRINT);
+  MAP(C1_SPACE, _Locale_SPACE | _Locale_PRINT);
+  MAP(C1_PUNCT, _Locale_PUNCT | _Locale_PRINT);
+  /* MAP(C1_BLANK, ?); */
+  MAP(C1_XDIGIT, _Locale_XDIGIT | _Locale_PRINT);
+  MAP(C1_ALPHA, _Locale_ALPHA | _Locale_PRINT);
+  if ((mask & C1_CNTRL) != 0) { ret |= _Locale_CNTRL; ret &= ~_Locale_PRINT; }
+  return ret;
+}
+
+static void MapCtypeMasks(unsigned short *cur, unsigned short *end) {
+  for (; cur != end; ++cur) {
+    *cur = MapCtypeMask(*cur);
+  }
+}
+
+_Locale_ctype_t* _Locale_ctype_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
+  char cp_name[MAX_CP_LEN + 1];
+  int NativeCP;
+  unsigned char Buffer[256];
+  unsigned char *ptr;
+  CPINFO CPInfo;
+  int i;
+  wchar_t *wbuffer;
+  int BufferSize;
+
+  _Locale_ctype_t *ltype = (_Locale_ctype_t*)malloc(sizeof(_Locale_ctype_t));
+
+  if (!ltype) { *__err_code = _STLP_LOC_NO_MEMORY; return ltype; }
+  memset(ltype, 0, sizeof(_Locale_ctype_t));
+
+  if (__GetLCIDFromName(name, &ltype->lc.id, cp_name, lc_hint) == -1)
+  { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+#if defined (__BORLANDC__)
+  if ( ltype->lc.id == INVARIANT_LCID && name[0] == 'C' && name[1] == 0 )
+  { ltype->lc.id = 0x409; }
+#endif
+
+  ltype->cp = atoi(cp_name);
+
+  NativeCP = __GetDefaultCP(ltype->lc.id);
+
+  /* Make table with all characters. */
+  for (i = 0; i < 256; ++i) Buffer[i] = (unsigned char)i;
+
+  if (!GetCPInfo(NativeCP, &CPInfo)) { free(ltype); return NULL; }
+
+  if (CPInfo.MaxCharSize > 1) {
+    for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr+=2)
+      for (i = *ptr; i <= *(ptr + 1); ++i) Buffer[i] = 0;
+  }
+
+  if ((UINT)NativeCP != ltype->cp) {
+    OSVERSIONINFO ver_info;
+    ver_info.dwOSVersionInfoSize = sizeof(ver_info);
+    GetVersionEx(&ver_info);
+    if (ver_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+      /* Convert character sequence to Unicode. */
+      BufferSize = MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0);
+      if (!BufferSize) { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+      wbuffer = (wchar_t*)malloc(BufferSize * sizeof(wchar_t));
+      if (!wbuffer) { free(ltype); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+      MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize);
+
+      GetStringTypeW(CT_CTYPE1, wbuffer, 256, ltype->ctable);
+      MapCtypeMasks(ltype->ctable, ltype->ctable + 256);
+      free(wbuffer);
+    }
+    else {
+      unsigned short ctable[256];
+      unsigned char TargetBuffer[256];
+      GetStringTypeA(ltype->lc.id, CT_CTYPE1, (const char*)Buffer, 256, ctable);
+
+      /* Convert character sequence to target code page. */
+      BufferSize = MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0);
+      if (!BufferSize) { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+      wbuffer = (wchar_t*)malloc(BufferSize * sizeof(wchar_t));
+      if (!wbuffer) { free(ltype); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+      MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize);
+      if (!WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuffer, BufferSize, (char*)TargetBuffer, 256, NULL, FALSE))
+      { free(wbuffer); free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+      free(wbuffer);
+
+      /* Translate ctype table. */
+      for (i = 0; i < 256; ++i) {
+        if (!TargetBuffer[i]) continue;
+        ltype->ctable[TargetBuffer[i]] = MapCtypeMask(ctable[i]);
+      }
+    }
+  }
+  else {
+    GetStringTypeA(ltype->lc.id, CT_CTYPE1, (const char*)Buffer, 256, ltype->ctable);
+    MapCtypeMasks(ltype->ctable, ltype->ctable + 256);
+  }
+  return ltype;
+}
+
+_Locale_numeric_t* _Locale_numeric_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
+  wchar_t wbuf[4];
+  char *GroupingBuffer;
+  int BufferSize;
+
+  _Locale_numeric_t *lnum = (_Locale_numeric_t*)malloc(sizeof(_Locale_numeric_t));
+  if (!lnum) { *__err_code = _STLP_LOC_NO_MEMORY; return lnum; }
+  memset(lnum, 0, sizeof(_Locale_numeric_t));
+
+  if (__GetLCIDFromName(name, &lnum->lc.id, lnum->cp, lc_hint) == -1)
+  { free(lnum); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
+
+#if defined (__BORLANDC__)
+  if (lnum->lc.id != INVARIANT_LCID) {
+#endif
+  __GetLocaleInfoUsingACP(lnum->lc.id, lnum->cp, LOCALE_SDECIMAL, lnum->decimal_point, 4, wbuf, 4);
+  __GetLocaleInfoUsingACP(lnum->lc.id, lnum->cp, LOCALE_STHOUSAND, lnum->thousands_sep, 4, wbuf, 4);
+#if defined (__BORLANDC__)
+  }
+  else
+    lnum->decimal_point[0] = '.';
+#endif
+
+  if (lnum->lc.id != INVARIANT_LCID) {
+    BufferSize = GetLocaleInfoA(lnum->lc.id, LOCALE_SGROUPING, NULL, 0);
+    GroupingBuffer = (char*)malloc(BufferSize);
+    if (!GroupingBuffer) { free(lnum); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+    GetLocaleInfoA(lnum->lc.id, LOCALE_SGROUPING, GroupingBuffer, BufferSize);
+    __FixGrouping(GroupingBuffer);
+    lnum->grouping = GroupingBuffer;
+  }
+  else {
+    lnum->grouping = (char*)malloc(1);
+    if (!lnum->grouping) { free(lnum); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; }
+    lnum->grouping[0] = 0;
+  }
+
+  return lnum;
+}
+
+static int __ConvertDate(const char *NTDate, char *buffer, int buf_size) {
+  /* This function will return an incomplete buffer if buffer is not long enough */
+  const char *cur_char;
+  char *cur_output, *end_output;
+
+  /* Correct time format. */
+  cur_char = NTDate;
+  cur_output = buffer;
+  end_output = cur_output + buf_size;
+  buf_size = 0;
+  while (*cur_char) {
+    if (cur_output && (cur_output == end_output)) break;
+    switch (*cur_char) {
+    case 'd':
+    {
+      if (*(cur_char + 1) == 'd') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (*(cur_char + 2) == 'd') {
+          if (*(cur_char + 3) == 'd') {
+            if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'A'; }
+            buf_size += 2;
+            cur_char += 3;
+          }
+          else {
+            if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'a'; }
+            buf_size += 2;
+            cur_char += 2;
+          }
+        }
+        else {
+          if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'd'; }
+          buf_size += 2;
+          cur_char++;
+        }
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'd'; }
+        buf_size += 3;
+      }
+    }
+    break;
+    case 'M':
+    {
+      if (*(cur_char + 1) == 'M') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (*(cur_char + 2) == 'M') {
+          if (*(cur_char + 3) == 'M') {
+            if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'B'; }
+            buf_size += 2;
+            cur_char += 3;
+          }
+          else {
+            if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'b'; }
+            buf_size += 2;
+            cur_char += 2;
+          }
+        }
+        else {
+          if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'm'; }
+          buf_size += 2;
+          cur_char++;
+        }
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'm'; }
+        buf_size += 3;
+      }
+    }
+    break;
+    case 'y':
+    {
+      if (*(cur_char + 1) == 'y') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (*(cur_char + 2) == 'y' && *(cur_char + 3) == 'y') {
+          if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'Y'; }
+          buf_size += 2;
+          cur_char += 3;
+        }
+        else {
+          if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'y'; }
+          buf_size += 2;
+          cur_char++;
+        }
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'y'; }
+        buf_size += 3;
+      }
+    }
+    break;
+    case '%':
+    {
+      if (cur_output && (cur_output + 2 > end_output)) {
+        *cur_output = 0;
+        return ++buf_size;
+      }
+      if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '%'; }
+      buf_size += 2;
+    }
+    break;
+    case '\'':
+    {
+      ++cur_char;
+      while (*cur_char != '\'' && *cur_char != 0 && (cur_output == NULL || cur_output != end_output)) {
+        if (cur_output) { *cur_output++ = *cur_char; }
+        ++cur_char;
+        buf_size += 1;
+      }
+    }
+    break;
+    default:
+    {
+      if (cur_output) { *(cur_output++) = *cur_char; }
+      buf_size += 1;
+    }
+    break;
+    }
+    if (*cur_char == 0) break;
+    ++cur_char;
+  }
+
+  if (!cur_output || cur_output != end_output) {
+    if (cur_output) *cur_output = 0;
+    buf_size += 1;
+  }
+  else {
+    /* We trunc result */
+    *(--cur_output) = 0;
+  }
+
+  return buf_size;
+}
+
+static int __ConvertTime(const char *NTTime, char *buffer, int buf_size) {
+  const char *cur_char;
+  char *cur_output, *end_output;
+  cur_char = NTTime;
+  cur_output = buffer;
+  end_output = cur_output + buf_size;
+  buf_size = 0;
+  while (*cur_char) {
+    switch(*cur_char) {
+    case 'h':
+      if (*(cur_char + 1) == 'h') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'I'; }
+        buf_size += 2;
+        ++cur_char;
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'I'; }
+        buf_size += 3;
+      }
+      break;
+    case 'H':
+      if (*(cur_char + 1) == 'H') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'H'; }
+        buf_size += 2;
+        ++cur_char;
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'H'; }
+        buf_size += 3;
+      }
+      break;
+    case 'm':
+      if (*(cur_char + 1) == 'm') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'M'; }
+        buf_size += 2;
+        cur_char++;
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'M'; }
+        buf_size += 3;
+      }
+      break;
+    case 's':
+      if (*(cur_char + 1) == 's') {
+        if (cur_output && (cur_output + 2 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'S'; }
+        buf_size += 2;
+        ++cur_char;
+      }
+      else {
+        if (cur_output && (cur_output + 3 > end_output)) {
+          *cur_output = 0;
+          return ++buf_size;
+        }
+        if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'S'; }
+        buf_size += 3;
+      }
+      break;
+    case 't':
+      if (*(cur_char + 1) == 't')
+        ++cur_char;
+      if (cur_output && (cur_output + 2 > end_output)) {
+        *cur_output = 0;
+        return ++buf_size;
+      }
+      if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'p'; }
+      buf_size += 2;
+      break;
+    case '%':
+      if (cur_output && (cur_output + 2 > end_output)) {
+        *cur_output = 0;
+        return ++buf_size;
+      }
+      if (cur_output) { *(cur_output++)='%'; *(cur_output++)='%'; }
+      buf_size += 2;
+      break;
+    case '\'':
+      ++cur_char;
+      while (*cur_char != '\'' && *cur_char != 0 && (!cur_output || (cur_output != end_output))) {
+        if (cur_output) *cur_output++ = *cur_char;
+        ++cur_char;
+        buf_size += 1;
+      }
+      break;
+    default:
+      if (cur_output) { *(cur_output++) = *cur_char; }
+      buf_size += 1;
+      break;
+    }
+    if (*cur_char == 0) break;
+    ++cur_char;
+  }
+
+  if (!cur_output || cur_output != end_output) {
+    if (cur_output) *cur_output = 0;
+    buf_size += 1;
+  }
+  else {
+    /* We trunc result */
+    *(--cur_output) = 0;
+  }
+
+  return buf_size;
+}
+
+_Locale_time_t* _Locale_time_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
+  int size, month, dayofweek;
+  size_t length;
+  char fmt80[80];
+  wchar_t wbuf80[80];
+
+  _Locale_time_t *ltime = (_Locale_time_t*)malloc(sizeof(_Locale_time_t));
+  
+  if (!ltime) { *__err_code = _STLP_LOC_NO_MEMORY; return ltime; }