From a23bebdc0f106c19de09e54d88eebc6b086fdaab Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 23 Apr 2010 17:17:15 +0100
Subject: Duplicate OpenSim.Data.SQLite into OpenSim.Data.SQLiteNG.  SQLiteNG
 will shortly be changed to work under mono 2.6 and above

---
 OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs   |   65 +
 OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql |   12 +
 OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql  |   18 +
 OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql     |    9 +
 .../Data/SQLiteNG/Resources/001_FriendsStore.sql   |   10 +
 .../Data/SQLiteNG/Resources/001_InventoryStore.sql |   32 +
 .../Data/SQLiteNG/Resources/001_RegionStore.sql    |  144 ++
 .../Data/SQLiteNG/Resources/001_UserAccount.sql    |   17 +
 OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql  |   39 +
 OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql |   10 +
 OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql  |    5 +
 .../Data/SQLiteNG/Resources/002_FriendsStore.sql   |    5 +
 .../Data/SQLiteNG/Resources/002_InventoryStore.sql |    8 +
 .../Data/SQLiteNG/Resources/002_RegionStore.sql    |   10 +
 .../Data/SQLiteNG/Resources/002_UserAccount.sql    |    5 +
 OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql  |    5 +
 OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql |    1 +
 .../Data/SQLiteNG/Resources/003_InventoryStore.sql |    5 +
 .../Data/SQLiteNG/Resources/003_RegionStore.sql    |    5 +
 OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql  |    6 +
 OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql |    7 +
 .../Data/SQLiteNG/Resources/004_InventoryStore.sql |   36 +
 .../Data/SQLiteNG/Resources/004_RegionStore.sql    |   38 +
 OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql  |    6 +
 .../Data/SQLiteNG/Resources/005_RegionStore.sql    |    5 +
 OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql  |    5 +
 .../Data/SQLiteNG/Resources/006_RegionStore.sql    |  102 +
 OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql  |   20 +
 .../Data/SQLiteNG/Resources/007_RegionStore.sql    |    8 +
 OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql  |    7 +
 .../Data/SQLiteNG/Resources/008_RegionStore.sql    |    6 +
 OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql  |    5 +
 .../Data/SQLiteNG/Resources/009_RegionStore.sql    |    8 +
 OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql  |   11 +
 .../Data/SQLiteNG/Resources/010_RegionStore.sql    |    5 +
 OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql  |   37 +
 .../Data/SQLiteNG/Resources/011_RegionStore.sql    |   28 +
 .../Data/SQLiteNG/Resources/012_RegionStore.sql    |    5 +
 .../Data/SQLiteNG/Resources/013_RegionStore.sql    |    6 +
 .../Data/SQLiteNG/Resources/014_RegionStore.sql    |    8 +
 .../Data/SQLiteNG/Resources/015_RegionStore.sql    |    6 +
 .../Data/SQLiteNG/Resources/016_RegionStore.sql    |    5 +
 .../Data/SQLiteNG/Resources/017_RegionStore.sql    |    8 +
 .../Data/SQLiteNG/Resources/018_RegionStore.sql    |   79 +
 .../Resources/OpenSim.Data.SQLite.addin.xml        |   20 +
 OpenSim/Data/SQLiteNG/SQLiteAssetData.cs           |  343 +++
 OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs  |  262 +++
 OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs          |   74 +
 OpenSim/Data/SQLiteNG/SQLiteEstateData.cs          |  387 ++++
 OpenSim/Data/SQLiteNG/SQLiteFramework.cs           |   91 +
 OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs         |   70 +
 OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs |  268 +++
 OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs      |  898 ++++++++
 OpenSim/Data/SQLiteNG/SQLiteRegionData.cs          | 2264 ++++++++++++++++++++
 OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs     |   81 +
 OpenSim/Data/SQLiteNG/SQLiteUtils.cs               |  307 +++
 OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs      |  155 ++
 OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs     |   64 +
 OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs    |   65 +
 OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs |   66 +
 OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs    |   64 +
 61 files changed, 6341 insertions(+)
 create mode 100644 OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql
 create mode 100644 OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteAssetData.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteEstateData.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteFramework.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteRegionData.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteUtils.cs
 create mode 100644 OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs
 create mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs
 create mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs
 create mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs
 create mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs

(limited to 'OpenSim/Data')

