Merge mozilla-central to tracemonkey.
authorRobert Sayre <sayrer@gmail.com>
Thu, 01 Oct 2009 14:08:25 -0700
changeset 33580 f619453024dcc020b0129c46cf9d8da5259de3a4
parent 33579 0fbe56341ebcf32156498dd5102c62e84dbf6187 (current diff)
parent 33343 e0e16a509fb6fdda1e7696b2f5d2279ff9a5eaec (diff)
child 33581 1e563137bd8e32228c895adf2a7b21014d9d5d6e
push id9581
push userrsayre@mozilla.com
push dateWed, 07 Oct 2009 06:47:58 +0000
treeherdermozilla-central@eb8a5ea7468c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a1pre
Merge mozilla-central to tracemonkey.
dom/locales/en-US/chrome/printdialog.properties
js/src/configure.in
js/src/jsobj.cpp
js/src/jstracer.h
storage/test/unit/test_storage_combined_sharing.js
testing/testsuite-targets.mk
toolkit/locales/en-US/chrome/global/gnomeprintdialog.properties
--- a/Makefile.in
+++ b/Makefile.in
@@ -100,16 +100,19 @@ default alldep all::
 export::
 	$(RM) -rf $(DIST)/sdk
 	$(MAKE) -C config export
 	$(MAKE) tier_nspr
 
 ifdef ENABLE_TESTS
 # Additional makefile targets to call automated test suites
 include $(topsrcdir)/testing/testsuite-targets.mk
+else
+# OS X Universal builds will want to call this, so stub it out
+package-tests:
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 # After we build tier toolkit, go back and build the tools from previous dirs
 tier_toolkit::
 	$(MAKE) tools_tier_js
 	$(MAKE) tools_tier_xpcom
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -1448,17 +1448,17 @@ NS_IMETHODIMP nsAccessibilityService::Ge
         *aIsHidden = PR_TRUE;
         return NS_OK;
       }
     }
     frame->GetAccessible(getter_AddRefs(newAcc));
     return InitAccessible(newAcc, aAccessible, nsnull);
   }
 
-  PRBool isHTML = content->IsNodeOfType(nsINode::eHTML);
+  PRBool isHTML = content->IsHTML();
   if (isHTML && content->Tag() == nsAccessibilityAtoms::map) {
     // Create hyper text accessible for HTML map if it is used to group links
     // (see http://www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass). If the HTML
     // map doesn't have 'name' attribute (or has empty name attribute) then we
     // suppose it is used for links grouping. Otherwise we think it is used in
     // conjuction with HTML image element and in this case we don't create any
     // accessible for it and don't walk into it. The accessibles for HTML area
     // (nsHTMLAreaAccessible) the map contains are attached as children of the
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -293,19 +293,19 @@ nsAccessible::GetName(nsAString& aName)
 
   // In the end get the name from tooltip.
   nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
   if (!content)
     return NS_OK;
 
   nsIAtom *tooltipAttr = nsnull;
 
-  if (content->IsNodeOfType(nsINode::eHTML))
+  if (content->IsHTML())
     tooltipAttr = nsAccessibilityAtoms::title;
-  else if (content->IsNodeOfType(nsINode::eXUL))
+  else if (content->IsXUL())
     tooltipAttr = nsAccessibilityAtoms::tooltiptext;
   else
     return NS_OK;
 
   // XXX: if CompressWhiteSpace worked on nsAString we could avoid a copy.
   nsAutoString name;
   if (content->GetAttr(kNameSpaceID_None, tooltipAttr, name)) {
     name.CompressWhitespace();
@@ -337,17 +337,17 @@ NS_IMETHODIMP nsAccessible::GetDescripti
   if (!content->IsNodeOfType(nsINode::eTEXT)) {
     nsAutoString description;
     nsresult rv = nsTextEquivUtils::
       GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_describedby,
                              description);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (description.IsEmpty()) {
-      PRBool isXUL = content->IsNodeOfType(nsINode::eXUL);
+      PRBool isXUL = content->IsXUL();
       if (isXUL) {
         // Try XUL <description control="[id]">description text</description>
         nsIContent *descriptionContent =
           nsCoreUtils::FindNeighbourPointingToNode(content,
                                                    nsAccessibilityAtoms::control,
                                                    nsAccessibilityAtoms::description);
 
         if (descriptionContent) {
@@ -1004,17 +1004,17 @@ nsAccessible::GetStateInternal(PRUint32 
     return NS_OK;  // On document, this is not an error
   }
 
   // Set STATE_UNAVAILABLE state based on disabled attribute
   // The disabled attribute is mostly used in XUL elements and HTML forms, but
   // if someone sets it on another attribute, 
   // it seems reasonable to consider it unavailable
   PRBool isDisabled;
-  if (content->IsNodeOfType(nsINode::eHTML)) {
+  if (content->IsHTML()) {
     // In HTML, just the presence of the disabled attribute means it is disabled,
     // therefore disabled="false" indicates disabled!
     isDisabled = content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::disabled);
   }
   else {
     isDisabled = content->AttrValueIs(kNameSpaceID_None,
                                       nsAccessibilityAtoms::disabled,
                                       nsAccessibilityAtoms::_true,
@@ -1044,17 +1044,17 @@ nsAccessible::GetStateInternal(PRUint32 
     *aState |= nsIAccessibleStates::STATE_OFFSCREEN;
   }
 
   nsIFrame *frame = GetFrame();
   if (frame && (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW))
     *aState |= nsIAccessibleStates::STATE_FLOATING;
 
   // Check if a XUL element has the popup attribute (an attached popup menu).
-  if (content->IsNodeOfType(nsINode::eXUL))
+  if (content->IsXUL())
     if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::popup))
       *aState |= nsIAccessibleStates::STATE_HASPOPUP;
 
   // Add 'linked' state for simple xlink.
   if (nsCoreUtils::IsXLink(content))
     *aState |= nsIAccessibleStates::STATE_LINKED;
 
   return NS_OK;
@@ -2408,17 +2408,17 @@ nsAccessible::GetRelationByType(PRUint32
 
   nsresult rv;
 
   switch (aRelationType)
   {
   case nsIAccessibleRelation::RELATION_LABEL_FOR:
     {
       if (content->Tag() == nsAccessibilityAtoms::label) {
-        nsIAtom *IDAttr = content->IsNodeOfType(nsINode::eHTML) ?
+        nsIAtom *IDAttr = content->IsHTML() ?
           nsAccessibilityAtoms::_for : nsAccessibilityAtoms::control;
         rv = nsRelUtils::
           AddTargetFromIDRefAttr(aRelationType, aRelation, content, IDAttr);
         NS_ENSURE_SUCCESS(rv, rv);
 
         if (rv != NS_OK_NO_RELATION_TARGET)
           return NS_OK; // XXX bug 381599, avoid performance problems
       }
@@ -2465,17 +2465,17 @@ nsAccessible::GetRelationByType(PRUint32
         AddTargetFromNeighbour(aRelationType, aRelation, content,
                                nsAccessibilityAtoms::aria_describedby);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (rv != NS_OK_NO_RELATION_TARGET)
         return NS_OK; // XXX bug 381599, avoid performance problems
 
       if (content->Tag() == nsAccessibilityAtoms::description &&
-          content->IsNodeOfType(nsINode::eXUL)) {
+          content->IsXUL()) {
         // This affectively adds an optional control attribute to xul:description,
         // which only affects accessibility, by allowing the description to be
         // tied to a control.
         return nsRelUtils::
           AddTargetFromIDRefAttr(aRelationType, aRelation, content,
                                  nsAccessibilityAtoms::control);
       }
 
@@ -2549,17 +2549,17 @@ nsAccessible::GetRelationByType(PRUint32
     {
       return nsRelUtils::
         AddTargetFromNeighbour(aRelationType, aRelation, content,
                                nsAccessibilityAtoms::aria_flowto);
     }
 
   case nsIAccessibleRelation::RELATION_DEFAULT_BUTTON:
     {
-      if (content->IsNodeOfType(nsINode::eHTML)) {
+      if (content->IsHTML()) {
         // HTML form controls implements nsIFormControl interface.
         nsCOMPtr<nsIFormControl> control(do_QueryInterface(content));
         if (control) {
           nsCOMPtr<nsIDOMHTMLFormElement> htmlform;
           control->GetForm(getter_AddRefs(htmlform));
           nsCOMPtr<nsIForm> form(do_QueryInterface(htmlform));
           if (form) {
             nsCOMPtr<nsIContent> formContent =
@@ -3096,20 +3096,20 @@ nsAccessible::GetARIAName(nsAString& aNa
 
 nsresult
 nsAccessible::GetNameInternal(nsAString& aName)
 {
   nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
   if (!content)
     return NS_OK;
 
-  if (content->IsNodeOfType(nsINode::eHTML))
+  if (content->IsHTML())
     return GetHTMLName(aName);
 
-  if (content->IsNodeOfType(nsINode::eXUL))
+  if (content->IsXUL())
     return GetXULName(aName);
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible private methods
 
@@ -3226,17 +3226,17 @@ nsAccessible::GetActionRule(PRUint32 aSt
   if (!content)
     return eNoAction;
   
   // Check if it's simple xlink.
   if (nsCoreUtils::IsXLink(content))
     return eJumpAction;
 
   // Return "click" action on elements that have an attached popup menu.
-  if (content->IsNodeOfType(nsINode::eXUL))
+  if (content->IsXUL())
     if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::popup))
       return eClickAction;
 
   // Has registered 'click' event handler.
   PRBool isOnclick = nsCoreUtils::HasListener(content,
                                               NS_LITERAL_STRING("click"));
 
   if (isOnclick)
--- a/accessible/src/base/nsAccessibleTreeWalker.cpp
+++ b/accessible/src/base/nsAccessibleTreeWalker.cpp
@@ -70,17 +70,17 @@ nsAccessibleTreeWalker::~nsAccessibleTre
   while (NS_SUCCEEDED(PopState()))
     /* do nothing */ ;
    MOZ_COUNT_DTOR(nsAccessibleTreeWalker);
 }
 
 void nsAccessibleTreeWalker::GetKids(nsIDOMNode *aParentNode)
 {
   nsCOMPtr<nsIContent> parentContent(do_QueryInterface(aParentNode));
-  if (!parentContent || !parentContent->IsNodeOfType(nsINode::eHTML)) {
+  if (!parentContent || !parentContent->IsHTML()) {
     mState.frame = nsnull;  // Don't walk frames in non-HTML content, just walk the DOM.
   }
 
   UpdateFrame(PR_TRUE);
 
   // Walk frames? UpdateFrame() sets this when it sees anonymous frames
   if (mState.siblingIndex == eSiblingsWalkFrames) {
     return;
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -755,17 +755,17 @@ nsCoreUtils::FindDescendantPointingToIDI
     }
   }
   return nsnull;
 }
 
 nsIContent*
 nsCoreUtils::GetLabelContent(nsIContent *aForNode)
 {
-  if (aForNode->IsNodeOfType(nsINode::eXUL))
+  if (aForNode->IsXUL())
     return FindNeighbourPointingToNode(aForNode, nsAccessibilityAtoms::control,
                                        nsAccessibilityAtoms::label);
 
   return GetHTMLLabelContent(aForNode);
 }
 
 nsIContent*
 nsCoreUtils::GetHTMLLabelContent(nsIContent *aForNode)
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -214,17 +214,17 @@ nsTextEquivUtils::AppendTextEquivFromTex
       if (isHTMLBlock && !aString->IsEmpty()) {
         aString->Append(PRUnichar(' '));
       }
     }
     
     return NS_OK;
   }
   
-  if (aContent->IsNodeOfType(nsINode::eHTML) &&
+  if (aContent->IsHTML() &&
       aContent->NodeInfo()->Equals(nsAccessibilityAtoms::br)) {
     aString->AppendLiteral("\r\n");
     return NS_OK;
   }
   
   return NS_OK_NO_NAME_CLAUSE_HANDLED;
 }
 
@@ -388,17 +388,17 @@ nsresult
 nsTextEquivUtils::AppendFromDOMNode(nsIContent *aContent, nsAString *aString)
 {
   nsresult rv = AppendTextEquivFromTextContent(aContent, aString);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
     return NS_OK;
 
-  if (aContent->IsNodeOfType(nsINode::eXUL)) {
+  if (aContent->IsXUL()) {
     nsAutoString textEquivalent;
     nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl =
       do_QueryInterface(aContent);
 
     if (labeledEl) {
       labeledEl->GetLabel(textEquivalent);
     } else {
       if (aContent->NodeInfo()->Equals(nsAccessibilityAtoms::label,
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -403,17 +403,17 @@ nsHTMLSelectListAccessible::CacheOptSibl
   // Recursive helper for CacheChildren()
 
   PRUint32 numChildren = aParentContent->GetChildCount();
   nsCOMPtr<nsIAccessible> lastGoodAccessible(aLastGoodAccessible);
   nsCOMPtr<nsIAccessible> newAccessible;
 
   for (PRUint32 count = 0; count < numChildren; count ++) {
     nsIContent *childContent = aParentContent->GetChildAt(count);
-    if (!childContent->IsNodeOfType(nsINode::eHTML)) {
+    if (!childContent->IsHTML()) {
       continue;
     }
     nsCOMPtr<nsIAtom> tag = childContent->Tag();
     if (tag == nsAccessibilityAtoms::option || tag == nsAccessibilityAtoms::optgroup) {
       newAccessible = AccessibleForOption(aAccService,
                                            childContent,
                                            lastGoodAccessible,
                                            aChildCount);
@@ -830,17 +830,17 @@ nsresult nsHTMLSelectOptionAccessible::G
   }
 
   return rv;
 }
 
 void nsHTMLSelectOptionAccessible::SelectionChangedIfOption(nsIContent *aPossibleOption)
 {
   if (!aPossibleOption || aPossibleOption->Tag() != nsAccessibilityAtoms::option ||
-      !aPossibleOption->IsNodeOfType(nsINode::eHTML)) {
+      !aPossibleOption->IsHTML()) {
     return;
   }
 
   nsCOMPtr<nsIDOMNode> optionNode(do_QueryInterface(aPossibleOption));
   NS_ASSERTION(optionNode, "No option node for nsIContent with option tag!");
 
   nsCOMPtr<nsIAccessible> multiSelect =
     nsAccUtils::GetMultiSelectFor(optionNode);
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -628,17 +628,17 @@ nsresult nsHyperTextAccessible::DOMPoint
     }
   }
 
   // Get accessible for this findNode, or if that node isn't accessible, use the
   // accessible for the next DOM node which has one (based on forward depth first search)
   nsCOMPtr<nsIAccessible> descendantAccessible;
   if (findNode) {
     nsCOMPtr<nsIContent> findContent = do_QueryInterface(findNode);
-    if (findContent->IsNodeOfType(nsINode::eHTML) && 
+    if (findContent->IsHTML() && 
         findContent->NodeInfo()->Equals(nsAccessibilityAtoms::br)) {
       nsIContent *parent = findContent->GetParent();
       if (parent &&
           parent->IsRootOfNativeAnonymousSubtree() &&
           parent->GetChildCount() == 1) {
         // This <br> is the only node in a text control, therefore it is the hacky
         // "bogus node" used when there is no text in a control
         *aHyperTextOffset = 0;
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -338,18 +338,20 @@ libs repackage:: $(PROGRAM) application.
 	rsync -a $(DIST)/bin/ $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
 	$(RM) $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/mangle $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/shlibsign
 ifdef LIBXUL_SDK
 	cp $(LIBXUL_DIST)/bin/$(XR_STUB_NAME) $(DIST)/$(APP_NAME).app/Contents/MacOS/firefox-bin
 else
 	rm -f $(DIST)/$(APP_NAME).app/Contents/MacOS/$(PROGRAM)
 	rsync -aL $(PROGRAM) $(DIST)/$(APP_NAME).app/Contents/MacOS
 endif
+ifndef MOZ_COCOA_PRINTING
 	mkdir -p $(DIST)/$(APP_NAME).app/Contents/Plug-Ins
 	rsync -a --copy-unsafe-links $(LIBXUL_DIST)/package/PrintPDE.plugin $(DIST)/$(APP_NAME).app/Contents/Plug-Ins
+endif
 	-cp -L $(DIST)/bin/mangle $(DIST)/bin/shlibsign $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
 	cp -RL $(DIST)/branding/firefox.icns $(DIST)/$(APP_NAME).app/Contents/Resources/firefox.icns
 	cp -RL $(DIST)/branding/document.icns $(DIST)/$(APP_NAME).app/Contents/Resources/document.icns
 	printf APPLMOZB > $(DIST)/$(APP_NAME).app/Contents/PkgInfo
 #       remove CVS dirs from packaged app
 	find $(DIST)/$(APP_NAME).app -type d -name "CVS" -prune -exec rm -rf {} \;
 
 else
--- a/browser/base/content/baseMenuOverlay.xul
+++ b/browser/base/content/baseMenuOverlay.xul
@@ -105,18 +105,18 @@
 #ifdef MOZ_UPDATER
         <menuitem id="checkForUpdates"
                   label="&updateCmd.label;"
                   class="menuitem-iconic"
                   oncommand="checkForUpdates();"/>
 #endif
         <menuseparator id="aboutSeparator"/>
         <menuitem id="aboutName"
-                  accesskey="&aboutCmd.accesskey;"
-                  label="&aboutCmd.label;"
+                  accesskey="&aboutProduct.accesskey;"
+                  label="&aboutProduct.label;"
                   oncommand="openAboutDialog();"/>
       </menupopup>
     </menu>
 
     <keyset id="baseMenuKeyset">
 #ifdef XP_MACOSX
         <key id="key_openHelpMac"
              oncommand="openHelpLink('firefox-osxkey');"
--- a/browser/base/content/browser-context.inc
+++ b/browser/base/content/browser-context.inc
@@ -97,16 +97,20 @@
       <menuitem id="context-media-showcontrols"
                 label="&mediaShowControls.label;"
                 accesskey="&mediaShowControls.accesskey;"
                 oncommand="gContextMenu.mediaCommand('showcontrols');"/>
       <menuitem id="context-media-hidecontrols"
                 label="&mediaHideControls.label;"
                 accesskey="&mediaHideControls.accesskey;"
                 oncommand="gContextMenu.mediaCommand('hidecontrols');"/>
+      <menuitem id="context-video-fullscreen"
+                accesskey="&videoFullScreen.accesskey;"
+                label="&videoFullScreen.label;"
+                oncommand="gContextMenu.fullScreenVideo();"/>
       <menuseparator id="context-media-sep-commands"/>
       <menuitem id="context-reloadimage"
                 label="&reloadImageCmd.label;"
                 accesskey="&reloadImageCmd.accesskey;"
                 oncommand="gContextMenu.reloadImage();"/>
       <menuitem id="context-viewimage"
                 label="&viewImageCmd.label;"
                 accesskey="&viewImageCmd.accesskey;"
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -66,16 +66,18 @@ toolbarpaletteitem[place="palette"] > to
 }
 
 #identity-box > hbox {
   max-width: 22em;
   min-width: 1px;
 }
 
 /* ::::: Unified Back-/Forward Button ::::: */
+#back-button > dropmarker,
+#forward-button > dropmarker,
 #back-forward-dropmarker > image ,
 #back-forward-dropmarker > label {
   display: none;
 }
 .unified-nav-current {
   font-weight: bold;
 }
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -78,20 +78,16 @@ var gInPrintPreviewMode = false;
 let gDownloadMgr = null;
 
 // Global variable that holds the nsContextMenu instance.
 var gContextMenu = null;
 
 var gAutoHideTabbarPrefListener = null;
 var gBookmarkAllTabsHandler = null;
 
-#ifdef XP_MACOSX
-var gClickAndHoldTimer = null;
-#endif
-
 #ifndef XP_MACOSX
 var gEditUIVisible = true;
 #endif
 
 [
   ["gBrowser",            "content"],
   ["gNavToolbox",         "navigator-toolbox"],
   ["gURLBar",             "urlbar"],
@@ -190,75 +186,72 @@ function UpdateBackForwardCommands(aWebN
   }
 }
 
 #ifdef XP_MACOSX
 /**
  * Click-and-Hold implementation for the Back and Forward buttons
  * XXXmano: should this live in toolbarbutton.xml?
  */
-function ClickAndHoldMouseDownCallback(aButton) {
-  aButton.open = true;
-  gClickAndHoldTimer = null;
-}
-
-function ClickAndHoldMouseDown(aEvent) {
-  /**
-   * 1. Only left click starts the click and hold timer.
-   * 2. Exclude the dropmarker area. This is done by excluding
-   *    elements which target their events directly to the toolbarbutton
-   *    element, i.e. when the nearest-parent-element which allows-events
-   *    is the toolbarbutton element itself.
-   * 3. Do not start the click-and-hold timer if the toolbarbutton is disabled.
-   */
-  if (aEvent.button != 0 ||
-      aEvent.originalTarget == aEvent.currentTarget ||
-      aEvent.currentTarget.disabled)
-    return;
-
-  gClickAndHoldTimer =
-    setTimeout(ClickAndHoldMouseDownCallback, 500, aEvent.currentTarget);
-}
-
-function MayStopClickAndHoldTimer(aEvent) {
-  // Note passing null here is a no-op
-  clearTimeout(gClickAndHoldTimer);
-}
-
-function ClickAndHoldStopEvent(aEvent) {
-  if (aEvent.originalTarget.localName != "menuitem" &&
-      aEvent.currentTarget.open)
-    aEvent.stopPropagation();
-}
-
 function SetClickAndHoldHandlers() {
+  var timer;
+
+  function timerCallback(aButton) {
+    aButton.firstChild.hidden = false;
+    aButton.open = true;
+    timer = null;
+  }
+
+  function mousedownHandler(aEvent) {
+    if (aEvent.button != 0 ||
+        aEvent.currentTarget.open ||
+        aEvent.currentTarget.disabled)
+      return;
+
+    // Prevent the menupopup from opening immediately
+    aEvent.currentTarget.firstChild.hidden = true;
+
+    timer = setTimeout(timerCallback, 500, aEvent.currentTarget);
+  }
+
+  function clickHandler(aEvent) {
+    if (aEvent.button == 0 &&
+        aEvent.target == aEvent.currentTarget &&
+        !aEvent.currentTarget.open &&
+        !aEvent.currentTarget.disabled)
+      aEvent.currentTarget.doCommand();
+  }
+
+  function stopTimer(aEvent) {
+    if (timer) {
+      clearTimeout(timer);
+      timer = null;
+    }
+  }
+
   function _addClickAndHoldListenersOnElement(aElm) {
-    aElm.addEventListener("mousedown", ClickAndHoldMouseDown, false);
-    aElm.addEventListener("mouseup", MayStopClickAndHoldTimer, false);
-    aElm.addEventListener("mouseout", MayStopClickAndHoldTimer, false);
-
-    // don't propagate onclick and oncommand events after
-    // click-and-hold opened the drop-down menu
-    aElm.addEventListener("command", ClickAndHoldStopEvent, true);
-    aElm.addEventListener("click", ClickAndHoldStopEvent, true);
+    aElm.addEventListener("mousedown", mousedownHandler, true);
+    aElm.addEventListener("mouseup", stopTimer, false);
+    aElm.addEventListener("mouseout", stopTimer, false);
+    aElm.addEventListener("click", clickHandler, true);
   }
 
   // Bug 414797: Clone the dropmarker's menu into both the back and
   // the forward buttons.
   var unifiedButton = document.getElementById("unified-back-forward-button");
   if (unifiedButton && !unifiedButton._clickHandlersAttached) {
     var popup = document.getElementById("back-forward-dropmarker")
                         .firstChild.cloneNode(true);
     var backButton = document.getElementById("back-button");
-    backButton.setAttribute("type", "menu-button");
+    backButton.setAttribute("type", "menu");
     backButton.appendChild(popup);
     _addClickAndHoldListenersOnElement(backButton);
     var forwardButton = document.getElementById("forward-button");
     popup = popup.cloneNode(true);
-    forwardButton.setAttribute("type", "menu-button");
+    forwardButton.setAttribute("type", "menu");
     forwardButton.appendChild(popup);    
     _addClickAndHoldListenersOnElement(forwardButton);
     unifiedButton._clickHandlersAttached = true;
   }
 }
 #endif
 
 function BookmarkThisTab() {
new file mode 100644
--- /dev/null
+++ b/browser/base/content/fullscreen-video.xhtml
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<!--
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Dão Gottwald <dao@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <style type="text/css"><![CDATA[
+
+html,
+body,
+video {
+  height: 100%;
+}
+body {
+  margin: 0;
+  background: black;
+  overflow: -moz-hidden-unscrollable;
+}
+body.userIdle {
+  cursor: none;
+}
+video {
+  width: 100%;
+  max-height: 100%;
+}
+body.loadingdata > video,
+body.loadingdata > #close,
+body.userIdle > #close {
+  visibility: hidden;
+}
+
+  ]]></style>
+  <link href="chrome://browser/skin/fullscreen-video.css"
+        rel="stylesheet" type="text/css"/>
+  <script type="application/javascript"><![CDATA[
+
+var contentVideo = window.arguments[0];
+var video;
+
+var title = (contentVideo.currentSrc || contentVideo.src).replace(/^.*\//, "");
+try {
+  title = decodeURI(title);
+} catch (e) {}
+document.title = title;
+
+window.addEventListener("focus", function () {
+  window.removeEventListener("focus", arguments.callee, false);
+
+  window.fullScreen = true;
+
+  video = document.querySelector("video");
+
+  video.addEventListener("loadeddata", function () {
+    video.removeEventListener("loadeddata", arguments.callee, false);
+    video.volume = contentVideo.volume;
+    video.muted = contentVideo.muted;
+    video.poster = contentVideo.poster;
+
+    if (contentVideo.currentTime && !contentVideo.ended) {
+      video.addEventListener("seeked", function () {
+        video.removeEventListener("seeked", arguments.callee, false);
+        playbackStarts();
+      }, false);
+
+      video.currentTime = contentVideo.currentTime;
+    } else {
+      playbackStarts();
+    }
+
+    video.controls = true;
+    video.play();
+  }, false);
+
+  // Automatically close this window when the playback ended, unless the user
+  // interacted with it.
+  video.addEventListener("ended", autoClose, false);
+  window.addEventListener("click", cancelAutoClose, false);
+  window.addEventListener("keypress", cancelAutoClose, false);
+
+  video.addEventListener("playing", hideUI, false);
+  video.addEventListener("seeked", hideUI, false);
+  video.addEventListener("seeking", showUI, false);
+  video.addEventListener("pause", showUI, false);
+  video.addEventListener("ended", showUI, false);
+
+  window.addEventListener("mousemove", function () {
+    showUI();
+    resetIdleTimer();
+  }, false);
+
+  video.mozLoadFrom(contentVideo);
+}, false);
+
+window.addEventListener("unload", function () {
+  if (video.currentSrc) {
+    contentVideo.currentTime = video.currentTime;
+    contentVideo.volume = video.volume;
+    contentVideo.muted = video.muted;
+    if (!video.paused && !video.ended) {
+      video.pause();
+      contentVideo.play();
+    }
+  }
+}, false);
+
+window.addEventListener("keypress", function (event) {
+  if (event.keyCode == event.DOM_VK_ESCAPE) {
+    window.close();
+    return;
+  }
+
+  resetIdleTimer();
+
+  if (!video.controls &&
+      String.fromCharCode(event.charCode) == " ")
+    video.pause();
+}, false);
+
+function playbackStarts() {
+  // Loading the data from the content video may take a second or two. We hide
+  // the video during that period.
+  document.body.classList.remove("loadingdata");
+  video.focus();
+}
+
+function autoClose() {
+  window.close();
+}
+
+function cancelAutoClose() {
+  video.removeEventListener("ended", autoClose, false);
+  window.removeEventListener("click", cancelAutoClose, false);
+  window.removeEventListener("keypress", cancelAutoClose, false);
+}
+
+var idleTimer;
+function resetIdleTimer() {
+  if (idleTimer) {
+    clearTimeout(idleTimer);
+    idleTimer = 0;
+  }
+  idleTimer = setTimeout(function () {
+    idleTimer = 0;
+    hideUI();
+  }, 2000);
+}
+
+function showUI() {
+  if (!video.controls) {
+    document.body.classList.remove("userIdle");
+    video.controls = true;
+  }
+}
+
+function hideUI() {
+  if (!video.paused && !video.ended && !video.seeking && !video.error) {
+    document.body.classList.add("userIdle");
+    video.controls = false;
+  }
+}
+
+  ]]></script>
+</head>
+<body class="loadingdata">
+  <span id="close" onclick="window.close();"/>
+  <video/>
+</body>
+</html>
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -409,27 +409,30 @@ nsContextMenu.prototype = {
 
   initMediaPlayerItems: function() {
     var onMedia = (this.onVideo || this.onAudio);
     // Several mutually exclusive items... play/pause, mute/unmute, show/hide
     this.showItem("context-media-play",  onMedia && (this.target.paused || this.target.ended));
     this.showItem("context-media-pause", onMedia && !this.target.paused && !this.target.ended);
     this.showItem("context-media-mute",   onMedia && !this.target.muted);
     this.showItem("context-media-unmute", onMedia && this.target.muted);
-    this.showItem("context-media-showcontrols", onMedia && !this.target.controls)
-    this.showItem("context-media-hidecontrols", onMedia && this.target.controls)
+    this.showItem("context-media-showcontrols", onMedia && !this.target.controls);
+    this.showItem("context-media-hidecontrols", onMedia && this.target.controls);
+    this.showItem("context-video-fullscreen", this.onVideo);
     // Disable them when there isn't a valid media source loaded.
     if (onMedia) {
       var hasError = (this.target.error != null);
       this.setItemAttr("context-media-play",  "disabled", hasError);
       this.setItemAttr("context-media-pause", "disabled", hasError);
       this.setItemAttr("context-media-mute",   "disabled", hasError);
       this.setItemAttr("context-media-unmute", "disabled", hasError);
       this.setItemAttr("context-media-showcontrols", "disabled", hasError);
       this.setItemAttr("context-media-hidecontrols", "disabled", hasError);
+      if (this.onVideo)
+        this.setItemAttr("context-video-fullscreen",  "disabled", hasError);
     }
     this.showItem("context-media-sep-commands",  onMedia);
   },
 
   // Set various context menu attributes based on the state of the world.
   setTarget: function (aNode, aRangeParent, aRangeOffset) {
     const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
     if (aNode.namespaceURI == xulNS ||
@@ -798,16 +801,23 @@ nsContextMenu.prototype = {
                        this.browser.contentPrincipal,
                        Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
     }
 
     var doc = this.target.ownerDocument;
     openUILink(viewURL, e, null, null, null, null, doc.documentURIObject );
   },
 
+  fullScreenVideo: function () {
+    this.target.pause();
+
+    openDialog("chrome://browser/content/fullscreen-video.xhtml",
+               "", "chrome,dialog=no", this.target);
+  },
+
   // Change current window to the URL of the background image.
   viewBGImage: function(e) {
     urlSecurityCheck(this.bgImageURL,
                      this.browser.contentPrincipal,
                      Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
     var doc = this.target.ownerDocument;
     openUILink(this.bgImageURL, e, null, null, null, null, doc.documentURIObject );
   },
@@ -1365,27 +1375,21 @@ nsContextMenu.prototype = {
   addBookmarkForFrame: function CM_addBookmarkForFrame() {
     var doc = this.target.ownerDocument;
     var uri = doc.documentURIObject;
 
     var itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
     if (itemId == -1) {
       var title = doc.title;
       var description = PlacesUIUtils.getDescriptionFromDocument(doc);
-
-      var descAnno = { name: DESCRIPTION_ANNO, value: description };
-      var txn = PlacesUIUtils.ptm.createItem(uri, 
-                                           PlacesUtils.bookmarksMenuFolderId,
-                                           -1, title, null, [descAnno]);
-      PlacesUIUtils.ptm.doTransaction(txn);
-      itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
-      StarUI.beginBatch();
+      PlacesUIUtils.showMinimalAddBookmarkUI(uri, title, description);
     }
-
-    window.top.StarUI.showEditBookmarkPopup(itemId, this.browser, "overlap");
+    else
+      PlacesUIUtils.showItemProperties(itemId,
+                                       PlacesUtils.bookmarks.TYPE_BOOKMARK);
   },
 
   savePageAs: function CM_savePageAs() {
     saveDocument(this.browser.contentDocument);
   },
 
   sendPage: function CM_sendPage() {
     MailIntegration.sendLinkForWindow(this.browser.contentWindow);  
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -300,25 +300,43 @@
             mStateFlags: 0,
             mStatus: 0,
             mMessage: "",
             mTotalProgress: 0,
 
             // count of open requests (should always be 0 or 1)
             mRequestCount: 0,
 
+            destroy: function () {
+              this._cancelStalledTimer();
+              this.mTab.removeAttribute("stalled");
+              delete this.mTab;
+              delete this.mBrowser;
+              delete this.mTabBrowser;
+            },
+
             onProgressChange : function (aWebProgress, aRequest,
                                          aCurSelfProgress, aMaxSelfProgress,
                                          aCurTotalProgress, aMaxTotalProgress)
             {
               this.mTotalProgress = aMaxTotalProgress ? aCurTotalProgress / aMaxTotalProgress : 0;
 
               if (this.mBlank)
                 return;
 
+              if (this.mTotalProgress) {
+                const STATES = 8;
+                let state = Math.ceil(STATES * this.mTotalProgress);
+                if (state != this.mTab.getAttribute("progress")) {
+                  this.mTab.setAttribute("progress", state);
+                  this.mTab.removeAttribute("stalled");
+                  this._startStalledTimer();
+                }
+              }
+
               if (this.mTabBrowser.mCurrentTab == this.mTab) {
                 for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
                   let p = this.mTabBrowser.mProgressListeners[i];
                   if (p)
                     try {
                       p.onProgressChange(aWebProgress, aRequest,
                                          aCurSelfProgress, aMaxSelfProgress,
                                          aCurTotalProgress, aMaxTotalProgress);
@@ -388,16 +406,17 @@
                 // cancelled a pending load which would have cleared
                 // its anchor scroll detection temporary increment.
                 if (aWebProgress.DOMWindow == this.mBrowser.contentWindow)
                   this.mBrowser.userTypedClear += 2;
 
                 if (!this.mBlank) {
                   if (!(aStateFlags & nsIWebProgressListener.STATE_RESTORING)) {
                     this.mTab.setAttribute("busy", "true");
+                    this._startStalledTimer();
                     this.mTabBrowser.updateIcon(this.mTab);
                     this.mTabBrowser.setTabTitleLoading(this.mTab);
                   }
 
                   if (this.mTabBrowser.mCurrentTab == this.mTab)
                     this.mTabBrowser.mIsBusy = true;
                 }
               }
@@ -414,16 +433,19 @@
                   if (!this.mBrowser.mIconURL)
                     this.mTabBrowser.useDefaultIcon(this.mTab);
                 }
 
                 if (this.mBlank)
                   this.mBlank = false;
 
                 this.mTab.removeAttribute("busy");
+                this.mTab.removeAttribute("progress");
+                this.mTab.removeAttribute("stalled");
+                this._cancelStalledTimer();
                 this.mTabBrowser.updateIcon(this.mTab);
 
                 var location = aRequest.QueryInterface(nsIChannel).URI;
 
                 // For keyword URIs clear the user typed value since they will be changed into real URIs
                 if (location.scheme == "keyword")
                   this.mBrowser.userTypedValue = null;
 
@@ -608,16 +630,30 @@
             QueryInterface : function(aIID)
             {
               if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
                   aIID.equals(Components.interfaces.nsIWebProgressListener2) ||
                   aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
                   aIID.equals(Components.interfaces.nsISupports))
                 return this;
               throw Components.results.NS_NOINTERFACE;
+            },
+
+            _startStalledTimer: function () {
+              this._cancelStalledTimer();
+              this._stalledTimer = setTimeout(function (self) { 
+                self.mTab.setAttribute("stalled", "true");
+              }, 700, this);
+            },
+
+            _cancelStalledTimer: function () {
+              if (this._stalledTimer) {
+                clearTimeout(this._stalledTimer);
+                this._stalledTimer = 0;
+              }
             }
           });
         ]]>
         </body>
       </method>
 
       <method name="setIcon">
         <parameter name="aTab"/>
@@ -1491,16 +1527,17 @@
             var evt = document.createEvent("UIEvent");
             evt.initUIEvent("TabClose", true, false, window, aTabWillBeMoved ? 1 : 0);
             aTab.dispatchEvent(evt);
 
             // Remove the tab's filter and progress listener.
             const filter = this.mTabFilters[aTab._tPos];
             browser.webProgress.removeProgressListener(filter);
             filter.removeProgressListener(this.mTabListeners[aTab._tPos]);
+            this.mTabListeners[aTab._tPos].destroy();
 
             // Remove our title change and blocking listeners
             browser.removeEventListener("DOMTitleChanged", this.onTitleChanged, true);
 
             // We are no longer the primary content area.
             browser.setAttribute("type", "content-targetable");
 
             // Remove this tab as the owner of any other tabs, since it's going away.
@@ -2731,16 +2768,17 @@
       </constructor>
 
       <destructor>
         <![CDATA[
           for (var i = 0; i < this.mTabListeners.length; ++i) {
             this.getBrowserAtIndex(i).webProgress.removeProgressListener(this.mTabFilters[i]);
             this.mTabFilters[i].removeProgressListener(this.mTabListeners[i]);
             this.mTabFilters[i] = null;
+            this.mTabListeners[i].destroy();
             this.mTabListeners[i] = null;
             this.getBrowserAtIndex(i).removeEventListener("DOMTitleChanged", this.onTitleChanged, true);
           }
           document.removeEventListener("keypress", this._keyEventHandler, false);
         ]]>
       </destructor>
     </implementation>
 
--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -23,17 +23,17 @@ netscape.security.PrivilegeManager.enabl
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 function openContextMenuFor(element) {
     // Context menu should be closed before we open it again.
     is(contextMenu.state, "closed", "checking if popup is closed");
 
-    var eventDetails = { type : "contextmenu", button : 2 }
+    var eventDetails = { type : "contextmenu", button : 2 };
     synthesizeMouse(element, 2, 2, eventDetails, element.ownerDocument.defaultView);
 }
 
 function closeContextMenu() {
     contextMenu.hidePopup();
 }
 
 function getVisibleMenuItems(aMenu) {
@@ -49,30 +49,30 @@ function getVisibleMenuItems(aMenu) {
             key = key.toLowerCase();
 
         if (item.nodeName == "menuitem") {
             ok(item.id, "child menuitem #" + i + " has an ID");
             ok(key, "menuitem has an access key");
             if (accessKeys[key])
                 ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
             else
-                accessKeys[key] = item.id
+                accessKeys[key] = item.id;
             items.push(item.id);
             items.push(!item.disabled);
         } else if (item.nodeName == "menuseparator") {
             ok(true, "--- seperator id is " + item.id);
             items.push("---");
             items.push(null);
         } else if (item.nodeName == "menu") {
             ok(item.id, "child menu #" + i + " has an ID");
             ok(key, "menu has an access key");
             if (accessKeys[key])
                 ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]);
             else
-                accessKeys[key] = item.id
+                accessKeys[key] = item.id;
             items.push(item.id);
             items.push(!item.disabled);
             // Add a dummy item to that the indexes in checkMenu are the same
             // for expectedItems and actualItems.
             items.push([]);
             items.push(null);
         } else {
             ok(false, "child #" + i + " of menu ID " + aMenu.id +
@@ -156,53 +156,53 @@ function runTest(testNum) {
                           "context-savepage",     true,
                           "context-sendpage",     true,
                           "---",                  null,
                           "context-viewbgimage",  false,
                           "context-selectall",    true,
                           "---",                  null,
                           "context-viewsource",   true,
                           "context-viewinfo",     true]);
-        closeContextMenu()
+        closeContextMenu();
         openContextMenuFor(link); // Invoke context menu for next test.
         break;
 
     case 3:
         // Context menu for text link
         checkContextMenu(["context-openlink",      true,
                           "context-openlinkintab", true,
                           "---",                   null,
                           "context-bookmarklink",  true,
                           "context-savelink",      true,
                           "context-sendlink",      true,
                           "context-copylink",      true]);
-        closeContextMenu()
+        closeContextMenu();
         openContextMenuFor(mailto); // Invoke context menu for next test.
         break;
 
     case 4:
         // Context menu for text mailto-link
         checkContextMenu(["context-copyemail", true]);
-        closeContextMenu()
+        closeContextMenu();
         openContextMenuFor(input); // Invoke context menu for next test.
         break;
 
     case 5:
         // Context menu for text input field
         checkContextMenu(["context-undo",        false,
                           "---",                 null,
                           "context-cut",         false,
                           "context-copy",        false,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      false,
                           "---",                 null,
                           "context-selectall",   true,
                           "---",                 null,
                           "spell-check-enabled", true]);
-        closeContextMenu()
+        closeContextMenu();
         openContextMenuFor(img); // Invoke context menu for next test.
         break;
 
     case 6:
         // Context menu for an image
         checkContextMenu(["context-viewimage",            true,
                           "context-copyimage-contents",   true,
                           "context-copyimage",            true,
@@ -225,46 +225,49 @@ function runTest(testNum) {
         openContextMenuFor(video_ok); // Invoke context menu for next test.
         break;
 
     case 8:
         // Context menu for a video (with a VALID media source)
         checkContextMenu(["context-media-play",         true,
                           "context-media-mute",         true,
                           "context-media-showcontrols", true,
+                          "context-video-fullscreen",   true,
                           "---",                        null,
                           "context-viewvideo",          true,
                           "context-copyvideourl",       true,
                           "---",                        null,
                           "context-savevideo",          true,
                           "context-sendvideo",          true]);
         closeContextMenu();
         openContextMenuFor(video_bad); // Invoke context menu for next test.
         break;
 
     case 9:
         // Context menu for a video (with a INVALID media source)
         checkContextMenu(["context-media-play",         false,
                           "context-media-mute",         false,
                           "context-media-showcontrols", false,
+                          "context-video-fullscreen",   false,
                           "---",                        null,
                           "context-viewvideo",          true,
                           "context-copyvideourl",       true,
                           "---",                        null,
                           "context-savevideo",          true,
                           "context-sendvideo",          true]);
         closeContextMenu();
         openContextMenuFor(video_bad2); // Invoke context menu for next test.
         break;
 
     case 10:
         // Context menu for a video (with a INVALID media source)
         checkContextMenu(["context-media-play",         false,
                           "context-media-mute",         false,
                           "context-media-showcontrols", false,
+                          "context-video-fullscreen",   false,
                           "---",                        null,
                           "context-viewvideo",          false,
                           "context-copyvideourl",       false,
                           "---",                        null,
                           "context-savevideo",          false,
                           "context-sendvideo",          false]);
         closeContextMenu();
         openContextMenuFor(iframe); // Invoke context menu for next test.
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -19,16 +19,17 @@ browser.jar:
         content/browser/aboutRobots-widget-left.png   (content/aboutRobots-widget-left.png)
         content/browser/aboutRobots-widget-right.png  (content/aboutRobots-widget-right.png)
 *       content/browser/aboutSupport.xhtml            (content/aboutSupport.xhtml)
 *       content/browser/browser.css                   (content/browser.css)
 *       content/browser/browser.js                    (content/browser.js)
 *       content/browser/browser.xul                   (content/browser.xul)
 *       content/browser/browser-tabPreviews.xml       (content/browser-tabPreviews.xml)
 *       content/browser/credits.xhtml                 (content/credits.xhtml)
+*       content/browser/fullscreen-video.xhtml        (content/fullscreen-video.xhtml)
 *       content/browser/pageinfo/pageInfo.xul         (content/pageinfo/pageInfo.xul)
 *       content/browser/pageinfo/pageInfo.js          (content/pageinfo/pageInfo.js)
 *       content/browser/pageinfo/pageInfo.css         (content/pageinfo/pageInfo.css)
 *       content/browser/pageinfo/feeds.js             (content/pageinfo/feeds.js)
 *       content/browser/pageinfo/feeds.xml            (content/pageinfo/feeds.xml)
 *       content/browser/pageinfo/permissions.js       (content/pageinfo/permissions.js)
 *       content/browser/pageinfo/security.js          (content/pageinfo/security.js)
 *       content/browser/openLocation.js               (content/openLocation.js)
--- a/browser/locales/en-US/chrome/browser/baseMenuOverlay.dtd
+++ b/browser/locales/en-US/chrome/browser/baseMenuOverlay.dtd
@@ -5,18 +5,18 @@
 <!ENTITY windowMenu.label         "Window">
 
 <!ENTITY helpMenu.label           "Help"> 
 <!ENTITY helpMenu.accesskey       "H"> 
 <!-- LOCALIZATION NOTE some localizations of Windows (ex:french, german) use "?"
                        for the help button in the menubar but Gnome does not.   -->
 <!ENTITY helpMenuWin.label        "Help"> 
 <!ENTITY helpMenuWin.accesskey    "H">
-<!ENTITY aboutCmd.label           "About &brandFullName;">
-<!ENTITY aboutCmd.accesskey       "A">
+<!ENTITY aboutProduct.label       "About &brandShortName;">
+<!ENTITY aboutProduct.accesskey   "A">
 <!ENTITY productHelp.label        "&brandShortName; Help">
 <!ENTITY productHelp.accesskey    "H">
 <!ENTITY helpForIEUsers.label     "For Internet Explorer Users">
 <!ENTITY helpForIEUsers.accesskey "I">
 <!ENTITY openHelp.commandkey      "VK_F1">
 <!ENTITY helpMac.commandkey       "?">
 
 <!ENTITY helpReleaseNotes.label         "Release Notes">
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -330,16 +330,18 @@
 <!ENTITY mediaMute.label             "Mute">
 <!ENTITY mediaMute.accesskey         "M">
 <!ENTITY mediaUnmute.label           "Unmute">
 <!ENTITY mediaUnmute.accesskey       "m">
 <!ENTITY mediaShowControls.label     "Show Controls">
 <!ENTITY mediaShowControls.accesskey "C">
 <!ENTITY mediaHideControls.label     "Hide Controls">
 <!ENTITY mediaHideControls.accesskey "C">
+<!ENTITY videoFullScreen.label       "Full Screen">
+<!ENTITY videoFullScreen.accesskey   "F">
 
 
 <!-- LOCALIZATION NOTE :
 fullZoomEnlargeCmd.commandkey3, fullZoomReduceCmd.commandkey2 and
 fullZoomResetCmd.commandkey2 are alternative acceleration keys for zoom.
 If shift key is needed with your locale popular keyboard for them,
 you can use these alternative items. Otherwise, their values should be empty.  -->
 
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -1122,17 +1122,45 @@ tabpanels {
   height: 16px;
   -moz-margin-start: 4px;
   -moz-margin-end: 3px;
   list-style-image: url("chrome://global/skin/icons/folder-item.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
 
 .tabbrowser-tab[busy] > .tab-icon-image {
-  list-style-image: url("chrome://global/skin/icons/loading_16.png") !important;
+  list-style-image: url("chrome://browser/skin/tabbrowser/progress.png") !important;
+  -moz-image-region: rect(0, 16px, 16px, 0);
+}
+.tabbrowser-tab[busy][stalled] > .tab-icon-image {
+  list-style-image: url("chrome://browser/skin/tabbrowser/progress-pulsing.png") !important;
+}
+.tabbrowser-tab[busy][progress="1"] > .tab-icon-image {
+  -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+.tabbrowser-tab[busy][progress="2"] > .tab-icon-image {
+  -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+.tabbrowser-tab[busy][progress="3"] > .tab-icon-image {
+  -moz-image-region: rect(0, 64px, 16px, 48px);
+}
+.tabbrowser-tab[busy][progress="4"] > .tab-icon-image {
+  -moz-image-region: rect(0, 80px, 16px, 64px);
+}
+.tabbrowser-tab[busy][progress="5"] > .tab-icon-image {
+  -moz-image-region: rect(0, 96px, 16px, 80px);
+}
+.tabbrowser-tab[busy][progress="6"] > .tab-icon-image {
+  -moz-image-region: rect(0, 112px, 16px, 96px);
+}
+.tabbrowser-tab[busy][progress="7"] > .tab-icon-image {
+  -moz-image-region: rect(0, 128px, 16px, 112px);
+}
+.tabbrowser-tab[busy][progress="8"] > .tab-icon-image {
+  -moz-image-region: rect(0, 144px, 16px, 128px);
 }
 
 .tabs-bottom {
   border-bottom: 1px solid threedshadow;
 }
 
 #context_newTab {
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
new file mode 100644
--- /dev/null
+++ b/browser/themes/gnomestripe/browser/fullscreen-video.css
@@ -0,0 +1,8 @@
+#close {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 32px;
+  height: 32px;
+  background: url(KUI-close.png) center center no-repeat;
+}
--- a/browser/themes/gnomestripe/browser/jar.mn
+++ b/browser/themes/gnomestripe/browser/jar.mn
@@ -3,16 +3,17 @@ browser.jar:
 % override chrome://global/skin/icons/warning-16.png moz-icon://stock/gtk-dialog-warning?size=menu
   skin/classic/browser/sanitizeDialog.css             (sanitizeDialog.css)
 * skin/classic/browser/aboutPrivateBrowsing.css             (aboutPrivateBrowsing.css)
 * skin/classic/browser/aboutSessionRestore.css        (aboutSessionRestore.css)
   skin/classic/browser/aboutSessionRestore-window-icon.png
   skin/classic/browser/aboutCertError.css             (aboutCertError.css)
 * skin/classic/browser/browser.css                    (browser.css)
 * skin/classic/browser/engineManager.css              (engineManager.css)
+  skin/classic/browser/fullscreen-video.css
   skin/classic/browser/Geo.png
   skin/classic/browser/Go-arrow.png
   skin/classic/browser/identity.png
   skin/classic/browser/Info.png
   skin/classic/browser/KUI-close.png
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
 * skin/classic/browser/pageInfo.css
@@ -54,9 +55,11 @@ browser.jar:
   skin/classic/browser/places/toolbarDropMarker.png   (places/toolbarDropMarker.png)
   skin/classic/browser/places/unsortedBookmarks.png   (places/unsortedBookmarks.png)
   skin/classic/browser/preferences/alwaysAsk.png      (preferences/alwaysAsk.png)
   skin/classic/browser/preferences/mail.png           (preferences/mail.png)
   skin/classic/browser/preferences/Options.png        (preferences/Options.png)
 * skin/classic/browser/preferences/preferences.css    (preferences/preferences.css)
   skin/classic/browser/preferences/applications.css   (preferences/applications.css)
   skin/classic/browser/tabbrowser/alltabs.png          (tabbrowser/alltabs.png)
+  skin/classic/browser/tabbrowser/progress.png         (tabbrowser/progress.png)
+  skin/classic/browser/tabbrowser/progress-pulsing.png (tabbrowser/progress-pulsing.png)
   skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
new file mode 100644
index 0000000000000000000000000000000000000000..3c66ed3c8e9fffbf428441b8015217ea2f575776
GIT binary patch
literal 10429
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
Sv(xa0-&B>f6yGUWh5ZNL!5OIl
new file mode 100644
index 0000000000000000000000000000000000000000..b8bd2efe554ea9d42d6c4a489e0a3a15e620521f
GIT binary patch
literal 2088
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
SX?6Jk0000<MNUMnLSTZ@*b?;s
index 9bbfe10662ee4c540666d196565e09702b06ddd1..31167bd90a3b806a4dfd3ad04cccf1cc9811ca72
GIT binary patch
literal 34227
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
CRLipf
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -382,36 +382,16 @@ toolbar[mode="text"] .toolbarbutton-1 > 
 
 toolbarbutton:not([disabled="true"]):hover,
 menubutton:not([disabled="true"]):hover,
 toolbarbutton:not([disabled="true"]):hover:active,
 menubutton:not([disabled="true"]):hover:active {
   color: ButtonText !important;
 }
 
-toolbar:not([mode="text"]) #back-button .toolbarbutton-menubutton-button,
-toolbar:not([mode="text"]) #forward-button .toolbarbutton-menubutton-button {
-  margin: 0;
-  padding: 0;
-  border-left: 0;
-  border-right: 0;
-}
-
-toolbar:not([mode="text"]) #back-button .toolbarbutton-menubutton-dropmarker,
-toolbar:not([mode="text"]) #forward-button .toolbarbutton-menubutton-dropmarker {
-  margin-top: 1px;
-}
-
-toolbar[mode="icons"] #back-button .toolbarbutton-text-box,
-toolbar[mode="icons"] #forward-button .toolbarbutton-text-box,
-#back-button > dropmarker,
-#forward-button > dropmarker {
-  display: none;
-}
-
 #back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
 #forward-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
 #back-forward-dropmarker:-moz-locale-dir(rtl) > .toolbarbutton-icon {
   -moz-transform: scaleX(-1);
 }
 
 /* ----- DEFAULT BACK BUTTON, STAND-ALONE ----- */	
 
@@ -1492,17 +1472,45 @@ tabbrowser > tabbox {
   margin-top: 2px;
 }
 
 .tabbrowser-tab[selected="true"] > .tab-icon-image {
   list-style-image: url("chrome://global/skin/tree/item.png");
 }
 
 .tabbrowser-tab[busy] > .tab-icon-image {
-  list-style-image: url("chrome://global/skin/icons/loading_16.png") !important;
+  list-style-image: url("chrome://browser/skin/tabbrowser/progress.png") !important;
+  -moz-image-region: rect(0, 16px, 16px, 0);
+}
+.tabbrowser-tab[busy][stalled] > .tab-icon-image {
+  list-style-image: url("chrome://browser/skin/tabbrowser/progress-pulsing.png") !important;
+}
+.tabbrowser-tab[busy][progress="1"] > .tab-icon-image {
+  -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+.tabbrowser-tab[busy][progress="2"] > .tab-icon-image {
+  -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+.tabbrowser-tab[busy][progress="3"] > .tab-icon-image {
+  -moz-image-region: rect(0, 64px, 16px, 48px);
+}
+.tabbrowser-tab[busy][progress="4"] > .tab-icon-image {
+  -moz-image-region: rect(0, 80px, 16px, 64px);
+}
+.tabbrowser-tab[busy][progress="5"] > .tab-icon-image {
+  -moz-image-region: rect(0, 96px, 16px, 80px);
+}
+.tabbrowser-tab[busy][progress="6"] > .tab-icon-image {
+  -moz-image-region: rect(0, 112px, 16px, 96px);
+}
+.tabbrowser-tab[busy][progress="7"] > .tab-icon-image {
+  -moz-image-region: rect(0, 128px, 16px, 112px);
+}
+.tabbrowser-tab[busy][progress="8"] > .tab-icon-image {
+  -moz-image-region: rect(0, 144px, 16px, 128px);
 }
 
 .tabbrowser-tab:not(:hover):not([selected="true"]) > .tab-icon-image {
   opacity: .6;
 }
 
 .tabbrowser-tab > .tab-text {
   margin-top: 3px;
new file mode 100644
--- /dev/null
+++ b/browser/themes/pinstripe/browser/fullscreen-video.css
@@ -0,0 +1,8 @@
+#close {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 32px;
+  height: 32px;
+  background: url(KUI-close.png) center center no-repeat;
+}
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -7,16 +7,17 @@ browser.jar:
   skin/classic/browser/aboutCertError.css                   (aboutCertError.css)
   skin/classic/browser/bookmark_toolbar_background.png
   skin/classic/browser/bookmark-open-left.png
   skin/classic/browser/bookmark-open-mid.png
   skin/classic/browser/bookmark-open-right.png
 * skin/classic/browser/browser.css                          (browser.css)
 * skin/classic/browser/engineManager.css                    (engineManager.css)
   skin/classic/browser/feed-icons.png
+  skin/classic/browser/fullscreen-video.css
   skin/classic/browser/Geo.png
   skin/classic/browser/Go-arrow.png
   skin/classic/browser/home.png
   skin/classic/browser/hud-panel.png
   skin/classic/browser/hud-style-button-middle-background.png
   skin/classic/browser/hud-style-check-box-checked.png
   skin/classic/browser/hud-style-check-box-empty.png
   skin/classic/browser/hud-style-dropmarker-double-arrows.png
@@ -95,16 +96,18 @@ browser.jar:
   skin/classic/browser/preferences/application.png          (preferences/application.png)
   skin/classic/browser/preferences/Options.png              (preferences/Options.png)
   skin/classic/browser/preferences/saveFile.png             (preferences/saveFile.png)
   skin/classic/browser/preferences/preferences.css          (preferences/preferences.css)
   skin/classic/browser/preferences/applications.css         (preferences/applications.css)
   skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon.png             (tabbrowser/alltabs-box-bkgnd-icon.png)
   skin/classic/browser/tabbrowser/alltabs-box-overflow-bkgnd-animate.png (tabbrowser/alltabs-box-overflow-bkgnd-animate.png)
   skin/classic/browser/tabbrowser/newtab.png                             (tabbrowser/newtab.png)
+  skin/classic/browser/tabbrowser/progress.png                           (tabbrowser/progress.png)
+  skin/classic/browser/tabbrowser/progress-pulsing.png                   (tabbrowser/progress-pulsing.png)
   skin/classic/browser/tabbrowser/tab-arrow-left.png                     (tabbrowser/tab-arrow-left.png)
   skin/classic/browser/tabbrowser/tab-arrow-right.png                    (tabbrowser/tab-arrow-right.png)
   skin/classic/browser/tabbrowser/tabbrowser-tabs-bkgnd.png              (tabbrowser/tabbrowser-tabs-bkgnd.png)
   skin/classic/browser/tabbrowser/tabDragIndicator.png                   (tabbrowser/tabDragIndicator.png)
   skin/classic/browser/tabbrowser/tab-bkgnd.png                          (tabbrowser/tab-bkgnd.png)
   skin/classic/browser/urlbar/endcap.png                                 (urlbar/endcap.png)
   skin/classic/browser/urlbar/endcap-rtl.png                             (urlbar/endcap-rtl.png)
   skin/classic/browser/urlbar/endcap-focused.png                         (urlbar/endcap-focused.png)
new file mode 100644
index 0000000000000000000000000000000000000000..3c66ed3c8e9fffbf428441b8015217ea2f575776
GIT binary patch
literal 10429
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
Sv(xa0-&B>f6yGUWh5ZNL!5OIl
new file mode 100644
index 0000000000000000000000000000000000000000..b8bd2efe554ea9d42d6c4a489e0a3a15e620521f
GIT binary patch
literal 2088
zc$@(!2-o+CP)<h;3K|Lk000e1NJLTq0058x000mO1^@s6`S$i;00001b5ch_0Itp)
z=>Px#24YJ`L;wH)0002_L%V+f000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXY<
z00kX|IsMK6000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}000MrNkl<Z
zXx{DGUu+Y}9S895jCa@TU9;Y`$sY{1$ra*62S{9+_Q-`0as87NRq(`viA14q1ofp{
z#Z^_I(uoQXf<u?`0E*N+AdnCTszN}0Ift~Ij)zLAN`Ug`Y|e2UlhjTed%bJ#_Tik$
zHBL+tsR}8-7kfwk?5yWEp4r(k!K={#;5`8E0I&d%0VDxD1@PCx>wHn_e+(cB;41((
z06co@m$lynpcBCR0BQkf04C@1mJ)nO6vYp=Y}v9l5D1t@j~>kq4-fySsi`UJbUKA(
zGTEqU+PeVm&r$g+eq>~%!EU#U7K^1$*Yyt#!`KMmi?@DR`r{14{M>H0e|P83ouRh2
zwwH!steMX<MffAH*Q*2q0j{H?Bku8dGK!+)Y&M&A@ZiC(tE;QCw{PFBx_tRE9}b5<
z0&u#d^0J;`n7kxOL=Xgl5aOMlo~}|=brpbLF4Q}nPGNL(v?Y~FeFot0TmN72iP!6;
zOYooB?e=<}=Qm_B8HMAxa7|53w346gK!?0uuhQM!ZRzan9NoBaW18oA0{|F?$?e*;
zYn)OFr_-q`ic-_l)1!pL;X?raP{~tD4N56AP2)0|jMCiPtb{_LKQGi<EEa=O%6L2;
z`NfMD^{G_qIDq4C{kJ2BD2m(m?%lf~5D0v_7;m@R>pdQioX_Wz(P-2W4u@;EZr%D#
zB~JnPMNxDI0s*eGvoqGv&@eMwIRLC)y*eQXg2D5=(a_K^)7jY>3j_k3D2ndFd^@iP
z0Mj%Pi^XbNT3XDWo}Nz@>H&ZdVzMl&a~zj<yWI|kVYU_K>;HHEuEk<$VHl?I!i5W~
z`uqEjEYvd$v(4>xJ2;NZOOiA#%W`~te7q)|PP3If1<<r<(<a){(GmCi{WC1fn#C2@
z)z!sk-?J=h`u+Zyj*gCaV`C!=pt+I<fXT^8rMbCTxO3;u$BXerUji)4>Q<{24u``E
z;HOLUyH<eziJ~aX+O=y(Wm%p$apHva)TvXyU5J-unYCK2U|CitgrK^*I<9G&HJMEE
zl{^LTPHSsx&gb)GIF5Ve;{AUAWbrY_ai-7b%k0>(BMZP+$?Lk#Y~H-N=GLuSA1}ri
zhhZ3WdV1PEF)`uFX0!gnYT>p0Y$GrXlapnc1@OHU;NN#R99FB<nsvL~QJ>HE^z`Y|
z=6s!~oM#v&M+iY-+B2)GtD{ezJgKeZDFDm%?b}sJl5*uL+_Ps-th7v$q+DBDn_5`K
z&FkCS+iPyzxbd6CdY8+^+ibSg0DQWx`#FyDDT<<aJRU0mYb9@*CMhkWl$wGdkis%`
zUe9rywiI73O1!W{Un>X#p_G~cV6)lO_3PI^zj*QD<oWaGf3Z+M8-gIHs;XKmd8X3E
zu3NV*g(bw<vu95(#SaV&Tq-jqGDAZ{^6uTc*-C!@{{7OKGiO+r%QaEjNUsx$qNHN6
zm~%1L-qqFhYXIR2AKSTa-@bZ6h)F5U^E{v7c|K#a+0vpYW-Jy<exdaeLZB#0qOY%y
zQc4%y_L`=#gb=gbkMKX82|)ht-MjqM)D-i&C!U&`Vg?5Xc>ww4?hhY6+;il}5%TQW
zv+qnzP1y@mAxWpxCV;U@-Y^Ven&vBIm3&uM*NNfb;n-Z~Eb<Y%-5&LLJkRUv>mT}j
zzEDj~&A22<sku5&i62X+)23k<<wja#DSoaIyx3C!&w|0AH53ZjbX_NvlBerB357zo
zU@&McJe6GbzPr2o?8%cS$0L!5FB}eg(&@A<kx1wO?pE@3b#?K{$w{SnMVZUxnECvH
z0|$N|3<f88p3jy^NU8ram&?T&hIy@#rkqbC5_&F|V@f;v|H4}UWRuC{W|zz5ShHqL
z*6DQW7K>%h<UM@&Q2hM!&ujbp`!!wH{{kTNCiteNru%NU+jsNk&9(V_-bf@8al<hF
z2;ljAUXrBrrAwE7=x{g^lu|?2byihXGB!3gQ_dedcI<c8u3gJ{Jf3e#r%cl{QO5s6
z*YzJrlEl+*!<fC9EtkCI<}CmwbX{)<hr^<xD614j(aI%ZHhBXB12w(9y}6e!Uq%4@
z=}qz+$Nf`L6ge0SzEoB99)Qc0yw~eh&z(Ehl1ioQf*_<dO|wKIkz_d^jYfZV<;oSI
zs;X*C6vcG8#xLXJhGA^TX0z3HyImlJka9^}u70+a?<bSV_Z~lfYy}_-f?ybi0n;?0
zsw$1eV%*5c$g1ntuh;hW_U6Lj@V@|jT6F$5#`pF0eI1X-!vK!GuD^Qq>c*Lw8Icg8
zj*gBdQmNEq0KY2nA3lBh)F#U^ktAuRkN{$uCdudXRM&M*RaFv+M3QCv7n-JhUsYAn
zX0zFfb_kZeCuKI{+>MQmY<qjV+S=NxQcCII;2<|RILJPD@F1H?rQ$_f5LoH{-o1P4
zhK7c!9zA-rI+;wWx~_j!v;|OZGjf~5;jqfG%m{)&DWxQpO68Nuq_z@$xyh~(z*Ybr
z0JBdb^8lU!_#1$c3inwn#d`s`0DMsRJH(d&ZUgvx1-}_UN8u^^x<c8C_5TJ#2?S>w
SX?6Jk0000<MNUMnLSTZ@*b?;s
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -1196,17 +1196,45 @@ statusbarpanel#statusbar-display {
   margin: 2px 0px 3px;
   padding: 1px;
   background-image: url("chrome://browser/skin/tabbrowser/tab-active-bkgnd.png");
   background-color: -moz-dialog;
   font-weight: bold;
 }
 
 .tabbrowser-tab[busy] > .tab-icon-image {
-  list-style-image: url("chrome://global/skin/icons/loading_16.png") !important;
+  list-style-image: url("chrome://browser/skin/tabbrowser/progress.png") !important;
+  -moz-image-region: rect(0, 16px, 16px, 0);
+}
+.tabbrowser-tab[busy][stalled] > .tab-icon-image {
+  list-style-image: url("chrome://browser/skin/tabbrowser/progress-pulsing.png") !important;
+}
+.tabbrowser-tab[busy][progress="1"] > .tab-icon-image {
+  -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+.tabbrowser-tab[busy][progress="2"] > .tab-icon-image {
+  -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+.tabbrowser-tab[busy][progress="3"] > .tab-icon-image {
+  -moz-image-region: rect(0, 64px, 16px, 48px);
+}
+.tabbrowser-tab[busy][progress="4"] > .tab-icon-image {
+  -moz-image-region: rect(0, 80px, 16px, 64px);
+}
+.tabbrowser-tab[busy][progress="5"] > .tab-icon-image {
+  -moz-image-region: rect(0, 96px, 16px, 80px);
+}
+.tabbrowser-tab[busy][progress="6"] > .tab-icon-image {
+  -moz-image-region: rect(0, 112px, 16px, 96px);
+}
+.tabbrowser-tab[busy][progress="7"] > .tab-icon-image {
+  -moz-image-region: rect(0, 128px, 16px, 112px);
+}
+.tabbrowser-tab[busy][progress="8"] > .tab-icon-image {
+  -moz-image-region: rect(0, 144px, 16px, 128px);
 }
 
 .tab-icon-image {
   margin-top: 1px;
   -moz-margin-start: 7px;
   -moz-margin-end: 3px;
   width: 16px;
   height: 16px;
new file mode 100644
--- /dev/null
+++ b/browser/themes/winstripe/browser/fullscreen-video.css
@@ -0,0 +1,8 @@
+#close {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 32px;
+  height: 32px;
+  background: url(KUI-close.png) center center no-repeat;
+}
--- a/browser/themes/winstripe/browser/jar.mn
+++ b/browser/themes/winstripe/browser/jar.mn
@@ -5,16 +5,17 @@ browser.jar:
 # section at the bottom of this file
         skin/classic/browser/sanitizeDialog.css                      (sanitizeDialog.css)
 *       skin/classic/browser/aboutPrivateBrowsing.css                (aboutPrivateBrowsing.css)
 *       skin/classic/browser/aboutSessionRestore.css                 (aboutSessionRestore.css)
         skin/classic/browser/aboutSessionRestore-window-icon.png     (aboutSessionRestore-window-icon.png)
         skin/classic/browser/aboutCertError.css                      (aboutCertError.css)
 *       skin/classic/browser/browser.css                             (browser.css)
 *       skin/classic/browser/engineManager.css                       (engineManager.css)
+        skin/classic/browser/fullscreen-video.css
         skin/classic/browser/Geo.png                                 (Geo.png)
         skin/classic/browser/Info.png                                (Info.png)
         skin/classic/browser/identity.png                            (identity.png)
         skin/classic/browser/KUI-background.png
         skin/classic/browser/KUI-close.png
         skin/classic/browser/mainwindow-dropdown-arrow.png
         skin/classic/browser/pageInfo.css
         skin/classic/browser/pageInfo.png                            (pageInfo.png)
@@ -77,16 +78,18 @@ browser.jar:
         skin/classic/browser/preferences/Options.png                 (preferences/Options.png)
         skin/classic/browser/preferences/saveFile.png                (preferences/saveFile.png)
         skin/classic/browser/preferences/preferences.css             (preferences/preferences.css)
         skin/classic/browser/preferences/applications.css            (preferences/applications.css)
         skin/classic/browser/tabbrowser/alltabs.png                             (tabbrowser/alltabs.png)
         skin/classic/browser/tabbrowser/alltabs-box-overflow-end-bkgnd-animate.png        (tabbrowser/alltabs-box-overflow-end-bkgnd-animate.png)
         skin/classic/browser/tabbrowser/alltabs-box-overflow-start-bkgnd-animate.png      (tabbrowser/alltabs-box-overflow-start-bkgnd-animate.png)
         skin/classic/browser/tabbrowser/newtab.png                              (tabbrowser/newtab.png)
+        skin/classic/browser/tabbrowser/progress.png                            (tabbrowser/progress.png)
+        skin/classic/browser/tabbrowser/progress-pulsing.png                    (tabbrowser/progress-pulsing.png)
         skin/classic/browser/tabbrowser/tab-arrow-left.png                      (tabbrowser/tab-arrow-left.png)
         skin/classic/browser/tabbrowser/tab-arrow-right.png                     (tabbrowser/tab-arrow-right.png)
         skin/classic/browser/tabbrowser/tabbrowser-tabs-bkgnd.png               (tabbrowser/tabbrowser-tabs-bkgnd.png)
         skin/classic/browser/tabbrowser/tabDragIndicator.png                    (tabbrowser/tabDragIndicator.png)
         skin/classic/browser/tabbrowser/tab-bkgnd.png                           (tabbrowser/tab-bkgnd.png)
         skin/classic/browser/tabbrowser/tab-active-bkgnd.png                    (tabbrowser/tab-active-bkgnd.png)
         skin/classic/browser/tabbrowser/tab-hover-bkgnd.png                     (tabbrowser/tab-hover-bkgnd.png)
         skin/classic/browser/tabbrowser/tabstrip-bottom.png                     (tabbrowser/tabstrip-bottom.png)
@@ -96,16 +99,17 @@ browser.jar:
 % skin browser classic/1.0 %skin/classic/aero/browser/ os=WINNT osversion>=6
         skin/classic/aero/browser/sanitizeDialog.css                       (sanitizeDialog.css)
 *       skin/classic/aero/browser/aboutPrivateBrowsing.css           (aboutPrivateBrowsing.css)
 *       skin/classic/aero/browser/aboutSessionRestore.css            (aboutSessionRestore.css)
         skin/classic/aero/browser/aboutSessionRestore-window-icon.png (aboutSessionRestore-window-icon-aero.png)
         skin/classic/aero/browser/aboutCertError.css                 (aboutCertError.css)
 *       skin/classic/aero/browser/browser.css                        (browser-aero.css)
 *       skin/classic/aero/browser/engineManager.css                  (engineManager.css)
+        skin/classic/aero/browser/fullscreen-video.css
         skin/classic/aero/browser/Geo.png                            (Geo-aero.png)
         skin/classic/aero/browser/Info.png                           (Info-aero.png)
         skin/classic/aero/browser/identity.png                       (identity-aero.png)
         skin/classic/aero/browser/KUI-background.png
         skin/classic/aero/browser/KUI-close.png
         skin/classic/aero/browser/mainwindow-dropdown-arrow.png      (mainwindow-dropdown-arrow-aero.png)
         skin/classic/aero/browser/pageInfo.css
         skin/classic/aero/browser/pageInfo.png                       (pageInfo-aero.png)
@@ -170,16 +174,18 @@ browser.jar:
         skin/classic/aero/browser/preferences/plugin.png             (preferences/plugin-aero.png)
         skin/classic/aero/browser/preferences/saveFile.png           (preferences/saveFile-aero.png)
         skin/classic/aero/browser/preferences/preferences.css        (preferences/preferences.css)
         skin/classic/aero/browser/preferences/applications.css       (preferences/applications.css)
         skin/classic/aero/browser/tabbrowser/alltabs.png                        (tabbrowser/alltabs-aero.png)
         skin/classic/aero/browser/tabbrowser/alltabs-box-overflow-end-bkgnd-animate.png   (tabbrowser/alltabs-box-overflow-end-bkgnd-animate.png)
         skin/classic/aero/browser/tabbrowser/alltabs-box-overflow-start-bkgnd-animate.png (tabbrowser/alltabs-box-overflow-start-bkgnd-animate.png)
         skin/classic/aero/browser/tabbrowser/newtab.png                         (tabbrowser/newtab-aero.png)
+        skin/classic/aero/browser/tabbrowser/progress.png                       (tabbrowser/progress.png)
+        skin/classic/aero/browser/tabbrowser/progress-pulsing.png               (tabbrowser/progress-pulsing.png)
         skin/classic/aero/browser/tabbrowser/tab-arrow-left.png                 (tabbrowser/tab-arrow-left-aero.png)
         skin/classic/aero/browser/tabbrowser/tab-arrow-right.png                (tabbrowser/tab-arrow-right-aero.png)
         skin/classic/aero/browser/tabbrowser/tabbrowser-tabs-bkgnd.png          (tabbrowser/tabbrowser-tabs-bkgnd.png)
         skin/classic/aero/browser/tabbrowser/tabDragIndicator.png               (tabbrowser/tabDragIndicator-aero.png)
         skin/classic/aero/browser/tabbrowser/tab-bkgnd.png                      (tabbrowser/tab-bkgnd.png)
         skin/classic/aero/browser/tabbrowser/tab-active-bkgnd.png               (tabbrowser/tab-active-bkgnd.png)
         skin/classic/aero/browser/tabbrowser/tab-hover-bkgnd.png                (tabbrowser/tab-hover-bkgnd.png)
         skin/classic/aero/browser/tabbrowser/tabstrip-bottom.png                (tabbrowser/tabstrip-bottom.png)
new file mode 100644
index 0000000000000000000000000000000000000000..3c66ed3c8e9fffbf428441b8015217ea2f575776
GIT binary patch
literal 10429
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
Sv(xa0-&B>f6yGUWh5ZNL!5OIl
new file mode 100644
index 0000000000000000000000000000000000000000..b8bd2efe554ea9d42d6c4a489e0a3a15e620521f
GIT binary patch
literal 2088
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
SX?6Jk0000<MNUMnLSTZ@*b?;s
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -96,15 +96,52 @@ libs:: bloaturls.txt
 # of bloaturls.txt.  This is for browsers that can't do -f
 # autocycling of URLs.
 libs:: bloatcycle.html
 	$(INSTALL) $< $(DIST)/bin/res
 
 ifeq ($(OS_ARCH),Darwin)
 libs:: $(topsrcdir)/tools/rb/fix-macosx-stack.pl
 	$(INSTALL) $< $(DIST)/bin
+
+# Basic unit tests for some stuff in the unify script
+check::
+# build ppc/i386 binaries, and unify them
+	rm -f unify-test-ppc unify-test-i386 unify-test-universal
+	$(HOST_CC) -arch ppc $(srcdir)/unify-test.c -o unify-test-ppc
+	$(HOST_CC) -arch i386 $(srcdir)/unify-test.c -o unify-test-i386
+	@if ! $(srcdir)/macosx/universal/unify ./unify-test-ppc ./unify-test-i386 \
+          ./unify-test-universal; then \
+          echo "TEST-UNEXPECTED-FAIL | build/ | unify failed to produce a universal binary!"; \
+          false; \
+        fi
+	@if ! test -f ./unify-test-universal; then \
+          echo "TEST-UNEXPECTED-FAIL | build/ | unify failed to produce a universal binary!"; \
+          false; \
+        fi
+	@if ! file -b ./unify-test-universal | head -n1 | grep -q "^Mach-O universal binary"; then \
+          echo "TEST-UNEXPECTED-FAIL | build/ | unify failed to produce a universal binary!"; \
+          false; \
+        fi
+# try unifying two identical Java class files
+	rm -f unifytesta.class unifytestb.class unifytestc.class
+	cp $(srcdir)/unifytest.class ./unifytesta.class
+	cp $(srcdir)/unifytest.class ./unifytestb.class
+	@if ! $(srcdir)/macosx/universal/unify ./unifytesta.class ./unifytestb.class \
+          ./unifytestc.class; then \
+          echo "TEST-UNEXPECTED-FAIL | build/ | unify failed to unify a Java class file!"; \
+          false; \
+        fi
+	@if ! test -f ./unifytestc.class; then \
+          echo "TEST-UNEXPECTED-FAIL | build/ | unify failed to unify a Java class file!"; \
+          false; \
+        fi
+	@if ! diff -q ./unifytesta.class ./unifytestc.class; then \
+          echo "TEST-UNEXPECTED-FAIL | build/ | unify failed to unify a Java class file!"; \
+          false; \
+        fi
 endif
 
 ifeq ($(OS_ARCH),Linux)
 libs:: $(topsrcdir)/tools/rb/fix-linux-stack.pl
 	$(INSTALL) $< $(DIST)/bin
 endif
-endif
+endif # ENABLE_TESTS
--- a/build/macosx/universal/flight.mk
+++ b/build/macosx/universal/flight.mk
@@ -105,8 +105,24 @@ postflight_all:
 	ln -s $(DIST_UNI) $(DIST_X86)/universal
 	rm -rf $(DIST_UNI)/$(MOZ_PKG_APPNAME)/$(APPNAME)
 	$(TOPSRCDIR)/build/macosx/universal/unify \
 	  $(DIST_PPC)/$(MOZ_PKG_APPNAME)/$(APPNAME) \
 	  $(DIST_X86)/$(MOZ_PKG_APPNAME)/$(APPNAME) \
 	  $(DIST_UNI)/$(MOZ_PKG_APPNAME)/$(APPNAME)
 # A universal .dmg can now be produced by making in either architecture's
 # INSTALLER_DIR.
+# Now, repeat the process for the test package.
+	$(MAKE) -C $(OBJDIR_PPC) UNIVERSAL_BINARY= package-tests
+	$(MAKE) -C $(OBJDIR_X86) UNIVERSAL_BINARY= package-tests
+# automation.py differs because it hardcodes a path to dist/bin.
+# It doesn't matter which one we use.
+	cp $(DIST_PPC)/test-package-stage/mochitest/automation.py \
+           $(DIST_X86)/test-package-stage/mochitest/
+	cp $(DIST_PPC)/test-package-stage/reftest/automation.py \
+           $(DIST_X86)/test-package-stage/reftest/
+	rm -rf $(DIST_UNI)/test-package-stage
+	if test -d $(DIST_PPC)/test-package-stage -a \
+                -d $(DIST_X86)/test-package-stage; then \
+           $(TOPSRCDIR)/build/macosx/universal/unify \
+             $(DIST_PPC)/test-package-stage \
+             $(DIST_X86)/test-package-stage \
+             $(DIST_UNI)/test-package-stage; fi
--- a/build/macosx/universal/unify
+++ b/build/macosx/universal/unify
@@ -209,16 +209,17 @@ sub readZipCRCs($);
   sub lIsDir($);
   sub lIsExecutable($);
   sub lIsRegularFile($);
   sub lIsSymLink($);
   sub lstat($);
   sub lstatMode($);
   sub lstatType($);
   sub magic($);
+  sub magic2($);
   sub path($);
   sub stat($);
   sub statSize($);
 }
 
 %gConfig = (
   'cmd_lipo' => 'lipo',
   'cmd_rm'   => 'rm',
@@ -1048,43 +1049,52 @@ sub readZipCRCs($) {
       $class = $proto;
     }
     $this = {
       'path'        => $path,
       'lstat'       => undef,
       'lstatErrno'  => 0,
       'lstatInit'   => 0,
       'magic'       => undef,
+      'magic2'       => undef,
       'magicErrno'  => 0,
       'magicErrMsg' => undef,
       'magicInit'   => 0,
       'stat'        => undef,
       'statErrno'   => 0,
       'statInit'    => 0,
     };
     bless($this, $class);
     return($this);
   }
 
   # $FileAttrCache->isFat()
   #
   # Returns true if the file is a fat Mach-O file, false if it's not, and
   # undef if an error occurs.  See /usr/include/mach-o/fat.h.
   sub isFat($) {
-    my ($magic, $this);
+    my ($magic, $magic2, $this);
     ($this) = @_;
 
     # magic() caches, there's no separate cache because isFat() doesn't hit
     # the disk other than by calling magic().
 
     if (!defined($magic = $this->magic())) {
       return undef;
     }
+    $magic2 = $this->magic2();
 
-    if ($magic == 0xcafebabe) {
+    # We have to sanity check the second four bytes, because Java class
+    # files use the same magic number as Mach-O fat binaries.
+    # This logic is adapted from file(1), which says that Mach-O uses
+    # these bytes to count the number of architectures within, while
+    # Java uses it for a version number. Conveniently, there are only
+    # 18 labelled Mach-O architectures, and Java's first released
+    # class format used the version 43.0.
+    if ($magic == 0xcafebabe && $magic2 < 20) {
       return 1;
     }
 
     return 0;
   }
 
   # $FileAttrCache->isMachO()
   #
@@ -1100,17 +1110,17 @@ sub readZipCRCs($) {
 
     if (!defined($magic = $this->magic())) {
       return undef;
     }
 
     # Accept Mach-O fat files or Mach-O thin files of either endianness.
     if ($magic == 0xfeedface ||
         $magic == 0xcefaedfe ||
-        $magic == 0xcafebabe) {
+        $this->isFat()) {
       return 1;
     }
 
     return 0;
   }
 
   # $FileAttrCache->isZip()
   #
@@ -1287,39 +1297,64 @@ sub readZipCRCs($) {
       $$this{'magicErrno'} = $!;
       $$this{'magicErrMsg'} = 'open "'.$$this{'path'}.'": '.$!;
       complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:',
                $$this{'path'});
       return undef;
     }
 
     $! = 0;
-    my ($bytes, $magic);
+    my ($bytes, $magic, $bytes2, $magic2);
     if (!defined($bytes = sysread($fh, $magic, 4))) {
       $$this{'magicErrno'} = $!;
       $$this{'magicErrMsg'} = 'read "'.$$this{'path'}.'": '.$!;
       complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:',
                $$this{'path'});
       close($fh);
       return undef;
     }
+    else {
+      $bytes2 = sysread($fh, $magic2, 4);
+    }
 
     close($fh);
 
     if ($bytes != 4) {
       # The file is too short, didn't read a magic number.  This isn't really
       # an error.  Return an unlikely value.
       $$this{'magic'} = -1;
+      $$this{'magic2'} = -1;
       return -1;
     }
+    if ($bytes2 != 4) {
+      # File is too short to read a second 4 bytes.
+      $magic2 = -1;
+    }
 
     $$this{'magic'} = unpack('N', $magic);
+    $$this{'magic2'} = unpack('N', $magic2);
     return $$this{'magic'};
   }
 
+  # $FileAttrCache->magic2()
+  #
+  # Returns the second four bytes of the file as a 32-bit little endian number.
+  # See magic(), above for more info.
+  sub magic2($) {
+    my ($this);
+    ($this) = @_;
+
+    # we do the actual work (and cache it) in magic().
+    if (!$$this{'magicInit'}) {
+      my $magic = $$this->magic();
+    }
+
+    return $$this{'magic2'};
+  }
+
   # $FileAttrCache->path()
   #
   # Returns the file's pathname.
   sub path($) {
     my ($this);
     ($this) = @_;
     return $$this{'path'};
   }
new file mode 100644
--- /dev/null
+++ b/build/unify-test.c
@@ -0,0 +1,4 @@
+int main(int argc, char** argv)
+{
+  return 0;
+}
new file mode 100644
index 0000000000000000000000000000000000000000..7eca557ad5052ad004722bda39d3dcdf7e03c782
GIT binary patch
literal 263
zc${TUy9&ZU5S%s9Xna<Jg<u&i6l=vsunJlzHddE-%88y3FM^+CC0O_Yew4V0poI%F
zy9_hKK413-fIg}&ER-CS9aIRpq0-8X2$t7g672DDEeTa$X*rD#fs7U+*t23Egwlk%
zxAJ%5EP8vPx4pTEl->@KpgTXtQ79)WF;`-(HWwpLrkj{cu#qJczAB;iE13m585*>Z
s;lGl}FgO5yj;|(f;+^f>KvzBp4s$LQxfFTE$J$60{M#&MH*GGy0h(GaUH||9
new file mode 100644
--- /dev/null
+++ b/build/unifytest.java
@@ -0,0 +1,5 @@
+class unifytest {
+    public static void main(String[] args) {
+        return;
+    }
+}
--- a/caps/idl/nsIScriptSecurityManager.idl
+++ b/caps/idl/nsIScriptSecurityManager.idl
@@ -36,17 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 #include "nsIPrincipal.idl"
 #include "nsIXPCSecurityManager.idl"
 interface nsIURI;
 interface nsIChannel;
 
-[scriptable, uuid(f8e350b9-9f31-451a-8c8f-d10fea26b780)]
+[scriptable, uuid(c0dbfd5e-b7ae-4c18-8674-82492f35d715)]
 interface nsIScriptSecurityManager : nsIXPCSecurityManager
 {
     ///////////////// Security Checks //////////////////
     /**
      * Checks whether the running script is allowed to access aProperty.
      */
     [noscript] void checkPropertyAccess(in JSContextPtr aJSContext,
                                         in JSObjectPtr aJSObject,
@@ -314,14 +314,37 @@ interface nsIScriptSecurityManager : nsI
      * Same as getSubjectPrincipal(), only faster. cx must *never* be
      * passed null, and it must be the context on the top of the
      * context stack. Does *not* reference count the returned
      * principal.
      */
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipal(in JSContextPtr cx);
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipalAndFrame(in JSContextPtr cx,
                                                                    out JSStackFramePtr fp);
+
+    /**
+     * If no scripted code is running "above" (or called from) fp, then
+     * instead of looking at cx->globalObject, we will return |principal|.
+     * This function only affects |cx|. If someone pushes another context onto
+     * the context stack, then it supercedes this call.
+     * NOTE: If |fp| is non-null popContextPrincipal must be called before fp
+     * has finished executing.
+     *
+     * @param cx The context to clamp.
+     * @param fp The frame pointer to clamp at. May be 'null'.
+     * @param principal The principal to clamp to.
+     */
+    [noscript] void pushContextPrincipal(in JSContextPtr cx,
+                                         in JSStackFramePtr fp,
+                                         in nsIPrincipal principal);
+
+    /**
+     * Removes a clamp set by pushContextPrincipal from cx. This must be
+     * called in a stack-like fashion (e.g., given two contexts |a| and |b|,
+     * it is not legal to do: push(a) push(b) pop(a)).
+     */
+    [noscript] void popContextPrincipal(in JSContextPtr cx);
 };
 
 %{C++
 #define NS_SCRIPTSECURITYMANAGER_CONTRACTID "@mozilla.org/scriptsecuritymanager;1"
 #define NS_SCRIPTSECURITYMANAGER_CLASSNAME "scriptsecuritymanager"
 %}
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -481,25 +481,25 @@ private:
                               nsISupports* aCertificate,
                               nsIURI* aURI,
                               PRBool aModifyTable,
                               nsIPrincipal **result);
 
     // Returns null if a principal cannot be found.  Note that rv can be NS_OK
     // when this happens -- this means that there was no script for the
     // context.  Callers MUST pass in a non-null rv here.
-    static nsIPrincipal*
+    nsIPrincipal*
     GetSubjectPrincipal(JSContext* cx, nsresult* rv);
 
     // Returns null if a principal cannot be found.  Note that rv can be NS_OK
     // when this happens -- this means that there was no script for the frame.
     // Callers MUST pass in a non-null rv here.
-    static nsIPrincipal*
+    nsIPrincipal*
     GetFramePrincipal(JSContext* cx, JSStackFrame* fp, nsresult* rv);
-                                                     
+
     // Returns null if a principal cannot be found.  Note that rv can be NS_OK
     // when this happens -- this means that there was no script.  Callers MUST
     // pass in a non-null rv here.
     static nsIPrincipal*
     GetScriptPrincipal(JSContext* cx, JSScript* script, nsresult* rv);
 
     // Returns null if a principal cannot be found.  Note that rv can be NS_OK
     // when this happens -- this means that there was no script associated
@@ -509,17 +509,17 @@ private:
     // Callers MUST pass in a non-null rv here.
     static nsIPrincipal*
     GetFunctionObjectPrincipal(JSContext* cx, JSObject* obj, JSStackFrame *fp,
                                nsresult* rv);
 
     // Returns null if a principal cannot be found.  Note that rv can be NS_OK
     // when this happens -- this means that there was no script
     // running.  Callers MUST pass in a non-null rv here.
-    static nsIPrincipal*
+    nsIPrincipal*
     GetPrincipalAndFrame(JSContext *cx,
                          JSStackFrame** frameResult,
                          nsresult* rv);
 
     static PRBool
     CheckConfirmDialog(JSContext* cx, nsIPrincipal* aPrincipal,
                        const char* aCapability, PRBool *checkValue);
 
@@ -596,16 +596,27 @@ private:
     nsresult
     CheckComponentPermissions(JSContext *cx, const nsCID &aCID);
 #endif
 #ifdef DEBUG_CAPS_HACKER
     void
     PrintPolicyDB();
 #endif
 
+    struct ContextPrincipal {
+        ContextPrincipal(ContextPrincipal *next, JSContext *cx,
+                         JSStackFrame *fp, nsIPrincipal *principal)
+            : mNext(next), mCx(cx), mFp(fp), mPrincipal(principal) {}
+
+        ContextPrincipal *mNext;
+        JSContext *mCx;
+        JSStackFrame *mFp;
+        nsCOMPtr<nsIPrincipal> mPrincipal;
+    };
+
     // JS strings we need to clean up on shutdown
     static jsval sEnabledID;
 
     inline void
     ScriptSecurityPrefChanged();
 
     static const char sJSEnabledPrefName[];
     static const char sFileOriginPolicyPrefName[];
@@ -613,16 +624,17 @@ private:
     nsObjectHashtable* mOriginToPolicyMap;
     DomainPolicy* mDefaultPolicy;
     nsObjectHashtable* mCapabilities;
 
     nsCOMPtr<nsIPrefBranch> mPrefBranch;
     nsCOMPtr<nsISecurityPref> mSecurityPref;
     nsCOMPtr<nsIPrincipal> mSystemPrincipal;
     nsCOMPtr<nsIPrincipal> mSystemCertificate;
+    ContextPrincipal *mContextPrincipals;
     nsInterfaceHashtable<PrincipalKey, nsIPrincipal> mPrincipals;
     PRPackedBool mIsJavaScriptEnabled;
     PRPackedBool mIsWritingPrefs;
     PRPackedBool mPolicyPrefsChanged;
 #ifdef XPC_IDISPATCH_SUPPORT    
     PRPackedBool mXPCDefaultGrantAll;
     static const char sXPCDefaultGrantAllName[];
 #endif
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -397,16 +397,42 @@ nsScriptSecurityManager::GetCxSubjectPri
     nsresult rv = NS_ERROR_FAILURE;
     nsIPrincipal *principal = GetPrincipalAndFrame(cx, fp, &rv);
     if (NS_FAILED(rv))
         return nsnull;
 
     return principal;
 }
 
+NS_IMETHODIMP
+nsScriptSecurityManager::PushContextPrincipal(JSContext *cx,
+                                              JSStackFrame *fp,
+                                              nsIPrincipal *principal)
+{
+    ContextPrincipal *cp = new ContextPrincipal(mContextPrincipals, cx, fp,
+                                                principal);
+    if (!cp)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    mContextPrincipals = cp;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsScriptSecurityManager::PopContextPrincipal(JSContext *cx)
+{
+    NS_ASSERTION(mContextPrincipals->mCx == cx, "Mismatched push/pop");
+
+    ContextPrincipal *next = mContextPrincipals->mNext;
+    delete mContextPrincipals;
+    mContextPrincipals = next;
+
+    return NS_OK;
+}
+
 ////////////////////
 // Policy Storage //
 ////////////////////
 
 // Table of security levels
 static PRBool
 DeleteCapability(nsHashKey *aKey, void *aData, void* closure)
 {
@@ -2191,17 +2217,16 @@ nsScriptSecurityManager::GetFunctionObje
         if (!result)
             *rv = NS_ERROR_FAILURE;
         return result;
     }
 
     return GetScriptPrincipal(cx, script, rv);
 }
 
-// static
 nsIPrincipal*
 nsScriptSecurityManager::GetFramePrincipal(JSContext *cx,
                                            JSStackFrame *fp,
                                            nsresult *rv)
 {
     NS_PRECONDITION(rv, "Null out param");
     JSObject *obj = JS_GetFrameFunctionObject(cx, fp);
     if (!obj)
@@ -2221,41 +2246,74 @@ nsScriptSecurityManager::GetFramePrincip
 
         NS_ASSERTION(!script, "Null principal for non-native function!");
     }
 #endif
 
     return result;
 }
 
-// static
 nsIPrincipal*
 nsScriptSecurityManager::GetPrincipalAndFrame(JSContext *cx,
                                               JSStackFrame **frameResult,
                                               nsresult* rv)
 {
-    NS_PRECONDITION(rv, "Null out param");    
+    NS_PRECONDITION(rv, "Null out param");
     //-- If there's no principal on the stack, look at the global object
     //   and return the innermost frame for annotations.
     *rv = NS_OK;
+
     if (cx)
     {
-        // Get principals from innermost frame of JavaScript or Java.
+        JSStackFrame *target = nsnull;
+        nsIPrincipal *targetPrincipal = nsnull;
+        for (ContextPrincipal *cp = mContextPrincipals; cp; cp = cp->mNext)
+        {
+            if (cp->mCx == cx)
+            {
+                target = cp->mFp;
+                targetPrincipal = cp->mPrincipal;
+                break;
+            }
+        }
+
+        // Get principals from innermost JavaScript frame.
         JSStackFrame *fp = nsnull; // tell JS_FrameIterator to start at innermost
         for (fp = JS_FrameIterator(cx, &fp); fp; fp = JS_FrameIterator(cx, &fp))
         {
+            if (fp == target)
+                break;
             nsIPrincipal* result = GetFramePrincipal(cx, fp, rv);
             if (result)
             {
                 NS_ASSERTION(NS_SUCCEEDED(*rv), "Weird return");
                 *frameResult = fp;
                 return result;
             }
         }
 
+        // If targetPrincipal is non-null, then it means that someone wants to
+        // clamp the principals on this context to this principal. Note that
+        // fp might not equal target here (fp might be null) because someone
+        // could have set aside the frame chain in the meantime.
+        if (targetPrincipal)
+        {
+            if (fp && fp == target)
+            {
+                *frameResult = fp;
+            }
+            else
+            {
+                JSStackFrame *inner = nsnull;
+                *frameResult = JS_FrameIterator(cx, &inner);
+            }
+
+            return targetPrincipal;
+        }
+
         nsIScriptContext *scriptContext = GetScriptContext(cx);
         if (scriptContext)
         {
             nsCOMPtr<nsIScriptObjectPrincipal> globalData =
                 do_QueryInterface(scriptContext->GetGlobalObject());
             if (!globalData)
             {
                 *rv = NS_ERROR_FAILURE;
@@ -2272,17 +2330,16 @@ nsScriptSecurityManager::GetPrincipalAnd
                 return result;
             }
         }
     }
 
     return nsnull;
 }
 
-// static
 nsIPrincipal*
 nsScriptSecurityManager::GetSubjectPrincipal(JSContext *cx,
                                              nsresult* rv)
 {
     NS_PRECONDITION(rv, "Null out param");
     JSStackFrame *fp;
     return GetPrincipalAndFrame(cx, &fp, rv);
 }
@@ -3273,16 +3330,17 @@ nsScriptSecurityManager::Observe(nsISupp
 
 /////////////////////////////////////////////
 // Constructor, Destructor, Initialization //
 /////////////////////////////////////////////
 nsScriptSecurityManager::nsScriptSecurityManager(void)
     : mOriginToPolicyMap(nsnull),
       mDefaultPolicy(nsnull),
       mCapabilities(nsnull),
+      mContextPrincipals(nsnull),
       mIsJavaScriptEnabled(PR_FALSE),
       mIsWritingPrefs(PR_FALSE),
       mPolicyPrefsChanged(PR_TRUE)
 #ifdef XPC_IDISPATCH_SUPPORT
       , mXPCDefaultGrantAll(PR_FALSE)
 #endif
 {
     NS_ASSERTION(sizeof(PRWord) == sizeof(void*),
@@ -3355,16 +3413,17 @@ nsresult nsScriptSecurityManager::Init()
 }
 
 static nsScriptSecurityManager *gScriptSecMan = nsnull;
 
 jsval nsScriptSecurityManager::sEnabledID   = JSVAL_VOID;
 
 nsScriptSecurityManager::~nsScriptSecurityManager(void)
 {
+    NS_ASSERTION(!mContextPrincipals, "Leaking mContextPrincipals");
     delete mOriginToPolicyMap;
     if(mDefaultPolicy)
         mDefaultPolicy->Drop();
     delete mCapabilities;
     gScriptSecMan = nsnull;
 }
 
 void
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -84,16 +84,17 @@ MOZ_WIDGET_TOOLKIT	= @MOZ_WIDGET_TOOLKIT
 MOZ_GFX_OPTIMIZE_MOBILE = @MOZ_GFX_OPTIMIZE_MOBILE@
 
 MOZ_DFB			= @MOZ_DFB@
 MOZ_X11			= @MOZ_X11@
 
 MOZ_PANGO = @MOZ_PANGO@
 
 MOZ_CORETEXT = @MOZ_CORETEXT@
+MOZ_COCOA_PRINTING = @MOZ_COCOA_PRINTING@
 
 MOZ_JS_LIBS		   = @MOZ_JS_LIBS@
 
 MOZ_DEBUG	= @MOZ_DEBUG@
 MOZ_DEBUG_MODULES = @MOZ_DEBUG_MODULES@
 MOZ_DEBUG_ENABLE_DEFS		= @MOZ_DEBUG_ENABLE_DEFS@
 MOZ_DEBUG_DISABLE_DEFS	= @MOZ_DEBUG_DISABLE_DEFS@
 MOZ_DEBUG_FLAGS	= @MOZ_DEBUG_FLAGS@
--- a/config/system-headers
+++ b/config/system-headers
@@ -729,16 +729,17 @@ sys/pda.h
 sys/poll.h
 sys/ppc.h
 sys/prctl.h
 sys/priv.h
 sys/procfs.h
 sys/pstat.h
 sys/ptrace.h
 sys/queue.h
+sys/quota.h
 sys/reg.h
 sys/regset.h
 sys/resource.h
 sys/sched.h
 sys/select.h
 sys/sem.h
 sys/sendfile.h
 sys/shm.h
--- a/configure.in
+++ b/configure.in
@@ -126,17 +126,17 @@ WINDRES_VERSION=2.14.90
 W32API_VERSION=3.8
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
 LIBGNOME_VERSION=2.0
 GIO_VERSION=2.0
 STARTUP_NOTIFICATION_VERSION=0.8
 DBUS_VERSION=0.60
-SQLITE_VERSION=3.6.16
+SQLITE_VERSION=3.6.18
 LIBNOTIFY_VERSION=0.4
 
 MSMANIFEST_TOOL=
 
 dnl Set various checks
 dnl ========================================================
 MISSING_X=
 AC_PROG_AWK
@@ -177,29 +177,33 @@ then
 	***
 	EOF
     exit 1
     break
   fi
 fi
 MOZ_BUILD_ROOT=`pwd`
 
-dnl Default to MSVC for win32
+dnl Default to MSVC for win32 and gcc-4.2 for darwin
 dnl ==============================================================
 if test -z "$CROSS_COMPILE"; then
 case "$target" in
 *-cygwin*|*-mingw*|*-msvc*|*-mks*)
     if test -z "$CC"; then CC=cl; fi
     if test -z "$CXX"; then CXX=cl; fi
     if test -z "$CPP"; then CPP="cl -E -nologo"; fi
     if test -z "$CXXCPP"; then CXXCPP="cl -TP -E -nologo"; ac_cv_prog_CXXCPP="$CXXCPP"; fi
     if test -z "$LD"; then LD=link; fi
     if test -z "$AS"; then AS=ml; fi
     if test -z "$MIDL"; then MIDL=midl; fi
     ;;
+*-darwin*)
+    if test -z "$CC"; then CC=gcc-4.2; fi
+    if test -z "$CXX"; then CXX=g++-4.2; fi
+    ;;
 esac
 fi
 
 COMPILE_ENVIRONMENT=1
 MOZ_ARG_ENABLE_BOOL(compile-environment,
 [  --disable-compile-environment
                            Disable compiler/library checks.],
     COMPILE_ENVIRONMENT=1,
@@ -1618,17 +1622,17 @@ case "$host" in
     fi
     HOST_CFLAGS="$HOST_CFLAGS -DXP_WIN32 -DXP_WIN -DWIN32 -D_WIN32 -DNO_X11"
     HOST_NSPR_MDCPUCFG='\"md/_winnt.cfg\"'
     HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O2}"
     HOST_BIN_SUFFIX=.exe
     case "$host" in
     *mingw*)
     dnl MinGW/MSYS does not need CYGWIN_WRAPPER
-        PERL="/bin/sh ${srcdir}/build/msys-perl-wrapper"
+        PERL="/bin/sh ${_topsrcdir}/build/msys-perl-wrapper"
         ;;
     *)
         CYGWIN_WRAPPER="${srcdir}/build/cygwin-wrapper"
         if test "`echo ${srcdir} | grep -c ^/ 2>/dev/null`" = 0; then
             _pwd=`pwd`
             CYGWIN_WRAPPER="${_pwd}/${srcdir}/build/cygwin-wrapper"
         fi
         if test "`${PERL} -v | grep -c cygwin  2>/dev/null`" = 0; then
@@ -3038,16 +3042,19 @@ AC_CHECK_HEADERS(sys/bitypes.h memory.h 
 AC_CHECK_HEADERS(gnu/libc-version.h nl_types.h)
 AC_CHECK_HEADERS(malloc.h)
 AC_CHECK_HEADERS(X11/XKBlib.h)
 AC_CHECK_HEADERS(io.h)
 
 dnl These are all the places some variant of statfs can be hiding.
 AC_CHECK_HEADERS(sys/statvfs.h sys/statfs.h sys/vfs.h sys/mount.h)
 
+dnl Quota support
+AC_CHECK_HEADERS(sys/quota.h)
+
 dnl Try for MMX support
 dnl NB - later gcc versions require -mmmx for this header to be successfully
 dnl included (or another option which implies it, such as -march=pentium-mmx)
 AC_CHECK_HEADERS(mmintrin.h)
 
 dnl Check whether the compiler supports the new-style C++ standard
 dnl library headers (i.e. <new>) or needs the old "new.h"
 AC_LANG_CPLUSPLUS
@@ -3130,45 +3137,61 @@ dnl OS/2 has socket in libc.
 case $target in
 *-os2*)
     ;;
 *)
     AC_CHECK_LIB(socket, socket)
 esac
 
 dnl ========================================================
-dnl Check whether we can compile code for Core Text
+dnl Check whether we can compile code for Core Text and
+dnl Cocoa printing
 dnl (Mac OS X 10.5 or later)
 dnl ========================================================
 case "$target" in
 *-darwin*)
   AC_MSG_CHECKING([for Core Text])
   AC_TRY_COMPILE([#include <ApplicationServices/ApplicationServices.h>],
                  [CTLineRef lineRef;],
-                  ac_cv_have_core_text="yes",
-                  ac_cv_have_core_text="no")
-  AC_MSG_RESULT([$ac_cv_have_core_text])
+                  ac_cv_have_leopard="yes",
+                  ac_cv_have_leopard="no")
+  AC_MSG_RESULT([$ac_cv_have_leopard])
 
   MOZ_CORETEXT=1
 
   MOZ_ARG_DISABLE_BOOL(coretext,
 [  --disable-coretext      Use ATSUI instead of Core Text for text rendering],
     MOZ_CORETEXT=,
     MOZ_CORETEXT=1)
 
   if test -n "$MOZ_CORETEXT"; then
-    if test "$ac_cv_have_core_text" = "no"; then
+    if test "$ac_cv_have_leopard" = "no"; then
       AC_MSG_ERROR([--enable-coretext requires MacOS SDK 10.5 or newer])
      fi
      AC_DEFINE(MOZ_CORETEXT)
   fi
+
+  MOZ_COCOA_PRINTING=1
+
+  MOZ_ARG_DISABLE_BOOL(cocoa-printing,
+[  --disable-cocoa-printing
+                          Use a Carbon print dialog instead of a Cocoa one],
+    MOZ_COCOA_PRINTING=,
+    MOZ_COCOA_PRINTING=1)
+
+  if test -n "$MOZ_COCOA_PRINTING"; then
+    if test "$ac_cv_have_leopard" = "no"; then
+        AC_MSG_ERROR([--enable-cocoa-printing requires MacOS SDK 10.5 or newer])
+    fi
+    AC_DEFINE(MOZ_COCOA_PRINTING)
+  fi
   ;;
 esac
 
-AC_SUBST(MOZ_CORETEXT)
+AC_SUBST(MOZ_COCOA_PRINTING)
 
 XLDFLAGS="$X_LIBS"
 XLIBS="$X_EXTRA_LIBS"
 
 dnl ========================================================
 dnl Checks for X libraries.
 dnl Ordering is important.
 dnl Xt is dependent upon SM as of X11R6
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -244,16 +244,37 @@ public:
    * Get the NodeInfo for this element
    * @return the nodes node info
    */
   nsINodeInfo *NodeInfo() const
   {
     return mNodeInfo;
   }
 
+  inline PRBool IsInNamespace(PRInt32 aNamespace) const {
+    return mNodeInfo->NamespaceID() == aNamespace;
+  }
+
+  inline PRBool IsHTML() const {
+    return IsInNamespace(kNameSpaceID_XHTML);
+  }
+
+  inline PRBool IsSVG() const {
+    /* Some things in the SVG namespace are not in fact SVG elements */
+    return IsNodeOfType(eSVG);
+  }
+
+  inline PRBool IsXUL() const {
+    return IsInNamespace(kNameSpaceID_XUL);
+  }
+
+  inline PRBool IsMathML() const {
+    return IsInNamespace(kNameSpaceID_MathML);
+  }
+
   /**
    * Returns an atom holding the name of the attribute of type ID on
    * this content node (if applicable).  Returns null for non-element
    * content nodes.
    */
   virtual nsIAtom *GetIDAttributeName() const = 0;
 
   /**
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -241,18 +241,18 @@ private:
   // sMutationCount is a global mutation counter which is decreased by one at
   // every mutation. It is capped at 0 to avoid wrapping.
   // Its value is always between 0 and 300, inclusive.
   static PRUint32 sMutationCount;
 };
 
 // IID for the nsINode interface
 #define NS_INODE_IID \
-{ 0xfc22c6df, 0x3e8e, 0x47c3, \
-  { 0x96, 0xa6, 0xaf, 0x14, 0x3c, 0x05, 0x88, 0x68 } }
+{ 0xc6485d02, 0x7c8a, 0x42fd, \
+ { 0x97, 0x15, 0x0f, 0x67, 0xfd, 0x69, 0xd5, 0x3e } }
  
 /**
  * An internal interface that abstracts some DOMNode-related parts that both
  * nsIContent and nsIDocument share.  An instance of this interface has a list
  * of nsIContent children and provides access to them.
  */
 class nsINode : public nsPIDOMEventTarget,
                 public nsWrapperCache
@@ -288,38 +288,32 @@ public:
     /** elements */
     eELEMENT             = 1 << 3,
     /** text nodes */
     eTEXT                = 1 << 4,
     /** xml processing instructions */
     ePROCESSING_INSTRUCTION = 1 << 5,
     /** comment nodes */
     eCOMMENT             = 1 << 6,
-    /** html elements */
-    eHTML                = 1 << 7,
     /** form control elements */
-    eHTML_FORM_CONTROL   = 1 << 8,
-    /** XUL elements */
-    eXUL                 = 1 << 9,
+    eHTML_FORM_CONTROL   = 1 << 7,
     /** svg elements */
-    eSVG                 = 1 << 10,
+    eSVG                 = 1 << 8,
     /** document fragments */
-    eDOCUMENT_FRAGMENT   = 1 << 11,
+    eDOCUMENT_FRAGMENT   = 1 << 9,
     /** data nodes (comments, PIs, text). Nodes of this type always
      returns a non-null value for nsIContent::GetText() */
-    eDATA_NODE           = 1 << 12,
-    /** nsMathMLElement */
-    eMATHML              = 1 << 13,
+    eDATA_NODE           = 1 << 10,
     /** nsHTMLMediaElement */
-    eMEDIA               = 1 << 14
+    eMEDIA               = 1 << 11
   };
 
   /**
    * API for doing a quick check if a content is of a given
-   * type, such as HTML, XUL, Text, ...  Use this when you can instead of
+   * type, such as Text, Document, Comment ...  Use this when you can instead of
    * checking the tag.
    *
    * @param aFlags what types you want to test for (see above)
    * @return whether the content matches ALL flags passed in
    */
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const = 0;
 
   /**
--- a/content/base/src/mozSanitizingSerializer.cpp
+++ b/content/base/src/mozSanitizingSerializer.cpp
@@ -209,17 +209,17 @@ mozSanitizingHTMLSerializer::IsContainer
    "I wonder if the sanitizing class could inherit from nsHTMLSerializer,
    so that at least these methods that none of us understand only have to be
    written once?" */
 
 // static
 PRInt32
 mozSanitizingHTMLSerializer::GetIdForContent(nsIContent* aContent)
 {
-  if (!aContent->IsNodeOfType(nsINode::eHTML)) {
+  if (!aContent->IsHTML()) {
     return eHTMLTag_unknown;
   }
 
   nsIParserService* parserService = nsContentUtils::GetParserService();
 
   return parserService ? parserService->HTMLAtomTagToId(aContent->Tag()) :
                          eHTMLTag_unknown;
 }
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -2115,17 +2115,17 @@ nsContentUtils::BelongsInForm(nsIDOMHTML
   while (content) {
     if (content == form) {
       // aContent is contained within the form so we return true.
 
       return PR_TRUE;
     }
 
     if (content->Tag() == nsGkAtoms::form &&
-        content->IsNodeOfType(nsINode::eHTML)) {
+        content->IsHTML()) {
       // The child is contained within a form, but not the right form
       // so we ignore it.
 
       return PR_FALSE;
     }
 
     content = content->GetParent();
   }
--- a/content/base/src/nsCopySupport.cpp
+++ b/content/base/src/nsCopySupport.cpp
@@ -344,17 +344,17 @@ nsresult nsCopySupport::IsPlainTextConte
   range->GetCommonAncestorContainer(getter_AddRefs(commonParent));
 
   for (nsCOMPtr<nsIContent> selContent(do_QueryInterface(commonParent));
        selContent;
        selContent = selContent->GetParent())
   {
     // checking for selection inside a plaintext form widget
 
-    if (!selContent->IsNodeOfType(nsINode::eHTML)) {
+    if (!selContent->IsHTML()) {
       continue;
     }
 
     nsIAtom *atom = selContent->Tag();
 
     if (atom == nsGkAtoms::input ||
         atom == nsGkAtoms::textarea)
     {
--- a/content/base/src/nsDOMAttributeMap.cpp
+++ b/content/base/src/nsDOMAttributeMap.cpp
@@ -349,17 +349,17 @@ nsDOMAttributeMap::SetNamedItemInternal(
     // Add the new attribute to the attribute map before updating
     // its value in the element. @see bug 364413.
     nsAttrKey attrkey(ni->NamespaceID(), ni->NameAtom());
     rv = mAttributeCache.Put(attrkey, attribute);
     NS_ENSURE_SUCCESS(rv, rv);
     iAttribute->SetMap(this);
 
     if (!aWithNS && ni->NamespaceID() == kNameSpaceID_None &&
-        mContent->IsNodeOfType(nsINode::eHTML)) {
+        mContent->IsHTML()) {
       // Set via setAttribute(), which may do normalization on the
       // attribute name for HTML
       nsCOMPtr<nsIDOMElement> ourElement(do_QueryInterface(mContent));
       NS_ASSERTION(ourElement, "HTML content that's not an element?");
       rv = ourElement->SetAttribute(name, value);
     }
     else {
       // It's OK to just use SetAttr
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -4888,40 +4888,40 @@ nsDocument::GetLocation(nsIDOMLocation *
   return w->GetLocation(_retval);
 }
 
 nsIContent*
 nsDocument::GetHtmlContent()
 {
   nsIContent* rootContent = GetRootContent();
   if (rootContent && rootContent->Tag() == nsGkAtoms::html &&
-      rootContent->IsNodeOfType(nsINode::eHTML))
+      rootContent->IsHTML())
     return rootContent;
   return nsnull;
 }
 
 nsIContent*
 nsDocument::GetHtmlChildContent(nsIAtom* aTag)
 {
   nsIContent* html = GetHtmlContent();
   if (!html)
     return nsnull;
 
   // Look for the element with aTag inside html. This needs to run
   // forwards to find the first such element.
   for (PRUint32 i = 0; i < html->GetChildCount(); ++i) {
     nsIContent* result = html->GetChildAt(i);
-    if (result->Tag() == aTag && result->IsNodeOfType(nsINode::eHTML))
+    if (result->Tag() == aTag && result->IsHTML())
       return result;
   }
   return nsnull;
 }
 
 nsIContent*
-nsDocument::GetTitleContent(PRUint32 aNodeType)
+nsDocument::GetTitleContent(PRUint32 aNamespace)
 {
   // mMayHaveTitleElement will have been set to true if any HTML or SVG
   // <title> element has been bound to this document. So if it's false,
   // we know there is nothing to do here. This avoids us having to search
   // the whole DOM if someone calls document.title on a large document
   // without a title.
   if (!mMayHaveTitleElement)
     return nsnull;
@@ -4933,25 +4933,25 @@ nsDocument::GetTitleContent(PRUint32 aNo
 
   for (PRUint32 i = 0; ; ++i) {
     // Avoid calling list->Length --- by calling Item one at a time,
     // we can avoid scanning the whole document to build the list of all
     // matches
     nsIContent* elem = list->Item(i, PR_FALSE);
     if (!elem)
       return nsnull;
-    if (elem->IsNodeOfType(aNodeType))
+    if (elem->IsInNamespace(aNamespace))
       return elem;
   }
 }
 
 void
-nsDocument::GetTitleFromElement(PRUint32 aNodeType, nsAString& aTitle)
-{
-  nsIContent* title = GetTitleContent(aNodeType);
+nsDocument::GetTitleFromElement(PRUint32 aNamespace, nsAString& aTitle)
+{
+  nsIContent* title = GetTitleContent(aNamespace);
   if (!title)
     return;
   nsContentUtils::GetNodeTextContent(title, PR_FALSE, aTitle);
 }
 
 NS_IMETHODIMP
 nsDocument::GetTitle(nsAString& aTitle)
 {
@@ -4967,22 +4967,22 @@ nsDocument::GetTitle(nsAString& aTitle)
 #ifdef MOZ_XUL
     case kNameSpaceID_XUL:
       rootContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, tmp);
       break;
 #endif
 #ifdef MOZ_SVG
     case kNameSpaceID_SVG:
       if (rootContent->Tag() == nsGkAtoms::svg) {
-        GetTitleFromElement(nsINode::eSVG, tmp);
+        GetTitleFromElement(kNameSpaceID_SVG, tmp);
         break;
       } // else fall through
 #endif
     default:
-      GetTitleFromElement(nsINode::eHTML, tmp);
+      GetTitleFromElement(kNameSpaceID_XHTML, tmp);
       break;
   }
 
   tmp.CompressWhitespace();
   aTitle = tmp;
   return NS_OK;
 }
 
@@ -5004,26 +5004,26 @@ nsDocument::SetTitle(const nsAString& aT
                                   aTitle, PR_TRUE);
 #endif
   }
 
   // Batch updates so that mutation events don't change "the title
   // element" under us
   mozAutoDocUpdate updateBatch(this, UPDATE_CONTENT_MODEL, PR_TRUE);
 
-  nsIContent* title = GetTitleContent(nsINode::eHTML);
+  nsIContent* title = GetTitleContent(kNameSpaceID_XHTML);
   if (!title) {
     nsIContent *head = GetHeadContent();
     if (!head)
       return NS_OK;
 
     {
       nsCOMPtr<nsINodeInfo> titleInfo;
       titleInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::title, nsnull,
-                                                kNameSpaceID_None);
+                                                kNameSpaceID_XHTML);
       if (!titleInfo)
         return NS_OK;
       title = NS_NewHTMLTitleElement(titleInfo);
       if (!title)
         return NS_OK;
     }
 
     head->AppendChildTo(title, PR_TRUE);
@@ -5083,17 +5083,17 @@ NS_IMETHODIMP
 nsDocument::GetBoxObjectFor(nsIDOMElement* aElement, nsIBoxObject** aResult)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(aElement));
   NS_ENSURE_TRUE(content, NS_ERROR_UNEXPECTED);
 
   nsIDocument* doc = content->GetOwnerDoc();
   NS_ENSURE_TRUE(doc == this, NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
 
-  if (!mHasWarnedAboutBoxObjects && !content->IsNodeOfType(eXUL)) {
+  if (!mHasWarnedAboutBoxObjects && !content->IsXUL()) {
     mHasWarnedAboutBoxObjects = PR_TRUE;
     nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
                                     "UseOfGetBoxObjectForWarning",
                                     nsnull, 0,
                                     static_cast<nsIDocument*>(this)->
                                       GetDocumentURI(),
                                     EmptyString(), 0, 0,
                                     nsIScriptError::warningFlag,
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -395,17 +395,17 @@ AddTreeItemToTreeOwner(nsIDocShellTreeIt
                        nsIDocShellTreeNode* aParentNode)
 {
   NS_PRECONDITION(aItem, "Must have docshell treeitem");
   NS_PRECONDITION(aOwningContent, "Must have owning content");
   
   nsAutoString value;
   PRBool isContent = PR_FALSE;
 
-  if (aOwningContent->IsNodeOfType(nsINode::eXUL)) {
+  if (aOwningContent->IsXUL()) {
       aOwningContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
   }
 
   // we accept "content" and "content-xxx" values.
   // at time of writing, we expect "xxx" to be "primary" or "targetable", but
   // someday it might be an integer expressing priority or something else.
 
   isContent = value.LowerCaseEqualsLiteral("content") ||
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -335,17 +335,18 @@ static nsIContent* GetEditorRootContent(
 }
 
 nsIContent*
 nsINode::GetTextEditorRootContent(nsIEditor** aEditor)
 {
   if (aEditor)
     *aEditor = nsnull;
   for (nsINode* node = this; node; node = node->GetNodeParent()) {
-    if (!node->IsNodeOfType(eHTML))
+    if (!node->IsNodeOfType(eELEMENT) ||
+        !static_cast<nsIContent*>(node)->IsHTML())
       continue;
 
     nsCOMPtr<nsIEditor> editor;
     static_cast<nsGenericHTMLElement*>(node)->
         GetEditorInternal(getter_AddRefs(editor));
     if (!editor)
       continue;
 
@@ -1163,17 +1164,17 @@ nsGenericElement::GetOffsetRect(nsRect& 
 
 void
 nsNSElementTearoff::GetScrollInfo(nsIScrollableView **aScrollableView,
                                   nsIFrame **aFrame)
 {
   *aScrollableView = nsnull;
 
   // it isn't clear what to return for SVG nodes, so just return nothing
-  if (mContent->IsNodeOfType(nsINode::eSVG)) {
+  if (mContent->IsSVG()) {
     if (aFrame)
       *aFrame = nsnull;
     return;
   }
 
   nsIFrame* frame =
     (static_cast<nsGenericElement*>(mContent))->GetStyledFrame();
 
@@ -1315,17 +1316,17 @@ nsNSElementTearoff::SetScrollLeft(PRInt3
 }
 
 nsresult
 nsNSElementTearoff::GetScrollHeight(PRInt32* aScrollHeight)
 {
   NS_ENSURE_ARG_POINTER(aScrollHeight);
   *aScrollHeight = 0;
 
-  if (mContent->IsNodeOfType(nsINode::eSVG))
+  if (mContent->IsSVG())
     return NS_OK;
 
   nsIScrollableView *scrollView;
   nsresult rv = NS_OK;
 
   GetScrollInfo(&scrollView);
 
   if (!scrollView) {
@@ -1346,17 +1347,17 @@ nsNSElementTearoff::GetScrollHeight(PRIn
 }
 
 nsresult
 nsNSElementTearoff::GetScrollWidth(PRInt32* aScrollWidth)
 {
   NS_ENSURE_ARG_POINTER(aScrollWidth);
   *aScrollWidth = 0;
 
-  if (mContent->IsNodeOfType(nsINode::eSVG))
+  if (mContent->IsSVG())
     return NS_OK;
 
   nsIScrollableView *scrollView;
   nsresult rv = NS_OK;
 
   GetScrollInfo(&scrollView);
 
   if (!scrollView) {
@@ -1377,17 +1378,17 @@ nsNSElementTearoff::GetScrollWidth(PRInt
 
 nsRect
 nsNSElementTearoff::GetClientAreaRect()
 {
   nsIScrollableView *scrollView;
   nsIFrame *frame;
 
   // it isn't clear what to return for SVG nodes, so just return 0
-  if (mContent->IsNodeOfType(nsINode::eSVG))
+  if (mContent->IsSVG())
     return nsRect(0, 0, 0, 0);
 
   GetScrollInfo(&scrollView, &frame);
 
   if (scrollView) {
     return scrollView->View()->GetBounds();
   }
 
@@ -3983,17 +3984,17 @@ nsGenericElement::doReplaceOrInsertBefor
         if (newContent->GetNodeParent() ||
             !IsAllowedAsChild(newContent, nodeType, aParent, aDocument,
                               PR_FALSE, refContent)) {
           return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
         }
       }
     }
 
-    if (!newContent->IsNodeOfType(eXUL)) {
+    if (!newContent->IsXUL()) {
       nsContentUtils::ReparentContentWrapper(newContent, aParent,
                                              container->GetOwnerDoc(),
                                              container->GetOwnerDoc());
     }
 
     res = container->InsertChildAt(newContent, insPos, PR_TRUE);
     NS_ENSURE_SUCCESS(res, res);
   }
@@ -4042,17 +4043,17 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsGeneric
 NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsGenericElement)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_ROOT_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericElement)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_LISTENERMANAGER
   NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA
 
-  if (tmp->HasProperties() && tmp->IsNodeOfType(nsINode::eXUL)) {
+  if (tmp->HasProperties() && tmp->IsXUL()) {
     tmp->DeleteProperty(nsGkAtoms::contextmenulistener);
     tmp->DeleteProperty(nsGkAtoms::popuplistener);
   }
 
   // Unlink child content (and unbind our subtree).
   {
     PRUint32 childCount = tmp->mAttrsAndChildren.ChildCount();
     if (childCount) {
@@ -4075,17 +4076,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
       slots->mStyle = nsnull;
 #ifdef MOZ_SMIL
       slots->mSMILOverrideStyle = nsnull;
 #endif // MOZ_SMIL
       if (slots->mAttributeMap) {
         slots->mAttributeMap->DropReference();
         slots->mAttributeMap = nsnull;
       }
-      if (tmp->IsNodeOfType(nsINode::eXUL))
+      if (tmp->IsXUL())
         NS_IF_RELEASE(slots->mControllers);
       slots->mChildrenList = nsnull;
     }
   }
 
   {
     nsIDocument *doc;
     if (!tmp->GetNodeParent() && (doc = tmp->GetOwnerDoc()) &&
@@ -4113,17 +4114,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   nsIDocument* ownerDoc = tmp->GetOwnerDoc();
   if (ownerDoc) {
     ownerDoc->BindingManager()->Traverse(tmp, cb);
   }
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_LISTENERMANAGER
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA
 
-  if (tmp->HasProperties() && tmp->IsNodeOfType(nsINode::eXUL)) {
+  if (tmp->HasProperties() && tmp->IsXUL()) {
     nsISupports* property =
       static_cast<nsISupports*>
                  (tmp->GetProperty(nsGkAtoms::contextmenulistener));
     cb.NoteXPCOMChild(property);
     property = static_cast<nsISupports*>
                           (tmp->GetProperty(nsGkAtoms::popuplistener));
     cb.NoteXPCOMChild(property);
   }
@@ -4160,17 +4161,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
 #ifdef MOZ_SMIL
       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "slots mSMILOverrideStyle");
       cb.NoteXPCOMChild(slots->mSMILOverrideStyle.get());
 #endif // MOZ_SMIL
 
       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "slots mAttributeMap");
       cb.NoteXPCOMChild(slots->mAttributeMap.get());
 
-      if (tmp->IsNodeOfType(nsINode::eXUL))
+      if (tmp->IsXUL())
         cb.NoteXPCOMChild(slots->mControllers);
       cb.NoteXPCOMChild(
         static_cast<nsIDOMNodeList*>(slots->mChildrenList.get()));
     }
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -50,16 +50,17 @@
 #include "nsIDOMAttr.h"
 #include "nsCOMArray.h"
 #include "nsPIDOMWindow.h"
 #include "nsDocument.h"
 #ifdef MOZ_XUL
 #include "nsXULElement.h"
 #endif
 #include "nsBindingManager.h"
+#include "nsGenericHTMLElement.h"
 
 // This macro expects the ownerDocument of content_ to be in scope as
 // |nsIDocument* doc|
 #define IMPL_MUTATION_NOTIFICATION(func_, content_, params_)      \
   PR_BEGIN_MACRO                                                  \
   nsINode* node = content_;                                       \
   NS_ASSERTION(node->GetOwnerDoc() == doc, "Bogus document");     \
   if (doc) {                                                      \
@@ -217,22 +218,33 @@ nsNodeUtils::LastRelease(nsINode* aNode)
   // Kill properties first since that may run external code, so we want to
   // be in as complete state as possible at that time.
   if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
     // Delete all properties before tearing down the document. Some of the
     // properties are bound to nsINode objects and the destructor functions of
     // the properties may want to use the owner document of the nsINode.
     static_cast<nsIDocument*>(aNode)->PropertyTable()->DeleteAllProperties();
   }
-  else if (aNode->HasProperties()) {
-    // Strong reference to the document so that deleting properties can't
-    // delete the document.
-    nsCOMPtr<nsIDocument> document = aNode->GetOwnerDoc();
-    if (document) {
-      document->PropertyTable()->DeleteAllPropertiesFor(aNode);
+  else {
+    if (aNode->HasProperties()) {
+      // Strong reference to the document so that deleting properties can't
+      // delete the document.
+      nsCOMPtr<nsIDocument> document = aNode->GetOwnerDoc();
+      if (document) {
+        document->PropertyTable()->DeleteAllPropertiesFor(aNode);
+      }
+    }
+
+    // I wonder whether it's faster to do the HasFlag check first....
+    if (aNode->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) &&
+        aNode->HasFlag(ADDED_TO_FORM)) {
+      // Tell the form (if any) this node is going away.  Don't
+      // notify, since we're being destroyed in any case.
+      static_cast<nsGenericHTMLFormElement*>(aNode)->ClearForm(PR_TRUE,
+                                                               PR_FALSE);
     }
   }
   aNode->UnsetFlags(NODE_HAS_PROPERTIES);
 
   if (aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
 #ifdef DEBUG
     if (nsContentUtils::IsInitialized()) {
       nsIEventListenerManager* manager =
@@ -695,17 +707,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
   // ChangeDocumentFor() call in nsXULElement::BindToTree as well.  Also,
   // remove the UnbindFromTree call in ~nsXULElement, and add back in the
   // precondition in nsXULElement::UnbindFromTree and remove the line in
   // nsXULElement.h that makes nsNodeUtils a friend of nsXULElement.
   // Note: Make sure to do this witchery _after_ we've done any deep
   // cloning, so kids of the new node aren't confused about whether they're
   // in a document.
 #ifdef MOZ_XUL
-  if (aClone && !aParent && aNode->IsNodeOfType(nsINode::eXUL)) {
+  if (aClone && !aParent && aNode->IsNodeOfType(nsINode::eELEMENT) && static_cast<nsIContent*>(aNode)->IsXUL()) {
     nsXULElement *xulElem = static_cast<nsXULElement*>(elem);
     if (!xulElem->mPrototype || xulElem->IsInDoc()) {
       clone->SetFlags(NODE_FORCE_XBL_BINDINGS);
     }
   }
 #endif
 
   if (aNode->HasProperties()) {
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1783,34 +1783,34 @@ nsObjectLoadingContent::ShouldShowDefaul
 
   return GetPluginSupportState(aContent, aContentType) == ePluginUnsupported;
 }
 
 /* static */ PluginSupportState
 nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
                                               const nsCString& aContentType)
 {
-  if (!aContent->IsNodeOfType(nsINode::eHTML)) {
+  if (!aContent->IsHTML()) {
     return ePluginOtherState;
   }
 
   if (aContent->Tag() == nsGkAtoms::embed ||
       aContent->Tag() == nsGkAtoms::applet) {
     return GetPluginDisabledState(aContentType);
   }
 
   PRBool hasAlternateContent = PR_FALSE;
 
   // Search for a child <param> with a pluginurl name
   PRUint32 count = aContent->GetChildCount();
   for (PRUint32 i = 0; i < count; ++i) {
     nsIContent* child = aContent->GetChildAt(i);
     NS_ASSERTION(child, "GetChildCount lied!");
 
-    if (child->IsNodeOfType(nsINode::eHTML) &&
+    if (child->IsHTML() &&
         child->Tag() == nsGkAtoms::param) {
       if (child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
                              NS_LITERAL_STRING("pluginurl"), eIgnoreCase)) {
         return GetPluginDisabledState(aContentType);
       }
     } else if (!hasAlternateContent) {
       hasAlternateContent =
         nsStyleUtil::IsSignificantChild(child, PR_TRUE, PR_FALSE);
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -409,20 +409,20 @@ class nsObjectLoadingContent : public ns
      * Type of the currently-loaded content.
      */
     ObjectType                  mType          : 16;
 
     /**
      * Whether we are about to call instantiate on our frame. If we aren't,
      * SetFrame needs to asynchronously call Instantiate.
      */
-    PRBool                      mInstantiating : 1;
+    PRPackedBool                mInstantiating : 1;
     // Blocking status from content policy
-    PRBool                      mUserDisabled  : 1;
-    PRBool                      mSuppressed    : 1;
+    PRPackedBool                mUserDisabled  : 1;
+    PRPackedBool                mSuppressed    : 1;
     // A specific state that caused us to fallback
     PluginSupportState          mPluginState;
 
     friend class nsAsyncInstantiateEvent;
 };
 
 
 #endif
--- a/content/base/src/nsPlainTextSerializer.cpp
+++ b/content/base/src/nsPlainTextSerializer.cpp
@@ -1848,17 +1848,17 @@ nsPlainTextSerializer::IsCurrentNodeConv
            value.EqualsIgnoreCase("\"moz-txt", 8)));
 }
 
 
 // static
 PRInt32
 nsPlainTextSerializer::GetIdForContent(nsIContent* aContent)
 {
-  if (!aContent->IsNodeOfType(nsINode::eHTML)) {
+  if (!aContent->IsHTML()) {
     return eHTMLTag_unknown;
   }
 
   nsIParserService* parserService = nsContentUtils::GetParserService();
 
   return parserService ? parserService->HTMLAtomTagToId(aContent->Tag()) :
                          eHTMLTag_unknown;
 }
--- a/content/base/src/nsScriptElement.cpp
+++ b/content/base/src/nsScriptElement.cpp
@@ -140,33 +140,33 @@ nsScriptElement::ContentInserted(nsIDocu
                                  nsIContent* aContainer,
                                  nsIContent* aChild,
                                  PRInt32 aIndexInContainer)
 {
   MaybeProcessScript();
 }
 
 static PRBool
-InNonScriptingContainer(nsINode* aNode)
+InNonScriptingContainer(nsIContent* aNode)
 {
-  aNode = aNode->GetNodeParent();
+  aNode = aNode->GetParent();
   while (aNode) {
     // XXX noframes and noembed are currently unconditionally not
     // displayed and processed. This might change if we support either
     // prefs or per-document container settings for not allowing
     // frames or plugins.
-    if (aNode->IsNodeOfType(nsINode::eHTML)) {
-      nsIAtom *localName = static_cast<nsIContent*>(aNode)->Tag();
+    if (aNode->IsHTML()) {
+      nsIAtom *localName = aNode->Tag();
       if (localName == nsGkAtoms::iframe ||
           localName == nsGkAtoms::noframes ||
           localName == nsGkAtoms::noembed) {
         return PR_TRUE;
       }
     }
-    aNode = aNode->GetNodeParent();
+    aNode = aNode->GetParent();
   }
 
   return PR_FALSE;
 }
 
 nsresult
 nsScriptElement::MaybeProcessScript()
 {
--- a/content/base/src/nsXHTMLContentSerializer.cpp
+++ b/content/base/src/nsXHTMLContentSerializer.cpp
@@ -498,17 +498,17 @@ nsXHTMLContentSerializer::AfterElementSt
 
     // Check if there already are any content-type meta children.
     // If there are, they will be modified to use the correct charset.
     // If there aren't, we'll insert one here.
     PRBool hasMeta = PR_FALSE;
     PRUint32 i, childCount = aContent->GetChildCount();
     for (i = 0; i < childCount; ++i) {
       nsIContent* child = aContent->GetChildAt(i);
-      if (child->IsNodeOfType(nsINode::eHTML) &&
+      if (child->IsHTML() &&
           child->Tag() == nsGkAtoms::meta &&
           child->HasAttr(kNameSpaceID_None, nsGkAtoms::content)) {
         nsAutoString header;
         child->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
 
         if (header.LowerCaseEqualsLiteral("content-type")) {
           hasMeta = PR_TRUE;
           break;
--- a/content/base/src/nsXMLContentSerializer.cpp
+++ b/content/base/src/nsXMLContentSerializer.cpp
@@ -767,17 +767,17 @@ nsXMLContentSerializer::ScanNamespaceDec
 }
 
 
 PRBool
 nsXMLContentSerializer::IsJavaScript(nsIContent * aContent, nsIAtom* aAttrNameAtom,
                                      PRInt32 aAttrNamespaceID, const nsAString& aValueString)
 {
   PRInt32 namespaceID = aContent->GetNameSpaceID();
-  PRBool isHtml = aContent->IsNodeOfType(nsINode::eHTML);
+  PRBool isHtml = aContent->IsHTML();
 
   if (aAttrNamespaceID == kNameSpaceID_None &&
       (isHtml ||
        namespaceID == kNameSpaceID_XUL ||
        namespaceID == kNameSpaceID_SVG) &&
       (aAttrNameAtom == nsGkAtoms::href ||
        aAttrNameAtom == nsGkAtoms::src)) {
 
--- a/content/events/src/nsContentEventHandler.cpp
+++ b/content/events/src/nsContentEventHandler.cpp
@@ -136,17 +136,17 @@ nsContentEventHandler::Init(nsQueryConte
 }
 
 // Editor places a bogus BR node under its root content if the editor doesn't
 // have any text. This happens even for single line editors.
 // When we get text content and when we change the selection,
 // we don't want to include the bogus BRs at the end.
 static PRBool IsContentBR(nsIContent* aContent)
 {
-  return aContent->IsNodeOfType(nsINode::eHTML) &&
+  return aContent->IsHTML() &&
          aContent->Tag() == nsGkAtoms::br &&
          !aContent->AttrValueIs(kNameSpaceID_None,
                                 nsGkAtoms::type,
                                 nsGkAtoms::moz,
                                 eIgnoreCase) &&
          !aContent->AttrValueIs(kNameSpaceID_None,
                                 nsGkAtoms::mozeditorbogusnode,
                                 nsGkAtoms::_true,
@@ -852,22 +852,22 @@ static void AdjustRangeForSelection(nsIC
 {
   nsINode* node = *aNode;
   PRInt32 offset = *aOffset;
   if (aRoot != node && node->GetParent() &&
       !node->IsNodeOfType(nsINode::eTEXT)) {
     node = node->GetParent();
     offset = node->IndexOf(*aNode) + (offset ? 1 : 0);
   }
-  nsINode* brNode = node->GetChildAt(offset - 1);
-  while (brNode && brNode->IsNodeOfType(nsINode::eHTML)) {
-    nsIContent* brContent = static_cast<nsIContent*>(brNode);
+  
+  nsIContent* brContent = node->GetChildAt(offset - 1);
+  while (brContent && brContent->IsHTML()) {
     if (brContent->Tag() != nsGkAtoms::br || IsContentBR(brContent))
       break;
-    brNode = node->GetChildAt(--offset - 1);
+    brContent = node->GetChildAt(--offset - 1);
   }
   *aNode = node;
   *aOffset = PR_MAX(offset, 0);
 }
 
 nsresult
 nsContentEventHandler::OnSelectionEvent(nsSelectionEvent* aEvent)
 {
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -1378,17 +1378,17 @@ static PRBool
 IsAccessKeyTarget(nsIContent* aContent, nsIFrame* aFrame, nsAString& aKey)
 {
   if (!aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::accesskey, aKey,
                              eIgnoreCase))
     return PR_FALSE;
 
   nsCOMPtr<nsIDOMXULDocument> xulDoc =
     do_QueryInterface(aContent->GetOwnerDoc());
-  if (!xulDoc && !aContent->IsNodeOfType(nsINode::eXUL))
+  if (!xulDoc && !aContent->IsXUL())
     return PR_TRUE;
 
     // For XUL we do visibility checks.
   if (!aFrame)
     return PR_FALSE;
 
   if (aFrame->IsFocusable())
     return PR_TRUE;
@@ -1399,27 +1399,27 @@ IsAccessKeyTarget(nsIContent* aContent, 
   if (!aFrame->AreAncestorViewsVisible())
     return PR_FALSE;
 
   // XUL controls can be activated.
   nsCOMPtr<nsIDOMXULControlElement> control(do_QueryInterface(aContent));
   if (control)
     return PR_TRUE;
 
-  if (aContent->IsNodeOfType(nsINode::eHTML)) {
+  if (aContent->IsHTML()) {
     nsIAtom* tag = aContent->Tag();
 
     // HTML area, label and legend elements are never focusable, so
     // we need to check for them explicitly before giving up.
     if (tag == nsGkAtoms::area ||
         tag == nsGkAtoms::label ||
         tag == nsGkAtoms::legend)
       return PR_TRUE;
 
-  } else if (aContent->IsNodeOfType(nsINode::eXUL)) {
+  } else if (aContent->IsXUL()) {
     // XUL label elements are never focusable, so we need to check for them
     // explicitly before giving up.
     if (aContent->Tag() == nsGkAtoms::label)
       return PR_TRUE;
   }
 
   return PR_FALSE;
 }
@@ -1692,17 +1692,17 @@ nsEventStateManager::FireContextClick()
       NS_ASSERTION(mPresContext == mCurrentTarget->PresContext(),
                    "a prescontext returned a primary frame that didn't belong to it?");
 
       // before dispatching, check that we're not on something that
       // doesn't get a context menu
       nsIAtom *tag = mGestureDownContent->Tag();
       PRBool allowedToDispatch = PR_TRUE;
 
-      if (mGestureDownContent->IsNodeOfType(nsINode::eXUL)) {
+      if (mGestureDownContent->IsXUL()) {
         if (tag == nsGkAtoms::scrollbar ||
             tag == nsGkAtoms::scrollbarbutton ||
             tag == nsGkAtoms::button)
           allowedToDispatch = PR_FALSE;
         else if (tag == nsGkAtoms::toolbarbutton) {
           // a <toolbarbutton> that has the container attribute set
           // will already have its own dropdown.
           if (nsContentUtils::HasNonEmptyAttr(mGestureDownContent,
@@ -1713,17 +1713,17 @@ nsEventStateManager::FireContextClick()
             // a second menu
             if (mGestureDownContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::open,
                                                  nsGkAtoms::_true, eCaseMatters)) {
               allowedToDispatch = PR_FALSE;
             }
           }
         }
       }
-      else if (mGestureDownContent->IsNodeOfType(nsINode::eHTML)) {
+      else if (mGestureDownContent->IsHTML()) {
         nsCOMPtr<nsIFormControl> formCtrl(do_QueryInterface(mGestureDownContent));
 
         if (formCtrl) {
           // of all form controls, only ones dealing with text are
           // allowed to have context menus
           PRInt32 type = formCtrl->GetType();
 
           allowedToDispatch = (type == NS_FORM_INPUT_TEXT ||
@@ -2342,17 +2342,17 @@ nsEventStateManager::DoScrollHistory(PRI
 void
 nsEventStateManager::DoScrollZoom(nsIFrame *aTargetFrame,
                                   PRInt32 adjustment)
 {
   // Exclude form controls and XUL content.
   nsIContent *content = aTargetFrame->GetContent();
   if (content &&
       !content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) &&
-      !content->IsNodeOfType(nsINode::eXUL))
+      !content->IsXUL())
     {
       // positive adjustment to decrease zoom, negative to increase
       PRInt32 change = (adjustment > 0) ? -1 : 1;
 
       if (nsContentUtils::GetBoolPref("browser.zoom.full"))
         ChangeFullZoom(change);
       else
         ChangeTextSize(change);
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -430,18 +430,18 @@ nsGenericHTMLElement::SetClassName(const
 {
   SetAttr(kNameSpaceID_None, nsGkAtoms::_class, aClassName, PR_TRUE);
   return NS_OK;
 }
 
 static PRBool
 IsBody(nsIContent *aContent)
 {
-  return (aContent->NodeInfo()->Equals(nsGkAtoms::body) &&
-          aContent->IsNodeOfType(nsINode::eHTML));
+  return aContent->NodeInfo()->Equals(nsGkAtoms::body) &&
+         aContent->IsHTML();
 }
 
 static PRBool IS_TABLE_CELL(nsIAtom* frameType) {
   return nsGkAtoms::tableCellFrame == frameType ||
     nsGkAtoms::bcTableCellFrame == frameType;
 }
 
 static PRBool
@@ -746,24 +746,23 @@ nsGenericHTMLElement::ScrollIntoView(PRB
 
 NS_IMETHODIMP
 nsGenericHTMLElement::GetSpellcheck(PRBool* aSpellcheck)
 {
   NS_ENSURE_ARG_POINTER(aSpellcheck);
   *aSpellcheck = PR_FALSE;              // Default answer is to not spellcheck
 
   // Has the state has been explicitly set?
-  nsINode* node;
-  for (node = this; node; node = node->GetNodeParent()) {
-    if (node->IsNodeOfType(nsINode::eHTML)) {
+  nsIContent* node;
+  for (node = this; node; node = node->GetParent()) {
+    if (node->IsHTML()) {
       static nsIContent::AttrValuesArray strings[] =
         {&nsGkAtoms::_true, &nsGkAtoms::_false, nsnull};
-      switch (static_cast<nsIContent*>(node)->
-              FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::spellcheck,
-                              strings, eCaseMatters)) {
+      switch (node->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::spellcheck,
+                                    strings, eCaseMatters)) {
         case 0:                         // spellcheck = "true"
           *aSpellcheck = PR_TRUE;
           // Fall through
         case 1:                         // spellcheck = "false"
           return NS_OK;
       }
     }
   }
@@ -900,17 +899,17 @@ nsGenericHTMLElement::FindForm(nsIForm* 
   // Make sure we don't end up finding a form that's anonymous from
   // our point of view.
   nsIContent* bindingParent = GetBindingParent();
 
   nsIContent* content = this;
   while (content != bindingParent && content) {
     // If the current ancestor is a form, return it as our form
     if (content->Tag() == nsGkAtoms::form &&
-        content->IsNodeOfType(nsINode::eHTML)) {
+        content->IsHTML()) {
 #ifdef DEBUG
       if (!nsContentUtils::IsInSameAnonymousTree(this, content)) {
         // It's possible that we started unbinding at |content| or
         // some ancestor of it, and |content| and |this| used to all be
         // anonymous.  Check for this the hard way.
         for (nsIContent* child = this; child != content;
              child = child->GetParent()) {
           NS_ASSERTION(child->GetParent()->IndexOf(child) != -1,
@@ -953,17 +952,17 @@ nsGenericHTMLElement::FindForm(nsIForm* 
 
   return nsnull;
 }
 
 static PRBool
 IsArea(nsIContent *aContent)
 {
   return (aContent->Tag() == nsGkAtoms::area &&
-          aContent->IsNodeOfType(nsINode::eHTML));
+          aContent->IsHTML());
 }
 
 PRBool
 nsGenericHTMLElement::CheckHandleEventForAnchorsPreconditions(nsEventChainVisitor& aVisitor)
 {
   NS_PRECONDITION(nsCOMPtr<nsILink>(do_QueryInterface(this)),
                   "should be called only when |this| implements |nsILink|");
 
@@ -1195,17 +1194,17 @@ nsGenericHTMLElement::GetBaseTarget(nsAS
   } else {
     aBaseTarget.Truncate();
   }
 }
 
 PRBool
 nsGenericHTMLElement::IsNodeOfType(PRUint32 aFlags) const
 {
-  return !(aFlags & ~(eCONTENT | eELEMENT | eHTML));
+  return !(aFlags & ~(eCONTENT | eELEMENT));
 }
 
 //----------------------------------------------------------------------
 
 
 PRBool
 nsGenericHTMLElement::ParseAttribute(PRInt32 aNamespaceID,
                                      nsIAtom* aAttribute,
@@ -2264,34 +2263,28 @@ NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsGeneric
 nsGenericHTMLFormElement::nsGenericHTMLFormElement(nsINodeInfo *aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
 {
   mForm = nsnull;
 }
 
 nsGenericHTMLFormElement::~nsGenericHTMLFormElement()
 {
-  // Check that this element is not still the default content
-  // of its parent form.
-  NS_ASSERTION(!mForm || mForm->GetDefaultSubmitElement() != this,
-               "Content being destroyed is the default content");
-
-  // Clean up.  Set the form to nsnull so it knows we went away.
-  // Do not notify as the content is being destroyed.
-  ClearForm(PR_TRUE, PR_FALSE);
+  // Check that this element doesn't know anything about its form at this point.
+  NS_ASSERTION(!mForm, "How did we get here?");
 }
 
 NS_IMPL_QUERY_INTERFACE_INHERITED1(nsGenericHTMLFormElement,
                                    nsGenericHTMLElement,
                                    nsIFormControl)
 
 PRBool
 nsGenericHTMLFormElement::IsNodeOfType(PRUint32 aFlags) const
 {
-  return !(aFlags & ~(eCONTENT | eELEMENT | eHTML | eHTML_FORM_CONTROL));
+  return !(aFlags & ~(eCONTENT | eELEMENT | eHTML_FORM_CONTROL));
 }
 
 void
 nsGenericHTMLFormElement::SaveSubtreeState()
 {
   SaveState();
 
   nsGenericHTMLElement::SaveSubtreeState();
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -74,17 +74,17 @@ public:
   nsGenericHTMLElement(nsINodeInfo *aNodeInfo)
     : nsGenericHTMLElementBase(aNodeInfo)
   {
   }
 
   /** Typesafe, non-refcounting cast from nsIContent.  Cheaper than QI. **/
   static nsGenericHTMLElement* FromContent(nsIContent *aContent)
   {
-    if (aContent->IsNodeOfType(eHTML))
+    if (aContent->IsHTML())
       return static_cast<nsGenericHTMLElement*>(aContent);
     return nsnull;
   }
 
   /** Call on shutdown to release globals */
   static void Shutdown();
 
   /**
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -79,17 +79,17 @@ NS_NewHTMLAudioElement(nsINodeInfo *aNod
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
     nsCOMPtr<nsIDocument> doc =
       do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
     NS_ENSURE_TRUE(doc, nsnull);
 
     nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::audio, nsnull,
-                                                   kNameSpaceID_None);
+                                                   kNameSpaceID_XHTML);
     NS_ENSURE_TRUE(nodeInfo, nsnull);
   }
 
   return new nsHTMLAudioElement(nodeInfo, aFromParser);
 }
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLAudioElement, nsHTMLMediaElement)
 NS_IMPL_RELEASE_INHERITED(nsHTMLAudioElement, nsHTMLMediaElement)
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -164,17 +164,17 @@ NS_NewHTMLImageElement(nsINodeInfo *aNod
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
     nsCOMPtr<nsIDocument> doc =
       do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
     NS_ENSURE_TRUE(doc, nsnull);
 
     nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::img, nsnull,
-                                                   kNameSpaceID_None);
+                                                   kNameSpaceID_XHTML);
     NS_ENSURE_TRUE(nodeInfo, nsnull);
   }
 
   return new nsHTMLImageElement(nodeInfo);
 }
 
 nsHTMLImageElement::nsHTMLImageElement(nsINodeInfo *aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -431,17 +431,17 @@ NS_IMETHODIMP nsHTMLMediaElement::Load()
 static PRBool HasSourceChildren(nsIContent *aElement)
 {
   PRUint32 count = aElement->GetChildCount();
   for (PRUint32 i = 0; i < count; ++i) {
     nsIContent* child = aElement->GetChildAt(i);
     NS_ASSERTION(child, "GetChildCount lied!");
     if (child &&
         child->Tag() == nsGkAtoms::source &&
-        child->IsNodeOfType(nsINode::eHTML))
+        child->IsHTML())
     {
       return PR_TRUE;
     }
   }
   return PR_FALSE;
 }
 
 // Returns true if aElement has a src attribute, or a <source> child.
@@ -1699,17 +1699,17 @@ void nsHTMLMediaElement::Thaw()
   if (mDecoder) {
     mDecoder->Resume();
   }
 }
 
 PRBool
 nsHTMLMediaElement::IsNodeOfType(PRUint32 aFlags) const
 {
-  return !(aFlags & ~(eCONTENT | eELEMENT | eHTML | eMEDIA));
+  return !(aFlags & ~(eCONTENT | eELEMENT | eMEDIA));
 }
 
 void nsHTMLMediaElement::NotifyAddedSource()
 {
   if (mLoadWaitStatus == WAITING_FOR_SRC_OR_SOURCE) {
     QueueSelectResourceTask();
   } else if (mLoadWaitStatus == WAITING_FOR_SOURCE) { 
     QueueLoadFromSourceTask();
@@ -1752,17 +1752,17 @@ already_AddRefed<nsIURI> nsHTMLMediaElem
     rv = mSourcePointer->SetStart(thisDomNode, startOffset+1);
     NS_ENSURE_SUCCESS(rv, nsnull);
 
     nsIContent* child = GetChildAt(startOffset);
 
     // If child is a <source> element, it may be the next candidate.
     if (child &&
         child->Tag() == nsGkAtoms::source &&
-        child->IsNodeOfType(nsINode::eHTML))
+        child->IsHTML())
     {
       nsCOMPtr<nsIURI> uri;
       nsAutoString src,type;
 
       // Must have src attribute.
       if (!child->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src))
         continue;
 
--- a/content/html/content/src/nsHTMLOptGroupElement.cpp
+++ b/content/html/content/src/nsHTMLOptGroupElement.cpp
@@ -153,18 +153,17 @@ nsHTMLOptGroupElement::PreHandleEvent(ns
 
   return nsGenericHTMLElement::PreHandleEvent(aVisitor);
 }
 
 nsIContent*
 nsHTMLOptGroupElement::GetSelect()
 {
   nsIContent* parent = this;
-  while ((parent = parent->GetParent()) &&
-         parent->IsNodeOfType(eHTML)) {
+  while ((parent = parent->GetParent()) && parent->IsHTML()) {
     if (parent->Tag() == nsGkAtoms::select) {
       return parent;
     }
     if (parent->Tag() != nsGkAtoms::optgroup) {
       break;
     }
   }
   
--- a/content/html/content/src/nsHTMLOptionElement.cpp
+++ b/content/html/content/src/nsHTMLOptionElement.cpp
@@ -437,17 +437,17 @@ nsHTMLOptionElement::IntrinsicState() co
 }
 
 // Get the select content element that contains this option
 nsIContent*
 nsHTMLOptionElement::GetSelect()
 {
   nsIContent* parent = this;
   while ((parent = parent->GetParent()) &&
-         parent->IsNodeOfType(eHTML)) {
+         parent->IsHTML()) {
     if (parent->Tag() == nsGkAtoms::select) {
       return parent;
     }
     if (parent->Tag() != nsGkAtoms::optgroup) {
       break;
     }
   }
   
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -326,17 +326,17 @@ nsHTMLSelectElement::RemoveOptionsFromLi
   }
 
   return NS_OK;
 }
 
 static PRBool IsOptGroup(nsIContent *aContent)
 {
   return (aContent->NodeInfo()->Equals(nsGkAtoms::optgroup) &&
-          aContent->IsNodeOfType(nsINode::eHTML));
+          aContent->IsHTML());
 }
 
 // If the document is such that recursing over these options gets us
 // deeper than four levels, there is something terribly wrong with the
 // world.
 nsresult
 nsHTMLSelectElement::InsertOptionsIntoListRecurse(nsIContent* aOptions,
                                                   PRInt32* aInsertIndex,
--- a/content/html/content/src/nsHTMLTableCellElement.cpp
+++ b/content/html/content/src/nsHTMLTableCellElement.cpp
@@ -135,17 +135,17 @@ nsIContent*
 nsHTMLTableCellElement::GetTable()
 {
   nsIContent *result = nsnull;
 
   nsIContent *parent = GetParent();
   if (parent) {  // GetParent() should be a row
     nsIContent* section = parent->GetParent();
     if (section) {
-      if (section->IsNodeOfType(eHTML) &&
+      if (section->IsHTML() &&
           section->NodeInfo()->Equals(nsGkAtoms::table)) {
         // XHTML, without a row group
         result = section;
       } else {
         // we have a row group.
         result = section->GetParent();
       }
     }
--- a/content/html/content/src/nsHTMLTableRowElement.cpp
+++ b/content/html/content/src/nsHTMLTableRowElement.cpp
@@ -232,17 +232,17 @@ nsHTMLTableRowElement::GetSectionRowInde
 
 static PRBool
 IsCell(nsIContent *aContent, PRInt32 aNamespaceID,
        nsIAtom* aAtom, void *aData)
 {
   nsIAtom* tag = aContent->Tag();
 
   return ((tag == nsGkAtoms::td || tag == nsGkAtoms::th) &&
-          aContent->IsNodeOfType(nsINode::eHTML));
+          aContent->IsHTML());
 }
 
 NS_IMETHODIMP
 nsHTMLTableRowElement::GetCells(nsIDOMHTMLCollection** aValue)
 {
   if (!mCells) {
     mCells = new nsContentList(this,
                                IsCell,
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1578,17 +1578,17 @@ nsHTMLDocument::SetBody(nsIDOMHTMLElemen
   nsCOMPtr<nsIContent> newBody = do_QueryInterface(aBody);
   nsIContent* root = GetRootContent();
 
   // The body element must be either a body tag or a frameset tag. And we must
   // have a html root tag, otherwise GetBody will not return the newly set
   // body.
   if (!newBody || !(newBody->Tag() == nsGkAtoms::body ||
                     newBody->Tag() == nsGkAtoms::frameset) ||
-      !root || !root->IsNodeOfType(nsINode::eHTML) ||
+      !root || !root->IsHTML() ||
       root->Tag() != nsGkAtoms::html) {
     return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
   }
 
   nsCOMPtr<nsIDOMElement> rootElem = do_QueryInterface(root);
   nsCOMPtr<nsIDOMNode> tmp;
 
   // Use DOM methods so that we pass through the appropriate security checks.
@@ -2739,17 +2739,17 @@ nsHTMLDocument::ResolveName(const nsAStr
 
   // No named items were found, see if there's one registerd by id for
   // aName. If we get this far, FindNamedItems() will have been called
   // for aName, so we're guaranteed that if there is an element with
   // the id aName, it'll be entry's IdContent.
 
   nsIContent *e = entry->GetIdContent();
 
-  if (e && e->IsNodeOfType(nsINode::eHTML)) {
+  if (e && e->IsHTML()) {
     nsIAtom *tag = e->Tag();
 
     if ((tag == nsGkAtoms::embed  ||
          tag == nsGkAtoms::img    ||
          tag == nsGkAtoms::object ||
          tag == nsGkAtoms::applet) &&
         (!aForm || nsContentUtils::BelongsInForm(aForm, e))) {
       NS_ADDREF(*aResult = e);
--- a/content/mathml/content/src/nsMathMLElement.cpp
+++ b/content/mathml/content/src/nsMathMLElement.cpp
@@ -405,17 +405,17 @@ nsMathMLElement::IntrinsicState() const
 {
   return nsMathMLElementBase::IntrinsicState() |
     (mIncrementScriptLevel ? NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL : 0);
 }
 
 PRBool
 nsMathMLElement::IsNodeOfType(PRUint32 aFlags) const
 {
-  return !(aFlags & ~(eCONTENT | eELEMENT | eMATHML));
+  return !(aFlags & ~(eCONTENT | eELEMENT));
 }
 
 void
 nsMathMLElement::SetIncrementScriptLevel(PRBool aIncrementScriptLevel,
                                          PRBool aNotify)
 {
   if (aIncrementScriptLevel == mIncrementScriptLevel)
     return;
--- a/content/svg/content/src/nsSVGLength2.cpp
+++ b/content/svg/content/src/nsSVGLength2.cpp
@@ -292,17 +292,17 @@ nsSVGLength2::GetUnitScaleFactor(nsSVGSV
     return 0;
   }
 }
 
 float
 nsSVGLength2::GetUnitScaleFactor(nsIFrame *aFrame, PRUint8 aUnitType) const
 {
   nsIContent* content = aFrame->GetContent();
-  if (content->IsNodeOfType(nsINode::eSVG))
+  if (content->IsSVG())
     return GetUnitScaleFactor(static_cast<nsSVGElement*>(content), aUnitType);
 
   switch (aUnitType) {
   case nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER:
   case nsIDOMSVGLength::SVG_LENGTHTYPE_PX:
     return 1;
   case nsIDOMSVGLength::SVG_LENGTHTYPE_MM:
     return GetMMPerPixel(aFrame);
--- a/content/xbl/src/nsXBLContentSink.cpp
+++ b/content/xbl/src/nsXBLContentSink.cpp
@@ -894,17 +894,17 @@ nsXBLContentSink::CreateElement(const PR
   return nsXULElement::Create(prototype, mDocument, PR_FALSE, aResult);
 #endif
 }
 
 nsresult 
 nsXBLContentSink::AddAttributes(const PRUnichar** aAtts,
                                 nsIContent* aContent)
 {
-  if (aContent->IsNodeOfType(nsINode::eXUL))
+  if (aContent->IsXUL())
     return NS_OK; // Nothing to do, since the proto already has the attrs.
 
   return nsXMLContentSink::AddAttributes(aAtts, aContent);
 }
 
 #ifdef MOZ_XUL
 nsresult
 nsXBLContentSink::AddAttributesToXULPrototype(const PRUnichar **aAtts, 
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -478,18 +478,17 @@ nsXBLPrototypeHandler::DispatchXBLComman
     nsIContent *content = focusedContent;
 
     // if the focused element is a link then we do want space to 
     // scroll down. The focused element may be an element in a link,
     // we need to check the parent node too. Only do this check if an
     // element is focused and has a parent.
     if (focusedContent && focusedContent->GetParent()) {
       while (content) {
-        if (content->Tag() == nsGkAtoms::a &&
-            content->IsNodeOfType(nsINode::eHTML)) {
+        if (content->Tag() == nsGkAtoms::a && content->IsHTML()) {
           isLink = PR_TRUE;
           break;
         }
 
         if (content->HasAttr(kNameSpaceID_XLink, nsGkAtoms::type)) {
           isLink = content->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type,
                                         nsGkAtoms::simple, eCaseMatters);
 
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -1167,18 +1167,17 @@ nsXBLService::LoadBindingDocumentInfo(ns
     if (aBoundElement)
       ni = aBoundElement->NodeInfo();
 
     if (!info && bindingManager &&
         (!ni || !(ni->Equals(nsGkAtoms::scrollbar, kNameSpaceID_XUL) ||
                   ni->Equals(nsGkAtoms::thumb, kNameSpaceID_XUL) ||
                   ((ni->Equals(nsGkAtoms::input) ||
                     ni->Equals(nsGkAtoms::select)) &&
-                   aBoundElement->IsNodeOfType(nsINode::eHTML)))) &&
-        !aForceSyncLoad) {
+                   aBoundElement->IsHTML()))) && !aForceSyncLoad) {
       // The third line of defense is to investigate whether or not the
       // document is currently being loaded asynchronously.  If so, there's no
       // document yet, but we need to glom on our request so that it will be
       // processed whenever the doc does finish loading.
       nsCOMPtr<nsIStreamListener> listener;
       if (bindingManager)
         listener = bindingManager->GetLoadingDocListener(documentURI);
       if (listener) {
--- a/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
+++ b/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
@@ -432,23 +432,16 @@ txXPathNodeUtils::getLocalName(const txX
 
         return;
     }
 
     if (aNode.isContent()) {
         if (aNode.mNode->IsNodeOfType(nsINode::eELEMENT)) {
             nsINodeInfo* nodeInfo = aNode.Content()->NodeInfo();
             nodeInfo->GetLocalName(aLocalName);
-
-            // Check for html
-            if (nodeInfo->NamespaceEquals(kNameSpaceID_None) &&
-                aNode.mNode->IsNodeOfType(nsINode::eHTML)) {
-                ToUpperCase(aLocalName);
-            }
-
             return;
         }
 
         if (aNode.mNode->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
             // PIs don't have a nodeinfo but do have a name
             nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode.mNode);
             node->GetNodeName(aLocalName);
 
@@ -460,17 +453,17 @@ txXPathNodeUtils::getLocalName(const txX
         return;
     }
 
     aNode.Content()->GetAttrNameAt(aNode.mIndex)->LocalName()->
       ToString(aLocalName);
 
     // Check for html
     if (aNode.Content()->NodeInfo()->NamespaceEquals(kNameSpaceID_None) &&
-        aNode.Content()->IsNodeOfType(nsINode::eHTML)) {
+        aNode.Content()->IsHTML()) {
         ToUpperCase(aLocalName);
     }
 }
 
 /* static */
 void
 txXPathNodeUtils::getNodeName(const txXPathNode& aNode, nsAString& aName)
 {
@@ -481,21 +474,19 @@ txXPathNodeUtils::getNodeName(const txXP
     }
 
     if (aNode.isContent()) {
         if (aNode.mNode->IsNodeOfType(nsINode::eELEMENT)) {
             nsINodeInfo* nodeInfo = aNode.Content()->NodeInfo();
             nodeInfo->GetQualifiedName(aName);
 
             // Check for html
-            if (nodeInfo->NamespaceEquals(kNameSpaceID_None) &&
-                aNode.Content()->IsNodeOfType(nsINode::eHTML)) {
+            if (aNode.Content()->IsHTML()) {
                 ToUpperCase(aName);
             }
-
             return;
         }
 
         if (aNode.mNode->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
             // PIs don't have a nodeinfo but do have a name
             nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode.mNode);
             node->GetNodeName(aName);
 
@@ -505,18 +496,17 @@ txXPathNodeUtils::getNodeName(const txXP
         aName.Truncate();
 
         return;
     }
 
     aNode.Content()->GetAttrNameAt(aNode.mIndex)->GetQualifiedName(aName);
 
     // Check for html
-    if (aNode.Content()->NodeInfo()->NamespaceEquals(kNameSpaceID_None) &&
-        aNode.Content()->IsNodeOfType(nsINode::eHTML)) {
+    if (aNode.Content()->IsHTML()) {
         ToUpperCase(aName);
     }
 }
 
 /* static */
 PRInt32
 txXPathNodeUtils::getNamespaceID(const txXPathNode& aNode)
 {
--- a/content/xslt/src/xpath/txXPathTreeWalker.h
+++ b/content/xslt/src/xpath/txXPathTreeWalker.h
@@ -145,17 +145,17 @@ public:
     static PRBool isText(const txXPathNode& aNode);
 #ifndef TX_EXE
     static inline PRBool isHTMLElementInHTMLDocument(const txXPathNode& aNode)
     {
       if (!aNode.isContent()) {
         return PR_FALSE;
       }
       nsIContent* content = aNode.Content();
-      return content->IsNodeOfType(nsINode::eHTML) && content->IsInHTMLDocument();
+      return content->IsHTML() && content->IsInHTMLDocument();
     }
 #else
 private:
     static void appendNodeValueHelper(NodeDefinition* aNode, nsAString& aResult);
 #endif
 };
 
 #ifdef TX_EXE
--- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp
@@ -303,24 +303,24 @@ txMozillaXMLOutput::endElement()
                    NS_ERROR_UNEXPECTED);
 
     nsIContent* element = static_cast<nsIContent*>
                                      (static_cast<nsINode*>
                                                  (mCurrentNode));
 
     // Handle html-elements
     if (!mNoFixup) {
-        if (element->IsNodeOfType(nsINode::eHTML)) {
+        if (element->IsHTML()) {
             rv = endHTMLElement(element);
             NS_ENSURE_SUCCESS(rv, rv);
         }
 
         // Handle script elements
         if (element->Tag() == nsGkAtoms::script &&
-            (element->IsNodeOfType(nsINode::eHTML) ||
+            (element->IsHTML() ||
             element->GetNameSpaceID() == kNameSpaceID_SVG)) {
 
             rv = element->DoneAddingChildren(PR_TRUE);
 
             // If the act of insertion evaluated the script, we're fine.
             // Else, add this script element to the array of loading scripts.
             if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
                 nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(element);
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -2152,17 +2152,17 @@ nsIContent *
 nsXULElement::GetBindingParent() const
 {
     return mBindingParent;
 }
 
 PRBool
 nsXULElement::IsNodeOfType(PRUint32 aFlags) const
 {
-    return !(aFlags & ~(eCONTENT | eELEMENT | eXUL));
+    return !(aFlags & ~(eCONTENT | eELEMENT));
 }
 
 static void
 PopupListenerPropertyDtor(void* aObject, nsIAtom* aPropertyName,
                           void* aPropertyValue, void* aData)
 {
   nsIDOMEventListener* listener =
     static_cast<nsIDOMEventListener*>(aPropertyValue);
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -470,17 +470,17 @@ class nsScriptEventHandlerOwnerTearoff;
 
 class nsXULElement : public nsGenericElement, public nsIDOMXULElement
 {
 public:
 
     /** Typesafe, non-refcounting cast from nsIContent.  Cheaper than QI. **/
     static nsXULElement* FromContent(nsIContent *aContent)
     {
-        if (aContent->IsNodeOfType(eXUL))
+        if (aContent->IsXUL())
             return static_cast<nsXULElement*>(aContent);
         return nsnull;
     }
 
 public:
     static nsIXBLService* GetXBLService() {
         if (!gXBLService)
             CallGetService("@mozilla.org/xbl;1", &gXBLService);
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -1297,17 +1297,17 @@ nsXULContentBuilder::EnsureElementHasGen
         return NS_ELEMENT_WAS_THERE;
     }
 }
 
 PRBool
 nsXULContentBuilder::IsOpen(nsIContent* aElement)
 {
     // Determine if this is a <treeitem> or <menu> element
-    if (!aElement->IsNodeOfType(nsINode::eXUL))
+    if (!aElement->IsXUL())
         return PR_TRUE;
 
     // XXXhyatt Use the XBL service to obtain a base tag.
     nsIAtom *tag = aElement->Tag();
     if (tag == nsGkAtoms::menu ||
         tag == nsGkAtoms::menubutton ||
         tag == nsGkAtoms::toolbarbutton ||
         tag == nsGkAtoms::button ||
--- a/content/xul/templates/src/nsXULSortService.cpp
+++ b/content/xul/templates/src/nsXULSortService.cpp
@@ -107,17 +107,17 @@ XULSortServiceImpl::SetSortColumnHints(n
 {
   // set sort info on current column. This ensures that the
   // column header sort indicator is updated properly.
   PRUint32 numChildren = content->GetChildCount();
 
   for (PRUint32 childIndex = 0; childIndex < numChildren; ++childIndex) {
     nsIContent *child = content->GetChildAt(childIndex);
 
-    if (child->IsNodeOfType(nsINode::eXUL)) {
+    if (child->IsXUL()) {
       nsIAtom *tag = child->Tag();
 
       if (tag == nsGkAtoms::treecols) {
         SetSortColumnHints(child, sortResource, sortDirection);
       } else if (tag == nsGkAtoms::treecol) {
         nsAutoString value;
         child->GetAttr(kNameSpaceID_None, nsGkAtoms::sort, value);
         // also check the resource attribute for older code
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -1244,17 +1244,17 @@ nsXULTemplateBuilder::LoadDataSources(ns
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Now set the database on the element, so that script writers can
     // access it.
     nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(aDocument);
     if (xuldoc)
         xuldoc->SetTemplateBuilderFor(mRoot, this);
 
-    if (!mRoot->IsNodeOfType(nsINode::eXUL)) {
+    if (!mRoot->IsXUL()) {
         // Hmm. This must be an HTML element. Try to set it as a
         // JS property "by hand".
         InitHTMLTemplateRoot();
     }
   
     return NS_OK;
 }
   
--- a/db/sqlite3/README.MOZILLA
+++ b/db/sqlite3/README.MOZILLA
@@ -1,11 +1,11 @@
-This is sqlite 3.6.16
+This is SQLite 3.6.18.
 
--- Shawn Wilsher <me@shawnwilsher.com>, 8/2009
+-- Shawn Wilsher <me@shawnwilsher.com>, 10/2009
 
 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/sqlite3.c
+++ b/db/sqlite3/src/sqlite3.c
@@ -1,28 +1,28 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.6.16.  By combining all the individual C code files into this 
+** version 3.6.18.  By combining all the individual C code files into this 
 ** single large file, the entire code can be compiled as a one translation
 ** unit.  This allows many compilers to do optimizations that would not be
 ** possible if the files were compiled separately.  Performance improvements
 ** of 5% are 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
 ** the programming interface to the SQLite library.  (If you do not have 
-** the "sqlite3.h" header file at hand, you will find a copy in the first
-** 5626 lines past this header comment.)  Additional code files may be
-** needed if you want a wrapper to interface SQLite with your choice of
-** programming language.  The code for the "sqlite3" command-line shell
-** is also in a separate file.  This file contains only code for the core
-** SQLite library.
-**
-** This amalgamation was generated on 2009-06-27 14:10:06 UTC.
+** the "sqlite3.h" header file at hand, you will find a copy embedded within
+** the text of this file.  Search for "Begin file sqlite3.h" to find the start
+** of the embedded sqlite3.h header file.) Additional code files may be needed
+** if you want a wrapper to interface SQLite with your choice of programming
+** language. The code for the "sqlite3" command-line shell is also in a
+** separate file. This file contains only code for the core SQLite library.
+**
+** This amalgamation was generated on 2009-09-11 15:35:42 UTC.
 */
 #define SQLITE_CORE 1
 #define SQLITE_AMALGAMATION 1
 #ifndef SQLITE_PRIVATE
 # define SQLITE_PRIVATE static
 #endif
 #ifndef SQLITE_API
 # define SQLITE_API
@@ -36,22 +36,48 @@
 **
 **    May you do good and not evil.
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.890 2009/06/26 15:14:55 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
 
 /*
+** These #defines should enable >2GB file support on POSIX if the
+** underlying operating system supports it.  If the OS lacks
+** large file support, or if the OS is windows, these should be no-ops.
+**
+** Ticket #2739:  The _LARGEFILE_SOURCE macro must appear before any
+** system #includes.  Hence, this block of code must be the very first
+** code in all source files.
+**
+** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
+** on the compiler command line.  This is necessary if you are compiling
+** on a recent machine (ex: Red Hat 7.2) but you want your code to work
+** on an older machine (ex: Red Hat 6.0).  If you compile on Red Hat 7.2
+** without this option, LFS is enable.  But LFS does not exist in the kernel
+** in Red Hat 6.0, so the code won't work.  Hence, for maximum binary
+** portability you should omit LFS.
+**
+** Similar is true for Mac OS X.  LFS is only supported on Mac OS X 9 and later.
+*/
+#ifndef SQLITE_DISABLE_LFS
+# define _LARGE_FILE       1
+# ifndef _FILE_OFFSET_BITS
+#   define _FILE_OFFSET_BITS 64
+# endif
+# define _LARGEFILE_SOURCE 1
+#endif
+
+/*
 ** Include the configuration header output by 'configure' if we're using the
 ** autoconf-based build
 */
 #ifdef _HAVE_SQLITE_CONFIG_H
 #include "config.h"
 #endif
 
 /************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
@@ -242,16 +268,27 @@
 /*
 ** Maximum length (in bytes) of the pattern in a LIKE or GLOB
 ** operator.
 */
 #ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
 # define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
 #endif
 
+/*
+** Maximum depth of recursion for triggers.
+*/
+#ifndef SQLITE_MAX_TRIGGER_DEPTH
+#if defined(SQLITE_SMALL_STACK)
+# define SQLITE_MAX_TRIGGER_DEPTH 10
+#else
+# define SQLITE_MAX_TRIGGER_DEPTH 1000
+#endif
+#endif
+
 /************** End of sqliteLimit.h *****************************************/
 /************** Continuing where we left off in sqliteInt.h ******************/
 
 /* Disable nuisance warnings on Borland compilers */
 #if defined(__BORLANDC__)
 #pragma warn -rch /* unreachable code */
 #pragma warn -ccc /* Condition is always true or false */
 #pragma warn -aus /* Assigned value is never used */
@@ -269,16 +306,18 @@
 */
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #endif
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
 #endif
 
+#define SQLITE_INDEX_SAMPLES 10
+
 /*
 ** This macro is used to "hide" some ugliness in casting an int
 ** value to a ptr value under the MSVC 64-bit compiler.   Casting
 ** non 64-bit values to ptr types results in a "hard" error with 
 ** the MSVC 64-bit compiler which this attempts to avoid.  
 **
 ** A simple compiler pragma or casting sequence could not be found
 ** to correct this in all situations, so this macro was introduced.
@@ -301,43 +340,16 @@
 #   define SQLITE_INT_TO_PTR(X)  ((void*)(X))
 #   define SQLITE_PTR_TO_INT(X)  ((int)(X))
 # endif
 #else
 # define SQLITE_INT_TO_PTR(X)   ((void*)&((char*)0)[X])
 # define SQLITE_PTR_TO_INT(X)   ((int)(((char*)X)-(char*)0))
 #endif
 
-/*
-** These #defines should enable >2GB file support on POSIX if the
-** underlying operating system supports it.  If the OS lacks
-** large file support, or if the OS is windows, these should be no-ops.
-**
-** Ticket #2739:  The _LARGEFILE_SOURCE macro must appear before any
-** system #includes.  Hence, this block of code must be the very first
-** code in all source files.
-**
-** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-** on the compiler command line.  This is necessary if you are compiling
-** on a recent machine (ex: Red Hat 7.2) but you want your code to work
-** on an older machine (ex: Red Hat 6.0).  If you compile on Red Hat 7.2
-** without this option, LFS is enable.  But LFS does not exist in the kernel
-** in Red Hat 6.0, so the code won't work.  Hence, for maximum binary
-** portability you should omit LFS.
-**
-** Similar is true for Mac OS X.  LFS is only supported on Mac OS X 9 and later.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE       1
-# ifndef _FILE_OFFSET_BITS
-#   define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
 
 /*
 ** The SQLITE_THREADSAFE macro must be defined as either 0 or 1.
 ** Older versions of SQLite used an optional THREADSAFE macro.
 ** We support that for legacy
 */
 #if !defined(SQLITE_THREADSAFE)
 #if defined(THREADSAFE)
@@ -529,29 +541,27 @@ SQLITE_PRIVATE   void sqlite3Coverage(in
 ** presents to client programs.  If a C-function, structure, datatype,
 ** or constant definition does not appear in this file, then it is
 ** not a published API of SQLite, is subject to change without
 ** notice, and should not be referenced by programs that use SQLite.
 **
 ** Some of the definitions that are in this file are marked as
 ** "experimental".  Experimental interfaces are normally new
 ** features recently added to SQLite.  We do not anticipate changes
-** to experimental interfaces but reserve to make minor changes if
-** experience from use "in the wild" suggest such changes are prudent.
+** to experimental interfaces but reserve the right to make minor changes
+** if experience from use "in the wild" suggest such changes are prudent.
 **
 ** The official C-language API documentation for SQLite is derived
 ** from comments in this file.  This file is the authoritative source
 ** on how SQLite interfaces are suppose to operate.
 **
 ** The name of this file under configuration management is "sqlite.h.in".
 ** The makefile makes some minor changes to this file (such as inserting
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
-**
-** @(#) $Id: sqlite.h.in,v 1.458 2009/06/19 22:50:31 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
 #include <stdarg.h>     /* Needed for the definition of va_list */
 
 /*
 ** Make sure we can call this stuff from C++.
 */
@@ -562,20 +572,25 @@ extern "C" {
 
 /*
 ** Add the ability to override 'extern'
 */
 #ifndef SQLITE_EXTERN
 # define SQLITE_EXTERN extern
 #endif
 
+#ifndef SQLITE_API
+# define SQLITE_API
+#endif
+
+
 /*
 ** These no-op macros are used in front of interfaces to mark those
 ** interfaces as either deprecated or experimental.  New applications
-** should not use deprecated intrfaces - they are support for backwards
+** should not use deprecated interfaces - they are support for backwards
 ** compatibility only.  Application writers should be aware that
 ** experimental interfaces are subject to change in point releases.
 **
 ** These macros used to resolve to various kinds of compiler magic that
 ** would generate warning messages when they were used.  But that
 ** compiler magic ended up generating such a flurry of bug reports
 ** that we have taken it all out and gone back to using simple
 ** noop macros.
@@ -595,72 +610,102 @@ extern "C" {
 
 /*
 ** CAPI3REF: Compile-Time Library Version Numbers {H10010} <S60100>
 **
 ** The SQLITE_VERSION and SQLITE_VERSION_NUMBER #defines in
 ** the sqlite3.h file specify the version of SQLite with which
 ** that header file is associated.
 **
-** The "version" of SQLite is a string of the form "X.Y.Z".
-** The phrase "alpha" or "beta" might be appended after the Z.
-** The X value is major version number always 3 in SQLite3.
-** The X value only changes when backwards compatibility is
+** The "version" of SQLite is a string of the form "W.X.Y" or "W.X.Y.Z".
+** The W value is major version number and is always 3 in SQLite3.
+** The W value only changes when backwards compatibility is
 ** broken and we intend to never break backwards compatibility.
-** The Y value is the minor version number and only changes when
+** The X value is the minor version number and only changes when
 ** there are major feature enhancements that are forwards compatible
 ** but not backwards compatible.
-** The Z value is the release number and is incremented with
-** each release but resets back to 0 whenever Y is incremented.
-**
-** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()].
+** The Y value is the release number and is incremented with
+** each release but resets back to 0 whenever X is incremented.
+** The Z value only appears on branch releases.
+**
+** The SQLITE_VERSION_NUMBER is an integer that is computed as
+** follows:
+**
+** <blockquote><pre>
+** SQLITE_VERSION_NUMBER = W*1000000 + X*1000 + Y
+** </pre></blockquote>
+**
+** Since version 3.6.18, SQLite source code has been stored in the
+** <a href="http://www.fossil-scm.org/">fossil configuration management
+** system</a>.  The SQLITE_SOURCE_ID
+** macro is a string which identifies a particular check-in of SQLite
+** within its configuration management system.  The 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()].
 **
 ** Requirements: [H10011] [H10014]
 */
-#define SQLITE_VERSION         "3.6.16"
-#define SQLITE_VERSION_NUMBER  3006016
+#define SQLITE_VERSION        "3.6.18"
+#define SQLITE_VERSION_NUMBER 3006018
+#define SQLITE_SOURCE_ID      "2009-09-11 14:05:07 b084828a771ec40be85f07c590ca99de4f6c24ee"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
 ** KEYWORDS: sqlite3_version
 **
-** These features provide the same information as the [SQLITE_VERSION]
-** and [SQLITE_VERSION_NUMBER] #defines in the header, but are associated
-** with the library instead of the header file.  Cautious programmers might
-** include a check in their application to verify that
-** sqlite3_libversion_number() always returns the value
-** [SQLITE_VERSION_NUMBER].
+** These interfaces provide the same information as the [SQLITE_VERSION],
+** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] #defines in the header,
+** but are associated with the library instead of the header file.  Cautious
+** programmers might include assert() statements in their application to
+** verify that values returned by these interfaces match the macros in
+** the header, and thus insure that the application is
+** compiled with matching library and header files.
+**
+** <blockquote><pre>
+** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
+** assert( strcmp(sqlite3_libversion,SQLITE_VERSION)==0 );
+** </pre></blockquote>
 **
 ** The sqlite3_libversion() function returns the same information as is
 ** in the sqlite3_version[] string constant.  The function is provided
 ** for use in DLLs since DLL users usually do not have direct access to string
-** constants within the DLL.
+** constants within the DLL.  Similarly, the sqlite3_sourceid() function
+** returns the same information as is in the [SQLITE_SOURCE_ID] #define of
+** the header file.
+**
+** See also: [sqlite_version()] and [sqlite_source_id()].
 **
 ** Requirements: [H10021] [H10022] [H10023]
 */
 SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
 SQLITE_API const char *sqlite3_libversion(void);
+SQLITE_API const char *sqlite3_sourceid(void);
 SQLITE_API int sqlite3_libversion_number(void);
 
 /*
 ** CAPI3REF: Test To See If The Library Is Threadsafe {H10100} <S60100>
 **
 ** SQLite can be compiled with or without mutexes.  When
-** the [SQLITE_THREADSAFE] C preprocessor macro 1 or 2, mutexes
+** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
 ** are enabled and SQLite is threadsafe.  When the
 ** [SQLITE_THREADSAFE] macro is 0, 
 ** the mutexes are omitted.  Without the mutexes, it is not safe
 ** to use SQLite concurrently from more than one thread.
 **
 ** Enabling mutexes incurs a measurable performance penalty.
 ** So if speed is of utmost importance, it makes sense to disable
 ** the mutexes.  But for maximum safety, mutexes should be enabled.
 ** The default behavior is for mutexes to be enabled.
 **
-** This interface can be used by a program to make sure that the
+** This interface can be used by an application to make sure that the
 ** version of SQLite that it is linking against was compiled with
 ** the desired setting of the [SQLITE_THREADSAFE] macro.
 **
 ** This interface only reports on the compile-time mutex setting
 ** of the [SQLITE_THREADSAFE] flag.  If SQLite is compiled with
 ** SQLITE_THREADSAFE=1 then mutexes are enabled by default but
 ** can be fully or partially disabled using a call to [sqlite3_config()]
 ** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
@@ -917,16 +962,18 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_OPEN_TEMP_DB          0x00000200  /* VFS only */
 #define SQLITE_OPEN_TRANSIENT_DB     0x00000400  /* VFS only */
 #define SQLITE_OPEN_MAIN_JOURNAL     0x00000800  /* VFS only */
 #define SQLITE_OPEN_TEMP_JOURNAL     0x00001000  /* VFS only */
 #define SQLITE_OPEN_SUBJOURNAL       0x00002000  /* VFS only */
 #define SQLITE_OPEN_MASTER_JOURNAL   0x00004000  /* VFS only */
 #define SQLITE_OPEN_NOMUTEX          0x00008000  /* Ok for sqlite3_open_v2() */
 #define SQLITE_OPEN_FULLMUTEX        0x00010000  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_SHAREDCACHE      0x00020000  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_PRIVATECACHE     0x00040000  /* Ok for sqlite3_open_v2() */
 
 /*
 ** CAPI3REF: Device Characteristics {H10240} <H11120>
 **
 ** The xDeviceCapabilities method of the [sqlite3_io_methods]
 ** object returns an integer which is a vector of the these
 ** bit values expressing I/O characteristics of the mass storage
 ** device that holds the file that the [sqlite3_io_methods]
@@ -984,18 +1031,19 @@ SQLITE_API int sqlite3_exec(
 */
 #define SQLITE_SYNC_NORMAL        0x00002
 #define SQLITE_SYNC_FULL          0x00003
 #define SQLITE_SYNC_DATAONLY      0x00010
 
 /*
 ** CAPI3REF: OS Interface Open File Handle {H11110} <S20110>
 **
-** An [sqlite3_file] object represents an open file in the OS
-** interface layer.  Individual OS interface implementations will
+** An [sqlite3_file] object represents an open file in the 
+** [sqlite3_vfs | OS interface layer].  Individual OS interface
+** implementations will
 ** want to subclass this object by appending additional fields
 ** for their own use.  The pMethods entry is a pointer to an
 ** [sqlite3_io_methods] object that defines methods for performing
 ** I/O operations on the open file.
 */
 typedef struct sqlite3_file sqlite3_file;
 struct sqlite3_file {
   const struct sqlite3_io_methods *pMethods;  /* Methods for an open file */
@@ -1361,18 +1409,19 @@ struct sqlite3_vfs {
 ** a default configuration using [sqlite3_config()].
 **
 ** The application should never invoke either sqlite3_os_init()
 ** or sqlite3_os_end() directly.  The application should only invoke
 ** sqlite3_initialize() and sqlite3_shutdown().  The sqlite3_os_init()
 ** interface is called automatically by sqlite3_initialize() and
 ** sqlite3_os_end() is called by sqlite3_shutdown().  Appropriate
 ** implementations for sqlite3_os_init() and sqlite3_os_end()
-** are built into SQLite when it is compiled for unix, windows, or os/2.
-** When built for other platforms (using the [SQLITE_OS_OTHER=1] compile-time
+** are built into SQLite when it is compiled for Unix, Windows, or OS/2.
+** When [custom builds | built for other platforms]
+** (using the [SQLITE_OS_OTHER=1] compile-time
 ** option) the application must supply a suitable implementation for
 ** sqlite3_os_init() and sqlite3_os_end().  An application-supplied
 ** implementation of sqlite3_os_init() or sqlite3_os_end()
 ** must return [SQLITE_OK] on success and some other [error code] upon
 ** failure.
 */
 SQLITE_API int sqlite3_initialize(void);
 SQLITE_API int sqlite3_shutdown(void);
@@ -1443,48 +1492,75 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlit
 ** EXPERIMENTAL
 **
 ** An instance of this object defines the interface between SQLite
 ** and low-level memory allocation routines.
 **
 ** This object is used in only one place in the SQLite interface.
 ** A pointer to an instance of this object is the argument to
 ** [sqlite3_config()] when the configuration option is
-** [SQLITE_CONFIG_MALLOC].  By creating an instance of this object
-** and passing it to [sqlite3_config()] during configuration, an
-** application can specify an alternative memory allocation subsystem
-** for SQLite to use for all of its dynamic memory needs.
-**
-** Note that SQLite comes with a built-in memory allocator that is
-** perfectly adequate for the overwhelming majority of applications
+** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].  
+** By creating an instance of this object
+** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC])
+** during configuration, an application can specify an alternative
+** memory allocation subsystem for SQLite to use for all of its
+** dynamic memory needs.
+**
+** Note that SQLite comes with several [built-in memory allocators]
+** that are perfectly adequate for the overwhelming majority of applications
 ** and that this object is only useful to a tiny minority of applications
 ** with specialized memory allocation requirements.  This object is
 ** also used during testing of SQLite in order to specify an alternative
 ** memory allocator that simulates memory out-of-memory conditions in
 ** order to verify that SQLite recovers gracefully from such
 ** conditions.
 **
-** The xMalloc, xFree, and xRealloc methods must work like the
-** malloc(), free(), and realloc() functions from the standard library.
+** The xMalloc and xFree methods must work like the
+** malloc() and free() functions from the standard C library.
+** The xRealloc method must work like realloc() from the standard C library
+** with the exception that if the second argument to xRealloc is zero,
+** xRealloc must be a no-op - it must not perform any allocation or
+** deallocation.  SQLite guaranteeds that the second argument to
+** xRealloc is always a value returned by a prior call to xRoundup.
+** And so in cases where xRoundup always returns a positive number,
+** xRealloc can perform exactly as the standard library realloc() and
+** still be in compliance with this specification.
 **
 ** xSize should return the allocated size of a memory allocation
 ** previously obtained from xMalloc or xRealloc.  The allocated size
 ** is always at least as big as the requested size but may be larger.
 **
 ** The xRoundup method returns what would be the allocated size of
 ** a memory allocation given a particular requested size.  Most memory
 ** allocators round up memory allocations at least to the next multiple
 ** of 8.  Some allocators round up to a larger multiple or to a power of 2.
+** Every memory allocation request coming in through [sqlite3_malloc()]
+** or [sqlite3_realloc()] first calls xRoundup.  If xRoundup returns 0, 
+** that causes the corresponding memory allocation to fail.
 **
 ** The xInit method initializes the memory allocator.  (For example,
 ** it might allocate any require mutexes or initialize internal data
 ** structures.  The xShutdown method is invoked (indirectly) by
 ** [sqlite3_shutdown()] and should deallocate any resources acquired
 ** by xInit.  The pAppData pointer is used as the only parameter to
 ** xInit and xShutdown.
+**
+** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
+** the xInit method, so the xInit method need not be threadsafe.  The
+** xShutdown method is only called from [sqlite3_shutdown()] so it does
+** not need to be threadsafe either.  For all other methods, SQLite
+** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the
+** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which
+** it is by default) and so the methods are automatically serialized.
+** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other
+** methods must be threadsafe or else make their own arrangements for
+** serialization.
+**
+** SQLite will never invoke xInit() more than once without an intervening
+** call to xShutdown().
 */
 typedef struct sqlite3_mem_methods sqlite3_mem_methods;
 struct sqlite3_mem_methods {
   void *(*xMalloc)(int);         /* Memory allocation function */
   void (*xFree)(void*);          /* Free a prior allocation */
   void *(*xRealloc)(void*,int);  /* Resize an allocation */
   int (*xSize)(void*);           /* Return the size of an allocation */
   int (*xRoundup)(int);          /* Round up request size to allocation size */
@@ -1628,19 +1704,22 @@ struct sqlite3_mem_methods {
 ** [sqlite3_mutex_methods]
 ** structure is filled with the currently defined mutex routines.
 ** This option can be used to overload the default mutex allocation
 ** routines with a wrapper used to track mutex usage for performance
 ** profiling or testing, for example.</dd>
 **
 ** <dt>SQLITE_CONFIG_LOOKASIDE</dt>
 ** <dd>This option takes two arguments that determine the default
-** memory allcation lookaside optimization.  The first argument is the
+** memory allocation lookaside optimization.  The first argument is the
 ** size of each lookaside buffer slot and the second is the number of
-** slots allocated to each database connection.</dd>
+** slots allocated to each database connection.  This option sets the
+** <i>default</i> lookaside size.  The [SQLITE_DBCONFIG_LOOKASIDE]
+** verb to [sqlite3_db_config()] can be used to change the lookaside
+** configuration on individual connections.</dd>
 **
 ** <dt>SQLITE_CONFIG_PCACHE</dt>
 ** <dd>This option takes a single argument which is a pointer to
 ** an [sqlite3_pcache_methods] object.  This object specifies the interface
 ** to a custom page cache implementation.  SQLite makes a copy of the
 ** object and uses it for page cache memory allocations.</dd>
 **
 ** <dt>SQLITE_CONFIG_GETPCACHE</dt>
@@ -1680,22 +1759,25 @@ struct sqlite3_mem_methods {
 ** non-zero [error code] if a discontinued or unsupported configuration option
 ** is invoked.
 **
 ** <dl>
 ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
 ** <dd>This option takes three additional arguments that determine the 
 ** [lookaside memory allocator] configuration for the [database connection].
 ** The first argument (the third parameter to [sqlite3_db_config()] is a
-** pointer to an 8-byte aligned memory buffer to use for lookaside memory.
+** pointer to an memory buffer to use for lookaside memory.
 ** The first argument may be NULL in which case SQLite will allocate the
 ** lookaside buffer itself using [sqlite3_malloc()].  The second argument is the
 ** size of each lookaside buffer slot and the third argument is the number of
 ** slots.  The size of the buffer in the first argument must be greater than
-** or equal to the product of the second and third arguments.</dd>
+** or equal to the product of the second and third arguments.  The buffer
+** must be aligned to an 8-byte boundary.  If the second argument is not
+** a multiple of 8, it is internally rounded down to the next smaller
+** multiple of 8.  See also: [SQLITE_CONFIG_LOOKASIDE]</dd>
 **
 ** </dl>
 */
 #define SQLITE_DBCONFIG_LOOKASIDE    1001  /* void* int int */
 
 
 /*
 ** CAPI3REF: Enable Or Disable Extended Result Codes {H12200} <S10700>
@@ -2089,17 +2171,17 @@ SQLITE_API int sqlite3_get_table(
   int *pnColumn,        /* Number of result columns written here */
   char **pzErrmsg       /* Error msg written here */
 );
 SQLITE_API void sqlite3_free_table(char **result);
 
 /*
 ** CAPI3REF: Formatted String Printing Functions {H17400} <S70000><S20000>
 **
-** These routines are workalikes of the "printf()" family of functions
+** These routines are work-alikes of the "printf()" family of functions
 ** from the standard C library.
 **
 ** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
 ** results into memory obtained from [sqlite3_malloc()].
 ** The strings returned by these two routines should be
 ** released by [sqlite3_free()].  Both routines return a
 ** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
 ** memory to hold the resulting string.
@@ -2376,17 +2458,17 @@ SQLITE_API void sqlite3_randomness(int N
 ** The authorizer is disabled by default.
 **
 ** The authorizer callback must not do anything that will modify
 ** the database connection that invoked the authorizer callback.
 ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
 ** database connections for the meaning of "modify" in this paragraph.
 **
 ** When [sqlite3_prepare_v2()] is used to prepare a statement, the
-** statement might be reprepared during [sqlite3_step()] due to a 
+** statement might be re-prepared during [sqlite3_step()] due to a 
 ** schema change.  Hence, the application should ensure that the
 ** correct authorizer callback remains in place during the [sqlite3_step()].
 **
 ** Note that the authorizer callback is invoked only during
 ** [sqlite3_prepare()] or its variants.  Authorization is not
 ** performed during statement evaluation in [sqlite3_step()], unless
 ** as stated in the previous paragraph, sqlite3_step() invokes
 ** sqlite3_prepare_v2() to reprepare a statement after a schema change.
@@ -2543,17 +2625,18 @@ SQLITE_API void sqlite3_progress_handler
 ** Whether or not an error occurs when it is opened, resources
 ** associated with the [database connection] handle should be released by
 ** passing it to [sqlite3_close()] when it is no longer required.
 **
 ** The sqlite3_open_v2() interface works like sqlite3_open()
 ** except that it accepts two additional parameters for additional control
 ** over the new database connection.  The flags parameter can take one of
 ** the following three values, optionally combined with the 
-** [SQLITE_OPEN_NOMUTEX] or [SQLITE_OPEN_FULLMUTEX] flags:
+** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
+** and/or [SQLITE_OPEN_PRIVATECACHE] flags:
 **
 ** <dl>
 ** <dt>[SQLITE_OPEN_READONLY]</dt>
 ** <dd>The database is opened in read-only mode.  If the database does not
 ** already exist, an error is returned.</dd>
 **
 ** <dt>[SQLITE_OPEN_READWRITE]</dt>
 ** <dd>The database is opened for reading and writing if possible, or reading
@@ -2563,25 +2646,31 @@ SQLITE_API void sqlite3_progress_handler
 ** <dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
 ** <dd>The database is opened for reading and writing, and is creates it if
 ** it does not already exist. This is the behavior that is always used for
 ** sqlite3_open() and sqlite3_open16().</dd>
 ** </dl>
 **
 ** If the 3rd parameter to sqlite3_open_v2() is not one of the
 ** combinations shown above or one of the combinations shown above combined
-** with the [SQLITE_OPEN_NOMUTEX] or [SQLITE_OPEN_FULLMUTEX] flags,
+** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX],
+** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_SHAREDCACHE] flags,
 ** then the behavior is undefined.
 **
 ** If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
 ** opens in the multi-thread [threading mode] as long as the single-thread
 ** mode has not been set at compile-time or start-time.  If the
 ** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
 ** in the serialized [threading mode] unless single-thread was
 ** previously selected at compile-time or start-time.
+** The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be
+** eligible to use [shared cache mode], regardless of whether or not shared
+** cache is enabled using [sqlite3_enable_shared_cache()].  The
+** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not
+** participate in [shared cache mode] even if it is enabled.
 **
 ** If the filename is ":memory:", then a private, temporary in-memory database
 ** is created for the connection.  This in-memory database will vanish when
 ** the database connection is closed.  Future versions of SQLite might
 ** make use of additional special filenames that begin with the ":" character.
 ** It is recommended that when a database filename actually does begin with
 ** a ":" character you should prefix the filename with a pathname such as
 ** "./" to avoid ambiguity.
@@ -2765,28 +2854,32 @@ SQLITE_API int sqlite3_limit(sqlite3*, i
 **
 ** <dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
 ** <dd>The maximum length of the pattern argument to the [LIKE] or
 ** [GLOB] operators.</dd>
 **
 ** <dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
 ** <dd>The maximum number of variables in an SQL statement that can
 ** be bound.</dd>
+**
+** <dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
+** <dd>The maximum depth of recursion for triggers.</dd>
 ** </dl>
 */
 #define SQLITE_LIMIT_LENGTH                    0
 #define SQLITE_LIMIT_SQL_LENGTH                1
 #define SQLITE_LIMIT_COLUMN                    2
 #define SQLITE_LIMIT_EXPR_DEPTH                3
 #define SQLITE_LIMIT_COMPOUND_SELECT           4
 #define SQLITE_LIMIT_VDBE_OP                   5
 #define SQLITE_LIMIT_FUNCTION_ARG              6
 #define SQLITE_LIMIT_ATTACHED                  7
 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH       8
 #define SQLITE_LIMIT_VARIABLE_NUMBER           9
+#define SQLITE_LIMIT_TRIGGER_DEPTH            10
 
 /*
 ** CAPI3REF: Compiling An SQL Statement {H13010} <S10000>
 ** KEYWORDS: {SQL statement compiler}
 **
 ** To execute an SQL query, it must first be compiled into a byte-code
 ** program using one of these routines.
 **
@@ -2953,28 +3046,29 @@ typedef struct Mem sqlite3_value;
 typedef struct sqlite3_context sqlite3_context;
 
 /*
 ** CAPI3REF: Binding Values To Prepared Statements {H13500} <S70300>
 ** KEYWORDS: {host parameter} {host parameters} {host parameter name}
 ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
 **
 ** In the SQL strings input to [sqlite3_prepare_v2()] and its variants,
-** literals may be replaced by a [parameter] in one of these forms:
+** literals may be replaced by a [parameter] that matches one of following
+** templates:
 **
 ** <ul>
 ** <li>  ?
 ** <li>  ?NNN
 ** <li>  :VVV
 ** <li>  @VVV
 ** <li>  $VVV
 ** </ul>
 **
-** In the parameter forms shown above NNN is an integer literal,
-** and VVV is an alpha-numeric parameter name. The values of these
+** In the templates above, NNN represents an integer literal,
+** and VVV represents an alphanumeric identifer.  The values of these
 ** parameters (also called "host parameter names" or "SQL parameters")
 ** can be set using the sqlite3_bind_*() routines defined here.
 **
 ** The first argument to the sqlite3_bind_*() routines is always
 ** a pointer to the [sqlite3_stmt] object returned from
 ** [sqlite3_prepare_v2()] or its variants.
 **
 ** The second argument is the index of the SQL parameter to be set.
@@ -3616,17 +3710,17 @@ SQLITE_API int sqlite3_reset(sqlite3_stm
 ** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]).  If the third
 ** parameter is less than -1 or greater than 127 then the behavior is
 ** undefined.
 **
 ** The fourth parameter, eTextRep, specifies what
 ** [SQLITE_UTF8 | text encoding] this SQL function prefers for
 ** its parameters.  Any SQL function implementation should be able to work
 ** work with UTF-8, UTF-16le, or UTF-16be.  But some implementations may be
-** more efficient with one encoding than another.  It is allowed to
+** more efficient with one encoding than another.  An application may
 ** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
 ** times with the same function but with different values of eTextRep.
 ** When multiple implementations of the same function are available, SQLite
 ** will pick the one that involves the least amount of data conversion.
 ** If there is only a single implementation which does not care what text
 ** encoding is used, then the fourth argument should be [SQLITE_ANY].
 **
 ** The fifth parameter is an arbitrary pointer.  The implementation of the
@@ -3638,17 +3732,17 @@ SQLITE_API int sqlite3_reset(sqlite3_stm
 ** callback only, NULL pointers should be passed as the xStep and xFinal
 ** parameters. An aggregate SQL function requires an implementation of xStep
 ** and xFinal and NULL should be passed for xFunc. To delete an existing
 ** SQL function or aggregate, pass NULL for all three function callbacks.
 **
 ** It is permitted to register multiple implementations of the same
 ** functions with the same name but with either differing numbers of
 ** arguments or differing preferred text encodings.  SQLite will use
-** the implementation most closely matches the way in which the
+** the implementation that most closely matches the way in which the
 ** SQL function is used.  A function implementation with a non-negative
 ** nArg parameter is a better match than a function implementation with
 ** a negative nArg.  A function where the preferred text encoding
 ** matches the database encoding is a better
 ** match than a function where the encoding is different.  
 ** A function where the encoding difference is between UTF16le and UTF16be
 ** is a closer match than a function where the encoding difference is
 ** between UTF8 and UTF16.
@@ -3986,20 +4080,21 @@ typedef void (*sqlite3_destructor_type)(
 ** If the 3rd parameter to the sqlite3_result_text* interfaces
 ** is non-negative, then as many bytes (not characters) of the text
 ** pointed to by the 2nd parameter are taken as the application-defined
 ** function result.
 ** If the 4th parameter to the sqlite3_result_text* interfaces
 ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
 ** function as the destructor on the text or BLOB result when it has
 ** finished using that result.
-** If the 4th parameter to the sqlite3_result_text* interfaces or
+** If the 4th parameter to the sqlite3_result_text* interfaces or to
 ** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite
 ** assumes that the text or BLOB result is in constant space and does not
-** copy the it or call a destructor when it has finished using that result.
+** copy the content of the parameter nor call a destructor on the content
+** when it has finished using that result.
 ** If the 4th parameter to the sqlite3_result_text* interfaces
 ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
 ** then SQLite makes a copy of the result into space obtained from
 ** from [sqlite3_malloc()] before it returns.
 **
 ** The sqlite3_result_value() interface sets the result of
 ** the application-defined function to be a copy the
 ** [unprotected sqlite3_value] object specified by the 2nd parameter.  The
@@ -4379,17 +4474,17 @@ SQLITE_API void *sqlite3_rollback_hook(s
 SQLITE_API void *sqlite3_update_hook(
   sqlite3*, 
   void(*)(void *,int ,char const *,char const *,sqlite3_int64),
   void*
 );
 
 /*
 ** CAPI3REF: Enable Or Disable Shared Pager Cache {H10330} <S30900>
-** KEYWORDS: {shared cache} {shared cache mode}
+** KEYWORDS: {shared cache}
 **
 ** This routine enables or disables the sharing of the database cache
 ** and schema data structures between [database connection | connections]
 ** to the same database. Sharing is enabled if the argument is true
 ** and disabled if the argument is false.
 **
 ** Cache sharing is enabled and disabled for an entire process.
 ** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
@@ -4842,17 +4937,17 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlit
 ** string obtained from [sqlite3_mprintf()] to zErrMsg.  The method should
 ** take care that any prior string is freed by a call to [sqlite3_free()]
 ** prior to assigning a new string to zErrMsg.  After the error message
 ** is delivered up to the client application, the string will be automatically
 ** freed by sqlite3_free() and the zErrMsg field will be zeroed.
 */
 struct sqlite3_vtab {
   const sqlite3_module *pModule;  /* The module for this virtual table */
-  int nRef;                       /* Used internally */
+  int nRef;                       /* NO LONGER USED */
   char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
   /* Virtual table implementations will typically add additional fields */
 };
 
 /*
 ** CAPI3REF: Virtual Table Cursor Object  {H18020} <S20400>
 ** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
 ** EXPERIMENTAL
@@ -4968,17 +5063,17 @@ typedef struct sqlite3_blob sqlite3_blob
 ** Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
 ** a expired BLOB handle fail with an return code of [SQLITE_ABORT].
 ** Changes written into a BLOB prior to the BLOB expiring are not
 ** rollback by the expiration of the BLOB.  Such changes will eventually
 ** commit if the transaction continues to completion.
 **
 ** Use the [sqlite3_blob_bytes()] interface to determine the size of
 ** the opened blob.  The size of a blob may not be changed by this
-** underface.  Use the [UPDATE] SQL command to change the size of a
+** interface.  Use the [UPDATE] SQL command to change the size of a
 ** blob.
 **
 ** The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
 ** and the built-in [zeroblob] SQL function can be used, if desired,
 ** to create an empty, zero-filled blob in which to read or write using
 ** this interface.
 **
 ** To avoid a resource leak, every open [BLOB handle] should eventually
@@ -5208,17 +5303,17 @@ SQLITE_API int sqlite3_vfs_unregister(sq
 ** The mutex implementation does not need to make a distinction
 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
 ** not want to.  {H17016} But SQLite will only request a recursive mutex in
 ** cases where it really needs one.  {END} If a faster non-recursive mutex
 ** implementation is available on the host platform, the mutex subsystem
 ** might return such a mutex in response to SQLITE_MUTEX_FAST.
 **
 ** {H17017} The other allowed parameters to sqlite3_mutex_alloc() each return
-** a pointer to a static preexisting mutex. {END}  Four static mutexes are
+** a pointer to a static preexisting mutex. {END}  Six static mutexes are
 ** used by the current version of SQLite.  Future versions of SQLite
 ** may add additional static mutexes.  Static mutexes are for internal
 ** use by SQLite only.  Applications that use SQLite mutexes should
 ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
 ** SQLITE_MUTEX_RECURSIVE.
 **
 ** {H17018} Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
@@ -5314,16 +5409,31 @@ SQLITE_API void sqlite3_mutex_leave(sqli
 **
 ** The only difference is that the public sqlite3_XXX functions enumerated
 ** above silently ignore any invocations that pass a NULL pointer instead
 ** of a valid mutex handle. The implementations of the methods defined
 ** by this structure are not required to handle this case, the results
 ** of passing a NULL pointer instead of a valid mutex handle are undefined
 ** (i.e. it is acceptable to provide an implementation that segfaults if
 ** it is passed a NULL pointer).
+**
+** The xMutexInit() method must be threadsafe.  It must be harmless to
+** invoke xMutexInit() mutiple times within the same process and without
+** intervening calls to xMutexEnd().  Second and subsequent calls to
+** xMutexInit() must be no-ops.
+**
+** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
+** and its associates).  Similarly, xMutexAlloc() must not use SQLite memory
+** allocation for a static mutex.  However xMutexAlloc() may use SQLite
+** memory allocation for a fast or recursive mutex.
+**
+** SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
+** called, but only if the prior call to xMutexInit returned SQLITE_OK.
+** If xMutexInit fails in any way, it is expected to clean up after itself
+** prior to returning.
 */
 typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
 struct sqlite3_mutex_methods {
   int (*xMutexInit)(void);
   int (*xMutexEnd)(void);
   sqlite3_mutex *(*xMutexAlloc)(int);
   void (*xMutexFree)(sqlite3_mutex *);
   void (*xMutexEnter)(sqlite3_mutex *);
@@ -5456,16 +5566,17 @@ SQLITE_API int sqlite3_test_control(int 
 #define SQLITE_TESTCTRL_PRNG_RESTORE             6
 #define SQLITE_TESTCTRL_PRNG_RESET               7
 #define SQLITE_TESTCTRL_BITVEC_TEST              8
 #define SQLITE_TESTCTRL_FAULT_INSTALL            9
 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10
 #define SQLITE_TESTCTRL_PENDING_BYTE            11
 #define SQLITE_TESTCTRL_ASSERT                  12
 #define SQLITE_TESTCTRL_ALWAYS                  13
+#define SQLITE_TESTCTRL_RESERVE                 14
 
 /*
 ** CAPI3REF: SQLite Runtime Status {H17200} <S60200>
 ** EXPERIMENTAL
 **
 ** This interface is used to retrieve runtime status information
 ** about the preformance of SQLite, and optionally to reset various
 ** highwater marks.  The first argument is an integer code for
@@ -5478,17 +5589,17 @@ SQLITE_API int sqlite3_test_control(int 
 ** value.  For those parameters
 ** nothing is written into *pHighwater and the resetFlag is ignored.
 ** Other parameters record only the highwater mark and not the current
 ** value.  For these latter parameters nothing is written into *pCurrent.
 **
 ** This routine returns SQLITE_OK on success and a non-zero
 ** [error code] on failure.
 **
-** This routine is threadsafe but is not atomic.  This routine can
+** This routine is threadsafe but is not atomic.  This routine can be
 ** called while other threads are running the same or different SQLite
 ** interfaces.  However the values returned in *pCurrent and
 ** *pHighwater reflect the status of SQLite at different points in time
 ** and it is possible that another thread might change the parameter
 ** in between the times when *pCurrent and *pHighwater are written.
 **
 ** See also: [sqlite3_db_status()]
 */
@@ -5601,17 +5712,24 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlit
 ** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
 */
 SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
 
 /*
 ** CAPI3REF: Status Parameters for database connections {H17520} <H17500>
 ** EXPERIMENTAL
 **
-** Status verbs for [sqlite3_db_status()].
+** These constants are the available integer "verbs" that can be passed as
+** the second argument to the [sqlite3_db_status()] interface.
+**
+** New verbs may be added in future releases of SQLite. Existing verbs
+** might be discontinued. Applications should check the return code from
+** [sqlite3_db_status()] to make sure that the call worked.
+** The [sqlite3_db_status()] interface will return a non-zero error code
+** if a discontinued or unsupported verb is invoked.
 **
 ** <dl>
 ** <dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
 ** <dd>This parameter returns the number of lookaside memory slots currently
 ** checked out.</dd>
 ** </dl>
 */
 #define SQLITE_DBSTATUS_LOOKASIDE_USED     0
@@ -5679,105 +5797,119 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlit
 ** to the object.
 **
 ** See [sqlite3_pcache_methods] for additional information.
 */
 typedef struct sqlite3_pcache sqlite3_pcache;
 
 /*
 ** CAPI3REF: Application Defined Page Cache.
+** KEYWORDS: {page cache}
 ** EXPERIMENTAL
 **
 ** The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
 ** register an alternative page cache implementation by passing in an 
 ** instance of the sqlite3_pcache_methods structure. The majority of the 
-** heap memory used by sqlite is used by the page cache to cache data read 
+** heap memory used by SQLite is used by the page cache to cache data read 
 ** from, or ready to be written to, the database file. By implementing a 
 ** custom page cache using this API, an application can control more 
-** precisely the amount of memory consumed by sqlite, the way in which 
-** said memory is allocated and released, and the policies used to 
+** precisely the amount of memory consumed by SQLite, the way in which 
+** that memory is allocated and released, and the policies used to 
 ** determine exactly which parts of a database file are cached and for 
 ** how long.
 **
-** The contents of the structure are copied to an internal buffer by sqlite
-** within the call to [sqlite3_config].
+** The contents of the sqlite3_pcache_methods structure are copied to an
+** internal buffer by SQLite within the call to [sqlite3_config].  Hence
+** the application may discard the parameter after the call to
+** [sqlite3_config()] returns.
 **
 ** The xInit() method is called once for each call to [sqlite3_initialize()]
 ** (usually only once during the lifetime of the process). It is passed
 ** a copy of the sqlite3_pcache_methods.pArg value. It can be used to set
 ** up global structures and mutexes required by the custom page cache 
-** implementation. The xShutdown() method is called from within 
-** [sqlite3_shutdown()], if the application invokes this API. It can be used
-** to clean up any outstanding resources before process shutdown, if required.
-**
-** The xCreate() method is used to construct a new cache instance. The
+** implementation. 
+**
+** The xShutdown() method is called from within [sqlite3_shutdown()], 
+** if the application invokes this API. It can be used to clean up 
+** any outstanding resources before process shutdown, if required.
+**
+** SQLite holds a [SQLITE_MUTEX_RECURSIVE] mutex when it invokes
+** the xInit method, so the xInit method need not be threadsafe.  The
+** xShutdown method is only called from [sqlite3_shutdown()] so it does
+** not need to be threadsafe either.  All other methods must be threadsafe
+** in multithreaded applications.
+**
+** SQLite will never invoke xInit() more than once without an intervening
+** call to xShutdown().
+**
+** The xCreate() method is used to construct a new cache instance.  SQLite
+** will typically create one cache instance for each open database file,
+** though this is not guaranteed. The
 ** first parameter, szPage, is the size in bytes of the pages that must
-** be allocated by the cache. szPage will not be a power of two. The
-** second argument, bPurgeable, is true if the cache being created will
-** be used to cache database pages read from a file stored on disk, or
+** be allocated by the cache.  szPage will not be a power of two.  szPage
+** will the page size of the database file that is to be cached plus an
+** increment (here called "R") of about 100 or 200.  SQLite will use the
+** extra R bytes on each page to store metadata about the underlying
+** database page on disk.  The value of R depends
+** on the SQLite version, the target platform, and how SQLite was compiled.
+** R is constant for a particular build of SQLite.  The second argument to
+** xCreate(), bPurgeable, is true if the cache being created will
+** be used to cache database pages of a file stored on disk, or
 ** false if it is used for an in-memory database. The cache implementation
-** does not have to do anything special based on the value of bPurgeable,
-** it is purely advisory. 
+** does not have to do anything special based with the value of bPurgeable;
+** it is purely advisory.  On a cache where bPurgeable is false, SQLite will
+** never invoke xUnpin() except to deliberately delete a page.
+** In other words, a cache created with bPurgeable set to false will
+** never contain any unpinned pages.
 **
 ** The xCachesize() method may be called at any time by SQLite to set the
 ** suggested maximum cache-size (number of pages stored by) the cache
 ** instance passed as the first argument. This is the value configured using
 ** the SQLite "[PRAGMA cache_size]" command. As with the bPurgeable parameter,
-** the implementation is not required to do anything special with this
-** value, it is advisory only.
+** the implementation is not required to do anything with this
+** value; it is advisory only.
 **
 ** The xPagecount() method should return the number of pages currently
-** stored in the cache supplied as an argument.
+** stored in the cache.
 ** 
 ** The xFetch() method is used to fetch a page and return a pointer to it. 
 ** A 'page', in this context, is a buffer of szPage bytes aligned at an
 ** 8-byte boundary. The page to be fetched is determined by the key. The
 ** mimimum key value is 1. After it has been retrieved using xFetch, the page 
-** is considered to be pinned.
-**
-** If the requested page is already in the page cache, then a pointer to
-** the cached buffer should be returned with its contents intact. If the
-** page is not already in the cache, then the expected behaviour of the
-** cache is determined by the value of the createFlag parameter passed
-** to xFetch, according to the following table:
+** is considered to be "pinned".
+**
+** If the requested page is already in the page cache, then the page cache
+** implementation must return a pointer to the page buffer with its content
+** intact.  If the requested page is not already in the cache, then the
+** behavior of the cache implementation is determined by the value of the
+** createFlag parameter passed to xFetch, according to the following table:
 **
 ** <table border=1 width=85% align=center>
-**   <tr><th>createFlag<th>Expected Behaviour
-**   <tr><td>0<td>NULL should be returned. No new cache entry is created.
-**   <tr><td>1<td>If createFlag is set to 1, this indicates that 
-**                SQLite is holding pinned pages that can be unpinned
-**                by writing their contents to the database file (a
-**                relatively expensive operation). In this situation the
-**                cache implementation has two choices: it can return NULL,
-**                in which case SQLite will attempt to unpin one or more 
-**                pages before re-requesting the same page, or it can
-**                allocate a new page and return a pointer to it. If a new
-**                page is allocated, then the first sizeof(void*) bytes of
-**                it (at least) must be zeroed before it is returned.
-**   <tr><td>2<td>If createFlag is set to 2, then SQLite is not holding any
-**                pinned pages associated with the specific cache passed
-**                as the first argument to xFetch() that can be unpinned. The
-**                cache implementation should attempt to allocate a new
-**                cache entry and return a pointer to it. Again, the first
-**                sizeof(void*) bytes of the page should be zeroed before 
-**                it is returned. If the xFetch() method returns NULL when 
-**                createFlag==2, SQLite assumes that a memory allocation 
-**                failed and returns SQLITE_NOMEM to the user.
+** <tr><th> createFlag <th> Behaviour when page is not already in cache
+** <tr><td> 0 <td> Do not allocate a new page.  Return NULL.
+** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
+**                 Otherwise return NULL.
+** <tr><td> 2 <td> Make every effort to allocate a new page.  Only return
+**                 NULL if allocating a new page is effectively impossible.
 ** </table>
 **
+** SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  If
+** a call to xFetch() with createFlag==1 returns NULL, then SQLite will
+** attempt to unpin one or more cache pages by spilling the content of
+** pinned pages to disk and synching the operating system disk cache. After
+** attempting to unpin pages, the xFetch() method will be invoked again with
+** a createFlag of 2.
+**
 ** xUnpin() is called by SQLite with a pointer to a currently pinned page
 ** as its second argument. If the third parameter, discard, is non-zero,
 ** then the page should be evicted from the cache. In this case SQLite 
 ** assumes that the next time the page is retrieved from the cache using
 ** the xFetch() method, it will be zeroed. If the discard parameter is
 ** zero, then the page is considered to be unpinned. The cache implementation
-** may choose to reclaim (free or recycle) unpinned pages at any time.
-** SQLite assumes that next time the page is retrieved from the cache
-** it will either be zeroed, or contain the same data that it did when it
-** was unpinned.
+** may choose to evict unpinned pages at any time.
 **
 ** The cache is not required to perform any reference counting. A single 
 ** call to xUnpin() unpins the page regardless of the number of prior calls 
 ** to xFetch().
 **
 ** The xRekey() method is used to change the key value associated with the
 ** page passed as the second argument from oldKey to newKey. If the cache
 ** previously contains an entry associated with newKey, it should be
@@ -6123,29 +6255,42 @@ SQLITE_API int sqlite3_backup_pagecount(
 ** SQLITE_LOCKED.
 */
 SQLITE_API int sqlite3_unlock_notify(
   sqlite3 *pBlocked,                          /* Waiting connection */
   void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
   void *pNotifyArg                            /* Argument to pass to xNotify */
 );
 
+
+/*
+** CAPI3REF: String Comparison
+** EXPERIMENTAL
+**
+** The [sqlite3_strnicmp()] API allows applications and extensions to
+** compare the contents of two buffers containing UTF-8 strings in a
+** case-indendent fashion, using the same definition of case independence 
+** that SQLite uses internally when comparing identifiers.
+*/
+SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
+
 /*
 ** Undo the hack that converts floating point types to integer for
 ** builds on processors without floating point support.
 */
 #ifdef SQLITE_OMIT_FLOATING_POINT
 # undef double
 #endif
 
 #if 0
 }  /* End of the 'extern "C"' block */
 #endif
 #endif
 
+
 /************** End of sqlite3.h *********************************************/
 /************** Continuing where we left off in sqliteInt.h ******************/
 /************** Include hash.h in the middle of sqliteInt.h ******************/
 /************** Begin file hash.h ********************************************/
 /*
 ** 2001 September 22
 **
 ** The author disclaims copyright to this source code.  In place of
@@ -6414,17 +6559,17 @@ SQLITE_PRIVATE void sqlite3HashClear(Has
 /*
 ** If compiling for a processor that lacks floating point support,
 ** substitute integer for floating-point
 */
 #ifdef SQLITE_OMIT_FLOATING_POINT
 # define double sqlite_int64
 # define LONGDOUBLE_TYPE sqlite_int64
 # ifndef SQLITE_BIG_DBL
-#   define SQLITE_BIG_DBL (((sqlite3_int64)1)<<60)
+#   define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
 # endif
 # define SQLITE_OMIT_DATETIME_FUNCS 1
 # define SQLITE_OMIT_TRACE 1
 # undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
 # undef SQLITE_HAVE_ISNAN
 #endif
 #ifndef SQLITE_BIG_DBL
 # define SQLITE_BIG_DBL (1e99)
@@ -6461,16 +6606,20 @@ SQLITE_PRIVATE void sqlite3HashClear(Has
 ** the default file format for new databases and the maximum file format
 ** that the library can read.
 */
 #define SQLITE_MAX_FILE_FORMAT 4
 #ifndef SQLITE_DEFAULT_FILE_FORMAT
 # define SQLITE_DEFAULT_FILE_FORMAT 1
 #endif
 
+#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS
+# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0
+#endif
+
 /*
 ** Provide a default value for SQLITE_TEMP_STORE in case it is not specified
 ** on the command-line
 */
 #ifndef SQLITE_TEMP_STORE
 # define SQLITE_TEMP_STORE 1
 #endif
 
@@ -6704,34 +6853,36 @@ typedef struct Schema Schema;
 typedef struct Expr Expr;
 typedef struct ExprList ExprList;
 typedef struct ExprSpan ExprSpan;
 typedef struct FKey FKey;
 typedef struct FuncDef FuncDef;
 typedef struct FuncDefHash FuncDefHash;
 typedef struct IdList IdList;
 typedef struct Index Index;
+typedef struct IndexSample IndexSample;
 typedef struct KeyClass KeyClass;
 typedef struct KeyInfo KeyInfo;
 typedef struct Lookaside Lookaside;
 typedef struct LookasideSlot LookasideSlot;
 typedef struct Module Module;
 typedef struct NameContext NameContext;
 typedef struct Parse Parse;
 typedef struct Savepoint Savepoint;
 typedef struct Select Select;
 typedef struct SrcList SrcList;
 typedef struct StrAccum StrAccum;
 typedef struct Table Table;
 typedef struct TableLock TableLock;
 typedef struct Token Token;
-typedef struct TriggerStack TriggerStack;
+typedef struct TriggerPrg TriggerPrg;
 typedef struct TriggerStep TriggerStep;
 typedef struct Trigger Trigger;
 typedef struct UnpackedRecord UnpackedRecord;
+typedef struct VTable VTable;
 typedef struct Walker Walker;
 typedef struct WherePlan WherePlan;
 typedef struct WhereInfo WhereInfo;
 typedef struct WhereLevel WhereLevel;
 
 /*
 ** Defer sourcing vdbe.h and btree.h until after the "u8" and 
 ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
@@ -6749,17 +6900,17 @@ typedef struct WhereLevel WhereLevel;
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
 ** This header file defines the interface that the sqlite B-Tree file
 ** subsystem.  See comments in the source code for a detailed description
 ** of what each interface routine does.
 **
-** @(#) $Id: btree.h,v 1.116 2009/06/03 11:25:07 danielk1977 Exp $
+** @(#) $Id: btree.h,v 1.120 2009/07/22 00:35:24 drh Exp $
 */
 #ifndef _BTREE_H_
 #define _BTREE_H_
 
 /* TODO: This definition is just included so other modules compile. It
 ** needs to be revisited.
 */
 #define SQLITE_N_BTREE_META 10
@@ -6833,18 +6984,18 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPha
 SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*);
 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 *);
-SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *, int, u8);
+SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree);
+SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
 SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int);
 
 SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *);
 SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *);
 SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *);
 
 SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
 
@@ -6854,17 +7005,17 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuu
 #define BTREE_INTKEY     1    /* Table has only 64-bit signed integer keys */
 #define BTREE_ZERODATA   2    /* Table has keys only - no data */
 #define BTREE_LEAFDATA   4    /* Data stored in leaves only.  Implies INTKEY */
 
 SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
 SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
 SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
 
-SQLITE_PRIVATE int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue);
+SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
 SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
 
 /*
 ** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
 ** should be one of the following values. The integer values are assigned 
 ** to constants so that the offset of the corresponding field in an
 ** SQLite database header may be found using the following formula:
 **
@@ -6888,40 +7039,32 @@ SQLITE_PRIVATE int sqlite3BtreeCursor(
   int iTable,                          /* Index of root page */
   int wrFlag,                          /* 1 for writing.  0 for read-only */
   struct KeyInfo*,                     /* First argument to compare function */
   BtCursor *pCursor                    /* Space to write cursor structure */
 );
 SQLITE_PRIVATE int sqlite3BtreeCursorSize(void);
 
 SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreeMoveto(
-  BtCursor*,
-  const void *pKey,
-  i64 nKey,
-  int bias,
-  int *pRes
-);
 SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
   BtCursor*,
   UnpackedRecord *pUnKey,
   i64 intKey,
   int bias,
   int *pRes
 );
 SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*, int*);
 SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*);
 SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
                                   const void *pData, int nData,
                                   int nZero, int bias, int seekResult);
 SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
 SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
 SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes);
 SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreeFlags(BtCursor*);
 SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes);
 SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
 SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
 SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
 SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
 SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
 SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
 SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64);
@@ -6929,16 +7072,20 @@ SQLITE_PRIVATE sqlite3_int64 sqlite3Btre
 
 SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
 SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
 
 SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
 SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *);
 SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
 
+#ifndef NDEBUG
+SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
+#endif
+
 #ifndef SQLITE_OMIT_BTREECOUNT
 SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *);
 #endif
 
 #ifdef SQLITE_TEST
 SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
 SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*);
 #endif
@@ -7002,17 +7149,17 @@ SQLITE_PRIVATE   int sqlite3BtreeHoldsAl
 **
 *************************************************************************
 ** Header file for the Virtual DataBase Engine (VDBE)
 **
 ** This header defines the interface to the virtual database engine
 ** or VDBE.  The VDBE implements an abstract machine that runs a
 ** simple program to access and modify the underlying database.
 **
-** $Id: vdbe.h,v 1.141 2009/04/10 00:56:29 drh Exp $
+** $Id: vdbe.h,v 1.142 2009/07/24 17:58:53 danielk1977 Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
 
 /*
 ** A single VDBE is an opaque structure named "Vdbe".  Only routines
 ** in the source file sqliteVdbe.c are allowed to see the insides
 ** of this structure.
@@ -7020,84 +7167,100 @@ SQLITE_PRIVATE   int sqlite3BtreeHoldsAl
 typedef struct Vdbe Vdbe;
 
 /*
 ** The names of the following types declared in vdbeInt.h are required
 ** for the VdbeOp definition.
 */
 typedef struct VdbeFunc VdbeFunc;
 typedef struct Mem Mem;
+typedef struct SubProgram SubProgram;
 
 /*
 ** A single instruction of the virtual machine has an opcode
 ** and as many as three operands.  The instruction is recorded
 ** as an instance of the following structure:
 */
 struct VdbeOp {
   u8 opcode;          /* What operation to perform */
   signed char p4type; /* One of the P4_xxx constants for p4 */
   u8 opflags;         /* Not currently used */
   u8 p5;              /* Fifth parameter is an unsigned character */
   int p1;             /* First operand */
   int p2;             /* Second parameter (often the jump destination) */
   int p3;             /* The third parameter */
-  union {             /* forth parameter */
+  union {             /* fourth parameter */
     int i;                 /* Integer value if p4type==P4_INT32 */
     void *p;               /* Generic pointer */
     char *z;               /* Pointer to data for string (char array) types */
     i64 *pI64;             /* Used when p4type is P4_INT64 */
     double *pReal;         /* Used when p4type is P4_REAL */
     FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
     VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
     CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
     Mem *pMem;             /* Used when p4type is P4_MEM */
-    sqlite3_vtab *pVtab;   /* Used when p4type is P4_VTAB */
+    VTable *pVtab;         /* Used when p4type is P4_VTAB */
     KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
     int *ai;               /* Used when p4type is P4_INTARRAY */
+    SubProgram *pProgram;  /* Used when p4type is P4_SUBPROGRAM */
   } p4;
 #ifdef SQLITE_DEBUG
   char *zComment;          /* Comment to improve readability */
 #endif
 #ifdef VDBE_PROFILE
   int cnt;                 /* Number of times this instruction was executed */
   u64 cycles;              /* Total time spent executing this instruction */
 #endif
 };
 typedef struct VdbeOp VdbeOp;
 
+
+/*
+** A sub-routine used to implement a trigger program.
+*/
+struct SubProgram {
+  VdbeOp *aOp;                  /* Array of opcodes for sub-program */
+  int nOp;                      /* Elements in aOp[] */
+  int nMem;                     /* Number of memory cells required */
+  int nCsr;                     /* Number of cursors required */
+  int nRef;                     /* Number of pointers to this structure */
+  void *token;                  /* id that may be used to recursive triggers */
+};
+
 /*
 ** A smaller version of VdbeOp used for the VdbeAddOpList() function because
 ** it takes up less space.
 */
 struct VdbeOpList {
   u8 opcode;          /* What operation to perform */
   signed char p1;     /* First operand */
   signed char p2;     /* Second parameter (often the jump destination) */
   signed char p3;     /* Third parameter */
 };
 typedef struct VdbeOpList VdbeOpList;
 
 /*
-** Allowed values of VdbeOp.p3type
+** Allowed values of VdbeOp.p4type
 */
 #define P4_NOTUSED    0   /* The P4 parameter is not used */
 #define P4_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
 #define P4_STATIC   (-2)  /* Pointer to a static string */
 #define P4_COLLSEQ  (-4)  /* P4 is a pointer to a CollSeq structure */
 #define P4_FUNCDEF  (-5)  /* P4 is a pointer to a FuncDef structure */
 #define P4_KEYINFO  (-6)  /* P4 is a pointer to a KeyInfo structure */
 #define P4_VDBEFUNC (-7)  /* P4 is a pointer to a VdbeFunc structure */
 #define P4_MEM      (-8)  /* P4 is a pointer to a Mem*    structure */
 #define P4_TRANSIENT (-9) /* P4 is a pointer to a transient string */
 #define P4_VTAB     (-10) /* P4 is a pointer to an sqlite3_vtab structure */
 #define P4_MPRINTF  (-11) /* P4 is a string obtained from sqlite3_mprintf() */
 #define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
 #define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
 #define P4_INT32    (-14) /* P4 is a 32-bit signed integer */
 #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
+#define P4_SUBPROGRAM  (-18) /* P4 is a pointer to a SubProgram structure */
 
 /* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
 ** is made.  That copy is freed when the Vdbe is finalized.  But if the
 ** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used.  It still
 ** gets freed when the Vdbe is finalized so it still should be obtained
 ** from a single sqliteMalloc().  But no copy is made and the calling
 ** function should *not* try to free the KeyInfo.
 */
@@ -7166,37 +7329,37 @@ typedef struct VdbeOpList VdbeOpList;
 #define OP_Sort                                18
 #define OP_Copy                                20
 #define OP_Trace                               21
 #define OP_Function                            22
 #define OP_IfNeg                               23
 #define OP_And                                 67   /* same as TK_AND      */
 #define OP_Subtract                            85   /* same as TK_MINUS    */
 #define OP_Noop                                24
-#define OP_Return                              25
+#define OP_Program                             25
+#define OP_Return                              26
 #define OP_Remainder                           88   /* same as TK_REM      */
-#define OP_NewRowid                            26
+#define OP_NewRowid                            27
 #define OP_Multiply                            86   /* same as TK_STAR     */
-#define OP_Variable                            27
-#define OP_String                              28
-#define OP_RealAffinity                        29
-#define OP_VRename                             30
-#define OP_ParseSchema                         31
-#define OP_VOpen                               32
-#define OP_Close                               33
-#define OP_CreateIndex                         34
-#define OP_IsUnique                            35
-#define OP_NotFound                            36
-#define OP_Int64                               37
-#define OP_MustBeInt                           38
-#define OP_Halt                                39
-#define OP_Rowid                               40
-#define OP_IdxLT                               41
-#define OP_AddImm                              42
-#define OP_Statement                           43
+#define OP_Variable                            28
+#define OP_String                              29
+#define OP_RealAffinity                        30
+#define OP_VRename                             31
+#define OP_ParseSchema                         32
+#define OP_VOpen                               33
+#define OP_Close                               34
+#define OP_CreateIndex                         35
+#define OP_IsUnique                            36
+#define OP_NotFound                            37
+#define OP_Int64                               38
+#define OP_MustBeInt                           39
+#define OP_Halt                                40
+#define OP_Rowid                               41
+#define OP_IdxLT                               42
+#define OP_AddImm                              43
 #define OP_RowData                             44
 #define OP_MemMax                              45
 #define OP_Or                                  66   /* same as TK_OR       */
 #define OP_NotExists                           46
 #define OP_Gosub                               47
 #define OP_Divide                              87   /* same as TK_SLASH    */
 #define OP_Integer                             48
 #define OP_ToNumeric                          143   /* same as TK_TO_NUMERIC*/
@@ -7209,20 +7372,20 @@ typedef struct VdbeOpList VdbeOpList;
 #define OP_CreateTable                         53
 #define OP_Last                                54
 #define OP_SeekLe                              55
 #define OP_IsNull                              71   /* same as TK_ISNULL   */
 #define OP_IncrVacuum                          56
 #define OP_IdxRowid                            57
 #define OP_ShiftRight                          83   /* same as TK_RSHIFT   */
 #define OP_ResetCount                          58
-#define OP_ContextPush                         59
-#define OP_Yield                               60
-#define OP_DropTrigger                         61
-#define OP_DropIndex                           62
+#define OP_Yield                               59
+#define OP_DropTrigger                         60
+#define OP_DropIndex                           61
+#define OP_Param                               62
 #define OP_IdxGE                               63
 #define OP_IdxDelete                           64
 #define OP_Vacuum                              65
 #define OP_IfNot                               68
 #define OP_DropTable                           69
 #define OP_SeekLt                              70
 #define OP_MakeRecord                          79
 #define OP_ToBlob                             142   /* same as TK_TO_BLOB  */
@@ -7235,55 +7398,55 @@ typedef struct VdbeOpList VdbeOpList;
 #define OP_TableLock                           97
 #define OP_Clear                               98
 #define OP_Le                                  76   /* same as TK_LE       */
 #define OP_VerifyCookie                        99
 #define OP_AggStep                            100
 #define OP_ToText                             141   /* same as TK_TO_TEXT  */
 #define OP_Not                                 19   /* same as TK_NOT      */
 #define OP_ToReal                             145   /* same as TK_TO_REAL  */
-#define OP_SetNumColumns                      101
-#define OP_Transaction                        102
-#define OP_VFilter                            103
+#define OP_Transaction                        101
+#define OP_VFilter                            102
 #define OP_Ne                                  73   /* same as TK_NE       */
-#define OP_VDestroy                           104
-#define OP_ContextPop                         105
+#define OP_VDestroy                           103
 #define OP_BitOr                               81   /* same as TK_BITOR    */
-#define OP_Next                               106
-#define OP_Count                              107
-#define OP_IdxInsert                          108
+#define OP_Next                               104
+#define OP_Count                              105
+#define OP_IdxInsert                          106
 #define OP_Lt                                  77   /* same as TK_LT       */
-#define OP_SeekGe                             109
-#define OP_Insert                             110
-#define OP_Destroy                            111
-#define OP_ReadCookie                         112
-#define OP_RowSetTest                         113
-#define OP_LoadAnalysis                       114
-#define OP_Explain                            115
-#define OP_HaltIfNull                         116
-#define OP_OpenPseudo                         117
-#define OP_OpenEphemeral                      118
-#define OP_Null                               119
-#define OP_Move                               120
-#define OP_Blob                               121
+#define OP_SeekGe                             107
+#define OP_Insert                             108
+#define OP_Destroy                            109
+#define OP_ReadCookie                         110
+#define OP_RowSetTest                         111
+#define OP_LoadAnalysis                       112
+#define OP_Explain                            113
+#define OP_HaltIfNull                         114
+#define OP_OpenPseudo                         115
+#define OP_OpenEphemeral                      116
+#define OP_Null                               117
+#define OP_Move                               118
+#define OP_Blob                               119
 #define OP_Add                                 84   /* same as TK_PLUS     */
-#define OP_Rewind                             122
-#define OP_SeekGt                             123
-#define OP_VBegin                             124
-#define OP_VUpdate                            125
-#define OP_IfZero                             126
+#define OP_Rewind                             120
+#define OP_SeekGt                             121
+#define OP_VBegin                             122
+#define OP_VUpdate                            123
+#define OP_IfZero                             124
 #define OP_BitNot                              93   /* same as TK_BITNOT   */
-#define OP_VCreate                            127
-#define OP_Found                              128
-#define OP_IfPos                              129
-#define OP_NullRow                            131
-#define OP_Jump                               132
-#define OP_Permutation                        133
+#define OP_VCreate                            125
+#define OP_Found                              126
+#define OP_IfPos                              127
+#define OP_NullRow                            128
+#define OP_Jump                               129
+#define OP_Permutation                        131
 
 /* The following opcode values are never used */
+#define OP_NotUsed_132                        132
+#define OP_NotUsed_133                        133
 #define OP_NotUsed_134                        134
 #define OP_NotUsed_135                        135
 #define OP_NotUsed_136                        136
 #define OP_NotUsed_137                        137
 #define OP_NotUsed_138                        138
 #define OP_NotUsed_139                        139
 #define OP_NotUsed_140                        140
 
@@ -7297,30 +7460,30 @@ typedef struct VdbeOpList VdbeOpList;
 #define OPFLG_IN1             0x0004  /* in1:   P1 is an input */
 #define OPFLG_IN2             0x0008  /* in2:   P2 is an input */
 #define OPFLG_IN3             0x0010  /* in3:   P3 is an input */
 #define OPFLG_OUT3            0x0020  /* out3:  P3 is an output */
 #define OPFLG_INITIALIZER {\
 /*   0 */ 0x00, 0x01, 0x00, 0x00, 0x10, 0x08, 0x02, 0x00,\
 /*   8 */ 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,\
 /*  16 */ 0x02, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x05,\
-/*  24 */ 0x00, 0x04, 0x02, 0x00, 0x02, 0x04, 0x00, 0x00,\
-/*  32 */ 0x00, 0x00, 0x02, 0x11, 0x11, 0x02, 0x05, 0x00,\
-/*  40 */ 0x02, 0x11, 0x04, 0x00, 0x00, 0x0c, 0x11, 0x01,\
+/*  24 */ 0x00, 0x01, 0x04, 0x02, 0x00, 0x02, 0x04, 0x00,\
+/*  32 */ 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x02, 0x05,\
+/*  40 */ 0x00, 0x02, 0x11, 0x04, 0x00, 0x08, 0x11, 0x01,\
 /*  48 */ 0x02, 0x01, 0x21, 0x08, 0x00, 0x02, 0x01, 0x11,\
-/*  56 */ 0x01, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x11,\
+/*  56 */ 0x01, 0x02, 0x00, 0x04, 0x00, 0x00, 0x02, 0x11,\
 /*  64 */ 0x00, 0x00, 0x2c, 0x2c, 0x05, 0x00, 0x11, 0x05,\
 /*  72 */ 0x05, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00,\
 /*  80 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,\
 /*  88 */ 0x2c, 0x2c, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00,\
-/*  96 */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\
-/* 104 */ 0x00, 0x00, 0x01, 0x02, 0x08, 0x11, 0x00, 0x02,\
-/* 112 */ 0x02, 0x15, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02,\
-/* 120 */ 0x00, 0x02, 0x01, 0x11, 0x00, 0x00, 0x05, 0x00,\
-/* 128 */ 0x11, 0x05, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,\
+/*  96 */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,\
+/* 104 */ 0x01, 0x02, 0x08, 0x11, 0x00, 0x02, 0x02, 0x15,\
+/* 112 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x02,\
+/* 120 */ 0x01, 0x11, 0x00, 0x00, 0x05, 0x00, 0x11, 0x05,\
+/* 128 */ 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\
 /* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,\
 /* 144 */ 0x04, 0x04,}
 
 /************** End of opcodes.h *********************************************/
 /************** Continuing where we left off in vdbe.h ***********************/
 
 /*
 ** Prototypes for the VDBE interface.  See comments on the implementation
@@ -7339,31 +7502,34 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP3(
 SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
 SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
 SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
 SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
 SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
 SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
 SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int);
+SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int);
 SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
 SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*);
 #ifdef SQLITE_DEBUG
+SQLITE_PRIVATE   int sqlite3VdbeAssertMayAbort(Vdbe *, int);
 SQLITE_PRIVATE   void sqlite3VdbeTrace(Vdbe*,FILE*);
 #endif
 SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*);
 SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int);
 SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
 SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
 SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
 SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
+SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
+SQLITE_PRIVATE void sqlite3VdbeProgramDelete(sqlite3 *, SubProgram *, int);
 
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
 SQLITE_PRIVATE int sqlite3VdbeReleaseMemory(int);
 #endif
 SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,char*,int);
 SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*);
 SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
 
@@ -7394,17 +7560,17 @@ SQLITE_PRIVATE   void sqlite3VdbeNoopCom
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
 ** This header file defines the interface that the sqlite page cache
 ** subsystem.  The page cache subsystem reads and writes a file a page
 ** at a time and provides a journal for rollback.
 **
-** @(#) $Id: pager.h,v 1.102 2009/06/18 17:22:39 drh Exp $
+** @(#) $Id: pager.h,v 1.104 2009/07/24 19:01:19 drh Exp $
 */
 
 #ifndef _PAGER_H_
 #define _PAGER_H_
 
 /*
 ** Default maximum size for persistent journal files. A negative 
 ** value means no limit. This value may be overridden using the 
@@ -7467,23 +7633,30 @@ typedef struct PgHdr DbPage;
 
 /*
 ** The remainder of this file contains the declarations of the functions
 ** that make up the Pager sub-system API. See source code comments for 
 ** a detailed description of each routine.
 */
 
 /* Open and close a Pager connection. */ 
-SQLITE_PRIVATE int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char*, int,int,int);
+SQLITE_PRIVATE int sqlite3PagerOpen(
+  sqlite3_vfs*,
+  Pager **ppPager,
+  const char*,
+  int,
+  int,
+  int,
+  void(*)(DbPage*)
+);
 SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager);
 SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
 
 /* Functions used to configure a Pager object. */
 SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
-SQLITE_PRIVATE void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*));
 SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u16*, int);
 SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
 SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
 SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int);
 SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
 SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *, int);
 SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
 SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
@@ -7507,16 +7680,17 @@ SQLITE_PRIVATE void *sqlite3PagerGetExtr
 SQLITE_PRIVATE int sqlite3PagerPagecount(Pager*, int*);
 SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int);
 SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
 SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager);
 SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*);
 SQLITE_PRIVATE int sqlite3PagerRollback(Pager*);
 SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
 SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
+SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
 
 /* Functions used to query pager state and configuration. */
 SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
 SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
 SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*);
 SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
 SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
@@ -7557,17 +7731,17 @@ SQLITE_PRIVATE   void sqlite3PagerRefdum
 **    May you do good and not evil.
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
 ** This header file defines the interface that the sqlite page cache
 ** subsystem. 
 **
-** @(#) $Id: pcache.h,v 1.19 2009/01/20 17:06:27 danielk1977 Exp $
+** @(#) $Id: pcache.h,v 1.20 2009/07/25 11:46:49 danielk1977 Exp $
 */
 
 #ifndef _PCACHE_H_
 
 typedef struct PgHdr PgHdr;
 typedef struct PCache PCache;
 
 /*
@@ -7669,17 +7843,17 @@ SQLITE_PRIVATE int sqlite3PcacheRefCount
 /* Increment the reference count of an existing page */
 SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*);
 
 SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*);
 
 /* Return the total number of pages stored in the cache */
 SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*);
 
-#ifdef SQLITE_CHECK_PAGES
+#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
 /* Iterate through all dirty pages currently stored in the cache. This
 ** interface is only available if SQLITE_CHECK_PAGES is defined when the 
 ** library is built.
 */
 SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *));
 #endif
 
 /* Set and get the suggested cache-size for the specified pager-cache.
@@ -7932,16 +8106,21 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefa
 ** 1GB boundary.
 **
 */
 #define PENDING_BYTE      sqlite3PendingByte
 #define RESERVED_BYTE     (PENDING_BYTE+1)
 #define SHARED_FIRST      (PENDING_BYTE+2)
 #define SHARED_SIZE       510
 
+/*
+** Wrapper around OS specific sqlite3_os_init() function.
+*/
+SQLITE_PRIVATE int sqlite3OsInit(void);
+
 /* 
 ** Functions for accessing sqlite3_file methods 
 */
 SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file*);
 SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
 SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
 SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size);
 SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int);
@@ -8125,17 +8304,17 @@ struct Schema {
 #define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
 #define DB_UnresetViews    0x0002  /* Some views have defined column names */
 #define DB_Empty           0x0004  /* The file is empty (length 0 bytes) */
 
 /*
 ** The number of different kinds of things that can be limited
 ** using the sqlite3_limit() interface.
 */
-#define SQLITE_N_LIMIT (SQLITE_LIMIT_VARIABLE_NUMBER+1)
+#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1)
 
 /*
 ** Lookaside malloc is a set of fixed-size buffers that can be used
 ** to satisfy small transient memory allocation requests for objects
 ** associated with a particular database connection.  The use of
 ** lookaside malloc provides a significant performance enhancement
 ** (approx 10%) by avoiding numerous malloc/free requests while parsing
 ** SQL statements.
@@ -8224,16 +8403,17 @@ struct sqlite3 {
   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 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 */
   void (*xTrace)(void*,const char*);        /* Trace function */
   void *pTraceArg;                          /* Argument to the trace function */
@@ -8264,18 +8444,19 @@ struct sqlite3 {
 #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
   Hash aModule;                 /* populated by sqlite3_create_module() */
   Table *pVTab;                 /* vtab with active Connect/Create method */
-  sqlite3_vtab **aVTrans;       /* Virtual tables with open transactions */
+  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 nSavepoint;               /* Number of non-transaction savepoints */
@@ -8330,19 +8511,18 @@ struct sqlite3 {
                                           ** accessing read-only databases */
 #define SQLITE_IgnoreChecks   0x00002000  /* Do not enforce check constraints */
 #define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */
 #define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */
 #define SQLITE_FullFSync      0x00010000  /* Use full fsync on the backend */
 #define SQLITE_LoadExtension  0x00020000  /* Enable load_extension */
 
 #define SQLITE_RecoveryMode   0x00040000  /* Ignore schema errors */
-#define SQLITE_SharedCache    0x00080000  /* Cache sharing is enabled */
-#define SQLITE_CommitBusy     0x00200000  /* In the process of committing */
-#define SQLITE_ReverseOrder   0x00400000  /* Reverse unordered SELECTs */
+#define SQLITE_ReverseOrder   0x00100000  /* Reverse unordered SELECTs */
+#define SQLITE_RecTriggers    0x00200000  /* Enable recursive triggers */
 
 /*
 ** Possible values for the sqlite.magic field.
 ** The numbers are obtained at random and have no special meaning, other
 ** than being distinct from one another.
 */
 #define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */
 #define SQLITE_MAGIC_CLOSED   0x9f3c2d33  /* Database is closed */
@@ -8541,16 +8721,66 @@ struct CollSeq {
 /*
 ** Additional bit values that can be ORed with an affinity without
 ** changing the affinity.
 */
 #define SQLITE_JUMPIFNULL   0x08  /* jumps if either operand is NULL */
 #define SQLITE_STOREP2      0x10  /* Store result in reg[P2] rather than jump */
 
 /*
+** An object of this type is created for each virtual table present in
+** the database schema. 
+**
+** If the database schema is shared, then there is one instance of this
+** structure for each database connection (sqlite3*) that uses the shared
+** schema. This is because each database connection requires its own unique
+** instance of the sqlite3_vtab* handle used to access the virtual table 
+** implementation. sqlite3_vtab* handles can not be shared between 
+** database connections, even when the rest of the in-memory database 
+** schema is shared, as the implementation often stores the database
+** connection handle passed to it via the xConnect() or xCreate() method
+** during initialization internally. This database connection handle may
+** then used by the virtual table implementation to access real tables 
+** within the database. So that they appear as part of the callers 
+** transaction, these accesses need to be made via the same database 
+** connection as that used to execute SQL operations on the virtual table.
+**
+** All VTable objects that correspond to a single table in a shared
+** database schema are initially stored in a linked-list pointed to by
+** the Table.pVTable member variable of the corresponding Table object.
+** When an sqlite3_prepare() operation is required to access the virtual
+** table, it searches the list for the VTable that corresponds to the
+** database connection doing the preparing so as to use the correct
+** sqlite3_vtab* handle in the compiled query.
+**
+** When an in-memory Table object is deleted (for example when the
+** schema is being reloaded for some reason), the VTable objects are not 
+** deleted and the sqlite3_vtab* handles are not xDisconnect()ed 
+** immediately. Instead, they are moved from the Table.pVTable list to
+** another linked list headed by the sqlite3.pDisconnect member of the
+** corresponding sqlite3 structure. They are then deleted/xDisconnected 
+** next time a statement is prepared using said sqlite3*. This is done
+** to avoid deadlock issues involving multiple sqlite3.mutex mutexes.
+** Refer to comments above function sqlite3VtabUnlockList() for an
+** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect
+** list without holding the corresponding sqlite3.mutex mutex.
+**
+** The memory for objects of this type is always allocated by 
+** sqlite3DbMalloc(), using the connection handle stored in VTable.db as 
+** the first argument.
+*/
+struct VTable {
+  sqlite3 *db;              /* Database connection associated with this table */
+  Module *pMod;             /* Pointer to module implementation */
+  sqlite3_vtab *pVtab;      /* Pointer to vtab instance */
+  int nRef;                 /* Number of pointers to this structure */
+  VTable *pNext;            /* Next in linked list (see above) */
+};
+
+/*
 ** Each SQL table is represented in memory by an instance of the
 ** following structure.
 **
 ** Table.zName is the name of the table.  The case of the original
 ** CREATE TABLE statement is stored, but case is not significant for
 ** comparisons.
 **
 ** Table.nCol is the number of columns in this table.  Table.aCol is a
@@ -8591,18 +8821,17 @@ struct Table {
   char *zColAff;       /* String defining the affinity of each column */
 #ifndef SQLITE_OMIT_CHECK
   Expr *pCheck;        /* The AND of all CHECK constraints */
 #endif
 #ifndef SQLITE_OMIT_ALTERTABLE
   int addColOffset;    /* Offset in CREATE TABLE stmt to add a new column */
 #endif
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  Module *pMod;        /* Pointer to the implementation of the module */
-  sqlite3_vtab *pVtab; /* Pointer to the module instance */
+  VTable *pVTable;     /* List of VTable objects. */
   int nModuleArg;      /* Number of arguments to the module */
   char **azModuleArg;  /* Text of all module args. [0] is module name */
 #endif
   Trigger *pTrigger;   /* List of triggers stored in pSchema */
   Schema *pSchema;     /* Schema that contains this table */
   Table *pNextZombie;  /* Next on the Parse.pZombieTab list */
 };
 
@@ -8785,16 +9014,30 @@ struct 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) */
   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 */
+  IndexSample *aSample;    /* Array of SQLITE_INDEX_SAMPLES samples */
+};
+
+/*
+** Each sample stored in the sqlite_stat2 table is represented in memory 
+** using a structure of this type.
+*/
+struct IndexSample {
+  union {
+    char *z;        /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */
+    double r;       /* Value if eType is SQLITE_FLOAT or SQLITE_INTEGER */
+  } u;
+  u8 eType;         /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
+  u8 nByte;         /* Size in byte of text or blob. */
 };
 
 /*
 ** Each token coming out of the lexer is an instance of
 ** this structure.  Tokens are also used as part of an expression.
 **
 ** Note if Token.z==0 then Token.dyn and Token.n are undefined and
 ** may contain random values.  Do not make any assumptions about Token.dyn
@@ -8935,21 +9178,23 @@ struct Expr {
   CollSeq *pColl;        /* The collation type of the column or 0 */
 
   /* If the EP_Reduced flag is set in the Expr.flags mask, then no
   ** space is allocated for the fields below this point. An attempt to
   ** access them will result in a segfault or malfunction.
   *********************************************************************/
 
   int iTable;            /* TK_COLUMN: cursor number of table holding column
-                         ** TK_REGISTER: register number */
+                         ** TK_REGISTER: register number
+                         ** TK_TRIGGER: 1 -> new, 0 -> old */
   i16 iColumn;           /* TK_COLUMN: column index.  -1 for rowid */
   i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
   i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
-  u16 flags2;            /* Second set of flags.  EP2_... */
+  u8 flags2;             /* Second set of flags.  EP2_... */
+  u8 op2;                /* If a TK_REGISTER, the original value of Expr.op */
   AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
   Table *pTab;           /* Table for TK_COLUMN expressions. */
 #if SQLITE_MAX_EXPR_DEPTH>0
   int nHeight;           /* Height of the tree headed by this node */
 #endif
 };
 
 /*
@@ -9374,16 +9619,41 @@ struct AutoincInfo {
 /*
 ** Size of the column cache
 */
 #ifndef SQLITE_N_COLCACHE
 # define SQLITE_N_COLCACHE 10
 #endif
 
 /*
+** At least one instance of the following structure is created for each 
+** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
+** statement. All such objects are stored in the linked list headed at
+** Parse.pTriggerPrg and deleted once statement compilation has been
+** completed.
+**
+** A Vdbe sub-program that implements the body and WHEN clause of trigger
+** TriggerPrg.pTrigger, assuming a default ON CONFLICT clause of
+** TriggerPrg.orconf, is stored in the TriggerPrg.pProgram variable.
+** The Parse.pTriggerPrg list never contains two entries with the same
+** values for both pTrigger and orconf.
+**
+** The TriggerPrg.oldmask variable is set to a mask of old.* columns
+** accessed (or set to 0 for triggers fired as a result of INSERT 
+** statements).
+*/
+struct TriggerPrg {
+  Trigger *pTrigger;      /* Trigger this program was coded from */
+  int orconf;             /* Default ON CONFLICT policy */
+  SubProgram *pProgram;   /* Program implementing pTrigger/orconf */
+  u32 oldmask;            /* Mask of old.* columns accessed */
+  TriggerPrg *pNext;      /* Next entry in Parse.pTriggerPrg list */
+};
+
+/*
 ** An SQL parser context.  A copy of this structure is passed through
 ** the parser and down into all the parser action routine in order to
 ** carry around information that is global to the entire parse.
 **
 ** The structure is divided into two parts.  When the parser and code
 ** generate call themselves recursively, the first part of the structure
 ** is constant but the second part is reset at the beginning and end of
 ** each recursion.
@@ -9424,54 +9694,62 @@ struct Parse {
     u8 affChange;         /* True if this register has had an affinity change */
     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 */
   u32 writeMask;       /* Start a write transaction on these databases */
   u32 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 */
 #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 */
+  u32 oldmask;         /* Mask of old.* columns referenced */
+  u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
+  u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
 
   /* 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 nVarExpr;        /* Number of used slots in apVarExpr[] */
   int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
   Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */
   int nAlias;          /* Number of aliased result set columns */
   int nAliasAlloc;     /* Number of allocated slots for aAlias[] */
   int *aAlias;         /* Register used to hold aliased result */
   u8 explain;          /* True if the EXPLAIN flag is found on the query */
-  Token sErrToken;     /* The token at which the error occurred */
   Token sNameToken;    /* Token with unqualified schema object name */
   Token sLastToken;    /* The last token parsed */
-  const char *zSql;    /* All SQL text */
   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 */
-  TriggerStack *trigStack;  /* Trigger actions being coded */
   const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
 #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 */
 };
 
 #ifdef SQLITE_OMIT_VIRTUALTABLE
   #define IN_DECLARE_VTAB 0
 #else
   #define IN_DECLARE_VTAB (pParse->declareVtab)
 #endif
 
@@ -9482,21 +9760,22 @@ struct Parse {
 struct AuthContext {
   const char *zAuthContext;   /* Put saved Parse.zAuthContext here */
   Parse *pParse;              /* The Parse structure */
 };
 
 /*
 ** Bitfield flags for P5 value in OP_Insert and OP_Delete
 */
-#define OPFLAG_NCHANGE    1    /* Set to update db->nChange */
-#define OPFLAG_LASTROWID  2    /* Set to update db->lastRowid */
-#define OPFLAG_ISUPDATE   4    /* This OP_Insert is an sql UPDATE */
-#define OPFLAG_APPEND     8    /* This is likely to be an append */
-#define OPFLAG_USESEEKRESULT 16    /* Try to avoid a seek in BtreeInsert() */
+#define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */
+#define OPFLAG_LASTROWID     0x02    /* Set to update db->lastRowid */
+#define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
+#define OPFLAG_APPEND        0x08    /* This is likely to be an append */
+#define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */
+#define OPFLAG_CLEARCACHE    0x20    /* Clear pseudo-table cache in OP_Column */
 
 /*
  * Each trigger present in the database schema is stored as an instance of
  * struct Trigger. 
  *
  * Pointers to instances of struct Trigger are stored in two ways.
  * 1. In the "trigHash" hash table (part of the sqlite3* that represents the 
  *    database). This allows Trigger structures to be retrieved by name.
@@ -9504,17 +9783,17 @@ struct AuthContext {
  *    pNext member of struct Trigger. A pointer to the first element of the
  *    linked list is stored as the "pTrigger" member of the associated
  *    struct Table.
  *
  * The "step_list" member points to the first element of a linked list
  * containing the SQL statements specified as the trigger program.
  */
 struct Trigger {
-  char *name;             /* The name of the trigger                        */
+  char *zName;            /* The name of the trigger                        */
   char *table;            /* The table or view to which the trigger applies */
   u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
   u8 tr_tm;               /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
   Expr *pWhen;            /* The WHEN clause of the expression (may be NULL) */
   IdList *pColumns;       /* If this is an UPDATE OF <column-list> trigger,
                              the <column-list> is stored here */
   Schema *pSchema;        /* Schema containing the trigger */
   Schema *pTabSchema;     /* Schema containing the table */
@@ -9566,71 +9845,29 @@ struct Trigger {
  * pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
  *              Otherwise NULL.
  * pExprList -> A list of the columns to update and the expressions to update
  *              them to. See sqlite3Update() documentation of "pChanges"
  *              argument.
  * 
  */
 struct TriggerStep {
-  int op;              /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
-  int orconf;          /* OE_Rollback etc. */
+  u8 op;               /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
+  u8 orconf;           /* OE_Rollback etc. */
   Trigger *pTrig;      /* The trigger that this step is a part of */
-
-  Select *pSelect;     /* Valid for SELECT and sometimes 
-                          INSERT steps (when pExprList == 0) */
-  Token target;        /* Target table for DELETE, UPDATE, INSERT.  Quoted */
-  Expr *pWhere;        /* Valid for DELETE, UPDATE steps */
-  ExprList *pExprList; /* Valid for UPDATE statements and sometimes 
-                           INSERT steps (when pSelect == 0)         */
-  IdList *pIdList;     /* Valid for INSERT statements only */
+  Select *pSelect;     /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
+  Token target;        /* Target table for DELETE, UPDATE, INSERT */
+  Expr *pWhere;        /* The WHERE clause for DELETE or UPDATE steps */
+  ExprList *pExprList; /* SET clause for UPDATE.  VALUES clause for INSERT */
+  IdList *pIdList;     /* Column names for INSERT */
   TriggerStep *pNext;  /* Next in the link-list */
   TriggerStep *pLast;  /* Last element in link-list. Valid for 1st elem only */
 };
 
 /*
- * An instance of struct TriggerStack stores information required during code
- * generation of a single trigger program. While the trigger program is being
- * coded, its associated TriggerStack instance is pointed to by the
- * "pTriggerStack" member of the Parse structure.
- *
- * The pTab member points to the table that triggers are being coded on. The 
- * newIdx member contains the index of the vdbe cursor that points at the temp
- * table that stores the new.* references. If new.* references are not valid
- * for the trigger being coded (for example an ON DELETE trigger), then newIdx
- * is set to -1. The oldIdx member is analogous to newIdx, for old.* references.
- *
- * The ON CONFLICT policy to be used for the trigger program steps is stored 
- * as the orconf member. If this is OE_Default, then the ON CONFLICT clause 
- * specified for individual triggers steps is used.
- *
- * struct TriggerStack has a "pNext" member, to allow linked lists to be
- * constructed. When coding nested triggers (triggers fired by other triggers)
- * each nested trigger stores its parent trigger's TriggerStack as the "pNext" 
- * pointer. Once the nested trigger has been coded, the pNext value is restored
- * to the pTriggerStack member of the Parse stucture and coding of the parent
- * trigger continues.
- *
- * Before a nested trigger is coded, the linked list pointed to by the 
- * pTriggerStack is scanned to ensure that the trigger is not about to be coded
- * recursively. If this condition is detected, the nested trigger is not coded.
- */
-struct TriggerStack {
-  Table *pTab;         /* Table that triggers are currently being coded on */
-  int newIdx;          /* Index of vdbe cursor to "new" temp table */
-  int oldIdx;          /* Index of vdbe cursor to "old" temp table */
-  u32 newColMask;
-  u32 oldColMask;
-  int orconf;          /* Current orconf policy */
-  int ignoreJump;      /* where to jump to for a RAISE(IGNORE) */
-  Trigger *pTrigger;   /* The trigger currently being coded */
-  TriggerStack *pNext; /* Next trigger down on the trigger stack */
-};
-
-/*
 ** The following structure contains information used by the sqliteFix...
 ** routines as they walk the parse tree to make database references
 ** explicit.  
 */
 typedef struct DbFixer DbFixer;
 struct DbFixer {
   Parse *pParse;      /* The parsing context.  Error messages written here */
   const char *zDb;    /* Make sure all objects are contained in this database */
@@ -9690,17 +9927,19 @@ struct Sqlite3Config {
   int szPage;                       /* Size of each page in pPage[] */
   int nPage;                        /* Number of pages in pPage[] */
   int mxParserStack;                /* maximum depth of the parser stack */
   int sharedCacheEnabled;           /* true if shared-cache mode enabled */
   /* The above might be initialized to non-zero.  The following need to always
   ** initially be zero, however. */
   int isInit;                       /* True after initialization has finished */
   int inProgress;                   /* True while initialization in progress */
+  int isMutexInit;                  /* True after mutexes are initialized */
   int isMallocInit;                 /* True after malloc is initialized */
+  int isPCacheInit;                 /* True after malloc is initialized */
   sqlite3_mutex *pInitMutex;        /* Mutex used by sqlite3_initialize() */
   int nRefInitMutex;                /* Number of users of pInitMutex */
 };
 
 /*
 ** Context pointer passed down through the tree-walk.
 */
 struct Walker {
@@ -9782,19 +10021,19 @@ SQLITE_PRIVATE   int sqlite3Corrupt(void
 # 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 *);
-SQLITE_PRIVATE int sqlite3StrNICmp(const char *, const char *, int);
 SQLITE_PRIVATE int sqlite3IsNumber(const char*, int*, u8);
 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);
 SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, int);
 SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
@@ -10007,24 +10246,26 @@ SQLITE_PRIVATE void sqlite3CommitTransac
 SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
 SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
 SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
 SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
 SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
 SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);
 SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
 SQLITE_PRIVATE int sqlite3IsRowid(const char*);
-SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int);
+SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
 SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
 SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
 SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
                                      int*,int,int,int,int,int*);
-SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int,int,int);
+SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
 SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
 SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
+SQLITE_PRIVATE void sqlite3MayAbort(Parse *);
+SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int);
 SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
 SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
 SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
 SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
 SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
 SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
@@ -10048,34 +10289,38 @@ SQLITE_PRIVATE void sqlite3MaterializeVi
 #ifndef SQLITE_OMIT_TRIGGER
 SQLITE_PRIVATE   void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
                            Expr*,int, int);
 SQLITE_PRIVATE   void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
 SQLITE_PRIVATE   void sqlite3DropTrigger(Parse*, SrcList*, int);
 SQLITE_PRIVATE   void sqlite3DropTriggerPtr(Parse*, Trigger*);
 SQLITE_PRIVATE   Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask);
 SQLITE_PRIVATE   Trigger *sqlite3TriggerList(Parse *, Table *);
-SQLITE_PRIVATE   int sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *,
-                            int, int, int, int, u32*, u32*);
+SQLITE_PRIVATE   void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *,
+                            int, int, int, int);
   void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
 SQLITE_PRIVATE   void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
 SQLITE_PRIVATE   TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
 SQLITE_PRIVATE   TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
-                                        ExprList*,Select*,int);
-SQLITE_PRIVATE   TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, int);
+                                        ExprList*,Select*,u8);
+SQLITE_PRIVATE   TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8);
 SQLITE_PRIVATE   TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
 SQLITE_PRIVATE   void sqlite3DeleteTrigger(sqlite3*, Trigger*);
 SQLITE_PRIVATE   void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
+SQLITE_PRIVATE   u32 sqlite3TriggerOldmask(Parse*,Trigger*,int,ExprList*,Table*,int);
+# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p))
 #else
 # define sqlite3TriggersExist(B,C,D,E,F) 0
 # define sqlite3DeleteTrigger(A,B)
 # define sqlite3DropTriggerPtr(A,B)
 # define sqlite3UnlinkAndDeleteTrigger(A,B,C)
-# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I,J,K,L) 0
+# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I,J)
 # define sqlite3TriggerList(X, Y) 0
+# define sqlite3ParseToplevel(p) p
+# define sqlite3TriggerOldmask(A,B,C,D,E,F) 0
 #endif
 
 SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*);
 SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
 SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int);
 #ifndef SQLITE_OMIT_AUTHORIZATION
 SQLITE_PRIVATE   void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*);
 SQLITE_PRIVATE   int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
@@ -10135,17 +10380,17 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 
 **
 */
 #define getVarint32(A,B)  (u8)((*(A)<(u8)0x80) ? ((B) = (u32)*(A)),1 : sqlite3GetVarint32((A), (u32 *)&(B)))
 #define putVarint32(A,B)  (u8)(((u32)(B)<(u32)0x80) ? (*(A) = (unsigned char)(B)),1 : sqlite3PutVarint32((A), (B)))
 #define getVarint    sqlite3GetVarint
 #define putVarint    sqlite3PutVarint
 
 
-SQLITE_PRIVATE void sqlite3IndexAffinityStr(Vdbe *, Index *);
+SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
 SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *, Table *);
 SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2);
 SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
 SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
 SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*);
 SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...);
 SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
 SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
@@ -10161,16 +10406,19 @@ SQLITE_PRIVATE void sqlite3VdbeSetChange
 
 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);
+#ifdef SQLITE_ENABLE_STAT2
+SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *);
+#endif
 SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
 SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
 #ifndef SQLITE_AMALGAMATION
 SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
 SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
 SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config;
 SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
 SQLITE_PRIVATE int sqlite3PendingByte;
@@ -10182,26 +10430,27 @@ SQLITE_PRIVATE void sqlite3AlterRenameTa
 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
 SQLITE_PRIVATE void sqlite3CodeSubselect(Parse *, Expr *, int, int);
 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
 SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
 SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
 SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
-SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int);
+SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
 SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
-SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char*);
+SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*);
 SQLITE_PRIVATE char sqlite3AffinityType(const char*);
 SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
 SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
 SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
 SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
 SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
+SQLITE_PRIVATE void sqlite3DeleteIndexSamples(Index*);
 SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
 SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int);
 SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
 SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
 SQLITE_PRIVATE void sqlite3SchemaFree(void *);
 SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
 SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
 SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
@@ -10243,46 +10492,51 @@ SQLITE_PRIVATE   void sqlite3TableLock(P
   #define sqlite3TableLock(v,w,x,y,z)
 #endif
 
 #ifdef SQLITE_TEST
 SQLITE_PRIVATE   int sqlite3Utf8To8(unsigned char*);
 #endif
 
 #ifdef SQLITE_OMIT_VIRTUALTABLE
-#  define sqlite3VtabClear(X)
+#  define sqlite3VtabClear(Y)
 #  define sqlite3VtabSync(X,Y) SQLITE_OK
 #  define sqlite3VtabRollback(X)
 #  define sqlite3VtabCommit(X)
 #  define sqlite3VtabInSync(db) 0
+#  define sqlite3VtabLock(X) 
+#  define sqlite3VtabUnlock(X)
+#  define sqlite3VtabUnlockList(X)
 #else
 SQLITE_PRIVATE    void sqlite3VtabClear(Table*);
 SQLITE_PRIVATE    int sqlite3VtabSync(sqlite3 *db, char **);
 SQLITE_PRIVATE    int sqlite3VtabRollback(sqlite3 *db);
 SQLITE_PRIVATE    int sqlite3VtabCommit(sqlite3 *db);
+SQLITE_PRIVATE    void sqlite3VtabLock(VTable *);
+SQLITE_PRIVATE    void sqlite3VtabUnlock(VTable *);
+SQLITE_PRIVATE    void sqlite3VtabUnlockList(sqlite3*);
 #  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
 #endif
 SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
-SQLITE_PRIVATE void sqlite3VtabLock(sqlite3_vtab*);
-SQLITE_PRIVATE void sqlite3VtabUnlock(sqlite3*, sqlite3_vtab*);
 SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
 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 *, sqlite3_vtab *);
+SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
 SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
 SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
 SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
 SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
 SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
+SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
 
 
 
 /*
 ** Available fault injectors.  Should be numbered beginning with 0.
 */
 #define SQLITE_FAULTINJECTOR_MALLOC     0
 #define SQLITE_FAULTINJECTOR_COUNT      1
@@ -10370,18 +10624,16 @@ SQLITE_PRIVATE void (*sqlite3IoTrace)(co
 **
 **    May you do good and not evil.
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
 **
 ** This file contains definitions of global variables and contants.
-**
-** $Id: global.c,v 1.12 2009/02/05 16:31:46 drh Exp $
 */
 
 
 /* An array to map all upper-case characters into their corresponding
 ** lower-case character. 
 **
 ** SQLite only considers US-ASCII (or EBCDIC) characters.  We do not
 ** handle case conversions for the UTF character set since the tables
@@ -10511,20 +10763,22 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3
    (void*)0,                  /* pScratch */
    0,                         /* szScratch */
    0,                         /* nScratch */
    (void*)0,                  /* pPage */
    0,                         /* szPage */
    0,                         /* nPage */
    0,                         /* mxParserStack */
    0,                         /* sharedCacheEnabled */
-   /* All the rest need to always be zero */
+   /* All the rest should always be initialized to zero */
    0,                         /* isInit */
    0,                         /* inProgress */
+   0,                         /* isMutexInit */
    0,                         /* isMallocInit */
+   0,                         /* isPCacheInit */
    0,                         /* pInitMutex */
    0,                         /* nRefInitMutex */
 };
 
 
 /*
 ** Hash table for global functions - functions common to all
 ** database connections.  After initialization, this table is
@@ -11120,17 +11374,17 @@ static sqlite3_int64 localtimeOffset(Dat
     x.s = 0.0;
   } else {
     int s = (int)(x.s + 0.5);
     x.s = s;
   }
   x.tz = 0;
   x.validJD = 0;
   computeJD(&x);
-  t = x.iJD/1000 - 21086676*(i64)10000;
+  t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
 #ifdef HAVE_LOCALTIME_R
   {
     struct tm sLocal;
     localtime_r(&t, &sLocal);
     y.Y = sLocal.tm_year + 1900;
     y.M = sLocal.tm_mon + 1;
     y.D = sLocal.tm_mday;
     y.h = sLocal.tm_hour;
@@ -11796,17 +12050,17 @@ SQLITE_PRIVATE void sqlite3RegisterDateT
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 **
 ******************************************************************************
 **
 ** This file contains OS interface code that is common to all
 ** architectures.
 **
-** $Id: os.c,v 1.126 2009/03/25 14:24:42 drh Exp $
+** $Id: os.c,v 1.127 2009/07/27 11:41:21 danielk1977 Exp $
 */
 #define _SQLITE_OS_C_ 1
 #undef _SQLITE_OS_C_
 
 /*
 ** The default SQLite sqlite3_vfs implementations do not allocate
 ** memory (actually, os_unix.c allocates a small amount of memory
 ** from within OsOpen()), but some third-party implementations may.
@@ -11819,23 +12073,23 @@ SQLITE_PRIVATE void sqlite3RegisterDateT
 **     sqlite3OsOpen()
 **     sqlite3OsRead()
 **     sqlite3OsWrite()
 **     sqlite3OsSync()
 **     sqlite3OsLock()
 **
 */
 #if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
-  #define DO_OS_MALLOC_TEST if (1) {            \
-    void *pTstAlloc = sqlite3Malloc(10);       \
-    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;  \
-    sqlite3_free(pTstAlloc);                    \
-  }
-#else
-  #define DO_OS_MALLOC_TEST
+  #define DO_OS_MALLOC_TEST(x) if (!x || !sqlite3IsMemJournal(x)) {     \
+    void *pTstAlloc = sqlite3Malloc(10);                             \
+    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
+    sqlite3_free(pTstAlloc);                                         \
+  }
+#else
+  #define DO_OS_MALLOC_TEST(x)
 #endif
 
 /*
 ** The following routines are convenience wrappers around methods
 ** of the sqlite3_file object.  This is mostly just syntactic sugar. All
 ** of this would be completely automatic if SQLite were coded using
 ** C++ instead of plain old C.
 */
@@ -11843,43 +12097,43 @@ SQLITE_PRIVATE int sqlite3OsClose(sqlite
   int rc = SQLITE_OK;
   if( pId->pMethods ){
     rc = pId->pMethods->xClose(pId);
     pId->pMethods = 0;
   }
   return rc;
 }
 SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
-  DO_OS_MALLOC_TEST;
+  DO_OS_MALLOC_TEST(id);
   return id->pMethods->xRead(id, pBuf, amt, offset);
 }
 SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
-  DO_OS_MALLOC_TEST;
+  DO_OS_MALLOC_TEST(id);
   return id->pMethods->xWrite(id, pBuf, amt, offset);
 }
 SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){
   return id->pMethods->xTruncate(id, size);
 }
 SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){
-  DO_OS_MALLOC_TEST;
+  DO_OS_MALLOC_TEST(id);
   return id->pMethods->xSync(id, flags);
 }
 SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
-  DO_OS_MALLOC_TEST;
+  DO_OS_MALLOC_TEST(id);
   return id->pMethods->xFileSize(id, pSize);
 }
 SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){
-  DO_OS_MALLOC_TEST;
+  DO_OS_MALLOC_TEST(id);
   return id->pMethods->xLock(id, lockType);
 }
 SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){
   return id->pMethods->xUnlock(id, lockType);
 }
 SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
-  DO_OS_MALLOC_TEST;
+  DO_OS_MALLOC_TEST(id);
   return id->pMethods->xCheckReservedLock(id, pResOut);
 }
 SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
   return id->pMethods->xFileControl(id, op, pArg);
 }
 SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
   int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
   return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
@@ -11895,31 +12149,35 @@ SQLITE_PRIVATE int sqlite3OsDeviceCharac
 SQLITE_PRIVATE int sqlite3OsOpen(
   sqlite3_vfs *pVfs, 
   const char *zPath, 
   sqlite3_file *pFile, 
   int flags, 
   int *pFlagsOut
 ){
   int rc;
-  DO_OS_MALLOC_TEST;
-  rc = pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
+  DO_OS_MALLOC_TEST(0);
+  /* 0x7f1f is a mask of SQLITE_OPEN_ flags that are valid to be passed
+  ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
+  ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
+  ** reaching the VFS. */
+  rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x7f1f, pFlagsOut);
   assert( rc==SQLITE_OK || pFile->pMethods==0 );
   return rc;
 }
 SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   return pVfs->xDelete(pVfs, zPath, dirSync);
 }
 SQLITE_PRIVATE int sqlite3OsAccess(
   sqlite3_vfs *pVfs, 
   const char *zPath, 
   int flags, 
   int *pResOut
 ){
-  DO_OS_MALLOC_TEST;
+  DO_OS_MALLOC_TEST(0);
   return pVfs->xAccess(pVfs, zPath, flags, pResOut);
 }
 SQLITE_PRIVATE int sqlite3OsFullPathname(
   sqlite3_vfs *pVfs, 
   const char *zPath, 
   int nPathOut, 
   char *zPathOut
 ){
@@ -11973,16 +12231,29 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sq
   int rc = SQLITE_OK;
   assert( pFile );
   rc = sqlite3OsClose(pFile);
   sqlite3_free(pFile);
   return rc;
 }
 
 /*
+** This function is a wrapper around the OS specific implementation of
+** sqlite3_os_init(). The purpose of the wrapper is to provide the
+** ability to simulate a malloc failure, so that the handling of an
+** error in sqlite3_os_init() by the upper layers can be tested.
+*/
+SQLITE_PRIVATE int sqlite3OsInit(void){
+  void *p = sqlite3_malloc(10);
+  if( p==0 ) return SQLITE_NOMEM;
+  sqlite3_free(p);
+  return sqlite3_os_init();
+}
+
+/*
 ** The list of all registered VFS implementations.
 */
 static sqlite3_vfs * SQLITE_WSD vfsList = 0;
 #define vfsList GLOBAL(sqlite3_vfs *, vfsList)
 
 /*
 ** Locate a VFS by name.  If no name is given, simply return the
 ** first VFS on the list.
@@ -13517,72 +13788,98 @@ SQLITE_PRIVATE const sqlite3_mem_methods
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
 ** This file contains the C functions that implement a memory
 ** allocation subsystem for use by SQLite. 
 **
 ** This version of the memory allocation subsystem omits all
-** use of malloc(). The SQLite user supplies a block of memory
+** use of malloc(). The application gives SQLite a block of memory
 ** before calling sqlite3_initialize() from which allocations
 ** are made and returned by the xMalloc() and xRealloc() 
 ** implementations. Once sqlite3_initialize() has been called,
 ** the amount of memory available to SQLite is fixed and cannot
 ** be changed.
 **
 ** This version of the memory allocation subsystem is included
 ** in the build only if SQLITE_ENABLE_MEMSYS5 is defined.
 **
-** $Id: mem5.c,v 1.19 2008/11/19 16:52:44 danielk1977 Exp $
+** This memory allocator uses the following algorithm:
+**
+**   1.  All memory allocations sizes are rounded up to a power of 2.
+**
+**   2.  If two adjacent free blocks are the halves of a larger block,
+**       then the two blocks are coalesed into the single larger block.
+**
+**   3.  New memory is allocated from the first available free block.
+**
+** This algorithm is described in: J. M. Robson. "Bounds for Some Functions
+** Concerning Dynamic Storage Allocation". Journal of the Association for
+** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499.
+** 
+** Let n be the size of the largest allocation divided by the minimum
+** allocation size (after rounding all sizes up to a power of 2.)  Let M
+** be the maximum amount of memory ever outstanding at one time.  Let
+** N be the total amount of memory available for allocation.  Robson
+** proved that this memory allocator will never breakdown due to 
+** fragmentation as long as the following constraint holds:
+**
+**      N >=  M*(1 + log2(n)/2) - n + 1
+**
+** The sqlite3_status() logic tracks the maximum values of n and M so
+** that an application can, at any time, verify this constraint.
 */
 
 /*
 ** This version of the memory allocator is used only when 
 ** SQLITE_ENABLE_MEMSYS5 is defined.
 */
 #ifdef SQLITE_ENABLE_MEMSYS5
 
 /*
 ** A minimum allocation is an instance of the following structure.
 ** Larger allocations are an array of these structures where the
 ** size of the array is a power of 2.
+**
+** The size of this object must be a power of two.  That fact is
+** verified in memsys5Init().
 */
 typedef struct Mem5Link Mem5Link;
 struct Mem5Link {
   int next;       /* Index of next free chunk */
   int prev;       /* Index of previous free chunk */
 };
 
 /*
-** Maximum size of any allocation is ((1<<LOGMAX)*mem5.nAtom). Since
-** mem5.nAtom is always at least 8, this is not really a practical
-** limitation.
+** Maximum size of any allocation is ((1<<LOGMAX)*mem5.szAtom). Since
+** mem5.szAtom is always at least 8 and 32-bit integers are used,
+** it is not actually possible to reach this limit.
 */
 #define LOGMAX 30
 
 /*
 ** Masks used for mem5.aCtrl[] elements.
 */
-#define CTRL_LOGSIZE  0x1f    /* Log2 Size of this block relative to POW2_MIN */
+#define CTRL_LOGSIZE  0x1f    /* Log2 Size of this block */
 #define CTRL_FREE     0x20    /* True if not checked out */
 
 /*
 ** All of the static variables used by this module are collected
 ** into a single structure named "mem5".  This is to keep the
 ** static variables organized and to reduce namespace pollution
 ** when this module is combined with other in the amalgamation.
 */
 static SQLITE_WSD struct Mem5Global {
   /*
   ** Memory available for allocation
   */
-  int nAtom;       /* Smallest possible allocation in bytes */
-  int nBlock;      /* Number of nAtom sized blocks in zPool */
-  u8 *zPool;
+  int szAtom;      /* Smallest possible allocation in bytes */
+  int nBlock;      /* Number of szAtom sized blocks in zPool */
+  u8 *zPool;       /* Memory available to be allocated */
   
   /*
   ** Mutex to control access to the memory allocation subsystem.
   */
   sqlite3_mutex *mutex;
 
   /*
   ** Performance statistics
@@ -13592,31 +13889,40 @@ static SQLITE_WSD struct Mem5Global {
   u64 totalExcess;    /* Total internal fragmentation */
   u32 currentOut;     /* Current checkout, including internal fragmentation */
   u32 currentCount;   /* Current number of distinct checkouts */
   u32 maxOut;         /* Maximum instantaneous currentOut */
   u32 maxCount;       /* Maximum instantaneous currentCount */
   u32 maxRequest;     /* Largest allocation (exclusive of internal frag) */
   
   /*
-  ** Lists of free blocks of various sizes.
+  ** Lists of free blocks.  aiFreelist[0] is a list of free blocks of
+  ** size mem5.szAtom.  aiFreelist[1] holds blocks of size szAtom*2.
+  ** and so forth.
   */
   int aiFreelist[LOGMAX+1];
 
   /*
   ** Space for tracking which blocks are checked out and the size
   ** of each block.  One byte per block.
   */
   u8 *aCtrl;
 
-} mem5 = { 19804167 };
-
+} mem5 = { 0 };
+
+/*
+** Access the static variable through a macro for SQLITE_OMIT_WSD
+*/
 #define mem5 GLOBAL(struct Mem5Global, mem5)
 
-#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.nAtom]))
+/*
+** Assuming mem5.zPool is divided up into an array of Mem5Link
+** structures, return a pointer to the idx-th such lik.
+*/
+#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))
 
 /*
 ** Unlink the chunk at mem5.aPool[i] from list it is currently
 ** on.  It should be found on mem5.aiFreelist[iLogsize].
 */
 static void memsys5Unlink(int i, int iLogsize){
   int next, prev;
   assert( i>=0 && i<mem5.nBlock );
@@ -13656,36 +13962,33 @@ static void memsys5Link(int i, int iLogs
 }
 
 /*
 ** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
 ** will already be held (obtained by code in malloc.c) if
 ** sqlite3GlobalConfig.bMemStat is true.
 */
 static void memsys5Enter(void){
-  if( sqlite3GlobalConfig.bMemstat==0 && mem5.mutex==0 ){
-    mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
-  }
   sqlite3_mutex_enter(mem5.mutex);
 }
 static void memsys5Leave(void){
   sqlite3_mutex_leave(mem5.mutex);
 }
 
 /*
 ** Return the size of an outstanding allocation, in bytes.  The
 ** size returned omits the 8-byte header overhead.  This only
 ** works for chunks that are currently checked out.
 */
 static int memsys5Size(void *p){
   int iSize = 0;
   if( p ){
-    int i = ((u8 *)p-mem5.zPool)/mem5.nAtom;
+    int i = ((u8 *)p-mem5.zPool)/mem5.szAtom;
     assert( i>=0 && i<mem5.nBlock );
-    iSize = mem5.nAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
+    iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
   }
   return iSize;
 }
 
 /*
 ** Find the first entry on the freelist iLogsize.  Unlink that
 ** entry and return its index. 
 */
@@ -13701,32 +14004,48 @@ static int memsys5UnlinkFirst(int iLogsi
     i = MEM5LINK(i)->next;
   }
   memsys5Unlink(iFirst, iLogsize);
   return iFirst;
 }
 
 /*
 ** Return a block of memory of at least nBytes in size.
-** Return NULL if unable.
+** Return NULL if unable.  Return NULL if nBytes==0.
+**
+** The caller guarantees that nByte positive.
+**
+** The caller has obtained a mutex prior to invoking this
+** routine so there is never any chance that two or more
+** threads can be in this routine at the same time.
 */
 static void *memsys5MallocUnsafe(int nByte){
   int i;           /* Index of a mem5.aPool[] slot */
   int iBin;        /* Index into mem5.aiFreelist[] */
   int iFullSz;     /* Size of allocation rounded up to power of 2 */
   int iLogsize;    /* Log2 of iFullSz/POW2_MIN */
 
+  /* nByte must be a positive */
+  assert( nByte>0 );
+
   /* Keep track of the maximum allocation request.  Even unfulfilled
   ** requests are counted */
   if( (u32)nByte>mem5.maxRequest ){
     mem5.maxRequest = nByte;
   }
 
+  /* Abort if the requested allocation size is larger than the largest
+  ** power of two that we can represent using 32-bit signed integers.
+  */
+  if( nByte > 0x40000000 ){
+    return 0;
+  }
+
   /* Round nByte up to the next valid power of two */
-  for(iFullSz=mem5.nAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}
+  for(iFullSz=mem5.szAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}
 
   /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
   ** block.  If not, then split a block of the next larger power of
   ** two in order to create a new free block of size iLogsize.
   */
   for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
   if( iBin>LOGMAX ) return 0;
   i = memsys5UnlinkFirst(iBin);
@@ -13745,51 +14064,51 @@ static void *memsys5MallocUnsafe(int nBy
   mem5.totalAlloc += iFullSz;
   mem5.totalExcess += iFullSz - nByte;
   mem5.currentCount++;
   mem5.currentOut += iFullSz;
   if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
   if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
 
   /* Return a pointer to the allocated memory. */
-  return (void*)&mem5.zPool[i*mem5.nAtom];
+  return (void*)&mem5.zPool[i*mem5.szAtom];
 }
 
 /*
 ** Free an outstanding memory allocation.
 */
 static void memsys5FreeUnsafe(void *pOld){
   u32 size, iLogsize;
-  int iBlock;             
+  int iBlock;
 
   /* Set iBlock to the index of the block pointed to by pOld in 
-  ** the array of mem5.nAtom byte blocks pointed to by mem5.zPool.
-  */
-  iBlock = ((u8 *)pOld-mem5.zPool)/mem5.nAtom;
+  ** the array of mem5.szAtom byte blocks pointed to by mem5.zPool.
+  */
+  iBlock = ((u8 *)pOld-mem5.zPool)/mem5.szAtom;
 
   /* Check that the pointer pOld points to a valid, non-free block. */
   assert( iBlock>=0 && iBlock<mem5.nBlock );
-  assert( ((u8 *)pOld-mem5.zPool)%mem5.nAtom==0 );
+  assert( ((u8 *)pOld-mem5.zPool)%mem5.szAtom==0 );
   assert( (mem5.aCtrl[iBlock] & CTRL_FREE)==0 );
 
   iLogsize = mem5.aCtrl[iBlock] & CTRL_LOGSIZE;
   size = 1<<iLogsize;
   assert( iBlock+size-1<(u32)mem5.nBlock );
 
   mem5.aCtrl[iBlock] |= CTRL_FREE;
   mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
   assert( mem5.currentCount>0 );
-  assert( mem5.currentOut>=(size*mem5.nAtom) );
+  assert( mem5.currentOut>=(size*mem5.szAtom) );
   mem5.currentCount--;
-  mem5.currentOut -= size*mem5.nAtom;
+  mem5.currentOut -= size*mem5.szAtom;
   assert( mem5.currentOut>0 || mem5.currentCount==0 );
   assert( mem5.currentCount>0 || mem5.currentOut==0 );
 
   mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
-  while( iLogsize<LOGMAX ){
+  while( ALWAYS(iLogsize<LOGMAX) ){
     int iBuddy;
     if( (iBlock>>iLogsize) & 1 ){
       iBuddy = iBlock - size;
     }else{
       iBuddy = iBlock + size;
     }
     assert( iBuddy>=0 );
     if( (iBuddy+(1<<iLogsize))>mem5.nBlock ) break;
@@ -13819,38 +14138,46 @@ static void *memsys5Malloc(int nBytes){
     p = memsys5MallocUnsafe(nBytes);
     memsys5Leave();
   }
   return (void*)p; 
 }
 
 /*
 ** Free memory.
+**
+** The outer layer memory allocator prevents this routine from
+** being called with pPrior==0.
 */
 static void memsys5Free(void *pPrior){
-  if( pPrior==0 ){
-assert(0);
-    return;
-  }
+  assert( pPrior!=0 );
   memsys5Enter();
   memsys5FreeUnsafe(pPrior);
   memsys5Leave();  
 }
 
 /*
-** Change the size of an existing memory allocation
+** Change the size of an existing memory allocation.
+**
+** The outer layer memory allocator prevents this routine from
+** being called with pPrior==0.  
+**
+** nBytes is always a value obtained from a prior call to
+** memsys5Round().  Hence nBytes is always a non-negative power
+** of two.  If nBytes==0 that means that an oversize allocation
+** (an allocation larger than 0x40000000) was requested and this
+** routine should return 0 without freeing pPrior.
 */
 static void *memsys5Realloc(void *pPrior, int nBytes){
   int nOld;
   void *p;
-  if( pPrior==0 ){
-    return memsys5Malloc(nBytes);
-  }
-  if( nBytes<=0 ){
-    memsys5Free(pPrior);
+  assert( pPrior!=0 );
+  assert( (nBytes&(nBytes-1))==0 );
+  assert( nBytes>=0 );
+  if( nBytes==0 ){
     return 0;
   }
   nOld = memsys5Size(pPrior);
   if( nBytes<=nOld ){
     return pPrior;
   }
   memsys5Enter();
   p = memsys5MallocUnsafe(nBytes);
@@ -13858,126 +14185,158 @@ static void *memsys5Realloc(void *pPrior
     memcpy(p, pPrior, nOld);
     memsys5FreeUnsafe(pPrior);
   }
   memsys5Leave();
   return p;
 }
 
 /*
-** Round up a request size to the next valid allocation size.
+** Round up a request size to the next valid allocation size.  If
+** the allocation is too large to be handled by this allocation system,
+** return 0.
+**
+** All allocations must be a power of two and must be expressed by a
+** 32-bit signed integer.  Hence the largest allocation is 0x40000000
+** or 1073741824 bytes.
 */
 static int memsys5Roundup(int n){
   int iFullSz;
-  for(iFullSz=mem5.nAtom; iFullSz<n; iFullSz *= 2);
+  if( n > 0x40000000 ) return 0;
+  for(iFullSz=mem5.szAtom; iFullSz<n; iFullSz *= 2);
   return iFullSz;
 }
 
+/*
+** Return the ceiling of the logarithm base 2 of iValue.
+**
+** Examples:   memsys5Log(1) -> 0
+**             memsys5Log(2) -> 1
+**             memsys5Log(4) -> 2
+**             memsys5Log(5) -> 3
+**             memsys5Log(8) -> 3
+**             memsys5Log(9) -> 4
+*/
 static int memsys5Log(int iValue){
   int iLog;
   for(iLog=0; (1<<iLog)<iValue; iLog++);
   return iLog;
 }
 
 /*
-** Initialize this module.
+** Initialize the memory allocator.
+**
+** This routine is not threadsafe.  The caller must be holding a mutex
+** to prevent multiple threads from entering at the same time.
 */
 static int memsys5Init(void *NotUsed){
-  int ii;
-  int nByte = sqlite3GlobalConfig.nHeap;
-  u8 *zByte = (u8 *)sqlite3GlobalConfig.pHeap;
-  int nMinLog;                 /* Log of minimum allocation size in bytes*/
-  int iOffset;
+  int ii;            /* Loop counter */
+  int nByte;         /* Number of bytes of memory available to this allocator */
+  u8 *zByte;         /* Memory usable by this allocator */
+  int nMinLog;       /* Log base 2 of minimum allocation size in bytes */
+  int iOffset;       /* An offset into mem5.aCtrl[] */
 
   UNUSED_PARAMETER(NotUsed);
 
-  if( !zByte ){
-    return SQLITE_ERROR;
-  }
+  /* For the purposes of this routine, disable the mutex */
+  mem5.mutex = 0;
+
+  /* The size of a Mem5Link object must be a power of two.  Verify that
+  ** this is case.
+  */
+  assert( (sizeof(Mem5Link)&(sizeof(Mem5Link)-1))==0 );
+
+  nByte = sqlite3GlobalConfig.nHeap;
+  zByte = (u8*)sqlite3GlobalConfig.pHeap;
+  assert( zByte!=0 );  /* sqlite3_config() does not allow otherwise */
 
   nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq);
-  mem5.nAtom = (1<<nMinLog);
-  while( (int)sizeof(Mem5Link)>mem5.nAtom ){
-    mem5.nAtom = mem5.nAtom << 1;
-  }
-
-  mem5.nBlock = (nByte / (mem5.nAtom+sizeof(u8)));
+  mem5.szAtom = (1<<nMinLog);
+  while( (int)sizeof(Mem5Link)>mem5.szAtom ){
+    mem5.szAtom = mem5.szAtom << 1;
+  }
+
+  mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8)));
   mem5.zPool = zByte;
-  mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.nAtom];
+  mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom];
 
   for(ii=0; ii<=LOGMAX; ii++){
     mem5.aiFreelist[ii] = -1;
   }
 
   iOffset = 0;
   for(ii=LOGMAX; ii>=0; ii--){
     int nAlloc = (1<<ii);
     if( (iOffset+nAlloc)<=mem5.nBlock ){
       mem5.aCtrl[iOffset] = ii | CTRL_FREE;
       memsys5Link(iOffset, ii);
       iOffset += nAlloc;
     }
     assert((iOffset+nAlloc)>mem5.nBlock);
   }
 
+  /* If a mutex is required for normal operation, allocate one */
+  if( sqlite3GlobalConfig.bMemstat==0 ){
+    mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
+  }
+
   return SQLITE_OK;
 }
 
 /*
 ** Deinitialize this module.
 */
 static void memsys5Shutdown(void *NotUsed){
   UNUSED_PARAMETER(NotUsed);
+  mem5.mutex = 0;
   return;
 }
 
+#ifdef SQLITE_TEST
 /*
 ** Open the file indicated and write a log of all unfreed memory 
 ** allocations into that log.
 */
 SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){
-#ifdef SQLITE_DEBUG
   FILE *out;
   int i, j, n;
   int nMinLog;
 
   if( zFilename==0 || zFilename[0]==0 ){
     out = stdout;
   }else{
     out = fopen(zFilename, "w");
     if( out==0 ){
       fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
                       zFilename);
       return;
     }
   }
   memsys5Enter();
-  nMinLog = memsys5Log(mem5.nAtom);
+  nMinLog = memsys5Log(mem5.szAtom);
   for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
     for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
-    fprintf(out, "freelist items of size %d: %d\n", mem5.nAtom << i, n);
+    fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n);
   }
   fprintf(out, "mem5.nAlloc       = %llu\n", mem5.nAlloc);
   fprintf(out, "mem5.totalAlloc   = %llu\n", mem5.totalAlloc);
   fprintf(out, "mem5.totalExcess  = %llu\n", mem5.totalExcess);
   fprintf(out, "mem5.currentOut   = %u\n", mem5.currentOut);
   fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount);
   fprintf(out, "mem5.maxOut       = %u\n", mem5.maxOut);
   fprintf(out, "mem5.maxCount     = %u\n", mem5.maxCount);
   fprintf(out, "mem5.maxRequest   = %u\n", mem5.maxRequest);
   memsys5Leave();
   if( out==stdout ){
     fflush(stdout);
   }else{
     fclose(out);
   }
-#else
-  UNUSED_PARAMETER(zFilename);
-#endif
-}
+}
+#endif
 
 /*
 ** This routine is the only routine in this file with external 
 ** linkage. It returns a pointer to a static sqlite3_mem_methods
 ** struct populated with the memsys5 methods.
 */
 SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){
   static const sqlite3_mem_methods memsys5Methods = {
@@ -14008,71 +14367,74 @@ SQLITE_PRIVATE const sqlite3_mem_methods
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
 ** This file contains the C functions that implement mutexes.
 **
 ** This file contains code that is common across all mutex implementations.
 
 **
-** $Id: mutex.c,v 1.30 2009/02/17 16:29:11 danielk1977 Exp $
-*/
+** $Id: mutex.c,v 1.31 2009/07/16 18:21:18 drh Exp $
+*/
+
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
+/*
+** For debugging purposes, record when the mutex subsystem is initialized
+** and uninitialized so that we can assert() if there is an attempt to
+** allocate a mutex while the system is uninitialized.
+*/
+static SQLITE_WSD int mutexIsInit = 0;
+#endif /* SQLITE_DEBUG */
+
 
 #ifndef SQLITE_MUTEX_OMIT
 /*
 ** Initialize the mutex system.
 */
 SQLITE_PRIVATE int sqlite3MutexInit(void){ 
   int rc = SQLITE_OK;
   if( sqlite3GlobalConfig.bCoreMutex ){
     if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
       /* If the xMutexAlloc method has not been set, then the user did not
       ** install a mutex implementation via sqlite3_config() prior to 
       ** sqlite3_initialize() being called. This block copies pointers to
       ** the default implementation into the sqlite3GlobalConfig structure.
-      **
-      ** The danger is that although sqlite3_config() is not a threadsafe
-      ** API, sqlite3_initialize() is, and so multiple threads may be
-      ** attempting to run this function simultaneously. To guard write
-      ** access to the sqlite3GlobalConfig structure, the 'MASTER' static mutex
-      ** is obtained before modifying it.
-      */
-      sqlite3_mutex_methods *p = sqlite3DefaultMutex();
-      sqlite3_mutex *pMaster = 0;
-  
-      rc = p->xMutexInit();
-      if( rc==SQLITE_OK ){
-        pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-        assert(pMaster);
-        p->xMutexEnter(pMaster);
-        assert( sqlite3GlobalConfig.mutex.xMutexAlloc==0 
-             || sqlite3GlobalConfig.mutex.xMutexAlloc==p->xMutexAlloc
-        );
-        if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
-          sqlite3GlobalConfig.mutex = *p;
-        }
-        p->xMutexLeave(pMaster);
-      }
-    }else{
-      rc = sqlite3GlobalConfig.mutex.xMutexInit();
-    }
-  }
+      */
+      sqlite3_mutex_methods *pFrom = sqlite3DefaultMutex();
+      sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
+
+      memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
+      memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
+             sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
+      pTo->xMutexAlloc = pFrom->xMutexAlloc;
+    }
+    rc = sqlite3GlobalConfig.mutex.xMutexInit();
+  }
+
+#ifdef SQLITE_DEBUG
+  GLOBAL(int, mutexIsInit) = 1;
+#endif
 
   return rc;
 }
 
 /*
 ** Shutdown the mutex system. This call frees resources allocated by
 ** sqlite3MutexInit().
 */
 SQLITE_PRIVATE int sqlite3MutexEnd(void){
   int rc = SQLITE_OK;
   if( sqlite3GlobalConfig.mutex.xMutexEnd ){
     rc = sqlite3GlobalConfig.mutex.xMutexEnd();
   }
+
+#ifdef SQLITE_DEBUG
+  GLOBAL(int, mutexIsInit) = 0;
+#endif
+
   return rc;
 }
 
 /*
 ** Retrieve a pointer to a static mutex or allocate a new dynamic one.
 */
 SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
 #ifndef SQLITE_OMIT_AUTOINIT
@@ -14080,16 +14442,17 @@ SQLITE_API sqlite3_mutex *sqlite3_mutex_
 #endif
   return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
 }
 
 SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
   if( !sqlite3GlobalConfig.bCoreMutex ){
     return 0;
   }
+  assert( GLOBAL(int, mutexIsInit) );
   return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
 }
 
 /*
 ** Free a dynamic mutex.
 */
 SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
   if( p ){
@@ -14698,30 +15061,31 @@ static int pthreadMutexEnd(void){ return
 ** <ul>
 ** <li>  SQLITE_MUTEX_FAST
 ** <li>  SQLITE_MUTEX_RECURSIVE
 ** <li>  SQLITE_MUTEX_STATIC_MASTER
 ** <li>  SQLITE_MUTEX_STATIC_MEM
 ** <li>  SQLITE_MUTEX_STATIC_MEM2
 ** <li>  SQLITE_MUTEX_STATIC_PRNG
 ** <li>  SQLITE_MUTEX_STATIC_LRU
+** <li>  SQLITE_MUTEX_STATIC_LRU2
 ** </ul>
 **
 ** The first two constants cause sqlite3_mutex_alloc() to create
 ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
 ** The mutex implementation does not need to make a distinction
 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
 ** not want to.  But SQLite will only request a recursive mutex in
 ** cases where it really needs one.  If a faster non-recursive mutex
 ** implementation is available on the host platform, the mutex subsystem
 ** might return such a mutex in response to SQLITE_MUTEX_FAST.
 **
 ** The other allowed parameters to sqlite3_mutex_alloc() each return
-** a pointer to a static preexisting mutex.  Three static mutexes are
+** a pointer to a static preexisting mutex.  Six static mutexes are
 ** used by the current version of SQLite.  Future versions of SQLite
 ** may add additional static mutexes.  Static mutexes are for internal
 ** use by SQLite only.  Applications that use SQLite mutexes should
 ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
 ** SQLITE_MUTEX_RECURSIVE.
 **
 ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
@@ -14949,17 +15313,17 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sq
 **
 **    May you do good and not evil.
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
 ** This file contains the C functions that implement mutexes for win32
 **
-** $Id: mutex_w32.c,v 1.17 2009/06/01 17:10:22 shane Exp $
+** $Id: mutex_w32.c,v 1.18 2009/08/10 03:23:21 shane Exp $
 */
 
 /*
 ** The code in this file is only used if we are compiling multithreaded
 ** on a win32 system.
 */
 #ifdef SQLITE_MUTEX_W32
 
@@ -15030,72 +15394,76 @@ static int winMutex_isInit = 0;
 ** of the sqlite3_initialize and sqlite3_shutdown()
 ** processing, the "interlocked" magic is probably not
 ** strictly necessary.
 */
 static long winMutex_lock = 0;
 
 static int winMutexInit(void){ 
   /* The first to increment to 1 does actual initialization */
-  if( InterlockedIncrement(&winMutex_lock)==1 ){
+  if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
     int i;
-    for(i=0; i<sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]); i++){
+    for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
       InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
     }
     winMutex_isInit = 1;
   }else{
+    /* Someone else is in the process of initing the static mutexes */
     while( !winMutex_isInit ){
       Sleep(1);
     }
   }
   return SQLITE_OK; 
 }
 
 static int winMutexEnd(void){ 
   /* The first to decrement to 0 does actual shutdown 
   ** (which should be the last to shutdown.) */
-  if( InterlockedDecrement(&winMutex_lock)==0 ){
+  if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
     if( winMutex_isInit==1 ){
       int i;
-      for(i=0; i<sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]); i++){
+      for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
         DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
       }
       winMutex_isInit = 0;
     }
   }
   return SQLITE_OK; 
 }
 
 /*
 ** The sqlite3_mutex_alloc() routine allocates a new
 ** mutex and returns a pointer to it.  If it returns NULL
 ** that means that a mutex could not be allocated.  SQLite
 ** will unwind its stack and return an error.  The argument
 ** to sqlite3_mutex_alloc() is one of these integer constants:
 **
 ** <ul>
-** <li>  SQLITE_MUTEX_FAST               0
-** <li>  SQLITE_MUTEX_RECURSIVE          1
-** <li>  SQLITE_MUTEX_STATIC_MASTER      2
-** <li>  SQLITE_MUTEX_STATIC_MEM         3
-** <li>  SQLITE_MUTEX_STATIC_PRNG        4
+** <li>  SQLITE_MUTEX_FAST
+** <li>  SQLITE_MUTEX_RECURSIVE
+** <li>  SQLITE_MUTEX_STATIC_MASTER
+** <li>  SQLITE_MUTEX_STATIC_MEM
+** <li>  SQLITE_MUTEX_STATIC_MEM2
+** <li>  SQLITE_MUTEX_STATIC_PRNG
+** <li>  SQLITE_MUTEX_STATIC_LRU
+** <li>  SQLITE_MUTEX_STATIC_LRU2
 ** </ul>
 **
 ** The first two constants cause sqlite3_mutex_alloc() to create
 ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
 ** The mutex implementation does not need to make a distinction
 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
 ** not want to.  But SQLite will only request a recursive mutex in
 ** cases where it really needs one.  If a faster non-recursive mutex
 ** implementation is available on the host platform, the mutex subsystem
 ** might return such a mutex in response to SQLITE_MUTEX_FAST.
 **
 ** The other allowed parameters to sqlite3_mutex_alloc() each return
-** a pointer to a static preexisting mutex.  Three static mutexes are
+** a pointer to a static preexisting mutex.  Six static mutexes are
 ** used by the current version of SQLite.  Future versions of SQLite
 ** may add additional static mutexes.  Static mutexes are for internal
 ** use by SQLite only.  Applications that use SQLite mutexes should
 ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
 ** SQLITE_MUTEX_RECURSIVE.
 **
 ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
@@ -15114,17 +15482,17 @@ static sqlite3_mutex *winMutexAlloc(int 
         p->id = iType;
         InitializeCriticalSection(&p->mutex);
       }
       break;
     }
     default: {
       assert( winMutex_isInit==1 );
       assert( iType-2 >= 0 );
-      assert( iType-2 < sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]) );
+      assert( iType-2 < ArraySize(winMutex_staticMutexes) );
       p = &winMutex_staticMutexes[iType-2];
       p->id = iType;
       break;
     }
   }
   return p;
 }
 
@@ -15232,17 +15600,17 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sq
 **    May you do good and not evil.
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
 **
 ** Memory allocation functions used throughout sqlite.
 **
-** $Id: malloc.c,v 1.64 2009/06/27 00:48:33 drh Exp $
+** $Id: malloc.c,v 1.66 2009/07/17 11:44:07 drh Exp $
 */
 
 /*
 ** This routine runs when the memory allocator sees that the
 ** total memory allocation is about to exceed the soft heap
 ** limit.
 */
 static void softHeapLimitEnforcer(
@@ -15261,17 +15629,19 @@ static void softHeapLimitEnforcer(
 SQLITE_API void sqlite3_soft_heap_limit(int n){
   sqlite3_uint64 iLimit;
   int overage;
   if( n<0 ){
     iLimit = 0;
   }else{
     iLimit = n;
   }
+#ifndef SQLITE_OMIT_AUTOINIT
   sqlite3_initialize();
+#endif
   if( iLimit>0 ){
     sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, iLimit);
   }else{
     sqlite3MemoryAlarm(0, 0, 0);
   }
   overage = (int)(sqlite3_memory_used() - (i64)n);
   if( overage>0 ){
     sqlite3_release_memory(overage);
@@ -15306,32 +15676,30 @@ static SQLITE_WSD struct Mem0Global {
   u32 nPageFree;
 
   sqlite3_mutex *mutex;         /* Mutex to serialize access */
 
   /*
   ** The alarm callback and its arguments.  The mem0.mutex lock will
   ** be held while the callback is running.  Recursive calls into
   ** the memory subsystem are allowed, but no new callbacks will be
-  ** issued.  The alarmBusy variable is set to prevent recursive
-  ** callbacks.
+  ** issued.
   */
   sqlite3_int64 alarmThreshold;
   void (*alarmCallback)(void*, sqlite3_int64,int);
   void *alarmArg;
-  int alarmBusy;
 
   /*
   ** Pointers to the end of sqlite3GlobalConfig.pScratch and
   ** sqlite3GlobalConfig.pPage to a block of memory that records
   ** which pages are available.
   */
   u32 *aScratchFree;
   u32 *aPageFree;
-} mem0 = { 62560955, 0, 0, 0, 0, 0, 0, 0, 0 };
+} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
 #define mem0 GLOBAL(struct Mem0Global, mem0)
 
 /*
 ** Initialize the memory allocation subsystem.
 */
 SQLITE_PRIVATE int sqlite3MallocInit(void){
   if( sqlite3GlobalConfig.m.xMalloc==0 ){
@@ -15438,25 +15806,26 @@ SQLITE_API int sqlite3_memory_alarm(
 
 /*
 ** Trigger the alarm 
 */
 static void sqlite3MallocAlarm(int nByte){
   void (*xCallback)(void*,sqlite3_int64,int);
   sqlite3_int64 nowUsed;
   void *pArg;
-  if( mem0.alarmCallback==0 || mem0.alarmBusy  ) return;
-  mem0.alarmBusy = 1;
+  if( mem0.alarmCallback==0 ) return;
   xCallback = mem0.alarmCallback;
   nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
   pArg = mem0.alarmArg;
+  mem0.alarmCallback = 0;
   sqlite3_mutex_leave(mem0.mutex);
   xCallback(pArg, nowUsed, nByte);
   sqlite3_mutex_enter(mem0.mutex);
-  mem0.alarmBusy = 0;
+  mem0.alarmCallback = xCallback;
+  mem0.alarmArg = pArg;
 }
 
 /*
 ** Do a memory allocation with statistics and alarms.  Assume the
 ** lock is already held.
 */
 static int mallocWithAlarm(int n, void **pp){
   int nFull;
@@ -15642,19 +16011,17 @@ static int isLookaside(sqlite3 *db, void
 ** Return the size of a memory allocation previously obtained from
 ** sqlite3Malloc() or sqlite3_malloc().
 */
 SQLITE_PRIVATE int sqlite3MallocSize(void *p){
   return sqlite3GlobalConfig.m.xSize(p);
 }
 SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
   assert( db==0 || sqlite3_mutex_held(db->mutex) );
-  if( p==0 ){
-    return 0;
-  }else if( isLookaside(db, p) ){
+  if( isLookaside(db, p) ){
     return db->lookaside.sz;
   }else{
     return sqlite3GlobalConfig.m.xSize(p);
   }
 }
 
 /*
 ** Free memory previously obtained from sqlite3Malloc().
@@ -15700,40 +16067,38 @@ SQLITE_PRIVATE void *sqlite3Realloc(void
     sqlite3_free(pOld);
     return 0;
   }
   if( nBytes>=0x7fffff00 ){
     /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
     return 0;
   }
   nOld = sqlite3MallocSize(pOld);
-  if( sqlite3GlobalConfig.bMemstat ){
+  nNew = sqlite3GlobalConfig.m.xRoundup(nBytes);
+  if( nOld==nNew ){
+    pNew = pOld;
+  }else if( sqlite3GlobalConfig.bMemstat ){
     sqlite3_mutex_enter(mem0.mutex);
     sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
-    nNew = sqlite3GlobalConfig.m.xRoundup(nBytes);
-    if( nOld==nNew ){
-      pNew = pOld;
-    }else{
-      if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= 
-            mem0.alarmThreshold ){
-        sqlite3MallocAlarm(nNew-nOld);
-      }
+    if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= 
+          mem0.alarmThreshold ){
+      sqlite3MallocAlarm(nNew-nOld);
+    }
+    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
+    if( pNew==0 && mem0.alarmCallback ){
+      sqlite3MallocAlarm(nBytes);
       pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
-      if( pNew==0 && mem0.alarmCallback ){
-        sqlite3MallocAlarm(nBytes);
-        pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
-      }
-      if( pNew ){
-        nNew = sqlite3MallocSize(pNew);
-        sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
-      }
+    }
+    if( pNew ){
+      nNew = sqlite3MallocSize(pNew);
+      sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
     }
     sqlite3_mutex_leave(mem0.mutex);
   }else{
-    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nBytes);
+    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
   }
   return pNew;
 }
 
 /*
 ** The public interface to sqlite3Realloc.  Make sure that the memory
 ** subsystem is initialized prior to invoking sqliteRealloc.
 */
@@ -17143,50 +17508,83 @@ struct VdbeCursor {
   BtCursor *pCursor;    /* The cursor structure of the backend */
   int iDb;              /* Index of cursor database in db->aDb[] (or -1) */
   i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
   Bool zeroed;          /* True if zeroed out and ready for reuse */
   Bool rowidIsValid;    /* True if lastRowid is valid */
   Bool atFirst;         /* True if pointing to first entry */
   Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
   Bool nullRow;         /* True if pointing to a row with no data */
-  Bool pseudoTable;     /* This is a NEW or OLD pseudo-tables of a trigger */
-  Bool ephemPseudoTable;
   Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
   Bool isTable;         /* True if a table requiring integer keys */
   Bool isIndex;         /* True if an index containing keys only - no data */
   i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
   Btree *pBt;           /* Separate file holding temporary table */
-  int nData;            /* Number of bytes in pData */
-  char *pData;          /* Data for a NEW or OLD pseudo-table */
-  i64 iKey;             /* Key for the NEW or OLD pseudo-table row */
+  int pseudoTableReg;   /* Register holding pseudotable content. */
   KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
   int nField;           /* Number of fields in the header */
   i64 seqCount;         /* Sequence counter */
   sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
   const sqlite3_module *pModule;     /* Module for cursor pVtabCursor */
 
   /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or 
   ** OP_IsUnique opcode on this cursor. */
   int seekResult;
 
   /* Cached information about the header for the data record that the
-  ** cursor is currently pointing to.  Only valid if cacheValid is true.
+  ** cursor is currently pointing to.  Only valid if cacheStatus matches
+  ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
+  ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
+  ** the cache is out of date.
+  **
   ** aRow might point to (ephemeral) data for the current row, or it might
   ** be NULL.
   */
-  int cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
+  u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
   int payloadSize;      /* Total number of bytes in the record */
   u32 *aType;           /* Type values for all entries in the record */
   u32 *aOffset;         /* Cached offsets to the start of each columns data */
   u8 *aRow;             /* Data for the current row, if all on one page */
 };
 typedef struct VdbeCursor VdbeCursor;
 
 /*
+** When a sub-program is executed (OP_Program), a structure of this type
+** is allocated to store the current value of the program counter, as
+** well as the current memory cell array and various other frame specific
+** values stored in the Vdbe struct. When the sub-program is finished, 
+** these values are copied back to the Vdbe from the VdbeFrame structure,
+** restoring the state of the VM to as it was before the sub-program
+** began executing.
+**
+** Frames are stored in a linked list headed at Vdbe.pParent. Vdbe.pParent
+** is the parent of the current frame, or zero if the current frame
+** is the main Vdbe program.
+*/
+typedef struct VdbeFrame VdbeFrame;
+struct VdbeFrame {
+  Vdbe *v;                /* VM this frame belongs to */
+  int pc;                 /* Program Counter */
+  Op *aOp;                /* Program instructions */
+  int nOp;                /* Size of aOp array */
+  Mem *aMem;              /* Array of memory cells */
+  int nMem;               /* Number of entries in aMem */
+  VdbeCursor **apCsr;     /* Element of Vdbe cursors */
+  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 */
+};
+
+#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
 
 /*
 ** Internally, the vdbe manipulates nearly all SQL values as Mem
 ** structures. Each Mem struct may cache multiple representations (string,
 ** integer etc.) of the same value.  A value (and therefore Mem structure)
@@ -17198,16 +17596,17 @@ typedef struct VdbeCursor VdbeCursor;
 ** SQLITE_BLOB.
 */
 struct Mem {
   union {
     i64 i;              /* Integer value. */
     int nZero;          /* Used when bit MEM_Zero is set in flags */
     FuncDef *pDef;      /* Used only when flags==MEM_Agg */
     RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
+    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
   } u;
   double r;           /* Real value */
   sqlite3 *db;        /* The associated database connection */
   char *z;            /* String or BLOB value */
   int n;              /* Number of characters in string value, excluding '\0' */
   u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
   u8  type;           /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
   u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
@@ -17231,16 +17630,17 @@ struct Mem {
 ** at a time can appear in Mem.type.
 */
 #define MEM_Null      0x0001   /* Value is NULL */
 #define MEM_Str       0x0002   /* Value is a string */
 #define MEM_Int       0x0004   /* Value is an integer */
 #define MEM_Real      0x0008   /* Value is a real number */
 #define MEM_Blob      0x0010   /* Value is a BLOB */
 #define MEM_RowSet    0x0020   /* Value is a RowSet object */
+#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
 #define MEM_TypeMask  0x00ff   /* Mask of type bits */
 
 /* Whenever Mem contains a valid string or blob representation, one of
 ** the following flags must be set to determine the memory management
 ** policy for Mem.z.  The MEM_Term flag tells us whether or not the
 ** string is \000 or \u0000 terminated
 */
 #define MEM_Term      0x0200   /* String rep is nul terminated */
@@ -17311,31 +17711,16 @@ struct sqlite3_context {
 */
 typedef struct Set Set;
 struct Set {
   Hash hash;             /* A set is just a hash table */
   HashElem *prev;        /* Previously accessed hash elemen */
 };
 
 /*
-** A Context stores the last insert rowid, the last statement change count,
-** and the current statement change count (i.e. changes since last statement).
-** The current keylist is also stored in the context.
-** Elements of Context structure type make up the ContextStack, which is
-** updated by the ContextPush and ContextPop opcodes (used by triggers).
-** The context is pushed before executing a trigger a popped when the
-** trigger finishes.
-*/
-typedef struct Context Context;
-struct Context {
-  i64 lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
-  int nChange;      /* Statement changes (Vdbe.nChanges)     */
-};
-
-/*
 ** An instance of the virtual machine.  This structure contains the complete
 ** state of the virtual machine.
 **
 ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()
 ** is really a pointer to an instance of this structure.
 **
 ** The Vdbe.inVtabMethod variable is set to non-zero for the duration of
 ** any virtual table method invocations made by the vdbe program. It is
@@ -17363,20 +17748,17 @@ struct Vdbe {
   u8 errorAction;         /* Recovery action to do in case of an error */
   u8 okVar;               /* True if azVar[] has been initialized */
   u16 nVar;               /* Number of entries in aVar[] */
   Mem *aVar;              /* Values for the OP_Variable opcode. */
   char **azVar;           /* Name of variables */
   u32 magic;              /* Magic number for sanity checking */
   int nMem;               /* Number of memory locations currently allocated */
   Mem *aMem;              /* The memory locations */
-  int cacheCtr;           /* VdbeCursor row cache generation counter */
-  int contextStackTop;    /* Index of top element in the context stack */
-  int contextStackDepth;  /* The size of the "context" stack */
-  Context *contextStack;  /* Stack used by opcodes ContextPush & ContextPop*/
+  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
   int pc;                 /* The program counter */
   int rc;                 /* Value to return */
   char *zErrMsg;          /* Error message written here */
   u8 explain;             /* True if EXPLAIN present on SQL command */
   u8 changeCntOn;         /* True to update the change-counter */
   u8 expired;             /* True if the VM needs to be recompiled */
   u8 minWriteFileFormat;  /* Minimum file format for writable database files */
   u8 inVtabMethod;        /* See comments above */
@@ -17389,16 +17771,18 @@ struct Vdbe {
   BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
   int aCounter[2];        /* Counters used by sqlite3_stmt_status() */
   char *zSql;             /* Text of the SQL statement that generated this */
   void *pFree;            /* Free this when deleting the vdbe */
   int iStatement;         /* Statement number (or 0 if has not opened stmt) */
 #ifdef SQLITE_DEBUG
   FILE *trace;            /* Write an execution trace here, if not NULL */
 #endif
+  VdbeFrame *pFrame;      /* Parent frame */
+  int nFrame;             /* Number of frames in pFrame list */
 };
 
 /*
 ** The following are allowed values for Vdbe.magic
 */
 #define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
 #define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
 #define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
@@ -17449,16 +17833,18 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerif
 SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
 SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p);
 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
 SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
 SQLITE_PRIVATE int sqlite3VdbeOpcodeHasProperty(int, int);
 SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
 SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
+SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
+SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
 SQLITE_PRIVATE int sqlite3VdbeReleaseBuffers(Vdbe *p);
 #endif
 
 #ifndef SQLITE_OMIT_SHARED_CACHE
 SQLITE_PRIVATE void sqlite3VdbeMutexArrayEnter(Vdbe *p);
 #else
 # define sqlite3VdbeMutexArrayEnter(p)
@@ -17893,16 +18279,42 @@ SQLITE_PRIVATE char *sqlite3Utf16to8(sql
     m.z = 0;
   }
   assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
   assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
   return (m.flags & MEM_Dyn)!=0 ? m.z : sqlite3DbStrDup(db, m.z);
 }
 
 /*
+** Convert a UTF-8 string to the UTF-16 encoding specified by parameter
+** enc. A pointer to the new string is returned, and the value of *pnOut
+** is set to the length of the returned string in bytes. The call should
+** arrange to call sqlite3DbFree() on the returned pointer when it is
+** no longer required.
+** 
+** If a malloc failure occurs, NULL is returned and the db.mallocFailed
+** flag set.
+*/
+#ifdef SQLITE_ENABLE_STAT2
+SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
+  Mem m;
+  memset(&m, 0, sizeof(m));
+  m.db = db;
+  sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
+  if( sqlite3VdbeMemTranslate(&m, enc) ){
+    assert( db->mallocFailed );
+    return 0;
+  }
+  assert( m.z==m.zMalloc );
+  *pnOut = m.n;
+  return m.z;
+}
+#endif
+
+/*
 ** pZ is a UTF-16 encoded unicode string at least nChar characters long.
 ** Return the number of bytes in the first nChar unicode characters
 ** in pZ.  nChar must be non-negative.
 */
 SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){
   int c;
   unsigned char const *z = zIn;
   int n = 0;
@@ -17997,17 +18409,16 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(v
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
 ** Utility functions used throughout sqlite.
 **
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.261 2009/06/24 10:26:33 drh Exp $
 */
 #ifdef SQLITE_HAVE_ISNAN
 # include <math.h>
 #endif
 
 /*
 ** Routine needed to support the testcase() macro.
 */
@@ -18206,17 +18617,17 @@ SQLITE_PRIVATE int sqlite3Dequote(char *
 */
 SQLITE_PRIVATE int sqlite3StrICmp(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_PRIVATE int sqlite3StrNICmp(const char *zLeft, const char *zRight, int N){
+SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
   register unsigned char *a, *b;
   a = (unsigned char *)zLeft;
   b = (unsigned char *)zRight;
   while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
   return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
 }
 
 /*
@@ -18254,93 +18665,149 @@ SQLITE_PRIVATE int sqlite3IsNumber(const
     if( !sqlite3Isdigit(*z) ) return 0;
     while( sqlite3Isdigit(*z) ){ z += incr; }
     *realnum = 1;
   }
   return *z==0;
 }
 
 /*
-** The string z[] is an ascii representation of a real number.
+** The string z[] is an ASCII representation of a real number.
 ** Convert this string to a double.
 **
 ** This routine assumes that z[] really is a valid number.  If it
 ** is not, the result is undefined.
 **
 ** This routine is used instead of the library atof() function because
 ** the library atof() might want to use "," as the decimal point instead
 ** of "." depending on how locale is set.  But that would cause problems
 ** for SQL.  So this routine always uses "." regardless of locale.
 */
 SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult){
 #ifndef SQLITE_OMIT_FLOATING_POINT
-  int sign = 1;
   const char *zBegin = z;
-  LONGDOUBLE_TYPE v1 = 0.0;
-  int nSignificant = 0;
+  /* sign * significand * (10 ^ (esign * exponent)) */
+  int sign = 1;   /* sign of significand */
+  i64 s = 0;      /* significand */
+  int d = 0;      /* adjust exponent for shifting decimal point */
+  int esign = 1;  /* sign of exponent */
+  int e = 0;      /* exponent */
+  double result;
+  int nDigits = 0;
+
+  /* skip leading spaces */
   while( sqlite3Isspace(*z) ) z++;
+  /* get sign of significand */
   if( *z=='-' ){
     sign = -1;
     z++;
   }else if( *z=='+' ){
     z++;
   }
-  while( z[0]=='0' ){
-    z++;
-  }
-  while( sqlite3Isdigit(*z) ){
-    v1 = v1*10.0 + (*z - '0');
-    z++;
-    nSignificant++;
-  }
+  /* skip leading zeroes */
+  while( z[0]=='0' ) z++, nDigits++;
+
+  /* copy max significant digits to significand */
+  while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
+    s = s*10 + (*z - '0');
+    z++, nDigits++;
+  }
+  /* skip non-significant significand digits
+  ** (increase exponent by d to shift decimal left) */
+  while( sqlite3Isdigit(*z) ) z++, nDigits++, d++;
+
+  /* if decimal point is present */
   if( *z=='.' ){
-    LONGDOUBLE_TYPE divisor = 1.0;
     z++;
-    if( nSignificant==0 ){
-      while( z[0]=='0' ){
-        divisor *= 10.0;
-        z++;
-      }
-    }
-    while( sqlite3Isdigit(*z) ){
-      if( nSignificant<18 ){
-        v1 = v1*10.0 + (*z - '0');
-        divisor *= 10.0;
-        nSignificant++;
-      }
-      z++;
-    }
-    v1 /= divisor;
-  }
+    /* copy digits from after decimal to significand
+    ** (decrease exponent by d to shift decimal right) */
+    while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
+      s = s*10 + (*z - '0');
+      z++, nDigits++, d--;
+    }
+    /* skip non-significant digits */
+    while( sqlite3Isdigit(*z) ) z++, nDigits++;
+  }
+
+  /* if exponent is present */
   if( *z=='e' || *z=='E' ){
-    int esign = 1;
-    int eval = 0;
-    LONGDOUBLE_TYPE scale = 1.0;
     z++;
+    /* get sign of exponent */
     if( *z=='-' ){
       esign = -1;
       z++;
     }else if( *z=='+' ){
       z++;
     }
+    /* copy digits to exponent */
     while( sqlite3Isdigit(*z) ){
-      eval = eval*10 + *z - '0';
+      e = e*10 + (*z - '0');
       z++;
     }
-    while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
-    while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }
-    while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }
-    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
-    if( esign<0 ){
-      v1 /= scale;
-    }else{
-      v1 *= scale;
-    }
-  }
-  *pResult = (double)(sign<0 ? -v1 : v1);
+  }
+
+  /* adjust exponent by d, and update sign */
+  e = (e*esign) + d;
+  if( e<0 ) {
+    esign = -1;
+    e *= -1;
+  } else {
+    esign = 1;
+  }
+
+  /* if 0 significand */
+  if( !s ) {
+    /* In the IEEE 754 standard, zero is signed.
+    ** Add the sign if we've seen at least one digit */
+    result = (sign<0 && nDigits) ? -(double)0 : (double)0;
+  } else {
+    /* attempt to reduce exponent */
+    if( esign>0 ){
+      while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
+    }else{
+      while( !(s%10) && e>0 ) e--,s/=10;
+    }
+
+    /* adjust the sign of significand */
+    s = sign<0 ? -s : s;
+
+    /* if exponent, scale significand as appropriate
+    ** and store in result. */
+    if( e ){
+      double scale = 1.0;
+      /* attempt to handle extremely small/large numbers better */
+      if( e>307 && e<342 ){
+        while( e%308 ) { scale *= 1.0e+1; e -= 1; }
+        if( esign<0 ){
+          result = s / scale;
+          result /= 1.0e+308;
+        }else{
+          result = s * scale;
+          result *= 1.0e+308;
+        }
+      }else{
+        /* 1.0e+22 is the largest power of 10 than can be 
+        ** represented exactly. */
+        while( e%22 ) { scale *= 1.0e+1; e -= 1; }
+        while( e>0 ) { scale *= 1.0e+22; e -= 22; }
+        if( esign<0 ){
+          result = s / scale;
+        }else{
+          result = s * scale;
+        }
+      }
+    } else {
+      result = (double)s;
+    }
+  }
+
+  /* store the result */
+  *pResult = result;
+
+  /* return number of characters used */
   return (int)(z - zBegin);
 #else
   return sqlite3Atoi64(z, pResult);
 #endif /* SQLITE_OMIT_FLOATING_POINT */
 }
 
 /*
 ** Compare the 19-character string zNum against the text representation
@@ -18885,17 +19352,17 @@ SQLITE_PRIVATE void sqlite3Put4byte(unsi
   p[3] = (u8)v;
 }
 
 
 
 #if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
 /*
 ** Translate a single byte of Hex into an integer.
-** This routinen only works if h really is a valid hexadecimal
+** This routine only works if h really is a valid hexadecimal
 ** character:  0..9a..fA..F
 */
 static u8 hexToInt(int h){
   assert( (h>='0' && h<='9') ||  (h>='a' && h<='f') ||  (h>='A' && h<='F') );
 #ifdef SQLITE_ASCII
   h += 9*(1&(h>>6));
 #endif
 #ifdef SQLITE_EBCDIC
@@ -19330,54 +19797,54 @@ SQLITE_PRIVATE const char *sqlite3Opcode
      /*  17 */ "IntegrityCk",
      /*  18 */ "Sort",
      /*  19 */ "Not",
      /*  20 */ "Copy",
      /*  21 */ "Trace",
      /*  22 */ "Function",
      /*  23 */ "IfNeg",
      /*  24 */ "Noop",
-     /*  25 */ "Return",
-     /*  26 */ "NewRowid",
-     /*  27 */ "Variable",
-     /*  28 */ "String",
-     /*  29 */ "RealAffinity",
-     /*  30 */ "VRename",
-     /*  31 */ "ParseSchema",
-     /*  32 */ "VOpen",
-     /*  33 */ "Close",
-     /*  34 */ "CreateIndex",
-     /*  35 */ "IsUnique",
-     /*  36 */ "NotFound",
-     /*  37 */ "Int64",
-     /*  38 */ "MustBeInt",
-     /*  39 */ "Halt",
-     /*  40 */ "Rowid",
-     /*  41 */ "IdxLT",
-     /*  42 */ "AddImm",
-     /*  43 */ "Statement",
+     /*  25 */ "Program",
+     /*  26 */ "Return",
+     /*  27 */ "NewRowid",
+     /*  28 */ "Variable",
+     /*  29 */ "String",
+     /*  30 */ "RealAffinity",
+     /*  31 */ "VRename",
+     /*  32 */ "ParseSchema",
+     /*  33 */ "VOpen",
+     /*  34 */ "Close",
+     /*  35 */ "CreateIndex",
+     /*  36 */ "IsUnique",
+     /*  37 */ "NotFound",
+     /*  38 */ "Int64",
+     /*  39 */ "MustBeInt",
+     /*  40 */ "Halt",
+     /*  41 */ "Rowid",
+     /*  42 */ "IdxLT",
+     /*  43 */ "AddImm",
      /*  44 */ "RowData",
      /*  45 */ "MemMax",
      /*  46 */ "NotExists",
      /*  47 */ "Gosub",
      /*  48 */ "Integer",
      /*  49 */ "Prev",
      /*  50 */ "RowSetRead",
      /*  51 */ "RowSetAdd",
      /*  52 */ "VColumn",
      /*  53 */ "CreateTable",
      /*  54 */ "Last",
      /*  55 */ "SeekLe",
      /*  56 */ "IncrVacuum",
      /*  57 */ "IdxRowid",
      /*  58 */ "ResetCount",
-     /*  59 */ "ContextPush",
-     /*  60 */ "Yield",
-     /*  61 */ "DropTrigger",
-     /*  62 */ "DropIndex",
+     /*  59 */ "Yield",
+     /*  60 */ "DropTrigger",
+     /*  61 */ "DropIndex",
+     /*  62 */ "Param",
      /*  63 */ "IdxGE",
      /*  64 */ "IdxDelete",
      /*  65 */ "Vacuum",
      /*  66 */ "Or",
      /*  67 */ "And",
      /*  68 */ "IfNot",
      /*  69 */ "DropTable",
      /*  70 */ "SeekLt",
@@ -19406,49 +19873,49 @@ SQLITE_PRIVATE const char *sqlite3Opcode
      /*  93 */ "BitNot",
      /*  94 */ "String8",
      /*  95 */ "Compare",
      /*  96 */ "Goto",
      /*  97 */ "TableLock",
      /*  98 */ "Clear",
      /*  99 */ "VerifyCookie",
      /* 100 */ "AggStep",
-     /* 101 */ "SetNumColumns",
-     /* 102 */ "Transaction",
-     /* 103 */ "VFilter",
-     /* 104 */ "VDestroy",
-     /* 105 */ "ContextPop",
-     /* 106 */ "Next",
-     /* 107 */ "Count",
-     /* 108 */ "IdxInsert",
-     /* 109 */ "SeekGe",
-     /* 110 */ "Insert",
-     /* 111 */ "Destroy",
-     /* 112 */ "ReadCookie",
-     /* 113 */ "RowSetTest",
-     /* 114 */ "LoadAnalysis",
-     /* 115 */ "Explain",
-     /* 116 */ "HaltIfNull",
-     /* 117 */ "OpenPseudo",
-     /* 118 */ "OpenEphemeral",
-     /* 119 */ "Null",
-     /* 120 */ "Move",
-     /* 121 */ "Blob",
-     /* 122 */ "Rewind",
-     /* 123 */ "SeekGt",
-     /* 124 */ "VBegin",
-     /* 125 */ "VUpdate",
-     /* 126 */ "IfZero",
-     /* 127 */ "VCreate",
-     /* 128 */ "Found",
-     /* 129 */ "IfPos",
+     /* 101 */ "Transaction",
+     /* 102 */ "VFilter",
+     /* 103 */ "VDestroy",
+     /* 104 */ "Next",
+     /* 105 */ "Count",
+     /* 106 */ "IdxInsert",
+     /* 107 */ "SeekGe",
+     /* 108 */ "Insert",
+     /* 109 */ "Destroy",
+     /* 110 */ "ReadCookie",
+     /* 111 */ "RowSetTest",
+     /* 112 */ "LoadAnalysis",
+     /* 113 */ "Explain",
+     /* 114 */ "HaltIfNull",
+     /* 115 */ "OpenPseudo",
+     /* 116 */ "OpenEphemeral",
+     /* 117 */ "Null",
+     /* 118 */ "Move",
+     /* 119 */ "Blob",
+     /* 120 */ "Rewind",
+     /* 121 */ "SeekGt",
+     /* 122 */ "VBegin",
+     /* 123 */ "VUpdate",
+     /* 124 */ "IfZero",
+     /* 125 */ "VCreate",
+     /* 126 */ "Found",
+     /* 127 */ "IfPos",
+     /* 128 */ "NullRow",
+     /* 129 */ "Jump",
      /* 130 */ "Real",
-     /* 131 */ "NullRow",
-     /* 132 */ "Jump",
-     /* 133 */ "Permutation",
+     /* 131 */ "Permutation",
+     /* 132 */ "NotUsed_132",
+     /* 133 */ "NotUsed_133",
      /* 134 */ "NotUsed_134",
      /* 135 */ "NotUsed_135",
      /* 136 */ "NotUsed_136",
      /* 137 */ "NotUsed_137",
      /* 138 */ "NotUsed_138",
      /* 139 */ "NotUsed_139",
      /* 140 */ "NotUsed_140",
      /* 141 */ "ToText",
@@ -20854,18 +21321,16 @@ SQLITE_API int sqlite3_os_end(void){
 **      + for AFP filesystem locks (MacOSX only)
 **   *  sqlite3_file methods not associated with locking.
 **   *  Definitions of sqlite3_io_methods objects for all locking
 **      methods plus "finder" functions for each locking method.
 **   *  sqlite3_vfs method implementations.
 **   *  Locking primitives for the proxy uber-locking-method. (MacOSX only)
 **   *  Definitions of sqlite3_vfs objects for all locking methods
 **      plus implementations of sqlite3_os_init() and sqlite3_os_end().
-**
-** $Id: os_unix.c,v 1.253 2009/06/17 13:09:39 drh Exp $
 */
 #if SQLITE_OS_UNIX              /* This file is used on unix only */
 
 /*
 ** There are various methods for file locking used for concurrency
 ** control:
 **
 **   1. POSIX locking (the default),
@@ -20979,29 +21444,44 @@ SQLITE_API int sqlite3_os_end(void){
 /*
 ** Only set the lastErrno if the error code is a real error and not 
 ** a normal expected return code of SQLITE_BUSY or SQLITE_OK
 */
 #define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))
 
 
 /*
+** Sometimes, after a file handle is closed by SQLite, the file descriptor
+** cannot be closed immediately. In these cases, instances of the following
+** structure are used to store the file descriptor while waiting for an
+** opportunity to either close or reuse it.
+*/
+typedef struct UnixUnusedFd UnixUnusedFd;
+struct UnixUnusedFd {
+  int fd;                   /* File descriptor to close */
+  int flags;                /* Flags this file descriptor was opened with */
+  UnixUnusedFd *pNext;      /* Next unused file descriptor on same file */
+};
+
+/*
 ** The unixFile structure is subclass of sqlite3_file specific to the unix
 ** VFS implementations.
 */
 typedef struct unixFile unixFile;
 struct unixFile {
   sqlite3_io_methods const *pMethod;  /* Always the first entry */
   struct unixOpenCnt *pOpen;       /* Info about all open fd's on this inode */
   struct unixLockInfo *pLock;      /* Info about locks on this inode */
   int h;                           /* The file descriptor */
   int dirfd;                       /* File descriptor for the directory */
   unsigned char locktype;          /* The type of lock held on this fd */
   int lastErrno;                   /* The unix errno from the last I/O error */
   void *lockingContext;            /* Locking style specific state */
+  UnixUnusedFd *pUnused;           /* Pre-allocated UnixUnusedFd */
+  int fileFlags;                   /* Miscellanous flags */
 #if SQLITE_ENABLE_LOCKING_STYLE
   int openFlags;                   /* The flags specified at open() */
 #endif
 #if SQLITE_THREADSAFE && defined(__linux__)
   pthread_t tid;                   /* The thread that "owns" this unixFile */
 #endif
 #if OS_VXWORKS
   int isDelete;                    /* Delete on close if true */
@@ -21013,31 +21493,31 @@ struct unixFile {
   ** whenever any part of the database changes.  An assertion fault will
   ** occur if a file is updated without also updating the transaction
   ** counter.  This test is made to avoid new problems similar to the
   ** one described by ticket #3584. 
   */
   unsigned char transCntrChng;   /* True if the transaction counter changed */
   unsigned char dbUpdate;        /* True if any part of database file changed */
   unsigned char inNormalWrite;   /* True if in a normal write operation */
-
-  /* If true, that means we are dealing with a database file that has
-  ** a range of locking bytes from PENDING_BYTE through PENDING_BYTE+511
-  ** which should never be read or written.  Asserts() will verify this */
-  unsigned char isLockable;      /* True if file might be locked */
 #endif
 #ifdef SQLITE_TEST
   /* In test mode, increase the size of this structure a bit so that 
   ** it is larger than the struct CrashFile defined in test6.c.
   */
   char aPadding[32];
 #endif
 };
 
 /*
+** The following macros define bits in unixFile.fileFlags
+*/
+#define SQLITE_WHOLE_FILE_LOCKING  0x0001   /* Use whole-file locking */
+
+/*
 ** 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
 **
 ** The author disclaims copyright to this source code.  In place of
@@ -21294,39 +21774,55 @@ SQLITE_API int sqlite3_open_file_count =
 #if SQLITE_THREADSAFE
 #define threadid pthread_self()
 #else
 #define threadid 0
 #endif
 
 
 /*
-** Helper functions to obtain and relinquish the global mutex.
+** Helper functions to obtain and relinquish the global mutex. The
+** global mutex is used to protect the unixOpenCnt, unixLockInfo and
+** vxworksFileId objects used by this file, all of which may be 
+** shared by multiple threads.
+**
+** Function unixMutexHeld() is used to assert() that the global mutex 
+** is held when required. This function is only used as part of assert() 
+** statements. e.g.
+**
+**   unixEnterMutex()
+**     assert( unixMutexHeld() );
+**   unixEnterLeave()
 */
 static void unixEnterMutex(void){
   sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
 }
 static void unixLeaveMutex(void){
   sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
 }
+#ifdef SQLITE_DEBUG
+static int unixMutexHeld(void) {
+  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+}
+#endif
 
 
 #ifdef SQLITE_DEBUG
 /*
 ** Helper function for printing out trace information from debugging
 ** binaries. This returns the string represetation of the supplied
 ** integer lock-type.
 */
 static const char *locktypeName(int locktype){
   switch( locktype ){
-  case NO_LOCK: return "NONE";
-  case SHARED_LOCK: return "SHARED";
-  case RESERVED_LOCK: return "RESERVED";
-  case PENDING_LOCK: return "PENDING";
-  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
+    case NO_LOCK: return "NONE";
+    case SHARED_LOCK: return "SHARED";
+    case RESERVED_LOCK: return "RESERVED";
+    case PENDING_LOCK: return "PENDING";
+    case EXCLUSIVE_LOCK: return "EXCLUSIVE";
   }
   return "ERROR";
 }
 #endif
 
 #ifdef SQLITE_LOCK_TRACE
 /*
 ** Print out information about all locking operations.
@@ -21770,21 +22266,20 @@ struct unixLockInfo {
 ** descriptor for each open file, even when it is opened multiple times.
 ** The close() system call would only occur when the last database
 ** using the file closes.
 */
 struct unixOpenCnt {
   struct unixFileId fileId;   /* The lookup key */
   int nRef;                   /* Number of pointers to this structure */
   int nLock;                  /* Number of outstanding locks */
-  int nPending;               /* Number of pending close() operations */
-  int *aPending;            /* Malloced space holding fd's awaiting a close() */
+  UnixUnusedFd *pUnused;      /* Unused file descriptors to close */
 #if OS_VXWORKS
   sem_t *pSem;                     /* Named POSIX semaphore */
-  char aSemName[MAX_PATHNAME+1];   /* Name of that semaphore */
+  char aSemName[MAX_PATHNAME+2];   /* Name of that semaphore */
 #endif
   struct unixOpenCnt *pNext, *pPrev;   /* List of all unixOpenCnt objects */
 };
 
 /*
 ** Lists of all unixLockInfo and unixOpenCnt objects.  These used to be hash
 ** tables.  But the number of objects is rarely more than a dozen and
 ** never exceeds a few thousand.  And lookup is not on a critical
@@ -21871,28 +22366,33 @@ static void testThreadLockingBehavior(in
   l.l_start = 0;
   l.l_whence = SEEK_SET;
   rc = fcntl(fd_orig, F_SETLK, &l);
   if( rc!=0 ) return;
   memset(&d, 0, sizeof(d));
   d.fd = fd;
   d.lock = l;
   d.lock.l_type = F_WRLCK;
-  pthread_create(&t, 0, threadLockingTest, &d);
-  pthread_join(t, 0);
+  if( pthread_create(&t, 0, threadLockingTest, &d)==0 ){
+    pthread_join(t, 0);
+  }
   close(fd);
   if( d.result!=0 ) return;
   threadsOverrideEachOthersLocks = (d.lock.l_type==F_UNLCK);
 }
-#endif /* SQLITE_THERADSAFE && defined(__linux__) */
+#endif /* SQLITE_THREADSAFE && defined(__linux__) */
 
 /*
 ** Release a unixLockInfo structure previously allocated by findLockInfo().
+**
+** The mutex entered using the unixEnterMutex() function must be held
+** when this function is called.
 */
 static void releaseLockInfo(struct unixLockInfo *pLock){
+  assert( unixMutexHeld() );
   if( pLock ){
     pLock->nRef--;
     if( pLock->nRef==0 ){
       if( pLock->pPrev ){
         assert( pLock->pPrev->pNext==pLock );
         pLock->pPrev->pNext = pLock->pNext;
       }else{
         assert( lockList==pLock );
@@ -21904,58 +22404,77 @@ static void releaseLockInfo(struct unixL
       }
       sqlite3_free(pLock);
     }
   }
 }
 
 /*
 ** Release a unixOpenCnt structure previously allocated by findLockInfo().
+**
+** The mutex entered using the unixEnterMutex() function must be held
+** when this function is called.
 */
 static void releaseOpenCnt(struct unixOpenCnt *pOpen){
+  assert( unixMutexHeld() );
   if( pOpen ){
     pOpen->nRef--;
     if( pOpen->nRef==0 ){
       if( pOpen->pPrev ){
         assert( pOpen->pPrev->pNext==pOpen );
         pOpen->pPrev->pNext = pOpen->pNext;
       }else{
         assert( openList==pOpen );
         openList = pOpen->pNext;
       }
       if( pOpen->pNext ){
         assert( pOpen->pNext->pPrev==pOpen );
         pOpen->pNext->pPrev = pOpen->pPrev;
       }
-      sqlite3_free(pOpen->aPending);
+#if SQLITE_THREADSAFE && defined(__linux__)
+      assert( !pOpen->pUnused || threadsOverrideEachOthersLocks==0 );
+#endif
+
+      /* If pOpen->pUnused is not null, then memory and file-descriptors
+      ** are leaked.
+      **
+      ** This will only happen if, under Linuxthreads, the user has opened
+      ** a transaction in one thread, then attempts to close the database
+      ** handle from another thread (without first unlocking the db file).
+      ** This is a misuse.  */
       sqlite3_free(pOpen);
     }
   }
 }
 
 /*
 ** Given a file descriptor, locate unixLockInfo and unixOpenCnt structures that
 ** describes that file descriptor.  Create new ones if necessary.  The
 ** return values might be uninitialized if an error occurs.
 **
+** The mutex entered using the unixEnterMutex() function must be held
+** when this function is called.
+**
 ** Return an appropriate error code.
 */
 static int findLockInfo(
   unixFile *pFile,               /* Unix file with file desc used in the key */
   struct unixLockInfo **ppLock,  /* Return the unixLockInfo structure here */
   struct unixOpenCnt **ppOpen    /* Return the unixOpenCnt structure here */
 ){
   int rc;                        /* System call return code */
   int fd;                        /* The file descriptor for pFile */
   struct unixLockKey lockKey;    /* Lookup key for the unixLockInfo structure */
   struct unixFileId fileId;      /* Lookup key for the unixOpenCnt struct */
   struct stat statbuf;           /* Low-level file information */
   struct unixLockInfo *pLock = 0;/* Candidate unixLockInfo object */
   struct unixOpenCnt *pOpen;     /* Candidate unixOpenCnt object */
 
+  assert( unixMutexHeld() );
+
   /* Get low-level information about the file that we can used to
   ** create a unique name for the file.
   */
   fd = pFile->h;
   rc = fstat(fd, &statbuf);
   if( rc!=0 ){
     pFile->lastErrno = errno;
 #ifdef EOVERFLOW
@@ -22033,29 +22552,22 @@ static int findLockInfo(
     }
     if( pOpen==0 ){
       pOpen = sqlite3_malloc( sizeof(*pOpen) );
       if( pOpen==0 ){
         releaseLockInfo(pLock);
         rc = SQLITE_NOMEM;
         goto exit_findlockinfo;
       }
+      memset(pOpen, 0, sizeof(*pOpen));
       pOpen->fileId = fileId;
       pOpen->nRef = 1;
-      pOpen->nLock = 0;
-      pOpen->nPending = 0;
-      pOpen->aPending = 0;
       pOpen->pNext = openList;
-      pOpen->pPrev = 0;
       if( openList ) openList->pPrev = pOpen;
       openList = pOpen;
-#if OS_VXWORKS
-      pOpen->pSem = NULL;
-      pOpen->aSemName[0] = '\0';
-#endif
     }else{
       pOpen->nRef++;
     }
     *ppOpen = pOpen;
   }
 
 exit_findlockinfo:
   return rc;
@@ -22153,16 +22665,72 @@ static int unixCheckReservedLock(sqlite3
   unixLeaveMutex();
   OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
 
   *pResOut = reserved;
   return rc;
 }
 
 /*
+** Perform a file locking operation on a range of bytes in a file.
+** The "op" parameter should be one of F_RDLCK, F_WRLCK, or F_UNLCK.
+** Return 0 on success or -1 for failure.  On failure, write the error
+** code into *pErrcode.
+**
+** If the SQLITE_WHOLE_FILE_LOCKING bit is clear, then only lock
+** the range of bytes on the locking page between SHARED_FIRST and
+** SHARED_SIZE.  If SQLITE_WHOLE_FILE_LOCKING is set, then lock all
+** bytes from 0 up to but not including PENDING_BYTE, and all bytes
+** that follow SHARED_FIRST.
+**
+** In other words, of SQLITE_WHOLE_FILE_LOCKING if false (the historical
+** default case) then only lock a small range of bytes from SHARED_FIRST
+** through SHARED_FIRST+SHARED_SIZE-1.  But if SQLITE_WHOLE_FILE_LOCKING is
+** true then lock every byte in the file except for PENDING_BYTE and
+** RESERVED_BYTE.
+**
+** SQLITE_WHOLE_FILE_LOCKING=true overlaps SQLITE_WHOLE_FILE_LOCKING=false
+** and so the locking schemes are compatible.  One type of lock will
+** effectively exclude the other type.  The reason for using the
+** SQLITE_WHOLE_FILE_LOCKING=true is that by indicating the full range
+** of bytes to be read or written, we give hints to NFS to help it
+** maintain cache coherency.  On the other hand, whole file locking
+** is slower, so we don't want to use it except for NFS.
+*/
+static int rangeLock(unixFile *pFile, int op, int *pErrcode){
+  struct flock lock;
+  int rc;
+  lock.l_type = op;
+  lock.l_start = SHARED_FIRST;
+  lock.l_whence = SEEK_SET;
+  if( (pFile->fileFlags & SQLITE_WHOLE_FILE_LOCKING)==0 ){
+    lock.l_len = SHARED_SIZE;
+    rc = fcntl(pFile->h, F_SETLK, &lock);
+    *pErrcode = errno;
+  }else{
+    lock.l_len = 0;
+    rc = fcntl(pFile->h, F_SETLK, &lock);
+    *pErrcode = errno;
+    if( NEVER(op==F_UNLCK) || rc!=(-1) ){
+      lock.l_start = 0;
+      lock.l_len = PENDING_BYTE;
+      rc = fcntl(pFile->h, F_SETLK, &lock);
+      if( ALWAYS(op!=F_UNLCK) && rc==(-1) ){
+        *pErrcode = errno;
+        lock.l_type = F_UNLCK;
+        lock.l_start = SHARED_FIRST;
+        lock.l_len = 0;
+        fcntl(pFile->h, F_SETLK, &lock);
+      }
+    }
+  }
+  return rc;
+}
+
+/*
 ** Lock the file with the lock specified by parameter locktype - one
 ** of the following:
 **
 **     (1) SHARED_LOCK
 **     (2) RESERVED_LOCK
 **     (3) PENDING_LOCK
 **     (4) EXCLUSIVE_LOCK
 **
@@ -22219,34 +22787,38 @@ static int unixLock(sqlite3_file *id, in
   ** range' is that some versions of windows do not support read-locks. By
   ** locking a random byte from a range, concurrent SHARED locks may exist
   ** even if the locking primitive used is always a write-lock.
   */
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile*)id;
   struct unixLockInfo *pLock = pFile->pLock;
   struct flock lock;
-  int s;
+  int s = 0;
+  int tErrno;
 
   assert( pFile );
   OSTRACE7("LOCK    %d %s was %s(%s,%d) pid=%d\n", pFile->h,
       locktypeName(locktype), locktypeName(pFile->locktype),
       locktypeName(pLock->locktype), pLock->cnt , getpid());
 
   /* If there is already a lock of this type or more restrictive on the
   ** unixFile, do nothing. Don't use the end_lock: exit path, as
   ** unixEnterMutex() hasn't been called yet.
   */
   if( pFile->locktype>=locktype ){
     OSTRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
             locktypeName(locktype));
     return SQLITE_OK;
   }
 
-  /* Make sure the locking sequence is correct
+  /* Make sure the locking sequence is correct.
+  **  (1) We never move from unlocked to anything higher than shared lock.
+  **  (2) SQLite never explicitly requests a pendig lock.
+  **  (3) A shared lock is always held when a reserve lock is requested.
   */
   assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
   assert( locktype!=PENDING_LOCK );
   assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
 
   /* This mutex is needed because pFile->pLock is shared across threads
   */
   unixEnterMutex();
@@ -22280,55 +22852,50 @@ static int unixLock(sqlite3_file *id, in
     assert( pFile->locktype==0 );
     assert( pLock->cnt>0 );
     pFile->locktype = SHARED_LOCK;
     pLock->cnt++;
     pFile->pOpen->nLock++;
     goto end_lock;
   }
 
-  lock.l_len = 1L;
-
-  lock.l_whence = SEEK_SET;
 
   /* A PENDING lock is needed before acquiring a SHARED lock and before
   ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
   ** be released.
   */
+  lock.l_len = 1L;
+  lock.l_whence = SEEK_SET;
   if( locktype==SHARED_LOCK 
       || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
   ){
     lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
     lock.l_start = PENDING_BYTE;
     s = fcntl(pFile->h, F_SETLK, &lock);
     if( s==(-1) ){
-      int tErrno = errno;
+      tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( IS_LOCK_ERROR(rc) ){
         pFile->lastErrno = tErrno;
       }
       goto end_lock;
     }
   }
 
 
   /* If control gets to this point, then actually go ahead and make
   ** operating system calls for the specified lock.
   */
   if( locktype==SHARED_LOCK ){
-    int tErrno = 0;
     assert( pLock->cnt==0 );
     assert( pLock->locktype==0 );
 
     /* Now get the read-lock */
-    lock.l_start = SHARED_FIRST;
-    lock.l_len = SHARED_SIZE;
-    if( (s = fcntl(pFile->h, F_SETLK, &lock))==(-1) ){
-      tErrno = errno;
-    }
+    s = rangeLock(pFile, F_RDLCK, &tErrno);
+
     /* Drop the temporary PENDING lock */
     lock.l_start = PENDING_BYTE;
     lock.l_len = 1L;
     lock.l_type = F_UNLCK;
     if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
       if( s != -1 ){
         /* This could happen with a network mount */
         tErrno = errno; 
@@ -22358,27 +22925,26 @@ static int unixLock(sqlite3_file *id, in
     ** assumed that there is a SHARED or greater lock on the file
     ** already.
     */
     assert( 0!=pFile->locktype );
     lock.l_type = F_WRLCK;
     switch( locktype ){
       case RESERVED_LOCK:
         lock.l_start = RESERVED_BYTE;
+        s = fcntl(pFile->h, F_SETLK, &lock);
+        tErrno = errno;
         break;
       case EXCLUSIVE_LOCK:
-        lock.l_start = SHARED_FIRST;
-        lock.l_len = SHARED_SIZE;
+        s = rangeLock(pFile, F_WRLCK, &tErrno);
         break;
       default:
         assert(0);
     }
-    s = fcntl(pFile->h, F_SETLK, &lock);
     if( s==(-1) ){
-      int tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( IS_LOCK_ERROR(rc) ){
         pFile->lastErrno = tErrno;
       }
     }
   }
   
 
@@ -22410,28 +22976,72 @@ static int unixLock(sqlite3_file *id, in
 end_lock:
   unixLeaveMutex();
   OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
       rc==SQLITE_OK ? "ok" : "failed");
   return rc;
 }
 
 /*
+** Close all file descriptors accumuated in the unixOpenCnt->pUnused list.
+** If all such file descriptors are closed without error, the list is
+** cleared and SQLITE_OK returned.
+**
+** Otherwise, if an error occurs, then successfully closed file descriptor
+** entries are removed from the list, and SQLITE_IOERR_CLOSE returned. 
+** not deleted and SQLITE_IOERR_CLOSE returned.
+*/ 
+static int closePendingFds(unixFile *pFile){
+  int rc = SQLITE_OK;
+  struct unixOpenCnt *pOpen = pFile->pOpen;
+  UnixUnusedFd *pError = 0;
+  UnixUnusedFd *p;
+  UnixUnusedFd *pNext;
+  for(p=pOpen->pUnused; p; p=pNext){
+    pNext = p->pNext;
+    if( close(p->fd) ){
+      pFile->lastErrno = errno;
+      rc = SQLITE_IOERR_CLOSE;
+      p->pNext = pError;
+      pError = p;
+    }else{
+      sqlite3_free(p);
+    }
+  }
+  pOpen->pUnused = pError;
+  return rc;
+}
+
+/*
+** Add the file descriptor used by file handle pFile to the corresponding
+** pUnused list.
+*/
+static void setPendingFd(unixFile *pFile){
+  struct unixOpenCnt *pOpen = pFile->pOpen;
+  UnixUnusedFd *p = pFile->pUnused;
+  p->pNext = pOpen->pUnused;
+  pOpen->pUnused = p;
+  pFile->h = -1;
+  pFile->pUnused = 0;
+}
+
+/*
 ** Lower the locking level on file descriptor pFile to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
 **
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 */
 static int unixUnlock(sqlite3_file *id, int locktype){
-  struct unixLockInfo *pLock;
-  struct flock lock;
-  int rc = SQLITE_OK;
-  unixFile *pFile = (unixFile*)id;
-  int h;
+  unixFile *pFile = (unixFile*)id; /* The open file */
+  struct unixLockInfo *pLock;      /* Structure describing current lock state */
+  struct flock lock;               /* Information passed into fcntl() */
+  int rc = SQLITE_OK;              /* Return code from this interface */
+  int h;                           /* The underlying file descriptor */
+  int tErrno;                      /* Error code from system call errors */
 
   assert( pFile );
   OSTRACE7("UNLOCK  %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype,
       pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid());
 
   assert( locktype<=SHARED_LOCK );
   if( pFile->locktype<=locktype ){
     return SQLITE_OK;
@@ -22461,102 +23071,79 @@ static int unixUnlock(sqlite3_file *id, 
     assert( pFile->inNormalWrite==0
          || pFile->dbUpdate==0
          || pFile->transCntrChng==1 );
     pFile->inNormalWrite = 0;
 #endif
 
 
     if( locktype==SHARED_LOCK ){
-      lock.l_type = F_RDLCK;
-      lock.l_whence = SEEK_SET;
-      lock.l_start = SHARED_FIRST;
-      lock.l_len = SHARED_SIZE;
-      if( fcntl(h, F_SETLK, &lock)==(-1) ){
-        int tErrno = errno;
+      if( rangeLock(pFile, F_RDLCK, &tErrno)==(-1) ){
         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
         if( IS_LOCK_ERROR(rc) ){
           pFile->lastErrno = tErrno;
         }
         goto end_unlock;
       }
     }
     lock.l_type = F_UNLCK;
     lock.l_whence = SEEK_SET;
     lock.l_start = PENDING_BYTE;
     lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
     if( fcntl(h, F_SETLK, &lock)!=(-1) ){
       pLock->locktype = SHARED_LOCK;
     }else{
-      int tErrno = errno;
+      tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
       if( IS_LOCK_ERROR(rc) ){
         pFile->lastErrno = tErrno;
       }
       goto end_unlock;
     }
   }
   if( locktype==NO_LOCK ){
     struct unixOpenCnt *pOpen;
-    int rc2 = SQLITE_OK;
 
     /* Decrement the shared lock counter.  Release the lock using an
     ** OS call only when all threads in this same process have released
     ** the lock.
     */
     pLock->cnt--;
     if( pLock->cnt==0 ){
       lock.l_type = F_UNLCK;
       lock.l_whence = SEEK_SET;
       lock.l_start = lock.l_len = 0L;
       SimulateIOErrorBenign(1);
       SimulateIOError( h=(-1) )
       SimulateIOErrorBenign(0);
       if( fcntl(h, F_SETLK, &lock)!=(-1) ){
         pLock->locktype = NO_LOCK;
       }else{
-        int tErrno = errno;
+        tErrno = errno;
         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
         if( IS_LOCK_ERROR(rc) ){
           pFile->lastErrno = tErrno;
         }
         pLock->locktype = NO_LOCK;
         pFile->locktype = NO_LOCK;
       }
     }
 
     /* Decrement the count of locks against this same file.  When the
     ** count reaches zero, close any other file descriptors whose close
     ** was deferred because of outstanding locks.
     */
     pOpen = pFile->pOpen;
     pOpen->nLock--;
     assert( pOpen->nLock>=0 );
-    if( pOpen->nLock==0 && pOpen->nPending>0 ){
-      int i;
-      for(i=0; i<pOpen->nPending; i++){
-        /* close pending fds, but if closing fails don't free the array
-        ** assign -1 to the successfully closed descriptors and record the
-        ** error.  The next attempt to unlock will try again. */
-        if( pOpen->aPending[i] < 0 ) continue;
-        if( close(pOpen->aPending[i]) ){
-          pFile->lastErrno = errno;
-          rc2 = SQLITE_IOERR_CLOSE;
-        }else{
-          pOpen->aPending[i] = -1;
-        }
-      }
-      if( rc2==SQLITE_OK ){
-        sqlite3_free(pOpen->aPending);
-        pOpen->nPending = 0;
-        pOpen->aPending = 0;
-      }
-    }
-    if( rc==SQLITE_OK ){
-      rc = rc2;
+    if( pOpen->nLock==0 ){
+      int rc2 = closePendingFds(pFile);
+      if( rc==SQLITE_OK ){
+        rc = rc2;
+      }
     }
   }
 	
 end_unlock:
   unixLeaveMutex();
   if( rc==SQLITE_OK ) pFile->locktype = locktype;
   return rc;
 }
@@ -22596,16 +23183,17 @@ static int closeUnixFile(sqlite3_file *i
         unlink(pFile->pId->zCanonicalName);
       }
       vxworksReleaseFileId(pFile->pId);
       pFile->pId = 0;
     }
 #endif
     OSTRACE2("CLOSE   %-3d\n", pFile->h);
     OpenCounter(-1);
+    sqlite3_free(pFile->pUnused);
     memset(pFile, 0, sizeof(unixFile));
   }
   return SQLITE_OK;
 }
 
 /*
 ** Close a file.
 */
@@ -22613,30 +23201,20 @@ static int unixClose(sqlite3_file *id){
   int rc = SQLITE_OK;
   if( id ){
     unixFile *pFile = (unixFile *)id;
     unixUnlock(id, NO_LOCK);
     unixEnterMutex();
     if( pFile->pOpen && pFile->pOpen->nLock ){
       /* If there are outstanding locks, do not actually close the file just
       ** yet because that would clear those locks.  Instead, add the file
-      ** descriptor to pOpen->aPending.  It will be automatically closed when
-      ** the last lock is cleared.
-      */
-      int *aNew;
-      struct unixOpenCnt *pOpen = pFile->pOpen;
-      aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
-      if( aNew==0 ){
-        /* If a malloc fails, just leak the file descriptor */
-      }else{
-        pOpen->aPending = aNew;
-        pOpen->aPending[pOpen->nPending] = pFile->h;
-        pOpen->nPending++;
-        pFile->h = -1;
-      }
+      ** descriptor to pOpen->pUnused list.  It will be automatically closed 
+      ** when the last lock is cleared.
+      */
+      setPendingFd(pFile);
     }
     releaseLockInfo(pFile->pLock);
     releaseOpenCnt(pFile->pOpen);
     rc = closeUnixFile(id);
     unixLeaveMutex();
   }
   return rc;
 }
@@ -22683,17 +23261,17 @@ static int nolockClose(sqlite3_file *id)
 }
 
 /******************* End of the no-op lock implementation *********************
 ******************************************************************************/
 
 /******************************************************************************
 ************************* Begin dot-file Locking ******************************
 **
-** The dotfile locking implementation uses the existing of separate lock
+** The dotfile locking implementation uses the existance of separate lock
 ** files in order to control access to the database.  This works on just
 ** about every filesystem imaginable.  But there are serious downsides:
 **
 **    (1)  There is zero concurrency.  A single reader blocks all other
 **         connections from reading or writing the database.
 **
 **    (2)  An application crash or power loss can leave stale lock files
 **         sitting around that need to be cleared manually.
@@ -23595,37 +24173,25 @@ static int afpUnlock(sqlite3_file *id, i
     rc = afpSetLock(pCtx->dbPath, pFile, sharedLockByte, 1, 0);
   }
 
   if( rc==SQLITE_OK ){
     if( locktype==NO_LOCK ){
       struct unixOpenCnt *pOpen = pFile->pOpen;
       pOpen->nLock--;
       assert( pOpen->nLock>=0 );
-      if( pOpen->nLock==0 && pOpen->nPending>0 ){
-        int i;
-        for(i=0; i<pOpen->nPending; i++){
-          if( pOpen->aPending[i] < 0 ) continue;
-          if( close(pOpen->aPending[i]) ){
-            pFile->lastErrno = errno;
-            rc = SQLITE_IOERR_CLOSE;
-          }else{
-            pOpen->aPending[i] = -1;
-          }
-        }
-        if( rc==SQLITE_OK ){
-          sqlite3_free(pOpen->aPending);
-          pOpen->nPending = 0;
-          pOpen->aPending = 0;
-        }
+      if( pOpen->nLock==0 ){
+        rc = closePendingFds(pFile);
       }
     }
   }
   unixLeaveMutex();
-  if( rc==SQLITE_OK ) pFile->locktype = locktype;
+  if( rc==SQLITE_OK ){
+    pFile->locktype = locktype;
+  }
   return rc;
 }
 
 /*
 ** Close a file & cleanup AFP specific locking context 
 */
 static int afpClose(sqlite3_file *id) {
   if( id ){
@@ -23633,27 +24199,17 @@ static int afpClose(sqlite3_file *id) {
     afpUnlock(id, NO_LOCK);
     unixEnterMutex();
     if( pFile->pOpen && pFile->pOpen->nLock ){
       /* If there are outstanding locks, do not actually close the file just
       ** yet because that would clear those locks.  Instead, add the file
       ** descriptor to pOpen->aPending.  It will be automatically closed when
       ** the last lock is cleared.
       */
-      int *aNew;
-      struct unixOpenCnt *pOpen = pFile->pOpen;
-      aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
-      if( aNew==0 ){
-        /* If a malloc fails, just leak the file descriptor */
-      }else{
-        pOpen->aPending = aNew;
-        pOpen->aPending[pOpen->nPending] = pFile->h;
-        pOpen->nPending++;
-        pFile->h = -1;
-      }
+      setPendingFd(pFile);
     }
     releaseOpenCnt(pFile->pOpen);
     sqlite3_free(pFile->lockingContext);
     closeUnixFile(id);
     unixLeaveMutex();
   }
   return SQLITE_OK;
 }
@@ -23729,32 +24285,35 @@ static int seekAndRead(unixFile *id, sql
 ** wrong.