Backout of bug 581000 - Upgrade to SQLite 3.7.0 due to potential database corruption issues (not exactly but I don't want to put the long story here)
authorShawn Wilsher <sdwilsh@shawnwilsher.com>
Tue, 03 Aug 2010 14:52:35 -0700
changeset 48789 e5e6583bd137587329725388594b5c4b549f2dcb
parent 48788 792c999694994eb0a9b62af7c671ae86a771e068
child 48790 7869f6618e7184653a32b0bcf7704f988f8aa1de
child 49342 55d92a5223aa8cab24f34ae620f9a059db47198c
push id14818
push usersdwilsh@shawnwilsher.com
push dateTue, 03 Aug 2010 21:54:45 +0000
treeherdermozilla-central@e5e6583bd137 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs581000
milestone2.0b3pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout of bug 581000 - Upgrade to SQLite 3.7.0 due to potential database corruption issues (not exactly but I don't want to put the long story here) a=potential corruption on a CLOSED TREE
configure.in
db/sqlite3/README.MOZILLA
db/sqlite3/src/sqlite3.c
db/sqlite3/src/sqlite3.h
--- a/configure.in
+++ b/configure.in
@@ -127,17 +127,17 @@ GTK2_VERSION=2.10.0
 WINDRES_VERSION=2.14.90
 W32API_VERSION=3.8
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
 GIO_VERSION=2.0
 STARTUP_NOTIFICATION_VERSION=0.8
 DBUS_VERSION=0.60
-SQLITE_VERSION=3.7.0
+SQLITE_VERSION=3.6.23.1
 LIBNOTIFY_VERSION=0.4
 
 MSMANIFEST_TOOL=
 
 dnl Set various checks
 dnl ========================================================
 MISSING_X=
 AC_PROG_AWK
--- a/db/sqlite3/README.MOZILLA
+++ b/db/sqlite3/README.MOZILLA
@@ -1,11 +1,11 @@
-This is sqlite 3.7.0
+This is sqlite 3.6.23.1
 
--- Shawn Wilsher <me@shawnwilsher.com>, 07/2010
+-- Shawn Wilsher <me@shawnwilsher.com>, 03/2010
 
 See http://www.sqlite.org/ for more info.
 
 We have a mozilla-specific Makefile.in in src/ (normally no
 Makefile.in there) that we use to build.
 
 To move to a new version:
 
--- a/db/sqlite3/src/sqlite3.c
+++ b/db/sqlite3/src/sqlite3.c
@@ -1,11 +1,11 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.7.0.  By combining all the individual C code files into this 
+** version 3.6.23.1.  By combining all the individual C code files into this 
 ** single large file, the entire code can be compiled as a one translation
 ** unit.  This allows many compilers to do optimizations that would not be
 ** possible if the files were compiled separately.  Performance improvements
 ** of 5% are more are commonly seen when SQLite is compiled as a single
 ** translation unit.
 **
 ** This file is all you need to compile SQLite.  To use SQLite in other
 ** programs, you need this file and the "sqlite3.h" header file that defines
@@ -186,24 +186,16 @@
 #ifndef SQLITE_DEFAULT_CACHE_SIZE
 # define SQLITE_DEFAULT_CACHE_SIZE  2000
 #endif
 #ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE
 # define SQLITE_DEFAULT_TEMP_CACHE_SIZE  500
 #endif
 
 /*
-** The default number of frames to accumulate in the log file before
-** checkpointing the database in WAL mode.
-*/
-#ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
-# define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT  1000
-#endif
-
-/*
 ** The maximum number of attached databases.  This must be between 0
 ** and 30.  The upper bound on 30 is because a 32-bit integer bitmap
 ** is used internally to track attached databases.
 */
 #ifndef SQLITE_MAX_ATTACHED
 # define SQLITE_MAX_ATTACHED 10
 #endif
 
@@ -326,17 +318,17 @@
 ** 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
-** that vary from one machine to the next.
+** that very from one machine to the next.
 **
 ** Ticket #3860:  The llvm-gcc-4.2 compiler from Apple chokes on
 ** the ((void*)&((char*)0)[X]) construct.  But MSVC chokes on ((void*)(X)).
 ** So we have to define the macros in different ways depending on the
 ** compiler.
 */
 #if defined(__PTRDIFF_TYPE__)  /* This case should work for GCC */
 # define SQLITE_INT_TO_PTR(X)  ((void*)(__PTRDIFF_TYPE__)(X))
@@ -507,23 +499,16 @@ SQLITE_PRIVATE   void sqlite3Coverage(in
 # define ALWAYS(X)      ((X)?1:(assert(0),0))
 # define NEVER(X)       ((X)?(assert(0),1):0)
 #else
 # define ALWAYS(X)      (X)
 # define NEVER(X)       (X)
 #endif
 
 /*
-** Return true (non-zero) if the input is a integer that is too large
-** to fit in 32-bits.  This macro is used inside of various testcase()
-** macros to verify that we have tested SQLite for large-file support.
-*/
-#define IS_BIG_INT(X)  (((X)&~(i64)0xffffffff)!=0)
-
-/*
 ** The macro unlikely() is a hint that surrounds a boolean
 ** expression that is usually false.  Macro likely() surrounds
 ** a boolean expression that is usually true.  GCC is able to
 ** use these hints to generate better code, sometimes.
 */
 #if defined(__GNUC__) && 0
 # define likely(X)    __builtin_expect((X),1)
 # define unlikely(X)  __builtin_expect((X),0)
@@ -638,19 +623,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.0"
-#define SQLITE_VERSION_NUMBER 3007000
-#define SQLITE_SOURCE_ID      "2010-07-21 16:16:28 b36b105eab6fd3195f4bfba6cb5cda0f063b7460"
+#define SQLITE_VERSION        "3.6.23.1"
+#define SQLITE_VERSION_NUMBER 3006023
+#define SQLITE_SOURCE_ID      "2010-03-26 22:28:06 b078b588d617e07886ad156e9f54ade6d823568e"
 
 /*
 ** 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
@@ -677,16 +662,17 @@ extern "C" {
 **
 ** See also: [sqlite_version()] and [sqlite_source_id()].
 */
 SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
 SQLITE_API const char *sqlite3_libversion(void);
 SQLITE_API const char *sqlite3_sourceid(void);
 SQLITE_API int sqlite3_libversion_number(void);
 
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
 /*
 ** CAPI3REF: Run-Time Library Compilation Options Diagnostics
 **
 ** ^The sqlite3_compileoption_used() function returns 0 or 1 
 ** indicating whether the specified option was defined at 
 ** compile time.  ^The SQLITE_ prefix may be omitted from the 
 ** option name passed to sqlite3_compileoption_used().  
 **
@@ -699,20 +685,19 @@ SQLITE_API int sqlite3_libversion_number
 **
 ** ^Support for the diagnostic functions sqlite3_compileoption_used()
 ** and sqlite3_compileoption_get() may be omitted by specifing the 
 ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time.
 **
 ** See also: SQL functions [sqlite_compileoption_used()] and
 ** [sqlite_compileoption_get()] and the [compile_options pragma].
 */
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
 SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
 SQLITE_API const char *sqlite3_compileoption_get(int N);
-#endif
+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
 
 /*
 ** 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_THREADSAFE] compile-time option being set to 0.
 **
@@ -924,17 +909,17 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_NOMEM        7   /* A malloc() failed */
 #define SQLITE_READONLY     8   /* Attempt to write a readonly database */
 #define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite3_interrupt()*/
 #define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
 #define SQLITE_CORRUPT     11   /* The database disk image is malformed */
 #define SQLITE_NOTFOUND    12   /* NOT USED. Table or record not found */
 #define SQLITE_FULL        13   /* Insertion failed because database is full */
 #define SQLITE_CANTOPEN    14   /* Unable to open the database file */
-#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
+#define SQLITE_PROTOCOL    15   /* NOT USED. Database lock protocol error */
 #define SQLITE_EMPTY       16   /* Database is empty */
 #define SQLITE_SCHEMA      17   /* The database schema changed */
 #define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
 #define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */
 #define SQLITE_MISMATCH    20   /* Data type mismatch */
 #define SQLITE_MISUSE      21   /* Library used incorrectly */
 #define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
 #define SQLITE_AUTH        23   /* Authorization denied */
@@ -980,22 +965,17 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_IOERR_DELETE            (SQLITE_IOERR | (10<<8))
 #define SQLITE_IOERR_BLOCKED           (SQLITE_IOERR | (11<<8))
 #define SQLITE_IOERR_NOMEM             (SQLITE_IOERR | (12<<8))
 #define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))
 #define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
 #define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))
 #define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
 #define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
-#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
-#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
-#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
-#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
-#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
-#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
+#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED | (1<<8) )
 
 /*
 ** CAPI3REF: Flags For File Open Operations
 **
 ** These bit values are intended for use in the
 ** 3rd parameter to the [sqlite3_open_v2()] interface and
 ** in the 4th parameter to the xOpen method of the
 ** [sqlite3_vfs] object.
@@ -1012,50 +992,48 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_OPEN_MAIN_JOURNAL     0x00000800  /* VFS only */
 #define SQLITE_OPEN_TEMP_JOURNAL     0x00001000  /* VFS only */
 #define SQLITE_OPEN_SUBJOURNAL       0x00002000  /* VFS only */
 #define SQLITE_OPEN_MASTER_JOURNAL   0x00004000  /* VFS only */
 #define SQLITE_OPEN_NOMUTEX          0x00008000  /* Ok for sqlite3_open_v2() */
 #define SQLITE_OPEN_FULLMUTEX        0x00010000  /* Ok for sqlite3_open_v2() */
 #define SQLITE_OPEN_SHAREDCACHE      0x00020000  /* Ok for sqlite3_open_v2() */
 #define SQLITE_OPEN_PRIVATECACHE     0x00040000  /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_WAL              0x00080000  /* VFS only */
 
 /*
 ** CAPI3REF: Device Characteristics
 **
-** The xDeviceCharacteristics method of the [sqlite3_io_methods]
+** The xDeviceCapabilities method of the [sqlite3_io_methods]
 ** object returns an integer which is a vector of the these
 ** bit values expressing I/O characteristics of the mass storage
 ** device that holds the file that the [sqlite3_io_methods]
 ** refers to.
 **
 ** The SQLITE_IOCAP_ATOMIC property means that all writes of
 ** 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().
 */
-#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_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
 
 /*
 ** 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.
 */
@@ -1196,22 +1174,16 @@ struct sqlite3_io_methods {
   int (*xSync)(sqlite3_file*, int flags);
   int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
   int (*xLock)(sqlite3_file*, int);
   int (*xUnlock)(sqlite3_file*, int);
   int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
   int (*xFileControl)(sqlite3_file*, int op, void *pArg);
   int (*xSectorSize)(sqlite3_file*);
   int (*xDeviceCharacteristics)(sqlite3_file*);
-  /* Methods above are valid for version 1 */
-  int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
-  int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
-  void (*xShmBarrier)(sqlite3_file*);
-  int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
-  /* Methods above are valid for version 2 */
   /* Additional methods may be added in future releases */
 };
 
 /*
 ** CAPI3REF: Standard File Control Opcodes
 **
 ** These integer constants are opcodes for the xFileControl method
 ** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
@@ -1219,29 +1191,21 @@ struct sqlite3_io_methods {
 **
 ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging.  This
 ** opcode causes the xFileControl method to write the current state of
 ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
 ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
 ** into an integer that the pArg argument points to. This capability
 ** is used during testing and only needs to be supported when SQLITE_TEST
 ** is defined.
-**
-** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
-** layer a hint of how large the database file will grow to be during the
-** current transaction.  This hint is not guaranteed to be accurate but it
-** is often close.  The underlying VFS might choose to preallocate database
-** file space based on this hint in order to help writes to the database
-** file run faster.
 */
 #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
 
 /*
 ** 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.
@@ -1363,37 +1327,30 @@ typedef struct sqlite3_mutex sqlite3_mut
 **
 ** SQLite will always allocate at least mxPathname+1 bytes for the
 ** output buffer xFullPathname.  The exact size of the output buffer
 ** is also passed as a parameter to both  methods. If the output buffer
 ** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
 ** handled as a fatal error by SQLite, vfs implementations should endeavor
 ** to prevent this by setting mxPathname to a sufficiently large value.
 **
-** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64()
-** interfaces are not strictly a part of the filesystem, but they are
+** The xRandomness(), xSleep(), and xCurrentTime() interfaces
+** are not strictly a part of the filesystem, but they are
 ** included in the VFS structure for completeness.
 ** The xRandomness() function attempts to return nBytes bytes
 ** of good-quality randomness into zOut.  The return value is
 ** the actual number of bytes of randomness obtained.
 ** The xSleep() method causes the calling thread to sleep for at
 ** least the number of microseconds given.  The xCurrentTime()
-** method returns a Julian Day Number for the current date and time as
-** a floating point value.
-** The xCurrentTimeInt64() method returns, as an integer, the Julian
-** Day Number multipled by 86400000 (the number of milliseconds in 
-** a 24-hour day).  
-** ^SQLite will use the xCurrentTimeInt64() method to get the current
-** date and time if that method is available (if iVersion is 2 or 
-** greater and the function pointer is not NULL) and will fall back
-** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
+** method returns a Julian Day Number for the current date and time.
+**
 */
 typedef struct sqlite3_vfs sqlite3_vfs;
 struct sqlite3_vfs {
-  int iVersion;            /* Structure version number (currently 2) */
+  int iVersion;            /* Structure version number */
   int szOsFile;            /* Size of subclassed sqlite3_file */
   int mxPathname;          /* Maximum file pathname length */
   sqlite3_vfs *pNext;      /* Next registered VFS */
   const char *zName;       /* Name of this virtual file system */
   void *pAppData;          /* Pointer to application-specific data */
   int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
                int flags, int *pOutFlags);
   int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
@@ -1402,89 +1359,36 @@ struct sqlite3_vfs {
   void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
   void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
   void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
   void (*xDlClose)(sqlite3_vfs*, void*);
   int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
   int (*xSleep)(sqlite3_vfs*, int microseconds);
   int (*xCurrentTime)(sqlite3_vfs*, double*);
   int (*xGetLastError)(sqlite3_vfs*, int, char *);
-  /*
-  ** The methods above are in version 1 of the sqlite_vfs object
-  ** definition.  Those that follow are added in version 2 or later
-  */
-  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
-  /*
-  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
-  ** New fields may be appended in figure versions.  The iVersion
-  ** value will increment whenever this happens. 
-  */
+  /* New fields may be appended in figure versions.  The iVersion
+  ** value will increment whenever this happens. */
 };
 
 /*
 ** CAPI3REF: Flags for the xAccess VFS method
 **
 ** These integer constants can be used as the third parameter to
 ** the xAccess method of an [sqlite3_vfs] object.  They determine
 ** what kind of permissions the xAccess method is looking for.
 ** With SQLITE_ACCESS_EXISTS, the xAccess method
 ** simply checks whether the file exists.
 ** With SQLITE_ACCESS_READWRITE, the xAccess method
-** checks whether the named directory is both readable and writable
-** (in other words, if files can be added, removed, and renamed within
-** the directory).
-** The SQLITE_ACCESS_READWRITE constant is currently used only by the
-** [temp_store_directory pragma], though this could change in a future
-** release of SQLite.
+** checks whether the file is both readable and writable.
 ** With SQLITE_ACCESS_READ, the xAccess method
-** checks whether the file is readable.  The SQLITE_ACCESS_READ constant is
-** currently unused, though it might be used in a future release of
-** SQLite.
+** checks whether the file is readable.
 */
 #define SQLITE_ACCESS_EXISTS    0
-#define SQLITE_ACCESS_READWRITE 1   /* Used by PRAGMA temp_store_directory */
-#define SQLITE_ACCESS_READ      2   /* Unused */
-
-/*
-** CAPI3REF: Flags for the xShmLock VFS method
-**
-** These integer constants define the various locking operations
-** allowed by the xShmLock method of [sqlite3_io_methods].  The
-** following are the only legal combinations of flags to the
-** xShmLock method:
-**
-** <ul>
-** <li>  SQLITE_SHM_LOCK | SQLITE_SHM_SHARED
-** <li>  SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE
-** <li>  SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED
-** <li>  SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE
-** </ul>
-**
-** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
-** was given no the corresponding lock.  
-**
-** The xShmLock method can transition between unlocked and SHARED or
-** between unlocked and EXCLUSIVE.  It cannot transition between SHARED
-** and EXCLUSIVE.
-*/
-#define SQLITE_SHM_UNLOCK       1
-#define SQLITE_SHM_LOCK         2
-#define SQLITE_SHM_SHARED       4
-#define SQLITE_SHM_EXCLUSIVE    8
-
-/*
-** CAPI3REF: Maximum xShmLock index
-**
-** The xShmLock method on [sqlite3_io_methods] may use values
-** between 0 and this upper bound as its "offset" argument.
-** The SQLite core will never attempt to acquire or release a
-** lock outside of this range
-*/
-#define SQLITE_SHM_NLOCK        8
-
+#define SQLITE_ACCESS_READWRITE 1
+#define SQLITE_ACCESS_READ      2
 
 /*
 ** CAPI3REF: Initialize The SQLite Library
 **
 ** ^The sqlite3_initialize() routine initializes the
 ** SQLite library.  ^The sqlite3_shutdown() routine
 ** deallocates any resources that were allocated by sqlite3_initialize().
 ** These routines are designed to aid in process initialization and
@@ -1585,20 +1489,21 @@ SQLITE_API int sqlite3_os_end(void);
 ** what property of SQLite is to be configured.  Subsequent arguments
 ** vary depending on the [SQLITE_CONFIG_SINGLETHREAD | configuration option]
 ** in the first argument.
 **
 ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
 ** ^If the option is unknown or SQLite is unable to set the option
 ** then this routine returns a non-zero [error code].
 */
-SQLITE_API int sqlite3_config(int, ...);
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_config(int, ...);
 
 /*
 ** CAPI3REF: Configure database connections
+** EXPERIMENTAL
 **
 ** The sqlite3_db_config() interface is used to make configuration
 ** changes to a [database connection].  The interface is similar to
 ** [sqlite3_config()] except that the changes apply to a single
 ** [database connection] (specified in the first argument).  The
 ** sqlite3_db_config() interface should only be used immediately after
 ** the database connection is created using [sqlite3_open()],
 ** [sqlite3_open16()], or [sqlite3_open_v2()].  
@@ -1608,20 +1513,21 @@ SQLITE_API int sqlite3_config(int, ...);
 ** aspect of the [database connection] is being configured.
 ** The only choice for this value is [SQLITE_DBCONFIG_LOOKASIDE].
 ** New verbs are likely to be added in future releases of SQLite.
 ** Additional arguments depend on the verb.
 **
 ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
 ** the call is considered successful.
 */
-SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...);
 
 /*
 ** CAPI3REF: Memory Allocation Routines
+** EXPERIMENTAL
 **
 ** An instance of this object defines the interface between SQLite
 ** and low-level memory allocation routines.
 **
 ** This object is used in only one place in the SQLite interface.
 ** A pointer to an instance of this object is the argument to
 ** [sqlite3_config()] when the configuration option is
 ** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].  
@@ -1693,16 +1599,17 @@ struct sqlite3_mem_methods {
   int (*xRoundup)(int);          /* Round up request size to allocation size */
   int (*xInit)(void*);           /* Initialize the memory allocator */
   void (*xShutdown)(void*);      /* Deinitialize the memory allocator */
   void *pAppData;                /* Argument to xInit() and xShutdown() */
 };
 
 /*
 ** CAPI3REF: Configuration Options
+** EXPERIMENTAL
 **
 ** These constants are the available integer configuration options that
 ** can be passed as the first argument to the [sqlite3_config()] interface.
 **
 ** New configuration options may be added in future releases of SQLite.
 ** Existing configuration options might be discontinued.  Applications
 ** should check the return code from [sqlite3_config()] to make sure that
 ** the call worked.  The [sqlite3_config()] interface will return a
@@ -1878,34 +1785,16 @@ struct sqlite3_mem_methods {
 ** to a custom page cache implementation.)^  ^SQLite makes a copy of the
 ** object and uses it for page cache memory allocations.</dd>
 **
 ** <dt>SQLITE_CONFIG_GETPCACHE</dt>
 ** <dd> ^(This option takes a single argument which is a pointer to an
 ** [sqlite3_pcache_methods] object.  SQLite copies of the current
 ** page cache implementation into that object.)^ </dd>
 **
-** <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.
-** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is
-** passed through as the first parameter to the application-defined logger
-** function whenever that function is invoked.  ^The second parameter to
-** the logger function is a copy of the first parameter to the corresponding
-** [sqlite3_log()] call and is intended to be a [result code] or an
-** [extended result code].  ^The third parameter passed to the logger is
-** log message after formatting via [sqlite3_snprintf()].
-** The SQLite logging interface is not reentrant; the logger function
-** supplied by the application must not invoke any SQLite interface.
-** In a multi-threaded application, the application-defined logger
-** function must be threadsafe. </dd>
-**
 ** </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 */
@@ -1916,17 +1805,18 @@ struct sqlite3_mem_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_LOG          16  /* xFunc, void* */
 
 /*
-** CAPI3REF: Database Connection Configuration Options
+** CAPI3REF: Configuration Options
+** EXPERIMENTAL
 **
 ** 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.
 ** Existing configuration options might be discontinued.  Applications
 ** should check the return code from [sqlite3_db_config()] to make sure that
 ** the call worked.  ^The [sqlite3_db_config()] interface will return a
@@ -2692,16 +2582,17 @@ SQLITE_API int sqlite3_set_authorizer(
 #define SQLITE_CREATE_VTABLE        29   /* Table Name      Module Name     */
 #define SQLITE_DROP_VTABLE          30   /* Table Name      Module Name     */
 #define SQLITE_FUNCTION             31   /* NULL            Function Name   */
 #define SQLITE_SAVEPOINT            32   /* Operation       Savepoint Name  */
 #define SQLITE_COPY                  0   /* No longer used */
 
 /*
 ** CAPI3REF: Tracing And Profiling Functions
+** EXPERIMENTAL
 **
 ** These routines register callback functions that can be used for
 ** tracing and profiling the execution of SQL statements.
 **
 ** ^The callback function registered by sqlite3_trace() is invoked at
 ** various times when an SQL statement is being run by [sqlite3_step()].
 ** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the
 ** SQL statement text as the statement first begins executing.
@@ -2709,17 +2600,17 @@ SQLITE_API int sqlite3_set_authorizer(
 ** as each triggered subprogram is entered.  The callbacks for triggers
 ** contain a UTF-8 SQL comment that identifies the trigger.)^
 **
 ** ^The callback function registered by sqlite3_profile() is invoked
 ** as each SQL statement finishes.  ^The profile callback contains
 ** the original statement text and an estimate of wall-clock time
 ** of how long that statement took to run.
 */
-SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
+SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
 SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
    void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
 
 /*
 ** CAPI3REF: Query Progress Callbacks
 **
 ** ^This routine configures a callback function - the
 ** progress callback - that is invoked periodically during long
@@ -3502,24 +3393,16 @@ SQLITE_API const void *sqlite3_column_de
 **
 ** [SQLITE_MISUSE] means that the this routine was called inappropriately.
 ** Perhaps it was called on a [prepared statement] that has
 ** already been [sqlite3_finalize | finalized] or on one that had
 ** previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
 ** be the case that the same database connection is being used by two or
 ** more threads at the same moment in time.
 **
-** For all versions of SQLite up to and including 3.6.23.1, it was required
-** after sqlite3_step() returned anything other than [SQLITE_ROW] that
-** [sqlite3_reset()] be called before any subsequent invocation of
-** sqlite3_step().  Failure to invoke [sqlite3_reset()] in this way would
-** result in an [SQLITE_MISUSE] return from sqlite3_step().  But after
-** version 3.6.23.1, sqlite3_step() began calling [sqlite3_reset()] 
-** automatically in this circumstance rather than returning [SQLITE_MISUSE].  
-**
 ** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
 ** API always returns a generic error code, [SQLITE_ERROR], following any
 ** error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
 ** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
 ** specific [error codes] that better describes the error.
 ** We admit that this is a goofy design.  The problem has been fixed
 ** with the "v2" interface.  If you prepare all of your SQL statements
 ** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
@@ -4322,17 +4205,17 @@ SQLITE_API int sqlite3_collation_needed(
   void(*)(void*,sqlite3*,int eTextRep,const char*)
 );
 SQLITE_API int sqlite3_collation_needed16(
   sqlite3*, 
   void*,
   void(*)(void*,sqlite3*,int eTextRep,const void*)
 );
 
-#ifdef SQLITE_HAS_CODEC
+#if SQLITE_HAS_CODEC
 /*
 ** Specify the key for an encrypted database.  This routine should be
 ** called right after sqlite3_open().
 **
 ** The code to implement this API is not available in the public release
 ** of SQLite.
 */
 SQLITE_API int sqlite3_key(
@@ -4505,16 +4388,18 @@ SQLITE_API sqlite3_stmt *sqlite3_next_st
 ** ^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.
 **
 ** ^For the purposes of this API, a transaction is said to have been
 ** rolled back if an explicit "ROLLBACK" statement is executed, or
 ** an error or constraint causes an implicit rollback to occur.
 ** ^The rollback callback is not invoked if a transaction is
 ** automatically rolled back because the database connection is closed.
+** ^The rollback callback is not invoked if a transaction is
+** rolled back because a commit callback returned non-zero.
 **
 ** See also the [sqlite3_update_hook()] interface.
 */
 SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
 SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
 
 /*
 ** CAPI3REF: Data Change Notification Callbacks
@@ -4790,16 +4675,18 @@ SQLITE_API int sqlite3_auto_extension(vo
 ** extensions. It undoes the effect of all prior
 ** [sqlite3_auto_extension()] calls.)^
 **
 ** ^This function disables automatic extensions in all threads.
 */
 SQLITE_API void sqlite3_reset_auto_extension(void);
 
 /*
+****** EXPERIMENTAL - subject to change without notice **************
+**
 ** The interface to the virtual-table mechanism is currently considered
 ** to be experimental.  The interface might change in incompatible ways.
 ** If this is a problem for you, do not use the interface at this time.
 **
 ** When the virtual-table mechanism stabilizes, we will declare the
 ** interface fixed, support it indefinitely, and remove this comment.
 */
 
@@ -4809,16 +4696,17 @@ SQLITE_API void sqlite3_reset_auto_exten
 typedef struct sqlite3_vtab sqlite3_vtab;
 typedef struct sqlite3_index_info sqlite3_index_info;
 typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
 typedef struct sqlite3_module sqlite3_module;
 
 /*
 ** CAPI3REF: Virtual Table Object
 ** KEYWORDS: sqlite3_module {virtual table module}
+** EXPERIMENTAL
 **
 ** This structure, sometimes called a a "virtual table module", 
 ** defines the implementation of a [virtual tables].  
 ** This structure consists mostly of methods for the module.
 **
 ** ^A virtual table module is created by filling in a persistent
 ** instance of this structure and passing a pointer to that instance
 ** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
@@ -4855,16 +4743,17 @@ struct sqlite3_module {
                        void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
                        void **ppArg);
   int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
 };
 
 /*
 ** CAPI3REF: Virtual Table Indexing Information
 ** KEYWORDS: sqlite3_index_info
+** EXPERIMENTAL
 **
 ** The sqlite3_index_info structure and its substructures is used to
 ** pass information into and receive the reply from the [xBestIndex]
 ** method of a [virtual table module].  The fields under **Inputs** are the
 ** inputs to xBestIndex and are read-only.  xBestIndex inserts its
 ** results into the **Outputs** fields.
 **
 ** ^(The aConstraint[] array records WHERE clause constraints of the form:
@@ -4936,16 +4825,17 @@ struct sqlite3_index_info {
 #define SQLITE_INDEX_CONSTRAINT_GT    4
 #define SQLITE_INDEX_CONSTRAINT_LE    8
 #define SQLITE_INDEX_CONSTRAINT_LT    16
 #define SQLITE_INDEX_CONSTRAINT_GE    32
 #define SQLITE_INDEX_CONSTRAINT_MATCH 64
 
 /*
 ** CAPI3REF: Register A Virtual Table Implementation
+** EXPERIMENTAL
 **
 ** ^These routines are used to register a new [virtual table module] name.
 ** ^Module names must be registered before
 ** creating a new [virtual table] using the module and before using a
 ** preexisting [virtual table] for the module.
 **
 ** ^The module name is registered on the [database connection] specified
 ** by the first parameter.  ^The name of the module is given by the 
@@ -4957,33 +4847,34 @@ struct sqlite3_index_info {
 **
 ** ^The sqlite3_create_module_v2() interface has a fifth parameter which
 ** is a pointer to a destructor for the pClientData.  ^SQLite will
 ** invoke the destructor function (if it is not NULL) when SQLite
 ** no longer needs the pClientData pointer.  ^The sqlite3_create_module()
 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
 ** destructor.
 */
-SQLITE_API int sqlite3_create_module(
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module(
   sqlite3 *db,               /* SQLite connection to register module with */
   const char *zName,         /* Name of the module */
   const sqlite3_module *p,   /* Methods for the module */
   void *pClientData          /* Client data for xCreate/xConnect */
 );
-SQLITE_API int sqlite3_create_module_v2(
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module_v2(
   sqlite3 *db,               /* SQLite connection to register module with */
   const char *zName,         /* Name of the module */
   const sqlite3_module *p,   /* Methods for the module */
   void *pClientData,         /* Client data for xCreate/xConnect */
   void(*xDestroy)(void*)     /* Module destructor function */
 );
 
 /*
 ** CAPI3REF: Virtual Table Instance Object
 ** KEYWORDS: sqlite3_vtab
+** EXPERIMENTAL
 **
 ** Every [virtual table module] implementation uses a subclass
 ** of this object to describe a particular instance
 ** of the [virtual table].  Each subclass will
 ** be tailored to the specific needs of the module implementation.
 ** The purpose of this superclass is to define certain fields that are
 ** common to all module implementations.
 **
@@ -4999,16 +4890,17 @@ struct sqlite3_vtab {
   int nRef;                       /* NO LONGER USED */
   char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
   /* Virtual table implementations will typically add additional fields */
 };
 
 /*
 ** CAPI3REF: Virtual Table Cursor Object
 ** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
+** EXPERIMENTAL
 **
 ** Every [virtual table module] implementation uses a subclass of the
 ** following structure to describe cursors that point into the
 ** [virtual table] and are used
 ** to loop through the virtual table.  Cursors are created using the
 ** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed
 ** by the [sqlite3_module.xClose | xClose] method.  Cursors are used
 ** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods
@@ -5020,50 +4912,54 @@ struct sqlite3_vtab {
 */
 struct sqlite3_vtab_cursor {
   sqlite3_vtab *pVtab;      /* Virtual table of this cursor */
   /* Virtual table implementations will typically add additional fields */
 };
 
 /*
 ** CAPI3REF: Declare The Schema Of A Virtual Table
+** EXPERIMENTAL
 **
 ** ^The [xCreate] and [xConnect] methods of a
 ** [virtual table module] call this interface
 ** to declare the format (the names and datatypes of the columns) of
 ** the virtual tables they implement.
 */
-SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
 
 /*
 ** CAPI3REF: Overload A Function For A Virtual Table
+** EXPERIMENTAL
 **
 ** ^(Virtual tables can provide alternative implementations of functions
 ** using the [xFindFunction] method of the [virtual table module].  
 ** But global versions of those functions
 ** must exist in order to be overloaded.)^
 **
 ** ^(This API makes sure a global version of a function with a particular
 ** name and number of parameters exists.  If no such function exists
 ** before this API is called, a new function is created.)^  ^The implementation
 ** of the new function always causes an exception to be thrown.  So
 ** the new function is not good for anything by itself.  Its only
 ** purpose is to be a placeholder function that can be overloaded
 ** by a [virtual table].
 */
-SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
 
 /*
 ** The interface to the virtual-table mechanism defined above (back up
 ** to a comment remarkably similar to this one) is currently considered
 ** to be experimental.  The interface might change in incompatible ways.
 ** If this is a problem for you, do not use the interface at this time.
 **
 ** When the virtual-table mechanism stabilizes, we will declare the
 ** interface fixed, support it indefinitely, and remove this comment.
+**
+****** EXPERIMENTAL - subject to change without notice **************
 */
 
 /*
 ** CAPI3REF: A Handle To An Open BLOB
 ** KEYWORDS: {BLOB handle} {BLOB handles}
 **
 ** An instance of this object represents an open BLOB on which
 ** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
@@ -5396,16 +5292,17 @@ SQLITE_API int sqlite3_vfs_unregister(sq
 SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
 SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
 SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
 SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
 SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
 
 /*
 ** CAPI3REF: Mutex Methods Object
+** EXPERIMENTAL
 **
 ** An instance of this structure defines the low-level routines
 ** used to allocate and use mutexes.
 **
 ** Usually, the default mutex implementations provided by SQLite are
 ** sufficient, however the user has the option of substituting a custom
 ** implementation for specialized deployments or systems for which SQLite
 ** does not provide a suitable implementation. In this case, the user
@@ -5608,21 +5505,21 @@ 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_LAST                    17
+#define SQLITE_TESTCTRL_LAST                    16
 
 /*
 ** CAPI3REF: SQLite Runtime Status
+** EXPERIMENTAL
 **
 ** ^This interface is used to retrieve runtime status information
 ** about the preformance of SQLite, and optionally to reset various
 ** highwater marks.  ^The first argument is an integer code for
 ** the specific parameter to measure.  ^(Recognized integer codes
 ** are of the form [SQLITE_STATUS_MEMORY_USED | SQLITE_STATUS_...].)^
 ** ^The current value of the parameter is returned into *pCurrent.
 ** ^The highest recorded value is returned in *pHighwater.  ^If the
@@ -5640,21 +5537,22 @@ SQLITE_API int sqlite3_test_control(int 
 ** called while other threads are running the same or different SQLite
 ** interfaces.  However the values returned in *pCurrent and
 ** *pHighwater reflect the status of SQLite at different points in time
 ** and it is possible that another thread might change the parameter
 ** in between the times when *pCurrent and *pHighwater are written.
 **
 ** See also: [sqlite3_db_status()]
 */
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
 
 
 /*
 ** CAPI3REF: Status Parameters
+** EXPERIMENTAL
 **
 ** These integer constants designate various run-time status parameters
 ** that can be returned by [sqlite3_status()].
 **
 ** <dl>
 ** ^(<dt>SQLITE_STATUS_MEMORY_USED</dt>
 ** <dd>This parameter is the current amount of memory checked out
 ** using [sqlite3_malloc()], either directly or indirectly.  The
@@ -5731,66 +5629,59 @@ SQLITE_API int sqlite3_status(int op, in
 #define SQLITE_STATUS_SCRATCH_OVERFLOW     4
 #define SQLITE_STATUS_MALLOC_SIZE          5
 #define SQLITE_STATUS_PARSER_STACK         6
 #define SQLITE_STATUS_PAGECACHE_SIZE       7
 #define SQLITE_STATUS_SCRATCH_SIZE         8
 
 /*
 ** CAPI3REF: Database Connection Status
+** EXPERIMENTAL
 **
 ** ^This interface is used to retrieve runtime status information 
 ** about a single [database connection].  ^The first argument is the
 ** database connection object to be interrogated.  ^The second argument
-** is an integer constant, taken from the set of
-** [SQLITE_DBSTATUS_LOOKASIDE_USED | SQLITE_DBSTATUS_*] macros, that
-** determiness the parameter to interrogate.  The set of 
-** [SQLITE_DBSTATUS_LOOKASIDE_USED | SQLITE_DBSTATUS_*] macros is likely
-** to grow in future releases of SQLite.
+** is the parameter to interrogate.  ^Currently, the only allowed value
+** for the second parameter is [SQLITE_DBSTATUS_LOOKASIDE_USED].
+** Additional options will likely appear in future releases of SQLite.
 **
 ** ^The current value of the requested parameter is written into *pCur
 ** and the highest instantaneous value is written into *pHiwtr.  ^If
 ** the resetFlg is true, then the highest instantaneous value is
 ** reset back down to the current value.
 **
 ** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
 */
-SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
 
 /*
 ** CAPI3REF: Status Parameters for database connections
+** EXPERIMENTAL
 **
 ** These constants are the available integer "verbs" that can be passed as
 ** the second argument to the [sqlite3_db_status()] interface.
 **
 ** New verbs may be added in future releases of SQLite. Existing verbs
 ** might be discontinued. Applications should check the return code from
 ** [sqlite3_db_status()] to make sure that the call worked.
 ** The [sqlite3_db_status()] interface will return a non-zero error code
 ** if a discontinued or unsupported verb is invoked.
 **
 ** <dl>
 ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
 ** <dd>This parameter returns the number of lookaside memory slots currently
 ** checked out.</dd>)^
-**
-** <dt>SQLITE_DBSTATUS_CACHE_USED</dt>
-** <dd>^This parameter returns the approximate number of of bytes of heap
-** memory used by all pager caches associated with the database connection.
-** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
-** </dd>
 ** </dl>
 */
 #define SQLITE_DBSTATUS_LOOKASIDE_USED     0
-#define SQLITE_DBSTATUS_CACHE_USED         1
-#define SQLITE_DBSTATUS_MAX                1   /* Largest defined DBSTATUS */
 
 
 /*
 ** CAPI3REF: Prepared Statement Status
+** EXPERIMENTAL
 **
 ** ^(Each prepared statement maintains various
 ** [SQLITE_STMTSTATUS_SORT | counters] that measure the number
 ** of times it has performed specific operations.)^  These counters can
 ** be used to monitor the performance characteristics of the prepared
 ** statements.  For example, if the number of table steps greatly exceeds
 ** the number of table searches or result rows, that would tend to indicate
 ** that the prepared statement is using a full table scan rather than
@@ -5802,20 +5693,21 @@ SQLITE_API int sqlite3_db_status(sqlite3
 ** is an integer code for a specific [SQLITE_STMTSTATUS_SORT | counter]
 ** to be interrogated.)^
 ** ^The current value of the requested counter is returned.
 ** ^If the resetFlg is true, then the counter is reset to zero after this
 ** interface call returns.
 **
 ** See also: [sqlite3_status()] and [sqlite3_db_status()].
 */
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
 
 /*
 ** CAPI3REF: Status Parameters for prepared statements
+** EXPERIMENTAL
 **
 ** These preprocessor macros define integer codes that name counter
 ** values associated with the [sqlite3_stmt_status()] interface.
 ** The meanings of the various counters are as follows:
 **
 ** <dl>
 ** <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
 ** <dd>^This is the number of times that SQLite has stepped forward in
@@ -5823,45 +5715,39 @@ SQLITE_API int sqlite3_stmt_status(sqlit
 ** may indicate opportunities for performance improvement through 
 ** careful use of indices.</dd>
 **
 ** <dt>SQLITE_STMTSTATUS_SORT</dt>
 ** <dd>^This is the number of sort operations that have occurred.
 ** A non-zero value in this counter may indicate an opportunity to
 ** improvement performance through careful use of indices.</dd>
 **
-** <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
+** EXPERIMENTAL
 **
 ** 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.
 */
 typedef struct sqlite3_pcache sqlite3_pcache;
 
 /*
 ** CAPI3REF: Application Defined Page Cache.
 ** KEYWORDS: {page cache}
+** EXPERIMENTAL
 **
 ** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
 ** register an alternative page cache implementation by passing in an 
 ** instance of the sqlite3_pcache_methods structure.)^ The majority of the 
 ** heap memory used by SQLite is used by the page cache to cache data read 
 ** from, or ready to be written to, the database file. By implementing a 
 ** custom page cache using this API, an application can control more 
 ** precisely the amount of memory consumed by SQLite, the way in which 
@@ -5993,28 +5879,30 @@ struct sqlite3_pcache_methods {
   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
+** EXPERIMENTAL
 **
 ** 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()].
 **
 ** See Also: [Using the SQLite Online Backup API]
 */
 typedef struct sqlite3_backup sqlite3_backup;
 
 /*
 ** CAPI3REF: Online Backup API.
+** EXPERIMENTAL
 **
 ** The backup API copies the content of one database into another.
 ** It is useful either for creating backups of databases or
 ** for copying in-memory databases to or from persistent files. 
 **
 ** See Also: [Using the SQLite Online Backup API]
 **
 ** ^Exclusive access is required to the destination database for the 
@@ -6073,24 +5961,20 @@ typedef struct sqlite3_backup sqlite3_ba
 ** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages
 ** from source to destination, then it returns [SQLITE_DONE].
 ** ^If an error occurs while running sqlite3_backup_step(B,N),
 ** then an [error code] is returned. ^As well as [SQLITE_OK] and
 ** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
 ** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
 ** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
 **
-** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if
-** <ol>
-** <li> the destination database was opened read-only, or
-** <li> the destination database is using write-ahead-log journaling
-** and the destination and source page sizes differ, or
-** <li> The destination database is an in-memory database and the
-** destination and source page sizes differ.
-** </ol>)^
+** ^The sqlite3_backup_step() might return [SQLITE_READONLY] if the destination
+** database was opened read-only or if
+** the destination is an in-memory database with a different page size
+** from the source database.
 **
 ** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
 ** the [sqlite3_busy_handler | busy-handler function]
 ** is invoked (if one is specified). ^If the 
 ** busy-handler returns non-zero before the lock is available, then 
 ** [SQLITE_BUSY] is returned to the caller. ^In this case the call to
 ** sqlite3_backup_step() can be retried later. ^If the source
 ** [database connection]
@@ -6196,16 +6080,17 @@ SQLITE_API sqlite3_backup *sqlite3_backu
 );
 SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
 SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
 SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
 SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
 
 /*
 ** CAPI3REF: Unlock Notification
+** EXPERIMENTAL
 **
 ** ^When running in shared-cache mode, a database operation may fail with
 ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
 ** individual tables within the shared-cache cannot be obtained. See
 ** [SQLite Shared-Cache Mode] for a description of shared-cache locking. 
 ** ^This API may be used to register a callback that SQLite will invoke 
 ** when the connection currently holding the required lock relinquishes it.
 ** ^This API is only available if the library was compiled with the
@@ -6317,31 +6202,33 @@ SQLITE_API int sqlite3_unlock_notify(
   sqlite3 *pBlocked,                          /* Waiting connection */
   void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
   void *pNotifyArg                            /* Argument to pass to xNotify */
 );
 
 
 /*
 ** CAPI3REF: String Comparison
+** EXPERIMENTAL
 **
 ** ^The [sqlite3_strnicmp()] API allows applications and extensions to
 ** compare the contents of two buffers containing UTF-8 strings in a
 ** case-indendent fashion, using the same definition of case independence 
 ** that SQLite uses internally when comparing identifiers.
 */
 SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
 
 /*
 ** CAPI3REF: Error Logging Interface
+** EXPERIMENTAL
 **
 ** ^The [sqlite3_log()] interface writes a message into the error log
 ** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()].
 ** ^If logging is enabled, the zFormat string and subsequent arguments are
-** used with [sqlite3_snprintf()] to generate the final output string.
+** passed through to [sqlite3_vmprintf()] to generate the final output string.
 **
 ** The sqlite3_log() interface is intended for use by extensions such as
 ** virtual tables, collating functions, and SQL functions.  While there is
 ** nothing to prevent an application from calling sqlite3_log(), doing so
 ** is considered bad form.
 **
 ** The zFormat string must not be NULL.
 **
@@ -6349,99 +6236,16 @@ SQLITE_API int sqlite3_strnicmp(const ch
 ** will not use dynamically allocated memory.  The log message is stored in
 ** a fixed-length buffer on the stack.  If the log message is longer than
 ** a few hundred characters, it will be truncated to the length of the
 ** buffer.
 */
 SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
 
 /*
-** CAPI3REF: Write-Ahead Log Commit Hook
-**
-** ^The [sqlite3_wal_hook()] function is used to register a callback that
-** will be invoked each time a database connection commits data to a
-** [write-ahead log] (i.e. whenever a transaction is committed in
-** [journal_mode | journal_mode=WAL mode]). 
-**
-** ^The callback is invoked by SQLite after the commit has taken place and 
-** the associated write-lock on the database released, so the implementation 
-** may read, write or [checkpoint] the database as required.
-**
-** ^The first parameter passed to the callback function when it is invoked
-** is a copy of the third parameter passed to sqlite3_wal_hook() when
-** registering the callback. ^The second is a copy of the database handle.
-** ^The third parameter is the name of the database that was written to -
-** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
-** is the number of pages currently in the write-ahead log file,
-** including those that were just committed.
-**
-** The callback function should normally return [SQLITE_OK].  ^If an error
-** code is returned, that error will propagate back up through the
-** SQLite code base to cause the statement that provoked the callback
-** to report an error, though the commit will have still occurred. If the
-** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
-** that does not correspond to any valid SQLite error code, the results
-** are undefined.
-**
-** A single database handle may have at most a single write-ahead log callback 
-** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
-** previously registered write-ahead log callback. ^Note that the
-** [sqlite3_wal_autocheckpoint()] interface and the
-** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
-** those overwrite any prior [sqlite3_wal_hook()] settings.
-*/
-SQLITE_API void *sqlite3_wal_hook(
-  sqlite3*, 
-  int(*)(void *,sqlite3*,const char*,int),
-  void*
-);
-
-/*
-** CAPI3REF: Configure an auto-checkpoint
-**
-** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
-** [sqlite3_wal_hook()] that causes any database on [database connection] D
-** to automatically [checkpoint]
-** after committing a transaction if there are N or
-** more frames in the [write-ahead log] file.  ^Passing zero or 
-** a negative value as the nFrame parameter disables automatic
-** checkpoints entirely.
-**
-** ^The callback registered by this function replaces any existing callback
-** registered using [sqlite3_wal_hook()].  ^Likewise, registering a callback
-** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
-** configured by this function.
-**
-** ^The [wal_autocheckpoint pragma] can be used to invoke this interface
-** from SQL.
-**
-** ^Every new [database connection] defaults to having the auto-checkpoint
-** enabled with a threshold of 1000 pages.  The use of this interface
-** is only necessary if the default setting is found to be suboptimal
-** for a particular application.
-*/
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
-
-/*
-** CAPI3REF: Checkpoint a database
-**
-** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X
-** on [database connection] D to be [checkpointed].  ^If X is NULL or an
-** empty string, then a checkpoint is run on all databases of
-** connection D.  ^If the database connection D is not in
-** [WAL | write-ahead log mode] then this interface is a harmless no-op.
-**
-** ^The [wal_checkpoint pragma] can be used to invoke this interface
-** from SQL.  ^The [sqlite3_wal_autocheckpoint()] interface and the
-** [wal_autocheckpoint pragma] can be used to cause this interface to be
-** run whenever the WAL reaches a certain size threshold.
-*/
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
-
-/*
 ** Undo the hack that converts floating point types to integer for
 ** builds on processors without floating point support.
 */
 #ifdef SQLITE_OMIT_FLOATING_POINT
 # undef double
 #endif
 
 #if 0
@@ -6722,17 +6526,16 @@ SQLITE_PRIVATE void sqlite3HashClear(Has
 #include <stddef.h>
 
 /*
 ** If compiling for a processor that lacks floating point support,
 ** substitute integer for floating-point
 */
 #ifdef SQLITE_OMIT_FLOATING_POINT
 # define double sqlite_int64
-# define float sqlite_int64
 # define LONGDOUBLE_TYPE sqlite_int64
 # ifndef SQLITE_BIG_DBL
 #   define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
 # endif
 # define SQLITE_OMIT_DATETIME_FUNCS 1
 # define SQLITE_OMIT_TRACE 1
 # undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
 # undef SQLITE_HAVE_ISNAN
@@ -7134,17 +6937,16 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
 
 SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
 SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
 SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
-SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
 SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
 SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
 SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
@@ -7239,18 +7041,16 @@ SQLITE_PRIVATE sqlite3_int64 sqlite3Btre
 
 SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
 SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
 
 SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
 SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *);
 SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
 
-SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
-
 #ifndef NDEBUG
 SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
 #endif
 
 #ifndef SQLITE_OMIT_BTREECOUNT
 SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *);
 #endif
 
@@ -7531,93 +7331,93 @@ typedef struct VdbeOpList VdbeOpList;
 #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_Trace                              135
-#define OP_Noop                               136
-#define OP_Explain                            137
+#define OP_OpenEphemeral                       40
+#define OP_OpenPseudo                          41
+#define OP_Close                               42
+#define OP_SeekLt                              43
+#define OP_SeekLe                              44
+#define OP_SeekGe                              45
+#define OP_SeekGt                              46
+#define OP_Seek                                47
+#define OP_NotFound                            48
+#define OP_Found                               49
+#define OP_IsUnique                            50
+#define OP_NotExists                           51
+#define OP_Sequence                            52
+#define OP_NewRowid                            53
+#define OP_Insert                              54
+#define OP_InsertInt                           55
+#define OP_Delete                              56
+#define OP_ResetCount                          57
+#define OP_RowKey                              58
+#define OP_RowData                             59
+#define OP_Rowid                               60
+#define OP_NullRow                             61
+#define OP_Last                                62
+#define OP_Sort                                63
+#define OP_Rewind                              64
+#define OP_Prev                                65
+#define OP_Next                                66
+#define OP_IdxInsert                           67
+#define OP_IdxDelete                           70
+#define OP_IdxRowid                            71
+#define OP_IdxLT                               72
+#define OP_IdxGE                               81
+#define OP_Destroy                             92
+#define OP_Clear                               95
+#define OP_CreateIndex                         96
+#define OP_CreateTable                         97
+#define OP_ParseSchema                         98
+#define OP_LoadAnalysis                        99
+#define OP_DropTable                          100
+#define OP_DropIndex                          101
+#define OP_DropTrigger                        102
+#define OP_IntegrityCk                        103
+#define OP_RowSetAdd                          104
+#define OP_RowSetRead                         105
+#define OP_RowSetTest                         106
+#define OP_Program                            107
+#define OP_Param                              108
+#define OP_FkCounter                          109
+#define OP_FkIfZero                           110
+#define OP_MemMax                             111
+#define OP_IfPos                              112
+#define OP_IfNeg                              113
+#define OP_IfZero                             114
+#define OP_AggStep                            115
+#define OP_AggFinal                           116
+#define OP_Vacuum                             117
+#define OP_IncrVacuum                         118
+#define OP_Expire                             119
+#define OP_TableLock                          120
+#define OP_VBegin                             121
+#define OP_VCreate                            122
+#define OP_VDestroy                           123
+#define OP_VOpen                              124
+#define OP_VFilter                            125
+#define OP_VColumn                            126
+#define OP_VNext                              127
+#define OP_VRename                            128
+#define OP_VUpdate                            129
+#define OP_Pagecount                          131
+#define OP_Trace                              132
+#define OP_Noop                               133
+#define OP_Explain                            134
 
 /* The following opcode values are never used */
+#define OP_NotUsed_135                        135
+#define OP_NotUsed_136                        136
+#define OP_NotUsed_137                        137
 #define OP_NotUsed_138                        138
 #define OP_NotUsed_139                        139
 #define OP_NotUsed_140                        140
 
 
 /* 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:
@@ -7626,32 +7426,32 @@ typedef struct VdbeOpList VdbeOpList;
 #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,\
-/*   8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x24, 0x24,\
+/*   8 */ 0x02, 0x02, 0x02, 0x02, 0x00, 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,\
+/*  40 */ 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x08,\
+/*  48 */ 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x00, 0x00,\
+/*  56 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01,\
+/*  64 */ 0x01, 0x01, 0x01, 0x08, 0x4c, 0x4c, 0x00, 0x02,\
+/*  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, 0x00,\
+/*  88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x02, 0x24, 0x02, 0x00,\
+/*  96 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 104 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\
+/* 112 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00,\
+/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,\
+/* 128 */ 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,\
 /* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,\
 /* 144 */ 0x04, 0x04,}
 
 /************** End of opcodes.h *********************************************/
 /************** Continuing where we left off in vdbe.h ***********************/
 
 /*
 ** Prototypes for the VDBE interface.  See comments on the implementation
@@ -7787,25 +7587,24 @@ typedef struct PgHdr DbPage;
 /*
 ** Valid values for the second argument to sqlite3PagerLockingMode().
 */
 #define PAGER_LOCKINGMODE_QUERY      -1
 #define PAGER_LOCKINGMODE_NORMAL      0
 #define PAGER_LOCKINGMODE_EXCLUSIVE   1
 
 /*
-** Numeric constants that encode the journalmode.  
-*/
-#define PAGER_JOURNALMODE_QUERY     (-1)  /* Query the value of journalmode */
+** Valid values for the second argument to sqlite3PagerJournalMode().
+*/
+#define PAGER_JOURNALMODE_QUERY      -1
 #define PAGER_JOURNALMODE_DELETE      0   /* Commit by deleting journal file */
 #define PAGER_JOURNALMODE_PERSIST     1   /* Commit by zeroing journal header */
 #define PAGER_JOURNALMODE_OFF         2   /* Journal omitted.  */
 #define PAGER_JOURNALMODE_TRUNCATE    3   /* Commit by truncating journal */
 #define PAGER_JOURNALMODE_MEMORY      4   /* In-memory journal file */
-#define PAGER_JOURNALMODE_WAL         5   /* Use write-ahead logging */
 
 /*
 ** The remainder of this file contains the declarations of the functions
 ** that make up the Pager sub-system API. See source code comments for 
 ** a detailed description of each routine.
 */
 
 /* Open and close a Pager connection. */ 
@@ -7823,19 +7622,17 @@ SQLITE_PRIVATE int sqlite3PagerReadFileh
 
 /* Functions used to configure a Pager object. */
 SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
 SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u16*, int);
 SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
 SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
 SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int);
 SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
-SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int);
-SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*);
-SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*);
+SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *, int);
 SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
 SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
 
 /* Functions used to obtain and release page references. */ 
 SQLITE_PRIVATE int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
 #define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0)
 SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
 SQLITE_PRIVATE void sqlite3PagerRef(DbPage*);
@@ -7855,41 +7652,30 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pag
 SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
 SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager);
 SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*);
 SQLITE_PRIVATE int sqlite3PagerRollback(Pager*);
 SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
 SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
 SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
 
-SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager);
-
 /* Functions used to query pager state and configuration. */
 SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
 SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
-SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
 SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*);
 SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
 SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
 SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
 SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
 SQLITE_PRIVATE int sqlite3PagerIsMemdb(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
-
 /* Functions to support testing and debugging. */
 #if !defined(NDEBUG) || defined(SQLITE_TEST)
 SQLITE_PRIVATE   Pgno sqlite3PagerPagenumber(DbPage*);
 SQLITE_PRIVATE   int sqlite3PagerIswriteable(DbPage*);
 #endif
 #ifdef SQLITE_TEST
 SQLITE_PRIVATE   int *sqlite3PagerStats(Pager*);
 SQLITE_PRIVATE   void sqlite3PagerRefdump(Pager*);
@@ -8281,21 +8067,17 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefa
 **
 ** Changing the value of PENDING_BYTE results in a subtly incompatible
 ** file format.  Depending on how it is changed, you might not notice
 ** the incompatibility right away, even running a full regression test.
 ** The default location of PENDING_BYTE is the first byte past the
 ** 1GB boundary.
 **
 */
-#ifdef SQLITE_OMIT_WSD
-# define PENDING_BYTE     (0x40000000)
-#else
-# define PENDING_BYTE      sqlite3PendingByte
-#endif
+#define PENDING_BYTE      sqlite3PendingByte
 #define RESERVED_BYTE     (PENDING_BYTE+1)
 #define SHARED_FIRST      (PENDING_BYTE+2)
 #define SHARED_SIZE       510
 
 /*
 ** Wrapper around OS specific sqlite3_os_init() function.
 */
 SQLITE_PRIVATE int sqlite3OsInit(void);
@@ -8311,37 +8093,33 @@ SQLITE_PRIVATE int sqlite3OsSync(sqlite3
 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*);
 #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
 SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *);
 SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *);
 SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void);
 SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *);
 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
 SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
 SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int);
-SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*);
+SQLITE_PRIVATE int sqlite3OsCurrentTime(sqlite3_vfs *, double*);
 
 /*
 ** Convenience functions for opening and closing files using 
 ** sqlite3_malloc() to obtain space for the file-handle structure.
 */
 SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*);
 SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
 
@@ -8575,16 +8353,17 @@ struct sqlite3 {
   int flags;                    /* Miscellaneous flags. See below */
   int openFlags;                /* Flags passed to sqlite3_vfs.xOpen() */
   int errCode;                  /* Most recent error code (SQLITE_*) */
   int errMask;                  /* & result codes with this before returning */
   u8 autoCommit;                /* The auto-commit flag. */
   u8 temp_store;                /* 1: file 2: memory 0: default */
   u8 mallocFailed;              /* True if we have seen a malloc failure */
   u8 dfltLockMode;              /* Default locking-mode for attached dbs */
+  u8 dfltJournalMode;           /* Default journal mode for attached dbs */
   signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
   u8 suppressErr;               /* Do not issue error messages if true */
   int nextPagesize;             /* Pagesize after VACUUM if >0 */
   int nTable;                   /* Number of tables in the database */
   CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
   i64 lastRowid;                /* ROWID of most recent insert (see above) */
   u32 magic;                    /* Magic number for detect library misuse */
   int nChange;                  /* Value returned by sqlite3_changes() */
@@ -8607,20 +8386,16 @@ struct sqlite3 {
   void (*xProfile)(void*,const char*,u64);  /* Profiling function */
   void *pProfileArg;                        /* Argument to profile function */
   void *pCommitArg;                 /* Argument to xCommitCallback() */   
   int (*xCommitCallback)(void*);    /* Invoked at every commit. */
   void *pRollbackArg;               /* Argument to xRollbackCallback() */   
   void (*xRollbackCallback)(void*); /* Invoked at every commit. */
   void *pUpdateArg;
   void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
-#ifndef SQLITE_OMIT_WAL
-  int (*xWalCallback)(void *, sqlite3 *, const char *, int);
-  void *pWalArg;
-#endif
   void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
   void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
   void *pCollNeededArg;
   sqlite3_value *pErr;          /* Most recent error message */
   char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */
   char *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */
   union {
     volatile int isInterrupted; /* True if sqlite3_interrupt has been called */
@@ -8700,31 +8475,28 @@ struct sqlite3 {
 #define SQLITE_ReadUncommitted 0x0080000  /* For shared-cache mode */
 #define SQLITE_LegacyFileFmt  0x00100000  /* Create new databases in format 1 */
 #define SQLITE_FullFSync      0x00200000  /* Use full fsync on the backend */
 #define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
 #define SQLITE_RecoveryMode   0x00800000  /* Ignore schema errors */
 #define SQLITE_ReverseOrder   0x01000000  /* Reverse unordered SELECTs */
 #define SQLITE_RecTriggers    0x02000000  /* Enable recursive triggers */
 #define SQLITE_ForeignKeys    0x04000000  /* Enforce foreign key constraints  */
-#define SQLITE_AutoIndex      0x08000000  /* Enable automatic indexes */
-#define SQLITE_PreferBuiltin  0x10000000  /* Preference to built-in funcs */
 
 /*
 ** Bits of the sqlite3.flags field that are used by the
 ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface.
 ** These must be the low-order bits of the flags field.
 */
 #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_OptMask        0xff        /* Mask of all disablable opts */
+#define SQLITE_OptMask        0x1f        /* 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 */
 #define SQLITE_MAGIC_CLOSED   0x9f3c2d33  /* Database is closed */
@@ -9565,19 +9337,16 @@ typedef u64 Bitmask;
 ** is modified by an INSERT, DELETE, or UPDATE statement.  In standard SQL,
 ** such a table must be a simple name: ID.  But in SQLite, the table can
 ** now be identified by a database name, a dot, then the table name: ID.ID.
 **
 ** The jointype starts out showing the join type between the current table
 ** and the next table on the list.  The parser builds the list this way.
 ** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each
 ** jointype expresses the join between the table and the previous table.
-**
-** In the colUsed field, the high-order bit (bit 63) is set if the table
-** contains more than 63 columns and the 64-th or later column is used.
 */
 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" */
@@ -9679,17 +9448,17 @@ 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_OPEN        0x0010 /* Table cursor 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 */
 
 /*
 ** 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
@@ -9702,17 +9471,16 @@ struct WhereInfo {
   u8 okOnePass;        /* Ok to use one-pass algorithm for UPDATE or DELETE */
   u8 untestedTerms;    /* Not all WHERE terms resolved by outer loop */
   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 */
   WhereLevel a[1];               /* Information about each nest loop in WHERE */
 };
 
 /*
 ** 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
@@ -9944,17 +9712,16 @@ struct Parse {
   /* Information used while coding trigger programs. */
   Parse *pToplevel;    /* Parse structure for main program (or NULL) */
   Table *pTriggerTab;  /* Table triggers are being coded for */
   u32 oldmask;         /* Mask of old.* columns referenced */
   u32 newmask;         /* Mask of new.* columns referenced */
   u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
   u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
   u8 disableTriggers;  /* True to disable triggers */
-  double nQueryLoop;   /* Estimated number of iterations of a query */
 
   /* Above is constant between recursions.  Below is reset before and after
   ** each recursion */
 
   int nVar;            /* Number of '?' variables seen in the SQL so far */
   int nVarExpr;        /* Number of used slots in apVarExpr[] */
   int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
   Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */
@@ -10320,18 +10087,17 @@ SQLITE_PRIVATE int sqlite3MemoryAlarm(vo
 SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
 #endif
 #ifdef SQLITE_ENABLE_MEMSYS5
 SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
 #endif
 
 
 #ifndef SQLITE_MUTEX_OMIT
-SQLITE_PRIVATE   sqlite3_mutex_methods const *sqlite3DefaultMutex(void);
-SQLITE_PRIVATE   sqlite3_mutex_methods const *sqlite3NoopMutex(void);
+SQLITE_PRIVATE   sqlite3_mutex_methods *sqlite3DefaultMutex(void);
 SQLITE_PRIVATE   sqlite3_mutex *sqlite3MutexAlloc(int);
 SQLITE_PRIVATE   int sqlite3MutexInit(void);
 SQLITE_PRIVATE   int sqlite3MutexEnd(void);
 #endif
 
 SQLITE_PRIVATE int sqlite3StatusValue(int);
 SQLITE_PRIVATE void sqlite3StatusAdd(int, int);
 SQLITE_PRIVATE void sqlite3StatusSet(int, int);
@@ -10453,17 +10219,16 @@ SQLITE_PRIVATE void sqlite3OpenTable(Par
 #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 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);
 SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int);
 SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
 SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
@@ -10480,17 +10245,16 @@ SQLITE_PRIVATE Table *sqlite3FindTable(s
 SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
 SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
 SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
 SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
 SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
 SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
-SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*);
 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
 SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
 SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
 SQLITE_PRIVATE void sqlite3PrngResetState(void);
 SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*);
 SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
@@ -10668,26 +10432,23 @@ SQLITE_PRIVATE char *sqlite3Utf16to8(sql
 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[];
-SQLITE_PRIVATE const Token sqlite3IntTokens[];
 SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config;
 SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
-#ifndef SQLITE_OMIT_WSD
 SQLITE_PRIVATE int sqlite3PendingByte;
 #endif
-#endif
 SQLITE_PRIVATE void sqlite3RootPageMoved(Db*, int, int);
 SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
-SQLITE_PRIVATE void sqlite3AlterFunctions(void);
+SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3*);
 SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
 SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
 SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
@@ -10786,19 +10547,16 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverl
 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);
-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
 ** this case foreign keys are parsed, but no other functionality is 
 ** provided (enforcement of FK constraints requires the triggers sub-system).
 */
@@ -10895,56 +10653,17 @@ SQLITE_PRIVATE   void sqlite3ParserTrace
 # define IOTRACE(A)  if( sqlite3IoTrace ){ sqlite3IoTrace A; }
 SQLITE_PRIVATE   void sqlite3VdbeIOTraceSql(Vdbe*);
 SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...);
 #else
 # define IOTRACE(A)
 # define sqlite3VdbeIOTraceSql(X)
 #endif
 
-/*
-** These routines are available for the mem2.c debugging memory allocator
-** only.  They are used to verify that different "types" of memory
-** allocations are properly tracked by the system.
-**
-** sqlite3MemdebugSetType() sets the "type" of an allocation to one of
-** the MEMTYPE_* macros defined below.  The type must be a bitmask with
-** a single bit set.
-**
-** sqlite3MemdebugHasType() returns true if any of the bits in its second
-** argument match the type set by the previous sqlite3MemdebugSetType().
-** sqlite3MemdebugHasType() is intended for use inside assert() statements.
-** For example:
-**
-**     assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
-**
-** Perhaps the most important point is the difference between MEMTYPE_HEAP
-** and MEMTYPE_DB.  If an allocation is MEMTYPE_DB, that means it might have
-** been allocated by lookaside, except the allocation was too large or
-** lookaside was already full.  It is important to verify that allocations
-** that might have been satisfied by lookaside are not passed back to 
-** non-lookaside free() routines.  Asserts such as the example above are
-** placed on the non-lookaside free() routines to verify this constraint. 
-**
-** All of this is no-op for a production build.  It only comes into
-** play when the SQLITE_MEMDEBUG compile-time option is used.
-*/
-#ifdef SQLITE_MEMDEBUG
-SQLITE_PRIVATE   void sqlite3MemdebugSetType(void*,u8);
-SQLITE_PRIVATE   int sqlite3MemdebugHasType(void*,u8);
-#else
-# define sqlite3MemdebugSetType(X,Y)  /* no-op */
-# define sqlite3MemdebugHasType(X,Y)  1
-#endif
-#define MEMTYPE_HEAP     0x01    /* General heap allocations */
-#define MEMTYPE_DB       0x02    /* Associated with a database connection */
-#define MEMTYPE_SCRATCH  0x04    /* Scratch allocations */
-#define MEMTYPE_PCACHE   0x08    /* Page cache allocations */
-
-#endif /* _SQLITEINT_H_ */
+#endif
 
 /************** End of sqliteInt.h *******************************************/
 /************** Begin file global.c ******************************************/
 /*
 ** 2008 June 13
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
@@ -11116,25 +10835,16 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3
 /*
 ** Hash table for global functions - functions common to all
 ** database connections.  After initialization, this table is
 ** read-only.
 */
 SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
 
 /*
-** Constant tokens for values 0 and 1.
-*/
-SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
-   { "0", 1 },
-   { "1", 1 }
-};
-
-
-/*
 ** The value of the "pending" byte must be 0x40000000 (1 byte past the
 ** 1-gibabyte boundary) in a compatible database.  SQLite never uses
 ** the database page that contains the pending byte.  It never attempts
 ** to read or write that page.  The pending byte page is set assign
 ** for use by the VFS layers as space for managing file locks.
 **
 ** During testing, it is often desirable to move the pending byte to
 ** a different position in the file.  This allows code that has to
@@ -11142,19 +10852,17 @@ SQLITE_PRIVATE const Token sqlite3IntTok
 ** than 1 GiB.  The sqlite3_test_control() interface can be used to
 ** move the pending byte.
 **
 ** IMPORTANT:  Changing the pending byte to any value other than
 ** 0x40000000 results in an incompatible database file format!
 ** Changing the pending byte during operating results in undefined
 ** and dileterious behavior.
 */
-#ifndef SQLITE_OMIT_WSD
 SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
-#endif
 
 /*
 ** Properties of opcodes.  The OPFLG_INITIALIZER macro is
 ** created by mkopcodeh.awk during compilation.  Data is obtained
 ** from the comments following the "case OP_xxxx:" statements in
 ** the vdbe.c file.  
 */
 SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
@@ -11328,19 +11036,16 @@ static const char * const azCompileOpt[]
   "OMIT_AUTHORIZATION",
 #endif
 #ifdef SQLITE_OMIT_AUTOINCREMENT
   "OMIT_AUTOINCREMENT",
 #endif
 #ifdef SQLITE_OMIT_AUTOINIT
   "OMIT_AUTOINIT",
 #endif
-#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
-  "OMIT_AUTOMATIC_INDEX",
-#endif
 #ifdef SQLITE_OMIT_AUTOVACUUM
   "OMIT_AUTOVACUUM",
 #endif
 #ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
   "OMIT_BETWEEN_OPTIMIZATION",
 #endif
 #ifdef SQLITE_OMIT_BLOB_LITERAL
   "OMIT_BLOB_LITERAL",
@@ -11352,21 +11057,19 @@ static const char * const azCompileOpt[]
   "OMIT_BUILTIN_TEST",
 #endif
 #ifdef SQLITE_OMIT_CAST
   "OMIT_CAST",
 #endif
 #ifdef SQLITE_OMIT_CHECK
   "OMIT_CHECK",
 #endif
-/* // redundant
-** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS
-**   "OMIT_COMPILEOPTION_DIAGS",
-** #endif
-*/
+#ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS
+  "OMIT_COMPILEOPTION_DIAGS",
+#endif
 #ifdef SQLITE_OMIT_COMPLETE
   "OMIT_COMPLETE",
 #endif
 #ifdef SQLITE_OMIT_COMPOUND_SELECT
   "OMIT_COMPOUND_SELECT",
 #endif
 #ifdef SQLITE_OMIT_DATETIME_FUNCS
   "OMIT_DATETIME_FUNCS",
@@ -11390,16 +11093,19 @@ static const char * const azCompileOpt[]
   "OMIT_FLOATING_POINT",
 #endif
 #ifdef SQLITE_OMIT_FOREIGN_KEY
   "OMIT_FOREIGN_KEY",
 #endif
 #ifdef SQLITE_OMIT_GET_TABLE
   "OMIT_GET_TABLE",
 #endif
+#ifdef SQLITE_OMIT_GLOBALRECOVER
+  "OMIT_GLOBALRECOVER",
+#endif
 #ifdef SQLITE_OMIT_INCRBLOB
   "OMIT_INCRBLOB",
 #endif
 #ifdef SQLITE_OMIT_INTEGRITY_CHECK
   "OMIT_INTEGRITY_CHECK",
 #endif
 #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
   "OMIT_LIKE_OPTIMIZATION",
@@ -11468,19 +11174,16 @@ static const char * const azCompileOpt[]
   "OMIT_VACUUM",
 #endif
 #ifdef SQLITE_OMIT_VIEW
   "OMIT_VIEW",
 #endif
 #ifdef SQLITE_OMIT_VIRTUALTABLE
   "OMIT_VIRTUALTABLE",
 #endif
-#ifdef SQLITE_OMIT_WAL
-  "OMIT_WAL",
-#endif
 #ifdef SQLITE_OMIT_WSD
   "OMIT_WSD",
 #endif
 #ifdef SQLITE_OMIT_XFER_OPT
   "OMIT_XFER_OPT",
 #endif
 #ifdef SQLITE_PERFORMANCE_TRACE
   "PERFORMANCE_TRACE",
@@ -11661,36 +11364,16 @@ SQLITE_API int sqlite3_db_status(
     case SQLITE_DBSTATUS_LOOKASIDE_USED: {
       *pCurrent = db->lookaside.nOut;
       *pHighwater = db->lookaside.mxOut;
       if( resetFlag ){
         db->lookaside.mxOut = db->lookaside.nOut;
       }
       break;
     }
-
-    /* 
-    ** Return an approximation for the amount of memory currently used
-    ** by all pagers associated with the given database connection.  The
-    ** highwater mark is meaningless and is returned as zero.
-    */
-    case SQLITE_DBSTATUS_CACHE_USED: {
-      int totalUsed = 0;
-      int i;
-      for(i=0; i<db->nDb; i++){
-        Btree *pBt = db->aDb[i].pBt;
-        if( pBt ){
-          Pager *pPager = sqlite3BtreePager(pBt);
-          totalUsed += sqlite3PagerMemUsed(pPager);
-        }
-      }
-      *pCurrent = totalUsed;
-      *pHighwater = 0;
-      break;
-    }
     default: {
       return SQLITE_ERROR;
     }
   }
   return SQLITE_OK;
 }
 
 /************** End of status.c **********************************************/
@@ -12003,18 +11686,20 @@ static int parseYyyyMmDd(const char *zDa
   }
   return 0;
 }
 
 /*
 ** Set the time to the current time reported by the VFS
 */
 static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
+  double r;
   sqlite3 *db = sqlite3_context_db_handle(context);
-  sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD);
+  sqlite3OsCurrentTime(db->pVfs, &r);
+  p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
   p->validJD = 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:
@@ -12725,25 +12410,32 @@ static void ctimestampFunc(
 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;
+  double rT;
   char zBuf[20];
 
   UNUSED_PARAMETER(argc);
   UNUSED_PARAMETER(argv);
 
   db = sqlite3_context_db_handle(context);
-  sqlite3OsCurrentTimeInt64(db->pVfs, &iT);
-  t = iT/1000 - 10000*(sqlite3_int64)21086676;
+  sqlite3OsCurrentTime(db->pVfs, &rT);
+#ifndef SQLITE_OMIT_FLOATING_POINT
+  t = 86400.0*(rT - 2440587.5) + 0.5;
+#else
+  /* without floating point support, rT will have
+  ** already lost fractional day precision.
+  */
+  t = 86400 * (rT - 2440587) - 43200;
+#endif
 #ifdef HAVE_GMTIME_R
   {
     struct tm sNow;
     gmtime_r(&t, &sNow);
     strftime(zBuf, 20, zFormat, &sNow);
   }
 #else
   {
@@ -12822,20 +12514,18 @@ SQLITE_PRIVATE void sqlite3RegisterDateT
 **
 **     sqlite3OsOpen()
 **     sqlite3OsRead()
 **     sqlite3OsWrite()
 **     sqlite3OsSync()
 **     sqlite3OsLock()
 **
 */
-#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))) {  \
+#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
+  #define DO_OS_MALLOC_TEST(x) if (!x || !sqlite3IsMemJournal(x)) {     \
     void *pTstAlloc = sqlite3Malloc(10);                             \
     if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
     sqlite3_free(pTstAlloc);                                         \
   }
 #else
   #define DO_OS_MALLOC_TEST(x)
 #endif
 
@@ -12888,53 +12578,35 @@ SQLITE_PRIVATE int sqlite3OsFileControl(
 }
 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){
-  return id->pMethods->xShmLock(id, offset, n, flags);
-}
-SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){
-  id->pMethods->xShmBarrier(id);
-}
-SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
-  return id->pMethods->xShmUnmap(id, deleteFlag);
-}
-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 */
-){
-  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
+  /* 0x7f3f 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 & 0x7f3f, pFlagsOut);
   assert( rc==SQLITE_OK || pFile->pMethods==0 );
   return rc;
 }
 SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   return pVfs->xDelete(pVfs, zPath, dirSync);
 }
 SQLITE_PRIVATE int sqlite3OsAccess(
   sqlite3_vfs *pVfs, 
@@ -12969,26 +12641,18 @@ SQLITE_PRIVATE void sqlite3OsDlClose(sql
 }
 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
 SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
   return pVfs->xRandomness(pVfs, nByte, zBufOut);
 }
 SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
   return pVfs->xSleep(pVfs, nMicro);
 }
-SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
-  int rc;
-  if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
-    rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
-  }else{
-    double r;
-    rc = pVfs->xCurrentTime(pVfs, &r);
-    *pTimeOut = (sqlite3_int64)(r*86400000.0);
-  }
-  return rc;
+SQLITE_PRIVATE int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
+  return pVfs->xCurrentTime(pVfs, pTimeOut);
 }
 
 SQLITE_PRIVATE int sqlite3OsOpenMalloc(
   sqlite3_vfs *pVfs, 
   const char *zFile, 
   sqlite3_file **ppFile, 
   int flags,
   int *pOutFlags
@@ -13473,18 +13137,17 @@ SQLITE_PRIVATE void sqlite3MemSetDefault
 ** backtrace pointers.  There is also a guard word at the end of the
 ** MemBlockHdr.
 */
 struct MemBlockHdr {
   i64 iSize;                          /* Size of this allocation */
   struct MemBlockHdr *pNext, *pPrev;  /* Linked list of all unfreed memory */
   char nBacktrace;                    /* Number of backtraces on this alloc */
   char nBacktraceSlots;               /* Available backtrace slots */
-  u8 nTitle;                          /* Bytes of title; includes '\0' */
-  u8 eType;                           /* Allocation type code */
+  short nTitle;                       /* Bytes of title; includes '\0' */
   int iForeGuard;                     /* Guard word for sanity */
 };
 
 /*
 ** Guard words
 */
 #define FOREGUARD 0x80F5E153
 #define REARGUARD 0xE4676B53
@@ -13682,17 +13345,16 @@ static void *sqlite3MemMalloc(int nByte)
     pHdr->pPrev = mem.pLast;
     if( mem.pLast ){
       mem.pLast->pNext = pHdr;
     }else{
       mem.pFirst = pHdr;
     }
     mem.pLast = pHdr;
     pHdr->iForeGuard = FOREGUARD;
-    pHdr->eType = MEMTYPE_HEAP;
     pHdr->nBacktraceSlots = mem.nBacktrace;
     pHdr->nTitle = mem.nTitle;
     if( mem.nBacktrace ){
       void *aAddr[40];
       pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
       memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
       assert(pBt[0]);
       if( mem.xBacktrace ){
@@ -13791,57 +13453,16 @@ SQLITE_PRIVATE void sqlite3MemSetDefault
      sqlite3MemInit,
      sqlite3MemShutdown,
      0
   };
   sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
 }
 
 /*
-** Set the "type" of an allocation.
-*/
-SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){
-  if( p ){
-    struct MemBlockHdr *pHdr;
-    pHdr = sqlite3MemsysGetHeader(p);
-    assert( pHdr->iForeGuard==FOREGUARD );
-    pHdr->eType = eType;
-  }
-}
-
-/*
-** Return TRUE if the mask of type in eType matches the type of the
-** allocation p.  Also return true if p==NULL.
-**
-** This routine is designed for use within an assert() statement, to
-** verify the type of an allocation.  For example:
-**
-**     assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
-*/
-SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
-  int rc = 1;
-  if( p ){
-    struct MemBlockHdr *pHdr;
-    pHdr = sqlite3MemsysGetHeader(p);
-    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
-    assert( (pHdr->eType & (pHdr->eType-1))==0 );  /* Only one type bit set */
-    if( (pHdr->eType&eType)==0 ){
-      void **pBt;
-      pBt = (void**)pHdr;
-      pBt -= pHdr->nBacktraceSlots;
-      backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(stderr));
-      fprintf(stderr, "\n");
-      rc = 0;
-    }
-  }
-  return rc;
-}
- 
-
-/*
 ** Set the number of backtrace levels kept for each allocation.
 ** A value of zero turns off backtracing.  The number is always rounded
 ** up to a multiple of 2.
 */
 SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){
   if( depth<0 ){ depth = 0; }
   if( depth>20 ){ depth = 20; }
   depth = (depth+1)&0xfe;
@@ -15232,36 +14853,33 @@ static SQLITE_WSD int mutexIsInit = 0;
 
 
 #ifndef SQLITE_MUTEX_OMIT
 /*
 ** Initialize the mutex system.
 */
 SQLITE_PRIVATE int sqlite3MutexInit(void){ 
   int rc = SQLITE_OK;
-  if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
-    /* If the xMutexAlloc method has not been set, then the user did not
-    ** install a mutex implementation via sqlite3_config() prior to 
-    ** sqlite3_initialize() being called. This block copies pointers to
-    ** the default implementation into the sqlite3GlobalConfig structure.
-    */
-    sqlite3_mutex_methods const *pFrom;
-    sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
-
-    if( sqlite3GlobalConfig.bCoreMutex ){
-      pFrom = sqlite3DefaultMutex();
-    }else{
-      pFrom = sqlite3NoopMutex();
-    }
-    memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
-    memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
-           sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
-    pTo->xMutexAlloc = pFrom->xMutexAlloc;
-  }
-  rc = sqlite3GlobalConfig.mutex.xMutexInit();
+  if( sqlite3GlobalConfig.bCoreMutex ){
+    if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
+      /* If the xMutexAlloc method has not been set, then the user did not
+      ** install a mutex implementation via sqlite3_config() prior to 
+      ** sqlite3_initialize() being called. This block copies pointers to
+      ** the default implementation into the sqlite3GlobalConfig structure.
+      */
+      sqlite3_mutex_methods *pFrom = sqlite3DefaultMutex();
+      sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
+
+      memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
+      memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
+             sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
+      pTo->xMutexAlloc = pFrom->xMutexAlloc;
+    }
+    rc = sqlite3GlobalConfig.mutex.xMutexInit();
+  }
 
 #ifdef SQLITE_DEBUG
   GLOBAL(int, mutexIsInit) = 1;
 #endif
 
   return rc;
 }
 
@@ -15383,98 +15001,91 @@ SQLITE_API int sqlite3_mutex_notheld(sql
 **
 ** interface.
 **
 ** If compiled with SQLITE_DEBUG, then additional logic is inserted
 ** that does error checking on mutexes to make sure they are being
 ** called correctly.
 */
 
-#ifndef SQLITE_MUTEX_OMIT
-
-#ifndef SQLITE_DEBUG
+
+#if defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG)
 /*
 ** Stub routines for all mutex methods.
 **
 ** This routines provide no mutual exclusion or error checking.
 */
+static int noopMutexHeld(sqlite3_mutex *p){ return 1; }
+static int noopMutexNotheld(sqlite3_mutex *p){ return 1; }
 static int noopMutexInit(void){ return SQLITE_OK; }
 static int noopMutexEnd(void){ return SQLITE_OK; }
-static sqlite3_mutex *noopMutexAlloc(int id){ 
-  UNUSED_PARAMETER(id);
-  return (sqlite3_mutex*)8; 
-}
-static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
-static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
-static int noopMutexTry(sqlite3_mutex *p){
-  UNUSED_PARAMETER(p);
-  return SQLITE_OK;
-}
-static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
-
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){
-  static const sqlite3_mutex_methods sMutex = {
+static sqlite3_mutex *noopMutexAlloc(int id){ return (sqlite3_mutex*)8; }
+static void noopMutexFree(sqlite3_mutex *p){ return; }
+static void noopMutexEnter(sqlite3_mutex *p){ return; }
+static int noopMutexTry(sqlite3_mutex *p){ return SQLITE_OK; }
+static void noopMutexLeave(sqlite3_mutex *p){ return; }
+
+SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
+  static sqlite3_mutex_methods sMutex = {
     noopMutexInit,
     noopMutexEnd,
     noopMutexAlloc,
     noopMutexFree,
     noopMutexEnter,
     noopMutexTry,
     noopMutexLeave,
 
-    0,
-    0,
+    noopMutexHeld,
+    noopMutexNotheld
   };
 
   return &sMutex;
 }
-#endif /* !SQLITE_DEBUG */
-
-#ifdef SQLITE_DEBUG
+#endif /* defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG) */
+
+#if defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG)
 /*
 ** In this implementation, error checking is provided for testing
 ** and debugging purposes.  The mutexes still do not provide any
 ** mutual exclusion.
 */
 
 /*
 ** The mutex object
 */
-typedef struct sqlite3_debug_mutex {
+struct sqlite3_mutex {
   int id;     /* The mutex type */
   int cnt;    /* Number of entries without a matching leave */
-} sqlite3_debug_mutex;
+};
 
 /*
 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
 ** intended for use inside assert() statements.
 */
-static int debugMutexHeld(sqlite3_mutex *pX){
-  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
+static int debugMutexHeld(sqlite3_mutex *p){
   return p==0 || p->cnt>0;
 }
-static int debugMutexNotheld(sqlite3_mutex *pX){
-  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
+static int debugMutexNotheld(sqlite3_mutex *p){
   return p==0 || p->cnt==0;
 }
 
 /*
 ** Initialize and deinitialize the mutex subsystem.
 */
 static int debugMutexInit(void){ return SQLITE_OK; }
 static int debugMutexEnd(void){ return SQLITE_OK; }
 
 /*
 ** The sqlite3_mutex_alloc() routine allocates a new
 ** mutex and returns a pointer to it.  If it returns NULL
 ** that means that a mutex could not be allocated. 
 */
 static sqlite3_mutex *debugMutexAlloc(int id){
-  static sqlite3_debug_mutex aStatic[6];
-  sqlite3_debug_mutex *pNew = 0;
+  static sqlite3_mutex aStatic[6];
+  sqlite3_mutex *pNew = 0;
   switch( id ){
     case SQLITE_MUTEX_FAST:
     case SQLITE_MUTEX_RECURSIVE: {
       pNew = sqlite3Malloc(sizeof(*pNew));
       if( pNew ){
         pNew->id = id;
         pNew->cnt = 0;
       }
@@ -15483,93 +15094,78 @@ static sqlite3_mutex *debugMutexAlloc(in
     default: {
       assert( id-2 >= 0 );
       assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
       pNew = &aStatic[id-2];
       pNew->id = id;
       break;
     }
   }
-  return (sqlite3_mutex*)pNew;
+  return pNew;
 }
 
 /*
 ** This routine deallocates a previously allocated mutex.
 */
-static void debugMutexFree(sqlite3_mutex *pX){
-  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
+static void debugMutexFree(sqlite3_mutex *p){
   assert( p->cnt==0 );
   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
   sqlite3_free(p);
 }
 
 /*
 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
 ** to enter a mutex.  If another thread is already within the mutex,
 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
 ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
 ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
 ** be entered multiple times by the same thread.  In such cases the,
 ** mutex must be exited an equal number of times before another thread
 ** can enter.  If the same thread tries to enter any other kind of mutex
 ** more than once, the behavior is undefined.
 */
-static void debugMutexEnter(sqlite3_mutex *pX){
-  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
+static void debugMutexEnter(sqlite3_mutex *p){
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) );
   p->cnt++;
 }
-static int debugMutexTry(sqlite3_mutex *pX){
-  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
+static int debugMutexTry(sqlite3_mutex *p){
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) );
   p->cnt++;
   return SQLITE_OK;
 }
 
 /*
 ** The sqlite3_mutex_leave() routine exits a mutex that was
 ** previously entered by the same thread.  The behavior
 ** is undefined if the mutex is not currently entered or
 ** is not currently allocated.  SQLite will never do either.
 */
-static void debugMutexLeave(sqlite3_mutex *pX){
-  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
-  assert( debugMutexHeld(pX) );
+static void debugMutexLeave(sqlite3_mutex *p){
+  assert( debugMutexHeld(p) );
   p->cnt--;
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
-}
-
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){
-  static const sqlite3_mutex_methods sMutex = {
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) );
+}
+
+SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
+  static sqlite3_mutex_methods sMutex = {
     debugMutexInit,
     debugMutexEnd,
     debugMutexAlloc,
     debugMutexFree,
     debugMutexEnter,
     debugMutexTry,
     debugMutexLeave,
 
     debugMutexHeld,
     debugMutexNotheld
   };
 
   return &sMutex;
 }
-#endif /* SQLITE_DEBUG */
-
-/*
-** 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) && defined(SQLITE_DEBUG) */
 
 /************** 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:
@@ -15815,18 +15411,18 @@ static void os2MutexLeave(sqlite3_mutex 
   assert( p->nRef>0 );
   DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
   assert( p->owner==tid );
   p->nRef--;
   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
   DosReleaseMutexSem(p->mutex);
 }
 
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
-  static const sqlite3_mutex_methods sMutex = {
+SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
+  static sqlite3_mutex_methods sMutex = {
     os2MutexInit,
     os2MutexEnd,
     os2MutexAlloc,
     os2MutexFree,
     os2MutexEnter,
     os2MutexTry,
     os2MutexLeave,
 #ifdef SQLITE_DEBUG
@@ -15861,43 +15457,33 @@ SQLITE_PRIVATE sqlite3_mutex_methods con
 **
 ** Note that this implementation requires a version of pthreads that
 ** supports recursive mutexes.
 */
 #ifdef SQLITE_MUTEX_PTHREADS
 
 #include <pthread.h>
 
-/*
-** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields
-** are necessary under two condidtions:  (1) Debug builds and (2) using
-** home-grown mutexes.  Encapsulate these conditions into a single #define.
-*/
-#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX)
-# define SQLITE_MUTEX_NREF 1
-#else
-# define SQLITE_MUTEX_NREF 0
-#endif
 
 /*
 ** Each recursive mutex is an instance of the following structure.
 */
 struct sqlite3_mutex {
   pthread_mutex_t mutex;     /* Mutex controlling the lock */
-#if SQLITE_MUTEX_NREF
   int id;                    /* Mutex type */
-  volatile int nRef;         /* Number of entrances */
-  volatile pthread_t owner;  /* Thread that is within this mutex */
+  int nRef;                  /* Number of entrances */
+  pthread_t owner;           /* Thread that is within this mutex */
+#ifdef SQLITE_DEBUG
   int trace;                 /* True to trace changes */
 #endif
 };
-#if SQLITE_MUTEX_NREF
+#ifdef SQLITE_DEBUG
 #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 }
 #else
-#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
+#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0 }
 #endif
 
 /*
 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
 ** intended for use only inside assert() statements.  On some platforms,
 ** there might be race conditions that can cause these routines to
 ** deliver incorrect results.  In particular, if pthread_equal() is
 ** not an atomic operation, then these routines might delivery
@@ -15989,39 +15575,33 @@ static sqlite3_mutex *pthreadMutexAlloc(
 #else
         /* Use a recursive mutex if it is available */
         pthread_mutexattr_t recursiveAttr;
         pthread_mutexattr_init(&recursiveAttr);
         pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
         pthread_mutex_init(&p->mutex, &recursiveAttr);
         pthread_mutexattr_destroy(&recursiveAttr);
 #endif
-#if SQLITE_MUTEX_NREF
         p->id = iType;
-#endif
       }
       break;
     }
     case SQLITE_MUTEX_FAST: {
       p = sqlite3MallocZero( sizeof(*p) );
       if( p ){
-#if SQLITE_MUTEX_NREF
         p->id = iType;
-#endif
         pthread_mutex_init(&p->mutex, 0);
       }
       break;
     }
     default: {
       assert( iType-2 >= 0 );
       assert( iType-2 < ArraySize(staticMutexes) );
       p = &staticMutexes[iType-2];
-#if SQLITE_MUTEX_NREF
       p->id = iType;
-#endif
       break;
     }
   }
   return p;
 }
 
 
 /*
@@ -16071,21 +15651,19 @@ static void pthreadMutexEnter(sqlite3_mu
       p->owner = self;
       p->nRef = 1;
     }
   }
 #else
   /* Use the built-in recursive mutexes if they are available.
   */
   pthread_mutex_lock(&p->mutex);
-#if SQLITE_MUTEX_NREF
   p->owner = pthread_self();
   p->nRef++;
 #endif
-#endif
 
 #ifdef SQLITE_DEBUG
   if( p->trace ){
     printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
   }
 #endif
 }
 static int pthreadMutexTry(sqlite3_mutex *p){
@@ -16116,20 +15694,18 @@ static int pthreadMutexTry(sqlite3_mutex
     }else{
       rc = SQLITE_BUSY;
     }
   }
 #else
   /* Use the built-in recursive mutexes if they are available.
   */
   if( pthread_mutex_trylock(&p->mutex)==0 ){
-#if SQLITE_MUTEX_NREF
     p->owner = pthread_self();
     p->nRef++;
-#endif
     rc = SQLITE_OK;
   }else{
     rc = SQLITE_BUSY;
   }
 #endif
 
 #ifdef SQLITE_DEBUG
   if( rc==SQLITE_OK && p->trace ){
@@ -16142,19 +15718,17 @@ static int pthreadMutexTry(sqlite3_mutex
 /*
 ** The sqlite3_mutex_leave() routine exits a mutex that was
 ** previously entered by the same thread.  The behavior
 ** is undefined if the mutex is not currently entered or
 ** is not currently allocated.  SQLite will never do either.
 */
 static void pthreadMutexLeave(sqlite3_mutex *p){
   assert( pthreadMutexHeld(p) );
-#if SQLITE_MUTEX_NREF
   p->nRef--;
-#endif
   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
 
 #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
   if( p->nRef==0 ){
     pthread_mutex_unlock(&p->mutex);
   }
 #else
   pthread_mutex_unlock(&p->mutex);
@@ -16162,18 +15736,18 @@ static void pthreadMutexLeave(sqlite3_mu
 
 #ifdef SQLITE_DEBUG
   if( p->trace ){
     printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
   }
 #endif
 }
 
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
-  static const sqlite3_mutex_methods sMutex = {
+SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
+  static sqlite3_mutex_methods sMutex = {
     pthreadMutexInit,
     pthreadMutexEnd,
     pthreadMutexAlloc,
     pthreadMutexFree,
     pthreadMutexEnter,
     pthreadMutexTry,
     pthreadMutexLeave,
 #ifdef SQLITE_DEBUG
@@ -16213,27 +15787,27 @@ SQLITE_PRIVATE sqlite3_mutex_methods con
 #ifdef SQLITE_MUTEX_W32
 
 /*
 ** Each recursive mutex is an instance of the following structure.
 */
 struct sqlite3_mutex {
   CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
   int id;                    /* Mutex type */
+  int nRef;                  /* Number of enterances */
+  DWORD owner;               /* Thread holding this mutex */
 #ifdef SQLITE_DEBUG
-  volatile int nRef;         /* Number of enterances */
-  volatile DWORD owner;      /* Thread holding this mutex */
   int trace;                 /* True to trace changes */
 #endif
 };
 #define SQLITE_W32_MUTEX_INITIALIZER { 0 }
 #ifdef SQLITE_DEBUG
 #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 }
 #else
-#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
+#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0 }
 #endif
 
 /*
 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
 ** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
 **
 ** Here is an interesting observation:  Win95, Win98, and WinME lack
 ** the LockFileEx() API.  But we can still statically link against that
@@ -16379,31 +15953,27 @@ static int winMutexEnd(void){
 static sqlite3_mutex *winMutexAlloc(int iType){
   sqlite3_mutex *p;
 
   switch( iType ){
     case SQLITE_MUTEX_FAST:
     case SQLITE_MUTEX_RECURSIVE: {
       p = sqlite3MallocZero( sizeof(*p) );
       if( p ){  
-#ifdef SQLITE_DEBUG
         p->id = iType;
-#endif
         InitializeCriticalSection(&p->mutex);
       }
       break;
     }
     default: {
       assert( winMutex_isInit==1 );
       assert( iType-2 >= 0 );
       assert( iType-2 < ArraySize(winMutex_staticMutexes) );
       p = &winMutex_staticMutexes[iType-2];
-#ifdef SQLITE_DEBUG
       p->id = iType;
-#endif
       break;
     }
   }
   return p;
 }
 
 
 /*
@@ -16426,24 +15996,22 @@ static void winMutexFree(sqlite3_mutex *
 ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
 ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
 ** be entered multiple times by the same thread.  In such cases the,
 ** mutex must be exited an equal number of times before another thread
 ** can enter.  If the same thread tries to enter any other kind of mutex
 ** more than once, the behavior is undefined.
 */
 static void winMutexEnter(sqlite3_mutex *p){
-#ifdef SQLITE_DEBUG
   DWORD tid = GetCurrentThreadId(); 
   assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
-#endif
   EnterCriticalSection(&p->mutex);
-#ifdef SQLITE_DEBUG
   p->owner = tid; 
   p->nRef++;
+#ifdef SQLITE_DEBUG
   if( p->trace ){
     printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
   }
 #endif
 }
 static int winMutexTry(sqlite3_mutex *p){
 #ifndef NDEBUG
   DWORD tid = GetCurrentThreadId(); 
@@ -16482,31 +16050,31 @@ static int winMutexTry(sqlite3_mutex *p)
 ** The sqlite3_mutex_leave() routine exits a mutex that was
 ** previously entered by the same thread.  The behavior
 ** is undefined if the mutex is not currently entered or
 ** is not currently allocated.  SQLite will never do either.
 */
 static void winMutexLeave(sqlite3_mutex *p){
 #ifndef NDEBUG
   DWORD tid = GetCurrentThreadId();
+#endif
   assert( p->nRef>0 );
   assert( p->owner==tid );
   p->nRef--;
   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
-#endif
   LeaveCriticalSection(&p->mutex);
 #ifdef SQLITE_DEBUG
   if( p->trace ){
     printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
   }
 #endif
 }
 
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
-  static const sqlite3_mutex_methods sMutex = {
+SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
+  static sqlite3_mutex_methods sMutex = {
     winMutexInit,
     winMutexEnd,
     winMutexAlloc,
     winMutexFree,
     winMutexEnter,
     winMutexTry,
     winMutexLeave,
 #ifdef SQLITE_DEBUG
@@ -16834,21 +16402,21 @@ static int scratchAllocOut = 0;
 ** structures that would not normally fit on the stack of an
 ** embedded processor.
 */
 SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
   void *p;
   assert( n>0 );
 
 #if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
-  /* Verify that no more than two scratch allocation per thread
+  /* Verify that no more than one scratch allocation per thread
   ** is outstanding at one time.  (This is only checked in the
   ** single-threaded case since checking in the multi-threaded case
   ** would be much more complicated.) */
-  assert( scratchAllocOut<=1 );
+  assert( scratchAllocOut==0 );
 #endif
 
   if( sqlite3GlobalConfig.szScratch<n ){
     goto scratch_overflow;
   }else{  
     sqlite3_mutex_enter(mem0.mutex);
     if( mem0.nScratchFree==0 ){
       sqlite3_mutex_leave(mem0.mutex);
@@ -16875,29 +16443,36 @@ scratch_overflow:
     sqlite3_mutex_enter(mem0.mutex);
     sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
     n = mallocWithAlarm(n, &p);
     if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
     sqlite3_mutex_leave(mem0.mutex);
   }else{
     p = sqlite3GlobalConfig.m.xMalloc(n);
   }
-  sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
 #if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
   scratchAllocOut = p!=0;
 #endif
   return p;    
 }
 SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
   if( p ){
+
+#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
+    /* Verify that no more than one scratch allocation per thread
+    ** is outstanding at one time.  (This is only checked in the
+    ** single-threaded case since checking in the multi-threaded case
+    ** would be much more complicated.) */
+    assert( scratchAllocOut==1 );
+    scratchAllocOut = 0;
+#endif
+
     if( sqlite3GlobalConfig.pScratch==0
            || p<sqlite3GlobalConfig.pScratch
            || p>=(void*)mem0.aScratchFree ){
-      assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
-      sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
       if( sqlite3GlobalConfig.bMemstat ){
         int iSize = sqlite3MallocSize(p);
         sqlite3_mutex_enter(mem0.mutex);
         sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize);
         sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
         sqlite3GlobalConfig.m.xFree(p);
         sqlite3_mutex_leave(mem0.mutex);
       }else{
@@ -16908,26 +16483,16 @@ SQLITE_PRIVATE void sqlite3ScratchFree(v
       i = (int)((u8*)p - (u8*)sqlite3GlobalConfig.pScratch);
       i /= sqlite3GlobalConfig.szScratch;
       assert( i>=0 && i<sqlite3GlobalConfig.nScratch );
       sqlite3_mutex_enter(mem0.mutex);
       assert( mem0.nScratchFree<(u32)sqlite3GlobalConfig.nScratch );
       mem0.aScratchFree[mem0.nScratchFree++] = i;
       sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
       sqlite3_mutex_leave(mem0.mutex);
-
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
-    /* Verify that no more than two scratch allocation per thread
-    ** is outstanding at one time.  (This is only checked in the
-    ** single-threaded case since checking in the multi-threaded case
-    ** would be much more complicated.) */
-    assert( scratchAllocOut>=1 && scratchAllocOut<=2 );
-    scratchAllocOut = 0;
-#endif
-
     }
   }
 }
 
 /*
 ** TRUE if p is a lookaside memory allocation from db
 */
 #ifndef SQLITE_OMIT_LOOKASIDE
@@ -16938,36 +16503,32 @@ static int isLookaside(sqlite3 *db, void
 #define isLookaside(A,B) 0
 #endif
 
 /*
 ** Return the size of a memory allocation previously obtained from
 ** sqlite3Malloc() or sqlite3_malloc().
 */
 SQLITE_PRIVATE int sqlite3MallocSize(void *p){
-  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
   return sqlite3GlobalConfig.m.xSize(p);
 }
 SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
   assert( db==0 || sqlite3_mutex_held(db->mutex) );
   if( isLookaside(db, p) ){
     return db->lookaside.sz;
   }else{
-    assert( sqlite3MemdebugHasType(p,
-             db ? (MEMTYPE_DB|MEMTYPE_HEAP) : MEMTYPE_HEAP) );
     return sqlite3GlobalConfig.m.xSize(p);
   }
 }
 
 /*
 ** Free memory previously obtained from sqlite3Malloc().
 */
 SQLITE_API void sqlite3_free(void *p){
   if( p==0 ) return;
-  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
   if( sqlite3GlobalConfig.bMemstat ){
     sqlite3_mutex_enter(mem0.mutex);
     sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
     sqlite3GlobalConfig.m.xFree(p);
     sqlite3_mutex_leave(mem0.mutex);
   }else{
     sqlite3GlobalConfig.m.xFree(p);
   }
@@ -16980,18 +16541,16 @@ SQLITE_API void sqlite3_free(void *p){
 SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
   assert( db==0 || sqlite3_mutex_held(db->mutex) );
   if( isLookaside(db, p) ){
     LookasideSlot *pBuf = (LookasideSlot*)p;
     pBuf->pNext = db->lookaside.pFree;
     db->lookaside.pFree = pBuf;
     db->lookaside.nOut--;
   }else{
-    assert( sqlite3MemdebugHasType(p, MEMTYPE_DB|MEMTYPE_HEAP) );
-    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
     sqlite3_free(p);
   }
 }
 
 /*
 ** Change the size of an existing memory allocation
 */
 SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
@@ -17014,17 +16573,16 @@ SQLITE_PRIVATE void *sqlite3Realloc(void
     pNew = pOld;
   }else if( sqlite3GlobalConfig.bMemstat ){
     sqlite3_mutex_enter(mem0.mutex);
     sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
     if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= 
           mem0.alarmThreshold ){
       sqlite3MallocAlarm(nNew-nOld);
     }
-    assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
     pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
     if( pNew==0 && mem0.alarmCallback ){
       sqlite3MallocAlarm(nBytes);
       pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
     }
     if( pNew ){
       nNew = sqlite3MallocSize(pNew);
       sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
@@ -17112,18 +16670,16 @@ SQLITE_PRIVATE void *sqlite3DbMallocRaw(
   if( db && db->mallocFailed ){
     return 0;
   }
 #endif
   p = sqlite3Malloc(n);
   if( !p && db ){
     db->mallocFailed = 1;
   }
-  sqlite3MemdebugSetType(p,
-            (db && db->lookaside.bEnabled) ? MEMTYPE_DB : MEMTYPE_HEAP);
   return p;
 }
 
 /*
 ** Resize the block of memory pointed to by p to n bytes. If the
 ** resize fails, set the mallocFailed flag in the connection object.
 */
 SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
@@ -17139,24 +16695,20 @@ SQLITE_PRIVATE void *sqlite3DbRealloc(sq
         return p;
       }
       pNew = sqlite3DbMallocRaw(db, n);
       if( pNew ){
         memcpy(pNew, p, db->lookaside.sz);
         sqlite3DbFree(db, p);
       }
     }else{
-      assert( sqlite3MemdebugHasType(p, MEMTYPE_DB|MEMTYPE_HEAP) );
-      sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
       pNew = sqlite3_realloc(p, n);
       if( !pNew ){
         db->mallocFailed = 1;
       }
-      sqlite3MemdebugSetType(pNew,
-            db->lookaside.bEnabled ? MEMTYPE_DB : MEMTYPE_HEAP);
     }
   }
   return pNew;
 }
 
 /*
 ** Attempt to reallocate p.  If the reallocation fails, then free p
 ** and set the mallocFailed flag in the database connection.
@@ -18750,17 +18302,17 @@ struct Vdbe {
   u8 inVtabMethod;        /* See comments above */
   u8 usesStmtJournal;     /* True if uses a statement journal */
   u8 readOnly;            /* True for read-only statements */
   u8 isPrepareV2;         /* True if prepared with prepare_v2() */
   int nChange;            /* Number of db changes made since last reset */
   int btreeMask;          /* Bitmask of db->aDb[] entries referenced */
   i64 startTime;          /* Time when query started - used for profiling */
   BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
-  int aCounter[3];        /* Counters used by sqlite3_stmt_status() */
+  int aCounter[2];        /* Counters used by sqlite3_stmt_status() */
   char *zSql;             /* Text of the SQL statement that generated this */
   void *pFree;            /* Free this when deleting the vdbe */
   i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
   i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
   int iStatement;         /* Statement number (or 0 if has not opened stmt) */
 #ifdef SQLITE_DEBUG
   FILE *trace;            /* Write an execution trace here, if not NULL */
 #endif
@@ -20790,114 +20342,114 @@ SQLITE_PRIVATE const char *sqlite3Opcode
      /*  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",
+     /*  40 */ "OpenEphemeral",
+     /*  41 */ "OpenPseudo",
+     /*  42 */ "Close",
+     /*  43 */ "SeekLt",
+     /*  44 */ "SeekLe",
+     /*  45 */ "SeekGe",
+     /*  46 */ "SeekGt",
+     /*  47 */ "Seek",
+     /*  48 */ "NotFound",
+     /*  49 */ "Found",
+     /*  50 */ "IsUnique",
+     /*  51 */ "NotExists",
+     /*  52 */ "Sequence",
+     /*  53 */ "NewRowid",
+     /*  54 */ "Insert",
+     /*  55 */ "InsertInt",
+     /*  56 */ "Delete",
+     /*  57 */ "ResetCount",
+     /*  58 */ "RowKey",
+     /*  59 */ "RowData",
+     /*  60 */ "Rowid",
+     /*  61 */ "NullRow",
+     /*  62 */ "Last",
+     /*  63 */ "Sort",
+     /*  64 */ "Rewind",
+     /*  65 */ "Prev",
+     /*  66 */ "Next",
+     /*  67 */ "IdxInsert",
      /*  68 */ "Or",
      /*  69 */ "And",
-     /*  70 */ "IdxInsert",
-     /*  71 */ "IdxDelete",
-     /*  72 */ "IdxRowid",
+     /*  70 */ "IdxDelete",
+     /*  71 */ "IdxRowid",
+     /*  72 */ "IdxLT",
      /*  73 */ "IsNull",
      /*  74 */ "NotNull",
      /*  75 */ "Ne",
      /*  76 */ "Eq",
      /*  77 */ "Gt",
      /*  78 */ "Le",
      /*  79 */ "Lt",
      /*  80 */ "Ge",
-     /*  81 */ "IdxLT",
+     /*  81 */ "IdxGE",
      /*  82 */ "BitAnd",
      /*  83 */ "BitOr",
      /*  84 */ "ShiftLeft",
      /*  85 */ "ShiftRight",
      /*  86 */ "Add",
      /*  87 */ "Subtract",
      /*  88 */ "Multiply",
      /*  89 */ "Divide",
      /*  90 */ "Remainder",
      /*  91 */ "Concat",
-     /*  92 */ "IdxGE",
+     /*  92 */ "Destroy",
      /*  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 */ "Clear",
+     /*  96 */ "CreateIndex",
+     /*  97 */ "CreateTable",
+     /*  98 */ "ParseSchema",
+     /*  99 */ "LoadAnalysis",
+     /* 100 */ "DropTable",
+     /* 101 */ "DropIndex",
+     /* 102 */ "DropTrigger",
+     /* 103 */ "IntegrityCk",
+     /* 104 */ "RowSetAdd",
+     /* 105 */ "RowSetRead",
+     /* 106 */ "RowSetTest",
+     /* 107 */ "Program",
+     /* 108 */ "Param",
+     /* 109 */ "FkCounter",
+     /* 110 */ "FkIfZero",
+     /* 111 */ "MemMax",
+     /* 112 */ "IfPos",
+     /* 113 */ "IfNeg",
+     /* 114 */ "IfZero",
+     /* 115 */ "AggStep",
+     /* 116 */ "AggFinal",
+     /* 117 */ "Vacuum",
+     /* 118 */ "IncrVacuum",
+     /* 119 */ "Expire",
+     /* 120 */ "TableLock",
+     /* 121 */ "VBegin",
+     /* 122 */ "VCreate",
+     /* 123 */ "VDestroy",
+     /* 124 */ "VOpen",
+     /* 125 */ "VFilter",
+     /* 126 */ "VColumn",
+     /* 127 */ "VNext",
+     /* 128 */ "VRename",
+     /* 129 */ "VUpdate",
      /* 130 */ "Real",
-     /* 131 */ "VNext",
-     /* 132 */ "VRename",
-     /* 133 */ "VUpdate",
-     /* 134 */ "Pagecount",
-     /* 135 */ "Trace",
-     /* 136 */ "Noop",
-     /* 137 */ "Explain",
+     /* 131 */ "Pagecount",
+     /* 132 */ "Trace",
+     /* 133 */ "Noop",
+     /* 134 */ "Explain",
+     /* 135 */ "NotUsed_135",
+     /* 136 */ "NotUsed_136",
+     /* 137 */ "NotUsed_137",
      /* 138 */ "NotUsed_138",
      /* 139 */ "NotUsed_139",
      /* 140 */ "NotUsed_140",
      /* 141 */ "ToText",
      /* 142 */ "ToBlob",
      /* 143 */ "ToNumeric",
      /* 144 */ "ToInt",
      /* 145 */ "ToReal",
@@ -20992,19 +20544,33 @@ SQLITE_PRIVATE const char *sqlite3Opcode
 ** 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)
+#define OSTRACE1(X)         if( sqlite3OSTrace ) sqlite3DebugPrintf(X)
+#define OSTRACE2(X,Y)       if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y)
+#define OSTRACE3(X,Y,Z)     if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z)
+#define OSTRACE4(X,Y,Z,A)   if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A)
+#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B)
+#define OSTRACE6(X,Y,Z,A,B,C) \
+    if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
+#define OSTRACE7(X,Y,Z,A,B,C,D) \
+    if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
+#else
+#define OSTRACE1(X)
+#define OSTRACE2(X,Y)
+#define OSTRACE3(X,Y,Z)
+#define OSTRACE4(X,Y,Z,A)
+#define OSTRACE5(X,Y,Z,A,B)
+#define OSTRACE6(X,Y,Z,A,B,C)
+#define OSTRACE7(X,Y,Z,A,B,C,D)
 #endif
 
 /*
 ** Macros for performance tracing.  Normally turned off.  Only works
 ** on i486 hardware.
 */
 #ifdef SQLITE_PERFORMANCE_TRACE
 
@@ -21190,17 +20756,17 @@ struct os2File {
 
 /*
 ** Close a file.
 */
 static int os2Close( sqlite3_file *id ){
   APIRET rc = NO_ERROR;
   os2File *pFile;
   if( id && (pFile = (os2File*)id) != 0 ){
-    OSTRACE(( "CLOSE %d\n", pFile->h ));
+    OSTRACE2( "CLOSE %d\n", pFile->h );
     rc = DosClose( pFile->h );
     pFile->locktype = NO_LOCK;
     if( pFile->pathToDel != NULL ){
       rc = DosForceDelete( (PSZ)pFile->pathToDel );
       free( pFile->pathToDel );
       pFile->pathToDel = NULL;
     }
     id = 0;
@@ -21221,17 +20787,17 @@ static int os2Read(
   int amt,                        /* Number of bytes to read */
   sqlite3_int64 offset            /* Begin reading at this offset */
 ){
   ULONG fileLocation = 0L;
   ULONG got;
   os2File *pFile = (os2File*)id;
   assert( id!=0 );
   SimulateIOError( return SQLITE_IOERR_READ );
-  OSTRACE(( "READ %d lock=%d\n", pFile->h, pFile->locktype ));
+  OSTRACE3( "READ %d lock=%d\n", pFile->h, pFile->locktype );
   if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){
     return SQLITE_IOERR;
   }
   if( DosRead( pFile->h, pBuf, amt, &got ) != NO_ERROR ){
     return SQLITE_IOERR_READ;
   }
   if( got == (ULONG)amt )
     return SQLITE_OK;
@@ -21254,17 +20820,17 @@ static int os2Write(
 ){
   ULONG fileLocation = 0L;
   APIRET rc = NO_ERROR;
   ULONG wrote;
   os2File *pFile = (os2File*)id;
   assert( id!=0 );
   SimulateIOError( return SQLITE_IOERR_WRITE );
   SimulateDiskfullError( return SQLITE_FULL );
-  OSTRACE(( "WRITE %d lock=%d\n", pFile->h, pFile->locktype ));
+  OSTRACE3( "WRITE %d lock=%d\n", pFile->h, pFile->locktype );
   if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){
     return SQLITE_IOERR;
   }
   assert( amt>0 );
   while( amt > 0 &&
          ( rc = DosWrite( pFile->h, (PVOID)pBuf, amt, &wrote ) ) == NO_ERROR &&
          wrote > 0
   ){
@@ -21276,17 +20842,17 @@ static int os2Write(
 }
 
 /*
 ** Truncate an open file to a specified size
 */
 static int os2Truncate( sqlite3_file *id, i64 nByte ){
   APIRET rc = NO_ERROR;
   os2File *pFile = (os2File*)id;
-  OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte ));
+  OSTRACE3( "TRUNCATE %d %lld\n", pFile->h, nByte );
   SimulateIOError( return SQLITE_IOERR_TRUNCATE );
   rc = DosSetFileSize( pFile->h, nByte );
   return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE;
 }
 
 #ifdef SQLITE_TEST
 /*
 ** Count the number of fullsyncs and normal syncs.  This is used to test
@@ -21296,17 +20862,17 @@ SQLITE_API int sqlite3_sync_count = 0;
 SQLITE_API int sqlite3_fullsync_count = 0;
 #endif
 
 /*
 ** Make sure all writes to a particular file are committed to disk.
 */
 static int os2Sync( sqlite3_file *id, int flags ){
   os2File *pFile = (os2File*)id;
-  OSTRACE(( "SYNC %d lock=%d\n", pFile->h, pFile->locktype ));
+  OSTRACE3( "SYNC %d lock=%d\n", pFile->h, pFile->locktype );
 #ifdef SQLITE_TEST
   if( flags & SQLITE_SYNC_FULL){
     sqlite3_fullsync_count++;
   }
   sqlite3_sync_count++;
 #endif
   /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
   ** no-op
@@ -21346,17 +20912,17 @@ static int getReadLock( os2File *pFile )
   APIRET res;
   memset(&LockArea, 0, sizeof(LockArea));
   memset(&UnlockArea, 0, sizeof(UnlockArea));
   LockArea.lOffset = SHARED_FIRST;
   LockArea.lRange = SHARED_SIZE;
   UnlockArea.lOffset = 0L;
   UnlockArea.lRange = 0L;
   res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L );
-  OSTRACE(( "GETREADLOCK %d res=%d\n", pFile->h, res ));
+  OSTRACE3( "GETREADLOCK %d res=%d\n", pFile->h, res );
   return res;
 }
 
 /*
 ** Undo a readlock
 */
 static int unlockReadLock( os2File *id ){
   FILELOCK  LockArea,
@@ -21364,17 +20930,17 @@ static int unlockReadLock( os2File *id )
   APIRET res;
   memset(&LockArea, 0, sizeof(LockArea));
   memset(&UnlockArea, 0, sizeof(UnlockArea));
   LockArea.lOffset = 0L;
   LockArea.lRange = 0L;
   UnlockArea.lOffset = SHARED_FIRST;
   UnlockArea.lRange = SHARED_SIZE;
   res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L );
-  OSTRACE(( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res ));
+  OSTRACE3( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res );
   return res;
 }
 
 /*
 ** Lock the file with the lock specified by parameter locktype - one
 ** of the following:
 **
 **     (1) SHARED_LOCK
@@ -21405,24 +20971,24 @@ static int os2Lock( sqlite3_file *id, in
   int newLocktype;       /* Set pFile->locktype to this value before exiting */
   int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
   FILELOCK  LockArea,
             UnlockArea;
   os2File *pFile = (os2File*)id;
   memset(&LockArea, 0, sizeof(LockArea));
   memset(&UnlockArea, 0, sizeof(UnlockArea));
   assert( pFile!=0 );
-  OSTRACE(( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype ));
+  OSTRACE4( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype );
 
   /* If there is already a lock of this type or more restrictive on the
   ** os2File, do nothing. Don't use the end_lock: exit path, as
   ** sqlite3_mutex_enter() hasn't been called yet.
   */
   if( pFile->locktype>=locktype ){
-    OSTRACE(( "LOCK %d %d ok (already held)\n", pFile->h, locktype ));
+    OSTRACE3( "LOCK %d %d ok (already held)\n", pFile->h, locktype );
     return SQLITE_OK;
   }
 
   /* Make sure the locking sequence is correct
   */
   assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
   assert( locktype!=PENDING_LOCK );
   assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
@@ -21439,138 +21005,137 @@ static int os2Lock( sqlite3_file *id, in
     LockArea.lRange = 1L;
     UnlockArea.lOffset = 0L;
     UnlockArea.lRange = 0L;
 
     /* wait longer than LOCK_TIMEOUT here not to have to try multiple times */
     res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 100L, 0L );
     if( res == NO_ERROR ){
       gotPendingLock = 1;
-      OSTRACE(( "LOCK %d pending lock boolean set.  res=%d\n", pFile->h, res ));
+      OSTRACE3( "LOCK %d pending lock boolean set.  res=%d\n", pFile->h, res );
     }
   }
 
   /* Acquire a shared lock
   */
   if( locktype==SHARED_LOCK && res == NO_ERROR ){
     assert( pFile->locktype==NO_LOCK );
     res = getReadLock(pFile);
     if( res == NO_ERROR ){
       newLocktype = SHARED_LOCK;
     }
-    OSTRACE(( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res ));
+    OSTRACE3( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res );
   }
 
   /* Acquire a RESERVED lock
   */
   if( locktype==RESERVED_LOCK && res == NO_ERROR ){
     assert( pFile->locktype==SHARED_LOCK );
     LockArea.lOffset = RESERVED_BYTE;
     LockArea.lRange = 1L;
     UnlockArea.lOffset = 0L;
     UnlockArea.lRange = 0L;
     res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
     if( res == NO_ERROR ){
       newLocktype = RESERVED_LOCK;
     }
-    OSTRACE(( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res ));
+    OSTRACE3( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res );
   }
 
   /* Acquire a PENDING lock
   */
   if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
     newLocktype = PENDING_LOCK;
     gotPendingLock = 0;
-    OSTRACE(( "LOCK %d acquire pending lock. pending lock boolean unset.\n",
-               pFile->h ));
+    OSTRACE2( "LOCK %d acquire pending lock. pending lock boolean unset.\n", pFile->h );
   }
 
   /* Acquire an EXCLUSIVE lock
   */
   if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
     assert( pFile->locktype>=SHARED_LOCK );
     res = unlockReadLock(pFile);
-    OSTRACE(( "unreadlock = %d\n", res ));
+    OSTRACE2( "unreadlock = %d\n", res );
     LockArea.lOffset = SHARED_FIRST;
     LockArea.lRange = SHARED_SIZE;
     UnlockArea.lOffset = 0L;
     UnlockArea.lRange = 0L;
     res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
     if( res == NO_ERROR ){
       newLocktype = EXCLUSIVE_LOCK;
     }else{
-      OSTRACE(( "OS/2 error-code = %d\n", res ));
+      OSTRACE2( "OS/2 error-code = %d\n", res );
       getReadLock(pFile);
     }
-    OSTRACE(( "LOCK %d acquire exclusive lock.  res=%d\n", pFile->h, res ));
+    OSTRACE3( "LOCK %d acquire exclusive lock.  res=%d\n", pFile->h, res );
   }
 
   /* If we are holding a PENDING lock that ought to be released, then
   ** release it now.
   */
   if( gotPendingLock && locktype==SHARED_LOCK ){
     int r;
     LockArea.lOffset = 0L;
     LockArea.lRange = 0L;
     UnlockArea.lOffset = PENDING_BYTE;
     UnlockArea.lRange = 1L;
     r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    OSTRACE(( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r ));
+    OSTRACE3( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r );
   }
 
   /* Update the state of the lock has held in the file descriptor then
   ** return the appropriate result code.
   */
   if( res == NO_ERROR ){
     rc = SQLITE_OK;
   }else{
-    OSTRACE(( "LOCK FAILED %d trying for %d but got %d\n", pFile->h,
-              locktype, newLocktype ));
+    OSTRACE4( "LOCK FAILED %d trying for %d but got %d\n", pFile->h,
+              locktype, newLocktype );
     rc = SQLITE_BUSY;
   }
   pFile->locktype = newLocktype;
-  OSTRACE(( "LOCK %d now %d\n", pFile->h, pFile->locktype ));
+  OSTRACE3( "LOCK %d now %d\n", pFile->h, pFile->locktype );
   return rc;
 }
 
 /*
 ** 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, return
 ** non-zero, otherwise zero.
 */
 static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){
   int r = 0;
   os2File *pFile = (os2File*)id;
   assert( pFile!=0 );
   if( pFile->locktype>=RESERVED_LOCK ){
     r = 1;
-    OSTRACE(( "TEST WR-LOCK %d %d (local)\n", pFile->h, r ));
+    OSTRACE3( "TEST WR-LOCK %d %d (local)\n", pFile->h, r );
   }else{
     FILELOCK  LockArea,
               UnlockArea;
     APIRET rc = NO_ERROR;
     memset(&LockArea, 0, sizeof(LockArea));
     memset(&UnlockArea, 0, sizeof(UnlockArea));
     LockArea.lOffset = RESERVED_BYTE;
     LockArea.lRange = 1L;
     UnlockArea.lOffset = 0L;
     UnlockArea.lRange = 0L;
     rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    OSTRACE(( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc ));
+    OSTRACE3( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc );
     if( rc == NO_ERROR ){
       APIRET rcu = NO_ERROR; /* return code for unlocking */
       LockArea.lOffset = 0L;
       LockArea.lRange = 0L;
       UnlockArea.lOffset = RESERVED_BYTE;
       UnlockArea.lRange = 1L;
       rcu = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-      OSTRACE(( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu ));
+      OSTRACE3( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu );
     }
     r = !(rc == NO_ERROR);
-    OSTRACE(( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r ));
+    OSTRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r );
   }
   *pOut = r;
   return SQLITE_OK;
 }
 
 /*
 ** Lower the locking level on file descriptor id to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
@@ -21588,67 +21153,65 @@ static int os2Unlock( sqlite3_file *id, 
   APIRET rc = SQLITE_OK;
   APIRET res = NO_ERROR;
   FILELOCK  LockArea,
             UnlockArea;
   memset(&LockArea, 0, sizeof(LockArea));
   memset(&UnlockArea, 0, sizeof(UnlockArea));
   assert( pFile!=0 );
   assert( locktype<=SHARED_LOCK );
-  OSTRACE(( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype ));
+  OSTRACE4( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype );
   type = pFile->locktype;
   if( type>=EXCLUSIVE_LOCK ){
     LockArea.lOffset = 0L;
     LockArea.lRange = 0L;
     UnlockArea.lOffset = SHARED_FIRST;
     UnlockArea.lRange = SHARED_SIZE;
     res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    OSTRACE(( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res ));
+    OSTRACE3( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res );
     if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){
       /* This should never happen.  We should always be able to
       ** reacquire the read lock */
-      OSTRACE(( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype ));
+      OSTRACE3( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype );
       rc = SQLITE_IOERR_UNLOCK;
     }
   }
   if( type>=RESERVED_LOCK ){
     LockArea.lOffset = 0L;
     LockArea.lRange = 0L;
     UnlockArea.lOffset = RESERVED_BYTE;
     UnlockArea.lRange = 1L;
     res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    OSTRACE(( "UNLOCK %d reserved res=%d\n", pFile->h, res ));
+    OSTRACE3( "UNLOCK %d reserved res=%d\n", pFile->h, res );
   }
   if( locktype==NO_LOCK && type>=SHARED_LOCK ){
     res = unlockReadLock(pFile);
-    OSTRACE(( "UNLOCK %d is %d want %d res=%d\n",
-              pFile->h, type, locktype, res ));
+    OSTRACE5( "UNLOCK %d is %d want %d res=%d\n", pFile->h, type, locktype, res );
   }
   if( type>=PENDING_LOCK ){
     LockArea.lOffset = 0L;
     LockArea.lRange = 0L;
     UnlockArea.lOffset = PENDING_BYTE;
     UnlockArea.lRange = 1L;
     res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    OSTRACE(( "UNLOCK %d pending res=%d\n", pFile->h, res ));
+    OSTRACE3( "UNLOCK %d pending res=%d\n", pFile->h, res );
   }
   pFile->locktype = locktype;
-  OSTRACE(( "UNLOCK %d now %d\n", pFile->h, pFile->locktype ));
+  OSTRACE3( "UNLOCK %d now %d\n", pFile->h, pFile->locktype );
   return rc;
 }
 
 /*
 ** Control and query of the open file handle.
 */
 static int os2FileControl(sqlite3_file *id, int op, void *pArg){
   switch( op ){
     case SQLITE_FCNTL_LOCKSTATE: {
       *(int*)pArg = ((os2File*)id)->locktype;
-      OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n",
-                ((os2File*)id)->h, ((os2File*)id)->locktype ));
+      OSTRACE3( "FCNTL_LOCKSTATE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
       return SQLITE_OK;
     }
   }
   return SQLITE_ERROR;
 }
 
 /*
 ** Return the sector size in bytes of the underlying block device for
@@ -21825,17 +21388,17 @@ static int getTempname(int nBuf, char *z
                       "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath );
   }
   j = sqlite3Strlen30( zBuf );
   sqlite3_randomness( 20, &zBuf[j] );
   for( i = 0; i < 20; i++, j++ ){
     zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
   }
   zBuf[j] = 0;
-  OSTRACE(( "TEMP FILENAME: %s\n", zBuf ));
+  OSTRACE2( "TEMP FILENAME: %s\n", zBuf );
   return SQLITE_OK;
 }
 
 
 /*
 ** Turn a relative pathname into a full pathname.  Write the full
 ** pathname into zFull[].  zFull[] will be at least pVfs->mxPathname
 ** bytes in size.
@@ -21888,53 +21451,53 @@ static int os2Open(
       return rc;
     }
     zName = zTmpname;
   }
 
 
   memset( pFile, 0, sizeof(*pFile) );
 
-  OSTRACE( "OPEN want %d\n", flags ));
+  OSTRACE2( "OPEN want %d\n", flags );
 
   if( flags & SQLITE_OPEN_READWRITE ){
     ulOpenMode |= OPEN_ACCESS_READWRITE;
-    OSTRACE(( "OPEN read/write\n" ));
+    OSTRACE1( "OPEN read/write\n" );
   }else{
     ulOpenMode |= OPEN_ACCESS_READONLY;
-    OSTRACE(( "OPEN read only\n" ));
+    OSTRACE1( "OPEN read only\n" );
   }
 
   if( flags & SQLITE_OPEN_CREATE ){
     ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
-    OSTRACE(( "OPEN open new/create\n" ));
+    OSTRACE1( "OPEN open new/create\n" );
   }else{
     ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
-    OSTRACE(( "OPEN open existing\n" ));
+    OSTRACE1( "OPEN open existing\n" );
   }
 
   if( flags & SQLITE_OPEN_MAIN_DB ){
     ulOpenMode |= OPEN_SHARE_DENYNONE;
-    OSTRACE(( "OPEN share read/write\n" ));
+    OSTRACE1( "OPEN share read/write\n" );
   }else{
     ulOpenMode |= OPEN_SHARE_DENYWRITE;
-    OSTRACE(( "OPEN share read only\n" ));
+    OSTRACE1( "OPEN share read only\n" );
   }
 
   if( flags & SQLITE_OPEN_DELETEONCLOSE ){
     char pathUtf8[CCHMAXPATH];
 #ifdef NDEBUG /* when debugging we want to make sure it is deleted */
     ulFileAttribute = FILE_HIDDEN;
 #endif
     os2FullPathname( pVfs, zName, CCHMAXPATH, pathUtf8 );
     pFile->pathToDel = convertUtf8PathToCp( pathUtf8 );
-    OSTRACE(( "OPEN hidden/delete on close file attributes\n" ));
+    OSTRACE1( "OPEN hidden/delete on close file attributes\n" );
   }else{
     pFile->pathToDel = NULL;
-    OSTRACE(( "OPEN normal file attribute\n" ));
+    OSTRACE1( "OPEN normal file attribute\n" );
   }
 
   /* always open in random access mode for possibly better speed */
   ulOpenMode |= OPEN_FLAGS_RANDOM;
   ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR;
   ulOpenMode |= OPEN_FLAGS_NOINHERIT;
 
   zNameCp = convertUtf8PathToCp( zName );
@@ -21943,57 +21506,56 @@ static int os2Open(
                 &ulAction,
                 0L,
                 ulFileAttribute,
                 ulOpenFlags,
                 ulOpenMode,
                 (PEAOP2)NULL );
   free( zNameCp );
   if( rc != NO_ERROR ){
-    OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
-              rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode ));
+    OSTRACE7( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
+              rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode );
     if( pFile->pathToDel )
       free( pFile->pathToDel );
     pFile->pathToDel = NULL;
     if( flags & SQLITE_OPEN_READWRITE ){
-      OSTRACE(( "OPEN %d Invalid handle\n",
-                ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) ));
+      OSTRACE2( "OPEN %d Invalid handle\n", ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) );
       return os2Open( pVfs, zName, id,
                       ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE),
                       pOutFlags );
     }else{
       return SQLITE_CANTOPEN;
     }
   }
 
   if( pOutFlags ){
     *pOutFlags = flags & SQLITE_OPEN_READWRITE ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
   }
 
   pFile->pMethod = &os2IoMethod;
   pFile->h = h;
   OpenCounter(+1);
-  OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ));
+  OSTRACE3( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags );
   return SQLITE_OK;
 }
 
 /*
 ** Delete the named file.
 */
 static int os2Delete(
   sqlite3_vfs *pVfs,                     /* Not used on os2 */
   const char *zFilename,                 /* Name of file to delete */
   int syncDir                            /* Not used on os2 */
 ){
   APIRET rc = NO_ERROR;
   char *zFilenameCp = convertUtf8PathToCp( zFilename );
   SimulateIOError( return SQLITE_IOERR_DELETE );
   rc = DosDelete( (PSZ)zFilenameCp );
   free( zFilenameCp );
-  OSTRACE(( "DELETE \"%s\"\n", zFilename ));
+  OSTRACE2( "DELETE \"%s\"\n", zFilename );
   return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_DELETE;
 }
 
 /*
 ** Check the existance and status of a file.
 */
 static int os2Access(
   sqlite3_vfs *pVfs,        /* Not used on os2 */
@@ -22004,27 +21566,27 @@ static int os2Access(
   FILESTATUS3 fsts3ConfigInfo;
   APIRET rc = NO_ERROR;
   char *zFilenameCp = convertUtf8PathToCp( zFilename );
 
   memset( &fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo) );
   rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD,
                          &fsts3ConfigInfo, sizeof(FILESTATUS3) );
   free( zFilenameCp );
-  OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n",
-            fsts3ConfigInfo.attrFile, flags, rc ));
+  OSTRACE4( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n",
+            fsts3ConfigInfo.attrFile, flags, rc );
   switch( flags ){
     case SQLITE_ACCESS_READ:
     case SQLITE_ACCESS_EXISTS:
       rc = (rc == NO_ERROR);
-      OSTRACE(( "ACCESS %s access of read and exists  rc=%d\n", zFilename, rc));
+      OSTRACE3( "ACCESS %s access of read and exists  rc=%d\n", zFilename, rc );
       break;
     case SQLITE_ACCESS_READWRITE:
       rc = (rc == NO_ERROR) && ( (fsts3ConfigInfo.attrFile & FILE_READONLY) == 0 );
-      OSTRACE(( "ACCESS %s access of read/write  rc=%d\n", zFilename, rc ));
+      OSTRACE3( "ACCESS %s access of read/write  rc=%d\n", zFilename, rc );
       break;
     default:
       assert( !"Invalid flags argument" );
   }
   *pOut = rc;
   return SQLITE_OK;
 }
 
@@ -22224,17 +21786,17 @@ SQLITE_API int sqlite3_os_init(void){
     os2FullPathname,   /* xFullPathname */
     os2DlOpen,         /* xDlOpen */
     os2DlError,        /* xDlError */
     os2DlSym,          /* xDlSym */
     os2DlClose,        /* xDlClose */
     os2Randomness,     /* xRandomness */
     os2Sleep,          /* xSleep */
     os2CurrentTime,    /* xCurrentTime */
-    os2GetLastError,   /* xGetLastError */
+    os2GetLastError    /* xGetLastError */
   };
   sqlite3_vfs_register(&os2Vfs, 1);
   initUconvObjects();
   return SQLITE_OK;
 }
 SQLITE_API int sqlite3_os_end(void){
   freeUconvObjects();
   return SQLITE_OK;
@@ -22358,17 +21920,16 @@ 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 <sys/time.h>
 #include <errno.h>
-#include <sys/mman.h>
 
 #if SQLITE_ENABLE_LOCKING_STYLE
 # include <sys/ioctl.h>
 # if OS_VXWORKS
 #  include <semaphore.h>
 #  include <limits.h>
 # else
 #  include <sys/file.h>
@@ -22413,60 +21974,58 @@ SQLITE_API int sqlite3_os_end(void){
 #define MAX_PATHNAME 512
 
 /*
 ** Only set the lastErrno if the error code is a real error and not 
 ** a normal expected return code of SQLITE_BUSY or SQLITE_OK
 */
 #define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))
 
-/* Forward references */
-typedef struct unixShm unixShm;               /* Connection shared memory */
-typedef struct unixShmNode unixShmNode;       /* Shared memory instance */
-typedef struct unixInodeInfo unixInodeInfo;   /* An i-node */
-typedef struct UnixUnusedFd UnixUnusedFd;     /* An unused file descriptor */
 
 /*
 ** Sometimes, after a file handle is closed by SQLite, the file descriptor
 ** cannot be closed immediately. In these cases, instances of the following
 ** structure are used to store the file descriptor while waiting for an
 ** opportunity to either close or reuse it.
 */
+typedef struct UnixUnusedFd UnixUnusedFd;
 struct UnixUnusedFd {
   int fd;                   /* File descriptor to close */
   int flags;                /* Flags this file descriptor was opened with */
   UnixUnusedFd *pNext;      /* Next unused file descriptor on same file */
 };
 
 /*
 ** The unixFile structure is subclass of sqlite3_file specific to the unix
 ** VFS implementations.
 */
 typedef struct unixFile unixFile;
 struct unixFile {
   sqlite3_io_methods const *pMethod;  /* Always the first entry */
-  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 */
-  int lastErrno;                      /* The unix errno from last I/O error */
-  void *lockingContext;               /* Locking style specific state */
-  UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
-  int fileFlags;                      /* Miscellanous flags */
-  const char *zPath;                  /* Name of the file */
-  unixShm *pShm;                      /* Shared memory segment information */
+  struct unixOpenCnt *pOpen;       /* Info about all open fd's on this inode */
+  struct unixLockInfo *pLock;      /* Info about locks on this inode */
+  int h;                           /* The file descriptor */
+  int dirfd;                       /* File descriptor for the directory */
+  unsigned char locktype;          /* The type of lock held on this fd */
+  int lastErrno;                   /* The unix errno from the last I/O error */
+  void *lockingContext;            /* Locking style specific state */
+  UnixUnusedFd *pUnused;           /* Pre-allocated UnixUnusedFd */
+  int fileFlags;                   /* Miscellanous flags */
 #if SQLITE_ENABLE_LOCKING_STYLE
-  int openFlags;                      /* The flags specified at open() */
+  int openFlags;                   /* The flags specified at open() */
 #endif
 #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
-  unsigned fsFlags;                   /* cached details from statfs() */
+  unsigned fsFlags;                 /* cached details from statfs() */
+#endif
+#if SQLITE_THREADSAFE && defined(__linux__)
+  pthread_t tid;                   /* The thread that "owns" this unixFile */
 #endif
 #if OS_VXWORKS
-  int isDelete;                       /* Delete on close if true */
-  struct vxworksFileId *pId;          /* Unique file ID */
+  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
   ** one described by ticket #3584. 
@@ -22521,19 +22080,33 @@ struct unixFile {
 ** 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)
+#define OSTRACE1(X)         if( sqlite3OSTrace ) sqlite3DebugPrintf(X)
+#define OSTRACE2(X,Y)       if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y)
+#define OSTRACE3(X,Y,Z)     if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z)
+#define OSTRACE4(X,Y,Z,A)   if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A)
+#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B)
+#define OSTRACE6(X,Y,Z,A,B,C) \
+    if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
+#define OSTRACE7(X,Y,Z,A,B,C,D) \
+    if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
+#else
+#define OSTRACE1(X)
+#define OSTRACE2(X,Y)
+#define OSTRACE3(X,Y,Z)
+#define OSTRACE4(X,Y,Z,A)
+#define OSTRACE5(X,Y,Z,A,B)
+#define OSTRACE6(X,Y,Z,A,B,C)
+#define OSTRACE7(X,Y,Z,A,B,C,D)
 #endif
 
 /*
 ** Macros for performance tracing.  Normally turned off.  Only works
 ** on i486 hardware.
 */
 #ifdef SQLITE_PERFORMANCE_TRACE
 
@@ -22733,17 +22306,17 @@ SQLITE_API int sqlite3_open_file_count =
 #define threadid pthread_self()
 #else
 #define threadid 0
 #endif
 
 
 /*
 ** Helper functions to obtain and relinquish the global mutex. The
-** global mutex is used to protect the unixInodeInfo and
+** global mutex is used to protect the unixOpenCnt, unixLockInfo and
 ** vxworksFileId objects used by this file, all of which may be 
 ** shared by multiple threads.
 **
 ** Function unixMutexHeld() is used to assert() that the global mutex 
 ** is held when required. This function is only used as part of assert() 
 ** statements. e.g.
 **
 **   unixEnterMutex()
@@ -22764,18 +22337,18 @@ static int unixMutexHeld(void) {
 
 
 #ifdef SQLITE_DEBUG
 /*
 ** Helper function for printing out trace information from debugging
 ** binaries. This returns the string represetation of the supplied
 ** integer lock-type.
 */
-static const char *azFileLock(int eFileLock){
-  switch( eFileLock ){
+static const char *locktypeName(int locktype){
+  switch( locktype ){
     case NO_LOCK: return "NONE";
     case SHARED_LOCK: return "SHARED";
     case RESERVED_LOCK: return "RESERVED";
     case PENDING_LOCK: return "PENDING";
     case EXCLUSIVE_LOCK: return "EXCLUSIVE";
   }
   return "ERROR";
 }
@@ -23102,171 +22675,337 @@ static void vxworksReleaseFileId(struct 
 ** structure.  The fcntl() system call is only invoked to set a 
 ** POSIX lock if the internal lock structure transitions between
 ** a locked and an unlocked state.
 **
 ** But wait:  there are yet more problems with POSIX advisory locks.
 **
 ** If you close a file descriptor that points to a file that has locks,
 ** all locks on that file that are owned by the current process are
-** released.  To work around this problem, each unixInodeInfo object
-** maintains a count of the number of pending locks on tha inode.
-** When an attempt is made to close an unixFile, if there are
+** released.  To work around this problem, each unixFile structure contains
+** a pointer to an unixOpenCnt structure.  There is one unixOpenCnt structure
+** per open inode, which means that multiple unixFile can point to a single
+** unixOpenCnt.  When an attempt is made to close an unixFile, if there are
 ** other unixFile open on the same inode that are holding locks, the call
 ** to close() the file descriptor is deferred until all of the locks clear.
-** The unixInodeInfo structure keeps a list of file descriptors that need to
+** The unixOpenCnt structure keeps a list of file descriptors that need to
 ** be closed and that list is walked (and cleared) when the last lock
 ** clears.
 **
 ** Yet another problem:  LinuxThreads do not play well with posix locks.
 **
 ** Many older versions of linux use the LinuxThreads library which is
 ** not posix compliant.  Under LinuxThreads, a lock created by thread
 ** A cannot be modified or overridden by a different thread B.
 ** Only thread A can modify the lock.  Locking behavior is correct
 ** if the appliation uses the newer Native Posix Thread Library (NPTL)
 ** on linux - with NPTL a lock created by thread A can override locks
 ** in thread B.  But there is no way to know at compile-time which
 ** threading library is being used.  So there is no way to know at
 ** compile-time whether or not thread A can override locks on thread B.
-** One has to do a run-time check to discover the behavior of the
+** We have to do a run-time check to discover the behavior of the
 ** current process.
 **
-** SQLite used to support LinuxThreads.  But support for LinuxThreads
-** was dropped beginning with version 3.7.0.  SQLite will still work with
-** LinuxThreads provided that (1) there is no more than one connection 
-** per database file in the same process and (2) database connections
-** do not move across threads.
-*/
+** On systems where thread A is unable to modify locks created by
+** thread B, we have to keep track of which thread created each
+** lock.  Hence there is an extra field in the key to the unixLockInfo
+** structure to record this information.  And on those systems it
+** is illegal to begin a transaction in one thread and finish it
+** in another.  For this latter restriction, there is no work-around.
+** It is a limitation of LinuxThreads.
+*/
+
+/*
+** Set or check the unixFile.tid field.  This field is set when an unixFile
+** is first opened.  All subsequent uses of the unixFile verify that the
+** same thread is operating on the unixFile.  Some operating systems do
+** not allow locks to be overridden by other threads and that restriction
+** means that sqlite3* database handles cannot be moved from one thread
+** to another while locks are held.
+**
+** Version 3.3.1 (2006-01-15):  unixFile can be moved from one thread to
+** another as long as we are running on a system that supports threads
+** overriding each others locks (which is now the most common behavior)
+** or if no locks are held.  But the unixFile.pLock field needs to be
+** recomputed because its key includes the thread-id.  See the 
+** transferOwnership() function below for additional information
+*/
+#if SQLITE_THREADSAFE && defined(__linux__)
+# define SET_THREADID(X)   (X)->tid = pthread_self()
+# define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \
+                            !pthread_equal((X)->tid, pthread_self()))
+#else
+# define SET_THREADID(X)
+# define CHECK_THREADID(X) 0
+#endif
 
 /*
 ** An instance of the following structure serves as the key used
-** to locate a particular unixInodeInfo object.
+** to locate a particular unixOpenCnt structure given its inode.  This
+** is the same as the unixLockKey except that the thread ID is omitted.
 */
 struct unixFileId {
   dev_t dev;                  /* Device number */
 #if OS_VXWORKS
   struct vxworksFileId *pId;  /* Unique file ID for vxworks. */
 #else
   ino_t ino;                  /* Inode number */
 #endif
 };
 
 /*
+** An instance of the following structure serves as the key used
+** to locate a particular unixLockInfo structure given its inode.
+**
+** If threads cannot override each others locks (LinuxThreads), then we
+** set the unixLockKey.tid field to the thread ID.  If threads can override
+** each others locks (Posix and NPTL) then tid is always set to zero.
+** tid is omitted if we compile without threading support or on an OS
+** other than linux.
+*/
+struct unixLockKey {
+  struct unixFileId fid;  /* Unique identifier for the file */
+#if SQLITE_THREADSAFE && defined(__linux__)
+  pthread_t tid;  /* Thread ID of lock owner. Zero if not using LinuxThreads */
+#endif
+};
+
+/*
 ** An instance of the following structure is allocated for each open
 ** inode.  Or, on LinuxThreads, there is one of these structures for
 ** each inode opened by each thread.
 **
 ** A single inode can have multiple file descriptors, so each unixFile
 ** structure contains a pointer to an instance of this object and this
 ** object keeps a count of the number of unixFile pointing to it.
 */
-struct unixInodeInfo {
-  struct unixFileId fileId;       /* The lookup key */
-  int nShared;                    /* Number of SHARED locks held */
-  int eFileLock;                  /* One of SHARED_LOCK, RESERVED_LOCK etc. */
+struct unixLockInfo {
+  struct unixLockKey lockKey;     /* The lookup key */
+  int cnt;                        /* Number of SHARED locks held */
+  int locktype;                   /* One of SHARED_LOCK, RESERVED_LOCK etc. */
   int nRef;                       /* Number of pointers to this structure */
-  unixShmNode *pShmNode;          /* Shared memory associated with this inode */
-  int nLock;                      /* Number of outstanding file locks */
-  UnixUnusedFd *pUnused;          /* Unused file descriptors to close */
-  unixInodeInfo *pNext;           /* List of all unixInodeInfo objects */
-  unixInodeInfo *pPrev;           /*    .... doubly linked */
 #if defined(SQLITE_ENABLE_LOCKING_STYLE)
   unsigned long long sharedByte;  /* for AFP simulated shared lock */
 #endif
+  struct unixLockInfo *pNext;     /* List of all unixLockInfo objects */
+  struct unixLockInfo *pPrev;     /*    .... doubly linked */
+};
+
+/*
+** An instance of the following structure is allocated for each open
+** inode.  This structure keeps track of the number of locks on that
+** inode.  If a close is attempted against an inode that is holding
+** locks, the close is deferred until all locks clear by adding the
+** file descriptor to be closed to the pending list.
+**
+** TODO:  Consider changing this so that there is only a single file
+** descriptor for each open file, even when it is opened multiple times.
+** The close() system call would only occur when the last database
+** using the file closes.
+*/
+struct unixOpenCnt {
+  struct unixFileId fileId;   /* The lookup key */
+  int nRef;                   /* Number of pointers to this structure */
+  int nLock;                  /* Number of outstanding locks */
+  UnixUnusedFd *pUnused;      /* Unused file descriptors to close */
 #if OS_VXWORKS
-  sem_t *pSem;                    /* Named POSIX semaphore */
-  char aSemName[MAX_PATHNAME+2];  /* Name of that semaphore */
-#endif
-};
-
-/*
-** A lists of all unixInodeInfo objects.
-*/
-static unixInodeInfo *inodeList = 0;
-
-/*
-** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
-** If all such file descriptors are closed without error, the list is
-** cleared and SQLITE_OK returned.
-**
-** Otherwise, if an error occurs, then successfully closed file descriptor
-** entries are removed from the list, and SQLITE_IOERR_CLOSE returned. 
-** not deleted and SQLITE_IOERR_CLOSE returned.
+  sem_t *pSem;                     /* Named POSIX semaphore */
+  char aSemName[MAX_PATHNAME+2];   /* Name of that semaphore */
+#endif
+  struct unixOpenCnt *pNext, *pPrev;   /* List of all unixOpenCnt objects */
+};
+
+/*
+** Lists of all unixLockInfo and unixOpenCnt objects.  These used to be hash
+** tables.  But the number of objects is rarely more than a dozen and
+** never exceeds a few thousand.  And lookup is not on a critical
+** path so a simple linked list will suffice.
+*/
+static struct unixLockInfo *lockList = 0;
+static struct unixOpenCnt *openList = 0;
+
+/*
+** This variable remembers whether or not threads can override each others
+** locks.
+**
+**    0:  No.  Threads cannot override each others locks.  (LinuxThreads)
+**    1:  Yes.  Threads can override each others locks.  (Posix & NLPT)
+**   -1:  We don't know yet.
+**
+** On some systems, we know at compile-time if threads can override each
+** others locks.  On those systems, the SQLITE_THREAD_OVERRIDE_LOCK macro
+** will be set appropriately.  On other systems, we have to check at
+** runtime.  On these latter systems, SQLTIE_THREAD_OVERRIDE_LOCK is
+** undefined.
+**
+** This variable normally has file scope only.  But during testing, we make
+** it a global so that the test code can change its value in order to verify
+** that the right stuff happens in either case.
+*/
+#if SQLITE_THREADSAFE && defined(__linux__)
+#  ifndef SQLITE_THREAD_OVERRIDE_LOCK
+#    define SQLITE_THREAD_OVERRIDE_LOCK -1
+#  endif
+#  ifdef SQLITE_TEST
+int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
+#  else
+static int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
+#  endif
+#endif
+
+/*
+** This structure holds information passed into individual test
+** threads by the testThreadLockingBehavior() routine.
+*/
+struct threadTestData {
+  int fd;                /* File to be locked */
+  struct flock lock;     /* The locking operation */
+  int result;            /* Result of the locking operation */
+};
+
+#if SQLITE_THREADSAFE && defined(__linux__)
+/*
+** This function is used as the main routine for a thread launched by
+** testThreadLockingBehavior(). It tests whether the shared-lock obtained
+** by the main thread in testThreadLockingBehavior() conflicts with a
+** hypothetical write-lock obtained by this thread on the same file.
+**
+** The write-lock is not actually acquired, as this is not possible if 
+** the file is open in read-only mode (see ticket #3472).
 */ 
-static int closePendingFds(unixFile *pFile){
-  int rc = SQLITE_OK;
-  unixInodeInfo *pInode = pFile->pInode;
-  UnixUnusedFd *pError = 0;
-  UnixUnusedFd *p;
-  UnixUnusedFd *pNext;
-  for(p=pInode->pUnused; p; p=pNext){
-    pNext = p->pNext;
-    if( close(p->fd) ){
-      pFile->lastErrno = errno;
-      rc = SQLITE_IOERR_CLOSE;
-      p->pNext = pError;
-      pError = p;
-    }else{
-      sqlite3_free(p);
-    }
-  }
-  pInode->pUnused = pError;
-  return rc;
-}
-
-/*
-** Release a unixInodeInfo structure previously allocated by findInodeInfo().
+static void *threadLockingTest(void *pArg){
+  struct threadTestData *pData = (struct threadTestData*)pArg;
+  pData->result = fcntl(pData->fd, F_GETLK, &pData->lock);
+  return pArg;
+}
+#endif /* SQLITE_THREADSAFE && defined(__linux__) */
+
+
+#if SQLITE_THREADSAFE && defined(__linux__)
+/*
+** This procedure attempts to determine whether or not threads
+** can override each others locks then sets the 
+** threadsOverrideEachOthersLocks variable appropriately.
+*/
+static void testThreadLockingBehavior(int fd_orig){
+  int fd;
+  int rc;
+  struct threadTestData d;
+  struct flock l;
+  pthread_t t;
+
+  fd = dup(fd_orig);
+  if( fd<0 ) return;
+  memset(&l, 0, sizeof(l));
+  l.l_type = F_RDLCK;
+  l.l_len = 1;
+  l.l_start = 0;
+  l.l_whence = SEEK_SET;
+  rc = fcntl(fd_orig, F_SETLK, &l);
+  if( rc!=0 ) return;
+  memset(&d, 0, sizeof(d));
+  d.fd = fd;
+  d.lock = l;
+  d.lock.l_type = F_WRLCK;
+  if( pthread_create(&t, 0, threadLockingTest, &d)==0 ){
+    pthread_join(t, 0);
+  }
+  close(fd);
+  if( d.result!=0 ) return;
+  threadsOverrideEachOthersLocks = (d.lock.l_type==F_UNLCK);
+}
+#endif /* SQLITE_THREADSAFE && defined(__linux__) */
+
+/*
+** Release a unixLockInfo structure previously allocated by findLockInfo().
 **
 ** The mutex entered using the unixEnterMutex() function must be held
 ** when this function is called.
 */
-static void releaseInodeInfo(unixFile *pFile){
-  unixInodeInfo *pInode = pFile->pInode;
+static void releaseLockInfo(struct unixLockInfo *pLock){
+  assert( unixMutexHeld() );
+  if( pLock ){
+    pLock->nRef--;
+    if( pLock->nRef==0 ){
+      if( pLock->pPrev ){
+        assert( pLock->pPrev->pNext==pLock );
+        pLock->pPrev->pNext = pLock->pNext;
+      }else{
+        assert( lockList==pLock );
+        lockList = pLock->pNext;
+      }
+      if( pLock->pNext ){
+        assert( pLock->pNext->pPrev==pLock );
+        pLock->pNext->pPrev = pLock->pPrev;
+      }
+      sqlite3_free(pLock);
+    }
+  }
+}
+
+/*
+** Release a unixOpenCnt structure previously allocated by findLockInfo().
+**
+** The mutex entered using the unixEnterMutex() function must be held
+** when this function is called.
+*/
+static void releaseOpenCnt(struct unixOpenCnt *pOpen){
   assert( unixMutexHeld() );
-  if( pInode ){
-    pInode->nRef--;
-    if( pInode->nRef==0 ){
-      assert( pInode->pShmNode==0 );
-      closePendingFds(pFile);
-      if( pInode->pPrev ){
-        assert( pInode->pPrev->pNext==pInode );
-        pInode->pPrev->pNext = pInode->pNext;
-      }else{
-        assert( inodeList==pInode );
-        inodeList = pInode->pNext;
-      }
-      if( pInode->pNext ){
-        assert( pInode->pNext->pPrev==pInode );
-        pInode->pNext->pPrev = pInode->pPrev;
-      }
-      sqlite3_free(pInode);
-    }
-  }
-}
-
-/*
-** Given a file descriptor, locate the unixInodeInfo object that
-** describes that file descriptor.  Create a new one if necessary.  The
-** return value might be uninitialized if an error occurs.
+  if( pOpen ){
+    pOpen->nRef--;
+    if( pOpen->nRef==0 ){
+      if( pOpen->pPrev ){
+        assert( pOpen->pPrev->pNext==pOpen );
+        pOpen->pPrev->pNext = pOpen->pNext;
+      }else{
+        assert( openList==pOpen );
+        openList = pOpen->pNext;
+      }
+      if( pOpen->pNext ){
+        assert( pOpen->pNext->pPrev==pOpen );
+        pOpen->pNext->pPrev = pOpen->pPrev;
+      }
+#if SQLITE_THREADSAFE && defined(__linux__)
+      assert( !pOpen->pUnused || threadsOverrideEachOthersLocks==0 );
+#endif
+
+      /* If pOpen->pUnused is not null, then memory and file-descriptors
+      ** are leaked.
+      **
+      ** This will only happen if, under Linuxthreads, the user has opened
+      ** a transaction in one thread, then attempts to close the database
+      ** handle from another thread (without first unlocking the db file).
+      ** This is a misuse.  */
+      sqlite3_free(pOpen);
+    }
+  }
+}
+
+/*
+** Given a file descriptor, locate unixLockInfo and unixOpenCnt structures that
+** describes that file descriptor.  Create new ones if necessary.  The
+** return values might be uninitialized if an error occurs.
 **
 ** The mutex entered using the unixEnterMutex() function must be held
 ** when this function is called.
 **
 ** Return an appropriate error code.
 */
-static int findInodeInfo(
+static int findLockInfo(
   unixFile *pFile,               /* Unix file with file desc used in the key */
-  unixInodeInfo **ppInode        /* Return the unixInodeInfo object here */
+  struct unixLockInfo **ppLock,  /* Return the unixLockInfo structure here */
+  struct unixOpenCnt **ppOpen    /* Return the unixOpenCnt structure here */
 ){
   int rc;                        /* System call return code */
   int fd;                        /* The file descriptor for pFile */
-  struct unixFileId fileId;      /* Lookup key for the unixInodeInfo */
+  struct unixLockKey lockKey;    /* Lookup key for the unixLockInfo structure */
+  struct unixFileId fileId;      /* Lookup key for the unixOpenCnt struct */
   struct stat statbuf;           /* Low-level file information */
-  unixInodeInfo *pInode = 0;     /* Candidate unixInodeInfo object */
+  struct unixLockInfo *pLock = 0;/* Candidate unixLockInfo object */
+  struct unixOpenCnt *pOpen;     /* Candidate unixOpenCnt object */
 
   assert( unixMutexHeld() );
 
   /* Get low-level information about the file that we can used to
   ** create a unique name for the file.
   */
   fd = pFile->h;
   rc = fstat(fd, &statbuf);
@@ -23298,65 +23037,152 @@ static int findInodeInfo(
     rc = fstat(fd, &statbuf);
     if( rc!=0 ){
       pFile->lastErrno = errno;
       return SQLITE_IOERR;
     }
   }
 #endif
 
-  memset(&fileId, 0, sizeof(fileId));
-  fileId.dev = statbuf.st_dev;
+  memset(&lockKey, 0, sizeof(lockKey));
+  lockKey.fid.dev = statbuf.st_dev;
 #if OS_VXWORKS
-  fileId.pId = pFile->pId;
-#else
-  fileId.ino = statbuf.st_ino;
-#endif
-  pInode = inodeList;
-  while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
-    pInode = pInode->pNext;
-  }
-  if( pInode==0 ){
-    pInode = sqlite3_malloc( sizeof(*pInode) );
-    if( pInode==0 ){
-      return SQLITE_NOMEM;
-    }
-    memset(pInode, 0, sizeof(*pInode));
-    memcpy(&pInode->fileId, &fileId, sizeof(fileId));
-    pInode->nRef = 1;
-    pInode->pNext = inodeList;
-    pInode->pPrev = 0;
-    if( inodeList ) inodeList->pPrev = pInode;
-    inodeList = pInode;
-  }else{
-    pInode->nRef++;
-  }
-  *ppInode = pInode;
-  return SQLITE_OK;
-}
+  lockKey.fid.pId = pFile->pId;
+#else
+  lockKey.fid.ino = statbuf.st_ino;
+#endif
+#if SQLITE_THREADSAFE && defined(__linux__)
+  if( threadsOverrideEachOthersLocks<0 ){
+    testThreadLockingBehavior(fd);
+  }
+  lockKey.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self();
+#endif
+  fileId = lockKey.fid;
+  if( ppLock!=0 ){
+    pLock = lockList;
+    while( pLock && memcmp(&lockKey, &pLock->lockKey, sizeof(lockKey)) ){
+      pLock = pLock->pNext;
+    }
+    if( pLock==0 ){
+      pLock = sqlite3_malloc( sizeof(*pLock) );
+      if( pLock==0 ){
+        rc = SQLITE_NOMEM;
+        goto exit_findlockinfo;
+      }
+      memcpy(&pLock->lockKey,&lockKey,sizeof(lockKey));
+      pLock->nRef = 1;
+      pLock->cnt = 0;
+      pLock->locktype = 0;
+#if defined(SQLITE_ENABLE_LOCKING_STYLE)
+      pLock->sharedByte = 0;
+#endif
+      pLock->pNext = lockList;
+      pLock->pPrev = 0;
+      if( lockList ) lockList->pPrev = pLock;
+      lockList = pLock;
+    }else{
+      pLock->nRef++;
+    }
+    *ppLock = pLock;
+  }
+  if( ppOpen!=0 ){
+    pOpen = openList;
+    while( pOpen && memcmp(&fileId, &pOpen->fileId, sizeof(fileId)) ){
+      pOpen = pOpen->pNext;
+    }
+    if( pOpen==0 ){
+      pOpen = sqlite3_malloc( sizeof(*pOpen) );
+      if( pOpen==0 ){
+        releaseLockInfo(pLock);
+        rc = SQLITE_NOMEM;
+        goto exit_findlockinfo;
+      }
+      memset(pOpen, 0, sizeof(*pOpen));
+      pOpen->fileId = fileId;
+      pOpen->nRef = 1;
+      pOpen->pNext = openList;
+      if( openList ) openList->pPrev = pOpen;
+      openList = pOpen;
+    }else{
+      pOpen->nRef++;
+    }
+    *ppOpen = pOpen;
+  }
+
+exit_findlockinfo:
+  return rc;
+}
+
+/*
+** If we are currently in a different thread than the thread that the
+** unixFile argument belongs to, then transfer ownership of the unixFile
+** over to the current thread.
+**
+** A unixFile is only owned by a thread on systems that use LinuxThreads.
+**
+** Ownership transfer is only allowed if the unixFile is currently unlocked.
+** If the unixFile is locked and an ownership is wrong, then return
+** SQLITE_MISUSE.  SQLITE_OK is returned if everything works.
+*/
+#if SQLITE_THREADSAFE && defined(__linux__)
+static int transferOwnership(unixFile *pFile){
+  int rc;
+  pthread_t hSelf;
+  if( threadsOverrideEachOthersLocks ){
+    /* Ownership transfers not needed on this system */
+    return SQLITE_OK;
+  }
+  hSelf = pthread_self();
+  if( pthread_equal(pFile->tid, hSelf) ){
+    /* We are still in the same thread */
+    OSTRACE1("No-transfer, same thread\n");
+    return SQLITE_OK;
+  }
+  if( pFile->locktype!=NO_LOCK ){
+    /* We cannot change ownership while we are holding a lock! */
+    return SQLITE_MISUSE_BKPT;
+  }
+  OSTRACE4("Transfer ownership of %d from %d to %d\n",
+            pFile->h, pFile->tid, hSelf);
+  pFile->tid = hSelf;
+  if (pFile->pLock != NULL) {
+    releaseLockInfo(pFile->pLock);
+    rc = findLockInfo(pFile, &pFile->pLock, 0);
+    OSTRACE5("LOCK    %d is now %s(%s,%d)\n", pFile->h,
+           locktypeName(pFile->locktype),
+           locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
+    return rc;
+  } else {
+    return SQLITE_OK;
+  }
+}
+#else  /* if not SQLITE_THREADSAFE */
+  /* On single-threaded builds, ownership transfer is a no-op */
+# define transferOwnership(X) SQLITE_OK
+#endif /* SQLITE_THREADSAFE */
 
 
 /*
 ** 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.
 */
 static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
   int rc = SQLITE_OK;
   int reserved = 0;
   unixFile *pFile = (unixFile*)id;
 
   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
 
   assert( pFile );
-  unixEnterMutex(); /* Because pFile->pInode is shared across threads */
+  unixEnterMutex(); /* Because pFile->pLock is shared across threads */
 
   /* Check if a thread in this process holds such a lock */
-  if( pFile->pInode->eFileLock>SHARED_LOCK ){
+  if( pFile->pLock->locktype>SHARED_LOCK ){
     reserved = 1;
   }
 
   /* Otherwise see if some other process holds it.
   */
 #ifndef __DJGPP__
   if( !reserved ){
     struct flock lock;
@@ -23370,24 +23196,24 @@ static int unixCheckReservedLock(sqlite3
       pFile->lastErrno = tErrno;
     } else if( lock.l_type!=F_UNLCK ){
       reserved = 1;
     }
   }
 #endif
   
   unixLeaveMutex();
-  OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved));
+  OSTRACE4("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved);
 
   *pResOut = reserved;
   return rc;
 }
 
 /*
-** Lock the file with the lock specified by parameter eFileLock - one
+** Lock the file with the lock specified by parameter locktype - one
 ** of the following:
 **
 **     (1) SHARED_LOCK
 **     (2) RESERVED_LOCK
 **     (3) PENDING_LOCK
 **     (4) EXCLUSIVE_LOCK
 **
 ** Sometimes when requesting one lock state, additional lock states
@@ -23400,17 +23226,17 @@ static int unixCheckReservedLock(sqlite3
 **    SHARED -> RESERVED
 **    SHARED -> (PENDING) -> EXCLUSIVE
 **    RESERVED -> (PENDING) -> EXCLUSIVE
 **    PENDING -> EXCLUSIVE
 **
 ** This routine will only increase a lock.  Use the sqlite3OsUnlock()
 ** routine to lower a locking level.
 */
-static int unixLock(sqlite3_file *id, int eFileLock){
+static int unixLock(sqlite3_file *id, int locktype){
   /* The following describes the implementation of the various locks and
   ** lock transitions in terms of the POSIX advisory shared and exclusive
   ** lock primitives (called read-locks and write-locks below, to avoid
   ** confusion with SQLite lock names). The algorithms are complicated
   ** slightly in order to be compatible with windows systems simultaneously
   ** accessing the same database file, in case that is ever required.
   **
   ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
@@ -23441,105 +23267,113 @@ 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;
+  struct unixLockInfo *pLock = pFile->pLock;
   struct flock lock;
   int s = 0;
   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()));
+  OSTRACE7("LOCK    %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
+      locktypeName(locktype), locktypeName(pFile->locktype),
+      locktypeName(pLock->locktype), pLock->cnt , getpid());
 
   /* If there is already a lock of this type or more restrictive on the
   ** unixFile, do nothing. Don't use the end_lock: exit path, as
   ** unixEnterMutex() hasn't been called yet.
   */
-  if( pFile->eFileLock>=eFileLock ){
-    OSTRACE(("LOCK    %d %s ok (already held) (unix)\n", pFile->h,
-            azFileLock(eFileLock)));
+  if( pFile->locktype>=locktype ){
+    OSTRACE3("LOCK    %d %s ok (already held) (unix)\n", pFile->h,
+            locktypeName(locktype));
     return SQLITE_OK;
   }
 
   /* Make sure the locking sequence is correct.
   **  (1) We never move from unlocked to anything higher than shared lock.
   **  (2) SQLite never explicitly requests a pendig lock.
   **  (3) A shared lock is always held when a reserve lock is requested.
   */
-  assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK );
-  assert( eFileLock!=PENDING_LOCK );
-  assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK );
-
-  /* This mutex is needed because pFile->pInode is shared across threads
+  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+  assert( locktype!=PENDING_LOCK );
+  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
+
+  /* This mutex is needed because pFile->pLock is shared across threads
   */
   unixEnterMutex();
-  pInode = pFile->pInode;
+
+  /* Make sure the current thread owns the pFile.
+  */
+  rc = transferOwnership(pFile);
+  if( rc!=SQLITE_OK ){
+    unixLeaveMutex();
+    return rc;
+  }
+  pLock = pFile->pLock;
 
   /* If some thread using this PID has a lock via a different unixFile*
   ** handle that precludes the requested lock, return BUSY.
   */
-  if( (pFile->eFileLock!=pInode->eFileLock && 
-          (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK))
+  if( (pFile->locktype!=pLock->locktype && 
+          (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK))
   ){
     rc = SQLITE_BUSY;
     goto end_lock;
   }
 
   /* If a SHARED lock is requested, and some thread using this PID already
   ** has a SHARED or RESERVED lock, then increment reference counts and
   ** return SQLITE_OK.
   */
-  if( eFileLock==SHARED_LOCK && 
-      (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){
-    assert( eFileLock==SHARED_LOCK );
-    assert( pFile->eFileLock==0 );
-    assert( pInode->nShared>0 );
-    pFile->eFileLock = SHARED_LOCK;
-    pInode->nShared++;
-    pInode->nLock++;
+  if( locktype==SHARED_LOCK && 
+      (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){
+    assert( locktype==SHARED_LOCK );
+    assert( pFile->locktype==0 );
+    assert( pLock->cnt>0 );
+    pFile->locktype = SHARED_LOCK;
+    pLock->cnt++;
+    pFile->pOpen->nLock++;
     goto end_lock;
   }
 
 
   /* A PENDING lock is needed before acquiring a SHARED lock and before
   ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
   ** be released.
   */
   lock.l_len = 1L;
   lock.l_whence = SEEK_SET;
-  if( eFileLock==SHARED_LOCK 
-      || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK)
+  if( locktype==SHARED_LOCK 
+      || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
   ){
-    lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK);
+    lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
     lock.l_start = PENDING_BYTE;
     s = fcntl(pFile->h, F_SETLK, &lock);
     if( s==(-1) ){
       tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( IS_LOCK_ERROR(rc) ){
         pFile->lastErrno = tErrno;
       }
       goto end_lock;
     }
   }
 
 
   /* If control gets to this point, then actually go ahead and make
   ** operating system calls for the specified lock.
   */
-  if( eFileLock==SHARED_LOCK ){
-    assert( pInode->nShared==0 );
-    assert( pInode->eFileLock==0 );
+  if( locktype==SHARED_LOCK ){
+    assert( pLock->cnt==0 );
+    assert( pLock->locktype==0 );
 
     /* Now get the read-lock */
     lock.l_start = SHARED_FIRST;
     lock.l_len = SHARED_SIZE;
     if( (s = fcntl(pFile->h, F_SETLK, &lock))==(-1) ){
       tErrno = errno;
     }
     /* Drop the temporary PENDING lock */
@@ -23558,32 +23392,32 @@ static int unixLock(sqlite3_file *id, in
       }
     }
     if( s==(-1) ){
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( IS_LOCK_ERROR(rc) ){
         pFile->lastErrno = tErrno;
       }
     }else{
-      pFile->eFileLock = SHARED_LOCK;
-      pInode->nLock++;
-      pInode->nShared = 1;
-    }
-  }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
+      pFile->locktype = SHARED_LOCK;
+      pFile->pOpen->nLock++;
+      pLock->cnt = 1;
+    }
+  }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){
     /* We are trying for an exclusive lock but another thread in this
     ** same process is still holding a shared lock. */
     rc = SQLITE_BUSY;
   }else{
     /* The request was for a RESERVED or EXCLUSIVE lock.  It is
     ** assumed that there is a SHARED or greater lock on the file
     ** already.
     */
-    assert( 0!=pFile->eFileLock );
+    assert( 0!=pFile->locktype );
     lock.l_type = F_WRLCK;
-    switch( eFileLock ){
+    switch( locktype ){
       case RESERVED_LOCK:
         lock.l_start = RESERVED_BYTE;
         break;
       case EXCLUSIVE_LOCK:
         lock.l_start = SHARED_FIRST;
         lock.l_len = SHARED_SIZE;
         break;
       default:
@@ -23602,121 +23436,151 @@ static int unixLock(sqlite3_file *id, in
 
 #ifndef NDEBUG
   /* Set up the transaction-counter change checking flags when
   ** transitioning from a SHARED to a RESERVED lock.  The change
   ** from SHARED to RESERVED marks the beginning of a normal
   ** write operation (not a hot journal rollback).
   */
   if( rc==SQLITE_OK
-   && pFile->eFileLock<=SHARED_LOCK
-   && eFileLock==RESERVED_LOCK
+   && pFile->locktype<=SHARED_LOCK
+   && locktype==RESERVED_LOCK
   ){
     pFile->transCntrChng = 0;
     pFile->dbUpdate = 0;
     pFile->inNormalWrite = 1;
   }
 #endif
 
 
   if( rc==SQLITE_OK ){
-    pFile->eFileLock = eFileLock;
-    pInode->eFileLock = eFileLock;
-  }else if( eFileLock==EXCLUSIVE_LOCK ){
-    pFile->eFileLock = PENDING_LOCK;
-    pInode->eFileLock = PENDING_LOCK;
+    pFile->locktype = locktype;
+    pLock->locktype = locktype;
+  }else if( locktype==EXCLUSIVE_LOCK ){
+    pFile->locktype = PENDING_LOCK;
+    pLock->locktype = PENDING_LOCK;
   }
 
 end_lock:
   unixLeaveMutex();
-  OSTRACE(("LOCK    %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), 
-      rc==SQLITE_OK ? "ok" : "failed"));
+  OSTRACE4("LOCK    %d %s %s (unix)\n", pFile->h, locktypeName(locktype), 
+      rc==SQLITE_OK ? "ok" : "failed");
+  return rc;
+}
+
+/*
+** Close all file descriptors accumuated in the unixOpenCnt->pUnused list.
+** If all such file descriptors are closed without error, the list is
+** cleared and SQLITE_OK returned.
+**
+** Otherwise, if an error occurs, then successfully closed file descriptor
+** entries are removed from the list, and SQLITE_IOERR_CLOSE returned. 
+** not deleted and SQLITE_IOERR_CLOSE returned.
+*/ 
+static int closePendingFds(unixFile *pFile){
+  int rc = SQLITE_OK;
+  struct unixOpenCnt *pOpen = pFile->pOpen;
+  UnixUnusedFd *pError = 0;
+  UnixUnusedFd *p;
+  UnixUnusedFd *pNext;
+  for(p=pOpen->pUnused; p; p=pNext){
+    pNext = p->pNext;
+    if( close(p->fd) ){
+      pFile->lastErrno = errno;
+      rc = SQLITE_IOERR_CLOSE;
+      p->pNext = pError;
+      pError = p;
+    }else{
+      sqlite3_free(p);
+    }
+  }
+  pOpen->pUnused = pError;
   return rc;
 }
 
 /*
 ** Add the file descriptor used by file handle pFile to the corresponding
 ** pUnused list.
 */
 static void setPendingFd(unixFile *pFile){
-  unixInodeInfo *pInode = pFile->pInode;
+  struct unixOpenCnt *pOpen = pFile->pOpen;
   UnixUnusedFd *p = pFile->pUnused;
-  p->pNext = pInode->pUnused;
-  pInode->pUnused = p;
+  p->pNext = pOpen->pUnused;
+  pOpen->pUnused = p;
   pFile->h = -1;
   pFile->pUnused = 0;
 }
 
 /*
-** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
+** Lower the locking level on file descriptor pFile to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
 **
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 ** 
 ** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED
 ** the byte range is divided into 2 parts and the first part is unlocked then
 ** set to a read lock, then the other part is simply unlocked.  This works 
 ** 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){
+static int _posixUnlock(sqlite3_file *id, int locktype, int handleNFSUnlock){
   unixFile *pFile = (unixFile*)id;
-  unixInodeInfo *pInode;
+  struct unixLockInfo *pLock;
   struct flock lock;
   int rc = SQLITE_OK;
   int h;
   int tErrno;                      /* Error code from system call errors */
 
   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 ){
+  OSTRACE7("UNLOCK  %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, locktype,
+      pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid());
+
+  assert( locktype<=SHARED_LOCK );
+  if( pFile->locktype<=locktype ){
     return SQLITE_OK;
   }
+  if( CHECK_THREADID(pFile) ){
+    return SQLITE_MISUSE_BKPT;
+  }
   unixEnterMutex();
   h = pFile->h;
-  pInode = pFile->pInode;
-  assert( pInode->nShared!=0 );
-  if( pFile->eFileLock>SHARED_LOCK ){
-    assert( pInode->eFileLock==pFile->eFileLock );
+  pLock = pFile->pLock;
+  assert( pLock->cnt!=0 );
+  if( pFile->locktype>SHARED_LOCK ){
+    assert( pLock->locktype==pFile->locktype );
     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]
     **  2:   [....W]
     **  3:   [RRRRW]
     **  4:   [RRRR.]
     */
-    if( eFileLock==SHARED_LOCK ){
+    if( locktype==SHARED_LOCK ){
       if( handleNFSUnlock ){
         off_t divSize = SHARED_SIZE - 1;
         
         lock.l_type = F_UNLCK;
         lock.l_whence = SEEK_SET;
         lock.l_start = SHARED_FIRST;
         lock.l_len = divSize;
         if( fcntl(h, F_SETLK, &lock)==(-1) ){
@@ -23766,81 +23630,84 @@ static int _posixUnlock(sqlite3_file *id
         }
       }
     }
     lock.l_type = F_UNLCK;
     lock.l_whence = SEEK_SET;
     lock.l_start = PENDING_BYTE;
     lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
     if( fcntl(h, F_SETLK, &lock)!=(-1) ){
-      pInode->eFileLock = SHARED_LOCK;
+      pLock->locktype = SHARED_LOCK;
     }else{
       tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
       if( IS_LOCK_ERROR(rc) ){
         pFile->lastErrno = tErrno;
       }
       goto end_unlock;
     }
   }
-  if( eFileLock==NO_LOCK ){
+  if( locktype==NO_LOCK ){
+    struct unixOpenCnt *pOpen;
+
     /* Decrement the shared lock counter.  Release the lock using an
     ** OS call only when all threads in this same process have released
     ** the lock.
     */
-    pInode->nShared--;
-    if( pInode->nShared==0 ){
+    pLock->cnt--;
+    if( pLock->cnt==0 ){
       lock.l_type = F_UNLCK;
       lock.l_whence = SEEK_SET;
       lock.l_start = lock.l_len = 0L;
       SimulateIOErrorBenign(1);
       SimulateIOError( h=(-1) )
       SimulateIOErrorBenign(0);
       if( fcntl(h, F_SETLK, &lock)!=(-1) ){
-        pInode->eFileLock = NO_LOCK;
+        pLock->locktype = NO_LOCK;
       }else{
         tErrno = errno;
         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
         if( IS_LOCK_ERROR(rc) ){
           pFile->lastErrno = tErrno;
         }
-        pInode->eFileLock = NO_LOCK;
-        pFile->eFileLock = NO_LOCK;
+        pLock->locktype = NO_LOCK;
+        pFile->locktype = NO_LOCK;
       }
     }
 
     /* Decrement the count of locks against this same file.  When the
     ** count reaches zero, close any other file descriptors whose close
     ** was deferred because of outstanding locks.
     */
-    pInode->nLock--;
-    assert( pInode->nLock>=0 );
-    if( pInode->nLock==0 ){
+    pOpen = pFile->pOpen;
+    pOpen->nLock--;
+    assert( pOpen->nLock>=0 );
+    if( pOpen->nLock==0 ){
       int rc2 = closePendingFds(pFile);
       if( rc==SQLITE_OK ){
         rc = rc2;
       }
     }
   }
 	
 end_unlock:
   unixLeaveMutex();
-  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
-  return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
+  if( rc==SQLITE_OK ) pFile->locktype = locktype;
+  return rc;
+}
+
+/*
+** Lower the locking level on file descriptor pFile to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
 **
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 */
-static int unixUnlock(sqlite3_file *id, int eFileLock){
-  return _posixUnlock(id, eFileLock, 0);
+static int unixUnlock(sqlite3_file *id, int locktype){
+  return _posixUnlock(id, locktype, 0);
 }
 
 /*
 ** This function performs the parts of the "close file" operation 
 ** common to all locking schemes. It closes the directory and file
 ** handles, if they are valid, and sets all fields of the unixFile
 ** structure to 0.
 **
@@ -23871,42 +23738,43 @@ static int closeUnixFile(sqlite3_file *i
     if( pFile->pId ){
       if( pFile->isDelete ){
         unlink(pFile->pId->zCanonicalName);
       }
       vxworksReleaseFileId(pFile->pId);
       pFile->pId = 0;
     }
 #endif
-    OSTRACE(("CLOSE   %-3d\n", pFile->h));
+    OSTRACE2("CLOSE   %-3d\n", pFile->h);
     OpenCounter(-1);
     sqlite3_free(pFile->pUnused);
     memset(pFile, 0, sizeof(unixFile));
   }
   return SQLITE_OK;
 }
 
 /*
 ** Close a file.
 */
 static int unixClose(sqlite3_file *id){
   int rc = SQLITE_OK;
   if( id ){
     unixFile *pFile = (unixFile *)id;
     unixUnlock(id, NO_LOCK);
     unixEnterMutex();
-    if( pFile->pInode && pFile->pInode->nLock ){
+    if( pFile->pOpen && pFile->pOpen->nLock ){
       /* If there are outstanding locks, do not actually close the file just
       ** yet because that would clear those locks.  Instead, add the file
-      ** descriptor to pInode->pUnused list.  It will be automatically closed 
+      ** descriptor to pOpen->pUnused list.  It will be automatically closed 
       ** when the last lock is cleared.
       */
       setPendingFd(pFile);
     }
-    releaseInodeInfo(pFile);
+    releaseLockInfo(pFile->pLock);
+    releaseOpenCnt(pFile->pOpen);
     rc = closeUnixFile(id);
     unixLeaveMutex();
   }
   return rc;
 }
 
 /************** End of the posix advisory lock implementation *****************
 ******************************************************************************/
@@ -23995,32 +23863,32 @@ static int dotlockCheckReservedLock(sqli
   int reserved = 0;
   unixFile *pFile = (unixFile*)id;
 
   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
   
   assert( pFile );
 
   /* Check if a thread in this process holds such a lock */
-  if( pFile->eFileLock>SHARED_LOCK ){
+  if( pFile->locktype>SHARED_LOCK ){
     /* Either this connection or some other connection in the same process
     ** holds a lock on the file.  No need to check further. */
     reserved = 1;
   }else{
     /* The lock is held if and only if the lockfile exists */
     const char *zLockFile = (const char*)pFile->lockingContext;
     reserved = access(zLockFile, 0)==0;
   }
-  OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
+  OSTRACE4("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved);
   *pResOut = reserved;
   return rc;
 }
 
 /*
-** Lock the file with the lock specified by parameter eFileLock - one
+** Lock the file with the lock specified by parameter locktype - one
 ** of the following:
 **
 **     (1) SHARED_LOCK
 **     (2) RESERVED_LOCK
 **     (3) PENDING_LOCK
 **     (4) EXCLUSIVE_LOCK
 **
 ** Sometimes when requesting one lock state, additional lock states
@@ -24036,28 +23904,28 @@ static int dotlockCheckReservedLock(sqli
 **    PENDING -> EXCLUSIVE
 **
 ** 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) {
+static int dotlockLock(sqlite3_file *id, int locktype) {
   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 ){
-    pFile->eFileLock = eFileLock;
+  if( pFile->locktype > NO_LOCK ){
+    pFile->locktype = locktype;
 #if !OS_VXWORKS
     /* Always update the timestamp on the old file */
     utimes(zLockFile, NULL);
 #endif
     return SQLITE_OK;
   }
   
   /* grab an exclusive lock */
@@ -24076,65 +23944,65 @@ static int dotlockLock(sqlite3_file *id,
     return rc;
   } 
   if( close(fd) ){
     pFile->lastErrno = errno;
     rc = SQLITE_IOERR_CLOSE;
   }
   
   /* got it, set the type and return ok */
-  pFile->eFileLock = eFileLock;
-  return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
+  pFile->locktype = locktype;
+  return rc;
+}
+
+/*
+** Lower the locking level on file descriptor pFile to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
 **
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 **
 ** When the locking level reaches NO_LOCK, delete the lock file.
 */
-static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
+static int dotlockUnlock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
   char *zLockFile = (char *)pFile->lockingContext;
 
   assert( pFile );
-  OSTRACE(("UNLOCK  %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
-	   pFile->eFileLock, getpid()));
-  assert( eFileLock<=SHARED_LOCK );
+  OSTRACE5("UNLOCK  %d %d was %d pid=%d (dotlock)\n", pFile->h, locktype,
+	   pFile->locktype, getpid());
+  assert( locktype<=SHARED_LOCK );
   
   /* no-op if possible */
-  if( pFile->eFileLock==eFileLock ){
+  if( pFile->locktype==locktype ){
     return SQLITE_OK;
   }
 
   /* To downgrade to shared, simply update our internal notion of the
   ** lock state.  No need to mess with the file on disk.
   */
-  if( eFileLock==SHARED_LOCK ){
-    pFile->eFileLock = SHARED_LOCK;
+  if( locktype==SHARED_LOCK ){
+    pFile->locktype = SHARED_LOCK;
     return SQLITE_OK;
   }
   
   /* To fully unlock the database, delete the lock file */
-  assert( eFileLock==NO_LOCK );
+  assert( locktype==NO_LOCK );
   if( unlink(zLockFile) ){
     int rc = 0;
     int tErrno = errno;
     if( ENOENT != tErrno ){
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
     }
     if( IS_LOCK_ERROR(rc) ){
       pFile->lastErrno = tErrno;
     }
     return rc; 
   }
-  pFile->eFileLock = NO_LOCK;
+  pFile->locktype = NO_LOCK;
   return SQLITE_OK;
 }
 
 /*
 ** Close a file.  Make sure the lock has been released before closing.
 */
 static int dotlockClose(sqlite3_file *id) {
   int rc;
@@ -24177,17 +24045,17 @@ static int flockCheckReservedLock(sqlite
   int reserved = 0;
   unixFile *pFile = (unixFile*)id;
   
   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
   
   assert( pFile );
   
   /* Check if a thread in this process holds such a lock */
-  if( pFile->eFileLock>SHARED_LOCK ){
+  if( pFile->locktype>SHARED_LOCK ){
     reserved = 1;
   }
   
   /* Otherwise see if some other process holds it. */
   if( !reserved ){
     /* attempt to get the lock */
     int lrc = flock(pFile->h, LOCK_EX | LOCK_NB);
     if( !lrc ){
@@ -24208,30 +24076,30 @@ static int flockCheckReservedLock(sqlite
       /* someone else might have it reserved */
       lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); 
       if( IS_LOCK_ERROR(lrc) ){
         pFile->lastErrno = tErrno;
         rc = lrc;
       }
     }
   }
-  OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
+  OSTRACE4("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved);
 
 #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
   if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
     rc = SQLITE_OK;
     reserved=1;
   }
 #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
   *pResOut = reserved;
   return rc;
 }
 
 /*
-** Lock the file with the lock specified by parameter eFileLock - one
+** Lock the file with the lock specified by parameter locktype - one
 ** of the following:
 **
 **     (1) SHARED_LOCK
 **     (2) RESERVED_LOCK
 **     (3) PENDING_LOCK
 **     (4) EXCLUSIVE_LOCK
 **
 ** Sometimes when requesting one lock state, additional lock states
@@ -24249,76 +24117,76 @@ static int flockCheckReservedLock(sqlite
 ** flock() only really support EXCLUSIVE locks.  We track intermediate
 ** lock states in the sqlite3_file structure, but all locks SHARED or
 ** above are really EXCLUSIVE locks and exclude all other processes from
 ** access the file.
 **
 ** This routine will only increase a lock.  Use the sqlite3OsUnlock()
 ** routine to lower a locking level.
 */
-static int flockLock(sqlite3_file *id, int eFileLock) {
+static int flockLock(sqlite3_file *id, int locktype) {
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile*)id;
 
   assert( pFile );
 
   /* if we already have a lock, it is exclusive.  
   ** Just adjust level and punt on outta here. */
-  if (pFile->eFileLock > NO_LOCK) {
-    pFile->eFileLock = eFileLock;
+  if (pFile->locktype > NO_LOCK) {
+    pFile->locktype = locktype;
     return SQLITE_OK;
   }
   
   /* grab an exclusive lock */
   
   if (flock(pFile->h, LOCK_EX | LOCK_NB)) {
     int tErrno = errno;
     /* didn't get, must be busy */
     rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
     if( IS_LOCK_ERROR(rc) ){
       pFile->lastErrno = tErrno;
     }
   } else {
     /* got it, set the type and return ok */
-    pFile->eFileLock = eFileLock;
-  }
-  OSTRACE(("LOCK    %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), 
-           rc==SQLITE_OK ? "ok" : "failed"));
+    pFile->locktype = locktype;
+  }
+  OSTRACE4("LOCK    %d %s %s (flock)\n", pFile->h, locktypeName(locktype), 
+           rc==SQLITE_OK ? "ok" : "failed");
 #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
   if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
     rc = SQLITE_BUSY;
   }
 #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
   return rc;
 }
 
 
 /*
-** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
+** Lower the locking level on file descriptor pFile to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
 **
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 */
-static int flockUnlock(sqlite3_file *id, int eFileLock) {
+static int flockUnlock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
   
   assert( pFile );
-  OSTRACE(("UNLOCK  %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock,
-           pFile->eFileLock, getpid()));
-  assert( eFileLock<=SHARED_LOCK );
+  OSTRACE5("UNLOCK  %d %d was %d pid=%d (flock)\n", pFile->h, locktype,
+           pFile->locktype, getpid());
+  assert( locktype<=SHARED_LOCK );
   
   /* no-op if possible */
-  if( pFile->eFileLock==eFileLock ){
+  if( pFile->locktype==locktype ){
     return SQLITE_OK;
   }
   
   /* shared can just be set because we always have an exclusive */
-  if (eFileLock==SHARED_LOCK) {
-    pFile->eFileLock = eFileLock;
+  if (locktype==SHARED_LOCK) {
+    pFile->locktype = locktype;
     return SQLITE_OK;
   }
   
   /* no, really, unlock. */
   int rc = flock(pFile->h, LOCK_UN);
   if (rc) {
     int r, tErrno = errno;
     r = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
@@ -24328,17 +24196,17 @@ static int flockUnlock(sqlite3_file *id,
 #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
     if( (r & SQLITE_IOERR) == SQLITE_IOERR ){
       r = SQLITE_BUSY;
     }
 #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
     
     return r;
   } else {
-    pFile->eFileLock = NO_LOCK;
+    pFile->locktype = NO_LOCK;
     return SQLITE_OK;
   }
 }
 
 /*
 ** Close a file.
 */
 static int flockClose(sqlite3_file *id) {
@@ -24376,47 +24244,47 @@ static int semCheckReservedLock(sqlite3_
   int reserved = 0;
   unixFile *pFile = (unixFile*)id;
 
   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
   
   assert( pFile );
 
   /* Check if a thread in this process holds such a lock */
-  if( pFile->eFileLock>SHARED_LOCK ){
+  if( pFile->locktype>SHARED_LOCK ){
     reserved = 1;
   }
   
   /* Otherwise see if some other process holds it. */
   if( !reserved ){
-    sem_t *pSem = pFile->pInode->pSem;
+    sem_t *pSem = pFile->pOpen->pSem;
     struct stat statBuf;
 
     if( sem_trywait(pSem)==-1 ){
       int tErrno = errno;
       if( EAGAIN != tErrno ){
         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
         pFile->lastErrno = tErrno;
       } else {
         /* someone else has the lock when we are in NO_LOCK */
-        reserved = (pFile->eFileLock < SHARED_LOCK);
+        reserved = (pFile->locktype < SHARED_LOCK);
       }
     }else{
       /* we could have it if we want it */
       sem_post(pSem);
     }
   }
-  OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved));
+  OSTRACE4("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved);
 
   *pResOut = reserved;
   return rc;
 }
 
 /*
-** Lock the file with the lock specified by parameter eFileLock - one
+** Lock the file with the lock specified by parameter locktype - one
 ** of the following:
 **
 **     (1) SHARED_LOCK
 **     (2) RESERVED_LOCK
 **     (3) PENDING_LOCK
 **     (4) EXCLUSIVE_LOCK
 **
 ** Sometimes when requesting one lock state, additional lock states
@@ -24434,94 +24302,95 @@ static int semCheckReservedLock(sqlite3_
 ** Semaphore locks only really support EXCLUSIVE locks.  We track intermediate
 ** lock states in the sqlite3_file structure, but all locks SHARED or
 ** above are really EXCLUSIVE locks and exclude all other processes from
 ** access the file.
 **
 ** This routine will only increase a lock.  Use the sqlite3OsUnlock()
 ** routine to lower a locking level.
 */
-static int semLock(sqlite3_file *id, int eFileLock) {
+static int semLock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
   int fd;
-  sem_t *pSem = pFile->pInode->pSem;
+  sem_t *pSem = pFile->pOpen->pSem;
   int rc = SQLITE_OK;
 
   /* if we already have a lock, it is exclusive.  
   ** Just adjust level and punt on outta here. */
-  if (pFile->eFileLock > NO_LOCK) {
-    pFile->eFileLock = eFileLock;
+  if (pFile->locktype > NO_LOCK) {
+    pFile->locktype = locktype;
     rc = SQLITE_OK;
     goto sem_end_lock;
   }
   
   /* lock semaphore now but bail out when already locked. */
   if( sem_trywait(pSem)==-1 ){
     rc = SQLITE_BUSY;
     goto sem_end_lock;
   }
 
   /* got it, set the type and return ok */
-  pFile->eFileLock = eFileLock;
+  pFile->locktype = locktype;
 
  sem_end_lock:
   return rc;
 }
 
 /*
-** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
+** Lower the locking level on file descriptor pFile to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
 **
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 */
-static int semUnlock(sqlite3_file *id, int eFileLock) {
+static int semUnlock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
-  sem_t *pSem = pFile->pInode->pSem;
+  sem_t *pSem = pFile->pOpen->pSem;
 
   assert( pFile );
   assert( pSem );
-  OSTRACE(("UNLOCK  %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
-	   pFile->eFileLock, getpid()));
-  assert( eFileLock<=SHARED_LOCK );
+  OSTRACE5("UNLOCK  %d %d was %d pid=%d (sem)\n", pFile->h, locktype,
+	   pFile->locktype, getpid());
+  assert( locktype<=SHARED_LOCK );
   
   /* no-op if possible */
-  if( pFile->eFileLock==eFileLock ){
+  if( pFile->locktype==locktype ){
     return SQLITE_OK;
   }
   
   /* shared can just be set because we always have an exclusive */
-  if (eFileLock==SHARED_LOCK) {
-    pFile->eFileLock = eFileLock;
+  if (locktype==SHARED_LOCK) {
+    pFile->locktype = locktype;
     return SQLITE_OK;
   }
   
   /* no, really unlock. */
   if ( sem_post(pSem)==-1 ) {
     int rc, tErrno = errno;
     rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
     if( IS_LOCK_ERROR(rc) ){
       pFile->lastErrno = tErrno;
     }
     return rc; 
   }
-  pFile->eFileLock = NO_LOCK;
+  pFile->locktype = NO_LOCK;
   return SQLITE_OK;
 }
 
 /*
  ** Close a file.
  */
 static int semClose(sqlite3_file *id) {
   if( id ){
     unixFile *pFile = (unixFile*)id;
     semUnlock(id, NO_LOCK);
     assert( pFile );
     unixEnterMutex();
-    releaseInodeInfo(pFile);
+    releaseLockInfo(pFile->pLock);
+    releaseOpenCnt(pFile->pOpen);
     unixLeaveMutex();
     closeUnixFile(id);
   }
   return SQLITE_OK;
 }
 
 #endif /* OS_VXWORKS */
 /*
@@ -24580,25 +24449,25 @@ static int afpSetLock(
   int err;
   
   pb.unLockFlag = setLockFlag ? 0 : 1;
   pb.startEndFlag = 0;
   pb.offset = offset;
   pb.length = length; 
   pb.fd = pFile->h;
   
-  OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", 
+  OSTRACE6("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", 
     (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""),
-    offset, length));
+    offset, length);
   err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0);
   if ( err==-1 ) {
     int rc;
     int tErrno = errno;
-    OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n",
-             path, tErrno, strerror(tErrno)));
+    OSTRACE4("AFPSETLOCK failed to fsctl() '%s' %d %s\n",
+             path, tErrno, strerror(tErrno));
 #ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
     rc = SQLITE_BUSY;
 #else
     rc = sqliteErrorFromPosixError(tErrno,
                     setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
 #endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
     if( IS_LOCK_ERROR(rc) ){
       pFile->lastErrno = tErrno;
@@ -24623,20 +24492,20 @@ static int afpCheckReservedLock(sqlite3_
   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
   
   assert( pFile );
   afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
   if( context->reserved ){
     *pResOut = 1;
     return SQLITE_OK;
   }
-  unixEnterMutex(); /* Because pFile->pInode is shared across threads */
+  unixEnterMutex(); /* Because pFile->pLock is shared across threads */
   
   /* Check if a thread in this process holds such a lock */
-  if( pFile->pInode->eFileLock>SHARED_LOCK ){
+  if( pFile->pLock->locktype>SHARED_LOCK ){
     reserved = 1;
   }
   
   /* Otherwise see if some other process holds it.
    */
   if( !reserved ){
     /* lock the RESERVED byte */
     int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);  
@@ -24649,24 +24518,24 @@ static int afpCheckReservedLock(sqlite3_
       reserved = 1;
     }
     if( IS_LOCK_ERROR(lrc) ){
       rc=lrc;
     }
   }
   
   unixLeaveMutex();
-  OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved));
+  OSTRACE4("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved);
   
   *pResOut = reserved;
   return rc;
 }
 
 /*
-** Lock the file with the lock specified by parameter eFileLock - one
+** Lock the file with the lock specified by parameter locktype - one
 ** of the following:
 **
 **     (1) SHARED_LOCK
 **     (2) RESERVED_LOCK
 **     (3) PENDING_LOCK
 **     (4) EXCLUSIVE_LOCK
 **
 ** Sometimes when requesting one lock state, additional lock states
@@ -24679,160 +24548,168 @@ static int afpCheckReservedLock(sqlite3_
 **    SHARED -> RESERVED
 **    SHARED -> (PENDING) -> EXCLUSIVE
 **    RESERVED -> (PENDING) -> EXCLUSIVE
 **    PENDING -> EXCLUSIVE
 **
 ** This routine will only increase a lock.  Use the sqlite3OsUnlock()
 ** routine to lower a locking level.
 */
-static int afpLock(sqlite3_file *id, int eFileLock){
+static int afpLock(sqlite3_file *id, int locktype){
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile*)id;
-  unixInodeInfo *pInode = pFile->pInode;
+  struct unixLockInfo *pLock = pFile->pLock;
   afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
   
   assert( pFile );
-  OSTRACE(("LOCK    %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h,
-           azFileLock(eFileLock), azFileLock(pFile->eFileLock),
-           azFileLock(pInode->eFileLock), pInode->nShared , getpid()));
+  OSTRACE7("LOCK    %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h,
+           locktypeName(locktype), locktypeName(pFile->locktype),
+           locktypeName(pLock->locktype), pLock->cnt , getpid());
 
   /* If there is already a lock of this type or more restrictive on the
   ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as
   ** unixEnterMutex() hasn't been called yet.
   */
-  if( pFile->eFileLock>=eFileLock ){
-    OSTRACE(("LOCK    %d %s ok (already held) (afp)\n", pFile->h,
-           azFileLock(eFileLock)));
+  if( pFile->locktype>=locktype ){
+    OSTRACE3("LOCK    %d %s ok (already held) (afp)\n", pFile->h,
+           locktypeName(locktype));
     return SQLITE_OK;
   }
 
   /* Make sure the locking sequence is correct
   **  (1) We never move from unlocked to anything higher than shared lock.
   **  (2) SQLite never explicitly requests a pendig lock.
   **  (3) A shared lock is always held when a reserve lock is requested.
   */
-  assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK );
-  assert( eFileLock!=PENDING_LOCK );
-  assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK );
-  
-  /* This mutex is needed because pFile->pInode is shared across threads
+  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+  assert( locktype!=PENDING_LOCK );
+  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
+  
+  /* This mutex is needed because pFile->pLock is shared across threads
   */
   unixEnterMutex();
-  pInode = pFile->pInode;
+
+  /* Make sure the current thread owns the pFile.
+  */
+  rc = transferOwnership(pFile);
+  if( rc!=SQLITE_OK ){
+    unixLeaveMutex();
+    return rc;
+  }
+  pLock = pFile->pLock;
 
   /* If some thread using this PID has a lock via a different unixFile*
   ** handle that precludes the requested lock, return BUSY.
   */
-  if( (pFile->eFileLock!=pInode->eFileLock && 
-       (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK))
+  if( (pFile->locktype!=pLock->locktype && 
+       (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK))
      ){
     rc = SQLITE_BUSY;
     goto afp_end_lock;
   }
   
   /* If a SHARED lock is requested, and some thread using this PID already
   ** has a SHARED or RESERVED lock, then increment reference counts and
   ** return SQLITE_OK.
   */
-  if( eFileLock==SHARED_LOCK && 
-     (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){
-    assert( eFileLock==SHARED_LOCK );
-    assert( pFile->eFileLock==0 );
-    assert( pInode->nShared>0 );
-    pFile->eFileLock = SHARED_LOCK;
-    pInode->nShared++;
-    pInode->nLock++;
+  if( locktype==SHARED_LOCK && 
+     (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){
+    assert( locktype==SHARED_LOCK );
+    assert( pFile->locktype==0 );
+    assert( pLock->cnt>0 );
+    pFile->locktype = SHARED_LOCK;
+    pLock->cnt++;
+    pFile->pOpen->nLock++;
     goto afp_end_lock;
   }
     
   /* A PENDING lock is needed before acquiring a SHARED lock and before
   ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
   ** be released.
   */
-  if( eFileLock==SHARED_LOCK 
-      || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK)
+  if( locktype==SHARED_LOCK 
+      || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
   ){
     int failed;
     failed = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 1);
     if (failed) {
       rc = failed;
       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 ){
+  if( locktype==SHARED_LOCK ){
     int lrc1, lrc2, lrc1Errno;
     long lk, mask;
     
-    assert( pInode->nShared==0 );
-    assert( pInode->eFileLock==0 );
+    assert( pLock->cnt==0 );
+    assert( pLock->locktype==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 */
     lk = random(); 
-    pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1);
+    pLock->sharedByte = (lk & mask)%(SHARED_SIZE - 1);
     lrc1 = afpSetLock(context->dbPath, pFile, 
-          SHARED_FIRST+pInode->sharedByte, 1, 1);
+          SHARED_FIRST+pLock->sharedByte, 1, 1);
     if( IS_LOCK_ERROR(lrc1) ){
       lrc1Errno = pFile->lastErrno;
     }
     /* Drop the temporary PENDING lock */
     lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
     
     if( IS_LOCK_ERROR(lrc1) ) {
       pFile->lastErrno = lrc1Errno;
       rc = lrc1;
       goto afp_end_lock;
     } else if( IS_LOCK_ERROR(lrc2) ){
       rc = lrc2;
       goto afp_end_lock;
     } else if( lrc1 != SQLITE_OK ) {
       rc = lrc1;
     } else {
-      pFile->eFileLock = SHARED_LOCK;
-      pInode->nLock++;
-      pInode->nShared = 1;
-    }
-  }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
+      pFile->locktype = SHARED_LOCK;
+      pFile->pOpen->nLock++;
+      pLock->cnt = 1;
+    }
+  }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){
     /* We are trying for an exclusive lock but another thread in this
      ** same process is still holding a shared lock. */
     rc = SQLITE_BUSY;
   }else{
     /* The request was for a RESERVED or EXCLUSIVE lock.  It is
     ** assumed that there is a SHARED or greater lock on the file
     ** already.
     */
     int failed = 0;
-    assert( 0!=pFile->eFileLock );
-    if (eFileLock >= RESERVED_LOCK && pFile->eFileLock < RESERVED_LOCK) {
+    assert( 0!=pFile->locktype );
+    if (locktype >= RESERVED_LOCK && pFile->locktype < RESERVED_LOCK) {
         /* Acquire a RESERVED lock */
         failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);
       if( !failed ){
         context->reserved = 1;
       }
     }
-    if (!failed && eFileLock == EXCLUSIVE_LOCK) {
+    if (!failed && locktype == EXCLUSIVE_LOCK) {
       /* Acquire an EXCLUSIVE lock */
         
       /* Remove the shared lock before trying the range.  we'll need to 
       ** reestablish the shared lock if we can't get the  afpUnlock
       */
       if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST +
-                         pInode->sharedByte, 1, 0)) ){
+                         pLock->sharedByte, 1, 0)) ){
         int failed2 = SQLITE_OK;
         /* now attemmpt to get the exclusive lock range */
         failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, 
                                SHARED_SIZE, 1);
         if( failed && (failed2 = afpSetLock(context->dbPath, pFile, 
-                       SHARED_FIRST + pInode->sharedByte, 1, 1)) ){
+                       SHARED_FIRST + pLock->sharedByte, 1, 1)) ){
           /* Can't reestablish the shared lock.  Sqlite can't deal, this is
           ** a critical I/O error
           */
           rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : 
                SQLITE_IOERR_LOCK;
           goto afp_end_lock;
         } 
       }else{
@@ -24840,61 +24717,63 @@ static int afpLock(sqlite3_file *id, int
       }
     }
     if( failed ){
       rc = failed;
     }
   }
   
   if( rc==SQLITE_OK ){
-    pFile->eFileLock = eFileLock;
-    pInode->eFileLock = eFileLock;
-  }else if( eFileLock==EXCLUSIVE_LOCK ){
-    pFile->eFileLock = PENDING_LOCK;
-    pInode->eFileLock = PENDING_LOCK;
+    pFile->locktype = locktype;
+    pLock->locktype = locktype;
+  }else if( locktype==EXCLUSIVE_LOCK ){
+    pFile->locktype = PENDING_LOCK;
+    pLock->locktype = PENDING_LOCK;
   }
   
 afp_end_lock:
   unixLeaveMutex();
-  OSTRACE(("LOCK    %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), 
-         rc==SQLITE_OK ? "ok" : "failed"));
-  return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
+  OSTRACE4("LOCK    %d %s %s (afp)\n", pFile->h, locktypeName(locktype), 
+         rc==SQLITE_OK ? "ok" : "failed");
+  return rc;
+}
+
+/*
+** Lower the locking level on file descriptor pFile to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
 **
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 */
-static int afpUnlock(sqlite3_file *id, int eFileLock) {
+static int afpUnlock(sqlite3_file *id, int locktype) {
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile*)id;
-  unixInodeInfo *pInode;
+  struct unixLockInfo *pLock;
   afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
   int skipShared = 0;
 #ifdef SQLITE_TEST
   int h = pFile->h;
 #endif
 
   assert( pFile );
-  OSTRACE(("UNLOCK  %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock,
-           pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
-           getpid()));
-
-  assert( eFileLock<=SHARED_LOCK );
-  if( pFile->eFileLock<=eFileLock ){
+  OSTRACE7("UNLOCK  %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, locktype,
+           pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid());
+
+  assert( locktype<=SHARED_LOCK );
+  if( pFile->locktype<=locktype ){
     return SQLITE_OK;
   }
+  if( CHECK_THREADID(pFile) ){
+    return SQLITE_MISUSE_BKPT;
+  }
   unixEnterMutex();
-  pInode = pFile->pInode;
-  assert( pInode->nShared!=0 );
-  if( pFile->eFileLock>SHARED_LOCK ){
-    assert( pInode->eFileLock==pFile->eFileLock );
+  pLock = pFile->pLock;
+  assert( pLock->cnt!=0 );
+  if( pFile->locktype>SHARED_LOCK ){
+    assert( pLock->locktype==pFile->locktype );
     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
@@ -24904,91 +24783,94 @@ static int afpUnlock(sqlite3_file *id, i
     ** cache.  The use of a stale cache can lead to database corruption.
     */
     assert( pFile->inNormalWrite==0
            || pFile->dbUpdate==0
            || pFile->transCntrChng==1 );
     pFile->inNormalWrite = 0;
 #endif
     
-    if( pFile->eFileLock==EXCLUSIVE_LOCK ){
+    if( pFile->locktype==EXCLUSIVE_LOCK ){
       rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0);
-      if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){
+      if( rc==SQLITE_OK && (locktype==SHARED_LOCK || pLock->cnt>1) ){
         /* only re-establish the shared lock if necessary */
-        int sharedLockByte = SHARED_FIRST+pInode->sharedByte;
+        int sharedLockByte = SHARED_FIRST+pLock->sharedByte;
         rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1);
       } else {
         skipShared = 1;
       }
     }
-    if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){
+    if( rc==SQLITE_OK && pFile->locktype>=PENDING_LOCK ){
       rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
     } 
-    if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){
+    if( rc==SQLITE_OK && pFile->locktype>=RESERVED_LOCK && context->reserved ){
       rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0);
       if( !rc ){ 
         context->reserved = 0; 
       }
     }
-    if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){
-      pInode->eFileLock = SHARED_LOCK;
-    }
-  }
-  if( rc==SQLITE_OK && eFileLock==NO_LOCK ){
+    if( rc==SQLITE_OK && (locktype==SHARED_LOCK || pLock->cnt>1)){
+      pLock->locktype = SHARED_LOCK;
+    }
+  }
+  if( rc==SQLITE_OK && locktype==NO_LOCK ){
 
     /* Decrement the shared lock counter.  Release the lock using an
     ** OS call only when all threads in this same process have released
     ** the lock.
     */
-    unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte;
-    pInode->nShared--;
-    if( pInode->nShared==0 ){
+    unsigned long long sharedLockByte = SHARED_FIRST+pLock->sharedByte;
+    pLock->cnt--;
+    if( pLock->cnt==0 ){
       SimulateIOErrorBenign(1);
       SimulateIOError( h=(-1) )
       SimulateIOErrorBenign(0);
       if( !skipShared ){
         rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0);
       }
       if( !rc ){
-        pInode->eFileLock = NO_LOCK;
-        pFile->eFileLock = NO_LOCK;
+        pLock->locktype = NO_LOCK;
+        pFile->locktype = NO_LOCK;
       }
     }
     if( rc==SQLITE_OK ){
-      pInode->nLock--;
-      assert( pInode->nLock>=0 );
-      if( pInode->nLock==0 ){
+      struct unixOpenCnt *pOpen = pFile->pOpen;
+        
+      pOpen->nLock--;
+      assert( pOpen->nLock>=0 );
+      if( pOpen->nLock==0 ){
         rc = closePendingFds(pFile);
       }
     }
   }
   
   unixLeaveMutex();
-  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
+  if( rc==SQLITE_OK ) pFile->locktype = locktype;
   return rc;
 }
 
 /*
 ** Close a file & cleanup AFP specific locking context 
 */
 static int afpClose(sqlite3_file *id) {
   int rc = SQLITE_OK;
   if( id ){
     unixFile *pFile = (unixFile*)id;
     afpUnlock(id, NO_LOCK);
     unixEnterMutex();
-    if( pFile->pInode && pFile->pInode->nLock ){
+    if( pFile->pOpen && pFile->pOpen->nLock ){
       /* If there are outstanding locks, do not actually close the file just
       ** yet because that would clear those locks.  Instead, add the file
-      ** descriptor to pInode->aPending.  It will be automatically closed when
+      ** descriptor to pOpen->aPending.  It will be automatically closed when
       ** the last lock is cleared.
       */
       setPendingFd(pFile);
     }
-    releaseInodeInfo(pFile);
+    releaseLockInfo(pFile->pLock);
+    releaseOpenCnt(pFile->pOpen);
     sqlite3_free(pFile->lockingContext);
     rc = closeUnixFile(id);
     unixLeaveMutex();
   }
   return rc;
 }
 
 #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
@@ -25001,24 +24883,24 @@ static int afpClose(sqlite3_file *id) {
 ********************* End of the AFP lock implementation **********************
 ******************************************************************************/
 
 /******************************************************************************
 *************************** Begin NFS Locking ********************************/
 
 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
 /*
- ** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
+ ** Lower the locking level on file descriptor pFile to locktype.  locktype
  ** must be either NO_LOCK or SHARED_LOCK.
  **
  ** If the locking level of the file descriptor is already at or below
  ** the requested locking level, this routine is a no-op.
  */
-static int nfsUnlock(sqlite3_file *id, int eFileLock){
-  return _posixUnlock(id, eFileLock, 1);
+static int nfsUnlock(sqlite3_file *id, int locktype){
+  return _posixUnlock(id, locktype, 1);
 }
 
 #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
 /*
 ** The code above is the NFS lock implementation.  The code is specific
 ** to MacOSX and does not work on other unix platforms.  No alternative
 ** is available.  
 **
@@ -25072,17 +24954,17 @@ static int seekAndRead(unixFile *id, sql
     return -1;
   }
   got = read(id->h, pBuf, cnt);
 #endif
   TIMER_END;
   if( got<0 ){
     ((unixFile*)id)->lastErrno = errno;
   }
-  OSTRACE(("READ    %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
+  OSTRACE5("READ    %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
   return got;
 }
 
 /*
 ** Read data from a file into a buffer.  Return SQLITE_OK if all
 ** bytes were read successfully and SQLITE_IOERR if anything goes
 ** wrong.
 */
@@ -25093,22 +24975,20 @@ static int unixRead(
   sqlite3_int64 offset
 ){
   unixFile *pFile = (unixFile *)id;
   int got;
   assert( id );
 
   /* If this is a database file (not a journal, master-journal or temp
   ** file), the bytes in the locking range should never be read or written. */
-#if 0
   assert( pFile->pUnused==0
        || offset>=PENDING_BYTE+512
        || offset+amt<=PENDING_BYTE 
   );
-#endif
 
   got = seekAndRead(pFile, offset, pBuf, amt);
   if( got==amt ){
     return SQLITE_OK;
   }else if( got<0 ){
     /* lastErrno set by seekAndRead */
     return SQLITE_IOERR_READ;
   }else{
@@ -25148,17 +25028,17 @@ static int seekAndWrite(unixFile *id, i6
   }
   got = write(id->h, pBuf, cnt);
 #endif
   TIMER_END;
   if( got<0 ){
     ((unixFile*)id)->lastErrno = errno;
   }
 
-  OSTRACE(("WRITE   %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
+  OSTRACE5("WRITE   %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
   return got;
 }
 
 
 /*
 ** Write data from a buffer into a file.  Return SQLITE_OK on success
 ** or some other error code on failure.
 */
@@ -25170,22 +25050,20 @@ static int unixWrite(
 ){
   unixFile *pFile = (unixFile*)id;
   int wrote = 0;
   assert( id );
   assert( amt>0 );
 
   /* If this is a database file (not a journal, master-journal or temp
   ** file), the bytes in the locking range should never be read or written. */
-#if 0
   assert( pFile->pUnused==0
        || offset>=PENDING_BYTE+512
        || offset+amt<=PENDING_BYTE 
   );
-#endif
 
 #ifndef NDEBUG
   /* If we are doing a normal write to a database file (as opposed to
   ** doing a hot-journal rollback or a write to some file other than a
   ** normal database file) then record the fact that the database
   ** has changed.  If the transaction counter is modified, record that
   ** fact too.
   */
@@ -25374,27 +25252,27 @@ static int unixSync(sqlite3_file *id, in
   );
 
   /* Unix cannot, but some systems may return SQLITE_FULL from here. This
   ** line is to test that doing so does not cause any problems.
   */
   SimulateDiskfullError( return SQLITE_FULL );
 
   assert( pFile );
-  OSTRACE(("SYNC    %-3d\n", pFile->h));
+  OSTRACE2("SYNC    %-3d\n", pFile->h);
   rc = full_fsync(pFile->h, isFullsync, isDataOnly);
   SimulateIOError( rc=1 );
   if( rc ){
     pFile->lastErrno = errno;
     return SQLITE_IOERR_FSYNC;
   }
   if( pFile->dirfd>=0 ){
     int err;
-    OSTRACE(("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
-            HAVE_FULLFSYNC, isFullsync));
+    OSTRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
+            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
@@ -25456,17 +25334,17 @@ static int unixFileSize(sqlite3_file *id
   rc = fstat(((unixFile*)id)->h, &buf);
   SimulateIOError( rc=1 );
   if( rc!=0 ){
     ((unixFile*)id)->lastErrno = errno;
     return SQLITE_IOERR_FSTAT;
   }
   *pSize = buf.st_size;
 
-  /* When opening a zero-size database, the findInodeInfo() procedure
+  /* When opening a zero-size database, the findLockInfo() procedure
   ** writes a single byte into that file in order to work around a bug
   ** in the OS-X msdos filesystem.  In order to avoid problems with upper
   ** layers, we need to report this file size as zero even though it is
   ** really 1.   Ticket #3260.
   */
   if( *pSize==1 ) *pSize = 0;
 
 
@@ -25483,31 +25361,23 @@ static int proxyFileControl(sqlite3_file
 
 
 /*
 ** Information and control of an open file handle.
 */
 static int unixFileControl(sqlite3_file *id, int op, void *pArg){
   switch( op ){
     case SQLITE_FCNTL_LOCKSTATE: {
-      *(int*)pArg = ((unixFile*)id)->eFileLock;
+      *(int*)pArg = ((unixFile*)id)->locktype;
       return SQLITE_OK;
     }
     case SQLITE_LAST_ERRNO: {
       *(int*)pArg = ((unixFile*)id)->lastErrno;
       return SQLITE_OK;
     }
-    case SQLITE_FCNTL_SIZE_HINT: {
-#if 0 /* No performance advantage seen on Linux */
-      sqlite3_int64 szFile = *(sqlite3_int64*)pArg;
-      unixFile *pFile = (unixFile*)id;
-      ftruncate(pFile->h, szFile);
-#endif
-      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: {
       ((unixFile*)id)->dbUpdate = 0;
@@ -25542,619 +25412,16 @@ static int unixSectorSize(sqlite3_file *
 /*
 ** Return the device characteristics for the file. This is always 0 for unix.
 */
 static int unixDeviceCharacteristics(sqlite3_file *NotUsed){
   UNUSED_PARAMETER(NotUsed);
   return 0;
 }
 
-#ifndef SQLITE_OMIT_WAL
-
-
-/*
-** Object used to represent an shared memory buffer.  
-**
-** When multiple threads all reference the same wal-index, each thread
-** has its own unixShm object, but they all point to a single instance
-** of this unixShmNode object.  In other words, each wal-index is opened
-** only once per process.
-**
-** Each unixShmNode object is connected to a single unixInodeInfo object.
-** We could coalesce this object into unixInodeInfo, but that would mean
-** every open file that does not use shared memory (in other words, most
-** open files) would have to carry around this extra information.  So
-** the unixInodeInfo object contains a pointer to this unixShmNode object
-** and the unixShmNode object is created only when needed.
-**
-** unixMutexHeld() must be true when creating or destroying
-** this object or while reading or writing the following fields:
-**
-**      nRef
-**
-** The following fields are read-only after the object is created:
-** 
-**      fid
-**      zFilename
-**
-** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
-** unixMutexHeld() is true when reading or writing any other field
-** in this structure.
-*/
-struct unixShmNode {
-  unixInodeInfo *pInode;     /* unixInodeInfo that owns this SHM node */
-  sqlite3_mutex *mutex;      /* Mutex to access this object */
-  char *zFilename;           /* Name of the mmapped file */
-  int h;                     /* Open file descriptor */
-  int szRegion;              /* Size of shared-memory regions */
-  int nRegion;               /* Size of array apRegion */
-  char **apRegion;           /* Array of mapped shared-memory regions */
-  int nRef;                  /* Number of unixShm objects pointing to this */
-  unixShm *pFirst;           /* All unixShm objects pointing to this */
-#ifdef SQLITE_DEBUG
-  u8 exclMask;               /* Mask of exclusive locks held */
-  u8 sharedMask;             /* Mask of shared locks held */
-  u8 nextShmId;              /* Next available unixShm.id value */
-#endif
-};
-
-/*
-** Structure used internally by this VFS to record the state of an
-** open shared memory connection.
-**
-** The following fields are initialized when this object is created and
-** are read-only thereafter:
-**
-**    unixShm.pFile
-**    unixShm.id
-**
-** 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 */
-  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 */
-
-/*
-** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
-**
-** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
-** otherwise.
-*/
-static int unixShmSystemLock(
-  unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */
-  int lockType,          /* F_UNLCK, F_RDLCK, or F_WRLCK */
-  int ofst,              /* First byte of the locking range */
-  int n                  /* Number of bytes to lock */
-){
-  struct flock f;       /* The posix advisory locking structure */
-  int rc = SQLITE_OK;   /* Result code form fcntl() */
-
-  /* Access to the unixShmNode object is serialized by the caller */
-  assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
-
-  /* Shared locks never span more than one byte */
-  assert( n==1 || lockType!=F_RDLCK );
-
-  /* Locks are within range */
-  assert( n>=1 && n<SQLITE_SHM_NLOCK );
-
-  /* Initialize the locking parameters */
-  memset(&f, 0, sizeof(f));
-  f.l_type = lockType;
-  f.l_whence = SEEK_SET;
-  f.l_start = ofst;
-  f.l_len = n;
-
-  rc = fcntl(pShmNode->h, F_SETLK, &f);
-  rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
-
-  /* Update the global lock state and do debug tracing */
-#ifdef SQLITE_DEBUG
-  { u16 mask;
-  OSTRACE(("SHM-LOCK "));
-  mask = (1<<(ofst+n)) - (1<<ofst);
-  if( rc==SQLITE_OK ){
-    if( lockType==F_UNLCK ){
-      OSTRACE(("unlock %d ok", ofst));
-      pShmNode->exclMask &= ~mask;
-      pShmNode->sharedMask &= ~mask;
-    }else if( lockType==F_RDLCK ){
-      OSTRACE(("read-lock %d ok", ofst));
-      pShmNode->exclMask &= ~mask;
-      pShmNode->sharedMask |= mask;
-    }else{
-      assert( lockType==F_WRLCK );
-      OSTRACE(("write-lock %d ok", ofst));
-      pShmNode->exclMask |= mask;
-      pShmNode->sharedMask &= ~mask;
-    }
-  }else{
-    if( lockType==F_UNLCK ){
-      OSTRACE(("unlock %d failed", ofst));
-    }else if( lockType==F_RDLCK ){
-      OSTRACE(("read-lock failed"));
-    }else{
-      assert( lockType==F_WRLCK );
-      OSTRACE(("write-lock %d failed", ofst));
-    }
-  }
-  OSTRACE((" - afterwards %03x,%03x\n",
-           pShmNode->sharedMask, pShmNode->exclMask));
-  }
-#endif
-
-  return rc;        
-}
-
-
-/*
-** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
-**
-** This is not a VFS shared-memory method; it is a utility function called
-** 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);
-    for(i=0; i<p->nRegion; i++){
-      munmap(p->apRegion[i], p->szRegion);
-    }
-    sqlite3_free(p->apRegion);
-    if( p->h>=0 ) close(p->h);
-    p->pInode->pShmNode = 0;
-    sqlite3_free(p);
-  }
-}
-
-/*
-** Open a shared-memory area associated with open database file pDbFd.  
-** This particular implementation uses mmapped files.
-**
-** The file used to implement shared-memory is in the same directory
-** as the open database file and has the same name as the open database
-** file with the "-shm" suffix added.  For example, if the database file
-** is "/home/user1/config.db" then the file that is created and mmapped
-** for shared memory will be called "/home/user1/config.db-shm".  
-**
-** Another approach to is to use files in /dev/shm or /dev/tmp or an
-** some other tmpfs mount. But if a file in a different directory
-** from the database file is used, then differing access permissions
-** or a chroot() might cause two different processes on the same
-** database to end up using different files for shared memory - 
-** meaning that their memory would not really be shared - resulting
-** in database corruption.  Nevertheless, this tmpfs file usage
-** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm"
-** or the equivalent.  The use of the SQLITE_SHM_DIRECTORY compile-time
-** option results in an incompatible build of SQLite;  builds of SQLite
-** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the
-** same database file at the same time, database corruption will likely
-** result. The SQLITE_SHM_DIRECTORY compile-time option is considered
-** "unsupported" and may go away in a future SQLite release.
-**
-** When opening a new shared-memory file, if no other instances of that
-** file are currently open, in this process or in other processes, then
-** the file must be truncated to zero length or have its header cleared.
-*/
-static int unixOpenSharedMemory(unixFile *pDbFd){
-  struct unixShm *p = 0;          /* The connection to be opened */
-  struct unixShmNode *pShmNode;   /* The underlying mmapped file */
-  int rc;                         /* Result code */
-  unixInodeInfo *pInode;          /* The inode of fd */
-  char *zShmFilename;             /* Name of the file used for SHM */
-  int nShmFilename;               /* Size of the SHM filename in bytes */
-
-  /* Allocate space for the new unixShm object. */
-  p = sqlite3_malloc( sizeof(*p) );
-  if( p==0 ) return SQLITE_NOMEM;
-  memset(p, 0, sizeof(*p));
-  assert( pDbFd->pShm==0 );
-
-  /* Check to see if a unixShmNode object already exists. Reuse an existing
-  ** one if present. Create a new one if necessary.
-  */
-  unixEnterMutex();
-  pInode = pDbFd->pInode;
-  pShmNode = pInode->pShmNode;
-  if( pShmNode==0 ){
-    struct stat sStat;                 /* fstat() info for database file */
-
-    /* Call fstat() to figure out the permissions on the database file. If
-    ** a new *-shm file is created, an attempt will be made to create it
-    ** with the same permissions. The actual permissions the file is created
-    ** with are subject to the current umask setting.
-    */
-    if( fstat(pDbFd->h, &sStat) ){
-      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);
-#endif
-    pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
-    if( pShmNode==0 ){
-      rc = SQLITE_NOMEM;
-      goto shm_open_err;
-    }
-    memset(pShmNode, 0, sizeof(*pShmNode));
-    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);
-#endif
-    pShmNode->h = -1;
-    pDbFd->pInode->pShmNode = pShmNode;
-    pShmNode->pInode = pDbFd->pInode;
-    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-    if( pShmNode->mutex==0 ){
-      rc = SQLITE_NOMEM;
-      goto shm_open_err;
-    }
-
-    pShmNode->h = open(zShmFilename, O_RDWR|O_CREAT, (sStat.st_mode & 0777));
-    if( pShmNode->h<0 ){
-      rc = SQLITE_CANTOPEN_BKPT;
-      goto shm_open_err;
-    }
-
-    /* Check to see if another process is holding the dead-man switch.
-    ** If not, truncate the file to zero length. 
-    */
-    rc = SQLITE_OK;
-    if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
-      if( ftruncate(pShmNode->h, 0) ){
-        rc = SQLITE_IOERR_SHMOPEN;
-      }
-    }
-    if( rc==SQLITE_OK ){
-      rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
-    }
-    if( rc ) goto shm_open_err;
-  }
-
-  /* Make the new connection a child of the unixShmNode */
-  p->pShmNode = pShmNode;
-#ifdef SQLITE_DEBUG
-  p->id = pShmNode->nextShmId++;
-#endif
-  pShmNode->nRef++;
-  pDbFd->pShm = p;
-  unixLeaveMutex();
-
-  /* The reference count on pShmNode has already been incremented under
-  ** the cover of the unixEnterMutex() mutex and the pointer from the
-  ** new (struct unixShm) object to the pShmNode has been set. All that is
-  ** left to do is to link the new object into the linked list starting
-  ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex 
-  ** mutex.
-  */
-  sqlite3_mutex_enter(pShmNode->mutex);
-  p->pNext = pShmNode->pFirst;
-  pShmNode->pFirst = p;
-  sqlite3_mutex_leave(pShmNode->mutex);
-  return SQLITE_OK;
-
-  /* Jump here on any error */
-shm_open_err:
-  unixShmPurge(pDbFd);       /* This call frees pShmNode if required */
-  sqlite3_free(p);
-  unixLeaveMutex();
-  return rc;
-}
-
-/*
-** This function is called to obtain a pointer to region iRegion of the 
-** shared-memory associated with the database file fd. Shared-memory regions 
-** are numbered starting from zero. Each shared-memory region is szRegion 
-** bytes in size.
-**
-** If an error occurs, an error code is returned and *pp is set to NULL.
-**
-** Otherwise, if the bExtend parameter is 0 and the requested shared-memory
-** region has not been allocated (by any client, including one running in a
-** separate process), then *pp is set to NULL and SQLITE_OK returned. If 
-** bExtend is non-zero and the requested shared-memory region has not yet 
-** been allocated, it is allocated by this function.
-**
-** If the shared-memory region has already been allocated or is allocated by
-** this call as described above, then it is mapped into this processes 
-** address space (if it is not already), *pp is set to point to the mapped 
-** memory and SQLITE_OK returned.
-*/
-static int unixShmMap(
-  sqlite3_file *fd,               /* Handle open on database file */
-  int iRegion,                    /* Region to retrieve */
-  int szRegion,                   /* Size of regions */
-  int bExtend,                    /* True to extend file if necessary */
-  void volatile **pp              /* OUT: Mapped memory */
-){
-  unixFile *pDbFd = (unixFile*)fd;
-  unixShm *p;
-  unixShmNode *pShmNode;
-  int rc = SQLITE_OK;
-
-  /* If the shared-memory file has not yet been opened, open it now. */
-  if( pDbFd->pShm==0 ){
-    rc = unixOpenSharedMemory(pDbFd);
-    if( rc!=SQLITE_OK ) return rc;
-  }
-
-  p = pDbFd->pShm;
-  pShmNode = p->pShmNode;
-  sqlite3_mutex_enter(pShmNode->mutex);
-  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
-
-  if( pShmNode->nRegion<=iRegion ){
-    char **apNew;                      /* New apRegion[] array */
-    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
-    struct stat sStat;                 /* Used by fstat() */
-
-    pShmNode->szRegion = szRegion;
-
-    /* The requested region is not mapped into this processes address space.
-    ** Check to see if it has been allocated (i.e. if the wal-index file is
-    ** large enough to contain the requested region).
-    */
-    if( fstat(pShmNode->h, &sStat) ){
-      rc = SQLITE_IOERR_SHMSIZE;
-      goto shmpage_out;
-    }
-
-    if( sStat.st_size<nByte ){
-      /* The requested memory region does not exist. If bExtend is set to
-      ** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
-      **
-      ** Alternatively, if bExtend is true, use ftruncate() to allocate
-      ** the requested memory region.
-      */
-      if( !bExtend ) goto shmpage_out;
-      if( ftruncate(pShmNode->h, nByte) ){
-        rc = SQLITE_IOERR_SHMSIZE;
-        goto shmpage_out;
-      }
-    }
-
-    /* Map the requested memory region into this processes address space. */
-    apNew = (char **)sqlite3_realloc(
-        pShmNode->apRegion, (iRegion+1)*sizeof(char *)
-    );
-    if( !apNew ){
-      rc = SQLITE_IOERR_NOMEM;
-      goto shmpage_out;
-    }
-    pShmNode->apRegion = apNew;
-    while(pShmNode->nRegion<=iRegion){
-      void *pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, 
-          MAP_SHARED, pShmNode->h, iRegion*szRegion
-      );
-      if( pMem==MAP_FAILED ){
-        rc = SQLITE_IOERR;
-        goto shmpage_out;
-      }
-      pShmNode->apRegion[pShmNode->nRegion] = pMem;
-      pShmNode->nRegion++;
-    }
-  }
-
-shmpage_out:
-  if( pShmNode->nRegion>iRegion ){
-    *pp = pShmNode->apRegion[iRegion];
-  }else{
-    *pp = 0;
-  }
-  sqlite3_mutex_leave(pShmNode->mutex);
-  return rc;
-}
-
-/*
-** Change the lock state for a shared-memory segment.
-**
-** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
-** different here than in posix.  In xShmLock(), one can go from unlocked
-** to shared and back or from unlocked to exclusive and back.  But one may
-** not go from shared to exclusive or from exclusive to shared.
-*/
-static int unixShmLock(
-  sqlite3_file *fd,          /* Database file holding the shared memory */
-  int ofst,                  /* First lock to acquire or release */
-  int n,                     /* Number of locks to acquire or release */
-  int flags                  /* What to do with the lock */
-){
-  unixFile *pDbFd = (unixFile*)fd;      /* Connection holding shared memory */
-  unixShm *p = pDbFd->pShm;             /* The shared memory being locked */
-  unixShm *pX;                          /* For looping over all siblings */
-  unixShmNode *pShmNode = p->pShmNode;  /* The underlying file iNode */
-  int rc = SQLITE_OK;                   /* Result code */
-  u16 mask;                             /* Mask of locks to take or release */
-
-  assert( pShmNode==pDbFd->pInode->pShmNode );
-  assert( pShmNode->pInode==pDbFd->pInode );
-  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
-  assert( n>=1 );
-  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
-       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
-       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
-       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
-  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
-
-  mask = (1<<(ofst+n)) - (1<<ofst);
-  assert( n>1 || mask==(1<<ofst) );
-  sqlite3_mutex_enter(pShmNode->mutex);
-  if( flags & SQLITE_SHM_UNLOCK ){
-    u16 allMask = 0; /* Mask of locks held by siblings */
-
-    /* See if any siblings hold this same lock */
-    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-      if( pX==p ) continue;
-      assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
-      allMask |= pX->sharedMask;
-    }
-
-    /* Unlock the system-level locks */
-    if( (mask & allMask)==0 ){
-      rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n);
-    }else{
-      rc = SQLITE_OK;
-    }
-
-    /* Undo the local locks */
-    if( rc==SQLITE_OK ){
-      p->exclMask &= ~mask;
-      p->sharedMask &= ~mask;
-    } 
-  }else if( flags & SQLITE_SHM_SHARED ){
-    u16 allShared = 0;  /* Union of locks held by connections other than "p" */
-
-    /* Find out which shared locks are already held by sibling connections.
-    ** If any sibling already holds an exclusive lock, go ahead and return
-    ** SQLITE_BUSY.
-    */
-    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-      if( (pX->exclMask & mask)!=0 ){
-        rc = SQLITE_BUSY;
-        break;
-      }
-      allShared |= pX->sharedMask;
-    }
-
-    /* Get shared locks at the system level, if necessary */
-    if( rc==SQLITE_OK ){
-      if( (allShared & mask)==0 ){
-        rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n);
-      }else{
-        rc = SQLITE_OK;
-      }
-    }
-
-    /* Get the local shared locks */
-    if( rc==SQLITE_OK ){
-      p->sharedMask |= mask;
-    }
-  }else{
-    /* Make sure no sibling connections hold locks that will block this
-    ** lock.  If any do, return SQLITE_BUSY right away.
-    */
-    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-      if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
-        rc = SQLITE_BUSY;
-        break;
-      }
-    }
-  
-    /* Get the exclusive locks at the system level.  Then if successful
-    ** also mark the local connection as being locked.
-    */
-    if( rc==SQLITE_OK ){
-      rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n);
-      if( rc==SQLITE_OK ){
-        assert( (p->sharedMask & mask)==0 );
-        p->exclMask |= mask;
-      }
-    }
-  }
-  sqlite3_mutex_leave(pShmNode->mutex);
-  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
-           p->id, getpid(), p->sharedMask, p->exclMask));
-  return rc;
-}
-
-/*
-** Implement a memory barrier or memory fence on shared memory.  
-**
-** All loads and stores begun before the barrier must complete before
-** any load or store begun after the barrier.
-*/
-static void unixShmBarrier(
-  sqlite3_file *fd                /* Database file holding the shared memory */
-){
-  UNUSED_PARAMETER(fd);
-  unixEnterMutex();
-  unixLeaveMutex();
-}
-
-/*
-** Close a connection to shared-memory.  Delete the underlying 
-** storage if deleteFlag is true.
-**
-** If there is no shared memory associated with the connection then this
-** routine is a harmless no-op.
-*/
-static int unixShmUnmap(
-  sqlite3_file *fd,               /* The underlying database file */
-  int deleteFlag                  /* Delete shared-memory if true */
-){
-  unixShm *p;                     /* The connection to be closed */
-  unixShmNode *pShmNode;          /* The underlying shared-memory file */
-  unixShm **pp;                   /* For looping over sibling connections */
-  unixFile *pDbFd;                /* The underlying database file */
-
-  pDbFd = (unixFile*)fd;
-  p = pDbFd->pShm;
-  if( p==0 ) return SQLITE_OK;
-  pShmNode = p->pShmNode;
-
-  assert( pShmNode==pDbFd->pInode->pShmNode );
-  assert( pShmNode->pInode==pDbFd->pInode );
-
-  /* Remove connection p from the set of connections associated
-  ** with pShmNode */
-  sqlite3_mutex_enter(pShmNode->mutex);
-  for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
-  *pp = p->pNext;
-
-  /* Free the connection p */
-  sqlite3_free(p);
-  pDbFd->pShm = 0;
-  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 ) unlink(pShmNode->zFilename);
-    unixShmPurge(pDbFd);
-  }
-  unixLeaveMutex();
-
-  return SQLITE_OK;
-}
-
-
-#else
-# define unixShmMap     0
-# define unixShmLock    0
-# define unixShmBarrier 0
-# define unixShmUnmap   0
-#endif /* #ifndef SQLITE_OMIT_WAL */
-
 /*
 ** Here ends the implementation of all sqlite3_file methods.
 **
 ********************** End sqlite3_file Methods *******************************
 ******************************************************************************/
 
 /*
 ** This division contains definitions of sqlite3_io_methods objects that
@@ -26185,105 +25452,95 @@ static int unixShmUnmap(
 ** Each instance of this macro generates two objects:
 **
 **   *  A constant sqlite3_io_methods object call METHOD that has locking
 **      methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
 **
 **   *  An I/O method finder function called FINDER that returns a pointer
 **      to the METHOD object in the previous bullet.
 */
-#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK)      \
+#define IOMETHODS(FINDER, METHOD, CLOSE, LOCK, UNLOCK, CKLOCK)               \
 static const sqlite3_io_methods METHOD = {                                   \
-   VERSION,                    /* iVersion */                                \
+   1,                          /* iVersion */                                \
    CLOSE,                      /* xClose */                                  \
    unixRead,                   /* xRead */                                   \
    unixWrite,                  /* xWrite */                                  \
    unixTruncate,               /* xTruncate */                               \
    unixSync,                   /* xSync */                                   \
    unixFileSize,               /* xFileSize */                               \
    LOCK,                       /* xLock */                                   \
    UNLOCK,                     /* xUnlock */                                 \
    CKLOCK,                     /* xCheckReservedLock */                      \
    unixFileControl,            /* xFileControl */                            \
    unixSectorSize,             /* xSectorSize */                             \
-   unixDeviceCharacteristics,  /* xDeviceCapabilities */                     \
-   unixShmMap,                 /* xShmMap */                                 \
-   unixShmLock,                /* xShmLock */                                \
-   unixShmBarrier,             /* xShmBarrier */                             \
-   unixShmUnmap                /* xShmUnmap */                               \
+   unixDeviceCharacteristics   /* xDeviceCapabilities */                     \
 };                                                                           \
 static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){   \
   UNUSED_PARAMETER(z); UNUSED_PARAMETER(p);                                  \
   return &METHOD;                                                            \
 }                                                                            \
 static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p)    \
     = FINDER##Impl;
 
 /*
 ** Here are all of the sqlite3_io_methods objects for each of the
 ** locking strategies.  Functions that return pointers to these methods
 ** are also created.
 */
 IOMETHODS(
   posixIoFinder,            /* Finder function name */
   posixIoMethods,           /* sqlite3_io_methods object name */
-  2,                        /* shared memory is enabled */
   unixClose,                /* xClose method */
   unixLock,                 /* xLock method */
   unixUnlock,               /* xUnlock method */
   unixCheckReservedLock     /* xCheckReservedLock method */
 )
 IOMETHODS(
   nolockIoFinder,           /* Finder function name */
   nolockIoMethods,          /* sqlite3_io_methods object name */
-  1,                        /* shared memory is disabled */
   nolockClose,              /* xClose method */
   nolockLock,               /* xLock method */
   nolockUnlock,             /* xUnlock method */
   nolockCheckReservedLock   /* xCheckReservedLock method */
 )
 IOMETHODS(
   dotlockIoFinder,          /* Finder function name */
   dotlockIoMethods,         /* sqlite3_io_methods object name */
-  1,                        /* shared memory is disabled */
   dotlockClose,             /* xClose method */
   dotlockLock,              /* xLock method */
   dotlockUnlock,            /* xUnlock method */
   dotlockCheckReservedLock  /* xCheckReservedLock method */
 )
 
 #if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
 IOMETHODS(
   flockIoFinder,            /* Finder function name */
   flockIoMethods,           /* sqlite3_io_methods object name */
-  1,                        /* shared memory is disabled */
   flockClose,               /* xClose method */
   flockLock,                /* xLock method */
   flockUnlock,              /* xUnlock method */
   flockCheckReservedLock    /* xCheckReservedLock method */
 )
 #endif
 
 #if OS_VXWORKS
 IOMETHODS(
   semIoFinder,              /* Finder function name */
   semIoMethods,             /* sqlite3_io_methods object name */
-  1,                        /* shared memory is disabled */
   semClose,                 /* xClose method */
   semLock,                  /* xLock method */
   semUnlock,                /* xUnlock method */
   semCheckReservedLock      /* xCheckReservedLock method */
 )
 #endif
 
 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
 IOMETHODS(
   afpIoFinder,              /* Finder function name */
   afpIoMethods,             /* sqlite3_io_methods object name */
-  1,                        /* shared memory is disabled */
   afpClose,                 /* xClose method */
   afpLock,                  /* xLock method */
   afpUnlock,                /* xUnlock method */
   afpCheckReservedLock      /* xCheckReservedLock method */
 )
 #endif
 
 /*
@@ -26298,30 +25555,28 @@ IOMETHODS(
 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
 static int proxyClose(sqlite3_file*);
 static int proxyLock(sqlite3_file*, int);
 static int proxyUnlock(sqlite3_file*, int);
 static int proxyCheckReservedLock(sqlite3_file*, int*);
 IOMETHODS(
   proxyIoFinder,            /* Finder function name */
   proxyIoMethods,           /* sqlite3_io_methods object name */
-  1,                        /* shared memory is disabled */
   proxyClose,               /* xClose method */
   proxyLock,                /* xLock method */
   proxyUnlock,              /* xUnlock method */
   proxyCheckReservedLock    /* xCheckReservedLock method */
 )
 #endif
 
 /* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */
 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
 IOMETHODS(
   nfsIoFinder,               /* Finder function name */
   nfsIoMethods,              /* sqlite3_io_methods object name */
-  1,                         /* shared memory is disabled */
   unixClose,                 /* xClose method */
   unixLock,                  /* xLock method */
   nfsUnlock,                 /* xUnlock method */
   unixCheckReservedLock      /* xCheckReservedLock method */
 )
 #endif
 
 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
@@ -26452,29 +25707,29 @@ static int fillInUnixFile(
   const char *zFilename,  /* Name of the file being opened */
   int noLock,             /* Omit locking if true */
   int isDelete            /* Delete on close if true */
 ){
   const sqlite3_io_methods *pLockingStyle;
   unixFile *pNew = (unixFile *)pId;
   int rc = SQLITE_OK;
 
-  assert( pNew->pInode==NULL );
+  assert( pNew->pLock==NULL );
+  assert( pNew->pOpen==NULL );
 
   /* Parameter isDelete is only used on vxworks. Express this explicitly 
   ** here to prevent compiler warnings about unused parameters.
   */
   UNUSED_PARAMETER(isDelete);
 
-  OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
+  OSTRACE3("OPEN    %-3d %s\n", h, zFilename);    
   pNew->h = h;
   pNew->dirfd = dirfd;
+  SET_THREADID(pNew);
   pNew->fileFlags = 0;
-  assert( zFilename==0 || zFilename[0]=='/' );  /* Never a relative pathname */
-  pNew->zPath = zFilename;
 
 #if OS_VXWORKS
   pNew->pId = vxworksFindFileId(zFilename);
   if( pNew->pId==0 ){
     noLock = 1;
     rc = SQLITE_NOMEM;
   }
 #endif
@@ -26492,29 +25747,29 @@ static int fillInUnixFile(
   }
 
   if( pLockingStyle == &posixIoMethods
 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
     || pLockingStyle == &nfsIoMethods
 #endif
   ){
     unixEnterMutex();
-    rc = findInodeInfo(pNew, &pNew->pInode);
+    rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
     if( rc!=SQLITE_OK ){
-      /* If an error occured in findInodeInfo(), close the file descriptor
-      ** immediately, before releasing the mutex. findInodeInfo() may fail
+      /* If an error occured in findLockInfo(), close the file descriptor
+      ** immediately, before releasing the mutex. findLockInfo() may fail
       ** in two scenarios:
       **
       **   (a) A call to fstat() failed.
       **   (b) A malloc failed.
       **
       ** Scenario (b) may only occur if the process is holding no other
       ** file descriptors open on the same file. If there were other file
       ** descriptors on this file, then no malloc would be required by
-      ** findInodeInfo(). If this is the case, it is quite safe to close
+      ** findLockInfo(). If this is the case, it is quite safe to close
       ** handle h - as it is guaranteed that no posix locks will be released
       ** by doing so.
       **
       ** If scenario (a) caused the error then things are not so safe. The
       ** implicit assumption here is that if fstat() fails, things are in
       ** such bad shape that dropping a lock or two doesn't matter much.
       */
       close(h);
@@ -26535,17 +25790,17 @@ static int fillInUnixFile(
     }else{
       /* NB: zFilename exists and remains valid until the file is closed
       ** according to requirement F11141.  So we do not need to make a
       ** copy of the filename. */
       pCtx->dbPath = zFilename;
       pCtx->reserved = 0;
       srandomdev();
       unixEnterMutex();
-      rc = findInodeInfo(pNew, &pNew->pInode);
+      rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
       if( rc!=SQLITE_OK ){
         sqlite3_free(pNew->lockingContext);
         close(h);
         h = -1;
       }
       unixLeaveMutex();        
     }
   }
@@ -26568,28 +25823,28 @@ static int fillInUnixFile(
   }
 
 #if OS_VXWORKS
   else if( pLockingStyle == &semIoMethods ){
     /* Named semaphore locking uses the file path so it needs to be
     ** included in the semLockingContext
     */
     unixEnterMutex();
-    rc = findInodeInfo(pNew, &pNew->pInode);
-    if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){
-      char *zSemName = pNew->pInode->aSemName;
+    rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
+    if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
+      char *zSemName = pNew->pOpen->aSemName;
       int n;
       sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem",
                        pNew->pId->zCanonicalName);
       for( n=1; zSemName[n]; n++ )
         if( zSemName[n]=='/' ) zSemName[n] = '_';
-      pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
-      if( pNew->pInode->pSem == SEM_FAILED ){
+      pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
+      if( pNew->pOpen->pSem == SEM_FAILED ){
         rc = SQLITE_NOMEM;
-        pNew->pInode->aSemName[0] = '\0';
+        pNew->pOpen->aSemName[0] = '\0';
       }
     }
     unixLeaveMutex();
   }
 #endif
   
   pNew->lastErrno = 0;
 #if OS_VXWORKS
@@ -26630,73 +25885,64 @@ static int openDirectory(const char *zFi
   for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
   if( ii>0 ){
     zDirname[ii] = '\0';
     fd = open(zDirname, O_RDONLY|O_BINARY, 0);
     if( fd>=0 ){
 #ifdef FD_CLOEXEC
       fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
 #endif
-      OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
+      OSTRACE3("OPENDIR %-3d %s\n", fd, zDirname);
     }
   }
   *pFd = fd;
   return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN_BKPT);
 }
 
 /*
-** 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){
+** Create a temporary file name in zBuf.  zBuf must be allocated
+** by the calling process and must be big enough to hold at least
+** pVfs->mxPathname bytes.
+*/
+static int getTempname(int nBuf, char *zBuf){
   static const char *azDirs[] = {
      0,
      0,
      "/var/tmp",
      "/usr/tmp",
      "/tmp",
-     0        /* List terminator */
+     ".",
   };
-  unsigned int i;
-  struct stat buf;
-  const char *zDir = 0;
-
-  azDirs[0] = sqlite3_temp_directory;
-  if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
-  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
-    if( zDir==0 ) continue;
-    if( stat(zDir, &buf) ) continue;
-    if( !S_ISDIR(buf.st_mode) ) continue;
-    if( access(zDir, 07) ) continue;
-    break;
-  }
-  return zDir;
-}
-
-/*
-** Create a temporary file name in zBuf.  zBuf must be allocated
-** by the calling process and must be big enough to hold at least
-** pVfs->mxPathname bytes.
-*/
-static int unixGetTempname(int nBuf, char *zBuf){
   static const unsigned char zChars[] =
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "0123456789";
   unsigned int i, j;
-  const char *zDir;
+  struct stat buf;
+  const char *zDir = ".";
 
   /* It's odd to simulate an io-error here, but really this is just
   ** using the io-error infrastructure to test that SQLite handles this
   ** function failing. 
   */
   SimulateIOError( return SQLITE_IOERR );
 
-  zDir = unixTempFileDir();
-  if( zDir==0 ) zDir = ".";
+  azDirs[0] = sqlite3_temp_directory;
+  if (NULL == azDirs[1]) {
+    azDirs[1] = getenv("TMPDIR");
+  }
+  
+  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
+    if( azDirs[i]==0 ) continue;
+    if( stat(azDirs[i], &buf) ) continue;
+    if( !S_ISDIR(buf.st_mode) ) continue;
+    if( access(azDirs[i], 07) ) continue;
+    zDir = azDirs[i];
+    break;
+  }
 
   /* 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 ){
     return SQLITE_ERROR;
   }
 
@@ -26752,84 +25998,39 @@ static UnixUnusedFd *findReusableFd(cons
   ** 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) ){
-    unixInodeInfo *pInode;
+    struct unixOpenCnt *pOpen;
 
     unixEnterMutex();
-    pInode = inodeList;
-    while( pInode && (pInode->fileId.dev!=sStat.st_dev
-                     || pInode->fileId.ino!=sStat.st_ino) ){
-       pInode = pInode->pNext;
-    }
-    if( pInode ){
+    pOpen = openList;
+    while( pOpen && (pOpen->fileId.dev!=sStat.st_dev
+                     || pOpen->fileId.ino!=sStat.st_ino) ){
+       pOpen = pOpen->pNext;
+    }
+    if( pOpen ){
       UnixUnusedFd **pp;
-      for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
+      for(pp=&pOpen->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
       pUnused = *pp;
       if( pUnused ){
         *pp = pUnused->pNext;
       }
     }
     unixLeaveMutex();
   }
 #endif    /* if !OS_VXWORKS */
   return pUnused;
 }
 
 /*
-** This function is called by unixOpen() to determine the unix permissions
-** to create new files with. If no error occurs, then SQLITE_OK is returned
-** and a value suitable for passing as the third argument to open(2) is
-** written to *pMode. If an IO error occurs, an SQLite error code is 
-** returned and the value of *pMode is not modified.
-**
-** If the file being opened is a temporary file, it is always created with
-** the octal permissions 0600 (read/writable by owner only). If the file
-** is a database or master journal file, it is created with the permissions 
-** mask SQLITE_DEFAULT_FILE_PERMISSIONS.
-**
-** Finally, if the file being opened is a WAL or regular journal file, then 
-** this function queries the file-system for the permissions on the 
-** corresponding database file and sets *pMode to this value. Whenever 
-** possible, WAL and journal files are created using the same permissions 
-** as the associated database file.
-*/
-static int findCreateFileMode(
-  const char *zPath,              /* Path of file (possibly) being created */
-  int flags,                      /* Flags passed as 4th argument to xOpen() */
-  mode_t *pMode                   /* OUT: Permissions to open file with */
-){
-  int rc = SQLITE_OK;             /* Return Code */
-  if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
-    char zDb[MAX_PATHNAME+1];     /* Database file path */
-    int nDb;                      /* Number of valid bytes in zDb */
-    struct stat sStat;            /* Output of stat() on database file */
-
-    nDb = sqlite3Strlen30(zPath) - ((flags & SQLITE_OPEN_WAL) ? 4 : 8);
-    memcpy(zDb, zPath, nDb);
-    zDb[nDb] = '\0';
-    if( 0==stat(zDb, &sStat) ){
-      *pMode = sStat.st_mode & 0777;
-    }else{
-      rc = SQLITE_IOERR_FSTAT;
-    }
-  }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
-    *pMode = 0600;
-  }else{
-    *pMode = SQLITE_DEFAULT_FILE_PERMISSIONS;
-  }
-  return rc;
-}
-
-/*
 ** Open the file zPath.
 ** 
 ** Previously, the SQLite OS layer used three functions in place of this
 ** one:
 **
 **     sqlite3OsOpenReadWrite();
 **     sqlite3OsOpenReadOnly();
 **     sqlite3OsOpenExclusive();
@@ -26869,21 +26070,19 @@ static int unixOpen(
 #if SQLITE_ENABLE_LOCKING_STYLE
   int isAutoProxy  = (flags & SQLITE_OPEN_AUTOPROXY);
 #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 && (
-        eType==SQLITE_OPEN_MASTER_JOURNAL 
-     || eType==SQLITE_OPEN_MAIN_JOURNAL 
-     || eType==SQLITE_OPEN_WAL
-  ));
+  int isOpenDirectory = (isCreate && 
+      (eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL)
+  );
 
   /* 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];
   const char *zName = zPath;
 
   /* Check the following statements are true: 
@@ -26893,28 +26092,27 @@ static int unixOpen(
   **   (c) if EXCLUSIVE is set, then CREATE must also be set.
   **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
   */
   assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
   assert(isCreate==0 || isReadWrite);
   assert(isExclusive==0 || isCreate);
   assert(isDelete==0 || isCreate);
 
-  /* The main DB, main journal, WAL file and master journal are never 
-  ** automatically deleted. Nor are they ever temporary files.  */
+  /* The main DB, main journal, and master journal are never automatically
+  ** deleted. Nor are they ever temporary files.  */
   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
   assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
-  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
 
   /* Assert that the upper layer has set one of the "file-type" flags. */
   assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB 
        || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 
        || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL 
-       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
+       || eType==SQLITE_OPEN_TRANSIENT_DB
   );
 
   memset(p, 0, sizeof(unixFile));
 
   if( eType==SQLITE_OPEN_MAIN_DB ){
     UnixUnusedFd *pUnused;
     pUnused = findReusableFd(zName, flags);
     if( pUnused ){
@@ -26924,17 +26122,17 @@ static int unixOpen(
       if( !pUnused ){
         return SQLITE_NOMEM;
       }
     }
     p->pUnused = pUnused;
   }else if( !zName ){
     /* If zName is NULL, the upper layer is requesting a temp file. */
     assert(isDelete && !isOpenDirectory);
-    rc = unixGetTempname(MAX_PATHNAME+1, zTmpname);
+    rc = getTempname(MAX_PATHNAME+1, zTmpname);
     if( rc!=SQLITE_OK ){
       return rc;
     }
     zName = zTmpname;
   }
 
   /* Determine the value of the flags parameter passed to POSIX function
   ** open(). These must be calculated even if open() is not called, as
@@ -26942,25 +26140,19 @@ static int unixOpen(
   ** 'conch file' locking functions later on.  */
   if( isReadonly )  openFlags |= O_RDONLY;
   if( isReadWrite ) openFlags |= O_RDWR;
   if( isCreate )    openFlags |= O_CREAT;
   if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
   openFlags |= (O_LARGEFILE|O_BINARY);
 
   if( fd<0 ){
-    mode_t openMode;              /* Permissions to create file with */
-    rc = findCreateFileMode(zName, flags, &openMode);
-    if( rc!=SQLITE_OK ){
-      assert( !p->pUnused );
-      assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
-      return rc;
-    }
+    mode_t openMode = (isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
     fd = open(zName, openFlags, openMode);
-    OSTRACE(("OPENX   %-3d %s 0%o\n", fd, zName, openFlags));
+    OSTRACE4("OPENX   %-3d %s 0%o\n", fd, zName, openFlags);
     if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
       /* Failed to open the file for read/write access. Try read-only. */
       flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
       openFlags &= ~(O_RDWR|O_CREAT);
       flags |= SQLITE_OPEN_READONLY;
       openFlags |= O_RDONLY;
       fd = open(zName, openFlags, openMode);
     }
@@ -27091,19 +26283,17 @@ 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 ){
-    return SQLITE_IOERR_DELETE;
-  }
+  unlink(zPath);
 #ifndef SQLITE_DISABLE_DIRSYNC
   if( dirSync ){
     int fd;
     rc = openDirectory(zPath, &fd);
     if( rc==SQLITE_OK ){
 #if OS_VXWORKS
       if( fsync(fd)==-1 )
 #else
@@ -27150,22 +26340,16 @@ static int unixAccess(
     case SQLITE_ACCESS_READ:
       amode = R_OK;
       break;
 
     default:
       assert(!"Invalid flags argument");
   }
   *pResOut = (access(zPath, amode)==0);
-  if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
-    struct stat buf;
-    if( 0==stat(zPath, &buf) && buf.st_size==0 ){
-      *pResOut = 0;
-    }
-  }
   return SQLITE_OK;
 }
 
 
 /*
 ** Turn a relative pathname into a full pathname. The relative path
 ** is stored as a nul-terminated string in the buffer pointed to by
 ** zPath. 
@@ -27344,59 +26528,45 @@ static int unixSleep(sqlite3_vfs *NotUse
 ** the number of seconds since 1970 and is used to set the result of
 ** sqlite3OsCurrentTime() during testing.
 */
 #ifdef SQLITE_TEST
 SQLITE_API int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
 #endif
 
 /*
-** 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.
-*/
-static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
-  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
-#if defined(NO_GETTOD)
-  time_t t;
-  time(&t);
-  *piNow = ((sqlite3_int64)i)*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;
-#endif
-
-#ifdef SQLITE_TEST
-  if( sqlite3_current_time ){
-    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
-  }
-#endif
-  UNUSED_PARAMETER(NotUsed);
-  return 0;
-}
-
-/*
 ** 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;
+#if defined(SQLITE_OMIT_FLOATING_POINT)
+  time_t t;
+  time(&t);
+  *prNow = (((sqlite3_int64)t)/8640 + 24405875)/10;
+#elif defined(NO_GETTOD)
+  time_t t;
+  time(&t);
+  *prNow = t/86400.0 + 2440587.5;
+#elif OS_VXWORKS
+  struct timespec sNow;
+  clock_gettime(CLOCK_REALTIME, &sNow);
+  *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_nsec/86400000000000.0;
+#else
+  struct timeval sNow;
+  gettimeofday(&sNow, 0);
+  *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_usec/86400000000.0;
+#endif
+
+#ifdef SQLITE_TEST
+  if( sqlite3_current_time ){
+    *prNow = sqlite3_current_time/86400.0 + 2440587.5;
+  }
+#endif
   UNUSED_PARAMETER(NotUsed);
-  unixCurrentTimeInt64(0, &i);
-  *prNow = i/86400000.0;
   return 0;
 }
 
 /*
 ** 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
@@ -27404,17 +26574,16 @@ static int unixCurrentTime(sqlite3_vfs *
 */
 static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
   UNUSED_PARAMETER(NotUsed);
   UNUSED_PARAMETER(NotUsed2);
   UNUSED_PARAMETER(NotUsed3);
   return 0;
 }
 
-
 /*
 ************************ End of sqlite3_vfs methods ***************************
 ******************************************************************************/
 
 /******************************************************************************
 ************************** Begin Proxy Locking ********************************
 **
 ** Proxy locking is a "uber-locking-method" in this sense:  It uses the
@@ -27595,40 +26764,40 @@ static int proxyGetLockPath(const char *
   int i;
 
 #ifdef LOCKPROXYDIR
   len = strlcpy(lPath, LOCKPROXYDIR, maxLen);
 #else
 # ifdef _CS_DARWIN_USER_TEMP_DIR
   {
     if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){
-      OSTRACE(("GETLOCKPATH  failed %s errno=%d pid=%d\n",
-               lPath, errno, getpid()));
+      OSTRACE4("GETLOCKPATH  failed %s errno=%d pid=%d\n",
+               lPath, errno, getpid());
       return SQLITE_IOERR_LOCK;
     }
     len = strlcat(lPath, "sqliteplocks", maxLen);    
   }
 # else
   len = strlcpy(lPath, "/tmp/", maxLen);
 # endif
 #endif
 
   if( lPath[len-1]!='/' ){
     len = strlcat(lPath, "/", maxLen);
   }
   
   /* transform the db path to a unique cache name */
   dbLen = (int)strlen(dbPath);
-  for( i=0; i<dbLen && (i+len+7)<(int)maxLen; i++){
+  for( i=0; i<dbLen && (i+len+7)<maxLen; i++){
     char c = dbPath[i];
     lPath[i+len] = (c=='/')?'_':c;
   }
   lPath[i+len]='\0';
   strlcat(lPath, ":auto:", maxLen);
-  OSTRACE(("GETLOCKPATH  proxy lock path=%s pid=%d\n", lPath, getpid()));
+  OSTRACE3("GETLOCKPATH  proxy lock path=%s pid=%d\n", lPath, getpid());
   return SQLITE_OK;
 }
 
 /* 
  ** Creates the lock file and any missing directories in lockPath
  */
 static int proxyCreateLockPath(const char *lockPath){
   int i, len;
@@ -27643,28 +26812,28 @@ static int proxyCreateLockPath(const cha
     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) ){
           int err=errno;
           if( err!=EEXIST ) {
-            OSTRACE(("CREATELOCKPATH  FAILED creating %s, "
+            OSTRACE5("CREATELOCKPATH  FAILED creating %s, "
                      "'%s' proxy lock path=%s pid=%d\n",
-                     buf, strerror(err), lockPath, getpid()));
+                     buf, strerror(err), lockPath, getpid());
             return err;
           }
         }
       }
       start=i+1;
     }
     buf[i] = lockPath[i];
   }
-  OSTRACE(("CREATELOCKPATH  proxy lock path=%s pid=%d\n", lockPath, getpid()));
+  OSTRACE3("CREATELOCKPATH  proxy lock path=%s pid=%d\n", lockPath, getpid());
   return 0;
 }
 
 /*
 ** Create a new VFS file descriptor (stored in memory obtained from
 ** sqlite3_malloc) and open the file named "path" in the file descriptor.
 **
 ** The caller is responsible not only for closing the file descriptor
@@ -27753,19 +26922,16 @@ end_create_proxy:
 
 #ifdef SQLITE_TEST
 /* simulate multiple hosts by creating unique hostid file paths */
 SQLITE_API int sqlite3_hostid_num = 0;
 #endif
 
 #define PROXY_HOSTIDLEN    16  /* conch file host id length */
 
-/* Not always defined in the headers as it ought to be */
-extern int gethostuuid(uuid_t id, const struct timespec *wait);
-
 /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN 
 ** bytes of writable memory.
 */
 static int proxyGetHostID(unsigned char *pHostID, int *pError){
   struct timespec timeout = {1, 0}; /* 1 sec timeout */
   
   assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
   memset(pHostID, 0, PROXY_HOSTIDLEN);
@@ -27805,17 +26971,16 @@ static int proxyBreakConchLock(unixFile 
   char tPath[MAXPATHLEN];
   char buf[PROXY_MAXCONCHLEN];
   char *cPath = pCtx->conchFilePath;
   size_t readLen = 0;
   size_t pathLen = 0;
   char errmsg[64] = "";
   int fd = -1;
   int rc = -1;
-  UNUSED_PARAMETER(myHostID);
 
   /* create a new path by replace the trailing '-conch' with '-break' */
   pathLen = strlcpy(tPath, cPath, MAXPATHLEN);
   if( pathLen>MAXPATHLEN || pathLen<6 || 
      (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){
     sprintf(errmsg, "path error (len %d)", (int)pathLen);
     goto end_breaklock;
   }
@@ -27826,17 +26991,17 @@ static int proxyBreakConchLock(unixFile 
     goto end_breaklock;
   }
   /* write it out to the temporary break file */
   fd = open(tPath, (O_RDWR|O_CREAT|O_EXCL), SQLITE_DEFAULT_FILE_PERMISSIONS);
   if( fd<0 ){
     sprintf(errmsg, "create failed (%d)", errno);
     goto end_breaklock;
   }
-  if( pwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){
+  if( pwrite(fd, buf, readLen, 0) != readLen ){
     sprintf(errmsg, "write failed (%d)", errno);
     goto end_breaklock;
   }
   if( rename(tPath, cPath) ){
     sprintf(errmsg, "rename failed (%d)", errno);
     goto end_breaklock;
   }
   rc = 0;
@@ -27950,18 +27115,18 @@ static int proxyTakeConch(unixFile *pFil
     char *tempLockPath = NULL;
     int rc = SQLITE_OK;
     int createConch = 0;
     int hostIdMatch = 0;
     int readLen = 0;
     int tryOldLockPath = 0;
     int forceNewLockPath = 0;
     
-    OSTRACE(("TAKECONCH  %d for %s pid=%d\n", conchFile->h,
-             (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid()));
+    OSTRACE4("TAKECONCH  %d for %s pid=%d\n", conchFile->h,
+             (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid());
 
     rc = proxyGetHostID(myHostID, &pError);
     if( (rc&0xff)==SQLITE_IOERR ){
       pFile->lastErrno = pError;
       goto end_takeconch;
     }
     rc = proxyConchLock(pFile, myHostID, SHARED_LOCK);
     if( rc!=SQLITE_OK ){
@@ -28031,17 +27196,17 @@ static int proxyTakeConch(unixFile *pFil
       }
       
       /* update conch with host and path (this will fail if other process
       ** has a shared lock already), if the host id matches, use the big
       ** stick.
       */
       futimes(conchFile->h, NULL);
       if( hostIdMatch && !createConch ){
-        if( conchFile->pInode && conchFile->pInode->nShared>1 ){
+        if( conchFile->pLock && conchFile->pLock->cnt>1 ){
           /* We are trying for an exclusive lock but another thread in this
            ** same process is still holding a shared lock. */
           rc = SQLITE_BUSY;
         } else {          
           rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
         }
       }else{
         rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
@@ -28087,32 +27252,32 @@ static int proxyTakeConch(unixFile *pFil
                     err, code, strerror(code));
 #endif
           }
         }
       }
       conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK);
       
     end_takeconch:
-      OSTRACE(("TRANSPROXY: CLOSE  %d\n", pFile->h));
+      OSTRACE2("TRANSPROXY: CLOSE  %d\n", pFile->h);
       if( rc==SQLITE_OK && pFile->openFlags ){
         if( pFile->h>=0 ){
 #ifdef STRICT_CLOSE_ERROR
           if( close(pFile->h) ){
             pFile->lastErrno = errno;
             return SQLITE_IOERR_CLOSE;
           }
 #else
           close(pFile->h); /* silently leak fd if fail */
 #endif
         }
         pFile->h = -1;
         int fd = open(pCtx->dbPath, pFile->openFlags,
                       SQLITE_DEFAULT_FILE_PERMISSIONS);
-        OSTRACE(("TRANSPROXY: OPEN  %d\n", fd));
+        OSTRACE2("TRANSPROXY: OPEN  %d\n", fd);
         if( fd>=0 ){
           pFile->h = fd;
         }else{
           rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called
            during locking */
         }
       }
       if( rc==SQLITE_OK && !pCtx->lockProxy ){
@@ -28144,43 +27309,41 @@ static int proxyTakeConch(unixFile *pFil
         if( pCtx->lockProxy->pMethod == &afpIoMethods ){
           afpLockingContext *afpCtx;
           afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext;
           afpCtx->dbPath = pCtx->lockProxyPath;
         }
       } else {
         conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
       }
-      OSTRACE(("TAKECONCH  %d %s\n", conchFile->h,
-               rc==SQLITE_OK?"ok":"failed"));
+      OSTRACE3("TAKECONCH  %d %s\n", conchFile->h, rc==SQLITE_OK?"ok":"failed");
       return rc;
-    } while (1); /* in case we need to retry the :auto: lock file - 
-                 ** we should never get here except via the 'continue' call. */
+    } while (1); /* in case we need to retry the :auto: lock file - we should never get here except via the 'continue' call. */
   }
 }
 
 /*
 ** If pFile holds a lock on a conch file, then release that lock.
 */
 static int proxyReleaseConch(unixFile *pFile){
-  int rc = SQLITE_OK;         /* Subroutine return code */
+  int rc;                     /* Subroutine return code */
   proxyLockingContext *pCtx;  /* The locking context for the proxy lock */
   unixFile *conchFile;        /* Name of the conch file */
 
   pCtx = (proxyLockingContext *)pFile->lockingContext;
   conchFile = pCtx->conchFile;
-  OSTRACE(("RELEASECONCH  %d for %s pid=%d\n", conchFile->h,
+  OSTRACE4("RELEASECONCH  %d for %s pid=%d\n", conchFile->h,
            (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), 
-           getpid()));
+           getpid());
   if( pCtx->conchHeld>0 ){
     rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
   }
   pCtx->conchHeld = 0;
-  OSTRACE(("RELEASECONCH  %d %s\n", conchFile->h,
-           (rc==SQLITE_OK ? "ok" : "failed")));
+  OSTRACE3("RELEASECONCH  %d %s\n", conchFile->h,
+           (rc==SQLITE_OK ? "ok" : "failed"));
   return rc;
 }
 
 /*
 ** Given the name of a database file, compute the name of its conch file.
 ** Store the conch filename in memory obtained from sqlite3_malloc().
 ** Make *pConchPath point to the new name.  Return SQLITE_OK on success
 ** or SQLITE_NOMEM if unable to obtain memory.
@@ -28227,17 +27390,17 @@ static int proxyCreateConchPathname(char
 /* Takes a fully configured proxy locking-style unix file and switches
 ** the local lock file path 
 */
 static int switchLockProxyPath(unixFile *pFile, const char *path) {
   proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
   char *oldPath = pCtx->lockProxyPath;
   int rc = SQLITE_OK;
 
-  if( pFile->eFileLock!=NO_LOCK ){
+  if( pFile->locktype!=NO_LOCK ){
     return SQLITE_BUSY;
   }  
 
   /* nothing to do if the path is NULL, :auto: or matches the existing path */
   if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ||
     (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){
     return SQLITE_OK;
   }else{
@@ -28294,28 +27457,28 @@ static int proxyGetDbPathForUnixFile(uni
 **  ->pMethod
 */
 static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
   proxyLockingContext *pCtx;
   char dbPath[MAXPATHLEN+1];       /* Name of the database file */
   char *lockPath=NULL;
   int rc = SQLITE_OK;
   
-  if( pFile->eFileLock!=NO_LOCK ){
+  if( pFile->locktype!=NO_LOCK ){
     return SQLITE_BUSY;
   }
   proxyGetDbPathForUnixFile(pFile, dbPath);
   if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){
     lockPath=NULL;
   }else{
     lockPath=(char *)path;
   }
   
-  OSTRACE(("TRANSPROXY  %d for %s pid=%d\n", pFile->h,
-           (lockPath ? lockPath : ":auto:"), getpid()));
+  OSTRACE4("TRANSPROXY  %d for %s pid=%d\n", pFile->h,
+           (lockPath ? lockPath : ":auto:"), getpid());
 
   pCtx = sqlite3_malloc( sizeof(*pCtx) );
   if( pCtx==0 ){
     return SQLITE_NOMEM;
   }
   memset(pCtx, 0, sizeof(*pCtx));
 
   rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath);
@@ -28365,18 +27528,18 @@ static int proxyTransformUnixFile(unixFi
     if( pCtx->conchFile ){ 
       pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile);
       sqlite3_free(pCtx->conchFile);
     }
     sqlite3_free(pCtx->lockProxyPath);
     sqlite3_free(pCtx->conchFilePath); 
     sqlite3_free(pCtx);
   }
-  OSTRACE(("TRANSPROXY  %d %s\n", pFile->h,
-           (rc==SQLITE_OK ? "ok" : "failed")));
+  OSTRACE3("TRANSPROXY  %d %s\n", pFile->h,
+           (rc==SQLITE_OK ? "ok" : "failed"));
   return rc;
 }
 
 
 /*
 ** This routine handles sqlite3_file_control() calls that are specific
 ** to proxy locking.
 */
@@ -28461,17 +27624,17 @@ static int proxyCheckReservedLock(sqlite
     }else{ /* conchHeld < 0 is lockless */
       pResOut=0;
     }
   }
   return rc;
 }
 
 /*
-** Lock the file with the lock specified by parameter eFileLock - one
+** Lock the file with the lock specified by parameter locktype - one
 ** of the following:
 **
 **     (1) SHARED_LOCK
 **     (2) RESERVED_LOCK
 **     (3) PENDING_LOCK
 **     (4) EXCLUSIVE_LOCK
 **
 ** Sometimes when requesting one lock state, additional lock states
@@ -28484,49 +27647,49 @@ static int proxyCheckReservedLock(sqlite
 **    SHARED -> RESERVED
 **    SHARED -> (PENDING) -> EXCLUSIVE
 **    RESERVED -> (PENDING) -> EXCLUSIVE
 **    PENDING -> EXCLUSIVE
 **
 ** This routine will only increase a lock.  Use the sqlite3OsUnlock()
 ** routine to lower a locking level.
 */
-static int proxyLock(sqlite3_file *id, int eFileLock) {
+static int proxyLock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
   int rc = proxyTakeConch(pFile);
   if( rc==SQLITE_OK ){
     proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
     if( pCtx->conchHeld>0 ){
       unixFile *proxy = pCtx->lockProxy;
-      rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock);
-      pFile->eFileLock = proxy->eFileLock;
+      rc = proxy->pMethod->xLock((sqlite3_file*)proxy, locktype);
+      pFile->locktype = proxy->locktype;
     }else{
       /* conchHeld < 0 is lockless */
     }
   }
   return rc;
 }
 
 
 /*
-** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
+** Lower the locking level on file descriptor pFile to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
 **
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 */
-static int proxyUnlock(sqlite3_file *id, int eFileLock) {
+static int proxyUnlock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
   int rc = proxyTakeConch(pFile);
   if( rc==SQLITE_OK ){
     proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
     if( pCtx->conchHeld>0 ){
       unixFile *proxy = pCtx->lockProxy;
-      rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock);
-      pFile->eFileLock = proxy->eFileLock;
+      rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, locktype);
+      pFile->locktype = proxy->locktype;
     }else{
       /* conchHeld < 0 is lockless */
     }
   }
   return rc;
 }
 
 /*
@@ -28611,35 +27774,34 @@ SQLITE_API int sqlite3_os_init(void){
   **
   ** Most finders simply return a pointer to a fixed sqlite3_io_methods
   ** object.  But the "autolockIoFinder" available on MacOSX does a little
   ** more than that; it looks at the filesystem type that hosts the 
   ** database file and tries to choose an locking method appropriate for
   ** that filesystem time.
   */
   #define UNIXVFS(VFSNAME, FINDER) {                        \
-    2,                    /* iVersion */                    \
+    1,                    /* iVersion */                    \
     sizeof(unixFile),     /* szOsFile */                    \
     MAX_PATHNAME,         /* mxPathname */                  \
     0,                    /* pNext */                       \
     VFSNAME,              /* zName */                       \
     (void*)&FINDER,       /* pAppData */                    \
     unixOpen,             /* xOpen */                       \
     unixDelete,           /* xDelete */                     \
     unixAccess,           /* xAccess */                     \
     unixFullPathname,     /* xFullPathname */               \
     unixDlOpen,           /* xDlOpen */                     \
     unixDlError,          /* xDlError */                    \
     unixDlSym,            /* xDlSym */                      \
     unixDlClose,          /* xDlClose */                    \
     unixRandomness,       /* xRandomness */                 \
     unixSleep,            /* xSleep */                      \
     unixCurrentTime,      /* xCurrentTime */                \
-    unixGetLastError,     /* xGetLastError */               \
-    unixCurrentTimeInt64, /* xCurrentTimeInt64 */           \
+    unixGetLastError      /* xGetLastError */               \
   }
 
   /*
   ** All default VFSes for unix are contained in the following array.
   **
   ** Note that the sqlite3_vfs.pNext field of the VFS object is modified
   ** by the SQLite core when the VFS is registered.  So the following
   ** array cannot be const.
@@ -28780,19 +27942,33 @@ SQLITE_API int sqlite3_os_end(void){
 ** 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)
+#define OSTRACE1(X)         if( sqlite3OSTrace ) sqlite3DebugPrintf(X)
+#define OSTRACE2(X,Y)       if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y)
+#define OSTRACE3(X,Y,Z)     if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z)
+#define OSTRACE4(X,Y,Z,A)   if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A)
+#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B)
+#define OSTRACE6(X,Y,Z,A,B,C) \
+    if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
+#define OSTRACE7(X,Y,Z,A,B,C,D) \
+    if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
+#else
+#define OSTRACE1(X)
+#define OSTRACE2(X,Y)
+#define OSTRACE3(X,Y,Z)
+#define OSTRACE4(X,Y,Z,A)
+#define OSTRACE5(X,Y,Z,A,B)
+#define OSTRACE6(X,Y,Z,A,B,C)
+#define OSTRACE7(X,Y,Z,A,B,C,D)
 #endif
 
 /*
 ** Macros for performance tracing.  Normally turned off.  Only works
 ** on i486 hardware.
 */
 #ifdef SQLITE_PERFORMANCE_TRACE
 
@@ -28968,20 +28144,16 @@ SQLITE_API int sqlite3_open_file_count =
 ** Determine if we are dealing with WindowsCE - which has a much
 ** reduced API.
 */
 #if SQLITE_OS_WINCE
 # define AreFileApisANSI() 1
 # define FormatMessageW(a,b,c,d,e,f,g) 0
 #endif
 
-/* Forward references */
-typedef struct winShm winShm;           /* A connection to shared-memory */
-typedef struct winShmNode winShmNode;   /* A region of shared-memory */
-
 /*
 ** WinCE lacks native support for file locking so we have to fake it
 ** with some code of our own.
 */
 #if SQLITE_OS_WINCE
 typedef struct winceLock {
   int nReaders;       /* Number of reader locks obtained */
   BOOL bPending;      /* Indicates a pending lock has been obtained */
@@ -28991,25 +28163,22 @@ typedef struct winceLock {
 #endif
 
 /*
 ** The winFile structure is a subclass of sqlite3_file* specific to the win32
 ** portability layer.
 */
 typedef struct winFile winFile;
 struct winFile {
-  const sqlite3_io_methods *pMethod; /*** Must be first ***/
-  sqlite3_vfs *pVfs;      /* The VFS used to open this file */
+  const sqlite3_io_methods *pMethod;/* Must be first */
   HANDLE h;               /* Handle for accessing the file */
   unsigned char locktype; /* Type of lock currently held on this file */
   short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
   DWORD lastErrno;        /* The Windows errno from the last I/O error */
   DWORD sectorSize;       /* Sector size of the device file is on */
-  winShm *pShm;           /* Instance of shared memory on this file */
-  const char *zPath;      /* Full pathname of this file */
 #if SQLITE_OS_WINCE
   WCHAR *zDeleteOnClose;  /* Name of file to delete when closing */
   HANDLE hMutex;          /* Mutex used to control access to shared lock */  
   HANDLE hShared;         /* Shared memory segment used for locking */
   winceLock local;        /* Locks obtained by this instance of winFile */
   winceLock *shared;      /* Global shared lock memory for the file  */
 #endif
 };
@@ -29527,38 +28696,35 @@ static BOOL winceLockFileEx(
 ** giving up and returning an error.
 */
 #define MX_CLOSE_ATTEMPT 3
 static int winClose(sqlite3_file *id){
   int rc, cnt = 0;
   winFile *pFile = (winFile*)id;
 
   assert( id!=0 );
-  assert( pFile->pShm==0 );
-  OSTRACE(("CLOSE %d\n", pFile->h));
+  OSTRACE2("CLOSE %d\n", pFile->h);
   do{
     rc = CloseHandle(pFile->h);
-    /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
   }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
 #if SQLITE_OS_WINCE
 #define WINCE_DELETION_ATTEMPTS 3
   winceDestroyLock(pFile);
   if( pFile->zDeleteOnClose ){
     int cnt = 0;
     while(
            DeleteFileW(pFile->zDeleteOnClose)==0
         && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff 
         && cnt++ < WINCE_DELETION_ATTEMPTS
     ){
        Sleep(100);  /* Wait a little before trying again */
     }
     free(pFile->zDeleteOnClose);
   }
 #endif
-  OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
   OpenCounter(-1);
   return rc ? SQLITE_OK : SQLITE_IOERR;
 }
 
 /*
 ** Some microsoft compilers lack this definition.
 */
 #ifndef INVALID_SET_FILE_POINTER
@@ -29580,17 +28746,17 @@ static int winRead(
   LONG lowerBits = (LONG)(offset & 0xffffffff);
   DWORD rc;
   winFile *pFile = (winFile*)id;
   DWORD error;
   DWORD got;
 
   assert( id!=0 );
   SimulateIOError(return SQLITE_IOERR_READ);
-  OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
+  OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype);
   rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
   if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
     pFile->lastErrno = error;
     return SQLITE_FULL;
   }
   if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
     pFile->lastErrno = GetLastError();
     return SQLITE_IOERR_READ;
@@ -29619,120 +28785,98 @@ static int winWrite(
   DWORD rc;
   winFile *pFile = (winFile*)id;
   DWORD error;
   DWORD wrote = 0;
 
   assert( id!=0 );
   SimulateIOError(return SQLITE_IOERR_WRITE);
   SimulateDiskfullError(return SQLITE_FULL);
-  OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
+  OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype);
   rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
   if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
     pFile->lastErrno = error;
-    if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
-      return SQLITE_FULL;
-    }else{
-      return SQLITE_IOERR_WRITE;
-    }
+    return SQLITE_FULL;
   }
   assert( amt>0 );
   while(
      amt>0
      && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
      && wrote>0
   ){
     amt -= wrote;
     pBuf = &((char*)pBuf)[wrote];
   }
   if( !rc || amt>(int)wrote ){
     pFile->lastErrno = GetLastError();
-    if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
-      return SQLITE_FULL;
-    }else{
-      return SQLITE_IOERR_WRITE;
-    }
+    return SQLITE_FULL;
   }
   return SQLITE_OK;
 }
 
 /*
 ** Truncate an open file to a specified size
 */
 static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
   LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff);
   LONG lowerBits = (LONG)(nByte & 0xffffffff);
-  DWORD dwRet;
+  DWORD rc;
   winFile *pFile = (winFile*)id;
   DWORD error;
-  int rc = SQLITE_OK;
 
   assert( id!=0 );
-  OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte));
+  OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);
   SimulateIOError(return SQLITE_IOERR_TRUNCATE);
-  dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
-  if( dwRet==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
+  rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
+  if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
     pFile->lastErrno = error;
-    rc = SQLITE_IOERR_TRUNCATE;
+    return SQLITE_IOERR_TRUNCATE;
+  }
   /* SetEndOfFile will fail if nByte is negative */
-  }else if( !SetEndOfFile(pFile->h) ){
+  if( !SetEndOfFile(pFile->h) ){
     pFile->lastErrno = GetLastError();
-    rc = SQLITE_IOERR_TRUNCATE;
-  }
-  OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc==SQLITE_OK ? "ok" : "failed"));
-  return rc;
+    return SQLITE_IOERR_TRUNCATE;
+  }
+  return SQLITE_OK;
 }
 
 #ifdef SQLITE_TEST
 /*
 ** Count the number of fullsyncs and normal syncs.  This is used to test
 ** that syncs and fullsyncs are occuring at the right times.
 */
 SQLITE_API int sqlite3_sync_count = 0;
 SQLITE_API int sqlite3_fullsync_count = 0;
 #endif
 
 /*
 ** Make sure all writes to a particular file are committed to disk.
 */
 static int winSync(sqlite3_file *id, int flags){
-#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || defined(SQLITE_DEBUG)
+#ifndef SQLITE_NO_SYNC
   winFile *pFile = (winFile*)id;
+
+  assert( id!=0 );
+  OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
 #else
   UNUSED_PARAMETER(id);
 #endif
-
-  assert( pFile );
-  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
-  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
-      || (flags&0x0F)==SQLITE_SYNC_FULL
-  );
-
-  OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype));
-
 #ifndef SQLITE_TEST
   UNUSED_PARAMETER(flags);
 #else
   if( flags & SQLITE_SYNC_FULL ){
     sqlite3_fullsync_count++;
   }
   sqlite3_sync_count++;
 #endif
-
-  /* Unix cannot, but some systems may return SQLITE_FULL from here. This
-  ** line is to test that doing so does not cause any problems.
-  */
-  SimulateDiskfullError( return SQLITE_FULL );
-  SimulateIOError( return SQLITE_IOERR; );
-
   /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
   ** no-op
   */
 #ifdef SQLITE_NO_SYNC
-  return SQLITE_OK;
+    return SQLITE_OK;
 #else
   if( FlushFileBuffers(pFile->h) ){
     return SQLITE_OK;
   }else{
     pFile->lastErrno = GetLastError();
     return SQLITE_IOERR;
   }
 #endif
@@ -29847,18 +28991,18 @@ static int winLock(sqlite3_file *id, int
   int rc = SQLITE_OK;    /* Return code from subroutines */
   int res = 1;           /* Result of a windows lock call */
   int newLocktype;       /* Set pFile->locktype to this value before exiting */
   int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
   winFile *pFile = (winFile*)id;
   DWORD error = NO_ERROR;
 
   assert( id!=0 );
-  OSTRACE(("LOCK %d %d was %d(%d)\n",
-           pFile->h, locktype, pFile->locktype, pFile->sharedLockByte));
+  OSTRACE5("LOCK %d %d was %d(%d)\n",
+          pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
 
   /* If there is already a lock of this type or more restrictive on the
   ** OsFile, do nothing. Don't use the end_lock: exit path, as
   ** sqlite3OsEnterMutex() hasn't been called yet.
   */
   if( pFile->locktype>=locktype ){
     return SQLITE_OK;
   }
@@ -29878,17 +29022,17 @@ static int winLock(sqlite3_file *id, int
      || (   (locktype==EXCLUSIVE_LOCK)
          && (pFile->locktype==RESERVED_LOCK))
   ){
     int cnt = 3;
     while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
       /* Try 3 times to get the pending lock.  The pending lock might be
       ** held by another reader process who will release it momentarily.
       */
-      OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt));
+      OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
       Sleep(1);
     }
     gotPendingLock = res;
     if( !res ){
       error = GetLastError();
     }
   }
 
@@ -29923,23 +29067,23 @@ static int winLock(sqlite3_file *id, int
     gotPendingLock = 0;
   }
 
   /* Acquire an EXCLUSIVE lock
   */
   if( locktype==EXCLUSIVE_LOCK && res ){
     assert( pFile->locktype>=SHARED_LOCK );
     res = unlockReadLock(pFile);
-    OSTRACE(("unreadlock = %d\n", res));
+    OSTRACE2("unreadlock = %d\n", res);
     res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
     if( res ){
       newLocktype = EXCLUSIVE_LOCK;
     }else{
       error = GetLastError();
-      OSTRACE(("error-code = %d\n", error));
+      OSTRACE2("error-code = %d\n", error);
       getReadLock(pFile);
     }
   }
 
   /* If we are holding a PENDING lock that ought to be released, then
   ** release it now.
   */
   if( gotPendingLock && locktype==SHARED_LOCK ){
@@ -29947,47 +29091,45 @@ static int winLock(sqlite3_file *id, int
   }
 
   /* Update the state of the lock has held in the file descriptor then
   ** return the appropriate result code.
   */
   if( res ){
     rc = SQLITE_OK;
   }else{
-    OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
-           locktype, newLocktype));
+    OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
+           locktype, newLocktype);
     pFile->lastErrno = error;
     rc = SQLITE_BUSY;
   }
   pFile->locktype = (u8)newLocktype;
   return rc;
 }
 
 /*
 ** 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, return
 ** non-zero, otherwise zero.
 */
 static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
   int rc;
   winFile *pFile = (winFile*)id;
 
-  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
   assert( id!=0 );
   if( pFile->locktype>=RESERVED_LOCK ){
     rc = 1;
-    OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
+    OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
   }else{
     rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
     if( rc ){
       UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
     }
     rc = !rc;
-    OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc));
+    OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
   }
   *pResOut = rc;
   return SQLITE_OK;
 }
 
 /*
 ** Lower the locking level on file descriptor id to locktype.  locktype
 ** must be either NO_LOCK or SHARED_LOCK.
@@ -30000,18 +29142,18 @@ static int winCheckReservedLock(sqlite3_
 ** might return SQLITE_IOERR;
 */
 static int winUnlock(sqlite3_file *id, int locktype){
   int type;
   winFile *pFile = (winFile*)id;
   int rc = SQLITE_OK;
   assert( pFile!=0 );
   assert( locktype<=SHARED_LOCK );
-  OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
-          pFile->locktype, pFile->sharedLockByte));
+  OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
+          pFile->locktype, pFile->sharedLockByte);
   type = pFile->locktype;
   if( type>=EXCLUSIVE_LOCK ){
     UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
     if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
       /* This should never happen.  We should always be able to
       ** reacquire the read lock */
       rc = SQLITE_IOERR_UNLOCK;
     }
@@ -30037,23 +29179,16 @@ static int winFileControl(sqlite3_file *
     case SQLITE_FCNTL_LOCKSTATE: {
       *(int*)pArg = ((winFile*)id)->locktype;
       return SQLITE_OK;
     }
     case SQLITE_LAST_ERRNO: {
       *(int*)pArg = (int)((winFile*)id)->lastErrno;
       return SQLITE_OK;
     }
-    case SQLITE_FCNTL_SIZE_HINT: {
-      sqlite3_int64 sz = *(sqlite3_int64*)pArg;
-      SimulateIOErrorBenign(1);
-      winTruncate(id, sz);
-      SimulateIOErrorBenign(0);
-      return SQLITE_OK;
-    }
   }
   return SQLITE_ERROR;
 }
 
 /*
 ** 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.
@@ -30068,657 +29203,44 @@ static int winSectorSize(sqlite3_file *i
   return (int)(((winFile*)id)->sectorSize);
 }
 
 /*
 ** Return a vector of device characteristics.
 */
 static int winDeviceCharacteristics(sqlite3_file *id){
   UNUSED_PARAMETER(id);
-  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
-}
-
-#ifndef SQLITE_OMIT_WAL
-
-/*
-** Helper functions to obtain and relinquish the global mutex. The
-** global mutex is used to protect the winLockInfo objects used by 
-** this file, all of which may be shared by multiple threads.
-**
-** Function winShmMutexHeld() is used to assert() that the global mutex 
-** is held when required. This function is only used as part of assert() 
-** statements. e.g.
-**
-**   winShmEnterMutex()
-**     assert( winShmMutexHeld() );
-**   winShmLeaveMutex()
-*/
-static void winShmEnterMutex(void){
-  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-static void winShmLeaveMutex(void){
-  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#ifdef SQLITE_DEBUG
-static int winShmMutexHeld(void) {
-  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#endif
-
-/*
-** Object used to represent a single file opened and mmapped to provide
-** shared memory.  When multiple threads all reference the same
-** log-summary, each thread has its own winFile object, but they all
-** point to a single instance of this object.  In other words, each
-** log-summary is opened only once per process.
-**
-** winShmMutexHeld() must be true when creating or destroying
-** this object or while reading or writing the following fields:
-**
-**      nRef
-**      pNext 
-**
-** The following fields are read-only after the object is created:
-** 
-**      fid
-**      zFilename
-**
-** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
-** winShmMutexHeld() is true when reading or writing any other field
-** in this structure.
-**
-*/
-struct winShmNode {
-  sqlite3_mutex *mutex;      /* Mutex to access this object */
-  char *zFilename;           /* Name of the file */
-  winFile hFile;             /* File handle from winOpen */
-
-  int szRegion;              /* Size of shared-memory regions */
-  int nRegion;               /* Size of array apRegion */
-  struct ShmRegion {
-    HANDLE hMap;             /* File handle from CreateFileMapping */
-    void *pMap;
-  } *aRegion;
-  DWORD lastErrno;           /* The Windows errno from the last I/O error */
-
-  int nRef;                  /* Number of winShm objects pointing to this */
-  winShm *pFirst;            /* All winShm objects pointing to this */
-  winShmNode *pNext;         /* Next in list of all winShmNode objects */
-#ifdef SQLITE_DEBUG
-  u8 nextShmId;              /* Next available winShm.id value */
-#endif
-};
-
-/*
-** A global array of all winShmNode objects.
-**
-** The winShmMutexHeld() must be true while reading or writing this list.
-*/
-static winShmNode *winShmNodeList = 0;
-
-/*
-** Structure used internally by this VFS to record the state of an
-** open shared memory connection.
-**
-** The following fields are initialized when this object is created and
-** are read-only thereafter:
-**
-**    winShm.pShmNode
-**    winShm.id
-**
-** All other fields are read/write.  The winShm.pShmNode->mutex must be held
-** while accessing any read/write fields.
-*/
-struct winShm {
-  winShmNode *pShmNode;      /* The underlying winShmNode object */
-  winShm *pNext;             /* Next winShm with the same winShmNode */
-  u8 hasMutex;               /* True if holding the winShmNode mutex */
-  u16 sharedMask;            /* Mask of shared locks held */
-  u16 exclMask;              /* Mask of exclusive locks held */
-#ifdef SQLITE_DEBUG
-  u8 id;                     /* Id of this connection with its winShmNode */
-#endif
-};
-
-/*
-** Constants used for locking
-*/
-#define WIN_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
-#define WIN_SHM_DMS    (WIN_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
-
-/*
-** Apply advisory locks for all n bytes beginning at ofst.
-*/
-#define _SHM_UNLCK  1
-#define _SHM_RDLCK  2
-#define _SHM_WRLCK  3
-static int winShmSystemLock(
-  winShmNode *pFile,    /* Apply locks to this open shared-memory segment */
-  int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
-  int ofst,             /* Offset to first byte to be locked/unlocked */
-  int nByte             /* Number of bytes to lock or unlock */
-){
-  OVERLAPPED ovlp;
-  DWORD dwFlags;
-  int rc = 0;           /* Result code form Lock/UnlockFileEx() */
-
-  /* Access to the winShmNode object is serialized by the caller */
-  assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
-
-  /* Initialize the locking parameters */
-  dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
-  if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
-
-  memset(&ovlp, 0, sizeof(OVERLAPPED));
-  ovlp.Offset = ofst;
-
-  /* Release/Acquire the system-level lock */
-  if( lockType==_SHM_UNLCK ){
-    rc = UnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp);
-  }else{
-    rc = LockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp);
-  }
-  
-  if( rc!= 0 ){
-    rc = SQLITE_OK;
-  }else{
-    pFile->lastErrno =  GetLastError();
-    rc = SQLITE_BUSY;
-  }
-
-  OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", 
-           pFile->hFile.h,
-           rc==SQLITE_OK ? "ok" : "failed",
-           lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx",
-           pFile->lastErrno));
-
-  return rc;
-}
-
-/* Forward references to VFS methods */
-static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
-static int winDelete(sqlite3_vfs *,const char*,int);
-
-/*
-** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
-**
-** This is not a VFS shared-memory method; it is a utility function called
-** by VFS shared-memory methods.
-*/
-static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
-  winShmNode **pp;
-  winShmNode *p;
-  assert( winShmMutexHeld() );
-  pp = &winShmNodeList;
-  while( (p = *pp)!=0 ){
-    if( p->nRef==0 ){
-      int i;
-      if( p->mutex ) sqlite3_mutex_free(p->mutex);
-      for(i=0; i<p->nRegion; i++){
-        UnmapViewOfFile(p->aRegion[i].pMap);
-        CloseHandle(p->aRegion[i].hMap);
-      }
-      if( p->hFile.h != INVALID_HANDLE_VALUE ){
-        SimulateIOErrorBenign(1);
-        winClose((sqlite3_file *)&p->hFile);
-        SimulateIOErrorBenign(0);
-      }
-      if( deleteFlag ){
-        SimulateIOErrorBenign(1);
-        winDelete(pVfs, p->zFilename, 0);
-        SimulateIOErrorBenign(0);
-      }
-      *pp = p->pNext;
-      sqlite3_free(p->aRegion);
-      sqlite3_free(p);
-    }else{
-      pp = &p->pNext;
-    }
-  }
-}
-
-/*
-** Open the shared-memory area associated with database file pDbFd.
-**
-** When opening a new shared-memory file, if no other instances of that
-** file are currently open, in this process or in other processes, then
-** the file must be truncated to zero length or have its header cleared.
-*/
-static int winOpenSharedMemory(winFile *pDbFd){
-  struct winShm *p;                  /* The connection to be opened */
-  struct winShmNode *pShmNode = 0;   /* The underlying mmapped file */
-  int rc;                            /* Result code */
-  struct winShmNode *pNew;           /* Newly allocated winShmNode */
-  int nName;                         /* Size of zName in bytes */
-
-  assert( pDbFd->pShm==0 );    /* Not previously opened */
-
-  /* Allocate space for the new sqlite3_shm object.  Also speculatively
-  ** allocate space for a new winShmNode and filename.
-  */
-  p = sqlite3_malloc( sizeof(*p) );
-  if( p==0 ) return SQLITE_NOMEM;
-  memset(p, 0, sizeof(*p));
-  nName = sqlite3Strlen30(pDbFd->zPath);
-  pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 15 );
-  if( pNew==0 ){
-    sqlite3_free(p);
-    return SQLITE_NOMEM;
-  }
-  memset(pNew, 0, sizeof(*pNew));
-  pNew->zFilename = (char*)&pNew[1];
-  sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
-
-  /* Look to see if there is an existing winShmNode that can be used.
-  ** If no matching winShmNode currently exists, create a new one.
-  */
-  winShmEnterMutex();
-  for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
-    /* TBD need to come up with better match here.  Perhaps
-    ** use FILE_ID_BOTH_DIR_INFO Structure.
-    */
-    if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
-  }
-  if( pShmNode ){
-    sqlite3_free(pNew);
-  }else{
-    pShmNode = pNew;
-    pNew = 0;
-    ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
-    pShmNode->pNext = winShmNodeList;
-    winShmNodeList = pShmNode;
-
-    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-    if( pShmNode->mutex==0 ){
-      rc = SQLITE_NOMEM;
-      goto shm_open_err;
-    }
-    rc = winOpen(pDbFd->pVfs,
-                 pShmNode->zFilename,             /* Name of the file (UTF-8) */
-                 (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
-                 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
-                 0);
-    if( SQLITE_OK!=rc ){
-      rc = SQLITE_CANTOPEN_BKPT;
-      goto shm_open_err;
-    }
-
-    /* Check to see if another process is holding the dead-man switch.
-    ** If not, truncate the file to zero length. 
-    */
-    if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
-      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
-      if( rc!=SQLITE_OK ){
-        rc = SQLITE_IOERR_SHMOPEN;
-      }
-    }
-    if( rc==SQLITE_OK ){
-      winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
-      rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
-    }
-    if( rc ) goto shm_open_err;
-  }
-
-  /* Make the new connection a child of the winShmNode */
-  p->pShmNode = pShmNode;
-#ifdef SQLITE_DEBUG
-  p->id = pShmNode->nextShmId++;
-#endif
-  pShmNode->nRef++;
-  pDbFd->pShm = p;
-  winShmLeaveMutex();
-
-  /* The reference count on pShmNode has already been incremented under
-  ** the cover of the winShmEnterMutex() mutex and the pointer from the
-  ** new (struct winShm) object to the pShmNode has been set. All that is
-  ** left to do is to link the new object into the linked list starting
-  ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex 
-  ** mutex.
-  */
-  sqlite3_mutex_enter(pShmNode->mutex);
-  p->pNext = pShmNode->pFirst;
-  pShmNode->pFirst = p;
-  sqlite3_mutex_leave(pShmNode->mutex);
-  return SQLITE_OK;
-
-  /* Jump here on any error */
-shm_open_err:
-  winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
-  winShmPurge(pDbFd->pVfs, 0);      /* This call frees pShmNode if required */
-  sqlite3_free(p);
-  sqlite3_free(pNew);
-  winShmLeaveMutex();
-  return rc;
-}
-
-/*
-** Close a connection to shared-memory.  Delete the underlying 
-** storage if deleteFlag is true.
-*/
-static int winShmUnmap(
-  sqlite3_file *fd,          /* Database holding shared memory */
-  int deleteFlag             /* Delete after closing if true */
-){
-  winFile *pDbFd;       /* Database holding shared-memory */
-  winShm *p;            /* The connection to be closed */
-  winShmNode *pShmNode; /* The underlying shared-memory file */
-  winShm **pp;          /* For looping over sibling connections */
-
-  pDbFd = (winFile*)fd;
-  p = pDbFd->pShm;
-  if( p==0 ) return SQLITE_OK;
-  pShmNode = p->pShmNode;
-
-  /* Remove connection p from the set of connections associated
-  ** with pShmNode */
-  sqlite3_mutex_enter(pShmNode->mutex);
-  for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
-  *pp = p->pNext;
-
-  /* Free the connection p */
-  sqlite3_free(p);
-  pDbFd->pShm = 0;
-  sqlite3_mutex_leave(pShmNode->mutex);
-
-  /* If pShmNode->nRef has reached 0, then close the underlying
-  ** shared-memory file, too */
-  winShmEnterMutex();
-  assert( pShmNode->nRef>0 );
-  pShmNode->nRef--;
-  if( pShmNode->nRef==0 ){
-    winShmPurge(pDbFd->pVfs, deleteFlag);
-  }
-  winShmLeaveMutex();
-
-  return SQLITE_OK;
-}
-
-/*
-** Change the lock state for a shared-memory segment.
-*/
-static int winShmLock(
-  sqlite3_file *fd,          /* Database file holding the shared memory */
-  int ofst,                  /* First lock to acquire or release */
-  int n,                     /* Number of locks to acquire or release */
-  int flags                  /* What to do with the lock */
-){
-  winFile *pDbFd = (winFile*)fd;        /* Connection holding shared memory */
-  winShm *p = pDbFd->pShm;              /* The shared memory being locked */
-  winShm *pX;                           /* For looping over all siblings */
-  winShmNode *pShmNode = p->pShmNode;
-  int rc = SQLITE_OK;                   /* Result code */
-  u16 mask;                             /* Mask of locks to take or release */
-
-  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
-  assert( n>=1 );
-  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
-       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
-       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
-       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
-  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
-
-  mask = (u16)((1U<<(ofst+n)) - (1U<<ofst));
-  assert( n>1 || mask==(1<<ofst) );
-  sqlite3_mutex_enter(pShmNode->mutex);
-  if( flags & SQLITE_SHM_UNLOCK ){
-    u16 allMask = 0; /* Mask of locks held by siblings */
-
-    /* See if any siblings hold this same lock */
-    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-      if( pX==p ) continue;
-      assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
-      allMask |= pX->sharedMask;
-    }
-
-    /* Unlock the system-level locks */
-    if( (mask & allMask)==0 ){
-      rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
-    }else{
-      rc = SQLITE_OK;
-    }
-
-    /* Undo the local locks */
-    if( rc==SQLITE_OK ){
-      p->exclMask &= ~mask;
-      p->sharedMask &= ~mask;
-    } 
-  }else if( flags & SQLITE_SHM_SHARED ){
-    u16 allShared = 0;  /* Union of locks held by connections other than "p" */
-
-    /* Find out which shared locks are already held by sibling connections.
-    ** If any sibling already holds an exclusive lock, go ahead and return
-    ** SQLITE_BUSY.
-    */
-    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-      if( (pX->exclMask & mask)!=0 ){
-        rc = SQLITE_BUSY;
-        break;
-      }
-      allShared |= pX->sharedMask;
-    }
-
-    /* Get shared locks at the system level, if necessary */
-    if( rc==SQLITE_OK ){
-      if( (allShared & mask)==0 ){
-        rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
-      }else{
-        rc = SQLITE_OK;
-      }
-    }
-
-    /* Get the local shared locks */
-    if( rc==SQLITE_OK ){
-      p->sharedMask |= mask;
-    }
-  }else{
-    /* Make sure no sibling connections hold locks that will block this
-    ** lock.  If any do, return SQLITE_BUSY right away.
-    */
-    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
-      if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
-        rc = SQLITE_BUSY;
-        break;
-      }
-    }
-  
-    /* Get the exclusive locks at the system level.  Then if successful
-    ** also mark the local connection as being locked.
-    */
-    if( rc==SQLITE_OK ){
-      rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
-      if( rc==SQLITE_OK ){
-        assert( (p->sharedMask & mask)==0 );
-        p->exclMask |= mask;
-      }
-    }
-  }
-  sqlite3_mutex_leave(pShmNode->mutex);
-  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n",
-           p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask,
-           rc ? "failed" : "ok"));
-  return rc;
-}
-
-/*
-** Implement a memory barrier or memory fence on shared memory.  
-**
-** All loads and stores begun before the barrier must complete before
-** any load or store begun after the barrier.
-*/
-static void winShmBarrier(
-  sqlite3_file *fd          /* Database holding the shared memory */
-){
-  UNUSED_PARAMETER(fd);
-  /* MemoryBarrier(); // does not work -- do not know why not */
-  winShmEnterMutex();
-  winShmLeaveMutex();
-}
-
-/*
-** This function is called to obtain a pointer to region iRegion of the 
-** shared-memory associated with the database file fd. Shared-memory regions 
-** are numbered starting from zero. Each shared-memory region is szRegion 
-** bytes in size.
-**
-** If an error occurs, an error code is returned and *pp is set to NULL.
-**
-** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
-** region has not been allocated (by any client, including one running in a
-** separate process), then *pp is set to NULL and SQLITE_OK returned. If 
-** isWrite is non-zero and the requested shared-memory region has not yet 
-** been allocated, it is allocated by this function.
-**
-** If the shared-memory region has already been allocated or is allocated by
-** this call as described above, then it is mapped into this processes 
-** address space (if it is not already), *pp is set to point to the mapped 
-** memory and SQLITE_OK returned.
-*/
-static int winShmMap(
-  sqlite3_file *fd,               /* Handle open on database file */
-  int iRegion,                    /* Region to retrieve */
-  int szRegion,                   /* Size of regions */
-  int isWrite,                    /* True to extend file if necessary */
-  void volatile **pp              /* OUT: Mapped memory */
-){
-  winFile *pDbFd = (winFile*)fd;
-  winShm *p = pDbFd->pShm;
-  winShmNode *pShmNode;
-  int rc = SQLITE_OK;
-
-  if( !p ){
-    rc = winOpenSharedMemory(pDbFd);
-    if( rc!=SQLITE_OK ) return rc;
-    p = pDbFd->pShm;
-  }
-  pShmNode = p->pShmNode;
-
-  sqlite3_mutex_enter(pShmNode->mutex);
-  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
-
-  if( pShmNode->nRegion<=iRegion ){
-    struct ShmRegion *apNew;           /* New aRegion[] array */
-    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
-    sqlite3_int64 sz;                  /* Current size of wal-index file */
-
-    pShmNode->szRegion = szRegion;
-
-    /* The requested region is not mapped into this processes address space.
-    ** Check to see if it has been allocated (i.e. if the wal-index file is
-    ** large enough to contain the requested region).
-    */
-    rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
-    if( rc!=SQLITE_OK ){
-      rc = SQLITE_IOERR_SHMSIZE;
-      goto shmpage_out;
-    }
-
-    if( sz<nByte ){
-      /* The requested memory region does not exist. If isWrite is set to
-      ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
-      **
-      ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
-      ** the requested memory region.
-      */
-      if( !isWrite ) goto shmpage_out;
-      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
-      if( rc!=SQLITE_OK ){
-        rc = SQLITE_IOERR_SHMSIZE;
-        goto shmpage_out;
-      }
-    }
-
-    /* Map the requested memory region into this processes address space. */
-    apNew = (struct ShmRegion *)sqlite3_realloc(
-        pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
-    );
-    if( !apNew ){
-      rc = SQLITE_IOERR_NOMEM;
-      goto shmpage_out;
-    }
-    pShmNode->aRegion = apNew;
-
-    while( pShmNode->nRegion<=iRegion ){
-      HANDLE hMap;                /* file-mapping handle */
-      void *pMap = 0;             /* Mapped memory region */
-     
-      hMap = CreateFileMapping(pShmNode->hFile.h, 
-          NULL, PAGE_READWRITE, 0, nByte, NULL
-      );
-      if( hMap ){
-        pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
-            0, 0, nByte
-        );
-      }
-      if( !pMap ){
-        pShmNode->lastErrno = GetLastError();
-        rc = SQLITE_IOERR;
-        if( hMap ) CloseHandle(hMap);
-        goto shmpage_out;
-      }
-
-      pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
-      pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
-      pShmNode->nRegion++;
-    }
-  }
-
-shmpage_out:
-  if( pShmNode->nRegion>iRegion ){
-    char *p = (char *)pShmNode->aRegion[iRegion].pMap;
-    *pp = (void *)&p[iRegion*szRegion];
-  }else{
-    *pp = 0;
-  }
-  sqlite3_mutex_leave(pShmNode->mutex);
-  return rc;
-}
-
-#else
-# define winShmMap     0
-# define winShmLock    0
-# define winShmBarrier 0
-# define winShmUnmap   0
-#endif /* #ifndef SQLITE_OMIT_WAL */
-
-/*
-** Here ends the implementation of all sqlite3_file methods.
-**
-********************** End sqlite3_file Methods *******************************
-******************************************************************************/
+  return 0;
+}
 
 /*
 ** This vector defines all the methods that can operate on an
 ** sqlite3_file for win32.
 */
 static const sqlite3_io_methods winIoMethod = {
-  2,                              /* iVersion */
-  winClose,                       /* xClose */
-  winRead,                        /* xRead */
-  winWrite,                       /* xWrite */
-  winTruncate,                    /* xTruncate */
-  winSync,                        /* xSync */
-  winFileSize,                    /* xFileSize */
-  winLock,                        /* xLock */
-  winUnlock,                      /* xUnlock */
-  winCheckReservedLock,           /* xCheckReservedLock */
-  winFileControl,                 /* xFileControl */
-  winSectorSize,                  /* xSectorSize */
-  winDeviceCharacteristics,       /* xDeviceCharacteristics */
-  winShmMap,                      /* xShmMap */
-  winShmLock,                     /* xShmLock */
-  winShmBarrier,                  /* xShmBarrier */
-  winShmUnmap                     /* xShmUnmap */
-};
-
-/****************************************************************************
-**************************** sqlite3_vfs methods ****************************
-**
-** This division contains the implementation of methods on the
-** sqlite3_vfs object.
-*/
+  1,                        /* iVersion */
+  winClose,
+  winRead,
+  winWrite,
+  winTruncate,
+  winSync,
+  winFileSize,
+  winLock,
+  winUnlock,
+  winCheckReservedLock,
+  winFileControl,
+  winSectorSize,
+  winDeviceCharacteristics
+};
+
+/***************************************************************************
+** Here ends the I/O methods that form the sqlite3_io_methods object.
+**
+** The next block of code implements the VFS methods.
+****************************************************************************/
 
 /*
 ** Convert a UTF-8 filename into whatever form the underlying
 ** operating system wants filenames in.  Space to hold the result
 ** is obtained from malloc and must be freed by the calling
 ** function.
 */
 static void *convertUtf8Filename(const char *zFilename){
@@ -30742,23 +29264,16 @@ static void *convertUtf8Filename(const c
 */
 static int getTempname(int nBuf, char *zBuf){
   static char zChars[] =
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "0123456789";
   size_t i, j;
   char zTempPath[MAX_PATH+1];
-
-  /* It's odd to simulate an io-error here, but really this is just
-  ** using the io-error infrastructure to test that SQLite handles this
-  ** function failing. 
-  */
-  SimulateIOError( return SQLITE_IOERR );
-
   if( sqlite3_temp_directory ){
     sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
   }else if( isNT() ){
     char *zMulti;
     WCHAR zWidePath[MAX_PATH];
     GetTempPathW(MAX_PATH-30, zWidePath);
     zMulti = unicodeToUtf8(zWidePath);
     if( zMulti ){
@@ -30780,37 +29295,27 @@ static int getTempname(int nBuf, char *z
     if( zUtf8 ){
       sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
       free(zUtf8);
     }else{
       return SQLITE_NOMEM;
     }
 #endif
   }
-
-  /* Check that the output buffer is large enough for the temporary file 
-  ** name. If it is not, return SQLITE_ERROR.
-  */
-  if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){
-    return SQLITE_ERROR;
-  }
-
   for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
   zTempPath[i] = 0;
-
-  sqlite3_snprintf(nBuf-17, zBuf,
+  sqlite3_snprintf(nBuf-30, zBuf,
                    "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
   j = sqlite3Strlen30(zBuf);
-  sqlite3_randomness(15, &zBuf[j]);
-  for(i=0; i<15; i++, j++){
+  sqlite3_randomness(20, &zBuf[j]);
+  for(i=0; i<20; i++, j++){
     zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
   }
   zBuf[j] = 0;
-
-  OSTRACE(("TEMP FILENAME: %s\n", zBuf));
+  OSTRACE2("TEMP FILENAME: %s\n", zBuf);
   return SQLITE_OK; 
 }
 
 /*
 ** The return value of getLastErrorMsg
 ** is zero if the error message fits in the buffer, or non-zero
 ** otherwise (if the message was truncated).
 */
@@ -30892,18 +29397,16 @@ static int winOpen(
   winFile *pFile = (winFile*)id;
   void *zConverted;                 /* Filename in OS encoding */
   const char *zUtf8Name = zName;    /* Filename in UTF-8 encoding */
   char zTmpname[MAX_PATH+1];        /* Buffer used to create temp filename */
 
   assert( id!=0 );
   UNUSED_PARAMETER(pVfs);
 
-  pFile->h = INVALID_HANDLE_VALUE;
-
   /* If the second argument to this function is NULL, generate a 
   ** temporary file name to use 
   */
   if( !zUtf8Name ){
     int rc = getTempname(MAX_PATH+1, zTmpname);
     if( rc!=SQLITE_OK ){
       return rc;
     }
@@ -30975,21 +29478,17 @@ static int winOpen(
        dwShareMode,
        NULL,
        dwCreationDisposition,
        dwFlagsAndAttributes,
        NULL
     );
 #endif
   }
-  OSTRACE(("OPEN %d %s 0x%lx %s\n", 
-           h, zName, dwDesiredAccess, 
-           h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
   if( h==INVALID_HANDLE_VALUE ){
-    pFile->lastErrno = GetLastError();
     free(zConverted);
     if( flags & SQLITE_OPEN_READWRITE ){
       return winOpen(pVfs, zName, id, 
              ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
     }else{
       return SQLITE_CANTOPEN_BKPT;
     }
   }
@@ -30999,19 +29498,16 @@ static int winOpen(
     }else{
       *pOutFlags = SQLITE_OPEN_READONLY;
     }
   }
   memset(pFile, 0, sizeof(*pFile));
   pFile->pMethod = &winIoMethod;
   pFile->h = h;
   pFile->lastErrno = NO_ERROR;
-  pFile->pVfs = pVfs;
-  pFile->pShm = 0;
-  pFile->zPath = zName;
   pFile->sectorSize = getSectorSize(pVfs, zUtf8Name);
 #if SQLITE_OS_WINCE
   if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
                (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
        && !winceCreateLock(zName, pFile)
   ){
     CloseHandle(h);
     free(zConverted);
@@ -31044,25 +29540,23 @@ static int winOpen(
 static int winDelete(
   sqlite3_vfs *pVfs,          /* Not used on win32 */
   const char *zFilename,      /* Name of file to delete */
   int syncDir                 /* Not used on win32 */
 ){
   int cnt = 0;
   DWORD rc;
   DWORD error = 0;
-  void *zConverted;
+  void *zConverted = convertUtf8Filename(zFilename);
   UNUSED_PARAMETER(pVfs);
   UNUSED_PARAMETER(syncDir);
-
-  SimulateIOError(return SQLITE_IOERR_DELETE);
-  zConverted = convertUtf8Filename(zFilename);
   if( zConverted==0 ){
     return SQLITE_NOMEM;
   }
+  SimulateIOError(return SQLITE_IOERR_DELETE);
   if( isNT() ){
     do{
       DeleteFileW(zConverted);
     }while(   (   ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
                || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
            && (++cnt < MX_DELETION_ATTEMPTS)
            && (Sleep(100), 1) );
 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
@@ -31075,67 +29569,39 @@ static int winDelete(
       DeleteFileA(zConverted);
     }while(   (   ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES)
                || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
            && (++cnt < MX_DELETION_ATTEMPTS)
            && (Sleep(100), 1) );
 #endif
   }
   free(zConverted);
-  OSTRACE(("DELETE \"%s\" %s\n", zFilename,
-       ( (rc==INVALID_FILE_ATTRIBUTES) && (error==ERROR_FILE_NOT_FOUND)) ?
-         "ok" : "failed" ));
- 
+  OSTRACE2("DELETE \"%s\"\n", zFilename);
   return (   (rc == INVALID_FILE_ATTRIBUTES) 
           && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;
 }
 
 /*
 ** Check the existance and status of a file.
 */
 static int winAccess(
   sqlite3_vfs *pVfs,         /* Not used on win32 */
   const char *zFilename,     /* Name of file to check */
   int flags,                 /* Type of test to make on this file */
   int *pResOut               /* OUT: Result */
 ){
   DWORD attr;
   int rc = 0;
-  void *zConverted;
+  void *zConverted = convertUtf8Filename(zFilename);
   UNUSED_PARAMETER(pVfs);
-
-  SimulateIOError( return SQLITE_IOERR_ACCESS; );
-  zConverted = convertUtf8Filename(zFilename);
   if( zConverted==0 ){
     return SQLITE_NOMEM;
   }
   if( isNT() ){
-    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
-    memset(&sAttrData, 0, sizeof(sAttrData));
-    if( GetFileAttributesExW((WCHAR*)zConverted,
-                             GetFileExInfoStandard, 
-                             &sAttrData) ){
-      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
-      ** as if it does not exist.
-      */
-      if(    flags==SQLITE_ACCESS_EXISTS
-          && sAttrData.nFileSizeHigh==0 
-          && sAttrData.nFileSizeLow==0 ){
-        attr = INVALID_FILE_ATTRIBUTES;
-      }else{
-        attr = sAttrData.dwFileAttributes;
-      }
-    }else{
-      if( GetLastError()!=ERROR_FILE_NOT_FOUND ){
-        free(zConverted);
-        return SQLITE_IOERR_ACCESS;
-      }else{
-        attr = INVALID_FILE_ATTRIBUTES;
-      }
-    }
+    attr = GetFileAttributesW((WCHAR*)zConverted);
 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
 ** Since the ASCII version of these Windows API do not exist for WINCE,
 ** it's important to not reference them for WINCE builds.
 */
 #if SQLITE_OS_WINCE==0
   }else{
     attr = GetFileAttributesA((char*)zConverted);
 #endif
@@ -31165,41 +29631,32 @@ static int winAccess(
 static int winFullPathname(
   sqlite3_vfs *pVfs,            /* Pointer to vfs object */
   const char *zRelative,        /* Possibly relative input path */
   int nFull,                    /* Size of output buffer in bytes */
   char *zFull                   /* Output buffer */
 ){
   
 #if defined(__CYGWIN__)
-  SimulateIOError( return SQLITE_ERROR );
   UNUSED_PARAMETER(nFull);
   cygwin_conv_to_full_win32_path(zRelative, zFull);
   return SQLITE_OK;
 #endif
 
 #if SQLITE_OS_WINCE
-  SimulateIOError( return SQLITE_ERROR );
   UNUSED_PARAMETER(nFull);
   /* WinCE has no concept of a relative pathname, or so I am told. */
   sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
   return SQLITE_OK;
 #endif
 
 #if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
   int nByte;
   void *zConverted;
   char *zOut;
-
-  /* It's odd to simulate an io-error here, but really this is just
-  ** using the io-error infrastructure to test that SQLite handles this
-  ** function failing. This function could fail if, for example, the
-  ** current working directory has been unlinked.
-  */
-  SimulateIOError( return SQLITE_ERROR );
   UNUSED_PARAMETER(nFull);
   zConverted = convertUtf8Filename(zRelative);
   if( isNT() ){
     WCHAR *zTemp;
     nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
     zTemp = malloc( nByte*sizeof(zTemp[0]) );
     if( zTemp==0 ){
       free(zConverted);
@@ -31257,19 +29714,17 @@ static int getSectorSize(
   DWORD dwRet = 0;
   DWORD dwDummy;
 
   /*
   ** We need to get the full path name of the file
   ** to get the drive letter to look up the sector
   ** size.
   */
-  SimulateIOErrorBenign(1);
   rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);
-  SimulateIOErrorBenign(0);
   if( rc == SQLITE_OK )
   {
     void *zConverted = convertUtf8Filename(zFullpath);
     if( zConverted ){
       if( isNT() ){
         /* trim path to just drive reference */
         WCHAR *p = zConverted;
         for(;*p;p++){
@@ -31407,86 +29862,76 @@ static int winRandomness(sqlite3_vfs *pV
 */
 static int winSleep(sqlite3_vfs *pVfs, int microsec){
   Sleep((microsec+999)/1000);
   UNUSED_PARAMETER(pVfs);
   return ((microsec+999)/1000)*1000;
 }
 
 /*
-** The following variable, if set to a non-zero value, is interpreted as
-** the number of seconds since 1970 and is used to set the result of
-** sqlite3OsCurrentTime() during testing.
+** The following variable, if set to a non-zero value, becomes the result
+** returned from sqlite3OsCurrentTime().  This is used for testing.
 */
 #ifdef SQLITE_TEST
-SQLITE_API int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
-#endif
-
-/*
-** 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.
-*/
-static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
+SQLITE_API int sqlite3_current_time = 0;
+#endif
+
+/*
+** 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.
+*/
+int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
+  FILETIME ft;
   /* FILETIME structure is a 64-bit value representing the number of 
      100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
   */
-  FILETIME ft;
-  static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
-#ifdef SQLITE_TEST
-  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
-#endif
+  sqlite3_int64 timeW;   /* Whole days */
+  sqlite3_int64 timeF;   /* Fractional Days */
+
+  /* Number of 100-nanosecond intervals in a single day */
+  static const sqlite3_int64 ntuPerDay = 
+      10000000*(sqlite3_int64)86400;
+
+  /* Number of 100-nanosecond intervals in half of a day */
+  static const sqlite3_int64 ntuPerHalfDay = 
+      10000000*(sqlite3_int64)43200;
+
   /* 2^32 - to avoid use of LL and warnings in gcc */
   static const sqlite3_int64 max32BitValue = 
       (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
 
 #if SQLITE_OS_WINCE
   SYSTEMTIME time;
   GetSystemTime(&time);
   /* if SystemTimeToFileTime() fails, it returns zero. */
   if (!SystemTimeToFileTime(&time,&ft)){
     return 1;
   }
 #else
   GetSystemTimeAsFileTime( &ft );
 #endif
-
-  *piNow = winFiletimeEpoch +
-            ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + 
-               (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
-
+  UNUSED_PARAMETER(pVfs);
+  timeW = (((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + (sqlite3_int64)ft.dwLowDateTime;
+  timeF = timeW % ntuPerDay;          /* fractional days (100-nanoseconds) */
+  timeW = timeW / ntuPerDay;          /* whole days */
+  timeW = timeW + 2305813;            /* add whole days (from 2305813.5) */
+  timeF = timeF + ntuPerHalfDay;      /* add half a day (from 2305813.5) */
+  timeW = timeW + (timeF/ntuPerDay);  /* add whole day if half day made one */
+  timeF = timeF % ntuPerDay;          /* compute new fractional days */
+  *prNow = (double)timeW + ((double)timeF / (double)ntuPerDay);
 #ifdef SQLITE_TEST
   if( sqlite3_current_time ){
-    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
-  }
-#endif
-  UNUSED_PARAMETER(pVfs);
+    *prNow = ((double)sqlite3_current_time + (double)43200) / (double)86400 + (double)2440587;
+  }
+#endif
   return 0;
 }
 
 /*
-** 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.
-*/
-int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
-  int rc;
-  sqlite3_int64 i;
-  rc = winCurrentTimeInt64(pVfs, &i);
-  if( !rc ){
-    *prNow = i/86400000.0;
-  }
-  return rc;
-}
-
-/*
 ** The idea is that this function works like a combination of
 ** GetLastError() and FormatMessage() on windows (or errno and
 ** strerror_r() on unix). After an error is returned by an OS
 ** function, SQLite calls this function with zBuf pointing to
 ** a buffer of nBuf bytes. The OS layer should populate the
 ** buffer with a nul-terminated UTF-8 encoded error message
 ** describing the last IO error to have occurred within the calling
 ** thread.
@@ -31511,42 +29956,40 @@ int winCurrentTime(sqlite3_vfs *pVfs, do
 ** by sqlite into the error message available to the user using
 ** sqlite3_errmsg(), possibly making IO errors easier to debug.
 */
 static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
   UNUSED_PARAMETER(pVfs);
   return getLastErrorMsg(nBuf, zBuf);
 }
 
-
-
 /*
 ** Initialize and deinitialize the operating system interface.
 */
 SQLITE_API int sqlite3_os_init(void){
   static sqlite3_vfs winVfs = {
-    2,                   /* iVersion */
-    sizeof(winFile),     /* szOsFile */
-    MAX_PATH,            /* mxPathname */
-    0,                   /* pNext */
-    "win32",             /* zName */
-    0,                   /* pAppData */
-    winOpen,             /* xOpen */
-    winDelete,           /* xDelete */
-    winAccess,           /* xAccess */
-    winFullPathname,     /* xFullPathname */
-    winDlOpen,           /* xDlOpen */
-    winDlError,          /* xDlError */
-    winDlSym,            /* xDlSym */
-    winDlClose,          /* xDlClose */
-    winRandomness,       /* xRandomness */
-    winSleep,            /* xSleep */
-    winCurrentTime,      /* xCurrentTime */
-    winGetLastError,     /* xGetLastError */
-    winCurrentTimeInt64, /* xCurrentTimeInt64 */
+    1,                 /* iVersion */
+    sizeof(winFile),   /* szOsFile */
+    MAX_PATH,          /* mxPathname */
+    0,                 /* pNext */
+    "win32",           /* zName */
+    0,                 /* pAppData */
+ 
+    winOpen,           /* xOpen */
+    winDelete,         /* xDelete */
+    winAccess,         /* xAccess */
+    winFullPathname,   /* xFullPathname */
+    winDlOpen,         /* xDlOpen */
+    winDlError,        /* xDlError */
+    winDlSym,          /* xDlSym */
+    winDlClose,        /* xDlClose */
+    winRandomness,     /* xRandomness */
+    winSleep,          /* xSleep */
+    winCurrentTime,    /* xCurrentTime */
+    winGetLastError    /* xGetLastError */
   };
 
   sqlite3_vfs_register(&winVfs, 1);
   return SQLITE_OK; 
 }
 SQLITE_API int sqlite3_os_end(void){ 
   return SQLITE_OK;
 }
@@ -32221,27 +30664,25 @@ SQLITE_PRIVATE int sqlite3PcacheFetch(
       }
     }
 
     pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, 2);
   }
 
   if( pPage ){
     if( !pPage->pData ){
-      memset(pPage, 0, sizeof(PgHdr));
-      pPage->pData = (void *)&pPage[1];
-      pPage->pExtra = (void*)&((char *)pPage->pData)[pCache->szPage];
-      memset(pPage->pExtra, 0, pCache->szExtra);
+      memset(pPage, 0, sizeof(PgHdr) + pCache->szExtra);
+      pPage->pExtra = (void*)&pPage[1];
+      pPage->pData = (void *)&((char *)pPage)[sizeof(PgHdr) + pCache->szExtra];
       pPage->pCache = pCache;
       pPage->pgno = pgno;
     }
     assert( pPage->pCache==pCache );
     assert( pPage->pgno==pgno );
-    assert( pPage->pData==(void *)&pPage[1] );
-    assert( pPage->pExtra==(void *)&((char *)&pPage[1])[pCache->szPage] );
+    assert( pPage->pExtra==(void *)&pPage[1] );
 
     if( 0==pPage->nRef ){
       pCache->nRef++;
     }
     pPage->nRef++;
     if( pgno==1 ){
       pCache->pPage1 = pPage;
     }
@@ -32370,22 +30811,17 @@ SQLITE_PRIVATE void sqlite3PcacheMove(Pg
 ** the page object is not dropped.
 */
 SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
   if( pCache->pCache ){
     PgHdr *p;
     PgHdr *pNext;
     for(p=pCache->pDirty; p; p=pNext){
       pNext = p->pDirtyNext;
-      /* This routine never gets call with a positive pgno except right
-      ** after sqlite3PcacheCleanAll().  So if there are dirty pages,
-      ** it must be that pgno==0.
-      */
-      assert( p->pgno>0 );
-      if( ALWAYS(p->pgno>pgno) ){
+      if( p->pgno>pgno ){
         assert( p->flags&PGHDR_DIRTY );
         sqlite3PcacheMakeClean(p);
       }
     }
     if( pgno==0 && pCache->pPage1 ){
       memset(pCache->pPage1->pData, 0, pCache->szPage);
       pgno = 1;
     }
@@ -32719,17 +31155,16 @@ static void *pcache1Alloc(int nByte){
     */
     pcache1LeaveMutex();
     p = sqlite3Malloc(nByte);
     pcache1EnterMutex();
     if( p ){
       int sz = sqlite3MallocSize(p);
       sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
     }
-    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
   }
   return p;
 }
 
 /*
 ** Free an allocated buffer obtained from pcache1Alloc().
 */
 static void pcache1Free(void *p){
@@ -32737,20 +31172,17 @@ static void pcache1Free(void *p){
   if( p==0 ) return;
   if( p>=pcache1.pStart && p<pcache1.pEnd ){
     PgFreeslot *pSlot;
     sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
     pSlot = (PgFreeslot*)p;
     pSlot->pNext = pcache1.pFree;
     pcache1.pFree = pSlot;
   }else{
-    int iSize;
-    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
-    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
-    iSize = sqlite3MallocSize(p);
+    int iSize = sqlite3MallocSize(p);
     sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
     sqlite3_free(p);
   }
 }
 
 /*
 ** Allocate a new page object initially associated with cache pCache.
 */
@@ -33262,17 +31694,17 @@ static void pcache1Destroy(sqlite3_pcach
 }
 
 /*
 ** This function is called during initialization (sqlite3_initialize()) to
 ** install the default pluggable cache module, assuming the user has not
 ** already provided an alternative.
 */
 SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
-  static const sqlite3_pcache_methods defaultMethods = {
+  static sqlite3_pcache_methods defaultMethods = {
     0,                       /* pArg */
     pcache1Init,             /* xInit */
     pcache1Shutdown,         /* xShutdown */
     pcache1Create,           /* xCreate */
     pcache1Cachesize,        /* xCachesize */
     pcache1Pagecount,        /* xPagecount */
     pcache1Fetch,            /* xFetch */
     pcache1Unpin,            /* xUnpin */
@@ -33775,208 +32207,16 @@ SQLITE_PRIVATE int sqlite3RowSetTest(Row
 ** The pager is used to access a database disk file.  It implements
 ** atomic commit and rollback through the use of a journal file that
 ** is separate from the database file.  The pager also implements file
 ** locking to prevent two processes from writing the same database
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 */
 #ifndef SQLITE_OMIT_DISKIO
-/************** Include wal.h in the middle of pager.c ***********************/
-/************** Begin file wal.h *********************************************/
-/*
-** 2010 February 1
-**
-** The author disclaims copyright to this source code.  In place of
-** 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 header file defines the interface to the write-ahead logging 
-** system. Refer to the comments below and the header comment attached to 
-** the implementation of each function in log.c for further details.
-*/
-
-#ifndef _WAL_H_
-#define _WAL_H_
-
-
-#ifdef SQLITE_OMIT_WAL
-# define sqlite3WalOpen(x,y,z)                 0
-# define sqlite3WalClose(w,x,y,z)              0
-# define sqlite3WalBeginReadTransaction(y,z)   0
-# define sqlite3WalEndReadTransaction(z)
-# define sqlite3WalRead(v,w,x,y,z)             0
-# define sqlite3WalDbsize(y,z)
-# define sqlite3WalBeginWriteTransaction(y)    0
-# define sqlite3WalEndWriteTransaction(x)      0
-# define sqlite3WalUndo(x,y,z)                 0
-# define sqlite3WalSavepoint(y,z)
-# define sqlite3WalSavepointUndo(y,z)          0
-# define sqlite3WalFrames(u,v,w,x,y,z)         0
-# define sqlite3WalCheckpoint(u,v,w,x)         0
-# define sqlite3WalCallback(z)                 0
-# define sqlite3WalExclusiveMode(y,z)          0
-#else
-
-#define WAL_SAVEPOINT_NDATA 4
-
-/* Connection to a write-ahead log (WAL) file. 
-** There is one object of this type for each pager. 
-*/
-typedef struct Wal Wal;
-
-/* Open and close a connection to a write-ahead log. */
-SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *zName, Wal**);
-SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
-
-/* Used by readers to open (lock) and close (unlock) a snapshot.  A 
-** snapshot is like a read-transaction.  It is the state of the database
-** at an instant in time.  sqlite3WalOpenSnapshot gets a read lock and
-** preserves the current state even if the other threads or processes
-** write to or checkpoint the WAL.  sqlite3WalCloseSnapshot() closes the
-** transaction and releases the lock.
-*/
-SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
-SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal);
-
-/* Read a page from the write-ahead log, if it is present. */
-SQLITE_PRIVATE int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut);
-
-/* Return the size of the database as it existed at the beginning
-** of the snapshot */
-SQLITE_PRIVATE void sqlite3WalDbsize(Wal *pWal, Pgno *pPgno);
-
-/* Obtain or release the WRITER lock. */
-SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal);
-SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal);
-
-/* Undo any frames written (but not committed) to the log */
-SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx);
-
-/* Return an integer that records the current (uncommitted) write
-** position in the WAL */
-SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData);
-
-/* Move the write position of the WAL back to iFrame.  Called in
-** response to a ROLLBACK TO command. */
-SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData);
-
-/* Write a frame or frames to the log. */
-SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
-
-/* Copy pages from the log to the database file */ 
-SQLITE_PRIVATE int sqlite3WalCheckpoint(
-  Wal *pWal,                      /* Write-ahead log connection */
-  int sync_flags,                 /* Flags to sync db file with (or 0) */
-  int nBuf,                       /* Size of buffer nBuf */
-  u8 *zBuf                        /* Temporary buffer to use */
-);
-
-/* Return the value to pass to a sqlite3_wal_hook callback, the
-** number of frames in the WAL at the point of the last commit since
-** sqlite3WalCallback() was called.  If no commits have occurred since
-** the last call, then return 0.
-*/
-SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal);
-
-/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released)
-** by the pager layer on the database file.
-*/
-SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op);
-
-#endif /* ifndef SQLITE_OMIT_WAL */
-#endif /* _WAL_H_ */
-
-/************** End of wal.h *************************************************/
-/************** Continuing where we left off in pager.c **********************/
-
-/*
-******************** NOTES ON THE DESIGN OF THE PAGER ************************
-**
-** Within this comment block, a page is deemed to have been synced
-** automatically as soon as it is written when PRAGMA synchronous=OFF.
-** Otherwise, the page is not synced until the xSync method of the VFS
-** is called successfully on the file containing the page.
-**
-** Definition:  A page of the database file is said to be "overwriteable" if
-** one or more of the following are true about the page:
-** 
-**     (a)  The original content of the page as it was at the beginning of
-**          the transaction has been written into the rollback journal and
-**          synced.
-** 
-**     (b)  The page was a freelist leaf page at the start of the transaction.
-** 
-**     (c)  The page number is greater than the largest page that existed in
-**          the database file at the start of the transaction.
-** 
-** (1) A page of the database file is never overwritten unless one of the
-**     following are true:
-** 
-**     (a) The page and all other pages on the same sector are overwriteable.
-** 
-**     (b) The atomic page write optimization is enabled, and the entire
-**         transaction other than the update of the transaction sequence
-**         number consists of a single page change.
-** 
-** (2) The content of a page written into the rollback journal exactly matches
-**     both the content in the database when the rollback journal was written
-**     and the content in the database at the beginning of the current
-**     transaction.
-** 
-** (3) Writes to the database file are an integer multiple of the page size
-**     in length and are aligned to a page boundary.
-** 
-** (4) Reads from the database file are either aligned on a page boundary and
-**     an integer multiple of the page size in length or are taken from the
-**     first 100 bytes of the database file.
-** 
-** (5) All writes to the database file are synced prior to the rollback journal
-**     being deleted, truncated, or zeroed.
-** 
-** (6) If a master journal file is used, then all writes to the database file
-**     are synced prior to the master journal being deleted.
-** 
-** Definition: Two databases (or the same database at two points it time)
-** are said to be "logically equivalent" if they give the same answer to
-** all queries.  Note in particular the the content of freelist leaf
-** pages can be changed arbitarily without effecting the logical equivalence
-** of the database.
-** 
-** (7) At any time, if any subset, including the empty set and the total set,
-**     of the unsynced changes to a rollback journal are removed and the 
-**     journal is rolled back, the resulting database file will be logical
-**     equivalent to the database file at the beginning of the transaction.
-** 
-** (8) When a transaction is rolled back, the xTruncate method of the VFS
-**     is called to restore the database file to the same size it was at
-**     the beginning of the transaction.  (In some VFSes, the xTruncate
-**     method is a no-op, but that does not change the fact the SQLite will
-**     invoke it.)
-** 
-** (9) Whenever the database file is modified, at least one bit in the range
-**     of bytes from 24 through 39 inclusive will be changed prior to releasing
-**     the EXCLUSIVE lock.
-**
-** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less
-**      than one billion transactions.
-**
-** (11) A database file is well-formed at the beginning and at the conclusion
-**      of every transaction.
-**
-** (12) An EXCLUSIVE lock is held on the database file when writing to
-**      the database file.
-**
-** (13) A SHARED lock is held on the database file while reading any
-**      content out of the database file.
-*/
 
 /*
 ** Macros for troubleshooting.  Normally turned off
 */
 #if 0
 int sqlite3PagerTrace=1;  /* True to enable tracing */
 #define sqlite3DebugPrintf printf
 #define PAGERTRACE(X)     if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; }
@@ -34086,19 +32326,16 @@ int sqlite3PagerTrace=1;  /* True to ena
 */
 typedef struct PagerSavepoint PagerSavepoint;
 struct PagerSavepoint {
   i64 iOffset;                 /* Starting offset in main journal */
   i64 iHdrOffset;              /* See above */
   Bitvec *pInSavepoint;        /* Set of pages in this savepoint */
   Pgno nOrig;                  /* Original number of pages in file */
   Pgno iSubRec;                /* Index of first record in sub-journal */
-#ifndef SQLITE_OMIT_WAL
-  u32 aWalData[WAL_SAVEPOINT_NDATA];        /* WAL savepoint context */
-#endif
 };
 
 /*
 ** A open page cache is an instance of the following structure.
 **
 ** errCode
 **
 **   Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, or
@@ -34147,18 +32384,17 @@ struct PagerSavepoint {
 **   The dbModified flag is set whenever a database page is dirtied.
 **   It is cleared at the end of each transaction.
 **
 **   It is used when committing or otherwise ending a transaction. If
 **   the dbModified flag is clear then less work has to be done.
 **
 ** journalStarted
 **
-**   This flag is set whenever the the main journal is opened and
-**   initialized
+**   This flag is set whenever the the main journal is synced. 
 **
 **   The point of this flag is that it must be set after the 
 **   first journal header in a journal file has been synced to disk.
 **   After this has happened, new pages appended to the database 
 **   do not need the PGHDR_NEED_SYNC flag set, as they do not need
 **   to wait for a journal sync before they can be written out to
 **   the database file (see function pager_write()).
 **   
@@ -34172,25 +32408,19 @@ struct PagerSavepoint {
 **   PAGER_RESERVED state (see CommitPhaseOne() for the action). It
 **   then attempts to upgrade to an exclusive lock. If this attempt
 **   fails, then SQLITE_BUSY may be returned to the user and the user
 **   may attempt to commit the transaction again later (calling
 **   CommitPhaseOne() again). This flag is used to ensure that the 
 **   master journal name is only written to the journal file the first
 **   time CommitPhaseOne() is called.
 **
-** doNotSpill, doNotSyncSpill
-**
-**   When enabled, cache spills are prohibited.  The doNotSpill variable
-**   inhibits all cache spill and doNotSyncSpill inhibits those spills that
-**   would require a journal sync.  The doNotSyncSpill is set and cleared 
-**   by sqlite3PagerWrite() in order to prevent a journal sync from happening 
-**   in between the journalling of two pages on the same sector.  The
-**   doNotSpill value set to prevent pagerStress() from trying to use
-**   the journal during a rollback.
+** doNotSync
+**
+**   This variable is set and cleared by sqlite3PagerWrite().
 **
 ** needSync
 **
 **   TODO: It might be easier to set this variable in writeJournalHdr()
 **   and writeMasterJournal() only. Change its meaning to "unsynced data
 **   has been written to the journal".
 **
 ** subjInMemory
@@ -34224,34 +32454,32 @@ struct Pager {
   ** above this class definition.
   */
   u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
   u8 dbModified;              /* True if there are any changes to the Db */
   u8 needSync;                /* True if an fsync() is needed on the journal */
   u8 journalStarted;          /* True if header of journal is synced */
   u8 changeCountDone;         /* Set after incrementing the change-counter */
   u8 setMaster;               /* True if a m-j name has been written to jrnl */
-  u8 doNotSpill;              /* Do not spill the cache when non-zero */
-  u8 doNotSyncSpill;          /* Do not do a spill that requires jrnl sync */
+  u8 doNotSync;               /* Boolean. While true, do not spill the cache */
   u8 dbSizeValid;             /* Set when dbSize is correct */
   u8 subjInMemory;            /* True to use in-memory sub-journals */
   Pgno dbSize;                /* Number of pages in the database */
   Pgno dbOrigSize;            /* dbSize before the current transaction */
   Pgno dbFileSize;            /* Number of pages in the database file */
   int errCode;                /* One of several kinds of errors */
   int nRec;                   /* Pages journalled since last j-header written */
   u32 cksumInit;              /* Quasi-random value added to every checksum */
   u32 nSubRec;                /* Number of records written to sub-journal */
   Bitvec *pInJournal;         /* One bit for each page in the database file */
   sqlite3_file *fd;           /* File descriptor for database */
   sqlite3_file *jfd;          /* File descriptor for main journal */
   sqlite3_file *sjfd;         /* File descriptor for sub-journal */
   i64 journalOff;             /* Current write offset in the journal file */
   i64 journalHdr;             /* Byte offset to previous journal header */
-  i64 journalSizeLimit;       /* Size limit for persistent journal files */
   PagerSavepoint *aSavepoint; /* Array of active savepoints */
   int nSavepoint;             /* Number of elements in aSavepoint[] */
   char dbFileVers[16];        /* Changes whenever database file changes */
   u32 sectorSize;             /* Assumed sector size during rollback */
 
   u16 nExtra;                 /* Add this many bytes to each in-memory page */
   i16 nReserve;               /* Number of unused bytes at end of each page */
   u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
@@ -34268,22 +32496,19 @@ struct Pager {
   void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
 #ifdef SQLITE_HAS_CODEC
   void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
   void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
   void (*xCodecFree)(void*);             /* Destructor for the codec */
   void *pCodec;               /* First argument to xCodec... methods */
 #endif
   char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
+  i64 journalSizeLimit;       /* Size limit for persistent journal files */
   PCache *pPCache;            /* Pointer to page cache object */
   sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
-#ifndef SQLITE_OMIT_WAL
-  Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */
-  char *zWal;                 /* File name for write-ahead log */
-#endif
 };
 
 /*
 ** The following global variables hold counters used for
 ** testing purposes only.  These variables do not exist in
 ** a non-testing build.  These variables are not thread-safe.
 */
 #ifdef SQLITE_TEST
@@ -34787,17 +33012,16 @@ static int writeJournalHdr(Pager *pPager
   ** The loop is required here in case the sector-size is larger than the 
   ** database page size. Since the zHeader buffer is only Pager.pageSize
   ** bytes in size, more than one call to sqlite3OsWrite() may be required
   ** to populate the entire journal header sector.
   */ 
   for(nWrite=0; rc==SQLITE_OK&&nWrite<JOURNAL_HDR_SZ(pPager); nWrite+=nHeader){
     IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, nHeader))
     rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff);
-    assert( pPager->journalHdr <= pPager->journalOff );
     pPager->journalOff += nHeader;
   }
 
   return rc;
 }
 
 /*
 ** The journal file must be open when this is called. A journal header file
@@ -34946,17 +33170,16 @@ static int writeMasterJournal(Pager *pPa
   if( !zMaster || pPager->setMaster
    || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
    || pPager->journalMode==PAGER_JOURNALMODE_OFF 
   ){
     return SQLITE_OK;
   }
   pPager->setMaster = 1;
   assert( isOpen(pPager->jfd) );
-  assert( pPager->journalHdr <= pPager->journalOff );
 
   /* Calculate the length in bytes and the checksum of zMaster */
   for(nMaster=0; zMaster[nMaster]; nMaster++){
     cksum += zMaster[nMaster];
   }
 
   /* If in full-sync mode, advance to the next disk sector before writing
   ** the master journal name. This is in case the previous page written to
@@ -35063,80 +33286,46 @@ static int addToSavepointBitvecs(Pager *
       testcase( rc==SQLITE_NOMEM );
       assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
     }
   }
   return rc;
 }
 
 /*
-** Return true if this pager uses a write-ahead log instead of the usual
-** rollback journal. Otherwise false.
-*/
-#ifndef SQLITE_OMIT_WAL
-static int pagerUseWal(Pager *pPager){
-  return (pPager->pWal!=0);
-}
-#else
-# define pagerUseWal(x) 0
-# define pagerRollbackWal(x) 0
-# define pagerWalFrames(v,w,x,y,z) 0
-# define pagerOpenWalIfPresent(z) SQLITE_OK
-# define pagerBeginReadTransaction(z) SQLITE_OK
-#endif
-
-/*
 ** Unlock the database file. This function is a no-op if the pager
 ** is in exclusive mode.
 **
 ** If the pager is currently in error state, discard the contents of 
 ** the cache and reset the Pager structure internal state. If there is
 ** an open journal-file, then the next time a shared-lock is obtained
 ** on the pager file (by this or any other process), it will be
 ** treated as a hot-journal and rolled back.
 */
 static void pager_unlock(Pager *pPager){
   if( !pPager->exclusiveMode ){
-    int rc = SQLITE_OK;          /* Return code */
-    int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
-
-    /* If the operating system support deletion of open files, then
-    ** close the journal file when dropping the database lock.  Otherwise
-    ** another connection with journal_mode=delete might delete the file
-    ** out from under us.
-    */
-    assert( (PAGER_JOURNALMODE_MEMORY   & 5)!=1 );
-    assert( (PAGER_JOURNALMODE_OFF      & 5)!=1 );
-    assert( (PAGER_JOURNALMODE_WAL      & 5)!=1 );
-    assert( (PAGER_JOURNALMODE_DELETE   & 5)!=1 );
-    assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
-    assert( (PAGER_JOURNALMODE_PERSIST  & 5)==1 );
-    if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
-     || 1!=(pPager->journalMode & 5)
-    ){
-      sqlite3OsClose(pPager->jfd);
-    }
-
+    int rc;                      /* Return code */
+
+    /* Always close the journal file when dropping the database lock.
+    ** Otherwise, another connection with journal_mode=delete might
+    ** delete the file out from under us.
+    */
+    sqlite3OsClose(pPager->jfd);
     sqlite3BitvecDestroy(pPager->pInJournal);
     pPager->pInJournal = 0;
     releaseAllSavepoints(pPager);
 
     /* If the file is unlocked, somebody else might change it. The
     ** values stored in Pager.dbSize etc. might become invalid if
-    ** this happens.  One can argue that this doesn't need to be cleared
+    ** this happens. TODO: Really, this doesn't need to be cleared
     ** until the change-counter check fails in PagerSharedLock().
-    ** Clearing the page size cache here is being conservative.
     */
     pPager->dbSizeValid = 0;
 
-    if( pagerUseWal(pPager) ){
-      sqlite3WalEndReadTransaction(pPager->pWal);
-    }else{
-      rc = osUnlock(pPager->fd, NO_LOCK);
-    }
+    rc = osUnlock(pPager->fd, NO_LOCK);
     if( rc ){
       pPager->errCode = rc;
     }
     IOTRACE(("UNLOCK %p\n", pPager))
 
     /* If Pager.errCode is set, the contents of the pager cache cannot be
     ** trusted. Now that the pager file is unlocked, the contents of the
     ** cache can be discarded and the error code safely cleared.
@@ -35157,17 +33346,17 @@ static void pager_unlock(Pager *pPager){
 /*
 ** This function should be called when an IOERR, CORRUPT or FULL error
 ** may have occurred. The first argument is a pointer to the pager 
 ** structure, the second the error-code about to be returned by a pager 
 ** API function. The value returned is a copy of the second argument 
 ** to this function. 
 **
 ** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL
-** the error becomes persistent. Until the persistent error is cleared,
+** the error becomes persistent. Until the persisten error is cleared,
 ** subsequent API calls on this Pager will immediately return the same 
 ** error code.
 **
 ** A persistent error indicates that the contents of the pager-cache 
 ** cannot be trusted. This state can be cleared by completely discarding 
 ** the contents of the pager-cache. If a transaction was active when
 ** the persistent error occurred, then the rollback journal may need
 ** to be replayed to restore the contents of the database file (as if
@@ -35275,74 +33464,61 @@ static int pager_end_transaction(Pager *
 
   if( pPager->state<PAGER_RESERVED ){
     return SQLITE_OK;
   }
   releaseAllSavepoints(pPager);
 
   assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
   if( isOpen(pPager->jfd) ){
-    assert( !pagerUseWal(pPager) );
 
     /* Finalize the journal file. */
     if( sqlite3IsMemJournal(pPager->jfd) ){
       assert( pPager->journalMode==PAGER_JOURNALMODE_MEM