diff --git a/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs b/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d45ab50
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly : AssemblyTitle("OpenSim.Data.SQLite")]
+[assembly : AssemblyDescription("")]
+[assembly : AssemblyConfiguration("")]
+[assembly : AssemblyCompany("http://opensimulator.org")]
+[assembly : AssemblyProduct("OpenSim.Data.SQLite")]
+[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
+[assembly : AssemblyTrademark("")]
+[assembly : AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly : ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly : Guid("6113d5ce-4547-49f4-9236-0dcc503457b1")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly : AssemblyVersion("0.6.5.*")]
+[assembly : AssemblyFileVersion("0.6.5.0")]
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql
new file mode 100644
index 0000000..2e026ca
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql
@@ -0,0 +1,12 @@
+BEGIN TRANSACTION;
+CREATE TABLE assets(
+       UUID varchar(255) primary key,
+       Name varchar(255),
+       Description varchar(255),
+       Type integer,
+       InvType integer,
+       Local integer,
+       Temporary integer,
+       Data blob);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql
new file mode 100644
index 0000000..468567d
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql
@@ -0,0 +1,18 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE auth (
+  UUID char(36) NOT NULL,
+  passwordHash char(32) NOT NULL default '',
+  passwordSalt char(32) NOT NULL default '',
+  webLoginKey varchar(255) NOT NULL default '',
+  accountType VARCHAR(32) NOT NULL DEFAULT 'UserAccount',
+  PRIMARY KEY  (`UUID`)
+);
+
+CREATE TABLE tokens (
+  UUID char(36) NOT NULL,
+  token varchar(255) NOT NULL,
+  validity datetime NOT NULL
+);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql b/OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql
new file mode 100644
index 0000000..7ec906b
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql
@@ -0,0 +1,9 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE Avatars (
+	PrincipalID CHAR(36) NOT NULL, 
+	Name VARCHAR(32) NOT NULL, 
+	Value VARCHAR(255) NOT NULL DEFAULT '', 
+	PRIMARY KEY(PrincipalID, Name));
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql
new file mode 100644
index 0000000..f1b9ab9
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql
@@ -0,0 +1,10 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE `Friends` (
+	`PrincipalID` CHAR(36) NOT NULL, 
+	`Friend` VARCHAR(255) NOT NULL, 
+	`Flags` VARCHAR(16) NOT NULL DEFAULT 0, 
+	`Offered` VARCHAR(32) NOT NULL DEFAULT 0, 
+	PRIMARY KEY(`PrincipalID`, `Friend`));
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql
new file mode 100644
index 0000000..554d5c2
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql
@@ -0,0 +1,32 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE inventoryfolders(
+       UUID varchar(255) primary key,
+       name varchar(255),
+       agentID varchar(255),
+       parentID varchar(255),
+       type integer,
+       version integer);
+
+CREATE TABLE inventoryitems(
+       UUID varchar(255) primary key,
+       assetID varchar(255),
+       assetType integer,
+       invType integer,
+       parentFolderID varchar(255),
+       avatarID varchar(255),
+       creatorsID varchar(255),
+       inventoryName varchar(255),
+       inventoryDescription varchar(255),
+       inventoryNextPermissions integer,
+       inventoryCurrentPermissions integer,
+       inventoryBasePermissions integer,
+       inventoryEveryOnePermissions integer, 
+       salePrice integer default 99, 
+       saleType integer default 0, 
+       creationDate integer default 2000, 
+       groupID varchar(255) default '00000000-0000-0000-0000-000000000000', 
+       groupOwned integer default 0, 
+       flags integer default 0);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql
new file mode 100644
index 0000000..39e8180
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql
@@ -0,0 +1,144 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE prims(
+       UUID varchar(255) primary key,
+       RegionUUID varchar(255),
+       ParentID integer,
+       CreationDate integer,
+       Name varchar(255),
+       SceneGroupID varchar(255),
+       Text varchar(255),
+       Description varchar(255),
+       SitName varchar(255),
+       TouchName varchar(255),
+       CreatorID varchar(255),
+       OwnerID varchar(255),
+       GroupID varchar(255),
+       LastOwnerID varchar(255),
+       OwnerMask integer,
+       NextOwnerMask integer,
+       GroupMask integer,
+       EveryoneMask integer,
+       BaseMask integer,
+       PositionX float,
+       PositionY float,
+       PositionZ float,
+       GroupPositionX float,
+       GroupPositionY float,
+       GroupPositionZ float,
+       VelocityX float,
+       VelocityY float,
+       VelocityZ float,
+       AngularVelocityX float,
+       AngularVelocityY float,
+       AngularVelocityZ float,
+       AccelerationX float,
+       AccelerationY float,
+       AccelerationZ float,
+       RotationX float,
+       RotationY float,
+       RotationZ float,
+       RotationW float, 
+       ObjectFlags integer, 
+       SitTargetOffsetX float NOT NULL default 0, 
+       SitTargetOffsetY float NOT NULL default 0, 
+       SitTargetOffsetZ float NOT NULL default 0, 
+       SitTargetOrientW float NOT NULL default 0, 
+       SitTargetOrientX float NOT NULL default 0, 
+       SitTargetOrientY float NOT NULL default 0, 
+       SitTargetOrientZ float NOT NULL default 0);
+
+CREATE TABLE primshapes(
+       UUID varchar(255) primary key,
+       Shape integer,
+       ScaleX float,
+       ScaleY float,
+       ScaleZ float,
+       PCode integer,
+       PathBegin integer,
+       PathEnd integer,
+       PathScaleX integer,
+       PathScaleY integer,
+       PathShearX integer,
+       PathShearY integer,
+       PathSkew integer,
+       PathCurve integer,
+       PathRadiusOffset integer,
+       PathRevolutions integer,
+       PathTaperX integer,
+       PathTaperY integer,
+       PathTwist integer,
+       PathTwistBegin integer,
+       ProfileBegin integer,
+       ProfileEnd integer,
+       ProfileCurve integer,
+       ProfileHollow integer,
+       Texture blob,
+       ExtraParams blob, 
+       State Integer NOT NULL default 0);
+
+CREATE TABLE primitems(
+       itemID varchar(255) primary key,
+       primID varchar(255),
+       assetID varchar(255),
+       parentFolderID varchar(255),
+       invType integer,
+       assetType integer,
+       name varchar(255),
+       description varchar(255),
+       creationDate integer,
+       creatorID varchar(255),
+       ownerID varchar(255),
+       lastOwnerID varchar(255),
+       groupID varchar(255),
+       nextPermissions string,
+       currentPermissions string,
+       basePermissions string,
+       everyonePermissions string,
+       groupPermissions string);
+
+CREATE TABLE terrain(
+       RegionUUID varchar(255),
+       Revision integer,
+       Heightfield blob);
+
+CREATE TABLE land(
+       UUID varchar(255) primary key,
+       RegionUUID varchar(255),
+       LocalLandID string,
+       Bitmap blob,
+       Name varchar(255),
+       Desc varchar(255),
+       OwnerUUID varchar(255),
+       IsGroupOwned string,
+       Area integer,
+       AuctionID integer,
+       Category integer,
+       ClaimDate integer,
+       ClaimPrice integer,
+       GroupUUID varchar(255),
+       SalePrice integer,
+       LandStatus integer,
+       LandFlags string,
+       LandingType string,
+       MediaAutoScale string,
+       MediaTextureUUID varchar(255),
+       MediaURL varchar(255),
+       MusicURL varchar(255),
+       PassHours float,
+       PassPrice string,
+       SnapshotUUID varchar(255),
+       UserLocationX float,
+       UserLocationY float,
+       UserLocationZ float,
+       UserLookAtX float,
+       UserLookAtY float,
+       UserLookAtZ float, 
+       AuthbuyerID varchar(36) NOT NULL default  '00000000-0000-0000-0000-000000000000');
+
+CREATE TABLE landaccesslist(
+       LandUUID varchar(255),
+       AccessUUID varchar(255),
+       Flags string);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql b/OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql
new file mode 100644
index 0000000..c38d9a7
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql
@@ -0,0 +1,17 @@
+BEGIN TRANSACTION;
+
+-- useraccounts table
+CREATE TABLE UserAccounts (
+    PrincipalID CHAR(36)  primary key,
+    ScopeID CHAR(36) NOT NULL,
+    FirstName VARCHAR(64) NOT NULL,
+    LastName VARCHAR(64) NOT NULL,
+    Email VARCHAR(64),
+    ServiceURLs TEXT,
+    Created INT(11),
+    UserLevel integer NOT NULL DEFAULT 0,
+    UserFlags integer NOT NULL DEFAULT 0,
+    UserTitle varchar(64) NOT NULL DEFAULT ''
+);
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql
new file mode 100644
index 0000000..b584594
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql
@@ -0,0 +1,39 @@
+BEGIN TRANSACTION;
+
+-- users table
+CREATE TABLE users(
+       UUID varchar(255) primary key,
+       username varchar(255),
+       surname varchar(255),
+       passwordHash varchar(255),
+       passwordSalt varchar(255),
+       homeRegionX integer,
+       homeRegionY integer,
+       homeLocationX float,
+       homeLocationY float,
+       homeLocationZ float,
+       homeLookAtX float,
+       homeLookAtY float,
+       homeLookAtZ float,
+       created integer,
+       lastLogin integer,
+       rootInventoryFolderID varchar(255),
+       userInventoryURI varchar(255),
+       userAssetURI varchar(255),
+       profileCanDoMask integer,
+       profileWantDoMask integer,
+       profileAboutText varchar(255),
+       profileFirstText varchar(255),
+       profileImage varchar(255),
+       profileFirstImage varchar(255), 
+       webLoginKey text default '00000000-0000-0000-0000-000000000000');
+-- friends table
+CREATE TABLE userfriends(
+       ownerID varchar(255),
+       friendID varchar(255),
+       friendPerms integer,
+       ownerPerms integer,
+       datetimestamp integer);
+
+COMMIT;
+
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql
new file mode 100644
index 0000000..5339b84
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql
@@ -0,0 +1,10 @@
+BEGIN TRANSACTION;
+
+CREATE TEMPORARY TABLE assets_backup(UUID,Name,Description,Type,Local,Temporary,Data);
+INSERT INTO assets_backup SELECT UUID,Name,Description,Type,Local,Temporary,Data FROM assets;
+DROP TABLE assets;
+CREATE TABLE assets(UUID,Name,Description,Type,Local,Temporary,Data);
+INSERT INTO assets SELECT UUID,Name,Description,Type,Local,Temporary,Data FROM assets_backup;
+DROP TABLE assets_backup;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql
new file mode 100644
index 0000000..3237b68
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql
@@ -0,0 +1,5 @@
+BEGIN TRANSACTION;
+
+INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey) SELECT `UUID` AS UUID, `passwordHash` AS passwordHash, `passwordSalt` AS passwordSalt, `webLoginKey` AS webLoginKey FROM users;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql
new file mode 100644
index 0000000..6733502
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql
@@ -0,0 +1,5 @@
+BEGIN TRANSACTION;
+
+INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userfriends`;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql
new file mode 100644
index 0000000..01951d6
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql
@@ -0,0 +1,8 @@
+BEGIN TRANSACTION;
+
+create index inventoryfolders_agentid on inventoryfolders(agentid);
+create index inventoryfolders_parentid on inventoryfolders(parentid);
+create index inventoryitems_parentfolderid on inventoryitems(parentfolderid);
+create index inventoryitems_avatarid on inventoryitems(avatarid);
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql
new file mode 100644
index 0000000..c5c7c99
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql
@@ -0,0 +1,10 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE regionban(
+		regionUUID varchar (255),
+		bannedUUID varchar (255),
+		bannedIp varchar (255),
+		bannedIpHostMask varchar (255)
+		);
+       
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql b/OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql
new file mode 100644
index 0000000..c7a6293
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql
@@ -0,0 +1,5 @@
+BEGIN TRANSACTION;
+
+INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT `UUID` AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID, username AS FirstName, surname AS LastName, '' as Email, '' AS ServiceURLs, created as Created FROM users;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql
new file mode 100644
index 0000000..48fc680
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+ALTER TABLE users add homeRegionID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000';
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql
new file mode 100644
index 0000000..f54f8d9
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql
@@ -0,0 +1 @@
+DELETE FROM assets WHERE UUID = 'dc4b9f0bd00845c696a401dd947ac621'
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql
new file mode 100644
index 0000000..4c6da91
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+alter table inventoryitems add column inventoryGroupPermissions integer unsigned not null default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql
new file mode 100644
index 0000000..4db2f75
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+ALTER TABLE primitems add flags integer not null default 0;
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql
new file mode 100644
index 0000000..6f890ee
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql
@@ -0,0 +1,6 @@
+BEGIN;
+
+ALTER TABLE users add userFlags integer NOT NULL default 0;
+ALTER TABLE users add godLevel integer NOT NULL default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql
new file mode 100644
index 0000000..39421c4
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql
@@ -0,0 +1,7 @@
+BEGIN;
+
+update assets
+  set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+  where UUID not like '%-%';
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql
new file mode 100644
index 0000000..e8f4d46
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql
@@ -0,0 +1,36 @@
+BEGIN;
+
+update inventoryitems 
+  set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+  where UUID not like '%-%';
+
+update inventoryitems
+  set assetID = substr(assetID, 1, 8) || "-" || substr(assetID, 9, 4) || "-" || substr(assetID, 13, 4) || "-" || substr(assetID, 17, 4) || "-" || substr(assetID, 21, 12) 
+  where assetID not like '%-%';
+
+update inventoryitems
+  set parentFolderID = substr(parentFolderID, 1, 8) || "-" || substr(parentFolderID, 9, 4) || "-" || substr(parentFolderID, 13, 4) || "-" || substr(parentFolderID, 17, 4) || "-" || substr(parentFolderID, 21, 12) 
+  where parentFolderID not like '%-%';
+
+update inventoryitems
+  set avatarID = substr(avatarID, 1, 8) || "-" || substr(avatarID, 9, 4) || "-" || substr(avatarID, 13, 4) || "-" || substr(avatarID, 17, 4) || "-" || substr(avatarID, 21, 12) 
+  where avatarID not like '%-%';
+
+update inventoryitems
+  set creatorsID = substr(creatorsID, 1, 8) || "-" || substr(creatorsID, 9, 4) || "-" || substr(creatorsID, 13, 4) || "-" || substr(creatorsID, 17, 4) || "-" || substr(creatorsID, 21, 12)
+  where creatorsID not like '%-%';
+
+
+update inventoryfolders
+  set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+  where UUID not like '%-%';
+
+update inventoryfolders
+  set agentID = substr(agentID, 1, 8) || "-" || substr(agentID, 9, 4) || "-" || substr(agentID, 13, 4) || "-" || substr(agentID, 17, 4) || "-" || substr(agentID, 21, 12)
+  where agentID not like '%-%';
+
+update inventoryfolders
+  set parentID = substr(parentID, 1, 8) || "-" || substr(parentID, 9, 4) || "-" || substr(parentID, 13, 4) || "-" || substr(parentID, 17, 4) || "-" || substr(parentID, 21, 12)
+  where parentID not like '%-%';
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql
new file mode 100644
index 0000000..de328cb
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql
@@ -0,0 +1,38 @@
+BEGIN;
+
+create table regionsettings (
+	regionUUID char(36) not null,
+	block_terraform integer not null,
+	block_fly integer not null,
+	allow_damage integer not null,
+	restrict_pushing integer not null,
+	allow_land_resell integer not null,
+	allow_land_join_divide integer not null,
+	block_show_in_search integer not null,
+	agent_limit integer not null,
+	object_bonus float not null,
+	maturity integer not null,
+	disable_scripts integer not null,
+	disable_collisions integer not null,
+	disable_physics integer not null,
+	terrain_texture_1 char(36) not null,
+	terrain_texture_2 char(36) not null,
+	terrain_texture_3 char(36) not null,
+	terrain_texture_4 char(36) not null,
+	elevation_1_nw float not null,
+	elevation_2_nw float not null,
+	elevation_1_ne float not null,
+	elevation_2_ne float not null,
+	elevation_1_se float not null,
+	elevation_2_se float not null,
+	elevation_1_sw float not null,
+	elevation_2_sw float not null,
+	water_height float not null,
+	terrain_raise_limit float not null,
+	terrain_lower_limit float not null,
+	use_estate_sun integer not null,
+	fixed_sun integer not null,
+	sun_position float not null,
+	covenant char(36));
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql
new file mode 100644
index 0000000..03142af
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql
@@ -0,0 +1,6 @@
+BEGIN;
+
+ALTER TABLE users add customType varchar(32) not null default '';
+ALTER TABLE users add partner char(36) not null default '00000000-0000-0000-0000-000000000000';
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql
new file mode 100644
index 0000000..1f6d1bd
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+delete from regionsettings;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql
new file mode 100644
index 0000000..e45c09a
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+CREATE TABLE `avatarattachments` (`UUID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', `attachpoint` int(11) NOT NULL DEFAULT 0, `item` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', `asset` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000');
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql
new file mode 100644
index 0000000..94ed818
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql
@@ -0,0 +1,102 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE estate_groups (
+  EstateID int(10) NOT NULL,
+  uuid char(36) NOT NULL
+);
+
+CREATE TABLE estate_managers (
+  EstateID int(10) NOT NULL,
+  uuid char(36) NOT NULL
+);
+
+CREATE TABLE estate_map (
+  RegionID char(36) NOT NULL default '00000000-0000-0000-0000-000000000000',
+  EstateID int(11) NOT NULL
+);
+
+CREATE TABLE estate_settings (
+  EstateID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  EstateName varchar(64) default NULL,
+  AbuseEmailToEstateOwner tinyint(4) NOT NULL,
+  DenyAnonymous tinyint(4) NOT NULL,
+  ResetHomeOnTeleport tinyint(4) NOT NULL,
+  FixedSun tinyint(4) NOT NULL,
+  DenyTransacted tinyint(4) NOT NULL,
+  BlockDwell tinyint(4) NOT NULL,
+  DenyIdentified tinyint(4) NOT NULL,
+  AllowVoice tinyint(4) NOT NULL,
+  UseGlobalTime tinyint(4) NOT NULL,
+  PricePerMeter int(11) NOT NULL,
+  TaxFree tinyint(4) NOT NULL,
+  AllowDirectTeleport tinyint(4) NOT NULL,
+  RedirectGridX int(11) NOT NULL,
+  RedirectGridY int(11) NOT NULL,
+  ParentEstateID int(10) NOT NULL,
+  SunPosition double NOT NULL,
+  EstateSkipScripts tinyint(4) NOT NULL,
+  BillableFactor float NOT NULL,
+  PublicAccess tinyint(4) NOT NULL
+);
+insert into estate_settings (EstateID,EstateName,AbuseEmailToEstateOwner,DenyAnonymous,ResetHomeOnTeleport,FixedSun,DenyTransacted,BlockDwell,DenyIdentified,AllowVoice,UseGlobalTime,PricePerMeter,TaxFree,AllowDirectTeleport,RedirectGridX,RedirectGridY,ParentEstateID,SunPosition,PublicAccess,EstateSkipScripts,BillableFactor) values ( 99, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');
+delete from estate_settings;
+CREATE TABLE estate_users (
+  EstateID int(10) NOT NULL,
+  uuid char(36) NOT NULL
+);
+
+CREATE TABLE estateban (
+  EstateID int(10) NOT NULL,
+  bannedUUID varchar(36) NOT NULL,
+  bannedIp varchar(16) NOT NULL,
+  bannedIpHostMask varchar(16) NOT NULL,
+  bannedNameMask varchar(64) default NULL
+);
+
+drop table regionsettings;
+CREATE TABLE regionsettings (
+  regionUUID char(36) NOT NULL,
+  block_terraform int(11) NOT NULL,
+  block_fly int(11) NOT NULL,
+  allow_damage int(11) NOT NULL,
+  restrict_pushing int(11) NOT NULL,
+  allow_land_resell int(11) NOT NULL,
+  allow_land_join_divide int(11) NOT NULL,
+  block_show_in_search int(11) NOT NULL,
+  agent_limit int(11) NOT NULL,
+  object_bonus float NOT NULL,
+  maturity int(11) NOT NULL,
+  disable_scripts int(11) NOT NULL,
+  disable_collisions int(11) NOT NULL,
+  disable_physics int(11) NOT NULL,
+  terrain_texture_1 char(36) NOT NULL,
+  terrain_texture_2 char(36) NOT NULL,
+  terrain_texture_3 char(36) NOT NULL,
+  terrain_texture_4 char(36) NOT NULL,
+  elevation_1_nw float NOT NULL,
+  elevation_2_nw float NOT NULL,
+  elevation_1_ne float NOT NULL,
+  elevation_2_ne float NOT NULL,
+  elevation_1_se float NOT NULL,
+  elevation_2_se float NOT NULL,
+  elevation_1_sw float NOT NULL,
+  elevation_2_sw float NOT NULL,
+  water_height float NOT NULL,
+  terrain_raise_limit float NOT NULL,
+  terrain_lower_limit float NOT NULL,
+  use_estate_sun int(11) NOT NULL,
+  fixed_sun int(11) NOT NULL,
+  sun_position float NOT NULL,
+  covenant char(36) default NULL,
+  Sandbox tinyint(4) NOT NULL,
+  PRIMARY KEY  (regionUUID)
+);
+
+CREATE INDEX estate_ban_estate_id on estateban(EstateID);
+CREATE INDEX estate_groups_estate_id on estate_groups(EstateID);
+CREATE INDEX estate_managers_estate_id on estate_managers(EstateID);
+CREATE INDEX estate_map_estate_id on estate_map(EstateID);
+CREATE UNIQUE INDEX estate_map_region_id on estate_map(RegionID);
+CREATE INDEX estate_users_estate_id on estate_users(EstateID);
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql
new file mode 100644
index 0000000..f9454c5
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql
@@ -0,0 +1,20 @@
+BEGIN TRANSACTION;
+
+-- usersagents table
+CREATE TABLE IF NOT EXISTS useragents(
+       UUID varchar(255) primary key,
+       agentIP varchar(255),
+       agentPort integer,
+       agentOnline boolean,
+       sessionID varchar(255),
+       secureSessionID varchar(255),
+       regionID varchar(255),
+       loginTime integer,
+       logoutTime integer,
+       currentRegion varchar(255),
+       currentHandle varchar(255),
+       currentPosX float,
+       currentPosY float,
+       currentPosZ float);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql
new file mode 100644
index 0000000..1c813a0
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql
@@ -0,0 +1,8 @@
+begin;
+
+alter table estate_settings add column AbuseEmail varchar(255) not null default '';
+
+alter table estate_settings add column EstateOwner varchar(36) not null default '';
+
+commit;
+
diff --git a/OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql
new file mode 100644
index 0000000..8b0cd28
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql
@@ -0,0 +1,7 @@
+BEGIN TRANSACTION;
+
+ALTER TABLE useragents add currentLookAtX float not null default 128;
+ALTER TABLE useragents add currentLookAtY float not null default 128;
+ALTER TABLE useragents add currentLookAtZ float not null default 70;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql
new file mode 100644
index 0000000..28bfbf5
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql
@@ -0,0 +1,6 @@
+begin;
+
+alter table estate_settings add column DenyMinors tinyint not null default 0;
+
+commit;
+
diff --git a/OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql
new file mode 100644
index 0000000..97da818
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql
@@ -0,0 +1,5 @@
+BEGIN TRANSACTION;
+
+ALTER TABLE users add email varchar(250);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql
new file mode 100644
index 0000000..1f40548
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql
@@ -0,0 +1,8 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN ColorR integer not null default 0;
+ALTER TABLE prims ADD COLUMN ColorG integer not null default 0;
+ALTER TABLE prims ADD COLUMN ColorB integer not null default 0;
+ALTER TABLE prims ADD COLUMN ColorA integer not null default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql
new file mode 100644
index 0000000..8ab03ef
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql
@@ -0,0 +1,11 @@
+BEGIN;
+
+update users
+  set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+  where UUID not like '%-%';
+
+update useragents
+  set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+  where UUID not like '%-%';
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql
new file mode 100644
index 0000000..b91ccf0
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN ClickAction INTEGER NOT NULL default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql
new file mode 100644
index 0000000..5f956da
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql
@@ -0,0 +1,37 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE IF NOT EXISTS avatarappearance(
+  Owner varchar(36) NOT NULL primary key,
+  BodyItem varchar(36) DEFAULT NULL,
+  BodyAsset varchar(36) DEFAULT NULL,
+  SkinItem varchar(36) DEFAULT NULL,
+  SkinAsset varchar(36) DEFAULT NULL,
+  HairItem varchar(36) DEFAULT NULL,
+  HairAsset varchar(36) DEFAULT NULL,
+  EyesItem varchar(36) DEFAULT NULL,
+  EyesAsset varchar(36) DEFAULT NULL,
+  ShirtItem varchar(36) DEFAULT NULL,
+  ShirtAsset varchar(36) DEFAULT NULL,
+  PantsItem varchar(36) DEFAULT NULL,
+  PantsAsset varchar(36) DEFAULT NULL,
+  ShoesItem varchar(36) DEFAULT NULL,
+  ShoesAsset varchar(36) DEFAULT NULL,
+  SocksItem varchar(36) DEFAULT NULL,
+  SocksAsset varchar(36) DEFAULT NULL,
+  JacketItem varchar(36) DEFAULT NULL,
+  JacketAsset varchar(36) DEFAULT NULL,
+  GlovesItem varchar(36) DEFAULT NULL,
+  GlovesAsset varchar(36) DEFAULT NULL,
+  UnderShirtItem varchar(36) DEFAULT NULL,
+  UnderShirtAsset varchar(36) DEFAULT NULL,
+  UnderPantsItem varchar(36) DEFAULT NULL,
+  UnderPantsAsset varchar(36) DEFAULT NULL,
+  SkirtItem varchar(36) DEFAULT NULL,
+  SkirtAsset varchar(36) DEFAULT NULL,
+  Texture blob,
+  VisualParams blob,
+  Serial int DEFAULT NULL,
+  AvatarHeight float DEFAULT NULL
+);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql
new file mode 100644
index 0000000..42bef89
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql
@@ -0,0 +1,28 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN PayPrice INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN PayButton1 INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN PayButton2 INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN PayButton3 INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN PayButton4 INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN LoopedSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000';
+ALTER TABLE prims ADD COLUMN LoopedSoundGain float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN TextureAnimation string;
+ALTER TABLE prims ADD COLUMN ParticleSystem string;
+ALTER TABLE prims ADD COLUMN OmegaX float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN OmegaY float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN OmegaZ float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraEyeOffsetX float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraEyeOffsetY float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraEyeOffsetZ float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraAtOffsetX float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraAtOffsetY float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraAtOffsetZ float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN ForceMouselook string NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN ScriptAccessPin INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN AllowedDrop INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN DieAtEdge string NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN SalePrice INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN SaleType string NOT NULL default 0;
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql
new file mode 100644
index 0000000..d952b78
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN Material INTEGER NOT NULL default 3;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql
new file mode 100644
index 0000000..11529cd
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql
@@ -0,0 +1,6 @@
+BEGIN;
+
+ALTER TABLE land ADD COLUMN OtherCleanTime INTEGER NOT NULL default 0;
+ALTER TABLE land ADD COLUMN Dwell INTEGER NOT NULL default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql
new file mode 100644
index 0000000..c59b27e
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql
@@ -0,0 +1,8 @@
+begin;
+
+ALTER TABLE regionsettings ADD COLUMN sunvectorx double NOT NULL default 0;
+ALTER TABLE regionsettings ADD COLUMN sunvectory double NOT NULL default 0;
+ALTER TABLE regionsettings ADD COLUMN sunvectorz double NOT NULL default 0;
+
+commit;
+
diff --git a/OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql
new file mode 100644
index 0000000..c43f356
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql
@@ -0,0 +1,6 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN CollisionSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000';
+ALTER TABLE prims ADD COLUMN CollisionSoundVolume float NOT NULL default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql
new file mode 100644
index 0000000..52f160c
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN VolumeDetect INTEGER NOT NULL DEFAULT 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql
new file mode 100644
index 0000000..6c6b7b5
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql
@@ -0,0 +1,8 @@
+BEGIN;
+CREATE TEMPORARY TABLE prims_backup(UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect);
+INSERT INTO prims_backup SELECT UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect FROM prims;
+DROP TABLE prims;
+CREATE TABLE prims(UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect);
+INSERT INTO prims SELECT UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect FROM prims_backup;
+DROP TABLE prims_backup;
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql
new file mode 100644
index 0000000..6a390c2
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql
@@ -0,0 +1,79 @@
+BEGIN;
+
+update terrain 
+  set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12)
+  where RegionUUID not like '%-%';
+  
+
+update landaccesslist
+  set LandUUID = substr(LandUUID, 1, 8) || "-" || substr(LandUUID, 9, 4) || "-" || substr(LandUUID, 13, 4) || "-" || substr(LandUUID, 17, 4) || "-" || substr(LandUUID, 21, 12) 
+  where LandUUID not like '%-%';
+
+update landaccesslist
+  set AccessUUID = substr(AccessUUID, 1, 8) || "-" || substr(AccessUUID, 9, 4) || "-" || substr(AccessUUID, 13, 4) || "-" || substr(AccessUUID, 17, 4) || "-" || substr(AccessUUID, 21, 12) 
+  where AccessUUID not like '%-%';
+  
+
+update prims
+  set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) 
+  where UUID not like '%-%';
+
+update prims
+  set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12) 
+  where RegionUUID not like '%-%';
+
+update prims
+  set SceneGroupID = substr(SceneGroupID, 1, 8) || "-" || substr(SceneGroupID, 9, 4) || "-" || substr(SceneGroupID, 13, 4) || "-" || substr(SceneGroupID, 17, 4) || "-" || substr(SceneGroupID, 21, 12) 
+  where SceneGroupID not like '%-%';
+
+update prims
+  set CreatorID = substr(CreatorID, 1, 8) || "-" || substr(CreatorID, 9, 4) || "-" || substr(CreatorID, 13, 4) || "-" || substr(CreatorID, 17, 4) || "-" || substr(CreatorID, 21, 12) 
+  where CreatorID not like '%-%';
+
+update prims
+  set OwnerID = substr(OwnerID, 1, 8) || "-" || substr(OwnerID, 9, 4) || "-" || substr(OwnerID, 13, 4) || "-" || substr(OwnerID, 17, 4) || "-" || substr(OwnerID, 21, 12) 
+  where OwnerID not like '%-%';
+
+update prims
+  set GroupID = substr(GroupID, 1, 8) || "-" || substr(GroupID, 9, 4) || "-" || substr(GroupID, 13, 4) || "-" || substr(GroupID, 17, 4) || "-" || substr(GroupID, 21, 12) 
+  where GroupID not like '%-%';
+
+update prims
+  set LastOwnerID = substr(LastOwnerID, 1, 8) || "-" || substr(LastOwnerID, 9, 4) || "-" || substr(LastOwnerID, 13, 4) || "-" || substr(LastOwnerID, 17, 4) || "-" || substr(LastOwnerID, 21, 12) 
+  where LastOwnerID not like '%-%';
+
+
+update primshapes
+  set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) 
+  where UUID not like '%-%';
+
+
+update land
+  set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12) 
+  where UUID not like '%-%';
+  
+update land
+  set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12)
+  where RegionUUID not like '%-%';
+
+update land
+  set OwnerUUID = substr(OwnerUUID, 1, 8) || "-" || substr(OwnerUUID, 9, 4) || "-" || substr(OwnerUUID, 13, 4) || "-" || substr(OwnerUUID, 17, 4) || "-" || substr(OwnerUUID, 21, 12)
+  where OwnerUUID not like '%-%';
+
+update land
+  set GroupUUID = substr(GroupUUID, 1, 8) || "-" || substr(GroupUUID, 9, 4) || "-" || substr(GroupUUID, 13, 4) || "-" || substr(GroupUUID, 17, 4) || "-" || substr(GroupUUID, 21, 12)
+  where GroupUUID not like '%-%';
+
+update land
+  set MediaTextureUUID = substr(MediaTextureUUID, 1, 8) || "-" || substr(MediaTextureUUID, 9, 4) || "-" || substr(MediaTextureUUID, 13, 4) || "-" || substr(MediaTextureUUID, 17, 4) || "-" || substr(MediaTextureUUID, 21, 12)
+  where MediaTextureUUID not like '%-%';
+
+update land
+  set SnapshotUUID = substr(SnapshotUUID, 1, 8) || "-" || substr(SnapshotUUID, 9, 4) || "-" || substr(SnapshotUUID, 13, 4) || "-" || substr(SnapshotUUID, 17, 4) || "-" || substr(SnapshotUUID, 21, 12)
+  where SnapshotUUID not like '%-%';
+
+update land
+  set AuthbuyerID = substr(AuthbuyerID, 1, 8) || "-" || substr(AuthbuyerID, 9, 4) || "-" || substr(AuthbuyerID, 13, 4) || "-" || substr(AuthbuyerID, 17, 4) || "-" || substr(AuthbuyerID, 21, 12)
+  where AuthbuyerID not like '%-%';
+  
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml b/OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml
new file mode 100644
index 0000000..e6764fa
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml
@@ -0,0 +1,20 @@
+<Addin id="OpenSim.Data.SQLite" version="0.1">
+    <Runtime>
+        <Import assembly="OpenSim.Data.SQLite.dll"/>
+    </Runtime>
+    <Dependencies>
+        <Addin id="OpenSim.Data" version="0.5" />
+    </Dependencies>
+    <Extension path = "/OpenSim/GridData">
+        <Plugin id="SQLiteGridData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteGridData" />
+    </Extension>
+    <Extension path = "/OpenSim/AssetData">
+        <Plugin id="SQLiteAssetData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteAssetData" />
+    </Extension>
+    <Extension path = "/OpenSim/InventoryData">
+        <Plugin id="SQLiteInventoryData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteInventoryStore" />
+    </Extension>
+    <Extension path = "/OpenSim/UserData">
+        <Plugin id="SQLiteUserData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteUserData" />
+    </Extension>
+</Addin>
diff --git a/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs b/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs
new file mode 100644
index 0000000..a032670
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Data;
+using System.Reflection;
+using System.Collections.Generic;
+using log4net;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Framework;
+
+namespace OpenSim.Data.SQLite
+{
+    /// <summary>
+    /// An asset storage interface for the SQLite database system
+    /// </summary>
+    public class SQLiteAssetData : AssetDataBase
+    {
+//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        private const string SelectAssetSQL = "select * from assets where UUID=:UUID";
+        private const string SelectAssetMetadataSQL = "select Name, Description, Type, Temporary, UUID from assets limit :start, :count";
+        private const string DeleteAssetSQL = "delete from assets where UUID=:UUID";
+        private const string InsertAssetSQL = "insert into assets(UUID, Name, Description, Type, Local, Temporary, Data) values(:UUID, :Name, :Description, :Type, :Local, :Temporary, :Data)";
+        private const string UpdateAssetSQL = "update assets set Name=:Name, Description=:Description, Type=:Type, Local=:Local, Temporary=:Temporary, Data=:Data where UUID=:UUID";
+        private const string assetSelect = "select * from assets";
+
+        private SqliteConnection m_conn;
+
+        override public void Dispose()
+        {
+            if (m_conn != null)
+            {
+                m_conn.Close();
+                m_conn = null;
+            }
+        }
+
+        /// <summary>
+        /// <list type="bullet">
+        /// <item>Initialises AssetData interface</item>
+        /// <item>Loads and initialises a new SQLite connection and maintains it.</item>
+        /// <item>use default URI if connect string is empty.</item>
+        /// </list>
+        /// </summary>
+        /// <param name="dbconnect">connect string</param>
+        override public void Initialise(string dbconnect)
+        {
+            if (dbconnect == string.Empty)
+            {
+                dbconnect = "URI=file:Asset.db,version=3";
+            }
+            m_conn = new SqliteConnection(dbconnect);
+            m_conn.Open();
+
+            Assembly assem = GetType().Assembly;
+            Migration m = new Migration(m_conn, assem, "AssetStore");
+            m.Update();
+
+            return;
+        }
+
+        /// <summary>
+        /// Fetch Asset
+        /// </summary>
+        /// <param name="uuid">UUID of ... ?</param>
+        /// <returns>Asset base</returns>
+        override public AssetBase GetAsset(UUID uuid)
+        {
+            lock (this)
+            {
+                using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
+                {
+                    cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
+                    using (IDataReader reader = cmd.ExecuteReader())
+                    {
+                        if (reader.Read())
+                        {
+                            AssetBase asset = buildAsset(reader);
+                            reader.Close();
+                            return asset;
+                        }
+                        else
+                        {
+                            reader.Close();
+                            return null;
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Create an asset
+        /// </summary>
+        /// <param name="asset">Asset Base</param>
+        override public void StoreAsset(AssetBase asset)
+        {
+            //m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
+            if (ExistsAsset(asset.FullID))
+            {
+                //LogAssetLoad(asset);
+
+                lock (this)
+                {
+                    using (SqliteCommand cmd = new SqliteCommand(UpdateAssetSQL, m_conn))
+                    {
+                        cmd.Parameters.Add(new SqliteParameter(":UUID", asset.FullID.ToString()));
+                        cmd.Parameters.Add(new SqliteParameter(":Name", asset.Name));
+                        cmd.Parameters.Add(new SqliteParameter(":Description", asset.Description));
+                        cmd.Parameters.Add(new SqliteParameter(":Type", asset.Type));
+                        cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local));
+                        cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary));
+                        cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
+ 
+                        cmd.ExecuteNonQuery();
+                    }
+                }
+            }
+            else
+            {
+                lock (this)
+                {
+                    using (SqliteCommand cmd = new SqliteCommand(InsertAssetSQL, m_conn))
+                    {
+                        cmd.Parameters.Add(new SqliteParameter(":UUID", asset.FullID.ToString()));
+                        cmd.Parameters.Add(new SqliteParameter(":Name", asset.Name));
+                        cmd.Parameters.Add(new SqliteParameter(":Description", asset.Description));
+                        cmd.Parameters.Add(new SqliteParameter(":Type", asset.Type));
+                        cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local));
+                        cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary));
+                        cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
+
+                        cmd.ExecuteNonQuery();
+                    }
+                }
+            }
+        }
+
+//        /// <summary>
+//        /// Some... logging functionnality
+//        /// </summary>
+//        /// <param name="asset"></param>
+//        private static void LogAssetLoad(AssetBase asset)
+//        {
+//            string temporary = asset.Temporary ? "Temporary" : "Stored";
+//            string local = asset.Local ? "Local" : "Remote";
+//
+//            int assetLength = (asset.Data != null) ? asset.Data.Length : 0;
+//
+//            m_log.Debug("[ASSET DB]: " +
+//                                     string.Format("Loaded {5} {4} Asset: [{0}][{3}] \"{1}\":{2} ({6} bytes)",
+//                                                   asset.FullID, asset.Name, asset.Description, asset.Type,
+//                                                   temporary, local, assetLength));
+//        }
+
+        /// <summary>
+        /// Check if an asset exist in database
+        /// </summary>
+        /// <param name="uuid">The asset UUID</param>
+        /// <returns>True if exist, or false.</returns>
+        override public bool ExistsAsset(UUID uuid)
+        {
+            lock (this) {
+                using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
+                {
+                    cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
+                    using (IDataReader reader = cmd.ExecuteReader())
+                    {
+                        if (reader.Read())
+                        {
+                            reader.Close();
+                            return true;
+                        }
+                        else
+                        {
+                            reader.Close();
+                            return false;
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Delete an asset from database
+        /// </summary>
+        /// <param name="uuid"></param>
+        public void DeleteAsset(UUID uuid)
+        {
+            using (SqliteCommand cmd = new SqliteCommand(DeleteAssetSQL, m_conn))
+            {
+                cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
+
+                cmd.ExecuteNonQuery();
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <returns></returns>
+        private static AssetBase buildAsset(IDataReader row)
+        {
+            // TODO: this doesn't work yet because something more
+            // interesting has to be done to actually get these values
+            // back out.  Not enough time to figure it out yet.
+            AssetBase asset = new AssetBase(
+                new UUID((String)row["UUID"]),
+                (String)row["Name"],
+                Convert.ToSByte(row["Type"]),
+                UUID.Zero.ToString()
+            );
+
+            asset.Description = (String) row["Description"];
+            asset.Local = Convert.ToBoolean(row["Local"]);
+            asset.Temporary = Convert.ToBoolean(row["Temporary"]);
+            asset.Data = (byte[]) row["Data"];
+            return asset;
+        }
+
+        private static AssetMetadata buildAssetMetadata(IDataReader row)
+        {
+            AssetMetadata metadata = new AssetMetadata();
+
+            metadata.FullID = new UUID((string) row["UUID"]);
+            metadata.Name = (string) row["Name"];
+            metadata.Description = (string) row["Description"];
+            metadata.Type = Convert.ToSByte(row["Type"]);
+            metadata.Temporary = Convert.ToBoolean(row["Temporary"]); // Not sure if this is correct.
+
+            // Current SHA1s are not stored/computed.
+            metadata.SHA1 = new byte[] {};
+
+            return metadata;
+        }
+
+        /// <summary>
+        /// Returns a list of AssetMetadata objects. The list is a subset of
+        /// the entire data set offset by <paramref name="start" /> containing
+        /// <paramref name="count" /> elements.
+        /// </summary>
+        /// <param name="start">The number of results to discard from the total data set.</param>
+        /// <param name="count">The number of rows the returned list should contain.</param>
+        /// <returns>A list of AssetMetadata objects.</returns>
+        public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
+        {
+            List<AssetMetadata> retList = new List<AssetMetadata>(count);
+
+            lock (this)
+            {
+                using (SqliteCommand cmd = new SqliteCommand(SelectAssetMetadataSQL, m_conn))
+                {
+                    cmd.Parameters.Add(new SqliteParameter(":start", start));
+                    cmd.Parameters.Add(new SqliteParameter(":count", count));
+
+                    using (IDataReader reader = cmd.ExecuteReader())
+                    {
+                        while (reader.Read())
+                        {
+                            AssetMetadata metadata = buildAssetMetadata(reader);
+                            retList.Add(metadata);
+                        }
+                    }
+                }
+            }
+
+            return retList;
+        }
+
+        /***********************************************************************
+         *
+         *  Database Binding functions
+         *
+         *  These will be db specific due to typing, and minor differences
+         *  in databases.
+         *
+         **********************************************************************/
+
+        #region IPlugin interface
+
+        /// <summary>
+        ///
+        /// </summary>
+        override public string Version
+        {
+            get
+            {
+                Module module = GetType().Module;
+                // string dllName = module.Assembly.ManifestModule.Name;
+                Version dllVersion = module.Assembly.GetName().Version;
+
+                return
+                    string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
+                                  dllVersion.Revision);
+            }
+        }
+
+        /// <summary>
+        /// Initialise the AssetData interface using default URI
+        /// </summary>
+        override public void Initialise()
+        {
+            Initialise("URI=file:Asset.db,version=3");
+        }
+
+        /// <summary>
+        /// Name of this DB provider
+        /// </summary>
+        override public string Name
+        {
+            get { return "SQLite Asset storage engine"; }
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs
new file mode 100644
index 0000000..aa10734
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+    public class SQLiteAuthenticationData : SQLiteFramework, IAuthenticationData
+    {
+        private string m_Realm;
+        private List<string> m_ColumnNames;
+        private int m_LastExpire;
+        private string m_connectionString;
+
+        protected static SqliteConnection m_Connection;
+        private static bool m_initialized = false;
+
+        public SQLiteAuthenticationData(string connectionString, string realm)
+                : base(connectionString)
+        {
+            m_Realm = realm;
+            m_connectionString = connectionString;
+
+            if (!m_initialized)
+            {
+                m_Connection = new SqliteConnection(connectionString);
+                m_Connection.Open();
+
+                using (SqliteConnection dbcon = (SqliteConnection)((ICloneable)m_Connection).Clone())
+                {
+                    dbcon.Open();
+                    Migration m = new Migration(dbcon, GetType().Assembly, "AuthStore");
+                    m.Update();
+                    dbcon.Close();
+                }
+
+                m_initialized = true;
+            }
+        }
+
+        public AuthenticationData Get(UUID principalID)
+        {
+            AuthenticationData ret = new AuthenticationData();
+            ret.Data = new Dictionary<string, object>();
+
+            SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID");
+            cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
+
+            IDataReader result = ExecuteReader(cmd, m_Connection);
+
+            try
+            {
+                if (result.Read())
+                {
+                    ret.PrincipalID = principalID;
+
+                    if (m_ColumnNames == null)
+                    {
+                        m_ColumnNames = new List<string>();
+
+                        DataTable schemaTable = result.GetSchemaTable();
+                        foreach (DataRow row in schemaTable.Rows)
+                            m_ColumnNames.Add(row["ColumnName"].ToString());
+                    }
+
+                    foreach (string s in m_ColumnNames)
+                    {
+                        if (s == "UUID")
+                            continue;
+
+                        ret.Data[s] = result[s].ToString();
+                    }
+
+                    return ret;
+                }
+                else
+                {
+                    return null;
+                }
+            }
+            catch
+            {
+            }
+            finally
+            {
+                CloseCommand(cmd);
+            }
+
+            return null;
+        }
+
+        public bool Store(AuthenticationData data)
+        {
+            if (data.Data.ContainsKey("UUID"))
+                data.Data.Remove("UUID");
+
+            string[] fields = new List<string>(data.Data.Keys).ToArray();
+            string[] values = new string[data.Data.Count];
+            int i = 0;
+            foreach (object o in data.Data.Values)
+                values[i++] = o.ToString();
+
+            SqliteCommand cmd = new SqliteCommand();
+
+            if (Get(data.PrincipalID) != null)
+            {
+
+
+                string update = "update `" + m_Realm + "` set ";
+                bool first = true;
+                foreach (string field in fields)
+                {
+                    if (!first)
+                        update += ", ";
+                    update += "`" + field + "` = :" + field;
+                    cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
+
+                    first = false;
+                }
+
+                update += " where UUID = :UUID";
+                cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
+
+                cmd.CommandText = update;
+                try
+                {
+                    if (ExecuteNonQuery(cmd, m_Connection) < 1)
+                    {
+                        CloseCommand(cmd);
+                        return false;
+                    }
+                }
+                catch (Exception e)
+                {
+                    Console.WriteLine(e.ToString());
+                    CloseCommand(cmd);
+                    return false;
+                }
+            }
+
+            else
+            {
+                string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
+                        String.Join("`, `", fields) +
+                        "`) values (:UUID, :" + String.Join(", :", fields) + ")";
+
+                cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
+                foreach (string field in fields)
+                    cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
+
+                cmd.CommandText = insert;
+
+                try
+                {
+                    if (ExecuteNonQuery(cmd, m_Connection) < 1)
+                    {
+                        CloseCommand(cmd);
+                        return false;
+                    }
+                }
+                catch (Exception e)
+                {
+                    Console.WriteLine(e.ToString());
+                    CloseCommand(cmd);
+                    return false;
+                }
+            }
+
+            CloseCommand(cmd);
+
+            return true;
+        }
+
+        public bool SetDataItem(UUID principalID, string item, string value)
+        {
+            SqliteCommand cmd = new SqliteCommand("update `" + m_Realm +
+                    "` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'");
+
+            if (ExecuteNonQuery(cmd, m_Connection) > 0)
+                return true;
+
+            return false;
+        }
+
+        public bool SetToken(UUID principalID, string token, int lifetime)
+        {
+            if (System.Environment.TickCount - m_LastExpire > 30000)
+                DoExpire();
+
+            SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() + 
+                "', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))");
+
+            if (ExecuteNonQuery(cmd, m_Connection) > 0)
+            {
+                cmd.Dispose();
+                return true;
+            }
+
+            cmd.Dispose();
+            return false;
+        }
+
+        public bool CheckToken(UUID principalID, string token, int lifetime)
+        {
+            if (System.Environment.TickCount - m_LastExpire > 30000)
+                DoExpire();
+
+            SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() + 
+                " minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')");
+
+            if (ExecuteNonQuery(cmd, m_Connection) > 0)
+            {
+                cmd.Dispose();
+                return true;
+            }
+
+            cmd.Dispose();
+
+            return false;
+        }
+
+        private void DoExpire()
+        {
+            SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')");
+            ExecuteNonQuery(cmd, m_Connection);
+
+            cmd.Dispose();
+
+            m_LastExpire = System.Environment.TickCount;
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs b/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs
new file mode 100644
index 0000000..b3f4a4c
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Reflection;
+using System.Threading;
+using log4net;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+    /// <summary>
+    /// A SQLite Interface for Avatar Data
+    /// </summary>
+    public class SQLiteAvatarData : SQLiteGenericTableHandler<AvatarBaseData>,
+            IAvatarData
+    {
+        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        public SQLiteAvatarData(string connectionString, string realm) :
+                base(connectionString, realm, "Avatar")
+        {
+        }
+
+        public bool Delete(UUID principalID, string name)
+        {
+            SqliteCommand cmd = new SqliteCommand();
+
+            cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = :PrincipalID and `Name` = :Name", m_Realm);
+            cmd.Parameters.Add(":PrincipalID", principalID.ToString());
+            cmd.Parameters.Add(":Name", name);
+
+            try
+            {
+                if (ExecuteNonQuery(cmd, m_Connection) > 0)
+                    return true;
+
+                return false;
+            }
+            finally
+            {
+                CloseCommand(cmd);
+            }
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs b/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs
new file mode 100644
index 0000000..bd6b776
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Reflection;
+using log4net;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+
+namespace OpenSim.Data.SQLite
+{
+    public class SQLiteEstateStore : IEstateDataStore
+    {
+        private static readonly ILog m_log =
+            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        private SqliteConnection m_connection;
+        private string m_connectionString;
+
+        private FieldInfo[] m_Fields;
+        private Dictionary<string, FieldInfo> m_FieldMap =
+                new Dictionary<string, FieldInfo>();
+
+        public void Initialise(string connectionString)
+        {
+            m_connectionString = connectionString;
+
+            m_log.Info("[ESTATE DB]: Sqlite - connecting: "+m_connectionString);
+
+            m_connection = new SqliteConnection(m_connectionString);
+            m_connection.Open();
+
+            Assembly assem = GetType().Assembly;
+            Migration m = new Migration(m_connection, assem, "EstateStore");
+            m.Update();
+
+            m_connection.Close();
+            m_connection.Open();
+
+            Type t = typeof(EstateSettings);
+            m_Fields = t.GetFields(BindingFlags.NonPublic |
+                                   BindingFlags.Instance |
+                                   BindingFlags.DeclaredOnly);
+
+            foreach (FieldInfo f in m_Fields)
+                if (f.Name.Substring(0, 2) == "m_")
+                    m_FieldMap[f.Name.Substring(2)] = f;
+        }
+
+        private string[] FieldList
+        {
+            get { return new List<string>(m_FieldMap.Keys).ToArray(); }
+        }
+
+        public EstateSettings LoadEstateSettings(UUID regionID, bool create)
+        {
+            string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = :RegionID";
+
+            SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+            cmd.CommandText = sql;
+            cmd.Parameters.Add(":RegionID", regionID.ToString());
+
+            return DoLoad(cmd, regionID, create);
+        }
+
+        private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID, bool create)
+        {
+            EstateSettings es = new EstateSettings();
+            es.OnSave += StoreEstateSettings;
+
+            IDataReader r = cmd.ExecuteReader();
+
+            if (r.Read())
+            {
+                foreach (string name in FieldList)
+                {
+                    if (m_FieldMap[name].GetValue(es) is bool)
+                    {
+                        int v = Convert.ToInt32(r[name]);
+                        if (v != 0)
+                            m_FieldMap[name].SetValue(es, true);
+                        else
+                            m_FieldMap[name].SetValue(es, false);
+                    }
+                    else if (m_FieldMap[name].GetValue(es) is UUID)
+                    {
+                        UUID uuid = UUID.Zero;
+
+                        UUID.TryParse(r[name].ToString(), out uuid);
+                        m_FieldMap[name].SetValue(es, uuid);
+                    }
+                    else
+                    {
+                        m_FieldMap[name].SetValue(es, Convert.ChangeType(r[name], m_FieldMap[name].FieldType));
+                    }
+                }
+                r.Close();
+            }
+            else if (create)
+            {
+                r.Close();
+
+                List<string> names = new List<string>(FieldList);
+
+                names.Remove("EstateID");
+
+                string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
+
+                cmd.CommandText = sql;
+                cmd.Parameters.Clear();
+
+                foreach (string name in FieldList)
+                {
+                    if (m_FieldMap[name].GetValue(es) is bool)
+                    {
+                        if ((bool)m_FieldMap[name].GetValue(es))
+                            cmd.Parameters.Add(":"+name, "1");
+                        else
+                            cmd.Parameters.Add(":"+name, "0");
+                    }
+                    else
+                    {
+                        cmd.Parameters.Add(":"+name, m_FieldMap[name].GetValue(es).ToString());
+                    }
+                }
+
+                cmd.ExecuteNonQuery();
+
+                cmd.CommandText = "select LAST_INSERT_ROWID() as id";
+                cmd.Parameters.Clear();
+
+                r = cmd.ExecuteReader();
+
+                r.Read();
+
+                es.EstateID = Convert.ToUInt32(r["id"]);
+
+                r.Close();
+
+                cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
+                cmd.Parameters.Add(":RegionID", regionID.ToString());
+                cmd.Parameters.Add(":EstateID", es.EstateID.ToString());
+
+                // This will throw on dupe key
+                try
+                {
+                    cmd.ExecuteNonQuery();
+                }
+                catch (Exception)
+                {
+                }
+
+                es.Save();
+            }
+
+            LoadBanList(es);
+
+            es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
+            es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
+            es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
+            return es;
+        }
+
+        public void StoreEstateSettings(EstateSettings es)
+        {
+            List<string> fields = new List<string>(FieldList);
+            fields.Remove("EstateID");
+
+            List<string> terms = new List<string>();
+
+            foreach (string f in fields)
+                terms.Add(f+" = :"+f);
+
+            string sql = "update estate_settings set "+String.Join(", ", terms.ToArray())+" where EstateID = :EstateID";
+
+            SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+            cmd.CommandText = sql;
+
+            foreach (string name in FieldList)
+            {
+                if (m_FieldMap[name].GetValue(es) is bool)
+                {
+                    if ((bool)m_FieldMap[name].GetValue(es))
+                        cmd.Parameters.Add(":"+name, "1");
+                    else
+                        cmd.Parameters.Add(":"+name, "0");
+                }
+                else
+                {
+                    cmd.Parameters.Add(":"+name, m_FieldMap[name].GetValue(es).ToString());
+                }
+            }
+
+            cmd.ExecuteNonQuery();
+
+            SaveBanList(es);
+            SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers);
+            SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess);
+            SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups);
+        }
+
+        private void LoadBanList(EstateSettings es)
+        {
+            es.ClearBans();
+
+            SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+            cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID";
+            cmd.Parameters.Add(":EstateID", es.EstateID);
+
+            IDataReader r = cmd.ExecuteReader();
+
+            while (r.Read())
+            {
+                EstateBan eb = new EstateBan();
+
+                UUID uuid = new UUID();
+                UUID.TryParse(r["bannedUUID"].ToString(), out uuid);
+
+                eb.BannedUserID = uuid;
+                eb.BannedHostAddress = "0.0.0.0";
+                eb.BannedHostIPMask = "0.0.0.0";
+                es.AddBan(eb);
+            }
+            r.Close();
+        }
+
+        private void SaveBanList(EstateSettings es)
+        {
+            SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+            cmd.CommandText = "delete from estateban where EstateID = :EstateID";
+            cmd.Parameters.Add(":EstateID", es.EstateID.ToString());
+
+            cmd.ExecuteNonQuery();
+
+            cmd.Parameters.Clear();
+
+            cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( :EstateID, :bannedUUID, '', '', '' )";
+
+            foreach (EstateBan b in es.EstateBans)
+            {
+                cmd.Parameters.Add(":EstateID", es.EstateID.ToString());
+                cmd.Parameters.Add(":bannedUUID", b.BannedUserID.ToString());
+
+                cmd.ExecuteNonQuery();
+                cmd.Parameters.Clear();
+            }
+        }
+
+        void SaveUUIDList(uint EstateID, string table, UUID[] data)
+        {
+            SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+            cmd.CommandText = "delete from "+table+" where EstateID = :EstateID";
+            cmd.Parameters.Add(":EstateID", EstateID.ToString());
+
+            cmd.ExecuteNonQuery();
+
+            cmd.Parameters.Clear();
+
+            cmd.CommandText = "insert into "+table+" (EstateID, uuid) values ( :EstateID, :uuid )";
+
+            foreach (UUID uuid in data)
+            {
+                cmd.Parameters.Add(":EstateID", EstateID.ToString());
+                cmd.Parameters.Add(":uuid", uuid.ToString());
+
+                cmd.ExecuteNonQuery();
+                cmd.Parameters.Clear();
+            }
+        }
+
+        UUID[] LoadUUIDList(uint EstateID, string table)
+        {
+            List<UUID> uuids = new List<UUID>();
+
+            SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+            cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID";
+            cmd.Parameters.Add(":EstateID", EstateID);
+
+            IDataReader r = cmd.ExecuteReader();
+
+            while (r.Read())
+            {
+                // EstateBan eb = new EstateBan();
+
+                UUID uuid = new UUID();
+                UUID.TryParse(r["uuid"].ToString(), out uuid);
+
+                uuids.Add(uuid);
+            }
+            r.Close();
+
+            return uuids.ToArray();
+        }
+
+        public EstateSettings LoadEstateSettings(int estateID)
+        {
+            string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_settings where estate_settings.EstateID :EstateID";
+
+            SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+            cmd.CommandText = sql;
+            cmd.Parameters.Add(":EstateID", estateID.ToString());
+
+            return DoLoad(cmd, UUID.Zero, false);
+        }
+
+        public List<int> GetEstates(string search)
+        {
+            List<int> result = new List<int>();
+
+            string sql = "select EstateID from estate_settings where estate_settings.EstateName :EstateName";
+
+            SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+            cmd.CommandText = sql;
+            cmd.Parameters.Add(":EstateName", search);
+
+            IDataReader r = cmd.ExecuteReader();
+
+            while (r.Read())
+            {
+                result.Add(Convert.ToInt32(r["EstateID"]));
+            }
+            r.Close();
+
+            return result;
+        }
+
+        public bool LinkRegion(UUID regionID, int estateID)
+        {
+            SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+            cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
+            cmd.Parameters.Add(":RegionID", regionID.ToString());
+            cmd.Parameters.Add(":EstateID", estateID.ToString());
+
+            if (cmd.ExecuteNonQuery() == 0)
+                return false;
+
+            return true;
+        }
+
+        public List<UUID> GetRegions(int estateID)
+        {
+            return new List<UUID>();
+        }
+
+        public bool DeleteEstate(int estateID)
+        {
+            return false;
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteFramework.cs b/OpenSim/Data/SQLiteNG/SQLiteFramework.cs
new file mode 100644
index 0000000..20b5085
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteFramework.cs
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+    /// <summary>
+    /// A database interface class to a user profile storage system
+    /// </summary>
+    public class SQLiteFramework
+    {
+        protected Object m_lockObject = new Object();
+
+        protected SQLiteFramework(string connectionString)
+        {
+        }
+
+        //////////////////////////////////////////////////////////////
+        //
+        // All non queries are funneled through one connection
+        // to increase performance a little
+        //
+        protected int ExecuteNonQuery(SqliteCommand cmd, SqliteConnection connection)
+        {
+            lock (connection)
+            {
+                SqliteConnection newConnection =
+                        (SqliteConnection)((ICloneable)connection).Clone();
+                newConnection.Open();
+
+                cmd.Connection = newConnection;
+                //Console.WriteLine("XXX " + cmd.CommandText);
+
+                return cmd.ExecuteNonQuery();
+            }
+        }
+
+        protected IDataReader ExecuteReader(SqliteCommand cmd, SqliteConnection connection)
+        {
+            lock (connection)
+            {
+                SqliteConnection newConnection =
+                        (SqliteConnection)((ICloneable)connection).Clone();
+                newConnection.Open();
+
+                cmd.Connection = newConnection;
+                //Console.WriteLine("XXX " + cmd.CommandText);
+
+                return cmd.ExecuteReader();
+            }
+        }
+
+        protected void CloseCommand(SqliteCommand cmd)
+        {
+            cmd.Connection.Close();
+            cmd.Connection.Dispose();
+            cmd.Dispose();
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs b/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs
new file mode 100644
index 0000000..0b12182
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+    public class SQLiteFriendsData : SQLiteGenericTableHandler<FriendsData>, IFriendsData
+    {
+        public SQLiteFriendsData(string connectionString, string realm)
+            : base(connectionString, realm, "FriendsStore")
+        {
+        }
+
+        public FriendsData[] GetFriends(UUID userID)
+        {
+            SqliteCommand cmd = new SqliteCommand();
+
+            cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = :PrincipalID", m_Realm);
+            cmd.Parameters.Add(":PrincipalID", userID.ToString());
+
+            return DoQuery(cmd);
+
+        }
+
+        public bool Delete(UUID principalID, string friend)
+        {
+            SqliteCommand cmd = new SqliteCommand();
+
+            cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm);
+            cmd.Parameters.Add(":PrincipalID", principalID.ToString());
+            cmd.Parameters.Add(":Friend", friend);
+
+            ExecuteNonQuery(cmd, cmd.Connection);
+
+            return true;
+        }
+
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs
new file mode 100644
index 0000000..b39bb19
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Reflection;
+using log4net;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+
+namespace OpenSim.Data.SQLite
+{
+    public class SQLiteGenericTableHandler<T> : SQLiteFramework where T: class, new()
+    {
+//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        protected Dictionary<string, FieldInfo> m_Fields =
+                new Dictionary<string, FieldInfo>();
+
+        protected List<string> m_ColumnNames = null;
+        protected string m_Realm;
+        protected FieldInfo m_DataField = null;
+
+        protected static SqliteConnection m_Connection;
+        private static bool m_initialized;
+
+        public SQLiteGenericTableHandler(string connectionString,
+                string realm, string storeName) : base(connectionString)
+        {
+            m_Realm = realm;
+
+            if (!m_initialized)
+            {
+                m_Connection = new SqliteConnection(connectionString);
+                m_Connection.Open();
+
+                if (storeName != String.Empty)
+                {
+                    Assembly assem = GetType().Assembly;
+                    SqliteConnection newConnection =
+                            (SqliteConnection)((ICloneable)m_Connection).Clone();
+                    newConnection.Open();
+
+                    Migration m = new Migration(newConnection, assem, storeName);
+                    m.Update();
+                    newConnection.Close();
+                    newConnection.Dispose();
+                }
+
+                m_initialized = true;
+            }
+
+            Type t = typeof(T);
+            FieldInfo[] fields = t.GetFields(BindingFlags.Public |
+                                             BindingFlags.Instance |
+                                             BindingFlags.DeclaredOnly);
+
+            if (fields.Length == 0)
+                return;
+
+            foreach (FieldInfo f in  fields)
+            {
+                if (f.Name != "Data")
+                    m_Fields[f.Name] = f;
+                else
+                    m_DataField = f;
+            }
+        }
+
+        private void CheckColumnNames(IDataReader reader)
+        {
+            if (m_ColumnNames != null)
+                return;
+
+            m_ColumnNames = new List<string>();
+
+            DataTable schemaTable = reader.GetSchemaTable();
+            foreach (DataRow row in schemaTable.Rows)
+            {
+                if (row["ColumnName"] != null &&
+                        (!m_Fields.ContainsKey(row["ColumnName"].ToString())))
+                    m_ColumnNames.Add(row["ColumnName"].ToString());
+            }
+        }
+
+        public T[] Get(string field, string key)
+        {
+            return Get(new string[] { field }, new string[] { key });
+        }
+
+        public T[] Get(string[] fields, string[] keys)
+        {
+            if (fields.Length != keys.Length)
+                return new T[0];
+
+            List<string> terms = new List<string>();
+
+            SqliteCommand cmd = new SqliteCommand();
+
+            for (int i = 0 ; i < fields.Length ; i++)
+            {
+                cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
+                terms.Add("`" + fields[i] + "` = :" + fields[i]);
+            }
+
+            string where = String.Join(" and ", terms.ToArray());
+
+            string query = String.Format("select * from {0} where {1}",
+                    m_Realm, where);
+
+            cmd.CommandText = query;
+
+            return DoQuery(cmd);
+        }
+
+        protected T[] DoQuery(SqliteCommand cmd)
+        {
+            IDataReader reader = ExecuteReader(cmd, m_Connection);
+            if (reader == null)
+                return new T[0];
+
+            CheckColumnNames(reader);
+
+            List<T> result = new List<T>();
+
+            while (reader.Read())
+            {
+                T row = new T();
+
+                foreach (string name in m_Fields.Keys)
+                {
+                    if (m_Fields[name].GetValue(row) is bool)
+                    {
+                        int v = Convert.ToInt32(reader[name]);
+                        m_Fields[name].SetValue(row, v != 0 ? true : false);
+                    }
+                    else if (m_Fields[name].GetValue(row) is UUID)
+                    {
+                        UUID uuid = UUID.Zero;
+
+                        UUID.TryParse(reader[name].ToString(), out uuid);
+                        m_Fields[name].SetValue(row, uuid);
+                    }
+                    else if (m_Fields[name].GetValue(row) is int)
+                    {
+                        int v = Convert.ToInt32(reader[name]);
+                        m_Fields[name].SetValue(row, v);
+                    }
+                    else
+                    {
+                        m_Fields[name].SetValue(row, reader[name]);
+                    }
+                }
+                
+                if (m_DataField != null)
+                {
+                    Dictionary<string, string> data =
+                            new Dictionary<string, string>();
+
+                    foreach (string col in m_ColumnNames)
+                    {
+                        data[col] = reader[col].ToString();
+                        if (data[col] == null)
+                            data[col] = String.Empty;
+                    }
+
+                    m_DataField.SetValue(row, data);
+                }
+
+                result.Add(row);
+            }
+
+            CloseCommand(cmd);
+
+            return result.ToArray();
+        }
+
+        public T[] Get(string where)
+        {
+            SqliteCommand cmd = new SqliteCommand();
+
+            string query = String.Format("select * from {0} where {1}",
+                    m_Realm, where);
+
+            cmd.CommandText = query;
+
+            return DoQuery(cmd);
+        }
+
+        public bool Store(T row)
+        {
+            SqliteCommand cmd = new SqliteCommand();
+
+            string query = "";
+            List<String> names = new List<String>();
+            List<String> values = new List<String>();
+
+            foreach (FieldInfo fi in m_Fields.Values)
+            {
+                names.Add(fi.Name);
+                values.Add(":" + fi.Name);
+                cmd.Parameters.Add(new SqliteParameter(":" + fi.Name, fi.GetValue(row).ToString()));
+            }
+
+            if (m_DataField != null)
+            {
+                Dictionary<string, string> data =
+                        (Dictionary<string, string>)m_DataField.GetValue(row);
+
+                foreach (KeyValuePair<string, string> kvp in data)
+                {
+                    names.Add(kvp.Key);
+                    values.Add(":" + kvp.Key);
+                    cmd.Parameters.Add(new SqliteParameter(":" + kvp.Key, kvp.Value));
+                }
+            }
+
+            query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")";
+
+            cmd.CommandText = query;
+
+            if (ExecuteNonQuery(cmd, m_Connection) > 0)
+                return true;
+
+            return false;
+        }
+
+        public bool Delete(string field, string val)
+        {
+            SqliteCommand cmd = new SqliteCommand();
+
+            cmd.CommandText = String.Format("delete from {0} where `{1}` = :{1}", m_Realm, field);
+            cmd.Parameters.Add(new SqliteParameter(field, val));
+
+            if (ExecuteNonQuery(cmd, m_Connection) > 0)
+                return true;
+
+            return false;
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs b/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs
new file mode 100644
index 0000000..a5e0517
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs
@@ -0,0 +1,898 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Reflection;
+using log4net;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Framework;
+
+namespace OpenSim.Data.SQLite
+{
+    /// <summary>
+    /// An Inventory Interface to the SQLite database
+    /// </summary>
+    public class SQLiteInventoryStore : SQLiteUtil, IInventoryDataPlugin
+    {
+        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        private const string invItemsSelect = "select * from inventoryitems";
+        private const string invFoldersSelect = "select * from inventoryfolders";
+
+        private static SqliteConnection conn;
+        private static DataSet ds;
+        private static SqliteDataAdapter invItemsDa;
+        private static SqliteDataAdapter invFoldersDa;
+
+        private static bool m_Initialized = false;
+
+        public void Initialise()
+        {
+            m_log.Info("[SQLiteInventoryData]: " + Name + " cannot be default-initialized!");
+            throw new PluginNotInitialisedException(Name);
+        }
+
+        /// <summary>
+        /// <list type="bullet">
+        /// <item>Initialises Inventory interface</item>
+        /// <item>Loads and initialises a new SQLite connection and maintains it.</item>
+        /// <item>use default URI if connect string string is empty.</item>
+        /// </list>
+        /// </summary>
+        /// <param name="dbconnect">connect string</param>
+        public void Initialise(string dbconnect)
+        {
+            if (!m_Initialized)
+            {
+                m_Initialized = true;
+
+                if (dbconnect == string.Empty)
+                {
+                    dbconnect = "URI=file:inventoryStore.db,version=3";
+                }
+                m_log.Info("[INVENTORY DB]: Sqlite - connecting: " + dbconnect);
+                conn = new SqliteConnection(dbconnect);
+
+                conn.Open();
+
+                Assembly assem = GetType().Assembly;
+                Migration m = new Migration(conn, assem, "InventoryStore");
+                m.Update();
+
+                SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn);
+                invItemsDa = new SqliteDataAdapter(itemsSelectCmd);
+                //            SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa);
+
+                SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn);
+                invFoldersDa = new SqliteDataAdapter(foldersSelectCmd);
+
+                ds = new DataSet();
+
+                ds.Tables.Add(createInventoryFoldersTable());
+                invFoldersDa.Fill(ds.Tables["inventoryfolders"]);
+                setupFoldersCommands(invFoldersDa, conn);
+                m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions");
+
+                ds.Tables.Add(createInventoryItemsTable());
+                invItemsDa.Fill(ds.Tables["inventoryitems"]);
+                setupItemsCommands(invItemsDa, conn);
+                m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions");
+
+                ds.AcceptChanges();
+            }
+        }
+
+        /// <summary>
+        /// Closes the inventory interface
+        /// </summary>
+        public void Dispose()
+        {
+            if (conn != null)
+            {
+                conn.Close();
+                conn = null;
+            }
+            if (invItemsDa != null)
+            {
+                invItemsDa.Dispose();
+                invItemsDa = null;
+            }
+            if (invFoldersDa != null)
+            {
+                invFoldersDa.Dispose();
+                invFoldersDa = null;
+            }
+            if (ds != null)
+            {
+                ds.Dispose();
+                ds = null;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <returns></returns>
+        public InventoryItemBase buildItem(DataRow row)
+        {
+            InventoryItemBase item = new InventoryItemBase();
+            item.ID = new UUID((string) row["UUID"]);
+            item.AssetID = new UUID((string) row["assetID"]);
+            item.AssetType = Convert.ToInt32(row["assetType"]);
+            item.InvType = Convert.ToInt32(row["invType"]);
+            item.Folder = new UUID((string) row["parentFolderID"]);
+            item.Owner = new UUID((string) row["avatarID"]);
+            item.CreatorId = (string)row["creatorsID"];
+            item.Name = (string) row["inventoryName"];
+            item.Description = (string) row["inventoryDescription"];
+
+            item.NextPermissions = Convert.ToUInt32(row["inventoryNextPermissions"]);
+            item.CurrentPermissions = Convert.ToUInt32(row["inventoryCurrentPermissions"]);
+            item.BasePermissions = Convert.ToUInt32(row["inventoryBasePermissions"]);
+            item.EveryOnePermissions = Convert.ToUInt32(row["inventoryEveryOnePermissions"]);
+            item.GroupPermissions = Convert.ToUInt32(row["inventoryGroupPermissions"]);
+
+            // new fields
+            if (!Convert.IsDBNull(row["salePrice"]))
+                item.SalePrice = Convert.ToInt32(row["salePrice"]);
+
+            if (!Convert.IsDBNull(row["saleType"]))
+                item.SaleType = Convert.ToByte(row["saleType"]);
+
+            if (!Convert.IsDBNull(row["creationDate"]))
+                item.CreationDate = Convert.ToInt32(row["creationDate"]);
+
+            if (!Convert.IsDBNull(row["groupID"]))
+                item.GroupID = new UUID((string)row["groupID"]);
+
+            if (!Convert.IsDBNull(row["groupOwned"]))
+                item.GroupOwned = Convert.ToBoolean(row["groupOwned"]);
+
+            if (!Convert.IsDBNull(row["Flags"]))
+                item.Flags = Convert.ToUInt32(row["Flags"]);
+
+            return item;
+        }
+
+        /// <summary>
+        /// Fill a database row with item data
+        /// </summary>
+        /// <param name="row"></param>
+        /// <param name="item"></param>
+        private static void fillItemRow(DataRow row, InventoryItemBase item)
+        {
+            row["UUID"] = item.ID.ToString();
+            row["assetID"] = item.AssetID.ToString();
+            row["assetType"] = item.AssetType;
+            row["invType"] = item.InvType;
+            row["parentFolderID"] = item.Folder.ToString();
+            row["avatarID"] = item.Owner.ToString();
+            row["creatorsID"] = item.CreatorId.ToString();
+            row["inventoryName"] = item.Name;
+            row["inventoryDescription"] = item.Description;
+
+            row["inventoryNextPermissions"] = item.NextPermissions;
+            row["inventoryCurrentPermissions"] = item.CurrentPermissions;
+            row["inventoryBasePermissions"] = item.BasePermissions;
+            row["inventoryEveryOnePermissions"] = item.EveryOnePermissions;
+            row["inventoryGroupPermissions"] = item.GroupPermissions;
+
+            // new fields
+            row["salePrice"] = item.SalePrice;
+            row["saleType"] = item.SaleType;
+            row["creationDate"] = item.CreationDate;
+            row["groupID"] = item.GroupID.ToString();
+            row["groupOwned"] = item.GroupOwned;
+            row["flags"] = item.Flags;
+        }
+
+        /// <summary>
+        /// Add inventory folder
+        /// </summary>
+        /// <param name="folder">Folder base</param>
+        /// <param name="add">true=create folder. false=update existing folder</param>
+        /// <remarks>nasty</remarks>
+        private void addFolder(InventoryFolderBase folder, bool add)
+        {
+            lock (ds)
+            {
+                DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+
+                DataRow inventoryRow = inventoryFolderTable.Rows.Find(folder.ID.ToString());
+                if (inventoryRow == null)
+                {
+                    if (! add)
+                        m_log.ErrorFormat("Interface Misuse: Attempting to Update non-existant inventory folder: {0}", folder.ID);
+
+                    inventoryRow = inventoryFolderTable.NewRow();
+                    fillFolderRow(inventoryRow, folder);
+                    inventoryFolderTable.Rows.Add(inventoryRow);
+                }
+                else
+                {
+                    if (add)
+                        m_log.ErrorFormat("Interface Misuse: Attempting to Add inventory folder that already exists: {0}", folder.ID);
+
+                    fillFolderRow(inventoryRow, folder);
+                }
+
+                invFoldersDa.Update(ds, "inventoryfolders");
+            }
+        }
+
+        /// <summary>
+        /// Move an inventory folder
+        /// </summary>
+        /// <param name="folder">folder base</param>
+        private void moveFolder(InventoryFolderBase folder)
+        {
+            lock (ds)
+            {
+                DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+
+                DataRow inventoryRow = inventoryFolderTable.Rows.Find(folder.ID.ToString());
+                if (inventoryRow == null)
+                {
+                    inventoryRow = inventoryFolderTable.NewRow();
+                    fillFolderRow(inventoryRow, folder);
+                    inventoryFolderTable.Rows.Add(inventoryRow);
+                }
+                else
+                {
+                    moveFolderRow(inventoryRow, folder);
+                }
+
+                invFoldersDa.Update(ds, "inventoryfolders");
+            }
+        }
+
+        /// <summary>
+        /// add an item in inventory
+        /// </summary>
+        /// <param name="item">the item</param>
+        /// <param name="add">true=add item ; false=update existing item</param>
+        private void addItem(InventoryItemBase item, bool add)
+        {
+            lock (ds)
+            {
+                DataTable inventoryItemTable = ds.Tables["inventoryitems"];
+
+                DataRow inventoryRow = inventoryItemTable.Rows.Find(item.ID.ToString());
+                if (inventoryRow == null)
+                {
+                    if (!add)
+                        m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Update non-existant inventory item: {0}", item.ID);
+
+                    inventoryRow = inventoryItemTable.NewRow();
+                    fillItemRow(inventoryRow, item);
+                    inventoryItemTable.Rows.Add(inventoryRow);
+                }
+                else
+                {
+                    if (add)
+                        m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Add inventory item that already exists: {0}", item.ID);
+
+                    fillItemRow(inventoryRow, item);
+                }
+
+                invItemsDa.Update(ds, "inventoryitems");
+
+                DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+
+                inventoryRow = inventoryFolderTable.Rows.Find(item.Folder.ToString());
+                if (inventoryRow != null) //MySQL doesn't throw an exception here, so sqlite shouldn't either.
+                    inventoryRow["version"] = (int)inventoryRow["version"] + 1;
+
+                invFoldersDa.Update(ds, "inventoryfolders");
+            }
+        }
+
+        /// <summary>
+        /// TODO : DataSet commit
+        /// </summary>
+        public void Shutdown()
+        {
+            // TODO: DataSet commit
+        }
+
+        /// <summary>
+        /// The name of this DB provider
+        /// </summary>
+        /// <returns>Name of DB provider</returns>
+        public string Name
+        {
+            get { return "SQLite Inventory Data Interface"; }
+        }
+
+        /// <summary>
+        /// Returns the version of this DB provider
+        /// </summary>
+        /// <returns>A string containing the DB provider version</returns>
+        public string Version
+        {
+            get
+            {
+                Module module = GetType().Module;
+                // string dllName = module.Assembly.ManifestModule.Name;
+                Version dllVersion = module.Assembly.GetName().Version;
+
+
+                return
+                    string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
+                            dllVersion.Revision);
+            }
+        }
+
+        /// <summary>
+        /// Returns a list of inventory items contained within the specified folder
+        /// </summary>
+        /// <param name="folderID">The UUID of the target folder</param>
+        /// <returns>A List of InventoryItemBase items</returns>
+        public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
+        {
+            lock (ds)
+            {
+                List<InventoryItemBase> retval = new List<InventoryItemBase>();
+                DataTable inventoryItemTable = ds.Tables["inventoryitems"];
+                string selectExp = "parentFolderID = '" + folderID + "'";
+                DataRow[] rows = inventoryItemTable.Select(selectExp);
+                foreach (DataRow row in rows)
+                {
+                    retval.Add(buildItem(row));
+                }
+
+                return retval;
+            }
+        }
+
+        /// <summary>
+        /// Returns a list of the root folders within a users inventory
+        /// </summary>
+        /// <param name="user">The user whos inventory is to be searched</param>
+        /// <returns>A list of folder objects</returns>
+        public List<InventoryFolderBase> getUserRootFolders(UUID user)
+        {
+            return new List<InventoryFolderBase>();
+        }
+
+        // see InventoryItemBase.getUserRootFolder
+        public InventoryFolderBase getUserRootFolder(UUID user)
+        {
+            lock (ds)
+            {
+                List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
+                DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+                string selectExp = "agentID = '" + user + "' AND parentID = '" + UUID.Zero + "'";
+                DataRow[] rows = inventoryFolderTable.Select(selectExp);
+                foreach (DataRow row in rows)
+                {
+                    folders.Add(buildFolder(row));
+                }
+
+                // There should only ever be one root folder for a user.  However, if there's more
+                // than one we'll simply use the first one rather than failing.  It would be even
+                // nicer to print some message to this effect, but this feels like it's too low a
+                // to put such a message out, and it's too minor right now to spare the time to
+                // suitably refactor.
+                if (folders.Count > 0)
+                {
+                    return folders[0];
+                }
+
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// Append a list of all the child folders of a parent folder
+        /// </summary>
+        /// <param name="folders">list where folders will be appended</param>
+        /// <param name="parentID">ID of parent</param>
+        protected void getInventoryFolders(ref List<InventoryFolderBase> folders, UUID parentID)
+        {
+            lock (ds)
+            {
+                DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+                string selectExp = "parentID = '" + parentID + "'";
+                DataRow[] rows = inventoryFolderTable.Select(selectExp);
+                foreach (DataRow row in rows)
+                {
+                    folders.Add(buildFolder(row));
+                }
+
+            }
+        }
+
+        /// <summary>
+        /// Returns a list of inventory folders contained in the folder 'parentID'
+        /// </summary>
+        /// <param name="parentID">The folder to get subfolders for</param>
+        /// <returns>A list of inventory folders</returns>
+        public List<InventoryFolderBase> getInventoryFolders(UUID parentID)
+        {
+            List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
+            getInventoryFolders(ref folders, parentID);
+            return folders;
+        }
+
+        /// <summary>
+        /// See IInventoryDataPlugin
+        /// </summary>
+        /// <param name="parentID"></param>
+        /// <returns></returns>
+        public List<InventoryFolderBase> getFolderHierarchy(UUID parentID)
+        {
+            /* Note: There are subtle changes between this implementation of getFolderHierarchy and the previous one
+                 * - We will only need to hit the database twice instead of n times.
+                 * - We assume the database is well-formed - no stranded/dangling folders, all folders in heirarchy owned
+                 *   by the same person, each user only has 1 inventory heirarchy
+                 * - The returned list is not ordered, instead of breadth-first ordered
+               There are basically 2 usage cases for getFolderHeirarchy:
+                 1) Getting the user's entire inventory heirarchy when they log in
+                 2) Finding a subfolder heirarchy to delete when emptying the trash.
+               This implementation will pull all inventory folders from the database, and then prune away any folder that
+               is not part of the requested sub-heirarchy. The theory is that it is cheaper to make 1 request from the
+               database than to make n requests. This pays off only if requested heirarchy is large.
+               By making this choice, we are making the worst case better at the cost of making the best case worse
+                 - Francis
+             */
+
+            List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
+            DataRow[] folderRows = null, parentRow;
+            InventoryFolderBase parentFolder = null;
+            lock (ds)
+            {
+                /* Fetch the parent folder from the database to determine the agent ID.
+                 * Then fetch all inventory folders for that agent from the agent ID.
+                 */
+                DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+                string selectExp = "UUID = '" + parentID + "'";
+                parentRow = inventoryFolderTable.Select(selectExp); // Assume at most 1 result
+                if (parentRow.GetLength(0) >= 1)                    // No result means parent folder does not exist
+                {
+                    parentFolder = buildFolder(parentRow[0]);
+                    UUID agentID = parentFolder.Owner;
+                    selectExp = "agentID = '" + agentID + "'";
+                    folderRows = inventoryFolderTable.Select(selectExp);
+                }
+
+                if (folderRows != null && folderRows.GetLength(0) >= 1)   // No result means parent folder does not exist
+                {                                                       // or has no children
+                    /* if we're querying the root folder, just return an unordered list of all folders in the user's
+                     * inventory
+                     */
+                    if (parentFolder.ParentID == UUID.Zero)
+                    {
+                        foreach (DataRow row in folderRows)
+                        {
+                            InventoryFolderBase curFolder = buildFolder(row);
+                            if (curFolder.ID != parentID)   // Return all folders except the parent folder of heirarchy
+                                folders.Add(buildFolder(row));
+                        }
+                    } // If requesting root folder
+                    /* else we are querying a non-root folder. We currently have a list of all of the user's folders,
+                     * we must construct a list of all folders in the heirarchy below parentID.
+                     * Our first step will be to construct a hash table of all folders, indexed by parent ID.
+                     * Once we have constructed the hash table, we will do a breadth-first traversal on the tree using the
+                     * hash table to find child folders.
+                     */
+                    else
+                    {                                                         // Querying a non-root folder
+
+                        // Build a hash table of all user's inventory folders, indexed by each folder's parent ID
+                        Dictionary<UUID, List<InventoryFolderBase>> hashtable =
+                            new Dictionary<UUID, List<InventoryFolderBase>>(folderRows.GetLength(0));
+
+                        foreach (DataRow row in folderRows)
+                        {
+                            InventoryFolderBase curFolder = buildFolder(row);
+                            if (curFolder.ParentID != UUID.Zero) // Discard root of tree - not needed
+                            {
+                                if (hashtable.ContainsKey(curFolder.ParentID))
+                                {
+                                    // Current folder already has a sibling - append to sibling list
+                                    hashtable[curFolder.ParentID].Add(curFolder);
+                                }
+                                else
+                                {
+                                    List<InventoryFolderBase> siblingList = new List<InventoryFolderBase>();
+                                    siblingList.Add(curFolder);
+                                    // Current folder has no known (yet) siblings
+                                    hashtable.Add(curFolder.ParentID, siblingList);
+                                }
+                            }
+                        } // For all inventory folders
+
+                        // Note: Could release the ds lock here - we don't access folderRows or the database anymore.
+                        // This is somewhat of a moot point as the callers of this function usually lock db anyways.
+
+                        if (hashtable.ContainsKey(parentID)) // if requested folder does have children
+                            folders.AddRange(hashtable[parentID]);
+
+                        // BreadthFirstSearch build inventory tree **Note: folders.Count is *not* static
+                        for (int i = 0; i < folders.Count; i++)
+                            if (hashtable.ContainsKey(folders[i].ID))
+                                folders.AddRange(hashtable[folders[i].ID]);
+
+                    } // if requesting a subfolder heirarchy
+                } // if folder parentID exists and has children
+            } // lock ds
+            return folders;
+        }
+
+        /// <summary>
+        /// Returns an inventory item by its UUID
+        /// </summary>
+        /// <param name="item">The UUID of the item to be returned</param>
+        /// <returns>A class containing item information</returns>
+        public InventoryItemBase getInventoryItem(UUID item)
+        {
+            lock (ds)
+            {
+                DataRow row = ds.Tables["inventoryitems"].Rows.Find(item.ToString());
+                if (row != null)
+                {
+                    return buildItem(row);
+                }
+                else
+                {
+                    return null;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Returns a specified inventory folder by its UUID
+        /// </summary>
+        /// <param name="folder">The UUID of the folder to be returned</param>
+        /// <returns>A class containing folder information</returns>
+        public InventoryFolderBase getInventoryFolder(UUID folder)
+        {
+            // TODO: Deep voodoo here.  If you enable this code then
+            // multi region breaks.  No idea why, but I figured it was
+            // better to leave multi region at this point.  It does mean
+            // that you don't get to see system textures why creating
+            // clothes and the like. :(
+            lock (ds)
+            {
+                DataRow row = ds.Tables["inventoryfolders"].Rows.Find(folder.ToString());
+                if (row != null)
+                {
+                    return buildFolder(row);
+                }
+                else
+                {
+                    return null;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Creates a new inventory item based on item
+        /// </summary>
+        /// <param name="item">The item to be created</param>
+        public void addInventoryItem(InventoryItemBase item)
+        {
+            addItem(item, true);
+        }
+
+        /// <summary>
+        /// Updates an inventory item with item (updates based on ID)
+        /// </summary>
+        /// <param name="item">The updated item</param>
+        public void updateInventoryItem(InventoryItemBase item)
+        {
+            addItem(item, false);
+        }
+
+        /// <summary>
+        /// Delete an inventory item
+        /// </summary>
+        /// <param name="item">The item UUID</param>
+        public void deleteInventoryItem(UUID itemID)
+        {
+            lock (ds)
+            {
+                DataTable inventoryItemTable = ds.Tables["inventoryitems"];
+
+                DataRow inventoryRow = inventoryItemTable.Rows.Find(itemID.ToString());
+                if (inventoryRow != null)
+                {
+                    inventoryRow.Delete();
+                }
+
+                invItemsDa.Update(ds, "inventoryitems");
+            }
+        }
+
+        public InventoryItemBase queryInventoryItem(UUID itemID)
+        {
+            return getInventoryItem(itemID);
+        }
+
+        public InventoryFolderBase queryInventoryFolder(UUID folderID)
+        {
+            return getInventoryFolder(folderID);
+        }
+
+        /// <summary>
+        /// Delete all items in the specified folder
+        /// </summary>
+        /// <param name="folderId">id of the folder, whose item content should be deleted</param>
+        /// <todo>this is horribly inefficient, but I don't want to ruin the overall structure of this implementation</todo>
+        private void deleteItemsInFolder(UUID folderId)
+        {
+            List<InventoryItemBase> items = getInventoryInFolder(folderId);
+
+            foreach (InventoryItemBase i in items)
+                deleteInventoryItem(i.ID);
+        }
+
+        /// <summary>
+        /// Adds a new folder specified by folder
+        /// </summary>
+        /// <param name="folder">The inventory folder</param>
+        public void addInventoryFolder(InventoryFolderBase folder)
+        {
+            addFolder(folder, true);
+        }
+
+        /// <summary>
+        /// Updates a folder based on its ID with folder
+        /// </summary>
+        /// <param name="folder">The inventory folder</param>
+        public void updateInventoryFolder(InventoryFolderBase folder)
+        {
+            addFolder(folder, false);
+        }
+
+        /// <summary>
+        /// Moves a folder based on its ID with folder
+        /// </summary>
+        /// <param name="folder">The inventory folder</param>
+        public void moveInventoryFolder(InventoryFolderBase folder)
+        {
+            moveFolder(folder);
+        }
+
+        /// <summary>
+        /// Delete a folder
+        /// </summary>
+        /// <remarks>
+        /// This will clean-up any child folders and child items as well
+        /// </remarks>
+        /// <param name="folderID">the folder UUID</param>
+        public void deleteInventoryFolder(UUID folderID)
+        {
+            lock (ds)
+            {
+                List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID);
+
+                DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+                DataRow inventoryRow;
+
+                //Delete all sub-folders
+                foreach (InventoryFolderBase f in subFolders)
+                {
+                    inventoryRow = inventoryFolderTable.Rows.Find(f.ID.ToString());
+                    if (inventoryRow != null)
+                    {
+                        deleteItemsInFolder(f.ID);
+                        inventoryRow.Delete();
+                    }
+                }
+
+                //Delete the actual row
+                inventoryRow = inventoryFolderTable.Rows.Find(folderID.ToString());
+                if (inventoryRow != null)
+                {
+                    deleteItemsInFolder(folderID);
+                    inventoryRow.Delete();
+                }
+
+                invFoldersDa.Update(ds, "inventoryfolders");
+            }
+        }
+
+        /***********************************************************************
+         *
+         *  Data Table definitions
+         *
+         **********************************************************************/
+
+        /// <summary>
+        /// Create the "inventoryitems" table
+        /// </summary>
+        private static DataTable createInventoryItemsTable()
+        {
+            DataTable inv = new DataTable("inventoryitems");
+
+            createCol(inv, "UUID", typeof (String)); //inventoryID
+            createCol(inv, "assetID", typeof (String));
+            createCol(inv, "assetType", typeof (Int32));
+            createCol(inv, "invType", typeof (Int32));
+            createCol(inv, "parentFolderID", typeof (String));
+            createCol(inv, "avatarID", typeof (String));
+            createCol(inv, "creatorsID", typeof (String));
+
+            createCol(inv, "inventoryName", typeof (String));
+            createCol(inv, "inventoryDescription", typeof (String));
+            // permissions
+            createCol(inv, "inventoryNextPermissions", typeof (Int32));
+            createCol(inv, "inventoryCurrentPermissions", typeof (Int32));
+            createCol(inv, "inventoryBasePermissions", typeof (Int32));
+            createCol(inv, "inventoryEveryOnePermissions", typeof (Int32));
+            createCol(inv, "inventoryGroupPermissions", typeof (Int32));
+
+            // sale info
+            createCol(inv, "salePrice", typeof(Int32));
+            createCol(inv, "saleType", typeof(Byte));
+
+            // creation date
+            createCol(inv, "creationDate", typeof(Int32));
+
+            // group info
+            createCol(inv, "groupID", typeof(String));
+            createCol(inv, "groupOwned", typeof(Boolean));
+
+            // Flags
+            createCol(inv, "flags", typeof(UInt32));
+
+            inv.PrimaryKey = new DataColumn[] { inv.Columns["UUID"] };
+            return inv;
+        }
+
+        /// <summary>
+        /// Creates the "inventoryfolders" table
+        /// </summary>
+        /// <returns></returns>
+        private static DataTable createInventoryFoldersTable()
+        {
+            DataTable fol = new DataTable("inventoryfolders");
+
+            createCol(fol, "UUID", typeof (String)); //folderID
+            createCol(fol, "name", typeof (String));
+            createCol(fol, "agentID", typeof (String));
+            createCol(fol, "parentID", typeof (String));
+            createCol(fol, "type", typeof (Int32));
+            createCol(fol, "version", typeof (Int32));
+
+            fol.PrimaryKey = new DataColumn[] {fol.Columns["UUID"]};
+            return fol;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="da"></param>
+        /// <param name="conn"></param>
+        private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn)
+        {
+            lock (ds)
+            {
+                da.InsertCommand = createInsertCommand("inventoryitems", ds.Tables["inventoryitems"]);
+                da.InsertCommand.Connection = conn;
+
+                da.UpdateCommand = createUpdateCommand("inventoryitems", "UUID=:UUID", ds.Tables["inventoryitems"]);
+                da.UpdateCommand.Connection = conn;
+
+                SqliteCommand delete = new SqliteCommand("delete from inventoryitems where UUID = :UUID");
+                delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
+                delete.Connection = conn;
+                da.DeleteCommand = delete;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="da"></param>
+        /// <param name="conn"></param>
+        private void setupFoldersCommands(SqliteDataAdapter da, SqliteConnection conn)
+        {
+            lock (ds)
+            {
+                da.InsertCommand = createInsertCommand("inventoryfolders", ds.Tables["inventoryfolders"]);
+                da.InsertCommand.Connection = conn;
+
+                da.UpdateCommand = createUpdateCommand("inventoryfolders", "UUID=:UUID", ds.Tables["inventoryfolders"]);
+                da.UpdateCommand.Connection = conn;
+
+                SqliteCommand delete = new SqliteCommand("delete from inventoryfolders where UUID = :UUID");
+                delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
+                delete.Connection = conn;
+                da.DeleteCommand = delete;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <returns></returns>
+        private static InventoryFolderBase buildFolder(DataRow row)
+        {
+            InventoryFolderBase folder = new InventoryFolderBase();
+            folder.ID = new UUID((string) row["UUID"]);
+            folder.Name = (string) row["name"];
+            folder.Owner = new UUID((string) row["agentID"]);
+            folder.ParentID = new UUID((string) row["parentID"]);
+            folder.Type = Convert.ToInt16(row["type"]);
+            folder.Version = Convert.ToUInt16(row["version"]);
+            return folder;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <param name="folder"></param>
+        private static void fillFolderRow(DataRow row, InventoryFolderBase folder)
+        {
+            row["UUID"] = folder.ID.ToString();
+            row["name"] = folder.Name;
+            row["agentID"] = folder.Owner.ToString();
+            row["parentID"] = folder.ParentID.ToString();
+            row["type"] = folder.Type;
+            row["version"] = folder.Version;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <param name="folder"></param>
+        private static void moveFolderRow(DataRow row, InventoryFolderBase folder)
+        {
+            row["UUID"] = folder.ID.ToString();
+            row["parentID"] = folder.ParentID.ToString();
+        }
+
+        public List<InventoryItemBase> fetchActiveGestures (UUID avatarID)
+        {
+            lock (ds)
+            {
+                List<InventoryItemBase> items = new List<InventoryItemBase>();
+
+                DataTable inventoryItemTable = ds.Tables["inventoryitems"];
+                string selectExp 
+                    = "avatarID = '" + avatarID + "' AND assetType = " + (int)AssetType.Gesture + " AND flags = 1";
+                //m_log.DebugFormat("[SQL]: sql = " + selectExp);
+                DataRow[] rows = inventoryItemTable.Select(selectExp);
+                foreach (DataRow row in rows)
+                {
+                    items.Add(buildItem(row));
+                }
+                return items;
+            }
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs
new file mode 100644
index 0000000..d2ba9ae
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs
@@ -0,0 +1,2264 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Drawing;
+using System.IO;
+using System.Reflection;
+using log4net;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Data.SQLite
+{
+    /// <summary>
+    /// A RegionData Interface to the SQLite database
+    /// </summary>
+    public class SQLiteRegionData : IRegionDataStore
+    {
+        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        private const string primSelect = "select * from prims";
+        private const string shapeSelect = "select * from primshapes";
+        private const string itemsSelect = "select * from primitems";
+        private const string terrainSelect = "select * from terrain limit 1";
+        private const string landSelect = "select * from land";
+        private const string landAccessListSelect = "select distinct * from landaccesslist";
+        private const string regionbanListSelect = "select * from regionban";
+        private const string regionSettingsSelect = "select * from regionsettings";
+
+        private DataSet ds;
+        private SqliteDataAdapter primDa;
+        private SqliteDataAdapter shapeDa;
+        private SqliteDataAdapter itemsDa;
+        private SqliteDataAdapter terrainDa;
+        private SqliteDataAdapter landDa;
+        private SqliteDataAdapter landAccessListDa;
+        private SqliteDataAdapter regionSettingsDa;
+
+        private SqliteConnection m_conn;
+
+        private String m_connectionString;
+
+        // Temporary attribute while this is experimental
+
+        /***********************************************************************
+         *
+         *  Public Interface Functions
+         *
+         **********************************************************************/
+
+        /// <summary>
+        /// See IRegionDataStore
+        /// <list type="bullet">
+        /// <item>Initialises RegionData Interface</item>
+        /// <item>Loads and initialises a new SQLite connection and maintains it.</item>
+        /// </list>
+        /// </summary>
+        /// <param name="connectionString">the connection string</param>
+        public void Initialise(string connectionString)
+        {
+            m_connectionString = connectionString;
+
+            ds = new DataSet();
+
+            m_log.Info("[REGION DB]: Sqlite - connecting: " + connectionString);
+            m_conn = new SqliteConnection(m_connectionString);
+            m_conn.Open();
+
+
+
+            SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn);
+            primDa = new SqliteDataAdapter(primSelectCmd);
+            //            SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa);
+
+            SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, m_conn);
+            shapeDa = new SqliteDataAdapter(shapeSelectCmd);
+            // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa);
+
+            SqliteCommand itemsSelectCmd = new SqliteCommand(itemsSelect, m_conn);
+            itemsDa = new SqliteDataAdapter(itemsSelectCmd);
+
+            SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, m_conn);
+            terrainDa = new SqliteDataAdapter(terrainSelectCmd);
+
+            SqliteCommand landSelectCmd = new SqliteCommand(landSelect, m_conn);
+            landDa = new SqliteDataAdapter(landSelectCmd);
+
+            SqliteCommand landAccessListSelectCmd = new SqliteCommand(landAccessListSelect, m_conn);
+            landAccessListDa = new SqliteDataAdapter(landAccessListSelectCmd);
+
+            SqliteCommand regionSettingsSelectCmd = new SqliteCommand(regionSettingsSelect, m_conn);
+            regionSettingsDa = new SqliteDataAdapter(regionSettingsSelectCmd);
+            // This actually does the roll forward assembly stuff
+            Assembly assem = GetType().Assembly;
+            Migration m = new Migration(m_conn, assem, "RegionStore");
+            m.Update();
+
+            lock (ds)
+            {
+                ds.Tables.Add(createPrimTable());
+                setupPrimCommands(primDa, m_conn);
+                primDa.Fill(ds.Tables["prims"]);
+
+                ds.Tables.Add(createShapeTable());
+                setupShapeCommands(shapeDa, m_conn);
+
+                ds.Tables.Add(createItemsTable());
+                setupItemsCommands(itemsDa, m_conn);
+                itemsDa.Fill(ds.Tables["primitems"]);
+
+                ds.Tables.Add(createTerrainTable());
+                setupTerrainCommands(terrainDa, m_conn);
+
+                ds.Tables.Add(createLandTable());
+                setupLandCommands(landDa, m_conn);
+
+                ds.Tables.Add(createLandAccessListTable());
+                setupLandAccessCommands(landAccessListDa, m_conn);
+
+                ds.Tables.Add(createRegionSettingsTable());
+                
+                setupRegionSettingsCommands(regionSettingsDa, m_conn);
+
+                // WORKAROUND: This is a work around for sqlite on
+                // windows, which gets really unhappy with blob columns
+                // that have no sample data in them.  At some point we
+                // need to actually find a proper way to handle this.
+                try
+                {
+                    shapeDa.Fill(ds.Tables["primshapes"]);
+                }
+                catch (Exception)
+                {
+                    m_log.Info("[REGION DB]: Caught fill error on primshapes table");
+                }
+
+                try
+                {
+                    terrainDa.Fill(ds.Tables["terrain"]);
+                }
+                catch (Exception)
+                {
+                    m_log.Info("[REGION DB]: Caught fill error on terrain table");
+                }
+
+                try
+                {
+                    landDa.Fill(ds.Tables["land"]);
+                }
+                catch (Exception)
+                {
+                    m_log.Info("[REGION DB]: Caught fill error on land table");
+                }
+
+                try
+                {
+                    landAccessListDa.Fill(ds.Tables["landaccesslist"]);
+                }
+                catch (Exception)
+                {
+                    m_log.Info("[REGION DB]: Caught fill error on landaccesslist table");
+                }
+
+                try
+                {
+                    regionSettingsDa.Fill(ds.Tables["regionsettings"]);
+                }
+                catch (Exception)
+                {
+                    m_log.Info("[REGION DB]: Caught fill error on regionsettings table");
+                }
+                return;
+            }
+        }
+
+        public void Dispose()
+        {
+            if (m_conn != null)
+            {
+                m_conn.Close();
+                m_conn = null;
+            }
+            if (ds != null)
+            {
+                ds.Dispose();
+                ds = null;
+            }
+            if (primDa != null)
+            {
+                primDa.Dispose();
+                primDa = null;
+            }
+            if (shapeDa != null)
+            {
+                shapeDa.Dispose();
+                shapeDa = null;
+            }
+            if (itemsDa != null)
+            {
+                itemsDa.Dispose();
+                itemsDa = null;
+            }
+            if (terrainDa != null)
+            {
+                terrainDa.Dispose();
+                terrainDa = null;
+            }
+            if (landDa != null)
+            {
+                landDa.Dispose();
+                landDa = null;
+            }
+            if (landAccessListDa != null)
+            {
+                landAccessListDa.Dispose();
+                landAccessListDa = null;
+            }
+            if (regionSettingsDa != null)
+            {
+                regionSettingsDa.Dispose();
+                regionSettingsDa = null;
+            }
+        }
+
+        public void StoreRegionSettings(RegionSettings rs)
+        {
+            lock (ds)
+            {
+                DataTable regionsettings = ds.Tables["regionsettings"];
+
+                DataRow settingsRow = regionsettings.Rows.Find(rs.RegionUUID.ToString());
+                if (settingsRow == null)
+                {
+                    settingsRow = regionsettings.NewRow();
+                    fillRegionSettingsRow(settingsRow, rs);
+                    regionsettings.Rows.Add(settingsRow);
+                }
+                else
+                {
+                    fillRegionSettingsRow(settingsRow, rs);
+                }
+
+                Commit();
+            }
+        }
+        public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
+        {
+            //This connector doesn't support the windlight module yet
+            //Return default LL windlight settings
+            return new RegionLightShareData();
+        }
+        public void StoreRegionWindlightSettings(RegionLightShareData wl)
+        {
+            //This connector doesn't support the windlight module yet
+        }
+        public RegionSettings LoadRegionSettings(UUID regionUUID)
+        {
+            lock (ds)
+            {
+                DataTable regionsettings = ds.Tables["regionsettings"];
+
+                string searchExp = "regionUUID = '" + regionUUID.ToString() + "'";
+                DataRow[] rawsettings = regionsettings.Select(searchExp);
+                if (rawsettings.Length == 0)
+                {
+                    RegionSettings rs = new RegionSettings();
+                    rs.RegionUUID = regionUUID;
+                    rs.OnSave += StoreRegionSettings;
+
+                    StoreRegionSettings(rs);
+
+                    return rs;
+                }
+                DataRow row = rawsettings[0];
+
+                RegionSettings newSettings = buildRegionSettings(row);
+                newSettings.OnSave += StoreRegionSettings;
+
+                return newSettings;
+            }
+        }
+
+        /// <summary>
+        /// Adds an object into region storage
+        /// </summary>
+        /// <param name="obj">the object</param>
+        /// <param name="regionUUID">the region UUID</param>
+        public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
+        {
+            uint flags = obj.RootPart.GetEffectiveObjectFlags();
+
+            // Eligibility check
+            //
+            if ((flags & (uint)PrimFlags.Temporary) != 0)
+                return;
+            if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
+                return;
+
+            lock (ds)
+            {
+                foreach (SceneObjectPart prim in obj.Children.Values)
+                {
+//                    m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
+                    addPrim(prim, obj.UUID, regionUUID);
+                }
+            }
+
+            Commit();
+            // m_log.Info("[Dump of prims]: " + ds.GetXml());
+        }
+
+        /// <summary>
+        /// Removes an object from region storage
+        /// </summary>
+        /// <param name="obj">the object</param>
+        /// <param name="regionUUID">the region UUID</param>
+        public void RemoveObject(UUID obj, UUID regionUUID)
+        {
+            // m_log.InfoFormat("[REGION DB]: Removing obj: {0} from region: {1}", obj.Guid, regionUUID);
+
+            DataTable prims = ds.Tables["prims"];
+            DataTable shapes = ds.Tables["primshapes"];
+
+            string selectExp = "SceneGroupID = '" + obj + "' and RegionUUID = '" + regionUUID + "'";
+            lock (ds)
+            {
+                DataRow[] primRows = prims.Select(selectExp);
+                foreach (DataRow row in primRows)
+                {
+                    // Remove shape rows
+                    UUID uuid = new UUID((string) row["UUID"]);
+                    DataRow shapeRow = shapes.Rows.Find(uuid.ToString());
+                    if (shapeRow != null)
+                    {
+                        shapeRow.Delete();
+                    }
+
+                    RemoveItems(uuid);
+
+                    // Remove prim row
+                    row.Delete();
+                }
+            }
+
+            Commit();
+        }
+
+        /// <summary>
+        /// Remove all persisted items of the given prim.
+        /// The caller must acquire the necessrary synchronization locks and commit or rollback changes.
+        /// </summary>
+        /// <param name="uuid">The item UUID</param>
+        private void RemoveItems(UUID uuid)
+        {
+            DataTable items = ds.Tables["primitems"];
+
+            String sql = String.Format("primID = '{0}'", uuid);
+            DataRow[] itemRows = items.Select(sql);
+
+            foreach (DataRow itemRow in itemRows)
+            {
+                itemRow.Delete();
+            }
+        }
+
+        /// <summary>
+        /// Load persisted objects from region storage.
+        /// </summary>
+        /// <param name="regionUUID">The region UUID</param>
+        /// <returns>List of loaded groups</returns>
+        public List<SceneObjectGroup> LoadObjects(UUID regionUUID)
+        {
+            Dictionary<UUID, SceneObjectGroup> createdObjects = new Dictionary<UUID, SceneObjectGroup>();
+
+            List<SceneObjectGroup> retvals = new List<SceneObjectGroup>();
+
+            DataTable prims = ds.Tables["prims"];
+            DataTable shapes = ds.Tables["primshapes"];
+
+            string byRegion = "RegionUUID = '" + regionUUID + "'";
+
+            lock (ds)
+            {
+                DataRow[] primsForRegion = prims.Select(byRegion);
+                m_log.Info("[REGION DB]: Loaded " + primsForRegion.Length + " prims for region: " + regionUUID);
+                
+                // First, create all groups 
+                foreach (DataRow primRow in primsForRegion)
+                {
+                    try
+                    {
+                        SceneObjectPart prim = null;
+
+                        string uuid = (string) primRow["UUID"];
+                        string objID = (string) primRow["SceneGroupID"];
+                        
+                        if (uuid == objID) //is new SceneObjectGroup ?
+                        {
+                            prim = buildPrim(primRow);
+                            DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
+                            if (shapeRow != null)
+                            {
+                                prim.Shape = buildShape(shapeRow);
+                            }
+                            else
+                            {
+                                m_log.Info(
+                                    "[REGION DB]: No shape found for prim in storage, so setting default box shape");
+                                prim.Shape = PrimitiveBaseShape.Default;
+                            }
+                            
+                            SceneObjectGroup group = new SceneObjectGroup(prim);
+                            createdObjects.Add(group.UUID, group);
+                            retvals.Add(group);
+                            LoadItems(prim);
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        m_log.Error("[REGION DB]: Failed create prim object in new group, exception and data follows");
+                        m_log.Info("[REGION DB]: " + e.ToString());
+                        foreach (DataColumn col in prims.Columns)
+                        {
+                            m_log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]);
+                        }
+                    }
+                }
+                
+                // Now fill the groups with part data
+                foreach (DataRow primRow in primsForRegion)
+                {
+                    try
+                    {
+                        SceneObjectPart prim = null;
+
+                        string uuid = (string) primRow["UUID"];
+                        string objID = (string) primRow["SceneGroupID"];
+                        if (uuid != objID) //is new SceneObjectGroup ?
+                        {
+                            prim = buildPrim(primRow);
+                            DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
+                            if (shapeRow != null)
+                            {
+                                prim.Shape = buildShape(shapeRow);
+                            }
+                            else
+                            {
+                                m_log.Warn(
+                                    "[REGION DB]: No shape found for prim in storage, so setting default box shape");
+                                prim.Shape = PrimitiveBaseShape.Default;
+                            }
+                            
+                            createdObjects[new UUID(objID)].AddPart(prim);
+                            LoadItems(prim);
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        m_log.Error("[REGION DB]: Failed create prim object in group, exception and data follows");
+                        m_log.Info("[REGION DB]: " + e.ToString());
+                        foreach (DataColumn col in prims.Columns)
+                        {
+                            m_log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]);
+                        }
+                    }
+                }
+            }
+            return retvals;
+        }
+
+        /// <summary>
+        /// Load in a prim's persisted inventory.
+        /// </summary>
+        /// <param name="prim">the prim</param>
+        private void LoadItems(SceneObjectPart prim)
+        {
+            //m_log.DebugFormat("[DATASTORE]: Loading inventory for {0}, {1}", prim.Name, prim.UUID);
+    
+            DataTable dbItems = ds.Tables["primitems"];
+            String sql = String.Format("primID = '{0}'", prim.UUID.ToString());
+            DataRow[] dbItemRows = dbItems.Select(sql);
+            IList<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
+
+            foreach (DataRow row in dbItemRows)
+            {
+                TaskInventoryItem item = buildItem(row);
+                inventory.Add(item);
+
+                //m_log.DebugFormat("[DATASTORE]: Restored item {0}, {1}", item.Name, item.ItemID);
+            }
+
+            prim.Inventory.RestoreInventoryItems(inventory);
+        }
+
+        /// <summary>
+        /// Store a terrain revision in region storage
+        /// </summary>
+        /// <param name="ter">terrain heightfield</param>
+        /// <param name="regionID">region UUID</param>
+        public void StoreTerrain(double[,] ter, UUID regionID)
+        {
+            lock (ds)
+            {
+                int revision = Util.UnixTimeSinceEpoch();
+
+                // This is added to get rid of the infinitely growing
+                // terrain databases which negatively impact on SQLite
+                // over time.  Before reenabling this feature there
+                // needs to be a limitter put on the number of
+                // revisions in the database, as this old
+                // implementation is a DOS attack waiting to happen.
+
+                using (
+                    SqliteCommand cmd =
+                        new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID and Revision <= :Revision",
+                                          m_conn))
+                {
+                    cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
+                    cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
+                    cmd.ExecuteNonQuery();
+                }
+
+                // the following is an work around for .NET.  The perf
+                // issues associated with it aren't as bad as you think.
+                m_log.Info("[REGION DB]: Storing terrain revision r" + revision.ToString());
+                String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" +
+                             " values(:RegionUUID, :Revision, :Heightfield)";
+
+                using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
+                {
+                    cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
+                    cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
+                    cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter)));
+                    cmd.ExecuteNonQuery();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Load the latest terrain revision from region storage
+        /// </summary>
+        /// <param name="regionID">the region UUID</param>
+        /// <returns>Heightfield data</returns>
+        public double[,] LoadTerrain(UUID regionID)
+        {
+            lock (ds)
+            {
+                double[,] terret = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
+                terret.Initialize();
+
+                String sql = "select RegionUUID, Revision, Heightfield from terrain" +
+                             " where RegionUUID=:RegionUUID order by Revision desc";
+
+                using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
+                {
+                    cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
+
+                    using (IDataReader row = cmd.ExecuteReader())
+                    {
+                        int rev = 0;
+                        if (row.Read())
+                        {
+                            // TODO: put this into a function
+                            using (MemoryStream str = new MemoryStream((byte[])row["Heightfield"]))
+                            {
+                                using (BinaryReader br = new BinaryReader(str))
+                                {
+                                    for (int x = 0; x < (int)Constants.RegionSize; x++)
+                                    {
+                                        for (int y = 0; y < (int)Constants.RegionSize; y++)
+                                        {
+                                            terret[x, y] = br.ReadDouble();
+                                        }
+                                    }
+                                }
+                            }
+                            rev = (int) row["Revision"];
+                        }
+                        else
+                        {
+                            m_log.Info("[REGION DB]: No terrain found for region");
+                            return null;
+                        }
+
+                        m_log.Info("[REGION DB]: Loaded terrain revision r" + rev.ToString());
+                    }
+                }
+                return terret;
+            }
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="globalID"></param>
+        public void RemoveLandObject(UUID globalID)
+        {
+            lock (ds)
+            {
+                // Can't use blanket SQL statements when using SqlAdapters unless you re-read the data into the adapter
+                // after you're done.
+                // replaced below code with the SqliteAdapter version.
+                //using (SqliteCommand cmd = new SqliteCommand("delete from land where UUID=:UUID", m_conn))
+                //{
+                //    cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString()));
+                //    cmd.ExecuteNonQuery();
+                //}
+
+                //using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:UUID", m_conn))
+                //{
+                //   cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString()));
+                //    cmd.ExecuteNonQuery();
+                //}
+
+                DataTable land = ds.Tables["land"];
+                DataTable landaccesslist = ds.Tables["landaccesslist"];
+                DataRow landRow = land.Rows.Find(globalID.ToString());
+                if (landRow != null)
+                {
+                    land.Rows.Remove(landRow);
+                }
+                List<DataRow> rowsToDelete = new List<DataRow>();
+                foreach (DataRow rowToCheck in landaccesslist.Rows)
+                {
+                    if (rowToCheck["LandUUID"].ToString() == globalID.ToString())
+                        rowsToDelete.Add(rowToCheck);
+                }
+                for (int iter = 0; iter < rowsToDelete.Count; iter++)
+                {
+                    landaccesslist.Rows.Remove(rowsToDelete[iter]);
+                }
+
+               
+            }
+            Commit();
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="parcel"></param>
+        public void StoreLandObject(ILandObject parcel)
+        {
+            lock (ds)
+            {
+                DataTable land = ds.Tables["land"];
+                DataTable landaccesslist = ds.Tables["landaccesslist"];
+
+                DataRow landRow = land.Rows.Find(parcel.LandData.GlobalID.ToString());
+                if (landRow == null)
+                {
+                    landRow = land.NewRow();
+                    fillLandRow(landRow, parcel.LandData, parcel.RegionUUID);
+                    land.Rows.Add(landRow);
+                }
+                else
+                {
+                    fillLandRow(landRow, parcel.LandData, parcel.RegionUUID);
+                }
+
+                // I know this caused someone issues before, but OpenSim is unusable if we leave this stuff around
+                //using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:LandUUID", m_conn))
+                //{
+                //    cmd.Parameters.Add(new SqliteParameter(":LandUUID", parcel.LandData.GlobalID.ToString()));
+                //    cmd.ExecuteNonQuery();
+
+//                }
+
+                // This is the slower..  but more appropriate thing to do
+
+                // We can't modify the table with direct queries before calling Commit() and re-filling them.
+                List<DataRow> rowsToDelete = new List<DataRow>();
+                foreach (DataRow rowToCheck in landaccesslist.Rows)
+                {
+                    if (rowToCheck["LandUUID"].ToString() == parcel.LandData.GlobalID.ToString())
+                        rowsToDelete.Add(rowToCheck);
+                }
+                for (int iter = 0; iter < rowsToDelete.Count; iter++)
+                {
+                    landaccesslist.Rows.Remove(rowsToDelete[iter]);
+                }
+                rowsToDelete.Clear();
+                foreach (ParcelManager.ParcelAccessEntry entry in parcel.LandData.ParcelAccessList)
+                {
+                    DataRow newAccessRow = landaccesslist.NewRow();
+                    fillLandAccessRow(newAccessRow, entry, parcel.LandData.GlobalID);
+                    landaccesslist.Rows.Add(newAccessRow);
+                }
+            }
+
+            Commit();
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="regionUUID"></param>
+        /// <returns></returns>
+        public List<LandData> LoadLandObjects(UUID regionUUID)
+        {
+            List<LandData> landDataForRegion = new List<LandData>();
+            lock (ds)
+            {
+                DataTable land = ds.Tables["land"];
+                DataTable landaccesslist = ds.Tables["landaccesslist"];
+                string searchExp = "RegionUUID = '" + regionUUID + "'";
+                DataRow[] rawDataForRegion = land.Select(searchExp);
+                foreach (DataRow rawDataLand in rawDataForRegion)
+                {
+                    LandData newLand = buildLandData(rawDataLand);
+                    string accessListSearchExp = "LandUUID = '" + newLand.GlobalID + "'";
+                    DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp);
+                    foreach (DataRow rawDataLandAccess in rawDataForLandAccessList)
+                    {
+                        newLand.ParcelAccessList.Add(buildLandAccessData(rawDataLandAccess));
+                    }
+
+                    landDataForRegion.Add(newLand);
+                }
+            }
+            return landDataForRegion;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        public void Commit()
+        {
+            lock (ds)
+            {
+                primDa.Update(ds, "prims");
+                shapeDa.Update(ds, "primshapes");
+
+                itemsDa.Update(ds, "primitems");
+
+                terrainDa.Update(ds, "terrain");
+                landDa.Update(ds, "land");
+                landAccessListDa.Update(ds, "landaccesslist");
+                try
+                {
+                    regionSettingsDa.Update(ds, "regionsettings");
+                } 
+                catch (SqliteExecutionException SqlEx)
+                {
+                  if (SqlEx.Message.Contains("logic error"))
+                  {
+                      throw new Exception(
+                          "There was a SQL error or connection string configuration error when saving the region settings.  This could be a bug, it could also happen if ConnectionString is defined in the [DatabaseService] section of StandaloneCommon.ini in the config_include folder.  This could also happen if the config_include folder doesn't exist or if the OpenSim.ini [Architecture] section isn't set.  If this is your first time running OpenSimulator, please restart the simulator and bug a developer to fix this!",
+                          SqlEx);
+                  }
+                  else
+                  {
+                      throw SqlEx;
+                  }
+                }
+                ds.AcceptChanges();
+            }
+        }
+
+        /// <summary>
+        /// See <see cref="Commit"/>
+        /// </summary>
+        public void Shutdown()
+        {
+            Commit();
+        }
+
+        /***********************************************************************
+         *
+         *  Database Definition Functions
+         *
+         *  This should be db agnostic as we define them in ADO.NET terms
+         *
+         **********************************************************************/
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="dt"></param>
+        /// <param name="name"></param>
+        /// <param name="type"></param>
+        private static void createCol(DataTable dt, string name, Type type)
+        {
+            DataColumn col = new DataColumn(name, type);
+            dt.Columns.Add(col);
+        }
+
+        /// <summary>
+        /// Creates the "terrain" table
+        /// </summary>
+        /// <returns>terrain table DataTable</returns>
+        private static DataTable createTerrainTable()
+        {
+            DataTable terrain = new DataTable("terrain");
+
+            createCol(terrain, "RegionUUID", typeof (String));
+            createCol(terrain, "Revision", typeof (Int32));
+            createCol(terrain, "Heightfield", typeof (Byte[]));
+
+            return terrain;
+        }
+
+        /// <summary>
+        /// Creates the "prims" table
+        /// </summary>
+        /// <returns>prim table DataTable</returns>
+        private static DataTable createPrimTable()
+        {
+            DataTable prims = new DataTable("prims");
+
+            createCol(prims, "UUID", typeof (String));
+            createCol(prims, "RegionUUID", typeof (String));
+            createCol(prims, "CreationDate", typeof (Int32));
+            createCol(prims, "Name", typeof (String));
+            createCol(prims, "SceneGroupID", typeof (String));
+            // various text fields
+            createCol(prims, "Text", typeof (String));
+            createCol(prims, "ColorR", typeof (Int32));
+            createCol(prims, "ColorG", typeof (Int32));
+            createCol(prims, "ColorB", typeof (Int32));
+            createCol(prims, "ColorA", typeof (Int32));
+            createCol(prims, "Description", typeof (String));
+            createCol(prims, "SitName", typeof (String));
+            createCol(prims, "TouchName", typeof (String));
+            // permissions
+            createCol(prims, "ObjectFlags", typeof (Int32));
+            createCol(prims, "CreatorID", typeof (String));
+            createCol(prims, "OwnerID", typeof (String));
+            createCol(prims, "GroupID", typeof (String));
+            createCol(prims, "LastOwnerID", typeof (String));
+            createCol(prims, "OwnerMask", typeof (Int32));
+            createCol(prims, "NextOwnerMask", typeof (Int32));
+            createCol(prims, "GroupMask", typeof (Int32));
+            createCol(prims, "EveryoneMask", typeof (Int32));
+            createCol(prims, "BaseMask", typeof (Int32));
+            // vectors
+            createCol(prims, "PositionX", typeof (Double));
+            createCol(prims, "PositionY", typeof (Double));
+            createCol(prims, "PositionZ", typeof (Double));
+            createCol(prims, "GroupPositionX", typeof (Double));
+            createCol(prims, "GroupPositionY", typeof (Double));
+            createCol(prims, "GroupPositionZ", typeof (Double));
+            createCol(prims, "VelocityX", typeof (Double));
+            createCol(prims, "VelocityY", typeof (Double));
+            createCol(prims, "VelocityZ", typeof (Double));
+            createCol(prims, "AngularVelocityX", typeof (Double));
+            createCol(prims, "AngularVelocityY", typeof (Double));
+            createCol(prims, "AngularVelocityZ", typeof (Double));
+            createCol(prims, "AccelerationX", typeof (Double));
+            createCol(prims, "AccelerationY", typeof (Double));
+            createCol(prims, "AccelerationZ", typeof (Double));
+            // quaternions
+            createCol(prims, "RotationX", typeof (Double));
+            createCol(prims, "RotationY", typeof (Double));
+            createCol(prims, "RotationZ", typeof (Double));
+            createCol(prims, "RotationW", typeof (Double));
+
+            // sit target
+            createCol(prims, "SitTargetOffsetX", typeof (Double));
+            createCol(prims, "SitTargetOffsetY", typeof (Double));
+            createCol(prims, "SitTargetOffsetZ", typeof (Double));
+
+            createCol(prims, "SitTargetOrientW", typeof (Double));
+            createCol(prims, "SitTargetOrientX", typeof (Double));
+            createCol(prims, "SitTargetOrientY", typeof (Double));
+            createCol(prims, "SitTargetOrientZ", typeof (Double));
+
+            createCol(prims, "PayPrice", typeof(Int32));
+            createCol(prims, "PayButton1", typeof(Int32));
+            createCol(prims, "PayButton2", typeof(Int32));
+            createCol(prims, "PayButton3", typeof(Int32));
+            createCol(prims, "PayButton4", typeof(Int32));
+
+            createCol(prims, "LoopedSound", typeof(String));
+            createCol(prims, "LoopedSoundGain", typeof(Double));
+            createCol(prims, "TextureAnimation", typeof(String));
+            createCol(prims, "ParticleSystem", typeof(String));
+
+            createCol(prims, "OmegaX", typeof(Double));
+            createCol(prims, "OmegaY", typeof(Double));
+            createCol(prims, "OmegaZ", typeof(Double));
+
+            createCol(prims, "CameraEyeOffsetX", typeof(Double));
+            createCol(prims, "CameraEyeOffsetY", typeof(Double));
+            createCol(prims, "CameraEyeOffsetZ", typeof(Double));
+
+            createCol(prims, "CameraAtOffsetX", typeof(Double));
+            createCol(prims, "CameraAtOffsetY", typeof(Double));
+            createCol(prims, "CameraAtOffsetZ", typeof(Double));
+
+            createCol(prims, "ForceMouselook", typeof(Int16));
+
+            createCol(prims, "ScriptAccessPin", typeof(Int32));
+
+            createCol(prims, "AllowedDrop", typeof(Int16));
+            createCol(prims, "DieAtEdge", typeof(Int16));
+
+            createCol(prims, "SalePrice", typeof(Int32));
+            createCol(prims, "SaleType", typeof(Int16));
+
+            // click action
+            createCol(prims, "ClickAction", typeof (Byte));
+
+            createCol(prims, "Material", typeof(Byte));
+
+            createCol(prims, "CollisionSound", typeof(String));
+            createCol(prims, "CollisionSoundVolume", typeof(Double));
+
+            createCol(prims, "VolumeDetect", typeof(Int16));
+
+            // Add in contraints
+            prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]};
+
+            return prims;
+        }
+
+        /// <summary>
+        /// Creates "primshapes" table
+        /// </summary>
+        /// <returns>shape table DataTable</returns>
+        private static DataTable createShapeTable()
+        {
+            DataTable shapes = new DataTable("primshapes");
+            createCol(shapes, "UUID", typeof (String));
+            // shape is an enum
+            createCol(shapes, "Shape", typeof (Int32));
+            // vectors
+            createCol(shapes, "ScaleX", typeof (Double));
+            createCol(shapes, "ScaleY", typeof (Double));
+            createCol(shapes, "ScaleZ", typeof (Double));
+            // paths
+            createCol(shapes, "PCode", typeof (Int32));
+            createCol(shapes, "PathBegin", typeof (Int32));
+            createCol(shapes, "PathEnd", typeof (Int32));
+            createCol(shapes, "PathScaleX", typeof (Int32));
+            createCol(shapes, "PathScaleY", typeof (Int32));
+            createCol(shapes, "PathShearX", typeof (Int32));
+            createCol(shapes, "PathShearY", typeof (Int32));
+            createCol(shapes, "PathSkew", typeof (Int32));
+            createCol(shapes, "PathCurve", typeof (Int32));
+            createCol(shapes, "PathRadiusOffset", typeof (Int32));
+            createCol(shapes, "PathRevolutions", typeof (Int32));
+            createCol(shapes, "PathTaperX", typeof (Int32));
+            createCol(shapes, "PathTaperY", typeof (Int32));
+            createCol(shapes, "PathTwist", typeof (Int32));
+            createCol(shapes, "PathTwistBegin", typeof (Int32));
+            // profile
+            createCol(shapes, "ProfileBegin", typeof (Int32));
+            createCol(shapes, "ProfileEnd", typeof (Int32));
+            createCol(shapes, "ProfileCurve", typeof (Int32));
+            createCol(shapes, "ProfileHollow", typeof (Int32));
+            createCol(shapes, "State", typeof(Int32));
+            // text TODO: this isn't right, but I'm not sure the right
+            // way to specify this as a blob atm
+            createCol(shapes, "Texture", typeof (Byte[]));
+            createCol(shapes, "ExtraParams", typeof (Byte[]));
+
+            shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]};
+
+            return shapes;
+        }
+
+        /// <summary>
+        /// creates "primitems" table
+        /// </summary>
+        /// <returns>item table DataTable</returns>
+        private static DataTable createItemsTable()
+        {
+            DataTable items = new DataTable("primitems");
+
+            createCol(items, "itemID", typeof (String));
+            createCol(items, "primID", typeof (String));
+            createCol(items, "assetID", typeof (String));
+            createCol(items, "parentFolderID", typeof (String));
+
+            createCol(items, "invType", typeof (Int32));
+            createCol(items, "assetType", typeof (Int32));
+
+            createCol(items, "name", typeof (String));
+            createCol(items, "description", typeof (String));
+
+            createCol(items, "creationDate", typeof (Int64));
+            createCol(items, "creatorID", typeof (String));
+            createCol(items, "ownerID", typeof (String));
+            createCol(items, "lastOwnerID", typeof (String));
+            createCol(items, "groupID", typeof (String));
+
+            createCol(items, "nextPermissions", typeof (UInt32));
+            createCol(items, "currentPermissions", typeof (UInt32));
+            createCol(items, "basePermissions", typeof (UInt32));
+            createCol(items, "everyonePermissions", typeof (UInt32));
+            createCol(items, "groupPermissions", typeof (UInt32));
+            createCol(items, "flags", typeof (UInt32));
+
+            items.PrimaryKey = new DataColumn[] { items.Columns["itemID"] };
+
+            return items;
+        }
+
+        /// <summary>
+        /// Creates "land" table
+        /// </summary>
+        /// <returns>land table DataTable</returns>
+        private static DataTable createLandTable()
+        {
+            DataTable land = new DataTable("land");
+            createCol(land, "UUID", typeof (String));
+            createCol(land, "RegionUUID", typeof (String));
+            createCol(land, "LocalLandID", typeof (UInt32));
+
+            // Bitmap is a byte[512]
+            createCol(land, "Bitmap", typeof (Byte[]));
+
+            createCol(land, "Name", typeof (String));
+            createCol(land, "Desc", typeof (String));
+            createCol(land, "OwnerUUID", typeof (String));
+            createCol(land, "IsGroupOwned", typeof (Boolean));
+            createCol(land, "Area", typeof (Int32));
+            createCol(land, "AuctionID", typeof (Int32)); //Unemplemented
+            createCol(land, "Category", typeof (Int32)); //Enum OpenMetaverse.Parcel.ParcelCategory
+            createCol(land, "ClaimDate", typeof (Int32));
+            createCol(land, "ClaimPrice", typeof (Int32));
+            createCol(land, "GroupUUID", typeof (string));
+            createCol(land, "SalePrice", typeof (Int32));
+            createCol(land, "LandStatus", typeof (Int32)); //Enum. OpenMetaverse.Parcel.ParcelStatus
+            createCol(land, "LandFlags", typeof (UInt32));
+            createCol(land, "LandingType", typeof (Byte));
+            createCol(land, "MediaAutoScale", typeof (Byte));
+            createCol(land, "MediaTextureUUID", typeof (String));
+            createCol(land, "MediaURL", typeof (String));
+            createCol(land, "MusicURL", typeof (String));
+            createCol(land, "PassHours", typeof (Double));
+            createCol(land, "PassPrice", typeof (UInt32));
+            createCol(land, "SnapshotUUID", typeof (String));
+            createCol(land, "UserLocationX", typeof (Double));
+            createCol(land, "UserLocationY", typeof (Double));
+            createCol(land, "UserLocationZ", typeof (Double));
+            createCol(land, "UserLookAtX", typeof (Double));
+            createCol(land, "UserLookAtY", typeof (Double));
+            createCol(land, "UserLookAtZ", typeof (Double));
+            createCol(land, "AuthbuyerID", typeof(String));
+            createCol(land, "OtherCleanTime", typeof(Int32));
+            createCol(land, "Dwell", typeof(Int32));
+
+            land.PrimaryKey = new DataColumn[] {land.Columns["UUID"]};
+
+            return land;
+        }
+
+        /// <summary>
+        /// create "landaccesslist" table
+        /// </summary>
+        /// <returns>Landacceslist DataTable</returns>
+        private static DataTable createLandAccessListTable()
+        {
+            DataTable landaccess = new DataTable("landaccesslist");
+            createCol(landaccess, "LandUUID", typeof (String));
+            createCol(landaccess, "AccessUUID", typeof (String));
+            createCol(landaccess, "Flags", typeof (UInt32));
+
+            return landaccess;
+        }
+
+        private static DataTable createRegionSettingsTable()
+        {
+            DataTable regionsettings = new DataTable("regionsettings");
+            createCol(regionsettings, "regionUUID", typeof(String));
+            createCol(regionsettings, "block_terraform", typeof (Int32));
+            createCol(regionsettings, "block_fly", typeof (Int32));
+            createCol(regionsettings, "allow_damage", typeof (Int32));
+            createCol(regionsettings, "restrict_pushing", typeof (Int32));
+            createCol(regionsettings, "allow_land_resell", typeof (Int32));
+            createCol(regionsettings, "allow_land_join_divide", typeof (Int32));
+            createCol(regionsettings, "block_show_in_search", typeof (Int32));
+            createCol(regionsettings, "agent_limit", typeof (Int32));
+            createCol(regionsettings, "object_bonus", typeof (Double));
+            createCol(regionsettings, "maturity", typeof (Int32));
+            createCol(regionsettings, "disable_scripts", typeof (Int32));
+            createCol(regionsettings, "disable_collisions", typeof (Int32));
+            createCol(regionsettings, "disable_physics", typeof (Int32));
+            createCol(regionsettings, "terrain_texture_1", typeof(String));
+            createCol(regionsettings, "terrain_texture_2", typeof(String));
+            createCol(regionsettings, "terrain_texture_3", typeof(String));
+            createCol(regionsettings, "terrain_texture_4", typeof(String));
+            createCol(regionsettings, "elevation_1_nw", typeof (Double));
+            createCol(regionsettings, "elevation_2_nw", typeof (Double));
+            createCol(regionsettings, "elevation_1_ne", typeof (Double));
+            createCol(regionsettings, "elevation_2_ne", typeof (Double));
+            createCol(regionsettings, "elevation_1_se", typeof (Double));
+            createCol(regionsettings, "elevation_2_se", typeof (Double));
+            createCol(regionsettings, "elevation_1_sw", typeof (Double));
+            createCol(regionsettings, "elevation_2_sw", typeof (Double));
+            createCol(regionsettings, "water_height", typeof (Double));
+            createCol(regionsettings, "terrain_raise_limit", typeof (Double));
+            createCol(regionsettings, "terrain_lower_limit", typeof (Double));
+            createCol(regionsettings, "use_estate_sun", typeof (Int32));
+            createCol(regionsettings, "sandbox", typeof (Int32));
+            createCol(regionsettings, "sunvectorx",typeof (Double));
+            createCol(regionsettings, "sunvectory",typeof (Double));
+            createCol(regionsettings, "sunvectorz",typeof (Double));
+            createCol(regionsettings, "fixed_sun", typeof (Int32));
+            createCol(regionsettings, "sun_position", typeof (Double));
+            createCol(regionsettings, "covenant", typeof(String));
+            regionsettings.PrimaryKey = new DataColumn[] { regionsettings.Columns["regionUUID"] };
+            return regionsettings;
+        }
+
+        /***********************************************************************
+         *
+         *  Convert between ADO.NET <=> OpenSim Objects
+         *
+         *  These should be database independant
+         *
+         **********************************************************************/
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <returns></returns>
+        private SceneObjectPart buildPrim(DataRow row)
+        {
+            // Code commented.  Uncomment to test the unit test inline.
+            
+            // The unit test mentions this commented code for the purposes 
+            // of debugging a unit test failure
+            
+            // SceneObjectGroup sog = new SceneObjectGroup();
+            // SceneObjectPart sop = new SceneObjectPart();
+            // sop.LocalId = 1;
+            // sop.Name = "object1";
+            // sop.Description = "object1";
+            // sop.Text = "";
+            // sop.SitName = "";
+            // sop.TouchName = "";
+            // sop.UUID = UUID.Random();
+            // sop.Shape = PrimitiveBaseShape.Default;
+            // sog.SetRootPart(sop);
+            // Add breakpoint in above line.  Check sop fields.
+
+            // TODO: this doesn't work yet because something more
+            // interesting has to be done to actually get these values
+            // back out.  Not enough time to figure it out yet.
+            
+            SceneObjectPart prim = new SceneObjectPart();
+            prim.UUID = new UUID((String) row["UUID"]);
+            // explicit conversion of integers is required, which sort
+            // of sucks.  No idea if there is a shortcut here or not.
+            prim.CreationDate = Convert.ToInt32(row["CreationDate"]);
+            prim.Name = row["Name"] == DBNull.Value ? string.Empty : (string)row["Name"];
+            // various text fields
+            prim.Text = (String) row["Text"];
+            prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]),
+                                        Convert.ToInt32(row["ColorR"]),
+                                        Convert.ToInt32(row["ColorG"]),
+                                        Convert.ToInt32(row["ColorB"]));
+            prim.Description = (String) row["Description"];
+            prim.SitName = (String) row["SitName"];
+            prim.TouchName = (String) row["TouchName"];
+            // permissions
+            prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]);
+            prim.CreatorID = new UUID((String) row["CreatorID"]);
+            prim.OwnerID = new UUID((String) row["OwnerID"]);
+            prim.GroupID = new UUID((String) row["GroupID"]);
+            prim.LastOwnerID = new UUID((String) row["LastOwnerID"]);
+            prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]);
+            prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]);
+            prim.GroupMask = Convert.ToUInt32(row["GroupMask"]);
+            prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]);
+            prim.BaseMask = Convert.ToUInt32(row["BaseMask"]);
+            // vectors
+            prim.OffsetPosition = new Vector3(
+                Convert.ToSingle(row["PositionX"]),
+                Convert.ToSingle(row["PositionY"]),
+                Convert.ToSingle(row["PositionZ"])
+                );
+            prim.GroupPosition = new Vector3(
+                Convert.ToSingle(row["GroupPositionX"]),
+                Convert.ToSingle(row["GroupPositionY"]),
+                Convert.ToSingle(row["GroupPositionZ"])
+                );
+            prim.Velocity = new Vector3(
+                Convert.ToSingle(row["VelocityX"]),
+                Convert.ToSingle(row["VelocityY"]),
+                Convert.ToSingle(row["VelocityZ"])
+                );
+            prim.AngularVelocity = new Vector3(
+                Convert.ToSingle(row["AngularVelocityX"]),
+                Convert.ToSingle(row["AngularVelocityY"]),
+                Convert.ToSingle(row["AngularVelocityZ"])
+                );
+            prim.Acceleration = new Vector3(
+                Convert.ToSingle(row["AccelerationX"]),
+                Convert.ToSingle(row["AccelerationY"]),
+                Convert.ToSingle(row["AccelerationZ"])
+                );
+            // quaternions
+            prim.RotationOffset = new Quaternion(
+                Convert.ToSingle(row["RotationX"]),
+                Convert.ToSingle(row["RotationY"]),
+                Convert.ToSingle(row["RotationZ"]),
+                Convert.ToSingle(row["RotationW"])
+                );
+
+            prim.SitTargetPositionLL = new Vector3(
+                                                   Convert.ToSingle(row["SitTargetOffsetX"]),
+                                                   Convert.ToSingle(row["SitTargetOffsetY"]),
+                                                   Convert.ToSingle(row["SitTargetOffsetZ"]));
+            prim.SitTargetOrientationLL = new Quaternion(
+                                                         Convert.ToSingle(
+                                                                          row["SitTargetOrientX"]),
+                                                         Convert.ToSingle(
+                                                                          row["SitTargetOrientY"]),
+                                                         Convert.ToSingle(
+                                                                          row["SitTargetOrientZ"]),
+                                                         Convert.ToSingle(
+                                                                          row["SitTargetOrientW"]));
+
+            prim.ClickAction = Convert.ToByte(row["ClickAction"]);
+            prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]);
+            prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]);
+            prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]);
+            prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]);
+            prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]);
+
+            prim.Sound = new UUID(row["LoopedSound"].ToString());
+            prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]);
+            prim.SoundFlags = 1; // If it's persisted at all, it's looped
+
+            if (!row.IsNull("TextureAnimation"))
+                prim.TextureAnimation = Convert.FromBase64String(row["TextureAnimation"].ToString());
+            if (!row.IsNull("ParticleSystem"))
+                prim.ParticleSystem = Convert.FromBase64String(row["ParticleSystem"].ToString());
+
+            prim.AngularVelocity = new Vector3(
+                Convert.ToSingle(row["OmegaX"]),
+                Convert.ToSingle(row["OmegaY"]),
+                Convert.ToSingle(row["OmegaZ"])
+                );
+
+            prim.SetCameraEyeOffset(new Vector3(
+                Convert.ToSingle(row["CameraEyeOffsetX"]),
+                Convert.ToSingle(row["CameraEyeOffsetY"]),
+                Convert.ToSingle(row["CameraEyeOffsetZ"])
+                ));
+
+            prim.SetCameraAtOffset(new Vector3(
+                Convert.ToSingle(row["CameraAtOffsetX"]),
+                Convert.ToSingle(row["CameraAtOffsetY"]),
+                Convert.ToSingle(row["CameraAtOffsetZ"])
+                ));
+
+            if (Convert.ToInt16(row["ForceMouselook"]) != 0)
+                prim.SetForceMouselook(true);
+
+            prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]);
+
+            if (Convert.ToInt16(row["AllowedDrop"]) != 0)
+                prim.AllowedDrop = true;
+
+            if (Convert.ToInt16(row["DieAtEdge"]) != 0)
+                prim.DIE_AT_EDGE = true;
+
+            prim.SalePrice = Convert.ToInt32(row["SalePrice"]);
+            prim.ObjectSaleType = Convert.ToByte(row["SaleType"]);
+
+            prim.Material = Convert.ToByte(row["Material"]);
+
+            prim.CollisionSound = new UUID(row["CollisionSound"].ToString());
+            prim.CollisionSoundVolume = Convert.ToSingle(row["CollisionSoundVolume"]);
+
+            if (Convert.ToInt16(row["VolumeDetect"]) != 0)
+                prim.VolumeDetectActive = true;
+
+            return prim;
+        }
+
+        /// <summary>
+        /// Build a prim inventory item from the persisted data.
+        /// </summary>
+        /// <param name="row"></param>
+        /// <returns></returns>
+        private static TaskInventoryItem buildItem(DataRow row)
+        {
+            TaskInventoryItem taskItem = new TaskInventoryItem();
+
+            taskItem.ItemID        = new UUID((String)row["itemID"]);
+            taskItem.ParentPartID  = new UUID((String)row["primID"]);
+            taskItem.AssetID       = new UUID((String)row["assetID"]);
+            taskItem.ParentID      = new UUID((String)row["parentFolderID"]);
+
+            taskItem.InvType       = Convert.ToInt32(row["invType"]);
+            taskItem.Type          = Convert.ToInt32(row["assetType"]);
+
+            taskItem.Name          = (String)row["name"];
+            taskItem.Description   = (String)row["description"];
+            taskItem.CreationDate  = Convert.ToUInt32(row["creationDate"]);
+            taskItem.CreatorID     = new UUID((String)row["creatorID"]);
+            taskItem.OwnerID       = new UUID((String)row["ownerID"]);
+            taskItem.LastOwnerID   = new UUID((String)row["lastOwnerID"]);
+            taskItem.GroupID       = new UUID((String)row["groupID"]);
+
+            taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]);
+            taskItem.CurrentPermissions     = Convert.ToUInt32(row["currentPermissions"]);
+            taskItem.BasePermissions      = Convert.ToUInt32(row["basePermissions"]);
+            taskItem.EveryonePermissions  = Convert.ToUInt32(row["everyonePermissions"]);
+            taskItem.GroupPermissions     = Convert.ToUInt32(row["groupPermissions"]);
+            taskItem.Flags         = Convert.ToUInt32(row["flags"]);
+
+            return taskItem;
+        }
+
+        /// <summary>
+        /// Build a Land Data from the persisted data.
+        /// </summary>
+        /// <param name="row"></param>
+        /// <returns></returns>
+        private LandData buildLandData(DataRow row)
+        {
+            LandData newData = new LandData();
+
+            newData.GlobalID = new UUID((String) row["UUID"]);
+            newData.LocalID = Convert.ToInt32(row["LocalLandID"]);
+
+            // Bitmap is a byte[512]
+            newData.Bitmap = (Byte[]) row["Bitmap"];
+
+            newData.Name = (String) row["Name"];
+            newData.Description = (String) row["Desc"];
+            newData.OwnerID = (UUID)(String) row["OwnerUUID"];
+            newData.IsGroupOwned = (Boolean) row["IsGroupOwned"];
+            newData.Area = Convert.ToInt32(row["Area"]);
+            newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented
+            newData.Category = (ParcelCategory) Convert.ToInt32(row["Category"]);
+                //Enum OpenMetaverse.Parcel.ParcelCategory
+            newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]);
+            newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]);
+            newData.GroupID = new UUID((String) row["GroupUUID"]);
+            newData.SalePrice = Convert.ToInt32(row["SalePrice"]);
+            newData.Status = (ParcelStatus) Convert.ToInt32(row["LandStatus"]);
+                //Enum. OpenMetaverse.Parcel.ParcelStatus
+            newData.Flags = Convert.ToUInt32(row["LandFlags"]);
+            newData.LandingType = (Byte) row["LandingType"];
+            newData.MediaAutoScale = (Byte) row["MediaAutoScale"];
+            newData.MediaID = new UUID((String) row["MediaTextureUUID"]);
+            newData.MediaURL = (String) row["MediaURL"];
+            newData.MusicURL = (String) row["MusicURL"];
+            newData.PassHours = Convert.ToSingle(row["PassHours"]);
+            newData.PassPrice = Convert.ToInt32(row["PassPrice"]);
+            newData.SnapshotID = (UUID)(String) row["SnapshotUUID"];
+            try
+            {
+
+                newData.UserLocation =
+                    new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]),
+                                  Convert.ToSingle(row["UserLocationZ"]));
+                newData.UserLookAt =
+                    new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]),
+                                  Convert.ToSingle(row["UserLookAtZ"]));
+
+            }
+            catch (InvalidCastException)
+            {
+                m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name);
+                newData.UserLocation = Vector3.Zero;
+                newData.UserLookAt = Vector3.Zero;
+            }
+            newData.ParcelAccessList = new List<ParcelManager.ParcelAccessEntry>();
+            UUID authBuyerID = UUID.Zero;
+
+            UUID.TryParse((string)row["AuthbuyerID"], out authBuyerID);
+
+            newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]);
+            newData.Dwell = Convert.ToInt32(row["Dwell"]);
+
+            return newData;
+        }
+
+        private RegionSettings buildRegionSettings(DataRow row)
+        {
+            RegionSettings newSettings = new RegionSettings();
+
+            newSettings.RegionUUID = new UUID((string) row["regionUUID"]);
+            newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]);
+            newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]);
+            newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]);
+            newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]);
+            newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]);
+            newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]);
+            newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]);
+            newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]);
+            newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]);
+            newSettings.Maturity = Convert.ToInt32(row["maturity"]);
+            newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]);
+            newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]);
+            newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]);
+            newSettings.TerrainTexture1 = new UUID((String) row["terrain_texture_1"]);
+            newSettings.TerrainTexture2 = new UUID((String) row["terrain_texture_2"]);
+            newSettings.TerrainTexture3 = new UUID((String) row["terrain_texture_3"]);
+            newSettings.TerrainTexture4 = new UUID((String) row["terrain_texture_4"]);
+            newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]);
+            newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]);
+            newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]);
+            newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]);
+            newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]);
+            newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]);
+            newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]);
+            newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]);
+            newSettings.WaterHeight = Convert.ToDouble(row["water_height"]);
+            newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]);
+            newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]);
+            newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]);
+            newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]);
+            newSettings.SunVector = new Vector3 (
+                                     Convert.ToSingle(row["sunvectorx"]),
+                                     Convert.ToSingle(row["sunvectory"]),
+                                     Convert.ToSingle(row["sunvectorz"])
+                                     );
+            newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]);
+            newSettings.SunPosition = Convert.ToDouble(row["sun_position"]);
+            newSettings.Covenant = new UUID((String) row["covenant"]);
+
+            return newSettings;
+        }
+
+        /// <summary>
+        /// Build a land access entry from the persisted data.
+        /// </summary>
+        /// <param name="row"></param>
+        /// <returns></returns>
+        private static ParcelManager.ParcelAccessEntry buildLandAccessData(DataRow row)
+        {
+            ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
+            entry.AgentID = new UUID((string) row["AccessUUID"]);
+            entry.Flags = (AccessList) row["Flags"];
+            entry.Time = new DateTime();
+            return entry;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="val"></param>
+        /// <returns></returns>
+        private static Array serializeTerrain(double[,] val)
+        {
+            MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) *sizeof (double));
+            BinaryWriter bw = new BinaryWriter(str);
+
+            // TODO: COMPATIBILITY - Add byte-order conversions
+            for (int x = 0; x < (int)Constants.RegionSize; x++)
+                for (int y = 0; y < (int)Constants.RegionSize; y++)
+                    bw.Write(val[x, y]);
+
+            return str.ToArray();
+        }
+
+//         private void fillTerrainRow(DataRow row, UUID regionUUID, int rev, double[,] val)
+//         {
+//             row["RegionUUID"] = regionUUID;
+//             row["Revision"] = rev;
+
+        //             MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize)*sizeof (double));
+//             BinaryWriter bw = new BinaryWriter(str);
+
+//             // TODO: COMPATIBILITY - Add byte-order conversions
+        //             for (int x = 0; x < (int)Constants.RegionSize; x++)
+        //                 for (int y = 0; y < (int)Constants.RegionSize; y++)
+//                     bw.Write(val[x, y]);
+
+//             row["Heightfield"] = str.ToArray();
+//         }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <param name="prim"></param>
+        /// <param name="sceneGroupID"></param>
+        /// <param name="regionUUID"></param>
+        private static void fillPrimRow(DataRow row, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
+        {
+            row["UUID"] = prim.UUID.ToString();
+            row["RegionUUID"] = regionUUID.ToString();
+            row["CreationDate"] = prim.CreationDate;
+            row["Name"] = prim.Name;
+            row["SceneGroupID"] = sceneGroupID.ToString();
+            // the UUID of the root part for this SceneObjectGroup
+            // various text fields
+            row["Text"] = prim.Text;
+            row["Description"] = prim.Description;
+            row["SitName"] = prim.SitName;
+            row["TouchName"] = prim.TouchName;
+            // permissions
+            row["ObjectFlags"] = prim.ObjectFlags;
+            row["CreatorID"] = prim.CreatorID.ToString();
+            row["OwnerID"] = prim.OwnerID.ToString();
+            row["GroupID"] = prim.GroupID.ToString();
+            row["LastOwnerID"] = prim.LastOwnerID.ToString();
+            row["OwnerMask"] = prim.OwnerMask;
+            row["NextOwnerMask"] = prim.NextOwnerMask;
+            row["GroupMask"] = prim.GroupMask;
+            row["EveryoneMask"] = prim.EveryoneMask;
+            row["BaseMask"] = prim.BaseMask;
+            // vectors
+            row["PositionX"] = prim.OffsetPosition.X;
+            row["PositionY"] = prim.OffsetPosition.Y;
+            row["PositionZ"] = prim.OffsetPosition.Z;
+            row["GroupPositionX"] = prim.GroupPosition.X;
+            row["GroupPositionY"] = prim.GroupPosition.Y;
+            row["GroupPositionZ"] = prim.GroupPosition.Z;
+            row["VelocityX"] = prim.Velocity.X;
+            row["VelocityY"] = prim.Velocity.Y;
+            row["VelocityZ"] = prim.Velocity.Z;
+            row["AngularVelocityX"] = prim.AngularVelocity.X;
+            row["AngularVelocityY"] = prim.AngularVelocity.Y;
+            row["AngularVelocityZ"] = prim.AngularVelocity.Z;
+            row["AccelerationX"] = prim.Acceleration.X;
+            row["AccelerationY"] = prim.Acceleration.Y;
+            row["AccelerationZ"] = prim.Acceleration.Z;
+            // quaternions
+            row["RotationX"] = prim.RotationOffset.X;
+            row["RotationY"] = prim.RotationOffset.Y;
+            row["RotationZ"] = prim.RotationOffset.Z;
+            row["RotationW"] = prim.RotationOffset.W;
+
+            // Sit target
+            Vector3 sitTargetPos = prim.SitTargetPositionLL;
+            row["SitTargetOffsetX"] = sitTargetPos.X;
+            row["SitTargetOffsetY"] = sitTargetPos.Y;
+            row["SitTargetOffsetZ"] = sitTargetPos.Z;
+
+            Quaternion sitTargetOrient = prim.SitTargetOrientationLL;
+            row["SitTargetOrientW"] = sitTargetOrient.W;
+            row["SitTargetOrientX"] = sitTargetOrient.X;
+            row["SitTargetOrientY"] = sitTargetOrient.Y;
+            row["SitTargetOrientZ"] = sitTargetOrient.Z;
+            row["ColorR"] = Convert.ToInt32(prim.Color.R);
+            row["ColorG"] = Convert.ToInt32(prim.Color.G);
+            row["ColorB"] = Convert.ToInt32(prim.Color.B);
+            row["ColorA"] = Convert.ToInt32(prim.Color.A);
+            row["PayPrice"] = prim.PayPrice[0];
+            row["PayButton1"] = prim.PayPrice[1];
+            row["PayButton2"] = prim.PayPrice[2];
+            row["PayButton3"] = prim.PayPrice[3];
+            row["PayButton4"] = prim.PayPrice[4];
+
+
+            row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation);
+            row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem);
+
+            row["OmegaX"] = prim.AngularVelocity.X;
+            row["OmegaY"] = prim.AngularVelocity.Y;
+            row["OmegaZ"] = prim.AngularVelocity.Z;
+
+            row["CameraEyeOffsetX"] = prim.GetCameraEyeOffset().X;
+            row["CameraEyeOffsetY"] = prim.GetCameraEyeOffset().Y;
+            row["CameraEyeOffsetZ"] = prim.GetCameraEyeOffset().Z;
+
+            row["CameraAtOffsetX"] = prim.GetCameraAtOffset().X;
+            row["CameraAtOffsetY"] = prim.GetCameraAtOffset().Y;
+            row["CameraAtOffsetZ"] = prim.GetCameraAtOffset().Z;
+
+
+            if ((prim.SoundFlags & 1) != 0) // Looped
+            {
+                row["LoopedSound"] = prim.Sound.ToString();
+                row["LoopedSoundGain"] = prim.SoundGain;
+            }
+            else
+            {
+                row["LoopedSound"] = UUID.Zero.ToString();
+                row["LoopedSoundGain"] = 0.0f;
+            }
+
+            if (prim.GetForceMouselook())
+                row["ForceMouselook"] = 1;
+            else
+                row["ForceMouselook"] = 0;
+
+            row["ScriptAccessPin"] = prim.ScriptAccessPin;
+
+            if (prim.AllowedDrop)
+                row["AllowedDrop"] = 1;
+            else
+                row["AllowedDrop"] = 0;
+
+            if (prim.DIE_AT_EDGE)
+                row["DieAtEdge"] = 1;
+            else
+                row["DieAtEdge"] = 0;
+
+            row["SalePrice"] = prim.SalePrice;
+            row["SaleType"] = Convert.ToInt16(prim.ObjectSaleType);
+
+            // click action
+            row["ClickAction"] = prim.ClickAction;
+
+            row["SalePrice"] = prim.SalePrice;
+            row["Material"] = prim.Material;
+
+            row["CollisionSound"] = prim.CollisionSound.ToString();
+            row["CollisionSoundVolume"] = prim.CollisionSoundVolume;
+            if (prim.VolumeDetectActive)
+                row["VolumeDetect"] = 1;
+            else
+                row["VolumeDetect"] = 0;
+
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <param name="taskItem"></param>
+        private static void fillItemRow(DataRow row, TaskInventoryItem taskItem)
+        {
+            row["itemID"] = taskItem.ItemID.ToString();
+            row["primID"] = taskItem.ParentPartID.ToString();
+            row["assetID"] = taskItem.AssetID.ToString();
+            row["parentFolderID"] = taskItem.ParentID.ToString();
+
+            row["invType"] = taskItem.InvType;
+            row["assetType"] = taskItem.Type;
+
+            row["name"] = taskItem.Name;
+            row["description"] = taskItem.Description;
+            row["creationDate"] = taskItem.CreationDate;
+            row["creatorID"] = taskItem.CreatorID.ToString();
+            row["ownerID"] = taskItem.OwnerID.ToString();
+            row["lastOwnerID"] = taskItem.LastOwnerID.ToString();
+            row["groupID"] = taskItem.GroupID.ToString();
+            row["nextPermissions"] = taskItem.NextPermissions;
+            row["currentPermissions"] = taskItem.CurrentPermissions;
+            row["basePermissions"] = taskItem.BasePermissions;
+            row["everyonePermissions"] = taskItem.EveryonePermissions;
+            row["groupPermissions"] = taskItem.GroupPermissions;
+            row["flags"] = taskItem.Flags;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <param name="land"></param>
+        /// <param name="regionUUID"></param>
+        private static void fillLandRow(DataRow row, LandData land, UUID regionUUID)
+        {
+            row["UUID"] = land.GlobalID.ToString();
+            row["RegionUUID"] = regionUUID.ToString();
+            row["LocalLandID"] = land.LocalID;
+
+            // Bitmap is a byte[512]
+            row["Bitmap"] = land.Bitmap;
+
+            row["Name"] = land.Name;
+            row["Desc"] = land.Description;
+            row["OwnerUUID"] = land.OwnerID.ToString();
+            row["IsGroupOwned"] = land.IsGroupOwned;
+            row["Area"] = land.Area;
+            row["AuctionID"] = land.AuctionID; //Unemplemented
+            row["Category"] = land.Category; //Enum OpenMetaverse.Parcel.ParcelCategory
+            row["ClaimDate"] = land.ClaimDate;
+            row["ClaimPrice"] = land.ClaimPrice;
+            row["GroupUUID"] = land.GroupID.ToString();
+            row["SalePrice"] = land.SalePrice;
+            row["LandStatus"] = land.Status; //Enum. OpenMetaverse.Parcel.ParcelStatus
+            row["LandFlags"] = land.Flags;
+            row["LandingType"] = land.LandingType;
+            row["MediaAutoScale"] = land.MediaAutoScale;
+            row["MediaTextureUUID"] = land.MediaID.ToString();
+            row["MediaURL"] = land.MediaURL;
+            row["MusicURL"] = land.MusicURL;
+            row["PassHours"] = land.PassHours;
+            row["PassPrice"] = land.PassPrice;
+            row["SnapshotUUID"] = land.SnapshotID.ToString();
+            row["UserLocationX"] = land.UserLocation.X;
+            row["UserLocationY"] = land.UserLocation.Y;
+            row["UserLocationZ"] = land.UserLocation.Z;
+            row["UserLookAtX"] = land.UserLookAt.X;
+            row["UserLookAtY"] = land.UserLookAt.Y;
+            row["UserLookAtZ"] = land.UserLookAt.Z;
+            row["AuthbuyerID"] = land.AuthBuyerID.ToString();
+            row["OtherCleanTime"] = land.OtherCleanTime;
+            row["Dwell"] = land.Dwell;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <param name="entry"></param>
+        /// <param name="parcelID"></param>
+        private static void fillLandAccessRow(DataRow row, ParcelManager.ParcelAccessEntry entry, UUID parcelID)
+        {
+            row["LandUUID"] = parcelID.ToString();
+            row["AccessUUID"] = entry.AgentID.ToString();
+            row["Flags"] = entry.Flags;
+        }
+
+        private static void fillRegionSettingsRow(DataRow row, RegionSettings settings)
+        {
+            row["regionUUID"] = settings.RegionUUID.ToString();
+            row["block_terraform"] = settings.BlockTerraform;
+            row["block_fly"] = settings.BlockFly;
+            row["allow_damage"] = settings.AllowDamage;
+            row["restrict_pushing"] = settings.RestrictPushing;
+            row["allow_land_resell"] = settings.AllowLandResell;
+            row["allow_land_join_divide"] = settings.AllowLandJoinDivide;
+            row["block_show_in_search"] = settings.BlockShowInSearch;
+            row["agent_limit"] = settings.AgentLimit;
+            row["object_bonus"] = settings.ObjectBonus;
+            row["maturity"] = settings.Maturity;
+            row["disable_scripts"] = settings.DisableScripts;
+            row["disable_collisions"] = settings.DisableCollisions;
+            row["disable_physics"] = settings.DisablePhysics;
+            row["terrain_texture_1"] = settings.TerrainTexture1.ToString();
+            row["terrain_texture_2"] = settings.TerrainTexture2.ToString();
+            row["terrain_texture_3"] = settings.TerrainTexture3.ToString();
+            row["terrain_texture_4"] = settings.TerrainTexture4.ToString();
+            row["elevation_1_nw"] = settings.Elevation1NW;
+            row["elevation_2_nw"] = settings.Elevation2NW;
+            row["elevation_1_ne"] = settings.Elevation1NE;
+            row["elevation_2_ne"] = settings.Elevation2NE;
+            row["elevation_1_se"] = settings.Elevation1SE;
+            row["elevation_2_se"] = settings.Elevation2SE;
+            row["elevation_1_sw"] = settings.Elevation1SW;
+            row["elevation_2_sw"] = settings.Elevation2SW;
+            row["water_height"] = settings.WaterHeight;
+            row["terrain_raise_limit"] = settings.TerrainRaiseLimit;
+            row["terrain_lower_limit"] = settings.TerrainLowerLimit;
+            row["use_estate_sun"] = settings.UseEstateSun;
+            row["Sandbox"] = settings.Sandbox; // database uses upper case S for sandbox
+            row["sunvectorx"] = settings.SunVector.X;
+            row["sunvectory"] = settings.SunVector.Y;
+            row["sunvectorz"] = settings.SunVector.Z;
+            row["fixed_sun"] = settings.FixedSun;
+            row["sun_position"] = settings.SunPosition;
+            row["covenant"] = settings.Covenant.ToString();
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <returns></returns>
+        private PrimitiveBaseShape buildShape(DataRow row)
+        {
+            PrimitiveBaseShape s = new PrimitiveBaseShape();
+            s.Scale = new Vector3(
+                Convert.ToSingle(row["ScaleX"]),
+                Convert.ToSingle(row["ScaleY"]),
+                Convert.ToSingle(row["ScaleZ"])
+                );
+            // paths
+            s.PCode = Convert.ToByte(row["PCode"]);
+            s.PathBegin = Convert.ToUInt16(row["PathBegin"]);
+            s.PathEnd = Convert.ToUInt16(row["PathEnd"]);
+            s.PathScaleX = Convert.ToByte(row["PathScaleX"]);
+            s.PathScaleY = Convert.ToByte(row["PathScaleY"]);
+            s.PathShearX = Convert.ToByte(row["PathShearX"]);
+            s.PathShearY = Convert.ToByte(row["PathShearY"]);
+            s.PathSkew = Convert.ToSByte(row["PathSkew"]);
+            s.PathCurve = Convert.ToByte(row["PathCurve"]);
+            s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]);
+            s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]);
+            s.PathTaperX = Convert.ToSByte(row["PathTaperX"]);
+            s.PathTaperY = Convert.ToSByte(row["PathTaperY"]);
+            s.PathTwist = Convert.ToSByte(row["PathTwist"]);
+            s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]);
+            // profile
+            s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]);
+            s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]);
+            s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]);
+            s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]);
+            s.State = Convert.ToByte(row["State"]);
+
+            byte[] textureEntry = (byte[])row["Texture"];
+            s.TextureEntry = textureEntry;
+
+            s.ExtraParams = (byte[]) row["ExtraParams"];
+            return s;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="row"></param>
+        /// <param name="prim"></param>
+        private static void fillShapeRow(DataRow row, SceneObjectPart prim)
+        {
+            PrimitiveBaseShape s = prim.Shape;
+            row["UUID"] = prim.UUID.ToString();
+            // shape is an enum
+            row["Shape"] = 0;
+            // vectors
+            row["ScaleX"] = s.Scale.X;
+            row["ScaleY"] = s.Scale.Y;
+            row["ScaleZ"] = s.Scale.Z;
+            // paths
+            row["PCode"] = s.PCode;
+            row["PathBegin"] = s.PathBegin;
+            row["PathEnd"] = s.PathEnd;
+            row["PathScaleX"] = s.PathScaleX;
+            row["PathScaleY"] = s.PathScaleY;
+            row["PathShearX"] = s.PathShearX;
+            row["PathShearY"] = s.PathShearY;
+            row["PathSkew"] = s.PathSkew;
+            row["PathCurve"] = s.PathCurve;
+            row["PathRadiusOffset"] = s.PathRadiusOffset;
+            row["PathRevolutions"] = s.PathRevolutions;
+            row["PathTaperX"] = s.PathTaperX;
+            row["PathTaperY"] = s.PathTaperY;
+            row["PathTwist"] = s.PathTwist;
+            row["PathTwistBegin"] = s.PathTwistBegin;
+            // profile
+            row["ProfileBegin"] = s.ProfileBegin;
+            row["ProfileEnd"] = s.ProfileEnd;
+            row["ProfileCurve"] = s.ProfileCurve;
+            row["ProfileHollow"] = s.ProfileHollow;
+            row["State"] = s.State;
+
+            row["Texture"] = s.TextureEntry;
+            row["ExtraParams"] = s.ExtraParams;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="prim"></param>
+        /// <param name="sceneGroupID"></param>
+        /// <param name="regionUUID"></param>
+        private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
+        {
+
+            DataTable prims = ds.Tables["prims"];
+            DataTable shapes = ds.Tables["primshapes"];
+
+            DataRow primRow = prims.Rows.Find(prim.UUID.ToString());
+            if (primRow == null)
+            {
+                primRow = prims.NewRow();
+                fillPrimRow(primRow, prim, sceneGroupID, regionUUID);
+                prims.Rows.Add(primRow);
+            }
+            else
+            {
+                fillPrimRow(primRow, prim, sceneGroupID, regionUUID);
+            }
+
+            DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
+            if (shapeRow == null)
+            {
+                shapeRow = shapes.NewRow();
+                fillShapeRow(shapeRow, prim);
+                shapes.Rows.Add(shapeRow);
+            }
+            else
+            {
+                fillShapeRow(shapeRow, prim);
+            }
+        }
+
+        /// <summary>
+        /// see IRegionDatastore
+        /// </summary>
+        /// <param name="primID"></param>
+        /// <param name="items"></param>
+        public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
+        {
+            m_log.InfoFormat("[REGION DB]: Entered StorePrimInventory with prim ID {0}", primID);
+
+            DataTable dbItems = ds.Tables["primitems"];
+
+            // For now, we're just going to crudely remove all the previous inventory items
+            // no matter whether they have changed or not, and replace them with the current set.
+            lock (ds)
+            {
+                RemoveItems(primID);
+
+                // repalce with current inventory details
+                foreach (TaskInventoryItem newItem in items)
+                {
+//                    m_log.InfoFormat(
+//                        "[DATASTORE]: ",
+//                        "Adding item {0}, {1} to prim ID {2}",
+//                        newItem.Name, newItem.ItemID, newItem.ParentPartID);
+
+                    DataRow newItemRow = dbItems.NewRow();
+                    fillItemRow(newItemRow, newItem);
+                    dbItems.Rows.Add(newItemRow);
+                }
+            }
+
+            Commit();
+        }
+
+        /***********************************************************************
+         *
+         *  SQL Statement Creation Functions
+         *
+         *  These functions create SQL statements for update, insert, and create.
+         *  They can probably be factored later to have a db independant
+         *  portion and a db specific portion
+         *
+         **********************************************************************/
+
+        /// <summary>
+        /// Create an insert command
+        /// </summary>
+        /// <param name="table">table name</param>
+        /// <param name="dt">data table</param>
+        /// <returns>the created command</returns>
+        /// <remarks>
+        /// This is subtle enough to deserve some commentary.
+        /// Instead of doing *lots* and *lots of hardcoded strings
+        /// for database definitions we'll use the fact that
+        /// realistically all insert statements look like "insert
+        /// into A(b, c) values(:b, :c) on the parameterized query
+        /// front.  If we just have a list of b, c, etc... we can
+        /// generate these strings instead of typing them out.
+        /// </remarks>
+        private static SqliteCommand createInsertCommand(string table, DataTable dt)
+        {
+            string[] cols = new string[dt.Columns.Count];
+            for (int i = 0; i < dt.Columns.Count; i++)
+            {
+                DataColumn col = dt.Columns[i];
+                cols[i] = col.ColumnName;
+            }
+
+            string sql = "insert into " + table + "(";
+            sql += String.Join(", ", cols);
+            // important, the first ':' needs to be here, the rest get added in the join
+            sql += ") values (:";
+            sql += String.Join(", :", cols);
+            sql += ")";
+            SqliteCommand cmd = new SqliteCommand(sql);
+
+            // this provides the binding for all our parameters, so
+            // much less code than it used to be
+            foreach (DataColumn col in dt.Columns)
+            {
+                cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
+            }
+            return cmd;
+        }
+
+
+        /// <summary>
+        /// create an update command
+        /// </summary>
+        /// <param name="table">table name</param>
+        /// <param name="pk"></param>
+        /// <param name="dt"></param>
+        /// <returns>the created command</returns>
+        private static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt)
+        {
+            string sql = "update " + table + " set ";
+            string subsql = String.Empty;
+            foreach (DataColumn col in dt.Columns)
+            {
+                if (subsql.Length > 0)
+                {
+                    // a map function would rock so much here
+                    subsql += ", ";
+                }
+                subsql += col.ColumnName + "= :" + col.ColumnName;
+            }
+            sql += subsql;
+            sql += " where " + pk;
+            SqliteCommand cmd = new SqliteCommand(sql);
+
+            // this provides the binding for all our parameters, so
+            // much less code than it used to be
+
+            foreach (DataColumn col in dt.Columns)
+            {
+                cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
+            }
+            return cmd;
+        }
+
+        /// <summary>
+        /// create an update command
+        /// </summary>
+        /// <param name="table">table name</param>
+        /// <param name="pk"></param>
+        /// <param name="dt"></param>
+        /// <returns>the created command</returns>
+        private static SqliteCommand createUpdateCommand(string table, string pk1, string pk2, DataTable dt)
+        {
+            string sql = "update " + table + " set ";
+            string subsql = String.Empty;
+            foreach (DataColumn col in dt.Columns)
+            {
+                if (subsql.Length > 0)
+                {
+                    // a map function would rock so much here
+                    subsql += ", ";
+                }
+                subsql += col.ColumnName + "= :" + col.ColumnName;
+            }
+            sql += subsql;
+            sql += " where " + pk1 + " and " + pk2;
+            SqliteCommand cmd = new SqliteCommand(sql);
+
+            // this provides the binding for all our parameters, so
+            // much less code than it used to be
+
+            foreach (DataColumn col in dt.Columns)
+            {
+                cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
+            }
+            return cmd;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="dt">Data Table</param>
+        /// <returns></returns>
+        // private static string defineTable(DataTable dt)
+        // {
+        //     string sql = "create table " + dt.TableName + "(";
+        //     string subsql = String.Empty;
+        //     foreach (DataColumn col in dt.Columns)
+        //     {
+        //         if (subsql.Length > 0)
+        //         {
+        //             // a map function would rock so much here
+        //             subsql += ",\n";
+        //         }
+        //         subsql += col.ColumnName + " " + sqliteType(col.DataType);
+        //         if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0])
+        //         {
+        //             subsql += " primary key";
+        //         }
+        //     }
+        //     sql += subsql;
+        //     sql += ")";
+        //     return sql;
+        // }
+
+        /***********************************************************************
+         *
+         *  Database Binding functions
+         *
+         *  These will be db specific due to typing, and minor differences
+         *  in databases.
+         *
+         **********************************************************************/
+
+        ///<summary>
+        /// This is a convenience function that collapses 5 repetitive
+        /// lines for defining SqliteParameters to 2 parameters:
+        /// column name and database type.
+        ///
+        /// It assumes certain conventions like :param as the param
+        /// name to replace in parametrized queries, and that source
+        /// version is always current version, both of which are fine
+        /// for us.
+        ///</summary>
+        ///<returns>a built sqlite parameter</returns>
+        private static SqliteParameter createSqliteParameter(string name, Type type)
+        {
+            SqliteParameter param = new SqliteParameter();
+            param.ParameterName = ":" + name;
+            param.DbType = dbtypeFromType(type);
+            param.SourceColumn = name;
+            param.SourceVersion = DataRowVersion.Current;
+            return param;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="da"></param>
+        /// <param name="conn"></param>
+        private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn)
+        {
+            da.InsertCommand = createInsertCommand("prims", ds.Tables["prims"]);
+            da.InsertCommand.Connection = conn;
+
+            da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", ds.Tables["prims"]);
+            da.UpdateCommand.Connection = conn;
+
+            SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID");
+            delete.Parameters.Add(createSqliteParameter("UUID", typeof (String)));
+            delete.Connection = conn;
+            da.DeleteCommand = delete;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="da"></param>
+        /// <param name="conn"></param>
+        private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn)
+        {
+            da.InsertCommand = createInsertCommand("primitems", ds.Tables["primitems"]);
+            da.InsertCommand.Connection = conn;
+
+            da.UpdateCommand = createUpdateCommand("primitems", "itemID = :itemID", ds.Tables["primitems"]);
+            da.UpdateCommand.Connection = conn;
+
+            SqliteCommand delete = new SqliteCommand("delete from primitems where itemID = :itemID");
+            delete.Parameters.Add(createSqliteParameter("itemID", typeof (String)));
+            delete.Connection = conn;
+            da.DeleteCommand = delete;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="da"></param>
+        /// <param name="conn"></param>
+        private void setupTerrainCommands(SqliteDataAdapter da, SqliteConnection conn)
+        {
+            da.InsertCommand = createInsertCommand("terrain", ds.Tables["terrain"]);
+            da.InsertCommand.Connection = conn;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="da"></param>
+        /// <param name="conn"></param>
+        private void setupLandCommands(SqliteDataAdapter da, SqliteConnection conn)
+        {
+            da.InsertCommand = createInsertCommand("land", ds.Tables["land"]);
+            da.InsertCommand.Connection = conn;
+
+            da.UpdateCommand = createUpdateCommand("land", "UUID=:UUID", ds.Tables["land"]);
+            da.UpdateCommand.Connection = conn;
+
+            SqliteCommand delete = new SqliteCommand("delete from land where UUID=:UUID");
+            delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
+            da.DeleteCommand = delete;
+            da.DeleteCommand.Connection = conn;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="da"></param>
+        /// <param name="conn"></param>
+        private void setupLandAccessCommands(SqliteDataAdapter da, SqliteConnection conn)
+        {
+            da.InsertCommand = createInsertCommand("landaccesslist", ds.Tables["landaccesslist"]);
+            da.InsertCommand.Connection = conn;
+
+            da.UpdateCommand = createUpdateCommand("landaccesslist", "LandUUID=:landUUID", "AccessUUID=:AccessUUID", ds.Tables["landaccesslist"]);
+            da.UpdateCommand.Connection = conn;
+
+            SqliteCommand delete = new SqliteCommand("delete from landaccesslist where LandUUID= :LandUUID and AccessUUID= :AccessUUID");
+            delete.Parameters.Add(createSqliteParameter("LandUUID", typeof(String)));
+            delete.Parameters.Add(createSqliteParameter("AccessUUID", typeof(String)));
+            da.DeleteCommand = delete;
+            da.DeleteCommand.Connection = conn;
+            
+        }
+
+        private void setupRegionSettingsCommands(SqliteDataAdapter da, SqliteConnection conn)
+        {
+            da.InsertCommand = createInsertCommand("regionsettings", ds.Tables["regionsettings"]);
+            da.InsertCommand.Connection = conn;
+            da.UpdateCommand = createUpdateCommand("regionsettings", "regionUUID=:regionUUID", ds.Tables["regionsettings"]);
+            da.UpdateCommand.Connection = conn;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="da"></param>
+        /// <param name="conn"></param>
+        private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn)
+        {
+            da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]);
+            da.InsertCommand.Connection = conn;
+
+            da.UpdateCommand = createUpdateCommand("primshapes", "UUID=:UUID", ds.Tables["primshapes"]);
+            da.UpdateCommand.Connection = conn;
+
+            SqliteCommand delete = new SqliteCommand("delete from primshapes where UUID = :UUID");
+            delete.Parameters.Add(createSqliteParameter("UUID", typeof (String)));
+            delete.Connection = conn;
+            da.DeleteCommand = delete;
+        }
+
+        /***********************************************************************
+         *
+         *  Type conversion functions
+         *
+         **********************************************************************/
+
+        /// <summary>
+        /// Type conversion function
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        private static DbType dbtypeFromType(Type type)
+        {
+            if (type == typeof (String))
+            {
+                return DbType.String;
+            }
+            else if (type == typeof (Int32))
+            {
+                return DbType.Int32;
+            }
+            else if (type == typeof (Double))
+            {
+                return DbType.Double;
+            }
+            else if (type == typeof (Byte))
+            {
+                return DbType.Byte;
+            }
+            else if (type == typeof (Double))
+            {
+                return DbType.Double;
+            }
+            else if (type == typeof (Byte[]))
+            {
+                return DbType.Binary;
+            }
+            else
+            {
+                return DbType.String;
+            }
+        }
+
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs b/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs
new file mode 100644
index 0000000..67cf716
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+    public class SQLiteUserAccountData : SQLiteGenericTableHandler<UserAccountData>, IUserAccountData
+    {
+        public SQLiteUserAccountData(string connectionString, string realm)
+                : base(connectionString, realm, "UserAccount")
+        {
+        }
+
+        public UserAccountData[] GetUsers(UUID scopeID, string query)
+        {
+            string[] words = query.Split(new char[] {' '});
+
+            for (int i = 0 ; i < words.Length ; i++)
+            {
+                if (words[i].Length < 3)
+                {
+                    if (i != words.Length - 1)
+                        Array.Copy(words, i + 1, words, i, words.Length - i - 1);
+                    Array.Resize(ref words, words.Length - 1);
+                }
+            }
+
+            if (words.Length == 0)
+                return new UserAccountData[0];
+
+            if (words.Length > 2)
+                return new UserAccountData[0];
+
+            SqliteCommand cmd = new SqliteCommand();
+
+            if (words.Length == 1)
+            {
+                cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{2}%')",
+                    m_Realm, scopeID.ToString(), words[0]);
+            }
+            else
+            {
+                cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{3}%')", 
+                    m_Realm, scopeID.ToString(), words[0], words[1]);
+            }
+
+            return DoQuery(cmd);
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteUtils.cs b/OpenSim/Data/SQLiteNG/SQLiteUtils.cs
new file mode 100644
index 0000000..4a835ce
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteUtils.cs
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Data;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+    /// <summary>
+    /// A base class for methods needed by all SQLite database classes
+    /// </summary>
+    public class SQLiteUtil
+    {
+        /***********************************************************************
+         *
+         *  Database Definition Helper Functions
+         *
+         *  This should be db agnostic as we define them in ADO.NET terms
+         *
+         **********************************************************************/
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="dt"></param>
+        /// <param name="name"></param>
+        /// <param name="type"></param>
+        public static void createCol(DataTable dt, string name, Type type)
+        {
+            DataColumn col = new DataColumn(name, type);
+            dt.Columns.Add(col);
+        }
+
+        /***********************************************************************
+         *
+         *  SQL Statement Creation Functions
+         *
+         *  These functions create SQL statements for update, insert, and create.
+         *  They can probably be factored later to have a db independant
+         *  portion and a db specific portion
+         *
+         **********************************************************************/
+
+        /// <summary>
+        /// Create an insert command
+        /// </summary>
+        /// <param name="table">table name</param>
+        /// <param name="dt">data table</param>
+        /// <returns>the created command</returns>
+        /// <remarks>
+        /// This is subtle enough to deserve some commentary.
+        /// Instead of doing *lots* and *lots of hardcoded strings
+        /// for database definitions we'll use the fact that
+        /// realistically all insert statements look like "insert
+        /// into A(b, c) values(:b, :c) on the parameterized query
+        /// front.  If we just have a list of b, c, etc... we can
+        /// generate these strings instead of typing them out.
+        /// </remarks>
+        public static SqliteCommand createInsertCommand(string table, DataTable dt)
+        {
+
+            string[] cols = new string[dt.Columns.Count];
+            for (int i = 0; i < dt.Columns.Count; i++)
+            {
+                DataColumn col = dt.Columns[i];
+                cols[i] = col.ColumnName;
+            }
+
+            string sql = "insert into " + table + "(";
+            sql += String.Join(", ", cols);
+            // important, the first ':' needs to be here, the rest get added in the join
+            sql += ") values (:";
+            sql += String.Join(", :", cols);
+            sql += ")";
+            SqliteCommand cmd = new SqliteCommand(sql);
+
+            // this provides the binding for all our parameters, so
+            // much less code than it used to be
+            foreach (DataColumn col in dt.Columns)
+            {
+                cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
+            }
+            return cmd;
+        }
+
+        /// <summary>
+        /// create an update command
+        /// </summary>
+        /// <param name="table">table name</param>
+        /// <param name="pk"></param>
+        /// <param name="dt"></param>
+        /// <returns>the created command</returns>
+        public static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt)
+        {
+            string sql = "update " + table + " set ";
+            string subsql = String.Empty;
+            foreach (DataColumn col in dt.Columns)
+            {
+                if (subsql.Length > 0)
+                {
+                    // a map function would rock so much here
+                    subsql += ", ";
+                }
+                subsql += col.ColumnName + "= :" + col.ColumnName;
+            }
+            sql += subsql;
+            sql += " where " + pk;
+            SqliteCommand cmd = new SqliteCommand(sql);
+
+            // this provides the binding for all our parameters, so
+            // much less code than it used to be
+
+            foreach (DataColumn col in dt.Columns)
+            {
+                cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
+            }
+            return cmd;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="dt">Data Table</param>
+        /// <returns></returns>
+        public static string defineTable(DataTable dt)
+        {
+            string sql = "create table " + dt.TableName + "(";
+            string subsql = String.Empty;
+            foreach (DataColumn col in dt.Columns)
+            {
+                if (subsql.Length > 0)
+                {
+                    // a map function would rock so much here
+                    subsql += ",\n";
+                }
+                subsql += col.ColumnName + " " + sqliteType(col.DataType);
+                if (dt.PrimaryKey.Length > 0)
+                {
+                    if (col == dt.PrimaryKey[0])
+                    {
+                        subsql += " primary key";
+                    }
+                }
+            }
+            sql += subsql;
+            sql += ")";
+            return sql;
+        }
+
+        /***********************************************************************
+         *
+         *  Database Binding functions
+         *
+         *  These will be db specific due to typing, and minor differences
+         *  in databases.
+         *
+         **********************************************************************/
+
+        ///<summary>
+        /// <para>
+        /// This is a convenience function that collapses 5 repetitive
+        /// lines for defining SqliteParameters to 2 parameters:
+        /// column name and database type.
+        /// </para>
+        /// 
+        /// <para>
+        /// It assumes certain conventions like :param as the param
+        /// name to replace in parametrized queries, and that source
+        /// version is always current version, both of which are fine
+        /// for us.
+        /// </para>
+        ///</summary>
+        /// <param name="name"></param>
+        /// <param name="type"></param>
+        ///<returns>a built sqlite parameter</returns>
+        public static SqliteParameter createSqliteParameter(string name, Type type)
+        {
+            SqliteParameter param = new SqliteParameter();
+            param.ParameterName = ":" + name;
+            param.DbType = dbtypeFromType(type);
+            param.SourceColumn = name;
+            param.SourceVersion = DataRowVersion.Current;
+            return param;
+        }
+
+        /***********************************************************************
+         *
+         *  Type conversion functions
+         *
+         **********************************************************************/
+
+        /// <summary>
+        /// Type conversion function
+        /// </summary>
+        /// <param name="type">a type</param>
+        /// <returns>a DbType</returns>
+        public static DbType dbtypeFromType(Type type)
+        {
+            if (type == typeof (String))
+            {
+                return DbType.String;
+            }
+            else if (type == typeof (Int32))
+            {
+                return DbType.Int32;
+            }
+            else if (type == typeof (UInt32))
+            {
+                return DbType.UInt32;
+            }
+            else if (type == typeof (Int64))
+            {
+                return DbType.Int64;
+            }
+            else if (type == typeof (UInt64))
+            {
+                return DbType.UInt64;
+            }
+            else if (type == typeof (Double))
+            {
+                return DbType.Double;
+            }
+            else if (type == typeof (Boolean))
+            {
+                return DbType.Boolean;
+            }
+            else if (type == typeof (Byte[]))
+            {
+                return DbType.Binary;
+            }
+            else
+            {
+                return DbType.String;
+            }
+        }
+
+        /// <summary>
+        /// </summary>
+        /// <param name="type">a Type</param>
+        /// <returns>a string</returns>
+        /// <remarks>this is something we'll need to implement for each db slightly differently.</remarks>
+        public static string sqliteType(Type type)
+        {
+            if (type == typeof (String))
+            {
+                return "varchar(255)";
+            }
+            else if (type == typeof (Int32))
+            {
+                return "integer";
+            }
+            else if (type == typeof (UInt32))
+            {
+                return "integer";
+            }
+            else if (type == typeof (Int64))
+            {
+                return "varchar(255)";
+            }
+            else if (type == typeof (UInt64))
+            {
+                return "varchar(255)";
+            }
+            else if (type == typeof (Double))
+            {
+                return "float";
+            }
+            else if (type == typeof (Boolean))
+            {
+                return "integer";
+            }
+            else if (type == typeof (Byte[]))
+            {
+                return "blob";
+            }
+            else
+            {
+                return "string";
+            }
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs b/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs
new file mode 100644
index 0000000..a66e0c6
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Data;
+using System.Reflection;
+using System.Collections.Generic;
+using Mono.Data.SqliteClient;
+using log4net;
+using OpenMetaverse;
+using OpenSim.Framework;
+
+namespace OpenSim.Data.SQLite
+{
+    /// <summary>
+    /// A MySQL Interface for the Asset Server
+    /// </summary>
+    public class SQLiteXInventoryData : IXInventoryData
+    {
+//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        private SQLiteGenericTableHandler<XInventoryFolder> m_Folders;
+        private SqliteItemHandler m_Items;
+
+        public SQLiteXInventoryData(string conn, string realm)
+        {
+            m_Folders = new SQLiteGenericTableHandler<XInventoryFolder>(
+                    conn, "inventoryfolders", "InventoryStore");
+            m_Items = new SqliteItemHandler(
+                    conn, "inventoryitems", String.Empty);
+        }
+
+        public XInventoryFolder[] GetFolders(string[] fields, string[] vals)
+        {
+            return m_Folders.Get(fields, vals);
+        }
+
+        public XInventoryItem[] GetItems(string[] fields, string[] vals)
+        {
+            return m_Items.Get(fields, vals);
+        }
+
+        public bool StoreFolder(XInventoryFolder folder)
+        {
+            return m_Folders.Store(folder);
+        }
+
+        public bool StoreItem(XInventoryItem item)
+        {
+            return m_Items.Store(item);
+        }
+
+        public bool DeleteFolders(string field, string val)
+        {
+            return m_Folders.Delete(field, val);
+        }
+
+        public bool DeleteItems(string field, string val)
+        {
+            return m_Items.Delete(field, val);
+        }
+
+        public bool MoveItem(string id, string newParent)
+        {
+            return m_Items.MoveItem(id, newParent);
+        }
+
+        public XInventoryItem[] GetActiveGestures(UUID principalID)
+        {
+            return m_Items.GetActiveGestures(principalID);
+        }
+
+        public int GetAssetPermissions(UUID principalID, UUID assetID)
+        {
+            return m_Items.GetAssetPermissions(principalID, assetID);
+        }
+    }
+
+    public class SqliteItemHandler : SQLiteGenericTableHandler<XInventoryItem>
+    {
+        public SqliteItemHandler(string c, string t, string m) :
+                base(c, t, m)
+        {
+        }
+
+        public bool MoveItem(string id, string newParent)
+        {
+            SqliteCommand cmd = new SqliteCommand();
+
+            cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm);
+            cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent));
+            cmd.Parameters.Add(new SqliteParameter(":InventoryID", id));
+
+            return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true;
+        }
+
+        public XInventoryItem[] GetActiveGestures(UUID principalID)
+        {
+            SqliteCommand cmd  = new SqliteCommand();
+            cmd.CommandText = String.Format("select * from inventoryitems where avatarId = :uuid and assetType = :type and flags = 1", m_Realm);
+
+            cmd.Parameters.Add(new SqliteParameter(":uuid", principalID.ToString()));
+            cmd.Parameters.Add(new SqliteParameter(":type", (int)AssetType.Gesture));
+
+            return DoQuery(cmd);
+        }
+
+        public int GetAssetPermissions(UUID principalID, UUID assetID)
+        {
+            SqliteCommand cmd = new SqliteCommand();
+
+            cmd.CommandText = String.Format("select inventoryCurrentPermissions from inventoryitems where avatarID = :PrincipalID and assetID = :AssetID", m_Realm);
+            cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
+            cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString()));
+
+            IDataReader reader = ExecuteReader(cmd, m_Connection);
+
+            int perms = 0;
+
+            while (reader.Read())
+            {
+                perms |= Convert.ToInt32(reader["inventoryCurrentPermissions"]);
+            }
+
+            reader.Close();
+            CloseCommand(cmd);
+
+            return perms;
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs b/OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs
new file mode 100644
index 0000000..0c2f5df
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.IO;
+using NUnit.Framework;
+using OpenSim.Data.Tests;
+using OpenSim.Tests.Common;
+
+namespace OpenSim.Data.SQLite.Tests
+{
+    [TestFixture, DatabaseTest]
+    public class SQLiteAssetTest : BasicAssetTest
+    {
+        public string file;
+        public string connect;
+        
+        [TestFixtureSetUp]
+        public void Init()
+        {
+            // SQLite doesn't work on power or z linux
+            if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
+            {
+                Assert.Ignore();
+            }
+
+            SuperInit();
+            file = Path.GetTempFileName() + ".db";
+            connect = "URI=file:" + file + ",version=3";
+            db = new SQLiteAssetData();
+            db.Initialise(connect);
+        }
+
+        [TestFixtureTearDown]
+        public void Cleanup()
+        {
+            db.Dispose();
+            File.Delete(file);
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs b/OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs
new file mode 100644
index 0000000..30f6641
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.IO;
+using NUnit.Framework;
+using OpenSim.Data.Tests;
+using OpenSim.Tests.Common;
+
+namespace OpenSim.Data.SQLite.Tests
+{
+    [TestFixture, DatabaseTest]
+    public class SQLiteEstateTest : BasicEstateTest
+    {
+        public string file = "regiontest.db";
+        public string connect;
+        
+        [TestFixtureSetUp]
+        public void Init()
+        {
+            // SQLite doesn't work on power or z linux
+            if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
+            {
+                Assert.Ignore();
+            }
+
+            SuperInit();
+            file = Path.GetTempFileName() + ".db";
+            connect = "URI=file:" + file + ",version=3";
+            db = new SQLiteEstateStore();
+            db.Initialise(connect);
+            regionDb = new SQLiteRegionData();
+            regionDb.Initialise(connect);
+        }
+
+        [TestFixtureTearDown]
+        public void Cleanup()
+        {
+            regionDb.Dispose();
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs b/OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs
new file mode 100644
index 0000000..98458a3
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.IO;
+using NUnit.Framework;
+using OpenSim.Data.Tests;
+using OpenSim.Tests.Common;
+
+namespace OpenSim.Data.SQLite.Tests
+{
+    [TestFixture, DatabaseTest]
+    public class SQLiteInventoryTest : BasicInventoryTest
+    {
+        public string file;
+        public string connect;
+        
+        [TestFixtureSetUp]
+        public void Init()
+        {
+            // SQLite doesn't work on power or z linux
+            if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
+            {
+                Assert.Ignore();
+            }
+
+            SuperInit();
+            
+            file = Path.GetTempFileName() + ".db";
+            connect = "URI=file:" + file + ",version=3";
+            
+            db = new SQLiteInventoryStore();
+            db.Initialise(connect);
+        }
+
+        [TestFixtureTearDown]
+        public void Cleanup()
+        {
+            db.Dispose();
+            File.Delete(file);
+        }
+    }
+}
diff --git a/OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs b/OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs
new file mode 100644
index 0000000..abb97cf
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.IO;
+using NUnit.Framework;
+using OpenSim.Data.Tests;
+using OpenSim.Tests.Common;
+
+namespace OpenSim.Data.SQLite.Tests
+{
+    [TestFixture, DatabaseTest]
+    public class SQLiteRegionTest : BasicRegionTest
+    {
+        public string file = "regiontest.db";
+        public string connect;
+        
+        [TestFixtureSetUp]
+        public void Init()
+        {
+            // SQLite doesn't work on power or z linux
+            if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
+            {
+                Assert.Ignore();
+            }
+
+            SuperInit();
+            file = Path.GetTempFileName() + ".db";
+            connect = "URI=file:" + file + ",version=3";
+            db = new SQLiteRegionData();
+            db.Initialise(connect);
+        }
+
+        [TestFixtureTearDown]
+        public void Cleanup()
+        {
+            db.Dispose();
+            File.Delete(file);
+        }
+    }
+}
-- 
cgit v1.1