Merge last PGO-green changeset of mozilla-inbound to mozilla-central
authorEd Morley <bmo@edmorley.co.uk>
Sat, 24 Mar 2012 16:05:07 +0000
changeset 93556 20a01901480f5d107d74df171f77f09acfed80f8
parent 93452 ae8de224173233054d226733679d8712a4c225e4 (current diff)
parent 93555 4c2c3a714ebe2e689630874ea350d3f67db969bf (diff)
child 93557 841924d85767a902376707569b083c6d4f8ad58a
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone14.0a1
first release with
nightly linux32
20a01901480f / 14.0a1 / 20120325031055 / files
nightly linux64
20a01901480f / 14.0a1 / 20120325031055 / files
nightly mac
20a01901480f / 14.0a1 / 20120325031055 / files
nightly win32
20a01901480f / 14.0a1 / 20120325031055 / files
nightly win64
20a01901480f / 14.0a1 / 20120325031055 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
b2g/chrome/content/shell.js
b2g/installer/package-manifest.in
config/autoconf.mk.in
configure.in
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
editor/libeditor/base/nsEditorEventListener.cpp
mobile/android/base/resources/menu-v11/gecko_menu.xml
mobile/android/base/resources/menu/gecko_menu.xml
toolkit/components/places/nsPlacesImportExportService.cpp
toolkit/components/places/nsPlacesImportExportService.h
xulrunner/installer/mac/Description.plist.in
xulrunner/installer/mac/Info.plist.in
xulrunner/installer/mac/Makefile.in
--- a/Makefile.in
+++ b/Makefile.in
@@ -67,16 +67,21 @@ tier_base_dirs = \
 
 ifndef LIBXUL_SDK
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
 tier_base_dirs += \
   other-licenses/android \
   other-licenses/skia-npapi \
   $(NULL)
 endif
+ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
+tier_base_dirs += \
+  other-licenses/android \
+  $(NULL)
+endif
 
 ifdef MOZ_MEMORY
 tier_base_dirs += memory/jemalloc
 endif
 tier_base_dirs += \
   mozglue \
   memory/mozalloc \
   $(NULL)
--- a/accessible/public/nsIAccessibleRole.idl
+++ b/accessible/public/nsIAccessibleRole.idl
@@ -788,14 +788,19 @@ interface nsIAccessibleRole : nsISupport
   const unsigned long ROLE_NOTE = 123;
 
   /**
    * A figure. Used for things like HTML5 figure element.
    */
   const unsigned long ROLE_FIGURE = 124;
 
   /**
+   * Represents a rich item with a check box.
+   */
+  const unsigned long ROLE_CHECK_RICH_OPTION = 125;
+
+  /**
    * It's not role actually. This constant is important to help ensure
    * nsRoleMap's are synchronized.
    */
-  const unsigned long ROLE_LAST_ENTRY = 125;
+  const unsigned long ROLE_LAST_ENTRY = 126;
 };
 
--- a/accessible/src/atk/nsRoleMap.h
+++ b/accessible/src/atk/nsRoleMap.h
@@ -165,11 +165,12 @@ static const PRUint32 atkRoleMap[] = {
     ATK_ROLE_LIST_ITEM,           // roles::OPTION               117
     ATK_ROLE_LIST_ITEM,           // roles::RICH_OPTION          118
     ATK_ROLE_LIST,                // roles::LISTBOX              119
     ATK_ROLE_UNKNOWN,             // roles::FLAT_EQUATION        120
     ATK_ROLE_TABLE_CELL,          // roles::GRID_CELL            121
     ATK_ROLE_PANEL,               // roles::EMBEDDED_OBJECT      122
     ATK_ROLE_SECTION,             // roles::NOTE                 123
     ATK_ROLE_PANEL,               // roles::FIGURE               124
+    ATK_ROLE_CHECK_BOX,           // roles::CHECK_RICH_OPTION    125
     kROLE_ATK_LAST_ENTRY          // roles::LAST_ENTRY
 };
 
--- a/accessible/src/base/AccGroupInfo.h
+++ b/accessible/src/base/AccGroupInfo.h
@@ -62,16 +62,18 @@ public:
     mozilla::a11y::role role = aAccessible->Role();
     if (role != mozilla::a11y::roles::ROW &&
         role != mozilla::a11y::roles::GRID_CELL &&
         role != mozilla::a11y::roles::OUTLINEITEM &&
         role != mozilla::a11y::roles::OPTION &&
         role != mozilla::a11y::roles::LISTITEM &&
         role != mozilla::a11y::roles::MENUITEM &&
         role != mozilla::a11y::roles::COMBOBOX_OPTION &&
+        role != mozilla::a11y::roles::RICH_OPTION &&
+        role != mozilla::a11y::roles::CHECK_RICH_OPTION &&
         role != mozilla::a11y::roles::PARENT_MENUITEM &&
         role != mozilla::a11y::roles::CHECK_MENU_ITEM &&
         role != mozilla::a11y::roles::RADIO_MENU_ITEM &&
         role != mozilla::a11y::roles::RADIOBUTTON &&
         role != mozilla::a11y::roles::PAGETAB)
       return nsnull;
 
     AccGroupInfo* info = new AccGroupInfo(aAccessible, BaseRole(role));
@@ -83,16 +85,20 @@ private:
   AccGroupInfo& operator =(const AccGroupInfo&);
 
   static mozilla::a11y::role BaseRole(mozilla::a11y::role aRole)
   {
     if (aRole == mozilla::a11y::roles::CHECK_MENU_ITEM ||
         aRole == mozilla::a11y::roles::PARENT_MENUITEM ||
         aRole == mozilla::a11y::roles::RADIO_MENU_ITEM)
       return mozilla::a11y::roles::MENUITEM;
+
+    if (aRole == mozilla::a11y::roles::CHECK_RICH_OPTION)
+      return mozilla::a11y::roles::RICH_OPTION;
+
     return aRole;
   }
 
   /**
    * Return true if the given parent role is conceptual parent of the given
    * role.
    */
   static bool IsConceptualParent(mozilla::a11y::role aRole,
--- a/accessible/src/base/Role.h
+++ b/accessible/src/base/Role.h
@@ -785,19 +785,24 @@ namespace roles {
   NOTE = 123,
 
   /**
    * A figure. Used for things like HTML5 figure element.
    */
   FIGURE = 124,
 
   /**
+   * Represents a rich item with a check box.
+   */
+  CHECK_RICH_OPTION = 125,
+
+  /**
    * It's not role actually. This constant is important to help ensure
    * nsRoleMap's are synchronized.
    */
-  LAST_ENTRY = 125
+  LAST_ENTRY = 126
   };
 } // namespace role
 typedef enum mozilla::a11y::roles::Role role;
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -129,57 +129,16 @@ nsAccUtils::GetARIAOrDefaultLevel(nsAcce
                            nsGkAtoms::aria_level, &level);
 
   if (level != 0)
     return level;
 
   return GetDefaultLevel(aAccessible);
 }
 
-void
-nsAccUtils::GetPositionAndSizeForXULSelectControlItem(nsIContent *aContent,
-                                                      PRInt32 *aPosInSet,
-                                                      PRInt32 *aSetSize)
-{
-  nsCOMPtr<nsIDOMXULSelectControlItemElement> item(do_QueryInterface(aContent));
-  if (!item)
-    return;
-
-  nsCOMPtr<nsIDOMXULSelectControlElement> control;
-  item->GetControl(getter_AddRefs(control));
-  if (!control)
-    return;
-
-  PRUint32 itemsCount = 0;
-  control->GetItemCount(&itemsCount);
-
-  PRInt32 indexOf = 0;
-  control->GetIndexOfItem(item, &indexOf);
-
-  *aSetSize = itemsCount;
-  *aPosInSet = indexOf;
-
-  for (PRUint32 index = 0; index < itemsCount; index++) {
-    nsCOMPtr<nsIDOMXULSelectControlItemElement> currItem;
-    control->GetItemAtIndex(index, getter_AddRefs(currItem));
-    nsCOMPtr<nsINode> currNode(do_QueryInterface(currItem));
-
-    nsAccessible* itemAcc = currNode ?
-      GetAccService()->GetAccessible(currNode, nsnull) : nsnull;
-
-    if (!itemAcc || itemAcc->State() & states::INVISIBLE) {
-      (*aSetSize)--;
-      if (index < static_cast<PRUint32>(indexOf))
-        (*aPosInSet)--;
-    }
-  }
-
-  (*aPosInSet)++; // group position is 1-index based.
-}
-
 PRInt32
 nsAccUtils::GetLevelForXULContainerItem(nsIContent *aContent)
 {
   nsCOMPtr<nsIDOMXULContainerItemElement> item(do_QueryInterface(aContent));
   if (!item)
     return 0;
 
   nsCOMPtr<nsIDOMXULContainerElement> container;
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -103,24 +103,16 @@ public:
 
   /**
    * Return ARIA level value or the default one if ARIA is missed for the
    * given accessible.
    */
   static PRInt32 GetARIAOrDefaultLevel(nsAccessible *aAccessible);
 
   /**
-   * Compute position in group (posinset) and group size (setsize) for
-   * nsIDOMXULSelectControlItemElement node.
-   */
-  static void GetPositionAndSizeForXULSelectControlItem(nsIContent *aContent,
-                                                        PRInt32 *aPosInSet,
-                                                        PRInt32 *aSetSize);
-
-  /**
    * Compute group level for nsIDOMXULContainerItemElement node.
    */
   static PRInt32 GetLevelForXULContainerItem(nsIContent *aContent);
 
   /**
    * Set container-foo live region attributes for the given node.
    *
    * @param aAttributes    where to store the attributes
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -410,17 +410,18 @@ static const char kRoleNames[][20] = {
   "image map",           //ROLE_IMAGE_MAP
   "listbox option",      //ROLE_OPTION
   "listbox rich option", //ROLE_RICH_OPTION
   "listbox",             //ROLE_LISTBOX
   "flat equation",       //ROLE_FLAT_EQUATION
   "gridcell",            //ROLE_GRID_CELL
   "embedded object",     //ROLE_EMBEDDED_OBJECT
   "note",                //ROLE_NOTE
-  "figure"               //ROLE_FIGURE
+  "figure",              //ROLE_FIGURE
+  "check rich option"    //ROLE_CHECK_RICH_OPTION
 };
 
 /**
  * Map nsIAccessibleEvents constants to strings. Used by
  * nsIAccessibleRetrieval::getStringEventType() method.
  */
 static const char kEventTypeNames[][40] = {
   "unknown",                                 //
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -645,17 +645,17 @@ protected:
    * Cache accessible children.
    */
   virtual void CacheChildren();
 
   /**
    * Set accessible parent and index in parent.
    */
   virtual void BindToParent(nsAccessible* aParent, PRUint32 aIndexInParent);
-  void UnbindFromParent();
+  virtual void UnbindFromParent();
 
   /**
    * Return sibling accessible at the given offset.
    */
   virtual nsAccessible* GetSiblingAtOffset(PRInt32 aOffset,
                                            nsresult *aError = nsnull) const;
 
   /**
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/base/nsBaseWidgetAccessible.cpp
@@ -243,16 +243,26 @@ nsLinkableAccessible::BindToParent(nsAcc
     if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) {
       mActionAcc = walkUpAcc;
       mIsOnclick = true;
       return;
     }
   }
 }
 
+void
+nsLinkableAccessible::UnbindFromParent()
+{
+  mActionAcc = nsnull;
+  mIsLink = false;
+  mIsOnclick = false;
+
+  nsAccessibleWrap::UnbindFromParent();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsEnumRoleAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsEnumRoleAccessible::
   nsEnumRoleAccessible(nsIContent* aNode, nsDocAccessible* aDoc,
                        roles::Role aRole) :
   nsAccessibleWrap(aNode, aDoc), mRole(aRole)
--- a/accessible/src/base/nsBaseWidgetAccessible.h
+++ b/accessible/src/base/nsBaseWidgetAccessible.h
@@ -103,16 +103,17 @@ public:
   virtual KeyBinding AccessKey() const;
 
   // HyperLinkAccessible
   virtual already_AddRefed<nsIURI> AnchorURIAt(PRUint32 aAnchorIndex);
 
 protected:
   // nsAccessible
   virtual void BindToParent(nsAccessible* aParent, PRUint32 aIndexInParent);
+  virtual void UnbindFromParent();
 
   /**
    * Parent accessible that provides an action for this linkable accessible.
    */
   nsAccessible* mActionAcc;
   bool mIsLink;
   bool mIsOnclick;
 };
--- a/accessible/src/html/nsHTMLImageMapAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageMapAccessible.cpp
@@ -211,63 +211,16 @@ nsHTMLAreaAccessible::Description(nsStri
   aDescription.Truncate();
 
   // Still to do - follow IE's standard here
   nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mContent));
   if (area) 
     area->GetShape(aDescription);
 }
 
-NS_IMETHODIMP
-nsHTMLAreaAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
-                                PRInt32 *aWidth, PRInt32 *aHeight)
-{
-  NS_ENSURE_ARG_POINTER(aX);
-  *aX = 0;
-  NS_ENSURE_ARG_POINTER(aY);
-  *aY = 0;
-  NS_ENSURE_ARG_POINTER(aWidth);
-  *aWidth = 0;
-  NS_ENSURE_ARG_POINTER(aHeight);
-  *aHeight = 0;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  // Essentially this uses GetRect on mAreas of nsImageMap from nsImageFrame.
-  nsPresContext *presContext = GetPresContext();
-  NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
-
-  nsIFrame *frame = GetFrame();
-  NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
-  nsImageFrame *imageFrame = do_QueryFrame(frame);
-
-  nsImageMap* map = imageFrame->GetImageMap();
-  NS_ENSURE_TRUE(map, NS_ERROR_FAILURE);
-
-  nsRect rect;
-  nsresult rv = map->GetBoundsForAreaContent(mContent, rect);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aX = presContext->AppUnitsToDevPixels(rect.x);
-  *aY = presContext->AppUnitsToDevPixels(rect.y);
-
-  // XXX Areas are screwy; they return their rects as a pair of points, one pair
-  // stored into the width and height.
-  *aWidth  = presContext->AppUnitsToDevPixels(rect.width - rect.x);
-  *aHeight = presContext->AppUnitsToDevPixels(rect.height - rect.y);
-
-  // Put coords in absolute screen coords
-  nsIntRect orgRectPixels = frame->GetScreenRectExternal();
-  *aX += orgRectPixels.x;
-  *aY += orgRectPixels.y;
-
-  return NS_OK;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLAreaAccessible: nsAccessNode public
 
 bool
 nsHTMLAreaAccessible::IsPrimaryForNode() const
 {
   // Make HTML area DOM element not accessible. HTML image map accessible
   // manages its tree itself.
@@ -321,8 +274,30 @@ nsHTMLAreaAccessible::EndOffset()
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLAreaAccessible: nsAccessible protected
 
 void
 nsHTMLAreaAccessible::CacheChildren()
 {
   // No children for aria accessible.
 }
+
+void
+nsHTMLAreaAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame)
+{
+  nsIFrame* frame = GetFrame();
+  if (!frame)
+    return;
+
+  nsImageFrame* imageFrame = do_QueryFrame(frame);
+  nsImageMap* map = imageFrame->GetImageMap();
+
+  nsresult rv = map->GetBoundsForAreaContent(mContent, aBounds);
+  if (NS_FAILED(rv))
+    return;
+
+  // XXX Areas are screwy; they return their rects as a pair of points, one pair
+  // stored into the width and height.
+  aBounds.width -= aBounds.x;
+  aBounds.height -= aBounds.y;
+
+  *aBoundingFrame = frame;
+}
--- a/accessible/src/html/nsHTMLImageMapAccessible.h
+++ b/accessible/src/html/nsHTMLImageMapAccessible.h
@@ -91,20 +91,16 @@ nsAccessible::AsImageMap()
  * Accessible for image map areas - must be child of image.
  */
 class nsHTMLAreaAccessible : public nsHTMLLinkAccessible
 {
 public:
 
   nsHTMLAreaAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
 
-  // nsIAccessible
-
-  NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
-
   // nsAccessNode
   virtual bool IsPrimaryForNode() const;
 
   // nsAccessible
   virtual void Description(nsString& aDescription);
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual PRUint64 NativeState();
   virtual nsAccessible* ChildAtPoint(PRInt32 aX, PRInt32 aY,
@@ -113,11 +109,12 @@ public:
   // HyperLinkAccessible
   virtual PRUint32 StartOffset();
   virtual PRUint32 EndOffset();
 
 protected:
 
   // nsAccessible
   virtual void CacheChildren();
+  virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
 };
 
 #endif  
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -1219,17 +1219,17 @@ nsHyperTextAccessible::GetAttributesInte
   nsIFrame *frame = GetFrame();
   if (frame && frame->GetType() == nsGkAtoms::blockFrame) {
     nsAutoString oldValueUnused;
     aAttributes->SetStringProperty(NS_LITERAL_CSTRING("formatting"), NS_LITERAL_STRING("block"),
                                    oldValueUnused);
   }
 
   if (FocusMgr()->IsFocused(this)) {
-    PRInt32 lineNumber = GetCaretLineNumber();
+    PRInt32 lineNumber = CaretLineNumber();
     if (lineNumber >= 1) {
       nsAutoString strLineNumber;
       strLineNumber.AppendInt(lineNumber);
       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::lineNumber,
                              strLineNumber);
     }
   }
 
@@ -1675,17 +1675,17 @@ nsHyperTextAccessible::GetCaretOffset(PR
       return NS_OK;
   }
 
   DOMPointToHypertextOffset(focusNode, focusOffset, aCaretOffset);
   return NS_OK;
 }
 
 PRInt32
-nsHyperTextAccessible::GetCaretLineNumber()
+nsHyperTextAccessible::CaretLineNumber()
 {
   // Provide the line number for the caret, relative to the
   // currently focused node. Use a 1-based index
   nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
   if (!frameSelection)
     return -1;
 
   nsISelection* domSel =
--- a/accessible/src/html/nsHyperTextAccessible.h
+++ b/accessible/src/html/nsHyperTextAccessible.h
@@ -259,16 +259,32 @@ public:
    *
    * @param  aOffset  [in] the given text offset
    */
   nsAccessible* GetChildAtOffset(PRUint32 aOffset)
   {
     return GetChildAt(GetChildIndexAtOffset(aOffset));
   }
 
+  /**
+   * Return the bounds of the text between given start and end offset.
+   */
+  nsIntRect GetTextBounds(PRInt32 aStartOffset, PRInt32 aEndOffset)
+  {
+    nsIntRect bounds;
+    GetPosAndText(aStartOffset, aEndOffset, nsnull, nsnull, &bounds);
+    return bounds;
+  }
+
+  /**
+   * Provide the line number for the caret.
+   * @return 1-based index for the line number with the caret
+   */
+  PRInt32 CaretLineNumber();
+
   //////////////////////////////////////////////////////////////////////////////
   // EditableTextAccessible
 
   /**
    * Return the editor associated with the accessible.
    */
   virtual already_AddRefed<nsIEditor> GetEditor() const;
 
@@ -368,23 +384,16 @@ protected:
 
   /**
    * Return selection ranges within the accessible subtree.
    */
   void GetSelectionDOMRanges(PRInt16 aType, nsTArray<nsRange*>* aRanges);
 
   nsresult SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos);
 
-  /**
-   * Provide the line number for the caret, relative to the
-   * current DOM node.
-   * @return 1-based index for the line number with the caret
-   */
-  PRInt32 GetCaretLineNumber();
-
   // Helpers
   nsresult GetDOMPointByFrameOffset(nsIFrame *aFrame, PRInt32 aOffset,
                                     nsIAccessible *aAccessible,
                                     nsIDOMNode **aNode, PRInt32 *aNodeOffset);
 
   
   /**
    * Return hyper text offset for the specified bound of the given DOM range.
--- a/accessible/src/mac/mozAccessible.h
+++ b/accessible/src/mac/mozAccessible.h
@@ -39,16 +39,28 @@
 #include "nsAccessibleWrap.h"
 
 #import <Cocoa/Cocoa.h>
 
 #import "mozAccessibleProtocol.h"
 
 @class mozRootAccessible;
 
+/**
+ * All mozAccessibles are either abstract objects (that correspond to XUL
+ * widgets, HTML frames, etc) or are attached to a certain view; for example
+ * a document view. When we hand an object off to an AT, we always want
+ * to give it the represented view, in the latter case.
+ */
+inline id <mozAccessible>
+GetObjectOrRepresentedView(id <mozAccessible> aObject)
+{
+  return [aObject hasRepresentedView] ? [aObject representedView] : aObject;
+}
+
 @interface mozAccessible : NSObject <mozAccessible>
 {
   /**
    * Weak reference; it owns us.
    */
   nsAccessibleWrap* mGeckoAccessible;
   
   /**
--- a/accessible/src/mac/mozAccessible.mm
+++ b/accessible/src/mac/mozAccessible.mm
@@ -66,31 +66,16 @@ using namespace mozilla::a11y;
 // of the screen), into a top-left screen point, that gecko can use.
 static inline void
 ConvertCocoaToGeckoPoint(NSPoint &aInPoint, nsPoint &aOutPoint)
 {
   float mainScreenHeight = [(NSView*)[[NSScreen screens] objectAtIndex:0] frame].size.height;
   aOutPoint.MoveTo ((nscoord)aInPoint.x, (nscoord)(mainScreenHeight - aInPoint.y));
 }
 
-// all mozAccessibles are either abstract objects (that correspond to XUL widgets, HTML frames, etc) or are
-// attached to a certain view; for example a document view. when we hand an object off to an AT, we always want
-// to give it the represented view, in the latter case.
-static inline id <mozAccessible>
-GetObjectOrRepresentedView(id <mozAccessible> anObject)
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
-  if ([anObject hasRepresentedView])
-    return [anObject representedView];
-  return anObject;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
 // returns the passed in object if it is not ignored. if it's ignored, will return
 // the first unignored ancestor.
 static inline id
 GetClosestInterestingAccessible(id anObject)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   // this object is not ignored, so let's return it.
--- a/accessible/src/mac/mozTextAccessible.h
+++ b/accessible/src/mac/mozTextAccessible.h
@@ -5,18 +5,8 @@
 @interface mozTextAccessible : mozAccessible
 {
   // both of these are the same old mGeckoAccessible, but already
   // QI'd for us, to the right type, for convenience.
   nsHyperTextAccessible     *mGeckoTextAccessible;         // strong
   nsIAccessibleEditableText *mGeckoEditableTextAccessible; // strong
 }
 @end
-
-/* A combobox (in the mac world) is a textfield with an associated menu, for example
-   the location bar. */
-@interface mozComboboxAccessible : mozTextAccessible
-// equivalent to pressing return key in this textfield.
-- (void)confirm;
-
-// shows the menu for this combobox.
-- (void)showMenu;
-@end
--- a/accessible/src/mac/mozTextAccessible.mm
+++ b/accessible/src/mac/mozTextAccessible.mm
@@ -1,8 +1,10 @@
+/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
 #include "nsAccessibleWrap.h"
 
 #include "nsCocoaUtils.h"
 #include "nsObjCExceptions.h"
 
 #import "mozTextAccessible.h"
 
 using namespace mozilla::a11y;
@@ -238,112 +240,15 @@ using namespace mozilla::a11y;
 }
 
 #pragma mark -
 
 - (void)valueDidChange
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
-  NSAccessibilityPostNotification([self hasRepresentedView] ? [self representedView] : self, 
+  NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
                                   NSAccessibilityValueChangedNotification);
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 @end
-
-@implementation mozComboboxAccessible
-
-- (NSArray*)accessibilityAttributeNames
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
-  static NSArray *supportedAttributes = nil;
-  if (!supportedAttributes) {
-    // standard attributes that are shared and supported by all generic elements.
-    supportedAttributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
-                                                           NSAccessibilityRoleAttribute,   // required
-                                                           NSAccessibilityTitleAttribute,
-                                                           NSAccessibilityValueAttribute, // required
-                                                           NSAccessibilityHelpAttribute,
-                                                           NSAccessibilityRoleDescriptionAttribute,
-                                                           NSAccessibilityPositionAttribute, // required
-                                                           NSAccessibilitySizeAttribute, // required
-                                                           NSAccessibilityWindowAttribute, // required
-                                                           NSAccessibilityFocusedAttribute, // required
-                                                           NSAccessibilityEnabledAttribute, // required
-                                                           NSAccessibilityChildrenAttribute, // required
-                                                           NSAccessibilityHelpAttribute,
-                                                           // NSAccessibilityExpandedAttribute, // required
-                                                           NSAccessibilityTopLevelUIElementAttribute, // required
-                                                           NSAccessibilityDescriptionAttribute, // required
-                                                           /* text-specific attributes */
-                                                           NSAccessibilitySelectedTextAttribute, // required
-                                                           NSAccessibilitySelectedTextRangeAttribute, // required
-                                                           NSAccessibilityNumberOfCharactersAttribute, // required
-                                                           // TODO: NSAccessibilityVisibleCharacterRangeAttribute, // required
-                                                           // TODO: NSAccessibilityInsertionPointLineNumberAttribute
-#if DEBUG
-                                                           @"AXMozDescription",
-#endif
-                                                           nil];
-  }
-  return supportedAttributes;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (NSArray *)accessibilityActionNames
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
-  if ([self isEnabled]) {
-    return [NSArray arrayWithObjects:NSAccessibilityConfirmAction,
-                                     NSAccessibilityShowMenuAction,
-                                     nil];
-  }
-  return nil;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (NSString *)accessibilityActionDescription:(NSString *)action
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
-  if ([action isEqualToString:NSAccessibilityShowMenuAction])
-    return @"show menu";
-  if ([action isEqualToString:NSAccessibilityConfirmAction])
-    return @"confirm";
-    
-  return [super accessibilityActionDescription:action];
-
-  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (void)accessibilityPerformAction:(NSString *)action
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
-  // both the ShowMenu and Click action do the same thing.
-  if ([self isEnabled]) {
-    if ([action isEqualToString:NSAccessibilityShowMenuAction])
-      [self showMenu];
-    if ([action isEqualToString:NSAccessibilityConfirmAction])
-      [self confirm];
-  }
-
-  NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (void)showMenu
-{
-  // currently unimplemented. waiting for support in bug 363697
-}
-
-- (void)confirm
-{
-  // should be the same as pressing enter/return in this textfield.
-  // not yet implemented
-}
-
-@end
--- a/accessible/src/mac/nsAccessibleWrap.mm
+++ b/accessible/src/mac/nsAccessibleWrap.mm
@@ -105,19 +105,16 @@ nsAccessibleWrap::GetNativeType ()
     }
     
     case roles::PAGETAB:
       return [mozButtonAccessible class];
 
     case roles::CHECKBUTTON:
       return [mozCheckboxAccessible class];
       
-    case roles::AUTOCOMPLETE:
-      return [mozComboboxAccessible class];
-
     case roles::HEADING:
       return [mozHeadingAccessible class];
 
     case roles::PAGETABLIST:
       return [mozTabsAccessible class];
       
     case roles::ENTRY:
     case roles::STATICTEXT:
--- a/accessible/src/mac/nsRoleMap.h
+++ b/accessible/src/mac/nsRoleMap.h
@@ -137,17 +137,17 @@ static const NSString* AXRoles [] = {
   NSAccessibilityGroupRole,                     // ROLE_TEXT_CONTAINER
   NSAccessibilityButtonRole,                    // ROLE_TOGGLE_BUTTON
   NSAccessibilityTableRole,                     // ROLE_TREE_TABLE
   NSAccessibilityUnknownRole,                   // ROLE_VIEWPORT
   NSAccessibilityGroupRole,                     // ROLE_HEADER
   NSAccessibilityGroupRole,                     // ROLE_FOOTER
   NSAccessibilityGroupRole,                     // ROLE_PARAGRAPH
   @"AXRuler",                                   // ROLE_RULER. 10.4+ only, so we re-define the constant.
-  NSAccessibilityComboBoxRole,                  // ROLE_AUTOCOMPLETE
+  NSAccessibilityUnknownRole,                   // ROLE_AUTOCOMPLETE
   NSAccessibilityTextFieldRole,                 // ROLE_EDITBAR
   NSAccessibilityTextFieldRole,                 // ROLE_ENTRY
   NSAccessibilityStaticTextRole,                // ROLE_CAPTION
   NSAccessibilityScrollAreaRole,                // ROLE_DOCUMENT_FRAME
   @"AXHeading",                                 // ROLE_HEADING
   NSAccessibilityGroupRole,                     // ROLE_PAG
   NSAccessibilityGroupRole,                     // ROLE_SECTION
   NSAccessibilityUnknownRole,                   // ROLE_REDUNDANT_OBJECT
@@ -162,10 +162,11 @@ static const NSString* AXRoles [] = {
   NSAccessibilityRowRole,                       // ROLE_OPTION
   NSAccessibilityRowRole,                       // ROLE_RICH_OPTION
   NSAccessibilityListRole,                      // ROLE_LISTBOX
   NSAccessibilityUnknownRole,                   // ROLE_FLAT_EQUATION
   NSAccessibilityGroupRole,                     // ROLE_GRID_CELL
   NSAccessibilityGroupRole,                     // ROLE_EMBEDDED_OBJECT
   NSAccessibilityGroupRole,                     // ROLE_NOTE
   NSAccessibilityGroupRole,                     // ROLE_FIGURE
+  NSAccessibilityCheckBoxRole,                  // ROLE_CHECK_RICH_OPTION
   @"ROLE_LAST_ENTRY"                            // ROLE_LAST_ENTRY. bogus role that will never be shown (just marks the end of this array)!
 };
--- a/accessible/src/msaa/nsRoleMap.h
+++ b/accessible/src/msaa/nsRoleMap.h
@@ -444,12 +444,15 @@ static const WindowsRoleMapItem gWindows
   { USE_ROLE_STRING, IA2_ROLE_EMBEDDED_OBJECT },
 
   // roles::NOTE
   { USE_ROLE_STRING, IA2_ROLE_NOTE },
 
   // roles::FIGURE
   { ROLE_SYSTEM_GROUPING, ROLE_SYSTEM_GROUPING },
 
+  // roles::CHECK_RICH_OPTION
+  { ROLE_SYSTEM_CHECKBUTTON, ROLE_SYSTEM_CHECKBUTTON },
+
   // roles::LAST_ENTRY
   { ROLE_WINDOWS_LAST_ENTRY, ROLE_WINDOWS_LAST_ENTRY }
 };
 
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -522,24 +522,16 @@ nsXULRadioButtonAccessible::NativeState(
     if (selected) {
       state |= states::CHECKED;
     }
   }
 
   return state;
 }
 
-void
-nsXULRadioButtonAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
-                                                       PRInt32 *aSetSize)
-{
-  nsAccUtils::GetPositionAndSizeForXULSelectControlItem(mContent, aPosInSet,
-                                                        aSetSize);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULRadioButtonAccessible: Widgets
 
 nsAccessible*
 nsXULRadioButtonAccessible::ContainerWidget() const
 {
   return mParent;
 }
--- a/accessible/src/xul/nsXULFormControlAccessible.h
+++ b/accessible/src/xul/nsXULFormControlAccessible.h
@@ -157,18 +157,16 @@ public:
  */
 class nsXULRadioButtonAccessible : public nsRadioButtonAccessible
 {
 
 public:
   nsXULRadioButtonAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
 
   // nsAccessible
-  virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
-                                          PRInt32 *aSetSize);
   virtual PRUint64 NativeState();
 
   // Widgets
   virtual nsAccessible* ContainerWidget() const;
 };
 
 /**
  * Used for XUL radiogroup element.
--- a/accessible/src/xul/nsXULListboxAccessible.cpp
+++ b/accessible/src/xul/nsXULListboxAccessible.cpp
@@ -971,17 +971,17 @@ nsXULListitemAccessible::NativeRole()
     NS_ERROR("No list accessible for listitem accessible!");
     return roles::NOTHING;
   }
 
   if (list->Role() == roles::TABLE)
     return roles::ROW;
 
   if (mIsCheckbox)
-    return roles::CHECKBUTTON;
+    return roles::CHECK_RICH_OPTION;
 
   if (mParent && mParent->Role() == roles::COMBOBOX_LIST)
     return roles::COMBOBOX_OPTION;
 
   return roles::RICH_OPTION;
 }
 
 PRUint64
@@ -1026,24 +1026,16 @@ NS_IMETHODIMP nsXULListitemAccessible::G
 
 bool
 nsXULListitemAccessible::CanHaveAnonChildren()
 {
   // That indicates we should walk anonymous children for listitems
   return true;
 }
 
-void
-nsXULListitemAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
-                                                    PRInt32 *aSetSize)
-{
-  nsAccUtils::GetPositionAndSizeForXULSelectControlItem(mContent, aPosInSet,
-                                                        aSetSize);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULListitemAccessible: Widgets
 
 nsAccessible*
 nsXULListitemAccessible::ContainerWidget() const
 {
   return Parent();
 }
--- a/accessible/src/xul/nsXULListboxAccessible.h
+++ b/accessible/src/xul/nsXULListboxAccessible.h
@@ -134,18 +134,16 @@ public:
   NS_IMETHOD GetActionName(PRUint8 index, nsAString& aName);
   // Don't use XUL menuitems's description attribute
 
   // nsAccessible
   virtual void Description(nsString& aDesc);
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
-  virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
-                                          PRInt32 *aSetSize);
   virtual bool CanHaveAnonChildren();
 
   // Widgets
   virtual nsAccessible* ContainerWidget() const;
 
 protected:
   /**
    * Return listbox accessible for the listitem.
--- a/accessible/src/xul/nsXULTabAccessible.cpp
+++ b/accessible/src/xul/nsXULTabAccessible.cpp
@@ -159,24 +159,16 @@ nsXULTabAccessible::RelationByType(PRUin
   if (!tabpanelNode)
     return rel;
 
   nsCOMPtr<nsIContent> tabpanelContent(do_QueryInterface(tabpanelNode));
   rel.AppendTarget(tabpanelContent);
   return rel;
 }
 
-void
-nsXULTabAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
-                                               PRInt32 *aSetSize)
-{
-  nsAccUtils::GetPositionAndSizeForXULSelectControlItem(mContent, aPosInSet,
-                                                        aSetSize);
-}
-
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTabsAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTabsAccessible::
   nsXULTabsAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
   XULSelectControlAccessible(aContent, aDoc)
--- a/accessible/src/xul/nsXULTabAccessible.h
+++ b/accessible/src/xul/nsXULTabAccessible.h
@@ -54,18 +54,16 @@ public:
 
   nsXULTabAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
 
   // nsIAccessible
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
 
   // nsAccessible
-  virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
-                                          PRInt32 *aSetSize);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
   virtual Relation RelationByType(PRUint32 aType);
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 };
 
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -87,22 +87,26 @@ nsXULTreeAccessible::
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: nsISupports and cycle collection implementation
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTreeAccessible)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeAccessible,
                                                   nsAccessible)
-CycleCollectorTraverseCache(tmp->mAccessibleCache, &cb);
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTree)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTreeView)
+  CycleCollectorTraverseCache(tmp->mAccessibleCache, &cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeAccessible,
                                                 nsAccessible)
-ClearCache(tmp->mAccessibleCache);
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTree)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTreeView)
+  ClearCache(tmp->mAccessibleCache);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXULTreeAccessible)
 NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsXULTreeAccessible)
 NS_INTERFACE_MAP_END_INHERITING(nsAccessible)
 
 NS_IMPL_ADDREF_INHERITED(nsXULTreeAccessible, nsAccessible)
 NS_IMPL_RELEASE_INHERITED(nsXULTreeAccessible, nsAccessible)
--- a/accessible/tests/mochitest/actions/test_tree.xul
+++ b/accessible/tests/mochitest/actions/test_tree.xul
@@ -38,17 +38,17 @@
     }
 
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
     // gA11yEventDumpID = "debug";
     //gA11yEventDumpToConsole = true; // debug
 
-    function doTestActions()
+    function doTest()
     {
       var treeNode = getNode("tree");
 
       var treeBodyNode = treeNode.boxObject.treeBody;
 
       var tree = getAccessible(treeNode);
       var expandedTreeItem = tree.getChildAt(2);
       var collapsedTreeItem = tree.getChildAt(5);
@@ -86,25 +86,18 @@
             testStates(this.ID, STATE_COLLAPSED);
           }
         }
       ];
 
       testActions(actions); // Will call SimpleTest.finish();
     }
 
-    function doTest()
-    {
-      var treeNode = getNode("tree");
-      waitForEvent(EVENT_REORDER, treeNode, doTestActions);
-      treeNode.view = new nsTreeTreeView();
-    }
-
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yXULTreeLoadEvent(doTest, "tree", new nsTreeTreeView());
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
          title="Reorganize implementation of XUL tree accessibility">
--- a/accessible/tests/mochitest/attributes/test_obj_group.xul
+++ b/accessible/tests/mochitest/attributes/test_obj_group.xul
@@ -72,18 +72,20 @@
 
     //gA11yEventDumpToConsole = true; // debug stuff
 
     var gQueue = null;
     function doTest()
     {
       //////////////////////////////////////////////////////////////////////////
       // xul:listbox (bug 417317)
-      testGroupAttrs("item1", 1, 2);
-      testGroupAttrs("item2", 2, 2);
+      testGroupAttrs("listitem1", 1, 4);
+      testGroupAttrs("listitem2", 2, 4);
+      testGroupAttrs("listitem3", 3, 4);
+      testGroupAttrs("listitem4", 4, 4);
 
       //////////////////////////////////////////////////////////////////////////
       // xul:tab
       testGroupAttrs("tab1", 1, 2);
       testGroupAttrs("tab2", 2, 2);
 
       //////////////////////////////////////////////////////////////////////////
       // xul:radio
@@ -138,19 +140,22 @@
     <p id="display"></p>
     <div id="content" style="display: none">
     </div>
     <pre id="test">
     </pre>
   </body>
 
   <vbox flex="1">
+
   <listbox>
-    <listitem label="item1" id="item1"/>
-    <listitem label="item2" id="item2"/>
+    <listitem label="listitem1" id="listitem1"/>
+    <listitem label="listitem2" id="listitem2" type="checkbox"/>
+    <listitem label="listitem3" id="listitem3" type="checkbox"/>
+    <listitem label="listitem4" id="listitem4"/>
   </listbox>
 
   <menubar>
     <menu label="item1" id="menu_item1">
       <menupopup>
         <menuitem label="item1.1" id="menu_item1.1"/>
         <menuseparator/>
         <menuitem label="item1.2" id="menu_item1.2"/>
--- a/accessible/tests/mochitest/attributes/test_obj_group_tree.xul
+++ b/accessible/tests/mochitest/attributes/test_obj_group_tree.xul
@@ -19,17 +19,17 @@
   <script type="application/javascript"
           src="../events.js" />
 
   <script type="application/javascript">
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
-    function doTestAttrs()
+    function doTest()
     {
       var treeNode = getNode("tree");
 
       var tree = getAccessible(treeNode);
       var treeitem1 = tree.firstChild.nextSibling;
       testGroupAttrs(treeitem1, 1, 4, 1);
 
       var treeitem2 = treeitem1.nextSibling;
@@ -45,25 +45,18 @@
       testGroupAttrs(treeitem5, 3, 4, 1);
 
       var treeitem6 = treeitem5.nextSibling;
       testGroupAttrs(treeitem6, 4, 4, 1);
 
       SimpleTest.finish();
     }
 
-    function doTest()
-    {
-      var treeNode = getNode("tree");
-      waitForEvent(EVENT_REORDER, treeNode, doTestAttrs);
-      treeNode.view = new nsTreeTreeView();
-    }
-
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yXULTreeLoadEvent(doTest, "tree", new nsTreeTreeView());
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
          title="Reorganize implementation of XUL tree accessibility">
--- a/accessible/tests/mochitest/bounds/test_zoom.html
+++ b/accessible/tests/mochitest/bounds/test_zoom.html
@@ -2,48 +2,68 @@
 <html>
 <head>
   <title>Accessible boundaries when page is zoomed</title>
   <link rel="stylesheet" type="text/css"
         href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
   <script type="application/javascript"
           src="../layout.js"></script>
   <script type="application/javascript"
           src="../browser.js"></script>
 
   <script type="application/javascript">
     function doTest()
     {
       var tabDocument = currentTabDocument();
-      var p1 = tabDocument.body.firstElementChild;
-      var p2 = tabDocument.body.lastElementChild;
+      var p1 = tabDocument.getElementById("p1");
+      var p2 = tabDocument.getElementById("p2");
+
+      var imgMap = tabDocument.getElementById("imgmap");
+      ensureImageMapTree(imgMap);
+      var imgMapAcc = getAccessible(imgMap);
+      var area = imgMapAcc.firstChild;
 
       testBounds(p1);
       testBounds(p2);
+      testBounds(area);
 
       zoomDocument(tabDocument, 2.0);
 
       testBounds(p1);
       testBounds(p2);
+      testBounds(area);
 
       closeBrowserWindow();
       SimpleTest.finish();
     }
 
+    var url = "data:text/html,<html><body>";
+    url += "<p id='p1'>para 1</p><p id='p2'>para 2</p>";
+    url += "<map name='atoz_map' id='map'>";
+    url += "  <area id='area1' href='http%3A%2F%2Fmozilla.org'";
+    url += "        coords=17,0,30,14' alt='mozilla.org' shape='rect'>";
+    url += "</map>";
+    url += "<img id='imgmap' width='447' height='15'";
+    url += "     usemap='%23atoz_map'";
+    url += "     src='chrome%3A%2F%2Fmochitests%2Fcontent%2Fa11y%2Faccessible%2Fletters.gif'>";
+    url += "</body></html>";
+
     SimpleTest.waitForExplicitFinish();
     openBrowserWindow(doTest,
-                      "data:text/html,<html><body><p>para 1</p><p>para 2</p></body></html>",
+                      url,
                       { left: 0, top: 0, width: 600, height: 600 });
   </script>
 </head>
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=650241"
      title="Location returned by accessibles incorrect when page zoomed">
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -489,17 +489,19 @@ function testDefunctAccessible(aAcc, aNo
 /**
  * Ensure that image map accessible tree is created.
  */
 function ensureImageMapTree(aID)
 {
   // XXX: We send a useless mouse move to the image to force it to setup its
   // image map, because flushing layout won't do it. Hopefully bug 135040
   // will make this not suck.
-  synthesizeMouse(getNode(aID), 10, 10, { type: "mousemove" });
+  var image = getNode(aID);
+  synthesizeMouse(image, 10, 10, { type: "mousemove" },
+                  image.ownerDocument.defaultView);
 
   // XXX This may affect a11y more than other code because imagemaps may not
   // get drawn or have an mouse event over them. Bug 570322 tracks a11y
   // dealing with this.
   todo(false, "Need to remove this image map workaround.");
 }
 
 /**
--- a/accessible/tests/mochitest/events/test_focus_tree.xul
+++ b/accessible/tests/mochitest/events/test_focus_tree.xul
@@ -24,33 +24,16 @@
           src="../events.js" />
 
   <script type="application/javascript">
   <![CDATA[
 
     ////////////////////////////////////////////////////////////////////////////
     // Invokers
 
-    function setTreeView(aTreeID, aView)
-    {
-      this.DOMNode = getNode(aTreeID);
-
-      this.eventSeq = [
-        new invokerChecker(EVENT_REORDER, this.DOMNode)
-      ];
-
-      this.invoke = function setTreeView_invoke()
-      {
-        this.DOMNode.treeBoxObject.view = aView;
-      }
-
-      this.getID = function setTreeView_getID()
-        { return "set tree view for " + prettyName(aTreeID); }
-    };
-
     function focusTree(aTreeID)
     {
       var checker = new focusChecker(getFirstTreeItem, aTreeID);
       this.__proto__ = new synthFocus(aTreeID, [ checker ]);
     }
 
     function moveToNextItem(aTreeID)
     {
@@ -77,29 +60,28 @@
 
     //gA11yEventDumpID = "debug"; // debugging
     //gA11yEventDumpToConsole = true; // debugging
 
     function doTest()
     {
       gQueue = new eventQueue();
 
-      gQueue.push(new setTreeView("tree", new nsTableTreeView(5)));
       gQueue.push(new focusTree("tree"));
       gQueue.push(new moveToNextItem("tree"));
       gQueue.push(new synthFocus("emptytree"));
 
       // no focus event for changed current item for unfocused tree
       gQueue.push(new changeCurrentItem("tree", 0));
 
       gQueue.invoke();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yXULTreeLoadEvent(doTest, "tree", new nsTableTreeView(5));
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=386821"
          title="Need better solution for firing delayed event against xul tree">
--- a/accessible/tests/mochitest/focus/test_takeFocus.xul
+++ b/accessible/tests/mochitest/focus/test_takeFocus.xul
@@ -21,33 +21,16 @@
   <script type="application/javascript"
           src="../treeview.js" />
 
   <script type="application/javascript">
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
     // Invokers
 
-    function setTreeView(aTreeID, aView)
-    {
-      this.DOMNode = getNode(aTreeID);
-
-      this.eventSeq = [
-        new invokerChecker(EVENT_REORDER, this.DOMNode)
-      ];
-
-      this.invoke = function setTreeView_invoke()
-      {
-        this.DOMNode.treeBoxObject.view = aView;
-      }
-
-      this.getID = function setTreeView_getID()
-        { return "set tree view for " + prettyName(aTreeID); }
-    };
-
     function takeFocusInvoker(aID, aArgConverterFunc)
     {
       this.targetFunc = aArgConverterFunc ? aArgConverterFunc : getAccessible;
 
       this.eventSeq = [ new focusChecker(this.targetFunc, aID) ];
 
       this.invoke = function takeFocusInvoker_invoke()
       {
@@ -72,25 +55,24 @@
     //gA11yEventDumpToConsole = true; // debug stuff
 
     var gQueue = null;
     function doTests()
     {
       // Test focus events.
       gQueue = new eventQueue();
 
-      gQueue.push(new setTreeView("tree", new nsTableTreeView(5)));
       gQueue.push(new takeFocusInvoker("tree", getLastChild));
       gQueue.push(new takeFocusInvoker("listitem2"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTests);
+    addA11yXULTreeLoadEvent(doTests, "tree", new nsTableTreeView(5));
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=706067"
          title="Make takeFocus work on widget items">
--- a/accessible/tests/mochitest/hittest/test_general.xul
+++ b/accessible/tests/mochitest/hittest/test_general.xul
@@ -10,42 +10,31 @@
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
 
   <script type="application/javascript"
           src="../treeview.js" />
 
   <script type="application/javascript"
           src="../common.js" />
   <script type="application/javascript"
+          src="../events.js" />
+  <script type="application/javascript"
           src="../layout.js" />
 
   <script type="application/javascript">
   <![CDATA[
     function doTest()
     {
-      // Initialize the tree
-      var view = new nsTableTreeView(5);
-
-      var tree = getNode("tree");
-      var treeBox = tree.treeBoxObject;
-      treeBox.view = view;
-
-      // Tests
-      var treecols = getNode("treecols");
-      var x = treecols.boxObject.x;
-      var y = treecols.boxObject.y;
-
-      testChildAtPoint(tree, x, y, false, treecols);
-      testChildAtPoint(tree, x, y, true, "col1");
+      hitTest("tree", "treecols", "col1");
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yXULTreeLoadEvent(doTest, "tree", new nsTableTreeView(5));
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=471493"
          title=" crash [@ nsPropertyTable::GetPropertyInternal]">
--- a/accessible/tests/mochitest/layout.js
+++ b/accessible/tests/mochitest/layout.js
@@ -102,21 +102,47 @@ function getBounds(aID)
 }
 
 /**
  * Return DOM node coordinates relative the screen and its size in device
  * pixels.
  */
 function getBoundsForDOMElm(aID)
 {
+  var x = 0, y = 0, width = 0, height = 0;
+
   var elm = getNode(aID);
+  if (elm.localName == "area") {
+    var mapName = elm.parentNode.getAttribute("name");
+    var selector = "[usemap='#" + mapName + "']";
+    var img = elm.ownerDocument.querySelector(selector);
+
+    var areaCoords = elm.coords.split(",");
+    var areaX = parseInt(areaCoords[0]);
+    var areaY = parseInt(areaCoords[1]);
+    var areaWidth = parseInt(areaCoords[2]) - areaX;
+    var areaHeight = parseInt(areaCoords[3]) - areaY;
+
+    var rect = img.getBoundingClientRect();
+    x = rect.left + areaX;
+    y = rect.top + areaY;
+    width = areaWidth;
+    height = areaHeight;
+  }
+  else {
+    var rect = elm.getBoundingClientRect();
+    x = rect.left;
+    y = rect.top;
+    width = rect.width;
+    height = rect.height;
+  }
+
   var elmWindow = elm.ownerDocument.defaultView;
   var winUtil = elmWindow.
     QueryInterface(Components.interfaces.nsIInterfaceRequestor).
     getInterface(Components.interfaces.nsIDOMWindowUtils);
 
   var ratio = winUtil.screenPixelsPerCSSPixel;
-  var rect = elm.getBoundingClientRect();
-  return [ (rect.left + elmWindow.mozInnerScreenX) * ratio,
-           (rect.top + elmWindow.mozInnerScreenY) * ratio,
-           rect.width * ratio,
-           rect.height * ratio ];
+  return [ (x + elmWindow.mozInnerScreenX) * ratio,
+           (y + elmWindow.mozInnerScreenY) * ratio,
+           width * ratio,
+           height * ratio ];
 }
--- a/accessible/tests/mochitest/relations/test_tree.xul
+++ b/accessible/tests/mochitest/relations/test_tree.xul
@@ -19,17 +19,17 @@
   <script type="application/javascript"
           src="../relations.js" />
 
   <script type="application/javascript">
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
-    function doTestRelations()
+    function doTest()
     {
       var treeNode = getNode("tree");
 
       var tree = getAccessible(treeNode);
       var treeitem1 = tree.firstChild.nextSibling;
       testRelation(treeitem1, RELATION_NODE_CHILD_OF, [tree]);
 
       var treeitem2 = treeitem1.nextSibling;
@@ -49,25 +49,18 @@
 
       // treeitems and treecells shouldn't pick up relations from tree
       testRelation(treeitem1, RELATION_LABELLED_BY, null);
       testRelation(treeitem1.firstChild, RELATION_LABELLED_BY, null);
 
       SimpleTest.finish();
     }
 
-    function doTest()
-    {
-      var treeNode = getNode("tree");
-      waitForEvent(EVENT_REORDER, treeNode, doTestRelations);
-      treeNode.view = new nsTreeTreeView();
-    }
-
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yXULTreeLoadEvent(doTest, "tree", new nsTreeTreeView());
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
          title="Reorganize implementation of XUL tree accessibility">
--- a/accessible/tests/mochitest/table/test_headers_tree.xul
+++ b/accessible/tests/mochitest/table/test_headers_tree.xul
@@ -19,36 +19,21 @@
   <script type="application/javascript"
           src="../table.js" />
 
   <script type="application/javascript">
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
-    var gTree = null;
-    var gTreeBox = null;
-    var gTreeView = null;
-
     // gA11yEventDumpID = "debug";
 
     function doTest()
     {
-      // Initialize the tree
-      gTree = document.getElementById("tree");
-      gTreeBox = gTree.treeBoxObject;
-      gView = new nsTableTreeView(3);
-
-      waitForEvent(EVENT_REORDER, gTree, continueTest);
-      gTreeBox.view = gView;
-    }
-
-    function continueTest()
-    {
-      var treeAcc = getAccessible(gTree, [nsIAccessibleTable]);
+      var treeAcc = getAccessible("tree", [nsIAccessibleTable]);
 
       var headerInfoMap = [
         {
           cell: treeAcc.getCellAt(0, 0),
           rowHeaderCells: [],
           columnHeaderCells: [ "col" ]
         },
         {
@@ -79,17 +64,17 @@
       ];
 
       testHeaderCells(headerInfoMap);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yXULTreeLoadEvent(doTest, "tree", new nsTableTreeView(3));
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=512424"
          title="implement IAccessibleTable2">
--- a/accessible/tests/mochitest/table/test_indexes_tree.xul
+++ b/accessible/tests/mochitest/table/test_indexes_tree.xul
@@ -19,47 +19,32 @@
   <script type="application/javascript"
           src="../table.js" />
 
   <script type="application/javascript">
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
-    var gTree = null;
-    var gTreeBox = null;
-    var gTreeView = null;
-
     // gA11yEventDumpID = "debug";
 
     function doTest()
     {
-      // Initialize the tree
-      gTree = document.getElementById("tree");
-      gTreeBox = gTree.treeBoxObject;
-      gView = new nsTableTreeView(3);
-
-      waitForEvent(EVENT_REORDER, gTree, continueTest);
-      gTreeBox.view = gView;
-    }
-
-    function continueTest()
-    {
       var idxes = [
         [0, 1],
         [2, 3],
         [4, 5]
       ];
-      testTableIndexes(gTree, idxes);
+      testTableIndexes("tree", idxes);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yXULTreeLoadEvent(doTest, "tree", new nsTableTreeView(3));
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
          title="Reorganize implementation of XUL tree accessibility">
--- a/accessible/tests/mochitest/table/test_sels_tree.xul
+++ b/accessible/tests/mochitest/table/test_sels_tree.xul
@@ -21,51 +21,36 @@
   <script type="application/javascript"
           src="../table.js" />
 
   <script type="application/javascript">
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
-    var gTree = null;
-    var gTreeBox = null;
-    var gTreeView = null;
-
     // gA11yEventDumpID = "debug";
 
     function doTest()
     {
-      // Initialize the tree
-      gTree = document.getElementById("tree");
-      gTreeBox = gTree.treeBoxObject;
-      gView = new nsTableTreeView(3);
-
-      waitForEvent(EVENT_REORDER, gTree, continueTest);
-      gTreeBox.view = gView;
-    }
-
-    function continueTest()
-    {
       var cellsArray =
       [
         [false, false],
         [false, false],
         [false, false]
       ];
 
-      testTableSelection(gTree, cellsArray);
-      testSelectTableRow(gTree, 0, cellsArray);
-      testUnselectTableRow(gTree, 0, cellsArray);
+      testTableSelection("tree", cellsArray);
+      testSelectTableRow("tree", 0, cellsArray);
+      testUnselectTableRow("tree", 0, cellsArray);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yXULTreeLoadEvent(doTest, "tree", new nsTableTreeView(3));
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
          title="Reorganize implementation of XUL tree accessibility">
--- a/accessible/tests/mochitest/table/test_struct_tree.xul
+++ b/accessible/tests/mochitest/table/test_struct_tree.xul
@@ -21,48 +21,33 @@
   <script type="application/javascript"
           src="../table.js" />
 
   <script type="application/javascript">
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
-    var gTree = null;
-    var gTreeBox = null;
-    var gTreeView = null;
-
     // gA11yEventDumpID = "debug";
 
     function doTest()
     {
-      // Initialize the tree
-      gTree = document.getElementById("table");
-      gTreeBox = gTree.treeBoxObject;
-      gView = new nsTableTreeView(3);
-
-      waitForEvent(EVENT_REORDER, gTree, continueTest);
-      gTreeBox.view = gView;
-    }
-
-    function continueTest()
-    {
       var cellsArray = [
         [kDataCell, kDataCell],
         [kDataCell, kDataCell],
         [kDataCell, kDataCell]
       ];
 
-      testTableStruct(gTree, cellsArray, kTreeColumnHeader);
+      testTableStruct("table", cellsArray, kTreeColumnHeader);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yXULTreeLoadEvent(doTest, "table", new nsTableTreeView(3));
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=512424"
          title="implement IAccessibleTable2">
--- a/accessible/tests/mochitest/treeview.js
+++ b/accessible/tests/mochitest/treeview.js
@@ -1,8 +1,49 @@
+/**
+ * Helper method to start a single XUL tree test.
+ */
+var gXULTreeLoadQueue = null;
+function addA11yXULTreeLoadEvent(aDoTestFunc, aTreeID, aTreeView)
+{
+  function loadXULTree(aTreeID, aTreeView)
+  {
+    this.treeNode = getNode(aTreeID);
+
+    this.eventSeq = [
+      new invokerChecker(EVENT_REORDER, this.treeNode)
+    ];
+
+    this.invoke = function loadXULTree_invoke()
+    {
+      this.treeNode.treeBoxObject.view = aTreeView;
+    }
+
+    this.getID = function loadXULTree_getID()
+    {
+      return "Load XUL tree " + prettyName(aTreeID);
+    }
+  }
+
+  function doXULTreeTest()
+  {
+    gXULTreeLoadQueue = new eventQueue();
+    gXULTreeLoadQueue.push(new loadXULTree(aTreeID, aTreeView));
+    gXULTreeLoadQueue.onFinish = function()
+    {
+      SimpleTest.executeSoon(aDoTestFunc);
+      return DO_NOT_FINISH_TEST;
+    }
+    gXULTreeLoadQueue.invoke();
+  }
+
+  addA11yLoadEvent(doXULTreeTest);
+}
+
+
 function nsTableTreeView(aRowCount)
 {
   this.__proto__ = new nsTreeView();
 
   for (var idx = 0; idx < aRowCount; idx++)
     this.mData.push(new treeItem("row" + String(idx) + "_"));
 }
 
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -69,16 +69,22 @@ config/doxygen.cfg
 config/expandlibs_config.py
 config/tests/src-simple/Makefile
 mfbt/Makefile
 probes/Makefile
 extensions/Makefile
 "
 
 if [ ! "$LIBXUL_SDK" ]; then
+  if [ "$STLPORT_SOURCES" ]; then
+    add_makefiles "
+      build/stlport/Makefile
+      build/stlport/stl/config/_android.h
+    "
+  fi
   add_makefiles "
     memory/mozalloc/Makefile
     mozglue/Makefile
     mozglue/build/Makefile
   "
   if [ "$MOZ_MEMORY" ]; then
     add_makefiles "
       memory/jemalloc/Makefile
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -273,27 +273,46 @@ var shell = {
   sendEvent: function shell_sendEvent(content, type, details) {
     let event = content.document.createEvent('CustomEvent');
     event.initCustomEvent(type, true, true, details ? details : {});
     content.dispatchEvent(event);
   }
 };
 
 (function PowerManager() {
-  let idleHandler = {
-    observe: function(subject, topic, time) {
-      if (topic === "idle") {
-        // TODO: Check wakelock status. See bug 697132.
+  // This will eventually be moved to content, so use content API as
+  // much as possible here. TODO: Bug 738530
+  let power = navigator.mozPower;
+  let idleHandler = function idleHandler(subject, topic, time) {
+    if (topic === "idle") {
+      if (power.getWakeLockState("screen") != "locked-foreground") {
         screen.mozEnabled = false;
       }
-    },
+    }
+  }
+  let wakeLockHandler = function wakeLockHandler(topic, state) {
+    // Turn off the screen when no one needs the it or all of them are
+    // invisible, otherwise turn the screen on. Note that the CPU
+    // might go to sleep as soon as the screen is turned off and
+    // acquiring wake lock will not bring it back (actually the code
+    // is not executed at all).
+    if (topic == "screen") {
+      if (state != "locked-foreground") {
+        if (Services.idle.idleTime > idleTimeout*1000) {
+          screen.mozEnabled = false;
+        }
+      } else {
+        screen.mozEnabled = true;
+      }
+    }
   }
   let idleTimeout = Services.prefs.getIntPref("power.screen.timeout");
   if (idleTimeout) {
     Services.idle.addIdleObserver(idleHandler, idleTimeout);
+    power.addWakeLockListener(wakeLockHandler);
   }
 })();
 
 function nsBrowserAccess() {
 }
 
 nsBrowserAccess.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow]),
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -231,16 +231,17 @@
 @BINPATH@/components/necko.xpt
 @BINPATH@/components/loginmgr.xpt
 @BINPATH@/components/parentalcontrols.xpt
 @BINPATH@/components/places.xpt
 @BINPATH@/components/plugin.xpt
 @BINPATH@/components/pref.xpt
 @BINPATH@/components/prefetch.xpt
 @BINPATH@/components/profile.xpt
+@BINPATH@/components/profiler.xpt
 @BINPATH@/components/proxyObject.xpt
 @BINPATH@/components/rdf.xpt
 @BINPATH@/components/satchel.xpt
 @BINPATH@/components/saxparser.xpt
 @BINPATH@/components/sessionstore.xpt
 #ifdef MOZ_SERVICES_SYNC
 @BINPATH@/components/services-crypto.xpt
 #endif
--- a/browser/base/content/test/browser_bug329212.js
+++ b/browser/base/content/test/browser_bug329212.js
@@ -2,40 +2,40 @@ function test () {
   waitForExplicitFinish();
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
     let doc = gBrowser.contentDocument;
     let tooltip = document.getElementById("aHTMLTooltip");
 
-    ok(FillInHTMLTooltip(doc.getElementById("svg1"), "should get title"));
+    ok(FillInHTMLTooltip(doc.getElementById("svg1")), "should get title");
     is(tooltip.getAttribute("label"), "This is a non-root SVG element title");
 
-    ok(FillInHTMLTooltip(doc.getElementById("text1"), "should get title"));
+    ok(FillInHTMLTooltip(doc.getElementById("text1")), "should get title");
     is(tooltip.getAttribute("label"), "\n\n\n    This            is a title\n\n    ");
 
-    ok(!FillInHTMLTooltip(doc.getElementById("text2"), "should not get title"));
+    ok(!FillInHTMLTooltip(doc.getElementById("text2")), "should not get title");
 
-    ok(!FillInHTMLTooltip(doc.getElementById("text3"), "should not get title"));
+    ok(!FillInHTMLTooltip(doc.getElementById("text3")), "should not get title");
 
-    ok(FillInHTMLTooltip(doc.getElementById("link1"), "should get title"));
+    ok(FillInHTMLTooltip(doc.getElementById("link1")), "should get title");
     is(tooltip.getAttribute("label"), "\n      This is a title\n    ");
-    ok(FillInHTMLTooltip(doc.getElementById("text4"), "should get title"));
+    ok(FillInHTMLTooltip(doc.getElementById("text4")), "should get title");
     is(tooltip.getAttribute("label"), "\n      This is a title\n    ");
 
-    ok(!FillInHTMLTooltip(doc.getElementById("link2"), "should not get title"));
+    ok(!FillInHTMLTooltip(doc.getElementById("link2")), "should not get title");
 
-    ok(FillInHTMLTooltip(doc.getElementById("link3"), "should get title"));
-    ok(tooltip.getAttribute("label") != "");
+    ok(FillInHTMLTooltip(doc.getElementById("link3")), "should get title");
+    isnot(tooltip.getAttribute("label"), "");
 
-    ok(FillInHTMLTooltip(doc.getElementById("link4"), "should get title"));
+    ok(FillInHTMLTooltip(doc.getElementById("link4")), "should get title");
     is(tooltip.getAttribute("label"), "This is an xlink:title attribute");
 
-    ok(!FillInHTMLTooltip(doc.getElementById("text5"), "should not get title"));
+    ok(!FillInHTMLTooltip(doc.getElementById("text5")), "should not get title");
 
     gBrowser.removeCurrentTab();
     finish();
   }, true);
 
   content.location = 
     "http://mochi.test:8888/browser/browser/base/content/test/title_test.svg";
 }
--- a/browser/components/migration/src/nsBrowserProfileMigratorUtils.cpp
+++ b/browser/components/migration/src/nsBrowserProfileMigratorUtils.cpp
@@ -158,25 +158,8 @@ GetProfilePath(nsIProfileStartup* aStart
       (do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
     if (dirSvc) {
       dirSvc->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
                   (void**) getter_AddRefs(aProfileDir));
     }
   }
 }
 
-nsresult
-ImportDefaultBookmarks()
-{
-  nsCOMPtr<nsIPlacesImportExportService> importer =
-    do_GetService(NS_PLACESIMPORTEXPORTSERVICE_CONTRACTID);
-  NS_ENSURE_STATE(importer);
-
-  nsCOMPtr<nsIIOService> ioService = mozilla::services::GetIOService();
-  NS_ENSURE_STATE(ioService);
-  nsCOMPtr<nsIURI> bookmarksURI;
-  nsresult rv = ioService->NewURI(DEFAULT_BOOKMARKS, nsnull, nsnull,
-                                  getter_AddRefs(bookmarksURI));
-  if (NS_FAILED(rv))
-    return rv;
-
-  return importer->ImportHTMLFromURI(bookmarksURI, true);
-}
--- a/browser/components/migration/src/nsBrowserProfileMigratorUtils.h
+++ b/browser/components/migration/src/nsBrowserProfileMigratorUtils.h
@@ -94,15 +94,10 @@ void GetMigrateDataFromArray(MigrationDa
                              nsIFile* aSourceProfile, 
                              PRUint16* aResult);
 
 
 // get the base directory of the *target* profile
 // this is already cloned, modify it to your heart's content
 void GetProfilePath(nsIProfileStartup* aStartup, nsCOMPtr<nsIFile>& aProfileDir);
 
-/**
- * Imports default bookmarks to the profile.
- */
-nsresult ImportDefaultBookmarks();
-
 #endif
 
--- a/browser/components/migration/src/nsIEProfileMigrator.cpp
+++ b/browser/components/migration/src/nsIEProfileMigrator.cpp
@@ -1393,21 +1393,16 @@ nsIEProfileMigrator::CopyFavoritesBatche
 
     rv = bms->CreateFolder(bookmarksMenuFolderId,
                            NS_ConvertUTF16toUTF8(importedIEFavsTitle),
                            nsINavBookmarksService::DEFAULT_INDEX,
                            &folder);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
-    // If importing defaults fails for whatever reason, let the import process
-    // continue.
-    DebugOnly<nsresult> rv = ImportDefaultBookmarks();
-    MOZ_ASSERT(NS_SUCCEEDED(rv), "Should be able to import default bookmarks");
-
     // Locate the Links toolbar folder, we want to replace the Personal Toolbar
     // content with Favorites in this folder.
     // On versions minor or equal to IE6 the folder name is stored in the
     // LinksFolderName registry key, but in newer versions it may be just a
     // Links subfolder inside the default Favorites folder.
     nsCOMPtr<nsIWindowsRegKey> regKey =
       do_CreateInstance("@mozilla.org/windows-registry-key;1");
     if (regKey &&
--- a/browser/components/migration/src/nsSafariProfileMigrator.cpp
+++ b/browser/components/migration/src/nsSafariProfileMigrator.cpp
@@ -969,21 +969,16 @@ nsSafariProfileMigrator::CopyBookmarksBa
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = bms->CreateFolder(bookmarksMenuFolderId,
                            NS_ConvertUTF16toUTF8(importedSafariBookmarksTitle),
                            nsINavBookmarksService::DEFAULT_INDEX, &folder);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
-    // If importing defaults fails for whatever reason, let the import process
-    // continue.
-    DebugOnly<nsresult> rv = ImportDefaultBookmarks();
-    MOZ_ASSERT(NS_SUCCEEDED(rv), "Should be able to import default bookmarks");
-
     // In replace mode we are merging at the top level.
     folder = bookmarksMenuFolderId;
   }
 
   nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
   nsCOMPtr<nsILocalFile> safariBookmarksFile;
   fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile),
                    getter_AddRefs(safariBookmarksFile));
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -57,16 +57,19 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/AddonManager.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils",
+                                  "resource://gre/modules/BookmarkHTMLUtils.jsm");
+
 XPCOMUtils.defineLazyModuleGetter(this, "KeywordURLResetPrompter",
                                   "resource:///modules/KeywordURLResetPrompter.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "webappsUI", 
                                   "resource:///modules/webappsUI.jsm");
 
 const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
 const PREF_PLUGINS_UPDATEURL  = "plugins.update.url";
@@ -223,20 +226,16 @@ BrowserGlue.prototype = {
         break;
       case "places-init-complete":
         this._initPlaces();
         Services.obs.removeObserver(this, "places-init-complete");
         this._isPlacesInitObserver = false;
         // no longer needed, since history was initialized completely.
         Services.obs.removeObserver(this, "places-database-locked");
         this._isPlacesLockedObserver = false;
-
-        // Now apply distribution customized bookmarks.
-        // This should always run after Places initialization.
-        this._distributionCustomizer.applyBookmarks();
         break;
       case "places-database-locked":
         this._isPlacesDatabaseLocked = true;
         // Stop observing, so further attempts to load history service
         // will not show the prompt.
         Services.obs.removeObserver(this, "places-database-locked");
         this._isPlacesLockedObserver = false;
         break;
@@ -252,23 +251,16 @@ BrowserGlue.prototype = {
         if (this._idleService.idleTime > BOOKMARKS_BACKUP_IDLE_TIME * 1000)
           this._backupBookmarks();
         break;
       case "distribution-customization-complete":
         Services.obs.removeObserver(this, "distribution-customization-complete");
         // Customization has finished, we don't need the customizer anymore.
         delete this._distributionCustomizer;
         break;
-      case "bookmarks-restore-success":
-      case "bookmarks-restore-failed":
-        Services.obs.removeObserver(this, "bookmarks-restore-success");
-        Services.obs.removeObserver(this, "bookmarks-restore-failed");
-        if (topic == "bookmarks-restore-success" && data == "html-initial")
-          this.ensurePlacesDefaultQueriesInitialized();
-        break;
       case "browser-glue-test": // used by tests
         if (data == "post-update-notification") {
           if (Services.prefs.prefHasUserValue("app.update.postupdate"))
             this._showUpdateNotification();
         }
         else if (data == "force-ui-migration") {
           this._migrateUI();
         }
@@ -283,16 +275,19 @@ BrowserGlue.prototype = {
         break;
       case "defaultURIFixup-using-keyword-pref":
         if (KeywordURLResetPrompter.shouldPrompt) {
           let keywordURI = subject.QueryInterface(Ci.nsIURI);
           KeywordURLResetPrompter.prompt(this.getMostRecentBrowserWindow(),
                                          keywordURI);
         }
         break;
+      case "initial-migration":
+        this._initialMigrationPerformed = true;
+        break;
     }
   }, 
 
   // initialization (called on application startup) 
   _init: function BG__init() {
     let os = Services.obs;
     os.addObserver(this, "xpcom-shutdown", false);
     os.addObserver(this, "prefservice:after-app-defaults", false);
@@ -985,28 +980,19 @@ BrowserGlue.prototype = {
    */
   _initPlaces: function BG__initPlaces() {
     // We must instantiate the history service since it will tell us if we
     // need to import or restore bookmarks due to first-run, corruption or
     // forced migration (due to a major schema change).
     // If the database is corrupt or has been newly created we should
     // import bookmarks.
     var dbStatus = PlacesUtils.history.databaseStatus;
-    var importBookmarks = dbStatus == PlacesUtils.history.DATABASE_STATUS_CREATE ||
-                          dbStatus == PlacesUtils.history.DATABASE_STATUS_CORRUPT;
-
-    if (dbStatus == PlacesUtils.history.DATABASE_STATUS_CREATE) {
-      // If the database has just been created, but we already have any
-      // bookmark, this is not the initial import.  This can happen after a
-      // migration from a different browser since migrators run before us.
-      // In such a case we should not import, unless some pref has been set.
-      if (PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.bookmarksMenuFolderId, 0) != -1 ||
-          PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0) != -1)
-        importBookmarks = false;
-    }
+    var importBookmarks = !this._initialMigrationPerformed &&
+                          (dbStatus == PlacesUtils.history.DATABASE_STATUS_CREATE ||
+                           dbStatus == PlacesUtils.history.DATABASE_STATUS_CORRUPT);
 
     // Check if user or an extension has required to import bookmarks.html
     var importBookmarksHTML = false;
     try {
       importBookmarksHTML =
         Services.prefs.getBoolPref("browser.places.importBookmarksHTML");
       if (importBookmarksHTML)
         importBookmarks = true;
@@ -1053,16 +1039,19 @@ BrowserGlue.prototype = {
     }
 
     // If bookmarks are not imported, then initialize smart bookmarks.  This
     // happens during a common startup.
     // Otherwise, if any kind of import runs, smart bookmarks creation should be
     // delayed till the import operations has finished.  Not doing so would
     // cause them to be overwritten by the newly imported bookmarks.
     if (!importBookmarks) {
+      // Now apply distribution customized bookmarks.
+      // This should always run after Places initialization.
+      this._distributionCustomizer.applyBookmarks();
       this.ensurePlacesDefaultQueriesInitialized();
     }
     else {
       // An import operation is about to run.
       // Don't try to recreate smart bookmarks if autoExportHTML is true or
       // smart bookmarks are disabled.
       var autoExportHTML = false;
       try {
@@ -1086,35 +1075,38 @@ BrowserGlue.prototype = {
       }
       else {
         var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile);
         if (bookmarksFile.exists())
           bookmarksURI = NetUtil.newURI(bookmarksFile);
       }
 
       if (bookmarksURI) {
-        // Add an import observer.  It will ensure that smart bookmarks are
-        // created once the operation is complete.
-        Services.obs.addObserver(this, "bookmarks-restore-success", false);
-        Services.obs.addObserver(this, "bookmarks-restore-failed", false);
-
         // Import from bookmarks.html file.
         try {
-          var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
-                         getService(Ci.nsIPlacesImportExportService);
-          importer.importHTMLFromURI(bookmarksURI, true /* overwrite existing */);
+          BookmarkHTMLUtils.importFromURL(bookmarksURI.spec, true, (function (success) {
+            if (success) {
+              // Now apply distribution customized bookmarks.
+              // This should always run after Places initialization.
+              this._distributionCustomizer.applyBookmarks();
+              // Ensure that smart bookmarks are created once the operation is
+              // complete.
+              this.ensurePlacesDefaultQueriesInitialized();
+            }
+            else {
+              Cu.reportError("Bookmarks.html file could be corrupt.");
+            }
+          }).bind(this));
         } catch (err) {
-          // Report the error, but ignore it.
           Cu.reportError("Bookmarks.html file could be corrupt. " + err);
-          Services.obs.removeObserver(this, "bookmarks-restore-success");
-          Services.obs.removeObserver(this, "bookmarks-restore-failed");
         }
       }
-      else
+      else {
         Cu.reportError("Unable to find bookmarks.html file.");
+      }
 
       // Reset preferences, so we won't try to import again at next run
       if (importBookmarksHTML)
         Services.prefs.setBoolPref("browser.places.importBookmarksHTML", false);
       if (restoreDefaultBookmarks)
         Services.prefs.setBoolPref("browser.bookmarks.restore_default_bookmarks",
                                    false);
     }
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -395,20 +395,19 @@ var PlacesOrganizer = {
    */
   importFromFile: function PO_importFromFile() {
     var fp = Cc["@mozilla.org/filepicker;1"].
              createInstance(Ci.nsIFilePicker);
     fp.init(window, PlacesUIUtils.getString("SelectImport"),
             Ci.nsIFilePicker.modeOpen);
     fp.appendFilters(Ci.nsIFilePicker.filterHTML);
     if (fp.show() != Ci.nsIFilePicker.returnCancel) {
-      if (fp.file) {
-        var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
-                       getService(Ci.nsIPlacesImportExportService);
-        importer.importHTMLFromFile(fp.file, false);
+      if (fp.fileURL) {
+        Components.utils.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
+        BookmarkHTMLUtils.importFromURL(fp.fileURL.spec, false);
       }
     }
   },
 
   /**
    * Allows simple exporting of bookmarks.
    */
   exportBookmarks: function PO_exportBookmarks() {
--- a/browser/components/places/tests/unit/test_384370.js
+++ b/browser/components/places/tests/unit/test_384370.js
@@ -52,18 +52,18 @@ function run_test() {
     - export as html, import, test (tests integrity of json > html)
 
     BACKUP/RESTORE SUMMARY:
     - create a bookmark in each root
     - tag multiple URIs with multiple tags
     - export as json, import, test
   */
 
-  // get places import/export service
-  var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].getService(Ci.nsIPlacesImportExportService);
+  // import the importer
+  Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
 
   // avoid creating the places smart folder during tests
   Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).
   setIntPref("browser.places.smartBookmarksVersion", -1);
 
   // file pointer to legacy bookmarks file
   //var bookmarksFileOld = do_get_file("bookmarks.large.html");
   var bookmarksFileOld = do_get_file("bookmarks.preplaces.html");
@@ -78,28 +78,36 @@ function run_test() {
   if (!jsonFile.exists())
     do_throw("couldn't create file: bookmarks.exported.json");
 
   // Test importing a pre-Places canonical bookmarks file.
   // 1. import bookmarks.preplaces.html
   // 2. run the test-suite
   // Note: we do not empty the db before this import to catch bugs like 380999
   try {
-    importer.importHTMLFromFile(bookmarksFileOld, true);
+    BookmarkHTMLUtils.importFromFile(bookmarksFileOld, true, after_import);
   } catch(ex) { do_throw("couldn't import legacy bookmarks file: " + ex); }
+}
+
+function after_import(success) {
+  if (!success) {
+    do_throw("Couldn't import legacy bookmarks file.");
+  }
   populate();
   validate();
 
   waitForAsyncUpdates(function () {
     // Test exporting a Places canonical json file.
     // 1. export to bookmarks.exported.json
     // 2. empty bookmarks db
     // 3. import bookmarks.exported.json
     // 4. run the test-suite
     try {
+      var jsonFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
+      jsonFile.append("bookmarks.exported.json");
       PlacesUtils.backups.saveBookmarksToJSONFile(jsonFile);
     } catch(ex) { do_throw("couldn't export to file: " + ex); }
     LOG("exported json");
     try {
       PlacesUtils.restoreBookmarksFromJSONFile(jsonFile);
     } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
     LOG("imported json");
     validate();
--- a/browser/components/places/tests/unit/test_421483.js
+++ b/browser/components/places/tests/unit/test_421483.js
@@ -51,16 +51,18 @@ try {
 } catch(ex) {
   do_throw("Could not get Annotation service\n");
 }
 
 // Get browser glue
 try {
   var gluesvc = Cc["@mozilla.org/browser/browserglue;1"].
                 getService(Ci.nsIBrowserGlue);
+  // Avoid default bookmarks import.
+  gluesvc.QueryInterface(Ci.nsIObserver).observe(null, "initial-migration", null);
 } catch(ex) {
   do_throw("Could not get BrowserGlue service\n");
 }
 
 // Get pref service
 try {
   var pref =  Cc["@mozilla.org/preferences-service;1"].
               getService(Ci.nsIPrefBranch);
--- a/browser/components/places/tests/unit/test_457441-import-export-corrupt-bookmarks-html.js
+++ b/browser/components/places/tests/unit/test_457441-import-export-corrupt-bookmarks-html.js
@@ -50,16 +50,17 @@ var bs = Cc["@mozilla.org/browser/nav-bo
 var as = Cc["@mozilla.org/browser/annotation-service;1"].
          getService(Ci.nsIAnnotationService);
 var icos = Cc["@mozilla.org/browser/favicon-service;1"].
            getService(Ci.nsIFaviconService);
 var ps = Cc["@mozilla.org/preferences-service;1"].
          getService(Ci.nsIPrefBranch);
 var ies = Cc["@mozilla.org/browser/places/import-export-service;1"].
           getService(Ci.nsIPlacesImportExportService);
+Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
 
 const DESCRIPTION_ANNO = "bookmarkProperties/description";
 const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
 const POST_DATA_ANNO = "bookmarkProperties/POSTData";
 
 const TEST_FAVICON_PAGE_URL = "http://en-US.www.mozilla.com/en-US/firefox/central/";
 const TEST_FAVICON_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==";
 
@@ -67,18 +68,24 @@ function run_test() {
   do_test_pending();
 
   // avoid creating the places smart folder during tests
   ps.setIntPref("browser.places.smartBookmarksVersion", -1);
 
   // import bookmarks from corrupt file
   var corruptBookmarksFile = do_get_file("bookmarks.corrupt.html");
   try {
-    ies.importHTMLFromFile(corruptBookmarksFile, true);
+    BookmarkHTMLUtils.importFromFile(corruptBookmarksFile, true, after_import);
   } catch(ex) { do_throw("couldn't import corrupt bookmarks file: " + ex); }
+}
+
+function after_import(success) {
+  if (!success) {
+    do_throw("Couldn't import corrupt bookmarks file.");
+  }
 
   // Check that every bookmark is correct
   // Corrupt bookmarks should not have been imported
   database_check();
   waitForAsyncUpdates(function() {
     // Create corruption in database
     var corruptItemId = bs.insertBookmark(bs.toolbarFolder,
                                           uri("http://test.mozilla.org"),
@@ -100,24 +107,26 @@ function run_test() {
       ies.exportHTMLToFile(bookmarksFile);
     } catch(ex) { do_throw("couldn't export to bookmarks.exported.html: " + ex); }
 
     // Clear all bookmarks
     remove_all_bookmarks();
 
     // Import bookmarks
     try {
-      ies.importHTMLFromFile(bookmarksFile, true);
+      BookmarkHTMLUtils.importFromFile(bookmarksFile, true, before_database_check);
     } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
+  });
+}
 
+function before_database_check(success) {
     // Check that every bookmark is correct
     database_check();
 
     waitForAsyncUpdates(do_test_finished);
-  });
 }
 
 /*
  * Check for imported bookmarks correctness
  */
 function database_check() {
   // BOOKMARKS MENU
   var query = hs.getNewQuery();
--- a/browser/components/places/tests/unit/test_bookmarksRestoreNotification.js
+++ b/browser/components/places/tests/unit/test_bookmarksRestoreNotification.js
@@ -31,16 +31,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
+
 /**
  * Tests the bookmarks-restore-* nsIObserver notifications after restoring
  * bookmarks from JSON and HTML.  See bug 470314.
  */
 
 // The topics and data passed to nsIObserver.observe() on bookmarks restore
 const NSIOBSERVER_TOPIC_BEGIN    = "bookmarks-restore-begin";
 const NSIOBSERVER_TOPIC_SUCCESS  = "bookmarks-restore-success";
@@ -129,37 +131,45 @@ var tests = [
     desc:       "HTML restore: normal restore should succeed",
     currTopic:  NSIOBSERVER_TOPIC_BEGIN,
     finalTopic: NSIOBSERVER_TOPIC_SUCCESS,
     data:       NSIOBSERVER_DATA_HTML,
     folderId:   null,
     run:        function () {
       this.file = createFile("bookmarks-test_restoreNotification.html");
       addBookmarks();
-      importer.exportHTMLToFile(this.file);
+      exporter.exportHTMLToFile(this.file);
       remove_all_bookmarks();
       try {
-        importer.importHTMLFromFile(this.file, false);
+        BookmarkHTMLUtils.importFromFile(this.file, false, function (success) {
+          if (!success) {
+            do_throw("  Restore should not have failed");
+          }
+        });
       }
       catch (e) {
         do_throw("  Restore should not have failed");
       }
     }
   },
 
   {
     desc:       "HTML restore: empty file should succeed",
     currTopic:  NSIOBSERVER_TOPIC_BEGIN,
     finalTopic: NSIOBSERVER_TOPIC_SUCCESS,
     data:       NSIOBSERVER_DATA_HTML,
     folderId:   null,
     run:        function () {
       this.file = createFile("bookmarks-test_restoreNotification.init.html");
       try {
-        importer.importHTMLFromFile(this.file, false);
+        BookmarkHTMLUtils.importFromFile(this.file, false, function (success) {
+          if (!success) {
+            do_throw("  Restore should not have failed");            
+          }
+        });
       }
       catch (e) {
         do_throw("  Restore should not have failed");
       }
     }
   },
 
   {
@@ -167,53 +177,65 @@ var tests = [
     currTopic:  NSIOBSERVER_TOPIC_BEGIN,
     finalTopic: NSIOBSERVER_TOPIC_FAILED,
     data:       NSIOBSERVER_DATA_HTML,
     folderId:   null,
     run:        function () {
       this.file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
       this.file.append("this file doesn't exist because nobody created it");
       try {
-        importer.importHTMLFromFile(this.file, false);
-        do_throw("  Restore should have failed");
+        BookmarkHTMLUtils.importFromFile(this.file, false, function (success) {
+          print("callback");
+          if (success) {
+            do_throw("  Restore should have failed");
+          }
+        });
       }
       catch (e) {}
     }
   },
 
   {
     desc:       "HTML initial restore: normal restore should succeed",
     currTopic:  NSIOBSERVER_TOPIC_BEGIN,
     finalTopic: NSIOBSERVER_TOPIC_SUCCESS,
     data:       NSIOBSERVER_DATA_HTML_INIT,
     folderId:   null,
     run:        function () {
       this.file = createFile("bookmarks-test_restoreNotification.init.html");
       addBookmarks();
-      importer.exportHTMLToFile(this.file);
+      exporter.exportHTMLToFile(this.file);
       remove_all_bookmarks();
       try {
-        importer.importHTMLFromFile(this.file, true);
+        BookmarkHTMLUtils.importFromFile(this.file, true, function (success) {
+          if (!success) {
+            do_throw("  Restore should not have failed");
+          }
+        });
       }
       catch (e) {
         do_throw("  Restore should not have failed");
       }
     }
   },
 
   {
     desc:       "HTML initial restore: empty file should succeed",
     currTopic:  NSIOBSERVER_TOPIC_BEGIN,
     finalTopic: NSIOBSERVER_TOPIC_SUCCESS,
     data:       NSIOBSERVER_DATA_HTML_INIT,
     folderId:   null,
     run:        function () {
       this.file = createFile("bookmarks-test_restoreNotification.init.html");
       try {
-        importer.importHTMLFromFile(this.file, true);
+        BookmarkHTMLUtils.importFromFile(this.file, true, function (success) {
+          if (!success) {
+            do_throw("  Restore should not have failed");
+          }
+        });
       }
       catch (e) {
         do_throw("  Restore should not have failed");
       }
     }
   },
 
   {
@@ -221,23 +243,25 @@ var tests = [
     currTopic:  NSIOBSERVER_TOPIC_BEGIN,
     finalTopic: NSIOBSERVER_TOPIC_FAILED,
     data:       NSIOBSERVER_DATA_HTML_INIT,
     folderId:   null,
     run:        function () {
       this.file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
       this.file.append("this file doesn't exist because nobody created it");
       try {
-        importer.importHTMLFromFile(this.file, true);
-        do_throw("  Restore should have failed");
+        BookmarkHTMLUtils.importFromFile(this.file, true, function (success) {
+          if (success) {
+            do_throw("  Restore should have failed");
+          }
+        });
       }
       catch (e) {}
     }
   }
-
 ];
 
 // nsIObserver that observes bookmarks-restore-begin.
 var beginObserver = {
   observe: function _beginObserver(aSubject, aTopic, aData) {
     var test = tests[currTestIndex];
 
     print("  Observed " + aTopic);
@@ -276,30 +300,30 @@ var successAndFailedObserver = {
     if (aSubject) {
       do_check_eq(aSubject.QueryInterface(Ci.nsISupportsPRInt64).data,
                   test.folderId);
     }
     else
       do_check_eq(test.folderId, null);
 
     remove_all_bookmarks();
-    doNextTest();
+    do_execute_soon(doNextTest);
   }
 };
 
 // Index of the currently running test.  See doNextTest().
 var currTestIndex = -1;
 
 var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
             getService(Ci.nsINavBookmarksService);
 
 var obssvc = Cc["@mozilla.org/observer-service;1"].
              getService(Ci.nsIObserverService);
 
-var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
+var exporter = Cc["@mozilla.org/browser/places/import-export-service;1"].
                getService(Ci.nsIPlacesImportExportService);
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /**
  * Adds some bookmarks for the URIs in |uris|.
  */
 function addBookmarks() {
--- a/browser/components/places/tests/unit/test_bookmarks_html.js
+++ b/browser/components/places/tests/unit/test_bookmarks_html.js
@@ -94,19 +94,21 @@ let test_bookmarks = {
   ]
 };
 
 // Pre-Places bookmarks.html file pointer.
 let gBookmarksFileOld;
 // Places bookmarks.html file pointer.
 let gBookmarksFileNew;
 
-let importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
+let exporter = Cc["@mozilla.org/browser/places/import-export-service;1"].
                getService(Ci.nsIPlacesImportExportService);
 
+Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
+
 function run_test()
 {
   run_next_test();
 }
 
 add_test(function setup() {
   // Avoid creating smart bookmarks during the test.
   Services.prefs.setIntPref("browser.places.smartBookmarksVersion", -1);
@@ -126,131 +128,157 @@ add_test(function setup() {
   }
 
   // This test must be the first one, since it setups the new bookmarks.html.
   // Test importing a pre-Places canonical bookmarks file.
   // 1. import bookmarks.preplaces.html
   // 2. run the test-suite
   // Note: we do not empty the db before this import to catch bugs like 380999
   try {
-    importer.importHTMLFromFile(gBookmarksFileOld, true);
-  } catch(ex) { do_throw("couldn't import legacy bookmarks file: " + ex); }
+    BookmarkHTMLUtils.importFromFile(gBookmarksFileOld, true, function(success) {
+      if (success) {
+        waitForAsyncUpdates(function () {
+          testImportedBookmarks();
 
-  waitForAsyncUpdates(function () {
-    testImportedBookmarks();
+          // Prepare for next tests.
+          try {
+            exporter.exportHTMLToFile(gBookmarksFileNew);
+          } catch(ex) { do_throw("couldn't export to file: " + ex); }
 
-    // Prepare for next tests.
-    try {
-      importer.exportHTMLToFile(gBookmarksFileNew);
-    } catch(ex) { do_throw("couldn't export to file: " + ex); }
-
-    waitForAsyncUpdates(function () {
-      remove_all_bookmarks();
-      run_next_test();
+          waitForAsyncUpdates(function () {
+            remove_all_bookmarks();
+            run_next_test();
+          });
+        });
+      } else {
+        do_throw("couldn't import legacy bookmarks file.");
+      }
     });
-  });
+  } catch(ex) { do_throw("couldn't import legacy bookmarks file: " + ex); }
 });
 
 add_test(function test_import_new()
 {
   // Test importing a Places bookmarks.html file.
   // 1. import bookmarks.exported.html
   // 2. run the test-suite
 
   try {
-    importer.importHTMLFromFile(gBookmarksFileNew, true);
-  } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
-
-  waitForAsyncUpdates(function () {
-    testImportedBookmarks();
+    BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true, function(success) {
+      if (success) {
+        waitForAsyncUpdates(function () {
+          testImportedBookmarks();
 
-    waitForAsyncUpdates(function () {
-      remove_all_bookmarks();
-      run_next_test();
+          waitForAsyncUpdates(function () {
+            remove_all_bookmarks();
+            run_next_test();
+          });
+        });
+      } else {
+        do_throw("couldn't import the exported file.");
+      }
     });
-  });
+  } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
 });
 
 add_test(function test_emptytitle_export()
 {
   // Test exporting and importing with an empty-titled bookmark.
   // 1. import bookmarks
   // 1. create an empty-titled bookmark.
   // 2. export to bookmarks.exported.html
   // 3. empty bookmarks db
   // 4. import bookmarks.exported.html
   // 5. run the test-suite
 
   try {
-    importer.importHTMLFromFile(gBookmarksFileNew, true);
-  } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
+    BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true, function(success) {
+      if (success) {
+        const NOTITLE_URL = "http://notitle.mozilla.org/";
+        let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
+                                                      NetUtil.newURI(NOTITLE_URL),
+                                                      PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                                      "");
+        test_bookmarks.unfiled.push({ title: "", url: NOTITLE_URL });
 
-  const NOTITLE_URL = "http://notitle.mozilla.org/";
-  let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
-                                                NetUtil.newURI(NOTITLE_URL),
-                                                PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                                "");
-  test_bookmarks.unfiled.push({ title: "", url: NOTITLE_URL });
+        try {
+          exporter.exportHTMLToFile(gBookmarksFileNew);
+        } catch(ex) { do_throw("couldn't export to file: " + ex); }
+
+        remove_all_bookmarks();
 
-  try {
-    importer.exportHTMLToFile(gBookmarksFileNew);
-  } catch(ex) { do_throw("couldn't export to file: " + ex); }
-
-  remove_all_bookmarks();
+        try {
+          BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true, function(success) {
+           if (success) {
+              waitForAsyncUpdates(function () {
+                testImportedBookmarks();
 
-  try {
-    importer.importHTMLFromFile(gBookmarksFileNew, true);
-  } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
+                // Cleanup.
+                test_bookmarks.unfiled.pop();
+                PlacesUtils.bookmarks.removeItem(id);
 
-  waitForAsyncUpdates(function () {
-    testImportedBookmarks();
+                try {
+                  exporter.exportHTMLToFile(gBookmarksFileNew);
+                } catch(ex) { do_throw("couldn't export to file: " + ex); }
 
-    // Cleanup.
-    test_bookmarks.unfiled.pop();
-    PlacesUtils.bookmarks.removeItem(id);
-
-    try {
-      importer.exportHTMLToFile(gBookmarksFileNew);
-    } catch(ex) { do_throw("couldn't export to file: " + ex); }
-
-    waitForAsyncUpdates(function () {
-      remove_all_bookmarks();
-      run_next_test();
+                waitForAsyncUpdates(function () {
+                  remove_all_bookmarks();
+                  run_next_test();
+                });
+              });
+            } else {
+              do_throw("couldn't import the exported file.");
+            }
+          });
+        } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
+      } else {
+        do_throw("couldn't import the exported file.");
+      }
     });
-  });
+  } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
 });
 
 add_test(function test_import_ontop()
 {
   // Test importing the exported bookmarks.html file *on top of* the existing
   // bookmarks.
   // 1. empty bookmarks db
   // 2. import the exported bookmarks file
   // 3. export to file
   // 3. import the exported bookmarks file
   // 4. run the test-suite
 
   try {
-    importer.importHTMLFromFile(gBookmarksFileNew, true);
-  } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
-  try {
-    importer.exportHTMLToFile(gBookmarksFileNew);
-  } catch(ex) { do_throw("couldn't export to file: " + ex); }
-  try {
-    importer.importHTMLFromFile(gBookmarksFileNew, true);
-  } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
+    BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true, function(success) {
+      if (success) {
+        try {
+          exporter.exportHTMLToFile(gBookmarksFileNew);
+        } catch(ex) { do_throw("couldn't export to file: " + ex); }
+        try {
+          BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true, function(success) {
+            if (success) {
+              waitForAsyncUpdates(function () {
+                testImportedBookmarks();
 
-  waitForAsyncUpdates(function () {
-    testImportedBookmarks();
+                waitForAsyncUpdates(function () {
+                  remove_all_bookmarks();
+                  run_next_test();
+                });
+              });
+            } else {
+              do_throw("couldn't import the exported file.");
+            }
+          });
+        } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
 
-    waitForAsyncUpdates(function () {
-      remove_all_bookmarks();
-      run_next_test();
+      } else {
+        do_throw("couldn't import the exported file.");
+      }
     });
-  });
+  } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
 });
 
 function testImportedBookmarks()
 {
   for (let group in test_bookmarks) {
     do_print("[testImportedBookmarks()] Checking group '" + group + "'");
 
     let root;
--- a/browser/components/places/tests/unit/test_browserGlue_migrate.js
+++ b/browser/components/places/tests/unit/test_browserGlue_migrate.js
@@ -24,24 +24,25 @@ function run_test() {
     do_check_false(db.exists());
   }
 
   // Initialize Places through the History Service and check that a new
   // database has been created.
   do_check_eq(PlacesUtils.history.databaseStatus,
               PlacesUtils.history.DATABASE_STATUS_CREATE);
 
-  // A migrator would run before nsBrowserGlue, so we mimic that behavior
-  // adding a bookmark.
+  //A migrator would run before nsBrowserGlue Places initialization, so mimic
+  //that behavior adding a bookmark and notifying the migration.
   PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.bookmarksMenuFolder, uri("http://mozilla.org/"),
                     PlacesUtils.bookmarks.DEFAULT_INDEX, "migrated");
 
   // Initialize nsBrowserGlue.
   let bg = Cc["@mozilla.org/browser/browserglue;1"].
-           getService(Ci.nsIBrowserGlue);
+           getService(Ci.nsIObserver);
+  bg.observe(null, "initial-migration", null)
 
   let bookmarksObserver = {
     onBeginUpdateBatch: function() {},
     onEndUpdateBatch: function() {
       // Check if the currently finished batch created the smart bookmarks.
       let itemId =
         PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
       do_check_neq(itemId, -1);
--- a/browser/components/places/tests/unit/test_browserGlue_prefs.js
+++ b/browser/components/places/tests/unit/test_browserGlue_prefs.js
@@ -12,16 +12,26 @@ const PREF_SMART_BOOKMARKS_VERSION = "br
 const PREF_AUTO_EXPORT_HTML = "browser.bookmarks.autoExportHTML";
 
 const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
 const TOPICDATA_FORCE_PLACES_INIT = "force-places-init";
 
 let bg = Cc["@mozilla.org/browser/browserglue;1"].
          getService(Ci.nsIBrowserGlue);
 
+function waitForImportAndSmartBookmarks(aCallback) {
+  Services.obs.addObserver(function waitImport() {
+    Services.obs.removeObserver(waitImport, "bookmarks-restore-success");
+    // Delay to test eventual smart bookmarks creation.
+    do_execute_soon(function () {
+      waitForAsyncUpdates(aCallback);
+    });
+  }, "bookmarks-restore-success", false);
+}
+
 let gTests = [
 
   // This test must be the first one.
   function test_checkPreferences() {
     // Initialize Places through the History Service and check that a new
     // database has been created.
     do_check_eq(PlacesUtils.history.databaseStatus,
                 PlacesUtils.history.DATABASE_STATUS_CREATE);
@@ -61,29 +71,30 @@ let gTests = [
       PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
     do_check_eq(itemId, -1);
 
     // Set preferences.
     Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true);
 
     // Force nsBrowserGlue::_initPlaces().
     print("Simulate Places init");
+    waitForImportAndSmartBookmarks(function () {
+      // Check bookmarks.html has been imported, and a smart bookmark has been
+      // created.
+      itemId = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
+                                                    SMART_BOOKMARKS_ON_TOOLBAR);
+      do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
+      // Check preferences have been reverted.
+      do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
+
+      run_next_test();
+    });
     bg.QueryInterface(Ci.nsIObserver).observe(null,
                                               TOPIC_BROWSERGLUE_TEST,
                                               TOPICDATA_FORCE_PLACES_INIT);
-
-    // Check bookmarks.html has been imported, and a smart bookmark has been
-    // created.
-    itemId = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
-                                                  SMART_BOOKMARKS_ON_TOOLBAR);
-    do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
-    // Check preferences have been reverted.
-    do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-
-    run_next_test();
   },
 
   function test_import_noSmartBookmarks()
   {
     do_log_info("import from bookmarks.html, but don't create smart bookmarks \
                  if they are disabled");
 
     remove_all_bookmarks();
@@ -93,29 +104,30 @@ let gTests = [
     do_check_eq(itemId, -1);
 
     // Set preferences.
     Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, -1);
     Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true);
 
     // Force nsBrowserGlue::_initPlaces().
     print("Simulate Places init");
+    waitForImportAndSmartBookmarks(function () {
+      // Check bookmarks.html has been imported, but smart bookmarks have not
+      // been created.
+      itemId =
+        PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
+      do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
+      // Check preferences have been reverted.
+      do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
+
+      run_next_test();
+    });
     bg.QueryInterface(Ci.nsIObserver).observe(null,
                                               TOPIC_BROWSERGLUE_TEST,
                                               TOPICDATA_FORCE_PLACES_INIT);
-
-    // Check bookmarks.html has been imported, but smart bookmarks have not
-    // been created.
-    itemId =
-      PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
-    do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
-    // Check preferences have been reverted.
-    do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-
-    run_next_test();
   },
 
   function test_import_autoExport_updatedSmartBookmarks()
   {
     do_log_info("Import from bookmarks.html, but don't create smart bookmarks \
                  if autoExportHTML is true and they are at latest version");
 
     remove_all_bookmarks();
@@ -126,30 +138,31 @@ let gTests = [
 
     // Set preferences.
     Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, 999);
     Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, true);
     Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true);
 
     // Force nsBrowserGlue::_initPlaces()
     print("Simulate Places init");
+    waitForImportAndSmartBookmarks(function () {
+      // Check bookmarks.html has been imported, but smart bookmarks have not
+      // been created.
+      itemId =
+        PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
+      do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
+      do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
+      // Check preferences have been reverted.
+      Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, false);
+
+      run_next_test();
+    });
     bg.QueryInterface(Ci.nsIObserver).observe(null,
                                               TOPIC_BROWSERGLUE_TEST,
                                               TOPICDATA_FORCE_PLACES_INIT);
-
-    // Check bookmarks.html has been imported, but smart bookmarks have not
-    // been created.
-    itemId =
-      PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
-    do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
-    do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-    // Check preferences have been reverted.
-    Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, false);
-
-    run_next_test();
   },
 
   function test_import_autoExport_oldSmartBookmarks()
   {
     do_log_info("Import from bookmarks.html, and create smart bookmarks if \
                  autoExportHTML is true and they are not at latest version.");
 
     remove_all_bookmarks();
@@ -160,31 +173,32 @@ let gTests = [
 
     // Set preferences.
     Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, 0);
     Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, true);
     Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true);
 
     // Force nsBrowserGlue::_initPlaces()
     print("Simulate Places init");
+    waitForImportAndSmartBookmarks(function () {
+      // Check bookmarks.html has been imported, but smart bookmarks have not
+      // been created.
+      itemId =
+        PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
+                                             SMART_BOOKMARKS_ON_TOOLBAR);
+      do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
+      do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
+      // Check preferences have been reverted.
+      Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, false);
+
+      run_next_test();
+    });
     bg.QueryInterface(Ci.nsIObserver).observe(null,
                                               TOPIC_BROWSERGLUE_TEST,
                                               TOPICDATA_FORCE_PLACES_INIT);
-
-    // Check bookmarks.html has been imported, but smart bookmarks have not
-    // been created.
-    itemId =
-      PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
-                                           SMART_BOOKMARKS_ON_TOOLBAR);
-    do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
-    do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-    // Check preferences have been reverted.
-    Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, false);
-
-    run_next_test();
   },
 
   function test_restore()
   {
     do_log_info("restore from default bookmarks.html if \
                  restore_default_bookmarks is true.");
 
     remove_all_bookmarks();
@@ -193,29 +207,31 @@ let gTests = [
       PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
     do_check_eq(itemId, -1);
 
     // Set preferences.
     Services.prefs.setBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS, true);
 
     // Force nsBrowserGlue::_initPlaces()
     print("Simulate Places init");
+    waitForImportAndSmartBookmarks(function () {
+      // Check bookmarks.html has been restored.
+      itemId =
+        PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
+                                             SMART_BOOKMARKS_ON_TOOLBAR);
+      do_check_true(itemId > 0);
+      // Check preferences have been reverted.
+      do_check_false(Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
+
+      run_next_test();
+    });
     bg.QueryInterface(Ci.nsIObserver).observe(null,
                                               TOPIC_BROWSERGLUE_TEST,
                                               TOPICDATA_FORCE_PLACES_INIT);
 
-    // Check bookmarks.html has been restored.
-    itemId =
-      PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
-                                           SMART_BOOKMARKS_ON_TOOLBAR);
-    do_check_true(itemId > 0);
-    // Check preferences have been reverted.
-    do_check_false(Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
-
-    run_next_test();
   },
 
   function test_restore_import()
   {
     do_log_info("setting both importBookmarksHTML and \
                  restore_default_bookmarks should restore defaults.");
 
     remove_all_bookmarks();
@@ -225,30 +241,31 @@ let gTests = [
     do_check_eq(itemId, -1);
 
     // Set preferences.
     Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true);
     Services.prefs.setBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS, true);
 
     // Force nsBrowserGlue::_initPlaces()
     print("Simulate Places init");
+    waitForImportAndSmartBookmarks(function () {
+      // Check bookmarks.html has been restored.
+      itemId =
+        PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
+                                             SMART_BOOKMARKS_ON_TOOLBAR);
+      do_check_true(itemId > 0);
+      // Check preferences have been reverted.
+      do_check_false(Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
+      do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
+
+      run_next_test();
+    });
     bg.QueryInterface(Ci.nsIObserver).observe(null,
                                               TOPIC_BROWSERGLUE_TEST,
                                               TOPICDATA_FORCE_PLACES_INIT);
-
-    // Check bookmarks.html has been restored.
-    itemId =
-      PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
-                                           SMART_BOOKMARKS_ON_TOOLBAR);
-    do_check_true(itemId > 0);
-    // Check preferences have been reverted.
-    do_check_false(Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
-    do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-
-    run_next_test();
   }
 
 ];
 
 do_register_cleanup(function () {
   remove_all_bookmarks();
   remove_bookmarks_html();
   remove_all_JSON_backups();
--- a/browser/components/places/tests/unit/test_browserGlue_smartBookmarks.js
+++ b/browser/components/places/tests/unit/test_browserGlue_smartBookmarks.js
@@ -359,11 +359,20 @@ function run_test() {
   do_check_false(Services.prefs.getBoolPref(PREF_AUTO_EXPORT_HTML));
   do_check_false(Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
   try {
     do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
     do_throw("importBookmarksHTML pref should not exist");
   }
   catch(ex) {}
 
-  // Kick-off tests.
-  next_test();
+  waitForImportAndSmartBookmarks(next_test);
 }
+
+function waitForImportAndSmartBookmarks(aCallback) {
+  Services.obs.addObserver(function waitImport() {
+    Services.obs.removeObserver(waitImport, "bookmarks-restore-success");
+    // Delay to test eventual smart bookmarks creation.
+    do_execute_soon(function () {
+      waitForAsyncUpdates(aCallback);
+    });
+  }, "bookmarks-restore-success", false);
+}
--- a/browser/components/places/tests/unit/test_clearHistory_shutdown.js
+++ b/browser/components/places/tests/unit/test_clearHistory_shutdown.js
@@ -105,17 +105,19 @@ let notificationsObserver = {
 }
 
 let timeInMicroseconds = Date.now() * 1000;
 
 function run_test() {
   do_test_pending();
 
   print("Initialize browserglue before Places");
-  Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIBrowserGlue);
+  // Avoid default bookmarks import.
+  Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver)
+    .observe(null, "initial-migration", null);
 
   Services.prefs.setBoolPref("privacy.clearOnShutdown.cache", true);
   Services.prefs.setBoolPref("privacy.clearOnShutdown.cookies", true);
   Services.prefs.setBoolPref("privacy.clearOnShutdown.offlineApps", true);
   Services.prefs.setBoolPref("privacy.clearOnShutdown.history", true);
   Services.prefs.setBoolPref("privacy.clearOnShutdown.downloads", true);
   Services.prefs.setBoolPref("privacy.clearOnShutdown.cookies", true);
   Services.prefs.setBoolPref("privacy.clearOnShutdown.formData", true);
--- a/browser/components/sessionstore/src/Makefile.in
+++ b/browser/components/sessionstore/src/Makefile.in
@@ -43,9 +43,12 @@ EXTRA_COMPONENTS = \
   nsSessionStore.manifest \
   $(NULL)
 
 EXTRA_PP_COMPONENTS = \
 	nsSessionStore.js \
 	nsSessionStartup.js \
 	$(NULL)
 
+libs::
+	$(NSINSTALL) $(srcdir)/*.jsm $(FINAL_TARGET)/modules/sessionstore
+
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/src/XPathGenerator.jsm
@@ -0,0 +1,97 @@
+/* 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/. */
+
+let EXPORTED_SYMBOLS = ["XPathGenerator"];
+
+let XPathGenerator = {
+  // these two hashes should be kept in sync
+  namespaceURIs:     { "xhtml": "http://www.w3.org/1999/xhtml" },
+  namespacePrefixes: { "http://www.w3.org/1999/xhtml": "xhtml" },
+
+  /**
+   * Generates an approximate XPath query to an (X)HTML node
+   */
+  generate: function sss_xph_generate(aNode) {
+    // have we reached the document node already?
+    if (!aNode.parentNode)
+      return "";
+    
+    // Access localName, namespaceURI just once per node since it's expensive.
+    let nNamespaceURI = aNode.namespaceURI;
+    let nLocalName = aNode.localName;
+
+    let prefix = this.namespacePrefixes[nNamespaceURI] || null;
+    let tag = (prefix ? prefix + ":" : "") + this.escapeName(nLocalName);
+    
+    // stop once we've found a tag with an ID
+    if (aNode.id)
+      return "//" + tag + "[@id=" + this.quoteArgument(aNode.id) + "]";
+    
+    // count the number of previous sibling nodes of the same tag
+    // (and possible also the same name)
+    let count = 0;
+    let nName = aNode.name || null;
+    for (let n = aNode; (n = n.previousSibling); )
+      if (n.localName == nLocalName && n.namespaceURI == nNamespaceURI &&
+          (!nName || n.name == nName))
+        count++;
+    
+    // recurse until hitting either the document node or an ID'd node
+    return this.generate(aNode.parentNode) + "/" + tag +
+           (nName ? "[@name=" + this.quoteArgument(nName) + "]" : "") +
+           (count ? "[" + (count + 1) + "]" : "");
+  },
+
+  /**
+   * Resolves an XPath query generated by XPathGenerator.generate
+   */
+  resolve: function sss_xph_resolve(aDocument, aQuery) {
+    let xptype = Components.interfaces.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE;
+    return aDocument.evaluate(aQuery, aDocument, this.resolveNS, xptype, null).singleNodeValue;
+  },
+
+  /**
+   * Namespace resolver for the above XPath resolver
+   */
+  resolveNS: function sss_xph_resolveNS(aPrefix) {
+    return XPathGenerator.namespaceURIs[aPrefix] || null;
+  },
+
+  /**
+   * @returns valid XPath for the given node (usually just the local name itself)
+   */
+  escapeName: function sss_xph_escapeName(aName) {
+    // we can't just use the node's local name, if it contains
+    // special characters (cf. bug 485482)
+    return /^\w+$/.test(aName) ? aName :
+           "*[local-name()=" + this.quoteArgument(aName) + "]";
+  },
+
+  /**
+   * @returns a properly quoted string to insert into an XPath query
+   */
+  quoteArgument: function sss_xph_quoteArgument(aArg) {
+    return !/'/.test(aArg) ? "'" + aArg + "'" :
+           !/"/.test(aArg) ? '"' + aArg + '"' :
+           "concat('" + aArg.replace(/'+/g, "',\"$&\",'") + "')";
+  },
+
+  /**
+   * @returns an XPath query to all savable form field nodes
+   */
+  get restorableFormNodes() {
+    // for a comprehensive list of all available <INPUT> types see
+    // http://mxr.mozilla.org/mozilla-central/search?string=kInputTypeTable
+    let ignoreTypes = ["password", "hidden", "button", "image", "submit", "reset"];
+    // XXXzeniko work-around until lower-case has been implemented (bug 398389)
+    let toLowerCase = '"ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"';
+    let ignore = "not(translate(@type, " + toLowerCase + ")='" +
+      ignoreTypes.join("' or translate(@type, " + toLowerCase + ")='") + "')";
+    let formNodesXPath = "//textarea|//select|//xhtml:textarea|//xhtml:select|" +
+      "//input[" + ignore + "]|//xhtml:input[" + ignore + "]";
+    
+    delete this.restorableFormNodes;
+    return (this.restorableFormNodes = formNodesXPath);
+  }
+};
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -138,16 +138,21 @@ XPCOMUtils.defineLazyGetter(this, "NetUt
   return NetUtil;
 });
 
 XPCOMUtils.defineLazyGetter(this, "ScratchpadManager", function() {
   Cu.import("resource:///modules/devtools/scratchpad-manager.jsm");
   return ScratchpadManager;
 });
 
+XPCOMUtils.defineLazyGetter(this, "XPathGenerator", function() {
+  Cu.import("resource:///modules/sessionstore/XPathGenerator.jsm");
+  return XPathGenerator;
+});
+
 XPCOMUtils.defineLazyServiceGetter(this, "CookieSvc",
   "@mozilla.org/cookiemanager;1", "nsICookieManager2");
 
 #ifdef MOZ_CRASHREPORTER
 XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
   "@mozilla.org/xre/app-info;1", "nsICrashReporter");
 #endif
 
@@ -2221,18 +2226,18 @@ SessionStoreService.prototype = {
   },
 
   /**
    * collect the state of all form elements
    * @param aDocument
    *        document reference
    */
   _collectFormDataForFrame: function sss_collectFormDataForFrame(aDocument) {
-    let formNodes = aDocument.evaluate(XPathHelper.restorableFormNodes, aDocument,
-                                       XPathHelper.resolveNS,
+    let formNodes = aDocument.evaluate(XPathGenerator.restorableFormNodes, aDocument,
+                                       XPathGenerator.resolveNS,
                                        Ci.nsIDOMXPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
     let node = formNodes.iterateNext();
     if (!node)
       return null;
 
     const MAX_GENERATED_XPATHS = 100;
     let generatedCount = 0;
 
@@ -2283,17 +2288,17 @@ SessionStoreService.prototype = {
       // In order to reduce XPath generation (which is slow), we only save data
       // for form fields that have been changed. (cf. bug 537289)
       if (!hasDefaultValue) {
         if (nId) {
           data["#" + nId] = value;
         }
         else {
           generatedCount++;
-          data[XPathHelper.generate(node)] = value;
+          data[XPathGenerator.generate(node)] = value;
         }
       }
 
     } while ((node = formNodes.iterateNext()));
 
     return data;
   },
 
@@ -3396,17 +3401,17 @@ SessionStoreService.prototype = {
       !aURL || aURL.replace(/#.*/, "") == aDocument.location.href.replace(/#.*/, "");
 
     function restoreFormData(aDocument, aData, aURL) {
       for (let key in aData) {
         if (!hasExpectedURL(aDocument, aURL))
           return;
 
         let node = key.charAt(0) == "#" ? aDocument.getElementById(key.slice(1)) :
-                                          XPathHelper.resolve(aDocument, key);
+                                          XPathGenerator.resolve(aDocument, key);
         if (!node)
           continue;
 
         let eventType;
         let value = aData[key];
 
         // for about:sessionrestore we saved the field as JSON to avoid nested
         // instances causing humongous sessionstore.js files. cf. bug 467409
@@ -4459,108 +4464,16 @@ SessionStoreService.prototype = {
         Services.obs.notifyObservers(null,
                                      "sessionstore-state-write-complete",
                                      "");
       }
     });
   }
 };
 
-let XPathHelper = {
-  // these two hashes should be kept in sync
-  namespaceURIs:     { "xhtml": "http://www.w3.org/1999/xhtml" },
-  namespacePrefixes: { "http://www.w3.org/1999/xhtml": "xhtml" },
-
-  /**
-   * Generates an approximate XPath query to an (X)HTML node
-   */
-  generate: function sss_xph_generate(aNode) {
-    // have we reached the document node already?
-    if (!aNode.parentNode)
-      return "";
-    
-    // Access localName, namespaceURI just once per node since it's expensive.
-    let nNamespaceURI = aNode.namespaceURI;
-    let nLocalName = aNode.localName;
-
-    let prefix = this.namespacePrefixes[nNamespaceURI] || null;
-    let tag = (prefix ? prefix + ":" : "") + this.escapeName(nLocalName);
-    
-    // stop once we've found a tag with an ID
-    if (aNode.id)
-      return "//" + tag + "[@id=" + this.quoteArgument(aNode.id) + "]";
-    
-    // count the number of previous sibling nodes of the same tag
-    // (and possible also the same name)
-    let count = 0;
-    let nName = aNode.name || null;
-    for (let n = aNode; (n = n.previousSibling); )
-      if (n.localName == nLocalName && n.namespaceURI == nNamespaceURI &&
-          (!nName || n.name == nName))
-        count++;
-    
-    // recurse until hitting either the document node or an ID'd node
-    return this.generate(aNode.parentNode) + "/" + tag +
-           (nName ? "[@name=" + this.quoteArgument(nName) + "]" : "") +
-           (count ? "[" + (count + 1) + "]" : "");
-  },
-
-  /**
-   * Resolves an XPath query generated by XPathHelper.generate
-   */
-  resolve: function sss_xph_resolve(aDocument, aQuery) {
-    let xptype = Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE;
-    return aDocument.evaluate(aQuery, aDocument, this.resolveNS, xptype, null).singleNodeValue;
-  },
-
-  /**
-   * Namespace resolver for the above XPath resolver
-   */
-  resolveNS: function sss_xph_resolveNS(aPrefix) {
-    return XPathHelper.namespaceURIs[aPrefix] || null;
-  },
-
-  /**
-   * @returns valid XPath for the given node (usually just the local name itself)
-   */
-  escapeName: function sss_xph_escapeName(aName) {
-    // we can't just use the node's local name, if it contains
-    // special characters (cf. bug 485482)
-    return /^\w+$/.test(aName) ? aName :
-           "*[local-name()=" + this.quoteArgument(aName) + "]";
-  },
-
-  /**
-   * @returns a properly quoted string to insert into an XPath query
-   */
-  quoteArgument: function sss_xph_quoteArgument(aArg) {
-    return !/'/.test(aArg) ? "'" + aArg + "'" :
-           !/"/.test(aArg) ? '"' + aArg + '"' :
-           "concat('" + aArg.replace(/'+/g, "',\"$&\",'") + "')";
-  },
-
-  /**
-   * @returns an XPath query to all savable form field nodes
-   */
-  get restorableFormNodes() {
-    // for a comprehensive list of all available <INPUT> types see
-    // http://mxr.mozilla.org/mozilla-central/search?string=kInputTypeTable
-    let ignoreTypes = ["password", "hidden", "button", "image", "submit", "reset"];
-    // XXXzeniko work-around until lower-case has been implemented (bug 398389)
-    let toLowerCase = '"ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"';
-    let ignore = "not(translate(@type, " + toLowerCase + ")='" +
-      ignoreTypes.join("' or translate(@type, " + toLowerCase + ")='") + "')";
-    let formNodesXPath = "//textarea|//select|//xhtml:textarea|//xhtml:select|" +
-      "//input[" + ignore + "]|//xhtml:input[" + ignore + "]";
-    
-    delete this.restorableFormNodes;
-    return (this.restorableFormNodes = formNodesXPath);
-  }
-};
-
 // This is used to help meter the number of restoring tabs. This is the control
 // point for telling the next tab to restore. It gets attached to each gBrowser
 // via gBrowser.addTabsProgressListener
 let gRestoreTabsProgressListener = {
   ss: null,
   onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
     // Ignore state changes on browsers that we've already restored and state
     // changes that aren't applicable.
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -94,17 +94,19 @@
 ; [Base Browser Files]
 #ifndef XP_UNIX
 @BINPATH@/@MOZ_APP_NAME@.exe
 #else
 @BINPATH@/@MOZ_APP_NAME@-bin
 @BINPATH@/@MOZ_APP_NAME@
 #endif
 @BINPATH@/application.ini
+#ifdef MOZ_UPDATER
 @BINPATH@/update-settings.ini
+#endif
 @BINPATH@/platform.ini
 #ifndef XP_OS2
 @BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
 #else
 @BINPATH@/mozsqlt3@DLL_SUFFIX@
 #endif
 @BINPATH@/blocklist.xml
 #ifdef XP_UNIX
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -275,17 +275,17 @@ can reach it easily. -->
 <!ENTITY preferencesCmd2.label       "Options">
 <!ENTITY preferencesCmd2.accesskey     "O">
 <!ENTITY preferencesCmdUnix.label       "Preferences">
 <!ENTITY preferencesCmdUnix.accesskey     "n"> 
 
 <!ENTITY clearRecentHistory.label               "Clear Recent History…">
 <!ENTITY clearRecentHistory.accesskey           "H">
 
-<!-- LOCALIZATION NOTE : These two strings can share an access key beause they never appear together on the menu -->
+<!-- LOCALIZATION NOTE : These two strings can share an access key because they never appear together on the menu -->
 <!ENTITY privateBrowsingCmd.start.label         "Start Private Browsing">
 <!ENTITY privateBrowsingCmd.start.accesskey     "P">
 <!ENTITY privateBrowsingCmd.stop.label          "Stop Private Browsing">
 <!ENTITY privateBrowsingCmd.stop.accesskey      "P">
 <!ENTITY privateBrowsingCmd.commandkey          "P">
 
 <!ENTITY viewMenu.label         "View"> 
 <!ENTITY viewMenu.accesskey       "V"> 
--- a/browser/themes/winstripe/browser-aero.css
+++ b/browser/themes/winstripe/browser-aero.css
@@ -153,19 +153,19 @@
   #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child:not(:-moz-lwtheme) {
     background-color: transparent !important;
     color: black;
     text-shadow: 0 0 .5em white, 0 0 .5em white, 0 1px 0 rgba(255,255,255,.4);
     border-left-style: none !important;
     border-right-style: none !important;
   }
 
-  #toolbar-menubar :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
+  #toolbar-menubar :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
   #TabsToolbar[tabsontop=true] :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
-  #navigator-toolbox[tabsontop=false] > #nav-bar :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
+  #navigator-toolbox[tabsontop=false] > #nav-bar :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
   #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme) {
     list-style-image: url("chrome://browser/skin/Toolbar-inverted.png");
   }
 
   #toolbar-menubar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme),
   #toolbar-menubar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme),
   #TabsToolbar[tabsontop=true] .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme),
   #TabsToolbar[tabsontop=true] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme),
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -998,16 +998,18 @@ toolbar[mode=full] .toolbarbutton-1 > .t
 #tabview-button,
 #menu_tabview {
   list-style-image: url(chrome://browser/skin/tabview/tabview.png);
 }
 
 %ifdef WINSTRIPE_AERO
 #TabsToolbar > #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
 #TabsToolbar > toolbarpaletteitem > #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+#navigator-toolbox[tabsontop=false] > #nav-bar #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+#toolbar-menubar #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
 %endif
 #tabview-button:-moz-lwtheme-brighttext {
   list-style-image: url(chrome://browser/skin/tabview/tabview-inverted.png);
 }
 
 #tabview-button {
   -moz-image-region: rect(0, 90px, 18px, 72px);
 }
@@ -2046,16 +2048,18 @@ richlistitem[type~="action"][actiontype=
 #alltabs-button[type="menu"] {
   list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
   -moz-image-region: auto;
 }
 
 %ifdef WINSTRIPE_AERO
 #TabsToolbar > #alltabs-button[type="menu"]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
 #TabsToolbar > toolbarpaletteitem > #alltabs-button[type="menu"]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+#navigator-toolbox[tabsontop=false] > #nav-bar #alltabs-button[type="menu"]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+#toolbar-menubar #alltabs-button[type="menu"]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
 %endif
 #alltabs-button[type="menu"]:-moz-lwtheme-brighttext {
   list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
 }
 
 #alltabs-button[type="menu"] > .toolbarbutton-icon {
   margin: 0 2px;
 }
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -48,34 +48,40 @@ MODULE = build
 ifeq (,$(filter WINNT OS2,$(OS_ARCH)))
 DIRS		= unix
 endif
 
 ifeq (WINNT,$(OS_ARCH))
 DIRS = win32
 endif
 
+ifdef STLPORT_SOURCES
+DIRS += stlport
+endif
+
 DIRS += pgo
 
 TEST_DIRS += autoconf/test
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
 TEST_DIRS += mobile/sutagent/android \
           mobile/sutagent/android/watcher \
           mobile/sutagent/android/ffxcp \
           mobile/sutagent/android/fencp \
           mobile/robocop \
           $(NULL)
 endif
 
 ifdef MOZ_APP_BASENAME
 DIST_FILES = application.ini
 
 ifneq (android,$(MOZ_WIDGET_TOOLKIT))
+ifdef MOZ_UPDATER
 DIST_FILES += update-settings.ini
 endif
+endif
 
 ifdef LIBXUL_SDK
 GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
 APP_INI_DEPS = $(LIBXUL_DIST)/bin/platform.ini
 else
 GRE_MILESTONE = $(shell tail -n 1 $(topsrcdir)/config/milestone.txt 2>/dev/null || tail -1 $(topsrcdir)/config/milestone.txt)
 APP_INI_DEPS = $(topsrcdir)/config/milestone.txt
 endif
@@ -155,20 +161,22 @@ GARBAGE_DIRS += $(_LEAKTEST_DIR)
 		$(NULL)
 
 leaktest.py: leaktest.py.in
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $^ > $@
 	chmod +x $@
 GARBAGE += leaktest.py
 
 ifneq (android,$(MOZ_WIDGET_TOOLKIT))
+ifdef MOZ_UPDATER
 update-settings.ini: update-settings.ini.in $(APP_INI_DEPS)
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@
 GARBAGE += update-settings.ini
 endif
+endif
 
 ifdef MOZ_APP_BASENAME
 application.ini: application.ini.in $(APP_INI_DEPS)
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@
 GARBAGE += application.ini
 
 ifdef MOZ_APP_STATIC_INI
 application.ini.h: appini_header.py application.ini 
--- a/build/mobile/devicemanager.py
+++ b/build/mobile/devicemanager.py
@@ -230,22 +230,22 @@ class DeviceManager:
       procName = proc[1].split('/')[-1]
       if (procName == app):
         pid = proc[0]
         break
     return pid
 
 
   @abstractmethod
-  def killProcess(self, appname):
+  def killProcess(self, appname, forceKill=False):
     """
     external function
     returns:
-    success: output from testagent
-    failure: None
+    success: True
+    failure: False
     """
     
   @abstractmethod
   def catFile(self, remoteFile):
     """
     external function
     returns:
     success: filecontents
--- a/build/mobile/devicemanagerADB.py
+++ b/build/mobile/devicemanagerADB.py
@@ -371,26 +371,31 @@ class DeviceManagerADB(DeviceManager):
       acmd.append("-d")
       acmd.append(''.join(['\'',uri, '\'']));
     print acmd
     self.checkCmd(acmd)
     return outputFile
 
   # external function
   # returns:
-  #  success: output from testagent
-  #  failure: None
-  def killProcess(self, appname):
+  #  success: True
+  #  failure: False
+  def killProcess(self, appname, forceKill=False):
     procs = self.getProcessList()
+    didKillProcess = False
     for (pid, name, user) in procs:
       if name == appname:
-        p = self.runCmdAs(["shell", "kill", pid])
-        return p.stdout.read()
+         args = ["shell", "kill"]
+         if forceKill:
+           args.append("-9")
+         args.append(pid)
+         p = self.runCmdAs(args)
+         didKillProcess = True
 
-    return None
+    return didKillProcess
 
   # external function
   # returns:
   #  success: filecontents
   #  failure: None
   def catFile(self, remoteFile):
     #p = self.runCmd(["shell", "cat", remoteFile])
     #return p.stdout.read()
@@ -764,17 +769,18 @@ class DeviceManagerADB(DeviceManager):
 
       # The problem here is that run-as doesn't cause a non-zero exit code
       # when failing because of a non-existent or non-debuggable package :(
       runAsOut = self.runCmd(["shell", "run-as", self.packageName, "mkdir", devroot + "/sanity"]).communicate()[0]
       if runAsOut.startswith("run-as:") and ("not debuggable" in runAsOut or
                                              "is unknown" in runAsOut):
         raise DMError("run-as failed sanity check")
 
-      self.checkCmd(["push", os.path.abspath(sys.argv[0]), tmpDir + "/tmpfile"])
+      tmpfile = tempfile.NamedTemporaryFile()
+      self.checkCmd(["push", tmpfile.name, tmpDir + "/tmpfile"])
       if self.useDDCopy:
         self.checkCmd(["shell", "run-as", self.packageName, "dd", "if=" + tmpDir + "/tmpfile", "of=" + devroot + "/sanity/tmpfile"])
       else:
         self.checkCmd(["shell", "run-as", self.packageName, "cp", tmpDir + "/tmpfile", devroot + "/sanity"])
       if (self.fileExists(devroot + "/sanity/tmpfile")):
         print "will execute commands via run-as " + self.packageName
         self.useRunAs = True
       self.checkCmd(["shell", "rm", devroot + "/tmp/tmpfile"])
--- a/build/mobile/devicemanagerSUT.py
+++ b/build/mobile/devicemanagerSUT.py
@@ -577,25 +577,27 @@ class DeviceManagerSUT(DeviceManager):
     cmdline = '%s %s' % (self.formatEnvString(env), cmdline)
 
     if self.fireProcess(cmdline, failIfRunning) is None:
       return None
     return outputFile
 
   # external function
   # returns:
-  #  success: output from testagent
-  #  failure: None
-  def killProcess(self, appname):
+  #  success: True
+  #  failure: False
+  def killProcess(self, appname, forceKill=False):
+    if forceKill:
+      print "WARNING: killProcess(): forceKill parameter unsupported on SUT"
     try:
       data = self.runCmds(['kill ' + appname])
     except AgentError:
-      return None
+      return False
 
-    return data
+    return True
 
   # external function
   # returns:
   #  success: tmpdir, string
   #  failure: None
   def getTempDir(self):
     try:
       data = self.runCmds(['tmpd'])
--- a/build/mobile/robocop/FennecNativeDriver.java.in
+++ b/build/mobile/robocop/FennecNativeDriver.java.in
@@ -65,16 +65,18 @@ import android.opengl.GLSurfaceView;
 import android.view.View;
 import android.util.Log;
 
 import org.json.*;
 
 import com.jayway.android.robotium.solo.Solo;
 
 public class FennecNativeDriver implements Driver {
+    private static final int FRAME_TIME_THRESHOLD = 17;     // allow 17ms per frame (~60fps)
+
     // Map of IDs to element names.
     private HashMap mLocators = null;
     private Activity mActivity;
     private Solo mSolo;
 
     private static String mLogFile = null;
     private static LogLevel mLogLevel = LogLevel.LOG_LEVEL_INFO;
 
@@ -220,31 +222,25 @@ public class FennecNativeDriver implemen
         } catch (InvocationTargetException e) {
             e.printStackTrace();
         }
     }
 
     public int stopFrameRecording() {
         Class [] parameters = new Class[1];
         parameters[0] = null;
-        List frames;
 
         try {
             Object [] params = null;
-            frames = (List)_stopFrameRecording.invoke(null, params);
-            Object [] framearray = frames.toArray();
-            Long last = new Long(0);
-            Long threshold = new Long(17);
+            List<Long> frames = (List<Long>)_stopFrameRecording.invoke(null, params);
             int numDelays = 0;
-            for (int i=0; i < framearray.length; i++) {
-                Long val = (Long)framearray[i];
-                if ((val - last) > threshold) {
+            for (int i = 1; i < frames.size(); i++) {
+                if (frames.get(i) - frames.get(i-1) > FRAME_TIME_THRESHOLD) {
                     numDelays++;
                 }
-                last = val;
             }
             return numDelays;
         } catch (IllegalAccessException e) {
             e.printStackTrace();
         } catch (InvocationTargetException e) {
             e.printStackTrace();
         }
 
@@ -260,28 +256,25 @@ public class FennecNativeDriver implemen
         } catch (InvocationTargetException e) {
             e.printStackTrace();
         }
     }
 
     public float stopCheckerboardRecording() {
         Class [] parameters = new Class[1];
         parameters[0] = null;
-        List checkerboard;
 
         try {
             Object [] params = null;
-            checkerboard = (List)_stopCheckerboardRecording.invoke(null, params);
-            Object [] amountarray = checkerboard.toArray();
-            double completeness = 0;
-            for (Object obj : amountarray) {
-                float val = (Float)obj;
-                completeness += (1.0 - (double)val) / (double)amountarray.length;
+            List<Float> checkerboard = (List<Float>)_stopCheckerboardRecording.invoke(null, params);
+            float completeness = 0;
+            for (float val : checkerboard) {
+                completeness += (1.0f - val);
             }
-            return (float)completeness;
+            return completeness / (float)checkerboard.size();
         } catch (IllegalAccessException e) {
             e.printStackTrace();
         } catch (InvocationTargetException e) {
             e.printStackTrace();
         }
 
         return 0.0f;
     }
--- a/build/stdc++compat.cpp
+++ b/build/stdc++compat.cpp
@@ -54,19 +54,17 @@
 namespace std {
 #if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 9)
     /* Instantiate these templates to avoid GLIBCXX_3.4.9 symbol versions */
     template ostream& ostream::_M_insert(double);
     template ostream& ostream::_M_insert(long);
     template ostream& ostream::_M_insert(unsigned long);
     template ostream& ostream::_M_insert(long long);
     template ostream& ostream::_M_insert(unsigned long long);
-#ifdef DEBUG
     template ostream& ostream::_M_insert(const void*);
-#endif
     template ostream& __ostream_insert(ostream&, const char*, streamsize);
     template istream& istream::_M_extract(double&);
 #endif
 #if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)
     /* Instantiate these templates to avoid GLIBCXX_3.4.14 symbol versions
      * depending on optimization level */
     template char *string::_S_construct_aux_2(size_type, char, allocator<char> const&);
 #ifdef _GLIBCXX_USE_WCHAR_T
new file mode 100644
--- /dev/null
+++ b/build/stlport/Makefile.in
@@ -0,0 +1,30 @@
+# 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/.
+
+DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULES = stlport
+LIBRARY_NAME = stlport_static
+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
+
+CPPSRCS = $(notdir $(wildcard $(STLPORT_SOURCES)/src/*.cpp))
+CSRCS = $(notdir $(wildcard $(STLPORT_SOURCES)/src/*.c))
+
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -D_GNU_SOURCE
+CXXFLAGS += -fuse-cxa-atexit
+INCLUDES += -I$(STLPORT_SOURCES)/stlport
new file mode 100644
--- /dev/null
+++ b/build/stlport/stl/config/_android.h.in
@@ -0,0 +1,23 @@
+/* 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/. */
+
+#ifndef mozilla_stl_config__android_h
+#define mozilla_stl_config__android_h
+
+#include "@STLPORT_SOURCES@/stlport/stl/config/_android.h"
+
+// No rtti support
+#undef _STLP_NO_RTTI
+#define _STLP_NO_RTTI 1
+
+// No throwing exceptions
+#undef _STLP_NO_EXCEPTIONS
+#define _STLP_NO_EXCEPTIONS 1
+
+#undef _STLP_NATIVE_CPP_C_HEADER
+#define _STLP_NATIVE_CPP_C_HEADER(header) <../../system/include/header>
+#undef _STLP_NATIVE_CPP_RUNTIME_HEADER
+#define _STLP_NATIVE_CPP_RUNTIME_HEADER(header) <../../system/include/header>
+
+#endif /* mozilla_stl_config__android_h */
--- a/build/unix/build-toolchain/build-gcc.py
+++ b/build/unix/build-toolchain/build-gcc.py
@@ -104,16 +104,17 @@ def build_gcc(stage_dir, is_stage_one):
     tool_inst_dir = stage_dir + '/inst'
     lib_inst_dir = stage_dir + '/libinst'
     gcc_configure_args = ["--prefix=%s" % tool_inst_dir,
                           "--enable-__cxa_atexit",
                           "--with-gmp=%s" % lib_inst_dir,
                           "--with-mpfr=%s" % lib_inst_dir,
                           "--with-mpc=%s" % lib_inst_dir,
                           "--enable-languages=c,c++",
+                          "--disable-lto",
                           "--disable-multilib",
                           "--disable-bootstrap"]
     if is_stage_one:
         # We build the stage1 gcc without shared libraries. Otherwise its
         # libgcc.so would depend on the system libc.so, which causes problems
         # when it tries to use that libgcc.so and the libc we are about to
         # build.
         gcc_configure_args.append("--disable-shared")
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -197,16 +197,17 @@ MOZ_WEBGL = @MOZ_WEBGL@
 MOZ_ANGLE = @MOZ_ANGLE@
 MOZ_DIRECTX_SDK_PATH = @MOZ_DIRECTX_SDK_PATH@
 MOZ_DIRECTX_SDK_CPU_SUFFIX = @MOZ_DIRECTX_SDK_CPU_SUFFIX@
 MOZ_D3DX9_VERSION = @MOZ_D3DX9_VERSION@
 MOZ_D3DX9_CAB = @MOZ_D3DX9_CAB@
 MOZ_D3DCOMPILER_CAB = @MOZ_D3DCOMPILER_CAB@
 MOZ_D3DX9_DLL = @MOZ_D3DX9_DLL@
 MOZ_D3DCOMPILER_DLL = @MOZ_D3DCOMPILER_DLL@
+MOZ_GL_PROVIDER = @MOZ_GL_PROVIDER@
 
 
 JAVA="@JAVA@"
 JAVAC="@JAVAC@"
 JAR="@JAR@"
 
 TAR=@TAR@
 
@@ -685,16 +686,17 @@ MOZ_APP_COMPONENT_LIBS = @MOZ_APP_COMPON
 MOZ_APP_EXTRA_LIBS = @MOZ_APP_EXTRA_LIBS@
 
 ANDROID_NDK       = @ANDROID_NDK@
 ANDROID_TOOLCHAIN = @ANDROID_TOOLCHAIN@
 ANDROID_PLATFORM  = @ANDROID_PLATFORM@
 ANDROID_SDK       = @ANDROID_SDK@
 ANDROID_PLATFORM_TOOLS = @ANDROID_PLATFORM_TOOLS@
 ANDROID_VERSION   = @ANDROID_VERSION@
+STLPORT_SOURCES   = @STLPORT_SOURCES@
 
 ANDROID_PACKAGE_NAME = @ANDROID_PACKAGE_NAME@
 
 JS_SHARED_LIBRARY = @JS_SHARED_LIBRARY@
 
 MOZ_INSTRUMENT_EVENT_LOOP = @MOZ_INSTRUMENT_EVENT_LOOP@
 
 MOZ_SYSTEM_PLY = @MOZ_SYSTEM_PLY@
--- a/configure.in
+++ b/configure.in
@@ -124,17 +124,17 @@ GTK2_VERSION=2.10.0
 WINDRES_VERSION=2.14.90
 W32API_VERSION=3.14
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
 GIO_VERSION=2.18
 STARTUP_NOTIFICATION_VERSION=0.8
 DBUS_VERSION=0.60
-SQLITE_VERSION=3.7.10
+SQLITE_VERSION=3.7.11
 LIBNOTIFY_VERSION=0.4
 
 MSMANIFEST_TOOL=
 
 dnl Set various checks
 dnl ========================================================
 MISSING_X=
 AC_PROG_AWK
@@ -1611,33 +1611,36 @@ fi
 if test "$OS_TARGET" = "Android" -a -z "$gonkdir"; then
     if test -n "$MOZ_ANDROID_LIBSTDCXX" ; then
        if test ! -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/libstdc++.a" ; then
           AC_MSG_ERROR([Cannot find path to libstdc++ (NDK version >= 5?)])
        fi
        STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include -D_GLIBCXX_PERMIT_BACKWARD_HASH"
        STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH"
        STLPORT_LIBS="-lstdc++"
-    elif test -e "$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a" ; then
-       STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/stlport/stlport"
-       STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
+    elif test -e "$android_ndk/sources/cxx-stl/stlport/src/iostream.cpp" ; then
+       STLPORT_SOURCES="$android_ndk/sources/cxx-stl/stlport"
+       STLPORT_CPPFLAGS="-I$_objdir/build/stlport -I$android_ndk/sources/cxx-stl/stlport/stlport"
+       STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
        STLPORT_LIBS="-lstlport_static"
     elif  test -e "$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a" ; then
        STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/stlport/stlport"
        STLPORT_LDFLAGS="-L$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH"
        STLPORT_LIBS="-lstlport_static"
     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])
     fi
     CXXFLAGS="$CXXFLAGS $STLPORT_CPPFLAGS"
     LDFLAGS="$LDFLAGS $STLPORT_LDFLAGS"
     LIBS="$LIBS $STLPORT_LIBS"
 fi
 
+AC_SUBST([STLPORT_SOURCES])
+
 dnl ========================================================
 dnl Suppress Clang Argument Warnings
 dnl ========================================================
 if test -n "$CLANG_CC"; then
     _WARNINGS_CFLAGS="-Qunused-arguments ${_WARNINGS_CFLAGS}"
     CPPFLAGS="-Qunused-arguments ${CPPFLAGS}"
 fi
 if test -n "$CLANG_CXX"; then
@@ -4772,17 +4775,17 @@ cairo-windows)
     MOZ_INSTRUMENT_EVENT_LOOP=1
     ;;
 
 cairo-gtk2|cairo-gtk2-x11)
     MOZ_WIDGET_TOOLKIT=gtk2
     MOZ_ENABLE_GTK2=1
     MOZ_ENABLE_XREMOTE=1
     MOZ_WEBGL=1
-    MOZ_WEBGL_GLX=1
+    MOZ_GL_DEFAULT_PROVIDER=GLX
 
     AC_DEFINE(MOZ_X11)
     MOZ_X11=1
     USE_FC_FREETYPE=1
 
     TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
     TK_LIBS='$(MOZ_GTK2_LIBS)'
     AC_DEFINE(MOZ_WIDGET_GTK2)
@@ -4790,17 +4793,17 @@ cairo-gtk2|cairo-gtk2-x11)
     MOZ_INSTRUMENT_EVENT_LOOP=1
     ;;
 
 cairo-qt)
     MOZ_WIDGET_TOOLKIT=qt
     MOZ_ENABLE_QT=1
     if test -z "$WITHOUT_X11"; then
       MOZ_ENABLE_XREMOTE=1
-      MOZ_WEBGL_GLX=1
+      MOZ_GL_DEFAULT_PROVIDER=GLX
       MOZ_X11=1
       AC_DEFINE(MOZ_X11)
       XT_LIBS=
     fi
 
     MOZ_WEBGL=1
     USE_ELF_DYNSTR_GC=
     USE_FC_FREETYPE=1
@@ -6727,17 +6730,17 @@ esac
 if test $MOZ_PLATFORM_MAEMO; then
    AC_DEFINE_UNQUOTED([MOZ_PLATFORM_MAEMO], $MOZ_PLATFORM_MAEMO)
 
    if test -z "$MOZ_ENABLE_DBUS"; then
        AC_MSG_ERROR([DBus is required when building for Maemo])
    fi
 
    MOZ_GFX_OPTIMIZE_MOBILE=1
-   MOZ_WEBGL_GLX=
+   MOZ_GL_DEFAULT_PROVIDER=EGL
    MOZ_MAEMO_LIBLOCATION=
 
    if test $MOZ_PLATFORM_MAEMO = 5; then
       dnl if we have Xcomposite we should also have Xdamage and Xfixes
       MOZ_CHECK_HEADERS([X11/extensions/Xdamage.h], [],
           [AC_MSG_ERROR([Couldn't find X11/extensions/Xdamage.h which is required for composited plugins.])])
       AC_CHECK_LIB(Xcomposite, XCompositeRedirectWindow, [XCOMPOSITE_LIBS="-lXcomposite -lXdamage -lXfixes"],
                    [MISSING_X="$MISSING_X -lXcomposite"], $XLIBS)
@@ -6855,16 +6858,32 @@ MOZ_ARG_ENABLE_BOOL(egl-xrender-composit
 
 if test -n "$MOZ_EGL_XRENDER_COMPOSITE"; then
     AC_DEFINE(MOZ_EGL_XRENDER_COMPOSITE)
 fi
 
 AC_SUBST(MOZ_EGL_XRENDER_COMPOSITE)
 
 dnl ========================================================
+dnl GL provider
+dnl ========================================================
+MOZ_GL_PROVIDER=
+MOZ_ARG_WITH_STRING(gl-provider,
+[  --with-gl-provider=ID
+                          Set GL provider backend type],
+[ val=`echo $withval`
+    MOZ_GL_PROVIDER="$val"])
+
+if test -n "$MOZ_GL_PROVIDER"; then
+MOZ_GL_DEFAULT_PROVIDER=$MOZ_GL_PROVIDER
+AC_SUBST(MOZ_GL_PROVIDER)
+AC_DEFINE_UNQUOTED(MOZ_GL_PROVIDER, GLContextProvider$MOZ_GL_PROVIDER)
+fi
+
+dnl ========================================================
 dnl = faststripe theme
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(faststripe,
 [  --enable-faststripe     Use faststripe theme],
     MOZ_THEME_FASTSTRIPE=1,
     MOZ_THEME_FASTSTRIPE= )
 AC_SUBST(MOZ_THEME_FASTSTRIPE)
 
@@ -7221,23 +7240,21 @@ AC_SUBST(MOZ_GLUE_PROGRAM_LDFLAGS)
 AC_SUBST(WIN32_CRT_LIBS)
 dnl Need to set this for make because NSS doesn't have configure
 AC_SUBST(DLLFLAGS)
 
 dnl We need to wrap dlopen and related functions on Android because we use
 dnl our own linker.
 if test "$OS_TARGET" = Android; then
     WRAP_LDFLAGS="${WRAP_LDFLAGS} -L$_objdir/dist/lib -lmozglue"
-    if test "$MOZ_WIDGET_TOOLKIT" = android; then
-        if test -n "$MOZ_OLD_LINKER"; then
-            WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr"
-        fi
-        WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=getaddrinfo,--wrap=freeaddrinfo,--wrap=gai_strerror"
-        WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=fork,--wrap=pthread_atfork"
-    fi
+    if test -n "$MOZ_OLD_LINKER"; then
+        WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr"
+    fi
+    WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=getaddrinfo,--wrap=freeaddrinfo,--wrap=gai_strerror"
+    WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=fork,--wrap=pthread_atfork"
 fi
 
 dnl ========================================================
 dnl = Use malloc wrapper lib
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(wrap-malloc,
 [  --enable-wrap-malloc    Wrap malloc calls (gnu linker only)],
     _WRAP_MALLOC=1,
@@ -8709,22 +8726,22 @@ if test "$MOZ_X11"; then
 
     if test -n "$MISSING_X"; then
         AC_MSG_ERROR([ Could not find the following X libraries: $MISSING_X ]);
     fi
 
 fi # MOZ_X11
 
 dnl Check for headers, etc. needed by WebGL.
-if test -n "$MOZ_WEBGL_GLX"; then
+if test "$MOZ_GL_DEFAULT_PROVIDER" = "GLX"; then
     MOZ_CHECK_HEADER(GL/glx.h)
     if test "$ac_cv_header_GL_glx_h" != "yes"; then
         AC_MSG_ERROR([Can't find header GL/glx.h for WebGL (install mesa-common-dev (Ubuntu), mesa-libGL-devel (Fedora), or Mesa-devel (openSUSE))])
     fi
-fi # MOZ_WEBGL_GLX
+fi # MOZ_GL_DEFAULT_PROVIDER=GLX
 fi # COMPILE_ENVIRONMENT
 
 if test "$USE_FC_FREETYPE"; then
     if test "$COMPILE_ENVIRONMENT"; then
     	_SAVE_CPPFLAGS="$CPPFLAGS"
     	CPPFLAGS="$CPPFLAGS $FT2_CFLAGS $XCFLAGS"
         MOZ_CHECK_HEADERS([fontconfig/fcfreetype.h], ,
             [AC_MSG_ERROR(Can't find header fontconfig/fcfreetype.h.)], [#include <fontconfig/fontconfig.h>])
@@ -9099,16 +9116,19 @@ if test "$MOZ_MEMORY"; then
 fi
 if test -n "$MOZ_GLUE_LDFLAGS"; then
    export MOZ_GLUE_LDFLAGS
 fi
 if test -n "$MOZ_GLUE_PROGRAM_LDFLAGS"; then
    export MOZ_GLUE_PROGRAM_LDFLAGS
 fi
 export MOZ_APP_NAME
+export STLPORT_CPPFLAGS
+export STLPORT_LDFLAGS
+export STLPORT_LIBS
 AC_OUTPUT_SUBDIRS(js/src)
 ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 
 fi # COMPILE_ENVIRONMENT && !LIBXUL_SDK_DIR
 
 dnl Prevent the regeneration of autoconf.mk forcing rebuilds of the world
 dnl Needs to be at the end to respect possible changes from NSPR configure
 if cmp -s config/autoconf.mk config/autoconf.mk.orig; then
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -237,16 +237,19 @@ nsDOMFileReader::GetResult(JSContext* aC
 {
   if (mDataFormat == FILE_AS_ARRAYBUFFER) {
     if (mReadyState == nsIDOMFileReader::DONE && mResultArrayBuffer) {
       JSObject* tmp = mResultArrayBuffer;
       *aResult = OBJECT_TO_JSVAL(tmp);
     } else {
       *aResult = JSVAL_NULL;
     }
+    if (!JS_WrapValue(aCx, aResult)) {
+      return NS_ERROR_FAILURE;
+    }
     return NS_OK;
   }
  
   nsString tmpResult = mResult;
   if (!xpc::StringToJsval(aCx, tmpResult, aResult)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -8962,17 +8962,17 @@ nsDocument::RequestFullScreen(Element* a
   sFullScreenDoc = do_GetWeakReference(static_cast<nsIDocument*>(this));
 
 #ifdef DEBUG
   // Note assertions must run before SetWindowFullScreen() as that does
   // synchronous event dispatch which can run script which exits full-screen!
   NS_ASSERTION(GetFullScreenElement() == aElement,
                "Full-screen element should be the requested element!");
   NS_ASSERTION(IsFullScreenDoc(), "Should be full-screen doc");
-  nsCOMPtr<nsIDOMHTMLElement> fse;
+  nsCOMPtr<nsIDOMElement> fse;
   GetMozFullScreenElement(getter_AddRefs(fse));
   nsCOMPtr<nsIContent> c(do_QueryInterface(fse));
   NS_ASSERTION(c->AsElement() == aElement,
     "GetMozFullScreenElement should match GetFullScreenElement()");
 #endif
 
   // Make the window full-screen. Note we must make the state changes above
   // before making the window full-screen, as then the document reports as
@@ -8980,17 +8980,17 @@ nsDocument::RequestFullScreen(Element* a
   // enabling chrome to distinguish between browser and dom full-screen
   // modes. Also note that nsGlobalWindow::SetFullScreen() (which
   // SetWindowFullScreen() calls) proxies to the root window in its hierarchy,
   // and does not operate on the a per-nsIDOMWindow basis.
   SetWindowFullScreen(this, true);
 }
 
 NS_IMETHODIMP
-nsDocument::GetMozFullScreenElement(nsIDOMHTMLElement **aFullScreenElement)
+nsDocument::GetMozFullScreenElement(nsIDOMElement **aFullScreenElement)
 {
   NS_ENSURE_ARG_POINTER(aFullScreenElement);
   *aFullScreenElement = nsnull;
   if (IsFullScreenDoc()) {
     // Must have a full-screen element while in full-screen mode.
     NS_ENSURE_STATE(GetFullScreenElement());
     CallQueryInterface(GetFullScreenElement(), aFullScreenElement);
   }
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -6412,8 +6412,34 @@ nsINode::Contains(const nsINode* aOther)
 
 nsresult
 nsINode::Contains(nsIDOMNode* aOther, bool* aReturn)
 {
   nsCOMPtr<nsINode> node = do_QueryInterface(aOther);
   *aReturn = Contains(node);
   return NS_OK;
 }
+
+nsresult nsGenericElement::MozRequestFullScreen()
+{
+  // Only grant full-screen requests if this is called from inside a trusted
+  // event handler (i.e. inside an event handler for a user initiated event).
+  // This stops the full-screen from being abused similar to the popups of old,
+  // and it also makes it harder for bad guys' script to go full-screen and
+  // spoof the browser chrome/window and phish logins etc.
+  if (!nsContentUtils::IsRequestFullScreenAllowed()) {
+    nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
+                                    "DOM", OwnerDoc(),
+                                    nsContentUtils::eDOM_PROPERTIES,
+                                    "FullScreenDeniedNotInputDriven");
+    nsRefPtr<nsAsyncDOMEvent> e =
+      new nsAsyncDOMEvent(OwnerDoc(),
+                          NS_LITERAL_STRING("mozfullscreenerror"),
+                          true,
+                          false);
+    e->PostDOMEvent();
+    return NS_OK;
+  }
+
+  OwnerDoc()->AsyncRequestFullScreen(this);
+
+  return NS_OK;
+}
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1243,23 +1243,24 @@ nsresult
 nsObjectLoadingContent::LoadObject(nsIURI* aURI,
                                    bool aNotify,
                                    const nsCString& aTypeHint,
                                    bool aForceLoad)
 {
   // Only do a URI equality check for things that aren't stopped plugins.
   // This is because we still need to load again if the plugin has been stopped.
   if (mType == eType_Document || mType == eType_Image || mInstanceOwner) {
-    if (mURI && aURI && !aForceLoad) {
+    if (mURI && aURI) {
       bool equal;
       nsresult rv = mURI->Equals(aURI, &equal);
-      if (NS_SUCCEEDED(rv) && equal) {
+      if (NS_SUCCEEDED(rv) && equal && !aForceLoad) {
         // URI didn't change, do nothing
         return NS_OK;
       }
+      StopPluginInstance();
     }
   }
 
   // Need to revoke any potentially pending instantiate events
   if (mType == eType_Plugin && mPendingInstantiateEvent) {
     mPendingInstantiateEvent = nsnull;
   }
 
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -412,18 +412,17 @@ nsScriptLoader::ProcessScriptElement(nsI
   // For now though, if JS is disabled we assume every language is
   // disabled.
   // XXX is this different from the mDocument->IsScriptEnabled() call?
   nsIScriptGlobalObject *globalObject = mDocument->GetScriptGlobalObject();
   if (!globalObject) {
     return false;
   }
   
-  nsIScriptContext *context = globalObject->GetScriptContext(
-                                        nsIProgrammingLanguage::JAVASCRIPT);
+  nsIScriptContext *context = globalObject->GetScriptContext();
 
   // If scripts aren't enabled in the current context, there's no
   // point in going on.
   if (!context || !context->GetScriptsEnabled()) {
     return false;
   }
 
   // Default script language is whatever the root element specifies
@@ -885,24 +884,24 @@ nsScriptLoader::EvaluateScript(nsScriptL
   nsCOMPtr<nsIScriptGlobalObject> globalObject = do_QueryInterface(pwin);
   NS_ASSERTION(globalObject, "windows must be global objects");
 
   // Get the script-type to be used by this element.
   NS_ASSERTION(scriptContent, "no content - what is default script-type?");
   PRUint32 stid = scriptContent ? scriptContent->GetScriptTypeID() :
                                   nsIProgrammingLanguage::JAVASCRIPT;
   // and make sure we are setup for this type of script.
-  rv = globalObject->EnsureScriptEnvironment(stid);
+  rv = globalObject->EnsureScriptEnvironment();
   if (NS_FAILED(rv))
     return rv;
 
   // Make sure context is a strong reference since we access it after
   // we've executed a script, which may cause all other references to
   // the context to go away.
-  nsCOMPtr<nsIScriptContext> context = globalObject->GetScriptContext(stid);
+  nsCOMPtr<nsIScriptContext> context = globalObject->GetScriptContext();
   if (!context) {
     return NS_ERROR_FAILURE;
   }
 
   bool oldProcessingScriptTag = context->GetProcessingScriptTag();
   context->SetProcessingScriptTag(true);
 
   // Update our current script.
--- a/content/canvas/public/nsICanvasElementExternal.h
+++ b/content/canvas/public/nsICanvasElementExternal.h
@@ -62,24 +62,29 @@ struct _cairo_surface;
  * same functionality is needed in both places, two separate methods should be
  * used.
  */
 
 class nsICanvasElementExternal : public nsISupports {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICANVASELEMENTEXTERNAL_IID)
 
+  enum {
+    RenderFlagPremultAlpha = 0x1
+  };
+
   /**
    * Get the size in pixels of this canvas element
    */
   NS_IMETHOD_(nsIntSize) GetSizeExternal() = 0;
 
   /*
    * Ask the canvas element to tell the contexts to render themselves
    * to the given gfxContext at the origin of its coordinate space.
    */
   NS_IMETHOD RenderContextsExternal(gfxContext *ctx,
-                                    gfxPattern::GraphicsFilter aFilter) = 0;
+                                    gfxPattern::GraphicsFilter aFilter,
+                                    PRUint32 aFlags = RenderFlagPremultAlpha) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasElementExternal, NS_ICANVASELEMENTEXTERNAL_IID)
 
 #endif /* nsICanvasElementExternal_h___ */
--- a/content/canvas/public/nsICanvasRenderingContextInternal.h
+++ b/content/canvas/public/nsICanvasRenderingContextInternal.h
@@ -69,28 +69,34 @@ class SourceSurface;
 
 class nsICanvasRenderingContextInternal : public nsISupports {
 public:
   typedef mozilla::layers::CanvasLayer CanvasLayer;
   typedef mozilla::layers::LayerManager LayerManager;
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)
 
+  enum {
+    RenderFlagPremultAlpha = 0x1
+  };
+
   // This method should NOT hold a ref to aParentCanvas; it will be called
   // with nsnull when the element is going away.
   NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas) = 0;
 
   // Sets the dimensions of the canvas, in pixels.  Called
   // whenever the size of the element changes.
   NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height) = 0;
 
   NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, PRInt32 width, PRInt32 height) = 0;
 
   // Render the canvas at the origin of the given gfxContext
-  NS_IMETHOD Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter) = 0;
+  NS_IMETHOD Render(gfxContext *ctx,
+                    gfxPattern::GraphicsFilter aFilter,
+                    PRUint32 aFlags = RenderFlagPremultAlpha) = 0;
 
   // Gives you a stream containing the image represented by this context.
   // The format is given in aMimeTime, for example "image/png".
   //
   // If the image format does not support transparency or aIncludeTransparency
   // is false, alpha will be discarded and the result will be the image
   // composited on black.
   NS_IMETHOD GetInputStream(const char *aMimeType,
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -556,28 +556,36 @@ WebGLContext::SetDimensions(PRInt32 widt
 
     gl->ClearSafely();
 
     reporter.SetSuccessful();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-WebGLContext::Render(gfxContext *ctx, gfxPattern::GraphicsFilter f)
+WebGLContext::Render(gfxContext *ctx, gfxPattern::GraphicsFilter f, PRUint32 aFlags)
 {
     if (!gl)
         return NS_OK;
 
     nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
                                                          gfxASurface::ImageFormatARGB32);
     if (surf->CairoStatus() != 0)
         return NS_ERROR_FAILURE;
 
     gl->ReadPixelsIntoImageSurface(0, 0, mWidth, mHeight, surf);
-    gfxUtils::PremultiplyImageSurface(surf);
+
+    bool srcPremultAlpha = mOptions.premultipliedAlpha;
+    bool dstPremultAlpha = aFlags & RenderFlagPremultAlpha;
+
+    if (!srcPremultAlpha && dstPremultAlpha) {
+        gfxUtils::PremultiplyImageSurface(surf);
+    } else if (srcPremultAlpha && !dstPremultAlpha) {
+        gfxUtils::UnpremultiplyImageSurface(surf);
+    }
 
     nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
     pat->SetFilter(f);
 
     // Pixels from ReadPixels will be "upside down" compared to
     // what cairo wants, so draw with a y-flip and a translte to
     // flip them.
     gfxMatrix m;
@@ -603,38 +611,50 @@ WebGLContext::GetInputStream(const char*
 
     nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
                                                          gfxASurface::ImageFormatARGB32);
     if (surf->CairoStatus() != 0)
         return NS_ERROR_FAILURE;
 
     nsRefPtr<gfxContext> tmpcx = new gfxContext(surf);
     // Use Render() to make sure that appropriate y-flip gets applied
-    nsresult rv = Render(tmpcx, gfxPattern::FILTER_NEAREST);
+    PRUint32 flags = mOptions.premultipliedAlpha ? RenderFlagPremultAlpha : 0;
+    nsresult rv = Render(tmpcx, gfxPattern::FILTER_NEAREST, flags);
     if (NS_FAILED(rv))
         return rv;
 
     const char encoderPrefix[] = "@mozilla.org/image/encoder;2?type=";
     nsAutoArrayPtr<char> conid(new char[strlen(encoderPrefix) + strlen(aMimeType) + 1]);
 
     if (!conid)
         return NS_ERROR_OUT_OF_MEMORY;
 
     strcpy(conid, encoderPrefix);
     strcat(conid, aMimeType);
 
     nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(conid);
     if (!encoder)
         return NS_ERROR_FAILURE;
 
+    int format = imgIEncoder::INPUT_FORMAT_HOSTARGB;
+    if (!mOptions.premultipliedAlpha) {
+        // We need to convert to INPUT_FORMAT_RGBA, otherwise
+        // we are automatically considered premult, and unpremult'd.
+        // Yes, it is THAT silly.
+        // Except for different lossy conversions by color,
+        // we could probably just change the label, and not change the data.
+        gfxUtils::ConvertBGRAtoRGBA(surf);
+        format = imgIEncoder::INPUT_FORMAT_RGBA;
+    }
+
     rv = encoder->InitFromData(surf->Data(),
                                mWidth * mHeight * 4,
                                mWidth, mHeight,
                                surf->Stride(),
-                               imgIEncoder::INPUT_FORMAT_HOSTARGB,
+                               format,
                                nsDependentString(aEncoderOptions));
     NS_ENSURE_SUCCESS(rv, rv);
 
     return CallQueryInterface(encoder, aStream);
 }
 
 NS_IMETHODIMP
 WebGLContext::GetThebesSurface(gfxASurface **surface)
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -537,17 +537,19 @@ public:
 
     // nsICanvasRenderingContextInternal
     NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas);
     NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
     NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, PRInt32 width, PRInt32 height)
         { return NS_ERROR_NOT_IMPLEMENTED; }
     NS_IMETHOD Reset()
         { /* (InitializeWithSurface) */ return NS_ERROR_NOT_IMPLEMENTED; }
-    NS_IMETHOD Render(gfxContext *ctx, gfxPattern::GraphicsFilter f);
+    NS_IMETHOD Render(gfxContext *ctx,
+                      gfxPattern::GraphicsFilter f,
+                      PRUint32 aFlags = RenderFlagPremultAlpha);
     NS_IMETHOD GetInputStream(const char* aMimeType,
                               const PRUnichar* aEncoderOptions,
                               nsIInputStream **aStream);
     NS_IMETHOD GetThebesSurface(gfxASurface **surface);
     mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot()
         { return nsnull; }
 
     NS_IMETHOD SetIsOpaque(bool b) { return NS_OK; };
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -346,17 +346,19 @@ public:
     nsresult Redraw();
 
     // nsICanvasRenderingContextInternal
     NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas);
     NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
     void Initialize(nsIDocShell *shell, PRInt32 width, PRInt32 height);
     NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, PRInt32 width, PRInt32 height);
     bool EnsureSurface();
-    NS_IMETHOD Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter);
+    NS_IMETHOD Render(gfxContext *ctx,
+                      gfxPattern::GraphicsFilter aFilter,
+                      PRUint32 aFlags = RenderFlagPremultAlpha);
     NS_IMETHOD GetInputStream(const char* aMimeType,
                               const PRUnichar* aEncoderOptions,
                               nsIInputStream **aStream);
     NS_IMETHOD GetThebesSurface(gfxASurface **surface);
     mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot()
         { return nsnull; }
 
     NS_IMETHOD SetIsOpaque(bool isOpaque);
@@ -1273,17 +1275,17 @@ nsCanvasRenderingContext2D::SetIsIPC(boo
          */
         return SetDimensions(mWidth, mHeight);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter)
+nsCanvasRenderingContext2D::Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter, PRUint32 aFlags)
 {
     nsresult rv = NS_OK;
 
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     nsRefPtr<gfxPattern> pat = new gfxPattern(mSurface);
 
@@ -1298,16 +1300,24 @@ nsCanvasRenderingContext2D::Render(gfxCo
     // pixel alignment for this stuff!
     ctx->NewPath();
     ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
     ctx->Fill();
 
     if (mOpaque)
         ctx->SetOperator(op);
 
+    if (!(aFlags & RenderFlagPremultAlpha)) {
+        nsRefPtr<gfxASurface> curSurface = ctx->CurrentSurface();
+        nsRefPtr<gfxImageSurface> gis = curSurface->GetAsImageSurface();
+        NS_ABORT_IF_FALSE(gis, "If non-premult alpha, must be able to get image surface!");
+
+        gfxUtils::UnpremultiplyImageSurface(gis);
+    }
+
     return rv;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetInputStream(const char *aMimeType,
                                            const PRUnichar *aEncoderOptions,
                                            nsIInputStream **aStream)
 {
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -401,17 +401,19 @@ public:
   nsresult Redraw();
 
   // nsICanvasRenderingContextInternal
   NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas);
   NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
   NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, PRInt32 width, PRInt32 height)
   { return NS_ERROR_NOT_IMPLEMENTED; }
 
-  NS_IMETHOD Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter);
+  NS_IMETHOD Render(gfxContext *ctx,
+                    gfxPattern::GraphicsFilter aFilter,
+                    PRUint32 aFlags = RenderFlagPremultAlpha);
   NS_IMETHOD GetInputStream(const char* aMimeType,
                             const PRUnichar* aEncoderOptions,
                             nsIInputStream **aStream);
   NS_IMETHOD GetThebesSurface(gfxASurface **surface);
 
   TemporaryRef<SourceSurface> GetSurfaceSnapshot()
   { return mTarget ? mTarget->Snapshot() : nsnull; }
 
@@ -1377,17 +1379,17 @@ nsCanvasRenderingContext2DAzure::SetIsIP
       */
     return SetDimensions(mWidth, mHeight);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter)
+nsCanvasRenderingContext2DAzure::Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter, PRUint32 aFlags)
 {
   nsresult rv = NS_OK;
 
   if (!mValid || !mTarget) {
     return NS_ERROR_FAILURE;
   }
 
   nsRefPtr<gfxASurface> surface;
@@ -1409,16 +1411,24 @@ nsCanvasRenderingContext2DAzure::Render(
   // pixel alignment for this stuff!
   ctx->NewPath();
   ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
   ctx->Fill();
 
   if (mOpaque)
       ctx->SetOperator(op);
 
+  if (!(aFlags & RenderFlagPremultAlpha)) {
+      nsRefPtr<gfxASurface> curSurface = ctx->CurrentSurface();
+      nsRefPtr<gfxImageSurface> gis = curSurface->GetAsImageSurface();
+      NS_ABORT_IF_FALSE(gis, "If non-premult alpha, must be able to get image surface!");
+
+      gfxUtils::UnpremultiplyImageSurface(gis);
+  }
+
   return rv;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetInputStream(const char *aMimeType,
                                                 const PRUnichar *aEncoderOptions,
                                                 nsIInputStream **aStream)
 {
--- a/content/canvas/test/webgl/failing_tests_linux.txt
+++ b/content/canvas/test/webgl/failing_tests_linux.txt
@@ -1,7 +1,6 @@
-conformance/context/premultiplyalpha-test.html
 conformance/misc/uninitialized-test.html
 conformance/programs/gl-get-active-attribute.html
 conformance/textures/texture-mips.html
 conformance/uniforms/gl-uniform-bool.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/renderbuffers/framebuffer-object-attachment.html
\ No newline at end of file
--- a/content/canvas/test/webgl/failing_tests_mac.txt
+++ b/content/canvas/test/webgl/failing_tests_mac.txt
@@ -1,6 +1,5 @@
-conformance/context/premultiplyalpha-test.html
 conformance/glsl/misc/glsl-function-nodes.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/programs/program-test.html
 conformance/textures/texture-mips.html
 conformance/textures/texture-npot.html
--- a/content/canvas/test/webgl/failing_tests_windows.txt
+++ b/content/canvas/test/webgl/failing_tests_windows.txt
@@ -1,6 +1,5 @@
-conformance/context/premultiplyalpha-test.html
 conformance/glsl/functions/glsl-function-atan.html
 conformance/glsl/functions/glsl-function-atan-xy.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/glsl/misc/struct-nesting-under-maximum.html
 conformance/more/functions/uniformfArrayLen1.html
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -527,22 +527,22 @@ nsEventListenerManager::AddScriptEventLi
                                  nsnull);
         return NS_OK;
       }
     }
   }
 
   // This might be the first reference to this language in the global
   // We must init the language before we attempt to fetch its context.
-  if (NS_FAILED(global->EnsureScriptEnvironment(aLanguage))) {
+  if (NS_FAILED(global->EnsureScriptEnvironment())) {
     NS_WARNING("Failed to setup script environment for this language");
     // but fall through and let the inevitable failure below handle it.
   }
 
-  nsIScriptContext* context = global->GetScriptContext(aLanguage);
+  nsIScriptContext* context = global->GetScriptContext();
   NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
 
   JSObject* scope = global->GetGlobalJSObject();
 
   nsListenerStruct *ls;
   rv = SetJSEventListener(context, scope, aName, nsnull,
                           aPermitUntrustedEvents, &ls);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/html/content/public/nsHTMLCanvasElement.h
+++ b/content/html/content/public/nsHTMLCanvasElement.h
@@ -137,17 +137,19 @@ public:
    * across its entire area.
    */
   bool GetIsOpaque();
 
   /*
    * nsICanvasElementExternal -- for use outside of content/layout
    */
   NS_IMETHOD_(nsIntSize) GetSizeExternal();
-  NS_IMETHOD RenderContextsExternal(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter);
+  NS_IMETHOD RenderContextsExternal(gfxContext *aContext,
+                                    gfxPattern::GraphicsFilter aFilter,
+                                    PRUint32 aFlags = RenderFlagPremultAlpha);
 
   virtual bool ParseAttribute(PRInt32 aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult);
   nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute, PRInt32 aModType) const;
 
   // SetAttr override.  C++ is stupid, so have to override both
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -3215,42 +3215,16 @@ nsGenericHTMLElement::Blur()
 nsresult
 nsGenericHTMLElement::Focus()
 {
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(this);
   return fm ? fm->SetFocus(elem, 0) : NS_OK;
 }
 
-nsresult nsGenericHTMLElement::MozRequestFullScreen()
-{
-  // Only grant full-screen requests if this is called from inside a trusted
-  // event handler (i.e. inside an event handler for a user initiated event).
-  // This stops the full-screen from being abused similar to the popups of old,
-  // and it also makes it harder for bad guys' script to go full-screen and
-  // spoof the browser chrome/window and phish logins etc.
-  if (!nsContentUtils::IsRequestFullScreenAllowed()) {
-    nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
-                                    "DOM", OwnerDoc(),
-                                    nsContentUtils::eDOM_PROPERTIES,
-                                    "FullScreenDeniedNotInputDriven");
-    nsRefPtr<nsAsyncDOMEvent> e =
-      new nsAsyncDOMEvent(OwnerDoc(),
-                          NS_LITERAL_STRING("mozfullscreenerror"),
-                          true,
-                          false);
-    e->PostDOMEvent();
-    return NS_OK;
-  }
-
-  OwnerDoc()->AsyncRequestFullScreen(this);
-
-  return NS_OK;
-}
-
 nsresult nsGenericHTMLElement::Click()
 {
   if (HasFlag(NODE_HANDLING_CLICK))
     return NS_OK;
 
   // Strong in case the event kills it
   nsCOMPtr<nsIDocument> doc = GetCurrentDoc();
 
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -127,17 +127,16 @@ public:
   nsresult GetOffsetParent(nsIDOMElement** aOffsetParent);
   NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
   NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML);
   NS_IMETHOD GetOuterHTML(nsAString& aOuterHTML);
   NS_IMETHOD SetOuterHTML(const nsAString& aOuterHTML);
   NS_IMETHOD InsertAdjacentHTML(const nsAString& aPosition,
                                 const nsAString& aText);
   nsresult ScrollIntoView(bool aTop, PRUint8 optional_argc);
-  nsresult MozRequestFullScreen();
   // Declare Focus(), Blur(), GetTabIndex(), SetTabIndex(), GetHidden(),
   // SetHidden(), GetSpellcheck(), SetSpellcheck(), and GetDraggable() such that
   // classes that inherit interfaces with those methods properly override them.
   NS_IMETHOD Focus();
   NS_IMETHOD Blur();
   NS_IMETHOD Click();
   NS_IMETHOD GetTabIndex(PRInt32 *aTabIndex);
   NS_IMETHOD SetTabIndex(PRInt32 aTabIndex);
@@ -1524,19 +1523,16 @@ PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_B
   NS_SCRIPTABLE NS_IMETHOD GetOffsetLeft(PRInt32* aOffsetLeft) { \
     return _to GetOffsetLeft(aOffsetLeft); \
   } \
   NS_SCRIPTABLE NS_IMETHOD GetOffsetWidth(PRInt32* aOffsetWidth) { \
     return _to GetOffsetWidth(aOffsetWidth); \
   } \
   NS_SCRIPTABLE NS_IMETHOD GetOffsetHeight(PRInt32* aOffsetHeight) { \
     return _to GetOffsetHeight(aOffsetHeight); \
-  } \
-  NS_SCRIPTABLE NS_IMETHOD MozRequestFullScreen() { \
-    return _to MozRequestFullScreen(); \
   }
 
 /**
  * A macro to declare the NS_NewHTMLXXXElement() functions.
  */
 #define NS_DECLARE_NS_NEW_HTML_ELEMENT(_elementName)                       \
 nsGenericHTMLElement*                                                      \
 NS_NewHTML##_elementName##Element(already_AddRefed<nsINodeInfo> aNodeInfo, \
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -789,22 +789,22 @@ nsHTMLCanvasElement::MarkContextClean()
 
 NS_IMETHODIMP_(nsIntSize)
 nsHTMLCanvasElement::GetSizeExternal()
 {
   return GetWidthHeight();
 }
 
 NS_IMETHODIMP
-nsHTMLCanvasElement::RenderContextsExternal(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter)
+nsHTMLCanvasElement::RenderContextsExternal(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter, PRUint32 aFlags)
 {
   if (!mCurrentContext)
     return NS_OK;
 
-  return mCurrentContext->Render(aContext, aFilter);
+  return mCurrentContext->Render(aContext, aFilter, aFlags);
 }
 
 nsresult NS_NewCanvasRenderingContext2DThebes(nsIDOMCanvasRenderingContext2D** aResult);
 nsresult NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult);
 
 nsresult
 NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult)
 {
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -850,16 +850,20 @@ nsHTMLInputElement::AfterSetAttr(PRInt32
       UpdateTooLongValidityState();
     } else if (aName == nsGkAtoms::pattern) {
       UpdatePatternMismatchValidityState();
     } else if (aName == nsGkAtoms::multiple) {
       UpdateTypeMismatchValidityState();
     }
 
     UpdateEditableState(aNotify);
+    nsTextEditorState *state = GetEditorState();
+    if (state) {
+      state->UpdateEditableState(aNotify);
+    }
     UpdateState(aNotify);
   }
 
   return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName,
                                                 aValue, aNotify);
 }
 
 // nsIDOMHTMLInputElement
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -1288,16 +1288,17 @@ nsHTMLTextAreaElement::AfterSetAttr(PRIn
         UpdateBarredFromConstraintValidation();
       }
     } else if (aName == nsGkAtoms::maxlength) {
       UpdateTooLongValidityState();
     }
 
     if (aName == nsGkAtoms::readonly) {
       UpdateEditableState(aNotify);
+      mState->UpdateEditableState(aNotify);
     }
     UpdateState(aNotify);
   }
 
   return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName, aValue,
                                                 aNotify);
 }
 
--- a/content/html/content/src/nsTextEditorState.h
+++ b/content/html/content/src/nsTextEditorState.h
@@ -39,16 +39,17 @@
 #ifndef nsTextEditorState_h__
 #define nsTextEditorState_h__
 
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "nsITextControlElement.h"
 #include "nsITextControlFrame.h"
 #include "nsCycleCollectionParticipant.h"
+#include "nsIContent.h"
 
 class nsTextInputListener;
 class nsTextControlFrame;
 class nsTextInputSelectionImpl;
 class nsAnonDivObserver;
 class nsISelectionController;
 class nsFrameSelection;
 class nsIEditor;
@@ -233,16 +234,22 @@ public:
 
   bool IsSelectionCached() const { return mSelectionCached; }
   SelectionProperties& GetSelectionProperties() {
     return mSelectionProperties;
   }
   void WillInitEagerly() { mSelectionRestoreEagerInit = true; }
   bool HasNeverInitializedBefore() const { return !mEverInited; }
 
+  void UpdateEditableState(bool aNotify) {
+    if (mRootNode) {
+      mRootNode->UpdateEditableState(aNotify);
+    }
+  }
+
 private:
   friend class RestoreSelectionState;
 
   // not copy constructible
   nsTextEditorState(const nsTextEditorState&);
   // not assignable
   void operator= (const nsTextEditorState&);
 
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -288,16 +288,17 @@ include $(topsrcdir)/config/rules.mk
 		file_fullscreen-plugins.html \
 		file_fullscreen-denied.html \
 		file_fullscreen-denied-inner.html \
 		file_fullscreen-hidden.html \
 		file_fullscreen-navigation.html \
 		file_fullscreen-esc-exit.html \
 		file_fullscreen-esc-exit-inner.html \
 		file_fullscreen-rollback.html \
+		file_fullscreen-svg-element.html \
 		test_li_attributes_reflection.html \
 		test_ol_attributes_reflection.html \
 		test_bug651956.html \
 		test_bug694503.html \
 		test_object_plugin_nav.html \
 		$(NULL)
 
 _BROWSER_TEST_FILES = \
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_fullscreen-svg-element.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+  <!--
+  https://bugzilla.mozilla.org/show_bug.cgi?id=735031
+  Bug 735031 - Fullscreen API implementation assumes an HTML Element
+  -->
+  <head>
+    <title>Bug 735031</title>
+    <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
+    </script>
+    <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js">
+    </script>
+    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  </head>
+  <body>
+    <a target="_blank"
+       href="https://bugzilla.mozilla.org/show_bug.cgi?id=73503">
+      Mozilla Bug 735031</a>
+
+    <svg width="100" height="100" viewbox="0 0 100 100">
+        <rect id="svg-elem" x="10" y="10" width="50" height="50"
+        fill="black" stroke="blue" stroke-width="2"/>
+    </svg>
+
+    <pre id="test">
+      <script type="application/javascript">
+        /*
+         * Test for Bug 735031
+         * Test locking non-html element.
+         */
+        function begin() {
+          var elem = document.getElementById("svg-elem")
+            , elemWasLocked = false;
+
+          document.addEventListener("mozfullscreenchange", function (e) {
+            if (document.mozFullScreenElement === elem) {
+              elemWasLocked = true;
+              document.mozCancelFullScreen();
+            } else {
+              opener.ok(elemWasLocked, "Expected SVG elem to become locked.");
+              opener.nextTest();
+            }
+          }, false);
+          elem.mozRequestFullScreen();
+        }
+      </script>
+    </pre>
+  </body>
+</html>
--- a/content/html/content/test/test_fullscreen-api.html
+++ b/content/html/content/test/test_fullscreen-api.html
@@ -36,16 +36,17 @@ SpecialPowers.setBoolPref("full-screen-a
 var gTestWindows = [
   "file_fullscreen-rollback.html",
   "file_fullscreen-esc-exit.html",
   "file_fullscreen-denied.html",
   "file_fullscreen-api.html",
   "file_fullscreen-api-keys.html",
   "file_fullscreen-plugins.html",
   "file_fullscreen-hidden.html",
+  "file_fullscreen-svg-element.html",
   "file_fullscreen-navigation.html"
 ];
 
 var testWindow = null;
 var gTestIndex = 0;
 
 const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
 const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -2676,32 +2676,32 @@ nsHTMLDocument::EditingStateChanged()
     nsCOMPtr<nsIURI> uri;
     rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_STRING("resource://gre/res/contenteditable.css"));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsRefPtr<nsCSSStyleSheet> sheet;
     rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet));
     NS_ENSURE_TRUE(sheet, rv);
 
-    rv = agentSheets.AppendObject(sheet);
-    NS_ENSURE_SUCCESS(rv, rv);
+    bool result = agentSheets.AppendObject(sheet);
+    NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
 
     // Should we update the editable state of all the nodes in the document? We
     // need to do this when the designMode value changes, as that overrides
     // specific states on the elements.
     if (designMode) {
       // designMode is being turned on (overrides contentEditable).
       rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_STRING("resource://gre/res/designmode.css"));
       NS_ENSURE_SUCCESS(rv, rv);
 
       rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet));
       NS_ENSURE_TRUE(sheet, rv);
 
-      rv = agentSheets.AppendObject(sheet);
-      NS_ENSURE_SUCCESS(rv, rv);
+      result = agentSheets.AppendObject(sheet);
+      NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
 
       // Disable scripting and plugins.
       rv = editSession->DisableJSAndPlugins(window);
       NS_ENSURE_SUCCESS(rv, rv);
 
       updateState = true;
       spellRecheckAll = oldState == eContentEditable;
     }
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -73,18 +73,18 @@ class nsXBLDocGlobalObject : public nsIS
 {
 public:
   nsXBLDocGlobalObject(nsIScriptGlobalObjectOwner *aGlobalObjectOwner);
 
   // nsISupports interface
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   
   // nsIScriptGlobalObject methods
-  virtual nsresult EnsureScriptEnvironment(PRUint32 aLangID);
-  virtual nsresult SetScriptContext(PRUint32 lang_id, nsIScriptContext *aContext);
+  virtual nsresult EnsureScriptEnvironment();
+  virtual nsresult SetScriptContext(nsIScriptContext *aContext);
 
   virtual nsIScriptContext *GetContext();
   virtual JSObject *GetGlobalJSObject();
   virtual void OnFinalize(JSObject* aObject);
   virtual void SetScriptsEnabled(bool aEnabled, bool aFireTimeouts);
 
   // nsIScriptObjectPrincipal methods
   virtual nsIPrincipal* GetPrincipal();
@@ -98,20 +98,20 @@ public:
   void ClearGlobalObjectOwner();
 
   void UnmarkScriptContext();
 
 protected:
   virtual ~nsXBLDocGlobalObject();
 
   void SetContext(nsIScriptContext *aContext);
-  nsIScriptContext *GetScriptContext(PRUint32 language);
+  nsIScriptContext *GetScriptContext();
 
   nsCOMPtr<nsIScriptContext> mScriptContext;
-  JSObject *mJSObject;    // XXX JS language rabies bigotry badness
+  JSObject *mJSObject;
 
   nsIScriptGlobalObjectOwner* mGlobalObjectOwner; // weak reference
   static JSClass gSharedGlobalClass;
 };
 
 JSBool
 nsXBLDocGlobalObject::doCheckAccess(JSContext *cx, JSObject *obj, jsid id, PRUint32 accessType)
 {
@@ -277,50 +277,44 @@ nsXBLDocGlobalObject::SetContext(nsIScri
   NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Script Language's InitContext failed");
   aScriptContext->SetGCOnDestruction(false);
   aScriptContext->DidInitializeContext();
   // and we set up our global manually
   mScriptContext = aScriptContext;
 }
 
 nsresult
-nsXBLDocGlobalObject::SetScriptContext(PRUint32 lang_id, nsIScriptContext *aContext)
+nsXBLDocGlobalObject::SetScriptContext(nsIScriptContext *aContext)
 {
-  NS_ASSERTION(lang_id == nsIProgrammingLanguage::JAVASCRIPT, "Only JS allowed!");
   SetContext(aContext);
   return NS_OK;
 }
 
 nsIScriptContext *
-nsXBLDocGlobalObject::GetScriptContext(PRUint32 language)
+nsXBLDocGlobalObject::GetScriptContext()
 {
-  // This impl still assumes JS
-  NS_ENSURE_TRUE(language==nsIProgrammingLanguage::JAVASCRIPT, nsnull);
   return GetContext();
 }
 
 nsresult
-nsXBLDocGlobalObject::EnsureScriptEnvironment(PRUint32 aLangID)
+nsXBLDocGlobalObject::EnsureScriptEnvironment()
 {
-  if (aLangID != nsIProgrammingLanguage::JAVASCRIPT) {
-    NS_WARNING("XBL still JS only");
-    return NS_ERROR_INVALID_ARG;
-  }
   if (mScriptContext)
     return NS_OK; // already initialized for this lang
   nsCOMPtr<nsIDOMScriptObjectFactory> factory = do_GetService(kDOMScriptObjectFactoryCID);
   NS_ENSURE_TRUE(factory, NS_OK);
 
   nsresult rv;
 
   nsCOMPtr<nsIScriptRuntime> scriptRuntime;
-  rv = NS_GetScriptRuntimeByID(aLangID, getter_AddRefs(scriptRuntime));
+  rv = NS_GetScriptRuntimeByID(nsIProgrammingLanguage::JAVASCRIPT,
+                               getter_AddRefs(scriptRuntime));
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIScriptContext> newCtx = scriptRuntime->CreateContext();
-  rv = SetScriptContext(aLangID, newCtx);
+  rv = SetScriptContext(newCtx);
 
   JSContext *cx = mScriptContext->GetNativeContext();
   JSAutoRequest ar(cx);
 
   // nsJSEnvironment set the error reporter to NS_ScriptErrorReporter so
   // we must apparently override that with our own (although it isn't clear 
   // why - see bug 339647)
   JS_SetErrorReporter(cx, XBL_ProtoErrorReporter);
@@ -342,17 +336,17 @@ nsXBLDocGlobalObject::EnsureScriptEnviro
 }
 
 nsIScriptContext *
 nsXBLDocGlobalObject::GetContext()
 {
   // This whole fragile mess is predicated on the fact that
   // GetContext() will be called before GetScriptObject() is.
   if (! mScriptContext) {
-    nsresult rv = EnsureScriptEnvironment(nsIProgrammingLanguage::JAVASCRIPT);
+    nsresult rv = EnsureScriptEnvironment();
     // JS is builtin so we make noise if it fails to initialize.
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to setup JS!?");
     NS_ENSURE_SUCCESS(rv, nsnull);
     NS_ASSERTION(mScriptContext, "Failed to find a script context!?");
   }
   return mScriptContext;
 }
 
@@ -558,17 +552,17 @@ nsXBLDocumentInfo::nsXBLDocumentInfo(nsI
   }
 }
 
 nsXBLDocumentInfo::~nsXBLDocumentInfo()
 {
   /* destructor code */
   if (mGlobalObject) {
     // remove circular reference
-    mGlobalObject->SetScriptContext(nsIProgrammingLanguage::JAVASCRIPT, nsnull);
+    mGlobalObject->SetScriptContext(nsnull);
     mGlobalObject->ClearGlobalObjectOwner(); // just in case
   }
   if (mBindingTable) {
     NS_DROP_JS_OBJECTS(this, nsXBLDocumentInfo);
     delete mBindingTable;
   }
 }
 
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -296,18 +296,17 @@ nsXBLPrototypeHandler::ExecuteHandler(ns
     }
 
     boundGlobal = boundDocument->GetScopeObject();
   }
 
   if (!boundGlobal)
     return NS_OK;
 
-  nsIScriptContext *boundContext =
-    boundGlobal->GetScriptContext(nsIProgrammingLanguage::JAVASCRIPT);
+  nsIScriptContext *boundContext = boundGlobal->GetScriptContext();
   if (!boundContext)
     return NS_OK;
 
   nsScriptObjectHolder<JSObject> handler(boundContext);
   nsISupports *scriptTarget;
 
   if (winRoot) {
     scriptTarget = boundGlobal;
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -766,17 +766,17 @@ nsScriptEventHandlerOwnerTearoff::Compil
         nsCOMPtr<nsIScriptGlobalObjectOwner> globalOwner;
         rv = xuldoc->GetScriptGlobalObjectOwner(getter_AddRefs(globalOwner));
         NS_ENSURE_SUCCESS(rv, rv);
         NS_ENSURE_TRUE(globalOwner, NS_ERROR_UNEXPECTED);
 
         nsIScriptGlobalObject* global = globalOwner->GetScriptGlobalObject();
         NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED);
 
-        context = global->GetScriptContext(aContext->GetScriptTypeID());
+        context = global->GetScriptContext();
         // It could be possible the language has been setup on aContext but
         // not on the global - we don't demand-create language contexts on the
         // nsGlobalWindow
         NS_ASSERTION(context,
                      "Failed to get a language context from the global!?");
         NS_ENSURE_TRUE(context, NS_ERROR_UNEXPECTED);
     }
     else {
@@ -2938,18 +2938,17 @@ nsXULPrototypeScript::~nsXULPrototypeScr
     UnlinkJSObjects();
 }
 
 nsresult
 nsXULPrototypeScript::Serialize(nsIObjectOutputStream* aStream,
                                 nsIScriptGlobalObject* aGlobal,
                                 const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
-    nsIScriptContext *context = aGlobal->GetScriptContext(
-                                        mScriptObject.mLangID);
+    nsIScriptContext *context = aGlobal->GetScriptContext();
     NS_ASSERTION(!mSrcLoading || mSrcLoadWaiters != nsnull ||
                  !mScriptObject.mObject,
                  "script source still loading when serializing?!");
     if (!mScriptObject.mObject)
         return NS_ERROR_FAILURE;
 
     // Write basic prototype data
     nsresult rv;
@@ -3017,18 +3016,17 @@ nsXULPrototypeScript::Deserialize(nsIObj
     NS_ASSERTION(!mSrcLoading || mSrcLoadWaiters != nsnull ||
                  !mScriptObject.mObject,
                  "prototype script not well-initialized when deserializing?!");
 
     // Read basic prototype data
     aStream->Read32(&mLineNo);
     aStream->Read32(&mLangVersion);
 
-    nsIScriptContext *context = aGlobal->GetScriptContext(
-                                            mScriptObject.mLangID);
+    nsIScriptContext *context = aGlobal->GetScriptContext();
     NS_ASSERTION(context != nsnull, "Have no context for deserialization");
     NS_ENSURE_TRUE(context, NS_ERROR_UNEXPECTED);
     nsScriptObjectHolder<JSScript> newScriptObject(context);
     rv = context->Deserialize(aStream, newScriptObject);
     if (NS_FAILED(rv)) {
         NS_WARNING("Language deseralization failed");
         return rv;
     }
@@ -3146,17 +3144,17 @@ nsXULPrototypeScript::Compile(const PRUn
     nsIScriptContext *context;
 
     {
         nsIScriptGlobalObject* global = aGlobalOwner->GetScriptGlobalObject();
         NS_ASSERTION(global != nsnull, "prototype doc has no script global");
         if (! global)
             return NS_ERROR_UNEXPECTED;
 
-        context = global->GetScriptContext(mScriptObject.mLangID);
+        context = global->GetScriptContext();
         NS_ASSERTION(context != nsnull, "no context for script global");
         if (! context)
             return NS_ERROR_UNEXPECTED;
     }
 
     nsCAutoString urlspec;
     nsContentUtils::GetWrapperSafeScriptFilename(aDocument, aURI, urlspec);
 
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -3548,19 +3548,18 @@ nsXULDocument::OnStreamComplete(nsIStrea
                 // Ignore the return value, as we don't need to propagate
                 // a failure to write to the FastLoad file, because this
                 // method aborts that whole process on error.
                 nsIScriptGlobalObject* global =
                     mCurrentPrototype->GetScriptGlobalObject();
 
                 NS_ASSERTION(global != nsnull, "master prototype w/o global?!");
                 if (global) {
-                    PRUint32 stid = scriptProto->mScriptObject.mLangID;
                     nsIScriptContext *scriptContext = \
-                          global->GetScriptContext(stid);
+                          global->GetScriptContext();
                     NS_ASSERTION(scriptContext != nsnull,
                                  "Failed to get script context for language");
                     if (scriptContext)
                         scriptProto->SerializeOutOfLine(nsnull, global);
                 }
             }
         }
         // ignore any evaluation errors
@@ -3614,24 +3613,23 @@ nsXULDocument::ExecuteScript(nsIScriptCo
 }
 
 nsresult
 nsXULDocument::ExecuteScript(nsXULPrototypeScript *aScript)
 {
     NS_PRECONDITION(aScript != nsnull, "null ptr");
     NS_ENSURE_TRUE(aScript, NS_ERROR_NULL_POINTER);
     NS_ENSURE_TRUE(mScriptGlobalObject, NS_ERROR_NOT_INITIALIZED);
-    PRUint32 stid = aScript->mScriptObject.mLangID;
 
     nsresult rv;
-    rv = mScriptGlobalObject->EnsureScriptEnvironment(stid);
+    rv = mScriptGlobalObject->EnsureScriptEnvironment();
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIScriptContext> context =
-      mScriptGlobalObject->GetScriptContext(stid);
+      mScriptGlobalObject->GetScriptContext();
     // failure getting a script context is fatal.
     NS_ENSURE_TRUE(context != nsnull, NS_ERROR_UNEXPECTED);
 
     if (aScript->mScriptObject.mObject)
         rv = ExecuteScript(context, aScript->mScriptObject.mObject);
     else
         rv = NS_ERROR_UNEXPECTED;
     return rv;
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -80,20 +80,20 @@ public:
     // nsISupports interface
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
     // nsIScriptGlobalObject methods
     virtual void OnFinalize(JSObject* aObject);
     virtual void SetScriptsEnabled(bool aEnabled, bool aFireTimeouts);
 
     virtual JSObject* GetGlobalJSObject();
-    virtual nsresult EnsureScriptEnvironment(PRUint32 aLangID);
+    virtual nsresult EnsureScriptEnvironment();
 
-    virtual nsIScriptContext *GetScriptContext(PRUint32 lang);
-    virtual nsresult SetScriptContext(PRUint32 language, nsIScriptContext *ctx);
+    virtual nsIScriptContext *GetScriptContext();
+    virtual nsresult SetScriptContext(nsIScriptContext *ctx);
 
     // nsIScriptObjectPrincipal methods
     virtual nsIPrincipal* GetPrincipal();
 
     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULPDGlobalObject,
                                              nsIScriptGlobalObject)
 
     void ClearGlobalObjectOwner();
@@ -678,20 +678,18 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULPDG
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULPDGlobalObject)
 
 //----------------------------------------------------------------------
 //
 // nsIScriptGlobalObject methods
 //
 
 nsresult
-nsXULPDGlobalObject::SetScriptContext(PRUint32 lang_id, nsIScriptContext *aScriptContext)
+nsXULPDGlobalObject::SetScriptContext(nsIScriptContext *aScriptContext)
 {
-  NS_ABORT_IF_FALSE(lang_id == nsIProgrammingLanguage::JAVASCRIPT,
-                    "We don't support this language ID");
   // almost a clone of nsGlobalWindow
   if (!aScriptContext) {
     NS_WARNING("Possibly early removal of script object, see bug #41608");
   } else {
     // should probably assert the context is clean???
     aScriptContext->WillInitializeContext();
     nsresult rv = aScriptContext->InitContext();
     NS_ENSURE_SUCCESS(rv, rv);
@@ -708,20 +706,18 @@ nsXULPDGlobalObject::SetScriptContext(PR
     NS_ASSERTION(global, "GetNativeGlobal returned NULL!");
   }
   mContext = aScriptContext;
   mJSObject = global;
   return NS_OK;
 }
 
 nsresult
-nsXULPDGlobalObject::EnsureScriptEnvironment(PRUint32 lang_id)
+nsXULPDGlobalObject::EnsureScriptEnvironment()
 {
-  NS_ABORT_IF_FALSE(lang_id == nsIProgrammingLanguage::JAVASCRIPT,
-                    "We don't support this language ID");
   if (mContext) {
     return NS_OK;
   }
   NS_ASSERTION(!mJSObject, "Have global without context?");
 
   nsCOMPtr<nsIScriptRuntime> languageRuntime;
   nsresult rv = NS_GetScriptRuntimeByID(nsIProgrammingLanguage::JAVASCRIPT,
                                         getter_AddRefs(languageRuntime));
@@ -747,33 +743,31 @@ nsXULPDGlobalObject::EnsureScriptEnviron
 
     // Add an owning reference from JS back to us. This'll be
     // released when the JSObject is finalized.
     ::JS_SetPrivate(newGlob, this);
     NS_ADDREF(this);
   }
 
   NS_ENSURE_SUCCESS(rv, NS_OK);
-  rv = SetScriptContext(lang_id, ctxNew);
+  rv = SetScriptContext(ctxNew);
   NS_ENSURE_SUCCESS(rv, NS_OK);
   return NS_OK;
 }
 
 nsIScriptContext*
-nsXULPDGlobalObject::GetScriptContext(PRUint32 lang_id)
+nsXULPDGlobalObject::GetScriptContext()
 {
-  NS_ABORT_IF_FALSE(lang_id == nsIProgrammingLanguage::JAVASCRIPT,
-                    "We don't support this language ID");
   // This global object creates a context on demand - do that now.
-  nsresult rv = EnsureScriptEnvironment(nsIProgrammingLanguage::JAVASCRIPT);
+  nsresult rv = EnsureScriptEnvironment();
   if (NS_FAILED(rv)) {
     NS_ERROR("Failed to setup script language");
     return NULL;
   }
-  // Note that EnsureScriptEnvironment has validated lang_id
+
   return mContext;
 }
 
 JSObject*
 nsXULPDGlobalObject::GetGlobalJSObject()
 {
   return mJSObject;
 }
--- a/db/sqlite3/README.MOZILLA
+++ b/db/sqlite3/README.MOZILLA
@@ -1,11 +1,11 @@
-This is sqlite 3.7.10
+This is sqlite 3.7.11
 
--- Ryan VanderMeulen <ryanvm@gmail.com>, 01/2012
+-- Ryan VanderMeulen <ryanvm@gmail.com>, 03/2012
 
 See http://www.sqlite.org/ for more info.
 
 We have a mozilla-specific Makefile.in in src/ (normally no
 Makefile.in there) that we use to build.
 
 To move to a new version:
 
--- a/db/sqlite3/src/Makefile.in
+++ b/db/sqlite3/src/Makefile.in
@@ -150,17 +150,20 @@ ifeq ($(OS_TARGET),Android)
 # default to user readable only to fit Android security model
 DEFINES += -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600
 endif
 
 # Force using malloc_usable_size when building with jemalloc because _msize
 # causes assertions on Win64. See bug 719579.
 ifeq ($(OS_ARCH),WINNT)
 ifdef MOZ_MEMORY
-DEFINES += -DHAVE_MALLOC_USABLE_SIZE
+DEFINES += \
+  -DHAVE_MALLOC_USABLE_SIZE \
+  -DSQLITE_WITHOUT_MSIZE \
+  $(NULL)
 endif
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 # next line allows use of MOZ_OBJDIR in .mozconfig with older gcc on BeOS, maybe others
 LOCAL_INCLUDES += -I$(srcdir)
 
--- a/db/sqlite3/src/sqlite3.c
+++ b/db/sqlite3/src/sqlite3.c
@@ -1,11 +1,11 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.7.10.  By combining all the individual C code files into this 
+** version 3.7.11.  By combining all the individual C code files into this 
 ** single large file, the entire code can be compiled as a single translation
 ** unit.  This allows many compilers to do optimizations that would not be
 ** possible if the files were compiled separately.  Performance improvements
 ** of 5% or more are commonly seen when SQLite is compiled as a single
 ** translation unit.
 **
 ** This file is all you need to compile SQLite.  To use SQLite in other
 ** programs, you need this file and the "sqlite3.h" header file that defines
@@ -652,19 +652,19 @@ extern "C" {
 ** within its configuration management system.  ^The SQLITE_SOURCE_ID
 ** string contains the date and time of the check-in (UTC) and an SHA1
 ** hash of the entire source tree.
 **
 ** See also: [sqlite3_libversion()],
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.7.10"
-#define SQLITE_VERSION_NUMBER 3007010
-#define SQLITE_SOURCE_ID      "2012-01-16 13:28:40 ebd01a8deffb5024a5d7494eef800d2366d97204"
+#define SQLITE_VERSION        "3.7.11"
+#define SQLITE_VERSION_NUMBER 3007011
+#define SQLITE_SOURCE_ID      "2012-03-20 11:35:50 00bb9c9ce4f465e6ac321ced2a9d0062dc364669"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
 **
 ** These interfaces provide the same information as the [SQLITE_VERSION],
 ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
 ** but are associated with the library instead of the header file.  ^(Cautious
@@ -1006,16 +1006,17 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
 #define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
 #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
 #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
 #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
 #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
 #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
 #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
+#define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
 
 /*
 ** CAPI3REF: Flags For File Open Operations
 **
 ** These bit values are intended for use in the
 ** 3rd parameter to the [sqlite3_open_v2()] interface and
 ** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
 */
@@ -1261,115 +1262,149 @@ struct sqlite3_io_methods {
 **
 ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging.  This
 ** opcode causes the xFileControl method to write the current state of
 ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
 ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
 ** into an integer that the pArg argument points to. This capability
 ** is used during testing and only needs to be supported when SQLITE_TEST
 ** is defined.
-**
+** <ul>
+** <li>[[SQLITE_FCNTL_SIZE_HINT]]
 ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
 ** layer a hint of how large the database file will grow to be during the
 ** current transaction.  This hint is not guaranteed to be accurate but it
 ** is often close.  The underlying VFS might choose to preallocate database
 ** file space based on this hint in order to help writes to the database
 ** file run faster.
 **
+** <li>[[SQLITE_FCNTL_CHUNK_SIZE]]
 ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
 ** extends and truncates the database file in chunks of a size specified
 ** by the user. The fourth argument to [sqlite3_file_control()] should 
 ** point to an integer (type int) containing the new chunk-size to use
 ** for the nominated database. Allocating database file space in large
 ** chunks (say 1MB at a time), may reduce file-system fragmentation and
 ** improve performance on some systems.
 **
+** <li>[[SQLITE_FCNTL_FILE_POINTER]]
 ** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
 ** to the [sqlite3_file] object associated with a particular database
 ** connection.  See the [sqlite3_file_control()] documentation for
 ** additional information.
 **
+** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
 ** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by
 ** SQLite and sent to all VFSes in place of a call to the xSync method
 ** when the database connection has [PRAGMA synchronous] set to OFF.)^
 ** Some specialized VFSes need this signal in order to operate correctly
 ** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most 
 ** VFSes do not need this signal and should silently ignore this opcode.
 ** Applications should not call [sqlite3_file_control()] with this
 ** opcode as doing so may disrupt the operation of the specialized VFSes
 ** that do require it.  
 **
+** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]]
 ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
 ** retry counts and intervals for certain disk I/O operations for the
 ** windows [VFS] in order to provide robustness in the presence of
 ** anti-virus programs.  By default, the windows VFS will retry file read,
 ** file write, and file delete operations up to 10 times, with a delay
 ** of 25 milliseconds before the first retry and with the delay increasing
 ** by an additional 25 milliseconds with each subsequent retry.  This
 ** opcode allows these two values (10 retries and 25 milliseconds of delay)
 ** to be adjusted.  The values are changed for all database connections
 ** within the same process.  The argument is a pointer to an array of two
 ** integers where the first integer i the new retry count and the second
 ** integer is the delay.  If either integer is negative, then the setting
 ** is not changed but instead the prior value of that setting is written
 ** into the array entry, allowing the current retry settings to be
 ** interrogated.  The zDbName parameter is ignored.
 **
+** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
 ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
 ** persistent [WAL | Write AHead Log] setting.  By default, the auxiliary
 ** write ahead log and shared memory files used for transaction control
 ** are automatically deleted when the latest connection to the database
 ** closes.  Setting persistent WAL mode causes those files to persist after
 ** close.  Persisting the files is useful when other processes that do not
 ** have write permission on the directory containing the database file want
 ** to read the database file, as the WAL and shared memory files must exist
 ** in order for the database to be readable.  The fourth parameter to
 ** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
 ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
 ** WAL mode.  If the integer is -1, then it is overwritten with the current
 ** WAL persistence setting.
 **
+** <li>[[SQLITE_FCNTL_POWERSAFE_OVERWRITE]]
 ** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the
 ** persistent "powersafe-overwrite" or "PSOW" setting.  The PSOW setting
 ** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the
 ** xDeviceCharacteristics methods. The fourth parameter to
 ** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
 ** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage
 ** mode.  If the integer is -1, then it is overwritten with the current
 ** zero-damage mode setting.
 **
+** <li>[[SQLITE_FCNTL_OVERWRITE]]
 ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
 ** a write transaction to indicate that, unless it is rolled back for some
 ** reason, the entire database file will be overwritten by the current 
 ** transaction. This is used by VACUUM operations.
 **
+** <li>[[SQLITE_FCNTL_VFSNAME]]
 ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of
 ** all [VFSes] in the VFS stack.  The names are of all VFS shims and the
 ** final bottom-level VFS are written into memory obtained from 
 ** [sqlite3_malloc()] and the result is stored in the char* variable
 ** that the fourth parameter of [sqlite3_file_control()] points to.
 ** The caller is responsible for freeing the memory when done.  As with
 ** all file-control actions, there is no guarantee that this will actually
 ** do anything.  Callers should initialize the char* variable to a NULL
 ** pointer in case this file-control is not implemented.  This file-control
 ** is intended for diagnostic use only.
+**
+** <li>[[SQLITE_FCNTL_PRAGMA]]
+** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] 
+** file control is sent to the open [sqlite3_file] object corresponding
+** to the database file to which the pragma statement refers. ^The argument
+** to the [SQLITE_FCNTL_PRAGMA] file control is an array of
+** pointers to strings (char**) in which the second element of the array
+** is the name of the pragma and the third element is the argument to the
+** pragma or NULL if the pragma has no argument.  ^The handler for an
+** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element
+** of the char** argument point to a string obtained from [sqlite3_mprintf()]
+** or the equivalent and that string will become the result of the pragma or
+** the error message if the pragma fails. ^If the
+** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal 
+** [PRAGMA] processing continues.  ^If the [SQLITE_FCNTL_PRAGMA]
+** file control returns [SQLITE_OK], then the parser assumes that the
+** VFS has handled the PRAGMA itself and the parser generates a no-op
+** prepared statement.  ^If the [SQLITE_FCNTL_PRAGMA] file control returns
+** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
+** that the VFS encountered an error while handling the [PRAGMA] and the
+** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
+** file control occurs at the beginning of pragma statement analysis and so
+** it is able to override built-in [PRAGMA] statements.
+** </ul>
 */
 #define SQLITE_FCNTL_LOCKSTATE               1
 #define SQLITE_GET_LOCKPROXYFILE             2
 #define SQLITE_SET_LOCKPROXYFILE             3
 #define SQLITE_LAST_ERRNO                    4
 #define SQLITE_FCNTL_SIZE_HINT               5
 #define SQLITE_FCNTL_CHUNK_SIZE              6
 #define SQLITE_FCNTL_FILE_POINTER            7
 #define SQLITE_FCNTL_SYNC_OMITTED            8
 #define SQLITE_FCNTL_WIN32_AV_RETRY          9
 #define SQLITE_FCNTL_PERSIST_WAL            10
 #define SQLITE_FCNTL_OVERWRITE              11
 #define SQLITE_FCNTL_VFSNAME                12
 #define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
+#define SQLITE_FCNTL_PRAGMA                 14
 
 /*
 ** CAPI3REF: Mutex Handle
 **
 ** The mutex module within SQLite defines [sqlite3_mutex] to be an
 ** abstract type for a mutex object.  The SQLite core never looks
 ** at the internal representation of an [sqlite3_mutex].  It only
 ** deals with pointers to the [sqlite3_mutex] object.
@@ -3189,19 +3224,24 @@ SQLITE_API int sqlite3_open_v2(
 ** sqlite3_uri_parameter(F,P) returns the value of the P
 ** parameter if it exists or a NULL pointer if P does not appear as a 
 ** query parameter on F.  If P is a query parameter of F
 ** has no explicit value, then sqlite3_uri_parameter(F,P) returns
 ** a pointer to an empty string.
 **
 ** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean
 ** parameter and returns true (1) or false (0) according to the value
-** of P.  The value of P is true if it is "yes" or "true" or "on" or 
-** a non-zero number and is false otherwise.  If P is not a query parameter
-** on F then sqlite3_uri_boolean(F,P,B) returns (B!=0).
+** of P.  The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the
+** value of query parameter P is one of "yes", "true", or "on" in any
+** case or if the value begins with a non-zero number.  The 
+** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of
+** query parameter P is one of "no", "false", or "off" in any case or
+** if the value begins with a numeric zero.  If P is not a query
+** parameter on F or if the value of P is does not match any of the
+** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0).
 **
 ** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
 ** 64-bit signed integer and returns that integer, or D if P does not
 ** exist.  If the value of P is something other than an integer, then
 ** zero is returned.
 ** 
 ** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
 ** sqlite3_uri_boolean(F,P,B) returns B.  If F is not a NULL pointer and
@@ -5005,16 +5045,25 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sq
 ** ^The filename returned by this function is the output of the
 ** xFullPathname method of the [VFS].  ^In other words, the filename
 ** will be an absolute pathname, even if the filename used
 ** to open the database originally was a URI or relative pathname.
 */
 SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
 
 /*
+** CAPI3REF: Determine if a database is read-only
+**
+** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
+** of connection D is read-only, 0 if it is read/write, or -1 if N is not
+** the name of a database on connection D.
+*/
+SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+
+/*
 ** CAPI3REF: Find the next prepared statement
 **
 ** ^This interface returns a pointer to the next [prepared statement] after
 ** pStmt associated with the [database connection] pDb.  ^If pStmt is NULL
 ** then this interface returns a pointer to the first prepared statement
 ** associated with the database connection pDb.  ^If no prepared statement
 ** satisfies the conditions of this routine, it returns NULL.
 **
@@ -7129,21 +7178,22 @@ SQLITE_API int sqlite3_unlock_notify(
   void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
   void *pNotifyArg                            /* Argument to pass to xNotify */
 );
 
 
 /*
 ** CAPI3REF: String Comparison
 **
-** ^The [sqlite3_strnicmp()] API allows applications and extensions to
-** compare the contents of two buffers containing UTF-8 strings in a
-** case-independent fashion, using the same definition of case independence 
-** that SQLite uses internally when comparing identifiers.
-*/
+** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications
+** and extensions to compare the contents of two buffers containing UTF-8
+** strings in a case-independent fashion, using the same definition of "case
+** independence" that SQLite uses internally when comparing identifiers.
+*/
+SQLITE_API int sqlite3_stricmp(const char *, const char *);
 SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
 
 /*
 ** CAPI3REF: Error Logging Interface
 **
 ** ^The [sqlite3_log()] interface writes a message into the error log
 ** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()].
 ** ^If logging is enabled, the zFormat string and subsequent arguments are
@@ -8010,19 +8060,23 @@ struct BusyHandler {
 /*
 ** A convenience macro that returns the number of elements in
 ** an array.
 */
 #define ArraySize(X)    ((int)(sizeof(X)/sizeof(X[0])))
 
 /*
 ** The following value as a destructor means to use sqlite3DbFree().
-** This is an internal extension to SQLITE_STATIC and SQLITE_TRANSIENT.
-*/
-#define SQLITE_DYNAMIC   ((sqlite3_destructor_type)sqlite3DbFree)
+** The sqlite3DbFree() routine requires two parameters instead of the 
+** one parameter that destructors normally want.  So we have to introduce 
+** this magic value that the code knows to handle differently.  Any 
+** pointer will work here as long as it is distinct from SQLITE_STATIC
+** and SQLITE_TRANSIENT.
+*/
+#define SQLITE_DYNAMIC   ((sqlite3_destructor_type)sqlite3MallocSize)
 
 /*
 ** When SQLITE_OMIT_WSD is defined, it means that the target platform does
 ** not support Writable Static Data (WSD) such as global and static variables.
 ** All variables must either be on the stack or dynamically allocated from
 ** the heap.  When WSD is unsupported, the variable declarations scattered
 ** throughout the SQLite code must become constants instead.  The SQLITE_WSD
 ** macro is used for this purpose.  And instead of referencing the variable
@@ -8172,20 +8226,19 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
 
 /* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
 ** following values.
 **
 ** NOTE:  These values must match the corresponding PAGER_ values in
 ** pager.h.
 */
 #define BTREE_OMIT_JOURNAL  1  /* Do not create or use a rollback journal */
-#define BTREE_NO_READLOCK   2  /* Omit readlocks on readonly files */
-#define BTREE_MEMORY        4  /* This is an in-memory DB */
-#define BTREE_SINGLE        8  /* The file contains at most 1 b-tree */
-#define BTREE_UNORDERED    16  /* Use of a hash implementation is OK */
+#define BTREE_MEMORY        2  /* This is an in-memory DB */
+#define BTREE_SINGLE        4  /* The file contains at most 1 b-tree */
+#define BTREE_UNORDERED     8  /* Use of a hash implementation is OK */
 
 SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
 SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
 SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
@@ -8193,17 +8246,17 @@ SQLITE_PRIVATE u32 sqlite3BtreeLastPage(
 SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
 SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
 SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
 SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
 SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*);
+SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags);
 SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*);
 SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
 SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree);
 SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
@@ -8848,18 +8901,17 @@ typedef struct PgHdr DbPage;
 #define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
 
 /*
 ** Allowed values for the flags parameter to sqlite3PagerOpen().
 **
 ** NOTE: These values must match the corresponding BTREE_ values in btree.h.
 */
 #define PAGER_OMIT_JOURNAL  0x0001    /* Do not use a rollback journal */
-#define PAGER_NO_READLOCK   0x0002    /* Omit readlocks on readonly files */
-#define PAGER_MEMORY        0x0004    /* In-memory database */
+#define PAGER_MEMORY        0x0002    /* In-memory database */
 
 /*
 ** Valid values for the second argument to sqlite3PagerLockingMode().
 */
 #define PAGER_LOCKINGMODE_QUERY      -1
 #define PAGER_LOCKINGMODE_NORMAL      0
 #define PAGER_LOCKINGMODE_EXCLUSIVE   1
 
@@ -8934,16 +8986,19 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavep
 SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
 SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
 
 SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
 SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
 SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
 SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
 SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager);
+#ifdef SQLITE_ENABLE_ZIPVFS
+SQLITE_PRIVATE   int sqlite3PagerWalFramesize(Pager *pPager);
+#endif
 
 /* Functions used to query pager state and configuration. */
 SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
 SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
 SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
 SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*);
 SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
@@ -9006,18 +9061,18 @@ typedef struct PCache PCache;
 ** Every page in the cache is controlled by an instance of the following
 ** structure.
 */
 struct PgHdr {
   sqlite3_pcache_page *pPage;    /* Pcache object page handle */
   void *pData;                   /* Page data */
   void *pExtra;                  /* Extra content */
   PgHdr *pDirty;                 /* Transient list of dirty pages */
+  Pager *pPager;                 /* The pager this page is part of */
   Pgno pgno;                     /* Page number for this page */
-  Pager *pPager;                 /* The pager this page is part of */
 #ifdef SQLITE_CHECK_PAGES
   u32 pageHash;                  /* Hash of page content */
 #endif
   u16 flags;                     /* PGHDR flags defined below */
 
   /**********************************************************************
   ** Elements above are public.  All that follows is private to pcache.c
   ** and should not be accessed by other modules.
@@ -9235,21 +9290,33 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefa
 # include <uconv.h>
 # define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP)
 #else
 # define SQLITE_TEMPNAME_SIZE 200
 #endif
 
 /*
 ** Determine if we are dealing with Windows NT.
-*/
-#if defined(_WIN32_WINNT)
+**
+** We ought to be able to determine if we are compiling for win98 or winNT
+** using the _WIN32_WINNT macro as follows:
+**
+** #if defined(_WIN32_WINNT)
+** # define SQLITE_OS_WINNT 1
+** #else
+** # define SQLITE_OS_WINNT 0
+** #endif
+**
+** However, vs2005 does not set _WIN32_WINNT by default, as it ought to,
+** so the above test does not work.  We'll just assume that everything is
+** winNT unless the programmer explicitly says otherwise by setting
+** SQLITE_OS_WINNT to 0.
+*/
+#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT)
 # define SQLITE_OS_WINNT 1
-#else
-# define SQLITE_OS_WINNT 0
 #endif
 
 /*
 ** Determine if we are dealing with WindowsCE - which has a much
 ** reduced API.
 */
 #if defined(_WIN32_WCE)
 # define SQLITE_OS_WINCE 1
@@ -9637,76 +9704,53 @@ struct LookasideSlot {
 ** Collisions are on the FuncDef.pHash chain.
 */
 struct FuncDefHash {
   FuncDef *a[23];       /* Hash table for functions */
 };
 
 /*
 ** Each database connection is an instance of the following structure.
-**
-** The sqlite.lastRowid records the last insert rowid generated by an
-** insert statement.  Inserts on views do not affect its value.  Each
-** trigger has its own context, so that lastRowid can be updated inside
-** triggers as usual.  The previous value will be restored once the trigger
-** exits.  Upon entering a before or instead of trigger, lastRowid is no
-** longer (since after version 2.8.12) reset to -1.
-**
-** The sqlite.nChange does not count changes within triggers and keeps no
-** context.  It is reset at start of sqlite3_exec.
-** The sqlite.lsChange represents the number of changes made by the last
-** insert, update, or delete statement.  It remains constant throughout the
-** length of a statement and is then updated by OP_SetCounts.  It keeps a
-** context stack just like lastRowid so that the count of changes
-** within a trigger is not seen outside the trigger.  Changes to views do not
-** affect the value of lsChange.
-** The sqlite.csChange keeps track of the number of current changes (since
-** the last statement) and is used to update sqlite_lsChange.
-**
-** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16
-** store the most recent error code and, if applicable, string. The
-** internal function sqlite3Error() is used to set these variables
-** consistently.
 */
 struct sqlite3 {
   sqlite3_vfs *pVfs;            /* OS Interface */
-  int nDb;                      /* Number of backends currently in use */
+  struct Vdbe *pVdbe;           /* List of active virtual machines */
+  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
+  sqlite3_mutex *mutex;         /* Connection mutex */
   Db *aDb;                      /* All backends */
+  int nDb;                      /* Number of backends currently in use */
   int flags;                    /* Miscellaneous flags. See below */
+  i64 lastRowid;                /* ROWID of most recent insert (see above) */
   unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
   int errCode;                  /* Most recent error code (SQLITE_*) */
   int errMask;                  /* & result codes with this before returning */
   u8 autoCommit;                /* The auto-commit flag. */
   u8 temp_store;                /* 1: file 2: memory 0: default */
   u8 mallocFailed;              /* True if we have seen a malloc failure */
   u8 dfltLockMode;              /* Default locking-mode for attached dbs */
   signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
   u8 suppressErr;               /* Do not issue error messages if true */
   u8 vtabOnConflict;            /* Value to return for s3_vtab_on_conflict() */
+  u8 isTransactionSavepoint;    /* True if the outermost savepoint is a TS */
   int nextPagesize;             /* Pagesize after VACUUM if >0 */
-  int nTable;                   /* Number of tables in the database */
-  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
-  i64 lastRowid;                /* ROWID of most recent insert (see above) */
   u32 magic;                    /* Magic number for detect library misuse */
   int nChange;                  /* Value returned by sqlite3_changes() */
   int nTotalChange;             /* Value returned by sqlite3_total_changes() */
-  sqlite3_mutex *mutex;         /* Connection mutex */
   int aLimit[SQLITE_N_LIMIT];   /* Limits */
   struct sqlite3InitInfo {      /* Information used during initialization */
-    int iDb;                    /* When back is being initialized */
     int newTnum;                /* Rootpage of table being initialized */
+    u8 iDb;                     /* Which db file is being initialized */
     u8 busy;                    /* TRUE if currently initializing */
     u8 orphanTrigger;           /* Last statement is orphaned TEMP trigger */
   } init;
-  int nExtension;               /* Number of loaded extensions */
-  void **aExtension;            /* Array of shared library handles */
-  struct Vdbe *pVdbe;           /* List of active virtual machines */
   int activeVdbeCnt;            /* Number of VDBEs currently executing */
   int writeVdbeCnt;             /* Number of active VDBEs that are writing */
   int vdbeExecCnt;              /* Number of nested calls to VdbeExec() */
+  int nExtension;               /* Number of loaded extensions */
+  void **aExtension;            /* Array of shared library handles */
   void (*xTrace)(void*,const char*);        /* Trace function */
   void *pTraceArg;                          /* Argument to the trace function */
   void (*xProfile)(void*,const char*,u64);  /* Profiling function */
   void *pProfileArg;                        /* Argument to profile function */
   void *pCommitArg;                 /* Argument to xCommitCallback() */   
   int (*xCommitCallback)(void*);    /* Invoked at every commit. */
   void *pRollbackArg;               /* Argument to xRollbackCallback() */   
   void (*xRollbackCallback)(void*); /* Invoked at every commit. */
@@ -9733,31 +9777,30 @@ struct sqlite3 {
   void *pAuthArg;               /* 1st argument to the access auth function */
 #endif
 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
   int (*xProgress)(void *);     /* The progress callback */
   void *pProgressArg;           /* Argument to the progress callback */
   int nProgressOps;             /* Number of opcodes for progress callback */
 #endif
 #ifndef SQLITE_OMIT_VIRTUALTABLE
+  int nVTrans;                  /* Allocated size of aVTrans */
   Hash aModule;                 /* populated by sqlite3_create_module() */
   VtabCtx *pVtabCtx;            /* Context for active vtab connect/create */
   VTable **aVTrans;             /* Virtual tables with open transactions */
-  int nVTrans;                  /* Allocated size of aVTrans */
   VTable *pDisconnect;    /* Disconnect these in next sqlite3_prepare() */
 #endif
   FuncDefHash aFunc;            /* Hash table of connection functions */
   Hash aCollSeq;                /* All collating sequences */
   BusyHandler busyHandler;      /* Busy callback */
-  int busyTimeout;              /* Busy handler timeout, in msec */
   Db aDbStatic[2];              /* Static space for the 2 default backends */
   Savepoint *pSavepoint;        /* List of active savepoints */
+  int busyTimeout;              /* Busy handler timeout, in msec */
   int nSavepoint;               /* Number of non-transaction savepoints */
   int nStatement;               /* Number of nested statement-transactions  */
-  u8 isTransactionSavepoint;    /* True if the outermost savepoint is a TS */
   i64 nDeferredCons;            /* Net deferred constraints this transaction. */
   int *pnBytesFreed;            /* If not NULL, increment this in DbFree() */
 
 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
   /* The following variables are all protected by the STATIC_MASTER 
   ** mutex, not by sqlite3.mutex. They are used by code in notify.c. 
   **
   ** When X.pUnlockConnection==Y, that means that X is waiting for Y to
@@ -9790,18 +9833,17 @@ struct sqlite3 {
 #define SQLITE_CountRows      0x00001000  /* Count rows changed by INSERT, */
                                           /*   DELETE, or UPDATE and return */
                                           /*   the count using a callback. */
 #define SQLITE_NullCallback   0x00002000  /* Invoke the callback once if the */
                                           /*   result set is empty */
 #define SQLITE_SqlTrace       0x00004000  /* Debug print SQL as it executes */
 #define SQLITE_VdbeListing    0x00008000  /* Debug listings of VDBE programs */
 #define SQLITE_WriteSchema    0x00010000  /* OK to update SQLITE_MASTER */
-#define SQLITE_NoReadlock     0x00020000  /* Readlocks are omitted when 
-                                          ** accessing read-only databases */
+                         /*   0x00020000  Unused */
 #define SQLITE_IgnoreChecks   0x00040000  /* Do not enforce check constraints */
 #define SQLITE_ReadUncommitted 0x0080000  /* For shared-cache mode */
 #define SQLITE_LegacyFileFmt  0x00100000  /* Create new databases in format 1 */
 #define SQLITE_FullFSync      0x00200000  /* Use full fsync on the backend */
 #define SQLITE_CkptFullFSync  0x00400000  /* Use full fsync for checkpoint */
 #define SQLITE_RecoveryMode   0x00800000  /* Ignore schema errors */
 #define SQLITE_ReverseOrder   0x01000000  /* Reverse unordered SELECTs */
 #define SQLITE_RecTriggers    0x02000000  /* Enable recursive triggers */
@@ -9880,17 +9922,16 @@ struct FuncDestructor {
 
 /*
 ** Possible values for FuncDef.flags
 */
 #define SQLITE_FUNC_LIKE     0x01 /* Candidate for the LIKE optimization */
 #define SQLITE_FUNC_CASE     0x02 /* Case-sensitive LIKE-type function */
 #define SQLITE_FUNC_EPHEM    0x04 /* Ephemeral.  Delete with VDBE */
 #define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */
-#define SQLITE_FUNC_PRIVATE  0x10 /* Allowed for internal use only */
 #define SQLITE_FUNC_COUNT    0x20 /* Built-in count(*) aggregate */
 #define SQLITE_FUNC_COALESCE 0x40 /* Built-in coalesce() or ifnull() function */
 
 /*
 ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
 ** used to create the initializers for the FuncDef structures.
 **
 **   FUNCTION(zName, nArg, iArg, bNC, xFunc)
@@ -10163,18 +10204,16 @@ struct Table {
 /*
 ** Allowed values for Tabe.tabFlags.
 */
 #define TF_Readonly        0x01    /* Read-only system table */
 #define TF_Ephemeral       0x02    /* An ephemeral table */
 #define TF_HasPrimaryKey   0x04    /* Table has a primary key */
 #define TF_Autoincrement   0x08    /* Integer primary key is autoincrement */
 #define TF_Virtual         0x10    /* Is a virtual table */
-#define TF_NeedMetadata    0x20    /* aCol[].zType and aCol[].pColl missing */
-
 
 
 /*
 ** Test to see whether or not a table is a virtual table.  This is
 ** done as a macro so that it will be optimized out when virtual
 ** table support is omitted from the build.
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -10326,29 +10365,29 @@ struct UnpackedRecord {
 ** must be unique and what to do if they are not.  When Index.onError=OE_None,
 ** it means this is not a unique index.  Otherwise it is a unique index
 ** and the value of Index.onError indicate the which conflict resolution 
 ** algorithm to employ whenever an attempt is made to insert a non-unique
 ** element.
 */
 struct Index {
   char *zName;     /* Name of this index */
-  int nColumn;     /* Number of columns in the table used by this index */
   int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
   tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
   Table *pTable;   /* The SQL table being indexed */
-  int tnum;        /* Page containing root of this index in database file */
-  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
-  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
-  u8 bUnordered;   /* Use this index for == or IN queries only */
   char *zColAff;   /* String defining the affinity of each column */
   Index *pNext;    /* The next index associated with the same table */
   Schema *pSchema; /* Schema containing this index */
   u8 *aSortOrder;  /* Array of size Index.nColumn. True==DESC, False==ASC */
   char **azColl;   /* Array of collation sequence names for index */
+  int nColumn;     /* Number of columns in the table used by this index */
+  int tnum;        /* Page containing root of this index in database file */
+  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
+  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
+  u8 bUnordered;   /* Use this index for == or IN queries only */
 #ifdef SQLITE_ENABLE_STAT3
   int nSample;             /* Number of elements in aSample[] */
   tRowcnt avgEq;           /* Average nEq value for key values not in aSample */
   IndexSample *aSample;    /* Samples of the left-most key */
 #endif
 };
 
 /*
@@ -10397,39 +10436,37 @@ struct Token {
 */
 struct AggInfo {
   u8 directMode;          /* Direct rendering mode means take data directly
                           ** from source tables rather than from accumulators */
   u8 useSortingIdx;       /* In direct mode, reference the sorting index rather
                           ** than the source table */
   int sortingIdx;         /* Cursor number of the sorting index */
   int sortingIdxPTab;     /* Cursor number of pseudo-table */
+  int nSortingColumn;     /* Number of columns in the sorting index */
   ExprList *pGroupBy;     /* The group by clause */
-  int nSortingColumn;     /* Number of columns in the sorting index */
   struct AggInfo_col {    /* For each column used in source tables */
     Table *pTab;             /* Source table */
     int iTable;              /* Cursor number of the source table */
     int iColumn;             /* Column number within the source table */
     int iSorterColumn;       /* Column number in the sorting index */
     int iMem;                /* Memory location that acts as accumulator */
     Expr *pExpr;             /* The original expression */
   } *aCol;
   int nColumn;            /* Number of used entries in aCol[] */
-  int nColumnAlloc;       /* Number of slots allocated for aCol[] */
   int nAccumulator;       /* Number of columns that show through to the output.
                           ** Additional columns are used only as parameters to
                           ** aggregate functions */
   struct AggInfo_func {   /* For each aggregate function */
     Expr *pExpr;             /* Expression encoding the function */
     FuncDef *pFunc;          /* The aggregate function implementation */
     int iMem;                /* Memory location that acts as accumulator */
     int iDistinct;           /* Ephemeral table used to enforce DISTINCT */
   } *aFunc;
   int nFunc;              /* Number of entries in aFunc[] */
-  int nFuncAlloc;         /* Number of slots allocated for aFunc[] */
 };
 
 /*
 ** The datatype ynVar is a signed integer, either 16-bit or 32-bit.
 ** Usually it is 16-bits.  But if SQLITE_MAX_VARIABLE_NUMBER is greater
 ** than 32767 we have to make it 32-bit.  16-bit is preferred because
 ** it uses less memory in the Expr object, which is a big memory user
 ** in systems with lots of prepared statements.  And few applications
@@ -10616,27 +10653,26 @@ struct Expr {
 ** name.  An expr/name combination can be used in several ways, such
 ** as the list of "expr AS ID" fields following a "SELECT" or in the
 ** list of "ID = expr" items in an UPDATE.  A list of expressions can
 ** also be used as the argument to a function, in which case the a.zName
 ** field is not used.
 */
 struct ExprList {
   int nExpr;             /* Number of expressions on the list */
-  int nAlloc;            /* Number of entries allocated below */
   int iECursor;          /* VDBE Cursor associated with this ExprList */
-  struct ExprList_item {
+  struct ExprList_item { /* For each expression in the list */
     Expr *pExpr;           /* The list of expressions */
     char *zName;           /* Token associated with this expression */
     char *zSpan;           /* Original text of the expression */
     u8 sortOrder;          /* 1 for DESC or 0 for ASC */
     u8 done;               /* A flag to indicate when processing is finished */
     u16 iOrderByCol;       /* For ORDER BY, column number in result set */
     u16 iAlias;            /* Index into Parse.aAlias[] for zName */
-  } *a;                  /* One entry for each expression */
+  } *a;                  /* Alloc a power of two greater or equal to nExpr */
 };
 
 /*
 ** An instance of this structure is used by the parser to record both
 ** the parse tree for an expression and the span of input text for an
 ** expression.
 */
 struct ExprSpan {
@@ -10661,17 +10697,16 @@ struct ExprSpan {
 ** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
 */
 struct IdList {
   struct IdList_item {
     char *zName;      /* Name of the identifier */
     int idx;          /* Index in some Table.aCol[] of a column named zName */
   } *a;
   int nId;         /* Number of identifiers on the list */
-  int nAlloc;      /* Number of entries allocated for a[] below */
 };
 
 /*
 ** The bitmask datatype defined below is used for various optimizations.
 **
 ** Changing this from a 64-bit to a 32-bit type limits the number of
 ** tables in a join to 32 instead of 64.  But it also reduces the size
 ** of the library by 738 bytes on ix86.
@@ -10905,42 +10940,43 @@ struct NameContext {
 ** for the result set.  The KeyInfo for addrOpenTran[2] contains collating
 ** sequences for the ORDER BY clause.
 */
 struct Select {
   ExprList *pEList;      /* The fields of the result */
   u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
   char affinity;         /* MakeRecord with this affinity for SRT_Set */
   u16 selFlags;          /* Various SF_* values */
+  int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
+  int addrOpenEphm[3];   /* OP_OpenEphem opcodes related to this select */
+  double nSelectRow;     /* Estimated number of result rows */
   SrcList *pSrc;         /* The FROM clause */
   Expr *pWhere;          /* The WHERE clause */
   ExprList *pGroupBy;    /* The GROUP BY clause */
   Expr *pHaving;         /* The HAVING clause */
   ExprList *pOrderBy;    /* The ORDER BY clause */
   Select *pPrior;        /* Prior select in a compound select statement */
   Select *pNext;         /* Next select to the left in a compound */
   Select *pRightmost;    /* Right-most select in a compound select statement */
   Expr *pLimit;          /* LIMIT expression. NULL means not used. */
   Expr *pOffset;         /* OFFSET expression. NULL means not used. */
-  int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
-  int addrOpenEphm[3];   /* OP_OpenEphem opcodes related to this select */
-  double nSelectRow;     /* Estimated number of result rows */
 };
 
 /*
 ** Allowed values for Select.selFlags.  The "SF" prefix stands for
 ** "Select Flag".
 */
 #define SF_Distinct        0x01  /* Output should be DISTINCT */
 #define SF_Resolved        0x02  /* Identifiers have been resolved */
 #define SF_Aggregate       0x04  /* Contains aggregate functions */
 #define SF_UsesEphemeral   0x08  /* Uses the OpenEphemeral opcode */
 #define SF_Expanded        0x10  /* sqlite3SelectExpand() called on this */
 #define SF_HasTypeInfo     0x20  /* FROM subqueries have Table metadata */
 #define SF_UseSorter       0x40  /* Sort using a sorter */
+#define SF_Values          0x80  /* Synthesized from VALUES clause */
 
 
 /*
 ** The results of a select can be distributed in several ways.  The
 ** "SRT" prefix means "SELECT Result Type".
 */
 #define SRT_Union        1  /* Store result as keys in an index */
 #define SRT_Except       2  /* Remove result from a UNION index */
@@ -11008,20 +11044,20 @@ struct AutoincInfo {
 **
 ** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns
 ** accessed (or set to 0 for triggers fired as a result of INSERT 
 ** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to
 ** a mask of new.* columns used by the program.
 */
 struct TriggerPrg {
   Trigger *pTrigger;      /* Trigger this program was coded from */
-  int orconf;             /* Default ON CONFLICT policy */
+  TriggerPrg *pNext;      /* Next entry in Parse.pTriggerPrg list */
   SubProgram *pProgram;   /* Program implementing pTrigger/orconf */
+  int orconf;             /* Default ON CONFLICT policy */
   u32 aColmask[2];        /* Masks of old.*, new.* columns accessed */
-  TriggerPrg *pNext;      /* Next entry in Parse.pTriggerPrg list */
 };
 
 /*
 ** The yDbMask datatype for the bitmask of all attached databases.
 */
 #if SQLITE_MAX_ATTACHED>30
   typedef sqlite3_uint64 yDbMask;
 #else
@@ -11041,102 +11077,106 @@ struct TriggerPrg {
 ** The nTableLock and aTableLock variables are only used if the shared-cache 
 ** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are
 ** used to store the set of table-locks required by the statement being
 ** compiled. Function sqlite3TableLock() is used to add entries to the
 ** list.
 */
 struct Parse {
   sqlite3 *db;         /* The main database structure */
-  int rc;              /* Return code from execution */
   char *zErrMsg;       /* An error message */
   Vdbe *pVdbe;         /* An engine for executing database bytecode */
+  int rc;              /* Return code from execution */
   u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
   u8 checkSchema;      /* Causes schema cookie check after an error */
   u8 nested;           /* Number of nested calls to the parser/code generator */
   u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
   u8 nTempInUse;       /* Number of aTempReg[] currently checked out */
+  u8 nColCache;        /* Number of entries in aColCache[] */
+  u8 iColCache;        /* Next entry in aColCache[] to replace */
+  u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
+  u8 mayAbort;         /* True if statement may throw an ABORT exception */
   int aTempReg[8];     /* Holding area for temporary registers */
   int nRangeReg;       /* Size of the temporary register block */
   int iRangeReg;       /* First register in temporary register block */
   int nErr;            /* Number of errors seen */
   int nTab;            /* Number of previously allocated VDBE cursors */
   int nMem;            /* Number of memory cells used so far */
   int nSet;            /* Number of sets used so far */
   int nOnce;           /* Number of OP_Once instructions so far */
   int ckBase;          /* Base register of data during check constraints */
   int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
   int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
-  u8 nColCache;        /* Number of entries in aColCache[] */
-  u8 iColCache;        /* Next entry in aColCache[] to replace */
   struct yColCache {
     int iTable;           /* Table cursor number */
     int iColumn;          /* Table column number */
     u8 tempReg;           /* iReg is a temp register that needs to be freed */
     int iLevel;           /* Nesting level */
     int iReg;             /* Reg with value of this column. 0 means none. */
     int lru;              /* Least recently used entry has the smallest value */
   } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
   yDbMask writeMask;   /* Start a write transaction on these databases */
   yDbMask cookieMask;  /* Bitmask of schema verified databases */
-  u8 isMultiWrite;     /* True if statement may affect/insert multiple rows */
-  u8 mayAbort;         /* True if statement may throw an ABORT exception */
   int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
   int cookieValue[SQLITE_MAX_ATTACHED+2];  /* Values of cookies to verify */
+  int regRowid;        /* Register holding rowid of CREATE TABLE entry */
+  int regRoot;         /* Register holding root page number for new objects */
+  int nMaxArg;         /* Max args passed to user function by sub-program */
 #ifndef SQLITE_OMIT_SHARED_CACHE
   int nTableLock;        /* Number of locks in aTableLock */
   TableLock *aTableLock; /* Required table locks for shared-cache mode */
 #endif
-  int regRowid;        /* Register holding rowid of CREATE TABLE entry */
-  int regRoot;         /* Register holding root page number for new objects */
   AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
-  int nMaxArg;         /* Max args passed to user function by sub-program */
 
   /* Information used while coding trigger programs. */
   Parse *pToplevel;    /* Parse structure for main program (or NULL) */
   Table *pTriggerTab;  /* Table triggers are being coded for */
+  double nQueryLoop;   /* Estimated number of iterations of a query */
   u32 oldmask;         /* Mask of old.* columns referenced */
   u32 newmask;         /* Mask of new.* columns referenced */
   u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
   u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
   u8 disableTriggers;  /* True to disable triggers */
-  double nQueryLoop;   /* Estimated number of iterations of a query */
 
   /* Above is constant between recursions.  Below is reset before and after
   ** each recursion */
 
-  int nVar;            /* Number of '?' variables seen in the SQL so far */
-  int nzVar;           /* Number of available slots in azVar[] */
-  char **azVar;        /* Pointers to names of parameters */
-  Vdbe *pReprepare;    /* VM being reprepared (sqlite3Reprepare()) */
-  int nAlias;          /* Number of aliased result set columns */
-  int *aAlias;         /* Register used to hold aliased result */
-  u8 explain;          /* True if the EXPLAIN flag is found on the query */
-  Token sNameToken;    /* Token with unqualified schema object name */
-  Token sLastToken;    /* The last token parsed */
-  const char *zTail;   /* All SQL text past the last semicolon parsed */
-  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
+  int nVar;                 /* Number of '?' variables seen in the SQL so far */
+  int nzVar;                /* Number of available slots in azVar[] */
+  u8 explain;               /* True if the EXPLAIN flag is found on the query */
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+  u8 declareVtab;           /* True if inside sqlite3_declare_vtab() */
+  int nVtabLock;            /* Number of virtual tables to lock */
+#endif
+  int nAlias;               /* Number of aliased result set columns */
+  int nHeight;              /* Expression tree height of current sub-select */
+#ifndef SQLITE_OMIT_EXPLAIN
+  int iSelectId;            /* ID of current select for EXPLAIN output */
+  int iNextSelectId;        /* Next available select ID for EXPLAIN output */
+#endif
+  char **azVar;             /* Pointers to names of parameters */
+  Vdbe *pReprepare;         /* VM being reprepared (sqlite3Reprepare()) */
+  int *aAlias;              /* Register used to hold aliased result */
+  const char *zTail;        /* All SQL text past the last semicolon parsed */
+  Table *pNewTable;         /* A table being constructed by CREATE TABLE */
   Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
   const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
+  Token sNameToken;         /* Token with unqualified schema object name */
+  Token sLastToken;         /* The last token parsed */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  Token sArg;                /* Complete text of a module argument */
-  u8 declareVtab;            /* True if inside sqlite3_declare_vtab() */
-  int nVtabLock;             /* Number of virtual tables to lock */
-  Table **apVtabLock;        /* Pointer to virtual tables needing locking */
-#endif
-  int nHeight;            /* Expression tree height of current sub-select */
-  Table *pZombieTab;      /* List of Table objects to delete after code gen */
-  TriggerPrg *pTriggerPrg;    /* Linked list of coded triggers */
-
-#ifndef SQLITE_OMIT_EXPLAIN
-  int iSelectId;
-  int iNextSelectId;
-#endif
-};
-
+  Token sArg;               /* Complete text of a module argument */
+  Table **apVtabLock;       /* Pointer to virtual tables needing locking */
+#endif
+  Table *pZombieTab;        /* List of Table objects to delete after code gen */
+  TriggerPrg *pTriggerPrg;  /* Linked list of coded triggers */
+};
+
+/*
+** Return true if currently inside an sqlite3_declare_vtab() call.
+*/
 #ifdef SQLITE_OMIT_VIRTUALTABLE
   #define IN_DECLARE_VTAB 0
 #else
   #define IN_DECLARE_VTAB (pParse->declareVtab)
 #endif
 
 /*
 ** An instance of the following structure can be declared on a stack and used
@@ -11277,18 +11317,18 @@ struct StrAccum {
 };
 
 /*
 ** A pointer to this structure is used to communicate information
 ** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
 */
 typedef struct {
   sqlite3 *db;        /* The database being initialized */
+  char **pzErrMsg;    /* Error message stored here */
   int iDb;            /* 0 for main database.  1 for TEMP, 2.. for ATTACHed */
-  char **pzErrMsg;    /* Error message stored here */
   int rc;             /* Result code stored here */
 } InitData;
 
 /*
 ** Structure containing global configuration data for the SQLite library.
 **
 ** This structure also contains some state information.
 */
@@ -11420,17 +11460,17 @@ SQLITE_PRIVATE int sqlite3CantopenError(
 # define sqlite3Isdigit(x)   isdigit((unsigned char)(x))
 # define sqlite3Isxdigit(x)  isxdigit((unsigned char)(x))
 # define sqlite3Tolower(x)   tolower((unsigned char)(x))
 #endif
 
 /*
 ** Internal function prototypes
 */
-SQLITE_PRIVATE int sqlite3StrICmp(const char *, const char *);
+#define sqlite3StrICmp sqlite3_stricmp
 SQLITE_PRIVATE int sqlite3Strlen30(const char*);
 #define sqlite3StrNICmp sqlite3_strnicmp
 
 SQLITE_PRIVATE int sqlite3MallocInit(void);
 SQLITE_PRIVATE void sqlite3MallocEnd(void);
 SQLITE_PRIVATE void *sqlite3Malloc(int);
 SQLITE_PRIVATE void *sqlite3MallocZero(int);
 SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, int);
@@ -11568,16 +11608,17 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Pa
 SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
 SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
 SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*);
 SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
 SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
 SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*);
 SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
                     sqlite3_vfs**,char**,char **);
+SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
 SQLITE_PRIVATE int sqlite3CodeOnce(Parse *);
 
 SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32);
 SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32);
 SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
 SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*);
 SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
 SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
@@ -11603,17 +11644,17 @@ SQLITE_PRIVATE void sqlite3DeleteTable(s
 #ifndef SQLITE_OMIT_AUTOINCREMENT
 SQLITE_PRIVATE   void sqlite3AutoincrementBegin(Parse *pParse);
 SQLITE_PRIVATE   void sqlite3AutoincrementEnd(Parse *pParse);
 #else
 # define sqlite3AutoincrementBegin(X)
 # define sqlite3AutoincrementEnd(X)
 #endif
 SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
-SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int,int*,int*,int*);
+SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
 SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
 SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
 SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
 SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
 SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
                                       Token*, Select*, Expr*, IdList*);
 SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
 SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
@@ -11667,17 +11708,17 @@ SQLITE_PRIVATE char *sqlite3NameFromToke
 SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
 SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*);
 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
 SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
 SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
 SQLITE_PRIVATE void sqlite3PrngResetState(void);
-SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*);
+SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int);
 SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
 SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
 SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int);
 SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
 SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
 SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
 SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
 SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
@@ -11841,17 +11882,17 @@ SQLITE_PRIVATE int sqlite3AddInt64(i64*,
 SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
 SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64);
 SQLITE_PRIVATE int sqlite3AbsInt32(int);
 #ifdef SQLITE_ENABLE_8_3_NAMES
 SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*);
 #else
 # define sqlite3FileSuffix3(X,Y)
 #endif
-SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z);
+SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,int);
 
 SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
 SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
 SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, 
                         void(*)(void*));
 SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
 SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
 SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
@@ -11967,17 +12008,17 @@ SQLITE_PRIVATE    int sqlite3VtabCommit(
 SQLITE_PRIVATE    void sqlite3VtabLock(VTable *);
 SQLITE_PRIVATE    void sqlite3VtabUnlock(VTable *);
 SQLITE_PRIVATE    void sqlite3VtabUnlockList(sqlite3*);
 SQLITE_PRIVATE    int sqlite3VtabSavepoint(sqlite3 *, int, int);
 SQLITE_PRIVATE    VTable *sqlite3GetVTable(sqlite3*, Table*);
 #  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
 #endif
 SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
-SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
+SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
 SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
 SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*);
 SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
 SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
 SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*);
 SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
 SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
@@ -12896,31 +12937,31 @@ typedef struct VdbeCursor VdbeCursor;
 ** child frame are released.
 **
 ** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is
 ** set to NULL if the currently executing frame is the main program.
 */
 typedef struct VdbeFrame VdbeFrame;
 struct VdbeFrame {
   Vdbe *v;                /* VM this frame belongs to */
-  int pc;                 /* Program Counter in parent (calling) frame */
+  VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
   Op *aOp;                /* Program instructions for parent frame */
+  Mem *aMem;              /* Array of memory cells for parent frame */
+  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
+  VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
+  void *token;            /* Copy of SubProgram.token */
+  i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
+  u16 nCursor;            /* Number of entries in apCsr */
+  int pc;                 /* Program Counter in parent (calling) frame */
   int nOp;                /* Size of aOp array */
-  Mem *aMem;              /* Array of memory cells for parent frame */
   int nMem;               /* Number of entries in aMem */
-  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
   int nOnceFlag;          /* Number of entries in aOnceFlag */
-  VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
-  u16 nCursor;            /* Number of entries in apCsr */
-  void *token;            /* Copy of SubProgram.token */
   int nChildMem;          /* Number of memory cells for child frame */
   int nChildCsr;          /* Number of cursors for child frame */
-  i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
   int nChange;            /* Statement changes (Vdbe.nChanges)     */
-  VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
 };
 
 #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
 
 /*
 ** A value for VdbeCursor.cacheValid that means the cache is always invalid.
 */
 #define CACHE_STALE 0
@@ -13037,18 +13078,19 @@ struct VdbeFunc {
 ** This structure is defined inside of vdbeInt.h because it uses substructures
 ** (Mem) which are only defined there.
 */
 struct sqlite3_context {
   FuncDef *pFunc;       /* Pointer to function information.  MUST BE FIRST */
   VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
   Mem s;                /* The return value is stored here */
   Mem *pMem;            /* Memory cell used to store aggregate context */
+  CollSeq *pColl;       /* Collating sequence */
   int isError;          /* Error code returned by the function. */
-  CollSeq *pColl;       /* Collating sequence */
+  int skipFlag;         /* Skip skip accumulator loading if true */
 };
 
 /*
 ** An Explain object accumulates indented output which is helpful
 ** in describing recursive data structures.
 */
 struct Explain {
   Vdbe *pVdbe;       /* Attach the explanation to this Vdbe */
@@ -13079,17 +13121,16 @@ struct Vdbe {
   Mem *aMem;              /* The memory locations */
   Mem **apArg;            /* Arguments to currently executing user function */
   Mem *aColName;          /* Column names to return */
   Mem *pResultSet;        /* Pointer to an array of results */
   int nMem;               /* Number of memory locations currently allocated */
   int nOp;                /* Number of instructions in the program */
   int nOpAlloc;           /* Number of slots allocated for aOp[] */
   int nLabel;             /* Number of labels used */
-  int nLabelAlloc;        /* Number of slots allocated in aLabel[] */
   int *aLabel;            /* Space to hold the labels */
   u16 nResColumn;         /* Number of columns in one row of the result set */
   u16 nCursor;            /* Number of slots in apCsr[] */
   u32 magic;              /* Magic number for sanity checking */
   char *zErrMsg;          /* Error message written here */
   Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
   VdbeCursor **apCsr;     /* One element of this array for each open cursor */
   Mem *aVar;              /* Values for the OP_Variable opcode. */
@@ -15146,63 +15187,95 @@ SQLITE_PRIVATE void sqlite3MemSetDefault
 **
 *************************************************************************
 **
 ** This file contains low-level memory allocation drivers for when
 ** SQLite will use the standard C-library malloc/realloc/free interface
 ** to obtain the memory it needs.
 **
 ** This file contains implementations of the low-level memory allocation
-** routines specified in the sqlite3_mem_methods object.
+** routines specified in the sqlite3_mem_methods object.  The content of
+** this file is only used if SQLITE_SYSTEM_MALLOC is defined.  The
+** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the
+** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined.  The
+** default configuration is to use memory allocation routines in this
+** file.
+**
+** C-preprocessor macro summary:
+**
+**    HAVE_MALLOC_USABLE_SIZE     The configure script sets this symbol if
+**                                the malloc_usable_size() interface exists
+**                                on the target platform.  Or, this symbol
+**                                can be set manually, if desired.
+**                                If an equivalent interface exists by
+**                                a different name, using a separate -D
+**                                option to rename it.
+**
+**    SQLITE_WITHOUT_ZONEMALLOC   Some older macs lack support for the zone
+**                                memory allocator.  Set this symbol to enable
+**                                building on older macs.
+**
+**    SQLITE_WITHOUT_MSIZE        Set this symbol to disable the use of
+**                                _msize() on windows systems.  This might
+**                                be necessary when compiling for Delphi,
+**                                for example.
 */
 
 /*
 ** This version of the memory allocator is the default.  It is
 ** used when no other memory allocator is specified using compile-time
 ** macros.
 */
 #ifdef SQLITE_SYSTEM_MALLOC
 
 /*
-** Windows systems have malloc_usable_size() but it is called _msize()
-*/
-#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN
-# define HAVE_MALLOC_USABLE_SIZE 1
-# define malloc_usable_size _msize
-#endif
-
-#if defined(__APPLE__)
-
-/*
-** Use the zone allocator available on apple products
+** The MSVCRT has malloc_usable_size() but it is called _msize().
+** The use of _msize() is automatic, but can be disabled by compiling
+** with -DSQLITE_WITHOUT_MSIZE
+*/
+#if defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)
+# define SQLITE_MALLOCSIZE _msize
+#endif
+
+#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
+
+/*
+** Use the zone allocator available on apple products unless the
+** SQLITE_WITHOUT_ZONEMALLOC symbol is defined.
 */
 #include <sys/sysctl.h>
 #include <malloc/malloc.h>
 #include <libkern/OSAtomic.h>
 static malloc_zone_t* _sqliteZone_;
 #define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
 #define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
 #define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
 #define SQLITE_MALLOCSIZE(x) \
         (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))
 
 #else /* if not __APPLE__ */
 
 /*
-** Use standard C library malloc and free on non-Apple systems.
+** Use standard C library malloc and free on non-Apple systems.  
+** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined.
 */
 #define SQLITE_MALLOC(x)    malloc(x)
 #define SQLITE_FREE(x)      free(x)
 #define SQLITE_REALLOC(x,y) realloc((x),(y))
 
+#if (defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)) \
+      || (defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE))
+# include <malloc.h>    /* Needed for malloc_usable_size on linux */
+#endif
 #ifdef HAVE_MALLOC_USABLE_SIZE
-#include <malloc.h>
-#define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
-#else
-#undef SQLITE_MALLOCSIZE
+# ifndef SQLITE_MALLOCSIZE
+#  define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
+# endif
+#else
+# undef SQLITE_MALLOCSIZE
 #endif
 
 #endif /* __APPLE__ or not __APPLE__ */
 
 /*
 ** Like malloc(), but remember the size of the allocation
 ** so that we can find it later using sqlite3MemSize().
 **
@@ -15314,17 +15387,17 @@ static void *sqlite3MemRealloc(void *pPr
 static int sqlite3MemRoundup(int n){
   return ROUND8(n);
 }
 
 /*
 ** Initialize this module.
 */
 static int sqlite3MemInit(void *NotUsed){
-#if defined(__APPLE__)
+#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
   int cpuCount;
   size_t len;
   if( _sqliteZone_ ){
     return SQLITE_OK;
   }
   len = sizeof(cpuCount);
   /* One usually wants to use hw.acctivecpu for MT decisions, but not here */
   sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);
@@ -21183,23 +21256,23 @@ SQLITE_PRIVATE int sqlite3Dequote(char *
 
 /* Convenient short-hand */
 #define UpperToLower sqlite3UpperToLower
 
 /*
 ** Some systems have stricmp().  Others have strcasecmp().  Because
 ** there is no consistency, we will define our own.
 **
-** IMPLEMENTATION-OF: R-20522-24639 The sqlite3_strnicmp() API allows
-** applications and extensions to compare the contents of two buffers
-** containing UTF-8 strings in a case-independent fashion, using the same
-** definition of case independence that SQLite uses internally when
-** comparing identifiers.
-*/
-SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
+** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and
+** sqlite3_strnicmp() APIs allow applications and extensions to compare
+** the contents of two buffers containing UTF-8 strings in a
+** case-independent fashion, using the same definition of "case
+** independence" that SQLite uses internally when comparing identifiers.
+*/
+SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
   register unsigned char *a, *b;
   a = (unsigned char *)zLeft;
   b = (unsigned char *)zRight;
   while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
   return UpperToLower[*a] - UpperToLower[*b];
 }
 SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
   register unsigned char *a, *b;
@@ -24940,17 +25013,17 @@ struct UnixUnusedFd {
 */
 typedef struct unixFile unixFile;
 struct unixFile {
   sqlite3_io_methods const *pMethod;  /* Always the first entry */
   sqlite3_vfs *pVfs;                  /* The VFS that created this unixFile */
   unixInodeInfo *pInode;              /* Info about locks on this inode */
   int h;                              /* The file descriptor */
   unsigned char eFileLock;            /* The type of lock held on this fd */
-  unsigned char ctrlFlags;            /* Behavioral bits.  UNIXFILE_* flags */
+  unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
   int lastErrno;                      /* The unix errno from last I/O error */
   void *lockingContext;               /* Locking style specific state */
   UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
   const char *zPath;                  /* Name of the file */
   unixShm *pShm;                      /* Shared memory segment information */
   int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
 #if SQLITE_ENABLE_LOCKING_STYLE
   int openFlags;                      /* The flags specified at open() */
@@ -24991,16 +25064,17 @@ struct unixFile {
 # define UNIXFILE_DIRSYNC    0x08     /* Directory sync needed */
 #else
 # define UNIXFILE_DIRSYNC    0x00
 #endif
 #define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
 #define UNIXFILE_DELETE      0x20     /* Delete on close */
 #define UNIXFILE_URI         0x40     /* Filename might have query parameters */
 #define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
+#define UNIXFILE_CHOWN      0x100     /* File ownership was changed */
 
 /*
 ** Include code that is common to all os_*.c files
 */
 /************** Include os_common.h in the middle of os_unix.c ***************/
 /************** Begin file os_common.h ***************************************/
 /*
 ** 2004 May 22
@@ -25355,16 +25429,22 @@ static struct unix_syscall {
 #define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent)
 
   { "mkdir",        (sqlite3_syscall_ptr)mkdir,           0 },
 #define osMkdir     ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)
 
   { "rmdir",        (sqlite3_syscall_ptr)rmdir,           0 },
 #define osRmdir     ((int(*)(const char*))aSyscall[19].pCurrent)
 
+  { "fchown",       (sqlite3_syscall_ptr)fchown,          0 },
+#define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
+
+  { "umask",        (sqlite3_syscall_ptr)umask,           0 },
+#define osUmask     ((mode_t(*)(mode_t))aSyscall[21].pCurrent)
+
 }; /* End of the overrideable system calls */
 
 /*
 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
 ** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
 ** system call pointer, or SQLITE_NOTFOUND if there is no configurable
 ** system call named zName.
 */
@@ -25441,21 +25521,46 @@ static const char *unixNextSystemCall(sq
   }
   for(i++; i<ArraySize(aSyscall); i++){
     if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
   }
   return 0;
 }
 
 /*
-** Retry open() calls that fail due to EINTR
-*/
-static int robust_open(const char *z, int f, int m){
-  int rc;
-  do{ rc = osOpen(z,f,m); }while( rc<0 && errno==EINTR );
+** Invoke open().  Do so multiple times, until it either succeeds or
+** files for some reason other than EINTR.
+**
+** If the file creation mode "m" is 0 then set it to the default for
+** SQLite.  The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
+** 0644) as modified by the system umask.  If m is not 0, then
+** make the file creation mode be exactly m ignoring the umask.
+**
+** The m parameter will be non-zero only when creating -wal, -journal,
+** and -shm files.  We want those files to have *exactly* the same
+** permissions as their original database, unadulterated by the umask.
+** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
+** transaction crashes and leaves behind hot journals, then any
+** process that is able to write to the database will also be able to
+** recover the hot journals.
+*/
+static int robust_open(const char *z, int f, mode_t m){
+  int rc;
+  mode_t m2;
+  mode_t origM = 0;
+  if( m==0 ){
+    m2 = SQLITE_DEFAULT_FILE_PERMISSIONS;
+  }else{
+    m2 = m;
+    origM = osUmask(0);
+  }
+  do{ rc = osOpen(z,f,m2); }while( rc<0 && errno==EINTR );
+  if( m ){
+    osUmask(origM);
+  }
   return rc;
 }
 
 /*
 ** Helper functions to obtain and relinquish the global mutex. The
 ** global mutex is used to protect the unixInodeInfo and
 ** vxworksFileId objects used by this file, all of which may be 
 ** shared by multiple threads.
@@ -28793,18 +28898,17 @@ static int unixOpenSharedMemory(unixFile
   unixEnterMutex();
   pInode = pDbFd->pInode;
   pShmNode = pInode->pShmNode;
   if( pShmNode==0 ){
     struct stat sStat;                 /* fstat() info for database file */
 
     /* Call fstat() to figure out the permissions on the database file. If
     ** a new *-shm file is created, an attempt will be made to create it
-    ** with the same permissions. The actual permissions the file is created
-    ** with are subject to the current umask setting.
+    ** with the same permissions.
     */
     if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){
       rc = SQLITE_IOERR_FSTAT;
       goto shm_open_err;
     }
 
 #ifdef SQLITE_SHM_DIRECTORY
     nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
@@ -28838,20 +28942,29 @@ static int unixOpenSharedMemory(unixFile
     if( pInode->bProcessLock==0 ){
       int openFlags = O_RDWR | O_CREAT;
       if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
         openFlags = O_RDONLY;
         pShmNode->isReadonly = 1;
       }
       pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
       if( pShmNode->h<0 ){
-        if( pShmNode->h<0 ){
-          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
-          goto shm_open_err;
-        }
+        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
+        goto shm_open_err;
+      }
+
+      /* If this process is running as root, make sure that the SHM file
+      ** is owned by the same user that owns the original database.  Otherwise,
+      ** the original owner will not be able to connect. If this process is
+      ** not root, the following fchown() will fail, but we don't care.  The
+      ** if(){..} and the UNIXFILE_CHOWN flag are purely to silence compiler
+      ** warnings.
+      */
+      if( osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid)==0 ){
+        pDbFd->ctrlFlags |= UNIXFILE_CHOWN;
       }
   
       /* Check to see if another process is holding the dead-man switch.
       ** If not, truncate the file to zero length. 
       */
       rc = SQLITE_OK;
       if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
         if( robust_ftruncate(pShmNode->h, 0) ){
@@ -29816,39 +29929,41 @@ static UnixUnusedFd *findReusableFd(cons
 
 /*
 ** This function is called by unixOpen() to determine the unix permissions
 ** to create new files with. If no error occurs, then SQLITE_OK is returned
 ** and a value suitable for passing as the third argument to open(2) is
 ** written to *pMode. If an IO error occurs, an SQLite error code is 
 ** returned and the value of *pMode is not modified.
 **
-** If the file being opened is a temporary file, it is always created with
-** the octal permissions 0600 (read/writable by owner only). If the file
-** is a database or master journal file, it is created with the permissions 
-** mask SQLITE_DEFAULT_FILE_PERMISSIONS.
-**
-** Finally, if the file being opened is a WAL or regular journal file, then 
+** In most cases cases, this routine sets *pMode to 0, which will become
+** an indication to robust_open() to create the file using
+** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask.
+** But if the file being opened is a WAL or regular journal file, then 
 ** this function queries the file-system for the permissions on the 
 ** corresponding database file and sets *pMode to this value. Whenever 
 ** possible, WAL and journal files are created using the same permissions 
 ** as the associated database file.
 **
 ** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the
 ** original filename is unavailable.  But 8_3_NAMES is only used for
 ** FAT filesystems and permissions do not matter there, so just use
 ** the default permissions.
 */
 static int findCreateFileMode(
   const char *zPath,              /* Path of file (possibly) being created */
   int flags,                      /* Flags passed as 4th argument to xOpen() */
-  mode_t *pMode                   /* OUT: Permissions to open file with */
+  mode_t *pMode,                  /* OUT: Permissions to open file with */
+  uid_t *pUid,                    /* OUT: uid to set on the file */
+  gid_t *pGid                     /* OUT: gid to set on the file */
 ){
   int rc = SQLITE_OK;             /* Return Code */
-  *pMode = SQLITE_DEFAULT_FILE_PERMISSIONS;
+  *pMode = 0;
+  *pUid = 0;
+  *pGid = 0;
   if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
     char zDb[MAX_PATHNAME+1];     /* Database file path */
     int nDb;                      /* Number of valid bytes in zDb */
     struct stat sStat;            /* Output of stat() on database file */
 
     /* zPath is a path to a WAL or journal file. The following block derives
     ** the path to the associated database file from zPath. This block handles
     ** the following naming conventions:
@@ -29872,16 +29987,18 @@ static int findCreateFileMode(
       nDb--;
     }
 #endif
     memcpy(zDb, zPath, nDb);
     zDb[nDb] = '\0';
 
     if( 0==osStat(zDb, &sStat) ){
       *pMode = sStat.st_mode & 0777;
+      *pUid = sStat.st_uid;
+      *pGid = sStat.st_gid;
     }else{
       rc = SQLITE_IOERR_FSTAT;
     }
   }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
     *pMode = 0600;
   }
   return rc;
 }
@@ -30018,17 +30135,19 @@ static int unixOpen(
   if( isReadonly )  openFlags |= O_RDONLY;
   if( isReadWrite ) openFlags |= O_RDWR;
   if( isCreate )    openFlags |= O_CREAT;
   if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
   openFlags |= (O_LARGEFILE|O_BINARY);
 
   if( fd<0 ){
     mode_t openMode;              /* Permissions to create file with */
-    rc = findCreateFileMode(zName, flags, &openMode);
+    uid_t uid;                    /* Userid for the file */
+    gid_t gid;                    /* Groupid for the file */
+    rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
     if( rc!=SQLITE_OK ){
       assert( !p->pUnused );
       assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
       return rc;
     }
     fd = robust_open(zName, openFlags, openMode);
     OSTRACE(("OPENX   %-3d %s 0%o\n", fd, zName, openFlags));
     if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
@@ -30039,16 +30158,27 @@ static int unixOpen(
       openFlags |= O_RDONLY;
       isReadonly = 1;
       fd = robust_open(zName, openFlags, openMode);
     }
     if( fd<0 ){
       rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
       goto open_finished;
     }
+
+    /* If this process is running as root and if creating a new rollback
+    ** journal or WAL file, set the ownership of the journal or WAL to be
+    ** the same as the original database.  If we are not running as root,
+    ** then the fchown() call will fail, but that's ok.  The "if(){}" and
+    ** the setting of the UNIXFILE_CHOWN flag are purely to silence compiler
+    ** warnings from gcc.
+    */
+    if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
+      if( osFchown(fd, uid, gid)==0 ){ p->ctrlFlags |= UNIXFILE_CHOWN; }
+    }
   }
   assert( fd>=0 );
   if( pOutFlags ){
     *pOutFlags = flags;
   }
 
   if( p->pUnused ){
     p->pUnused->fd = fd;
@@ -30350,28 +30480,28 @@ static int unixRandomness(sqlite3_vfs *N
   **
   ** When testing, initializing zBuf[] to zero is all we do.  That means
   ** that we always use the same random number sequence.  This makes the
   ** tests repeatable.
   */
   memset(zBuf, 0, nBuf);
 #if !defined(SQLITE_TEST)
   {
-    int pid, fd;
+    int pid, fd, got;
     fd = robust_open("/dev/urandom", O_RDONLY, 0);
     if( fd<0 ){
       time_t t;
       time(&t);
       memcpy(zBuf, &t, sizeof(t));
       pid = getpid();
       memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid));
       assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf );
       nBuf = sizeof(t) + sizeof(pid);
     }else{
-      do{ nBuf = osRead(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR );
+      do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR );
       robust_close(0, fd, __LINE__);
     }
   }
 #endif
   return nBuf;
 }
 
 
@@ -30765,27 +30895,27 @@ static int proxyCreateUnixFile(
     fd = pUnused->fd;
   }else{
     pUnused = sqlite3_malloc(sizeof(*pUnused));
     if( !pUnused ){
       return SQLITE_NOMEM;
     }
   }
   if( fd<0 ){
-    fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
+    fd = robust_open(path, openFlags, 0);
     terrno = errno;
     if( fd<0 && errno==ENOENT && islockfile ){
       if( proxyCreateLockPath(path) == SQLITE_OK ){
-        fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
+        fd = robust_open(path, openFlags, 0);
       }
     }
   }
   if( fd<0 ){
     openFlags = O_RDONLY;
-    fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
+    fd = robust_open(path, openFlags, 0);
     terrno = errno;
   }
   if( fd<0 ){
     if( islockfile ){
       return SQLITE_BUSY;
     }
     switch (terrno) {
       case EACCES:
@@ -30899,18 +31029,17 @@ static int proxyBreakConchLock(unixFile 
   }
   /* read the conch content */
   readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0);
   if( readLen<PROXY_PATHINDEX ){
     sqlite3_snprintf(sizeof(errmsg),errmsg,"read error (len %d)",(int)readLen);
     goto end_breaklock;
   }
   /* write it out to the temporary break file */
-  fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL),
-                   SQLITE_DEFAULT_FILE_PERMISSIONS);
+  fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), 0);
   if( fd<0 ){
     sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno);
     goto end_breaklock;
   }
   if( osPwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){
     sqlite3_snprintf(sizeof(errmsg), errmsg, "write failed (%d)", errno);
     goto end_breaklock;
   }
@@ -31177,18 +31306,17 @@ static int proxyTakeConch(unixFile *pFil
     end_takeconch:
       OSTRACE(("TRANSPROXY: CLOSE  %d\n", pFile->h));
       if( rc==SQLITE_OK && pFile->openFlags ){
         int fd;
         if( pFile->h>=0 ){
           robust_close(pFile, pFile->h, __LINE__);
         }
         pFile->h = -1;
-        fd = robust_open(pCtx->dbPath, pFile->openFlags,
-                      SQLITE_DEFAULT_FILE_PERMISSIONS);
+        fd = robust_open(pCtx->dbPath, pFile->openFlags, 0);
         OSTRACE(("TRANSPROXY: OPEN  %d\n", fd));
         if( fd>=0 ){
           pFile->h = fd;
         }else{
           rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called
            during locking */
         }
       }
@@ -31747,17 +31875,17 @@ SQLITE_API int sqlite3_os_init(void){
     UNIXVFS("unix-nfs",      nfsIoFinder ),
     UNIXVFS("unix-proxy",    proxyIoFinder ),
 #endif
   };
   unsigned int i;          /* Loop counter */
 
   /* Double-check that the aSyscall[] array has been constructed
   ** correctly.  See ticket [bb3a86e890c8e96ab] */
-  assert( ArraySize(aSyscall)==20 );
+  assert( ArraySize(aSyscall)==22 );
 
   /* Register all VFSes defined in the aVfs[] array */
   for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
     sqlite3_vfs_register(&aVfs[i], i==0);
   }
   return SQLITE_OK; 
 }
 
@@ -36786,26 +36914,25 @@ struct PCache1 {
   */
   PGroup *pGroup;                     /* PGroup this cache belongs to */
   int szPage;                         /* Size of allocated pages in bytes */
   int szExtra;                        /* Size of extra space in bytes */
   int bPurgeable;                     /* True if cache is purgeable */
   unsigned int nMin;                  /* Minimum number of pages reserved */
   unsigned int nMax;                  /* Configured "cache_size" value */
   unsigned int n90pct;                /* nMax*9/10 */
+  unsigned int iMaxKey;               /* Largest key seen since xTruncate() */
 
   /* Hash table of all pages. The following variables may only be accessed
   ** when the accessor is holding the PGroup mutex.
   */
   unsigned int nRecyclable;           /* Number of pages in the LRU list */
   unsigned int nPage;                 /* Total number of pages in apHash */
   unsigned int nHash;                 /* Number of slots in apHash[] */
   PgHdr1 **apHash;                    /* Hash table for fast lookup by key */
-
-  unsigned int iMaxKey;               /* Largest key seen since xTruncate() */
 };
 
 /*
 ** Each cache entry is represented by an instance of the following 
 ** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
 ** PgHdr1.pCache->szPage bytes is allocated directly before this structure 
 ** in memory.
 */
@@ -36839,18 +36966,18 @@ static SQLITE_WSD struct PCacheGlobal {
   */
   int isInit;                    /* True if initialized */
   int szSlot;                    /* Size of each free slot */
   int nSlot;                     /* The number of pcache slots */
   int nReserve;                  /* Try to keep nFreeSlot above this */
   void *pStart, *pEnd;           /* Bounds of pagecache malloc range */
   /* Above requires no mutex.  Use mutex below for variable that follow. */
   sqlite3_mutex *mutex;          /* Mutex for accessing the following: */
+  PgFreeslot *pFree;             /* Free page blocks */
   int nFreeSlot;                 /* Number of unused pcache slots */
-  PgFreeslot *pFree;             /* Free page blocks */
   /* The following value requires a mutex to change.  We skip the mutex on
   ** reading because (1) most platforms read a 32-bit integer atomically and
   ** (2) even if an incorrect value is read, no great harm is done since this
   ** is really just an optimization. */
   int bUnderPressure;            /* True if low on PAGECACHE memory */
 } pcache1_g;
 
 /*
@@ -38221,16 +38348,17 @@ SQLITE_PRIVATE int sqlite3RowSetTest(Row
 # define sqlite3WalUndo(x,y,z)                   0
 # define sqlite3WalSavepoint(y,z)
 # define sqlite3WalSavepointUndo(y,z)            0
 # define sqlite3WalFrames(u,v,w,x,y,z)           0
 # define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
 # define sqlite3WalCallback(z)                   0
 # define sqlite3WalExclusiveMode(y,z)            0
 # define sqlite3WalHeapMemory(z)                 0
+# define sqlite3WalFramesize(z)                  0
 #else
 
 #define WAL_SAVEPOINT_NDATA 4
 
 /* Connection to a write-ahead log (WAL) file. 
 ** There is one object of this type for each pager. 
 */
 typedef struct Wal Wal;
@@ -38302,16 +38430,23 @@ SQLITE_PRIVATE int sqlite3WalCallback(Wa
 SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op);
 
 /* Return true if the argument is non-NULL and the WAL module is using
 ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
 ** WAL module is using shared-memory, return false. 
 */
 SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
 
+#ifdef SQLITE_ENABLE_ZIPVFS
+/* If the WAL file is not empty, return the number of bytes of content
+** stored in each frame (i.e. the db page-size when the WAL was created).
+*/
+SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
+#endif
+
 #endif /* ifndef SQLITE_OMIT_WAL */
 #endif /* _WAL_H_ */
 
 /************** End of wal.h *************************************************/
 /************** Continuing where we left off in pager.c **********************/
 
 
 /******************* NOTES ON THE DESIGN OF THE PAGER ************************
@@ -38898,17 +39033,16 @@ struct PagerSavepoint {
 **   is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX 
 **   sub-codes.
 */
 struct Pager {
   sqlite3_vfs *pVfs;          /* OS functions to use for IO */
   u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
   u8 journalMode;             /* One of the PAGER_JOURNALMODE_* values */
   u8 useJournal;              /* Use a rollback journal on this file */
-  u8 noReadlock;              /* Do not bother to obtain readlocks */
   u8 noSync;                  /* Do not sync the journal if true */
   u8 fullSync;                /* Do extra syncs of the journal for robustness */
   u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
   u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
   u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
   u8 tempFile;                /* zFilename is a temporary file */
   u8 readOnly;                /* True for a read-only database */
   u8 memDb;                   /* True to inhibit all file I/O */
@@ -39146,17 +39280,17 @@ static int assert_pager_state(Pager *p){
       assert( !MEMDB );
       assert( pPager->errCode==SQLITE_OK );
       assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile );
       break;
 
     case PAGER_READER:
       assert( pPager->errCode==SQLITE_OK );
       assert( p->eLock!=UNKNOWN_LOCK );
-      assert( p->eLock>=SHARED_LOCK || p->noReadlock );
+      assert( p->eLock>=SHARED_LOCK );
       break;
 
     case PAGER_WRITER_LOCKED:
       assert( p->eLock!=UNKNOWN_LOCK );
       assert( pPager->errCode==SQLITE_OK );
       if( !pagerUseWal(pPager) ){
         assert( p->eLock>=RESERVED_LOCK );
       }
@@ -41355,17 +41489,17 @@ static int pagerPagecount(Pager *pPager,
 
   /* Query the WAL sub-system for the database size. The WalDbsize()
   ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
   ** if the database size is not available. The database size is not
   ** available from the WAL sub-system if the log file is empty or
   ** contains no valid committed transactions.
   */
   assert( pPager->eState==PAGER_OPEN );
-  assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
+  assert( pPager->eLock>=SHARED_LOCK );
   nPage = sqlite3WalDbsize(pPager->pWal);
 
   /* If the database size was not available from the WAL sub-system,
   ** determine it based on the size of the database file. If the size
   ** of the database file is not an integer multiple of the page-size,
   ** round down to the nearest page. Except, any file larger than 0
   ** bytes in size is considered to contain at least one page.
   */
@@ -41410,17 +41544,17 @@ static int pagerPagecount(Pager *pPager,
 ** function. Because an EXCLUSIVE lock on the db file is required to delete 
 ** a WAL on a none-empty database, this ensures there is no race condition 
 ** between the xAccess() below and an xDelete() being executed by some 
 ** other connection.
 */
 static int pagerOpenWalIfPresent(Pager *pPager){
   int rc = SQLITE_OK;
   assert( pPager->eState==PAGER_OPEN );
-  assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
+  assert( pPager->eLock>=SHARED_LOCK );
 
   if( !pPager->tempFile ){
     int isWal;                    /* True if WAL file exists */
     Pgno nPage;                   /* Size of the database file */
 
     rc = pagerPagecount(pPager, &nPage);
     if( rc ) return rc;
     if( nPage==0 ){
@@ -42573,17 +42707,17 @@ static int pagerStress(void *p, PgHdr *p
 ** This can be used to implement an in-memory database.
 **
 ** The nExtra parameter specifies the number of bytes of space allocated
 ** along with each page reference. This space is available to the user
 ** via the sqlite3PagerGetExtra() API.
 **
 ** The flags argument is used to specify properties that affect the
 ** operation of the pager. It should be passed some bitwise combination
-** of the PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK flags.
+** of the PAGER_* flags.
 **
 ** The vfsFlags parameter is a bitmask to pass to the flags parameter
 ** of the xOpen() method of the supplied VFS when opening files. 
 **
 ** If the pager object is allocated and the specified file opened 
 ** successfully, SQLITE_OK is returned and *ppPager set to point to
 ** the new pager object. If an error occurs, *ppPager is set to NULL
 ** and error code returned. This function may return SQLITE_NOMEM
@@ -42604,17 +42738,16 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
   int rc = SQLITE_OK;      /* Return code */
   int tempFile = 0;        /* True for temp files (incl. in-memory files) */
   int memDb = 0;           /* True if this is an in-memory file */
   int readOnly = 0;        /* True if this is a read-only file */
   int journalFileSize;     /* Bytes to allocate for each journal fd */
   char *zPathname = 0;     /* Full path to database file */
   int nPathname = 0;       /* Number of bytes in zPathname */
   int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
-  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;  /* True to omit read-lock */
   int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
   u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
   const char *zUri = 0;    /* URI args to copy */
   int nUri = 0;            /* Number of bytes of URI args at *zUri */
 
   /* Figure out how much space is required for each journal file-handle
   ** (there are two of them, the main journal and the sub-journal). This
   ** is the maximum space required for an in-memory journal file handle 
@@ -42811,17 +42944,16 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
   nExtra = ROUND8(nExtra);
   sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
                     !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
 
   PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
   IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
 
   pPager->useJournal = (u8)useJournal;
-  pPager->noReadlock = (noReadlock && readOnly) ?1:0;
   /* pPager->stmtOpen = 0; */
   /* pPager->stmtInUse = 0; */
   /* pPager->nRef = 0; */
   /* pPager->stmtSize = 0; */
   /* pPager->stmtJSize = 0; */
   /* pPager->nPage = 0; */
   pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
   /* pPager->state = PAGER_UNLOCK; */
@@ -43033,24 +43165,21 @@ SQLITE_PRIVATE int sqlite3PagerSharedLoc
   assert( assert_pager_state(pPager) );
   assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
   if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
 
   if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
     int bHotJournal = 1;          /* True if there exists a hot journal-file */
 
     assert( !MEMDB );
-    assert( pPager->noReadlock==0 || pPager->readOnly );
-
-    if( pPager->noReadlock==0 ){
-      rc = pager_wait_on_lock(pPager, SHARED_LOCK);
-      if( rc!=SQLITE_OK ){
-        assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
-        goto failed;
-      }
+
+    rc = pager_wait_on_lock(pPager, SHARED_LOCK);
+    if( rc!=SQLITE_OK ){
+      assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
+      goto failed;
     }
 
     /* If a journal file exists, and there is no RESERVED lock on the
     ** database file, then it either needs to be played back or deleted.
     */
     if( pPager->eLock<=SHARED_LOCK ){
       rc = hasHotJournal(pPager, &bHotJournal);
     }
@@ -45048,17 +45177,17 @@ static int pagerExclusiveLock(Pager *pPa
 ** exclusive-locking mode when this function is called, take an EXCLUSIVE
 ** lock on the database file and use heap-memory to store the wal-index
 ** in. Otherwise, use the normal shared-memory.
 */
 static int pagerOpenWal(Pager *pPager){
   int rc = SQLITE_OK;
 
   assert( pPager->pWal==0 && pPager->tempFile==0 );
-  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK || pPager->noReadlock);
+  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
 
   /* If the pager is already in exclusive-mode, the WAL module will use 
   ** heap-memory for the wal-index instead of the VFS shared-memory 
   ** implementation. Take the exclusive lock now, before opening the WAL
   ** file, to make sure this is safe.
   */
   if( pPager->exclusiveMode ){
     rc = pagerExclusiveLock(pPager);
@@ -45163,16 +45292,30 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(
       rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
                            pPager->pageSize, (u8*)pPager->pTmpSpace);
       pPager->pWal = 0;
     }
   }
   return rc;
 }
 
+#ifdef SQLITE_ENABLE_ZIPVFS
+/*
+** A read-lock must be held on the pager when this function is called. If
+** the pager is in WAL mode and the WAL file currently contains one or more
+** frames, return the size in bytes of the page images stored within the
+** WAL frames. Otherwise, if this is not a WAL database or the WAL file
+** is empty, return 0.
+*/
+SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
+  assert( pPager->eState==PAGER_READER );
+  return sqlite3WalFramesize(pPager->pWal);
+}
+#endif
+
 #ifdef SQLITE_HAS_CODEC
 /*
 ** This function is called by the wal module when writing page content
 ** into the log file.
 **
 ** This function returns a pointer to a buffer containing the encrypted
 ** page content. If a malloc fails, this function may return NULL.
 */
@@ -47582,17 +47725,17 @@ SQLITE_PRIVATE int sqlite3WalRead(
     i64 iOffset;
     sz = pWal->hdr.szPage;
     sz = (sz&0xfe00) + ((sz&0x0001)<<16);
     testcase( sz<=32768 );
     testcase( sz>=65536 );
     iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
     *pInWal = 1;
     /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
-    return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset);
+    return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
   }
 
   *pInWal = 0;
   return SQLITE_OK;
 }
 
 
 /* 
@@ -48253,16 +48396,28 @@ SQLITE_PRIVATE int sqlite3WalExclusiveMo
 ** Return true if the argument is non-NULL and the WAL module is using
 ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
 ** WAL module is using shared-memory, return false. 
 */
 SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){
   return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
 }
 
+#ifdef SQLITE_ENABLE_ZIPVFS
+/*
+** If the argument is not NULL, it points to a Wal object that holds a
+** read-lock. This function returns the database page-size if it is known,
+** or zero if it is not (or if pWal is NULL).
+*/
+SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
+  assert( pWal==0 || pWal->readLock>=0 );
+  return (pWal ? pWal->szPage : 0);
+}
+#endif
+
 #endif /* #ifndef SQLITE_OMIT_WAL */
 
 /************** End of wal.c *************************************************/
 /************** Begin file btmutex.c *****************************************/
 /*
 ** 2007 August 27
 **
 ** The author disclaims copyright to this source code.  In place of
@@ -48561,20 +48716,19 @@ struct MemPage {
   u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
   u8 max1bytePayload;  /* min(maxLocal,127) */
   u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
   u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
   u16 cellOffset;      /* Index in aData of first cell pointer */
   u16 nFree;           /* Number of free bytes on the page */
   u16 nCell;           /* Number of cells on this page, local and ovfl */
   u16 maskPage;        /* Mask for page offset */
-  struct _OvflCell {   /* Cells that will not fit on aData[] */
-    u8 *pCell;          /* Pointers to the body of the overflow cell */
-    u16 idx;            /* Insert this cell before idx-th non-overflow cell */
-  } aOvfl[5];
+  u16 aiOvfl[5];       /* Insert the i-th overflow cell before the aiOvfl-th
+                       ** non-overflow cell */
+  u8 *apOvfl[5];       /* Pointers to the body of overflow cells */
   BtShared *pBt;       /* Pointer to BtShared that this page is part of */
   u8 *aData;           /* Pointer to disk image of the page data */
   u8 *aDataEnd;        /* One byte past the end of usable data */
   u8 *aCellIdx;        /* The cell index area */
   DbPage *pDbPage;     /* Pager page handle */
   Pgno pgno;           /* Page number for this page */
 };
 
@@ -48772,28 +48926,30 @@ struct CellInfo {
 ** Fields in this structure are accessed under the BtShared.mutex
 ** found at self->pBt->mutex. 
 */
 struct BtCursor {
   Btree *pBtree;            /* The Btree to which this cursor belongs */
   BtShared *pBt;            /* The BtShared this cursor points to */
   BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
   struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
+#ifndef SQLITE_OMIT_INCRBLOB
+  Pgno *aOverflow;          /* Cache of overflow page locations */
+#endif
   Pgno pgnoRoot;            /* The root page of this tree */
   sqlite3_int64 cachedRowid; /* Next rowid cache.  0 means not valid */
   CellInfo info;            /* A parse of the cell we are pointing at */
   i64 nKey;        /* Size of pKey, or last integer key */
   void *pKey;      /* Saved key that was cursor's last known position */
   int skipNext;    /* Prev() is noop if negative. Next() is noop if positive */
   u8 wrFlag;                /* True if writable */
   u8 atLast;                /* Cursor pointing to the last entry */
   u8 validNKey;             /* True if info.nKey is valid */
   u8 eState;                /* One of the CURSOR_XXX constants (see below) */
 #ifndef SQLITE_OMIT_INCRBLOB
-  Pgno *aOverflow;          /* Cache of overflow page locations */
   u8 isIncrblobHandle;      /* True if this cursor is an incr. io handle */
 #endif
   i16 iPage;                            /* Index of current page in apPage */
   u16 aiIdx[BTCURSOR_MAX_DEPTH];        /* Current index in apPage[i] */
   MemPage *apPage[BTCURSOR_MAX_DEPTH];  /* Pages from root to current page */
 };
 
 /*
@@ -48912,18 +49068,18 @@ struct BtCursor {
 /*
 ** This structure is passed around through all the sanity checking routines
 ** in order to keep track of some global state information.
 */
 typedef struct IntegrityCk IntegrityCk;
 struct IntegrityCk {
   BtShared *pBt;    /* The tree being checked out */
   Pager *pPager;    /* The associated pager.  Also accessible by pBt->pPager */
+  int *anRef;       /* Number of times each page is referenced */
   Pgno nPage;       /* Number of pages in the database */
-  int *anRef;       /* Number of times each page is referenced */
   int mxErr;        /* Stop accumulating errors when this reaches zero */
   int nErr;         /* Number of messages written to zErrMsg so far */
   int mallocFailed; /* A memory allocation error has occurred */
   StrAccum errMsg;  /* Accumulate the error message text here */
 };
 
 /*
 ** Routines to read or write a two- and four-byte big-endian integer values.
@@ -50073,22 +50229,20 @@ static int ptrmapGet(BtShared *pBt, Pgno
 ** This a more complex version of findCell() that works for
 ** pages that do contain overflow cells.
 */
 static u8 *findOverflowCell(MemPage *pPage, int iCell){
   int i;
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   for(i=pPage->nOverflow-1; i>=0; i--){
     int k;
-    struct _OvflCell *pOvfl;
-    pOvfl = &pPage->aOvfl[i];
-    k = pOvfl->idx;
+    k = pPage->aiOvfl[i];
     if( k<=iCell ){
       if( k==iCell ){
-        return pOvfl->pCell;
+        return pPage->apOvfl[i];
       }
       iCell--;
     }
   }
   return findCell(pPage, iCell);
 }
 
 /*
@@ -50892,21 +51046,18 @@ static int btreeInvokeBusyHandler(void *
 ** then an ephemeral database is created.  The ephemeral database might
 ** be exclusively in memory, or it might use a disk-based memory cache.
 ** Either way, the ephemeral database will be automatically deleted 
 ** when sqlite3BtreeClose() is called.
 **
 ** If zFilename is ":memory:" then an in-memory database is created
 ** that is automatically destroyed when it is closed.
 **
-** The "flags" parameter is a bitmask that might contain bits
-** BTREE_OMIT_JOURNAL and/or BTREE_NO_READLOCK.  The BTREE_NO_READLOCK
-** bit is also set if the SQLITE_NoReadlock flags is set in db->flags.
-** These flags are passed through into sqlite3PagerOpen() and must
-** be the same values as PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK.
+** The "flags" parameter is a bitmask that might contain bits like
+** BTREE_OMIT_JOURNAL and/or BTREE_MEMORY.
 **
 ** If the database is already opened in the same database connection
 ** and we are in shared cache mode, then the open will fail with an
 ** SQLITE_CONSTRAINT error.  We cannot allow two or more BtShared
 ** objects in the same database connection since doing so will lead
 ** to problems with locking.
 */
 SQLITE_PRIVATE int sqlite3BtreeOpen(
@@ -50943,19 +51094,16 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
   assert( (flags&0xff)==flags );   /* flags fit in 8 bits */
 
   /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */
   assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 );
 
   /* A BTREE_SINGLE database is always a temporary and/or ephemeral */
   assert( (flags & BTREE_SINGLE)==0 || isTempDb );
 
-  if( db->flags & SQLITE_NoReadlock ){
-    flags |= BTREE_NO_READLOCK;
-  }
   if( isMemdb ){
     flags |= BTREE_MEMORY;
   }
   if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){
     vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB;
   }
   p = sqlite3MallocZero(sizeof(Btree));
   if( !p ){
@@ -51252,17 +51400,17 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btr
       sqlite3BtreeCloseCursor(pTmp);
     }
   }
 
   /* Rollback any active transaction and free the handle structure.
   ** The call to sqlite3BtreeRollback() drops any table-locks held by
   ** this handle.
   */
-  sqlite3BtreeRollback(p);
+  sqlite3BtreeRollback(p, SQLITE_OK);
   sqlite3BtreeLeave(p);
 
   /* If there are still other outstanding references to the shared-btree
   ** structure, return now. The remainder of this procedure cleans 
   ** up the shared-btree.
   */
   assert( p->wantToLock==0 && p->locked==0 );
   if( !p->sharable || removeFromSharingList(pBt) ){
@@ -52490,16 +52638,17 @@ static int countWriteCursors(BtShared *p
 ** to prevent them from trying to use the btree after
 ** the rollback.  The rollback may have deleted tables
 ** or moved root pages, so it is not sufficient to
 ** save the state of the cursor.  The cursor must be
 ** invalidated.
 */
 SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
   BtCursor *p;
+  if( pBtree==0 ) return;
   sqlite3BtreeEnter(pBtree);
   for(p=pBtree->pBt->pCursor; p; p=p->pNext){
     int i;
     sqlite3BtreeClearCursor(p);
     p->eState = CURSOR_FAULT;
     p->skipNext = errCode;
     for(i=0; i<=p->iPage; i++){
       releasePage(p->apPage[i]);
@@ -52513,35 +52662,30 @@ SQLITE_PRIVATE void sqlite3BtreeTripAllC
 ** Rollback the transaction in progress.  All cursors will be
 ** invalided by this operation.  Any attempt to use a cursor
 ** that was open at the beginning of this operation will result
 ** in an error.
 **
 ** This will release the write lock on the database file.  If there
 ** are no active cursors, it also releases the read lock.
 */
-SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p){
+SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){
   int rc;
   BtShared *pBt = p->pBt;
   MemPage *pPage1;
 
   sqlite3BtreeEnter(p);
-  rc = saveAllCursors(pBt, 0, 0);
-#ifndef SQLITE_OMIT_SHARED_CACHE
-  if( rc!=SQLITE_OK ){
-    /* This is a horrible situation. An IO or malloc() error occurred whilst
-    ** trying to save cursor positions. If this is an automatic rollback (as
-    ** the result of a constraint, malloc() failure or IO error) then 
-    ** the cache may be internally inconsistent (not contain valid trees) so
-    ** we cannot simply return the error to the caller. Instead, abort 
-    ** all queries that may be using any of the cursors that failed to save.
-    */
-    sqlite3BtreeTripAllCursors(p, rc);
-  }
-#endif
+  if( tripCode==SQLITE_OK ){
+    rc = tripCode = saveAllCursors(pBt, 0, 0);
+  }else{
+    rc = SQLITE_OK;
+  }
+  if( tripCode ){
+    sqlite3BtreeTripAllCursors(p, tripCode);
+  }
   btreeIntegrity(p);
 
   if( p->inTrans==TRANS_WRITE ){
     int rc2;
 
     assert( TRANS_WRITE==pBt->inTransaction );
     rc2 = sqlite3PagerRollback(pBt->pPager);
     if( rc2!=SQLITE_OK ){
@@ -54730,17 +54874,17 @@ static void dropCell(MemPage *pPage, int
 
 /*
 ** Insert a new cell on pPage at cell index "i".  pCell points to the
 ** content of the cell.
 **
 ** If the cell content will fit on the page, then put it there.  If it
 ** will not fit, then make a copy of the cell content into pTemp if
 ** pTemp is not null.  Regardless of pTemp, allocate a new entry
-** in pPage->aOvfl[] and make it point to the cell content (either
+** in pPage->apOvfl[] and make it point to the cell content (either
 ** in pTemp or the original pCell) and also record its index. 
 ** Allocating a new entry in pPage->aCell[] implies that 
 ** pPage->nOverflow is incremented.
 **
 ** If nSkip is non-zero, then do not copy the first nSkip bytes of the
 ** cell. The caller will overwrite them after this function returns. If
 ** nSkip is non-zero, then pCell may not point to an invalid memory location 
 ** (but pCell+nSkip is always valid).
@@ -54764,36 +54908,37 @@ static void insertCell(
   u8 *endPtr;       /* End of the loop */
 
   int nSkip = (iChild ? 4 : 0);
 
   if( *pRC ) return;
 
   assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
   assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921 );
-  assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) );
+  assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
+  assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   /* The cell should normally be sized correctly.  However, when moving a
   ** malformed cell from a leaf page to an interior page, if the cell size
   ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
   ** might be less than 8 (leaf-size + pointer) on the interior node.  Hence
   ** the term after the || in the following assert(). */
   assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
   if( pPage->nOverflow || sz+2>pPage->nFree ){
     if( pTemp ){
       memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
       pCell = pTemp;
     }
     if( iChild ){
       put4byte(pCell, iChild);
     }
     j = pPage->nOverflow++;
-    assert( j<(int)(sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0])) );
-    pPage->aOvfl[j].pCell = pCell;
-    pPage->aOvfl[j].idx = (u16)i;
+    assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) );
+    pPage->apOvfl[j] = pCell;
+    pPage->aiOvfl[j] = (u16)i;
   }else{
     int rc = sqlite3PagerWrite(pPage->pDbPage);
     if( rc!=SQLITE_OK ){
       *pRC = rc;
       return;
     }
     assert( sqlite3PagerIswriteable(pPage->pDbPage) );
     data = pPage->aData;
@@ -54931,17 +55076,17 @@ static int balance_quick(MemPage *pParen
   ** pPage. Make the parent page writable, so that the new divider cell
   ** may be inserted. If both these operations are successful, proceed.
   */
   rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
 
   if( rc==SQLITE_OK ){
 
     u8 *pOut = &pSpace[4];
-    u8 *pCell = pPage->aOvfl[0].pCell;
+    u8 *pCell = pPage->apOvfl[0];
     u16 szCell = cellSizePtr(pPage, pCell);
     u8 *pStop;
 
     assert( sqlite3PagerIswriteable(pNew->pDbPage) );
     assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
     zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
     assemblePage(pNew, 1, &pCell, &szCell);
 
@@ -55041,17 +55186,17 @@ static int ptrmapCheckPages(MemPage **ap
 ** This function is used to copy the contents of the b-tree node stored 
 ** on page pFrom to page pTo. If page pFrom was not a leaf page, then
 ** the pointer-map entries for each child page are updated so that the
 ** parent page stored in the pointer map is page pTo. If pFrom contained
 ** any cells with overflow page pointers, then the corresponding pointer
 ** map entries are also updated so that the parent page is page pTo.
 **
 ** If pFrom is currently carrying any overflow cells (entries in the
-** MemPage.aOvfl[] array), they are not copied to pTo. 
+** MemPage.apOvfl[] array), they are not copied to pTo. 
 **
 ** Before returning, page pTo is reinitialized using btreeInitPage().
 **
 ** The performance of this function is not critical. It is only used by 
 ** the balance_shallower() and balance_deeper() procedures, neither of
 ** which are called often under normal circumstances.
 */
 static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
@@ -55178,17 +55323,17 @@ static int balance_nonroot(
 #endif
 
   /* At this point pParent may have at most one overflow cell. And if
   ** this overflow cell is present, it must be the cell with 
   ** index iParentIdx. This scenario comes about when this function
   ** is called (indirectly) from sqlite3BtreeDelete().
   */
   assert( pParent->nOverflow==0 || pParent->nOverflow==1 );
-  assert( pParent->nOverflow==0 || pParent->aOvfl[0].idx==iParentIdx );
+  assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx );
 
   if( !aOvflSpace ){
     return SQLITE_NOMEM;
   }
 
   /* Find the sibling pages to balance. Also locate the cells in pParent 
   ** that divide the siblings. An attempt is made to find NN siblings on 
   ** either side of pPage. More siblings are taken from one side, however, 
@@ -55225,18 +55370,18 @@ static int balance_nonroot(
     rc = getAndInitPage(pBt, pgno, &apOld[i]);
     if( rc ){
       memset(apOld, 0, (i+1)*sizeof(MemPage*));
       goto balance_cleanup;
     }
     nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
     if( (i--)==0 ) break;
 
-    if( i+nxDiv==pParent->aOvfl[0].idx && pParent->nOverflow ){
-      apDiv[i] = pParent->aOvfl[0].pCell;
+    if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){
+      apDiv[i] = pParent->apOvfl[0];
       pgno = get4byte(apDiv[i]);
       szNew[i] = cellSizePtr(pParent, apDiv[i]);
       pParent->nOverflow = 0;
     }else{
       apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow);
       pgno = get4byte(apDiv[i]);
       szNew[i] = cellSizePtr(pParent, apDiv[i]);
 
@@ -55667,38 +55812,38 @@ static int balance_nonroot(
     ** block deals with cases 3 and 4 and the one after that, case 5. Since
     ** setting a pointer map entry is a relatively expensive operation, this
     ** code only sets pointer map entries for child or overflow pages that have
     ** actually moved between pages.  */
     MemPage *pNew = apNew[0];
     MemPage *pOld = apCopy[0];
     int nOverflow = pOld->nOverflow;
     int iNextOld = pOld->nCell + nOverflow;
-    int iOverflow = (nOverflow ? pOld->aOvfl[0].idx : -1);
+    int iOverflow = (nOverflow ? pOld->aiOvfl[0] : -1);
     j = 0;                             /* Current 'old' sibling page */
     k = 0;                             /* Current 'new' sibling page */
     for(i=0; i<nCell; i++){
       int isDivider = 0;
       while( i==iNextOld ){
         /* Cell i is the cell immediately following the last cell on old
         ** sibling page j. If the siblings are not leaf pages of an
         ** intkey b-tree, then cell i was a divider cell. */
         assert( j+1 < ArraySize(apCopy) );
         pOld = apCopy[++j];
         iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
         if( pOld->nOverflow ){
           nOverflow = pOld->nOverflow;
-          iOverflow = i + !leafData + pOld->aOvfl[0].idx;
+          iOverflow = i + !leafData + pOld->aiOvfl[0];
         }
         isDivider = !leafData;  
       }
 
       assert(nOverflow>0 || iOverflow<i );
-      assert(nOverflow<2 || pOld->aOvfl[0].idx==pOld->aOvfl[1].idx-1);
-      assert(nOverflow<3 || pOld->aOvfl[1].idx==pOld->aOvfl[2].idx-1);
+      assert(nOverflow<2 || pOld->aiOvfl[0]==pOld->aiOvfl[1]-1);
+      assert(nOverflow<3 || pOld->aiOvfl[1]==pOld->aiOvfl[2]-1);
       if( i==iOverflow ){
         isDivider = 1;
         if( (--nOverflow)>0 ){
           iOverflow++;
         }
       }
 
       if( i==cntNew[k] ){
@@ -55809,17 +55954,20 @@ static int balance_deeper(MemPage *pRoot
   }
   assert( sqlite3PagerIswriteable(pChild->pDbPage) );
   assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
   assert( pChild->nCell==pRoot->nCell );
 
   TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno));
 
   /* Copy the overflow cells from pRoot to pChild */
-  memcpy(pChild->aOvfl, pRoot->aOvfl, pRoot->nOverflow*sizeof(pRoot->aOvfl[0]));
+  memcpy(pChild->aiOvfl, pRoot->aiOvfl,
+         pRoot->nOverflow*sizeof(pRoot->aiOvfl[0]));
+  memcpy(pChild->apOvfl, pRoot->apOvfl,
+         pRoot->nOverflow*sizeof(pRoot->apOvfl[0]));
   pChild->nOverflow = pRoot->nOverflow;
 
   /* Zero the contents of pRoot. Then install pChild as the right-child. */
   zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF);
   put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild);
 
   *ppChild = pChild;
   return SQLITE_OK;
@@ -55872,17 +56020,17 @@ static int balance(BtCursor *pCur){
       MemPage * const pParent = pCur->apPage[iPage-1];
       int const iIdx = pCur->aiIdx[iPage-1];
 
       rc = sqlite3PagerWrite(pParent->pDbPage);
       if( rc==SQLITE_OK ){
 #ifndef SQLITE_OMIT_QUICKBALANCE
         if( pPage->hasData
          && pPage->nOverflow==1
-         && pPage->aOvfl[0].idx==pPage->nCell
+         && pPage->aiOvfl[0]==pPage->nCell
          && pParent->pgno!=1
          && pParent->nCell==iIdx
         ){
           /* Call balance_quick() to create a new sibling of pPage on which
           ** to store the overflow cell. balance_quick() inserts a new cell
           ** into pParent, which may cause pParent overflow. If this
           ** happens, the next interation of the do-loop will balance pParent 
           ** use either balance_nonroot() or balance_deeper(). Until this
@@ -58049,17 +58197,17 @@ SQLITE_API int sqlite3_backup_finish(sql
     pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
     while( *pp!=p ){
       pp = &(*pp)->pNext;
     }
     *pp = p->pNext;
   }
 
   /* If a transaction is still open on the Btree, roll it back. */
-  sqlite3BtreeRollback(p->pDest);
+  sqlite3BtreeRollback(p->pDest, SQLITE_OK);
 
   /* Set the error code of the destination database handle. */
   rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
   sqlite3Error(p->pDestDb, rc, 0);
 
   /* Exit the mutexes and free the backup context structure. */
   if( p->pDestDb ){
     sqlite3_mutex_leave(p->pDestDb->mutex);
@@ -58293,16 +58441,17 @@ SQLITE_PRIVATE int sqlite3VdbeMemGrow(Me
       pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
     }
   }
 
   if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){
     memcpy(pMem->zMalloc, pMem->z, pMem->n);
   }
   if( pMem->flags&MEM_Dyn && pMem->xDel ){
+    assert( pMem->xDel!=SQLITE_DYNAMIC );
     pMem->xDel((void *)(pMem->z));
   }
 
   pMem->z = pMem->zMalloc;
   if( pMem->z==0 ){
     pMem->flags = MEM_Null;
   }else{
     pMem->flags &= ~(MEM_Ephem|MEM_Static);
@@ -58472,16 +58621,17 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinaliz
 SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){
   assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
   if( p->flags&MEM_Agg ){
     sqlite3VdbeMemFinalize(p, p->u.pDef);
     assert( (p->flags & MEM_Agg)==0 );
     sqlite3VdbeMemRelease(p);
   }else if( p->flags&MEM_Dyn && p->xDel ){
     assert( (p->flags&MEM_RowSet)==0 );
+    assert( p->xDel!=SQLITE_DYNAMIC );
     p->xDel((void *)p->z);
     p->xDel = 0;
   }else if( p->flags&MEM_RowSet ){
     sqlite3RowSetClear(p->u.pRowSet);
   }else if( p->flags&MEM_Frame ){
     sqlite3VdbeMemSetNull(p);
   }
 }
@@ -58614,18 +58764,24 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAf
   **        possible integer (ticket #3922)
   **
   ** The second and third terms in the following conditional enforces
   ** the second condition under the assumption that addition overflow causes
   ** values to wrap around.  On x86 hardware, the third term is always
   ** true and could be omitted.  But we leave it in because other
   ** architectures might behave differently.
   */
-  if( pMem->r==(double)pMem->u.i && pMem->u.i>SMALLEST_INT64
-      && ALWAYS(pMem->u.i<LARGEST_INT64) ){
+  if( pMem->r==(double)pMem->u.i
+   && pMem->u.i>SMALLEST_INT64
+#if defined(__i486__) || defined(__x86_64__)
+   && ALWAYS(pMem->u.i<LARGEST_INT64)
+#else
+   && pMem->u.i<LARGEST_INT64
+#endif
+  ){
     pMem->flags |= MEM_Int;
   }
 }
 
 /*
 ** Convert pMem to type integer.  Invalidate any prior representations.
 */
 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){
@@ -59589,24 +59745,21 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(
 **
 ** The VDBE knows that a P2 value is a label because labels are
 ** always negative and P2 values are suppose to be non-negative.
 ** Hence, a negative P2 value is a label that has yet to be resolved.
 **
 ** Zero is returned if a malloc() fails.
 */
 SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){
-  int i;
-  i = p->nLabel++;
+  int i = p->nLabel++;
   assert( p->magic==VDBE_MAGIC_INIT );
-  if( i>=p->nLabelAlloc ){
-    int n = p->nLabelAlloc*2 + 5;
-    p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
-                                       n*sizeof(p->aLabel[0]));
-    p->nLabelAlloc = sqlite3DbMallocSize(p->db, p->aLabel)/sizeof(p->aLabel[0]);
+  if( (i & (i-1))==0 ){
+    p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, 
+                                       (i*2+1)*sizeof(p->aLabel[0]));
   }
   if( p->aLabel ){
     p->aLabel[i] = -1;
   }
   return -1-i;
 }
 
 /*
@@ -61355,42 +61508,16 @@ static void checkActiveVdbeCnt(sqlite3 *
   assert( cnt==db->activeVdbeCnt );
   assert( nWrite==db->writeVdbeCnt );
 }
 #else
 #define checkActiveVdbeCnt(x)
 #endif
 
 /*
-** For every Btree that in database connection db which 
-** has been modified, "trip" or invalidate each cursor in
-** that Btree might have been modified so that the cursor
-** can never be used again.  This happens when a rollback
-*** occurs.  We have to trip all the other cursors, even
-** cursor from other VMs in different database connections,
-** so that none of them try to use the data at which they
-** were pointing and which now may have been changed due
-** to the rollback.
-**
-** Remember that a rollback can delete tables complete and
-** reorder rootpages.  So it is not sufficient just to save
-** the state of the cursor.  We have to invalidate the cursor
-** so that it is never used again.
-*/
-static void invalidateCursorsOnModifiedBtrees(sqlite3 *db){
-  int i;
-  for(i=0; i<db->nDb; i++){
-    Btree *p = db->aDb[i].pBt;
-    if( p && sqlite3BtreeIsInTrans(p) ){
-      sqlite3BtreeTripAllCursors(p, SQLITE_ABORT);
-    }
-  }
-}
-
-/*
 ** If the Vdbe passed as the first argument opened a statement-transaction,
 ** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
 ** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement
 ** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the 
 ** statement transaction is commtted.
 **
 ** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. 
 ** Otherwise SQLITE_OK.
@@ -61544,18 +61671,17 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe 
       */
       if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){
         if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){
           eStatementOp = SAVEPOINT_ROLLBACK;
         }else{
           /* We are forced to roll back the active transaction. Before doing
           ** so, abort any other statements this handle currently has active.
           */
-          invalidateCursorsOnModifiedBtrees(db);
-          sqlite3RollbackAll(db);
+          sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
           sqlite3CloseSavepoints(db);
           db->autoCommit = 1;
         }
       }
     }
 
     /* Check for immediate foreign key violations. */
     if( p->rc==SQLITE_OK ){
@@ -61587,33 +61713,32 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe 
           ** is required. */
           rc = vdbeCommit(db, p);
         }
         if( rc==SQLITE_BUSY && p->readOnly ){
           sqlite3VdbeLeave(p);
           return SQLITE_BUSY;
         }else if( rc!=SQLITE_OK ){
           p->rc = rc;
-          sqlite3RollbackAll(db);
+          sqlite3RollbackAll(db, SQLITE_OK);
         }else{
           db->nDeferredCons = 0;
           sqlite3CommitInternalChanges(db);
         }
       }else{
-        sqlite3RollbackAll(db);
+        sqlite3RollbackAll(db, SQLITE_OK);
       }
       db->nStatement = 0;
     }else if( eStatementOp==0 ){
       if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
         eStatementOp = SAVEPOINT_RELEASE;
       }else if( p->errorAction==OE_Abort ){
         eStatementOp = SAVEPOINT_ROLLBACK;
       }else{
-        invalidateCursorsOnModifiedBtrees(db);
-        sqlite3RollbackAll(db);
+        sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
         sqlite3CloseSavepoints(db);
         db->autoCommit = 1;
       }
     }
   
     /* If eStatementOp is non-zero, then a statement transaction needs to
     ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to
     ** do so. If this operation returns an error, and the current statement
@@ -61623,40 +61748,33 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe 
     if( eStatementOp ){
       rc = sqlite3VdbeCloseStatement(p, eStatementOp);
       if( rc ){
         if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){
           p->rc = rc;
           sqlite3DbFree(db, p->zErrMsg);
           p->zErrMsg = 0;
         }
-        invalidateCursorsOnModifiedBtrees(db);
-        sqlite3RollbackAll(db);
+        sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
         sqlite3CloseSavepoints(db);
         db->autoCommit = 1;
       }
     }
   
     /* If this was an INSERT, UPDATE or DELETE and no statement transaction
     ** has been rolled back, update the database connection change-counter. 
     */
     if( p->changeCntOn ){
       if( eStatementOp!=SAVEPOINT_ROLLBACK ){
         sqlite3VdbeSetChanges(db, p->nChange);
       }else{
         sqlite3VdbeSetChanges(db, 0);
       }
       p->nChange = 0;
     }
-  
-    /* Rollback or commit any schema changes that occurred. */
-    if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){
-      sqlite3ResetInternalSchema(db, -1);
-      db->flags = (db->flags | SQLITE_InternChanges);
-    }
 
     /* Release the locks */
     sqlite3VdbeLeave(p);
   }
 
   /* We have successfully halted and closed the VM.  Record this fact. */
   if( p->pc>=0 ){
     db->activeVdbeCnt--;
@@ -66067,29 +66185,36 @@ fp_math:
   }
   break;
 
 arithmetic_result_is_null:
   sqlite3VdbeMemSetNull(pOut);
   break;
 }
 
-/* Opcode: CollSeq * * P4
+/* Opcode: CollSeq P1 * * P4
 **
 ** P4 is a pointer to a CollSeq struct. If the next call to a user function
 ** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
 ** be returned. This is used by the built-in min(), max() and nullif()
 ** functions.
 **
+** If P1 is not zero, then it is a register that a subsequent min() or
+** max() aggregate will set to 1 if the current row is not the minimum or
+** maximum.  The P1 register is initialized to 0 by this instruction.
+**
 ** The interface used by the implementation of the aforementioned functions
 ** to retrieve the collation sequence set by this opcode is not available
 ** publicly, only to user functions defined in func.c.
 */
 case OP_CollSeq: {
   assert( pOp->p4type==P4_COLLSEQ );
+  if( pOp->p1 ){
+    sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0);
+  }
   break;
 }
 
 /* Opcode: Function P1 P2 P3 P4 P5
 **
 ** Invoke a user function (P4 is a pointer to a Function structure that
 ** defines the function) with P5 arguments taken from register P2 and
 ** successors.  The result of the function is stored in register P3.
@@ -67435,26 +67560,22 @@ case OP_Savepoint: {
       u.ar.pSavepoint && sqlite3StrICmp(u.ar.pSavepoint->zName, u.ar.zName);
       u.ar.pSavepoint = u.ar.pSavepoint->pNext
     ){
       u.ar.iSavepoint++;
     }
     if( !u.ar.pSavepoint ){
       sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.ar.zName);
       rc = SQLITE_ERROR;
-    }else if(
-        db->writeVdbeCnt>0 || (u.ar.p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1)
-    ){
+    }else if( db->writeVdbeCnt>0 && u.ar.p1==SAVEPOINT_RELEASE ){
       /* It is not possible to release (commit) a savepoint if there are
-      ** active write statements. It is not possible to rollback a savepoint
-      ** if there are any active statements at all.
+      ** active write statements.
       */
       sqlite3SetString(&p->zErrMsg, db,
-        "cannot %s savepoint - SQL statements in progress",
-        (u.ar.p1==SAVEPOINT_ROLLBACK ? "rollback": "release")
+        "cannot release savepoint - SQL statements in progress"
       );
       rc = SQLITE_BUSY;
     }else{
 
       /* Determine whether or not this is a transaction savepoint. If so,
       ** and this is a RELEASE command, then the current transaction
       ** is committed.
       */
@@ -67470,16 +67591,19 @@ case OP_Savepoint: {
           p->rc = rc = SQLITE_BUSY;
           goto vdbe_return;
         }
         db->isTransactionSavepoint = 0;
         rc = p->rc;
       }else{
         u.ar.iSavepoint = db->nSavepoint - u.ar.iSavepoint - 1;
         for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){
+          sqlite3BtreeTripAllCursors(db->aDb[u.ar.ii].pBt, SQLITE_ABORT);
+        }
+        for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){
           rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint);
           if( rc!=SQLITE_OK ){
             goto abort_due_to_error;
           }
         }
         if( u.ar.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
           sqlite3ExpirePreparedStatements(db);
           sqlite3ResetInternalSchema(db, -1);
@@ -67539,35 +67663,38 @@ case OP_AutoCommit: {
 
   u.as.desiredAutoCommit = pOp->p1;
   u.as.iRollback = pOp->p2;
   u.as.turnOnAC = u.as.desiredAutoCommit && !db->autoCommit;
   assert( u.as.desiredAutoCommit==1 || u.as.desiredAutoCommit==0 );
   assert( u.as.desiredAutoCommit==1 || u.as.iRollback==0 );
   assert( db->activeVdbeCnt>0 );  /* At least this one VM is active */
 
+#if 0
   if( u.as.turnOnAC && u.as.iRollback && db->activeVdbeCnt>1 ){
     /* If this instruction implements a ROLLBACK and other VMs are
     ** still running, and a transaction is active, return an error indicating
     ** that the other VMs must complete first.
     */
     sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
         "SQL statements in progress");
     rc = SQLITE_BUSY;
-  }else if( u.as.turnOnAC && !u.as.iRollback && db->writeVdbeCnt>0 ){
+  }else
+#endif
+  if( u.as.turnOnAC && !u.as.iRollback && db->writeVdbeCnt>0 ){
     /* If this instruction implements a COMMIT and other VMs are writing
     ** return an error indicating that the other VMs must complete first.
     */
     sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
         "SQL statements in progress");
     rc = SQLITE_BUSY;
   }else if( u.as.desiredAutoCommit!=db->autoCommit ){
     if( u.as.iRollback ){
       assert( u.as.desiredAutoCommit==1 );
-      sqlite3RollbackAll(db);
+      sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
       db->autoCommit = 1;
     }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
       goto vdbe_return;
     }else{
       db->autoCommit = (u8)u.as.desiredAutoCommit;
       if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
         p->pc = pc;
         db->autoCommit = (u8)(1-u.as.desiredAutoCommit);
@@ -67613,17 +67740,17 @@ case OP_AutoCommit: {
 ** database.  If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
 ** on the file.
 **
 ** If a write-transaction is started and the Vdbe.usesStmtJournal flag is
 ** true (this flag is set if the Vdbe may modify more than one row and may
 ** throw an ABORT exception), a statement transaction may also be opened.
 ** More specifically, a statement transaction is opened iff the database
 ** connection is currently not in autocommit mode, or if there are other
-** active statements. A statement transaction allows the affects of this
+** active statements. A statement transaction allows the changes made by this
 ** VDBE to be rolled back after an error without having to roll back the
 ** entire transaction. If no error is encountered, the statement transaction
 ** will automatically commit when the VDBE halts.
 **
 ** If P2 is zero, then a read-lock is obtained on the database file.
 */
 case OP_Transaction: {
 #if 0  /* local variables moved into u.at */
@@ -68623,17 +68750,17 @@ case OP_NewRowid: {           /* out2-pr
           goto abort_due_to_error;
         }
         if( u.bg.res ){
           u.bg.v = 1;   /* IMP: R-61914-48074 */
         }else{
           assert( sqlite3BtreeCursorIsValid(u.bg.pC->pCursor) );
           rc = sqlite3BtreeKeySize(u.bg.pC->pCursor, &u.bg.v);
           assert( rc==SQLITE_OK );   /* Cannot fail following BtreeLast() */
-          if( u.bg.v==MAX_ROWID ){
+          if( u.bg.v>=MAX_ROWID ){
             u.bg.pC->useRandomRowid = 1;
           }else{
             u.bg.v++;   /* IMP: R-29538-34987 */
           }
         }
       }
 
 #ifndef SQLITE_OMIT_AUTOINCREMENT
@@ -69657,16 +69784,17 @@ case OP_ParseSchema: {
       u.by.initData.rc = SQLITE_OK;
       assert( !db->mallocFailed );
       rc = sqlite3_exec(db, u.by.zSql, sqlite3InitCallback, &u.by.initData, 0);
       if( rc==SQLITE_OK ) rc = u.by.initData.rc;
       sqlite3DbFree(db, u.by.zSql);
       db->init.busy = 0;
     }
   }
+  if( rc ) sqlite3ResetInternalSchema(db, -1);
   if( rc==SQLITE_NOMEM ){
     goto no_mem;
   }
   break;
 }
 
 #if !defined(SQLITE_OMIT_ANALYZE)
 /* Opcode: LoadAnalysis P1 * * * *
@@ -69999,17 +70127,16 @@ case OP_Program: {        /* jump */
   p->aMem = aMem = &VdbeFrameMem(u.cc.pFrame)[-1];
   p->nMem = u.cc.pFrame->nChildMem;
   p->nCursor = (u16)u.cc.pFrame->nChildCsr;
   p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
   p->aOp = aOp = u.cc.pProgram->aOp;
   p->nOp = u.cc.pProgram->nOp;
   p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
   p->nOnceFlag = u.cc.pProgram->nOnce;
-  p->nOp = u.cc.pProgram->nOp;
   pc = -1;
   memset(p->aOnceFlag, 0, p->nOnceFlag);
 
   break;
 }
 
 /* Opcode: Param P1 P2 * * *
 **
@@ -70194,27 +70321,33 @@ case OP_AggStep: {
   u.cf.pMem->n++;
   u.cf.ctx.s.flags = MEM_Null;
   u.cf.ctx.s.z = 0;
   u.cf.ctx.s.zMalloc = 0;
   u.cf.ctx.s.xDel = 0;
   u.cf.ctx.s.db = db;
   u.cf.ctx.isError = 0;
   u.cf.ctx.pColl = 0;
+  u.cf.ctx.skipFlag = 0;
   if( u.cf.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
     assert( pOp>p->aOp );
     assert( pOp[-1].p4type==P4_COLLSEQ );
     assert( pOp[-1].opcode==OP_CollSeq );
     u.cf.ctx.pColl = pOp[-1].p4.pColl;
   }
   (u.cf.ctx.pFunc->xStep)(&u.cf.ctx, u.cf.n, u.cf.apVal); /* IMP: R-24505-23230 */
   if( u.cf.ctx.isError ){
     sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cf.ctx.s));
     rc = u.cf.ctx.isError;
   }
+  if( u.cf.ctx.skipFlag ){
+    assert( pOp[-1].opcode==OP_CollSeq );
+    u.cf.i = pOp[-1].p1;
+    if( u.cf.i ) sqlite3VdbeMemSetInt64(&aMem[u.cf.i], 1);
+  }
 
   sqlite3VdbeMemRelease(&u.cf.ctx.s);
 
   break;
 }
 
 /* Opcode: AggFinal P1 P2 * P4 *
 **
@@ -71598,41 +71731,41 @@ typedef struct SorterRecord SorterRecord
 **
 **     aTree[] = { X, 0   0, 6    0, 3, 5, 6 }
 **
 ** In other words, each time we advance to the next sorter element, log2(N)
 ** key comparison operations are required, where N is the number of segments
 ** being merged (rounded up to the next power of 2).
 */
 struct VdbeSorter {
-  int nInMemory;                  /* Current size of pRecord list as PMA */
-  int nTree;                      /* Used size of aTree/aIter (power of 2) */
-  VdbeSorterIter *aIter;          /* Array of iterators to merge */
-  int *aTree;                     /* Current state of incremental merge */
   i64 iWriteOff;                  /* Current write offset within file pTemp1 */
   i64 iReadOff;                   /* Current read offset within file pTemp1 */
-  sqlite3_file *pTemp1;           /* PMA file 1 */
+  int nInMemory;                  /* Current size of pRecord list as PMA */
+  int nTree;                      /* Used size of aTree/aIter (power of 2) */
   int nPMA;                       /* Number of PMAs stored in pTemp1 */
-  SorterRecord *pRecord;          /* Head of in-memory record list */
   int mnPmaSize;                  /* Minimum PMA size, in bytes */
   int mxPmaSize;                  /* Maximum PMA size, in bytes.  0==no limit */
+  VdbeSorterIter *aIter;          /* Array of iterators to merge */
+  int *aTree;                     /* Current state of incremental merge */
+  sqlite3_file *pTemp1;           /* PMA file 1 */
+  SorterRecord *pRecord;          /* Head of in-memory record list */
   UnpackedRecord *pUnpacked;      /* Used to unpack keys */
 };
 
 /*
 ** The following type is an iterator for a PMA. It caches the current key in 
 ** variables nKey/aKey. If the iterator is at EOF, pFile==0.
 */
 struct VdbeSorterIter {
   i64 iReadOff;                   /* Current read offset */
   i64 iEof;                       /* 1 byte past EOF for this iterator */
+  int nAlloc;                     /* Bytes of space at aAlloc */
+  int nKey;                       /* Number of bytes in key */
   sqlite3_file *pFile;            /* File iterator is reading from */
-  int nAlloc;                     /* Bytes of space at aAlloc */
   u8 *aAlloc;                     /* Allocated space */
-  int nKey;                       /* Number of bytes in key */
   u8 *aKey;                       /* Pointer to current key */
 };
 
 /*
 ** A structure to store a single record. All in-memory records are connected
 ** together into a linked list headed at VdbeSorter.pRecord using the 
 ** SorterRecord.pNext pointer.
 */
@@ -75109,18 +75242,19 @@ SQLITE_PRIVATE Expr *sqlite3ExprDup(sqli
 SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
   ExprList *pNew;
   struct ExprList_item *pItem, *pOldItem;
   int i;
   if( p==0 ) return 0;
   pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
   if( pNew==0 ) return 0;
   pNew->iECursor = 0;
-  pNew->nExpr = pNew->nAlloc = p->nExpr;
-  pNew->a = pItem = sqlite3DbMallocRaw(db,  p->nExpr*sizeof(p->a[0]) );
+  pNew->nExpr = i = p->nExpr;
+  if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){}
+  pNew->a = pItem = sqlite3DbMallocRaw(db,  i*sizeof(p->a[0]) );
   if( pItem==0 ){
     sqlite3DbFree(db, pNew);
     return 0;
   } 
   pOldItem = p->a;
   for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
     Expr *pOldExpr = pOldItem->pExpr;
     pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags);
@@ -75178,22 +75312,25 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDu
   return pNew;
 }
 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
   IdList *pNew;
   int i;
   if( p==0 ) return 0;
   pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
   if( pNew==0 ) return 0;
-  pNew->nId = pNew->nAlloc = p->nId;
+  pNew->nId = p->nId;
   pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) );
   if( pNew->a==0 ){
     sqlite3DbFree(db, pNew);
     return 0;
   }
+  /* Note that because the size of the allocation for p->a[] is not
+  ** necessarily a power of two, sqlite3IdListAppend() may not be called
+  ** on the duplicate created by this function. */
   for(i=0; i<p->nId; i++){
     struct IdList_item *pNewItem = &pNew->a[i];
     struct IdList_item *pOldItem = &p->a[i];
     pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
     pNewItem->idx = pOldItem->idx;
   }
   return pNew;
 }
@@ -75245,27 +75382,26 @@ SQLITE_PRIVATE ExprList *sqlite3ExprList
   Expr *pExpr             /* Expression to be appended. Might be NULL */
 ){
   sqlite3 *db = pParse->db;
   if( pList==0 ){
     pList = sqlite3DbMallocZero(db, sizeof(ExprList) );
     if( pList==0 ){
       goto no_mem;
     }
-    assert( pList->nAlloc==0 );
-  }
-  if( pList->nAlloc<=pList->nExpr ){
+    pList->a = sqlite3DbMallocRaw(db, sizeof(pList->a[0]));
+    if( pList->a==0 ) goto no_mem;
+  }else if( (pList->nExpr & (pList->nExpr-1))==0 ){
     struct ExprList_item *a;
-    int n = pList->nAlloc*2 + 4;
-    a = sqlite3DbRealloc(db, pList->a, n*sizeof(pList->a[0]));
+    assert( pList->nExpr>0 );
+    a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0]));
     if( a==0 ){
       goto no_mem;
     }
     pList->a = a;
-    pList->nAlloc = sqlite3DbMallocSize(db, a)/sizeof(a[0]);
   }
   assert( pList->a!=0 );
   if( 1 ){
     struct ExprList_item *pItem = &pList->a[pList->nExpr++];
     memset(pItem, 0, sizeof(*pItem));
     pItem->pExpr = pExpr;
   }
   return pList;
@@ -75346,18 +75482,17 @@ SQLITE_PRIVATE void sqlite3ExprListCheck
 
 /*
 ** Delete an entire expression list.
 */
 SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
   int i;
   struct ExprList_item *pItem;
   if( pList==0 ) return;
-  assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
-  assert( pList->nExpr<=pList->nAlloc );
+  assert( pList->a!=0 || pList->nExpr==0 );
   for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
     sqlite3ExprDelete(db, pItem->pExpr);
     sqlite3DbFree(db, pItem->zName);
     sqlite3DbFree(db, pItem->zSpan);
   }
   sqlite3DbFree(db, pList->a);
   sqlite3DbFree(db, pList);
 }
@@ -78028,37 +78163,33 @@ SQLITE_PRIVATE int sqlite3ExprListCompar
 ** the new element.  Return a negative number if malloc fails.
 */
 static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){
   int i;
   pInfo->aCol = sqlite3ArrayAllocate(
        db,
        pInfo->aCol,
        sizeof(pInfo->aCol[0]),
-       3,
        &pInfo->nColumn,
-       &pInfo->nColumnAlloc,
        &i
   );
   return i;
 }    
 
 /*
 ** Add a new element to the pAggInfo->aFunc[] array.  Return the index of
 ** the new element.  Return a negative number if malloc fails.
 */
 static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){
   int i;
   pInfo->aFunc = sqlite3ArrayAllocate(
        db, 
        pInfo->aFunc,
        sizeof(pInfo->aFunc[0]),
-       3,
        &pInfo->nFunc,
-       &pInfo->nFuncAlloc,
        &i
   );
   return i;
 }    
 
 /*
 ** This is the xExprCallback for a tree walker.  It is used to
 ** implement sqlite3ExprAnalyzeAggregates().  See sqlite3ExprAnalyzeAggregates
@@ -78825,17 +78956,17 @@ SQLITE_PRIVATE void sqlite3AlterRenameTa
             "ELSE sqlite_rename_table(sql, %Q) END, "
 #endif
           "tbl_name = %Q, "
           "name = CASE "
             "WHEN type='table' THEN %Q "
             "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
              "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
             "ELSE name END "
-      "WHERE tbl_name=%Q AND "
+      "WHERE tbl_name=%Q COLLATE nocase AND "
           "(type='table' OR type='index' OR type='trigger');", 
       zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
 #ifndef SQLITE_OMIT_TRIGGER
       zName,
 #endif
       zName, nTabName, zTabName
   );
 
@@ -80055,16 +80186,17 @@ static int loadStat3(sqlite3 *db, const 
   int rc;                       /* Result codes from subroutines */
   sqlite3_stmt *pStmt = 0;      /* An SQL statement being run */
   char *zSql;                   /* Text of the SQL statement */
   Index *pPrevIdx = 0;          /* Previous index in the loop */
   int idx = 0;                  /* slot in pIdx->aSample[] for next sample */
   int eType;                    /* Datatype of a sample */
   IndexSample *pSample;         /* A slot in pIdx->aSample[] */
 
+  assert( db->lookaside.bEnabled==0 );
   if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){
     return SQLITE_OK;
   }
 
   zSql = sqlite3MPrintf(db, 
       "SELECT idx,count(*) FROM %Q.sqlite_stat3"
       " GROUP BY idx", zDb);
   if( !zSql ){
@@ -80081,17 +80213,17 @@ static int loadStat3(sqlite3 *db, const 
 
     zIndex = (char *)sqlite3_column_text(pStmt, 0);
     if( zIndex==0 ) continue;
     nSample = sqlite3_column_int(pStmt, 1);
     pIdx = sqlite3FindIndex(db, zIndex, zDb);
     if( pIdx==0 ) continue;
     assert( pIdx->nSample==0 );
     pIdx->nSample = nSample;
-    pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) );
+    pIdx->aSample = sqlite3DbMallocZero(db, nSample*sizeof(IndexSample));
     pIdx->avgEq = pIdx->aiRowEst[1];
     if( pIdx->aSample==0 ){
       db->mallocFailed = 1;
       sqlite3_finalize(pStmt);
       return SQLITE_NOMEM;
     }
   }
   rc = sqlite3_finalize(pStmt);
@@ -80154,17 +80286,17 @@ static int loadStat3(sqlite3 *db, const 
               sqlite3_column_blob(pStmt, 4):
               sqlite3_column_text(pStmt, 4)
            );
         int n = z ? sqlite3_column_bytes(pStmt, 4) : 0;
         pSample->nByte = n;
         if( n < 1){
           pSample->u.z = 0;
         }else{
-          pSample->u.z = sqlite3Malloc(n);
+          pSample->u.z = sqlite3DbMallocRaw(db, n);
           if( pSample->u.z==0 ){
             db->mallocFailed = 1;
             sqlite3_finalize(pStmt);
             return SQLITE_NOMEM;
           }
           memcpy(pSample->u.z, z, n);
         }
       }
@@ -80230,17 +80362,20 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(s
     rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
     sqlite3DbFree(db, zSql);
   }
 
 
   /* Load the statistics from the sqlite_stat3 table. */
 #ifdef SQLITE_ENABLE_STAT3
   if( rc==SQLITE_OK ){
+    int lookasideEnabled = db->lookaside.bEnabled;
+    db->lookaside.bEnabled = 0;
     rc = loadStat3(db, sInfo.zDatabase);
+    db->lookaside.bEnabled = lookasideEnabled;
   }
 #endif
 
   if( rc==SQLITE_NOMEM ){
     db->mallocFailed = 1;
   }
   return rc;
 }
@@ -82694,17 +82829,16 @@ SQLITE_PRIVATE void sqlite3EndTable(
     pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName,
                              sqlite3Strlen30(p->zName),p);
     if( pOld ){
       assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
       db->mallocFailed = 1;
       return;
     }
     pParse->pNewTable = 0;
-    db->nTable++;
     db->flags |= SQLITE_InternChanges;
 
 #ifndef SQLITE_OMIT_ALTERTABLE
     if( !p->pSelect ){
       const char *zName = (const char *)pParse->sNameToken.z;
       int nName;
       assert( !pSelect && pCons && pEnd );
       if( pCons->z==0 ){
@@ -84115,61 +84249,54 @@ exit_drop_index:
 ** This routine returns a pointer to the array of objects.  This
 ** might be the same as the pArray parameter or it might be a different
 ** pointer if the array was resized.
 */
 SQLITE_PRIVATE void *sqlite3ArrayAllocate(
   sqlite3 *db,      /* Connection to notify of malloc failures */
   void *pArray,     /* Array of objects.  Might be reallocated */
   int szEntry,      /* Size of each object in the array */
-  int initSize,     /* Suggested initial allocation, in elements */
   int *pnEntry,     /* Number of objects currently in use */
-  int *pnAlloc,     /* Current size of the allocation, in elements */
   int *pIdx         /* Write the index of a new slot here */
 ){
   char *z;
-  if( *pnEntry >= *pnAlloc ){
-    void *pNew;
-    int newSize;
-    newSize = (*pnAlloc)*2 + initSize;
-    pNew = sqlite3DbRealloc(db, pArray, newSize*szEntry);
+  int n = *pnEntry;
+  if( (n & (n-1))==0 ){
+    int sz = (n==0) ? 1 : 2*n;
+    void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry);
     if( pNew==0 ){
       *pIdx = -1;
       return pArray;
     }
-    *pnAlloc = sqlite3DbMallocSize(db, pNew)/szEntry;
     pArray = pNew;
   }
   z = (char*)pArray;
-  memset(&z[*pnEntry * szEntry], 0, szEntry);
-  *pIdx = *pnEntry;
+  memset(&z[n * szEntry], 0, szEntry);
+  *pIdx = n;
   ++*pnEntry;
   return pArray;
 }
 
 /*
 ** Append a new element to the given IdList.  Create a new IdList if
 ** need be.
 **
 ** A new IdList is returned, or NULL if malloc() fails.
 */
 SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
   int i;
   if( pList==0 ){
     pList = sqlite3DbMallocZero(db, sizeof(IdList) );
     if( pList==0 ) return 0;
-    pList->nAlloc = 0;
   }
   pList->a = sqlite3ArrayAllocate(
       db,
       pList->a,
       sizeof(pList->a[0]),
-      5,
       &pList->nId,
-      &pList->nAlloc,
       &i
   );
   if( i<0 ){
     sqlite3IdListDelete(db, pList);
     return 0;
   }
   pList->a[i].zName = sqlite3NameFromToken(db, pToken);
   return pList;
@@ -86020,16 +86147,24 @@ SQLITE_PRIVATE int sqlite3GenerateIndexK
 /*
 ** Return the collating function associated with a function.
 */
 static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
   return context->pColl;
 }
 
 /*
+** Indicate that the accumulator load should be skipped on this
+** iteration of the aggregate loop.
+*/
+static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){
+  context->skipFlag = 1;
+}
+
+/*
 ** Implementation of the non-aggregate min() and max() functions
 */
 static void minmaxFunc(
   sqlite3_context *context,
   int argc,
   sqlite3_value **argv
 ){
   int i;
@@ -86399,17 +86534,17 @@ static void randomFunc(
     /* We need to prevent a random number of 0x8000000000000000 
     ** (or -9223372036854775808) since when you do abs() of that
     ** number of you get the same value back again.  To do this
     ** in a way that is testable, mask the sign bit off of negative
     ** values, resulting in a positive value.  Then take the 
     ** 2s complement of that positive value.  The end result can
     ** therefore be no less than -9223372036854775807.
     */
-    r = -(r ^ (((sqlite3_int64)1)<<63));
+    r = -(r & LARGEST_INT64);
   }
   sqlite3_result_int64(context, r);
 }
 
 /*
 ** Implementation of randomblob(N).  Return a random blob
 ** that is N bytes long.
 */
@@ -87325,46 +87460,49 @@ static void minmaxStep(
   sqlite3_context *context, 
   int NotUsed, 
   sqlite3_value **argv
 ){
   Mem *pArg  = (Mem *)argv[0];
   Mem *pBest;
   UNUSED_PARAMETER(NotUsed);
 
-  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
   pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
   if( !pBest ) return;
 
-  if( pBest->flags ){
+  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
+    if( pBest->flags ) sqlite3SkipAccumulatorLoad(context);
+  }else if( pBest->flags ){
     int max;
     int cmp;
     CollSeq *pColl = sqlite3GetFuncCollSeq(context);
     /* This step function is used for both the min() and max() aggregates,
     ** the only difference between the two being that the sense of the
     ** comparison is inverted. For the max() aggregate, the
     ** sqlite3_user_data() function returns (void *)-1. For min() it
     ** returns (void *)db, where db is the sqlite3* database pointer.
     ** Therefore the next statement sets variable 'max' to 1 for the max()
     ** aggregate, or 0 for min().
     */
     max = sqlite3_user_data(context)!=0;
     cmp = sqlite3MemCompare(pBest, pArg, pColl);
     if( (max && cmp<0) || (!max && cmp>0) ){
       sqlite3VdbeMemCopy(pBest, pArg);
+    }else{
+      sqlite3SkipAccumulatorLoad(context);
     }
   }else{
     sqlite3VdbeMemCopy(pBest, pArg);
   }
 }
 static void minMaxFinalize(sqlite3_context *context){
   sqlite3_value *pRes;
   pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
   if( pRes ){
-    if( ALWAYS(pRes->flags) ){
+    if( pRes->flags ){
       sqlite3_result_value(context, pRes);
     }
     sqlite3VdbeMemRelease(pRes);
   }
 }
 
 /*
 ** group_concat(EXPR, ?SEPARATOR?)
@@ -91936,47 +92074,48 @@ SQLITE_PRIVATE void sqlite3AutoLoadExten
 **
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 */
 
 /*
 ** Interpret the given string as a safety level.  Return 0 for OFF,
 ** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or 
-** unrecognized string argument.
+** unrecognized string argument.  The FULL option is disallowed
+** if the omitFull parameter it 1.
 **
 ** Note that the values returned are one less that the values that
 ** should be passed into sqlite3BtreeSetSafetyLevel().  The is done
 ** to support legacy SQL code.  The safety level used to be boolean
 ** and older scripts may have used numbers 0 for OFF and 1 for ON.
 */
-static u8 getSafetyLevel(const char *z){
+static u8 getSafetyLevel(const char *z, int omitFull, int dflt){
                              /* 123456789 123456789 */
   static const char zText[] = "onoffalseyestruefull";
   static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
   static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
   static const u8 iValue[] =  {1, 0, 0, 0, 1, 1, 2};
   int i, n;
   if( sqlite3Isdigit(*z) ){
     return (u8)sqlite3Atoi(z);
   }
   n = sqlite3Strlen30(z);
-  for(i=0; i<ArraySize(iLength); i++){
+  for(i=0; i<ArraySize(iLength)-omitFull; i++){
     if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
       return iValue[i];
     }
   }
-  return 1;
+  return dflt;
 }
 
 /*
 ** Interpret the given string as a boolean value.
 */
-SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z){
-  return getSafetyLevel(z)&1;
+SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, int dflt){
+  return getSafetyLevel(z,1,dflt)!=0;
 }
 
 /* The sqlite3GetBoolean() function is used by other modules but the
 ** remainder of this file is specific to PRAGMA processing.  So omit
 ** the rest of the file if PRAGMAs are omitted from the build.
 */
 #if !defined(SQLITE_OMIT_PRAGMA)
 
@@ -92109,17 +92248,16 @@ static int flagPragma(Parse *pParse, con
     { "vdbe_listing",             SQLITE_VdbeListing   },
     { "vdbe_trace",               SQLITE_VdbeTrace     },
 #endif
 #ifndef SQLITE_OMIT_CHECK
     { "ignore_check_constraints", SQLITE_IgnoreChecks  },
 #endif
     /* The following is VERY experimental */
     { "writable_schema",          SQLITE_WriteSchema|SQLITE_RecoveryMode },
-    { "omit_readlock",            SQLITE_NoReadlock    },
 
     /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
     ** flag if there are any active statements. */
     { "read_uncommitted",         SQLITE_ReadUncommitted },
     { "recursive_triggers",       SQLITE_RecTriggers },
 
     /* This flag may only be set if both foreign-key and trigger support
     ** are present in the build.  */
@@ -92141,17 +92279,17 @@ static int flagPragma(Parse *pParse, con
         }else{
           int mask = p->mask;          /* Mask of bits to set or clear. */
           if( db->autoCommit==0 ){
             /* Foreign key support may not be enabled or disabled while not
             ** in auto-commit mode.  */
             mask &= ~(SQLITE_ForeignKeys);
           }
 
-          if( sqlite3GetBoolean(zRight) ){
+          if( sqlite3GetBoolean(zRight, 0) ){
             db->flags |= mask;
           }else{
             db->flags &= ~mask;
           }
 
           /* Many of the flag-pragmas modify the code generated by the SQL 
           ** compiler (eg. count_changes). So add an opcode to expire all
           ** compiled SQL statements after modifying a pragma value.
@@ -92232,19 +92370,22 @@ SQLITE_PRIVATE void sqlite3Pragma(
   Token *pValue,      /* Token for <value>, or NULL */
   int minusFlag       /* True if a '-' sign preceded <value> */
 ){
   char *zLeft = 0;       /* Nul-terminated UTF-8 string <id> */
   char *zRight = 0;      /* Nul-terminated UTF-8 string <value>, or NULL */
   const char *zDb = 0;   /* The database name */
   Token *pId;            /* Pointer to <id> token */
   int iDb;               /* Database index for <database> */
-  sqlite3 *db = pParse->db;
-  Db *pDb;
-  Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db);
+  char *aFcntl[4];       /* Argument to SQLITE_FCNTL_PRAGMA */
+  int rc;                      /* return value form SQLITE_FCNTL_PRAGMA */
+  sqlite3 *db = pParse->db;    /* The database connection */
+  Db *pDb;                     /* The specific database being pragmaed */
+  Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db);  /* Prepared statement */
+
   if( v==0 ) return;
   sqlite3VdbeRunOnlyOnce(v);
   pParse->nMem = 2;
 
   /* Interpret the [database.] part of the pragma statement. iDb is the
   ** index of the database this pragma is being applied to in db.aDb[]. */
   iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
   if( iDb<0 ) return;
@@ -92265,16 +92406,44 @@ SQLITE_PRIVATE void sqlite3Pragma(
     zRight = sqlite3NameFromToken(db, pValue);
   }
 
   assert( pId2 );
   zDb = pId2->n>0 ? pDb->zName : 0;
   if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
     goto pragma_out;
   }
+
+  /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS
+  ** connection.  If it returns SQLITE_OK, then assume that the VFS
+  ** handled the pragma and generate a no-op prepared statement.
+  */
+  aFcntl[0] = 0;
+  aFcntl[1] = zLeft;
+  aFcntl[2] = zRight;
+  aFcntl[3] = 0;
+  rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
+  if( rc==SQLITE_OK ){
+    if( aFcntl[0] ){
+      int mem = ++pParse->nMem;
+      sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0);
+      sqlite3VdbeSetNumCols(v, 1);
+      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
+      sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
+      sqlite3_free(aFcntl[0]);
+    }
+  }else if( rc!=SQLITE_NOTFOUND ){
+    if( aFcntl[0] ){
+      sqlite3ErrorMsg(pParse, "%s", aFcntl[0]);
+      sqlite3_free(aFcntl[0]);
+    }
+    pParse->nErr++;
+    pParse->rc = rc;
+  }else
+                            
  
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
   /*
   **  PRAGMA [database.]default_cache_size
   **  PRAGMA [database.]default_cache_size=N
   **
   ** The first form reports the current persistent setting for the
   ** page cache size.  The value returned is the maximum number of
@@ -92357,17 +92526,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
   ** secure_delete flag.  The second form changes the secure_delete
   ** flag setting and reports thenew value.
   */
   if( sqlite3StrICmp(zLeft,"secure_delete")==0 ){
     Btree *pBt = pDb->pBt;
     int b = -1;
     assert( pBt!=0 );
     if( zRight ){
-      b = sqlite3GetBoolean(zRight);
+      b = sqlite3GetBoolean(zRight, 0);
     }
     if( pId2->n==0 && b>=0 ){
       int ii;
       for(ii=0; ii<db->nDb; ii++){
         sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b);
       }
     }
     b = sqlite3BtreeSecureDelete(pBt, b);
@@ -92552,17 +92721,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
       assert( eAuto>=0 && eAuto<=2 );
       db->nextAutovac = (u8)eAuto;
       if( ALWAYS(eAuto>=0) ){
         /* Call SetAutoVacuum() to set initialize the internal auto and
         ** incr-vacuum flags. This is required in case this connection
         ** creates the database file. It is important that it is created
         ** as an auto-vacuum capable db.
         */
-        int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
+        rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
         if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){
           /* When setting the auto_vacuum mode to either "full" or 
           ** "incremental", write the value of meta[6] in the database
           ** file. Before writing to meta[6], check that meta[3] indicates
           ** that this really is an auto-vacuum capable database.
           */
           static const VdbeOpList setMeta6[] = {
             { OP_Transaction,    0,         1,                 0},    /* 0 */
@@ -92670,17 +92839,16 @@ SQLITE_PRIVATE void sqlite3Pragma(
         sqlite3VdbeSetColName(v, 0, COLNAME_NAME, 
             "temp_store_directory", SQLITE_STATIC);
         sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0);
         sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
       }
     }else{
 #ifndef SQLITE_OMIT_WSD
       if( zRight[0] ){
-        int rc;
         int res;
         rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
         if( rc!=SQLITE_OK || res==0 ){
           sqlite3ErrorMsg(pParse, "not a writable directory");
           goto pragma_out;
         }
       }
       if( SQLITE_TEMP_STORE==0
@@ -92762,17 +92930,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     if( !zRight ){
       returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
     }else{
       if( !db->autoCommit ){
         sqlite3ErrorMsg(pParse, 
             "Safety level may not be changed inside a transaction");
       }else{
-        pDb->safety_level = getSafetyLevel(zRight)+1;
+        pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
       }
     }
   }else
 #endif /* SQLITE_OMIT_PAGER_PRAGMAS */
 
 #ifndef SQLITE_OMIT_FLAG_PRAGMAS
   if( flagPragma(pParse, zLeft, zRight) ){
     /* The flagPragma() subroutine also generates any necessary code
@@ -92961,31 +93129,31 @@ SQLITE_PRIVATE void sqlite3Pragma(
       }
     }
   }else
 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
 
 #ifndef NDEBUG
   if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
     if( zRight ){
-      if( sqlite3GetBoolean(zRight) ){
+      if( sqlite3GetBoolean(zRight, 0) ){
         sqlite3ParserTrace(stderr, "parser: ");
       }else{
         sqlite3ParserTrace(0, 0);
       }
     }
   }else
 #endif
 
   /* Reinstall the LIKE and GLOB functions.  The variant of LIKE
   ** used will be case sensitive or not depending on the RHS.
   */
   if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){
     if( zRight ){
-      sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight));
+      sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
     }
   }else
 
 #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
 # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
 #endif
 
 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
@@ -94401,16 +94569,17 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
     assert( db->mallocFailed );
     pNew = &standin;
     memset(pNew, 0, sizeof(*pNew));
   }
   if( pEList==0 ){
     pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
   }
   pNew->pEList = pEList;
+  if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
   pNew->pSrc = pSrc;
   pNew->pWhere = pWhere;
   pNew->pGroupBy = pGroupBy;
   pNew->pHaving = pHaving;
   pNew->pOrderBy = pOrderBy;
   pNew->selFlags = isDistinct ? SF_Distinct : 0;
   pNew->op = TK_SELECT;
   pNew->pLimit = pLimit;
@@ -95585,17 +95754,17 @@ static int selectColumnsFromExprList(
   int i, j;                   /* Loop counters */
   int cnt;                    /* Index added to make the name unique */
   Column *aCol, *pCol;        /* For looping over result columns */
   int nCol;                   /* Number of columns in the result set */
   Expr *p;                    /* Expression for a single result column */
   char *zName;                /* Column name */
   int nName;                  /* Size of name in zName[] */
 
-  *pnCol = nCol = pEList->nExpr;
+  *pnCol = nCol = pEList ? pEList->nExpr : 0;
   aCol = *paCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
   if( aCol==0 ) return SQLITE_NOMEM;
   for(i=0, pCol=aCol; i<nCol; i++, pCol++){
     /* Get an appropriate name for the column
     */
     p = pEList->a[i].pExpr;
     assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
                || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
@@ -95939,18 +96108,22 @@ static int multiSelect(
     dest.eDest = SRT_Table;
   }
 
   /* Make sure all SELECTs in the statement have the same number of elements
   ** in their result sets.
   */
   assert( p->pEList && pPrior->pEList );
   if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
-    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
-      " do not have the same number of result columns", selectOpName(p->op));
+    if( p->selFlags & SF_Values ){
+      sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
+    }else{
+      sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
+        " do not have the same number of result columns", selectOpName(p->op));
+    }
     rc = 1;
     goto multi_select_end;
   }
 
   /* Compound SELECTs that have an ORDER BY clause are handled separately.
   */
   if( p->pOrderBy ){
     return multiSelectOrderBy(pParse, p, pDest);
@@ -96556,17 +96729,17 @@ static int multiSelectOrderBy(
         if( pItem->iOrderByCol==i ) break;
       }
       if( j==nOrderBy ){
         Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
         if( pNew==0 ) return SQLITE_NOMEM;
         pNew->flags |= EP_IntValue;
         pNew->u.iValue = i;
         pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
-        pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i;
+        if( pOrderBy ) pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i;
       }
     }
   }
 
   /* Compute the comparison permutation and keyinfo that is used with
   ** the permutation used to determine if the next
   ** row of results comes from selectA or selectB.  Also add explicit
   ** collations to the ORDER BY clause terms so that when the subqueries
@@ -97919,16 +98092,18 @@ static void finalizeAggFunctions(Parse *
 
 /*
 ** Update the accumulator memory cells for an aggregate based on
 ** the current cursor position.
 */
 static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
   Vdbe *v = pParse->pVdbe;
   int i;
+  int regHit = 0;
+  int addrHitTest = 0;
   struct AggInfo_func *pF;
   struct AggInfo_col *pC;
 
   pAggInfo->directMode = 1;
   sqlite3ExprCacheClear(pParse);
   for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
     int nArg;
     int addrNext = 0;
@@ -97954,17 +98129,18 @@ static void updateAccumulator(Parse *pPa
       int j;
       assert( pList!=0 );  /* pList!=0 if pF->pFunc has NEEDCOLL */
       for(j=0, pItem=pList->a; !pColl && j<nArg; j++, pItem++){
         pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
       }
       if( !pColl ){
         pColl = pParse->db->pDfltColl;
       }
-      sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
+      if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
+      sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
     }
     sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
                       (void*)pF->pFunc, P4_FUNCDEF);
     sqlite3VdbeChangeP5(v, (u8)nArg);
     sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
     sqlite3ReleaseTempRange(pParse, regAgg, nArg);
     if( addrNext ){
       sqlite3VdbeResolveLabel(v, addrNext);
@@ -97977,22 +98153,28 @@ static void updateAccumulator(Parse *pPa
   ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value
   ** to pC->iMem. But by the time the value is used, the original register
   ** may have been used, invalidating the underlying buffer holding the
   ** text or blob value. See ticket [883034dcb5].
   **
   ** Another solution would be to change the OP_SCopy used to copy cached
   ** values to an OP_Copy.
   */
+  if( regHit ){
+    addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit);
+  }
   sqlite3ExprCacheClear(pParse);
   for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
     sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
   }
   pAggInfo->directMode = 0;
   sqlite3ExprCacheClear(pParse);
+  if( addrHitTest ){
+    sqlite3VdbeJumpHere(v, addrHitTest);
+  }
 }
 
 /*
 ** Add a single OP_Explain instruction to the VDBE to explain a simple
 ** count(*) query ("SELECT count(*) FROM pTab").
 */
 #ifndef SQLITE_OMIT_EXPLAIN
 static void explainSimpleCount(
@@ -98923,17 +99105,17 @@ SQLITE_PRIVATE void sqlite3ExplainSelect
     sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op));
   }
   sqlite3ExplainPrintf(pVdbe, "END");
   sqlite3ExplainPop(pVdbe);
 }
 
 /* End of the structure debug printing code
 *****************************************************************************/
-#endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */
+#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
 
 /************** End of select.c **********************************************/
 /************** Begin file table.c *******************************************/
 /*
 ** 2001 September 15
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
@@ -101103,43 +101285,47 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char
     extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
     int nKey;
     char *zKey;
     sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
     if( nKey ) db->nextPagesize = 0;
   }
 #endif
 
+  rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
+  if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
+  /* Begin a transaction and take an exclusive lock on the main database
+  ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
+  ** to ensure that we do not try to change the page-size on a WAL database.
+  */
+  rc = execSql(db, pzErrMsg, "BEGIN;");
+  if( rc!=SQLITE_OK ) goto end_of_vacuum;
+  rc = sqlite3BtreeBeginTrans(pMain, 2);
+  if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
   /* Do not attempt to change the page size for a WAL database */
   if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
                                                ==PAGER_JOURNALMODE_WAL ){
     db->nextPagesize = 0;
   }
 
   if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
    || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
    || NEVER(db->mallocFailed)
   ){
     rc = SQLITE_NOMEM;
     goto end_of_vacuum;
   }
-  rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
-  if( rc!=SQLITE_OK ){
-    goto end_of_vacuum;
-  }
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
   sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac :
                                            sqlite3BtreeGetAutoVacuum(pMain));
 #endif
 
-  /* Begin a transaction */
-  rc = execSql(db, pzErrMsg, "BEGIN EXCLUSIVE;");
-  if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
   /* Query the schema of the main database. Create a mirror schema
   ** in the temporary database.
   */
   rc = execExecSql(db, pzErrMsg,
       "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
       "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
       "   AND rootpage>0"
   );
@@ -101550,23 +101736,24 @@ static void addModuleArgument(sqlite3 *d
 ** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE
 ** statement.  The module name has been parsed, but the optional list
 ** of parameters that follow the module name are still pending.
 */
 SQLITE_PRIVATE void sqlite3VtabBeginParse(
   Parse *pParse,        /* Parsing context */
   Token *pName1,        /* Name of new table, or database name */
   Token *pName2,        /* Name of new table or NULL */
-  Token *pModuleName    /* Name of the module for the virtual table */
+  Token *pModuleName,   /* Name of the module for the virtual table */
+  int ifNotExists       /* No error if the table already exists */
 ){
   int iDb;              /* The database the table is being created in */
   Table *pTable;        /* The new virtual table */
   sqlite3 *db;          /* Database connection */
 
-  sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
+  sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists);
   pTable = pParse->pNewTable;
   if( pTable==0 ) return;
   assert( 0==pTable->pIndex );
 
   db = pParse->db;
   iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
   assert( iDb>=0 );
 
@@ -101591,17 +101778,17 @@ SQLITE_PRIVATE void sqlite3VtabBeginPars
 }
 
 /*
 ** This routine takes the module argument that has been accumulating
 ** in pParse->zArg[] and appends it to the list of arguments on the
 ** virtual table currently under construction in pParse->pTable.
 */
 static void addArgumentToVtab(Parse *pParse){
-  if( pParse->sArg.z && ALWAYS(pParse->pNewTable) ){
+  if( pParse->sArg.z && pParse->pNewTable ){
     const char *z = (const char*)pParse->sArg.z;
     int n = pParse->sArg.n;
     sqlite3 *db = pParse->db;
     addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
   }
 }
 
 /*
@@ -105443,17 +105630,19 @@ static void bestBtreeIndex(
       bSort = 0;
       wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
       wsFlags |= (rev ? WHERE_REVERSE : 0);
     }
 
     /* If there is a DISTINCT qualifier and this index will scan rows in
     ** order of the DISTINCT expressions, clear bDist and set the appropriate
     ** flags in wsFlags. */
-    if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq) ){
+    if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq)
+     && (wsFlags & WHERE_COLUMN_IN)==0
+    ){
       bDist = 0;
       wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT;
     }
 
     /* If currently calculating the cost of using an index (not the IPK
     ** index), determine if all required column data may be obtained without 
     ** using the main table (i.e. if the index is a covering
     ** index for this query). If it is, set the WHERE_IDX_ONLY flag in
@@ -106140,18 +106329,17 @@ static void explainOneScan(
 /*
 ** Generate code for the start of the iLevel-th loop in the WHERE clause
 ** implementation described by pWInfo.
 */
 static Bitmask codeOneLoopStart(
   WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
   int iLevel,          /* Which level of pWInfo->a[] should be coded */
   u16 wctrlFlags,      /* One of the WHERE_* flags defined in sqliteInt.h */
-  Bitmask notReady,    /* Which tables are currently available */
-  Expr *pWhere         /* Complete WHERE clause */
+  Bitmask notReady     /* Which tables are currently available */
 ){
   int j, k;            /* Loop counters */
   int iCur;            /* The VDBE cursor for the table */
   int addrNxt;         /* Where to jump to continue with the next IN case */
   int omitTable;       /* True if we use the index only */
   int bRev;            /* True if we need to scan in reverse order */
   WhereLevel *pLevel;  /* The where level to be coded */
   WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
@@ -106680,20 +106868,35 @@ static Bitmask codeOneLoopStart(
       sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
     }
     iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
 
     /* If the original WHERE clause is z of the form:  (x1 OR x2 OR ...) AND y
     ** Then for every term xN, evaluate as the subexpression: xN AND z
     ** That way, terms in y that are factored into the disjunction will
     ** be picked up by the recursive calls to sqlite3WhereBegin() below.
+    **
+    ** Actually, each subexpression is converted to "xN AND w" where w is
+    ** the "interesting" terms of z - terms that did not originate in the
+    ** ON or USING clause of a LEFT JOIN, and terms that are usable as 
+    ** indices.
     */
     if( pWC->nTerm>1 ){
-      pAndExpr = sqlite3ExprAlloc(pParse->db, TK_AND, 0, 0);
-      pAndExpr->pRight = pWhere;
+      int iTerm;
+      for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
+        Expr *pExpr = pWC->a[iTerm].pExpr;
+        if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
+        if( pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_ORINFO) ) continue;
+        if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
+        pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
+        pAndExpr = sqlite3ExprAnd(pParse->db, pAndExpr, pExpr);
+      }
+      if( pAndExpr ){
+        pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
+      }
     }
 
     for(ii=0; ii<pOrWc->nTerm; ii++){
       WhereTerm *pOrTerm = &pOrWc->a[ii];
       if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
         WhereInfo *pSubWInfo;          /* Info for single OR-term scan */
         Expr *pOrExpr = pOrTerm->pExpr;
         if( pAndExpr ){
@@ -106725,17 +106928,20 @@ static Bitmask codeOneLoopStart(
           */
           if( pSubWInfo->untestedTerms ) untestedTerms = 1;
 
           /* Finish the loop through table entries that match term pOrTerm. */
           sqlite3WhereEnd(pSubWInfo);
         }
       }
     }
-    sqlite3DbFree(pParse->db, pAndExpr);
+    if( pAndExpr ){
+      pAndExpr->pLeft = 0;
+      sqlite3ExprDelete(pParse->db, pAndExpr);
+    }
     sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
     sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
     sqlite3VdbeResolveLabel(v, iLoopBody);
 
     if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab);
     if( !untestedTerms ) disableTerm(pLevel, pTerm);
   }else
 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
@@ -107381,17 +107587,17 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBe
   /* Generate the code to do the search.  Each iteration of the for
   ** loop below generates code for a single nested loop of the VM
   ** program.
   */
   notReady = ~(Bitmask)0;
   for(i=0; i<nTabList; i++){
     pLevel = &pWInfo->a[i];
     explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags);
-    notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady, pWhere);
+    notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady);
     pWInfo->iContinue = pLevel->addrCont;
   }
 
 #ifdef SQLITE_TEST  /* For testing and debugging use only */
   /* Record in the query plan information about the current table
   ** and the index used to access it (if any).  If the table itself
   ** is not used, its name is just '{}'.  If no index is used
   ** the index is listed as "{}".  If the primary key is used the
@@ -107636,16 +107842,24 @@ struct LikeOp {
 */
 struct TrigEvent { int a; IdList * b; };
 
 /*
 ** An instance of this structure holds the ATTACH key and the key type.
 */
 struct AttachKey { int type;  Token key; };
 
+/*
+** One or more VALUES claues
+*/
+struct ValueList {
+  ExprList *pList;
+  Select *pSelect;
+};
+
 
   /* This is a utility routine used to set the ExprSpan.zStart and
   ** ExprSpan.zEnd values of pOut so that the span covers the complete
   ** range of text beginning with pStart and going to the end of pEnd.
   */
   static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
     pOut->zStart = pStart->z;
     pOut->zEnd = &pEnd->z[pEnd->n];
@@ -107759,46 +107973,47 @@ struct AttachKey { int type;  Token key;
 **    sqlite3ParserARG_STORE     Code to store %extra_argument into yypParser
 **    sqlite3ParserARG_FETCH     Code to extract %extra_argument from yypParser
 **    YYNSTATE           the combined number of states.
 **    YYNRULE            the number of rules in the grammar
 **    YYERRORSYMBOL      is the code number of the error symbol.  If not
 **                       defined, then do no error processing.
 */
 #define YYCODETYPE unsigned char
-#define YYNOCODE 253
+#define YYNOCODE 251
 #define YYACTIONTYPE unsigned short int
 #define YYWILDCARD 67
 #define sqlite3ParserTOKENTYPE Token
 typedef union {
   int yyinit;
   sqlite3ParserTOKENTYPE yy0;
-  int yy4;
-  struct TrigEvent yy90;
-  ExprSpan yy118;
-  TriggerStep* yy203;
-  u8 yy210;
-  struct {int value; int mask;} yy215;
-  SrcList* yy259;
-  struct LimitVal yy292;
-  Expr* yy314;
-  ExprList* yy322;
-  struct LikeOp yy342;
-  IdList* yy384;
-  Select* yy387;
+  struct LimitVal yy64;
+  Expr* yy122;
+  Select* yy159;
+  IdList* yy180;
+  struct {int value; int mask;} yy207;
+  u8 yy258;
+  struct LikeOp yy318;
+  TriggerStep* yy327;
+  ExprSpan yy342;
+  SrcList* yy347;
+  int yy392;
+  struct TrigEvent yy410;
+  ExprList* yy442;
+  struct ValueList yy487;
 } YYMINORTYPE;
 #ifndef YYSTACKDEPTH
 #define YYSTACKDEPTH 100
 #endif
 #define sqlite3ParserARG_SDECL Parse *pParse;
 #define sqlite3ParserARG_PDECL ,Parse *pParse
 #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
 #define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 630
-#define YYNRULE 329
+#define YYNSTATE 629
+#define YYNRULE 327
 #define YYFALLBACK 1
 #define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
 #define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
 #define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)
 
 /* The yyzerominor constant is used to initialize instances of
 ** YYMINORTYPE objects to zero. */
 static const YYMINORTYPE yyzerominor = { 0 };
@@ -107858,483 +108073,486 @@ static const YYMINORTYPE yyzerominor = {
 **  yy_lookahead[]     A table containing the lookahead for each entry in
 **                     yy_action.  Used to detect hash collisions.
 **  yy_shift_ofst[]    For each state, the offset into yy_action for
 **                     shifting terminals.
 **  yy_reduce_ofst[]   For each state, the offset into yy_action for
 **                     shifting non-terminals after a reduce.
 **  yy_default[]       Default action for each state.
 */
-#define YY_ACTTAB_COUNT (1557)
+#define YY_ACTTAB_COUNT (1580)
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */   313,  960,  186,  419,    2,  172,  627,  597,   55,   55,
- /*    10 */    55,   55,   48,   53,   53,   53,   53,   52,   52,   51,
- /*    20 */    51,   51,   50,  238,  302,  283,  623,  622,  516,  515,
- /*    30 */   590,  584,   55,   55,   55,   55,  282,   53,   53,   53,
- /*    40 */    53,   52,   52,   51,   51,   51,   50,  238,    6,   56,
- /*    50 */    57,   47,  582,  581,  583,  583,   54,   54,   55,   55,
- /*    60 */    55,   55,  608,   53,   53,   53,   53,   52,   52,   51,
- /*    70 */    51,   51,   50,  238,  313,  597,  409,  330,  579,  579,
- /*    80 */    32,   53,   53,   53,   53,   52,   52,   51,   51,   51,
- /*    90 */    50,  238,  330,  217,  620,  619,  166,  411,  624,  382,
- /*   100 */   379,  378,    7,  491,  590,  584,  200,  199,  198,   58,
- /*   110 */   377,  300,  414,  621,  481,   66,  623,  622,  621,  580,
- /*   120 */   254,  601,   94,   56,   57,   47,  582,  581,  583,  583,
- /*   130 */    54,   54,   55,   55,   55,   55,  671,   53,   53,   53,
- /*   140 */    53,   52,   52,   51,   51,   51,   50,  238,  313,  532,
- /*   150 */   226,  506,  507,  133,  177,  139,  284,  385,  279,  384,
- /*   160 */   169,  197,  342,  398,  251,  226,  253,  275,  388,  167,
- /*   170 */   139,  284,  385,  279,  384,  169,  570,  236,  590,  584,
- /*   180 */   672,  240,  275,  157,  620,  619,  554,  437,   51,   51,
- /*   190 */    51,   50,  238,  343,  439,  553,  438,   56,   57,   47,
- /*   200 */   582,  581,  583,  583,   54,   54,   55,   55,   55,   55,
- /*   210 */   465,   53,   53,   53,   53,   52,   52,   51,   51,   51,
- /*   220 */    50,  238,  313,  390,   52,   52,   51,   51,   51,   50,
- /*   230 */   238,  391,  166,  491,  566,  382,  379,  378,  409,  440,
- /*   240 */   579,  579,  252,  440,  607,   66,  377,  513,  621,   49,
- /*   250 */    46,  147,  590,  584,  621,   16,  466,  189,  621,  441,
- /*   260 */   442,  673,  526,  441,  340,  577,  595,   64,  194,  482,
- /*   270 */   434,   56,   57,   47,  582,  581,  583,  583,   54,   54,
- /*   280 */    55,   55,   55,   55,   30,   53,   53,   53,   53,   52,
- /*   290 */    52,   51,   51,   51,   50,  238,  313,  593,  593,  593,
- /*   300 */   387,  578,  606,  493,  259,  351,  258,  411,    1,  623,
- /*   310 */   622,  496,  623,  622,   65,  240,  623,  622,  597,  443,
- /*   320 */   237,  239,  414,  341,  237,  602,  590,  584,   18,  603,
- /*   330 */   166,  601,   87,  382,  379,  378,   67,  623,  622,   38,
- /*   340 */   623,  622,  176,  270,  377,   56,   57,   47,  582,  581,
- /*   350 */   583,  583,   54,   54,   55,   55,   55,   55,  175,   53,
- /*   360 */    53,   53,   53,   52,   52,   51,   51,   51,   50,  238,
- /*   370 */   313,  396,  233,  411,  531,  565,  317,  620,  619,   44,
- /*   380 */   620,  619,  240,  206,  620,  619,  597,  266,  414,  268,
- /*   390 */   409,  597,  579,  579,  352,  184,  505,  601,   73,  533,
- /*   400 */   590,  584,  466,  548,  190,  620,  619,  576,  620,  619,
- /*   410 */   547,  383,  551,   35,  332,  575,  574,  600,  504,   56,
- /*   420 */    57,   47,  582,  581,  583,  583,   54,   54,   55,   55,
- /*   430 */    55,   55,  567,   53,   53,   53,   53,   52,   52,   51,
- /*   440 */    51,   51,   50,  238,  313,  411,  561,  561,  528,  364,
- /*   450 */   259,  351,  258,  183,  361,  549,  524,  374,  411,  597,
- /*   460 */   414,  240,  560,  560,  409,  604,  579,  579,  328,  601,
- /*   470 */    93,  623,  622,  414,  590,  584,  237,  564,  559,  559,
- /*   480 */   520,  402,  601,   87,  409,  210,  579,  579,  168,  421,
- /*   490 */   950,  519,  950,   56,   57,   47,  582,  581,  583,  583,
- /*   500 */    54,   54,   55,   55,   55,   55,  192,   53,   53,   53,
- /*   510 */    53,   52,   52,   51,   51,   51,   50,  238,  313,  600,
- /*   520 */   293,  563,  511,  234,  357,  146,  475,  475,  367,  411,
- /*   530 */   562,  411,  358,  542,  425,  171,  411,  215,  144,  620,
- /*   540 */   619,  544,  318,  353,  414,  203,  414,  275,  590,  584,
- /*   550 */   549,  414,  174,  601,   94,  601,   79,  558,  471,   61,
- /*   560 */   601,   79,  421,  949,  350,  949,   34,   56,   57,   47,
- /*   570 */   582,  581,  583,  583,   54,   54,   55,   55,   55,   55,
- /*   580 */   535,   53,   53,   53,   53,   52,   52,   51,   51,   51,
- /*   590 */    50,  238,  313,  307,  424,  394,  272,   49,   46,  147,
- /*   600 */   349,  322,    4,  411,  491,  312,  321,  425,  568,  492,
- /*   610 */   216,  264,  407,  575,  574,  429,   66,  549,  414,  621,
- /*   620 */   540,  602,  590,  584,   13,  603,  621,  601,   72,   12,
- /*   630 */   618,  617,  616,  202,  210,  621,  546,  469,  422,  319,
- /*   640 */   148,   56,   57,   47,  582,  581,  583,  583,   54,   54,
- /*   650 */    55,   55,   55,   55,  338,   53,   53,   53,   53,   52,
- /*   660 */    52,   51,   51,   51,   50,  238,  313,  600,  600,  411,
- /*   670 */    39,   21,   37,  170,  237,  875,  411,  572,  572,  201,
- /*   680 */   144,  473,  538,  331,  414,  474,  143,  146,  630,  628,
- /*   690 */   334,  414,  353,  601,   68,  168,  590,  584,  132,  365,
- /*   700 */   601,   96,  307,  423,  530,  336,   49,   46,  147,  568,
- /*   710 */   406,  216,  549,  360,  529,   56,   57,   47,  582,  581,
- /*   720 */   583,  583,   54,   54,   55,   55,   55,   55,  411,   53,
- /*   730 */    53,   53,   53,   52,   52,   51,   51,   51,   50,  238,
- /*   740 */   313,  411,  605,  414,  484,  510,  172,  422,  597,  318,
- /*   750 */   496,  485,  601,   99,  411,  142,  414,  411,  231,  411,
- /*   760 */   540,  411,  359,  629,    2,  601,   97,  426,  308,  414,
- /*   770 */   590,  584,  414,   20,  414,  621,  414,  621,  601,  106,
- /*   780 */   503,  601,  105,  601,  108,  601,  109,  204,   28,   56,
- /*   790 */    57,   47,  582,  581,  583,  583,   54,   54,   55,   55,
- /*   800 */    55,   55,  411,   53,   53,   53,   53,   52,   52,   51,
- /*   810 */    51,   51,   50,  238,  313,  411,  597,  414,  411,  276,
- /*   820 */   214,  600,  411,  366,  213,  381,  601,  134,  274,  500,
- /*   830 */   414,  167,  130,  414,  621,  411,  354,  414,  376,  601,
- /*   840 */   135,  129,  601,  100,  590,  584,  601,  104,  522,  521,
- /*   850 */   414,  621,  224,  273,  600,  167,  327,  282,  600,  601,
- /*   860 */   103,  468,  521,   56,   57,   47,  582,  581,  583,  583,
- /*   870 */    54,   54,   55,   55,   55,   55,  411,   53,   53,   53,
- /*   880 */    53,   52,   52,   51,   51,   51,   50,  238,  313,  411,
- /*   890 */    27,  414,  411,  375,  276,  167,  359,  544,   50,  238,
- /*   900 */   601,   95,  128,  223,  414,  411,  165,  414,  411,  621,
- /*   910 */   411,  621,  612,  601,  102,  372,  601,   76,  590,  584,
- /*   920 */   414,  570,  236,  414,  470,  414,  167,  621,  188,  601,
- /*   930 */    98,  225,  601,  138,  601,  137,  232,   56,   45,   47,
- /*   940 */   582,  581,  583,  583,   54,   54,   55,   55,   55,   55,
- /*   950 */   411,   53,   53,   53,   53,   52,   52,   51,   51,   51,
- /*   960 */    50,  238,  313,  276,  276,  414,  411,  276,  544,  459,
- /*   970 */   359,  171,  209,  479,  601,  136,  628,  334,  621,  621,
- /*   980 */   125,  414,  621,  368,  411,  621,  257,  540,  589,  588,
- /*   990 */   601,   75,  590,  584,  458,  446,   23,   23,  124,  414,
- /*  1000 */   326,  325,  621,  427,  324,  309,  600,  288,  601,   92,
- /*  1010 */   586,  585,   57,   47,  582,  581,  583,  583,   54,   54,
- /*  1020 */    55,   55,   55,   55,  411,   53,   53,   53,   53,   52,
- /*  1030 */    52,   51,   51,   51,   50,  238,  313,  587,  411,  414,
- /*  1040 */   411,  207,  611,  476,  171,  472,  160,  123,  601,   91,
- /*  1050 */   323,  261,   15,  414,  464,  414,  411,  621,  411,  354,
- /*  1060 */   222,  411,  601,   74,  601,   90,  590,  584,  159,  264,
- /*  1070 */   158,  414,  461,  414,  621,  600,  414,  121,  120,   25,
- /*  1080 */   601,   89,  601,  101,  621,  601,   88,   47,  582,  581,
- /*  1090 */   583,  583,   54,   54,   55,   55,   55,   55,  544,   53,
- /*  1100 */    53,   53,   53,   52,   52,   51,   51,   51,   50,  238,
- /*  1110 */    43,  405,  263,    3,  610,  264,  140,  415,  622,   24,
- /*  1120 */   410,   11,  456,  594,  118,  155,  219,  452,  408,  621,
- /*  1130 */   621,  621,  156,   43,  405,  621,    3,  286,  621,  113,
- /*  1140 */   415,  622,  111,  445,  411,  400,  557,  403,  545,   10,
- /*  1150 */   411,  408,  264,  110,  205,  436,  541,  566,  453,  414,
- /*  1160 */   621,  621,   63,  621,  435,  414,  411,  621,  601,   94,
- /*  1170 */   403,  621,  411,  337,  601,   86,  150,   40,   41,  534,
- /*  1180 */   566,  414,  242,  264,   42,  413,  412,  414,  600,  595,
- /*  1190 */   601,   85,  191,  333,  107,  451,  601,   84,  621,  539,
- /*  1200 */    40,   41,  420,  230,  411,  149,  316,   42,  413,  412,
- /*  1210 */   398,  127,  595,  315,  621,  399,  278,  625,  181,  414,
- /*  1220 */   593,  593,  593,  592,  591,   14,  450,  411,  601,   71,
- /*  1230 */   240,  621,   43,  405,  264,    3,  615,  180,  264,  415,
- /*  1240 */   622,  614,  414,  593,  593,  593,  592,  591,   14,  621,
- /*  1250 */   408,  601,   70,  621,  417,   33,  405,  613,    3,  411,
- /*  1260 */   264,  411,  415,  622,  418,  626,  178,  509,    8,  403,
- /*  1270 */   241,  416,  126,  408,  414,  621,  414,  449,  208,  566,
- /*  1280 */   240,  221,  621,  601,   83,  601,   82,  599,  297,  277,
- /*  1290 */   296,   30,  403,   31,  395,  264,  295,  397,  489,   40,
- /*  1300 */    41,  411,  566,  220,  621,  294,   42,  413,  412,  271,
- /*  1310 */   621,  595,  600,  621,   59,   60,  414,  269,  267,  623,
- /*  1320 */   622,   36,   40,   41,  621,  601,   81,  598,  235,   42,
- /*  1330 */   413,  412,  621,  621,  595,  265,  344,  411,  248,  556,
- /*  1340 */   173,  185,  593,  593,  593,  592,  591,   14,  218,   29,
- /*  1350 */   621,  543,  414,  305,  304,  303,  179,  301,  411,  566,
- /*  1360 */   454,  601,   80,  289,  335,  593,  593,  593,  592,  591,
- /*  1370 */    14,  411,  287,  414,  151,  392,  246,  260,  411,  196,
- /*  1380 */   195,  523,  601,   69,  411,  245,  414,  526,  537,  285,
- /*  1390 */   389,  595,  621,  414,  536,  601,   17,  362,  153,  414,
- /*  1400 */   466,  463,  601,   78,  154,  414,  462,  152,  601,   77,
- /*  1410 */   355,  255,  621,  455,  601,    9,  621,  386,  444,  517,
- /*  1420 */   247,  621,  593,  593,  593,  621,  621,  244,  621,  243,
- /*  1430 */   430,  518,  292,  621,  329,  621,  145,  393,  280,  513,
- /*  1440 */   291,  131,  621,  514,  621,  621,  311,  621,  259,  346,
- /*  1450 */   249,  621,  621,  229,  314,  621,  228,  512,  227,  240,
- /*  1460 */   494,  488,  310,  164,  487,  486,  373,  480,  163,  262,
- /*  1470 */   369,  371,  162,   26,  212,  478,  477,  161,  141,  363,
- /*  1480 */   467,  122,  339,  187,  119,  348,  347,  117,  116,  115,
- /*  1490 */   114,  112,  182,  457,  320,   22,  433,  432,  448,   19,
- /*  1500 */   609,  431,  428,   62,  193,  596,  573,  298,  555,  552,
- /*  1510 */   571,  404,  290,  380,  498,  510,  495,  306,  281,  499,
- /*  1520 */   250,    5,  497,  460,  345,  447,  569,  550,  238,  299,
- /*  1530 */   527,  525,  508,  961,  502,  501,  961,  401,  961,  211,
- /*  1540 */   490,  356,  256,  961,  483,  961,  961,  961,  961,  961,
- /*  1550 */   961,  961,  961,  961,  961,  961,  370,
+ /*     0 */   310,  328,  574,  573,   15,  172,  187,  596,   56,   56,
+ /*    10 */    56,   56,   49,   54,   54,   54,   54,   53,   53,   52,
+ /*    20 */    52,   52,   51,  234,  622,  621,  626,  622,  621,  299,
+ /*    30 */   589,  583,   56,   56,   56,   56,  236,   54,   54,   54,
+ /*    40 */    54,   53,   53,   52,   52,   52,   51,  234,  351,   57,
+ /*    50 */    58,   48,  581,  580,  582,  582,   55,   55,   56,   56,
+ /*    60 */    56,   56,  570,   54,   54,   54,   54,   53,   53,   52,
+ /*    70 */    52,   52,   51,  234,  310,  596,  326,  607,  233,  232,
+ /*    80 */    33,   54,   54,   54,   54,   53,   53,   52,   52,   52,
+ /*    90 */    51,  234,  619,  618,  326,  619,  618,  166,  605,  492,
+ /*   100 */   381,  378,  377,  235,  589,  583,  554,  495,    1,   59,
+ /*   110 */    19,  376,  622,  621,   53,   53,   52,   52,   52,   51,
+ /*   120 */   234,  571,  571,   57,   58,   48,  581,  580,  582,  582,
+ /*   130 */    55,   55,   56,   56,   56,   56,  215,   54,   54,   54,
+ /*   140 */    54,   53,   53,   52,   52,   52,   51,  234,  310,  224,
+ /*   150 */    50,   47,  147,  177,  139,  281,  384,  276,  383,  169,
+ /*   160 */   408,  553,  578,  578,  622,  621,  272,  224,  439,  550,
+ /*   170 */   552,  410,  139,  281,  384,  276,  383,  169,  589,  583,
+ /*   180 */   619,  618,  280,  620,  272,  195,  413,  309,  440,  441,
+ /*   190 */   567,  491,  214,  279,  560,  600,   92,   57,   58,   48,
+ /*   200 */   581,  580,  582,  582,   55,   55,   56,   56,   56,   56,
+ /*   210 */   559,   54,   54,   54,   54,   53,   53,   52,   52,   52,
+ /*   220 */    51,  234,  310,  464,  233,  232,  558,  133,  519,   50,
+ /*   230 */    47,  147,  619,  618,  565,  436,  397,  515,  514,  518,
+ /*   240 */   410,  387,  438,  389,  437,  622,  621,  442,  570,  433,
+ /*   250 */   203,  390,  589,  583,    6,  413,  166,  670,  250,  381,
+ /*   260 */   378,  377,  525,  190,  600,   92,  594,  571,  571,  465,
+ /*   270 */   376,   57,   58,   48,  581,  580,  582,  582,   55,   55,
+ /*   280 */    56,   56,   56,   56,  599,   54,   54,   54,   54,   53,
+ /*   290 */    53,   52,   52,   52,   51,  234,  310,  592,  592,  592,
+ /*   300 */   490,  182,  247,  548,  249,  397,  273,  410,    7,  439,
+ /*   310 */   398,  606,   67,  619,  618,  620,  472,  256,  347,  255,
+ /*   320 */   473,  620,  413,  576,  620,   65,  589,  583,  236,  440,
+ /*   330 */   336,  600,   92,   68,  364,  192,  481,  622,  621,  547,
+ /*   340 */   622,  621,  560,  323,  207,   57,   58,   48,  581,  580,
+ /*   350 */   582,  582,   55,   55,   56,   56,   56,   56,  559,   54,
+ /*   360 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  234,
+ /*   370 */   310,  410,  397,  146,  558,  531,  401,  348,  599,  166,
+ /*   380 */   248,  204,  381,  378,  377,  541,  413,  171,  337,  570,
+ /*   390 */   622,  621,   40,  376,   38,  600,   74,  465,  548,  490,
+ /*   400 */   589,  583,  532,  350,  579,  619,  618,  297,  619,  618,
+ /*   410 */   480,   67,  470,   39,  620,  599,  406,  574,  573,   57,
+ /*   420 */    58,   48,  581,  580,  582,  582,   55,   55,   56,   56,
+ /*   430 */    56,   56,  577,   54,   54,   54,   54,   53,   53,   52,
+ /*   440 */    52,   52,   51,  234,  310,  256,  347,  255,  530,   52,
+ /*   450 */    52,   52,   51,  234,  345,  564,  236,  386,  619,  618,
+ /*   460 */   957,  185,  418,    2,  408,  410,  578,  578,  198,  197,
+ /*   470 */   196,  499,  183,  167,  589,  583,  671,  570,  505,  506,
+ /*   480 */   413,  267,  601,  672,  546,  208,  602,   36,  601,  600,
+ /*   490 */    91,  468,  602,   57,   58,   48,  581,  580,  582,  582,
+ /*   500 */    55,   55,   56,   56,   56,   56,  202,   54,   54,   54,
+ /*   510 */    54,   53,   53,   52,   52,   52,   51,  234,  310,  599,
+ /*   520 */   157,  408,  527,  578,  578,  263,  490,  265,  410,  873,
+ /*   530 */   410,  474,  474,  366,  373,  410,  504,  428,   67,  290,
+ /*   540 */   599,  620,  352,  413,  408,  413,  578,  578,  589,  583,
+ /*   550 */   413,  382,  600,   92,  600,   16,  543,   62,  503,  600,
+ /*   560 */    92,  408,  346,  578,  578,  168,   45,   57,   58,   48,
+ /*   570 */   581,  580,  582,  582,   55,   55,   56,   56,   56,   56,
+ /*   580 */   200,   54,   54,   54,   54,   53,   53,   52,   52,   52,
+ /*   590 */    51,  234,  310,  393,  395,  534,  510,  617,  616,  615,
+ /*   600 */   318,  314,  172,   66,  596,  410,  338,  596,  324,  571,
+ /*   610 */   571,   50,   47,  147,  599,  629,  627,  330,  539,  315,
+ /*   620 */   413,   30,  589,  583,  272,  236,  199,  144,  176,  600,
+ /*   630 */    73,  420,  947,  620,  947,  420,  946,  351,  946,  175,
+ /*   640 */   596,   57,   58,   48,  581,  580,  582,  582,   55,   55,
+ /*   650 */    56,   56,   56,   56,  410,   54,   54,   54,   54,   53,
+ /*   660 */    53,   52,   52,   52,   51,  234,  310,  261,  410,  413,
+ /*   670 */   269,  208,  596,  363,  410,  596,  424,  360,  600,   69,
+ /*   680 */   424,  327,  620,  413,   50,   47,  147,  410,  358,  413,
+ /*   690 */   575,  553,  600,   94,  483,  509,  589,  583,  600,   97,
+ /*   700 */   552,  484,  413,  620,  188,  599,  551,  563,  596,  566,
+ /*   710 */   334,  600,   95,  205,  201,   57,   58,   48,  581,  580,
+ /*   720 */   582,  582,   55,   55,   56,   56,   56,   56,  352,   54,
+ /*   730 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  234,
+ /*   740 */   310,  410,  261,  410,  167,   22,  356,  599,  359,  623,
+ /*   750 */    50,   47,  147,  548,  357,  562,  413,  620,  413,  332,
+ /*   760 */   523,  270,  410,  167,  620,  600,  104,  600,  103,  603,
+ /*   770 */   589,  583,  339,  539,  304,  423,  222,  413,  174,  304,
+ /*   780 */   422,  561,  567,  405,  214,  260,  600,  106,  620,   57,
+ /*   790 */    58,   48,  581,  580,  582,  582,   55,   55,   56,   56,
+ /*   800 */    56,   56,  410,   54,   54,   54,   54,   53,   53,   52,
+ /*   810 */    52,   52,   51,  234,  310,  410,  557,  413,  410,  421,
+ /*   820 */   273,   35,  512,  146,  421,   12,  600,  107,  213,  144,
+ /*   830 */   413,  410,   32,  413,  410,  620,  365,  353,  358,  600,
+ /*   840 */   134,   11,  600,  135,  589,  583,  413,   21,  548,  413,
+ /*   850 */   316,  148,  620,  620,  170,  600,   98,  223,  600,  102,
+ /*   860 */   374,  168,  167,   57,   58,   48,  581,  580,  582,  582,
+ /*   870 */    55,   55,   56,   56,   56,   56,  410,   54,   54,   54,
+ /*   880 */    54,   53,   53,   52,   52,   52,   51,  234,  310,  410,
+ /*   890 */   273,  413,  410,  273,  212,  469,  410,  167,  628,    2,
+ /*   900 */   600,  101,  545,  221,  413,  620,  130,  413,  620,  410,
+ /*   910 */   539,  413,  537,  600,   93,  315,  600,  100,  589,  583,
+ /*   920 */   600,   77,  425,  305,  413,  620,  254,  322,  599,  458,
+ /*   930 */   320,  171,  543,  600,   96,  521,  520,   57,   58,   48,
+ /*   940 */   581,  580,  582,  582,   55,   55,   56,   56,   56,   56,
+ /*   950 */   410,   54,   54,   54,   54,   53,   53,   52,   52,   52,
+ /*   960 */    51,  234,  310,  410,  273,  413,  410,  457,  358,   35,
+ /*   970 */   426,  230,  306,  319,  600,  138,  467,  520,  413,  620,
+ /*   980 */   143,  413,  410,  620,  410,  353,  529,  600,  137,  142,
+ /*   990 */   600,  136,  589,  583,  604,  261,  528,  413,  229,  413,
+ /*  1000 */   620,  321,  495,   28,  543,  543,  600,   76,  600,   90,
+ /*  1010 */   620,   57,   46,   48,  581,  580,  582,  582,   55,   55,
+ /*  1020 */    56,   56,   56,   56,  410,   54,   54,   54,   54,   53,
+ /*  1030 */    53,   52,   52,   52,   51,  234,  310,  261,  451,  413,
+ /*  1040 */   410,  211,  611,  285,  283,  610,  609,  502,  600,   89,
+ /*  1050 */   380,  217,  620,  128,  140,  413,  220,  620,  410,  409,
+ /*  1060 */   620,  620,  588,  587,  600,   75,  589,  583,  271,  620,
+ /*  1070 */    51,  234,  127,  413,  620,  599,  627,  330,   27,  375,
+ /*  1080 */   449,  279,  600,   88,  585,  584,   58,   48,  581,  580,
+ /*  1090 */   582,  582,   55,   55,   56,   56,   56,   56,  410,   54,
+ /*  1100 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  234,
+ /*  1110 */   310,  586,  410,  413,  410,  261,  593,  165,  399,  556,
+ /*  1120 */   126,  371,  600,   87,  478,  186,  123,  413,  367,  413,
+ /*  1130 */   620,  620,  410,  620,  620,  410,  600,   99,  600,   86,
+ /*  1140 */   589,  583,  475,  122,  258,  171,  471,  413,  160,  121,
+ /*  1150 */   413,   14,  159,  463,   25,   24,  600,   17,  448,  600,
+ /*  1160 */    85,   48,  581,  580,  582,  582,   55,   55,   56,   56,
+ /*  1170 */    56,   56,  158,   54,   54,   54,   54,   53,   53,   52,
+ /*  1180 */    52,   52,   51,  234,   44,  404,  261,    3,  544,  261,
+ /*  1190 */   540,  414,  621,  460,  119,  118,  538,  275,   10,  349,
+ /*  1200 */     4,  620,  407,  620,  620,  620,  116,   44,  404,  410,
+ /*  1210 */     3,  620,  620,  410,  414,  621,  456,  454,  252,  450,
+ /*  1220 */   508,  402,  111,  109,  413,  407,  155,  444,  413,  447,
+ /*  1230 */   435,  565,  219,  600,   84,  620,  108,  600,   83,   64,
+ /*  1240 */   434,  417,  625,  150,  402,  333,  410,  237,  238,  124,
+ /*  1250 */   274,   41,   42,  533,  565,  206,  189,  261,   43,  412,
+ /*  1260 */   411,  413,  261,  594,  488,  620,  329,  149,  419,  268,
+ /*  1270 */   600,   72,  620,  266,   41,   42,  181,  620,  410,  620,
+ /*  1280 */   105,   43,  412,  411,  620,  624,  594,  614,  620,  599,
+ /*  1290 */   228,  125,  313,  413,  592,  592,  592,  591,  590,   13,
+ /*  1300 */   218,  410,  600,   71,  236,  244,   44,  404,  264,    3,
+ /*  1310 */   312,  613,  340,  414,  621,  180,  413,  592,  592,  592,
+ /*  1320 */   591,  590,   13,  620,  407,  600,   82,  410,  416,   34,
+ /*  1330 */   404,  410,    3,  410,  262,  410,  414,  621,  612,  331,
+ /*  1340 */   178,  415,  413,  402,    8,  236,  413,  407,  413,  620,
+ /*  1350 */   413,  600,   81,  565,  257,  600,   80,  600,   70,  600,
+ /*  1360 */    18,  598,  361,  462,  461,   30,  402,  294,   31,  620,
+ /*  1370 */   293,  354,  251,   41,   42,  410,  565,  620,  620,  620,
+ /*  1380 */    43,  412,  411,  453,  396,  594,  620,  620,  394,   61,
+ /*  1390 */   413,  292,  443,  622,  621,  243,   41,   42,  620,  600,
+ /*  1400 */    79,  597,  291,   43,  412,  411,   60,  620,  594,  240,
+ /*  1410 */   620,  410,  231,   37,  555,  173,  592,  592,  592,  591,
+ /*  1420 */   590,   13,  216,  239,  620,  184,  413,  302,  301,  300,
+ /*  1430 */   179,  298,  388,  565,  452,  600,   78,  286,  620,  592,
+ /*  1440 */   592,  592,  591,  590,   13,  429,   29,  413,  151,  289,
+ /*  1450 */   242,  145,  392,  194,  193,  288,  600,    9,  542,  241,
+ /*  1460 */   620,  525,  391,  284,  620,  594,  620,  620,  522,  536,
+ /*  1470 */   620,  535,  153,  385,  465,  516,  282,  325,  154,  517,
+ /*  1480 */   277,  152,  512,  511,  513,  129,  226,  308,  487,  486,
+ /*  1490 */   485,  164,  372,  493,  307,  227,  592,  592,  592,  225,
+ /*  1500 */   479,  163,  368,  370,  162,  476,  210,  477,   26,  259,
+ /*  1510 */   161,  466,  362,  141,  132,  120,  117,  455,  156,  115,
+ /*  1520 */   344,  343,  256,  342,  245,  114,  113,  446,  311,  112,
+ /*  1530 */    23,  317,  432,  236,  131,  431,  110,  430,   20,  427,
+ /*  1540 */   608,  595,  295,   63,  379,  287,  509,  191,  278,  403,
+ /*  1550 */   572,  569,  497,  498,  496,  494,  335,  459,  445,  303,
+ /*  1560 */   296,  246,  341,  355,    5,  568,  369,  507,  253,  549,
+ /*  1570 */   526,  209,  400,  501,  500,  524,  234,  958,  489,  482,
 };
 static const YYCODETYPE yy_lookahead[] = {
- /*     0 */    19,  142,  143,  144,  145,   24,    1,   26,   77,   78,
+ /*     0 */    19,  169,  170,  171,   22,   24,   24,   26,   77,   78,
  /*    10 */    79,   80,   81,   82,   83,   84,   85,   86,   87,   88,
<