diff lib/AceDB-2.0/AceDB-2.0.lua @ 22:1b9323256a1b

Merging in 1.0 dev tree
author Flick <flickerstreak@gmail.com>
date Fri, 07 Mar 2008 22:10:55 +0000
parents libs/AceDB-2.0/AceDB-2.0.lua@c11ca1d8ed91
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/AceDB-2.0/AceDB-2.0.lua	Fri Mar 07 22:10:55 2008 +0000
@@ -0,0 +1,2187 @@
+--[[
+Name: AceDB-2.0
+Revision: $Rev: 46764 $
+Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
+Inspired By: Ace 1.x by Turan (turan@gryphon.com)
+Website: http://www.wowace.com/
+Documentation: http://www.wowace.com/index.php/AceDB-2.0
+SVN: http://svn.wowace.com/root/trunk/Ace2/AceDB-2.0
+Description: Mixin to allow for fast, clean, and featureful saved variable
+             access.
+Dependencies: AceLibrary, AceOO-2.0, AceEvent-2.0
+License: LGPL v2.1
+]]
+
+local MAJOR_VERSION = "AceDB-2.0"
+local MINOR_VERSION = "$Revision: 46764 $"
+
+if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
+if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
+
+if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
+
+local function safecall(func,...)
+	local success, err = pcall(func,...)
+	if not success then geterrorhandler()(err) end
+end
+
+local ACTIVE, ENABLED, STATE, TOGGLE_ACTIVE, MAP_ACTIVESUSPENDED, SET_PROFILE, SET_PROFILE_USAGE, PROFILE, PLAYER_OF_REALM, CHOOSE_PROFILE_DESC, CHOOSE_PROFILE_GUI, COPY_PROFILE_DESC, COPY_PROFILE_GUI, OTHER_PROFILE_DESC, OTHER_PROFILE_GUI, OTHER_PROFILE_USAGE, RESET_PROFILE, RESET_PROFILE_DESC, CHARACTER_COLON, REALM_COLON, CLASS_COLON, DEFAULT, ALTERNATIVE
+
+-- Move these into "enUS" when they've been translated in all other locales
+local DELETE_PROFILE = "Delete"
+local DELETE_PROFILE_DESC = "Deletes a profile. Note that no check is made whether this profile is in use by other characters or not."
+local DELETE_PROFILE_USAGE = "<profile name>"
+
+if GetLocale() == "deDE" then
+	ACTIVE = "Aktiv"
+	ENABLED = "Aktiviert"
+	STATE = "Status"
+	TOGGLE_ACTIVE = "Stoppt/Aktiviert dieses Addon."
+	MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Aktiv|r", [false] = "|cffff0000Gestoppt|r" }
+	SET_PROFILE = "Setzt das Profil f\195\188r dieses Addon."
+	SET_PROFILE_USAGE = "{Charakter || Klasse || Realm || <Profilname>}"
+	PROFILE = "Profil"
+	PLAYER_OF_REALM = "%s von %s"
+	CHOOSE_PROFILE_DESC = "W\195\164hle ein Profil."
+	CHOOSE_PROFILE_GUI = "W\195\164hle"
+	COPY_PROFILE_DESC = "Kopiert Einstellungen von einem anderem Profil."
+	COPY_PROFILE_GUI = "Kopiere von"
+	OTHER_PROFILE_DESC = "W\195\164hle ein anderes Profil."
+	OTHER_PROFILE_GUI = "Anderes"
+	OTHER_PROFILE_USAGE = "<Profilname>"
+	RESET_PROFILE = "Reset profile" -- fix
+	RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix
+
+	CHARACTER_COLON = "Charakter: "
+	REALM_COLON = "Realm: "
+	CLASS_COLON = "Klasse: "
+
+	DEFAULT = "Default" -- fix
+	ALTERNATIVE = "Alternative" -- fix
+elseif GetLocale() == "frFR" then
+	ACTIVE = "Actif"
+	ENABLED = "Activ\195\169"
+	STATE = "Etat"
+	TOGGLE_ACTIVE = "Suspend/active cet addon."
+	MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Actif|r", [false] = "|cffff0000Suspendu|r" }
+	SET_PROFILE = "S\195\169lectionne le profil pour cet addon."
+	SET_PROFILE_USAGE = "{perso || classe || royaume || <nom de profil>}"
+	PROFILE = "Profil"
+	PLAYER_OF_REALM = "%s de %s"
+	CHOOSE_PROFILE_DESC = "Choisissez un profil."
+	CHOOSE_PROFILE_GUI = "Choix"
+	COPY_PROFILE_DESC = "Copier les param\195\168tres d'un autre profil."
+	COPY_PROFILE_GUI = "Copier \195\160 partir de"
+	OTHER_PROFILE_DESC = "Choisissez un autre profil."
+	OTHER_PROFILE_GUI = "Autre"
+	OTHER_PROFILE_USAGE = "<nom de profil>"
+	RESET_PROFILE = "Reset profile" -- fix
+	RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix
+
+	CHARACTER_COLON = "Personnage: "
+	REALM_COLON = "Royaume: "
+	CLASS_COLON = "Classe: "
+
+	DEFAULT = "Default" -- fix
+	ALTERNATIVE = "Alternative" -- fix
+elseif GetLocale() == "koKR" then
+	DELETE_PROFILE = "삭제"
+	DELETE_PROFILE_DESC = "프로필을 삭제합니다."
+	DELETE_PROFILE_USAGE = "<프로필명>"
+
+	ACTIVE = "사용"
+	ENABLED = "사용"
+	STATE = "상태"
+	TOGGLE_ACTIVE = "이 애드온 중지/다시 시작"
+	MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00사용|r", [false] = "|cffff0000중지|r" }
+	SET_PROFILE = "이 애드온에 프로필 설정"
+	SET_PROFILE_USAGE = "{캐릭터명 || 직업 || 서버명 || <프로필명>}"
+	PROFILE = "프로필"
+	PLAYER_OF_REALM = "%s (%s 서버)"
+	CHOOSE_PROFILE_DESC = "프로필을 선택합니다."
+	CHOOSE_PROFILE_GUI = "선택"
+	COPY_PROFILE_DESC = "다른 프로필 설정을 복사합니다."
+	COPY_PROFILE_GUI = "복사"
+	OTHER_PROFILE_DESC = "다른 프로필을 선택합니다."
+	OTHER_PROFILE_GUI = "기타"
+	OTHER_PROFILE_USAGE = "<프로필명>"
+	RESET_PROFILE = "프로필 초기화"
+	RESET_PROFILE_DESC = "모든 세팅에서 현재 프로필을 초기화 합니다."
+
+	CHARACTER_COLON = "캐릭터: "
+	REALM_COLON = "서버: "
+	CLASS_COLON = "직업: "
+
+	DEFAULT = "기본값"
+	ALTERNATIVE = "대체"
+elseif GetLocale() == "zhTW" then
+	DELETE_PROFILE = "刪除"
+	DELETE_PROFILE_DESC = "刪除記錄檔。注意,有可能別的角色也使用這個記錄檔。"
+	DELETE_PROFILE_USAGE = "<記錄檔名稱>"
+
+	ACTIVE = "啟動"
+	ENABLED = "啟用"
+	STATE = "狀態"
+	TOGGLE_ACTIVE = "暫停/繼續使用這個插件。"
+	MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00啟動|r", [false] = "|cffff0000已暫停|r" }
+	SET_PROFILE = "設定這插件的記錄檔。"
+	SET_PROFILE_USAGE = "{角色 || 職業 || 伺服器 || <記錄檔名稱>}"
+	PROFILE = "記錄檔"
+	PLAYER_OF_REALM = "%s - %s"
+	CHOOSE_PROFILE_DESC = "選擇一個記錄檔。"
+	CHOOSE_PROFILE_GUI = "選擇"
+	COPY_PROFILE_DESC = "由其他記錄檔複製設定。"
+	COPY_PROFILE_GUI = "複製自"
+	OTHER_PROFILE_DESC = "選擇其他記錄檔。"
+	OTHER_PROFILE_GUI = "其他"
+	OTHER_PROFILE_USAGE = "<記錄檔名稱>"
+	RESET_PROFILE = "重設記錄檔"
+	RESET_PROFILE_DESC = "清除目前的記錄檔上的所有設定。"
+
+	CHARACTER_COLON = "角色: "
+	REALM_COLON = "伺服器: "
+	CLASS_COLON = "職業: "
+
+	DEFAULT = "預設"
+	ALTERNATIVE = "替代"
+elseif GetLocale() == "zhCN" then
+	ACTIVE = "\230\156\137\230\149\136"
+	ENABLED = "\229\144\175\231\148\168"
+	STATE = "\231\138\182\230\128\129"
+	TOGGLE_ACTIVE = "\230\154\130\229\129\156/\230\129\162\229\164\141 \230\173\164\230\143\146\228\187\182."
+	MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00\230\156\137\230\149\136|r", [false] = "|cffff0000\230\154\130\229\129\156|r" }
+	SET_PROFILE = "\232\174\190\231\189\174\233\133\141\231\189\174\230\150\135\228\187\182\228\184\186\232\191\153\230\143\146\228\187\182."
+	SET_PROFILE_USAGE = "{\229\173\151\231\172\166 || \233\128\137\228\187\182\231\177\187 || \229\159\159 || <\233\133\141\231\189\174\230\150\135\228\187\182\229\144\141\229\173\151>}"
+	PROFILE = "\233\133\141\231\189\174\230\150\135\228\187\182"
+	PLAYER_OF_REALM = "%s \231\154\132 %s"
+	CHOOSE_PROFILE_DESC = "\233\128\137\230\139\169\233\133\141\231\189\174\230\150\135\228\187\182."
+	CHOOSE_PROFILE_GUI = "\233\128\137\230\139\169"
+	COPY_PROFILE_DESC = "\229\164\141\229\136\182\232\174\190\231\189\174\228\187\142\229\143\166\228\184\128\228\184\170\233\133\141\231\189\174\230\150\135\228\187\182."
+	COPY_PROFILE_GUI = "\229\164\141\229\136\182\228\187\142"
+	OTHER_PROFILE_DESC = "\233\128\137\230\139\169\229\143\166\228\184\128\228\184\170\233\133\141\231\189\174\230\150\135\228\187\182."
+	OTHER_PROFILE_GUI = "\229\133\182\228\187\150"
+	OTHER_PROFILE_USAGE = "<\233\133\141\231\189\174\230\150\135\228\187\182\229\144\141\229\173\151>"
+	RESET_PROFILE = "Reset profile" -- fix
+	RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix
+
+	CHARACTER_COLON = "\229\173\151\231\172\166: "
+	REALM_COLON = "\229\159\159: "
+	CLASS_COLON = "\233\128\137\228\187\182\231\177\187: "
+
+	DEFAULT = "Default" -- fix
+	ALTERNATIVE = "Alternative" -- fix
+elseif GetLocale() == "esES" then
+	ACTIVE = "Activo"
+	ENABLED = "Activado"
+	STATE = "Estado"
+	TOGGLE_ACTIVE = "Parar/Continuar este accesorio"
+	MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Activo|r", [false] = "|cffff0000Parado|r" }
+	SET_PROFILE = "Selecciona el perfil para este accesorio."
+	SET_PROFILE_USAGE = "{perso || clase || reino || <nombre del perfil>}"
+	PROFILE = "Perfil"
+	PLAYER_OF_REALM = "%s de %s"
+	CHOOSE_PROFILE_DESC = "Elige un perfil."
+	CHOOSE_PROFILE_GUI = "Elige"
+	COPY_PROFILE_DESC = "Copiar de un perfil a otro"
+	COPY_PROFILE_GUI = "Copiar desde"
+	OTHER_PROFILE_DESC = "Elige otro perfil."
+	OTHER_PROFILE_GUI = "Otro"
+	OTHER_PROFILE_USAGE = "<nombre del perfil>"
+	RESET_PROFILE = "Reset profile" -- fix
+	RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix
+
+	CHARACTER_COLON = "Personaje: "
+	REALM_COLON = "Reino: "
+	CLASS_COLON = "Clase: "
+
+	DEFAULT = "Por defecto"
+	ALTERNATIVE = "Alternativo"
+else -- enUS
+	ACTIVE = "Active"
+	ENABLED = "Enabled"
+	STATE = "State"
+	TOGGLE_ACTIVE = "Suspend/resume this addon."
+	MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Active|r", [false] = "|cffff0000Suspended|r" }
+	SET_PROFILE = "Set profile for this addon."
+	SET_PROFILE_USAGE = "{char || class || realm || <profile name>}"
+	PROFILE = "Profile"
+	PLAYER_OF_REALM = "%s of %s"
+	CHOOSE_PROFILE_DESC = "Choose a profile."
+	CHOOSE_PROFILE_GUI = "Choose"
+	COPY_PROFILE_DESC = "Copy settings from another profile."
+	COPY_PROFILE_GUI = "Copy from"
+	OTHER_PROFILE_DESC = "Choose another profile."
+	OTHER_PROFILE_GUI = "Other"
+	OTHER_PROFILE_USAGE = "<profile name>"
+	RESET_PROFILE = "Reset profile"
+	RESET_PROFILE_DESC = "Clear all settings of the current profile."
+
+	CHARACTER_COLON = "Character: "
+	REALM_COLON = "Realm: "
+	CLASS_COLON = "Class: "
+
+	DEFAULT = "Default"
+	ALTERNATIVE = "Alternative"
+end
+local convertFromOldCharID
+do
+	local matchStr = "^" .. PLAYER_OF_REALM:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1"):gsub("%%s", "(.+)") .. "$"
+	function convertFromOldCharID(str)
+		local player, realm = str:match(matchStr)
+		if not player then
+			return str
+		end
+		return player .. " - " .. realm
+	end
+end
+
+local AceOO = AceLibrary("AceOO-2.0")
+local AceEvent
+local Mixin = AceOO.Mixin
+local AceDB = Mixin {
+						"RegisterDB",
+						"RegisterDefaults",
+						"ResetDB",
+						"SetProfile",
+						"GetProfile",
+						"CopyProfileFrom",
+						"DeleteProfile",
+						"ToggleActive",
+						"IsActive",
+						"AcquireDBNamespace",
+					}
+local Dewdrop = AceLibrary:HasInstance("Dewdrop-2.0") and AceLibrary("Dewdrop-2.0")
+
+local _G = getfenv(0)
+
+local function inheritDefaults(t, defaults)
+	if not defaults then
+		return t
+	end
+	for k,v in pairs(defaults) do
+		if k == "*" or k == "**" then
+			local v = v
+			if type(v) == "table" then
+				setmetatable(t, {
+					__index = function(self, key)
+						if key == nil then
+							return nil
+						end
+						self[key] = {}
+						inheritDefaults(self[key], v)
+						return self[key]
+					end
+				} )
+			else
+				setmetatable(t, {
+					__index = function(self, key)
+						if key == nil then
+							return nil
+						end
+						self[key] = v
+						return self[key]
+					end
+				} )
+			end
+			for key in pairs(t) do
+				if (defaults[key] == nil or key == k) and type(t[key]) == "table" then
+					inheritDefaults(t[key], v)
+				end
+			end
+		else
+			if type(v) == "table" then
+				if type(rawget(t, k)) ~= "table" then
+					t[k] = {}
+				end
+				inheritDefaults(t[k], v)
+				if defaults["**"] then
+					inheritDefaults(t[k], defaults["**"])
+				end
+			elseif rawget(t, k) == nil then
+				t[k] = v
+			end
+		end
+	end
+	return t
+end
+
+local _,race = UnitRace("player")
+local faction
+if race == "Orc" or race == "Scourge" or race == "Troll" or race == "Tauren" or race == "BloodElf" then
+	faction = FACTION_HORDE
+else
+	faction = FACTION_ALLIANCE
+end
+local server = GetRealmName():trim()
+local charID = UnitName("player") .. " - " .. server
+local realmID = server .. " - " .. faction
+local classID = UnitClass("player")
+
+AceDB.CHAR_ID = charID
+AceDB.REALM_ID = realmID
+AceDB.CLASS_ID = classID
+
+AceDB.FACTION = faction
+AceDB.REALM = server
+AceDB.NAME = UnitName("player")
+
+local new, del
+do
+	local list = setmetatable({}, {__mode="k"})
+	function new()
+		local t = next(list)
+		if t then
+			list[t] = nil
+			return t
+		else
+			return {}
+		end
+	end
+
+	function del(t)
+		setmetatable(t, nil)
+		for k in pairs(t) do
+			t[k] = nil
+		end
+		list[t] = true
+	end
+end
+
+local caseInsensitive_mt = {
+	__index = function(self, key)
+		if type(key) ~= "string" then
+			return nil
+		end
+		local lowerKey = key:lower()
+		for k,v in pairs(self) do
+			if k:lower() == lowerKey then
+				return self[k]
+			end
+		end
+	end,
+	__newindex = function(self, key, value)
+		if type(key) ~= "string" then
+			return error("table index is nil", 2)
+		end
+		local lowerKey = key:lower()
+		for k in pairs(self) do
+			if k:lower() == lowerKey then
+				rawset(self, k, nil)
+				rawset(self, key, value)
+				return
+			end
+		end
+		rawset(self, key, value)
+	end
+}
+
+local db_mt = { __index = function(db, key)
+	if key == "char" then
+		if db.charName then
+			if type(_G[db.charName]) ~= "table" then
+				_G[db.charName] = {}
+			end
+			if type(_G[db.charName].global) ~= "table" then
+				_G[db.charName].global = {}
+			end
+			rawset(db, 'char', _G[db.charName].global)
+		else
+			if type(db.raw.chars) ~= "table" then
+				db.raw.chars = {}
+			end
+			local id = charID
+			if type(db.raw.chars[id]) ~= "table" then
+				db.raw.chars[id] = {}
+			end
+			rawset(db, 'char', db.raw.chars[id])
+		end
+		if db.defaults and db.defaults.char then
+			inheritDefaults(db.char, db.defaults.char)
+		end
+		return db.char
+	elseif key == "realm" then
+		if type(db.raw.realms) ~= "table" then
+			db.raw.realms = {}
+		end
+		local id = realmID
+		if type(db.raw.realms[id]) ~= "table" then
+			db.raw.realms[id] = {}
+		end
+		rawset(db, 'realm', db.raw.realms[id])
+		if db.defaults and db.defaults.realm then
+			inheritDefaults(db.realm, db.defaults.realm)
+		end
+		return db.realm
+	elseif key == "server" then
+		if type(db.raw.servers) ~= "table" then
+			db.raw.servers = {}
+		end
+		local id = server
+		if type(db.raw.servers[id]) ~= "table" then
+			db.raw.servers[id] = {}
+		end
+		rawset(db, 'server', db.raw.servers[id])
+		if db.defaults and db.defaults.server then
+			inheritDefaults(db.server, db.defaults.server)
+		end
+		return db.server
+	elseif key == "account" then
+		if type(db.raw.account) ~= "table" then
+			db.raw.account = {}
+		end
+		rawset(db, 'account', db.raw.account)
+		if db.defaults and db.defaults.account then
+			inheritDefaults(db.account, db.defaults.account)
+		end
+		return db.account
+	elseif key == "faction" then
+		if type(db.raw.factions) ~= "table" then
+			db.raw.factions = {}
+		end
+		local id = faction
+		if type(db.raw.factions[id]) ~= "table" then
+			db.raw.factions[id] = {}
+		end
+		rawset(db, 'faction', db.raw.factions[id])
+		if db.defaults and db.defaults.faction then
+			inheritDefaults(db.faction, db.defaults.faction)
+		end
+		return db.faction
+	elseif key == "class" then
+		if type(db.raw.classes) ~= "table" then
+			db.raw.classes = {}
+		end
+		local id = classID
+		if type(db.raw.classes[id]) ~= "table" then
+			db.raw.classes[id] = {}
+		end
+		rawset(db, 'class', db.raw.classes[id])
+		if db.defaults and db.defaults.class then
+			inheritDefaults(db.class, db.defaults.class)
+		end
+		return db.class
+	elseif key == "profile" then
+		if type(db.raw.profiles) ~= "table" then
+			db.raw.profiles = setmetatable({}, caseInsensitive_mt)
+		else
+			setmetatable(db.raw.profiles, caseInsensitive_mt)
+		end
+		local id = db.raw.currentProfile[charID]
+		if id == "char" then
+			id = "char/" .. charID
+		elseif id == "class" then
+			id = "class/" .. classID
+		elseif id == "realm" then
+			id = "realm/" .. realmID
+		end
+		if type(db.raw.profiles[id]) ~= "table" then
+			db.raw.profiles[id] = {}
+		end
+		rawset(db, 'profile', db.raw.profiles[id])
+		if db.defaults and db.defaults.profile then
+			inheritDefaults(db.profile, db.defaults.profile)
+		end
+		return db.profile
+	elseif key == "raw" or key == "defaults" or key == "name" or key == "charName" or key == "namespaces" then
+		return nil
+	end
+	error(("Cannot access key %q in db table. You may want to use db.profile[%q]"):format(tostring(key), tostring(key)), 2)
+end, __newindex = function(db, key, value)
+	error(("Cannot access key %q in db table. You may want to use db.profile[%q]"):format(tostring(key), tostring(key)), 2)
+end }
+
+local function RecalculateAceDBCopyFromList(target)
+	local db = target.db
+	local t = target['acedb-profile-copylist']
+	for k,v in pairs(t) do
+		t[k] = nil
+	end
+	local _,currentProfile = AceDB.GetProfile(target)
+	if db and db.raw then
+		if db.raw.profiles then
+			for k in pairs(db.raw.profiles) do
+				if currentProfile ~= k then
+					if k:find("^char/") then
+						local name = k:sub(6)
+						local player, realm = name:match("^(.*) %- (.*)$")
+						if player then
+							name = PLAYER_OF_REALM:format(player, realm)
+						end
+						t[k] = CHARACTER_COLON .. name
+					elseif k:find("^realm/") then
+						local name = k:sub(7)
+						t[k] = REALM_COLON .. name
+					elseif k:find("^class/") then
+						local name = k:sub(7)
+						t[k] = CLASS_COLON .. name
+					else
+						t[k] = k
+					end
+				end
+			end
+		end
+		if db.raw.namespaces then
+			for _,n in pairs(db.raw.namespaces) do
+				if n.profiles then
+					for k in pairs(n.profiles) do
+						if currentProfile ~= k then
+							if k:find('^char/') then
+								local name = k:sub(6)
+								local player, realm = name:match("^(.*) %- (.*)$")
+								if player then
+									name = PLAYER_OF_REALM:format(player, realm)
+								end
+								t[k] = CHARACTER_COLON .. name
+							elseif k:find('^realm/') then
+								local name = k:sub(7)
+								t[k] = REALM_COLON .. name
+							elseif k:find('^class/') then
+								local name = k:sub(7)
+								t[k] = CLASS_COLON .. name
+							else
+								t[k] = k
+							end
+						end
+					end
+				end
+			end
+		end
+	end
+	if t.Default then
+		t.Default = DEFAULT
+	end
+	if t.Alternative then
+		t.Alternative = ALTERNATIVE
+	end
+end
+
+local function RecalculateAceDBProfileList(target)
+	local t = target['acedb-profile-list']
+	for k,v in pairs(t) do
+		t[k] = nil
+	end
+	t.char = CHARACTER_COLON .. PLAYER_OF_REALM:format(UnitName("player"), server)
+	t.realm = REALM_COLON .. realmID
+	t.class = CLASS_COLON .. classID
+	t.Default = DEFAULT
+	local db = target.db
+	if db and db.raw then
+		if db.raw.profiles then
+			for k in pairs(db.raw.profiles) do
+				if not k:find("^char/") and not k:find("^realm/") and not k:find("^class/") then
+					t[k] = k
+				end
+			end
+		end
+		if db.raw.namespaces then
+			for _,n in pairs(db.raw.namespaces) do
+				if n.profiles then
+					for k in pairs(n.profiles) do
+						if not k:find("^char/") and not k:find("^realm/") and not k:find("^class/") then
+							t[k] = k
+						end
+					end
+				end
+			end
+		end
+		local curr = db.raw.currentProfile and db.raw.currentProfile[charID]
+		if curr and not t[curr] then
+			t[curr] = curr
+		end
+	end
+	if t.Alternative then
+		t.Alternative = ALTERNATIVE
+	end
+end
+
+local CrawlForSerialization
+local CrawlForDeserialization
+
+local function SerializeObject(o)
+	local t = { o:Serialize() }
+	CrawlForSerialization(t)
+	t[0] = o.class:GetLibraryVersion()
+	return t
+end
+
+local function DeserializeObject(t)
+	CrawlForDeserialization(t)
+	local className = t[0]
+	t[0] = nil
+	return AceLibrary(className):Deserialize(unpack(t))
+end
+
+local function IsSerializable(t)
+	return AceOO.inherits(t, AceOO.Class) and t.class and type(t.class.Deserialize) == "function" and type(t.Serialize) == "function" and type(t.class.GetLibraryVersion) == "function"
+end
+
+function CrawlForSerialization(t)
+	local tmp = new()
+	for k,v in pairs(t) do
+		tmp[k] = v
+	end
+	for k,v in pairs(tmp) do
+		if type(v) == "table" and type(rawget(v, 0)) ~= "userdata" then
+			if IsSerializable(v) then
+				v = SerializeObject(v)
+				t[k] = v
+			else
+				CrawlForSerialization(v)
+			end
+		end
+		if type(k) == "table" and type(rawget(k, 0)) ~= "userdata" then
+			if IsSerializable(k) then
+				t[k] = nil
+				t[SerializeObject(k)] = v
+			else
+				CrawlForSerialization(k)
+			end
+		end
+		tmp[k] = nil
+		k = nil
+	end
+	tmp = del(tmp)
+end
+
+local function IsDeserializable(t)
+	return type(rawget(t, 0)) == "string" and AceLibrary:HasInstance(rawget(t, 0))
+end
+
+function CrawlForDeserialization(t)
+	local tmp = new()
+	for k,v in pairs(t) do
+		tmp[k] = v
+	end
+	for k,v in pairs(tmp) do
+		if type(v) == "table" then
+			if IsDeserializable(v) then
+				t[k] = DeserializeObject(v)
+				del(v)
+				v = t[k]
+			elseif type(rawget(v, 0)) ~= "userdata" then
+				CrawlForDeserialization(v)
+			end
+		end
+		if type(k) == "table" then
+			if IsDeserializable(k) then
+				t[k] = nil
+				t[DeserializeObject(k)] = v
+				del(k)
+			elseif type(rawget(k, 0)) ~= "userdata" then
+				CrawlForDeserialization(k)
+			end
+		end
+		tmp[k] = nil
+		k = nil
+	end
+	tmp = del(tmp)
+end
+
+local namespace_mt = { __index = function(namespace, key)
+	local db = namespace.db
+	local name = namespace.name
+	if key == "char" then
+		if db.charName then
+			if type(_G[db.charName]) ~= "table" then
+				_G[db.charName] = {}
+			end
+			if type(_G[db.charName].namespaces) ~= "table" then
+				_G[db.charName].namespaces = {}
+			end
+			if type(_G[db.charName].namespaces[name]) ~= "table" then
+				_G[db.charName].namespaces[name] = {}
+			end
+			rawset(namespace, 'char', _G[db.charName].namespaces[name])
+		else
+			if type(db.raw.namespaces) ~= "table" then
+				db.raw.namespaces = {}
+			end
+			if type(db.raw.namespaces[name]) ~= "table" then
+				db.raw.namespaces[name] = {}
+			end
+			if type(db.raw.namespaces[name].chars) ~= "table" then
+				db.raw.namespaces[name].chars = {}
+			end
+			local id = charID
+			if type(db.raw.namespaces[name].chars[id]) ~= "table" then
+				db.raw.namespaces[name].chars[id] = {}
+			end
+			rawset(namespace, 'char', db.raw.namespaces[name].chars[id])
+		end
+		if namespace.defaults and namespace.defaults.char then
+			inheritDefaults(namespace.char, namespace.defaults.char)
+		end
+		return namespace.char
+	elseif key == "realm" then
+		if type(db.raw.namespaces) ~= "table" then
+			db.raw.namespaces = {}
+		end
+		if type(db.raw.namespaces[name]) ~= "table" then
+			db.raw.namespaces[name] = {}
+		end
+		if type(db.raw.namespaces[name].realms) ~= "table" then
+			db.raw.namespaces[name].realms = {}
+		end
+		local id = realmID
+		if type(db.raw.namespaces[name].realms[id]) ~= "table" then
+			db.raw.namespaces[name].realms[id] = {}
+		end
+		rawset(namespace, 'realm', db.raw.namespaces[name].realms[id])
+		if namespace.defaults and namespace.defaults.realm then
+			inheritDefaults(namespace.realm, namespace.defaults.realm)
+		end
+		return namespace.realm
+	elseif key == "server" then
+		if type(db.raw.namespaces) ~= "table" then
+			db.raw.namespaces = {}
+		end
+		if type(db.raw.namespaces[name]) ~= "table" then
+			db.raw.namespaces[name] = {}
+		end
+		if type(db.raw.namespaces[name].servers) ~= "table" then
+			db.raw.namespaces[name].servers = {}
+		end
+		local id = server
+		if type(db.raw.namespaces[name].servers[id]) ~= "table" then
+			db.raw.namespaces[name].servers[id] = {}
+		end
+		rawset(namespace, 'server', db.raw.namespaces[name].servers[id])
+		if namespace.defaults and namespace.defaults.server then
+			inheritDefaults(namespace.server, namespace.defaults.server)
+		end
+		return namespace.server
+	elseif key == "account" then
+		if type(db.raw.namespaces) ~= "table" then
+			db.raw.namespaces = {}
+		end
+		if type(db.raw.namespaces[name]) ~= "table" then
+			db.raw.namespaces[name] = {}
+		end
+		if type(db.raw.namespaces[name].account) ~= "table" then
+			db.raw.namespaces[name].account = {}
+		end
+		rawset(namespace, 'account', db.raw.namespaces[name].account)
+		if namespace.defaults and namespace.defaults.account then
+			inheritDefaults(namespace.account, namespace.defaults.account)
+		end
+		return namespace.account
+	elseif key == "faction" then
+		if type(db.raw.namespaces) ~= "table" then
+			db.raw.namespaces = {}
+		end
+		if type(db.raw.namespaces[name]) ~= "table" then
+			db.raw.namespaces[name] = {}
+		end
+		if type(db.raw.namespaces[name].factions) ~= "table" then
+			db.raw.namespaces[name].factions = {}
+		end
+		local id = faction
+		if type(db.raw.namespaces[name].factions[id]) ~= "table" then
+			db.raw.namespaces[name].factions[id] = {}
+		end
+		rawset(namespace, 'faction', db.raw.namespaces[name].factions[id])
+		if namespace.defaults and namespace.defaults.faction then
+			inheritDefaults(namespace.faction, namespace.defaults.faction)
+		end
+		return namespace.faction
+	elseif key == "class" then
+		if type(db.raw.namespaces) ~= "table" then
+			db.raw.namespaces = {}
+		end
+		if type(db.raw.namespaces[name]) ~= "table" then
+			db.raw.namespaces[name] = {}
+		end
+		if type(db.raw.namespaces[name].classes) ~= "table" then
+			db.raw.namespaces[name].classes = {}
+		end
+		local id = classID
+		if type(db.raw.namespaces[name].classes[id]) ~= "table" then
+			db.raw.namespaces[name].classes[id] = {}
+		end
+		rawset(namespace, 'class', db.raw.namespaces[name].classes[id])
+		if namespace.defaults and namespace.defaults.class then
+			inheritDefaults(namespace.class, namespace.defaults.class)
+		end
+		return namespace.class
+	elseif key == "profile" then
+		if type(db.raw.namespaces) ~= "table" then
+			db.raw.namespaces = {}
+		end
+		if type(db.raw.namespaces[name]) ~= "table" then
+			db.raw.namespaces[name] = {}
+		end
+		if type(db.raw.namespaces[name].profiles) ~= "table" then
+			db.raw.namespaces[name].profiles = setmetatable({}, caseInsensitive_mt)
+		else
+			setmetatable(db.raw.namespaces[name].profiles, caseInsensitive_mt)
+		end
+		local id = db.raw.currentProfile[charID]
+		if id == "char" then
+			id = "char/" .. charID
+		elseif id == "class" then
+			id = "class/" .. classID
+		elseif id == "realm" then
+			id = "realm/" .. realmID
+		end
+		if type(db.raw.namespaces[name].profiles[id]) ~= "table" then
+			db.raw.namespaces[name].profiles[id] = {}
+		end
+		rawset(namespace, 'profile', db.raw.namespaces[name].profiles[id])
+		if namespace.defaults and namespace.defaults.profile then
+			inheritDefaults(namespace.profile, namespace.defaults.profile)
+		end
+		return namespace.profile
+	elseif key == "defaults" or key == "name" or key == "db" then
+		return nil
+	end
+	error(("Cannot access key %q in db table. You may want to use db.profile[%q]"):format(tostring(key), tostring(key)), 2)
+end, __newindex = function(db, key, value)
+	error(("Cannot access key %q in db table. You may want to use db.profile[%q]"):format(tostring(key), tostring(key)), 2)
+end }
+
+local tmp = {}
+function AceDB:InitializeDB(addonName)
+	local db = self.db
+
+	if not db then
+		if addonName then
+			AceDB.addonsLoaded[addonName] = true
+		end
+		return
+	end
+
+	if db.raw then
+		-- someone manually initialized
+		return
+	end
+
+	if type(_G[db.name]) ~= "table" then
+		_G[db.name] = {}
+	else
+		CrawlForDeserialization(_G[db.name])
+	end
+	if db.charName then
+		if type(_G[db.charName]) ~= "table" then
+			_G[db.charName] = {}
+		else
+			CrawlForDeserialization(_G[db.charName])
+		end
+	end
+	rawset(db, 'raw', _G[db.name])
+	if not db.raw.currentProfile then
+		db.raw.currentProfile = {}
+	else
+		for k,v in pairs(db.raw.currentProfile) do
+			tmp[convertFromOldCharID(k)] = v
+			db.raw.currentProfile[k] = nil
+		end
+		for k,v in pairs(tmp) do
+			db.raw.currentProfile[k] = v
+			tmp[k] = nil
+		end
+	end
+	if not db.raw.currentProfile[charID] then
+		db.raw.currentProfile[charID] = AceDB.registry[self] or "Default"
+	end
+	if db.raw.profiles then
+		for k,v in pairs(db.raw.profiles) do
+			local new_k = k
+			if k:find("^char/") then
+				new_k = "char/" .. convertFromOldCharID(k:sub(6))
+			end
+			tmp[new_k] = v
+			db.raw.profiles[k] = nil
+		end
+		for k,v in pairs(tmp) do
+			db.raw.profiles[k] = v
+			tmp[k] = nil
+		end
+	end
+	if db.raw.disabledModules then -- AceModuleCore-2.0
+		for k,v in pairs(db.raw.disabledModules) do
+			local new_k = k
+			if k:find("^char/") then
+				new_k = "char/" .. convertFromOldCharID(k:sub(6))
+			end
+			tmp[new_k] = v
+			db.raw.disabledModules[k] = nil
+		end
+		for k,v in pairs(tmp) do
+			db.raw.disabledModules[k] = v
+			tmp[k] = nil
+		end
+	end
+	if db.raw.chars then
+		for k,v in pairs(db.raw.chars) do
+			tmp[convertFromOldCharID(k)] = v
+			db.raw.chars[k] = nil
+		end
+		for k,v in pairs(tmp) do
+			db.raw.chars[k] = v
+			tmp[k] = nil
+		end
+	end
+	if db.raw.namespaces then
+		for l,u in pairs(db.raw.namespaces) do
+			if u.chars then
+				for k,v in pairs(u.chars) do
+					tmp[convertFromOldCharID(k)] = v
+					u.chars[k] = nil
+				end
+				for k,v in pairs(tmp) do
+					u.chars[k] = v
+					tmp[k] = nil
+				end
+			end
+		end
+	end
+	if db.raw.disabled then
+		setmetatable(db.raw.disabled, caseInsensitive_mt)
+	end
+	if self['acedb-profile-copylist'] then
+		RecalculateAceDBCopyFromList(self)
+	end
+	if self['acedb-profile-list'] then
+		RecalculateAceDBProfileList(self)
+	end
+	setmetatable(db, db_mt)
+end
+
+function AceDB:OnEmbedInitialize(target, name)
+	if name then
+		self:ADDON_LOADED(name)
+	end
+	self.InitializeDB(target, name)
+end
+
+function AceDB:RegisterDB(name, charName, defaultProfile)
+	AceDB:argCheck(name, 2, "string")
+	AceDB:argCheck(charName, 3, "string", "nil")
+	AceDB:argCheck(defaultProfile, 4, "string", "nil")
+	if self.db then
+		AceDB:error("Cannot call \"RegisterDB\" if self.db is set.")
+	end
+	local stack = debugstack()
+	local addonName = stack:gsub(".-\n.-\\AddOns\\(.-)\\.*", "%1")
+	self.db = {
+		name = name,
+		charName = charName
+	}
+	AceDB.registry[self] = defaultProfile or "Default"
+	if AceDB.addonsLoaded[addonName] then
+		AceDB.InitializeDB(self, addonName)
+	else
+		AceDB.addonsToBeInitialized[self] = addonName
+	end
+end
+
+function AceDB:RegisterDefaults(kind, defaults, a3)
+	local name
+	if a3 then
+		name, kind, defaults = kind, defaults, a3
+		AceDB:argCheck(name, 2, "string")
+		AceDB:argCheck(kind, 3, "string")
+		AceDB:argCheck(defaults, 4, "table")
+	else
+		AceDB:argCheck(kind, 2, "string")
+		AceDB:argCheck(defaults, 3, "table")
+	end
+	if kind ~= "char" and kind ~= "class" and kind ~= "profile" and kind ~= "account" and kind ~= "realm" and kind ~= "faction" and kind ~= "server" then
+		AceDB:error("Bad argument #%d to `RegisterDefaults' (\"char\", \"class\", \"profile\", \"account\", \"realm\", \"server\", or \"faction\" expected, got %q)", a3 and 3 or 2, kind)
+	end
+	if type(self.db) ~= "table" or type(self.db.name) ~= "string" then
+		AceDB:error("Cannot call \"RegisterDefaults\" unless \"RegisterDB\" has been previously called.")
+	end
+	local db
+	if name then
+		local namespace = self:AcquireDBNamespace(name)
+		if namespace.defaults and namespace.defaults[kind] then
+			AceDB:error("\"RegisterDefaults\" has already been called for %q::%q.", name, kind)
+		end
+		db = namespace
+	else
+		if self.db.defaults and self.db.defaults[kind] then
+			AceDB:error("\"RegisterDefaults\" has already been called for %q.", kind)
+		end
+		db = self.db
+	end
+	if not db.defaults then
+		rawset(db, 'defaults', {})
+	end
+	db.defaults[kind] = defaults
+	if rawget(db, kind) then
+		inheritDefaults(db[kind], defaults)
+	end
+end
+
+function AceDB:ResetDB(kind, a2)
+	local name
+	if a2 then
+		name, kind = kind, a2
+		AceDB:argCheck(name, 2, "nil", "string")
+		AceDB:argCheck(kind, 3, "nil", "string")
+	else
+		AceDB:argCheck(kind, 2, "nil", "string")
+		if kind ~= "char" and kind ~= "class" and kind ~= "profile" and kind ~= "account" and kind ~= "realm" and kind ~= "faction" and kind ~= "server" then
+			name, kind = kind, nil
+		end
+	end
+	if not self.db or not self.db.raw then
+		AceDB:error("Cannot call \"ResetDB\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
+	end
+	local db = self.db
+	if not kind then
+		if not name then
+			if db.charName then
+				_G[db.charName] = nil
+			end
+			_G[db.name] = nil
+			rawset(db, 'raw', nil)
+			AceDB.InitializeDB(self)
+			if db.namespaces then
+				for name,v in pairs(db.namespaces) do
+					rawset(v, 'account', nil)
+					rawset(v, 'char', nil)
+					rawset(v, 'class', nil)
+					rawset(v, 'profile', nil)
+					rawset(v, 'realm', nil)
+					rawset(v, 'server', nil)
+					rawset(v, 'faction', nil)
+				end
+			end
+		else
+			if db.raw.namespaces then
+				db.raw.namespaces[name] = nil
+			end
+			if db.namespaces then
+				local v = db.namespaces[name]
+				if v then
+					rawset(v, 'account', nil)
+					rawset(v, 'char', nil)
+					rawset(v, 'class', nil)
+					rawset(v, 'profile', nil)
+					rawset(v, 'realm', nil)
+					rawset(v, 'server', nil)
+					rawset(v, 'faction', nil)
+				end
+			end
+		end
+	elseif kind == "account" then
+		if name then
+			db.raw.account = nil
+			rawset(db, 'account', nil)
+			if db.raw.namespaces then
+				for name,v in pairs(db.raw.namespaces) do
+					v.account = nil
+				end
+			end
+			if db.namespaces then
+				for name,v in pairs(db.namespaces) do
+					rawset(v, 'account', nil)
+				end
+			end
+		else
+			if db.raw.namespaces and db.raw.namespaces[name] then
+				db.raw.namespaces[name].account = nil
+			end
+			if db.namespaces then
+				local v = db.namespaces[name]
+				if v then
+					rawset(v, 'account', nil)
+				end
+			end
+		end
+	elseif kind == "char" then
+		if name then
+			if db.charName then
+				_G[db.charName] = nil
+			else
+				if db.raw.chars then
+					db.raw.chars[charID] = nil
+				end
+				if db.raw.namespaces then
+					for name,v in pairs(db.raw.namespaces) do
+						if v.chars then
+							v.chars[charID] = nil
+						end
+					end
+				end
+			end
+			rawset(db, 'char', nil)
+			if db.namespaces then
+				for name,v in pairs(db.namespaces) do
+					rawset(v, 'char', nil)
+				end
+			end
+		else
+			if db.charName then
+				local x = _G[db.charName]
+				if x.namespaces then
+					x.namespaces[name] = nil
+				end
+			else
+				if db.raw.namespaces then
+					local v = db.namespaces[name]
+					if v and v.chars then
+						v.chars[charID] = nil
+					end
+				end
+			end
+			if db.namespaces then
+				local v = db.namespaces[name]
+				if v then
+					rawset(v, 'char', nil)
+				end
+			end
+		end
+	elseif kind == "realm" then
+		if not name then
+			if db.raw.realms then
+				db.raw.realms[realmID] = nil
+			end
+			rawset(db, 'realm', nil)
+			if db.raw.namespaces then
+				for name,v in pairs(db.raw.namespaces) do
+					if v.realms then
+						v.realms[realmID] = nil
+					end
+				end
+			end
+			if db.namespaces then
+				for name,v in pairs(db.namespaces) do
+					rawset(v, 'realm', nil)
+				end
+			end
+		else
+			if db.raw.namespaces then
+				local v = db.raw.namespaces[name]
+				if v and v.realms then
+					v.realms[realmID] = nil
+				end
+			end
+			if db.namespaces then
+				local v = db.namespaces[name]
+				if v then
+					rawset(v, 'realm', nil)
+				end
+			end
+		end
+	elseif kind == "server" then
+		if not name then
+			if db.raw.servers then
+				db.raw.servers[server] = nil
+			end
+			rawset(db, 'server', nil)
+			if db.raw.namespaces then
+				for name,v in pairs(db.raw.namespaces) do
+					if v.servers then
+						v.servers[server] = nil
+					end
+				end
+			end
+			if db.namespaces then
+				for name,v in pairs(db.namespaces) do
+					rawset(v, 'server', nil)
+				end
+			end
+		else
+			if db.raw.namespaces then
+				local v = db.raw.namespaces[name]
+				if v and v.servers then
+					v.servers[server] = nil
+				end
+			end
+			if db.namespaces then
+				local v = db.namespaces[name]
+				if v then
+					rawset(v, 'server', nil)
+				end
+			end
+		end
+	elseif kind == "faction" then
+		if not name then
+			if db.raw.factions then
+				db.raw.factions[faction] = nil
+			end
+			rawset(db, 'faction', nil)
+			if db.raw.namespaces then
+				for name,v in pairs(db.raw.namespaces) do
+					if v.factions then
+						v.factions[faction] = nil
+					end
+				end
+			end
+			if db.namespaces then
+				for name,v in pairs(db.namespaces) do
+					rawset(v, 'faction', nil)
+				end
+			end
+		else
+			if db.raw.namespaces then
+				local v = db.raw.namespaces[name]
+				if v and v.factions then
+					v.factions[faction] = nil
+				end
+			end
+			if db.namespaces then
+				local v = db.namespaces[name]
+				if v then
+					rawset(v, 'faction', nil)
+				end
+			end
+		end
+	elseif kind == "class" then
+		if not name then
+			if db.raw.realms then
+				db.raw.realms[classID] = nil
+			end
+			rawset(db, 'class', nil)
+			if db.raw.namespaces then
+				for name,v in pairs(db.raw.namespaces) do
+					if v.classes then
+						v.classes[classID] = nil
+					end
+				end
+			end
+			if db.namespaces then
+				for name,v in pairs(db.namespaces) do
+					rawset(v, 'class', nil)
+				end
+			end
+		else
+			if db.raw.namespaces then
+				local v = db.raw.namespaces[name]
+				if v and v.classes then
+					v.classes[classID] = nil
+				end
+			end
+			if db.namespaces then
+				local v = db.namespaces[name]
+				if v then
+					rawset(v, 'class', nil)
+				end
+			end
+		end
+	elseif kind == "profile" then
+		local id = db.raw.currentProfile and db.raw.currentProfile[charID] or AceDB.registry[self] or "Default"
+		if id == "char" then
+			id = "char/" .. charID
+		elseif id == "class" then
+			id = "class/" .. classID
+		elseif id == "realm" then
+			id = "realm/" .. realmID
+		end
+
+		local current = self.class
+		while current and current ~= AceOO.Class do
+			if current.mixins then
+				for mixin in pairs(current.mixins) do
+					if type(mixin.OnEmbedProfileDisable) == "function" then
+						safecall(mixin.OnEmbedProfileDisable, mixin, self, id)
+					end
+				end
+			end
+			current = current.super
+		end
+		if type(self.OnProfileDisable) == "function" then
+			safecall(self.OnProfileDisable, self, id)
+		end
+		local active = self:IsActive()
+
+		if not name then
+			if db.raw.profiles then
+				db.raw.profiles[id] = nil
+			end
+			rawset(db, 'profile', nil)
+			if db.raw.namespaces then
+				for name,v in pairs(db.raw.namespaces) do
+					if v.profiles then
+						v.profiles[id] = nil
+					end
+				end
+			end
+			if db.namespaces then
+				for name,v in pairs(db.namespaces) do
+					rawset(v, 'profile', nil)
+				end
+			end
+		else
+			if db.raw.namespaces then
+				local v = db.raw.namespaces[name]
+				if v and v.profiles then
+					v.profiles[id] = nil
+				end
+			end
+			if db.namespaces then
+				local v = db.namespaces[name]
+				if v then
+					rawset(v, 'profile', nil)
+				end
+			end
+		end
+
+		local current = self.class
+		while current and current ~= AceOO.Class do
+			if current.mixins then
+				for mixin in pairs(current.mixins) do
+					if type(mixin.OnEmbedProfileEnable) == "function" then
+						safecall(mixin.OnEmbedProfileEnable, mixin, self, id)
+					end
+				end
+			end
+			current = current.super
+		end
+		if type(self.OnProfileEnable) == "function" then
+			safecall(self.OnProfileEnable, self, id)
+		end
+		local newactive = self:IsActive()
+		if active ~= newactive then
+			if newactive then
+				local first = nil
+				if AceOO.inherits(self, "AceAddon-2.0") then
+					local AceAddon = AceLibrary("AceAddon-2.0")
+					if not AceAddon.addonsStarted[self] then
+						return
+					end
+					if AceAddon.addonsEnabled and not AceAddon.addonsEnabled[self] then
+						AceAddon.addonsEnabled[self] = true
+						first = true
+					end
+				end
+				local current = self.class
+				while current and current ~= AceOO.Class do
+					if current.mixins then
+						for mixin in pairs(current.mixins) do
+							if type(mixin.OnEmbedEnable) == "function" then
+								safecall(mixin.OnEmbedEnable, mixin, self, first)
+							end
+						end
+					end
+					current = current.super
+				end
+				if type(self.OnEnable) == "function" then
+					safecall(self.OnEnable, self, first)
+				end
+				if AceEvent then
+					AceEvent:TriggerEvent("Ace2_AddonEnabled", self, first)
+				end
+			else
+				local current = self.class
+				while current and current ~= AceOO.Class do
+					if current.mixins then
+						for mixin in pairs(current.mixins) do
+							if type(mixin.OnEmbedDisable) == "function" then
+								safecall(mixin.OnEmbedDisable, mixin, self)
+							end
+						end
+					end
+					current = current.super
+				end
+				if type(self.OnDisable) == "function" then
+					safecall(self.OnDisable, self)
+				end
+				if AceEvent then
+					AceEvent:TriggerEvent("Ace2_AddonDisabled", self)
+				end
+			end
+		end
+	else
+		return -- skip event
+	end
+	if AceEvent then
+		AceEvent:TriggerEvent("AceDB20_ResetDB", self, self.db.name, kind)
+	end
+end
+
+local function cleanDefaults(t, defaults, blocker)
+	if defaults then
+		for k,v in pairs(t) do
+			if (not blocker or (blocker[k] == nil and blocker['*'] == nil and blocker['**'] == nil)) and (defaults[k] ~= nil or defaults['*'] ~= nil or defaults['**'] ~= nil) then
+				local u = defaults[k]
+				if u == nil then
+					u = defaults['*']
+					if u == nil then
+						u = defaults['**']
+					end
+				end
+				if v == u then
+					t[k] = nil
+				elseif type(v) == "table" and type(u) == "table" then
+					if cleanDefaults(v, u) then
+						t[k] = nil
+					else
+						local w = defaults['**']
+						if w ~= u then
+							if cleanDefaults(v, w, u) then
+								t[k] = nil
+							end
+						end
+					end
+				end
+			end
+		end
+	end
+	return t and next(t) == nil
+end
+
+function AceDB:GetProfile()
+	if not self.db or not self.db.raw then
+		return nil
+	end
+	if not self.db.raw.currentProfile then
+		self.db.raw.currentProfile = {}
+	end
+	if not self.db.raw.currentProfile[charID] then
+		self.db.raw.currentProfile[charID] = AceDB.registry[self] or "Default"
+	end
+	local profile = self.db.raw.currentProfile[charID]
+	if profile == "char" then
+		return "char", "char/" .. charID
+	elseif profile == "class" then
+		return "class", "class/" .. classID
+	elseif profile == "realm" then
+		return "realm", "realm/" .. realmID
+	end
+	return profile, profile
+end
+
+local function copyTable(to, from)
+	setmetatable(to, nil)
+	for k,v in pairs(from) do
+		if type(k) == "table" then
+			k = copyTable({}, k)
+		end
+		if type(v) == "table" then
+			v = copyTable({}, v)
+		end
+		to[k] = v
+	end
+	setmetatable(to, from)
+	return to
+end
+
+function AceDB:SetProfile(name)
+	AceDB:argCheck(name, 2, "string")
+	if not self.db or not self.db.raw then
+		AceDB:error("Cannot call \"SetProfile\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
+	end
+	local db = self.db
+	local lowerName = name:lower()
+	if lowerName:find("^char/") or lowerName:find("^realm/") or lowerName:find("^class/") then
+		if lowerName:find("^char/") then
+			name = "char"
+		else
+			name = lowerName:sub(1, 5)
+		end
+		lowerName = name:lower()
+	end
+	local oldName = db.raw.currentProfile[charID]
+	if oldName:lower() == name:lower() then
+		return
+	end
+	local oldProfileData = db.profile
+	local realName = name
+	if lowerName == "char" then
+		realName = name .. "/" .. charID
+	elseif lowerName == "realm" then
+		realName = name .. "/" .. realmID
+	elseif lowerName == "class" then
+		realName = name .. "/" .. classID
+	end
+	local current = self.class
+	while current and current ~= AceOO.Class do
+		if current.mixins then
+			for mixin in pairs(current.mixins) do
+				if type(mixin.OnEmbedProfileDisable) == "function" then
+					safecall(mixin.OnEmbedProfileDisable, mixin, self, realName)
+				end
+			end
+		end
+		current = current.super
+	end
+	if type(self.OnProfileDisable) == "function" then
+		safecall(self.OnProfileDisable, self, realName)
+	end
+	local active = self:IsActive()
+	db.raw.currentProfile[charID] = name
+	rawset(db, 'profile', nil)
+	if db.namespaces then
+		for k,v in pairs(db.namespaces) do
+			rawset(v, 'profile', nil)
+		end
+	end
+	local current = self.class
+	while current and current ~= AceOO.Class do
+		if current.mixins then
+			for mixin in pairs(current.mixins) do
+				if type(mixin.OnEmbedProfileEnable) == "function" then
+					safecall(mixin.OnEmbedProfileEnable, mixin, self, oldName, oldProfileData)
+				end
+			end
+		end
+		current = current.super
+	end
+	if type(self.OnProfileEnable) == "function" then
+		safecall(self.OnProfileEnable, self, oldName, oldProfileData)
+	end
+	if cleanDefaults(oldProfileData, db.defaults and db.defaults.profile) then
+		db.raw.profiles[oldName] = nil
+		if not next(db.raw.profiles) then
+			db.raw.profiles = nil
+		end
+	end
+	local newactive = self:IsActive()
+	if active ~= newactive then
+		local first = nil
+		if AceOO.inherits(self, "AceAddon-2.0") then
+			local AceAddon = AceLibrary("AceAddon-2.0")
+			if not AceAddon.addonsStarted[self] then
+				return
+			end
+			if AceAddon.addonsEnabled and not AceAddon.addonsEnabled[self] then
+				first = true
+			end
+		end
+		if newactive then
+			local current = self.class
+			while current and current ~= AceOO.Class do
+				if current.mixins then
+					for mixin in pairs(current.mixins) do
+						if type(mixin.OnEmbedEnable) == "function" then
+							safecall(mixin.OnEmbedEnable, mixin, self, first)
+						end
+					end
+				end
+				current = current.super
+			end
+			if type(self.OnEnable) == "function" then
+				safecall(self.OnEnable, self, first)
+			end
+			if AceEvent then
+				AceEvent:TriggerEvent("Ace2_AddonEnabled", self, first)
+			end
+		else
+			local current = self.class
+			while current and current ~= AceOO.Class do
+				if current.mixins then
+					for mixin in pairs(current.mixins) do
+						if type(mixin.OnEmbedDisable) == "function" then
+							safecall(mixin.OnEmbedDisable, mixin, self)
+						end
+					end
+				end
+				current = current.super
+			end
+			if type(self.OnDisable) == "function" then
+				safecall(self.OnDisable, self)
+			end
+			if AceEvent then
+				AceEvent:TriggerEvent("Ace2_AddonDisabled", self)
+			end
+		end
+	end
+	if self['acedb-profile-list'] then
+		RecalculateAceDBProfileList(self)
+	end
+	if self['acedb-profile-copylist'] then
+		RecalculateAceDBCopyFromList(self)
+	end
+	if Dewdrop then
+		Dewdrop:Refresh()
+	end
+end
+
+function AceDB:CopyProfileFrom(copyFrom)
+	AceDB:argCheck(copyFrom, 2, "string")
+	if not self.db or not self.db.raw then
+		AceDB:error("Cannot call \"CopyProfileFrom\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
+	end
+	local db = self.db
+	local lowerCopyFrom = copyFrom:lower()
+	if not db.raw.profiles or not db.raw.profiles[copyFrom] then
+		local good = false
+		if db.raw.namespaces then
+			for _,n in pairs(db.raw.namespaces) do
+				if n.profiles and n.profiles[copyFrom] then
+					good = true
+					break
+				end
+			end
+		end
+		if not good then
+			AceDB:error("Cannot copy from profile %q, it does not exist.", copyFrom)
+		end
+	end
+	local currentProfile = db.raw.currentProfile[charID]
+	if currentProfile:lower() == lowerCopyFrom then
+		AceDB:error("Cannot copy from profile %q, it is currently in use.", copyFrom)
+	end
+	local oldProfileData = db.profile
+	local current = self.class
+	while current and current ~= AceOO.Class do
+		if current.mixins then
+			for mixin in pairs(current.mixins) do
+				if type(mixin.OnEmbedProfileDisable) == "function" then
+					safecall(mixin.OnEmbedProfileDisable, mixin, self, currentProfile)
+				end
+			end
+		end
+		current = current.super
+	end
+	if type(self.OnProfileDisable) == "function" then
+		safecall(self.OnProfileDisable, self, realName)
+	end
+	local active = self:IsActive()
+	for k,v in pairs(db.profile) do
+		db.profile[k] = nil
+	end
+	if db.raw.profiles[copyFrom] then
+		copyTable(db.profile, db.raw.profiles[copyFrom])
+	end
+	inheritDefaults(db.profile, db.defaults and db.defaults.profile)
+	if db.namespaces then
+		for l,u in pairs(db.namespaces) do
+			for k,v in pairs(u.profile) do
+				u.profile[k] = nil
+			end
+			if db.raw.namespaces[l].profiles[copyFrom] then
+				copyTable(u.profile, db.raw.namespaces[l].profiles[copyFrom])
+			end
+			inheritDefaults(u.profile, u.defaults and u.defaults.profile)
+		end
+	end
+	local current = self.class
+	while current and current ~= AceOO.Class do
+		if current.mixins then
+			for mixin in pairs(current.mixins) do
+				if type(mixin.OnEmbedProfileEnable) == "function" then
+					safecall(mixin.OnEmbedProfileEnable, mixin, self, copyFrom, oldProfileData, copyFrom)
+				end
+			end
+		end
+		current = current.super
+	end
+	if type(self.OnProfileEnable) == "function" then
+		safecall(self.OnProfileEnable, self, copyFrom, oldProfileData, copyFrom)
+	end
+	local newactive = self:IsActive()
+	if active ~= newactive then
+		if AceOO.inherits(self, "AceAddon-2.0") then
+			local AceAddon = AceLibrary("AceAddon-2.0")
+			if not AceAddon.addonsStarted[self] then
+				return
+			end
+		end
+		if newactive then
+			local current = self.class
+			while current and current ~= AceOO.Class do
+				if current.mixins then
+					for mixin in pairs(current.mixins) do
+						if type(mixin.OnEmbedEnable) == "function" then
+							safecall(mixin.OnEmbedEnable, mixin, self)
+						end
+					end
+				end
+				current = current.super
+			end
+			if type(self.OnEnable) == "function" then
+				safecall(self.OnEnable, self)
+			end
+			if AceEvent then
+				AceEvent:TriggerEvent("Ace2_AddonEnabled", self)
+			end
+		else
+			local current = self.class
+			while current and current ~= AceOO.Class do
+				if current.mixins then
+					for mixin in pairs(current.mixins) do
+						if type(mixin.OnEmbedDisable) == "function" then
+							safecall(mixin.OnEmbedDisable, mixin, self)
+						end
+					end
+				end
+				current = current.super
+			end
+			if type(self.OnDisable) == "function" then
+				safecall(self.OnDisable, self)
+			end
+			if AceEvent then
+				AceEvent:TriggerEvent("Ace2_AddonDisabled", self)
+			end
+		end
+	end
+	if self['acedb-profile-list'] then
+		RecalculateAceDBProfileList(self)
+	end
+	if self['acedb-profile-copylist'] then
+		RecalculateAceDBCopyFromList(self)
+	end
+	if Dewdrop then
+		Dewdrop:Refresh()
+	end
+end
+
+function AceDB:DeleteProfile(profile, noconfirm)
+	AceDB:argCheck(profile , 2, "string")
+	if not self.db or not self.db.raw then
+		AceDB:error("Cannot call \"DeleteProfile\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
+	end
+	local db = self.db
+
+	local currentProfile = db.raw.currentProfile[charID]
+	if currentProfile:lower() == profile:lower() then
+		AceDB:error("Cannot delete profile %q, it is currently in use.", profile)
+	end
+
+	if not (noconfirm or IsShiftKeyDown()) then
+		if not StaticPopupDialogs["ACEDB20_CONFIRM_DELETE_DIALOG"] then
+			StaticPopupDialogs["ACEDB20_CONFIRM_DELETE_DIALOG"] = {}
+		end
+		local t = StaticPopupDialogs["ACEDB20_CONFIRM_DELETE_DIALOG"]
+		t.text = format("%s: %s?", DELETE_PROFILE, profile)
+		t.button1 = DELETE_PROFILE
+		t.button2 = CANCEL or "Cancel"
+		t.OnAccept = function()
+			self:DeleteProfile(profile, true)
+		end
+		t.timeout = 0
+		t.whileDead = 1
+		t.hideOnEscape = 1
+
+		StaticPopup_Show("ACEDB20_CONFIRM_DELETE_DIALOG")
+		return;
+	end
+
+	local good = false
+	if db.raw.profiles and db.raw.profiles[profile] then
+		good = true;
+		db.raw.profiles[profile] = nil;
+	end
+
+	if db.raw.namespaces then
+		for _,n in pairs(db.raw.namespaces) do
+			if n.profiles and n.profiles[profile] then
+				n.profiles[profile] = nil;
+				good = true
+			end
+		end
+	end
+
+	if not good then
+		AceDB:error("Cannot delete profile %q, it does not exist.", profile)
+	end
+
+	if self['acedb-profile-list'] then
+		RecalculateAceDBProfileList(self)
+	end
+	if self['acedb-profile-copylist'] then
+		RecalculateAceDBCopyFromList(self)
+	end
+
+	if Dewdrop then
+		Dewdrop:Refresh()
+	end
+end
+
+function AceDB:IsActive()
+	return not self.db or not self.db.raw or not self.db.raw.disabled or not self.db.raw.disabled[self.db.raw.currentProfile[charID]]
+end
+
+function AceDB:ToggleActive(state)
+	AceDB:argCheck(state, 2, "boolean", "nil")
+	if not self.db or not self.db.raw then
+		AceDB:error("Cannot call \"ToggleActive\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
+	end
+	local db = self.db
+	if not db.raw.disabled then
+		db.raw.disabled = setmetatable({}, caseInsensitive_mt)
+	end
+	local profile = db.raw.currentProfile[charID]
+	local disable
+	if state == nil then
+		disable = not db.raw.disabled[profile]
+	else
+		disable = not state
+		if disable == db.raw.disabled[profile] then
+			return
+		end
+	end
+	db.raw.disabled[profile] = disable or nil
+	if AceOO.inherits(self, "AceAddon-2.0") then
+		local AceAddon = AceLibrary("AceAddon-2.0")
+		if not AceAddon.addonsStarted[self] then
+			return
+		end
+	end
+	if not disable then
+		local current = self.class
+		while current and current ~= AceOO.Class do
+			if current.mixins then
+				for mixin in pairs(current.mixins) do
+					if type(mixin.OnEmbedEnable) == "function" then
+						safecall(mixin.OnEmbedEnable, mixin, self)
+					end
+				end
+			end
+			current = current.super
+		end
+		if type(self.OnEnable) == "function" then
+			safecall(self.OnEnable, self)
+		end
+		if AceEvent then
+			AceEvent:TriggerEvent("Ace2_AddonEnabled", self)
+		end
+	else
+		local current = self.class
+		while current and current ~= AceOO.Class do
+			if current.mixins then
+				for mixin in pairs(current.mixins) do
+					if type(mixin.OnEmbedDisable) == "function" then
+						safecall(mixin.OnEmbedDisable, mixin, self)
+					end
+				end
+			end
+			current = current.super
+		end
+		if type(self.OnDisable) == "function" then
+			safecall(self.OnDisable, self)
+		end
+		if AceEvent then
+			AceEvent:TriggerEvent("Ace2_AddonDisabled", self)
+		end
+	end
+	return not disable
+end
+
+function AceDB:embed(target)
+	self.super.embed(self, target)
+	if not AceEvent then
+		AceDB:error(MAJOR_VERSION .. " requires AceEvent-2.0")
+	end
+end
+
+function AceDB:ADDON_LOADED(name)
+	AceDB.addonsLoaded[name] = true
+	for addon, addonName in pairs(AceDB.addonsToBeInitialized) do
+		if name == addonName then
+			AceDB.InitializeDB(addon, name)
+			AceDB.addonsToBeInitialized[addon] = nil
+		end
+	end
+end
+
+function AceDB:PLAYER_LOGOUT()
+	for addon, defaultProfile in pairs(AceDB.registry) do
+		local db = addon.db
+		if db then
+			if type(addon.OnDatabaseCleanup) == "function" then
+				safecall(addon.OnDatabaseCleanup, addon)
+			end
+			setmetatable(db, nil)
+			CrawlForSerialization(db.raw)
+			if type(_G[db.charName]) == "table" then
+				CrawlForSerialization(_G[db.charName])
+			end
+			if db.char and cleanDefaults(db.char, db.defaults and db.defaults.char) then
+				if db.charName and _G[db.charName] and _G[db.charName].global == db.char then
+					_G[db.charName].global = nil
+					if not next(_G[db.charName]) then
+						_G[db.charName] = nil
+					end
+				else
+					if db.raw.chars then
+						db.raw.chars[charID] = nil
+						if not next(db.raw.chars) then
+							db.raw.chars = nil
+						end
+					end
+				end
+			end
+			if db.realm and cleanDefaults(db.realm, db.defaults and db.defaults.realm) then
+				if db.raw.realms then
+					db.raw.realms[realmID] = nil
+					if not next(db.raw.realms) then
+						db.raw.realms = nil
+					end
+				end
+			end
+			if db.server and cleanDefaults(db.server, db.defaults and db.defaults.server) then
+				if db.raw.servers then
+					db.raw.servers[server] = nil
+					if not next(db.raw.servers) then
+						db.raw.servers = nil
+					end
+				end
+			end
+			if db.faction and cleanDefaults(db.faction, db.defaults and db.defaults.faction) then
+				if db.raw.factions then
+					db.raw.factions[faction] = nil
+					if not next(db.raw.factions) then
+						db.raw.factions = nil
+					end
+				end
+			end
+			if db.class and cleanDefaults(db.class, db.defaults and db.defaults.class) then
+				if db.raw.classes then
+					db.raw.classes[classID] = nil
+					if not next(db.raw.classes) then
+						db.raw.classes = nil
+					end
+				end
+			end
+			if db.account and cleanDefaults(db.account, db.defaults and db.defaults.account) then
+				db.raw.account = nil
+			end
+			if db.profile and cleanDefaults(db.profile, db.defaults and db.defaults.profile) then
+				if db.raw.profiles then
+					db.raw.profiles[db.raw.currentProfile and db.raw.currentProfile[charID] or defaultProfile or "Default"] = nil
+					if not next(db.raw.profiles) then
+						db.raw.profiles = nil
+					end
+				end
+			end
+			if db.namespaces and db.raw.namespaces then
+				for name,v in pairs(db.namespaces) do
+					if db.raw.namespaces[name] then
+						setmetatable(v, nil)
+						if v.char and cleanDefaults(v.char, v.defaults and v.defaults.char) then
+							if db.charName and _G[db.charName] and _G[db.charName].namespaces and _G[db.charName].namespaces[name] == v then
+								_G[db.charName].namespaces[name] = nil
+								if not next(_G[db.charName].namespaces) then
+									_G[db.charName].namespaces = nil
+									if not next(_G[db.charName]) then
+										_G[db.charName] = nil
+									end
+								end
+							else
+								if db.raw.namespaces[name].chars then
+									db.raw.namespaces[name].chars[charID] = nil
+									if not next(db.raw.namespaces[name].chars) then
+										db.raw.namespaces[name].chars = nil
+									end
+								end
+							end
+						end
+						if v.realm and cleanDefaults(v.realm, v.defaults and v.defaults.realm) then
+							if db.raw.namespaces[name].realms then
+								db.raw.namespaces[name].realms[realmID] = nil
+								if not next(db.raw.namespaces[name].realms) then
+									db.raw.namespaces[name].realms = nil
+								end
+							end
+						end
+						if v.server and cleanDefaults(v.server, v.defaults and v.defaults.server) then
+							if db.raw.namespaces[name].servers then
+								db.raw.namespaces[name].servers[server] = nil
+								if not next(db.raw.namespaces[name].servers) then
+									db.raw.namespaces[name].servers = nil
+								end
+							end
+						end
+						if v.faction and cleanDefaults(v.faction, v.defaults and v.defaults.faction) then
+							if db.raw.namespaces[name].factions then
+								db.raw.namespaces[name].factions[faction] = nil
+								if not next(db.raw.namespaces[name].factions) then
+									db.raw.namespaces[name].factions = nil
+								end
+							end
+						end
+						if v.class and cleanDefaults(v.class, v.defaults and v.defaults.class) then
+							if db.raw.namespaces[name].classes then
+								db.raw.namespaces[name].classes[classID] = nil
+								if not next(db.raw.namespaces[name].classes) then
+									db.raw.namespaces[name].classes = nil
+								end
+							end
+						end
+						if v.account and cleanDefaults(v.account, v.defaults and v.defaults.account) then
+							db.raw.namespaces[name].account = nil
+						end
+						if v.profile and cleanDefaults(v.profile, v.defaults and v.defaults.profile) then
+							if db.raw.namespaces[name].profiles then
+								db.raw.namespaces[name].profiles[db.raw.currentProfile and db.raw.currentProfile[charID] or defaultProfile or "Default"] = nil
+								if not next(db.raw.namespaces[name].profiles) then
+									db.raw.namespaces[name].profiles = nil
+								end
+							end
+						end
+						if not next(db.raw.namespaces[name]) then
+							db.raw.namespaces[name] = nil
+						end
+					end
+				end
+				if not next(db.raw.namespaces) then
+					db.raw.namespaces = nil
+				end
+			end
+			if db.raw.disabled and not next(db.raw.disabled) then
+				db.raw.disabled = nil
+			end
+			if db.raw.currentProfile then
+				for k,v in pairs(db.raw.currentProfile) do
+					if v:lower() == (defaultProfile or "Default"):lower() then
+						db.raw.currentProfile[k] = nil
+					end
+				end
+				if not next(db.raw.currentProfile) then
+					db.raw.currentProfile = nil
+				end
+			end
+			if _G[db.name] and not next(_G[db.name]) then
+				_G[db.name] = nil
+			end
+		end
+	end
+end
+
+function AceDB:AcquireDBNamespace(name)
+	AceDB:argCheck(name, 2, "string")
+	local db = self.db
+	if not db then
+		AceDB:error("Cannot call `AcquireDBNamespace' before `RegisterDB' has been called.", 2)
+	end
+	if not db.namespaces then
+		rawset(db, 'namespaces', {})
+	end
+	if not db.namespaces[name] then
+		local namespace = {}
+		db.namespaces[name] = namespace
+		namespace.db = db
+		namespace.name = name
+		setmetatable(namespace, namespace_mt)
+	end
+	return db.namespaces[name]
+end
+
+function AceDB:GetAceOptionsDataTable(target)
+	if not target['acedb-profile-list'] then
+		target['acedb-profile-list'] = setmetatable({}, caseInsensitive_mt)
+		RecalculateAceDBProfileList(target)
+	end
+	if not target['acedb-profile-copylist'] then
+		target['acedb-profile-copylist'] = setmetatable({}, caseInsensitive_mt)
+		RecalculateAceDBCopyFromList(target)
+	end
+	return {
+		standby = {
+			cmdName = STATE,
+			guiName = ENABLED,
+			name = ACTIVE,
+			desc = TOGGLE_ACTIVE,
+			type = "toggle",
+			get = "IsActive",
+			set = "ToggleActive",
+			map = MAP_ACTIVESUSPENDED,
+			order = -3,
+		},
+		profile = {
+			type = 'group',
+			name = PROFILE,
+			desc = SET_PROFILE,
+			order = -3.5,
+			get = "GetProfile",
+			args = {
+				choose = {
+					guiName = CHOOSE_PROFILE_GUI,
+					cmdName = PROFILE,
+					desc = CHOOSE_PROFILE_DESC,
+					type = 'text',
+					get = "GetProfile",
+					set = "SetProfile",
+					validate = target['acedb-profile-list']
+				},
+				copy = {
+					guiName = COPY_PROFILE_GUI,
+					cmdName = PROFILE,
+					desc = COPY_PROFILE_DESC,
+					type = 'text',
+					get = false,
+					set = "CopyProfileFrom",
+					validate = target['acedb-profile-copylist'],
+					disabled = function()
+						return not next(target['acedb-profile-copylist'])
+					end,
+				},
+				other = {
+					guiName = OTHER_PROFILE_GUI,
+					cmdName = PROFILE,
+					desc = OTHER_PROFILE_DESC,
+					usage = OTHER_PROFILE_USAGE,
+					type = 'text',
+					get = "GetProfile",
+					set = "SetProfile",
+				},
+				delete = {
+					name = DELETE_PROFILE,
+					desc = DELETE_PROFILE_DESC,
+					usage = DELETE_PROFILE_USAGE,
+					type = 'text',
+					set = "DeleteProfile",
+					get = false,
+					validate = target['acedb-profile-copylist'],
+					disabled = function()
+						return not next(target['acedb-profile-copylist'])
+					end,
+				},
+				reset = {
+					name = RESET_PROFILE,
+					desc = RESET_PROFILE_DESC,
+					type = 'execute',
+					func = function()
+						target:ResetDB('profile')
+					end,
+					confirm = true,
+				}
+			}
+		},
+	}
+end
+
+local function activate(self, oldLib, oldDeactivate)
+	AceDB = self
+	AceEvent = AceLibrary:HasInstance("AceEvent-2.0") and AceLibrary("AceEvent-2.0")
+
+	self.addonsToBeInitialized = oldLib and oldLib.addonsToBeInitialized or {}
+	self.addonsLoaded = oldLib and oldLib.addonsLoaded or {}
+	self.registry = oldLib and oldLib.registry or {}
+	for k, v in pairs(self.registry) do
+		if v == true then
+			self.registry[k] = "Default"
+		end
+	end
+
+	self:activate(oldLib, oldDeactivate)
+
+	for t in pairs(self.embedList) do
+		if t.db then
+			rawset(t.db, 'char', nil)
+			rawset(t.db, 'realm', nil)
+			rawset(t.db, 'class', nil)
+			rawset(t.db, 'account', nil)
+			rawset(t.db, 'server', nil)
+			rawset(t.db, 'faction', nil)
+			rawset(t.db, 'profile', nil)
+			setmetatable(t.db, db_mt)
+		end
+	end
+
+	if oldLib then
+		oldDeactivate(oldLib)
+	end
+end
+
+local function external(self, major, instance)
+	if major == "AceEvent-2.0" then
+		AceEvent = instance
+
+		AceEvent:embed(self)
+
+		self:RegisterEvent("ADDON_LOADED")
+		self:RegisterEvent("PLAYER_LOGOUT")
+	elseif major == "Dewdrop-2.0" then
+		Dewdrop = instance
+	end
+end
+
+AceLibrary:Register(AceDB, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
+AceDB = AceLibrary(MAJOR_VERSION)