Merge last green changeset of mozilla-inbound to mozilla-central
authorEd Morley <bmo@edmorley.co.uk>
Wed, 25 Jan 2012 14:14:48 +0000
changeset 86558 0d5ad6a6f814daabf70822accbdcd05619b4bcd5
parent 86438 03ae304e45afdc7e6f4f0db9201659faeba4deaf (current diff)
parent 86557 fa01b899854a2ba1ed337ba6411aed1051bd78e2 (diff)
child 86568 edf8075b0333a0ed7be2d77b1fd06bc87ca7bdec
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone12.0a1
Merge last green changeset of mozilla-inbound to mozilla-central
build/mobile/robocop/robotium-solo-3.0.jar
js/src/jit-test/tests/basic/bug684796.js
js/src/jit-test/tests/basic/testBug650618.js
js/src/jit-test/tests/basic/testInitSharp.js
js/src/jit-test/tests/jaeger/bug580883.js
js/src/jit-test/tests/jaeger/bug606662-1.js
js/src/jslock.cpp
js/src/jslocko.asm
js/src/lock_sparcv8plus.il
js/src/lock_sparcv9.il
js/src/tests/e4x/extensions/regress-335051.js
js/src/tests/js1_5/extensions/regress-367630.js
js/src/tests/js1_5/extensions/regress-368859.js
js/src/tests/js1_5/extensions/regress-379523.js
js/src/tests/js1_8_1/extensions/regress-452498-224.js
js/src/tests/js1_8_5/extensions/regress-613452.js
js/src/tests/js1_8_5/extensions/regress-630377.js
js/xpconnect/tests/chrome/test_ccbeginfail.xul
js/xpconnect/tests/chrome/test_ccdump.xul
mobile/android/base/resources/drawable/checkerboard.png
parser/htmlparser/public/nsILoggingSink.h
parser/htmlparser/src/nsLoggingSink.cpp
parser/htmlparser/src/nsLoggingSink.h
--- a/accessible/src/mac/mozTextAccessible.mm
+++ b/accessible/src/mac/mozTextAccessible.mm
@@ -1,22 +1,25 @@
 #include "nsAccessibleWrap.h"
+
+#include "nsCocoaUtils.h"
 #include "nsObjCExceptions.h"
 
 #import "mozTextAccessible.h"
 
 using namespace mozilla::a11y;
 
 @interface mozTextAccessible (Private)
 - (NSString*)subrole;
 - (NSString*)selectedText;
 - (NSValue*)selectedTextRange;
 - (long)textLength;
 - (BOOL)isReadOnly;
 - (void)setText:(NSString*)newText;
+- (NSString*)text;
 @end
 
 @implementation mozTextAccessible
 
 - (id)initWithAccessible:(nsAccessibleWrap*)accessible
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
@@ -74,18 +77,19 @@ using namespace mozilla::a11y;
   if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute])
     return [NSNumber numberWithInt:[self textLength]];
   if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute])
     return [self selectedTextRange];
   if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute])
     return [self selectedText];
   // Apple's SpeechSynthesisServer expects AXValue to return an AXStaticText
   // object's AXSelectedText attribute.  See bug 674612.
+  // Also if there is no selected text, we return the full text.See bug 369710
   if ([attribute isEqualToString:NSAccessibilityValueAttribute])
-    return [self selectedText];
+    return [self selectedText] ? : [self text];
 
   // let mozAccessible handle all other attributes
   return [super accessibilityAttributeValue:attribute];
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
@@ -153,16 +157,30 @@ using namespace mozilla::a11y;
 
   if (mGeckoEditableTextAccessible) {
     mGeckoEditableTextAccessible->SetTextContents(NS_ConvertUTF8toUTF16([newString UTF8String]));
   }
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
+- (NSString*)text
+{
+  if (!mGeckoTextAccessible)
+    return nil;
+    
+  nsAutoString text;
+  nsresult rv = 
+    mGeckoTextAccessible->GetText(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT,
+				  text);
+  NS_ENSURE_SUCCESS(rv, nil);
+
+  return text.IsEmpty() ? nil : nsCocoaUtils::ToNSString(text);
+}
+
 - (long)textLength
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
 
   return mGeckoTextAccessible ? mGeckoTextAccessible->CharacterCount() : 0;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
 }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1496,16 +1496,18 @@ function prepareForStartup() {
   gBrowser.addEventListener("MozApplicationManifest",
                             OfflineApps, false);
 
   // setup simple gestures support
   gGestureSupport.init(true);
 }
 
 function delayedStartup(isLoadingBlank, mustLoadSidebar) {
+  Cu.import("resource:///modules/TelemetryTimestamps.jsm");
+  TelemetryTimestamps.add("delayedStartupStarted");
   gDelayedStartupTimeoutId = null;
 
   Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
   Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled", false);
   Services.obs.addObserver(gXPInstallObserver, "addon-install-started", false);
   Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
   Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
   Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
@@ -1760,16 +1762,17 @@ function delayedStartup(isLoadingBlank, 
                                              Ci.nsIPrefLocalizedString).data)
     document.getElementById("appmenu_charsetMenu").hidden = true;
 #endif
 
   window.addEventListener("mousemove", MousePosTracker, false);
   window.addEventListener("dragover", MousePosTracker, false);
 
   Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
+  TelemetryTimestamps.add("delayedStartupFinished");
 }
 
 function BrowserShutdown() {
   // In certain scenarios it's possible for unload to be fired before onload,
   // (e.g. if the window is being closed after browser.js loads but before the
   // load completes). In that case, there's nothing to do here.
   if (!gStartupRan)
     return;
@@ -3104,30 +3107,23 @@ function FillInHTMLTooltip(tipElement)
     tipElement = tipElement.parentNode;
   }
 
   var tipNode = document.getElementById("aHTMLTooltip");
   tipNode.style.direction = direction;
 
   [titleText, XLinkTitleText, SVGTitleText].forEach(function (t) {
     if (t && /\S/.test(t)) {
-
-      // Per HTML 4.01 6.2 (CDATA section), literal CRs and tabs should be
-      // replaced with spaces, and LFs should be removed entirely.
-      // XXX Bug 322270: We don't preserve the result of entities like &#13;,
-      // which should result in a line break in the tooltip, because we can't
-      // distinguish that from a literal character in the source by this point.
-      t = t.replace(/[\r\t]/g, ' ');
-      t = t.replace(/\n/g, '');
+      // Make CRLF and CR render one line break each.  
+      t = t.replace(/\r\n?/g, '\n');
 
       tipNode.setAttribute("label", t);
       retVal = true;
     }
   });
-
   return retVal;
 }
 
 var browserDragAndDrop = {
   canDropLink: function (aEvent) Services.droppedLinkHandler.canDropLink(aEvent, true),
 
   dragOver: function (aEvent)
   {
--- a/browser/base/content/test/browser_bug329212.js
+++ b/browser/base/content/test/browser_bug329212.js
@@ -6,26 +6,26 @@ function test () {
 
     let doc = gBrowser.contentDocument;
     let tooltip = document.getElementById("aHTMLTooltip");
 
     ok(FillInHTMLTooltip(doc.getElementById("svg1"), "should get title"));
     is(tooltip.getAttribute("label"), "This is a non-root SVG element title");
 
     ok(FillInHTMLTooltip(doc.getElementById("text1"), "should get title"));
-    is(tooltip.getAttribute("label"), "    This            is a title    ");
+    is(tooltip.getAttribute("label"), "\n\n\n    This            is a title\n\n    ");
 
     ok(!FillInHTMLTooltip(doc.getElementById("text2"), "should not get title"));
 
     ok(!FillInHTMLTooltip(doc.getElementById("text3"), "should not get title"));
 
     ok(FillInHTMLTooltip(doc.getElementById("link1"), "should get title"));
-    is(tooltip.getAttribute("label"), "      This is a title    ");
+    is(tooltip.getAttribute("label"), "\n      This is a title\n    ");
     ok(FillInHTMLTooltip(doc.getElementById("text4"), "should get title"));
-    is(tooltip.getAttribute("label"), "      This is a title    ");
+    is(tooltip.getAttribute("label"), "\n      This is a title\n    ");
 
     ok(!FillInHTMLTooltip(doc.getElementById("link2"), "should not get title"));
 
     ok(FillInHTMLTooltip(doc.getElementById("link3"), "should get title"));
     ok(tooltip.getAttribute("label") != "");
 
     ok(FillInHTMLTooltip(doc.getElementById("link4"), "should get title"));
     is(tooltip.getAttribute("label"), "This is an xlink:title attribute");
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -125,16 +125,18 @@ const TAB_EVENTS = ["TabOpen", "TabClose
 #define BROKEN_WM_Z_ORDER
 #endif
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 // debug.js adds NS_ASSERT. cf. bug 669196
 Cu.import("resource://gre/modules/debug.js");
 
+Cu.import("resource:///modules/TelemetryTimestamps.jsm");
+
 XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
   Cu.import("resource://gre/modules/NetUtil.jsm");
   return NetUtil;
 });
 
 XPCOMUtils.defineLazyGetter(this, "ScratchpadManager", function() {
   Cu.import("resource:///modules/devtools/scratchpad-manager.jsm");
   return ScratchpadManager;
@@ -289,16 +291,17 @@ SessionStoreService.prototype = {
   },
 
 /* ........ Global Event Handlers .............. */
 
   /**
    * Initialize the component
    */
   initService: function() {
+    TelemetryTimestamps.add("sessionRestoreInitialized");
     OBSERVING.forEach(function(aTopic) {
       Services.obs.addObserver(this, aTopic, true);
     }, this);
 
     var pbs = Cc["@mozilla.org/privatebrowsing;1"].
               getService(Ci.nsIPrivateBrowsingService);
     this._inPrivateBrowsing = pbs.privateBrowsingEnabled;
 
@@ -828,24 +831,25 @@ SessionStoreService.prototype = {
 
     // and create its internal data object
     this._internalWindows[aWindow.__SSi] = { hosts: {} }
 
     if (!this._isWindowLoaded(aWindow))
       this._windows[aWindow.__SSi]._restoring = true;
     if (!aWindow.toolbar.visible)
       this._windows[aWindow.__SSi].isPopup = true;
-    
+
     // perform additional initialization when the first window is loading
     if (this._loadState == STATE_STOPPED) {
       this._loadState = STATE_RUNNING;
       this._lastSaveTime = Date.now();
       
       // restore a crashed session resp. resume the last session if requested
       if (this._initialState) {
+        TelemetryTimestamps.add("sessionRestoreRestoring");
         // make sure that the restored tabs are first in the window
         this._initialState._firstTabs = true;
         this._restoreCount = this._initialState.windows ? this._initialState.windows.length : 0;
         this.restoreWindow(aWindow, this._initialState,
                            this._isCmdLineEmpty(aWindow, this._initialState));
         delete this._initialState;
         
         // _loadState changed from "stopped" to "running"
--- a/browser/modules/Makefile.in
+++ b/browser/modules/Makefile.in
@@ -47,16 +47,17 @@ include $(topsrcdir)/config/config.mk
 ifdef ENABLE_TESTS
 DIRS += test
 endif
 
 EXTRA_JS_MODULES = \
 	openLocationLastURL.jsm \
 	NetworkPrioritizer.jsm \
 	offlineAppCache.jsm \
+	TelemetryTimestamps.jsm \
 	$(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows) 
 EXTRA_JS_MODULES += \
 	WindowsPreviewPerTab.jsm \
 	WindowsJumpLists.jsm \
 	$(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/browser/modules/TelemetryTimestamps.jsm
@@ -0,0 +1,26 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+let EXPORTED_SYMBOLS = ["TelemetryTimestamps"];
+
+let TelemetryTimestamps = {
+  timeStamps: {},
+  add: function TT_add(name, value) {
+    // Default to "now" if not specified
+    if (value == null)
+      value = Date.now();
+
+    if (isNaN(value))
+      throw new Error("Value must be a timestamp");
+
+    // If there's an existing value, just ignore the new value.
+    if (this.timeStamps.hasOwnProperty(name))
+      return;
+
+    this.timeStamps[name] = value;
+  },
+  get: function TT_get() {
+    return JSON.parse(JSON.stringify(this.timeStamps));
+  }
+};
--- a/browser/modules/test/Makefile.in
+++ b/browser/modules/test/Makefile.in
@@ -40,16 +40,17 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = browser/modules/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = \
                  browser_NetworkPrioritizer.js \
+                 browser_TelemetryTimestamps.js \
                  $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows) 
 _BROWSER_FILES += \
                  browser_taskbar_preview.js \
                  $(NULL)
 endif
 
new file mode 100644
--- /dev/null
+++ b/browser/modules/test/browser_TelemetryTimestamps.js
@@ -0,0 +1,62 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function getSimpleMeasurementsFromTelemetryPing() {
+  const TelemetryPing = Cc["@mozilla.org/base/telemetry-ping;1"].getService(Ci.nsIObserver);
+  let str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
+  TelemetryPing.observe(str, "get-payload", "");
+
+  return JSON.parse(str.data).simpleMeasurements;
+}
+
+function test() {
+  // Test the module logic
+  Cu.import("resource:///modules/TelemetryTimestamps.jsm");
+  let now = Date.now();
+  TelemetryTimestamps.add("foo");
+  let fooValue = TelemetryTimestamps.get().foo;
+  ok(fooValue, "foo was added");
+  ok(fooValue >= now, "foo has a reasonable value");
+
+  // Add timestamp with value
+  TelemetryTimestamps.add("bar", 1);
+  ok(TelemetryTimestamps.get().bar, "bar was added");
+  is(TelemetryTimestamps.get().bar, 1, "bar has the right value");
+
+  // Can't add the same timestamp twice
+  TelemetryTimestamps.add("bar", 2);
+  is(TelemetryTimestamps.get().bar, 1, "bar wasn't overwritten");
+
+  let threw = false;
+  try {
+    TelemetryTimestamps.add("baz", "this isn't a number");
+  } catch (ex) {
+    threw = true;
+  }
+  ok(threw, "adding baz threw");
+  ok(!TelemetryTimestamps.get().baz, "no baz was added");
+
+  // Test that the data gets added to the telemetry ping properly
+  let simpleMeasurements = getSimpleMeasurementsFromTelemetryPing();
+  ok(simpleMeasurements, "got simple measurements from ping data");
+  is(simpleMeasurements.foo, fooValue, "foo was included");
+  is(simpleMeasurements.bar, 1, "bar was included");
+  ok(!simpleMeasurements.baz, "baz wasn't included since it wasn't added");
+
+  // Check browser timestamps that we add
+  let props = [
+    // These can't be reliably tested when the test is run alone
+    //"delayedStartupStarted",
+    //"delayedStartupFinished",
+    "sessionRestoreInitialized",
+    // This doesn't get hit in the testing profile
+    //"sessionRestoreRestoring"
+  ];
+
+  props.forEach(function (p) {
+    let value = simpleMeasurements[p];
+    ok(value, p + " exists");
+    ok(!isNaN(value), p + " is a number");
+    ok(value > 0 && value < Date.now(), p + " value is reasonable");
+  });
+}
--- a/build/mobile/devicemanager.py
+++ b/build/mobile/devicemanager.py
@@ -57,252 +57,292 @@ class DMError(Exception):
 
   def __init__(self, msg= ''):
     self.msg = msg
 
   def __str__(self):
     return self.msg
 
 
+def abstractmethod(method):
+  line = method.func_code.co_firstlineno
+  filename = method.func_code.co_filename
+  def not_implemented(*args, **kwargs):
+    raise NotImplementedError('Abstract method %s at File "%s", line %s \
+                              should be implemented by a concrete class' %
+                              (repr(method), filename,line))
+    return not_implemented
+  
 class DeviceManager:
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
+  
+  @abstractmethod
   def pushFile(self, localname, destname):
-    assert 0 == 1
-    return False
-
-  # external function
-  # returns:
-  #  success: directory name
-  #  failure: None
+    """
+    external function
+    returns:
+    success: True
+    failure: False
+    """
+    
+  @abstractmethod
   def mkDir(self, name):
-      assert 0 == 1
-      return None
-
-  # make directory structure on the device
-  # external function
-  # returns:
-  #  success: directory structure that we created
-  #  failure: None
+    """
+    external function
+    returns:
+    success: directory name
+    failure: None
+    """
+    
+  @abstractmethod
   def mkDirs(self, filename):
-      assert 0 == 1
-      return None
-
-  # push localDir from host to remoteDir on the device
-  # external function
-  # returns:
-  #  success: remoteDir
-  #  failure: None
+    """
+    make directory structure on the device
+    external function
+    returns:
+    success: directory structure that we created
+    failure: None
+    """
+    
+  @abstractmethod
   def pushDir(self, localDir, remoteDir):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
-  def dirExists(self, dirname):
-    assert 0 == 1
-    return False
-
-  # Because we always have / style paths we make this a lot easier with some
-  # assumptions
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
-  def fileExists(self, filepath):
-    assert 0 == 1
-    return False
+    """
+    push localDir from host to remoteDir on the device
+    external function
+    returns:
+    success: remoteDir
+    failure: None
+    """
 
-  # list files on the device, requires cd to directory first
-  # external function
-  # returns:
-  #  success: array of filenames, ['file1', 'file2', ...]
-  #  failure: []
+  @abstractmethod
+  def dirExists(self, dirname):
+    """
+    external function
+    returns:
+    success: True
+    failure: False
+    """
+    
+  @abstractmethod
+  def fileExists(self, filepath):
+    """
+    Because we always have / style paths we make this a lot easier with some
+    assumptions
+    external function
+    returns:
+    success: True
+    failure: False
+    """
+    
+  @abstractmethod
   def listFiles(self, rootdir):
-    assert 0 == 1
-    return []
-
-  # external function
-  # returns:
-  #  success: output of telnet, i.e. "removing file: /mnt/sdcard/tests/test.txt"
-  #  failure: None
+    """
+    list files on the device, requires cd to directory first
+    external function
+    returns:
+    success: array of filenames, ['file1', 'file2', ...]
+    failure: None
+    """
+  
+  @abstractmethod
   def removeFile(self, filename):
-    assert 0 == 1
-    return False
-
-  # does a recursive delete of directory on the device: rm -Rf remoteDir
-  # external function
-  # returns:
-  #  success: output of telnet, i.e. "removing file: /mnt/sdcard/tests/test.txt"
-  #  failure: None
+    """
+    external function
+    returns:
+    success: output of telnet, i.e. "removing file: /mnt/sdcard/tests/test.txt"
+    failure: None
+    """
+    
+  @abstractmethod
   def removeDir(self, remoteDir):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: array of process tuples
-  #  failure: []
+    """
+    does a recursive delete of directory on the device: rm -Rf remoteDir
+    external function
+    returns:
+    success: output of telnet, i.e. "removing file: /mnt/sdcard/tests/test.txt"
+    failure: None
+    """
+    
+  @abstractmethod
   def getProcessList(self):
-    assert 0 == 1
-    return []
-
-  # external function
-  # returns:
-  #  success: pid
-  #  failure: None
+    """
+    external function
+    returns:
+    success: array of process tuples
+    failure: None
+    """
+    
+  @abstractmethod
   def fireProcess(self, appname, failIfRunning=False):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: output filename
-  #  failure: None
+    """
+    external function
+    returns:
+    success: pid
+    failure: None
+    """
+    
+  @abstractmethod
   def launchProcess(self, cmd, outputFile = "process.txt", cwd = '', env = '', failIfRunning=False):
-    assert 0 == 1
-    return None
-
-  # loops until 'process' has exited or 'timeout' seconds is reached
-  # loop sleeps for 'interval' seconds between iterations
-  # external function
-  # returns:
-  #  success: [file contents, None]
-  #  failure: [None, None]
+    """
+    external function
+    returns:
+    success: output filename
+    failure: None
+    """
+    
   def communicate(self, process, timeout = 600, interval = 5):
+    """
+    loops until 'process' has exited or 'timeout' seconds is reached
+    loop sleeps for 'interval' seconds between iterations
+    external function
+    returns:
+    success: [file contents, None]
+    failure: [None, None]
+    """
+    
     timed_out = True
     if (timeout > 0):
       total_time = 0
       while total_time < timeout:
         time.sleep(interval)
         if self.processExist(process) == None:
           timed_out = False
           break
         total_time += interval
 
     if (timed_out == True):
       return [None, None]
 
     return [self.getFile(process, "temp.txt"), None]
 
-  # iterates process list and returns pid if exists, otherwise None
-  # external function
-  # returns:
-  #  success: pid
-  #  failure: None
   def processExist(self, appname):
+    """
+    iterates process list and returns pid if exists, otherwise None
+    external function
+    returns:
+    success: pid
+    failure: None
+    """
+    
     pid = None
 
     #filter out extra spaces
     parts = filter(lambda x: x != '', appname.split(' '))
     appname = ' '.join(parts)
 
     #filter out the quoted env string if it exists
     #ex: '"name=value;name2=value2;etc=..." process args' -> 'process args'
     parts = appname.split('"')
     if (len(parts) > 2):
       appname = ' '.join(parts[2:]).strip()
   
     pieces = appname.split(' ')
     parts = pieces[0].split('/')
     app = parts[-1]
+    procre = re.compile('.*' + app + '.*')
 
     procList = self.getProcessList()
     if (procList == []):
       return None
       
     for proc in procList:
-      procName = proc[1].split('/')[-1]
-      if (procName == app):
+      if (procre.match(proc[1])):
         pid = proc[0]
         break
     return pid
 
-  # external function
-  # returns:
-  #  success: output from testagent
-  #  failure: None
+
+  @abstractmethod
   def killProcess(self, appname):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: filecontents
-  #  failure: None
+    """
+    external function
+    returns:
+    success: output from testagent
+    failure: None
+    """
+    
+  @abstractmethod
   def catFile(self, remoteFile):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: output of pullfile, string
-  #  failure: None
+    """
+    external function
+    returns:
+    success: filecontents
+    failure: None
+    """
+    
+  @abstractmethod
   def pullFile(self, remoteFile):
-    assert 0 == 1
-    return None
-
-  # copy file from device (remoteFile) to host (localFile)
-  # external function
-  # returns:
-  #  success: output of pullfile, string
-  #  failure: None
+    """
+    external function
+    returns:
+    success: output of pullfile, string
+    failure: None
+    """
+    
+  @abstractmethod
   def getFile(self, remoteFile, localFile = ''):
-    assert 0 == 1
-    return None
-
-  # copy directory structure from device (remoteDir) to host (localDir)
-  # external function
-  # checkDir exists so that we don't create local directories if the
-  # remote directory doesn't exist but also so that we don't call isDir
-  # twice when recursing.
-  # returns:
-  #  success: list of files, string
-  #  failure: None
+    """
+    copy file from device (remoteFile) to host (localFile)
+    external function
+    returns:
+    success: output of pullfile, string
+    failure: None
+    """
+    
+  @abstractmethod
   def getDirectory(self, remoteDir, localDir, checkDir=True):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
-  #  Throws a FileError exception when null (invalid dir/filename)
+    """
+    copy directory structure from device (remoteDir) to host (localDir)
+    external function
+    checkDir exists so that we don't create local directories if the
+    remote directory doesn't exist but also so that we don't call isDir
+    twice when recursing.
+    returns:
+    success: list of files, string
+    failure: None
+    """
+    
+  @abstractmethod
   def isDir(self, remotePath):
-    assert 0 == 1
-    return False
-
-  # true/false check if the two files have the same md5 sum
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
+    """
+    external function
+    returns:
+    success: True
+    failure: False
+    Throws a FileError exception when null (invalid dir/filename)
+    """
+    
+  @abstractmethod
   def validateFile(self, remoteFile, localFile):
-    assert 0 == 1
-    return False
-
-  # return the md5 sum of a remote file
-  # internal function
-  # returns:
-  #  success: MD5 hash for given filename
-  #  failure: None
+    """
+    true/false check if the two files have the same md5 sum
+    external function
+    returns:
+    success: True
+    failure: False
+    """
+    
+  @abstractmethod
   def getRemoteHash(self, filename):
-    assert 0 == 1
-    return None
-
-  # return the md5 sum of a file on the host
-  # internal function
-  # returns:
-  #  success: MD5 hash for given filename
-  #  failure: None
+    """
+    return the md5 sum of a remote file
+    internal function
+    returns:
+    success: MD5 hash for given filename
+    failure: None
+    """
+    
   def getLocalHash(self, filename):
+    """
+    return the md5 sum of a file on the host
+    internal function
+    returns:
+    success: MD5 hash for given filename
+    failure: None
+    """
+    
     file = open(filename, 'rb')
     if (file == None):
       return None
 
     try:
       mdsum = hashlib.md5()
     except:
       return None
@@ -312,162 +352,201 @@ class DeviceManager:
       if not data:
         break
       mdsum.update(data)
 
     file.close()
     hexval = mdsum.hexdigest()
     if (self.debug >= 3): print "local hash returned: '" + hexval + "'"
     return hexval
-  # Gets the device root for the testing area on the device
-  # For all devices we will use / type slashes and depend on the device-agent
-  # to sort those out.  The agent will return us the device location where we
-  # should store things, we will then create our /tests structure relative to
-  # that returned path.
-  # Structure on the device is as follows:
-  # /tests
-  #       /<fennec>|<firefox>  --> approot
-  #       /profile
-  #       /xpcshell
-  #       /reftest
-  #       /mochitest
-  #
-  # external function
-  # returns:
-  #  success: path for device root
-  #  failure: None
+  
+  @abstractmethod
   def getDeviceRoot(self):
-    assert 0 == 1
+    """
+    Gets the device root for the testing area on the device
+    For all devices we will use / type slashes and depend on the device-agent
+    to sort those out.  The agent will return us the device location where we
+    should store things, we will then create our /tests structure relative to
+    that returned path.
+    Structure on the device is as follows:
+    /tests
+          /<fennec>|<firefox>  --> approot
+          /profile
+          /xpcshell
+          /reftest
+          /mochitest
+    external 
+    returns:
+    success: path for device root
+    failure: None
+    """
+  
+  def getAppRoot(self):
+    """
+    Either we will have /tests/fennec or /tests/firefox but we will never have
+    both.  Return the one that exists
+    TODO: ensure we can support org.mozilla.firefox
+    external function
+    returns:
+    success: path for app root
+    failure: None
+    """
+    
+    devroot = self.getDeviceRoot()
+    if (devroot == None):
+      return None
+
+    if (self.dirExists(devroot + '/fennec')):
+      return devroot + '/fennec'
+    elif (self.dirExists(devroot + '/firefox')):
+      return devroot + '/firefox'
+    elif (self.dirExsts('/data/data/org.mozilla.fennec')):
+      return 'org.mozilla.fennec'
+    elif (self.dirExists('/data/data/org.mozilla.firefox')):
+      return 'org.mozilla.firefox'
+    elif (self.dirExists('/data/data/org.mozilla.fennec_aurora')):
+      return 'org.mozilla.fennec_aurora'
+    elif (self.dirExists('/data/data/org.mozilla.firefox_beta')):
+      return 'org.mozilla.firefox_beta'
+
+    # Failure (either not installed or not a recognized platform)
     return None
 
-  # Either we will have /tests/fennec or /tests/firefox but we will never have
-  # both.  Return the one that exists
-  # TODO: ensure we can support org.mozilla.firefox
-  # external function
-  # returns:
-  #  success: path for app root
-  #  failure: None
-  def getAppRoot(self):
-    assert 0 == 1
-    return None
-
-  # Gets the directory location on the device for a specific test type
-  # Type is one of: xpcshell|reftest|mochitest
-  # external function
-  # returns:
-  #  success: path for test root
-  #  failure: None
   def getTestRoot(self, type):
+    """
+    Gets the directory location on the device for a specific test type
+    Type is one of: xpcshell|reftest|mochitest
+    external function
+    returns:
+    success: path for test root
+    failure: None
+    """
+    
     devroot = self.getDeviceRoot()
     if (devroot == None):
       return None
 
     if (re.search('xpcshell', type, re.I)):
       self.testRoot = devroot + '/xpcshell'
     elif (re.search('?(i)reftest', type)):
       self.testRoot = devroot + '/reftest'
     elif (re.search('?(i)mochitest', type)):
       self.testRoot = devroot + '/mochitest'
     return self.testRoot
 
-  # Sends a specific process ID a signal code and action.
-  # For Example: SIGINT and SIGDFL to process x
   def signal(self, processID, signalType, signalAction):
-    # currently not implemented in device agent - todo
+    """
+    Sends a specific process ID a signal code and action.
+    For Example: SIGINT and SIGDFL to process x
+    """
+    #currently not implemented in device agent - todo
+    
     pass
 
-  # Get a return code from process ending -- needs support on device-agent
   def getReturnCode(self, processID):
+    """Get a return code from process ending -- needs support on device-agent"""
     # TODO: make this real
+    
     return 0
 
-  # external function
-  # returns:
-  #  success: output of unzip command
-  #  failure: None
+  @abstractmethod
   def unpackFile(self, filename):
-    return None
-
-  # external function
-  # returns:
-  #  success: status from test agent
-  #  failure: None
+    """
+    external function
+    returns:
+    success: output of unzip command
+    failure: None
+    """
+    
+  @abstractmethod
   def reboot(self, ipAddr=None, port=30000):
-    assert 0 == 1
-    return None
-
-  # validate localDir from host to remoteDir on the device
-  # external function
-  # returns:
-  #  success: True
-  #  failure: False
+    """
+    external function
+    returns:
+    success: status from test agent
+    failure: None
+    """
+    
   def validateDir(self, localDir, remoteDir):
+    """
+    validate localDir from host to remoteDir on the device
+    external function
+    returns:
+    success: True
+    failure: False
+    """
+    
     if (self.debug >= 2): print "validating directory: " + localDir + " to " + remoteDir
     for root, dirs, files in os.walk(localDir):
       parts = root.split(localDir)
       for file in files:
         remoteRoot = remoteDir + '/' + parts[1]
         remoteRoot = remoteRoot.replace('/', '/')
         if (parts[1] == ""): remoteRoot = remoteDir
         remoteName = remoteRoot + '/' + file
         if (self.validateFile(remoteName, os.path.join(root, file)) <> True):
             return False
     return True
-
-  # Returns information about the device:
-  # Directive indicates the information you want to get, your choices are:
-  # os - name of the os
-  # id - unique id of the device
-  # uptime - uptime of the device
-  # systime - system time of the device
-  # screen - screen resolution
-  # memory - memory stats
-  # process - list of running processes (same as ps)
-  # disk - total, free, available bytes on disk
-  # power - power status (charge, battery temp)
-  # all - all of them - or call it with no parameters to get all the information
-  # returns:
-  #   success: dict of info strings by directive name
-  #   failure: {}
+    
+  @abstractmethod
   def getInfo(self, directive=None):
-    assert 0 == 1
-    return {}
-
-  # external function
-  # returns:
-  #  success: output from agent for inst command
-  #  failure: None
+    """
+    Returns information about the device:
+    Directive indicates the information you want to get, your choices are:
+    os - name of the os
+    id - unique id of the device
+    uptime - uptime of the device
+    systime - system time of the device
+    screen - screen resolution
+    memory - memory stats
+    process - list of running processes (same as ps)
+    disk - total, free, available bytes on disk
+    power - power status (charge, battery temp)
+    all - all of them - or call it with no parameters to get all the information
+    returns:
+    success: dict of info strings by directive name
+    failure: None
+    """
+    
+  @abstractmethod
   def installApp(self, appBundlePath, destPath=None):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: True
-  #  failure: None
+    """
+    external function
+    returns:
+    success: output from agent for inst command
+    failure: None
+    """
+    
+  @abstractmethod
   def uninstallAppAndReboot(self, appName, installPath=None):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: text status from command or callback server
-  #  failure: None
-  def updateApp(self, appBundlePath, processName=None, destPath=None, ipAddr=None, port=30000):
-    assert 0 == 1
-    return None
-
-  # external function
-  # returns:
-  #  success: time in ms
-  #  failure: None
+    """
+    external function
+    returns:
+    success: True
+    failure: None
+    """
+    
+  @abstractmethod
+  def updateApp(self, appBundlePath, processName=None,
+                destPath=None, ipAddr=None, port=30000):
+    """
+    external function
+    returns:
+    success: text status from command or callback server
+    failure: None
+    """
+  
+  @abstractmethod
   def getCurrentTime(self):
-    assert 0 == 1
-    return None
-
+    """
+    external function
+    returns:
+    success: time in ms
+    failure: None
+    """
 
 class NetworkTools:
   def __init__(self):
     pass
 
   # Utilities to get the local ip address
   def getInterfaceIp(self, ifname):
     if os.name != "nt":
@@ -478,20 +557,17 @@ class NetworkTools:
                               s.fileno(),
                               0x8915,  # SIOCGIFADDR
                               struct.pack('256s', ifname[:15])
                               )[20:24])
     else:
       return None
 
   def getLanIp(self):
-    try:
-      ip = socket.gethostbyname(socket.gethostname())
-    except socket.gaierror:
-      ip = socket.gethostbyname(socket.gethostname() + ".local") # for Mac OS X
+    ip = socket.gethostbyname(socket.gethostname())
     if ip.startswith("127.") and os.name != "nt":
       interfaces = ["eth0","eth1","eth2","wlan0","wlan1","wifi0","ath0","ath1","ppp0"]
       for ifname in interfaces:
         try:
           ip = self.getInterfaceIp(ifname)
           break;
         except IOError:
           pass
@@ -516,9 +592,8 @@ class NetworkTools:
           if seed > maxportnum:
             print "Could not find open port after checking 5000 ports"
           raise
         seed += 1
     except:
       print "Socket error trying to find open port"
         
     return seed
-
--- a/build/mobile/devicemanagerADB.py
+++ b/build/mobile/devicemanagerADB.py
@@ -110,24 +110,27 @@ class DeviceManagerADB(DeviceManager):
     # adb "push" accepts a directory as an argument, but if the directory
     # contains symbolic links, the links are pushed, rather than the linked
     # files; we either zip/unzip or push file-by-file to get around this 
     # limitation
     try:
       if (not self.dirExists(remoteDir)):
         self.mkDirs(remoteDir+"/x")
       if (self.useZip):
-        localZip = tempfile.mktemp()+".zip"
-        remoteZip = remoteDir + "/adbdmtmp.zip"
-        subprocess.check_output(["zip", "-r", localZip, '.'], cwd=localDir)
-        self.pushFile(localZip, remoteZip)
-        os.remove(localZip)
-        data = self.runCmdAs(["shell", "unzip", "-o", remoteZip, "-d", remoteDir]).stdout.read()
-        self.checkCmdAs(["shell", "rm", remoteZip])
-        if (re.search("unzip: exiting", data) or re.search("Operation not permitted", data)):
+        try:
+          localZip = tempfile.mktemp()+".zip"
+          remoteZip = remoteDir + "/adbdmtmp.zip"
+          subprocess.check_output(["zip", "-r", localZip, '.'], cwd=localDir)
+          self.pushFile(localZip, remoteZip)
+          os.remove(localZip)
+          data = self.runCmdAs(["shell", "unzip", "-o", remoteZip, "-d", remoteDir]).stdout.read()
+          self.checkCmdAs(["shell", "rm", remoteZip])
+          if (re.search("unzip: exiting", data) or re.search("Operation not permitted", data)):
+            raise Exception("unzip failed, or permissions error")
+        except:
           print "zip/unzip failure: falling back to normal push"
           self.useZip = False
           self.pushDir(localDir, remoteDir)
       else:
         for root, dirs, files in os.walk(localDir, followlinks='true'):
           relRoot = os.path.relpath(root, localDir)
           for file in files:
             localFile = os.path.join(root, file)
--- a/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -40,17 +40,17 @@ topsrcdir   = @top_srcdir@
 srcdir      = @srcdir@
 VPATH       = @srcdir@
 TESTPATH    = $(topsrcdir)/mobile/android/base/tests
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = robocop
 
-ROBOTIUM_PATH = $(srcdir)/robotium-solo-3.0.jar
+ROBOTIUM_PATH = $(srcdir)/robotium-solo-3.1.jar
 
 JAVAFILES = \
   R.java \
 
 _JAVA_HARNESS = \
   Actions.java \
   Assert.java \
   Driver.java \
--- a/build/mobile/robocop/README
+++ b/build/mobile/robocop/README
@@ -1,9 +1,9 @@
 Robocop is a Mozilla project which uses Robotium to test Firefox on Android devices.
 
 Robotium is an open source tool licensed under the Apache 2.0 license and the original 
 source can be found here:
 http://code.google.com/p/robotium/
 
-We are including robotium-solo-3.0.jar as a binary and are not modifying it in anyway 
+We are including robotium-solo-3.1.jar as a binary and are not modifying it in anyway 
 from the original download found at: 
 http://code.google.com/p/robotium/
deleted file mode 100644
index 3305251f61d61702e0f3dd61f67eb11e984ac587..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0ba05859b90a8c29ca519e228674db9aebe69d90
GIT binary patch
literal 49691
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
KV6(Nqwf+y-lXzPI
--- a/build/unix/build-toolchain/build-gcc.py
+++ b/build/unix/build-toolchain/build-gcc.py
@@ -66,16 +66,24 @@ def build_one_stage(env, stage_dir):
                    "--with-mpfr=%s" % lib_inst_dir])
 
     tool_inst_dir = stage_dir + '/inst'
 
     binutils_build_dir = stage_dir + '/binutils'
     build_package(binutils_source_dir, binutils_build_dir,
                   ["--prefix=%s" % tool_inst_dir])
 
+    glibc_build_dir = stage_dir + '/glibc'
+    build_package(glibc_source_dir, glibc_build_dir,
+                  ["--disable-profile",
+                   "--enable-add-ons=nptl",
+                   "--without-selinux",
+                   "--enable-kernel=2.6.25",
+                   "--prefix=%s" % tool_inst_dir])
+
     gcc_build_dir = stage_dir + '/gcc'
     build_package(gcc_source_dir, gcc_build_dir,
                   ["--prefix=%s" % tool_inst_dir,
                    "--enable-__cxa_atexit",
                    "--with-gmp=%s" % lib_inst_dir,
                    "--with-mpfr=%s" % lib_inst_dir,
                    "--with-mpc=%s" % lib_inst_dir,
                    "--enable-languages=c,c++",
@@ -91,54 +99,61 @@ def build_tar_package(tar, name, base, d
 ##############################################
 
 source_dir = os.path.realpath('src')
 
 def build_source_dir(prefix, version):
     return source_dir + '/' + prefix + version
 
 binutils_version = "2.21.1"
+glibc_version = "2.13" #FIXME: should probably use 2.5.1
 tar_version = "1.26"
 gcc_version = "4.5.2"
 mpfr_version = "2.4.2"
 gmp_version = "5.0.1"
 mpc_version = "0.8.1"
 
 binutils_source_uri = "http://ftp.gnu.org/gnu/binutils/binutils-%sa.tar.bz2" % \
     binutils_version
+glibc_source_uri = "http://ftp.gnu.org/gnu/glibc/glibc-%s.tar.bz2" % \
+    glibc_version
 tar_source_uri = "http://ftp.gnu.org/gnu/tar/tar-%s.tar.bz2" % \
     tar_version
 gcc_source_uri = "http://ftp.gnu.org/gnu/gcc/gcc-%s/gcc-%s.tar.bz2" % \
     (gcc_version, gcc_version)
 mpfr_source_uri = "http://www.mpfr.org/mpfr-%s/mpfr-%s.tar.bz2" % \
     (mpfr_version, mpfr_version)
 gmp_source_uri = "http://ftp.gnu.org/gnu/gmp/gmp-%s.tar.bz2" % gmp_version
 mpc_source_uri = "http://www.multiprecision.org/mpc/download/mpc-%s.tar.gz" % \
     mpc_version
 
 binutils_source_tar = download_uri(binutils_source_uri)
+glibc_source_tar = download_uri(glibc_source_uri)
 tar_source_tar = download_uri(tar_source_uri)
 mpc_source_tar = download_uri(mpc_source_uri)
 mpfr_source_tar = download_uri(mpfr_source_uri)
 gmp_source_tar = download_uri(gmp_source_uri)
 gcc_source_tar = download_uri(gcc_source_uri)
 
 build_dir = os.path.realpath('build')
 
 binutils_source_dir  = build_source_dir('binutils-', binutils_version)
+glibc_source_dir  = build_source_dir('glibc-', glibc_version)
 tar_source_dir  = build_source_dir('tar-', tar_version)
 mpc_source_dir  = build_source_dir('mpc-', mpc_version)
 mpfr_source_dir = build_source_dir('mpfr-', mpfr_version)
 gmp_source_dir  = build_source_dir('gmp-', gmp_version)
 gcc_source_dir  = build_source_dir('gcc-', gcc_version)
 
 if not os.path.exists(source_dir):
     os.mkdir(source_dir)
     extract(binutils_source_tar, source_dir)
     patch('binutils-deterministic.patch', 1, binutils_source_dir)
+    extract(glibc_source_tar, source_dir)
+    patch('glibc-deterministic.patch', 1, glibc_source_dir)
     extract(tar_source_tar, source_dir)
     extract(mpc_source_tar, source_dir)
     extract(mpfr_source_tar, source_dir)
     extract(gmp_source_tar, source_dir)
     extract(gcc_source_tar, source_dir)
     patch('plugin_finish_decl.diff', 0, gcc_source_dir)
     patch('pr49911.diff', 1, gcc_source_dir)
     patch('r159628-r163231-r171807.patch', 1, gcc_source_dir)
@@ -153,12 +168,13 @@ build_tar(build_dir, tar_inst_dir)
 stage1_dir = build_dir + '/stage1'
 build_one_stage({"CC": "gcc", "CXX" : "g++"}, stage1_dir)
 
 stage1_tool_inst_dir = stage1_dir + '/inst'
 stage2_dir = build_dir + '/stage2'
 build_one_stage({"CC"     : stage1_tool_inst_dir + "/bin/gcc",
                  "CXX"    : stage1_tool_inst_dir + "/bin/g++",
                  "AR"     : stage1_tool_inst_dir + "/bin/ar",
-                 "RANLIB" : "true" })
+                 "RANLIB" : "true" },
+                stage2_dir)
 
 build_tar_package(tar_inst_dir + "/bin/tar",
                   "toolchain.tar", stage2_dir, "inst")
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -143,16 +143,17 @@ MOZ_UPDATER	= @MOZ_UPDATER@
 MOZ_UPDATE_CHANNEL	= @MOZ_UPDATE_CHANNEL@
 MOZ_UPDATE_PACKAGING	= @MOZ_UPDATE_PACKAGING@
 MOZ_DISABLE_PARENTAL_CONTROLS = @MOZ_DISABLE_PARENTAL_CONTROLS@
 NS_ENABLE_TSF = @NS_ENABLE_TSF@
 MOZ_SPELLCHECK = @MOZ_SPELLCHECK@
 MOZ_ANDROID_HISTORY = @MOZ_ANDROID_HISTORY@
 MOZ_WEBSMS_BACKEND = @MOZ_WEBSMS_BACKEND@
 MOZ_JAVA_COMPOSITOR = @MOZ_JAVA_COMPOSITOR@
+MOZ_ONLY_TOUCH_EVENTS = @MOZ_ONLY_TOUCH_EVENTS@
 MOZ_TOUCH = @MOZ_TOUCH@
 MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
 MOZ_FEEDS = @MOZ_FEEDS@
 MOZ_TOOLKIT_SEARCH = @MOZ_TOOLKIT_SEARCH@
 MOZ_PLACES = @MOZ_PLACES@
 MOZ_SAFE_BROWSING = @MOZ_SAFE_BROWSING@
 MOZ_URL_CLASSIFIER = @MOZ_URL_CLASSIFIER@
 MOZ_ZIPWRITER = @MOZ_ZIPWRITER@
--- a/config/expandlibs.py
+++ b/config/expandlibs.py
@@ -81,16 +81,21 @@ def relativize(path):
         del abspath[0]
     if not curdir and not abspath:
         return '.'
     relpath = os.path.join(*[os.pardir for i in curdir] + abspath)
     if len(path) > len(relpath):
         return relpath
     return path
 
+def isObject(path):
+    '''Returns whether the given path points to an object file, that is,
+    ends with OBJ_SUFFIX or .i_o'''
+    return os.path.splitext(path)[1] in [conf.OBJ_SUFFIX, '.i_o']
+
 class LibDescriptor(dict):
     KEYS = ['OBJS', 'LIBS']
 
     def __init__(self, content=None):
         '''Creates an instance of a lib descriptor, initialized with contents
         from a list of strings when given. This is intended for use with
         file.readlines()'''
         if isinstance(content, list) and all([isinstance(item, str) for item in content]):
--- a/config/expandlibs_exec.py
+++ b/config/expandlibs_exec.py
@@ -51,17 +51,17 @@ See https://bugzilla.mozilla.org/show_bu
 
 With the --reorder argument, followed by a file name, it will reorder the
 object files from the command line according to the order given in the file.
 Implies --extract.
 '''
 from __future__ import with_statement
 import sys
 import os
-from expandlibs import ExpandArgs, relativize
+from expandlibs import ExpandArgs, relativize, isObject
 import expandlibs_config as conf
 from optparse import OptionParser
 import subprocess
 import tempfile
 import shutil
 
 class ExpandArgsMore(ExpandArgs):
     ''' Meant to be used as 'with ExpandArgsMore(args) as ...: '''
@@ -92,29 +92,29 @@ class ExpandArgsMore(ExpandArgs):
                 if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
                     newlist += self._extract(self._expand_desc(arg))
                 elif os.path.exists(arg) and len(ar_extract):
                     tmp = tempfile.mkdtemp(dir=os.curdir)
                     self.tmp.append(tmp)
                     subprocess.call(ar_extract + [os.path.abspath(arg)], cwd=tmp)
                     objs = []
                     for root, dirs, files in os.walk(tmp):
-                        objs += [relativize(os.path.join(root, f)) for f in files if os.path.splitext(f)[1] in [conf.OBJ_SUFFIX, '.i_o']]
+                        objs += [relativize(os.path.join(root, f)) for f in files if isObject(f)]
                     newlist += objs
                 else:
                     newlist += [arg]
             else:
                 newlist += [arg]
         return newlist
 
     def makelist(self):
         '''Replaces object file names with a temporary list file, using a
         list format depending on the EXPAND_LIBS_LIST_STYLE variable
         '''
-        objs = [o for o in self if os.path.splitext(o)[1] == conf.OBJ_SUFFIX]
+        objs = [o for o in self if isObject(o)]
         if not len(objs): return
         fd, tmp = tempfile.mkstemp(suffix=".list",dir=os.curdir)
         if conf.EXPAND_LIBS_LIST_STYLE == "linkerscript":
             content = ["INPUT(%s)\n" % obj for obj in objs]
             ref = tmp
         elif conf.EXPAND_LIBS_LIST_STYLE == "list":
             content = ["%s\n" % obj for obj in objs]
             ref = "@" + tmp
@@ -129,25 +129,25 @@ class ExpandArgsMore(ExpandArgs):
         newlist = self[0:idx] + [ref] + [item for item in self[idx:] if item not in objs]
         self[0:] = newlist
 
     def reorder(self, order_list):
         '''Given a list of file names without OBJ_SUFFIX, rearrange self
         so that the object file names it contains are ordered according to
         that list.
         '''
-        objs = [o for o in self if o.endswith(conf.OBJ_SUFFIX)]
+        objs = [o for o in self if isObject(o)]
         if not objs: return
         idx = self.index(objs[0])
         # Keep everything before the first object, then the ordered objects,
         # then any other objects, then any non-objects after the first object
         objnames = dict([(os.path.splitext(os.path.basename(o))[0], o) for o in objs])
         self[0:] = self[0:idx] + [objnames[o] for o in order_list if o in objnames] + \
                    [o for o in objs if os.path.splitext(os.path.basename(o))[0] not in order_list] + \
-                   [x for x in self[idx:] if not x.endswith(conf.OBJ_SUFFIX)]
+                   [x for x in self[idx:] if not isObject(x)]
 
 
 def main():
     parser = OptionParser()
     parser.add_option("--extract", action="store_true", dest="extract",
         help="when a library has no descriptor file, extract it first, when possible")
     parser.add_option("--uselist", action="store_true", dest="uselist",
         help="use a list file for objects when executing a command")
--- a/config/expandlibs_gen.py
+++ b/config/expandlibs_gen.py
@@ -36,22 +36,22 @@
 # ***** END LICENSE BLOCK *****
 
 '''Given a list of object files and library names, prints a library
 descriptor to standard output'''
 
 import sys
 import os
 import expandlibs_config as conf
-from expandlibs import LibDescriptor
+from expandlibs import LibDescriptor, isObject
 
 def generate(args):
     desc = LibDescriptor()
     for arg in args:
-        if os.path.splitext(arg)[1] in [conf.OBJ_SUFFIX, '.i_o']:
+        if isObject(arg):
             desc['OBJS'].append(os.path.abspath(arg))
         elif os.path.splitext(arg)[1] == conf.LIB_SUFFIX and \
              (os.path.exists(arg) or os.path.exists(arg + conf.LIBS_DESC_SUFFIX)):
             desc['LIBS'].append(os.path.abspath(arg))
     return desc
 
 if __name__ == '__main__':
     print generate(sys.argv[1:])
--- a/configure.in
+++ b/configure.in
@@ -124,17 +124,17 @@ GTK2_VERSION=2.10.0
 WINDRES_VERSION=2.14.90
 W32API_VERSION=3.14
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
 GIO_VERSION=2.18
 STARTUP_NOTIFICATION_VERSION=0.8
 DBUS_VERSION=0.60
-SQLITE_VERSION=3.7.7.1
+SQLITE_VERSION=3.7.10
 LIBNOTIFY_VERSION=0.4
 
 MSMANIFEST_TOOL=
 
 dnl Set various checks
 dnl ========================================================
 MISSING_X=
 AC_PROG_AWK
--- a/content/base/src/Link.h
+++ b/content/base/src/Link.h
@@ -46,18 +46,18 @@
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/IHistory.h"
 
 namespace mozilla {
 namespace dom {
 
 #define MOZILLA_DOM_LINK_IMPLEMENTATION_IID \
-  { 0xa687a99c, 0x3893, 0x45c0, \
-    {0x8e, 0xab, 0xb8, 0xf7, 0xd7, 0x9e, 0x9e, 0x7b } }
+  { 0x7EA57721, 0xE373, 0x458E, \
+    {0x8F, 0x44, 0xF8, 0x96, 0x56, 0xB4, 0x14, 0xF5 } }
 
 class Link : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_LINK_IMPLEMENTATION_IID)
 
   static const nsLinkState defaultState = eLinkState_Unknown;
 
@@ -108,16 +108,34 @@ public:
    *        true if ResetLinkState should notify the owning document about style
    *        changes or false if it should not.
    */
   void ResetLinkState(bool aNotify);
   
   // This method nevers returns a null element.
   Element* GetElement() const { return mElement; }
 
+  /**
+   * DNS prefetch has been deferred until later, e.g. page load complete.
+   */
+  virtual void OnDNSPrefetchDeferred() { /*do nothing*/ }
+  
+  /**
+   * DNS prefetch has been submitted to Host Resolver.
+   */
+  virtual void OnDNSPrefetchRequested() { /*do nothing*/ }
+
+  /**
+   * Checks if DNS Prefetching is ok
+   * 
+   * @returns boolean
+   *          Defaults to true; should be overridden for specialised cases
+   */
+  virtual bool HasDeferredDNSPrefetchRequest() { return true; }
+
 protected:
   virtual ~Link();
 
   bool HasCachedURI() const { return !!mCachedURI; }
 
 private:
   /**
    * Unregisters from History so this node no longer gets notifications about
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -92,16 +92,17 @@
 #include "nsFrameLoader.h"
 
 #include "nsObjectLoadingContent.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIChannelPolicy.h"
 #include "nsChannelPolicy.h"
 #include "mozilla/dom/Element.h"
+#include "sampler.h"
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
 #endif
 
 #define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
 
@@ -504,16 +505,17 @@ nsObjectLoadingContent::~nsObjectLoading
   }
 }
 
 // nsIRequestObserver
 NS_IMETHODIMP
 nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
                                        nsISupports *aContext)
 {
+  SAMPLE_LABEL("nsObjectLoadingContent", "OnStartRequest");
   if (aRequest != mChannel || !aRequest) {
     // This is a bit of an edge case - happens when a new load starts before the
     // previous one got here
     return NS_BINDING_ABORTED;
   }
 
   AutoNotifier notifier(this, true);
 
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1815,16 +1815,17 @@ IsSameOrBaseChannel(nsIRequest* aPossibl
 
   return aPossibleBase == aChannel;
 }
 
 /* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
 NS_IMETHODIMP
 nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
 {
+  SAMPLE_LABEL("nsXMLHttpRequest", "OnStartRequest");
   nsresult rv = NS_OK;
   if (!mFirstStartRequestSeen && mRequestObserver) {
     mFirstStartRequestSeen = true;
     mRequestObserver->OnStartRequest(request, ctxt);
   }
 
   if (!IsSameOrBaseChannel(request, mChannel)) {
     return NS_OK;
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -216,17 +216,16 @@ NS_NewCanvasRenderingContextWebGL(nsIDOM
     NS_ADDREF(*aResult = ctx);
     return NS_OK;
 }
 
 WebGLContext::WebGLContext()
     : mCanvasElement(nsnull),
       gl(nsnull)
 {
-    mWidth = mHeight = 0;
     mGeneration = 0;
     mInvalidated = false;
     mResetLayer = true;
     mVerbose = false;
     mOptionsFrozen = false;
 
     mActiveTexture = 0;
     mWebGLError = LOCAL_GL_NO_ERROR;
@@ -1100,16 +1099,27 @@ WebGLContext::EnsureBackbufferClearedAsN
     ForceClearFramebufferWithDefaultValues(LOCAL_GL_COLOR_BUFFER_BIT |
                                            LOCAL_GL_DEPTH_BUFFER_BIT |
                                            LOCAL_GL_STENCIL_BUFFER_BIT,
                                            nsIntRect(0, 0, mWidth, mHeight));
 
     Invalidate();
 }
 
+nsresult
+WebGLContext::DummyFramebufferOperation(const char *info)
+{
+    WebGLenum status;
+    CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER, &status);
+    if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE)
+        return NS_OK;
+    else
+        return ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
+}
+
 // We use this timer for many things. Here are the things that it is activated for:
 // 1) If a script is using the MOZ_WEBGL_lose_context extension.
 // 2) If we are using EGL and _NOT ANGLE_, we query periodically to see if the
 //    CONTEXT_LOST_WEBGL error has been triggered.
 // 3) If we are using ANGLE, or anything that supports ARB_robustness, query the
 //    GPU periodically to see if the reset status bit has been set.
 // In all of these situations, we use this timer to send the script context lost
 // and restored events asynchronously. For example, if it triggers a context loss,
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -92,16 +92,17 @@ class WebGLBuffer;
 class WebGLProgram;
 class WebGLShader;
 class WebGLFramebuffer;
 class WebGLRenderbuffer;
 class WebGLUniformLocation;
 class WebGLExtension;
 struct WebGLVertexAttribData;
 
+class WebGLRectangleObject;
 class WebGLContextBoundObject;
 
 enum FakeBlackStatus { DoNotNeedFakeBlack, DoNeedFakeBlack, DontKnowIfNeedFakeBlack };
 
 struct VertexAttrib0Status {
     enum { Default, EmulatedUninitializedArray, EmulatedInitializedArray };
 };
 
@@ -430,16 +431,57 @@ private:
             NS_RUNTIMEABORT("ran out of monotonic ids!");
         return mCurrentMonotonicHandle.value();
     }
 
     nsTArray<Entry> mArray;
     CheckedInt<WebGLMonotonicHandle> mCurrentMonotonicHandle;
 };
 
+// this class is a mixin for GL objects that have dimensions
+// that we need to track.
+class WebGLRectangleObject
+{
+public:
+    WebGLRectangleObject()
+        : mWidth(0), mHeight(0) { }
+
+    WebGLRectangleObject(WebGLsizei width, WebGLsizei height)
+        : mWidth(width), mHeight(height) { }
+
+    WebGLsizei Width() const { return mWidth; }
+    void width(WebGLsizei value) { mWidth = value; }
+
+    WebGLsizei Height() const { return mHeight; }
+    void height(WebGLsizei value) { mHeight = value; }
+
+    void setDimensions(WebGLsizei width, WebGLsizei height) {
+        mWidth = width;
+        mHeight = height;
+    }
+
+    void setDimensions(WebGLRectangleObject *rect) {
+        if (rect) {
+            mWidth = rect->Width();
+            mHeight = rect->Height();
+        } else {
+            mWidth = 0;
+            mHeight = 0;
+        }
+    }
+
+    bool HasSameDimensionsAs(const WebGLRectangleObject& other) const {
+        return Width() == other.Width() && Height() == other.Height(); 
+    }
+
+protected:
+    WebGLsizei mWidth;
+    WebGLsizei mHeight;
+};
+
 struct WebGLContextOptions {
     // these are defaults
     WebGLContextOptions()
         : alpha(true), depth(true), stencil(false),
           premultipliedAlpha(true), antialias(true),
           preserveDrawingBuffer(false)
     { }
 
@@ -464,17 +506,18 @@ struct WebGLContextOptions {
     bool antialias;
     bool preserveDrawingBuffer;
 };
 
 class WebGLContext :
     public nsIDOMWebGLRenderingContext,
     public nsICanvasRenderingContextInternal,
     public nsSupportsWeakReference,
-    public nsITimerCallback
+    public nsITimerCallback,
+    public WebGLRectangleObject
 {
     friend class WebGLMemoryReporter;
     friend class WebGLExtensionLoseContext;
     friend class WebGLContextUserData;
 
 public:
     WebGLContext();
     virtual ~WebGLContext();
@@ -518,37 +561,42 @@ public:
     bool RestoreContext();
 
     nsresult SynthesizeGLError(WebGLenum err);
     nsresult SynthesizeGLError(WebGLenum err, const char *fmt, ...);
 
     nsresult ErrorInvalidEnum(const char *fmt = 0, ...);
     nsresult ErrorInvalidOperation(const char *fmt = 0, ...);
     nsresult ErrorInvalidValue(const char *fmt = 0, ...);
+    nsresult ErrorInvalidFramebufferOperation(const char *fmt = 0, ...);
     nsresult ErrorInvalidEnumInfo(const char *info, PRUint32 enumvalue) {
         return ErrorInvalidEnum("%s: invalid enum value 0x%x", info, enumvalue);
     }
     nsresult ErrorOutOfMemory(const char *fmt = 0, ...);
-    
+
     const char *ErrorName(GLenum error);
 
+    nsresult DummyFramebufferOperation(const char *info);
+
     WebGLTexture *activeBoundTextureForTarget(WebGLenum target) {
         return target == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture]
                                              : mBoundCubeMapTextures[mActiveTexture];
     }
 
     already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                  CanvasLayer *aOldLayer,
                                                  LayerManager *aManager);
     void MarkContextClean() { mInvalidated = false; }
 
     // a number that increments every time we have an event that causes
     // all context resources to be lost.
     PRUint32 Generation() { return mGeneration.value(); }
 
+    const WebGLRectangleObject *FramebufferRectangleObject() const;
+
     // this is similar to GLContext::ClearSafely, but is more comprehensive
     // (takes care of scissor, stencil write mask, dithering, viewport...)
     // WebGL has more complex needs than GLContext as content controls GL state.
     void ForceClearFramebufferWithDefaultValues(PRUint32 mask, const nsIntRect& viewportRect);
 
     // if the preserveDrawingBuffer context option is false, we need to clear the back buffer
     // after it's been presented to the compositor. This function does that if needed.
     // See section 2.2 in the WebGL spec.
@@ -637,17 +685,16 @@ protected:
 
     nsCOMPtr<nsIDOMHTMLCanvasElement> mCanvasElement;
     nsHTMLCanvasElement *HTMLCanvasElement() {
         return static_cast<nsHTMLCanvasElement*>(mCanvasElement.get());
     }
 
     nsRefPtr<gl::GLContext> gl;
 
-    PRInt32 mWidth, mHeight;
     CheckedUint32 mGeneration;
 
     WebGLContextOptions mOptions;
 
     bool mInvalidated;
     bool mResetLayer;
     bool mVerbose;
     bool mOptionsFrozen;
@@ -906,55 +953,16 @@ public:
     friend class WebGLFramebuffer;
     friend class WebGLRenderbuffer;
     friend class WebGLProgram;
     friend class WebGLBuffer;
     friend class WebGLShader;
     friend class WebGLUniformLocation;
 };
 
-// this class is a mixin for GL objects that have dimensions
-// that we need to track.
-class WebGLRectangleObject
-{
-protected:
-    WebGLRectangleObject()
-        : mWidth(0), mHeight(0) { }
-
-public:
-    WebGLsizei width() const { return mWidth; }
-    void width(WebGLsizei value) { mWidth = value; }
-
-    WebGLsizei height() const { return mHeight; }
-    void height(WebGLsizei value) { mHeight = value; }
-
-    void setDimensions(WebGLsizei width, WebGLsizei height) {
-        mWidth = width;
-        mHeight = height;
-    }
-
-    void setDimensions(WebGLRectangleObject *rect) {
-        if (rect) {
-            mWidth = rect->width();
-            mHeight = rect->height();
-        } else {
-            mWidth = 0;
-            mHeight = 0;
-        }
-    }
-
-    bool HasSameDimensionsAs(const WebGLRectangleObject& other) const {
-        return width() == other.width() && height() == other.height(); 
-    }
-
-protected:
-    WebGLsizei mWidth;
-    WebGLsizei mHeight;
-};
-
 // This class is a mixin for objects that are tied to a specific
 // context (which is to say, all of them).  They provide initialization
 // as well as comparison with the current context.
 class WebGLContextBoundObject
 {
 public:
     WebGLContextBoundObject(WebGLContext *context) {
         mContext = context;
@@ -1201,21 +1209,22 @@ protected:
     bool mHasEverBeenBound;
     WebGLuint mGLName;
 
     // we store information about the various images that are part of
     // this texture (cubemap faces, mipmap levels)
 
 public:
 
-    struct ImageInfo {
-        ImageInfo() : mWidth(0), mHeight(0), mFormat(0), mType(0), mIsDefined(false) {}
+    class ImageInfo : public WebGLRectangleObject {
+    public:
+        ImageInfo() : mFormat(0), mType(0), mIsDefined(false) {}
         ImageInfo(WebGLsizei width, WebGLsizei height,
                   WebGLenum format, WebGLenum type)
-            : mWidth(width), mHeight(height), mFormat(format), mType(type), mIsDefined(true) {}
+            : WebGLRectangleObject(width, height), mFormat(format), mType(type), mIsDefined(true) {}
 
         bool operator==(const ImageInfo& a) const {
             return mWidth == a.mWidth && mHeight == a.mHeight &&
                    mFormat == a.mFormat && mType == a.mType;
         }
         bool operator!=(const ImageInfo& a) const {
             return !(*this == a);
         }
@@ -1230,19 +1239,23 @@ public:
                    is_pot_assuming_nonnegative(mHeight); // negative sizes should never happen (caught in texImage2D...)
         }
         PRInt64 MemoryUsage() const {
             if (!mIsDefined)
                 return 0;
             PRInt64 texelSize = WebGLContext::GetTexelSize(mFormat, mType);
             return PRInt64(mWidth) * PRInt64(mHeight) * texelSize;
         }
-        WebGLsizei mWidth, mHeight;
+        WebGLenum Format() const { return mFormat; }
+        WebGLenum Type() const { return mType; }
+    protected:
         WebGLenum mFormat, mType;
         bool mIsDefined;
+
+        friend class WebGLTexture;
     };
 
     ImageInfo& ImageInfoAt(size_t level, size_t face = 0) {
 #ifdef DEBUG
         if (face >= mFacesCount)
             NS_ERROR("wrong face index, must be 0 for TEXTURE_2D and at most 5 for cube maps");
 #endif
         // no need to check level as a wrong value would be caught by ElementAt().
@@ -1821,17 +1834,17 @@ public:
 
     WebGLenum InternalFormat() const { return mInternalFormat; }
     void SetInternalFormat(WebGLenum aInternalFormat) { mInternalFormat = aInternalFormat; }
     
     WebGLenum InternalFormatForGL() const { return mInternalFormatForGL; }
     void SetInternalFormatForGL(WebGLenum aInternalFormatForGL) { mInternalFormatForGL = aInternalFormatForGL; }
     
     PRInt64 MemoryUsage() const {
-        PRInt64 pixels = PRInt64(width()) * PRInt64(height());
+        PRInt64 pixels = PRInt64(Width()) * PRInt64(Height());
         switch (mInternalFormatForGL) {
             case LOCAL_GL_STENCIL_INDEX8:
                 return pixels;
             case LOCAL_GL_RGBA4:
             case LOCAL_GL_RGB5_A1:
             case LOCAL_GL_RGB565:
             case LOCAL_GL_DEPTH_COMPONENT16:
                 return 2 * pixels;
@@ -1859,17 +1872,16 @@ protected:
     WebGLMonotonicHandle mMonotonicHandle;
     bool mHasEverBeenBound;
     bool mInitialized;
 
     friend class WebGLFramebuffer;
 };
 
 class WebGLFramebufferAttachment
-    : public WebGLRectangleObject
 {
     // deleting a texture or renderbuffer immediately detaches it
     WebGLRefPtr<WebGLTexture> mTexturePtr;
     WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
     WebGLenum mAttachmentPoint;
     WebGLint mTextureLevel;
     WebGLenum mTextureCubeMapFace;
 
@@ -1885,90 +1897,113 @@ public:
     bool IsDeleteRequested() const {
         return Texture() ? Texture()->IsDeleteRequested()
              : Renderbuffer() ? Renderbuffer()->IsDeleteRequested()
              : false;
     }
 
     bool HasAlpha() const {
         WebGLenum format = 0;
-        if (Texture() && Texture()->HasImageInfoAt(0,0))
-            format = mTexturePtr->ImageInfoAt(0,0).mFormat;
+        if (Texture() && Texture()->HasImageInfoAt(mTextureLevel, mTextureCubeMapFace))
+            format = Texture()->ImageInfoAt(mTextureLevel, mTextureCubeMapFace).Format();
         else if (Renderbuffer())
-            format = mRenderbufferPtr->InternalFormat();
+            format = Renderbuffer()->InternalFormat();
         return format == LOCAL_GL_RGBA ||
                format == LOCAL_GL_LUMINANCE_ALPHA ||
                format == LOCAL_GL_ALPHA ||
                format == LOCAL_GL_RGBA4 ||
                format == LOCAL_GL_RGB5_A1;
     }
 
     void SetTexture(WebGLTexture *tex, WebGLint level, WebGLenum face) {
         mTexturePtr = tex;
         mRenderbufferPtr = nsnull;
         mTextureLevel = level;
         mTextureCubeMapFace = face;
-        if (tex) {
-            const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face);
-            setDimensions(imageInfo.mWidth, imageInfo.mHeight);
-        } else {
-            setDimensions(0, 0);
-        }
     }
     void SetRenderbuffer(WebGLRenderbuffer *rb) {
         mTexturePtr = nsnull;
         mRenderbufferPtr = rb;
-        setDimensions(rb);
+    }
+    const WebGLTexture *Texture() const {
+        return mTexturePtr;
     }
-    WebGLTexture *Texture() const {
-        return mTexturePtr.get();
+    WebGLTexture *Texture() {
+        return mTexturePtr;
     }
-    WebGLRenderbuffer *Renderbuffer() const {
-        return mRenderbufferPtr.get();
+    const WebGLRenderbuffer *Renderbuffer() const {
+        return mRenderbufferPtr;
+    }
+    WebGLRenderbuffer *Renderbuffer() {
+        return mRenderbufferPtr;
     }
     WebGLint TextureLevel() const {
         return mTextureLevel;
     }
     WebGLenum TextureCubeMapFace() const {
         return mTextureCubeMapFace;
     }
 
-    bool IsIncompatibleWithAttachmentPoint() const
-    {
-        // textures can only be color textures in WebGL
-        if (mTexturePtr)
-            return mAttachmentPoint != LOCAL_GL_COLOR_ATTACHMENT0;
-
-        if (mRenderbufferPtr) {
-            WebGLenum format = mRenderbufferPtr->InternalFormat();
-            switch (mAttachmentPoint) {
-                case LOCAL_GL_COLOR_ATTACHMENT0:
-                    return format != LOCAL_GL_RGB565 &&
-                           format != LOCAL_GL_RGB5_A1 &&
-                           format != LOCAL_GL_RGBA4;
-                case LOCAL_GL_DEPTH_ATTACHMENT:
-                    return format != LOCAL_GL_DEPTH_COMPONENT16;
-                case LOCAL_GL_STENCIL_ATTACHMENT:
-                    return format != LOCAL_GL_STENCIL_INDEX8;
-                case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
-                    return format != LOCAL_GL_DEPTH_STENCIL;
-            }
-        }
-
-        return false; // no attachment at all, so no incompatibility
-    }
-
     bool HasUninitializedRenderbuffer() const {
         return mRenderbufferPtr && !mRenderbufferPtr->Initialized();
     }
 
     void Reset() {
         mTexturePtr = nsnull;
         mRenderbufferPtr = nsnull;
     }
+
+    const WebGLRectangleObject* RectangleObject() const {
+        if (Texture() && Texture()->HasImageInfoAt(mTextureLevel, mTextureCubeMapFace))
+            return &Texture()->ImageInfoAt(mTextureLevel, mTextureCubeMapFace);
+        else if (Renderbuffer())
+            return Renderbuffer();
+        else
+            return nsnull;
+    }
+    bool HasSameDimensionsAs(const WebGLFramebufferAttachment& other) const {
+        const WebGLRectangleObject *thisRect = RectangleObject();
+        const WebGLRectangleObject *otherRect = other.RectangleObject();
+        return thisRect &&
+               otherRect &&
+               thisRect->HasSameDimensionsAs(*otherRect);
+    }
+
+    bool IsComplete() const {
+        const WebGLRectangleObject *thisRect = RectangleObject();
+
+        if (!thisRect ||
+            !thisRect->Width() ||
+            !thisRect->Height())
+            return false;
+
+        if (mTexturePtr)
+            return mAttachmentPoint == LOCAL_GL_COLOR_ATTACHMENT0;
+
+        if (mRenderbufferPtr) {
+            WebGLenum format = mRenderbufferPtr->InternalFormat();
+            switch (mAttachmentPoint) {
+                case LOCAL_GL_COLOR_ATTACHMENT0:
+                    return format == LOCAL_GL_RGB565 ||
+                           format == LOCAL_GL_RGB5_A1 ||
+                           format == LOCAL_GL_RGBA4;
+                case LOCAL_GL_DEPTH_ATTACHMENT:
+                    return format == LOCAL_GL_DEPTH_COMPONENT16;
+                case LOCAL_GL_STENCIL_ATTACHMENT:
+                    return format == LOCAL_GL_STENCIL_INDEX8;
+                case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
+                    return format == LOCAL_GL_DEPTH_STENCIL;
+                default:
+                    NS_ABORT(); // should have been validated earlier
+            }
+        }
+
+        NS_ABORT(); // should never get there
+        return false;
+    }
 };
 
 class WebGLFramebuffer
     : public nsIWebGLFramebuffer
     , public WebGLRefCountedObject<WebGLFramebuffer>
     , public WebGLContextBoundObject
 {
 public:
@@ -1998,19 +2033,16 @@ public:
         mContext->gl->fDeleteFramebuffers(1, &mGLName);
         mContext->mFramebuffers.RemoveElement(mMonotonicHandle);
     }
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
     WebGLuint GLName() { return mGLName; }
 
-    WebGLsizei width() { return mColorAttachment.width(); }
-    WebGLsizei height() { return mColorAttachment.height(); }
-
     nsresult FramebufferRenderbuffer(WebGLenum target,
                                      WebGLenum attachment,
                                      WebGLenum rbtarget,
                                      nsIWebGLRenderbuffer *rbobj)
     {
         WebGLuint renderbuffername;
         bool isNull;
         WebGLRenderbuffer *wrb;
@@ -2109,60 +2141,33 @@ public:
             mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_STENCIL_ATTACHMENT, textarget, texturename, level);
         } else {
             mContext->gl->fFramebufferTexture2D(target, attachment, textarget, texturename, level);
         }
 
         return NS_OK;
     }
 
-    bool CheckAndInitializeRenderbuffers()
-    {
-        if (HasBadAttachments()) {
-            mContext->SynthesizeGLError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
-            return false;
-        }
-
-        if (mColorAttachment.HasUninitializedRenderbuffer() ||
-            mDepthAttachment.HasUninitializedRenderbuffer() ||
-            mStencilAttachment.HasUninitializedRenderbuffer() ||
-            mDepthStencilAttachment.HasUninitializedRenderbuffer())
-        {
-            InitializeRenderbuffers();
-        }
-
-        return true;
+    bool HasIncompleteAttachment() const {
+        return (mColorAttachment.IsDefined() && !mColorAttachment.IsComplete()) ||
+               (mDepthAttachment.IsDefined() && !mDepthAttachment.IsComplete()) ||
+               (mStencilAttachment.IsDefined() && !mStencilAttachment.IsComplete()) ||
+               (mDepthStencilAttachment.IsDefined() && !mDepthStencilAttachment.IsComplete());
     }
 
-    bool HasBadAttachments() const {
-        if (mColorAttachment.IsIncompatibleWithAttachmentPoint() ||
-            mDepthAttachment.IsIncompatibleWithAttachmentPoint() ||
-            mStencilAttachment.IsIncompatibleWithAttachmentPoint() ||
-            mDepthStencilAttachment.IsIncompatibleWithAttachmentPoint())
-        {
-            // some attachment is incompatible with its attachment point
-            return true;
-        }
-
-        if (int(mDepthAttachment.IsDefined()) +
-            int(mStencilAttachment.IsDefined()) +
-            int(mDepthStencilAttachment.IsDefined()) >= 2)
-        {
-            // has at least two among Depth, Stencil, DepthStencil
-            return true;
-        }
-
-        if (mDepthAttachment.IsDefined() && !mDepthAttachment.HasSameDimensionsAs(mColorAttachment))
-            return true;
-        if (mStencilAttachment.IsDefined() && !mStencilAttachment.HasSameDimensionsAs(mColorAttachment))
-            return true;
-        if (mDepthStencilAttachment.IsDefined() && !mDepthStencilAttachment.HasSameDimensionsAs(mColorAttachment))
-            return true;
-
-        return false;
+    bool HasDepthStencilConflict() const {
+        return int(mDepthAttachment.IsDefined()) +
+               int(mStencilAttachment.IsDefined()) +
+               int(mDepthStencilAttachment.IsDefined()) >= 2;
+    }
+
+    bool HasAttachmentsOfMismatchedDimensions() const {
+        return (mDepthAttachment.IsDefined() && !mDepthAttachment.HasSameDimensionsAs(mColorAttachment)) ||
+               (mStencilAttachment.IsDefined() && !mStencilAttachment.HasSameDimensionsAs(mColorAttachment)) ||
+               (mDepthStencilAttachment.IsDefined() && !mDepthStencilAttachment.HasSameDimensionsAs(mColorAttachment));
     }
 
     const WebGLFramebufferAttachment& ColorAttachment() const {
         return mColorAttachment;
     }
 
     const WebGLFramebufferAttachment& DepthAttachment() const {
         return mDepthAttachment;
@@ -2205,28 +2210,49 @@ public:
         if (mDepthAttachment.Renderbuffer() == rb)
             FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nsnull);
         if (mStencilAttachment.Renderbuffer() == rb)
             FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nsnull);
         if (mDepthStencilAttachment.Renderbuffer() == rb)
             FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nsnull);
     }
 
+    const WebGLRectangleObject *RectangleObject() {
+        return mColorAttachment.RectangleObject();
+    }
+
     NS_DECL_ISUPPORTS
     NS_DECL_NSIWEBGLFRAMEBUFFER
 
-protected:
-
-    // protected because WebGLContext should only call InitializeRenderbuffers
-    void InitializeRenderbuffers()
+    bool CheckAndInitializeRenderbuffers()
     {
+        // enforce WebGL section 6.5 which is WebGL-specific, hence OpenGL itself would not
+        // generate the INVALID_FRAMEBUFFER_OPERATION that we need here
+        if (HasDepthStencilConflict())
+            return false;
+
+        if (!mColorAttachment.HasUninitializedRenderbuffer() &&
+            !mDepthAttachment.HasUninitializedRenderbuffer() &&
+            !mStencilAttachment.HasUninitializedRenderbuffer() &&
+            !mDepthStencilAttachment.HasUninitializedRenderbuffer())
+            return true;
+
+        // ensure INVALID_FRAMEBUFFER_OPERATION in zero-size case
+        const WebGLRectangleObject *rect = mColorAttachment.RectangleObject();
+        if (!rect ||
+            !rect->Width() ||
+            !rect->Height())
+            return false;
+
         mContext->MakeContextCurrent();
 
-        if (mContext->gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER) != LOCAL_GL_FRAMEBUFFER_COMPLETE)
-            return;
+        WebGLenum status;
+        mContext->CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER, &status);
+        if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
+            return false;
 
         PRUint32 mask = 0;
 
         if (mColorAttachment.HasUninitializedRenderbuffer())
             mask |= LOCAL_GL_COLOR_BUFFER_BIT;
 
         if (mDepthAttachment.HasUninitializedRenderbuffer() ||
             mDepthStencilAttachment.HasUninitializedRenderbuffer())
@@ -2235,30 +2261,31 @@ protected:
         }
 
         if (mStencilAttachment.HasUninitializedRenderbuffer() ||
             mDepthStencilAttachment.HasUninitializedRenderbuffer())
         {
             mask |= LOCAL_GL_STENCIL_BUFFER_BIT;
         }
 
-        // the one useful line of code
-        mContext->ForceClearFramebufferWithDefaultValues(mask, nsIntRect(0,0,width(),height()));
+        mContext->ForceClearFramebufferWithDefaultValues(mask, nsIntRect(0, 0, rect->Width(), rect->Height()));
 
         if (mColorAttachment.HasUninitializedRenderbuffer())
             mColorAttachment.Renderbuffer()->SetInitialized(true);
 
         if (mDepthAttachment.HasUninitializedRenderbuffer())
             mDepthAttachment.Renderbuffer()->SetInitialized(true);
 
         if (mStencilAttachment.HasUninitializedRenderbuffer())
             mStencilAttachment.Renderbuffer()->SetInitialized(true);
 
         if (mDepthStencilAttachment.HasUninitializedRenderbuffer())
             mDepthStencilAttachment.Renderbuffer()->SetInitialized(true);
+
+        return true;
     }
 
     WebGLuint mGLName;
     bool mHasEverBeenBound;
 
     // we only store pointers to attached renderbuffers, not to attached textures, because
     // we will only need to initialize renderbuffers. Textures are already initialized.
     WebGLFramebufferAttachment mColorAttachment,
@@ -2358,16 +2385,21 @@ public:
     WebGLExtension(WebGLContext *baseContext)
         : WebGLContextBoundObject(baseContext)
     {}
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIWEBGLEXTENSION
 };
 
+inline const WebGLRectangleObject *WebGLContext::FramebufferRectangleObject() const {
+    return mBoundFramebuffer ? mBoundFramebuffer->RectangleObject()
+                             : static_cast<const WebGLRectangleObject*>(this);
+}
+
 /**
  ** Template implementations
  **/
 
 /* Helper function taking a BaseInterfaceType pointer, casting it to
  * ConcreteObjectType and performing some checks along the way.
  *
  * By default, null (respectively: deleted) aInterface pointers are
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -681,18 +681,26 @@ WebGLContext::CheckFramebufferStatus(Web
     }
 
     *retval = 0;
 
     MakeContextCurrent();
     if (target != LOCAL_GL_FRAMEBUFFER)
         return ErrorInvalidEnum("checkFramebufferStatus: target must be FRAMEBUFFER");
 
-    if (mBoundFramebuffer && mBoundFramebuffer->HasBadAttachments())
+    if (!mBoundFramebuffer)
+        *retval = LOCAL_GL_FRAMEBUFFER_COMPLETE;
+    else if(mBoundFramebuffer->HasDepthStencilConflict())
         *retval = LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
+    else if(!mBoundFramebuffer->ColorAttachment().IsDefined())
+        *retval = LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+    else if(mBoundFramebuffer->HasIncompleteAttachment())
+        *retval = LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+    else if(mBoundFramebuffer->HasAttachmentsOfMismatchedDimensions())
+        *retval = LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
     else
         *retval = gl->fCheckFramebufferStatus(target);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::Clear(PRUint32 mask)
@@ -705,17 +713,17 @@ WebGLContext::Clear(PRUint32 mask)
     PRUint32 m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
     if (mask != m)
         return ErrorInvalidValue("clear: invalid mask bits");
 
     bool needClearCallHere = true;
 
     if (mBoundFramebuffer) {
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-            return NS_OK;
+            return ErrorInvalidFramebufferOperation("clear: incomplete framebuffer");
     } else {
         // no FBO is bound, so we are clearing the backbuffer here
         EnsureBackbufferClearedAsNeeded();
         bool valuesAreDefault = mColorClearValue[0] == 0.0f &&
                                   mColorClearValue[1] == 0.0f &&
                                   mColorClearValue[2] == 0.0f &&
                                   mColorClearValue[3] == 0.0f &&
                                   mDepthClearValue    == 1.0f &&
@@ -797,19 +805,19 @@ WebGLContext::CopyTexSubImage2D_base(Web
                                      WebGLint xoffset,
                                      WebGLint yoffset,
                                      WebGLint x,
                                      WebGLint y,
                                      WebGLsizei width,
                                      WebGLsizei height,
                                      bool sub)
 {
-
-    WebGLsizei framebufferWidth =  mBoundFramebuffer ? mBoundFramebuffer->width() : mWidth;
-    WebGLsizei framebufferHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
+    const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject();
+    WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
+    WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
     const char *info = sub ? "copyTexSubImage2D" : "copyTexImage2D";
 
     MakeContextCurrent();
 
     if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
         if (sub)
             gl->fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
@@ -856,17 +864,17 @@ WebGLContext::CopyTexSubImage2D_base(Web
 
         // if we are completely outside of the framebuffer, we can exit now with our black texture
         if (   x >= framebufferWidth
             || x+width <= 0
             || y >= framebufferHeight
             || y+height <= 0)
         {
             // we are completely outside of range, can exit now with buffer filled with zeros
-            return NS_OK;
+            return DummyFramebufferOperation(info);
         }
 
         GLint   actual_x             = clamped(x, 0, framebufferWidth);
         GLint   actual_x_plus_width  = clamped(x + width, 0, framebufferWidth);
         GLsizei actual_width   = actual_x_plus_width  - actual_x;
         GLint   actual_xoffset = xoffset + actual_x - x;
 
         GLint   actual_y             = clamped(y, 0, framebufferHeight);
@@ -941,36 +949,37 @@ WebGLContext::CopyTexImage2D(WebGLenum t
                                     internalformat == LOCAL_GL_ALPHA ||
                                     internalformat == LOCAL_GL_LUMINANCE_ALPHA;
     bool fboFormatHasAlpha = mBoundFramebuffer ? mBoundFramebuffer->ColorAttachment().HasAlpha()
                                                  : bool(gl->ActualFormat().alpha > 0);
     if (texFormatRequiresAlpha && !fboFormatHasAlpha)
         return ErrorInvalidOperation("copyTexImage2D: texture format requires an alpha channel "
                                      "but the framebuffer doesn't have one");
 
-    if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-        return NS_OK;
+    if (mBoundFramebuffer)
+        if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
+            return ErrorInvalidFramebufferOperation("copyTexImage2D: incomplete framebuffer");
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
     if (!tex)
         return ErrorInvalidOperation("copyTexImage2D: no texture bound to this target");
 
     // copyTexImage2D only generates textures with type = UNSIGNED_BYTE
     GLenum type = LOCAL_GL_UNSIGNED_BYTE;
 
     // check if the memory size of this texture may change with this call
     bool sizeMayChange = true;
     size_t face = WebGLTexture::FaceForTarget(target);
     if (tex->HasImageInfoAt(level, face)) {
         const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(level, face);
 
-        sizeMayChange = width != imageInfo.mWidth ||
-                        height != imageInfo.mHeight ||
-                        internalformat != imageInfo.mFormat ||
-                        type != imageInfo.mType;
+        sizeMayChange = width != imageInfo.Width() ||
+                        height != imageInfo.Height() ||
+                        internalformat != imageInfo.Format() ||
+                        type != imageInfo.Type();
     }
 
     if (sizeMayChange) {
         UpdateWebGLErrorAndClearGLError();
         CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
         GLenum error = LOCAL_GL_NO_ERROR;
         UpdateWebGLErrorAndClearGLError(&error);
         if (error) {
@@ -1027,38 +1036,40 @@ WebGLContext::CopyTexSubImage2D(WebGLenu
     WebGLTexture *tex = activeBoundTextureForTarget(target);
     if (!tex)
         return ErrorInvalidOperation("copyTexSubImage2D: no texture bound to this target");
 
     WebGLint face = WebGLTexture::FaceForTarget(target);
     if (!tex->HasImageInfoAt(level, face))
         return ErrorInvalidOperation("copyTexSubImage2D: no texture image previously defined for this level and face");
 
-    WebGLsizei texWidth = tex->ImageInfoAt(level, face).mWidth;
-    WebGLsizei texHeight = tex->ImageInfoAt(level, face).mHeight;
+    const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face);
+    WebGLsizei texWidth = imageInfo.Width();
+    WebGLsizei texHeight = imageInfo.Height();
 
     if (xoffset + width > texWidth || xoffset + width < 0)
       return ErrorInvalidValue("copyTexSubImage2D: xoffset+width is too large");
 
     if (yoffset + height > texHeight || yoffset + height < 0)
       return ErrorInvalidValue("copyTexSubImage2D: yoffset+height is too large");
 
-    WebGLenum format = tex->ImageInfoAt(level, face).mFormat;
+    WebGLenum format = imageInfo.Format();
     bool texFormatRequiresAlpha = format == LOCAL_GL_RGBA ||
-                                    format == LOCAL_GL_ALPHA ||
-                                    format == LOCAL_GL_LUMINANCE_ALPHA;
+                                  format == LOCAL_GL_ALPHA ||
+                                  format == LOCAL_GL_LUMINANCE_ALPHA;
     bool fboFormatHasAlpha = mBoundFramebuffer ? mBoundFramebuffer->ColorAttachment().HasAlpha()
                                                  : bool(gl->ActualFormat().alpha > 0);
 
     if (texFormatRequiresAlpha && !fboFormatHasAlpha)
         return ErrorInvalidOperation("copyTexSubImage2D: texture format requires an alpha channel "
                                      "but the framebuffer doesn't have one");
 
-    if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-        return NS_OK;
+    if (mBoundFramebuffer)
+        if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
+            return ErrorInvalidFramebufferOperation("copyTexSubImage2D: incomplete framebuffer");
 
     return CopyTexSubImage2D_base(target, level, format, xoffset, yoffset, x, y, width, height, true);
 }
 
 
 NS_IMETHODIMP
 WebGLContext::CreateProgram(nsIWebGLProgram **retval)
 {
@@ -1582,17 +1593,17 @@ WebGLContext::DrawArrays(GLenum mode, We
 
     if (checked_firstPlusCount.value() > maxAllowedCount)
         return ErrorInvalidOperation("drawArrays: bound vertex attribute buffers do not have sufficient size for given first and count");
 
     MakeContextCurrent();
 
     if (mBoundFramebuffer) {
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-            return NS_OK;
+            return ErrorInvalidFramebufferOperation("drawArrays: incomplete framebuffer");
     } else {
         EnsureBackbufferClearedAsNeeded();
     }
 
     BindFakeBlackTextures();
     if (!DoFakeVertexAttrib0(checked_firstPlusCount.value()))
         return NS_OK;
 
@@ -1693,17 +1704,17 @@ WebGLContext::DrawElements(WebGLenum mod
                 "size for given indices from the bound element array");
         }
     }
 
     MakeContextCurrent();
 
     if (mBoundFramebuffer) {
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-            return NS_OK;
+            return ErrorInvalidFramebufferOperation("drawElements: incomplete framebuffer");
     } else {
         EnsureBackbufferClearedAsNeeded();
     }
 
     BindFakeBlackTextures();
     if (!DoFakeVertexAttrib0(checked_maxIndexPlusOne.value()))
         return NS_OK;
 
@@ -2401,30 +2412,30 @@ WebGLContext::GetFramebufferAttachmentPa
 
     if (fba.Renderbuffer()) {
         switch (pname) {
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                 wrval->SetAsInt32(LOCAL_GL_RENDERBUFFER);
                 break;
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-                wrval->SetAsISupports(fba.Renderbuffer());
+                wrval->SetAsISupports(const_cast<WebGLRenderbuffer*>(fba.Renderbuffer()));
                 break;
 
             default:
                 return ErrorInvalidEnumInfo("GetFramebufferAttachmentParameter: pname", pname);
         }
     } else if (fba.Texture()) {
         switch (pname) {
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                 wrval->SetAsInt32(LOCAL_GL_TEXTURE);
                 break;
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-                wrval->SetAsISupports(fba.Texture());
+                wrval->SetAsISupports(const_cast<WebGLTexture*>(fba.Texture()));
                 break;
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
                 wrval->SetAsInt32(fba.TextureLevel());
                 break;
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
                 wrval->SetAsInt32(fba.TextureCubeMapFace());
@@ -3283,18 +3294,19 @@ WebGLContext::ReadPixels_base(WebGLint x
     }
 
     if (width < 0 || height < 0)
         return ErrorInvalidValue("ReadPixels: negative size passed");
 
     if (!pixels)
         return ErrorInvalidValue("ReadPixels: null array passed");
 
-    WebGLsizei boundWidth = mBoundFramebuffer ? mBoundFramebuffer->width() : mWidth;
-    WebGLsizei boundHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
+    const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject();
+    WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
+    WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
     void* data = JS_GetTypedArrayData(pixels);
     PRUint32 dataByteLen = JS_GetTypedArrayByteLength(pixels);
     int dataType = JS_GetTypedArrayType(pixels);
 
     PRUint32 channels = 0;
 
     // Check the format param
@@ -3365,57 +3377,57 @@ WebGLContext::ReadPixels_base(WebGLint x
             return ErrorInvalidOperation("readPixels: Invalid format/type pair");
     }
 
     MakeContextCurrent();
 
     if (mBoundFramebuffer) {
         // prevent readback of arbitrary video memory through uninitialized renderbuffers!
         if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
-            return NS_OK;
+            return ErrorInvalidFramebufferOperation("readPixels: incomplete framebuffer");
     } else {
         EnsureBackbufferClearedAsNeeded();
     }
     // Now that the errors are out of the way, on to actually reading
 
     // If we won't be reading any pixels anyways, just skip the actual reading
     if (width == 0 || height == 0)
-        return NS_OK;
-
-    if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, boundWidth, boundHeight)) {
+        return DummyFramebufferOperation("readPixels");
+
+    if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
         // the easy case: we're not reading out-of-range pixels
         gl->fReadPixels(x, y, width, height, format, type, data);
     } else {
         // the rectangle doesn't fit entirely in the bound buffer. We then have to set to zero the part
         // of the buffer that correspond to out-of-range pixels. We don't want to rely on system OpenGL
         // to do that for us, because passing out of range parameters to a buggy OpenGL implementation
         // could conceivably allow to read memory we shouldn't be allowed to read. So we manually initialize
         // the buffer to zero and compute the parameters to pass to OpenGL. We have to use an intermediate buffer
         // to accomodate the potentially different strides (widths).
 
         // zero the whole destination buffer. Too bad for the part that's going to be overwritten, we're not
         // 100% efficient here, but in practice this is a quite rare case anyway.
         memset(data, 0, dataByteLen);
 
-        if (   x >= boundWidth
+        if (   x >= framebufferWidth
             || x+width <= 0
-            || y >= boundHeight
+            || y >= framebufferHeight
             || y+height <= 0)
         {
             // we are completely outside of range, can exit now with buffer filled with zeros
-            return NS_OK;
+            return DummyFramebufferOperation("readPixels");
         }
 
         // compute the parameters of the subrect we're actually going to call glReadPixels on
         GLint   subrect_x      = NS_MAX(x, 0);
-        GLint   subrect_end_x  = NS_MIN(x+width, boundWidth);
+        GLint   subrect_end_x  = NS_MIN(x+width, framebufferWidth);
         GLsizei subrect_width  = subrect_end_x - subrect_x;
 
         GLint   subrect_y      = NS_MAX(y, 0);
-        GLint   subrect_end_y  = NS_MIN(y+height, boundHeight);
+        GLint   subrect_end_y  = NS_MIN(y+height, framebufferHeight);
         GLsizei subrect_height = subrect_end_y - subrect_y;
 
         if (subrect_width < 0 || subrect_height < 0 ||
             subrect_width > width || subrect_height > height)
             return ErrorInvalidOperation("ReadPixels: integer overflow computing clipped rect size");
 
         // now we know that subrect_width is in the [0..width] interval, and same for heights.
 
@@ -3552,26 +3564,26 @@ WebGLContext::RenderbufferStorage(WebGLe
         internalformatForGL = LOCAL_GL_DEPTH24_STENCIL8;
         break;
     default:
         return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
     }
 
     MakeContextCurrent();
 
-    bool sizeChanges = width != mBoundRenderbuffer->width() ||
-                       height != mBoundRenderbuffer->height() ||
+    bool sizeChanges = width != mBoundRenderbuffer->Width() ||
+                       height != mBoundRenderbuffer->Height() ||
                        internalformat != mBoundRenderbuffer->InternalFormat();
     if (sizeChanges) {
         UpdateWebGLErrorAndClearGLError();
         gl->fRenderbufferStorage(target, internalformatForGL, width, height);
         GLenum error = LOCAL_GL_NO_ERROR;
         UpdateWebGLErrorAndClearGLError(&error);
         if (error) {
-            LogMessageIfVerbose("bufferData generated error %s", ErrorName(error));
+            LogMessageIfVerbose("renderbufferStorage generated error %s", ErrorName(error));
             return NS_OK;
         }
     } else {
         gl->fRenderbufferStorage(target, internalformatForGL, width, height);
     }
 
     mBoundRenderbuffer->SetInternalFormat(internalformat);
     mBoundRenderbuffer->SetInternalFormatForGL(internalformatForGL);
@@ -4727,20 +4739,20 @@ GLenum WebGLContext::CheckedTexImage2D(G
     WebGLTexture *tex = activeBoundTextureForTarget(target);
     NS_ABORT_IF_FALSE(tex != nsnull, "no texture bound");
 
     bool sizeMayChange = true;
     size_t face = WebGLTexture::FaceForTarget(target);
     
     if (tex->HasImageInfoAt(level, face)) {
         const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(level, face);
-        sizeMayChange = width != imageInfo.mWidth ||
-                        height != imageInfo.mHeight ||
-                        format != imageInfo.mFormat ||
-                        type != imageInfo.mType;
+        sizeMayChange = width != imageInfo.Width() ||
+                        height != imageInfo.Height() ||
+                        format != imageInfo.Format() ||
+                        type != imageInfo.Type();
     }
     
     if (sizeMayChange) {
         UpdateWebGLErrorAndClearGLError();
         gl->fTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
         GLenum error = LOCAL_GL_NO_ERROR;
         UpdateWebGLErrorAndClearGLError(&error);
         return error;
@@ -5034,21 +5046,21 @@ WebGLContext::TexSubImage2D_base(WebGLen
         return ErrorInvalidOperation("texSubImage2D: no texture is bound to this target");
 
     size_t face = WebGLTexture::FaceForTarget(target);
     
     if (!tex->HasImageInfoAt(level, face))
         return ErrorInvalidOperation("texSubImage2D: no texture image previously defined for this level and face");
     
     const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face);
-    if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, imageInfo.mWidth, imageInfo.mHeight))
+    if (!CanvasUtils::CheckSaneSubrectSize(xoffset, yoffset, width, height, imageInfo.Width(), imageInfo.Height()))
         return ErrorInvalidValue("texSubImage2D: subtexture rectangle out of bounds");
     
     // Require the format and type in texSubImage2D to match that of the existing texture as created by texImage2D
-    if (imageInfo.mFormat != format || imageInfo.mType != type)
+    if (imageInfo.Format() != format || imageInfo.Type() != type)
         return ErrorInvalidOperation("texSubImage2D: format or type doesn't match the existing texture");
 
     MakeContextCurrent();
 
     int dstFormat = GetWebGLTexelFormat(format, type);
     int actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
     size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
 
--- a/content/canvas/src/WebGLContextUtils.cpp
+++ b/content/canvas/src/WebGLContextUtils.cpp
@@ -193,16 +193,27 @@ WebGLContext::ErrorInvalidValue(const ch
     va_start(va, fmt);
     LogMessageIfVerbose(fmt, va);
     va_end(va);
 
     return SynthesizeGLError(LOCAL_GL_INVALID_VALUE);
 }
 
 nsresult
+WebGLContext::ErrorInvalidFramebufferOperation(const char *fmt, ...)
+{
+    va_list va;
+    va_start(va, fmt);
+    LogMessageIfVerbose(fmt, va);
+    va_end(va);
+
+    return SynthesizeGLError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
+}
+
+nsresult
 WebGLContext::ErrorOutOfMemory(const char *fmt, ...)
 {
     va_list va;
     va_start(va, fmt);
     LogMessageIfVerbose(fmt, va);
     va_end(va);
 
     return SynthesizeGLError(LOCAL_GL_OUT_OF_MEMORY);
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -2535,17 +2535,17 @@ nsCanvasRenderingContext2D::SetFont(cons
     nsRefPtr<nsStyleContext> sc =
         styleSet->ResolveStyleForRules(parentContext, rules);
     if (!sc)
         return NS_ERROR_FAILURE;
     const nsStyleFont* fontStyle = sc->GetStyleFont();
 
     NS_ASSERTION(fontStyle, "Could not obtain font style");
 
-    nsIAtom* language = sc->GetStyleVisibility()->mLanguage;
+    nsIAtom* language = sc->GetStyleFont()->mLanguage;
     if (!language) {
         language = presShell->GetPresContext()->GetLanguageFromCharset();
     }
 
     // use CSS pixels instead of dev pixels to avoid being affected by page zoom
     const PRUint32 aupcp = nsPresContext::AppUnitsPerCSSPixel();
     // un-zoom the font size to avoid being affected by text-only zoom
     const nscoord fontSize = nsStyleFont::UnZoomText(parentContext->PresContext(), fontStyle->mFont.size);
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -2746,17 +2746,17 @@ nsCanvasRenderingContext2DAzure::SetFont
   if (!sc) {
     return NS_ERROR_FAILURE;
   }
 
   const nsStyleFont* fontStyle = sc->GetStyleFont();
 
   NS_ASSERTION(fontStyle, "Could not obtain font style");
 
-  nsIAtom* language = sc->GetStyleVisibility()->mLanguage;
+  nsIAtom* language = sc->GetStyleFont()->mLanguage;
   if (!language) {
     language = presShell->GetPresContext()->GetLanguageFromCharset();
   }
 
   // use CSS pixels instead of dev pixels to avoid being affected by page zoom
   const PRUint32 aupcp = nsPresContext::AppUnitsPerCSSPixel();
   // un-zoom the font size to avoid being affected by text-only zoom
   const nscoord fontSize = nsStyleFont::UnZoomText(parentContext->PresContext(), fontStyle->mFont.size);
--- a/content/canvas/test/webgl/failing_tests_linux.txt
+++ b/content/canvas/test/webgl/failing_tests_linux.txt
@@ -6,9 +6,8 @@ conformance/misc/uninitialized-test.html
 conformance/programs/gl-get-active-attribute.html
 conformance/textures/texture-mips.html
 conformance/uniforms/gl-uniform-bool.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/more/functions/uniformfArrayLen1.html
 conformance/glsl/misc/attrib-location-length-limits.html
 conformance/glsl/misc/uniform-location-length-limits.html
 conformance/renderbuffers/framebuffer-object-attachment.html
-conformance/misc/object-deletion-behaviour.html
--- a/content/canvas/test/webgl/failing_tests_mac.txt
+++ b/content/canvas/test/webgl/failing_tests_mac.txt
@@ -2,11 +2,9 @@ conformance/context/premultiplyalpha-tes
 conformance/glsl/misc/glsl-function-nodes.html
 conformance/glsl/misc/glsl-long-variable-names.html
 conformance/glsl/misc/shader-with-256-character-identifier.frag.html
 conformance/glsl/misc/shader-with-long-line.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/more/functions/uniformfBadArgs.html
 conformance/more/functions/uniformiBadArgs.html
 conformance/glsl/misc/attrib-location-length-limits.html
-conformance/glsl/misc/uniform-location-length-limits.html
-conformance/renderbuffers/framebuffer-object-attachment.html
-conformance/misc/object-deletion-behaviour.html
+conformance/glsl/misc/uniform-location-length-limits.html
\ No newline at end of file
--- a/content/canvas/test/webgl/failing_tests_windows.txt
+++ b/content/canvas/test/webgl/failing_tests_windows.txt
@@ -3,11 +3,9 @@ conformance/glsl/functions/glsl-function
 conformance/glsl/functions/glsl-function-atan-xy.html
 conformance/glsl/misc/glsl-long-variable-names.html
 conformance/glsl/misc/shader-with-256-character-identifier.frag.html
 conformance/glsl/misc/shader-with-long-line.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/more/functions/uniformfArrayLen1.html
 conformance/glsl/misc/attrib-location-length-limits.html
 conformance/glsl/misc/struct-nesting-under-maximum.html
-conformance/glsl/misc/uniform-location-length-limits.html
-conformance/renderbuffers/framebuffer-object-attachment.html
-conformance/misc/object-deletion-behaviour.html
+conformance/glsl/misc/uniform-location-length-limits.html
\ No newline at end of file
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -77,16 +77,17 @@
 #include "nsDOMJSUtils.h"
 #include "nsDOMScriptObjectHolder.h"
 #include "nsDataHashtable.h"
 #include "nsCOMArray.h"
 #include "nsEventListenerService.h"
 #include "nsDOMEvent.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsJSEnvironment.h"
+#include "sampler.h"
 
 using namespace mozilla::dom;
 
 #define EVENT_TYPE_EQUALS( ls, type, userType ) \
   (ls->mEventType == type && \
   (ls->mEventType != NS_USER_DEFINED_EVENT || ls->mTypeAtom == userType))
 
 static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
@@ -746,16 +747,17 @@ void
 nsEventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
                                             nsEvent* aEvent,
                                             nsIDOMEvent** aDOMEvent,
                                             nsIDOMEventTarget* aCurrentTarget,
                                             PRUint32 aFlags,
                                             nsEventStatus* aEventStatus,
                                             nsCxPusher* aPusher)
 {
+  SAMPLE_LABEL("nsEventListenerManager", "HandleEventInternal");
   //Set the value of the internal PreventDefault flag properly based on aEventStatus
   if (*aEventStatus == nsEventStatus_eConsumeNoDefault) {
     aEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT;
   }
 
   nsAutoTObserverArray<nsListenerStruct, 2>::EndLimitedIterator iter(mListeners);
   nsAutoPopupStatePusher popupStatePusher(nsDOMEvent::GetEventPopupControlState(aEvent));
   bool hasListener = false;
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -2544,17 +2544,18 @@ GetScrollableLineHeight(nsIFrame* aTarge
     nsIScrollableFrame* sf = f->GetScrollTargetFrame();
     if (sf)
       return sf->GetLineScrollAmount().height;
   }
 
   // Fall back to the font height of the target frame.
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(aTargetFrame, getter_AddRefs(fm),
-    nsLayoutUtils::FontSizeInflationFor(aTargetFrame));
+    nsLayoutUtils::FontSizeInflationFor(aTargetFrame,
+                                        nsLayoutUtils::eNotInReflow));
   NS_ASSERTION(fm, "FontMetrics is null!");
   if (fm)
     return fm->MaxHeight();
   return 0;
 }
 
 void
 nsEventStateManager::SendLineScrollEvent(nsIFrame* aTargetFrame,
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -1821,17 +1821,17 @@ nsGenericHTMLElement::MapCommonAttribute
         else if (value->Equals(nsGkAtoms::_false, eIgnoreCase)) {
             userModify->SetIntValue(NS_STYLE_USER_MODIFY_READ_ONLY,
                                     eCSSUnit_Enumerated);
         }
       }
     }
   }
 
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Visibility)) {
+  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) {
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::lang);
     if (value && value->Type() == nsAttrValue::eString) {
       aData->ValueForLang()->SetStringValue(value->GetStringValue(),
                                             eCSSUnit_Ident);
     }
   }
 }
 
--- a/content/html/content/src/nsHTMLAnchorElement.cpp
+++ b/content/html/content/src/nsHTMLAnchorElement.cpp
@@ -135,24 +135,37 @@ public:
                                 const nsAString& aValue,
                                 nsAttrValue& aResult);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsEventStates IntrinsicState() const;
 
   virtual nsXPCClassInfo* GetClassInfo();
+  
+  virtual void OnDNSPrefetchDeferred();
+  virtual void OnDNSPrefetchRequested();
+  virtual bool HasDeferredDNSPrefetchRequest();
 };
 
+// Indicates that a DNS Prefetch has been requested from this Anchor elem
+#define HTML_ANCHOR_DNS_PREFETCH_REQUESTED \
+  (1 << ELEMENT_TYPE_SPECIFIC_BITS_OFFSET)
+// Indicates that a DNS Prefetch was added to the deferral queue
+#define HTML_ANCHOR_DNS_PREFETCH_DEFERRED \
+  (1 << (ELEMENT_TYPE_SPECIFIC_BITS_OFFSET+1))
+
+// Make sure we have enough space for those bits
+PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET+1 < 32);
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Anchor)
 
 nsHTMLAnchorElement::nsHTMLAnchorElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo),
-    Link(this)
+  : nsGenericHTMLElement(aNodeInfo)
+  , Link(this)
 {
 }
 
 nsHTMLAnchorElement::~nsHTMLAnchorElement()
 {
 }
 
 
@@ -197,16 +210,36 @@ nsHTMLAnchorElement::GetDraggable(bool* 
                                nsGkAtoms::_false, eIgnoreCase);
     return NS_OK;
   }
 
   // no href, so just use the same behavior as other elements
   return nsGenericHTMLElement::GetDraggable(aDraggable);
 }
 
+void
+nsHTMLAnchorElement::OnDNSPrefetchRequested()
+{
+  UnsetFlags(HTML_ANCHOR_DNS_PREFETCH_DEFERRED);
+  SetFlags(HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
+}
+
+void
+nsHTMLAnchorElement::OnDNSPrefetchDeferred()
+{
+  UnsetFlags(HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
+  SetFlags(HTML_ANCHOR_DNS_PREFETCH_DEFERRED);
+}
+
+bool
+nsHTMLAnchorElement::HasDeferredDNSPrefetchRequest()
+{
+  return HasFlag(HTML_ANCHOR_DNS_PREFETCH_DEFERRED);
+}
+
 nsresult
 nsHTMLAnchorElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                                 nsIContent* aBindingParent,
                                 bool aCompileEventHandlers)
 {
   Link::ResetLinkState(false);
 
   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
@@ -223,16 +256,31 @@ nsHTMLAnchorElement::BindToTree(nsIDocum
   }
 
   return rv;
 }
 
 void
 nsHTMLAnchorElement::UnbindFromTree(bool aDeep, bool aNullParent)
 {
+  // Cancel any DNS prefetches
+  // Note: Must come before ResetLinkState.  If called after, it will recreate
+  // mCachedURI based on data that is invalid - due to a call to GetHostname.
+
+  // If prefetch was deferred, clear flag and move on
+  if (HasFlag(HTML_ANCHOR_DNS_PREFETCH_DEFERRED))
+    UnsetFlags(HTML_ANCHOR_DNS_PREFETCH_DEFERRED);
+  // Else if prefetch was requested, clear flag and send cancellation
+  else if (HasFlag(HTML_ANCHOR_DNS_PREFETCH_REQUESTED)) {
+    UnsetFlags(HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
+    // Possible that hostname could have changed since binding, but since this
+    // covers common cases, most DNS prefetch requests will be canceled
+    nsHTMLDNSPrefetch::CancelPrefetchLow(this, NS_ERROR_ABORT);
+  }
+  
   // If this link is ever reinserted into a document, it might
   // be under a different xml:base, so forget the cached state now.
   Link::ResetLinkState(false);
   
   nsIDocument* doc = GetCurrentDoc();
   if (doc) {
     doc->UnregisterPendingLinkUpdate(this);
   }
--- a/content/html/content/src/nsHTMLDNSPrefetch.cpp
+++ b/content/html/content/src/nsHTMLDNSPrefetch.cpp
@@ -160,54 +160,112 @@ nsHTMLDNSPrefetch::PrefetchMedium(Link *
 
 nsresult
 nsHTMLDNSPrefetch::PrefetchHigh(Link *aElement)
 {
   return Prefetch(aElement, 0);
 }
 
 nsresult
-nsHTMLDNSPrefetch::Prefetch(nsAString &hostname, PRUint16 flags)
+nsHTMLDNSPrefetch::Prefetch(const nsAString &hostname, PRUint16 flags)
 {
   if (IsNeckoChild()) {
     // We need to check IsEmpty() because net_IsValidHostName()
     // considers empty strings to be valid hostnames
     if (!hostname.IsEmpty() &&
         net_IsValidHostName(NS_ConvertUTF16toUTF8(hostname))) {
       gNeckoChild->SendHTMLDNSPrefetch(nsAutoString(hostname), flags);
     }
     return NS_OK;
   }
 
   if (!(sInitialized && sDNSService && sPrefetches && sDNSListener))
     return NS_ERROR_NOT_AVAILABLE;
 
   nsCOMPtr<nsICancelable> tmpOutstanding;
-  return sDNSService->AsyncResolve(NS_ConvertUTF16toUTF8(hostname), flags | nsIDNSService::RESOLVE_SPECULATE,
-                                   sDNSListener, nsnull, getter_AddRefs(tmpOutstanding));
+  return sDNSService->AsyncResolve(NS_ConvertUTF16toUTF8(hostname),
+                                   flags | nsIDNSService::RESOLVE_SPECULATE,
+                                   sDNSListener, nsnull, 
+                                   getter_AddRefs(tmpOutstanding));
 }
 
 nsresult
-nsHTMLDNSPrefetch::PrefetchLow(nsAString &hostname)
+nsHTMLDNSPrefetch::PrefetchLow(const nsAString &hostname)
 {
   return Prefetch(hostname, nsIDNSService::RESOLVE_PRIORITY_LOW);
 }
 
 nsresult
-nsHTMLDNSPrefetch::PrefetchMedium(nsAString &hostname)
+nsHTMLDNSPrefetch::PrefetchMedium(const nsAString &hostname)
 {
   return Prefetch(hostname, nsIDNSService::RESOLVE_PRIORITY_MEDIUM);
 }
 
 nsresult
-nsHTMLDNSPrefetch::PrefetchHigh(nsAString &hostname)
+nsHTMLDNSPrefetch::PrefetchHigh(const nsAString &hostname)
 {
   return Prefetch(hostname, 0);
 }
 
+nsresult
+nsHTMLDNSPrefetch::CancelPrefetch(Link *aElement,
+                                  PRUint16 flags,
+                                  nsresult aReason)
+{
+  if (!(sInitialized && sPrefetches && sDNSService && sDNSListener))
+    return NS_ERROR_NOT_AVAILABLE;
+
+  nsAutoString hostname;
+  nsresult rv = aElement->GetHostname(hostname);
+  NS_ENSURE_SUCCESS(rv, rv);
+  return CancelPrefetch(hostname, flags, aReason);
+}
+
+nsresult
+nsHTMLDNSPrefetch::CancelPrefetch(const nsAString &hostname,
+                                  PRUint16 flags,
+                                  nsresult aReason)
+{
+  // Forward this request to Necko Parent if we're a child process
+  if (IsNeckoChild()) {
+    // We need to check IsEmpty() because net_IsValidHostName()
+    // considers empty strings to be valid hostnames
+    if (!hostname.IsEmpty() &&
+        net_IsValidHostName(NS_ConvertUTF16toUTF8(hostname))) {
+      gNeckoChild->SendCancelHTMLDNSPrefetch(nsString(hostname), flags,
+                                             aReason);
+    }
+    return NS_OK;
+  }
+
+  if (!(sInitialized && sDNSService && sPrefetches && sDNSListener))
+    return NS_ERROR_NOT_AVAILABLE;
+
+  // Forward cancellation to DNS service
+  return sDNSService->CancelAsyncResolve(NS_ConvertUTF16toUTF8(hostname),
+                                         flags
+                                         | nsIDNSService::RESOLVE_SPECULATE,
+                                         sDNSListener, aReason);
+}
+
+nsresult
+nsHTMLDNSPrefetch::CancelPrefetchLow(Link *aElement, nsresult aReason)
+{
+  return CancelPrefetch(aElement, nsIDNSService::RESOLVE_PRIORITY_LOW,
+                        aReason);
+}
+
+nsresult
+nsHTMLDNSPrefetch::CancelPrefetchLow(const nsAString &hostname, nsresult aReason)
+{
+  return CancelPrefetch(hostname, nsIDNSService::RESOLVE_PRIORITY_LOW,
+                        aReason);
+}
+
+
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsHTMLDNSPrefetch::nsListener,
                               nsIDNSListener)
 
 NS_IMETHODIMP
 nsHTMLDNSPrefetch::nsListener::OnLookupComplete(nsICancelable *request,
                                               nsIDNSRecord  *rec,
@@ -252,16 +310,18 @@ nsHTMLDNSPrefetch::nsDeferrals::Flush()
 }
 
 nsresult
 nsHTMLDNSPrefetch::nsDeferrals::Add(PRUint16 flags, Link *aElement)
 {
   // The FIFO has no lock, so it can only be accessed on main thread
   NS_ASSERTION(NS_IsMainThread(), "nsDeferrals::Add must be on main thread");
 
+  aElement->OnDNSPrefetchDeferred();
+
   if (((mHead + 1) & sMaxDeferredMask) == mTail)
     return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
     
   mEntries[mHead].mFlags = flags;
   mEntries[mHead].mElement = do_GetWeakReference(aElement);
   mHead = (mHead + 1) & sMaxDeferredMask;
 
   if (!mActiveLoaderCount && !mTimerArmed && mTimer) {
@@ -278,30 +338,38 @@ nsHTMLDNSPrefetch::nsDeferrals::SubmitQu
   NS_ASSERTION(NS_IsMainThread(), "nsDeferrals::SubmitQueue must be on main thread");
   nsCString hostName;
   if (!sDNSService) return;
 
   while (mHead != mTail) {
     nsCOMPtr<nsIContent> content = do_QueryReferent(mEntries[mTail].mElement);
     if (content) {
       nsCOMPtr<Link> link = do_QueryInterface(content);
-      nsCOMPtr<nsIURI> hrefURI(link ? link->GetURI() : nsnull);
-      if (hrefURI)
-        hrefURI->GetAsciiHost(hostName);
+      // Only prefetch here if request was deferred and deferral not cancelled
+      if (link && link->HasDeferredDNSPrefetchRequest()) {
+        nsCOMPtr<nsIURI> hrefURI(link ? link->GetURI() : nsnull);
+        if (hrefURI)
+          hrefURI->GetAsciiHost(hostName);
 
-      if (!hostName.IsEmpty()) {
-        if (IsNeckoChild()) {
-          gNeckoChild->SendHTMLDNSPrefetch(NS_ConvertUTF8toUTF16(hostName),
+        if (!hostName.IsEmpty()) {
+          if (IsNeckoChild()) {
+            gNeckoChild->SendHTMLDNSPrefetch(NS_ConvertUTF8toUTF16(hostName),
                                            mEntries[mTail].mFlags);
-        } else {
-          nsCOMPtr<nsICancelable> tmpOutstanding;
+          } else {
+            nsCOMPtr<nsICancelable> tmpOutstanding;
 
-          sDNSService->AsyncResolve(hostName, 
-                                  mEntries[mTail].mFlags | nsIDNSService::RESOLVE_SPECULATE,
-                                  sDNSListener, nsnull, getter_AddRefs(tmpOutstanding));
+            nsresult rv = sDNSService->AsyncResolve(hostName, 
+                                    mEntries[mTail].mFlags
+                                    | nsIDNSService::RESOLVE_SPECULATE,
+                                    sDNSListener, nsnull,
+                                    getter_AddRefs(tmpOutstanding));
+            // Tell link that deferred prefetch was requested
+            if (NS_SUCCEEDED(rv))
+              link->OnDNSPrefetchRequested();
+          }
         }
       }
     }
     
     mEntries[mTail].mElement = nsnull;
     mTail = (mTail + 1) & sMaxDeferredMask;
   }
   
--- a/content/html/content/src/nsHTMLDNSPrefetch.h
+++ b/content/html/content/src/nsHTMLDNSPrefetch.h
@@ -79,23 +79,32 @@ public:
   // complete, while the string versions submit the lookup to 
   // the DNS system immediately. The URI version is somewhat lighter
   // weight, but its request is also more likely to be dropped due to a 
   // full queue and it may only be used from the main thread.
 
   static nsresult PrefetchHigh(mozilla::dom::Link *aElement);
   static nsresult PrefetchMedium(mozilla::dom::Link *aElement);
   static nsresult PrefetchLow(mozilla::dom::Link *aElement);
-  static nsresult PrefetchHigh(nsAString &host);
-  static nsresult PrefetchMedium(nsAString &host);
-  static nsresult PrefetchLow(nsAString &host);
+  static nsresult PrefetchHigh(const nsAString &host);
+  static nsresult PrefetchMedium(const nsAString &host);
+  static nsresult PrefetchLow(const nsAString &host);
+  static nsresult CancelPrefetchLow(const nsAString &host, nsresult aReason);
+  static nsresult CancelPrefetchLow(mozilla::dom::Link *aElement,
+                                    nsresult aReason);
 
 private:
-  static nsresult Prefetch(nsAString &host, PRUint16 flags);
+  static nsresult Prefetch(const nsAString &host, PRUint16 flags);
   static nsresult Prefetch(mozilla::dom::Link *aElement, PRUint16 flags);
+  static nsresult CancelPrefetch(const nsAString &hostname,
+                                 PRUint16 flags,
+                                 nsresult aReason);
+  static nsresult CancelPrefetch(mozilla::dom::Link *aElement,
+                                 PRUint16 flags,
+                                 nsresult aReason);
   
 public:
   class nsListener : public nsIDNSListener
   {
     // This class exists to give a safe callback no-op DNSListener
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIDNSLISTENER
--- a/content/html/document/src/PluginDocument.cpp
+++ b/content/html/document/src/PluginDocument.cpp
@@ -42,16 +42,17 @@
 #include "nsIObjectFrame.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentPolicyUtils.h"
 #include "nsIPropertyBag2.h"
 #include "mozilla/dom/Element.h"
+#include "sampler.h"
 
 namespace mozilla {
 namespace dom {
 
 class PluginDocument : public MediaDocument
                      , public nsIPluginDocument
 {
 public:
@@ -108,16 +109,17 @@ private:
 
   nsRefPtr<PluginDocument> mPluginDoc;
 };
 
 
 NS_IMETHODIMP
 PluginStreamListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
 {
+  SAMPLE_LABEL("PluginStreamListener", "OnStartRequest");
   // Have to set up our plugin stuff before we call OnStartRequest, so
   // that the plugin listener can get that call.
   nsresult rv = SetupPlugin();
 
   NS_ASSERTION(NS_FAILED(rv) || mNextStream,
                "We should have a listener by now");
   nsresult rv2 = MediaDocumentStreamListener::OnStartRequest(request, ctxt);
   return NS_SUCCEEDED(rv) ? rv2 : rv;
--- a/content/media/nsMediaDecoder.h
+++ b/content/media/nsMediaDecoder.h
@@ -361,17 +361,17 @@ public:
   nsHTMLMediaElement* GetMediaElement();
 
   // Returns the current size of the framebuffer used in
   // MozAudioAvailable events.
   PRUint32 GetFrameBufferLength() { return mFrameBufferLength; };
 
   // Sets the length of the framebuffer used in MozAudioAvailable events.
   // The new size must be between 512 and 16384.
-  nsresult RequestFrameBufferLength(PRUint32 aLength);
+  virtual nsresult RequestFrameBufferLength(PRUint32 aLength);
 
   // Moves any existing channel loads into the background, so that they don't
   // block the load event. This is called when we stop delaying the load
   // event. Any new loads initiated (for example to seek) will also be in the
   // background. Implementations of this must call MoveLoadsToBackground() on
   // their nsMediaStream.
   virtual void MoveLoadsToBackground()=0;
 
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -271,16 +271,17 @@ ifdef MOZ_OGG
 		noContentLength.sjs \
 		test_seekable2.html \
 		test_seekable3.html \
 		test_a4_tone.html \
 		file_audio_event_adopt_iframe.html \
 		test_audio_event_adopt.html \
 		test_framebuffer.html \
 		test_referer.html \
+		test_bug686137.html \
 		$(NULL)
 else
 _TEST_FILES += \
 		test_can_play_type_no_ogg.html \
 		$(NULL)
 endif
 
 ifdef MOZ_WEBM
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_bug686137.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=686137
+-->
+
+<head>
+  <title>Media test: changing mozFrameBufferLength</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=686137">Mozilla Bug 686137</a>
+
+<audio id='a1' controls muted></audio>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+var testFile = "bug495794.ogg";
+var a1 = document.getElementById('a1');
+
+function audioAvailable(event) {
+  a1.removeEventListener("MozAudioAvailable", audioAvailable);
+  is( event.frameBuffer.length, 9001, "event.frameBuffer.length should be 9001.");
+  is( event.frameBuffer.length, a1.mozFrameBufferLength, "event.frameBuffer.length should be " + a1.mozFrameBufferLength + ".");
+  SimpleTest.finish();
+}
+
+function metaDataLoaded(){
+  a1.addEventListener("MozAudioAvailable", audioAvailable, false);
+  a1.mozFrameBufferLength = 9001;
+  a1.play();
+}
+
+a1.addEventListener("loadedmetadata", metaDataLoaded, false);
+a1.src = testFile;
+a1.load();
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
--- a/db/sqlite3/README.MOZILLA
+++ b/db/sqlite3/README.MOZILLA
@@ -1,22 +1,21 @@
-This is sqlite 3.7.7.1
+This is sqlite 3.7.10
 
--- Marco Bonardo <mak77@bonardo.net>, 08/2011
+-- Ryan VanderMeulen <ryanvm@gmail.com>, 01/2012
 
 See http://www.sqlite.org/ for more info.
 
 We have a mozilla-specific Makefile.in in src/ (normally no
 Makefile.in there) that we use to build.
 
 To move to a new version:
 
-Simply copy the sqlite3.h and sqlite3.c files from the amalgamation of sqlite.
-
-Also copy test_quota.h and test_quota.c from the full source package.
+Copy the sqlite3.h and sqlite3.c files from the amalgamation of sqlite. Also,
+copy test_quota.h and test_quota.c from the full source package.
 
 Be sure to update SQLITE_VERSION accordingly in $(topsrcdir)/configure.in as
 well as the version number at the top of this file.
 
 -- Paul O’Shannessy <paul@oshannessy.com>, 01/2011
 
 We are using an experimental quota management feature included in test_quota.c.
 This file is not compiled into mozsqlite, but instead included directly into
--- a/db/sqlite3/src/Makefile.in
+++ b/db/sqlite3/src/Makefile.in
@@ -84,16 +84,22 @@ MOZ_GLUE_LDFLAGS =
 endif
 
 # XXX Force -O2 optimisation on Mac because using the default -O3 causes
 # crashes. See bug 676499.
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 MODULE_OPTIMIZE_FLAGS = -O2
 endif
 
+# Force /O2 optimisation on Windows because using the default /O1 causes
+# crashes with MSVC2005 and PGO. See bug 719584.
+ifeq ($(OS_ARCH),WINNT)
+MODULE_OPTIMIZE_FLAGS = -O2
+endif
+
 EXPORTS = \
   sqlite3.h \
   $(NULL)
 
 CSRCS = \
   sqlite3.c \
   $(NULL)
 
@@ -138,18 +144,24 @@ ifeq ($(OS_ARCH),OS2)
 ifdef MOZ_OS2_HIGH_MEMORY
 DEFINES += -DOS2_HIGH_MEMORY
 endif
 endif
 
 ifeq ($(OS_TARGET),Android)
 # default to user readable only to fit Android security model
 DEFINES += -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600
-# Force using fsync, since there is not fdatasync in ndk 5.
-DEFINES += -Dfdatasync=fsync
+endif
+
+# Force using malloc_usable_size when building with jemalloc because _msize
+# causes assertions on Win64. See bug 719579.
+ifeq ($(OS_ARCH),WINNT)
+ifdef MOZ_MEMORY
+DEFINES += -DHAVE_MALLOC_USABLE_SIZE
+endif
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 # next line allows use of MOZ_OBJDIR in .mozconfig with older gcc on BeOS, maybe others
 LOCAL_INCLUDES += -I$(srcdir)
 
 ifeq ($(OS_ARCH),OS2)
--- a/db/sqlite3/src/sqlite3.c
+++ b/db/sqlite3/src/sqlite3.c
@@ -1,11 +1,11 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.7.7.1.  By combining all the individual C code files into this 
+** version 3.7.10.  By combining all the individual C code files into this 
 ** single large file, the entire code can be compiled as a single translation
 ** unit.  This allows many compilers to do optimizations that would not be
 ** possible if the files were compiled separately.  Performance improvements
 ** of 5% or more are commonly seen when SQLite is compiled as a single
 ** translation unit.
 **
 ** This file is all you need to compile SQLite.  To use SQLite in other
 ** programs, you need this file and the "sqlite3.h" header file that defines
@@ -312,23 +312,16 @@
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #endif
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
 #endif
 
 /*
-** The number of samples of an index that SQLite takes in order to 
-** construct a histogram of the table content when running ANALYZE
-** and with SQLITE_ENABLE_STAT2
-*/
-#define SQLITE_INDEX_SAMPLES 10
-
-/*
 ** The following macros are used to cast pointers to integers and
 ** integers to pointers.  The way you do this varies from one compiler
 ** to the next, so we have developed the following set of #if statements
 ** to generate appropriate macros for a wide range of compilers.
 **
 ** The correct "ANSI" way to do this is to use the intptr_t type. 
 ** Unfortunately, that typedef is not available on all compilers, or
 ** if it is available, it requires an #include of specific headers
@@ -368,43 +361,57 @@
 #if defined(THREADSAFE)
 # define SQLITE_THREADSAFE THREADSAFE
 #else
 # define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
 #endif
 #endif
 
 /*
+** Powersafe overwrite is on by default.  But can be turned off using
+** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option.
+*/
+#ifndef SQLITE_POWERSAFE_OVERWRITE
+# define SQLITE_POWERSAFE_OVERWRITE 1
+#endif
+
+/*
 ** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
 ** It determines whether or not the features related to 
 ** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
 ** be overridden at runtime using the sqlite3_config() API.
 */
 #if !defined(SQLITE_DEFAULT_MEMSTATUS)
 # define SQLITE_DEFAULT_MEMSTATUS 1
 #endif
 
 /*
 ** Exactly one of the following macros must be defined in order to
 ** specify which memory allocation subsystem to use.
 **
 **     SQLITE_SYSTEM_MALLOC          // Use normal system malloc()
+**     SQLITE_WIN32_MALLOC           // Use Win32 native heap API
 **     SQLITE_MEMDEBUG               // Debugging version of system malloc()
 **
+** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
+** assert() macro is enabled, each call into the Win32 native heap subsystem
+** will cause HeapValidate to be called.  If heap validation should fail, an
+** assertion will be triggered.
+**
 ** (Historical note:  There used to be several other options, but we've
-** pared it down to just these two.)
+** pared it down to just these three.)
 **
 ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
 ** the default.
 */
-#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)>1
+#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1
 # error "At most one of the following compile-time configuration options\
- is allows: SQLITE_SYSTEM_MALLOC, SQLITE_MEMDEBUG"
-#endif
-#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)==0
+ is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG"
+#endif
+#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0
 # define SQLITE_SYSTEM_MALLOC 1
 #endif
 
 /*
 ** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the
 ** sizes of memory allocations below this value where possible.
 */
 #if !defined(SQLITE_MALLOC_SOFT_LIMIT)
@@ -645,19 +652,19 @@ extern "C" {
 ** within its configuration management system.  ^The SQLITE_SOURCE_ID
 ** string contains the date and time of the check-in (UTC) and an SHA1
 ** hash of the entire source tree.
 **
 ** See also: [sqlite3_libversion()],
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.7.7.1"
-#define SQLITE_VERSION_NUMBER 3007007
-#define SQLITE_SOURCE_ID      "2011-06-28 17:39:05 af0d91adf497f5f36ec3813f04235a6e195a605f"
+#define SQLITE_VERSION        "3.7.10"
+#define SQLITE_VERSION_NUMBER 3007010
+#define SQLITE_SOURCE_ID      "2012-01-16 13:28:40 ebd01a8deffb5024a5d7494eef800d2366d97204"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
 **
 ** These interfaces provide the same information as the [SQLITE_VERSION],
 ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
 ** but are associated with the library instead of the header file.  ^(Cautious
@@ -715,17 +722,17 @@ SQLITE_API int sqlite3_libversion_number
 SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
 SQLITE_API const char *sqlite3_compileoption_get(int N);
 #endif
 
 /*
 ** CAPI3REF: Test To See If The Library Is Threadsafe
 **
 ** ^The sqlite3_threadsafe() function returns zero if and only if
-** SQLite was compiled mutexing code omitted due to the
+** SQLite was compiled with mutexing code omitted due to the
 ** [SQLITE_THREADSAFE] compile-time option being set to 0.
 **
 ** SQLite can be compiled with or without mutexes.  When
 ** 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.
@@ -909,17 +916,17 @@ SQLITE_API int sqlite3_exec(
 );
 
 /*
 ** CAPI3REF: Result Codes
 ** KEYWORDS: SQLITE_OK {error code} {error codes}
 ** KEYWORDS: {result code} {result codes}
 **
 ** Many SQLite functions return an integer result code from the set shown
-** here in order to indicates success or failure.
+** here in order to indicate success or failure.
 **
 ** New error codes may be added in future versions of SQLite.
 **
 ** See also: [SQLITE_IOERR_READ | extended result codes],
 ** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes].
 */
 #define SQLITE_OK           0   /* Successful result */
 /* beginning-of-error-codes */
@@ -1047,30 +1054,35 @@ SQLITE_API int sqlite3_exec(
 ** any size are atomic.  The SQLITE_IOCAP_ATOMICnnn values
 ** mean that writes of blocks that are nnn bytes in size and
 ** are aligned to an address which is an integer multiple of
 ** nnn are atomic.  The SQLITE_IOCAP_SAFE_APPEND value means
 ** that when data is appended to a file, the data is appended
 ** first then the size of the file is extended, never the other
 ** way around.  The SQLITE_IOCAP_SEQUENTIAL property means that
 ** information is written to disk in the same order as calls
-** to xWrite().
+** to xWrite().  The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that
+** after reboot following a crash or power loss, the only bytes in a
+** file that were written at the application level might have changed
+** and that adjacent bytes, even bytes within the same sector are
+** guaranteed to be unchanged.
 */
 #define SQLITE_IOCAP_ATOMIC                 0x00000001
 #define SQLITE_IOCAP_ATOMIC512              0x00000002
 #define SQLITE_IOCAP_ATOMIC1K               0x00000004
 #define SQLITE_IOCAP_ATOMIC2K               0x00000008
 #define SQLITE_IOCAP_ATOMIC4K               0x00000010
 #define SQLITE_IOCAP_ATOMIC8K               0x00000020
 #define SQLITE_IOCAP_ATOMIC16K              0x00000040
 #define SQLITE_IOCAP_ATOMIC32K              0x00000080
 #define SQLITE_IOCAP_ATOMIC64K              0x00000100
 #define SQLITE_IOCAP_SAFE_APPEND            0x00000200
 #define SQLITE_IOCAP_SEQUENTIAL             0x00000400
 #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN  0x00000800
+#define SQLITE_IOCAP_POWERSAFE_OVERWRITE    0x00001000
 
 /*
 ** CAPI3REF: File Locking Levels
 **
 ** SQLite uses one of these integer values as the second
 ** argument to calls it makes to the xLock() and xUnlock() methods
 ** of an [sqlite3_io_methods] object.
 */
@@ -1279,26 +1291,85 @@ struct sqlite3_io_methods {
 ** SQLite and sent to all VFSes in place of a call to the xSync method
 ** when the database connection has [PRAGMA synchronous] set to OFF.)^
 ** Some specialized VFSes need this signal in order to operate correctly
 ** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most 
 ** VFSes do not need this signal and should silently ignore this opcode.
 ** Applications should not call [sqlite3_file_control()] with this
 ** opcode as doing so may disrupt the operation of the specialized VFSes
 ** that do require it.  
-*/
-#define SQLITE_FCNTL_LOCKSTATE        1
-#define SQLITE_GET_LOCKPROXYFILE      2
-#define SQLITE_SET_LOCKPROXYFILE      3
-#define SQLITE_LAST_ERRNO             4
-#define SQLITE_FCNTL_SIZE_HINT        5
-#define SQLITE_FCNTL_CHUNK_SIZE       6
-#define SQLITE_FCNTL_FILE_POINTER     7
-#define SQLITE_FCNTL_SYNC_OMITTED     8
-
+**
+** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
+** retry counts and intervals for certain disk I/O operations for the
+** windows [VFS] in order to provide robustness in the presence of
+** anti-virus programs.  By default, the windows VFS will retry file read,
+** file write, and file delete operations up to 10 times, with a delay
+** of 25 milliseconds before the first retry and with the delay increasing
+** by an additional 25 milliseconds with each subsequent retry.  This
+** opcode allows these two values (10 retries and 25 milliseconds of delay)
+** to be adjusted.  The values are changed for all database connections
+** within the same process.  The argument is a pointer to an array of two
+** integers where the first integer i the new retry count and the second
+** integer is the delay.  If either integer is negative, then the setting
+** is not changed but instead the prior value of that setting is written
+** into the array entry, allowing the current retry settings to be
+** interrogated.  The zDbName parameter is ignored.
+**
+** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
+** persistent [WAL | Write AHead Log] setting.  By default, the auxiliary
+** write ahead log and shared memory files used for transaction control
+** are automatically deleted when the latest connection to the database
+** closes.  Setting persistent WAL mode causes those files to persist after
+** close.  Persisting the files is useful when other processes that do not
+** have write permission on the directory containing the database file want
+** to read the database file, as the WAL and shared memory files must exist
+** in order for the database to be readable.  The fourth parameter to
+** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
+** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
+** WAL mode.  If the integer is -1, then it is overwritten with the current
+** WAL persistence setting.
+**
+** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the
+** persistent "powersafe-overwrite" or "PSOW" setting.  The PSOW setting
+** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the
+** xDeviceCharacteristics methods. The fourth parameter to
+** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
+** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage
+** mode.  If the integer is -1, then it is overwritten with the current
+** zero-damage mode setting.
+**
+** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
+** a write transaction to indicate that, unless it is rolled back for some
+** reason, the entire database file will be overwritten by the current 
+** transaction. This is used by VACUUM operations.
+**
+** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of
+** all [VFSes] in the VFS stack.  The names are of all VFS shims and the
+** final bottom-level VFS are written into memory obtained from 
+** [sqlite3_malloc()] and the result is stored in the char* variable
+** that the fourth parameter of [sqlite3_file_control()] points to.
+** The caller is responsible for freeing the memory when done.  As with
+** all file-control actions, there is no guarantee that this will actually
+** do anything.  Callers should initialize the char* variable to a NULL
+** pointer in case this file-control is not implemented.  This file-control
+** is intended for diagnostic use only.
+*/
+#define SQLITE_FCNTL_LOCKSTATE               1
+#define SQLITE_GET_LOCKPROXYFILE             2
+#define SQLITE_SET_LOCKPROXYFILE             3
+#define SQLITE_LAST_ERRNO                    4
+#define SQLITE_FCNTL_SIZE_HINT               5
+#define SQLITE_FCNTL_CHUNK_SIZE              6
+#define SQLITE_FCNTL_FILE_POINTER            7
+#define SQLITE_FCNTL_SYNC_OMITTED            8
+#define SQLITE_FCNTL_WIN32_AV_RETRY          9
+#define SQLITE_FCNTL_PERSIST_WAL            10
+#define SQLITE_FCNTL_OVERWRITE              11
+#define SQLITE_FCNTL_VFSNAME                12
+#define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
 
 /*
 ** CAPI3REF: Mutex Handle
 **
 ** The mutex module within SQLite defines [sqlite3_mutex] to be an
 ** abstract type for a mutex object.  The SQLite core never looks
 ** at the internal representation of an [sqlite3_mutex].  It only
 ** deals with pointers to the [sqlite3_mutex] object.
@@ -1343,17 +1414,17 @@ typedef struct sqlite3_mutex sqlite3_mut
 ** be unique across all VFS modules.
 **
 ** [[sqlite3_vfs.xOpen]]
 ** ^SQLite guarantees that the zFilename parameter to xOpen
 ** is either a NULL pointer or string obtained
 ** from xFullPathname() with an optional suffix added.
 ** ^If a suffix is added to the zFilename parameter, it will
 ** consist of a single "-" character followed by no more than
-** 10 alphanumeric and/or "-" characters.
+** 11 alphanumeric and/or "-" characters.
 ** ^SQLite further guarantees that
 ** the string will be valid and unchanged until xClose() is
 ** called. Because of the previous sentence,
 ** the [sqlite3_file] can safely store a pointer to the
 ** filename if it needs to remember the filename for some reason.
 ** If the zFilename parameter to xOpen is a NULL pointer then xOpen
 ** must invent its own temporary name for the file.  ^Whenever the 
 ** xFilename parameter is NULL it will also be the case that the
@@ -1716,26 +1787,20 @@ SQLITE_API int sqlite3_db_config(sqlite3
 ** 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 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 guarantees that the second argument to
+** The xMalloc, xRealloc, and xFree methods must work like the
+** malloc(), realloc() and free() functions from the standard C library.
+** ^SQLite guarantees 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
@@ -1880,17 +1945,17 @@ struct sqlite3_mem_methods {
 ** times the database page size. ^If SQLite needs needs additional
 ** scratch memory beyond what is provided by this configuration option, then 
 ** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
 **
 ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
 ** <dd> ^This option specifies a static memory buffer that SQLite can use for
 ** the database page cache with the default page cache implementation.  
 ** This configuration should not be used if an application-define page
-** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option.
+** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option.
 ** There are three arguments to this option: A pointer to 8-byte aligned
 ** memory, the size of each page buffer (sz), and the number of pages (N).
 ** The sz argument should be the size of the largest database page
 ** (a power of two between 512 and 32768) plus a little extra for each
 ** page header.  ^The page header size is 20 to 40 bytes depending on
 ** the host architecture.  ^It is harmless, apart from the wasted memory,
 ** to make sz a little too large.  The first
 ** argument should point to an allocation of at least sz*N bytes of memory.
@@ -1911,18 +1976,18 @@ struct sqlite3_mem_methods {
 ** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
 ** to using its default memory allocator (the system malloc() implementation),
 ** undoing any prior invocation of [SQLITE_CONFIG_MALLOC].  ^If the
 ** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
 ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
 ** allocator is engaged to handle all of SQLites memory allocation needs.
 ** The first pointer (the memory pointer) must be aligned to an 8-byte
 ** boundary or subsequent behavior of SQLite will be undefined.
-** The minimum allocation size is capped at 2^12. Reasonable values
-** for the minimum allocation size are 2^5 through 2^8.</dd>
+** The minimum allocation size is capped at 2**12. Reasonable values
+** for the minimum allocation size are 2**5 through 2**8.</dd>
 **
 ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
 ** <dd> ^(This option takes a single argument which is a pointer to an
 ** instance of the [sqlite3_mutex_methods] structure.  The argument specifies
 ** alternative low-level mutex routines to be used in place
 ** the mutex routines built into SQLite.)^  ^SQLite makes a copy of the
 ** content of the [sqlite3_mutex_methods] structure before the call to
 ** [sqlite3_config()] returns. ^If SQLite is compiled with
@@ -1949,25 +2014,25 @@ struct sqlite3_mem_methods {
 ** memory allocation for the lookaside memory allocator on each
 ** [database connection].  The first argument is the
 ** size of each lookaside buffer slot and the second is the number of
 ** 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>
 **
-** [[SQLITE_CONFIG_PCACHE]] <dt>SQLITE_CONFIG_PCACHE</dt>
+** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
 ** <dd> ^(This option takes a single argument which is a pointer to
-** an [sqlite3_pcache_methods] object.  This object specifies the interface
+** an [sqlite3_pcache_methods2] 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>
 **
-** [[SQLITE_CONFIG_GETPCACHE]] <dt>SQLITE_CONFIG_GETPCACHE</dt>
+** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
 ** <dd> ^(This option takes a single argument which is a pointer to an
-** [sqlite3_pcache_methods] object.  SQLite copies of the current
+** [sqlite3_pcache_methods2] object.  SQLite copies of the current
 ** page cache implementation into that object.)^ </dd>
 **
 ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
 ** <dd> ^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
 ** function with a call signature of void(*)(void*,int,const char*), 
 ** and a pointer to void. ^If the function pointer is not NULL, it is
 ** invoked by [sqlite3_log()] to process each logging event.  ^If the
 ** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op.
@@ -1990,35 +2055,42 @@ struct sqlite3_mem_methods {
 ** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
 ** specified as part of [ATTACH] commands are interpreted as URIs, regardless
 ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
 ** connection is opened. If it is globally disabled, filenames are
 ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
 ** database connection is opened. By default, URI handling is globally
 ** disabled. The default value may be changed by compiling with the
 ** [SQLITE_USE_URI] symbol defined.
+**
+** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
+** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFNIG_GETPCACHE
+** <dd> These options are obsolete and should not be used by new code.
+** They are retained for backwards compatibility but are now no-ops.
 ** </dl>
 */
 #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
 #define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
 #define SQLITE_CONFIG_SERIALIZED    3  /* nil */
 #define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
 #define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
 #define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */
 #define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */
 #define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
 #define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
 #define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
 #define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
 /* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ 
 #define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
-#define SQLITE_CONFIG_PCACHE       14  /* sqlite3_pcache_methods* */
-#define SQLITE_CONFIG_GETPCACHE    15  /* sqlite3_pcache_methods* */
+#define SQLITE_CONFIG_PCACHE       14  /* no-op */
+#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
 #define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
 #define SQLITE_CONFIG_URI          17  /* int */
+#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
+#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
 
 /*
 ** CAPI3REF: Database Connection Configuration Options
 **
 ** These constants are the available integer configuration options that
 ** can be passed as the second argument to the [sqlite3_db_config()] interface.
 **
 ** New configuration options may be added in future releases of SQLite.
@@ -2493,17 +2565,17 @@ SQLITE_API void sqlite3_free_table(char 
 **
 ** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
 **
 ** These routines all implement some additional formatting
 ** options that are useful for constructing SQL statements.
 ** All of the usual printf() formatting options apply.  In addition, there
 ** is are "%q", "%Q", and "%z" options.
 **
-** ^(The %q option works like %s in that it substitutes a null-terminated
+** ^(The %q option works like %s in that it substitutes a nul-terminated
 ** string from the argument list.  But %q also doubles every '\'' character.
 ** %q is designed for use inside a string literal.)^  By doubling each '\''
 ** character it escapes that character and allows it to be inserted into
 ** the string.
 **
 ** For example, assume the string variable zText contains text as follows:
 **
 ** <blockquote><pre>
@@ -3101,31 +3173,50 @@ SQLITE_API int sqlite3_open_v2(
   sqlite3 **ppDb,         /* OUT: SQLite db handle */
   int flags,              /* Flags */
   const char *zVfs        /* Name of VFS module to use */
 );
 
 /*
 ** CAPI3REF: Obtain Values For URI Parameters
 **
-** This is a utility routine, useful to VFS implementations, that checks
+** These are utility routines, useful to VFS implementations, that check
 ** to see if a database file was a URI that contained a specific query 
-** parameter, and if so obtains the value of the query parameter.
-**
-** The zFilename argument is the filename pointer passed into the xOpen()
-** method of a VFS implementation.  The zParam argument is the name of the
-** query parameter we seek.  This routine returns the value of the zParam
-** parameter if it exists.  If the parameter does not exist, this routine
-** returns a NULL pointer.
-**
-** If the zFilename argument to this function is not a pointer that SQLite
-** passed into the xOpen VFS method, then the behavior of this routine
-** is undefined and probably undesirable.
+** parameter, and if so obtains the value of that query parameter.
+**
+** If F is the database filename pointer passed into the xOpen() method of 
+** a VFS implementation when the flags parameter to xOpen() has one or 
+** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and
+** P is the name of the query parameter, then
+** sqlite3_uri_parameter(F,P) returns the value of the P
+** parameter if it exists or a NULL pointer if P does not appear as a 
+** query parameter on F.  If P is a query parameter of F
+** has no explicit value, then sqlite3_uri_parameter(F,P) returns
+** a pointer to an empty string.
+**
+** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean
+** parameter and returns true (1) or false (0) according to the value
+** of P.  The value of P is true if it is "yes" or "true" or "on" or 
+** a non-zero number and is false otherwise.  If P is not a query parameter
+** on F then sqlite3_uri_boolean(F,P,B) returns (B!=0).
+**
+** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
+** 64-bit signed integer and returns that integer, or D if P does not
+** exist.  If the value of P is something other than an integer, then
+** zero is returned.
+** 
+** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
+** sqlite3_uri_boolean(F,P,B) returns B.  If F is not a NULL pointer and
+** is not a database file pathname pointer that SQLite passed into the xOpen
+** VFS method, then the behavior of this routine is undefined and probably
+** undesirable.
 */
 SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
 
 
 /*
 ** CAPI3REF: Error Codes And Messages
 **
 ** ^The sqlite3_errcode() interface returns the numeric [result code] or
 ** [extended result code] for the most recent failed sqlite3_* API call
 ** associated with a [database connection]. If a prior API call failed
@@ -3311,17 +3402,18 @@ SQLITE_API int sqlite3_limit(sqlite3*, i
 ** ^If the nByte argument is less than zero, then zSql is read up to the
 ** first zero terminator. ^If nByte is non-negative, then it is the maximum
 ** number of  bytes read from zSql.  ^When nByte is non-negative, the
 ** zSql string ends at either the first '\000' or '\u0000' character or
 ** the nByte-th byte, whichever comes first. If the caller knows
 ** that the supplied string is nul-terminated, then there is a small
 ** performance advantage to be gained by passing an nByte parameter that
 ** is equal to the number of bytes in the input string <i>including</i>
-** the nul-terminator bytes.
+** the nul-terminator bytes as this saves SQLite from having to
+** make a copy of the input string.
 **
 ** ^If pzTail is not NULL then *pzTail is made to point to the first byte
 ** past the end of the first SQL statement in zSql.  These routines only
 ** compile the first statement in zSql, so *pzTail is left pointing to
 ** what remains uncompiled.
 **
 ** ^*ppStmt is left pointing to a compiled [prepared statement] that can be
 ** executed using [sqlite3_step()].  ^If there is an error, *ppStmt is set
@@ -3362,17 +3454,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, i
 ** ^If the specific value bound to [parameter | host parameter] in the 
 ** WHERE clause might influence the choice of query plan for a statement,
 ** then the statement will be automatically recompiled, as if there had been 
 ** a schema change, on the first  [sqlite3_step()] call following any change
 ** to the [sqlite3_bind_text | bindings] of that [parameter]. 
 ** ^The specific value of WHERE-clause [parameter] might influence the 
 ** choice of query plan if the parameter is the left-hand side of a [LIKE]
 ** or [GLOB] operator or if the parameter is compared to an indexed column
-** and the [SQLITE_ENABLE_STAT2] compile-time option is enabled.
+** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
 ** the 
 ** </li>
 ** </ol>
 */
 SQLITE_API int sqlite3_prepare(
   sqlite3 *db,            /* Database handle */
   const char *zSql,       /* SQL statement, UTF-8 encoded */
   int nByte,              /* Maximum length of zSql in bytes. */
@@ -3437,16 +3529,35 @@ SQLITE_API const char *sqlite3_sql(sqlit
 ** database.  ^The [ATTACH] and [DETACH] statements also cause
 ** sqlite3_stmt_readonly() to return true since, while those statements
 ** change the configuration of a database connection, they do not make 
 ** changes to the content of the database files on disk.
 */
 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
 
 /*
+** CAPI3REF: Determine If A Prepared Statement Has Been Reset
+**
+** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
+** [prepared statement] S has been stepped at least once using 
+** [sqlite3_step(S)] but has not run to completion and/or has not 
+** been reset using [sqlite3_reset(S)].  ^The sqlite3_stmt_busy(S)
+** interface returns false if S is a NULL pointer.  If S is not a 
+** NULL pointer and is not a pointer to a valid [prepared statement]
+** object, then the behavior is undefined and probably undesirable.
+**
+** This interface can be used in combination [sqlite3_next_stmt()]
+** to locate all prepared statements associated with a database 
+** connection that are in need of being reset.  This can be used,
+** for example, in diagnostic routines to search for prepared 
+** statements that are holding a transaction open.
+*/
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+
+/*
 ** CAPI3REF: Dynamically Typed Value Object
 ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
 **
 ** SQLite uses the sqlite3_value object to represent all values
 ** that can be stored in a database table. SQLite uses dynamic typing
 ** for the values it stores.  ^Values stored in sqlite3_value objects
 ** can be integers, floating point values, strings, BLOBs, or NULL.
 **
@@ -3532,16 +3643,23 @@ typedef struct sqlite3_context sqlite3_c
 **
 ** ^The third argument is the value to bind to the parameter.
 **
 ** ^(In those routines that have a fourth argument, its value is the
 ** number of bytes in the parameter.  To be clear: the value is the
 ** number of <u>bytes</u> in the value, not the number of characters.)^
 ** ^If the fourth parameter is negative, the length of the string is
 ** the number of bytes up to the first zero terminator.
+** If a non-negative fourth parameter is provided to sqlite3_bind_text()
+** or sqlite3_bind_text16() then that parameter must be the byte offset
+** where the NUL terminator would occur assuming the string were NUL
+** terminated.  If any NUL characters occur at byte offsets less than 
+** the value of the fourth parameter then the resulting string value will
+** contain embedded NULs.  The result of expressions involving strings
+** with embedded NULs is undefined.
 **
 ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
 ** string after SQLite has finished with it.  ^The destructor is called
 ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
 ** sqlite3_bind_text(), or sqlite3_bind_text16() fails.  
 ** ^If the fifth argument is
 ** the special value [SQLITE_STATIC], then SQLite assumes that the
@@ -3865,16 +3983,22 @@ SQLITE_API int sqlite3_step(sqlite3_stmt
 ** CAPI3REF: Number of columns in a result set
 **
 ** ^The sqlite3_data_count(P) interface returns the number of columns in the
 ** current row of the result set of [prepared statement] P.
 ** ^If prepared statement P does not have results ready to return
 ** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
 ** interfaces) then sqlite3_data_count(P) returns 0.
 ** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
+** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
+** [sqlite3_step](P) returned [SQLITE_DONE].  ^The sqlite3_data_count(P)
+** will return non-zero if previous call to [sqlite3_step](P) returned
+** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
+** where it always returns zero since each step of that multi-step
+** pragma returns 0 columns of data.
 **
 ** See also: [sqlite3_column_count()]
 */
 SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Fundamental Datatypes
 ** KEYWORDS: SQLITE_TEXT
@@ -3964,17 +4088,17 @@ SQLITE_API int sqlite3_data_count(sqlite
 **
 ** ^The values returned by [sqlite3_column_bytes()] and 
 ** [sqlite3_column_bytes16()] do not include the zero terminators at the end
 ** of the string.  ^For clarity: the values returned by
 ** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of
 ** bytes in the string, not the number of characters.
 **
 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
-** even empty strings, are always zero terminated.  ^The return
+** even empty strings, are always zero-terminated.  ^The return
 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
 **
 ** ^The object returned by [sqlite3_column_value()] is an
 ** [unprotected sqlite3_value] object.  An unprotected sqlite3_value object
 ** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
 ** If the [unprotected sqlite3_value] object returned by
 ** [sqlite3_column_value()] is used in any other way, including calls
 ** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
@@ -4544,17 +4668,22 @@ typedef void (*sqlite3_destructor_type)(
 ** ^SQLite takes the text result from the application from
 ** the 2nd parameter of the sqlite3_result_text* interfaces.
 ** ^If the 3rd parameter to the sqlite3_result_text* interfaces
 ** is negative, then SQLite takes result text from the 2nd parameter
 ** through the first zero character.
 ** ^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.
+** function result.  If the 3rd parameter is non-negative, then it
+** must be the byte offset into the string where the NUL terminator would
+** appear if the string where NUL terminated.  If any NUL characters occur
+** in the string at a byte offset that is less than the value of the 3rd
+** parameter, then the resulting string will contain embedded NULs and the
+** result of expressions operating on strings with embedded NULs is undefined.
 ** ^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 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 content of the parameter nor call a destructor on the content
@@ -4860,16 +4989,32 @@ SQLITE_API int sqlite3_get_autocommit(sq
 ** returned by sqlite3_db_handle is the same [database connection]
 ** that was the first argument
 ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
 ** create the statement in the first place.
 */
 SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
 
 /*
+** CAPI3REF: Return The Filename For A Database Connection
+**
+** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
+** associated with database N of connection D.  ^The main database file
+** has the name "main".  If there is no attached database N on the database
+** connection D, or if database N is a temporary or in-memory database, then
+** a NULL pointer is returned.
+**
+** ^The filename returned by this function is the output of the
+** xFullPathname method of the [VFS].  ^In other words, the filename
+** will be an absolute pathname, even if the filename used
+** to open the database originally was a URI or relative pathname.
+*/
+SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+
+/*
 ** CAPI3REF: Find the next prepared statement
 **
 ** ^This interface returns a pointer to the next [prepared statement] after
 ** pStmt associated with the [database connection] pDb.  ^If pStmt is NULL
 ** then this interface returns a pointer to the first prepared statement
 ** associated with the database connection pDb.  ^If no prepared statement
 ** satisfies the conditions of this routine, it returns NULL.
 **
@@ -4894,23 +5039,25 @@ SQLITE_API sqlite3_stmt *sqlite3_next_st
 ** ^If the callback on a commit hook function returns non-zero,
 ** then the commit is converted into a rollback.
 **
 ** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions
 ** return the P argument from the previous call of the same function
 ** on the same [database connection] D, or NULL for
 ** the first call for each function on D.
 **
+** The commit and rollback hook callbacks are not reentrant.
 ** The callback implementation must not do anything that will modify
 ** the database connection that invoked the callback.  Any actions
 ** to modify the database connection must be deferred until after the
 ** completion of the [sqlite3_step()] call that triggered the commit
 ** or rollback hook in the first place.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
+** Note that running any other SQL statements, including SELECT statements,
+** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify
+** the database connections for the meaning of "modify" in this paragraph.
 **
 ** ^Registering a NULL function disables the callback.
 **
 ** ^When the commit hook callback routine returns zero, the [COMMIT]
 ** operation is allowed to continue normally.  ^If the commit hook
 ** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
 ** ^The rollback hook is invoked on a rollback that results from a commit
 ** hook returning non-zero, just as it would be with any other rollback.
@@ -5013,50 +5160,66 @@ SQLITE_API int sqlite3_enable_shared_cac
 ** ^The sqlite3_release_memory() interface attempts to free N bytes
 ** of heap memory by deallocating non-essential memory allocations
 ** held by the database library.   Memory used to cache database
 ** pages to improve performance is an example of non-essential memory.
 ** ^sqlite3_release_memory() returns the number of bytes actually freed,
 ** which might be more or less than the amount requested.
 ** ^The sqlite3_release_memory() routine is a no-op returning zero
 ** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT].
+**
+** See also: [sqlite3_db_release_memory()]
 */
 SQLITE_API int sqlite3_release_memory(int);
 
 /*
+** CAPI3REF: Free Memory Used By A Database Connection
+**
+** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
+** memory as possible from database connection D. Unlike the
+** [sqlite3_release_memory()] interface, this interface is effect even
+** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
+** omitted.
+**
+** See also: [sqlite3_release_memory()]
+*/
+SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+
+/*
 ** CAPI3REF: Impose A Limit On Heap Size
 **
 ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
 ** soft limit on the amount of heap memory that may be allocated by SQLite.
 ** ^SQLite strives to keep heap memory utilization below the soft heap
 ** limit by reducing the number of pages held in the page cache
 ** as heap memory usages approaches the limit.
 ** ^The soft heap limit is "soft" because even though SQLite strives to stay
 ** below the limit, it will exceed the limit rather than generate
 ** an [SQLITE_NOMEM] error.  In other words, the soft heap limit 
 ** is advisory only.
 **
 ** ^The return value from sqlite3_soft_heap_limit64() is the size of
-** the soft heap limit prior to the call.  ^If the argument N is negative
+** the soft heap limit prior to the call, or negative in the case of an
+** error.  ^If the argument N is negative
 ** then no change is made to the soft heap limit.  Hence, the current
 ** size of the soft heap limit can be determined by invoking
 ** sqlite3_soft_heap_limit64() with a negative argument.
 **
 ** ^If the argument N is zero then the soft heap limit is disabled.
 **
 ** ^(The soft heap limit is not enforced in the current implementation
 ** if one or more of following conditions are true:
 **
 ** <ul>
 ** <li> The soft heap limit is set to zero.
 ** <li> Memory accounting is disabled using a combination of the
 **      [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
 **      the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
 ** <li> An alternative page cache implementation is specified using
-**      [sqlite3_config]([SQLITE_CONFIG_PCACHE],...).
+**      [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...).
 ** <li> The page cache allocates from its own memory pool supplied
 **      by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
 **      from the heap.
 ** </ul>)^
 **
 ** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
 ** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
 ** compile-time option is invoked.  With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
@@ -5788,25 +5951,25 @@ SQLITE_API int sqlite3_vfs_unregister(sq
 **
 ** The SQLite source code contains multiple implementations
 ** of these mutex routines.  An appropriate implementation
 ** is selected automatically at compile-time.  ^(The following
 ** implementations are available in the SQLite core:
 **
 ** <ul>
 ** <li>   SQLITE_MUTEX_OS2
-** <li>   SQLITE_MUTEX_PTHREAD
+** <li>   SQLITE_MUTEX_PTHREADS
 ** <li>   SQLITE_MUTEX_W32
 ** <li>   SQLITE_MUTEX_NOOP
 ** </ul>)^
 **
 ** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
 ** that does no real locking and is appropriate for use in
 ** a single-threaded application.  ^The SQLITE_MUTEX_OS2,
-** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations
+** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations
 ** are appropriate for use on OS/2, Unix, and Windows.
 **
 ** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
 ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
 ** implementation is included with the library. In this case the
 ** application must supply a custom mutex implementation using the
 ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
 ** before calling sqlite3_initialize() or any other public sqlite3_
@@ -5986,17 +6149,17 @@ struct sqlite3_mutex_methods {
 ** provides implementations for these routines when it is compiled
 ** with the SQLITE_DEBUG flag.  ^External mutex implementations
 ** are only required to provide these routines if SQLITE_DEBUG is
 ** defined and if NDEBUG is not defined.
 **
 ** ^These routines should return true if the mutex in their argument
 ** is held or not held, respectively, by the calling thread.
 **
-** ^The implementation is not required to provided versions of these
+** ^The implementation is not required to provide versions of these
 ** routines that actually work. If the implementation does not provide working
 ** versions of these routines, it should at least provide stubs that always
 ** return true so that one does not get spurious assertion failures.
 **
 ** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
 ** the routine should return 1.   This seems counter-intuitive since
 ** clearly the mutex cannot be held if it does not exist.  But
 ** the reason the mutex does not exist is because the build is not
@@ -6114,19 +6277,19 @@ SQLITE_API int sqlite3_test_control(int 
 #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
 #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
 #define SQLITE_TESTCTRL_ISKEYWORD               16
-#define SQLITE_TESTCTRL_PGHDRSZ                 17
-#define SQLITE_TESTCTRL_SCRATCHMALLOC           18
-#define SQLITE_TESTCTRL_LOCALTIME_FAULT         19
+#define SQLITE_TESTCTRL_SCRATCHMALLOC           17
+#define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
+#define SQLITE_TESTCTRL_EXPLAIN_STMT            19
 #define SQLITE_TESTCTRL_LAST                    19
 
 /*
 ** CAPI3REF: SQLite Runtime Status
 **
 ** ^This interface is used to retrieve runtime status information
 ** about the performance of SQLite, and optionally to reset various
 ** highwater marks.  ^The first argument is an integer code for
@@ -6327,26 +6490,40 @@ SQLITE_API int sqlite3_db_status(sqlite3
 ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
 **
 ** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
 ** <dd>This parameter returns the approximate number of of bytes of heap
 ** and lookaside memory used by all prepared statements associated with
 ** the database connection.)^
 ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
 ** </dd>
+**
+** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
+** <dd>This parameter returns the number of pager cache hits that have
+** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT 
+** is always 0.
+** </dd>
+**
+** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
+** <dd>This parameter returns the number of pager cache misses that have
+** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS 
+** is always 0.
+** </dd>
 ** </dl>
 */
 #define SQLITE_DBSTATUS_LOOKASIDE_USED       0
 #define SQLITE_DBSTATUS_CACHE_USED           1
 #define SQLITE_DBSTATUS_SCHEMA_USED          2
 #define SQLITE_DBSTATUS_STMT_USED            3
 #define SQLITE_DBSTATUS_LOOKASIDE_HIT        4
 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE  5
 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL  6
-#define SQLITE_DBSTATUS_MAX                  6   /* Largest defined DBSTATUS */
+#define SQLITE_DBSTATUS_CACHE_HIT            7
+#define SQLITE_DBSTATUS_CACHE_MISS           8
+#define SQLITE_DBSTATUS_MAX                  8   /* Largest defined DBSTATUS */
 
 
 /*
 ** CAPI3REF: Prepared Statement Status
 **
 ** ^(Each prepared statement maintains various
 ** [SQLITE_STMTSTATUS counters] that measure the number
 ** of times it has performed specific operations.)^  These counters can
@@ -6390,66 +6567,81 @@ SQLITE_API int sqlite3_stmt_status(sqlit
 ** improvement performance through careful use of indices.</dd>
 **
 ** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt>
 ** <dd>^This is the number of rows inserted into transient indices that
 ** were created automatically in order to help joins run faster.
 ** A non-zero value in this counter may indicate an opportunity to
 ** improvement performance by adding permanent indices that do not
 ** need to be reinitialized each time the statement is run.</dd>
-**
 ** </dl>
 */
 #define SQLITE_STMTSTATUS_FULLSCAN_STEP     1
 #define SQLITE_STMTSTATUS_SORT              2
 #define SQLITE_STMTSTATUS_AUTOINDEX         3
 
 /*
 ** CAPI3REF: Custom Page Cache Object
 **
 ** The sqlite3_pcache type is opaque.  It is implemented by
 ** the pluggable module.  The SQLite core has no knowledge of
 ** its size or internal structure and never deals with the
 ** sqlite3_pcache object except by holding and passing pointers
 ** to the object.
 **
-** See [sqlite3_pcache_methods] for additional information.
+** See [sqlite3_pcache_methods2] for additional information.
 */
 typedef struct sqlite3_pcache sqlite3_pcache;
 
 /*
+** CAPI3REF: Custom Page Cache Object
+**
+** The sqlite3_pcache_page object represents a single page in the
+** page cache.  The page cache will allocate instances of this
+** object.  Various methods of the page cache use pointers to instances
+** of this object as parameters or as their return value.
+**
+** See [sqlite3_pcache_methods2] for additional information.
+*/
+typedef struct sqlite3_pcache_page sqlite3_pcache_page;
+struct sqlite3_pcache_page {
+  void *pBuf;        /* The content of the page */
+  void *pExtra;      /* Extra information associated with the page */
+};
+
+/*
 ** CAPI3REF: Application Defined Page Cache.
 ** KEYWORDS: {page cache}
 **
-** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
+** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can
 ** register an alternative page cache implementation by passing in an 
-** instance of the sqlite3_pcache_methods structure.)^
+** instance of the sqlite3_pcache_methods2 structure.)^
 ** In many applications, most of the heap memory allocated by 
 ** SQLite is used for the page cache.
 ** By implementing a 
 ** custom page cache using this API, an application can better control
 ** 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 alternative page cache mechanism is an
 ** extreme measure that is only needed by the most demanding applications.
 ** The built-in page cache is recommended for most uses.
 **
-** ^(The contents of the sqlite3_pcache_methods structure are copied to an
+** ^(The contents of the sqlite3_pcache_methods2 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() page cache method]]
 ** ^(The xInit() method is called once for each effective 
 ** call to [sqlite3_initialize()])^
 ** (usually only once during the lifetime of the process). ^(The xInit()
-** method is passed a copy of the sqlite3_pcache_methods.pArg value.)^
+** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^
 ** The intent of the xInit() method is to set up global data structures 
 ** required by the custom page cache implementation. 
 ** ^(If the xInit() method is NULL, then the 
 ** built-in default page cache is used instead of the application defined
 ** page cache.)^
 **
 ** [[the xShutdown() page cache method]]
 ** ^The xShutdown() method is called by [sqlite3_shutdown()].
@@ -6466,27 +6658,25 @@ typedef struct sqlite3_pcache sqlite3_pc
 ** ^SQLite will never invoke xInit() more than once without an intervening
 ** call to xShutdown().
 **
 ** [[the xCreate() page cache methods]]
 ** ^SQLite invokes the xCreate() method 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.  ^szPage
-** will the page size of the database file that is to be cached plus an
-** increment (here called "R") of less than 250.  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
+** be allocated by the cache.  ^szPage will always a power of two.  ^The
+** second parameter szExtra is a number of bytes of extra storage 
+** associated with each page cache entry.  ^The szExtra parameter will
+** a number less than 250.  SQLite will use the
+** extra szExtra bytes on each page to store metadata about the underlying
+** database page on disk.  The value passed into szExtra depends
 ** on the SQLite version, the target platform, and how SQLite was compiled.
-** ^(R is constant for a particular build of SQLite. Except, there are two
-** distinct values of R when SQLite is compiled with the proprietary
-** ZIPVFS extension.)^  ^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
+** ^The third 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 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, calls to xUnpin() on a cache with bPurgeable set to
 ** false will always have the "discard" flag set to true.  
 ** ^Hence, a cache created with bPurgeable false will
 ** never contain any unpinned pages.
@@ -6500,21 +6690,26 @@ typedef struct sqlite3_pcache sqlite3_pc
 ** value; it is advisory only.
 **
 ** [[the xPagecount() page cache methods]]
 ** The xPagecount() method must return the number of pages currently
 ** stored in the cache, both pinned and unpinned.
 ** 
 ** [[the xFetch() page cache methods]]
 ** The xFetch() method locates a page in the cache and returns a pointer to 
-** the page, or a NULL pointer.
-** A "page", in this context, means a buffer of szPage bytes aligned at an
-** 8-byte boundary. The page to be fetched is determined by the key. ^The
-** minimum key value is 1.  After it has been retrieved using xFetch, the page 
-** is considered to be "pinned".
+** an sqlite3_pcache_page object associated with that page, or a NULL pointer.
+** The pBuf element of the returned sqlite3_pcache_page object will be a
+** pointer to a buffer of szPage bytes used to store the content of a 
+** single database page.  The pExtra element of sqlite3_pcache_page will be
+** a pointer to the szExtra bytes of extra storage that SQLite has requested
+** for each entry in the page cache.
+**
+** The page to be fetched is determined by the key. ^The minimum 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 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
 ** cache implementation should use the value of the createFlag
 ** parameter to help it determined what action to take:
 **
 ** <table border=1 width=85% align=center>
@@ -6557,34 +6752,64 @@ typedef struct sqlite3_pcache sqlite3_pc
 ** to the value of the iLimit parameter passed to xTruncate(). If any
 ** of these pages are pinned, they are implicitly unpinned, meaning that
 ** they can be safely discarded.
 **
 ** [[the xDestroy() page cache method]]
 ** ^The xDestroy() method is used to delete a cache allocated by xCreate().
 ** All resources associated with the specified cache should be freed. ^After
 ** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*]
-** handle invalid, and will not use it with any other sqlite3_pcache_methods
+** handle invalid, and will not use it with any other sqlite3_pcache_methods2
 ** functions.
+**
+** [[the xShrink() page cache method]]
+** ^SQLite invokes the xShrink() method when it wants the page cache to
+** free up as much of heap memory as possible.  The page cache implementation
+** is not obligated to free any memory, but well-behaved implementations should
+** do their best.
+*/
+typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2;
+struct sqlite3_pcache_methods2 {
+  int iVersion;
+  void *pArg;
+  int (*xInit)(void*);
+  void (*xShutdown)(void*);
+  sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
+  void (*xCachesize)(sqlite3_pcache*, int nCachesize);
+  int (*xPagecount)(sqlite3_pcache*);
+  sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
+  void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
+  void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, 
+      unsigned oldKey, unsigned newKey);
+  void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
+  void (*xDestroy)(sqlite3_pcache*);
+  void (*xShrink)(sqlite3_pcache*);
+};
+
+/*
+** This is the obsolete pcache_methods object that has now been replaced
+** by sqlite3_pcache_methods2.  This object is not used by SQLite.  It is
+** retained in the header file for backwards compatibility only.
 */
 typedef struct sqlite3_pcache_methods sqlite3_pcache_methods;
 struct sqlite3_pcache_methods {
   void *pArg;
   int (*xInit)(void*);
   void (*xShutdown)(void*);
   sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable);
   void (*xCachesize)(sqlite3_pcache*, int nCachesize);
   int (*xPagecount)(sqlite3_pcache*);
   void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
   void (*xUnpin)(sqlite3_pcache*, void*, int discard);
   void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
   void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
   void (*xDestroy)(sqlite3_pcache*);
 };
 
+
 /*
 ** CAPI3REF: Online Backup Object
 **
 ** The sqlite3_backup object records state information about an ongoing
 ** online backup operation.  ^The sqlite3_backup object is created by
 ** a call to [sqlite3_backup_init()] and is destroyed by a call to
 ** [sqlite3_backup_finish()].
 **
@@ -7578,17 +7803,17 @@ SQLITE_PRIVATE void sqlite3HashClear(Has
 /*
 ** The "file format" number is an integer that is incremented whenever
 ** the VDBE-level file format changes.  The following macros define the
 ** 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
+# define SQLITE_DEFAULT_FILE_FORMAT 4
 #endif
 
 /*
 ** Determine whether triggers are recursive by default.  This can be
 ** changed at run-time using a pragma.
 */
 #ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS
 # define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0
@@ -7677,16 +7902,28 @@ typedef INT8_TYPE i8;              /* 1-
 ** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value
 ** that can be stored in a u32 without loss of data.  The value
 ** is 0x00000000ffffffff.  But because of quirks of some compilers, we
 ** have to specify the value in the less intuitive manner shown:
 */
 #define SQLITE_MAX_U32  ((((u64)1)<<32)-1)
 
 /*
+** The datatype used to store estimates of the number of rows in a
+** table or index.  This is an unsigned integer type.  For 99.9% of
+** the world, a 32-bit integer is sufficient.  But a 64-bit integer
+** can be used at compile-time if desired.
+*/
+#ifdef SQLITE_64BIT_STATS
+ typedef u64 tRowcnt;    /* 64-bit only if requested at compile-time */
+#else
+ typedef u32 tRowcnt;    /* 32-bit is the default */
+#endif
+
+/*
 ** Macros to determine whether the machine is big or little endian,
 ** evaluated at runtime.
 */
 #ifdef SQLITE_AMALGAMATION
 SQLITE_PRIVATE const int sqlite3one = 1;
 #else
 SQLITE_PRIVATE const int sqlite3one;
 #endif
@@ -8141,16 +8378,17 @@ SQLITE_PRIVATE   int sqlite3SchemaMutexH
 ** 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.
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
+/* #include <stdio.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.
 */
 typedef struct Vdbe Vdbe;
 
@@ -8184,16 +8422,17 @@ struct VdbeOp {
     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 */
     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 */
+    int (*xAdvance)(BtCursor *, int *);
   } 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
@@ -8204,16 +8443,17 @@ 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 nOnce;                    /* Number of OP_Once instructions */
   void *token;                  /* id that may be used to recursive triggers */
   SubProgram *pNext;            /* Next sub-program already visited */
 };
 
 /*
 ** A smaller version of VdbeOp used for the VdbeAddOpList() function because
 ** it takes up less space.
 */
@@ -8239,16 +8479,17 @@ typedef struct VdbeOpList VdbeOpList;
 #define P4_TRANSIENT  0   /* 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 */
+#define P4_ADVANCE  (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */
 
 /* 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.
 */
@@ -8336,145 +8577,148 @@ typedef struct VdbeOpList VdbeOpList;
 #define OP_Ge                                  80   /* same as TK_GE       */
 #define OP_Permutation                         23
 #define OP_Compare                             24
 #define OP_Jump                                25
 #define OP_And                                 69   /* same as TK_AND      */
 #define OP_Or                                  68   /* same as TK_OR       */
 #define OP_Not                                 19   /* same as TK_NOT      */
 #define OP_BitNot                              93   /* same as TK_BITNOT   */
-#define OP_If                                  26
-#define OP_IfNot                               27
+#define OP_Once                                26
+#define OP_If                                  27
+#define OP_IfNot                               28
 #define OP_IsNull                              73   /* same as TK_ISNULL   */
 #define OP_NotNull                             74   /* same as TK_NOTNULL  */
-#define OP_Column                              28
-#define OP_Affinity                            29
-#define OP_MakeRecord                          30
-#define OP_Count                               31
-#define OP_Savepoint                           32
-#define OP_AutoCommit                          33
-#define OP_Transaction                         34
-#define OP_ReadCookie                          35
-#define OP_SetCookie                           36
-#define OP_VerifyCookie                        37
-#define OP_OpenRead                            38
-#define OP_OpenWrite                           39
-#define OP_OpenAutoindex                       40
-#define OP_OpenEphemeral                       41
-#define OP_OpenPseudo                          42
-#define OP_Close                               43
-#define OP_SeekLt                              44
-#define OP_SeekLe                              45
-#define OP_SeekGe                              46
-#define OP_SeekGt                              47
-#define OP_Seek                                48
-#define OP_NotFound                            49
-#define OP_Found                               50
-#define OP_IsUnique                            51
-#define OP_NotExists                           52
-#define OP_Sequence                            53
-#define OP_NewRowid                            54
-#define OP_Insert                              55
-#define OP_InsertInt                           56
-#define OP_Delete                              57
-#define OP_ResetCount                          58
-#define OP_RowKey                              59
-#define OP_RowData                             60
-#define OP_Rowid                               61
-#define OP_NullRow                             62
-#define OP_Last                                63
-#define OP_Sort                                64
-#define OP_Rewind                              65
-#define OP_Prev                                66
-#define OP_Next                                67
-#define OP_IdxInsert                           70
-#define OP_IdxDelete                           71
-#define OP_IdxRowid                            72
-#define OP_IdxLT                               81
-#define OP_IdxGE                               92
-#define OP_Destroy                             95
-#define OP_Clear                               96
-#define OP_CreateIndex                         97
-#define OP_CreateTable                         98
-#define OP_ParseSchema                         99
-#define OP_LoadAnalysis                       100
-#define OP_DropTable                          101
-#define OP_DropIndex                          102
-#define OP_DropTrigger                        103
-#define OP_IntegrityCk                        104
-#define OP_RowSetAdd                          105
-#define OP_RowSetRead                         106
-#define OP_RowSetTest                         107
-#define OP_Program                            108
-#define OP_Param                              109
-#define OP_FkCounter                          110
-#define OP_FkIfZero                           111
-#define OP_MemMax                             112
-#define OP_IfPos                              113
-#define OP_IfNeg                              114
-#define OP_IfZero                             115
-#define OP_AggStep                            116
-#define OP_AggFinal                           117
-#define OP_Checkpoint                         118
-#define OP_JournalMode                        119
-#define OP_Vacuum                             120
-#define OP_IncrVacuum                         121
-#define OP_Expire                             122
-#define OP_TableLock                          123
-#define OP_VBegin                             124
-#define OP_VCreate                            125
-#define OP_VDestroy                           126
-#define OP_VOpen                              127
-#define OP_VFilter                            128
-#define OP_VColumn                            129
-#define OP_VNext                              131
-#define OP_VRename                            132
-#define OP_VUpdate                            133
-#define OP_Pagecount                          134
-#define OP_MaxPgcnt                           135
-#define OP_Trace                              136
-#define OP_Noop                               137
-#define OP_Explain                            138
-
-/* The following opcode values are never used */
-#define OP_NotUsed_139                        139
-#define OP_NotUsed_140                        140
+#define OP_Column                              29
+#define OP_Affinity                            30
+#define OP_MakeRecord                          31
+#define OP_Count                               32
+#define OP_Savepoint                           33
+#define OP_AutoCommit                          34
+#define OP_Transaction                         35
+#define OP_ReadCookie                          36
+#define OP_SetCookie                           37
+#define OP_VerifyCookie                        38
+#define OP_OpenRead                            39
+#define OP_OpenWrite                           40
+#define OP_OpenAutoindex                       41
+#define OP_OpenEphemeral                       42
+#define OP_SorterOpen                          43
+#define OP_OpenPseudo                          44
+#define OP_Close                               45
+#define OP_SeekLt                              46
+#define OP_SeekLe                              47
+#define OP_SeekGe                              48
+#define OP_SeekGt                              49
+#define OP_Seek                                50
+#define OP_NotFound                            51
+#define OP_Found                               52
+#define OP_IsUnique                            53
+#define OP_NotExists                           54
+#define OP_Sequence                            55
+#define OP_NewRowid                            56
+#define OP_Insert                              57
+#define OP_InsertInt                           58
+#define OP_Delete                              59
+#define OP_ResetCount                          60
+#define OP_SorterCompare                       61
+#define OP_SorterData                          62
+#define OP_RowKey                              63
+#define OP_RowData                             64
+#define OP_Rowid                               65
+#define OP_NullRow                             66
+#define OP_Last                                67
+#define OP_SorterSort                          70
+#define OP_Sort                                71
+#define OP_Rewind                              72
+#define OP_SorterNext                          81
+#define OP_Prev                                92
+#define OP_Next                                95
+#define OP_SorterInsert                        96
+#define OP_IdxInsert                           97
+#define OP_IdxDelete                           98
+#define OP_IdxRowid                            99
+#define OP_IdxLT                              100
+#define OP_IdxGE                              101
+#define OP_Destroy                            102
+#define OP_Clear                              103
+#define OP_CreateIndex                        104
+#define OP_CreateTable                        105
+#define OP_ParseSchema                        106
+#define OP_LoadAnalysis                       107
+#define OP_DropTable                          108
+#define OP_DropIndex                          109
+#define OP_DropTrigger                        110
+#define OP_IntegrityCk                        111
+#define OP_RowSetAdd                          112
+#define OP_RowSetRead                         113
+#define OP_RowSetTest                         114
+#define OP_Program                            115
+#define OP_Param                              116
+#define OP_FkCounter                          117
+#define OP_FkIfZero                           118
+#define OP_MemMax                             119
+#define OP_IfPos                              120
+#define OP_IfNeg                              121
+#define OP_IfZero                             122
+#define OP_AggStep                            123
+#define OP_AggFinal                           124
+#define OP_Checkpoint                         125
+#define OP_JournalMode                        126
+#define OP_Vacuum                             127
+#define OP_IncrVacuum                         128
+#define OP_Expire                             129
+#define OP_TableLock                          131
+#define OP_VBegin                             132
+#define OP_VCreate                            133
+#define OP_VDestroy                           134
+#define OP_VOpen                              135
+#define OP_VFilter                            136
+#define OP_VColumn                            137
+#define OP_VNext                              138
+#define OP_VRename                            139
+#define OP_VUpdate                            140
+#define OP_Pagecount                          146
+#define OP_MaxPgcnt                           147
+#define OP_Trace                              148
+#define OP_Noop                               149
+#define OP_Explain                            150
 
 
 /* Properties such as "out2" or "jump" that are specified in
 ** comments following the "case" for each opcode in the vdbe.c
 ** are encoded into bitvectors as follows:
 */
 #define OPFLG_JUMP            0x0001  /* jump:  P2 holds jmp target */
 #define OPFLG_OUT2_PRERELEASE 0x0002  /* out2-prerelease: */
 #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_OUT2            0x0020  /* out2:  P2 is an output */
 #define OPFLG_OUT3            0x0040  /* out3:  P3 is an output */
 #define OPFLG_INITIALIZER {\
-/*   0 */ 0x00, 0x01, 0x05, 0x04, 0x04, 0x10, 0x00, 0x02,\
+/*   0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\
 /*   8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x24, 0x24,\
 /*  16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\
-/*  24 */ 0x00, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02,\
-/*  32 */ 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00,\
-/*  40 */ 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\
-/*  48 */ 0x08, 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x00,\
-/*  56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,\
-/*  64 */ 0x01, 0x01, 0x01, 0x01, 0x4c, 0x4c, 0x08, 0x00,\
-/*  72 */ 0x02, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
+/*  24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\
+/*  32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\
+/*  40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\
+/*  48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\
+/*  56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/*  64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\
+/*  72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
 /*  80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
-/*  88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x02,\
-/*  96 */ 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 104 */ 0x00, 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01,\
-/* 112 */ 0x08, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02,\
-/* 120 */ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 128 */ 0x01, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x02,\
-/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,\
-/* 144 */ 0x04, 0x04,}
+/*  88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\
+/*  96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
+/* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\
+/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\
+/* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\
+/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,}
 
 /************** End of opcodes.h *********************************************/
 /************** Continuing where we left off in vdbe.h ***********************/
 
 /*
 ** Prototypes for the VDBE interface.  See comments on the implementation
 ** for a description of what each of these routines does.
 */
@@ -8482,22 +8726,22 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(s
 SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int);
 SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int);
 SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
 SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
 SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
 SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
 SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
 SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
-SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
-SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
-SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
+SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
+SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
+SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
 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 sqlite3VdbeChangeToNoop(Vdbe*, int addr);
 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 sqlite3VdbeRunOnlyOnce(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
@@ -8519,19 +8763,19 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vd
 SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
 SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
 SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8);
 SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
 #ifndef SQLITE_OMIT_TRACE
 SQLITE_PRIVATE   char *sqlite3VdbeExpandSql(Vdbe*, const char*);
 #endif
 
-SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,char*,int);
-SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*);
+SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
 SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
+SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
 
 #ifndef SQLITE_OMIT_TRIGGER
 SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
 #endif
 
 
 #ifndef NDEBUG
 SQLITE_PRIVATE   void sqlite3VdbeComment(Vdbe*, const char*, ...);
@@ -8649,16 +8893,17 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
 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 int sqlite3PagerSetPagesize(Pager*, u32*, int);
 SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
 SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
+SQLITE_PRIVATE void sqlite3PagerShrink(Pager*);
 SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
 SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
 SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int);
 SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*);
 SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*);
 SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
 SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
 
@@ -8701,16 +8946,18 @@ SQLITE_PRIVATE int sqlite3PagerRefcount(
 SQLITE_PRIVATE int sqlite3PagerMemUsed(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*);
 SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
 SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
+SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
+SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *);
 
 /* Functions used to truncate the database file. */
 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
 
 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
 SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *);
 #endif
 
@@ -8755,17 +9002,18 @@ SQLITE_PRIVATE   void sqlite3PagerRefdum
 typedef struct PgHdr PgHdr;
 typedef struct PCache PCache;
 
 /*
 ** Every page in the cache is controlled by an instance of the following
 ** structure.
 */
 struct PgHdr {
-  void *pData;                   /* Content of this page */
+  sqlite3_pcache_page *pPage;    /* Pcache object page handle */
+  void *pData;                   /* Page data */
   void *pExtra;                  /* Extra content */
   PgHdr *pDirty;                 /* Transient list of dirty pages */
   Pgno pgno;                     /* Page number for this page */
   Pager *pPager;                 /* The pager this page is part of */
 #ifdef SQLITE_CHECK_PAGES
   u32 pageHash;                  /* Hash of page content */
 #endif
   u16 flags;                     /* PGHDR flags defined below */
@@ -8873,16 +9121,19 @@ SQLITE_PRIVATE void sqlite3PcacheIterate
 ** the total number of pages cached by purgeable pager-caches to the sum
 ** of the suggested cache-sizes.
 */
 SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *, int);
 #ifdef SQLITE_TEST
 SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *);
 #endif
 
+/* Free up as much memory as possible from the page cache */
+SQLITE_PRIVATE void sqlite3PcacheShrink(PCache*);
+
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
 /* Try to return memory used by the pcache module to the main memory heap */
 SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int);
 #endif
 
 #ifdef SQLITE_TEST
 SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*);
 #endif
@@ -8959,27 +9210,16 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefa
 # endif
 #else
 # ifndef SQLITE_OS_WIN
 #  define SQLITE_OS_WIN 0
 # endif
 #endif
 
 /*
-** Determine if we are dealing with WindowsCE - which has a much
-** reduced API.
-*/
-#if defined(_WIN32_WCE)
-# define SQLITE_OS_WINCE 1
-#else
-# define SQLITE_OS_WINCE 0
-#endif
-
-
-/*
 ** Define the maximum size of a temporary filename
 */
 #if SQLITE_OS_WIN
 # include <windows.h>
 # define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
 #elif SQLITE_OS_OS2
 # if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY)
 #  include <os2safe.h> /* has to be included before os2.h for linking to work */
@@ -8993,28 +9233,47 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefa
 # define INCL_DOSSEMAPHORES
 # include <os2.h>
 # include <uconv.h>
 # define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP)
 #else
 # define SQLITE_TEMPNAME_SIZE 200
 #endif
 
+/*
+** Determine if we are dealing with Windows NT.
+*/
+#if defined(_WIN32_WINNT)
+# define SQLITE_OS_WINNT 1
+#else
+# define SQLITE_OS_WINNT 0
+#endif
+
+/*
+** Determine if we are dealing with WindowsCE - which has a much
+** reduced API.
+*/
+#if defined(_WIN32_WCE)
+# define SQLITE_OS_WINCE 1
+#else
+# define SQLITE_OS_WINCE 0
+#endif
+
 /* If the SET_FULLSYNC macro is not defined above, then make it
 ** a no-op
 */
 #ifndef SET_FULLSYNC
 # define SET_FULLSYNC(x,y)
 #endif
 
 /*
 ** The default size of a disk sector
 */
 #ifndef SQLITE_DEFAULT_SECTOR_SIZE
-# define SQLITE_DEFAULT_SECTOR_SIZE 512
+# define SQLITE_DEFAULT_SECTOR_SIZE 4096
 #endif
 
 /*
 ** Temporary files are named starting with this prefix followed by 16 random
 ** alphanumeric characters, and no file extension. They are stored in the
 ** OS's standard temporary file directory, and are deleted prior to exit.
 ** If sqlite is being embedded in another program, you may wish to change the
 ** prefix to reflect your program's name, so that if your program exits
@@ -9137,24 +9396,26 @@ SQLITE_PRIVATE int sqlite3OsRead(sqlite3
 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);
 SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize);
 SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int);
 SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int);
 SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut);
 SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*);
+SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*);
 #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0
 SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id);
 SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
 SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
 SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
 SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id);
 SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int);
 
+
 /* 
 ** Functions for accessing sqlite3_vfs methods 
 */
 SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *);
 SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int);
 SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut);
 SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *);
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
@@ -9237,24 +9498,27 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sq
 #endif
 
 #ifdef SQLITE_MUTEX_OMIT
 /*
 ** If this is a no-op implementation, implement everything as macros.
 */
 #define sqlite3_mutex_alloc(X)    ((sqlite3_mutex*)8)
 #define sqlite3_mutex_free(X)
-#define sqlite3_mutex_enter(X)
+#define sqlite3_mutex_enter(X)    
 #define sqlite3_mutex_try(X)      SQLITE_OK
-#define sqlite3_mutex_leave(X)
+#define sqlite3_mutex_leave(X)    
 #define sqlite3_mutex_held(X)     ((void)(X),1)
 #define sqlite3_mutex_notheld(X)  ((void)(X),1)
 #define sqlite3MutexAlloc(X)      ((sqlite3_mutex*)8)
 #define sqlite3MutexInit()        SQLITE_OK
 #define sqlite3MutexEnd()
+#define MUTEX_LOGIC(X)
+#else
+#define MUTEX_LOGIC(X)            X
 #endif /* defined(SQLITE_MUTEX_OMIT) */
 
 /************** End of mutex.h ***********************************************/
 /************** Continuing where we left off in sqliteInt.h ******************/
 
 
 /*
 ** Each database file to be accessed by the system is an instance
@@ -9555,16 +9819,17 @@ struct sqlite3 {
 #define SQLITE_QueryFlattener 0x01        /* Disable query flattening */
 #define SQLITE_ColumnCache    0x02        /* Disable the column cache */
 #define SQLITE_IndexSort      0x04        /* Disable indexes for sorting */
 #define SQLITE_IndexSearch    0x08        /* Disable indexes for searching */
 #define SQLITE_IndexCover     0x10        /* Disable index covering table */
 #define SQLITE_GroupByOrder   0x20        /* Disable GROUPBY cover of ORDERBY */
 #define SQLITE_FactorOutConst 0x40        /* Disable factoring out constants */
 #define SQLITE_IdxRealAsInt   0x80        /* Store REAL as INT in indices */
+#define SQLITE_DistinctOpt    0x80        /* DISTINCT using indexes */
 #define SQLITE_OptMask        0xff        /* Mask of all disablable opts */
 
 /*
 ** 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 */
@@ -9731,31 +9996,22 @@ struct Column {
 **
 ** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
 ** collating sequence is undefined.  Indices built on an undefined
 ** collating sequence may not be read or written.
 */
 struct CollSeq {
   char *zName;          /* Name of the collating sequence, UTF-8 encoded */
   u8 enc;               /* Text encoding handled by xCmp() */
-  u8 type;              /* One of the SQLITE_COLL_... values below */
   void *pUser;          /* First argument to xCmp() */
   int (*xCmp)(void*,int, const void*, int, const void*);
   void (*xDel)(void*);  /* Destructor for pUser */
 };
 
 /*
-** Allowed values of CollSeq.type:
-*/
-#define SQLITE_COLL_BINARY  1  /* The default memcmp() collating sequence */
-#define SQLITE_COLL_NOCASE  2  /* The built-in NOCASE collating sequence */
-#define SQLITE_COLL_REVERSE 3  /* The built-in REVERSE collating sequence */
-#define SQLITE_COLL_USER    0  /* Any other user-defined collating sequence */
-
-/*
 ** A sort order can be either ASC or DESC.
 */
 #define SQLITE_SO_ASC       0  /* Sort in ascending order */
 #define SQLITE_SO_DESC      1  /* Sort in ascending order */
 
 /*
 ** Column affinity types.
 **
@@ -9876,17 +10132,17 @@ struct VTable {
 */
 struct Table {
   char *zName;         /* Name of the table or view */
   int iPKey;           /* If not negative, use aCol[iPKey] as the primary key */
   int nCol;            /* Number of columns in this table */
   Column *aCol;        /* Information about each column */
   Index *pIndex;       /* List of SQL indexes on this table. */
   int tnum;            /* Root BTree node for this table (see note above) */
-  unsigned nRowEst;    /* Estimated rows in table - from sqlite_stat1 table */
+  tRowcnt nRowEst;     /* Estimated rows in table - from sqlite_stat1 table */
   Select *pSelect;     /* NULL for tables.  Points to definition if a view. */
   u16 nRef;            /* Number of pointers to this Table */
   u8 tabFlags;         /* Mask of TF_* values */
   u8 keyConf;          /* What to do in case of uniqueness conflict on iPKey */
   FKey *pFKey;         /* Linked list of all foreign keys in this table */
   char *zColAff;       /* String defining the affinity of each column */
 #ifndef SQLITE_OMIT_CHECK
   Expr *pCheck;        /* The AND of all CHECK constraints */
@@ -10030,30 +10286,27 @@ struct KeyInfo {
 ** OP_Column opcode.
 **
 ** This structure holds a record that has already been disassembled
 ** into its constituent fields.
 */
 struct UnpackedRecord {
   KeyInfo *pKeyInfo;  /* Collation and sort-order information */
   u16 nField;         /* Number of entries in apMem[] */
-  u16 flags;          /* Boolean settings.  UNPACKED_... below */
+  u8 flags;           /* Boolean settings.  UNPACKED_... below */
   i64 rowid;          /* Used by UNPACKED_PREFIX_SEARCH */
   Mem *aMem;          /* Values */
 };
 
 /*
 ** Allowed values of UnpackedRecord.flags
 */
-#define UNPACKED_NEED_FREE     0x0001  /* Memory is from sqlite3Malloc() */
-#define UNPACKED_NEED_DESTROY  0x0002  /* apMem[]s should all be destroyed */
-#define UNPACKED_IGNORE_ROWID  0x0004  /* Ignore trailing rowid on key1 */
-#define UNPACKED_INCRKEY       0x0008  /* Make this key an epsilon larger */
-#define UNPACKED_PREFIX_MATCH  0x0010  /* A prefix match is considered OK */
-#define UNPACKED_PREFIX_SEARCH 0x0020  /* A prefix match is considered OK */
+#define UNPACKED_INCRKEY       0x01  /* Make this key an epsilon larger */
+#define UNPACKED_PREFIX_MATCH  0x02  /* A prefix match is considered OK */
+#define UNPACKED_PREFIX_SEARCH 0x04  /* Ignore final (rowid) field */
 
 /*
 ** Each SQL index is represented in memory by an
 ** instance of the following structure.
 **
 ** The columns of the table that are to be indexed are described
 ** by the aiColumn[] field of this structure.  For example, suppose
 ** we have the following table and index:
@@ -10075,41 +10328,50 @@ struct UnpackedRecord {
 ** and the value of Index.onError indicate the which conflict resolution 
 ** algorithm to employ whenever an attempt is made to insert a non-unique
 ** element.
 */
 struct Index {
   char *zName;     /* Name of this index */
   int nColumn;     /* Number of columns in the table used by this index */
   int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
-  unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
+  tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
   Table *pTable;   /* The SQL table being indexed */
   int tnum;        /* Page containing root of this index in database file */
   u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
   u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
   u8 bUnordered;   /* Use this index for == or IN queries only */
   char *zColAff;   /* String defining the affinity of each column */
   Index *pNext;    /* The next index associated with the same table */
   Schema *pSchema; /* Schema containing this index */
   u8 *aSortOrder;  /* Array of size Index.nColumn. True==DESC, False==ASC */
   char **azColl;   /* Array of collation sequence names for index */
-  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.
+#ifdef SQLITE_ENABLE_STAT3
+  int nSample;             /* Number of elements in aSample[] */
+  tRowcnt avgEq;           /* Average nEq value for key values not in aSample */
+  IndexSample *aSample;    /* Samples of the left-most key */
+#endif
+};
+
+/*
+** Each sample stored in the sqlite_stat3 table is represented in memory 
+** using a structure of this type.  See documentation at the top of the
+** analyze.c source file for additional information.
 */
 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 */
+    double r;       /* Value if eType is SQLITE_FLOAT */
+    i64 i;          /* Value if eType is SQLITE_INTEGER */
   } u;
   u8 eType;         /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
-  u8 nByte;         /* Size in byte of text or blob. */
+  int nByte;        /* Size in byte of text or blob. */
+  tRowcnt nEq;      /* Est. number of rows where the key equals this sample */
+  tRowcnt nLt;      /* Est. number of rows where key is less than this sample */
+  tRowcnt nDLt;     /* Est. number of distinct keys less than this sample */
 };
 
 /*
 ** 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
@@ -10134,16 +10396,17 @@ struct Token {
 ** fields do not need to be freed when deallocating the AggInfo structure.
 */
 struct AggInfo {
   u8 directMode;          /* Direct rendering mode means take data directly
                           ** from source tables rather than from accumulators */
   u8 useSortingIdx;       /* In direct mode, reference the sorting index rather
                           ** than the source table */
   int sortingIdx;         /* Cursor number of the sorting index */
+  int sortingIdxPTab;     /* Cursor number of pseudo-table */
   ExprList *pGroupBy;     /* The group by clause */
   int nSortingColumn;     /* Number of columns in the sorting index */
   struct AggInfo_col {    /* For each column used in source tables */
     Table *pTab;             /* Source table */
     int iTable;              /* Cursor number of the source table */
     int iColumn;             /* Column number within the source table */
     int iSorterColumn;       /* Column number in the sorting index */
     int iMem;                /* Memory location that acts as accumulator */
@@ -10296,20 +10559,20 @@ struct Expr {
 #define EP_Distinct   0x0010  /* Aggregate function with DISTINCT keyword */
 #define EP_VarSelect  0x0020  /* pSelect is correlated, not constant */
 #define EP_DblQuoted  0x0040  /* token.z was originally in "..." */
 #define EP_InfixFunc  0x0080  /* True for an infix function: LIKE, GLOB, etc */
 #define EP_ExpCollate 0x0100  /* Collating sequence specified explicitly */
 #define EP_FixedDest  0x0200  /* Result needed in a specific register */
 #define EP_IntValue   0x0400  /* Integer value contained in u.iValue */
 #define EP_xIsSelect  0x0800  /* x.pSelect is valid (otherwise x.pList is) */
-
-#define EP_Reduced    0x1000  /* Expr struct is EXPR_REDUCEDSIZE bytes only */
-#define EP_TokenOnly  0x2000  /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
-#define EP_Static     0x4000  /* Held in memory not obtained from malloc() */
+#define EP_Hint       0x1000  /* Optimizer hint. Not required for correctness */
+#define EP_Reduced    0x2000  /* Expr struct is EXPR_REDUCEDSIZE bytes only */
+#define EP_TokenOnly  0x4000  /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
+#define EP_Static     0x8000  /* Held in memory not obtained from malloc() */
 
 /*
 ** The following are the meanings of bits in the Expr.flags2 field.
 */
 #define EP2_MallocedToken  0x0001  /* Need to sqlite3DbFree() Expr.zToken */
 #define EP2_Irreducible    0x0002  /* Cannot EXPRDUP_REDUCE this Expr */
 
 /*
@@ -10361,17 +10624,17 @@ struct ExprList {
   int nAlloc;            /* Number of entries allocated below */
   int iECursor;          /* VDBE Cursor associated with this ExprList */
   struct ExprList_item {
     Expr *pExpr;           /* The list of expressions */
     char *zName;           /* Token associated with this expression */
     char *zSpan;           /* Original text of the expression */
     u8 sortOrder;          /* 1 for DESC or 0 for ASC */
     u8 done;               /* A flag to indicate when processing is finished */
-    u16 iCol;              /* For ORDER BY, column number in result set */
+    u16 iOrderByCol;       /* For ORDER BY, column number in result set */
     u16 iAlias;            /* Index into Parse.aAlias[] for zName */
   } *a;                  /* One entry for each expression */
 };
 
 /*
 ** An instance of this structure is used by the parser to record both
 ** the parse tree for an expression and the span of input text for an
 ** expression.
@@ -10443,19 +10706,21 @@ struct SrcList {
   i16 nSrc;        /* Number of tables or subqueries in the FROM clause */
   i16 nAlloc;      /* Number of entries allocated in a[] below */
   struct SrcList_item {
     char *zDatabase;  /* Name of database holding this table */
     char *zName;      /* Name of the table */
     char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
     Table *pTab;      /* An SQL table corresponding to zName */
     Select *pSelect;  /* A SELECT statement used in place of a table name */
-    u8 isPopulated;   /* Temporary table associated with SELECT is populated */
+    int addrFillSub;  /* Address of subroutine to manifest a subquery */
+    int regReturn;    /* Register holding return address of addrFillSub */
     u8 jointype;      /* Type of join between this able and the previous */
     u8 notIndexed;    /* True if there is a NOT INDEXED clause */
+    u8 isCorrelated;  /* True if sub-query is correlated */
 #ifndef SQLITE_OMIT_EXPLAIN
     u8 iSelectId;     /* If pSelect!=0, the id of the sub-select in EQP */
 #endif
     int iCursor;      /* The VDBE cursor number used to access this table */
     Expr *pOn;        /* The ON clause of a join */
     IdList *pUsing;   /* The USING clause of a join */
     Bitmask colUsed;  /* Bit N (1<<N) set if column N of pTab is used */
     char *zIndex;     /* Identifier from "INDEXED BY <zIndex>" clause */
@@ -10548,44 +10813,48 @@ struct WhereLevel {
 ** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
 ** and the WhereInfo.wctrlFlags member.
 */
 #define WHERE_ORDERBY_NORMAL   0x0000 /* No-op */
 #define WHERE_ORDERBY_MIN      0x0001 /* ORDER BY processing for min() func */
 #define WHERE_ORDERBY_MAX      0x0002 /* ORDER BY processing for max() func */
 #define WHERE_ONEPASS_DESIRED  0x0004 /* Want to do one-pass UPDATE/DELETE */
 #define WHERE_DUPLICATES_OK    0x0008 /* Ok to return a row more than once */
-#define WHERE_OMIT_OPEN        0x0010 /* Table cursors are already open */
-#define WHERE_OMIT_CLOSE       0x0020 /* Omit close of table & index cursors */
-#define WHERE_FORCE_TABLE      0x0040 /* Do not use an index-only search */
-#define WHERE_ONETABLE_ONLY    0x0080 /* Only code the 1st table in pTabList */
+#define WHERE_OMIT_OPEN_CLOSE  0x0010 /* Table cursors are already open */
+#define WHERE_FORCE_TABLE      0x0020 /* Do not use an index-only search */
+#define WHERE_ONETABLE_ONLY    0x0040 /* Only code the 1st table in pTabList */
+#define WHERE_AND_ONLY         0x0080 /* Don't use indices for OR terms */
 
 /*
 ** The WHERE clause processing routine has two halves.  The
 ** first part does the start of the WHERE loop and the second
 ** half does the tail of the WHERE loop.  An instance of
 ** this structure is returned by the first half and passed
 ** into the second half to give some continuity.
 */
 struct WhereInfo {
   Parse *pParse;       /* Parsing and code generating context */
   u16 wctrlFlags;      /* Flags originally passed to sqlite3WhereBegin() */
   u8 okOnePass;        /* Ok to use one-pass algorithm for UPDATE or DELETE */
   u8 untestedTerms;    /* Not all WHERE terms resolved by outer loop */
+  u8 eDistinct;
   SrcList *pTabList;             /* List of tables in the join */
   int iTop;                      /* The very beginning of the WHERE loop */
   int iContinue;                 /* Jump here to continue with next record */
   int iBreak;                    /* Jump here to break out of the loop */
   int nLevel;                    /* Number of nested loop */
   struct WhereClause *pWC;       /* Decomposition of the WHERE clause */
   double savedNQueryLoop;        /* pParse->nQueryLoop outside the WHERE loop */
   double nRowOut;                /* Estimated number of output rows */
   WhereLevel a[1];               /* Information about each nest loop in WHERE */
 };
 
+#define WHERE_DISTINCT_UNIQUE 1
+#define WHERE_DISTINCT_ORDERED 2
+
 /*
 ** A NameContext defines a context in which to resolve table and column
 ** names.  The context consists of a list of tables (the pSrcList) field and
 ** a list of named expression (pEList).  The named expression list may
 ** be NULL.  The pSrc corresponds to the FROM clause of a SELECT or
 ** to the table being operated on by INSERT, UPDATE, or DELETE.  The
 ** pEList corresponds to the result set of a SELECT and is NULL for
 ** other statements.
@@ -10655,22 +10924,23 @@ struct Select {
   int addrOpenEphm[3];   /* OP_OpenEphem opcodes related to this select */
   double nSelectRow;     /* Estimated number of result rows */
 };
 
 /*
 ** Allowed values for Select.selFlags.  The "SF" prefix stands for
 ** "Select Flag".
 */
-#define SF_Distinct        0x0001  /* Output should be DISTINCT */
-#define SF_Resolved        0x0002  /* Identifiers have been resolved */
-#define SF_Aggregate       0x0004  /* Contains aggregate functions */
-#define SF_UsesEphemeral   0x0008  /* Uses the OpenEphemeral opcode */
-#define SF_Expanded        0x0010  /* sqlite3SelectExpand() called on this */
-#define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
+#define SF_Distinct        0x01  /* Output should be DISTINCT */
+#define SF_Resolved        0x02  /* Identifiers have been resolved */
+#define SF_Aggregate       0x04  /* Contains aggregate functions */
+#define SF_UsesEphemeral   0x08  /* Uses the OpenEphemeral opcode */
+#define SF_Expanded        0x10  /* sqlite3SelectExpand() called on this */
+#define SF_HasTypeInfo     0x20  /* FROM subqueries have Table metadata */
+#define SF_UseSorter       0x40  /* Sort using a sorter */
 
 
 /*
 ** The results of a select can be distributed in several ways.  The
 ** "SRT" prefix means "SELECT Result Type".
 */
 #define SRT_Union        1  /* Store result as keys in an index */
 #define SRT_Except       2  /* Remove result from a UNION index */
@@ -10775,34 +11045,33 @@ struct TriggerPrg {
 ** list.
 */
 struct Parse {
   sqlite3 *db;         /* The main database structure */
   int rc;              /* Return code from execution */
   char *zErrMsg;       /* An error message */
   Vdbe *pVdbe;         /* An engine for executing database bytecode */
   u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
-  u8 nameClash;        /* A permanent table name clashes with temp table name */
   u8 checkSchema;      /* Causes schema cookie check after an error */
   u8 nested;           /* Number of nested calls to the parser/code generator */
-  u8 parseError;       /* True after a parsing error.  Ticket #1794 */
   u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
   u8 nTempInUse;       /* Number of aTempReg[] currently checked out */
   int aTempReg[8];     /* Holding area for temporary registers */
   int nRangeReg;       /* Size of the temporary register block */
   int iRangeReg;       /* First register in temporary register block */
   int nErr;            /* Number of errors seen */
   int nTab;            /* Number of previously allocated VDBE cursors */
   int nMem;            /* Number of memory cells used so far */
   int nSet;            /* Number of sets used so far */
+  int nOnce;           /* Number of OP_Once instructions so far */
   int ckBase;          /* Base register of data during check constraints */
   int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
   int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
-  u8 nColCache;        /* Number of entries in the column cache */
-  u8 iColCache;        /* Next entry of the cache to replace */
+  u8 nColCache;        /* Number of entries in aColCache[] */
+  u8 iColCache;        /* Next entry in aColCache[] to replace */
   struct yColCache {
     int iTable;           /* Table cursor number */
     int iColumn;          /* Table column number */
     u8 tempReg;           /* iReg is a temp register that needs to be freed */
     int iLevel;           /* Nesting level */
     int iReg;             /* Reg with value of this column. 0 means none. */
     int lru;              /* Least recently used entry has the smallest value */
   } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
@@ -10834,17 +11103,16 @@ struct Parse {
   /* Above is constant between recursions.  Below is reset before and after
   ** each recursion */
 
   int nVar;            /* Number of '?' variables seen in the SQL so far */
   int nzVar;           /* Number of available slots in azVar[] */
   char **azVar;        /* Pointers to names of parameters */
   Vdbe *pReprepare;    /* VM being reprepared (sqlite3Reprepare()) */
   int nAlias;          /* Number of aliased result set columns */
-  int 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 sNameToken;    /* Token with unqualified schema object name */
   Token sLastToken;    /* The last token parsed */
   const char *zTail;   /* All SQL text past the last semicolon parsed */
   Table *pNewTable;    /* A table being constructed by CREATE TABLE */
   Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
   const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
@@ -11029,17 +11297,17 @@ struct Sqlite3Config {
   int bCoreMutex;                   /* True to enable core mutexing */
   int bFullMutex;                   /* True to enable full mutexing */
   int bOpenUri;                     /* True to interpret filenames as URIs */
   int mxStrlen;                     /* Maximum string length */
   int szLookaside;                  /* Default lookaside buffer size */
   int nLookaside;                   /* Default lookaside buffer count */
   sqlite3_mem_methods m;            /* Low-level memory allocation interface */
   sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
-  sqlite3_pcache_methods pcache;    /* Low-level page-cache interface */
+  sqlite3_pcache_methods2 pcache2;  /* Low-level page-cache interface */
   void *pHeap;                      /* Heap storage space */
   int nHeap;                        /* Size of pHeap[] */
   int mnReq, mxReq;                 /* Min and max heap requests sizes */
   void *pScratch;                   /* Scratch memory */
   int szScratch;                    /* Size of each scratch buffer */
   int nScratch;                     /* Number of scratch buffers */
   void *pPage;                      /* Page cache memory */
   int szPage;                       /* Size of each page in pPage[] */
@@ -11235,26 +11503,50 @@ SQLITE_PRIVATE char *sqlite3MPrintf(sqli
 SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
 SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
 SQLITE_PRIVATE   void sqlite3DebugPrintf(const char*, ...);
 #endif
 #if defined(SQLITE_TEST)
 SQLITE_PRIVATE   void *sqlite3TestTextToPtr(const char*);
 #endif
+
+/* Output formatting for SQLITE_TESTCTRL_EXPLAIN */
+#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
+SQLITE_PRIVATE   void sqlite3ExplainBegin(Vdbe*);
+SQLITE_PRIVATE   void sqlite3ExplainPrintf(Vdbe*, const char*, ...);
+SQLITE_PRIVATE   void sqlite3ExplainNL(Vdbe*);
+SQLITE_PRIVATE   void sqlite3ExplainPush(Vdbe*);
+SQLITE_PRIVATE   void sqlite3ExplainPop(Vdbe*);
+SQLITE_PRIVATE   void sqlite3ExplainFinish(Vdbe*);
+SQLITE_PRIVATE   void sqlite3ExplainSelect(Vdbe*, Select*);
+SQLITE_PRIVATE   void sqlite3ExplainExpr(Vdbe*, Expr*);
+SQLITE_PRIVATE   void sqlite3ExplainExprList(Vdbe*, ExprList*);
+SQLITE_PRIVATE   const char *sqlite3VdbeExplanation(Vdbe*);
+#else
+# define sqlite3ExplainBegin(X)
+# define sqlite3ExplainSelect(A,B)
+# define sqlite3ExplainExpr(A,B)
+# define sqlite3ExplainExprList(A,B)
+# define sqlite3ExplainFinish(X)
+# define sqlite3VdbeExplanation(X) 0
+#endif
+
+
 SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
 SQLITE_PRIVATE int sqlite3Dequote(char*);
 SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
 SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
 SQLITE_PRIVATE void sqlite3FinishCoding(Parse*);
 SQLITE_PRIVATE int sqlite3GetTempReg(Parse*);
 SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int);
 SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int);
 SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int);
+SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*);
 SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
 SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
 SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
 SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
 SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
 SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
@@ -11276,16 +11568,17 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Pa
 SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
 SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
 SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*);
 SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
 SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
 SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*);
 SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
                     sqlite3_vfs**,char**,char **);
+SQLITE_PRIVATE int sqlite3CodeOnce(Parse *);
 
 SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32);
 SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32);
 SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
 SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*);
 SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
 SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
 SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
@@ -11300,16 +11593,17 @@ SQLITE_PRIVATE void sqlite3CreateView(Pa
 
 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
 SQLITE_PRIVATE   int sqlite3ViewGetColumnNames(Parse*,Table*);
 #else
 # define sqlite3ViewGetColumnNames(A,B) 0
 #endif
 
 SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
+SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
 SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
 #ifndef SQLITE_OMIT_AUTOINCREMENT
 SQLITE_PRIVATE   void sqlite3AutoincrementBegin(Parse *pParse);
 SQLITE_PRIVATE   void sqlite3AutoincrementEnd(Parse *pParse);
 #else
 # define sqlite3AutoincrementBegin(X)
 # define sqlite3AutoincrementEnd(X)
 #endif
@@ -11337,17 +11631,17 @@ SQLITE_PRIVATE void sqlite3SelectDelete(
 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
 SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *);
 #endif
 SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
-SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, u16);
+SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**,ExprList*,u16);
 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
 SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int);
 SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
 SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
 SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, int, int, int);
 SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
 SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
 SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int);
@@ -11556,17 +11850,17 @@ SQLITE_PRIVATE u8 sqlite3GetBoolean(cons
 
 SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
 SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
 SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, 
                         void(*)(void*));
 SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
 SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
 SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
-#ifdef SQLITE_ENABLE_STAT2
+#ifdef SQLITE_ENABLE_STAT3
 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 sqlite3OpcodeProperty[];
 SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
 SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
@@ -11613,16 +11907,17 @@ SQLITE_PRIVATE int sqlite3CreateFunc(sql
   void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
   FuncDestructor *pDestructor
 );
 SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
 SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
 
 SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
 SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
+SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum*,int);
 SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
 SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
 SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
 SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
 
 SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
 SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
 
@@ -11658,25 +11953,27 @@ SQLITE_PRIVATE   int sqlite3Utf8To8(unsi
 #  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)
 #  define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
+#  define sqlite3GetVTable(X,Y)  ((VTable*)0)
 #else
 SQLITE_PRIVATE    void sqlite3VtabClear(sqlite3 *db, 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*);
 SQLITE_PRIVATE    int sqlite3VtabSavepoint(sqlite3 *, int, int);
+SQLITE_PRIVATE    VTable *sqlite3GetVTable(sqlite3*, Table*);
 #  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
 #endif
 SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
 SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
 SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
 SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*);
 SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
 SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
@@ -11686,17 +11983,16 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqli
 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
 SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
 SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
 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*);
 SQLITE_PRIVATE const char *sqlite3JournalModename(int);
 SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
 SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
 
 /* Declarations for functions in fkey.c. All of these are replaced by
 ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
 ** key functionality is available. If OMIT_TRIGGER is defined but
 ** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
@@ -11987,21 +12283,21 @@ SQLITE_PRIVATE const unsigned char sqlit
 ** the SQLite library.
 */
 SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
    SQLITE_DEFAULT_MEMSTATUS,  /* bMemstat */
    1,                         /* bCoreMutex */
    SQLITE_THREADSAFE==1,      /* bFullMutex */
    SQLITE_USE_URI,            /* bOpenUri */
    0x7ffffffe,                /* mxStrlen */
-   100,                       /* szLookaside */
+   128,                       /* szLookaside */
    500,                       /* nLookaside */
    {0,0,0,0,0,0,0,0},         /* m */
    {0,0,0,0,0,0,0,0,0},       /* mutex */
-   {0,0,0,0,0,0,0,0,0,0,0},   /* pcache */
+   {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
    (void*)0,                  /* pHeap */
    0,                         /* nHeap */
    0, 0,                      /* mnHeap, mxHeap */
    (void*)0,                  /* pScratch */
    0,                         /* szScratch */
    0,                         /* nScratch */
    (void*)0,                  /* pPage */
    0,                         /* szPage */
@@ -12180,18 +12476,18 @@ static const char * const azCompileOpt[]
   "ENABLE_MEMSYS5",
 #endif
 #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
   "ENABLE_OVERSIZE_CELL_CHECK",
 #endif
 #ifdef SQLITE_ENABLE_RTREE
   "ENABLE_RTREE",
 #endif
-#ifdef SQLITE_ENABLE_STAT2
-  "ENABLE_STAT2",
+#ifdef SQLITE_ENABLE_STAT3
+  "ENABLE_STAT3",
 #endif
 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
   "ENABLE_UNLOCK_NOTIFY",
 #endif
 #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   "ENABLE_UPDATE_DELETE_LIMIT",
 #endif
 #ifdef SQLITE_HAS_CODEC
@@ -12210,16 +12506,19 @@ static const char * const azCompileOpt[]
   "IGNORE_FLOCK_LOCK_ERRORS",
 #endif
 #ifdef SQLITE_INT64_TYPE
   "INT64_TYPE",
 #endif
 #ifdef SQLITE_LOCK_TRACE
   "LOCK_TRACE",
 #endif
+#ifdef SQLITE_MAX_SCHEMA_RETRY
+  "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
+#endif
 #ifdef SQLITE_MEMDEBUG
   "MEMDEBUG",
 #endif
 #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
   "MIXED_ENDIAN_64BIT_FLOAT",
 #endif
 #ifdef SQLITE_NO_SYNC
   "NO_SYNC",
@@ -12323,16 +12622,19 @@ static const char * const azCompileOpt[]
   "OMIT_LOCALTIME",
 #endif
 #ifdef SQLITE_OMIT_LOOKASIDE
   "OMIT_LOOKASIDE",
 #endif
 #ifdef SQLITE_OMIT_MEMORYDB
   "OMIT_MEMORYDB",
 #endif
+#ifdef SQLITE_OMIT_MERGE_SORT
+  "OMIT_MERGE_SORT",
+#endif
 #ifdef SQLITE_OMIT_OR_OPTIMIZATION
   "OMIT_OR_OPTIMIZATION",
 #endif
 #ifdef SQLITE_OMIT_PAGER_PRAGMAS
   "OMIT_PAGER_PRAGMAS",
 #endif
 #ifdef SQLITE_OMIT_PRAGMA
   "OMIT_PRAGMA",
@@ -12509,16 +12811,22 @@ SQLITE_API const char *sqlite3_compileop
 */
 typedef struct VdbeOp Op;
 
 /*
 ** Boolean values
 */
 typedef unsigned char Bool;
 
+/* Opaque type used by code in vdbesort.c */
+typedef struct VdbeSorter VdbeSorter;
+
+/* Opaque type used by the explainer */
+typedef struct Explain Explain;
+
 /*
 ** A cursor is a pointer into a single BTree within a database file.
 ** The cursor can seek to a BTree entry with a particular key, or
 ** loop over all entries of the Btree.  You can also insert new BTree
 ** entries or retrieve the key or data from the entry that the cursor
 ** is currently pointing to.
 ** 
 ** Every cursor that the virtual machine has open is represented by an
@@ -12535,21 +12843,23 @@ struct VdbeCursor {
   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 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 */
   Bool isOrdered;       /* True if the underlying table is BTREE_UNORDERED */
+  Bool isSorter;        /* True if a new-style sorter */
   sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
   const sqlite3_module *pModule;     /* Module for cursor pVtabCursor */
   i64 seqCount;         /* Sequence counter */
   i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
   i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
+  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
 
   /* 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 cacheStatus matches
   ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
@@ -12591,16 +12901,18 @@ typedef struct VdbeCursor VdbeCursor;
 typedef struct VdbeFrame VdbeFrame;
 struct VdbeFrame {
   Vdbe *v;                /* VM this frame belongs to */
   int pc;                 /* Program Counter in parent (calling) frame */
   Op *aOp;                /* Program instructions for parent frame */
   int nOp;                /* Size of aOp array */
   Mem *aMem;              /* Array of memory cells for parent frame */
   int nMem;               /* Number of entries in aMem */
+  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
+  int nOnceFlag;          /* Number of entries in aOnceFlag */
   VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
   u16 nCursor;            /* Number of entries in apCsr */
   void *token;            /* Copy of SubProgram.token */
   int nChildMem;          /* Number of memory cells for child frame */
   int nChildCsr;          /* Number of cursors for child frame */
   i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
   int nChange;            /* Statement changes (Vdbe.nChanges)     */
   VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
@@ -12730,16 +13042,28 @@ struct sqlite3_context {
   VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
   Mem s;                /* The return value is stored here */
   Mem *pMem;            /* Memory cell used to store aggregate context */
   int isError;          /* Error code returned by the function. */
   CollSeq *pColl;       /* Collating sequence */
 };
 
 /*
+** An Explain object accumulates indented output which is helpful
+** in describing recursive data structures.
+*/
+struct Explain {
+  Vdbe *pVdbe;       /* Attach the explanation to this Vdbe */
+  StrAccum str;      /* The string being accumulated */
+  int nIndent;       /* Number of elements in aIndent */
+  u16 aIndent[100];  /* Levels of indentation */
+  char zBase[100];   /* Initial space */
+};
+
+/*
 ** 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_prepare()
 ** 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
@@ -12795,21 +13119,27 @@ struct Vdbe {
 #endif
   i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
   i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
   char *zSql;             /* Text of the SQL statement that generated this */
   void *pFree;            /* Free this when deleting the vdbe */
 #ifdef SQLITE_DEBUG
   FILE *trace;            /* Write an execution trace here, if not NULL */
 #endif
+#ifdef SQLITE_ENABLE_TREE_EXPLAIN
+  Explain *pExplain;      /* The explainer */
+  char *zExplain;         /* Explanation of data structures */
+#endif
   VdbeFrame *pFrame;      /* Parent frame */
   VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
   int nFrame;             /* Number of frames in pFrame list */
   u32 expmask;            /* Binding to these vars invalidates VM */
   SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
+  int nOnceFlag;          /* Size of array aOnceFlag[] */
+  u8 *aOnceFlag;          /* Flags for OP_Once */
 };
 
 /*
 ** 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 */
@@ -12859,34 +13189,56 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(M
 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
 SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
 SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
 SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
 SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
 SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p);
+#define VdbeMemRelease(X)  \
+  if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \
+    sqlite3VdbeMemReleaseExternal(X);
 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
 SQLITE_PRIVATE const char *sqlite3OpcodeName(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 *);
 SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem);
+SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
+
+#ifdef SQLITE_OMIT_MERGE_SORT
+# define sqlite3VdbeSorterInit(Y,Z)      SQLITE_OK
+# define sqlite3VdbeSorterWrite(X,Y,Z)   SQLITE_OK
+# define sqlite3VdbeSorterClose(Y,Z)
+# define sqlite3VdbeSorterRowkey(Y,Z)    SQLITE_OK
+# define sqlite3VdbeSorterRewind(X,Y,Z)  SQLITE_OK
+# define sqlite3VdbeSorterNext(X,Y,Z)    SQLITE_OK
+# define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK
+#else
+SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
+SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
+SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *);
+SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *);
+SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *);
+SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *);
+SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *);
+#endif
 
 #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
 SQLITE_PRIVATE   void sqlite3VdbeEnter(Vdbe*);
 SQLITE_PRIVATE   void sqlite3VdbeLeave(Vdbe*);
 #else
 # define sqlite3VdbeEnter(X)
 # define sqlite3VdbeLeave(X)
 #endif
 
 #ifdef SQLITE_DEBUG
-SQLITE_PRIVATE void sqlite3VdbeMemPrepareToChange(Vdbe*,Mem*);
+SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
 #endif
 
 #ifndef SQLITE_OMIT_FOREIGN_KEY
 SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int);
 #else
 # define sqlite3VdbeCheckFk(p,i) 0
 #endif
 
@@ -12894,18 +13246,20 @@ SQLITE_PRIVATE int sqlite3VdbeMemTransla
 #ifdef SQLITE_DEBUG
 SQLITE_PRIVATE   void sqlite3VdbePrintSql(Vdbe*);
 SQLITE_PRIVATE   void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
 #endif
 SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
 
 #ifndef SQLITE_OMIT_INCRBLOB
 SQLITE_PRIVATE   int sqlite3VdbeMemExpandBlob(Mem *);
+  #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)
 #else
   #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK
+  #define ExpandBlob(P) SQLITE_OK
 #endif
 
 #endif /* !defined(_VDBEINT_H_) */
 
 /************** End of vdbeInt.h *********************************************/
 /************** Continuing where we left off in status.c *********************/
 
 /*
@@ -13105,16 +13459,38 @@ SQLITE_API int sqlite3_db_status(
       db->pnBytesFreed = 0;
 
       *pHighwater = 0;
       *pCurrent = nByte;
 
       break;
     }
 
+    /*
+    ** Set *pCurrent to the total cache hits or misses encountered by all
+    ** pagers the database handle is connected to. *pHighwater is always set 
+    ** to zero.
+    */
+    case SQLITE_DBSTATUS_CACHE_HIT:
+    case SQLITE_DBSTATUS_CACHE_MISS: {
+      int i;
+      int nRet = 0;
+      assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
+
+      for(i=0; i<db->nDb; i++){
+        if( db->aDb[i].pBt ){
+          Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
+          sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
+        }
+      }
+      *pHighwater = 0;
+      *pCurrent = nRet;
+      break;
+    }
+
     default: {
       rc = SQLITE_ERROR;
     }
   }
   sqlite3_mutex_leave(db->mutex);
   return rc;
 }
 
@@ -13160,16 +13536,18 @@ SQLITE_API int sqlite3_db_status(
 ** in the following text:
 **
 **      Jean Meeus
 **      Astronomical Algorithms, 2nd Edition, 1998
 **      ISBM 0-943396-61-1
 **      Willmann-Bell, Inc
 **      Richmond, Virginia (USA)
 */
+/* #include <stdlib.h> */
+/* #include <assert.h> */
 #include <time.h>
 
 #ifndef SQLITE_OMIT_DATETIME_FUNCS
 
 
 /*
 ** A structure for holding a single date and time.
 */
@@ -13403,22 +13781,28 @@ static int parseYyyyMmDd(const char *zDa
   p->D = D;
   if( p->validTZ ){
     computeJD(p);
   }
   return 0;
 }
 
 /*
-** Set the time to the current time reported by the VFS
-*/
-static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
+** Set the time to the current time reported by the VFS.
+**
+** Return the number of errors.
+*/
+static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
   sqlite3 *db = sqlite3_context_db_handle(context);
-  sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD);
-  p->validJD = 1;
+  if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){
+    p->validJD = 1;
+    return 0;
+  }else{
+    return 1;
+  }
 }
 
 /*
 ** Attempt to parse the given string into a Julian Day Number.  Return
 ** the number of errors.
 **
 ** The following are acceptable forms for the input string:
 **
@@ -13438,18 +13822,17 @@ static int parseDateOrTime(
   DateTime *p
 ){
   double r;
   if( parseYyyyMmDd(zDate,p)==0 ){
     return 0;
   }else if( parseHhMmSs(zDate, p)==0 ){
     return 0;
   }else if( sqlite3StrICmp(zDate,"now")==0){
-    setDateTimeToCurrent(context, p);
-    return 0;
+    return setDateTimeToCurrent(context, p);
   }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
     p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
     p->validJD = 1;
     return 0;
   }
   return 1;
 }
 
@@ -13541,17 +13924,19 @@ static void clearYMD_HMS_TZ(DateTime *p)
 ** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
 ** routine will always fail.
 */
 static int osLocaltime(time_t *t, struct tm *pTm){
   int rc;
 #if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \
       && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S)
   struct tm *pX;
+#if SQLITE_THREADSAFE>0
   sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+#endif
   sqlite3_mutex_enter(mutex);
   pX = localtime(t);
 #ifndef SQLITE_OMIT_BUILTIN_TEST
   if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
 #endif
   if( pX ) *pTm = *pX;
   sqlite3_mutex_leave(mutex);
   rc = pX==0;
@@ -13864,18 +14249,19 @@ static int isDate(
   sqlite3_value **argv, 
   DateTime *p
 ){
   int i;
   const unsigned char *z;
   int eType;
   memset(p, 0, sizeof(*p));
   if( argc==0 ){
-    setDateTimeToCurrent(context, p);
-  }else if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
+    return setDateTimeToCurrent(context, p);
+  }
+  if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
                    || eType==SQLITE_INTEGER ){
     p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
     p->validJD = 1;
   }else{
     z = sqlite3_value_text(argv[0]);
     if( !z || parseDateOrTime(context, (char*)z, p) ){
       return 1;
     }
@@ -14177,41 +14563,38 @@ static void currentTimeFunc(
   sqlite3_context *context,
   int argc,
   sqlite3_value **argv
 ){
   time_t t;
   char *zFormat = (char *)sqlite3_user_data(context);
   sqlite3 *db;
   sqlite3_int64 iT;
+  struct tm *pTm;
+  struct tm sNow;
   char zBuf[20];
 
   UNUSED_PARAMETER(argc);
   UNUSED_PARAMETER(argv);
 
   db = sqlite3_context_db_handle(context);
-  sqlite3OsCurrentTimeInt64(db->pVfs, &iT);
+  if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return;
   t = iT/1000 - 10000*(sqlite3_int64)21086676;
 #ifdef HAVE_GMTIME_R
-  {
-    struct tm sNow;
-    gmtime_r(&t, &sNow);
+  pTm = gmtime_r(&t, &sNow);
+#else
+  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+  pTm = gmtime(&t);
+  if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
+  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+#endif
+  if( pTm ){
     strftime(zBuf, 20, zFormat, &sNow);
-  }
-#else
-  {
-    struct tm *pTm;
-    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-    pTm = gmtime(&t);
-    strftime(zBuf, 20, zFormat, pTm);
-    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-  }
-#endif
-
-  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+  }
 }
 #endif
 
 /*
 ** This function registered all of the above C functions as SQL
 ** functions.  This should be the only routine in this file with
 ** external linkage.
 */
@@ -14266,21 +14649,28 @@ SQLITE_PRIVATE void sqlite3RegisterDateT
 ** memory (actually, os_unix.c allocates a small amount of memory
 ** from within OsOpen()), but some third-party implementations may.
 ** So we test the effects of a malloc() failing and the sqlite3OsXXX()
 ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
 **
 ** The following functions are instrumented for malloc() failure 
 ** testing:
 **
-**     sqlite3OsOpen()
 **     sqlite3OsRead()
 **     sqlite3OsWrite()
 **     sqlite3OsSync()
+**     sqlite3OsFileSize()
 **     sqlite3OsLock()
+**     sqlite3OsCheckReservedLock()
+**     sqlite3OsFileControl()
+**     sqlite3OsShmMap()
+**     sqlite3OsOpen()
+**     sqlite3OsDelete()
+**     sqlite3OsAccess()
+**     sqlite3OsFullPathname()
 **
 */
 #if defined(SQLITE_TEST)
 SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
   #define DO_OS_MALLOC_TEST(x)                                       \
   if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
     void *pTstAlloc = sqlite3Malloc(10);                             \
     if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
@@ -14329,19 +14719,33 @@ SQLITE_PRIVATE int sqlite3OsLock(sqlite3
 }
 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(id);
   return id->pMethods->xCheckReservedLock(id, pResOut);
 }
+
+/*
+** Use sqlite3OsFileControl() when we are doing something that might fail
+** and we need to know about the failures.  Use sqlite3OsFileControlHint()
+** when simply tossing information over the wall to the VFS and we do not
+** really care if the VFS receives and understands the information since it
+** is only a hint and can be safely ignored.  The sqlite3OsFileControlHint()
+** routine has no return value since the return value would be meaningless.
+*/
 SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
+  DO_OS_MALLOC_TEST(id);
   return id->pMethods->xFileControl(id, op, pArg);
 }
+SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
+  (void)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);
 }
 SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
   return id->pMethods->xDeviceCharacteristics(id);
 }
 SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
@@ -14355,41 +14759,44 @@ SQLITE_PRIVATE int sqlite3OsShmUnmap(sql
 }
 SQLITE_PRIVATE int sqlite3OsShmMap(
   sqlite3_file *id,               /* Database file handle */
   int iPage,
   int pgsz,
   int bExtend,                    /* True to extend file if necessary */
   void volatile **pp              /* OUT: Pointer to mapping */
 ){
+  DO_OS_MALLOC_TEST(id);
   return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
 }
 
 /*
 ** The next group of routines are convenience wrappers around the
 ** VFS methods.
 */
 SQLITE_PRIVATE int sqlite3OsOpen(
   sqlite3_vfs *pVfs, 
   const char *zPath, 
   sqlite3_file *pFile, 
   int flags, 
   int *pFlagsOut
 ){
   int rc;
   DO_OS_MALLOC_TEST(0);
-  /* 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed
+  /* 0x87f7f 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 & 0x87f3f, pFlagsOut);
+  rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
   assert( rc==SQLITE_OK || pFile->pMethods==0 );
   return rc;
 }
 SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
+  DO_OS_MALLOC_TEST(0);
+  assert( dirSync==0 || dirSync==1 );
   return pVfs->xDelete(pVfs, zPath, dirSync);
 }
 SQLITE_PRIVATE int sqlite3OsAccess(
   sqlite3_vfs *pVfs, 
   const char *zPath, 
   int flags, 
   int *pResOut
 ){
@@ -14397,16 +14804,17 @@ SQLITE_PRIVATE int sqlite3OsAccess(
   return pVfs->xAccess(pVfs, zPath, flags, pResOut);
 }
 SQLITE_PRIVATE int sqlite3OsFullPathname(
   sqlite3_vfs *pVfs, 
   const char *zPath, 
   int nPathOut, 
   char *zPathOut
 ){
+  DO_OS_MALLOC_TEST(0);
   zPathOut[0] = 0;
   return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
 }
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
 SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
   return pVfs->xDlOpen(pVfs, zPath);
 }
 SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
@@ -14447,17 +14855,17 @@ SQLITE_PRIVATE int sqlite3OsOpenMalloc(
   sqlite3_vfs *pVfs, 
   const char *zFile, 
   sqlite3_file **ppFile, 
   int flags,
   int *pOutFlags
 ){
   int rc = SQLITE_NOMEM;
   sqlite3_file *pFile;
-  pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile);
+  pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
   if( pFile ){
     rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
     if( rc!=SQLITE_OK ){
       sqlite3_free(pFile);
     }else{
       *ppFile = pFile;
     }
   }
@@ -14536,22 +14944,22 @@ static void vfsUnlink(sqlite3_vfs *pVfs)
 }
 
 /*
 ** Register a VFS with the system.  It is harmless to register the same
 ** VFS multiple times.  The new VFS becomes the default if makeDflt is
 ** true.
 */
 SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
-  sqlite3_mutex *mutex = 0;
+  MUTEX_LOGIC(sqlite3_mutex *mutex;)
 #ifndef SQLITE_OMIT_AUTOINIT
   int rc = sqlite3_initialize();
   if( rc ) return rc;
 #endif
-  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
   sqlite3_mutex_enter(mutex);
   vfsUnlink(pVfs);
   if( makeDflt || vfsList==0 ){
     pVfs->pNext = vfsList;
     vfsList = pVfs;
   }else{
     pVfs->pNext = vfsList->pNext;
     vfsList->pNext = pVfs;
@@ -14749,104 +15157,201 @@ SQLITE_PRIVATE void sqlite3MemSetDefault
 /*
 ** This version of the memory allocator is the default.  It is
 ** used when no other memory allocator is specified using compile-time
 ** macros.
 */
 #ifdef SQLITE_SYSTEM_MALLOC
 
 /*
+** Windows systems have malloc_usable_size() but it is called _msize()
+*/
+#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN
+# define HAVE_MALLOC_USABLE_SIZE 1
+# define malloc_usable_size _msize
+#endif
+
+#if defined(__APPLE__)
+
+/*
+** Use the zone allocator available on apple products
+*/
+#include <sys/sysctl.h>
+#include <malloc/malloc.h>
+#include <libkern/OSAtomic.h>
+static malloc_zone_t* _sqliteZone_;
+#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
+#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
+#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
+#define SQLITE_MALLOCSIZE(x) \
+        (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))
+
+#else /* if not __APPLE__ */
+
+/*
+** Use standard C library malloc and free on non-Apple systems.
+*/
+#define SQLITE_MALLOC(x)    malloc(x)
+#define SQLITE_FREE(x)      free(x)
+#define SQLITE_REALLOC(x,y) realloc((x),(y))
+
+#ifdef HAVE_MALLOC_USABLE_SIZE
+#include <malloc.h>
+#define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
+#else
+#undef SQLITE_MALLOCSIZE
+#endif
+
+#endif /* __APPLE__ or not __APPLE__ */
+
+/*
 ** Like malloc(), but remember the size of the allocation
 ** so that we can find it later using sqlite3MemSize().
 **
 ** For this low-level routine, we are guaranteed that nByte>0 because
 ** cases of nByte<=0 will be intercepted and dealt with by higher level
 ** routines.
 */
 static void *sqlite3MemMalloc(int nByte){
+#ifdef SQLITE_MALLOCSIZE
+  void *p = SQLITE_MALLOC( nByte );
+  if( p==0 ){
+    testcase( sqlite3GlobalConfig.xLog!=0 );
+    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
+  }
+  return p;
+#else
   sqlite3_int64 *p;
   assert( nByte>0 );
   nByte = ROUND8(nByte);
-  p = malloc( nByte+8 );
+  p = SQLITE_MALLOC( nByte+8 );
   if( p ){
     p[0] = nByte;
     p++;
   }else{
     testcase( sqlite3GlobalConfig.xLog!=0 );
     sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
   }
   return (void *)p;
+#endif
 }
 
 /*
 ** Like free() but works for allocations obtained from sqlite3MemMalloc()
 ** or sqlite3MemRealloc().
 **
 ** For this low-level routine, we already know that pPrior!=0 since
 ** cases where pPrior==0 will have been intecepted and dealt with
 ** by higher-level routines.
 */
 static void sqlite3MemFree(void *pPrior){
+#ifdef SQLITE_MALLOCSIZE
+  SQLITE_FREE(pPrior);
+#else
   sqlite3_int64 *p = (sqlite3_int64*)pPrior;
   assert( pPrior!=0 );
   p--;
-  free(p);
+  SQLITE_FREE(p);
+#endif
 }
 
 /*
 ** Report the allocated size of a prior return from xMalloc()
 ** or xRealloc().
 */
 static int sqlite3MemSize(void *pPrior){
+#ifdef SQLITE_MALLOCSIZE
+  return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
+#else
   sqlite3_int64 *p;
   if( pPrior==0 ) return 0;
   p = (sqlite3_int64*)pPrior;
   p--;
   return (int)p[0];
+#endif
 }
 
 /*
 ** Like realloc().  Resize an allocation previously obtained from
 ** sqlite3MemMalloc().
 **
 ** For this low-level interface, we know that pPrior!=0.  Cases where
 ** pPrior==0 while have been intercepted by higher-level routine and
 ** redirected to xMalloc.  Similarly, we know that nByte>0 becauses
 ** cases where nByte<=0 will have been intercepted by higher-level
 ** routines and redirected to xFree.
 */
 static void *sqlite3MemRealloc(void *pPrior, int nByte){
+#ifdef SQLITE_MALLOCSIZE
+  void *p = SQLITE_REALLOC(pPrior, nByte);
+  if( p==0 ){
+    testcase( sqlite3GlobalConfig.xLog!=0 );
+    sqlite3_log(SQLITE_NOMEM,
+      "failed memory resize %u to %u bytes",
+      SQLITE_MALLOCSIZE(pPrior), nByte);
+  }
+  return p;
+#else
   sqlite3_int64 *p = (sqlite3_int64*)pPrior;
   assert( pPrior!=0 && nByte>0 );
   assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */
   p--;
-  p = realloc(p, nByte+8 );
+  p = SQLITE_REALLOC(p, nByte+8 );
   if( p ){
     p[0] = nByte;
     p++;
   }else{
     testcase( sqlite3GlobalConfig.xLog!=0 );
     sqlite3_log(SQLITE_NOMEM,
       "failed memory resize %u to %u bytes",
       sqlite3MemSize(pPrior), nByte);
   }
   return (void*)p;
+#endif
 }
 
 /*
 ** Round up a request size to the next valid allocation size.
 */
 static int sqlite3MemRoundup(int n){
   return ROUND8(n);
 }
 
 /*
 ** Initialize this module.
 */
 static int sqlite3MemInit(void *NotUsed){
+#if defined(__APPLE__)
+  int cpuCount;
+  size_t len;
+  if( _sqliteZone_ ){
+    return SQLITE_OK;
+  }
+  len = sizeof(cpuCount);
+  /* One usually wants to use hw.acctivecpu for MT decisions, but not here */
+  sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);
+  if( cpuCount>1 ){
+    /* defer MT decisions to system malloc */
+    _sqliteZone_ = malloc_default_zone();
+  }else{
+    /* only 1 core, use our own zone to contention over global locks, 
+    ** e.g. we have our own dedicated locks */
+    bool success;		
+    malloc_zone_t* newzone = malloc_create_zone(4096, 0);
+    malloc_set_zone_name(newzone, "Sqlite_Heap");
+    do{
+      success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, 
+                                 (void * volatile *)&_sqliteZone_);
+    }while(!_sqliteZone_);
+    if( !success ){	
+      /* somebody registered a zone first */
+      malloc_destroy_zone(newzone);
+    }
+  }
+#endif
   UNUSED_PARAMETER(NotUsed);
   return SQLITE_OK;
 }
 
 /*
 ** Deinitialize this module.
 */
 static void sqlite3MemShutdown(void *NotUsed){
@@ -14911,16 +15416,17 @@ SQLITE_PRIVATE void sqlite3MemSetDefault
 */
 #ifdef __GLIBC__
   extern int backtrace(void**,int);
   extern void backtrace_symbols_fd(void*const*,int,int);
 #else
 # define backtrace(A,B) 1
 # define backtrace_symbols_fd(A,B,C)
 #endif
+/* #include <stdio.h> */
 
 /*
 ** Each memory allocation looks like this:
 **
 **  ------------------------------------------------------------------------
 **  | Title |  backtrace pointers |  MemBlockHdr |  allocation |  EndGuard |
 **  ------------------------------------------------------------------------
 **
@@ -15836,17 +16342,17 @@ static void *memsys3MallocUnsafe(int nBy
 }
 
 /*
 ** Free an outstanding memory allocation.
 **
 ** This function assumes that the necessary mutexes, if any, are
 ** already held by the caller. Hence "Unsafe".
 */
-void memsys3FreeUnsafe(void *pOld){
+static void memsys3FreeUnsafe(void *pOld){
   Mem3Block *p = (Mem3Block*)pOld;
   int i;
   u32 size, x;
   assert( sqlite3_mutex_held(mem3.mutex) );
   assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] );
   i = p - mem3.aPool;
   assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 );
   size = mem3.aPool[i-1].u.hdr.size4x/4;
@@ -15911,27 +16417,27 @@ static void *memsys3Malloc(int nBytes){
   p = memsys3MallocUnsafe(nBytes);
   memsys3Leave();
   return (void*)p; 
 }
 
 /*
 ** Free memory.
 */
-void memsys3Free(void *pPrior){
+static void memsys3Free(void *pPrior){
   assert( pPrior );
   memsys3Enter();
   memsys3FreeUnsafe(pPrior);
   memsys3Leave();
 }
 
 /*
 ** Change the size of an existing memory allocation
 */
-void *memsys3Realloc(void *pPrior, int nBytes){
+static void *memsys3Realloc(void *pPrior, int nBytes){
   int nOld;
   void *p;
   if( pPrior==0 ){
     return sqlite3_malloc(nBytes);
   }
   if( nBytes<=0 ){
     sqlite3_free(pPrior);
     return 0;
@@ -16825,17 +17331,17 @@ SQLITE_API void sqlite3_mutex_leave(sqli
 SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
   return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
 }
 SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
   return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
 }
 #endif
 
-#endif /* SQLITE_MUTEX_OMIT */
+#endif /* !defined(SQLITE_MUTEX_OMIT) */
 
 /************** End of mutex.c ***********************************************/
 /************** Begin file mutex_noop.c **************************************/
 /*
 ** 2008 October 07
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
@@ -17032,18 +17538,18 @@ SQLITE_PRIVATE sqlite3_mutex_methods con
 /*
 ** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation
 ** is used regardless of the run-time threadsafety setting.
 */
 #ifdef SQLITE_MUTEX_NOOP
 SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
   return sqlite3NoopMutex();
 }
-#endif /* SQLITE_MUTEX_NOOP */
-#endif /* SQLITE_MUTEX_OMIT */
+#endif /* defined(SQLITE_MUTEX_NOOP) */
+#endif /* !defined(SQLITE_MUTEX_OMIT) */
 
 /************** End of mutex_noop.c ******************************************/
 /************** Begin file mutex_os2.c ***************************************/
 /*
 ** 2007 August 28
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
@@ -17662,17 +18168,17 @@ SQLITE_PRIVATE sqlite3_mutex_methods con
     0,
     0
 #endif
   };
 
   return &sMutex;
 }
 
-#endif /* SQLITE_MUTEX_PTHREAD */
+#endif /* SQLITE_MUTEX_PTHREADS */
 
 /************** End of mutex_unix.c ******************************************/
 /************** Begin file mutex_w32.c ***************************************/
 /*
 ** 2007 August 14
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
@@ -18014,16 +18520,17 @@ SQLITE_PRIVATE sqlite3_mutex_methods con
 **    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.
 */
+/* #include <stdarg.h> */
 
 /*
 ** Attempt to release up to n bytes of non-essential memory currently
 ** held by SQLite. An example of non-essential memory is memory used to
 ** cache database pages that are not currently in use.
 */
 SQLITE_API int sqlite3_release_memory(int n){
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
@@ -18130,17 +18637,18 @@ SQLITE_API int sqlite3_memory_alarm(
 /*
 ** Set the soft heap-size limit for the library. Passing a zero or 
 ** negative value indicates no limit.
 */
 SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
   sqlite3_int64 priorLimit;
   sqlite3_int64 excess;
 #ifndef SQLITE_OMIT_AUTOINIT
-  sqlite3_initialize();
+  int rc = sqlite3_initialize();
+  if( rc ) return -1;
 #endif
   sqlite3_mutex_enter(mem0.mutex);
   priorLimit = mem0.alarmThreshold;
   sqlite3_mutex_leave(mem0.mutex);
   if( n<0 ) return priorLimit;
   if( n>0 ){
     sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);
   }else{
@@ -18787,58 +19295,20 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite
 ** The "printf" code that follows dates from the 1980's.  It is in
 ** the public domain.  The original comments are included here for
 ** completeness.  They are very out-of-date but might be useful as
 ** an historical reference.  Most of the "enhancements" have been backed
 ** out so that the functionality is now the same as standard printf().
 **
 **************************************************************************
 **
-** The following modules is an enhanced replacement for the "printf" subroutines
-** found in the standard C library.  The following enhancements are
-** supported:
-**
-**      +  Additional functions.  The standard set of "printf" functions
-**         includes printf, fprintf, sprintf, vprintf, vfprintf, and
-**         vsprintf.  This module adds the following:
-**
-**           *  snprintf -- Works like sprintf, but has an extra argument
-**                          which is the size of the buffer written to.
-**
-**           *  mprintf --  Similar to sprintf.  Writes output to memory
-**                          obtained from malloc.
-**
-**           *  xprintf --  Calls a function to dispose of output.
-**
-**           *  nprintf --  No output, but returns the number of characters
-**                          that would have been output by printf.
-**
-**           *  A v- version (ex: vsnprintf) of every function is also
-**              supplied.
-**
-**      +  A few extensions to the formatting notation are supported:
-**
-**           *  The "=" flag (similar to "-") causes the output to be
-**              be centered in the appropriately sized field.
-**
-**           *  The %b field outputs an integer in binary notation.
-**
-**           *  The %c field now accepts a precision.  The character output
-**              is repeated by the number of times the precision specifies.
-**
-**           *  The %' field works like %c, but takes as its character the
-**              next character of the format string, instead of the next
-**              argument.  For example,  printf("%.78'-")  prints 78 minus
-**              signs, the same as  printf("%.78c",'-').
-**
-**      +  When compiled using GCC on a SPARC, this version of printf is
-**         faster than the library printf for SUN OS 4.1.
-**
-**      +  All functions are fully reentrant.
-**
+** This file contains code for a set of "printf"-like routines.  These
+** routines format strings much like the printf() from the standard C
+** library, though the implementation here has enhancements to support
+** SQLlite.
 */
 
 /*
 ** Conversion types fall into various categories as defined by the
 ** following enumeration.
 */
 #define etRADIX       1 /* Integer types.  %d, %x, %o, and so forth */
 #define etFLOAT       2 /* Floating point.  %f */
@@ -18953,66 +19423,38 @@ static char et_getdigit(LONGDOUBLE_TYPE 
   *val = (*val - d)*10.0;
   return (char)digit;
 }
 #endif /* SQLITE_OMIT_FLOATING_POINT */
 
 /*
 ** Append N space characters to the given string buffer.
 */
-static void appendSpace(StrAccum *pAccum, int N){
+SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *pAccum, int N){
   static const char zSpaces[] = "                             ";
   while( N>=(int)sizeof(zSpaces)-1 ){
     sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1);
     N -= sizeof(zSpaces)-1;
   }
   if( N>0 ){
     sqlite3StrAccumAppend(pAccum, zSpaces, N);
   }
 }
 
 /*
 ** On machines with a small stack size, you can redefine the
-** SQLITE_PRINT_BUF_SIZE to be less than 350.
+** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
 */
 #ifndef SQLITE_PRINT_BUF_SIZE
-# if defined(SQLITE_SMALL_STACK)
-#   define SQLITE_PRINT_BUF_SIZE 50
-# else
-#   define SQLITE_PRINT_BUF_SIZE 350
-# endif
+# define SQLITE_PRINT_BUF_SIZE 70
 #endif
 #define etBUFSIZE SQLITE_PRINT_BUF_SIZE  /* Size of the output buffer */
 
 /*
-** The root program.  All variations call this core.
-**
-** INPUTS:
-**   func   This is a pointer to a function taking three arguments
-**            1. A pointer to anything.  Same as the "arg" parameter.
-**            2. A pointer to the list of characters to be output
-**               (Note, this list is NOT null terminated.)
-**            3. An integer number of characters to be output.
-**               (Note: This number might be zero.)
-**
-**   arg    This is the pointer to anything which will be passed as the
-**          first argument to "func".  Use it for whatever you like.
-**
-**   fmt    This is the format string, as in the usual print.
-**
-**   ap     This is a pointer to a list of arguments.  Same as in
-**          vfprint.
-**
-** OUTPUTS:
-**          The return value is the total number of characters sent to
-**          the function "func".  Returns -1 on a error.
-**
-** Note that the order in which automatic variables are declared below
-** seems to make a big difference in determining how fast this beast
-** will run.
+** Render a string given by "fmt" into the StrAccum object.
 */
 SQLITE_PRIVATE void sqlite3VXPrintf(
   StrAccum *pAccum,                  /* Accumulate results here */
   int useExtended,                   /* Allow extended %-conversions */
   const char *fmt,                   /* Format string */
   va_list ap                         /* arguments */
 ){
   int c;                     /* Next character in the format string */
@@ -19025,33 +19467,33 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
   etByte flag_plussign;      /* True if "+" flag is present */
   etByte flag_blanksign;     /* True if " " flag is present */
   etByte flag_alternateform; /* True if "#" flag is present */
   etByte flag_altform2;      /* True if "!" flag is present */
   etByte flag_zeropad;       /* True if field width constant starts with zero */
   etByte flag_long;          /* True if "l" flag is present */
   etByte flag_longlong;      /* True if the "ll" flag is present */
   etByte done;               /* Loop termination flag */
+  etByte xtype = 0;          /* Conversion paradigm */
+  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
   sqlite_uint64 longvalue;   /* Value for integer types */
   LONGDOUBLE_TYPE realvalue; /* Value for real types */
   const et_info *infop;      /* Pointer to the appropriate info structure */
-  char buf[etBUFSIZE];       /* Conversion buffer */
-  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
-  etByte xtype = 0;          /* Conversion paradigm */
-  char *zExtra;              /* Extra memory used for etTCLESCAPE conversions */
+  char *zOut;                /* Rendering buffer */
+  int nOut;                  /* Size of the rendering buffer */
+  char *zExtra;              /* Malloced memory used by some conversion */
 #ifndef SQLITE_OMIT_FLOATING_POINT
   int  exp, e2;              /* exponent of real numbers */
+  int nsd;                   /* Number of significant digits returned */
   double rounder;            /* Used for rounding floating point values */
   etByte flag_dp;            /* True if decimal point should be shown */
   etByte flag_rtz;           /* True if trailing zeros should be removed */
-  etByte flag_exp;           /* True to force display of the exponent */
-  int nsd;                   /* Number of significant digits returned */
-#endif
-
-  length = 0;
+#endif
+  char buf[etBUFSIZE];       /* Conversion buffer */
+
   bufpt = 0;
   for(; (c=(*fmt))!=0; ++fmt){
     if( c!='%' ){
       int amt;
       bufpt = (char *)fmt;
       amt = 1;
       while( (c=(*++fmt))!='%' && c!=0 ) amt++;
       sqlite3StrAccumAppend(pAccum, bufpt, amt);
@@ -19086,19 +19528,16 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
       }
       c = *++fmt;
     }else{
       while( c>='0' && c<='9' ){
         width = width*10 + c - '0';
         c = *++fmt;
       }
     }
-    if( width > etBUFSIZE-10 ){
-      width = etBUFSIZE-10;
-    }
     /* Get the precision */
     if( c=='.' ){
       precision = 0;
       c = *++fmt;
       if( c=='*' ){
         precision = va_arg(ap,int);
         if( precision<0 ) precision = -precision;
         c = *++fmt;
@@ -19135,22 +19574,16 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         }else{
           return;
         }
         break;
       }
     }
     zExtra = 0;
 
-
-    /* Limit the precision to prevent overflowing buf[] during conversion */
-    if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
-      precision = etBUFSIZE-40;
-    }
-
     /*
     ** At this point, variables are initialized as follows:
     **
     **   flag_alternateform          TRUE if a '#' is present.
     **   flag_altform2               TRUE if a '!' is present.
     **   flag_plussign               TRUE if a '+' is present.
     **   flag_leftjustify            TRUE if a '-' is present or if the
     **                               field width was negative.
@@ -19205,59 +19638,68 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
             longvalue = va_arg(ap,unsigned int);
           }
           prefix = 0;
         }
         if( longvalue==0 ) flag_alternateform = 0;
         if( flag_zeropad && precision<width-(prefix!=0) ){
           precision = width-(prefix!=0);
         }
-        bufpt = &buf[etBUFSIZE-1];
+        if( precision<etBUFSIZE-10 ){
+          nOut = etBUFSIZE;
+          zOut = buf;
+        }else{
+          nOut = precision + 10;
+          zOut = zExtra = sqlite3Malloc( nOut );
+          if( zOut==0 ){
+            pAccum->mallocFailed = 1;
+            return;
+          }
+        }
+        bufpt = &zOut[nOut-1];
         if( xtype==etORDINAL ){
           static const char zOrd[] = "thstndrd";
           int x = (int)(longvalue % 10);
           if( x>=4 || (longvalue/10)%10==1 ){
             x = 0;
           }
-          buf[etBUFSIZE-3] = zOrd[x*2];
-          buf[etBUFSIZE-2] = zOrd[x*2+1];
-          bufpt -= 2;
+          *(--bufpt) = zOrd[x*2+1];
+          *(--bufpt) = zOrd[x*2];
         }
         {
           register const char *cset;      /* Use registers for speed */
           register int base;
           cset = &aDigits[infop->charset];
           base = infop->base;
           do{                                           /* Convert to ascii */
             *(--bufpt) = cset[longvalue%base];
             longvalue = longvalue/base;
           }while( longvalue>0 );
         }
-        length = (int)(&buf[etBUFSIZE-1]-bufpt);
+        length = (int)(&zOut[nOut-1]-bufpt);
         for(idx=precision-length; idx>0; idx--){
           *(--bufpt) = '0';                             /* Zero pad */
         }
         if( prefix ) *(--bufpt) = prefix;               /* Add sign */
         if( flag_alternateform && infop->prefix ){      /* Add "0" or "0x" */
           const char *pre;
           char x;
           pre = &aPrefix[infop->prefix];
           for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
         }
-        length = (int)(&buf[etBUFSIZE-1]-bufpt);
+        length = (int)(&zOut[nOut-1]-bufpt);
         break;
       case etFLOAT:
       case etEXP:
       case etGENERIC:
         realvalue = va_arg(ap,double);
 #ifdef SQLITE_OMIT_FLOATING_POINT
         length = 0;
 #else
         if( precision<0 ) precision = 6;         /* Set default precision */
-        if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10;
         if( realvalue<0.0 ){
           realvalue = -realvalue;
           prefix = '-';
         }else{
           if( flag_plussign )          prefix = '+';
           else if( flag_blanksign )    prefix = ' ';
           else                         prefix = 0;
         }
@@ -19295,17 +19737,16 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
             break;
           }
         }
         bufpt = buf;
         /*
         ** If the field type is etGENERIC, then convert to either etEXP
         ** or etFLOAT, as appropriate.
         */
-        flag_exp = xtype==etEXP;
         if( xtype!=etFLOAT ){
           realvalue += rounder;
           if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
         }
         if( xtype==etGENERIC ){
           flag_rtz = !flag_alternateform;
           if( exp<-4 || exp>precision ){
             xtype = etEXP;
@@ -19316,16 +19757,24 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         }else{
           flag_rtz = 0;
         }
         if( xtype==etEXP ){
           e2 = 0;
         }else{
           e2 = exp;
         }
+        if( e2+precision+width > etBUFSIZE - 15 ){
+          bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
+          if( bufpt==0 ){
+            pAccum->mallocFailed = 1;
+            return;
+          }
+        }
+        zOut = bufpt;
         nsd = 0;
         flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
         /* The sign in front of the number */
         if( prefix ){
           *(bufpt++) = prefix;
         }
         /* Digits prior to the decimal point */
         if( e2<0 ){
@@ -19347,27 +19796,27 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         }
         /* Significant digits after the decimal point */
         while( (precision--)>0 ){
           *(bufpt++) = et_getdigit(&realvalue,&nsd);
         }
         /* Remove trailing zeros and the "." if no digits follow the "." */
         if( flag_rtz && flag_dp ){
           while( bufpt[-1]=='0' ) *(--bufpt) = 0;
-          assert( bufpt>buf );
+          assert( bufpt>zOut );
           if( bufpt[-1]=='.' ){
             if( flag_altform2 ){
               *(bufpt++) = '0';
             }else{
               *(--bufpt) = 0;
             }
           }
         }
         /* Add the "eNNN" suffix */
-        if( flag_exp || xtype==etEXP ){
+        if( xtype==etEXP ){
           *(bufpt++) = aDigits[infop->charset];
           if( exp<0 ){
             *(bufpt++) = '-'; exp = -exp;
           }else{
             *(bufpt++) = '+';
           }
           if( exp>=100 ){
             *(bufpt++) = (char)((exp/100)+'0');        /* 100's digit */
@@ -19376,18 +19825,18 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
           *(bufpt++) = (char)(exp/10+'0');             /* 10's digit */
           *(bufpt++) = (char)(exp%10+'0');             /* 1's digit */
         }
         *bufpt = 0;
 
         /* The converted number is in buf[] and zero terminated. Output it.
         ** Note that the number is in the usual order, not reversed as with
         ** integer conversions. */
-        length = (int)(bufpt-buf);
-        bufpt = buf;
+        length = (int)(bufpt-zOut);
+        bufpt = zOut;
 
         /* Special case:  Add leading zeros if the flag_zeropad flag is
         ** set and we are not left justified */
         if( flag_zeropad && !flag_leftjustify && length < width){
           int i;
           int nPad = width - length;
           for(i=width; i>=nPad; i--){
             bufpt[i] = bufpt[i-nPad];
@@ -19502,45 +19951,44 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
     ** The text of the conversion is pointed to by "bufpt" and is
     ** "length" characters long.  The field width is "width".  Do
     ** the output.
     */
     if( !flag_leftjustify ){
       register int nspace;
       nspace = width-length;
       if( nspace>0 ){
-        appendSpace(pAccum, nspace);
+        sqlite3AppendSpace(pAccum, nspace);
       }
     }
     if( length>0 ){
       sqlite3StrAccumAppend(pAccum, bufpt, length);
     }
     if( flag_leftjustify ){
       register int nspace;
       nspace = width-length;
       if( nspace>0 ){
-        appendSpace(pAccum, nspace);
-      }
-    }
-    if( zExtra ){
-      sqlite3_free(zExtra);
-    }
+        sqlite3AppendSpace(pAccum, nspace);
+      }
+    }
+    sqlite3_free(zExtra);
   }/* End for loop over the format string */
 } /* End of function */
 
 /*
 ** Append N bytes of text from z to the StrAccum object.
 */
 SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
   assert( z!=0 || N==0 );
   if( p->tooBig | p->mallocFailed ){
     testcase(p->tooBig);
     testcase(p->mallocFailed);
     return;
   }
+  assert( p->zText!=0 || p->nChar==0 );
   if( N<0 ){
     N = sqlite3Strlen30(z);
   }
   if( N==0 || NEVER(z==0) ){
     return;
   }
   if( p->nChar+N >= p->nAlloc ){
     char *zNew;
@@ -19562,25 +20010,26 @@ SQLITE_PRIVATE void sqlite3StrAccumAppen
         p->nAlloc = (int)szNew;
       }
       if( p->useMalloc==1 ){
         zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
       }else{
         zNew = sqlite3_realloc(zOld, p->nAlloc);
       }
       if( zNew ){
-        if( zOld==0 ) memcpy(zNew, p->zText, p->nChar);
+        if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
         p->zText = zNew;
       }else{
         p->mallocFailed = 1;
         sqlite3StrAccumReset(p);
         return;
       }
     }
   }
+  assert( p->zText );
   memcpy(&p->zText[p->nChar], z, N);
   p->nChar += N;
 }
 
 /*
 ** Finish off a string by making sure it is zero-terminated.
 ** Return a pointer to the resulting string.  Return a NULL
 ** pointer if any kind of error was encountered.
@@ -19991,16 +20440,17 @@ SQLITE_PRIVATE void sqlite3PrngResetStat
 **  zzzzyyyy yyxxxxxx                        00000000 zzzzyyyy yyxxxxxx
 **
 **
 ** BOM or Byte Order Mark:
 **     0xff 0xfe   little-endian utf-16 follows
 **     0xfe 0xff   big-endian utf-16 follows
 **
 */
+/* #include <assert.h> */
 
 #ifndef SQLITE_AMALGAMATION
 /*
 ** The following constant value is used by the SQLITE_BIGENDIAN and
 ** SQLITE_LITTLEENDIAN macros.
 */
 SQLITE_PRIVATE const int sqlite3one = 1;
 #endif /* SQLITE_AMALGAMATION */
@@ -20419,17 +20869,17 @@ SQLITE_PRIVATE char *sqlite3Utf16to8(sql
 ** 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
+#ifdef SQLITE_ENABLE_STAT3
 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;
@@ -20533,16 +20983,17 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(v
 **
 *************************************************************************
 ** Utility functions used throughout sqlite.
 **
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
 */
+/* #include <stdarg.h> */
 #ifdef SQLITE_HAVE_ISNAN
 # include <math.h>
 #endif
 
 /*
 ** Routine needed to support the testcase() macro.
 */
 #ifdef SQLITE_COVERAGE_TEST
@@ -20847,17 +21298,17 @@ SQLITE_PRIVATE int sqlite3AtoF(const cha
     if( *z=='-' ){
       esign = -1;
       z+=incr;
     }else if( *z=='+' ){
       z+=incr;
     }
     /* copy digits to exponent */
     while( z<zEnd && sqlite3Isdigit(*z) ){
-      e = e*10 + (*z - '0');
+      e = e<10000 ? (e*10 + (*z - '0')) : 10000;
       z+=incr;
       eValid = 1;
     }
   }
 
   /* skip trailing spaces */
   if( nDigits && eValid ){
     while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
@@ -20898,16 +21349,22 @@ do_atof_calc:
         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 if( e>=342 ){
+        if( esign<0 ){
+          result = 0.0*s;
+        }else{
+          result = 1e308*1e308*s;  /* Infinity */
+        }
       }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{
@@ -21665,36 +22122,41 @@ SQLITE_PRIVATE int sqlite3MulInt64(i64 *
 SQLITE_PRIVATE int sqlite3AbsInt32(int x){
   if( x>=0 ) return x;
   if( x==(int)0x80000000 ) return 0x7fffffff;
   return -x;
 }
 
 #ifdef SQLITE_ENABLE_8_3_NAMES
 /*
-** If SQLITE_ENABLE_8_3_NAME is set at compile-time and if the database
+** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database
 ** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
 ** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
 ** three characters, then shorten the suffix on z[] to be the last three
 ** characters of the original suffix.
 **
+** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always
+** do the suffix shortening regardless of URI parameter.
+**
 ** Examples:
 **
 **     test.db-journal    =>   test.nal
 **     test.db-wal        =>   test.wal
 **     test.db-shm        =>   test.shm
+**     test.db-mj7f3319fa =>   test.9fa
 */
 SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
-  const char *zOk;
-  zOk = sqlite3_uri_parameter(zBaseFilename, "8_3_names");
-  if( zOk && sqlite3GetBoolean(zOk) ){
+#if SQLITE_ENABLE_8_3_NAMES<2
+  if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) )
+#endif
+  {
     int i, sz;
     sz = sqlite3Strlen30(z);
     for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
-    if( z[i]=='.' && ALWAYS(sz>i+4) ) memcpy(&z[i+1], &z[sz-3], 4);
+    if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
   }
 }
 #endif
 
 /************** End of util.c ************************************************/
 /************** Begin file hash.c ********************************************/
 /*
 ** 2001 September 22
@@ -21705,16 +22167,17 @@ SQLITE_PRIVATE void sqlite3FileSuffix3(c
 **    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 is the implementation of generic hash-tables
 ** used in SQLite.
 */
+/* #include <assert.h> */
 
 /* Turn bulk memory into a hash table object by initializing the
 ** fields of the Hash structure.
 **
 ** "pNew" is a pointer to the hash table that is to be initialized.
 */
 SQLITE_PRIVATE void sqlite3HashInit(Hash *pNew){
   assert( pNew!=0 );
@@ -21999,136 +22462,141 @@ SQLITE_PRIVATE const char *sqlite3Opcode
      /*  18 */ "Function",
      /*  19 */ "Not",
      /*  20 */ "AddImm",
      /*  21 */ "MustBeInt",
      /*  22 */ "RealAffinity",
      /*  23 */ "Permutation",
      /*  24 */ "Compare",
      /*  25 */ "Jump",
-     /*  26 */ "If",
-     /*  27 */ "IfNot",
-     /*  28 */ "Column",
-     /*  29 */ "Affinity",
-     /*  30 */ "MakeRecord",
-     /*  31 */ "Count",
-     /*  32 */ "Savepoint",
-     /*  33 */ "AutoCommit",
-     /*  34 */ "Transaction",
-     /*  35 */ "ReadCookie",
-     /*  36 */ "SetCookie",
-     /*  37 */ "VerifyCookie",
-     /*  38 */ "OpenRead",
-     /*  39 */ "OpenWrite",
-     /*  40 */ "OpenAutoindex",
-     /*  41 */ "OpenEphemeral",
-     /*  42 */ "OpenPseudo",
-     /*  43 */ "Close",
-     /*  44 */ "SeekLt",
-     /*  45 */ "SeekLe",
-     /*  46 */ "SeekGe",
-     /*  47 */ "SeekGt",
-     /*  48 */ "Seek",
-     /*  49 */ "NotFound",
-     /*  50 */ "Found",
-     /*  51 */ "IsUnique",
-     /*  52 */ "NotExists",
-     /*  53 */ "Sequence",
-     /*  54 */ "NewRowid",
-     /*  55 */ "Insert",
-     /*  56 */ "InsertInt",
-     /*  57 */ "Delete",
-     /*  58 */ "ResetCount",
-     /*  59 */ "RowKey",
-     /*  60 */ "RowData",
-     /*  61 */ "Rowid",
-     /*  62 */ "NullRow",
-     /*  63 */ "Last",
-     /*  64 */ "Sort",
-     /*  65 */ "Rewind",
-     /*  66 */ "Prev",
-     /*  67 */ "Next",
+     /*  26 */ "Once",
+     /*  27 */ "If",
+     /*  28 */ "IfNot",
+     /*  29 */ "Column",
+     /*  30 */ "Affinity",
+     /*  31 */ "MakeRecord",
+     /*  32 */ "Count",
+     /*  33 */ "Savepoint",
+     /*  34 */ "AutoCommit",
+     /*  35 */ "Transaction",
+     /*  36 */ "ReadCookie",
+     /*  37 */ "SetCookie",
+     /*  38 */ "VerifyCookie",
+     /*  39 */ "OpenRead",
+     /*  40 */ "OpenWrite",
+     /*  41 */ "OpenAutoindex",
+     /*  42 */ "OpenEphemeral",
+     /*  43 */ "SorterOpen",
+     /*  44 */ "OpenPseudo",
+     /*  45 */ "Close",
+     /*  46 */ "SeekLt",
+     /*  47 */ "SeekLe",
+     /*  48 */ "SeekGe",
+     /*  49 */ "SeekGt",
+     /*  50 */ "Seek",
+     /*  51 */ "NotFound",
+     /*  52 */ "Found",
+     /*  53 */ "IsUnique",
+     /*  54 */ "NotExists",
+     /*  55 */ "Sequence",
+     /*  56 */ "NewRowid",
+     /*  57 */ "Insert",
+     /*  58 */ "InsertInt",
+     /*  59 */ "Delete",
+     /*  60 */ "ResetCount",
+     /*  61 */ "SorterCompare",
+     /*  62 */ "SorterData",
+     /*  63 */ "RowKey",
+     /*  64 */ "RowData",
+     /*  65 */ "Rowid",
+     /*  66 */ "NullRow",
+     /*  67 */ "Last",
      /*  68 */ "Or",
      /*  69 */ "And",
-     /*  70 */ "IdxInsert",
-     /*  71 */ "IdxDelete",
-     /*  72 */ "IdxRowid",
+     /*  70 */ "SorterSort",
+     /*  71 */ "Sort",
+     /*  72 */ "Rewind",
      /*  73 */ "IsNull",
      /*  74 */ "NotNull",
      /*  75 */ "Ne",
      /*  76 */ "Eq",
      /*  77 */ "Gt",
      /*  78 */ "Le",
      /*  79 */ "Lt",
      /*  80 */ "Ge",
-     /*  81 */ "IdxLT",
+     /*  81 */ "SorterNext",
      /*  82 */ "BitAnd",
      /*  83 */ "BitOr",
      /*  84 */ "ShiftLeft",
      /*  85 */ "ShiftRight",
      /*  86 */ "Add",
      /*  87 */ "Subtract",
      /*  88 */ "Multiply",
      /*  89 */ "Divide",
      /*  90 */ "Remainder",
      /*  91 */ "Concat",
-     /*  92 */ "IdxGE",
+     /*  92 */ "Prev",
      /*  93 */ "BitNot",
      /*  94 */ "String8",
-     /*  95 */ "Destroy",
-     /*  96 */ "Clear",
-     /*  97 */ "CreateIndex",
-     /*  98 */ "CreateTable",
-     /*  99 */ "ParseSchema",
-     /* 100 */ "LoadAnalysis",
-     /* 101 */ "DropTable",
-     /* 102 */ "DropIndex",
-     /* 103 */ "DropTrigger",
-     /* 104 */ "IntegrityCk",
-     /* 105 */ "RowSetAdd",
-     /* 106 */ "RowSetRead",
-     /* 107 */ "RowSetTest",
-     /* 108 */ "Program",
-     /* 109 */ "Param",
-     /* 110 */ "FkCounter",
-     /* 111 */ "FkIfZero",
-     /* 112 */ "MemMax",
-     /* 113 */ "IfPos",
-     /* 114 */ "IfNeg",
-     /* 115 */ "IfZero",
-     /* 116 */ "AggStep",
-     /* 117 */ "AggFinal",
-     /* 118 */ "Checkpoint",
-     /* 119 */ "JournalMode",
-     /* 120 */ "Vacuum",
-     /* 121 */ "IncrVacuum",
-     /* 122 */ "Expire",
-     /* 123 */ "TableLock",
-     /* 124 */ "VBegin",
-     /* 125 */ "VCreate",
-     /* 126 */ "VDestroy",
-     /* 127 */ "VOpen",
-     /* 128 */ "VFilter",
-     /* 129 */ "VColumn",
+     /*  95 */ "Next",
+     /*  96 */ "SorterInsert",
+     /*  97 */ "IdxInsert",
+     /*  98 */ "IdxDelete",
+     /*  99 */ "IdxRowid",
+     /* 100 */ "IdxLT",
+     /* 101 */ "IdxGE",
+     /* 102 */ "Destroy",
+     /* 103 */ "Clear",
+     /* 104 */ "CreateIndex",
+     /* 105 */ "CreateTable",
+     /* 106 */ "ParseSchema",
+     /* 107 */ "LoadAnalysis",
+     /* 108 */ "DropTable",
+     /* 109 */ "DropIndex",
+     /* 110 */ "DropTrigger",
+     /* 111 */ "IntegrityCk",
+     /* 112 */ "RowSetAdd",
+     /* 113 */ "RowSetRead",
+     /* 114 */ "RowSetTest",
+     /* 115 */ "Program",
+     /* 116 */ "Param",
+     /* 117 */ "FkCounter",
+     /* 118 */ "FkIfZero",
+     /* 119 */ "MemMax",
+     /* 120 */ "IfPos",
+     /* 121 */ "IfNeg",
+     /* 122 */ "IfZero",
+     /* 123 */ "AggStep",
+     /* 124 */ "AggFinal",
+     /* 125 */ "Checkpoint",
+     /* 126 */ "JournalMode",
+     /* 127 */ "Vacuum",
+     /* 128 */ "IncrVacuum",
+     /* 129 */ "Expire",
      /* 130 */ "Real",
-     /* 131 */ "VNext",
-     /* 132 */ "VRename",
-     /* 133 */ "VUpdate",
-     /* 134 */ "Pagecount",
-     /* 135 */ "MaxPgcnt",
-     /* 136 */ "Trace",
-     /* 137 */ "Noop",
-     /* 138 */ "Explain",
-     /* 139 */ "NotUsed_139",
-     /* 140 */ "NotUsed_140",
+     /* 131 */ "TableLock",
+     /* 132 */ "VBegin",
+     /* 133 */ "VCreate",
+     /* 134 */ "VDestroy",
+     /* 135 */ "VOpen",
+     /* 136 */ "VFilter",
+     /* 137 */ "VColumn",
+     /* 138 */ "VNext",
+     /* 139 */ "VRename",
+     /* 140 */ "VUpdate",
      /* 141 */ "ToText",
      /* 142 */ "ToBlob",
      /* 143 */ "ToNumeric",
      /* 144 */ "ToInt",
      /* 145 */ "ToReal",
+     /* 146 */ "Pagecount",
+     /* 147 */ "MaxPgcnt",
+     /* 148 */ "Trace",
+     /* 149 */ "Noop",
+     /* 150 */ "Explain",
   };
   return azName[i];
 }
 #endif
 
 /************** End of opcodes.c *********************************************/
 /************** Begin file os_os2.c ******************************************/
 /*
@@ -22213,21 +22681,24 @@ SQLITE_PRIVATE const char *sqlite3Opcode
 ** At least two bugs have slipped in because we changed the MEMORY_DEBUG
 ** macro to SQLITE_DEBUG and some older makefiles have not yet made the
 ** switch.  The following code should catch this problem at compile-time.
 */
 #ifdef MEMORY_DEBUG
 # error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
 #endif
 
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3OSTrace = 0;
-#define OSTRACE(X)          if( sqlite3OSTrace ) sqlite3DebugPrintf X
-#else
-#define OSTRACE(X)
+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+# ifndef SQLITE_DEBUG_OS_TRACE
+#   define SQLITE_DEBUG_OS_TRACE 0
+# endif
+  int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
+# define OSTRACE(X)          if( sqlite3OSTrace ) sqlite3DebugPrintf X
+#else
+# define OSTRACE(X)
 #endif
 
 /*
 ** Macros for performance tracing.  Normally turned off.  Only works
 ** on i486 hardware.
 */
 #ifdef SQLITE_PERFORMANCE_TRACE
 
@@ -24374,22 +24845,24 @@ SQLITE_API int sqlite3_os_end(void){
 
 /*
 ** standard include files.
 */
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+/* #include <time.h> */
 #include <sys/time.h>
 #include <errno.h>
 #ifndef SQLITE_OMIT_WAL
 #include <sys/mman.h>
 #endif
 
+
 #if SQLITE_ENABLE_LOCKING_STYLE
 # include <sys/ioctl.h>
 # if OS_VXWORKS
 #  include <semaphore.h>
 #  include <limits.h>
 # else
 #  include <sys/file.h>
 #  include <sys/param.h>
@@ -24409,16 +24882,17 @@ SQLITE_API int sqlite3_os_end(void){
 */
 #define SQLITE_FSFLAGS_IS_MSDOS     0x1
 
 /*
 ** If we are to be thread-safe, include the pthreads header and define
 ** the SQLITE_UNIX_THREADS macro.
 */
 #if SQLITE_THREADSAFE
+/* # include <pthread.h> */
 # define SQLITE_UNIX_THREADS 1
 #endif
 
 /*
 ** Default permissions when creating a new file
 */
 #ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
 # define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
@@ -24462,35 +24936,34 @@ struct UnixUnusedFd {
 
 /*
 ** 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 */
+  sqlite3_vfs *pVfs;                  /* The VFS that created this unixFile */
   unixInodeInfo *pInode;              /* Info about locks on this inode */
   int h;                              /* The file descriptor */
-  int dirfd;                          /* File descriptor for the directory */
   unsigned char eFileLock;            /* The type of lock held on this fd */
   unsigned char ctrlFlags;            /* Behavioral bits.  UNIXFILE_* flags */
   int lastErrno;                      /* The unix errno from last I/O error */
   void *lockingContext;               /* Locking style specific state */
   UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
   const char *zPath;                  /* Name of the file */
   unixShm *pShm;                      /* Shared memory segment information */
   int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
 #if SQLITE_ENABLE_LOCKING_STYLE
   int openFlags;                      /* The flags specified at open() */
 #endif
 #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
   unsigned fsFlags;                   /* cached details from statfs() */
 #endif
 #if OS_VXWORKS
-  int isDelete;                       /* Delete on close if true */
   struct vxworksFileId *pId;          /* Unique file ID */
 #endif
 #ifndef NDEBUG
   /* The next group of variables are used to track whether or not the
   ** transaction counter in bytes 24-27 of database files are updated
   ** 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
@@ -24506,18 +24979,28 @@ struct unixFile {
   */
   char aPadding[32];
 #endif
 };
 
 /*
 ** Allowed values for the unixFile.ctrlFlags bitmask:
 */
-#define UNIXFILE_EXCL   0x01     /* Connections from one process only */
-#define UNIXFILE_RDONLY 0x02     /* Connection is read only */
+#define UNIXFILE_EXCL        0x01     /* Connections from one process only */
+#define UNIXFILE_RDONLY      0x02     /* Connection is read only */
+#define UNIXFILE_PERSIST_WAL 0x04     /* Persistent WAL mode */
+#ifndef SQLITE_DISABLE_DIRSYNC
+# define UNIXFILE_DIRSYNC    0x08     /* Directory sync needed */
+#else
+# define UNIXFILE_DIRSYNC    0x00
+#endif
+#define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
+#define UNIXFILE_DELETE      0x20     /* Delete on close */
+#define UNIXFILE_URI         0x40     /* Filename might have query parameters */
+#define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
 
 /*
 ** 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
@@ -24545,21 +25028,24 @@ struct unixFile {
 ** At least two bugs have slipped in because we changed the MEMORY_DEBUG
 ** macro to SQLITE_DEBUG and some older makefiles have not yet made the
 ** switch.  The following code should catch this problem at compile-time.
 */
 #ifdef MEMORY_DEBUG
 # error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
 #endif
 
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3OSTrace = 0;
-#define OSTRACE(X)          if( sqlite3OSTrace ) sqlite3DebugPrintf X
-#else
-#define OSTRACE(X)
+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+# ifndef SQLITE_DEBUG_OS_TRACE
+#   define SQLITE_DEBUG_OS_TRACE 0
+# endif
+  int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
+# define OSTRACE(X)          if( sqlite3OSTrace ) sqlite3DebugPrintf X
+#else
+# define OSTRACE(X)
 #endif
 
 /*
 ** Macros for performance tracing.  Normally turned off.  Only works
 ** on i486 hardware.
 */
 #ifdef SQLITE_PERFORMANCE_TRACE
 
@@ -24758,16 +25244,19 @@ SQLITE_API int sqlite3_open_file_count =
 **
 ** The safest way to deal with the problem is to always use this wrapper
 ** which always has the same well-defined interface.
 */
 static int posixOpen(const char *zFile, int flags, int mode){
   return open(zFile, flags, mode);
 }
 
+/* Forward reference */
+static int openDirectory(const char*, int*);
+
 /*
 ** Many system calls are accessed through pointer-to-functions so that
 ** they may be overridden at runtime to facilitate fault injection during
 ** testing and sandboxing.  The following array holds the names and pointers
 ** to all overrideable system calls.
 */
 static struct unix_syscall {
   const char *zName;            /* Name of the sytem call */
@@ -24854,16 +25343,28 @@ static struct unix_syscall {
 
 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
   { "fallocate",    (sqlite3_syscall_ptr)posix_fallocate,  0 },
 #else
   { "fallocate",    (sqlite3_syscall_ptr)0,                0 },
 #endif
 #define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent)
 
+  { "unlink",       (sqlite3_syscall_ptr)unlink,           0 },
+#define osUnlink    ((int(*)(const char*))aSyscall[16].pCurrent)
+
+  { "openDirectory",    (sqlite3_syscall_ptr)openDirectory,      0 },
+#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent)
+
+  { "mkdir",        (sqlite3_syscall_ptr)mkdir,           0 },
+#define osMkdir     ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)
+
+  { "rmdir",        (sqlite3_syscall_ptr)rmdir,           0 },
+#define osRmdir     ((int(*)(const char*))aSyscall[19].pCurrent)
+
 }; /* End of the overrideable system calls */
 
 /*
 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
 ** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
 ** system call pointer, or SQLITE_NOTFOUND if there is no configurable
 ** system call named zName.
 */
@@ -24975,17 +25476,17 @@ static void unixLeaveMutex(void){
 }
 #ifdef SQLITE_DEBUG
 static int unixMutexHeld(void) {
   return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
 }
 #endif
 
 
-#ifdef SQLITE_DEBUG
+#if defined(SQLITE_TEST) && defined(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 *azFileLock(int eFileLock){
   switch( eFileLock ){
     case NO_LOCK: return "NONE";
@@ -25138,17 +25639,19 @@ static int sqliteErrorFromPosixError(int
 #endif
   case EIO:
   case EBADF:
   case EINVAL:
   case ENOTCONN:
   case ENODEV:
   case ENXIO:
   case ENOENT:
+#ifdef ESTALE                     /* ESTALE is not defined on Interix systems */
   case ESTALE:
+#endif
   case ENOSYS:
     /* these should force the client to close the file and reconnect */
     
   default: 
     return sqliteIOErr;
   }
 }
 
@@ -25808,24 +26311,24 @@ static int unixLock(sqlite3_file *id, in
   **
   ** The reason a single byte cannot be used instead of the 'shared byte
   ** 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;
-  unixInodeInfo *pInode = pFile->pInode;
+  unixInodeInfo *pInode;
   struct flock lock;
   int tErrno = 0;
 
   assert( pFile );
   OSTRACE(("LOCK    %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
       azFileLock(eFileLock), azFileLock(pFile->eFileLock),
-      azFileLock(pInode->eFileLock), pInode->nShared , getpid()));
+      azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , 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->eFileLock>=eFileLock ){
     OSTRACE(("LOCK    %d %s ok (already held) (unix)\n", pFile->h,
             azFileLock(eFileLock)));
@@ -26019,51 +26522,41 @@ static void setPendingFd(unixFile *pFile
 ** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to 
 ** remove the write lock on a region when a read lock is set.
 */
 static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
   unixFile *pFile = (unixFile*)id;
   unixInodeInfo *pInode;
   struct flock lock;
   int rc = SQLITE_OK;
-  int h;
 
   assert( pFile );
   OSTRACE(("UNLOCK  %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
       pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
       getpid()));
 
   assert( eFileLock<=SHARED_LOCK );
   if( pFile->eFileLock<=eFileLock ){
     return SQLITE_OK;
   }
   unixEnterMutex();
-  h = pFile->h;
   pInode = pFile->pInode;
   assert( pInode->nShared!=0 );
   if( pFile->eFileLock>SHARED_LOCK ){
     assert( pInode->eFileLock==pFile->eFileLock );
-    SimulateIOErrorBenign(1);
-    SimulateIOError( h=(-1) )
-    SimulateIOErrorBenign(0);
 
 #ifndef NDEBUG
     /* When reducing a lock such that other processes can start
     ** reading the database file again, make sure that the
     ** transaction counter was updated if any part of the database
     ** file changed.  If the transaction counter is not updated,
     ** other connections to the same file might not realize that
     ** the file has changed and hence might not know to flush their
     ** cache.  The use of a stale cache can lead to database corruption.
     */
-#if 0
-    assert( pFile->inNormalWrite==0
-         || pFile->dbUpdate==0
-         || pFile->transCntrChng==1 );
-#endif
     pFile->inNormalWrite = 0;
 #endif
 
     /* downgrading to a shared lock on NFS involves clearing the write lock
     ** before establishing the readlock - to avoid a race condition we downgrade
     ** the lock in 2 blocks, so that part of the range will be covered by a 
     ** write lock until the rest is covered by a read lock:
     **  1:   [WWWWW]
@@ -26155,19 +26648,16 @@ static int posixUnlock(sqlite3_file *id,
     ** OS call only when all threads in this same process have released
     ** the lock.
     */
     pInode->nShared--;
     if( pInode->nShared==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( unixFileLock(pFile, &lock)==0 ){
         pInode->eFileLock = NO_LOCK;
       }else{
         rc = SQLITE_IOERR_UNLOCK;
 	pFile->lastErrno = errno;
         pInode->eFileLock = NO_LOCK;
         pFile->eFileLock = NO_LOCK;
       }
@@ -26208,28 +26698,24 @@ static int unixUnlock(sqlite3_file *id, 
 ** structure to 0.
 **
 ** It is *not* necessary to hold the mutex when this routine is called,
 ** even on VxWorks.  A mutex will be acquired on VxWorks by the
 ** vxworksReleaseFileId() routine.
 */
 static int closeUnixFile(sqlite3_file *id){
   unixFile *pFile = (unixFile*)id;
-  if( pFile->dirfd>=0 ){
-    robust_close(pFile, pFile->dirfd, __LINE__);
-    pFile->dirfd=-1;
-  }
   if( pFile->h>=0 ){
     robust_close(pFile, pFile->h, __LINE__);
     pFile->h = -1;
   }
 #if OS_VXWORKS
   if( pFile->pId ){
-    if( pFile->isDelete ){
-      unlink(pFile->pId->zCanonicalName);
+    if( pFile->ctrlFlags & UNIXFILE_DELETE ){
+      osUnlink(pFile->pId->zCanonicalName);
     }
     vxworksReleaseFileId(pFile->pId);
     pFile->pId = 0;
   }
 #endif
   OSTRACE(("CLOSE   %-3d\n", pFile->h));
   OpenCounter(-1);
   sqlite3_free(pFile->pUnused);
@@ -26307,37 +26793,37 @@ static int nolockClose(sqlite3_file *id)
 
 /******************* End of the no-op lock implementation *********************
 ******************************************************************************/
 
 /******************************************************************************
 ************************* Begin dot-file Locking ******************************
 **
 ** 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:
+** files (really a directory) 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.
 **
 ** Nevertheless, a dotlock is an appropriate locking mode for use if no
 ** other locking strategy is available.
 **
-** Dotfile locking works by creating a file in the same directory as the
-** database and with the same name but with a ".lock" extension added.
-** The existance of a lock file implies an EXCLUSIVE lock.  All other lock
-** types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
+** Dotfile locking works by creating a subdirectory in the same directory as
+** the database and with the same name but with a ".lock" extension added.
+** The existance of a lock directory implies an EXCLUSIVE lock.  All other
+** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
 */
 
 /*
 ** The file suffix added to the data base filename in order to create the
-** lock file.
+** lock directory.
 */
 #define DOTLOCK_SUFFIX ".lock"
 
 /*
 ** This routine checks if there is a RESERVED lock held on the specified
 ** file by this or any other process. If such a lock is held, set *pResOut
 ** to a non-zero value otherwise *pResOut is set to zero.  The return value
 ** is set to SQLITE_OK unless an I/O error occurs during lock checking.
@@ -26394,17 +26880,16 @@ static int dotlockCheckReservedLock(sqli
 ** This routine will only increase a lock.  Use the sqlite3OsUnlock()
 ** routine to lower a locking level.
 **
 ** With dotfile locking, we really only support state (4): EXCLUSIVE.
 ** But we track the other locking levels internally.
 */
 static int dotlockLock(sqlite3_file *id, int eFileLock) {
   unixFile *pFile = (unixFile*)id;
-  int fd;
   char *zLockFile = (char *)pFile->lockingContext;
   int rc = SQLITE_OK;
 
 
   /* If we have any lock, then the lock file already exists.  All we have
   ** to do is adjust our internal record of the lock level.
   */
   if( pFile->eFileLock > NO_LOCK ){
@@ -26414,31 +26899,30 @@ static int dotlockLock(sqlite3_file *id,
     utime(zLockFile, NULL);
 #else
     utimes(zLockFile, NULL);
 #endif
     return SQLITE_OK;
   }
   
   /* grab an exclusive lock */
-  fd = robust_open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600);
-  if( fd<0 ){
-    /* failed to open/create the file, someone else may have stolen the lock */
+  rc = osMkdir(zLockFile, 0777);
+  if( rc<0 ){
+    /* failed to open/create the lock directory */
     int tErrno = errno;
     if( EEXIST == tErrno ){
       rc = SQLITE_BUSY;
     } else {
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( IS_LOCK_ERROR(rc) ){
         pFile->lastErrno = tErrno;
       }
     }
     return rc;
   } 
-  robust_close(pFile, fd, __LINE__);
   
   /* got it, set the type and return ok */
   pFile->eFileLock = eFileLock;
   return rc;
 }
 
 /*
 ** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
@@ -26447,16 +26931,17 @@ static int dotlockLock(sqlite3_file *id,
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 **
 ** When the locking level reaches NO_LOCK, delete the lock file.
 */
 static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
   unixFile *pFile = (unixFile*)id;
   char *zLockFile = (char *)pFile->lockingContext;
+  int rc;
 
   assert( pFile );
   OSTRACE(("UNLOCK  %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
 	   pFile->eFileLock, getpid()));
   assert( eFileLock<=SHARED_LOCK );
   
   /* no-op if possible */
   if( pFile->eFileLock==eFileLock ){
@@ -26468,19 +26953,21 @@ static int dotlockUnlock(sqlite3_file *i
   */
   if( eFileLock==SHARED_LOCK ){
     pFile->eFileLock = SHARED_LOCK;
     return SQLITE_OK;
   }
   
   /* To fully unlock the database, delete the lock file */
   assert( eFileLock==NO_LOCK );
-  if( unlink(zLockFile) ){
-    int rc = 0;
+  rc = osRmdir(zLockFile);
+  if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
+  if( rc<0 ){
     int tErrno = errno;
+    rc = 0;
     if( ENOENT != tErrno ){
       rc = SQLITE_IOERR_UNLOCK;
     }
     if( IS_LOCK_ERROR(rc) ){
       pFile->lastErrno = tErrno;
     }
     return rc; 
   }
@@ -26974,21 +27461,22 @@ static int afpSetLock(
 ** file by this or any other process. If such a lock is held, set *pResOut
 ** to a non-zero value otherwise *pResOut is set to zero.  The return value
 ** is set to SQLITE_OK unless an I/O error occurs during lock checking.
 */
 static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){
   int rc = SQLITE_OK;
   int reserved = 0;
   unixFile *pFile = (unixFile*)id;
+  afpLockingContext *context;
   
   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
   
   assert( pFile );
-  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
+  context = (afpLockingContext *) pFile->lockingContext;
   if( context->reserved ){
     *pResOut = 1;
     return SQLITE_OK;
   }
   unixEnterMutex(); /* Because pFile->pInode is shared across threads */
   
   /* Check if a thread in this process holds such a lock */
   if( pFile->pInode->eFileLock>SHARED_LOCK ){
@@ -27118,17 +27606,17 @@ static int afpLock(sqlite3_file *id, int
       goto afp_end_lock;
     }
   }
   
   /* If control gets to this point, then actually go ahead and make
   ** operating system calls for the specified lock.
   */
   if( eFileLock==SHARED_LOCK ){
-    int lrc1, lrc2, lrc1Errno;
+    int lrc1, lrc2, lrc1Errno = 0;
     long lk, mask;
     
     assert( pInode->nShared==0 );
     assert( pInode->eFileLock==0 );
         
     mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff;
     /* Now get the read-lock SHARED_LOCK */
     /* note that the quality of the randomness doesn't matter that much */
@@ -27405,45 +27893,58 @@ static int nfsUnlock(sqlite3_file *id, i
 ** any any form by default, we will not attempt to define _XOPEN_SOURCE.
 ** See tickets #2741 and #2681.
 **
 ** To avoid stomping the errno value on a failed read the lastErrno value
 ** is set before returning.
 */
 static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
   int got;
+  int prior = 0;
 #if (!defined(USE_PREAD) && !defined(USE_PREAD64))
   i64 newOffset;
 #endif
   TIMER_START;
+  do{
 #if defined(USE_PREAD)
-  do{ got = osPread(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
-  SimulateIOError( got = -1 );
+    got = osPread(id->h, pBuf, cnt, offset);
+    SimulateIOError( got = -1 );
 #elif defined(USE_PREAD64)
-  do{ got = osPread64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR);
-  SimulateIOError( got = -1 );
-#else
-  newOffset = lseek(id->h, offset, SEEK_SET);
-  SimulateIOError( newOffset-- );
-  if( newOffset!=offset ){
-    if( newOffset == -1 ){
+    got = osPread64(id->h, pBuf, cnt, offset);
+    SimulateIOError( got = -1 );
+#else
+    newOffset = lseek(id->h, offset, SEEK_SET);
+    SimulateIOError( newOffset-- );
+    if( newOffset!=offset ){
+      if( newOffset == -1 ){
+        ((unixFile*)id)->lastErrno = errno;
+      }else{
+        ((unixFile*)id)->lastErrno = 0;			
+      }
+      return -1;
+    }
+    got = osRead(id->h, pBuf, cnt);
+#endif
+    if( got==cnt ) break;
+    if( got<0 ){
+      if( errno==EINTR ){ got = 1; continue; }
+      prior = 0;
       ((unixFile*)id)->lastErrno = errno;
-    }else{
-      ((unixFile*)id)->lastErrno = 0;			
-    }
-    return -1;
-  }
-  do{ got = osRead(id->h, pBuf, cnt); }while( got<0 && errno==EINTR );
-#endif
+      break;
+    }else if( got>0 ){
+      cnt -= got;
+      offset += got;
+      prior += got;
+      pBuf = (void*)(got + (char*)pBuf);
+    }
+  }while( got>0 );
   TIMER_END;
-  if( got<0 ){
-    ((unixFile*)id)->lastErrno = errno;
-  }
-  OSTRACE(("READ    %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
-  return got;
+  OSTRACE(("READ    %-3d %5d %7lld %llu\n",
+            id->h, got+prior, offset-prior, TIMER_ELAPSED));
+  return got+prior;
 }
 
 /*
 ** Read data from a file into a buffer.  Return SQLITE_OK if all
 ** bytes were read successfully and SQLITE_IOERR if anything goes
 ** wrong.
 */
 static int unixRead(
@@ -27492,27 +27993,29 @@ static int seekAndWrite(unixFile *id, i6
   i64 newOffset;
 #endif
   TIMER_START;
 #if defined(USE_PREAD)
   do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
 #elif defined(USE_PREAD64)
   do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR);
 #else
-  newOffset = lseek(id->h, offset, SEEK_SET);
-  SimulateIOError( newOffset-- );
-  if( newOffset!=offset ){
-    if( newOffset == -1 ){
-      ((unixFile*)id)->lastErrno = errno;
-    }else{
-      ((unixFile*)id)->lastErrno = 0;			
-    }
-    return -1;
-  }
-  do{ got = osWrite(id->h, pBuf, cnt); }while( got<0 && errno==EINTR );
+  do{
+    newOffset = lseek(id->h, offset, SEEK_SET);
+    SimulateIOError( newOffset-- );
+    if( newOffset!=offset ){
+      if( newOffset == -1 ){
+        ((unixFile*)id)->lastErrno = errno;
+      }else{
+        ((unixFile*)id)->lastErrno = 0;			
+      }
+      return -1;
+    }
+    got = osWrite(id->h, pBuf, cnt);
+  }while( got<0 && errno==EINTR );
 #endif
   TIMER_END;
   if( got<0 ){
     ((unixFile*)id)->lastErrno = errno;
   }
 
   OSTRACE(("WRITE   %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
   return got;
@@ -27592,21 +28095,21 @@ static int unixWrite(
 ** that syncs and fullsyncs are occurring at the right times.
 */
 SQLITE_API int sqlite3_sync_count = 0;
 SQLITE_API int sqlite3_fullsync_count = 0;
 #endif
 
 /*
 ** We do not trust systems to provide a working fdatasync().  Some do.
-** Others do no.  To be safe, we will stick with the (slower) fsync().
-** If you know that your system does support fdatasync() correctly,
+** Others do no.  To be safe, we will stick with the (slightly slower)
+** fsync(). If you know that your system does support fdatasync() correctly,
 ** then simply compile with -Dfdatasync=fdatasync
 */
-#if !defined(fdatasync) && !defined(__linux__)
+#if !defined(fdatasync)
 # define fdatasync fsync
 #endif
 
 /*
 ** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
 ** the F_FULLFSYNC macro is defined.  F_FULLFSYNC is currently
 ** only available on Mac OS X.  But that could change.
 */
@@ -27705,16 +28208,60 @@ static int full_fsync(int fd, int fullSy
 
   if( OS_VXWORKS && rc!= -1 ){
     rc = 0;
   }
   return rc;
 }
 
 /*
+** Open a file descriptor to the directory containing file zFilename.
+** If successful, *pFd is set to the opened file descriptor and
+** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
+** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
+** value.
+**
+** The directory file descriptor is used for only one thing - to
+** fsync() a directory to make sure file creation and deletion events
+** are flushed to disk.  Such fsyncs are not needed on newer
+** journaling filesystems, but are required on older filesystems.
+**
+** This routine can be overridden using the xSetSysCall interface.
+** The ability to override this routine was added in support of the
+** chromium sandbox.  Opening a directory is a security risk (we are
+** told) so making it overrideable allows the chromium sandbox to
+** replace this routine with a harmless no-op.  To make this routine
+** a no-op, replace it with a stub that returns SQLITE_OK but leaves
+** *pFd set to a negative number.
+**
+** If SQLITE_OK is returned, the caller is responsible for closing
+** the file descriptor *pFd using close().
+*/
+static int openDirectory(const char *zFilename, int *pFd){
+  int ii;
+  int fd = -1;
+  char zDirname[MAX_PATHNAME+1];
+
+  sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
+  for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
+  if( ii>0 ){
+    zDirname[ii] = '\0';
+    fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
+    if( fd>=0 ){
+#ifdef FD_CLOEXEC
+      osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
+#endif
+      OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
+    }
+  }
+  *pFd = fd;
+  return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
+}
+
+/*
 ** Make sure all writes to a particular file are committed to disk.
 **
 ** If dataOnly==0 then both the file itself and its metadata (file
 ** size, access time, etc) are synced.  If dataOnly!=0 then only the
 ** file data is synced.
 **
 ** Under Unix, also make sure that the directory entry for the file
 ** has been created by fsync-ing the directory that contains the file.
@@ -27744,38 +28291,33 @@ static int unixSync(sqlite3_file *id, in
   assert( pFile );
   OSTRACE(("SYNC    %-3d\n", pFile->h));
   rc = full_fsync(pFile->h, isFullsync, isDataOnly);
   SimulateIOError( rc=1 );
   if( rc ){
     pFile->lastErrno = errno;
     return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
   }
-  if( pFile->dirfd>=0 ){
-    OSTRACE(("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
+
+  /* Also fsync the directory containing the file if the DIRSYNC flag
+  ** is set.  This is a one-time occurrance.  Many systems (examples: AIX)
+  ** are unable to fsync a directory, so ignore errors on the fsync.
+  */
+  if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){
+    int dirfd;
+    OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
             HAVE_FULLFSYNC, isFullsync));
-#ifndef SQLITE_DISABLE_DIRSYNC
-    /* The directory sync is only attempted if full_fsync is
-    ** turned off or unavailable.  If a full_fsync occurred above,
-    ** then the directory sync is superfluous.
-    */
-    if( (!HAVE_FULLFSYNC || !isFullsync) && full_fsync(pFile->dirfd,0,0) ){
-       /*
-       ** We have received multiple reports of fsync() returning
-       ** errors when applied to directories on certain file systems.
-       ** A failed directory sync is not a big deal.  So it seems
-       ** better to ignore the error.  Ticket #1657
-       */
-       /* pFile->lastErrno = errno; */
-       /* return SQLITE_IOERR; */
-    }
-#endif
-    /* Only need to sync once, so close the  directory when we are done */
-    robust_close(pFile, pFile->dirfd, __LINE__);
-    pFile->dirfd = -1;
+    rc = osOpenDirectory(pFile->zPath, &dirfd);
+    if( rc==SQLITE_OK && dirfd>=0 ){
+      full_fsync(dirfd, 0, 0);
+      robust_close(pFile, dirfd, __LINE__);
+    }else if( rc==SQLITE_CANTOPEN ){
+      rc = SQLITE_OK;
+    }
+    pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
   }
   return rc;
 }
 
 /*
 ** Truncate an open file to a specified size
 */
 static int unixTruncate(sqlite3_file *id, i64 nByte){
@@ -27847,24 +28389,22 @@ static int unixFileSize(sqlite3_file *id
 ** Handler for proxy-locking file-control verbs.  Defined below in the
 ** proxying locking division.
 */
 static int proxyFileControl(sqlite3_file*,int,void*);
 #endif
 
 /* 
 ** This function is called to handle the SQLITE_FCNTL_SIZE_HINT 
-** file-control operation.
-**
-** If the user has configured a chunk-size for this file, it could be
-** that the file needs to be extended at this point. Otherwise, the
-** SQLITE_FCNTL_SIZE_HINT operation is a no-op for Unix.
+** file-control operation.  Enlarge the database to nBytes in size
+** (rounded up to the next chunk-size).  If the database is already
+** nBytes or larger, this routine is a no-op.
 */
 static int fcntlSizeHint(unixFile *pFile, i64 nByte){
-  if( pFile->szChunk ){
+  if( pFile->szChunk>0 ){
     i64 nSize;                    /* Required file size */
     struct stat buf;              /* Used to hold return values of fstat() */
    
     if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
 
     nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
     if( nSize>(i64)buf.st_size ){
 
@@ -27900,34 +28440,67 @@ static int fcntlSizeHint(unixFile *pFile
 #endif
     }
   }
 
   return SQLITE_OK;
 }
 
 /*
+** If *pArg is inititially negative then this is a query.  Set *pArg to
+** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
+**
+** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
+*/
+static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){
+  if( *pArg<0 ){
+    *pArg = (pFile->ctrlFlags & mask)!=0;
+  }else if( (*pArg)==0 ){
+    pFile->ctrlFlags &= ~mask;
+  }else{
+    pFile->ctrlFlags |= mask;
+  }
+}
+
+/*
 ** Information and control of an open file handle.
 */
 static int unixFileControl(sqlite3_file *id, int op, void *pArg){
+  unixFile *pFile = (unixFile*)id;
   switch( op ){
     case SQLITE_FCNTL_LOCKSTATE: {
-      *(int*)pArg = ((unixFile*)id)->eFileLock;
+      *(int*)pArg = pFile->eFileLock;
       return SQLITE_OK;
     }
     case SQLITE_LAST_ERRNO: {
-      *(int*)pArg = ((unixFile*)id)->lastErrno;
+      *(int*)pArg = pFile->lastErrno;
       return SQLITE_OK;
     }
     case SQLITE_FCNTL_CHUNK_SIZE: {
-      ((unixFile*)id)->szChunk = *(int *)pArg;
+      pFile->szChunk = *(int *)pArg;
       return SQLITE_OK;
     }
     case SQLITE_FCNTL_SIZE_HINT: {
-      return fcntlSizeHint((unixFile *)id, *(i64 *)pArg);
+      int rc;
+      SimulateIOErrorBenign(1);
+      rc = fcntlSizeHint(pFile, *(i64 *)pArg);
+      SimulateIOErrorBenign(0);
+      return rc;
+    }
+    case SQLITE_FCNTL_PERSIST_WAL: {
+      unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg);
+      return SQLITE_OK;
+    }
+    case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
+      unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
+      return SQLITE_OK;
+    }
+    case SQLITE_FCNTL_VFSNAME: {
+      *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
+      return SQLITE_OK;
     }
 #ifndef NDEBUG
     /* The pager calls this method to signal that it has done
     ** a rollback and that the database is therefore unchanged and
     ** it hence it is OK for the transaction change counter to be
     ** unchanged.
     */
     case SQLITE_FCNTL_DB_UNCHANGED: {
@@ -27936,44 +28509,55 @@ static int unixFileControl(sqlite3_file 
     }
 #endif
 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
     case SQLITE_SET_LOCKPROXYFILE:
     case SQLITE_GET_LOCKPROXYFILE: {
       return proxyFileControl(id,op,pArg);
     }
 #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
-    case SQLITE_FCNTL_SYNC_OMITTED: {
-      return SQLITE_OK;  /* A no-op */
-    }
   }
   return SQLITE_NOTFOUND;
 }
 
 /*
 ** Return the sector size in bytes of the underlying block device for
 ** the specified file. This is almost always 512 bytes, but may be
 ** larger for some devices.
 **
 ** SQLite code assumes this function cannot fail. It also assumes that
 ** if two files are created in the same file-system directory (i.e.
 ** a database and its journal file) that the sector size will be the
 ** same for both.
 */
-static int unixSectorSize(sqlite3_file *NotUsed){
-  UNUSED_PARAMETER(NotUsed);
+static int unixSectorSize(sqlite3_file *pFile){
+  (void)pFile;
   return SQLITE_DEFAULT_SECTOR_SIZE;
 }
 
 /*
-** Return the device characteristics for the file. This is always 0 for unix.
-*/
-static int unixDeviceCharacteristics(sqlite3_file *NotUsed){
-  UNUSED_PARAMETER(NotUsed);
-  return 0;
+** Return the device characteristics for the file.
+**
+** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
+** However, that choice is contraversial since technically the underlying
+** file system does not always provide powersafe overwrites.  (In other
+** words, after a power-loss event, parts of the file that were never
+** written might end up being altered.)  However, non-PSOW behavior is very,
+** very rare.  And asserting PSOW makes a large reduction in the amount
+** of required I/O for journaling, since a lot of padding is eliminated.
+**  Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
+** available to turn it off and URI query parameter available to turn it off.
+*/
+static int unixDeviceCharacteristics(sqlite3_file *id){
+  unixFile *p = (unixFile*)id;
+  if( p->ctrlFlags & UNIXFILE_PSOW ){
+    return SQLITE_IOCAP_POWERSAFE_OVERWRITE;
+  }else{
+    return 0;
+  }
 }
 
 #ifndef SQLITE_OMIT_WAL
 
 
 /*
 ** Object used to represent an shared memory buffer.  
 **
@@ -28033,21 +28617,19 @@ struct unixShmNode {
 **
 ** All other fields are read/write.  The unixShm.pFile->mutex must be held
 ** while accessing any read/write fields.
 */
 struct unixShm {
   unixShmNode *pShmNode;     /* The underlying unixShmNode object */
   unixShm *pNext;            /* Next unixShm with the same unixShmNode */
   u8 hasMutex;               /* True if holding the unixShmNode mutex */
+  u8 id;                     /* Id of this connection within its unixShmNode */
   u16 sharedMask;            /* Mask of shared locks held */
   u16 exclMask;              /* Mask of exclusive locks held */
-#ifdef SQLITE_DEBUG
-  u8 id;                     /* Id of this connection within its unixShmNode */
-#endif
 };
 
 /*
 ** Constants used for locking
 */
 #define UNIX_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)         /* first lock byte */
 #define UNIX_SHM_DMS    (UNIX_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
 
@@ -28133,17 +28715,17 @@ static int unixShmSystemLock(
 ** by VFS shared-memory methods.
 */
 static void unixShmPurge(unixFile *pFd){
   unixShmNode *p = pFd->pInode->pShmNode;
   assert( unixMutexHeld() );
   if( p && p->nRef==0 ){
     int i;
     assert( p->pInode==pFd->pInode );
-    if( p->mutex ) sqlite3_mutex_free(p->mutex);
+    sqlite3_mutex_free(p->mutex);
     for(i=0; i<p->nRegion; i++){
       if( p->h>=0 ){
         munmap(p->apRegion[i], p->szRegion);
       }else{
         sqlite3_free(p->apRegion[i]);
       }
     }
     sqlite3_free(p->apRegion);
@@ -28220,26 +28802,26 @@ static int unixOpenSharedMemory(unixFile
     ** with are subject to the current umask setting.
     */
     if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){
       rc = SQLITE_IOERR_FSTAT;
       goto shm_open_err;
     }
 
 #ifdef SQLITE_SHM_DIRECTORY
-    nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 30;
-#else
-    nShmFilename = 5 + (int)strlen(pDbFd->zPath);
+    nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
+#else
+    nShmFilename = 6 + (int)strlen(pDbFd->zPath);
 #endif
     pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
     if( pShmNode==0 ){
       rc = SQLITE_NOMEM;
       goto shm_open_err;
     }
-    memset(pShmNode, 0, sizeof(*pShmNode));
+    memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
     zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1];
 #ifdef SQLITE_SHM_DIRECTORY
     sqlite3_snprintf(nShmFilename, zShmFilename, 
                      SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
                      (u32)sStat.st_ino, (u32)sStat.st_dev);
 #else
     sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
     sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
@@ -28249,26 +28831,23 @@ static int unixOpenSharedMemory(unixFile
     pShmNode->pInode = pDbFd->pInode;
     pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
     if( pShmNode->mutex==0 ){
       rc = SQLITE_NOMEM;
       goto shm_open_err;
     }
 
     if( pInode->bProcessLock==0 ){
-      pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT,
-                               (sStat.st_mode & 0777));
+      int openFlags = O_RDWR | O_CREAT;
+      if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+        openFlags = O_RDONLY;
+        pShmNode->isReadonly = 1;
+      }
+      pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
       if( pShmNode->h<0 ){
-        const char *zRO;
-        zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm");
-        if( zRO && sqlite3GetBoolean(zRO) ){
-          pShmNode->h = robust_open(zShmFilename, O_RDONLY,
-                                    (sStat.st_mode & 0777));
-          pShmNode->isReadonly = 1;
-        }
         if( pShmNode->h<0 ){
           rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
           goto shm_open_err;
         }
       }
   
       /* Check to see if another process is holding the dead-man switch.
       ** If not, truncate the file to zero length. 
@@ -28602,17 +29181,17 @@ static int unixShmUnmap(
   sqlite3_mutex_leave(pShmNode->mutex);
 
   /* If pShmNode->nRef has reached 0, then close the underlying
   ** shared-memory file, too */
   unixEnterMutex();
   assert( pShmNode->nRef>0 );
   pShmNode->nRef--;
   if( pShmNode->nRef==0 ){
-    if( deleteFlag && pShmNode->h>=0 ) unlink(pShmNode->zFilename);
+    if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
     unixShmPurge(pDbFd);
   }
   unixLeaveMutex();
 
   return SQLITE_OK;
 }
 
 
@@ -28915,67 +29494,62 @@ typedef const sqlite3_io_methods *(*find
 */
 
 /*
 ** Initialize the contents of the unixFile structure pointed to by pId.
 */
 static int fillInUnixFile(
   sqlite3_vfs *pVfs,      /* Pointer to vfs object */
   int h,                  /* Open file descriptor of file being opened */
-  int dirfd,              /* Directory file descriptor */
   sqlite3_file *pId,      /* Write to the unixFile structure here */
   const char *zFilename,  /* Name of the file being opened */
-  int noLock,             /* Omit locking if true */
-  int isDelete,           /* Delete on close if true */
-  int isReadOnly          /* True if the file is opened read-only */
+  int ctrlFlags           /* Zero or more UNIXFILE_* values */
 ){
   const sqlite3_io_methods *pLockingStyle;
   unixFile *pNew = (unixFile *)pId;
   int rc = SQLITE_OK;
 
   assert( pNew->pInode==NULL );
 
-  /* Parameter isDelete is only used on vxworks. Express this explicitly 
-  ** here to prevent compiler warnings about unused parameters.
-  */
-  UNUSED_PARAMETER(isDelete);
-
   /* Usually the path zFilename should not be a relative pathname. The
   ** exception is when opening the proxy "conch" file in builds that
   ** include the special Apple locking styles.
   */
 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
   assert( zFilename==0 || zFilename[0]=='/' 
     || pVfs->pAppData==(void*)&autolockIoFinder );
 #else
   assert( zFilename==0 || zFilename[0]=='/' );
 #endif
 
+  /* No locking occurs in temporary files */
+  assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );
+
   OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
   pNew->h = h;
-  pNew->dirfd = dirfd;
+  pNew->pVfs = pVfs;
   pNew->zPath = zFilename;
+  pNew->ctrlFlags = (u8)ctrlFlags;
+  if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
+                           "psow", SQLITE_POWERSAFE_OVERWRITE) ){
+    pNew->ctrlFlags |= UNIXFILE_PSOW;
+  }
   if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
-    pNew->ctrlFlags = UNIXFILE_EXCL;
-  }else{
-    pNew->ctrlFlags = 0;
-  }
-  if( isReadOnly ){
-    pNew->ctrlFlags |= UNIXFILE_RDONLY;
+    pNew->ctrlFlags |= UNIXFILE_EXCL;
   }
 
 #if OS_VXWORKS
   pNew->pId = vxworksFindFileId(zFilename);
   if( pNew->pId==0 ){
-    noLock = 1;
+    ctrlFlags |= UNIXFILE_NOLOCK;
     rc = SQLITE_NOMEM;
   }
 #endif
 
-  if( noLock ){
+  if( ctrlFlags & UNIXFILE_NOLOCK ){
     pLockingStyle = &nolockIoMethods;
   }else{
     pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew);
 #if SQLITE_ENABLE_LOCKING_STYLE
     /* Cache zFilename in the locking context (AFP and dotlock override) for
     ** proxyLock activation is possible (remote proxy is based on db name)
     ** zFilename remains valid until file is closed, to support */
     pNew->lockingContext = (void*)zFilename;
@@ -29043,16 +29617,17 @@ static int fillInUnixFile(
 #endif
 
   else if( pLockingStyle == &dotlockIoMethods ){
     /* Dotfile locking uses the file path so it needs to be included in
     ** the dotlockLockingContext 
     */
     char *zLockFile;
     int nFilename;
+    assert( zFilename!=0 );
     nFilename = (int)strlen(zFilename) + 6;
     zLockFile = (char *)sqlite3_malloc(nFilename);
     if( zLockFile==0 ){
       rc = SQLITE_NOMEM;
     }else{
       sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
     }
     pNew->lockingContext = zLockFile;
@@ -29082,63 +29657,31 @@ static int fillInUnixFile(
   }
 #endif
   
   pNew->lastErrno = 0;
 #if OS_VXWORKS
   if( rc!=SQLITE_OK ){
     if( h>=0 ) robust_close(pNew, h, __LINE__);
     h = -1;
-    unlink(zFilename);
+    osUnlink(zFilename);
     isDelete = 0;
   }
-  pNew->isDelete = isDelete;
+  if( isDelete ) pNew->ctrlFlags |= UNIXFILE_DELETE;
 #endif
   if( rc!=SQLITE_OK ){
-    if( dirfd>=0 ) robust_close(pNew, dirfd, __LINE__);
     if( h>=0 ) robust_close(pNew, h, __LINE__);
   }else{
     pNew->pMethod = pLockingStyle;
     OpenCounter(+1);
   }
   return rc;
 }
 
 /*
-** Open a file descriptor to the directory containing file zFilename.
-** If successful, *pFd is set to the opened file descriptor and
-** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
-** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
-** value.
-**
-** If SQLITE_OK is returned, the caller is responsible for closing
-** the file descriptor *pFd using close().
-*/
-static int openDirectory(const char *zFilename, int *pFd){
-  int ii;
-  int fd = -1;
-  char zDirname[MAX_PATHNAME+1];
-
-  sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
-  for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
-  if( ii>0 ){
-    zDirname[ii] = '\0';
-    fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
-    if( fd>=0 ){
-#ifdef FD_CLOEXEC
-      osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
-#endif
-      OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
-    }
-  }
-  *pFd = fd;
-  return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
-}
-
-/*
 ** Return the name of a directory in which to put temporary files.
 ** If no suitable temporary file directory can be found, return NULL.
 */
 static const char *unixTempFileDir(void){
   static const char *azDirs[] = {
      0,
      0,
      "/var/tmp",
@@ -29182,28 +29725,29 @@ static int unixGetTempname(int nBuf, cha
   SimulateIOError( return SQLITE_IOERR );
 
   zDir = unixTempFileDir();
   if( zDir==0 ) zDir = ".";
 
   /* Check that the output buffer is large enough for the temporary file 
   ** name. If it is not, return SQLITE_ERROR.
   */
-  if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= (size_t)nBuf ){
+  if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){
     return SQLITE_ERROR;
   }
 
   do{
-    sqlite3_snprintf(nBuf-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
+    sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
     j = (int)strlen(zBuf);
     sqlite3_randomness(15, &zBuf[j]);
     for(i=0; i<15; i++, j++){
       zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
     }
     zBuf[j] = 0;
+    zBuf[j+1] = 0;
   }while( osAccess(zBuf,0)==0 );
   return SQLITE_OK;
 }
 
 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
 /*
 ** Routine to transform a unixFile into a proxy-locking unixFile.
 ** Implementation in the proxy-lock division, but used by unixOpen()
@@ -29242,17 +29786,17 @@ static UnixUnusedFd *findReusableFd(cons
   /* A stat() call may fail for various reasons. If this happens, it is
   ** almost certain that an open() call on the same path will also fail.
   ** For this reason, if an error occurs in the stat() call here, it is
   ** ignored and -1 is returned. The caller will try to open a new file
   ** descriptor on the same path, fail, and return an error to SQLite.
   **
   ** Even if a subsequent open() call does succeed, the consequences of
   ** not searching for a resusable file descriptor are not dire.  */
-  if( 0==stat(zPath, &sStat) ){
+  if( 0==osStat(zPath, &sStat) ){
     unixInodeInfo *pInode;
 
     unixEnterMutex();
     pInode = inodeList;
     while( pInode && (pInode->fileId.dev!=sStat.st_dev
                      || pInode->fileId.ino!=sStat.st_ino) ){
        pInode = pInode->pNext;
     }
@@ -29309,26 +29853,34 @@ static int findCreateFileMode(
     ** the path to the associated database file from zPath. This block handles
     ** the following naming conventions:
     **
     **   "<path to db>-journal"
     **   "<path to db>-wal"
     **   "<path to db>-journalNN"
     **   "<path to db>-walNN"
     **
-    ** where NN is a 4 digit decimal number. The NN naming schemes are 
+    ** where NN is a decimal number. The NN naming schemes are 
     ** used by the test_multiplex.c module.
     */
     nDb = sqlite3Strlen30(zPath) - 1; 
-    while( nDb>0 && zPath[nDb]!='-' ) nDb--;
-    if( nDb==0 ) return SQLITE_OK;
+#ifdef SQLITE_ENABLE_8_3_NAMES
+    while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--;
+    if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK;
+#else
+    while( zPath[nDb]!='-' ){
+      assert( nDb>0 );
+      assert( zPath[nDb]!='\n' );
+      nDb--;
+    }
+#endif
     memcpy(zDb, zPath, nDb);
     zDb[nDb] = '\0';
 
-    if( 0==stat(zDb, &sStat) ){
+    if( 0==osStat(zDb, &sStat) ){
       *pMode = sStat.st_mode & 0777;
     }else{
       rc = SQLITE_IOERR_FSTAT;
     }
   }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
     *pMode = 0600;
   }
   return rc;
@@ -29360,45 +29912,48 @@ static int unixOpen(
   sqlite3_vfs *pVfs,           /* The VFS for which this is the xOpen method */
   const char *zPath,           /* Pathname of file to be opened */
   sqlite3_file *pFile,         /* The file descriptor to be filled in */
   int flags,                   /* Input flags to control the opening */
   int *pOutFlags               /* Output flags returned to SQLite core */
 ){
   unixFile *p = (unixFile *)pFile;
   int fd = -1;                   /* File descriptor returned by open() */
-  int dirfd = -1;                /* Directory file descriptor */
   int openFlags = 0;             /* Flags to pass to open() */
   int eType = flags&0xFFFFFF00;  /* Type of file to open */
   int noLock;                    /* True to omit locking primitives */
   int rc = SQLITE_OK;            /* Function Return Code */
+  int ctrlFlags = 0;             /* UNIXFILE_* flags */
 
   int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
   int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
   int isCreate     = (flags & SQLITE_OPEN_CREATE);
   int isReadonly   = (flags & SQLITE_OPEN_READONLY);
   int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
 #if SQLITE_ENABLE_LOCKING_STYLE
   int isAutoProxy  = (flags & SQLITE_OPEN_AUTOPROXY);
 #endif
+#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
+  struct statfs fsInfo;
+#endif
 
   /* If creating a master or main-file journal, this function will open
   ** a file-descriptor on the directory too. The first time unixSync()
   ** is called the directory file descriptor will be fsync()ed and close()d.
   */
-  int isOpenDirectory = (isCreate && (
+  int syncDir = (isCreate && (
         eType==SQLITE_OPEN_MASTER_JOURNAL 
      || eType==SQLITE_OPEN_MAIN_JOURNAL 
      || eType==SQLITE_OPEN_WAL
   ));
 
   /* If argument zPath is a NULL pointer, this function is required to open
   ** a temporary file. Use this buffer to store the file name in.
   */
-  char zTmpname[MAX_PATHNAME+1];
+  char zTmpname[MAX_PATHNAME+2];
   const char *zName = zPath;
 
   /* Check the following statements are true: 
   **
   **   (a) Exactly one of the READWRITE and READONLY flags must be set, and 
   **   (b) if CREATE is set, then READWRITE must also be set, and
   **   (c) if EXCLUSIVE is set, then CREATE must also be set.
   **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
@@ -29431,24 +29986,34 @@ static int unixOpen(
       fd = pUnused->fd;
     }else{
       pUnused = sqlite3_malloc(sizeof(*pUnused));
       if( !pUnused ){
         return SQLITE_NOMEM;
       }
     }
     p->pUnused = pUnused;
+
+    /* Database filenames are double-zero terminated if they are not
+    ** URIs with parameters.  Hence, they can always be passed into
+    ** sqlite3_uri_parameter(). */
+    assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 );
+
   }else if( !zName ){
     /* If zName is NULL, the upper layer is requesting a temp file. */
-    assert(isDelete && !isOpenDirectory);
-    rc = unixGetTempname(MAX_PATHNAME+1, zTmpname);
+    assert(isDelete && !syncDir);
+    rc = unixGetTempname(MAX_PATHNAME+2, zTmpname);
     if( rc!=SQLITE_OK ){
       return rc;
     }
     zName = zTmpname;
+
+    /* Generated temporary filenames are always double-zero terminated
+    ** for use by sqlite3_uri_parameter(). */
+    assert( zName[strlen(zName)+1]==0 );
   }
 
   /* Determine the value of the flags parameter passed to POSIX function
   ** open(). These must be calculated even if open() is not called, as
   ** they may be stored as part of the file handle and used by the 
   ** 'conch file' locking functions later on.  */
   if( isReadonly )  openFlags |= O_RDONLY;
   if( isReadWrite ) openFlags |= O_RDWR;
@@ -29489,111 +30054,98 @@ static int unixOpen(
     p->pUnused->fd = fd;
     p->pUnused->flags = flags;
   }
 
   if( isDelete ){
 #if OS_VXWORKS
     zPath = zName;
 #else
-    unlink(zName);
+    osUnlink(zName);
 #endif
   }
 #if SQLITE_ENABLE_LOCKING_STYLE
   else{
     p->openFlags = openFlags;
   }
 #endif
 
-  if( isOpenDirectory ){
-    rc = openDirectory(zPath, &dirfd);
-    if( rc!=SQLITE_OK ){
-      /* It is safe to close fd at this point, because it is guaranteed not
-      ** to be open on a database file. If it were open on a database file,
-      ** it would not be safe to close as this would release any locks held
-      ** on the file by this process.  */
-      assert( eType!=SQLITE_OPEN_MAIN_DB );
-      robust_close(p, fd, __LINE__);
-      goto open_finished;
-    }
-  }
-
 #ifdef FD_CLOEXEC
   osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
 #endif
 
   noLock = eType!=SQLITE_OPEN_MAIN_DB;
 
   
 #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
-  struct statfs fsInfo;
   if( fstatfs(fd, &fsInfo) == -1 ){
     ((unixFile*)pFile)->lastErrno = errno;
-    if( dirfd>=0 ) robust_close(p, dirfd, __LINE__);
     robust_close(p, fd, __LINE__);
     return SQLITE_IOERR_ACCESS;
   }
   if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
     ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
   }
 #endif
-  
+
+  /* Set up appropriate ctrlFlags */
+  if( isDelete )                ctrlFlags |= UNIXFILE_DELETE;
+  if( isReadonly )              ctrlFlags |= UNIXFILE_RDONLY;
+  if( noLock )                  ctrlFlags |= UNIXFILE_NOLOCK;
+  if( syncDir )                 ctrlFlags |= UNIXFILE_DIRSYNC;
+  if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
+
 #if SQLITE_ENABLE_LOCKING_STYLE
 #if SQLITE_PREFER_PROXY_LOCKING
   isAutoProxy = 1;
 #endif
   if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){
     char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
     int useProxy = 0;
 
     /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means 
     ** never use proxy, NULL means use proxy for non-local files only.  */
     if( envforce!=NULL ){
       useProxy = atoi(envforce)>0;
     }else{
-      struct statfs fsInfo;
       if( statfs(zPath, &fsInfo) == -1 ){
         /* In theory, the close(fd) call is sub-optimal. If the file opened
         ** with fd is a database file, and there are other connections open
         ** on that file that are currently holding advisory locks on it,
         ** then the call to close() will cancel those locks. In practice,
         ** we're assuming that statfs() doesn't fail very often. At least
         ** not while other file descriptors opened by the same process on
         ** the same file are working.  */
         p->lastErrno = errno;
-        if( dirfd>=0 ){
-          robust_close(p, dirfd, __LINE__);
-        }
         robust_close(p, fd, __LINE__);
         rc = SQLITE_IOERR_ACCESS;
         goto open_finished;
       }
       useProxy = !(fsInfo.f_flags&MNT_LOCAL);
     }
     if( useProxy ){
-      rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock,
-                          isDelete, isReadonly);
+      rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
       if( rc==SQLITE_OK ){
         rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
         if( rc!=SQLITE_OK ){
           /* Use unixClose to clean up the resources added in fillInUnixFile 
           ** and clear all the structure's references.  Specifically, 
           ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op 
           */
           unixClose(pFile);
           return rc;
         }
       }
       goto open_finished;
     }
   }
 #endif
   
-  rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock,
-                      isDelete, isReadonly);
+  rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
+
 open_finished:
   if( rc!=SQLITE_OK ){
     sqlite3_free(p->pUnused);
   }
   return rc;
 }
 
 
@@ -29604,33 +30156,35 @@ open_finished:
 static int unixDelete(
   sqlite3_vfs *NotUsed,     /* VFS containing this as the xDelete method */
   const char *zPath,        /* Name of file to be deleted */
   int dirSync               /* If true, fsync() directory after deleting file */
 ){
   int rc = SQLITE_OK;
   UNUSED_PARAMETER(NotUsed);
   SimulateIOError(return SQLITE_IOERR_DELETE);
-  if( unlink(zPath)==(-1) && errno!=ENOENT ){
+  if( osUnlink(zPath)==(-1) && errno!=ENOENT ){
     return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
   }
 #ifndef SQLITE_DISABLE_DIRSYNC
-  if( dirSync ){
+  if( (dirSync & 1)!=0 ){
     int fd;
-    rc = openDirectory(zPath, &fd);
+    rc = osOpenDirectory(zPath, &fd);
     if( rc==SQLITE_OK ){
 #if OS_VXWORKS
       if( fsync(fd)==-1 )
 #else
       if( fsync(fd) )
 #endif
       {
         rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
       }
       robust_close(0, fd, __LINE__);
+    }else if( rc==SQLITE_CANTOPEN ){
+      rc = SQLITE_OK;
     }
   }
 #endif
   return rc;
 }
 
 /*
 ** Test the existance of or access permissions of file zPath. The
@@ -29663,17 +30217,17 @@ static int unixAccess(
       break;
 
     default:
       assert(!"Invalid flags argument");
   }
   *pResOut = (osAccess(zPath, amode)==0);
   if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
     struct stat buf;
-    if( 0==stat(zPath, &buf) && buf.st_size==0 ){
+    if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
       *pResOut = 0;
     }
   }
   return SQLITE_OK;
 }
 
 
 /*
@@ -29861,54 +30415,60 @@ SQLITE_API int sqlite3_current_time = 0;
 
 /*
 ** Find the current time (in Universal Coordinated Time).  Write into *piNow
 ** the current time and date as a Julian Day number times 86_400_000.  In
 ** other words, write into *piNow the number of milliseconds since the Julian
 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
 ** proleptic Gregorian calendar.
 **
-** On success, return 0.  Return 1 if the time and date cannot be found.
+** On success, return SQLITE_OK.  Return SQLITE_ERROR if the time and date 
+** cannot be found.
 */
 static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
   static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
+  int rc = SQLITE_OK;
 #if defined(NO_GETTOD)
   time_t t;
   time(&t);
   *piNow = ((sqlite3_int64)t)*1000 + unixEpoch;
 #elif OS_VXWORKS
   struct timespec sNow;
   clock_gettime(CLOCK_REALTIME, &sNow);
   *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
 #else
   struct timeval sNow;
-  gettimeofday(&sNow, 0);
-  *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
+  if( gettimeofday(&sNow, 0)==0 ){
+    *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
+  }else{
+    rc = SQLITE_ERROR;
+  }
 #endif
 
 #ifdef SQLITE_TEST
   if( sqlite3_current_time ){
     *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
   }
 #endif
   UNUSED_PARAMETER(NotUsed);
-  return 0;
+  return rc;
 }
 
 /*
 ** Find the current time (in Universal Coordinated Time).  Write the
 ** current time and date as a Julian Day number into *prNow and
 ** return 0.  Return 1 if the time and date cannot be found.
 */
 static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
-  sqlite3_int64 i;
+  sqlite3_int64 i = 0;
+  int rc;
   UNUSED_PARAMETER(NotUsed);
-  unixCurrentTimeInt64(0, &i);
+  rc = unixCurrentTimeInt64(0, &i);
   *prNow = i/86400000.0;
-  return 0;
+  return rc;
 }
 
 /*
 ** We added the xGetLastError() method with the intention of providing
 ** better low-level error messages when operating-system problems come up
 ** during SQLite operation.  But so far, none of that has been implemented
 ** in the core.  So this routine is never called.  For now, it is merely
 ** a place-holder.
@@ -30151,17 +30711,17 @@ static int proxyCreateLockPath(const cha
   len = (int)strlen(lockPath);
   buf[0] = lockPath[0];
   for( i=1; i<len; i++ ){
     if( lockPath[i] == '/' && (i - start > 0) ){
       /* only mkdir if leaf dir != "." or "/" or ".." */
       if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') 
          || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){
         buf[i]='\0';
-        if( mkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){
+        if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){
           int err=errno;
           if( err!=EEXIST ) {
             OSTRACE(("CREATELOCKPATH  FAILED creating %s, "
                      "'%s' proxy lock path=%s pid=%d\n",
                      buf, strerror(err), lockPath, getpid()));
             return err;
           }
         }
@@ -30182,17 +30742,16 @@ static int proxyCreateLockPath(const cha
 ** but also for freeing the memory associated with the file descriptor.
 */
 static int proxyCreateUnixFile(
     const char *path,        /* path for the new unixFile */
     unixFile **ppFile,       /* unixFile created and returned by ref */
     int islockfile           /* if non zero missing dirs will be created */
 ) {
   int fd = -1;
-  int dirfd = -1;
   unixFile *pNew;
   int rc = SQLITE_OK;
   int openFlags = O_RDWR | O_CREAT;
   sqlite3_vfs dummyVfs;
   int terrno = 0;
   UnixUnusedFd *pUnused = NULL;
 
   /* 1. first try to open/create the file
@@ -30247,17 +30806,17 @@ static int proxyCreateUnixFile(
   pNew->openFlags = openFlags;
   memset(&dummyVfs, 0, sizeof(dummyVfs));
   dummyVfs.pAppData = (void*)&autolockIoFinder;
   dummyVfs.zName = "dummy";
   pUnused->fd = fd;
   pUnused->flags = openFlags;
   pNew->pUnused = pUnused;
   
-  rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0, 0);
+  rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0);
   if( rc==SQLITE_OK ){
     *ppFile = pNew;
     return SQLITE_OK;
   }
 end_create_proxy:    
   robust_close(pNew, fd, __LINE__);
   sqlite3_free(pNew);
   sqlite3_free(pUnused);
@@ -30287,16 +30846,18 @@ static int proxyGetHostID(unsigned char 
     if( gethostuuid(pHostID, &timeout) ){
       int err = errno;
       if( pError ){
         *pError = err;
       }
       return SQLITE_IOERR;
     }
   }
+#else
+  UNUSED_PARAMETER(pError);
 #endif
 #ifdef SQLITE_TEST
   /* simulate multiple hosts by creating unique hostid file paths */
   if( sqlite3_hostid_num != 0){
     pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF));
   }
 #endif
   
@@ -30361,17 +30922,17 @@ static int proxyBreakConchLock(unixFile 
   fprintf(stderr, "broke stale lock on %s\n", cPath);
   robust_close(pFile, conchFile->h, __LINE__);
   conchFile->h = fd;
   conchFile->openFlags = O_RDWR | O_CREAT;
 
 end_breaklock:
   if( rc ){
     if( fd>=0 ){
-      unlink(tPath);
+      osUnlink(tPath);
       robust_close(pFile, fd, __LINE__);
     }
     fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg);
   }
   return rc;
 }
 
 /* Take the requested lock on the conch file and break a stale lock if the 
@@ -30379,16 +30940,17 @@ end_breaklock:
 */
 static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
   proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; 
   unixFile *conchFile = pCtx->conchFile;
   int rc = SQLITE_OK;
   int nTries = 0;
   struct timespec conchModTime;
   
+  memset(&conchModTime, 0, sizeof(conchModTime));
   do {
     rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
     nTries ++;
     if( rc==SQLITE_BUSY ){
       /* If the lock failed (busy):
        * 1st try: get the mod time of the conch, wait 0.5s and try again. 
        * 2nd try: fail if the mod time changed or host id is different, wait 
        *           10 sec and try again
@@ -30610,21 +31172,22 @@ static int proxyTakeConch(unixFile *pFil
           }
         }
       }
       conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK);
       
     end_takeconch:
       OSTRACE(("TRANSPROXY: CLOSE  %d\n", pFile->h));
       if( rc==SQLITE_OK && pFile->openFlags ){
+        int fd;
         if( pFile->h>=0 ){
           robust_close(pFile, pFile->h, __LINE__);
         }
         pFile->h = -1;
-        int fd = robust_open(pCtx->dbPath, pFile->openFlags,
+        fd = robust_open(pCtx->dbPath, pFile->openFlags,
                       SQLITE_DEFAULT_FILE_PERMISSIONS);
         OSTRACE(("TRANSPROXY: OPEN  %d\n", fd));
         if( fd>=0 ){
           pFile->h = fd;
         }else{
           rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called
            during locking */
         }
@@ -31184,17 +31747,17 @@ SQLITE_API int sqlite3_os_init(void){
     UNIXVFS("unix-nfs",      nfsIoFinder ),
     UNIXVFS("unix-proxy",    proxyIoFinder ),
 #endif
   };
   unsigned int i;          /* Loop counter */
 
   /* Double-check that the aSyscall[] array has been constructed
   ** correctly.  See ticket [bb3a86e890c8e96ab] */
-  assert( ArraySize(aSyscall)==16 );
+  assert( ArraySize(aSyscall)==20 );
 
   /* Register all VFSes defined in the aVfs[] array */
   for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
     sqlite3_vfs_register(&aVfs[i], i==0);
   }
   return SQLITE_OK; 
 }
 
@@ -31220,61 +31783,25 @@ SQLITE_API int sqlite3_os_end(void){
 ** a legal notice, here is a blessing:
 **
 **    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 code that is specific to windows.
-*/
-#if SQLITE_OS_WIN               /* This file is used for windows only */
-
-
-/*
-** A Note About Memory Allocation:
-**
-** This driver uses malloc()/free() directly rather than going through
-** the SQLite-wrappers sqlite3_malloc()/sqlite3_free().  Those wrappers
-** are designed for use on embedded systems where memory is scarce and
-** malloc failures happen frequently.  Win32 does not typically run on
-** embedded systems, and when it does the developers normally have bigger
-** problems to worry about than running out of memory.  So there is not
-** a compelling need to use the wrappers.
-**
-** But there is a good reason to not use the wrappers.  If we use the
-** wrappers then we will get simulated malloc() failures within this
-** driver.  And that causes all kinds of problems for our tests.  We
-** could enhance SQLite to deal with simulated malloc failures within
-** the OS driver, but the code to deal with those failure would not
-** be exercised on Linux (which does not need to malloc() in the driver)
-** and so we would have difficulty writing coverage tests for that
-** code.  Better to leave the code out, we think.
-**
-** The point of this discussion is as follows:  When creating a new
-** OS layer for an embedded system, if you use this file as an example,
-** avoid the use of malloc()/free().  Those routines work ok on windows
-** desktops but not so well in embedded systems.
-*/
-
-#include <winbase.h>
+** This file contains code that is specific to Windows.
+*/
+#if SQLITE_OS_WIN               /* This file is used for Windows only */
 
 #ifdef __CYGWIN__
 # include <sys/cygwin.h>
 #endif
 
 /*
-** Macros used to determine whether or not to use threads.