Quantcast

Fixed CR/LF issues and trailing whitespace in the Ace libraries.

Kevin Lyles [10-02-10 - 20:53]
Fixed CR/LF issues and trailing whitespace in the Ace libraries.
Filename
Libs/AceAddon-2.0/AceAddon-2.0.lua
Libs/AceAddon-2.0/AceAddon-2.0.toc
Libs/AceEvent-2.0/AceEvent-2.0.lua
Libs/AceEvent-2.0/AceEvent-2.0.toc
Libs/AceHook-2.1/AceHook-2.1.lua
Libs/AceHook-2.1/AceHook-2.1.toc
Libs/AceLibrary/AceLibrary.lua
Libs/AceLibrary/AceLibrary.toc
Libs/AceOO-2.0/AceOO-2.0.lua
Libs/AceOO-2.0/AceOO-2.0.toc
diff --git a/Libs/AceAddon-2.0/AceAddon-2.0.lua b/Libs/AceAddon-2.0/AceAddon-2.0.lua
index a1f4810..b770a71 100644
--- a/Libs/AceAddon-2.0/AceAddon-2.0.lua
+++ b/Libs/AceAddon-2.0/AceAddon-2.0.lua
@@ -1,1450 +1,1450 @@
---[[
-Name: AceAddon-2.0
-Revision: $Rev: 1094 $
-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/wiki/AceAddon-2.0
-SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceAddon-2.0
-Description: Base for all Ace addons to inherit from.
-Dependencies: AceLibrary, AceOO-2.0, AceEvent-2.0, (optional) AceConsole-2.0
-License: LGPL v2.1
-]]
-
-local MAJOR_VERSION = "AceAddon-2.0"
-local MINOR_VERSION = 90000 + tonumber(("$Revision: 1094 $"):match("(%d+)"))
-
--- This ensures the code is only executed if the libary doesn't already exist, or is a newer version
-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:find("%.lua:%d+:") and err or (debugstack():match("\n(.-: )in.-\n") or "") .. err) end
-end
--- Localization
-local STANDBY, TITLE, NOTES, VERSION, AUTHOR, DATE, CATEGORY, EMAIL, CREDITS, WEBSITE, CATEGORIES, ABOUT, LICENSE, PRINT_ADDON_INFO, DONATE, DONATE_DESC, HOWTO_DONATE_WINDOWS, HOWTO_DONATE_MAC
-if GetLocale() == "deDE" then
-	STANDBY = "|cffff5050(Standby)|r" -- capitalized
-
-	TITLE = "Titel"
-	NOTES = "Anmerkung"
-	VERSION = "Version"
-	AUTHOR = "Autor"
-	DATE = "Datum"
-	CATEGORY = "Kategorie"
-	EMAIL = "E-Mail"
-	WEBSITE = "Webseite"
-	CREDITS = "Credits" -- fix
-	LICENSE = "License" -- fix
-
-	ABOUT = "Über"
-	PRINT_ADDON_INFO = "Gibt Addondaten aus"
-	DONATE = "Donate" -- fix
-	DONATE_DESC = "Give a much-needed donation to the author of this addon." -- fix
-	HOWTO_DONATE_WINDOWS = "Press Ctrl-A to select the link, then Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
-	HOWTO_DONATE_MAC = "Press Cmd-A to select the link, then Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
-
-	CATEGORIES = {
-		["Action Bars"] = "Aktionsleisten",
-		["Auction"] = "Auktion",
-		["Audio"] = "Audio",
-		["Battlegrounds/PvP"] = "Schlachtfeld/PvP",
-		["Buffs"] = "Stärkungszauber",
-		["Chat/Communication"] = "Chat/Kommunikation",
-		["Druid"] = "Druide",
-		["Hunter"] = "Jäger",
-		["Mage"] = "Magier",
-		["Paladin"] = "Paladin",
-		["Priest"] = "Priester",
-		["Rogue"] = "Schurke",
-		["Shaman"] = "Schamane",
-		["Warlock"] = "Hexenmeister",
-		["Warrior"] = "Krieger",
-		["Healer"] = "Heiler",
-		["Tank"] = "Tank",
-		["Caster"] = "Zauberer",
-		["Combat"] = "Kampf",
-		["Compilations"] = "Zusammenstellungen",
-		["Data Export"] = "Datenexport",
-		["Development Tools"] = "Entwicklungs Tools",
-		["Guild"] = "Gilde",
-		["Frame Modification"] = "Frame Veränderungen",
-		["Interface Enhancements"] = "Interface Verbesserungen",
-		["Inventory"] = "Inventar",
-		["Library"] = "Bibliotheken",
-		["Map"] = "Karte",
-		["Mail"] = "Post",
-		["Miscellaneous"] = "Diverses",
-		["Quest"] = "Quest",
-		["Raid"] = "Schlachtzug",
-		["Tradeskill"] = "Beruf",
-		["UnitFrame"] = "Einheiten-Fenster",
-	}
-elseif GetLocale() == "frFR" then
-	STANDBY = "|cffff5050(attente)|r"
-
-	TITLE = "Titre"
-	NOTES = "Notes"
-	VERSION = "Version"
-	AUTHOR = "Auteur"
-	DATE = "Date"
-	CATEGORY = "Catégorie"
-	EMAIL = "E-mail"
-	WEBSITE = "Site web"
-	CREDITS = "Credits" -- fix
-	LICENSE = "License" -- fix
-
-	ABOUT = "A propos"
-	PRINT_ADDON_INFO = "Afficher les informations sur l'addon"
-	DONATE = "Donate" -- fix
-	DONATE_DESC = "Give a much-needed donation to the author of this addon." -- fix
-	HOWTO_DONATE_WINDOWS = "Press Ctrl-A to select the link, then Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
-	HOWTO_DONATE_MAC = "Press Cmd-A to select the link, then Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
-
-	CATEGORIES = {
-		["Action Bars"] = "Barres d'action",
-		["Auction"] = "Hôtel des ventes",
-		["Audio"] = "Audio",
-		["Battlegrounds/PvP"] = "Champs de bataille/JcJ",
-		["Buffs"] = "Buffs",
-		["Chat/Communication"] = "Chat/Communication",
-		["Druid"] = "Druide",
-		["Hunter"] = "Chasseur",
-		["Mage"] = "Mage",
-		["Paladin"] = "Paladin",
-		["Priest"] = "Prêtre",
-		["Rogue"] = "Voleur",
-		["Shaman"] = "Chaman",
-		["Warlock"] = "Démoniste",
-		["Warrior"] = "Guerrier",
-		["Healer"] = "Soigneur",
-		["Tank"] = "Tank",
-		["Caster"] = "Casteur",
-		["Combat"] = "Combat",
-		["Compilations"] = "Compilations",
-		["Data Export"] = "Exportation de données",
-		["Development Tools"] = "Outils de développement",
-		["Guild"] = "Guilde",
-		["Frame Modification"] = "Modification des fenêtres",
-		["Interface Enhancements"] = "Améliorations de l'interface",
-		["Inventory"] = "Inventaire",
-		["Library"] = "Bibliothèques",
-		["Map"] = "Carte",
-		["Mail"] = "Courrier",
-		["Miscellaneous"] = "Divers",
-		["Quest"] = "Quêtes",
-		["Raid"] = "Raid",
-		["Tradeskill"] = "Métiers",
-		["UnitFrame"] = "Fenêtres d'unité",
-	}
-elseif GetLocale() == "koKR" then
-	STANDBY = "|cffff5050(사용가능)|r"
-
-	TITLE = "제목"
-	NOTES = "노트"
-	VERSION = "버전"
-	AUTHOR = "저작자"
-	DATE = "날짜"
-	CATEGORY = "분류"
-	EMAIL = "전자 우편"
-	WEBSITE = "웹 사이트"
-	CREDITS = "공로자"
-	LICENSE = "라이센스"
-
-	ABOUT = "정보"
-	PRINT_ADDON_INFO = "애드온에 대한 정보를 출력합니다."
-	DONATE = "기부"
-	DONATE_DESC = "이 애드온의 저작자에게 기부를 합니다."
-	HOWTO_DONATE_WINDOWS = "Ctrl-A를 눌려 링크를 선택후, Ctrl-C로 복사합니다. Alt-Tab 눌려 게임으로 부터 나간후 웹 브라우저를 엽니다. 복사된 링크를 주소 창에 붙여넣기 합니다."
-	HOWTO_DONATE_MAC = "Cmd-A를 눌려 링크를 선택후, Cmd-C로 복사합니다. Cmd-Tab 눌려 게임으로 부터 나간후 웹 브라우저를 엽니다. 복사된 링크를 주소 창에 붙여넣기 합니다."
-
-	CATEGORIES = {
-		["Action Bars"] = "액션바",
-		["Auction"] = "경매",
-		["Audio"] = "음향",
-		["Battlegrounds/PvP"] = "전장/PvP",
-		["Buffs"] = "버프",
-		["Chat/Communication"] = "대화/의사소통",
-		["Druid"] = "드루이드",
-		["Hunter"] = "사냥꾼",
-		["Mage"] = "마법사",
-		["Paladin"] = "성기사",
-		["Priest"] = "사제",
-		["Rogue"] = "도적",
-		["Shaman"] = "주술사",
-		["Warlock"] = "흑마법사",
-		["Warrior"] = "전사",
-		["Healer"] = "힐러",
-		["Tank"] = "탱커",
-		["Caster"] = "캐스터",
-		["Combat"] = "전투",
-		["Compilations"] = "복합",
-		["Data Export"] = "자료 출력",
-		["Development Tools"] = "개발 도구",
-		["Guild"] = "길드",
-		["Frame Modification"] = "구조 변경",
-		["Interface Enhancements"] = "인터페이스 강화",
-		["Inventory"] = "인벤토리",
-		["Library"] = "라이브러리",
-		["Map"] = "지도",
-		["Mail"] = "우편",
-		["Miscellaneous"] = "기타",
-		["Quest"] = "퀘스트",
-		["Raid"] = "공격대",
-		["Tradeskill"] = "전문기술",
-		["UnitFrame"] = "유닛 프레임",
-	}
-elseif GetLocale() == "zhTW" then
-	STANDBY = "|cffff5050(待命)|r"
-
-	TITLE = "標題"
-	NOTES = "註記"
-	VERSION = "版本"
-	AUTHOR = "作者"
-	DATE = "日期"
-	CATEGORY = "類別"
-	EMAIL = "電子郵件"
-	WEBSITE = "網站"
-	CREDITS = "特別感謝"
-	LICENSE = "版權"
-
-	ABOUT = "關於"
-	PRINT_ADDON_INFO = "顯示插件資訊。"
-	DONATE = "捐贈"
-	DONATE_DESC = "捐贈金錢給插件作者。"
-	HOWTO_DONATE_WINDOWS = "請按Ctrl-A選擇網站連結,Ctrl-C複製網址,Alt-Tab切換到電腦桌面,打開瀏覽器,在網址列貼上網址。"
-	HOWTO_DONATE_MAC = "請按Cmd-A選擇網站連結,Cmd-C複製網址,Cmd-Tab切換到電腦桌面,打開瀏覽器,在網址列貼上網址。"
-
-	CATEGORIES = {
-		["Action Bars"] = "動作條",
-		["Auction"] = "拍賣",
-		["Audio"] = "音效",
-		["Battlegrounds/PvP"] = "戰場/PvP",
-		["Buffs"] = "增益",
-		["Chat/Communication"] = "聊天/通訊",
-		["Druid"] = "德魯伊",
-		["Hunter"] = "獵人",
-		["Mage"] = "法師",
-		["Paladin"] = "聖騎士",
-		["Priest"] = "牧師",
-		["Rogue"] = "盜賊",
-		["Shaman"] = "薩滿",
-		["Warlock"] = "術士",
-		["Warrior"] = "戰士",
-		["Healer"] = "治療者",
-		["Tank"] = "坦克",
-		["Caster"] = "施法者",
-		["Combat"] = "戰鬥",
-		["Compilations"] = "整合",
-		["Data Export"] = "資料匯出",
-		["Development Tools"] = "開發工具",
-		["Guild"] = "公會",
-		["Frame Modification"] = "框架修改",
-		["Interface Enhancements"] = "介面增強",
-		["Inventory"] = "庫存",
-		["Library"] = "程式庫",
-		["Map"] = "地圖",
-		["Mail"] = "郵件",
-		["Miscellaneous"] = "雜項",
-		["Quest"] = "任務",
-		["Raid"] = "團隊",
-		["Tradeskill"] = "交易技能",
-		["UnitFrame"] = "單位框架",
-	}
-elseif GetLocale() == "zhCN" then
-	STANDBY = "|cffff5050(暂挂)|r"
-
-	TITLE = "标题"
-	NOTES = "附注"
-	VERSION = "版本"
-	AUTHOR = "作者"
-	DATE = "日期"
-	CATEGORY = "分类"
-	EMAIL = "电子邮件"
-	WEBSITE = "网站"
-	CREDITS = "Credits" -- fix
-	LICENSE = "License" -- fix
-
-	ABOUT = "关于"
-	PRINT_ADDON_INFO = "印列出插件信息"
-	DONATE = "Donate" -- fix
-	DONATE_DESC = "Give a much-needed donation to the author of this addon." -- fix
-	HOWTO_DONATE_WINDOWS = "Press Ctrl-A to select the link, then Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
-	HOWTO_DONATE_MAC = "Press Cmd-A to select the link, then Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
-
-	CATEGORIES = {
-		["Action Bars"] = "动作条",
-		["Auction"] = "拍卖",
-		["Audio"] = "音频",
-		["Battlegrounds/PvP"] = "战场/PvP",
-		["Buffs"] = "增益魔法",
-		["Chat/Communication"] = "聊天/交流",
-		["Druid"] = "德鲁伊",
-		["Hunter"] = "猎人",
-		["Mage"] = "法师",
-		["Paladin"] = "圣骑士",
-		["Priest"] = "牧师",
-		["Rogue"] = "盗贼",
-		["Shaman"] = "萨满祭司",
-		["Warlock"] = "术士",
-		["Warrior"] = "战士",
-		["Healer"] = "Healer",
-		["Tank"] = "Tank",
-		["Caster"] = "Caster",
-		["Combat"] = "战斗",
-		["Compilations"] = "编译",
-		["Data Export"] = "数据导出",
-		["Development Tools"] = "开发工具",
-		["Guild"] = "公会",
-		["Frame Modification"] = "框架修改",
-		["Interface Enhancements"] = "界面增强",
-		["Inventory"] = "背包",
-		["Library"] = "库",
-		["Map"] = "地图",
-		["Mail"] = "邮件",
-		["Miscellaneous"] = "杂项",
-		["Quest"] = "任务",
-		["Raid"] = "团队",
-		["Tradeskill"] = "商业技能",
-		["UnitFrame"] = "头像框架",
-	}
-elseif GetLocale() == "esES" then
-	STANDBY = "|cffff5050(espera)|r"
-
-	TITLE = "Título"
-	NOTES = "Notas"
-	VERSION = "Versión"
-	AUTHOR = "Autor"
-	DATE = "Fecha"
-	CATEGORY = "Categoría"
-	EMAIL = "E-mail"
-	WEBSITE = "Web"
-	CREDITS = "Créditos"
-	LICENSE = "License" -- fix
-
-	ABOUT = "Acerca de"
-	PRINT_ADDON_INFO = "Muestra información acerca del accesorio."
-	DONATE = "Donate" -- fix
-	DONATE_DESC = "Give a much-needed donation to the author of this addon." -- fix
-	HOWTO_DONATE_WINDOWS = "Press Ctrl-A to select the link, then Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
-	HOWTO_DONATE_MAC = "Press Cmd-A to select the link, then Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
-
-	CATEGORIES = {
-		["Action Bars"] = "Barras de Acción",
-		["Auction"] = "Subasta",
-		["Audio"] = "Audio",
-		["Battlegrounds/PvP"] = "Campos de Batalla/JcJ",
-		["Buffs"] = "Buffs",
-		["Chat/Communication"] = "Chat/Comunicación",
-		["Druid"] = "Druida",
-		["Hunter"] = "Cazador",
-		["Mage"] = "Mago",
-		["Paladin"] = "Paladín",
-		["Priest"] = "Sacerdote",
-		["Rogue"] = "Pícaro",
-		["Shaman"] = "Chamán",
-		["Warlock"] = "Brujo",
-		["Warrior"] = "Guerrero",
-		["Healer"] = "Sanador",
-		["Tank"] = "Tanque",
-		["Caster"] = "Conjurador",
-		["Combat"] = "Combate",
-		["Compilations"] = "Compilaciones",
-		["Data Export"] = "Exportar Datos",
-		["Development Tools"] = "Herramientas de Desarrollo",
-		["Guild"] = "Hermandad",
-		["Frame Modification"] = "Modificación de Marcos",
-		["Interface Enhancements"] = "Mejoras de la Interfaz",
-		["Inventory"] = "Inventario",
-		["Library"] = "Biblioteca",
-		["Map"] = "Mapa",
-		["Mail"] = "Correo",
-		["Miscellaneous"] = "Misceláneo",
-		["Quest"] = "Misión",
-		["Raid"] = "Banda",
-		["Tradeskill"] = "Habilidad de Comercio",
-		["UnitFrame"] = "Marco de Unidades",
-	}
-elseif GetLocale() == "ruRU" then
-	STANDBY = "|cffff5050(в режиме ожидания)|r"
-
-	TITLE = "Название"
-	NOTES = "Описание"
-	VERSION = "Версия"
-	AUTHOR = "Автор"
-	DATE = "Дата"
-	CATEGORY = "Категория"
-	EMAIL = "E-mail"
-	WEBSITE = "Сайт"
-	CREDITS = "Титры"
-	LICENSE = "Лицензия"
-
-	ABOUT = "Об аддоне"
-	PRINT_ADDON_INFO = "Показать информацию об аддоне."
-	DONATE = "Пожертвовать"
-	DONATE_DESC = "Отблагодарить автора за разработку аддона."
-	HOWTO_DONATE_WINDOWS = "Для выделения всей ссылки нажмите Ctrl-A, потом для её копирования Ctrl-C, чтобы свернуть игру - Alt-Tab, откройте ваш браузер и вставьте ссылку в адресную строку - Ctrl-V"
-	HOWTO_DONATE_MAC = "Для выделения всей ссылки нажмите Cmd-A, потом для её копирования Ctrl-C, чтобы свернуть игру -  Cmd-Tab, откройте ваш браузер и вставьте ссылку в адресную строку Cmd-V"
-
-	CATEGORIES = {
-		["Action Bars"] = "Панели команд",
-		["Auction"] = "Аукцион",
-		["Audio"] = "Аудио",
-		["Battlegrounds/PvP"] = "Поля сражений/PvP",
-		["Buffs"] = "Баффы",
-		["Chat/Communication"] = "Чат/Коммуникация",
-		["Druid"] = "Друид",
-		["Hunter"] = "Охотник",
-		["Mage"] = "Маг",
-		["Paladin"] = "Паладин",
-		["Priest"] = "Жрец",
-		["Rogue"] = "Разбойник",
-		["Shaman"] = "Шаман",
-		["Warlock"] = "Чернокнижник",
-		["Warrior"] = "Воин",
-		["Healer"] = "Лекарь",
-		["Tank"] = "Танк",
-		["Caster"] = "Кастер",
-		["Combat"] = "Сражения",
-		["Compilations"] = "Компиляция",
-		["Data Export"] = "Экспорт данных",
-		["Development Tools"] = "Инструменты разработчика",
-		["Guild"] = "Гильдия",
-		["Frame Modification"] = "Модификация фреймов",
-		["Interface Enhancements"] = "Улучшение интерфейса",
-		["Inventory"] = "Инвентарь",
-		["Library"] = "Библиотеки",
-		["Map"] = "Карта",
-		["Mail"] = "Почта",
-		["Miscellaneous"] = "Разное",
-		["Quest"] = "Задания",
-		["Raid"] = "Рейд",
-		["Tradeskill"] = "Умения",
-		["UnitFrame"] = "Фреймы персонажей",
-	}
-else -- enUS
-	STANDBY = "|cffff5050(standby)|r"
-
-	TITLE = "Title"
-	NOTES = "Notes"
-	VERSION = "Version"
-	AUTHOR = "Author"
-	DATE = "Date"
-	CATEGORY = "Category"
-	EMAIL = "E-mail"
-	WEBSITE = "Website"
-	CREDITS = "Credits"
-	LICENSE = "License"
-
-	ABOUT = "About"
-	PRINT_ADDON_INFO = "Show information about the addon."
-	DONATE = "Donate"
-	DONATE_DESC = "Give a much-needed donation to the author of this addon."
-	HOWTO_DONATE_WINDOWS = "Press Ctrl-A to select the link, then Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."
-	HOWTO_DONATE_MAC = "Press Cmd-A to select the link, then Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."
-
-	CATEGORIES = {
-		["Action Bars"] = "Action Bars",
-		["Auction"] = "Auction",
-		["Audio"] = "Audio",
-		["Battlegrounds/PvP"] = "Battlegrounds/PvP",
-		["Buffs"] = "Buffs",
-		["Chat/Communication"] = "Chat/Communication",
-		["Druid"] = "Druid",
-		["Hunter"] = "Hunter",
-		["Mage"] = "Mage",
-		["Paladin"] = "Paladin",
-		["Priest"] = "Priest",
-		["Rogue"] = "Rogue",
-		["Shaman"] = "Shaman",
-		["Warlock"] = "Warlock",
-		["Warrior"] = "Warrior",
-		["Healer"] = "Healer",
-		["Tank"] = "Tank",
-		["Caster"] = "Caster",
-		["Combat"] = "Combat",
-		["Compilations"] = "Compilations",
-		["Data Export"] = "Data Export",
-		["Development Tools"] = "Development Tools",
-		["Guild"] = "Guild",
-		["Frame Modification"] = "Frame Modification",
-		["Interface Enhancements"] = "Interface Enhancements",
-		["Inventory"] = "Inventory",
-		["Library"] = "Library",
-		["Map"] = "Map",
-		["Mail"] = "Mail",
-		["Miscellaneous"] = "Miscellaneous",
-		["Quest"] = "Quest",
-		["Raid"] = "Raid",
-		["Tradeskill"] = "Tradeskill",
-		["UnitFrame"] = "UnitFrame",
-	}
-end
-
-setmetatable(CATEGORIES, { __index = function(self, key) -- case-insensitive
-	local lowerKey = key:lower()
-	for k,v in pairs(CATEGORIES) do
-		if k:lower() == lowerKey then
-			self[lowerKey] = v
-			return v
-		end
-	end
-end })
-
--- Create the library object
-
-local AceOO = AceLibrary("AceOO-2.0")
-local AceAddon = AceOO.Class()
-local AceEvent
-local AceConsole
-local AceModuleCore
-
-function AceAddon:GetLocalizedCategory(name)
-	self:argCheck(name, 2, "string")
-	return CATEGORIES[name] or UNKNOWN
-end
-
-function AceAddon:ToString()
-	return "AceAddon"
-end
-
-local function print(text)
-	DEFAULT_CHAT_FRAME:AddMessage(text)
-end
-
-function AceAddon:ADDON_LOADED(name)
-	local unregister = true
-	local initAddon = {}
-	while #self.nextAddon > 0 do
-		local addon = table.remove(self.nextAddon, 1)
-		if addon.possibleNames[name] then
-			table.insert(initAddon, addon)
-		else
-			unregister = nil
-			table.insert(self.skipAddon, addon)
-		end
-	end
-	self.nextAddon, self.skipAddon = self.skipAddon, self.nextAddon
-	if unregister then
-		AceAddon:UnregisterEvent("ADDON_LOADED")
-	end
-	while #initAddon > 0 do
-		local addon = table.remove(initAddon, 1)
-		table.insert(self.addons, addon)
-		if not self.addons[name] then
-			self.addons[name] = addon
-		end
-		addon.possibleNames = nil
-		self:InitializeAddon(addon, name)
-	end
-end
-
-local function RegisterOnEnable(self)
-	if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage then -- HACK
-		AceAddon.playerLoginFired = true
-	end
-	if AceAddon.playerLoginFired then
-		AceAddon.addonsStarted[self] = true
-		if (type(self.IsActive) ~= "function" or self:IsActive()) and (not AceModuleCore or not AceModuleCore:IsModule(self) or AceModuleCore:IsModuleActive(self)) then
-			AceAddon:ManualEnable(self)
-		end
-	else
-		if not AceAddon.addonsToOnEnable then
-			AceAddon.addonsToOnEnable = {}
-		end
-		table.insert(AceAddon.addonsToOnEnable, self)
-	end
-end
-
-function AceAddon:InitializeAddon(addon, name)
-	if addon.name == nil then
-		addon.name = name
-	end
-	if GetAddOnMetadata then
-		-- TOC checks
-		if addon.title == nil then
-			addon.title = GetAddOnMetadata(name, "Title")
-		end
-		if type(addon.title) == "string" then
-			local num = addon.title:find(" |cff7fff7f %-Ace2%-|r$")
-			if num then
-				addon.title = addon.title:sub(1, num - 1)
-			end
-			addon.title = addon.title:trim()
-		end
-		if addon.notes == nil then
-			addon.notes = GetAddOnMetadata(name, "Notes")
-		end
-		if type(addon.notes) == "string" then
-			addon.notes = addon.notes:trim()
-		end
-		if addon.version == nil then
-			addon.version = GetAddOnMetadata(name, "Version")
-		end
-		if type(addon.version) == "string" then
-			if addon.version:find("%$Revision: (%d+) %$") then
-				addon.version = addon.version:gsub("%$Revision: (%d+) %$", "%1")
-			elseif addon.version:find("%$Rev: (%d+) %$") then
-				addon.version = addon.version:gsub("%$Rev: (%d+) %$", "%1")
-			elseif addon.version:find("%$LastChangedRevision: (%d+) %$") then
-				addon.version = addon.version:gsub("%$LastChangedRevision: (%d+) %$", "%1")
-			end
-			addon.version = addon.version:trim()
-		end
-		if addon.author == nil then
-			addon.author = GetAddOnMetadata(name, "Author")
-		end
-		if type(addon.author) == "string" then
-			addon.author = addon.author:trim()
-		end
-		if addon.credits == nil then
-			addon.credits = GetAddOnMetadata(name, "X-Credits")
-		end
-		if type(addon.credits) == "string" then
-			addon.credits = addon.credits:trim()
-		end
-		if addon.donate == nil then
-			addon.donate = GetAddOnMetadata(name, "X-Donate")
-		end
-		if type(addon.donate) == "string" then
-			addon.donate = addon.donate:trim()
-		end
-		if addon.date == nil then
-			addon.date = GetAddOnMetadata(name, "X-Date") or GetAddOnMetadata(name, "X-ReleaseDate")
-		end
-		if type(addon.date) == "string" then
-			if addon.date:find("%$Date: (.-) %$") then
-				addon.date = addon.date:gsub("%$Date: (.-) %$", "%1")
-			elseif addon.date:find("%$LastChangedDate: (.-) %$") then
-				addon.date = addon.date:gsub("%$LastChangedDate: (.-) %$", "%1")
-			end
-			addon.date = addon.date:trim()
-		end
-
-		if addon.category == nil then
-			addon.category = GetAddOnMetadata(name, "X-Category")
-		end
-		if type(addon.category) == "string" then
-			addon.category = addon.category:trim()
-		end
-		if addon.email == nil then
-			addon.email = GetAddOnMetadata(name, "X-eMail") or GetAddOnMetadata(name, "X-Email")
-		end
-		if type(addon.email) == "string" then
-			addon.email = addon.email:trim()
-		end
-		if addon.license == nil then
-			addon.license = GetAddOnMetadata(name, "X-License")
-		end
-		if type(addon.license) == "string" then
-			addon.license = addon.license:trim()
-		end
-		if addon.website == nil then
-			addon.website = GetAddOnMetadata(name, "X-Website")
-		end
-		if type(addon.website) == "string" then
-			addon.website = addon.website:trim()
-		end
-	end
-	local current = addon.class
-	while true do
-		if current == AceOO.Class or not current then
-			break
-		end
-		if current.mixins then
-			for mixin in pairs(current.mixins) do
-				if type(mixin.OnEmbedInitialize) == "function" then
-					mixin:OnEmbedInitialize(addon, name)
-				end
-			end
-		end
-		current = current.super
-	end
-	local n = AceAddon.addonsToOnEnable and #AceAddon.addonsToOnEnable or 0
-
-	if type(addon.OnInitialize) == "function" then
-		safecall(addon.OnInitialize, addon, name)
-	end
-	if AceEvent then
-		AceEvent:TriggerEvent("Ace2_AddonInitialized", addon)
-	end
-	RegisterOnEnable(addon)
-	local n2 = AceAddon.addonsToOnEnable and #AceAddon.addonsToOnEnable or 0
-	if n2 - n > 1 then
-		local mine = table.remove(AceAddon.addonsToOnEnable)
-		table.insert(AceAddon.addonsToOnEnable, n+1, mine)
-	end
-end
-
-local aboutFrame
-local function createAboutFrame()
-	aboutFrame = CreateFrame("Frame", "AceAddon20AboutFrame", UIParent, "DialogBoxFrame")
-	aboutFrame:SetWidth(500)
-	aboutFrame:SetHeight(400)
-	aboutFrame:SetPoint("CENTER")
-	aboutFrame:SetBackdrop({
-		bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]],
-	    edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
-	    tile = true, tileSize = 16, edgeSize = 16,
-	    insets = { left = 5, right = 5, top = 5, bottom = 5 }
-	})
-	aboutFrame:SetBackdropColor(0,0,0,1)
-
-	local donateButton = CreateFrame("Button", "AceAddon20AboutFrameDonateButton", aboutFrame, "UIPanelButtonTemplate2")
-	aboutFrame.donateButton = donateButton
-	donateButton:SetPoint("BOTTOMRIGHT", -20, 20)
-	_G.AceAddon20AboutFrameDonateButtonText:SetText(DONATE)
-	donateButton:SetWidth(_G.AceAddon20AboutFrameDonateButtonText:GetWidth()+20)
-	donateButton:SetScript("OnClick", function()
-		aboutFrame.currentAddon:OpenDonationFrame()
-	end)
-
-	local text = aboutFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
-	aboutFrame.title = text
-	text:SetPoint("TOP", 0, -5)
-
-	aboutFrame:Hide()
-
-	aboutFrame.lefts = {}
-	aboutFrame.rights = {}
-	aboutFrame.textLefts = {}
-	aboutFrame.textRights = {}
-	function aboutFrame:Clear()
-		self.title:SetText("")
-		for i = 1, #self.lefts do
-			self.lefts[i] = nil
-			self.rights[i] = nil
-		end
-	end
-
-	function aboutFrame:AddLine(left, right)
-		aboutFrame.lefts[#aboutFrame.lefts+1] = left
-		aboutFrame.rights[#aboutFrame.rights+1] = right
-	end
-
-	local aboutFrame_Show = aboutFrame.Show
-	function aboutFrame:Show(...)
-		local maxLeftWidth = 0
-		local maxRightWidth = 0
-		local textHeight = 0
-		for i = 1, #self.lefts do
-			if not self.textLefts[i] then
-				local left = aboutFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
-				self.textLefts[i] = left
-				local right = aboutFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
-				self.textRights[i] = right
-				if i == 1 then
-					left:SetPoint("TOPRIGHT", aboutFrame, "TOPLEFT", 75, -35)
-				else
-					left:SetPoint("TOPRIGHT", self.textLefts[i-1], "BOTTOMRIGHT", 0, -5)
-				end
-				right:SetPoint("LEFT", left, "RIGHT", 5, 0)
-			end
-			self.textLefts[i]:SetText(self.lefts[i] .. ":")
-			self.textRights[i]:SetText(self.rights[i])
-			local leftWidth = self.textLefts[i]:GetWidth()
-			local rightWidth = self.textRights[i]:GetWidth()
-			textHeight = self.textLefts[i]:GetHeight()
-			if maxLeftWidth < leftWidth then
-				maxLeftWidth = leftWidth
-			end
-			if maxRightWidth < rightWidth then
-				maxRightWidth = rightWidth
-			end
-		end
-		for i = #self.lefts+1, #self.textLefts do
-			self.textLefts[i]:SetText('')
-			self.textRights[i]:SetText('')
-		end
-		aboutFrame:SetWidth(75 + maxRightWidth + 20)
-		aboutFrame:SetHeight(#self.lefts * (textHeight + 5) + 100)
-
-		aboutFrame_Show(self, ...)
-	end
-	aboutFrame:Hide()
-
-	createAboutFrame = nil
-end
-local donateFrame
-
-local function unobfuscateEmail(email)
-	return email:gsub(" AT ", "@"):gsub(" DOT ", ".")
-end
-
-local function isGoodVariable(var)
-	return type(var) == "string" or type(var) == "number"
-end
-function AceAddon.prototype:PrintAddonInfo()
-	if createAboutFrame then
-		createAboutFrame()
-	end
-	aboutFrame:Clear()
-	local x
-	if isGoodVariable(self.title) then
-		x = tostring(self.title)
-	elseif isGoodVariable(self.name) then
-		x = tostring(self.name)
-	else
-		x = "<" .. tostring(self.class) .. " instance>"
-	end
-	if type(self.IsActive) == "function" then
-		if not self:IsActive() then
-			x = x .. " " .. STANDBY
-		end
-	end
-	aboutFrame.title:SetText(x)
-
-	if isGoodVariable(self.version) then
-		aboutFrame:AddLine(VERSION, tostring(self.version))
-	end
-	if isGoodVariable(self.notes) then
-		aboutFrame:AddLine(NOTES, tostring(self.notes))
-	end
-	if isGoodVariable(self.author) then
-		aboutFrame:AddLine(AUTHOR, tostring(self.author))
-	end
-	if isGoodVariable(self.credits) then
-		aboutFrame:AddLine(CREDITS, tostring(self.credits))
-	end
-	if isGoodVariable(self.date) then
-		aboutFrame:AddLine(DATE, tostring(self.date))
-	end
-	if isGoodVariable(self.category) then
-		local category = CATEGORIES[self.category]
-		aboutFrame:AddLine(CATEGORY, category or tostring(self.category))
-	end
-	if isGoodVariable(self.email) then
-		aboutFrame:AddLine(EMAIL, unobfuscateEmail(tostring(self.email)))
-	end
-	if isGoodVariable(self.website) then
-		aboutFrame:AddLine(WEBSITE, tostring(self.website))
-	end
-	if isGoodVariable(self.license) then
-		aboutFrame:AddLine(LICENSE, tostring(self.license))
-	end
-
-	if donateFrame and donateFrame:IsShown() then
-		donateFrame:Hide()
-	end
-
-	aboutFrame.currentAddon = self
-
-	aboutFrame:Show()
-
-	if self.donate then
-		aboutFrame.donateButton:Show()
-	else
-		aboutFrame.donateButton:Hide()
-	end
-end
-
-local function createDonateFrame()
-	donateFrame = CreateFrame("Frame", "AceAddon20Frame", UIParent, "DialogBoxFrame")
-
-	donateFrame:SetWidth(500)
-	donateFrame:SetHeight(200)
-	donateFrame:SetPoint("CENTER")
-	donateFrame:SetBackdrop({
-		bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]],
-		edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
-		tile = true, tileSize = 16, edgeSize = 16,
-		insets = { left = 5, right = 5, top = 5, bottom = 5 }
-	})
-	donateFrame:SetBackdropColor(0,0,0,1)
-
-	local text = donateFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
-	text:SetPoint("TOP", 0, -5)
-	text:SetText(DONATE)
-
-	local howto = donateFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
-	howto:SetPoint("TOP", text, "BOTTOM", 0, -5)
-	howto:SetPoint("LEFT", 16, 0)
-	howto:SetPoint("RIGHT", -16, 0)
-	if not IsMacClient() then
-		-- Windows or Linux
-		howto:SetText(HOWTO_DONATE_WINDOWS)
-	else
-		howto:SetText(HOWTO_DONATE_MAC)
-	end
-
-	local scrollFrame = CreateFrame("ScrollFrame", "AceAddon20FrameScrollFrame", donateFrame, "UIPanelScrollFrameTemplate")
-	scrollFrame:SetToplevel(true)
-	scrollFrame:SetPoint("TOP", -10, -76)
-	scrollFrame:SetWidth(455)
-	scrollFrame:SetHeight(70)
-	howto:SetPoint("BOTTOM", scrollFrame, "TOP")
-
-	local editBox = CreateFrame("EditBox", nil, scrollFrame)
-	donateFrame.editBox = editBox
-	scrollFrame:SetScrollChild(editBox)
-	editBox:SetFontObject(ChatFontNormal)
-	editBox:SetMultiLine(true)
-	editBox:SetMaxLetters(99999)
-	editBox:SetWidth(450)
-	editBox:SetHeight(54)
-	editBox:SetPoint("BOTTOM", 5, 0)
-	editBox:SetJustifyH("LEFT")
-	editBox:SetJustifyV("TOP")
-	editBox:SetAutoFocus(false)
-	editBox:SetScript("OnTextChanged", function(this)
-		if this:GetText() ~= this.text then
-			this:SetText(this.text)
-		end
-	end)
-	editBox:SetScript("OnEscapePressed", function(this)
-		this:ClearFocus()
-	end)
-	createDonateFrame = nil
-end
-
-local function fix(char)
-	return ("%%%02x"):format(char:byte())
-end
-
-local function urlencode(text)
-	return text:gsub("[^0-9A-Za-z]", fix)
-end
-
-function AceAddon.prototype:OpenDonationFrame()
-	if createDonateFrame then
-		createDonateFrame()
-	end
-	local donate = self.donate
-	if type(donate) ~= "string" then
-		donate = "Wowace"
-	end
-	local style, data = (":"):split(donate, 2)
-	style = style:lower()
-	if style ~= "website" and style ~= "paypal" then
-		style = "wowace"
-	end
-	if style == "wowace" then
-		donateFrame.editBox.text = "http://www.wowace.com/wiki/Donations"
-	elseif style == "website" then
-		donateFrame.editBox.text = data
-	else -- PayPal
-		local text = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=" .. urlencode(unobfuscateEmail(data))
-		local name
-		if type(self.title) == "string" then
-			name = self.title
-		elseif type(self.name) == "string" then
-			name = self.name
-		end
-		if name then
-			name = name:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "")
-			text = text .. "&item_name=" .. urlencode(name)
-		end
-		donateFrame.editBox.text = text
-	end
-	donateFrame.editBox:SetText(donateFrame.editBox.text)
-
-	if aboutFrame and aboutFrame:IsShown() then
-		aboutFrame:Hide()
-	end
-
-	donateFrame:Show()
-
-	donateFrame.editBox:SetFocus()
-end
-
-local options
-function AceAddon:GetAceOptionsDataTable(target)
-	return {
-		about = {
-			name = ABOUT,
-			desc = PRINT_ADDON_INFO,
-			type = "execute",
-			func = "PrintAddonInfo",
-			order = -1,
-		},
-		donate = {
-			name = DONATE,
-			desc = DONATE_DESC,
-			type = "execute",
-			func = "OpenDonationFrame",
-			order = -1,
-			hidden = function()
-				return not target.donate
-			end
-		}
-	}
-end
-
-function AceAddon:PLAYER_LOGIN()
-	self.playerLoginFired = true
-	if self.addonsToOnEnable then
-		while #self.addonsToOnEnable > 0 do
-			local addon = table.remove(self.addonsToOnEnable, 1)
-			self.addonsStarted[addon] = true
-			if (type(addon.IsActive) ~= "function" or addon:IsActive()) and (not AceModuleCore or not AceModuleCore:IsModule(addon) or AceModuleCore:IsModuleActive(addon)) then
-				AceAddon:ManualEnable(addon)
-			end
-		end
-		self.addonsToOnEnable = nil
-	end
-end
-
-function AceAddon.prototype:Inject(t)
-	AceAddon:argCheck(t, 2, "table")
-	for k,v in pairs(t) do
-		self[k] = v
-	end
-end
-
-function AceAddon.prototype:init()
-	if not AceEvent then
-		error(MAJOR_VERSION .. " requires AceEvent-2.0", 4)
-	end
-	AceAddon.super.prototype.init(self)
-
-	self.super = self.class.prototype
-
-	AceAddon:RegisterEvent("ADDON_LOADED", "ADDON_LOADED")
-	local names = {}
-	for i = 1, GetNumAddOns() do
-		if IsAddOnLoaded(i) then names[GetAddOnInfo(i)] = true end
-	end
-	self.possibleNames = names
-	table.insert(AceAddon.nextAddon, self)
-end
-
-function AceAddon.prototype:ToString()
-	local x
-	if type(self.title) == "string" then
-		x = self.title
-	elseif type(self.name) == "string" then
-		x = self.name
-	else
-		x = "<" .. tostring(self.class) .. " instance>"
-	end
-	if (type(self.IsActive) == "function" and not self:IsActive()) or (AceModuleCore and AceModuleCore:IsModule(addon) and AceModuleCore:IsModuleActive(addon)) then
-		x = x .. " " .. STANDBY
-	end
-	return x
-end
-
-AceAddon.new = function(self, ...)
-	local class = AceAddon:pcall(AceOO.Classpool, self, ...)
-	return class:new()
-end
-
-function AceAddon:ManualEnable(addon)
-	AceAddon:argCheck(addon, 2, "table")
-	local first = nil
-	if AceOO.inherits(addon, "AceAddon-2.0") then
-		if AceAddon.addonsEnabled and not AceAddon.addonsEnabled[addon] then
-			first = true
-			AceAddon.addonsEnabled[addon] = true
-		end
-	end
-	local current = addon.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, addon, first)
-				end
-			end
-		end
-		current = current.super
-	end
-	if type(addon.OnEnable) == "function" then
-		safecall(addon.OnEnable, addon, first)
-	end
-	if AceEvent then
-		AceEvent:TriggerEvent("Ace2_AddonEnabled", addon, first)
-	end
-end
-
-function AceAddon:ManualDisable(addon)
-	AceAddon:argCheck(addon, 2, "table")
-	local current = addon.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, addon)
-				end
-			end
-		end
-		current = current.super
-	end
-	if type(module.OnDisable) == "function" then
-		safecall(module.OnDisable, addon)
-	end
-	if AceEvent then
-		AceEvent:TriggerEvent("Ace2_AddonDisabled", addon)
-	end
-end
-
-local function external(self, major, instance)
-	if major == "AceEvent-2.0" then
-		AceEvent = instance
-
-		AceEvent:embed(self)
-
-		self:RegisterEvent("PLAYER_LOGIN", "PLAYER_LOGIN", true)
-	elseif major == "AceConsole-2.0" then
-		AceConsole = instance
-
-		local slashCommands = { "/ace2" }
-		local _,_,_,enabled,loadable = GetAddOnInfo("Ace")
-		if not enabled or not loadable then
-			table.insert(slashCommands, "/ace")
-		end
-		local function listAddon(addon, depth)
-			if not depth then
-				depth = 0
-			end
-
-			local s = ("  "):rep(depth) .. " - " .. tostring(addon)
-			if rawget(addon, 'version') then
-				s = s .. " - |cffffff7f" .. tostring(addon.version) .. "|r"
-			end
-			if rawget(addon, 'slashCommand') then
-				s = s .. " |cffffff7f(" .. tostring(addon.slashCommand) .. ")|r"
-			end
-			print(s)
-			if type(rawget(addon, 'modules')) == "table" then
-				local i = 0
-				for k,v in pairs(addon.modules) do
-					i = i + 1
-					if i == 6 then
-						print(("  "):rep(depth + 1) .. " - more...")
-						break
-					else
-						listAddon(v, depth + 1)
-					end
-				end
-			end
-		end
-		local function listNormalAddon(i)
-			local name,_,_,enabled,loadable = GetAddOnInfo(i)
-			if not loadable then
-				enabled = false
-			end
-			if self.addons[name] then
-				listAddon(self.addons[name])
-			else
-				local s = " - " .. tostring(GetAddOnMetadata(i, "Title") or name)
-				local version = GetAddOnMetadata(i, "Version")
-				if version then
-					if version:find("%$Revision: (%d+) %$") then
-						version = version:gsub("%$Revision: (%d+) %$", "%1")
-					elseif version:find("%$Rev: (%d+) %$") then
-						version = version:gsub("%$Rev: (%d+) %$", "%1")
-					elseif version:find("%$LastChangedRevision: (%d+) %$") then
-						version = version:gsub("%$LastChangedRevision: (%d+) %$", "%1")
-					end
-					s = s .. " - |cffffff7f" .. version .. "|r"
-				end
-				if not enabled then
-					s = s .. " |cffff0000(disabled)|r"
-				end
-				if IsAddOnLoadOnDemand(i) then
-					s = s .. " |cff00ff00[LoD]|r"
-				end
-				print(s)
-			end
-		end
-		local function mySort(alpha, bravo)
-			return tostring(alpha) < tostring(bravo)
-		end
-		AceConsole.RegisterChatCommand(self, slashCommands, {
-			desc = "AddOn development framework",
-			name = "Ace2",
-			type = "group",
-			args = {
-				about = {
-					desc = "Get information about Ace2",
-					name = "About",
-					type = "execute",
-					func = function()
-						print("|cffffff7fAce2|r - |cffffff7f2.0." .. MINOR_VERSION:gsub("%$Revision: (%d+) %$", "%1") .. "|r - AddOn development framework")
-						print(" - |cffffff7f" .. AUTHOR .. ":|r Ace Development Team")
-						print(" - |cffffff7f" .. WEBSITE .. ":|r http://www.wowace.com/")
-					end
-				},
-				list = {
-					desc = "List addons",
-					name = "List",
-					type = "group",
-					args = {
-						ace2 = {
-							desc = "List addons using Ace2",
-							name = "Ace2",
-							type = "execute",
-							func = function()
-								print("|cffffff7fAddon list:|r")
-								table.sort(self.addons, mySort)
-								for _,v in ipairs(self.addons) do
-									listAddon(v)
-								end
-							end
-						},
-						all = {
-							desc = "List all addons",
-							name = "All",
-							type = "execute",
-							func = function()
-								print("|cffffff7fAddon list:|r")
-								local count = GetNumAddOns()
-								for i = 1, count do
-									listNormalAddon(i)
-								end
-							end
-						},
-						enabled = {
-							desc = "List all enabled addons",
-							name = "Enabled",
-							type = "execute",
-							func = function()
-								print("|cffffff7fAddon list:|r")
-								local count = GetNumAddOns()
-								for i = 1, count do
-									local _,_,_,enabled,loadable = GetAddOnInfo(i)
-									if enabled and loadable then
-										listNormalAddon(i)
-									end
-								end
-							end
-						},
-						disabled = {
-							desc = "List all disabled addons",
-							name = "Disabled",
-							type = "execute",
-							func = function()
-								print("|cffffff7fAddon list:|r")
-								local count = GetNumAddOns()
-								for i = 1, count do
-									local _,_,_,enabled,loadable = GetAddOnInfo(i)
-									if not enabled or not loadable then
-										listNormalAddon(i)
-									end
-								end
-							end
-						},
-						lod = {
-							desc = "List all LoadOnDemand addons",
-							name = "LoadOnDemand",
-							type = "execute",
-							func = function()
-								print("|cffffff7fAddon list:|r")
-								local count = GetNumAddOns()
-								for i = 1, count do
-									if IsAddOnLoadOnDemand(i) then
-										listNormalAddon(i)
-									end
-								end
-							end
-						},
-						ace1 = {
-							desc = "List all addons using Ace1",
-							name = "Ace 1.x",
-							type = "execute",
-							func = function()
-								print("|cffffff7fAddon list:|r")
-								local count = GetNumAddOns()
-								for i = 1, count do
-									local dep1, dep2, dep3, dep4 = GetAddOnDependencies(i)
-									if dep1 == "Ace" or dep2 == "Ace" or dep3 == "Ace" or dep4 == "Ace" then
-										listNormalAddon(i)
-									end
-								end
-							end
-						},
-						libs = {
-							desc = "List all libraries using AceLibrary",
-							name = "Libraries",
-							type = "execute",
-							func = function()
-								if type(AceLibrary) == "table" and type(AceLibrary.libs) == "table" then
-									print("|cffffff7fLibrary list:|r")
-									for name, data in pairs(AceLibrary.libs) do
-										local s
-										if data.minor then
-											s = " - " .. tostring(name) .. "." .. tostring(data.minor)
-										else
-											s = " - " .. tostring(name)
-										end
-										if rawget(AceLibrary(name), 'slashCommand') then
-											s = s .. " |cffffff7f(" .. tostring(AceLibrary(name).slashCommand) .. "|cffffff7f)"
-										end
-										print(s)
-									end
-								end
-							end
-						},
-						search = {
-							desc = "Search by name",
-							name = "Search",
-							type = "text",
-							usage = "<keyword>",
-							input = true,
-							get = false,
-							set = function(...)
-								local arg = { ... }
-								for i,v in ipairs(arg) do
-									arg[i] = v:gsub('%*', '.*'):gsub('%%', '%%%%'):lower()
-								end
-								local count = GetNumAddOns()
-								for i = 1, count do
-									local name = GetAddOnInfo(i)
-									local good = true
-									for _,v in ipairs(arg) do
-										if not name:lower():find(v) then
-											good = false
-											break
-										end
-									end
-									if good then
-										listNormalAddon(i)
-									end
-								end
-							end
-						}
-					},
-				},
-				enable = {
-					desc = "Enable addon(s).",
-					name = "Enable",
-					type = "text",
-					usage = "<addon 1> <addon 2> ...",
-					get = false,
-					input = true,
-					set = function(...)
-						for i = 1, select("#", ...) do
-							local addon = select(i, ...)
-							local name, title, _, enabled, _, reason = GetAddOnInfo(addon)
-							if reason == "MISSING" then
-								print(("|cffffff7fAce2:|r AddOn %q does not exist."):format(addon))
-							elseif not enabled then
-								EnableAddOn(addon)
-								print(("|cffffff7fAce2:|r %s is now enabled."):format(addon or name))
-							else
-								print(("|cffffff7fAce2:|r %s is already enabled."):format(addon or name))
-							end
-						end
-					end,
-				},
-				disable = {
-					desc = "Disable addon(s).",
-					name = "Disable",
-					type = "text",
-					usage = "<addon 1> <addon 2> ...",
-					get = false,
-					input = true,
-					set = function(...)
-						for i = 1, select("#", ...) do
-							local addon = select(i, ...)
-							local name, title, _, enabled, _, reason = GetAddOnInfo(addon)
-							if reason == "MISSING" then
-							print(("|cffffff7fAce2:|r AddOn %q does not exist."):format(addon))
-							elseif enabled then
-								DisableAddOn(addon)
-								print(("|cffffff7fAce2:|r %s is now disabled."):format(addon or name))
-							else
-								print(("|cffffff7fAce2:|r %s is already disabled."):format(addon or name))
-							end
-						end
-					end,
-				},
-				load = {
-					desc = "Load addon(s).",
-					name = "Load",
-					type = "text",
-					usage = "<addon 1> <addon 2> ...",
-					get = false,
-					input = true,
-					set = function(...)
-						for i = 1, select("#", ...) do
-							local addon = select(i, ...)
-							local name, title, _, _, loadable, reason = GetAddOnInfo(addon)
-							if reason == "MISSING" then
-								print(("|cffffff7fAce2:|r AddOn %q does not exist."):format(addon))
-							elseif not loadable then
-								print(("|cffffff7fAce2:|r AddOn %q is not loadable. Reason: %s."):format(addon, reason))
-							else
-								LoadAddOn(addon)
-								print(("|cffffff7fAce2:|r %s is now loaded."):format(addon or name))
-							end
-						end
-					end
-				},
-				info = {
-					desc = "Display information",
-					name = "Information",
-					type = "execute",
-					func = function()
-						local mem, threshold = gcinfo()
-						print((" - |cffffff7fMemory usage [|r%.3f MiB|cffffff7f]|r"):format(mem / 1024))
-						if threshold then
-							print((" - |cffffff7fThreshold [|r%.3f MiB|cffffff7f]|r"):format(threshold / 1024))
-						end
-						print((" - |cffffff7fFramerate [|r%.0f fps|cffffff7f]|r"):format(GetFramerate()))
-						local bandwidthIn, bandwidthOut, latency = GetNetStats()
-						bandwidthIn, bandwidthOut = floor(bandwidthIn * 1024), floor(bandwidthOut * 1024)
-						print((" - |cffffff7fLatency [|r%.0f ms|cffffff7f]|r"):format(latency))
-						print((" - |cffffff7fBandwidth in [|r%.0f B/s|cffffff7f]|r"):format(bandwidthIn))
-						print((" - |cffffff7fBandwidth out [|r%.0f B/s|cffffff7f]|r"):format(bandwidthOut))
-						print((" - |cffffff7fTotal addons [|r%d|cffffff7f]|r"):format(GetNumAddOns()))
-						print((" - |cffffff7fAce2 addons [|r%d|cffffff7f]|r"):format(#self.addons))
-						local ace = 0
-						local enabled = 0
-						local disabled = 0
-						local lod = 0
-						for i = 1, GetNumAddOns() do
-							local dep1, dep2, dep3, dep4 = GetAddOnDependencies(i)
-							if dep1 == "Ace" or dep2 == "Ace" or dep3 == "Ace" or dep4 == "Ace" then
-								ace = ace + 1
-							end
-							if IsAddOnLoadOnDemand(i) then
-								lod = lod + 1
-							end
-							local isActive, loadable = select(4, GetAddOnInfo(i))
-							if not isActive or not loadable then
-								disabled = disabled + 1
-							else
-								enabled = enabled + 1
-							end
-						end
-						print((" - |cffffff7fAce 1.x addons [|r%d|cffffff7f]|r"):format(ace))
-						print((" - |cffffff7fLoadOnDemand addons [|r%d|cffffff7f]|r"):format(lod))
-						print((" - |cffffff7fenabled addons [|r%d|cffffff7f]|r"):format(enabled))
-						print((" - |cffffff7fdisabled addons [|r%d|cffffff7f]|r"):format(disabled))
-						local libs = 0
-						if type(AceLibrary) == "table" and type(AceLibrary.libs) == "table" then
-							for _ in pairs(AceLibrary.libs) do
-								libs = libs + 1
-							end
-						end
-						print((" - |cffffff7fAceLibrary instances [|r%d|cffffff7f]|r"):format(libs))
-					end
-				}
-			}
-		})
-	elseif major == "AceModuleCore-2.0" then
-		AceModuleCore = instance
-	end
-end
-
-local function activate(self, oldLib, oldDeactivate)
-	AceAddon = self
-
-	self.playerLoginFired = oldLib and oldLib.playerLoginFired or DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage
-	self.addonsToOnEnable = oldLib and oldLib.addonsToOnEnable
-	self.addons = oldLib and oldLib.addons or {}
-	self.nextAddon = oldLib and oldLib.nextAddon or {}
-	self.skipAddon = oldLib and oldLib.skipAddon or {}
-	self.addonsStarted = oldLib and oldLib.addonsStarted or {}
-	self.addonsEnabled = oldLib and oldLib.addonsEnabled or {}
-
-	if oldDeactivate then
-		oldDeactivate(oldLib)
-	end
-end
-
-AceLibrary:Register(AceAddon, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
+--[[
+Name: AceAddon-2.0
+Revision: $Rev: 1094 $
+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/wiki/AceAddon-2.0
+SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceAddon-2.0
+Description: Base for all Ace addons to inherit from.
+Dependencies: AceLibrary, AceOO-2.0, AceEvent-2.0, (optional) AceConsole-2.0
+License: LGPL v2.1
+]]
+
+local MAJOR_VERSION = "AceAddon-2.0"
+local MINOR_VERSION = 90000 + tonumber(("$Revision: 1094 $"):match("(%d+)"))
+
+-- This ensures the code is only executed if the libary doesn't already exist, or is a newer version
+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:find("%.lua:%d+:") and err or (debugstack():match("\n(.-: )in.-\n") or "") .. err) end
+end
+-- Localization
+local STANDBY, TITLE, NOTES, VERSION, AUTHOR, DATE, CATEGORY, EMAIL, CREDITS, WEBSITE, CATEGORIES, ABOUT, LICENSE, PRINT_ADDON_INFO, DONATE, DONATE_DESC, HOWTO_DONATE_WINDOWS, HOWTO_DONATE_MAC
+if GetLocale() == "deDE" then
+	STANDBY = "|cffff5050(Standby)|r" -- capitalized
+
+	TITLE = "Titel"
+	NOTES = "Anmerkung"
+	VERSION = "Version"
+	AUTHOR = "Autor"
+	DATE = "Datum"
+	CATEGORY = "Kategorie"
+	EMAIL = "E-Mail"
+	WEBSITE = "Webseite"
+	CREDITS = "Credits" -- fix
+	LICENSE = "License" -- fix
+
+	ABOUT = "Über"
+	PRINT_ADDON_INFO = "Gibt Addondaten aus"
+	DONATE = "Donate" -- fix
+	DONATE_DESC = "Give a much-needed donation to the author of this addon." -- fix
+	HOWTO_DONATE_WINDOWS = "Press Ctrl-A to select the link, then Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
+	HOWTO_DONATE_MAC = "Press Cmd-A to select the link, then Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
+
+	CATEGORIES = {
+		["Action Bars"] = "Aktionsleisten",
+		["Auction"] = "Auktion",
+		["Audio"] = "Audio",
+		["Battlegrounds/PvP"] = "Schlachtfeld/PvP",
+		["Buffs"] = "Stärkungszauber",
+		["Chat/Communication"] = "Chat/Kommunikation",
+		["Druid"] = "Druide",
+		["Hunter"] = "Jäger",
+		["Mage"] = "Magier",
+		["Paladin"] = "Paladin",
+		["Priest"] = "Priester",
+		["Rogue"] = "Schurke",
+		["Shaman"] = "Schamane",
+		["Warlock"] = "Hexenmeister",
+		["Warrior"] = "Krieger",
+		["Healer"] = "Heiler",
+		["Tank"] = "Tank",
+		["Caster"] = "Zauberer",
+		["Combat"] = "Kampf",
+		["Compilations"] = "Zusammenstellungen",
+		["Data Export"] = "Datenexport",
+		["Development Tools"] = "Entwicklungs Tools",
+		["Guild"] = "Gilde",
+		["Frame Modification"] = "Frame Veränderungen",
+		["Interface Enhancements"] = "Interface Verbesserungen",
+		["Inventory"] = "Inventar",
+		["Library"] = "Bibliotheken",
+		["Map"] = "Karte",
+		["Mail"] = "Post",
+		["Miscellaneous"] = "Diverses",
+		["Quest"] = "Quest",
+		["Raid"] = "Schlachtzug",
+		["Tradeskill"] = "Beruf",
+		["UnitFrame"] = "Einheiten-Fenster",
+	}
+elseif GetLocale() == "frFR" then
+	STANDBY = "|cffff5050(attente)|r"
+
+	TITLE = "Titre"
+	NOTES = "Notes"
+	VERSION = "Version"
+	AUTHOR = "Auteur"
+	DATE = "Date"
+	CATEGORY = "Catégorie"
+	EMAIL = "E-mail"
+	WEBSITE = "Site web"
+	CREDITS = "Credits" -- fix
+	LICENSE = "License" -- fix
+
+	ABOUT = "A propos"
+	PRINT_ADDON_INFO = "Afficher les informations sur l'addon"
+	DONATE = "Donate" -- fix
+	DONATE_DESC = "Give a much-needed donation to the author of this addon." -- fix
+	HOWTO_DONATE_WINDOWS = "Press Ctrl-A to select the link, then Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
+	HOWTO_DONATE_MAC = "Press Cmd-A to select the link, then Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
+
+	CATEGORIES = {
+		["Action Bars"] = "Barres d'action",
+		["Auction"] = "Hôtel des ventes",
+		["Audio"] = "Audio",
+		["Battlegrounds/PvP"] = "Champs de bataille/JcJ",
+		["Buffs"] = "Buffs",
+		["Chat/Communication"] = "Chat/Communication",
+		["Druid"] = "Druide",
+		["Hunter"] = "Chasseur",
+		["Mage"] = "Mage",
+		["Paladin"] = "Paladin",
+		["Priest"] = "Prêtre",
+		["Rogue"] = "Voleur",
+		["Shaman"] = "Chaman",
+		["Warlock"] = "Démoniste",
+		["Warrior"] = "Guerrier",
+		["Healer"] = "Soigneur",
+		["Tank"] = "Tank",
+		["Caster"] = "Casteur",
+		["Combat"] = "Combat",
+		["Compilations"] = "Compilations",
+		["Data Export"] = "Exportation de données",
+		["Development Tools"] = "Outils de développement",
+		["Guild"] = "Guilde",
+		["Frame Modification"] = "Modification des fenêtres",
+		["Interface Enhancements"] = "Améliorations de l'interface",
+		["Inventory"] = "Inventaire",
+		["Library"] = "Bibliothèques",
+		["Map"] = "Carte",
+		["Mail"] = "Courrier",
+		["Miscellaneous"] = "Divers",
+		["Quest"] = "Quêtes",
+		["Raid"] = "Raid",
+		["Tradeskill"] = "Métiers",
+		["UnitFrame"] = "Fenêtres d'unité",
+	}
+elseif GetLocale() == "koKR" then
+	STANDBY = "|cffff5050(사용가능)|r"
+
+	TITLE = "제목"
+	NOTES = "노트"
+	VERSION = "버전"
+	AUTHOR = "저작자"
+	DATE = "날짜"
+	CATEGORY = "분류"
+	EMAIL = "전자 우편"
+	WEBSITE = "웹 사이트"
+	CREDITS = "공로자"
+	LICENSE = "라이센스"
+
+	ABOUT = "정보"
+	PRINT_ADDON_INFO = "애드온에 대한 정보를 출력합니다."
+	DONATE = "기부"
+	DONATE_DESC = "이 애드온의 저작자에게 기부를 합니다."
+	HOWTO_DONATE_WINDOWS = "Ctrl-A를 눌려 링크를 선택후, Ctrl-C로 복사합니다. Alt-Tab 눌려 게임으로 부터 나간후 웹 브라우저를 엽니다. 복사된 링크를 주소 창에 붙여넣기 합니다."
+	HOWTO_DONATE_MAC = "Cmd-A를 눌려 링크를 선택후, Cmd-C로 복사합니다. Cmd-Tab 눌려 게임으로 부터 나간후 웹 브라우저를 엽니다. 복사된 링크를 주소 창에 붙여넣기 합니다."
+
+	CATEGORIES = {
+		["Action Bars"] = "액션바",
+		["Auction"] = "경매",
+		["Audio"] = "음향",
+		["Battlegrounds/PvP"] = "전장/PvP",
+		["Buffs"] = "버프",
+		["Chat/Communication"] = "대화/의사소통",
+		["Druid"] = "드루이드",
+		["Hunter"] = "사냥꾼",
+		["Mage"] = "마법사",
+		["Paladin"] = "성기사",
+		["Priest"] = "사제",
+		["Rogue"] = "도적",
+		["Shaman"] = "주술사",
+		["Warlock"] = "흑마법사",
+		["Warrior"] = "전사",
+		["Healer"] = "힐러",
+		["Tank"] = "탱커",
+		["Caster"] = "캐스터",
+		["Combat"] = "전투",
+		["Compilations"] = "복합",
+		["Data Export"] = "자료 출력",
+		["Development Tools"] = "개발 도구",
+		["Guild"] = "길드",
+		["Frame Modification"] = "구조 변경",
+		["Interface Enhancements"] = "인터페이스 강화",
+		["Inventory"] = "인벤토리",
+		["Library"] = "라이브러리",
+		["Map"] = "지도",
+		["Mail"] = "우편",
+		["Miscellaneous"] = "기타",
+		["Quest"] = "퀘스트",
+		["Raid"] = "공격대",
+		["Tradeskill"] = "전문기술",
+		["UnitFrame"] = "유닛 프레임",
+	}
+elseif GetLocale() == "zhTW" then
+	STANDBY = "|cffff5050(待命)|r"
+
+	TITLE = "標題"
+	NOTES = "註記"
+	VERSION = "版本"
+	AUTHOR = "作者"
+	DATE = "日期"
+	CATEGORY = "類別"
+	EMAIL = "電子郵件"
+	WEBSITE = "網站"
+	CREDITS = "特別感謝"
+	LICENSE = "版權"
+
+	ABOUT = "關於"
+	PRINT_ADDON_INFO = "顯示插件資訊。"
+	DONATE = "捐贈"
+	DONATE_DESC = "捐贈金錢給插件作者。"
+	HOWTO_DONATE_WINDOWS = "請按Ctrl-A選擇網站連結,Ctrl-C複製網址,Alt-Tab切換到電腦桌面,打開瀏覽器,在網址列貼上網址。"
+	HOWTO_DONATE_MAC = "請按Cmd-A選擇網站連結,Cmd-C複製網址,Cmd-Tab切換到電腦桌面,打開瀏覽器,在網址列貼上網址。"
+
+	CATEGORIES = {
+		["Action Bars"] = "動作條",
+		["Auction"] = "拍賣",
+		["Audio"] = "音效",
+		["Battlegrounds/PvP"] = "戰場/PvP",
+		["Buffs"] = "增益",
+		["Chat/Communication"] = "聊天/通訊",
+		["Druid"] = "德魯伊",
+		["Hunter"] = "獵人",
+		["Mage"] = "法師",
+		["Paladin"] = "聖騎士",
+		["Priest"] = "牧師",
+		["Rogue"] = "盜賊",
+		["Shaman"] = "薩滿",
+		["Warlock"] = "術士",
+		["Warrior"] = "戰士",
+		["Healer"] = "治療者",
+		["Tank"] = "坦克",
+		["Caster"] = "施法者",
+		["Combat"] = "戰鬥",
+		["Compilations"] = "整合",
+		["Data Export"] = "資料匯出",
+		["Development Tools"] = "開發工具",
+		["Guild"] = "公會",
+		["Frame Modification"] = "框架修改",
+		["Interface Enhancements"] = "介面增強",
+		["Inventory"] = "庫存",
+		["Library"] = "程式庫",
+		["Map"] = "地圖",
+		["Mail"] = "郵件",
+		["Miscellaneous"] = "雜項",
+		["Quest"] = "任務",
+		["Raid"] = "團隊",
+		["Tradeskill"] = "交易技能",
+		["UnitFrame"] = "單位框架",
+	}
+elseif GetLocale() == "zhCN" then
+	STANDBY = "|cffff5050(暂挂)|r"
+
+	TITLE = "标题"
+	NOTES = "附注"
+	VERSION = "版本"
+	AUTHOR = "作者"
+	DATE = "日期"
+	CATEGORY = "分类"
+	EMAIL = "电子邮件"
+	WEBSITE = "网站"
+	CREDITS = "Credits" -- fix
+	LICENSE = "License" -- fix
+
+	ABOUT = "关于"
+	PRINT_ADDON_INFO = "印列出插件信息"
+	DONATE = "Donate" -- fix
+	DONATE_DESC = "Give a much-needed donation to the author of this addon." -- fix
+	HOWTO_DONATE_WINDOWS = "Press Ctrl-A to select the link, then Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
+	HOWTO_DONATE_MAC = "Press Cmd-A to select the link, then Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
+
+	CATEGORIES = {
+		["Action Bars"] = "动作条",
+		["Auction"] = "拍卖",
+		["Audio"] = "音频",
+		["Battlegrounds/PvP"] = "战场/PvP",
+		["Buffs"] = "增益魔法",
+		["Chat/Communication"] = "聊天/交流",
+		["Druid"] = "德鲁伊",
+		["Hunter"] = "猎人",
+		["Mage"] = "法师",
+		["Paladin"] = "圣骑士",
+		["Priest"] = "牧师",
+		["Rogue"] = "盗贼",
+		["Shaman"] = "萨满祭司",
+		["Warlock"] = "术士",
+		["Warrior"] = "战士",
+		["Healer"] = "Healer",
+		["Tank"] = "Tank",
+		["Caster"] = "Caster",
+		["Combat"] = "战斗",
+		["Compilations"] = "编译",
+		["Data Export"] = "数据导出",
+		["Development Tools"] = "开发工具",
+		["Guild"] = "公会",
+		["Frame Modification"] = "框架修改",
+		["Interface Enhancements"] = "界面增强",
+		["Inventory"] = "背包",
+		["Library"] = "库",
+		["Map"] = "地图",
+		["Mail"] = "邮件",
+		["Miscellaneous"] = "杂项",
+		["Quest"] = "任务",
+		["Raid"] = "团队",
+		["Tradeskill"] = "商业技能",
+		["UnitFrame"] = "头像框架",
+	}
+elseif GetLocale() == "esES" then
+	STANDBY = "|cffff5050(espera)|r"
+
+	TITLE = "Título"
+	NOTES = "Notas"
+	VERSION = "Versión"
+	AUTHOR = "Autor"
+	DATE = "Fecha"
+	CATEGORY = "Categoría"
+	EMAIL = "E-mail"
+	WEBSITE = "Web"
+	CREDITS = "Créditos"
+	LICENSE = "License" -- fix
+
+	ABOUT = "Acerca de"
+	PRINT_ADDON_INFO = "Muestra información acerca del accesorio."
+	DONATE = "Donate" -- fix
+	DONATE_DESC = "Give a much-needed donation to the author of this addon." -- fix
+	HOWTO_DONATE_WINDOWS = "Press Ctrl-A to select the link, then Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
+	HOWTO_DONATE_MAC = "Press Cmd-A to select the link, then Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar." -- fix
+
+	CATEGORIES = {
+		["Action Bars"] = "Barras de Acción",
+		["Auction"] = "Subasta",
+		["Audio"] = "Audio",
+		["Battlegrounds/PvP"] = "Campos de Batalla/JcJ",
+		["Buffs"] = "Buffs",
+		["Chat/Communication"] = "Chat/Comunicación",
+		["Druid"] = "Druida",
+		["Hunter"] = "Cazador",
+		["Mage"] = "Mago",
+		["Paladin"] = "Paladín",
+		["Priest"] = "Sacerdote",
+		["Rogue"] = "Pícaro",
+		["Shaman"] = "Chamán",
+		["Warlock"] = "Brujo",
+		["Warrior"] = "Guerrero",
+		["Healer"] = "Sanador",
+		["Tank"] = "Tanque",
+		["Caster"] = "Conjurador",
+		["Combat"] = "Combate",
+		["Compilations"] = "Compilaciones",
+		["Data Export"] = "Exportar Datos",
+		["Development Tools"] = "Herramientas de Desarrollo",
+		["Guild"] = "Hermandad",
+		["Frame Modification"] = "Modificación de Marcos",
+		["Interface Enhancements"] = "Mejoras de la Interfaz",
+		["Inventory"] = "Inventario",
+		["Library"] = "Biblioteca",
+		["Map"] = "Mapa",
+		["Mail"] = "Correo",
+		["Miscellaneous"] = "Misceláneo",
+		["Quest"] = "Misión",
+		["Raid"] = "Banda",
+		["Tradeskill"] = "Habilidad de Comercio",
+		["UnitFrame"] = "Marco de Unidades",
+	}
+elseif GetLocale() == "ruRU" then
+	STANDBY = "|cffff5050(в режиме ожидания)|r"
+
+	TITLE = "Название"
+	NOTES = "Описание"
+	VERSION = "Версия"
+	AUTHOR = "Автор"
+	DATE = "Дата"
+	CATEGORY = "Категория"
+	EMAIL = "E-mail"
+	WEBSITE = "Сайт"
+	CREDITS = "Титры"
+	LICENSE = "Лицензия"
+
+	ABOUT = "Об аддоне"
+	PRINT_ADDON_INFO = "Показать информацию об аддоне."
+	DONATE = "Пожертвовать"
+	DONATE_DESC = "Отблагодарить автора за разработку аддона."
+	HOWTO_DONATE_WINDOWS = "Для выделения всей ссылки нажмите Ctrl-A, потом для её копирования Ctrl-C, чтобы свернуть игру - Alt-Tab, откройте ваш браузер и вставьте ссылку в адресную строку - Ctrl-V"
+	HOWTO_DONATE_MAC = "Для выделения всей ссылки нажмите Cmd-A, потом для её копирования Ctrl-C, чтобы свернуть игру -  Cmd-Tab, откройте ваш браузер и вставьте ссылку в адресную строку Cmd-V"
+
+	CATEGORIES = {
+		["Action Bars"] = "Панели команд",
+		["Auction"] = "Аукцион",
+		["Audio"] = "Аудио",
+		["Battlegrounds/PvP"] = "Поля сражений/PvP",
+		["Buffs"] = "Баффы",
+		["Chat/Communication"] = "Чат/Коммуникация",
+		["Druid"] = "Друид",
+		["Hunter"] = "Охотник",
+		["Mage"] = "Маг",
+		["Paladin"] = "Паладин",
+		["Priest"] = "Жрец",
+		["Rogue"] = "Разбойник",
+		["Shaman"] = "Шаман",
+		["Warlock"] = "Чернокнижник",
+		["Warrior"] = "Воин",
+		["Healer"] = "Лекарь",
+		["Tank"] = "Танк",
+		["Caster"] = "Кастер",
+		["Combat"] = "Сражения",
+		["Compilations"] = "Компиляция",
+		["Data Export"] = "Экспорт данных",
+		["Development Tools"] = "Инструменты разработчика",
+		["Guild"] = "Гильдия",
+		["Frame Modification"] = "Модификация фреймов",
+		["Interface Enhancements"] = "Улучшение интерфейса",
+		["Inventory"] = "Инвентарь",
+		["Library"] = "Библиотеки",
+		["Map"] = "Карта",
+		["Mail"] = "Почта",
+		["Miscellaneous"] = "Разное",
+		["Quest"] = "Задания",
+		["Raid"] = "Рейд",
+		["Tradeskill"] = "Умения",
+		["UnitFrame"] = "Фреймы персонажей",
+	}
+else -- enUS
+	STANDBY = "|cffff5050(standby)|r"
+
+	TITLE = "Title"
+	NOTES = "Notes"
+	VERSION = "Version"
+	AUTHOR = "Author"
+	DATE = "Date"
+	CATEGORY = "Category"
+	EMAIL = "E-mail"
+	WEBSITE = "Website"
+	CREDITS = "Credits"
+	LICENSE = "License"
+
+	ABOUT = "About"
+	PRINT_ADDON_INFO = "Show information about the addon."
+	DONATE = "Donate"
+	DONATE_DESC = "Give a much-needed donation to the author of this addon."
+	HOWTO_DONATE_WINDOWS = "Press Ctrl-A to select the link, then Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."
+	HOWTO_DONATE_MAC = "Press Cmd-A to select the link, then Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."
+
+	CATEGORIES = {
+		["Action Bars"] = "Action Bars",
+		["Auction"] = "Auction",
+		["Audio"] = "Audio",
+		["Battlegrounds/PvP"] = "Battlegrounds/PvP",
+		["Buffs"] = "Buffs",
+		["Chat/Communication"] = "Chat/Communication",
+		["Druid"] = "Druid",
+		["Hunter"] = "Hunter",
+		["Mage"] = "Mage",
+		["Paladin"] = "Paladin",
+		["Priest"] = "Priest",
+		["Rogue"] = "Rogue",
+		["Shaman"] = "Shaman",
+		["Warlock"] = "Warlock",
+		["Warrior"] = "Warrior",
+		["Healer"] = "Healer",
+		["Tank"] = "Tank",
+		["Caster"] = "Caster",
+		["Combat"] = "Combat",
+		["Compilations"] = "Compilations",
+		["Data Export"] = "Data Export",
+		["Development Tools"] = "Development Tools",
+		["Guild"] = "Guild",
+		["Frame Modification"] = "Frame Modification",
+		["Interface Enhancements"] = "Interface Enhancements",
+		["Inventory"] = "Inventory",
+		["Library"] = "Library",
+		["Map"] = "Map",
+		["Mail"] = "Mail",
+		["Miscellaneous"] = "Miscellaneous",
+		["Quest"] = "Quest",
+		["Raid"] = "Raid",
+		["Tradeskill"] = "Tradeskill",
+		["UnitFrame"] = "UnitFrame",
+	}
+end
+
+setmetatable(CATEGORIES, { __index = function(self, key) -- case-insensitive
+	local lowerKey = key:lower()
+	for k,v in pairs(CATEGORIES) do
+		if k:lower() == lowerKey then
+			self[lowerKey] = v
+			return v
+		end
+	end
+end })
+
+-- Create the library object
+
+local AceOO = AceLibrary("AceOO-2.0")
+local AceAddon = AceOO.Class()
+local AceEvent
+local AceConsole
+local AceModuleCore
+
+function AceAddon:GetLocalizedCategory(name)
+	self:argCheck(name, 2, "string")
+	return CATEGORIES[name] or UNKNOWN
+end
+
+function AceAddon:ToString()
+	return "AceAddon"
+end
+
+local function print(text)
+	DEFAULT_CHAT_FRAME:AddMessage(text)
+end
+
+function AceAddon:ADDON_LOADED(name)
+	local unregister = true
+	local initAddon = {}
+	while #self.nextAddon > 0 do
+		local addon = table.remove(self.nextAddon, 1)
+		if addon.possibleNames[name] then
+			table.insert(initAddon, addon)
+		else
+			unregister = nil
+			table.insert(self.skipAddon, addon)
+		end
+	end
+	self.nextAddon, self.skipAddon = self.skipAddon, self.nextAddon
+	if unregister then
+		AceAddon:UnregisterEvent("ADDON_LOADED")
+	end
+	while #initAddon > 0 do
+		local addon = table.remove(initAddon, 1)
+		table.insert(self.addons, addon)
+		if not self.addons[name] then
+			self.addons[name] = addon
+		end
+		addon.possibleNames = nil
+		self:InitializeAddon(addon, name)
+	end
+end
+
+local function RegisterOnEnable(self)
+	if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage then -- HACK
+		AceAddon.playerLoginFired = true
+	end
+	if AceAddon.playerLoginFired then
+		AceAddon.addonsStarted[self] = true
+		if (type(self.IsActive) ~= "function" or self:IsActive()) and (not AceModuleCore or not AceModuleCore:IsModule(self) or AceModuleCore:IsModuleActive(self)) then
+			AceAddon:ManualEnable(self)
+		end
+	else
+		if not AceAddon.addonsToOnEnable then
+			AceAddon.addonsToOnEnable = {}
+		end
+		table.insert(AceAddon.addonsToOnEnable, self)
+	end
+end
+
+function AceAddon:InitializeAddon(addon, name)
+	if addon.name == nil then
+		addon.name = name
+	end
+	if GetAddOnMetadata then
+		-- TOC checks
+		if addon.title == nil then
+			addon.title = GetAddOnMetadata(name, "Title")
+		end
+		if type(addon.title) == "string" then
+			local num = addon.title:find(" |cff7fff7f %-Ace2%-|r$")
+			if num then
+				addon.title = addon.title:sub(1, num - 1)
+			end
+			addon.title = addon.title:trim()
+		end
+		if addon.notes == nil then
+			addon.notes = GetAddOnMetadata(name, "Notes")
+		end
+		if type(addon.notes) == "string" then
+			addon.notes = addon.notes:trim()
+		end
+		if addon.version == nil then
+			addon.version = GetAddOnMetadata(name, "Version")
+		end
+		if type(addon.version) == "string" then
+			if addon.version:find("%$Revision: (%d+) %$") then
+				addon.version = addon.version:gsub("%$Revision: (%d+) %$", "%1")
+			elseif addon.version:find("%$Rev: (%d+) %$") then
+				addon.version = addon.version:gsub("%$Rev: (%d+) %$", "%1")
+			elseif addon.version:find("%$LastChangedRevision: (%d+) %$") then
+				addon.version = addon.version:gsub("%$LastChangedRevision: (%d+) %$", "%1")
+			end
+			addon.version = addon.version:trim()
+		end
+		if addon.author == nil then
+			addon.author = GetAddOnMetadata(name, "Author")
+		end
+		if type(addon.author) == "string" then
+			addon.author = addon.author:trim()
+		end
+		if addon.credits == nil then
+			addon.credits = GetAddOnMetadata(name, "X-Credits")
+		end
+		if type(addon.credits) == "string" then
+			addon.credits = addon.credits:trim()
+		end
+		if addon.donate == nil then
+			addon.donate = GetAddOnMetadata(name, "X-Donate")
+		end
+		if type(addon.donate) == "string" then
+			addon.donate = addon.donate:trim()
+		end
+		if addon.date == nil then
+			addon.date = GetAddOnMetadata(name, "X-Date") or GetAddOnMetadata(name, "X-ReleaseDate")
+		end
+		if type(addon.date) == "string" then
+			if addon.date:find("%$Date: (.-) %$") then
+				addon.date = addon.date:gsub("%$Date: (.-) %$", "%1")
+			elseif addon.date:find("%$LastChangedDate: (.-) %$") then
+				addon.date = addon.date:gsub("%$LastChangedDate: (.-) %$", "%1")
+			end
+			addon.date = addon.date:trim()
+		end
+
+		if addon.category == nil then
+			addon.category = GetAddOnMetadata(name, "X-Category")
+		end
+		if type(addon.category) == "string" then
+			addon.category = addon.category:trim()
+		end
+		if addon.email == nil then
+			addon.email = GetAddOnMetadata(name, "X-eMail") or GetAddOnMetadata(name, "X-Email")
+		end
+		if type(addon.email) == "string" then
+			addon.email = addon.email:trim()
+		end
+		if addon.license == nil then
+			addon.license = GetAddOnMetadata(name, "X-License")
+		end
+		if type(addon.license) == "string" then
+			addon.license = addon.license:trim()
+		end
+		if addon.website == nil then
+			addon.website = GetAddOnMetadata(name, "X-Website")
+		end
+		if type(addon.website) == "string" then
+			addon.website = addon.website:trim()
+		end
+	end
+	local current = addon.class
+	while true do
+		if current == AceOO.Class or not current then
+			break
+		end
+		if current.mixins then
+			for mixin in pairs(current.mixins) do
+				if type(mixin.OnEmbedInitialize) == "function" then
+					mixin:OnEmbedInitialize(addon, name)
+				end
+			end
+		end
+		current = current.super
+	end
+	local n = AceAddon.addonsToOnEnable and #AceAddon.addonsToOnEnable or 0
+
+	if type(addon.OnInitialize) == "function" then
+		safecall(addon.OnInitialize, addon, name)
+	end
+	if AceEvent then
+		AceEvent:TriggerEvent("Ace2_AddonInitialized", addon)
+	end
+	RegisterOnEnable(addon)
+	local n2 = AceAddon.addonsToOnEnable and #AceAddon.addonsToOnEnable or 0
+	if n2 - n > 1 then
+		local mine = table.remove(AceAddon.addonsToOnEnable)
+		table.insert(AceAddon.addonsToOnEnable, n+1, mine)
+	end
+end
+
+local aboutFrame
+local function createAboutFrame()
+	aboutFrame = CreateFrame("Frame", "AceAddon20AboutFrame", UIParent, "DialogBoxFrame")
+	aboutFrame:SetWidth(500)
+	aboutFrame:SetHeight(400)
+	aboutFrame:SetPoint("CENTER")
+	aboutFrame:SetBackdrop({
+		bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]],
+	    edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
+	    tile = true, tileSize = 16, edgeSize = 16,
+	    insets = { left = 5, right = 5, top = 5, bottom = 5 }
+	})
+	aboutFrame:SetBackdropColor(0,0,0,1)
+
+	local donateButton = CreateFrame("Button", "AceAddon20AboutFrameDonateButton", aboutFrame, "UIPanelButtonTemplate2")
+	aboutFrame.donateButton = donateButton
+	donateButton:SetPoint("BOTTOMRIGHT", -20, 20)
+	_G.AceAddon20AboutFrameDonateButtonText:SetText(DONATE)
+	donateButton:SetWidth(_G.AceAddon20AboutFrameDonateButtonText:GetWidth()+20)
+	donateButton:SetScript("OnClick", function()
+		aboutFrame.currentAddon:OpenDonationFrame()
+	end)
+
+	local text = aboutFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
+	aboutFrame.title = text
+	text:SetPoint("TOP", 0, -5)
+
+	aboutFrame:Hide()
+
+	aboutFrame.lefts = {}
+	aboutFrame.rights = {}
+	aboutFrame.textLefts = {}
+	aboutFrame.textRights = {}
+	function aboutFrame:Clear()
+		self.title:SetText("")
+		for i = 1, #self.lefts do
+			self.lefts[i] = nil
+			self.rights[i] = nil
+		end
+	end
+
+	function aboutFrame:AddLine(left, right)
+		aboutFrame.lefts[#aboutFrame.lefts+1] = left
+		aboutFrame.rights[#aboutFrame.rights+1] = right
+	end
+
+	local aboutFrame_Show = aboutFrame.Show
+	function aboutFrame:Show(...)
+		local maxLeftWidth = 0
+		local maxRightWidth = 0
+		local textHeight = 0
+		for i = 1, #self.lefts do
+			if not self.textLefts[i] then
+				local left = aboutFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+				self.textLefts[i] = left
+				local right = aboutFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
+				self.textRights[i] = right
+				if i == 1 then
+					left:SetPoint("TOPRIGHT", aboutFrame, "TOPLEFT", 75, -35)
+				else
+					left:SetPoint("TOPRIGHT", self.textLefts[i-1], "BOTTOMRIGHT", 0, -5)
+				end
+				right:SetPoint("LEFT", left, "RIGHT", 5, 0)
+			end
+			self.textLefts[i]:SetText(self.lefts[i] .. ":")
+			self.textRights[i]:SetText(self.rights[i])
+			local leftWidth = self.textLefts[i]:GetWidth()
+			local rightWidth = self.textRights[i]:GetWidth()
+			textHeight = self.textLefts[i]:GetHeight()
+			if maxLeftWidth < leftWidth then
+				maxLeftWidth = leftWidth
+			end
+			if maxRightWidth < rightWidth then
+				maxRightWidth = rightWidth
+			end
+		end
+		for i = #self.lefts+1, #self.textLefts do
+			self.textLefts[i]:SetText('')
+			self.textRights[i]:SetText('')
+		end
+		aboutFrame:SetWidth(75 + maxRightWidth + 20)
+		aboutFrame:SetHeight(#self.lefts * (textHeight + 5) + 100)
+
+		aboutFrame_Show(self, ...)
+	end
+	aboutFrame:Hide()
+
+	createAboutFrame = nil
+end
+local donateFrame
+
+local function unobfuscateEmail(email)
+	return email:gsub(" AT ", "@"):gsub(" DOT ", ".")
+end
+
+local function isGoodVariable(var)
+	return type(var) == "string" or type(var) == "number"
+end
+function AceAddon.prototype:PrintAddonInfo()
+	if createAboutFrame then
+		createAboutFrame()
+	end
+	aboutFrame:Clear()
+	local x
+	if isGoodVariable(self.title) then
+		x = tostring(self.title)
+	elseif isGoodVariable(self.name) then
+		x = tostring(self.name)
+	else
+		x = "<" .. tostring(self.class) .. " instance>"
+	end
+	if type(self.IsActive) == "function" then
+		if not self:IsActive() then
+			x = x .. " " .. STANDBY
+		end
+	end
+	aboutFrame.title:SetText(x)
+
+	if isGoodVariable(self.version) then
+		aboutFrame:AddLine(VERSION, tostring(self.version))
+	end
+	if isGoodVariable(self.notes) then
+		aboutFrame:AddLine(NOTES, tostring(self.notes))
+	end
+	if isGoodVariable(self.author) then
+		aboutFrame:AddLine(AUTHOR, tostring(self.author))
+	end
+	if isGoodVariable(self.credits) then
+		aboutFrame:AddLine(CREDITS, tostring(self.credits))
+	end
+	if isGoodVariable(self.date) then
+		aboutFrame:AddLine(DATE, tostring(self.date))
+	end
+	if isGoodVariable(self.category) then
+		local category = CATEGORIES[self.category]
+		aboutFrame:AddLine(CATEGORY, category or tostring(self.category))
+	end
+	if isGoodVariable(self.email) then
+		aboutFrame:AddLine(EMAIL, unobfuscateEmail(tostring(self.email)))
+	end
+	if isGoodVariable(self.website) then
+		aboutFrame:AddLine(WEBSITE, tostring(self.website))
+	end
+	if isGoodVariable(self.license) then
+		aboutFrame:AddLine(LICENSE, tostring(self.license))
+	end
+
+	if donateFrame and donateFrame:IsShown() then
+		donateFrame:Hide()
+	end
+
+	aboutFrame.currentAddon = self
+
+	aboutFrame:Show()
+
+	if self.donate then
+		aboutFrame.donateButton:Show()
+	else
+		aboutFrame.donateButton:Hide()
+	end
+end
+
+local function createDonateFrame()
+	donateFrame = CreateFrame("Frame", "AceAddon20Frame", UIParent, "DialogBoxFrame")
+
+	donateFrame:SetWidth(500)
+	donateFrame:SetHeight(200)
+	donateFrame:SetPoint("CENTER")
+	donateFrame:SetBackdrop({
+		bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]],
+		edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
+		tile = true, tileSize = 16, edgeSize = 16,
+		insets = { left = 5, right = 5, top = 5, bottom = 5 }
+	})
+	donateFrame:SetBackdropColor(0,0,0,1)
+
+	local text = donateFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
+	text:SetPoint("TOP", 0, -5)
+	text:SetText(DONATE)
+
+	local howto = donateFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
+	howto:SetPoint("TOP", text, "BOTTOM", 0, -5)
+	howto:SetPoint("LEFT", 16, 0)
+	howto:SetPoint("RIGHT", -16, 0)
+	if not IsMacClient() then
+		-- Windows or Linux
+		howto:SetText(HOWTO_DONATE_WINDOWS)
+	else
+		howto:SetText(HOWTO_DONATE_MAC)
+	end
+
+	local scrollFrame = CreateFrame("ScrollFrame", "AceAddon20FrameScrollFrame", donateFrame, "UIPanelScrollFrameTemplate")
+	scrollFrame:SetToplevel(true)
+	scrollFrame:SetPoint("TOP", -10, -76)
+	scrollFrame:SetWidth(455)
+	scrollFrame:SetHeight(70)
+	howto:SetPoint("BOTTOM", scrollFrame, "TOP")
+
+	local editBox = CreateFrame("EditBox", nil, scrollFrame)
+	donateFrame.editBox = editBox
+	scrollFrame:SetScrollChild(editBox)
+	editBox:SetFontObject(ChatFontNormal)
+	editBox:SetMultiLine(true)
+	editBox:SetMaxLetters(99999)
+	editBox:SetWidth(450)
+	editBox:SetHeight(54)
+	editBox:SetPoint("BOTTOM", 5, 0)
+	editBox:SetJustifyH("LEFT")
+	editBox:SetJustifyV("TOP")
+	editBox:SetAutoFocus(false)
+	editBox:SetScript("OnTextChanged", function(this)
+		if this:GetText() ~= this.text then
+			this:SetText(this.text)
+		end
+	end)
+	editBox:SetScript("OnEscapePressed", function(this)
+		this:ClearFocus()
+	end)
+	createDonateFrame = nil
+end
+
+local function fix(char)
+	return ("%%%02x"):format(char:byte())
+end
+
+local function urlencode(text)
+	return text:gsub("[^0-9A-Za-z]", fix)
+end
+
+function AceAddon.prototype:OpenDonationFrame()
+	if createDonateFrame then
+		createDonateFrame()
+	end
+	local donate = self.donate
+	if type(donate) ~= "string" then
+		donate = "Wowace"
+	end
+	local style, data = (":"):split(donate, 2)
+	style = style:lower()
+	if style ~= "website" and style ~= "paypal" then
+		style = "wowace"
+	end
+	if style == "wowace" then
+		donateFrame.editBox.text = "http://www.wowace.com/wiki/Donations"
+	elseif style == "website" then
+		donateFrame.editBox.text = data
+	else -- PayPal
+		local text = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=" .. urlencode(unobfuscateEmail(data))
+		local name
+		if type(self.title) == "string" then
+			name = self.title
+		elseif type(self.name) == "string" then
+			name = self.name
+		end
+		if name then
+			name = name:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "")
+			text = text .. "&item_name=" .. urlencode(name)
+		end
+		donateFrame.editBox.text = text
+	end
+	donateFrame.editBox:SetText(donateFrame.editBox.text)
+
+	if aboutFrame and aboutFrame:IsShown() then
+		aboutFrame:Hide()
+	end
+
+	donateFrame:Show()
+
+	donateFrame.editBox:SetFocus()
+end
+
+local options
+function AceAddon:GetAceOptionsDataTable(target)
+	return {
+		about = {
+			name = ABOUT,
+			desc = PRINT_ADDON_INFO,
+			type = "execute",
+			func = "PrintAddonInfo",
+			order = -1,
+		},
+		donate = {
+			name = DONATE,
+			desc = DONATE_DESC,
+			type = "execute",
+			func = "OpenDonationFrame",
+			order = -1,
+			hidden = function()
+				return not target.donate
+			end
+		}
+	}
+end
+
+function AceAddon:PLAYER_LOGIN()
+	self.playerLoginFired = true
+	if self.addonsToOnEnable then
+		while #self.addonsToOnEnable > 0 do
+			local addon = table.remove(self.addonsToOnEnable, 1)
+			self.addonsStarted[addon] = true
+			if (type(addon.IsActive) ~= "function" or addon:IsActive()) and (not AceModuleCore or not AceModuleCore:IsModule(addon) or AceModuleCore:IsModuleActive(addon)) then
+				AceAddon:ManualEnable(addon)
+			end
+		end
+		self.addonsToOnEnable = nil
+	end
+end
+
+function AceAddon.prototype:Inject(t)
+	AceAddon:argCheck(t, 2, "table")
+	for k,v in pairs(t) do
+		self[k] = v
+	end
+end
+
+function AceAddon.prototype:init()
+	if not AceEvent then
+		error(MAJOR_VERSION .. " requires AceEvent-2.0", 4)
+	end
+	AceAddon.super.prototype.init(self)
+
+	self.super = self.class.prototype
+
+	AceAddon:RegisterEvent("ADDON_LOADED", "ADDON_LOADED")
+	local names = {}
+	for i = 1, GetNumAddOns() do
+		if IsAddOnLoaded(i) then names[GetAddOnInfo(i)] = true end
+	end
+	self.possibleNames = names
+	table.insert(AceAddon.nextAddon, self)
+end
+
+function AceAddon.prototype:ToString()
+	local x
+	if type(self.title) == "string" then
+		x = self.title
+	elseif type(self.name) == "string" then
+		x = self.name
+	else
+		x = "<" .. tostring(self.class) .. " instance>"
+	end
+	if (type(self.IsActive) == "function" and not self:IsActive()) or (AceModuleCore and AceModuleCore:IsModule(addon) and AceModuleCore:IsModuleActive(addon)) then
+		x = x .. " " .. STANDBY
+	end
+	return x
+end
+
+AceAddon.new = function(self, ...)
+	local class = AceAddon:pcall(AceOO.Classpool, self, ...)
+	return class:new()
+end
+
+function AceAddon:ManualEnable(addon)
+	AceAddon:argCheck(addon, 2, "table")
+	local first = nil
+	if AceOO.inherits(addon, "AceAddon-2.0") then
+		if AceAddon.addonsEnabled and not AceAddon.addonsEnabled[addon] then
+			first = true
+			AceAddon.addonsEnabled[addon] = true
+		end
+	end
+	local current = addon.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, addon, first)
+				end
+			end
+		end
+		current = current.super
+	end
+	if type(addon.OnEnable) == "function" then
+		safecall(addon.OnEnable, addon, first)
+	end
+	if AceEvent then
+		AceEvent:TriggerEvent("Ace2_AddonEnabled", addon, first)
+	end
+end
+
+function AceAddon:ManualDisable(addon)
+	AceAddon:argCheck(addon, 2, "table")
+	local current = addon.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, addon)
+				end
+			end
+		end
+		current = current.super
+	end
+	if type(module.OnDisable) == "function" then
+		safecall(module.OnDisable, addon)
+	end
+	if AceEvent then
+		AceEvent:TriggerEvent("Ace2_AddonDisabled", addon)
+	end
+end
+
+local function external(self, major, instance)
+	if major == "AceEvent-2.0" then
+		AceEvent = instance
+
+		AceEvent:embed(self)
+
+		self:RegisterEvent("PLAYER_LOGIN", "PLAYER_LOGIN", true)
+	elseif major == "AceConsole-2.0" then
+		AceConsole = instance
+
+		local slashCommands = { "/ace2" }
+		local _,_,_,enabled,loadable = GetAddOnInfo("Ace")
+		if not enabled or not loadable then
+			table.insert(slashCommands, "/ace")
+		end
+		local function listAddon(addon, depth)
+			if not depth then
+				depth = 0
+			end
+
+			local s = ("  "):rep(depth) .. " - " .. tostring(addon)
+			if rawget(addon, 'version') then
+				s = s .. " - |cffffff7f" .. tostring(addon.version) .. "|r"
+			end
+			if rawget(addon, 'slashCommand') then
+				s = s .. " |cffffff7f(" .. tostring(addon.slashCommand) .. ")|r"
+			end
+			print(s)
+			if type(rawget(addon, 'modules')) == "table" then
+				local i = 0
+				for k,v in pairs(addon.modules) do
+					i = i + 1
+					if i == 6 then
+						print(("  "):rep(depth + 1) .. " - more...")
+						break
+					else
+						listAddon(v, depth + 1)
+					end
+				end
+			end
+		end
+		local function listNormalAddon(i)
+			local name,_,_,enabled,loadable = GetAddOnInfo(i)
+			if not loadable then
+				enabled = false
+			end
+			if self.addons[name] then
+				listAddon(self.addons[name])
+			else
+				local s = " - " .. tostring(GetAddOnMetadata(i, "Title") or name)
+				local version = GetAddOnMetadata(i, "Version")
+				if version then
+					if version:find("%$Revision: (%d+) %$") then
+						version = version:gsub("%$Revision: (%d+) %$", "%1")
+					elseif version:find("%$Rev: (%d+) %$") then
+						version = version:gsub("%$Rev: (%d+) %$", "%1")
+					elseif version:find("%$LastChangedRevision: (%d+) %$") then
+						version = version:gsub("%$LastChangedRevision: (%d+) %$", "%1")
+					end
+					s = s .. " - |cffffff7f" .. version .. "|r"
+				end
+				if not enabled then
+					s = s .. " |cffff0000(disabled)|r"
+				end
+				if IsAddOnLoadOnDemand(i) then
+					s = s .. " |cff00ff00[LoD]|r"
+				end
+				print(s)
+			end
+		end
+		local function mySort(alpha, bravo)
+			return tostring(alpha) < tostring(bravo)
+		end
+		AceConsole.RegisterChatCommand(self, slashCommands, {
+			desc = "AddOn development framework",
+			name = "Ace2",
+			type = "group",
+			args = {
+				about = {
+					desc = "Get information about Ace2",
+					name = "About",
+					type = "execute",
+					func = function()
+						print("|cffffff7fAce2|r - |cffffff7f2.0." .. MINOR_VERSION:gsub("%$Revision: (%d+) %$", "%1") .. "|r - AddOn development framework")
+						print(" - |cffffff7f" .. AUTHOR .. ":|r Ace Development Team")
+						print(" - |cffffff7f" .. WEBSITE .. ":|r http://www.wowace.com/")
+					end
+				},
+				list = {
+					desc = "List addons",
+					name = "List",
+					type = "group",
+					args = {
+						ace2 = {
+							desc = "List addons using Ace2",
+							name = "Ace2",
+							type = "execute",
+							func = function()
+								print("|cffffff7fAddon list:|r")
+								table.sort(self.addons, mySort)
+								for _,v in ipairs(self.addons) do
+									listAddon(v)
+								end
+							end
+						},
+						all = {
+							desc = "List all addons",
+							name = "All",
+							type = "execute",
+							func = function()
+								print("|cffffff7fAddon list:|r")
+								local count = GetNumAddOns()
+								for i = 1, count do
+									listNormalAddon(i)
+								end
+							end
+						},
+						enabled = {
+							desc = "List all enabled addons",
+							name = "Enabled",
+							type = "execute",
+							func = function()
+								print("|cffffff7fAddon list:|r")
+								local count = GetNumAddOns()
+								for i = 1, count do
+									local _,_,_,enabled,loadable = GetAddOnInfo(i)
+									if enabled and loadable then
+										listNormalAddon(i)
+									end
+								end
+							end
+						},
+						disabled = {
+							desc = "List all disabled addons",
+							name = "Disabled",
+							type = "execute",
+							func = function()
+								print("|cffffff7fAddon list:|r")
+								local count = GetNumAddOns()
+								for i = 1, count do
+									local _,_,_,enabled,loadable = GetAddOnInfo(i)
+									if not enabled or not loadable then
+										listNormalAddon(i)
+									end
+								end
+							end
+						},
+						lod = {
+							desc = "List all LoadOnDemand addons",
+							name = "LoadOnDemand",
+							type = "execute",
+							func = function()
+								print("|cffffff7fAddon list:|r")
+								local count = GetNumAddOns()
+								for i = 1, count do
+									if IsAddOnLoadOnDemand(i) then
+										listNormalAddon(i)
+									end
+								end
+							end
+						},
+						ace1 = {
+							desc = "List all addons using Ace1",
+							name = "Ace 1.x",
+							type = "execute",
+							func = function()
+								print("|cffffff7fAddon list:|r")
+								local count = GetNumAddOns()
+								for i = 1, count do
+									local dep1, dep2, dep3, dep4 = GetAddOnDependencies(i)
+									if dep1 == "Ace" or dep2 == "Ace" or dep3 == "Ace" or dep4 == "Ace" then
+										listNormalAddon(i)
+									end
+								end
+							end
+						},
+						libs = {
+							desc = "List all libraries using AceLibrary",
+							name = "Libraries",
+							type = "execute",
+							func = function()
+								if type(AceLibrary) == "table" and type(AceLibrary.libs) == "table" then
+									print("|cffffff7fLibrary list:|r")
+									for name, data in pairs(AceLibrary.libs) do
+										local s
+										if data.minor then
+											s = " - " .. tostring(name) .. "." .. tostring(data.minor)
+										else
+											s = " - " .. tostring(name)
+										end
+										if rawget(AceLibrary(name), 'slashCommand') then
+											s = s .. " |cffffff7f(" .. tostring(AceLibrary(name).slashCommand) .. "|cffffff7f)"
+										end
+										print(s)
+									end
+								end
+							end
+						},
+						search = {
+							desc = "Search by name",
+							name = "Search",
+							type = "text",
+							usage = "<keyword>",
+							input = true,
+							get = false,
+							set = function(...)
+								local arg = { ... }
+								for i,v in ipairs(arg) do
+									arg[i] = v:gsub('%*', '.*'):gsub('%%', '%%%%'):lower()
+								end
+								local count = GetNumAddOns()
+								for i = 1, count do
+									local name = GetAddOnInfo(i)
+									local good = true
+									for _,v in ipairs(arg) do
+										if not name:lower():find(v) then
+											good = false
+											break
+										end
+									end
+									if good then
+										listNormalAddon(i)
+									end
+								end
+							end
+						}
+					},
+				},
+				enable = {
+					desc = "Enable addon(s).",
+					name = "Enable",
+					type = "text",
+					usage = "<addon 1> <addon 2> ...",
+					get = false,
+					input = true,
+					set = function(...)
+						for i = 1, select("#", ...) do
+							local addon = select(i, ...)
+							local name, title, _, enabled, _, reason = GetAddOnInfo(addon)
+							if reason == "MISSING" then
+								print(("|cffffff7fAce2:|r AddOn %q does not exist."):format(addon))
+							elseif not enabled then
+								EnableAddOn(addon)
+								print(("|cffffff7fAce2:|r %s is now enabled."):format(addon or name))
+							else
+								print(("|cffffff7fAce2:|r %s is already enabled."):format(addon or name))
+							end
+						end
+					end,
+				},
+				disable = {
+					desc = "Disable addon(s).",
+					name = "Disable",
+					type = "text",
+					usage = "<addon 1> <addon 2> ...",
+					get = false,
+					input = true,
+					set = function(...)
+						for i = 1, select("#", ...) do
+							local addon = select(i, ...)
+							local name, title, _, enabled, _, reason = GetAddOnInfo(addon)
+							if reason == "MISSING" then
+							print(("|cffffff7fAce2:|r AddOn %q does not exist."):format(addon))
+							elseif enabled then
+								DisableAddOn(addon)
+								print(("|cffffff7fAce2:|r %s is now disabled."):format(addon or name))
+							else
+								print(("|cffffff7fAce2:|r %s is already disabled."):format(addon or name))
+							end
+						end
+					end,
+				},
+				load = {
+					desc = "Load addon(s).",
+					name = "Load",
+					type = "text",
+					usage = "<addon 1> <addon 2> ...",
+					get = false,
+					input = true,
+					set = function(...)
+						for i = 1, select("#", ...) do
+							local addon = select(i, ...)
+							local name, title, _, _, loadable, reason = GetAddOnInfo(addon)
+							if reason == "MISSING" then
+								print(("|cffffff7fAce2:|r AddOn %q does not exist."):format(addon))
+							elseif not loadable then
+								print(("|cffffff7fAce2:|r AddOn %q is not loadable. Reason: %s."):format(addon, reason))
+							else
+								LoadAddOn(addon)
+								print(("|cffffff7fAce2:|r %s is now loaded."):format(addon or name))
+							end
+						end
+					end
+				},
+				info = {
+					desc = "Display information",
+					name = "Information",
+					type = "execute",
+					func = function()
+						local mem, threshold = gcinfo()
+						print((" - |cffffff7fMemory usage [|r%.3f MiB|cffffff7f]|r"):format(mem / 1024))
+						if threshold then
+							print((" - |cffffff7fThreshold [|r%.3f MiB|cffffff7f]|r"):format(threshold / 1024))
+						end
+						print((" - |cffffff7fFramerate [|r%.0f fps|cffffff7f]|r"):format(GetFramerate()))
+						local bandwidthIn, bandwidthOut, latency = GetNetStats()
+						bandwidthIn, bandwidthOut = floor(bandwidthIn * 1024), floor(bandwidthOut * 1024)
+						print((" - |cffffff7fLatency [|r%.0f ms|cffffff7f]|r"):format(latency))
+						print((" - |cffffff7fBandwidth in [|r%.0f B/s|cffffff7f]|r"):format(bandwidthIn))
+						print((" - |cffffff7fBandwidth out [|r%.0f B/s|cffffff7f]|r"):format(bandwidthOut))
+						print((" - |cffffff7fTotal addons [|r%d|cffffff7f]|r"):format(GetNumAddOns()))
+						print((" - |cffffff7fAce2 addons [|r%d|cffffff7f]|r"):format(#self.addons))
+						local ace = 0
+						local enabled = 0
+						local disabled = 0
+						local lod = 0
+						for i = 1, GetNumAddOns() do
+							local dep1, dep2, dep3, dep4 = GetAddOnDependencies(i)
+							if dep1 == "Ace" or dep2 == "Ace" or dep3 == "Ace" or dep4 == "Ace" then
+								ace = ace + 1
+							end
+							if IsAddOnLoadOnDemand(i) then
+								lod = lod + 1
+							end
+							local isActive, loadable = select(4, GetAddOnInfo(i))
+							if not isActive or not loadable then
+								disabled = disabled + 1
+							else
+								enabled = enabled + 1
+							end
+						end
+						print((" - |cffffff7fAce 1.x addons [|r%d|cffffff7f]|r"):format(ace))
+						print((" - |cffffff7fLoadOnDemand addons [|r%d|cffffff7f]|r"):format(lod))
+						print((" - |cffffff7fenabled addons [|r%d|cffffff7f]|r"):format(enabled))
+						print((" - |cffffff7fdisabled addons [|r%d|cffffff7f]|r"):format(disabled))
+						local libs = 0
+						if type(AceLibrary) == "table" and type(AceLibrary.libs) == "table" then
+							for _ in pairs(AceLibrary.libs) do
+								libs = libs + 1
+							end
+						end
+						print((" - |cffffff7fAceLibrary instances [|r%d|cffffff7f]|r"):format(libs))
+					end
+				}
+			}
+		})
+	elseif major == "AceModuleCore-2.0" then
+		AceModuleCore = instance
+	end
+end
+
+local function activate(self, oldLib, oldDeactivate)
+	AceAddon = self
+
+	self.playerLoginFired = oldLib and oldLib.playerLoginFired or DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage
+	self.addonsToOnEnable = oldLib and oldLib.addonsToOnEnable
+	self.addons = oldLib and oldLib.addons or {}
+	self.nextAddon = oldLib and oldLib.nextAddon or {}
+	self.skipAddon = oldLib and oldLib.skipAddon or {}
+	self.addonsStarted = oldLib and oldLib.addonsStarted or {}
+	self.addonsEnabled = oldLib and oldLib.addonsEnabled or {}
+
+	if oldDeactivate then
+		oldDeactivate(oldLib)
+	end
+end
+
+AceLibrary:Register(AceAddon, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
diff --git a/Libs/AceAddon-2.0/AceAddon-2.0.toc b/Libs/AceAddon-2.0/AceAddon-2.0.toc
index f2a25c7..76061ce 100644
--- a/Libs/AceAddon-2.0/AceAddon-2.0.toc
+++ b/Libs/AceAddon-2.0/AceAddon-2.0.toc
@@ -1,16 +1,16 @@
-## Interface: 30000
-## X-Curse-Packaged-Version: r1094
-## X-Curse-Project-Name: Ace2
-## X-Curse-Project-ID: ace2
-## X-Curse-Repository-ID: wow/ace2/mainline
-
-## Title: Lib: AceAddon-2.0
-## Notes: AddOn development framework
-## Author: Ace Development Team
-## LoadOnDemand: 1
-## X-Website: http://www.wowace.com
-## X-Category: Library
-## X-License: LGPL v2.1 + MIT for AceOO-2.0
-## Dependencies: AceLibrary, AceOO-2.0
-
-AceAddon-2.0.lua
+## Interface: 30000
+## X-Curse-Packaged-Version: r1094
+## X-Curse-Project-Name: Ace2
+## X-Curse-Project-ID: ace2
+## X-Curse-Repository-ID: wow/ace2/mainline
+
+## Title: Lib: AceAddon-2.0
+## Notes: AddOn development framework
+## Author: Ace Development Team
+## LoadOnDemand: 1
+## X-Website: http://www.wowace.com
+## X-Category: Library
+## X-License: LGPL v2.1 + MIT for AceOO-2.0
+## Dependencies: AceLibrary, AceOO-2.0
+
+AceAddon-2.0.lua
diff --git a/Libs/AceEvent-2.0/AceEvent-2.0.lua b/Libs/AceEvent-2.0/AceEvent-2.0.lua
index 3f31770..8d0e2a2 100644
--- a/Libs/AceEvent-2.0/AceEvent-2.0.lua
+++ b/Libs/AceEvent-2.0/AceEvent-2.0.lua
@@ -1,998 +1,998 @@
---[[
-Name: AceEvent-2.0
-Revision: $Rev: 1091 $
-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/AceEvent-2.0
-SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceEvent-2.0
-Description: Mixin to allow for event handling, scheduling, and inter-addon
-             communication.
-Dependencies: AceLibrary, AceOO-2.0
-License: LGPL v2.1
-]]
-
-local MAJOR_VERSION = "AceEvent-2.0"
-local MINOR_VERSION = 90000 + tonumber(("$Revision: 1091 $"):match("(%d+)"))
-
-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 AceOO = AceLibrary:GetInstance("AceOO-2.0")
-local Mixin = AceOO.Mixin
-local AceEvent = Mixin {
-	"RegisterEvent",
-	"RegisterAllEvents",
-	"UnregisterEvent",
-	"UnregisterAllEvents",
-	"TriggerEvent",
-	"ScheduleEvent",
-	"ScheduleRepeatingEvent",
-	"CancelScheduledEvent",
-	"CancelAllScheduledEvents",
-	"IsEventRegistered",
-	"IsEventScheduled",
-	"RegisterBucketEvent",
-	"UnregisterBucketEvent",
-	"UnregisterAllBucketEvents",
-	"IsBucketEventRegistered",
-	"ScheduleLeaveCombatAction",
-	"CancelAllCombatSchedules",
-}
-
-local weakKey = {__mode="k"}
-
-local FAKE_NIL
-local RATE
-
-local eventsWhichHappenOnce = {
-	PLAYER_LOGIN = true,
-	AceEvent_FullyInitialized = true,
-	VARIABLES_LOADED = true,
-	PLAYER_LOGOUT = true,
-}
-local next = next
-local pairs = pairs
-local pcall = pcall
-local type = type
-local GetTime = GetTime
-local gcinfo = gcinfo
-local unpack = unpack
-local geterrorhandler = geterrorhandler
-
-local new, del
-do
-	local cache = setmetatable({}, {__mode='k'})
-	function new(...)
-		local t = next(cache)
-		if t then
-			cache[t] = nil
-			for i = 1, select('#', ...) do
-				t[i] = select(i, ...)
-			end
-			return t
-		else
-			return { ... }
-		end
-	end
-	function del(t)
-		for k in pairs(t) do
-			t[k] = nil
-		end
-		cache[t] = true
-		return nil
-	end
-end
-
-local registeringFromAceEvent
---[[----------------------------------------------------------------------------------
-Notes:
-	* Registers the addon with a Blizzard event or a custom AceEvent, which will cause the given method to be called when that is triggered.
-Arguments:
-	string - name of the event to register
-	[optional] string or function - name of the method or function to call. Default: same name as "event".
-	[optional] boolean - whether to have method called only once. Default: false
-------------------------------------------------------------------------------------]]
-function AceEvent:RegisterEvent(event, method, once)
-	AceEvent:argCheck(event, 2, "string")
-	if self == AceEvent and not registeringFromAceEvent then
-		AceEvent:argCheck(method, 3, "function")
-		self = method
-	else
-		AceEvent:argCheck(method, 3, "string", "function", "nil", "boolean", "number")
-		if type(method) == "boolean" or type(method) == "number" then
-			AceEvent:argCheck(once, 4, "nil")
-			once, method = method, event
-		end
-	end
-	AceEvent:argCheck(once, 4, "number", "boolean", "nil")
-	if eventsWhichHappenOnce[event] then
-		once = true
-	end
-	local throttleRate
-	if type(once) == "number" then
-		throttleRate, once = once
-	end
-	if not method then
-		method = event
-	end
-	if type(method) == "string" and type(self[method]) ~= "function" then
-		AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
-	else
-		assert(type(method) == "function" or type(method) == "string")
-	end
-
-	local AceEvent_registry = AceEvent.registry
-	if not AceEvent_registry[event] then
-		AceEvent_registry[event] = new()
-		AceEvent.frame:RegisterEvent(event)
-	end
-
-	local remember = true
-	if AceEvent_registry[event][self] then
-		remember = false
-	end
-	AceEvent_registry[event][self] = method
-
-	local AceEvent_onceRegistry = AceEvent.onceRegistry
-	if once then
-		if not AceEvent_onceRegistry then
-			AceEvent.onceRegistry = {}
-			AceEvent_onceRegistry = AceEvent.onceRegistry
-		end
-		if not AceEvent_onceRegistry[event] then
-			AceEvent_onceRegistry[event] = new()
-		end
-		AceEvent_onceRegistry[event][self] = true
-	else
-		if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
-			AceEvent_onceRegistry[event][self] = nil
-			if not next(AceEvent_onceRegistry[event]) then
-				AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
-			end
-		end
-	end
-
-	local AceEvent_throttleRegistry = AceEvent.throttleRegistry
-	if throttleRate then
-		if not AceEvent_throttleRegistry then
-			AceEvent.throttleRegistry = {}
-			AceEvent_throttleRegistry = AceEvent.throttleRegistry
-		end
-		if not AceEvent_throttleRegistry[event] then
-			AceEvent_throttleRegistry[event] = new()
-		end
-		if AceEvent_throttleRegistry[event][self] then
-			AceEvent_throttleRegistry[event][self] = nil
-		end
-		AceEvent_throttleRegistry[event][self] = setmetatable(new(), weakKey)
-		local t = AceEvent_throttleRegistry[event][self]
-		t[RATE] = throttleRate
-	else
-		if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] then
-			if AceEvent_throttleRegistry[event][self] then
-				AceEvent_throttleRegistry[event][self] = nil
-			end
-			if not next(AceEvent_throttleRegistry[event]) then
-				AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
-			end
-		end
-	end
-
-	if remember then
-		AceEvent:TriggerEvent("AceEvent_EventRegistered", self, event)
-	end
-end
-
-local ALL_EVENTS
-
---[[----------------------------------------------------------------------------------
-Notes:
-	* Registers all events to the given method
-	* To access the current event, check AceEvent.currentEvent
-	* To access the current event's unique identifier, check AceEvent.currentEventUID
-	* This is only for debugging purposes.
-Arguments:
-	[optional] string or function - name of the method or function to call. Default: same name as "event".
-------------------------------------------------------------------------------------]]
-function AceEvent:RegisterAllEvents(method)
-	if self == AceEvent then
-		AceEvent:argCheck(method, 1, "function")
-		self = method
-	else
-		AceEvent:argCheck(method, 1, "string", "function")
-		if type(method) == "string" and type(self[method]) ~= "function" then
-			AceEvent:error("Cannot register all events to method %q, it does not exist", method)
-		end
-	end
-
-	local AceEvent_registry = AceEvent.registry
-	if not AceEvent_registry[ALL_EVENTS] then
-		AceEvent_registry[ALL_EVENTS] = new()
-		AceEvent.frame:RegisterAllEvents()
-	end
-
-	local remember = not AceEvent_registry[ALL_EVENTS][self]
-	AceEvent_registry[ALL_EVENTS][self] = method
-	if remember then
-		AceEvent:TriggerEvent("AceEvent_EventRegistered", self, "all")
-	end
-end
-
---[[----------------------------------------------------------------------------------
-Notes:
-	* Trigger a custom AceEvent.
-	* This should never be called to simulate fake Blizzard events.
-	* Custom events should be in the form of AddonName_SpecificEvent
-Arguments:
-	string - name of the event
-	tuple - list of arguments to pass along
-------------------------------------------------------------------------------------]]
-function AceEvent:TriggerEvent(event, ...)
-	AceEvent:argCheck(event, 2, "string")
-	local AceEvent_registry = AceEvent.registry
-	if (not AceEvent_registry[event] or not next(AceEvent_registry[event])) and (not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS])) then
-		return
-	end
-	local lastEvent = AceEvent.currentEvent
-	AceEvent.currentEvent = event
-	local lastEventUID = AceEvent.currentEventUID
-	local uid = AceEvent.UID_NUM + 1
-	AceEvent.UID_NUM = uid
-	AceEvent.currentEventUID = uid
-
-	local tmp = new()
-
-	local AceEvent_onceRegistry = AceEvent.onceRegistry
-	if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
-		for obj, method in pairs(AceEvent_onceRegistry[event]) do
-			tmp[obj] = AceEvent_registry[event] and AceEvent_registry[event][obj] or nil
-		end
-		local obj = next(tmp)
-		while obj do
-			local method = tmp[obj]
-			AceEvent.UnregisterEvent(obj, event)
-			if type(method) == "string" then
-				local obj_method = obj[method]
-				if obj_method then
-					local success, err = pcall(obj_method, obj, ...)
-					if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
-				end
-			elseif method then -- function
-				local success, err = pcall(method, ...)
-				if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
-			end
-			tmp[obj] = nil
-			obj = next(tmp)
-		end
-	end
-
-	local AceEvent_throttleRegistry = AceEvent.throttleRegistry
-	local throttleTable = AceEvent_throttleRegistry and AceEvent_throttleRegistry[event]
-	if AceEvent_registry[event] then
-		for obj, method in pairs(AceEvent_registry[event]) do
-			tmp[obj] = method
-		end
-		local obj = next(tmp)
-		while obj do
-			local cont = nil
-			if throttleTable and throttleTable[obj] then
-				local a1 = ...
-				if a1 == nil then
-					a1 = FAKE_NIL
-				end
-				if not throttleTable[obj][a1] or GetTime() - throttleTable[obj][a1] >= throttleTable[obj][RATE] then
-					throttleTable[obj][a1] = GetTime()
-				else
-					cont = true
-				end
-			end
-			if not cont then
-				local method = tmp[obj]
-				local t = type(method)
-				if t == "string" then
-					local obj_method = obj[method]
-					if obj_method then
-						local success, err = pcall(obj_method, obj, ...)
-						if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
-					end
-				elseif t == "function" then -- function
-					local success, err = pcall(method, ...)
-					if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
-				else
-					AceEvent:error("Cannot trigger event %q. %q's handler, %q, is not a method or function (%s).", event, obj, method, t)
-				end
-			end
-			tmp[obj] = nil
-			obj = next(tmp)
-		end
-	end
-	if AceEvent_registry[ALL_EVENTS] then
-		for obj, method in pairs(AceEvent_registry[ALL_EVENTS]) do
-			tmp[obj] = method
-		end
-		local obj = next(tmp)
-		while obj do
-			local method = tmp[obj]
-			local t = type(method)
-			if t == "string" then
-				local obj_method = obj[method]
-				if obj_method then
-					local success, err = pcall(obj_method, obj, ...)
-					if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
-				end
-			elseif t == "function" then
-				local success, err = pcall(method, ...)
-				if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
-			else
-				AceEvent:error("Cannot trigger event %q. %q's handler, %q, is not a method or function (%s).", event, obj, method, t)
-			end
-			tmp[obj] = nil
-			obj = next(tmp)
-		end
-	end
-	tmp = del(tmp)
-	AceEvent.currentEvent = lastEvent
-	AceEvent.currentEventUID = lastEventUID
-end
-
-local delayRegistry
-local OnUpdate
-do
-	local tmp = {}
-	OnUpdate = function()
-		local t = GetTime()
-		for k,v in pairs(delayRegistry) do
-			tmp[k] = true
-		end
-		for k in pairs(tmp) do
-			local v = delayRegistry[k]
-			if v then
-				local v_time = v.time
-				if not v_time then
-					delayRegistry[k] = nil
-				elseif v_time <= t then
-					local v_repeatDelay = v.repeatDelay
-					if v_repeatDelay then
-						-- use the event time, not the current time, else timing inaccuracies add up over time
-						v.time = v_time + v_repeatDelay
-					end
-					local event = v.event
-					local t = type(event)
-					if t == "function" then
-						local uid = AceEvent.UID_NUM + 1
-						AceEvent.UID_NUM = uid
-						AceEvent.currentEventUID = uid
-						local success, err = pcall(event, unpack(v, 1, v.n))
-						if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
-						AceEvent.currentEventUID = nil
-					elseif t == "string" then
-						AceEvent:TriggerEvent(event, unpack(v, 1, v.n))
-					else
-						AceEvent:error("Cannot trigger event %q, it's not a method or function (%s).", event, t)
-					end
-					if not v_repeatDelay then
-						local x = delayRegistry[k]
-						if x and x.time == v_time then -- check if it was manually reset
-							if type(k) == "string" then
-								del(delayRegistry[k])
-							end
-							delayRegistry[k] = nil
-						end
-					end
-				end
-			end
-		end
-		for k in pairs(tmp) do
-			tmp[k] = nil
-		end
-		if not next(delayRegistry) then
-			AceEvent.frame:Hide()
-		end
-	end
-end
-
-local function ScheduleEvent(self, repeating, event, delay, ...)
-	local id
-	if type(event) == "string" and type(delay) ~= "number" then
-		id, event, delay = event, delay, ...
-		AceEvent:argCheck(event, 3, "string", "function", --[[ so message is right ]] "number")
-		AceEvent:argCheck(delay, 4, "number")
-		self:CancelScheduledEvent(id)
-	else
-		AceEvent:argCheck(event, 2, "string", "function")
-		AceEvent:argCheck(delay, 3, "number")
-	end
-
-	if not delayRegistry then
-		AceEvent.delayRegistry = {}
-		delayRegistry = AceEvent.delayRegistry
-		AceEvent.frame:SetScript("OnUpdate", OnUpdate)
-	end
-	local t
-	if id then
-		t = new(select(2, ...))
-		t.n = select('#', ...) - 1
-	else
-		t = new(...)
-		t.n = select('#', ...)
-	end
-	t.event = event
-	t.time = GetTime() + delay
-	t.self = self
-	t.id = id or t
-	t.repeatDelay = repeating and delay
-	delayRegistry[t.id] = t
-	AceEvent.frame:Show()
-end
-
---[[----------------------------------------------------------------------------------
-Notes:
-	* Schedule an event to fire.
-	* To fire on the next frame, specify a delay of 0.
-Arguments:
-	string or function - name of the event to fire, or a function to call.
-	number - the amount of time to wait until calling.
-	tuple - a list of arguments to pass along.
-------------------------------------------------------------------------------------]]
-function AceEvent:ScheduleEvent(event, delay, ...)
-	if type(event) == "string" and type(delay) ~= "number" then
-		AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
-		AceEvent:argCheck(..., 4, "number")
-	else
-		AceEvent:argCheck(event, 2, "string", "function")
-		AceEvent:argCheck(delay, 3, "number")
-	end
-
-	return ScheduleEvent(self, false, event, delay, ...)
-end
-
-function AceEvent:ScheduleRepeatingEvent(event, delay, ...)
-	if type(event) == "string" and type(delay) ~= "number" then
-		AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
-		AceEvent:argCheck(..., 4, "number")
-	else
-		AceEvent:argCheck(event, 2, "string", "function")
-		AceEvent:argCheck(delay, 3, "number")
-	end
-
-	return ScheduleEvent(self, true, event, delay, ...)
-end
-
-function AceEvent:CancelScheduledEvent(t)
-	AceEvent:argCheck(t, 2, "string")
-	if delayRegistry then
-		local v = delayRegistry[t]
-		if v then
-			if type(t) == "string" then
-				del(delayRegistry[t])
-			end
-			delayRegistry[t] = nil
-			if not next(delayRegistry) then
-				AceEvent.frame:Hide()
-			end
-			return true
-		end
-	end
-	return false
-end
-
-function AceEvent:IsEventScheduled(t)
-	AceEvent:argCheck(t, 2, "string")
-	if delayRegistry then
-		local v = delayRegistry[t]
-		if v then
-			return true, v.time - GetTime()
-		end
-	end
-	return false, nil
-end
-
-function AceEvent:UnregisterEvent(event)
-	AceEvent:argCheck(event, 2, "string")
-	local AceEvent_registry = AceEvent.registry
-	if AceEvent_registry[event] and AceEvent_registry[event][self] then
-		AceEvent_registry[event][self] = nil
-		local AceEvent_onceRegistry = AceEvent.onceRegistry
-		if AceEvent_onceRegistry and AceEvent_onceRegistry[event] and AceEvent_onceRegistry[event][self] then
-			AceEvent_onceRegistry[event][self] = nil
-			if not next(AceEvent_onceRegistry[event]) then
-				AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
-			end
-		end
-		local AceEvent_throttleRegistry = AceEvent.throttleRegistry
-		if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] and AceEvent_throttleRegistry[event][self] then
-			AceEvent_throttleRegistry[event][self] = nil
-			if not next(AceEvent_throttleRegistry[event]) then
-				AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
-			end
-		end
-		if not next(AceEvent_registry[event]) then
-			AceEvent_registry[event] = del(AceEvent_registry[event])
-			if not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS]) then
-				AceEvent.frame:UnregisterEvent(event)
-			end
-		end
-	else
-		if self == AceEvent then
-			error(("Cannot unregister event %q. Improperly unregistering from AceEvent-2.0."):format(event), 2)
-		else
-			AceEvent:error("Cannot unregister event %q. %q is not registered with it.", event, self)
-		end
-	end
-	AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
-end
-
-function AceEvent:UnregisterAllEvents()
-	local AceEvent_registry = AceEvent.registry
-	if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then
-		AceEvent_registry[ALL_EVENTS][self] = nil
-		if not next(AceEvent_registry[ALL_EVENTS]) then
-			AceEvent_registry[ALL_EVENTS] = del(AceEvent_registry[ALL_EVENTS])
-			AceEvent.frame:UnregisterAllEvents()
-			for k,v in pairs(AceEvent_registry) do
-				AceEvent.frame:RegisterEvent(k)
-			end
-		end
-	end
-	if AceEvent_registry.AceEvent_EventUnregistered then
-		local event, data = "AceEvent_EventUnregistered", AceEvent_registry.AceEvent_EventUnregistered
-		local x = data[self]
-		data[self] = nil
-		if x then
-			if not next(data) then
-				if not AceEvent_registry[ALL_EVENTS] then
-					AceEvent.frame:UnregisterEvent(event)
-				end
-				AceEvent_registry[event] = del(AceEvent_registry[event])
-			end
-			AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
-		end
-	end
-	for event, data in pairs(AceEvent_registry) do
-		local x = data[self]
-		data[self] = nil
-		if x and event ~= ALL_EVENTS then
-			if not next(data) then
-				if not AceEvent_registry[ALL_EVENTS] then
-					AceEvent.frame:UnregisterEvent(event)
-				end
-				AceEvent_registry[event] = del(AceEvent_registry[event])
-			end
-			AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
-		end
-	end
-	if AceEvent.onceRegistry then
-		for event, data in pairs(AceEvent.onceRegistry) do
-			data[self] = nil
-		end
-	end
-end
-
-function AceEvent:CancelAllScheduledEvents()
-	if delayRegistry then
-		for k,v in pairs(delayRegistry) do
-			if v.self == self then
-				if type(k) == "string" then
-					del(delayRegistry[k])
-				end
-				delayRegistry[k] = nil
-			end
-		end
-		if not next(delayRegistry) then
-			AceEvent.frame:Hide()
-		end
-	end
-end
-
-function AceEvent:IsEventRegistered(event)
-	AceEvent:argCheck(event, 2, "string")
-	local AceEvent_registry = AceEvent.registry
-	if self == AceEvent then
-		return AceEvent_registry[event] and next(AceEvent_registry[event]) or AceEvent_registry[ALL_EVENTS] and next(AceEvent_registry[ALL_EVENTS]) and true or false
-	end
-	if AceEvent_registry[event] and AceEvent_registry[event][self] then
-		return true, AceEvent_registry[event][self]
-	end
-	if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then
-		return true, AceEvent_registry[ALL_EVENTS][self]
-	end
-	return false, nil
-end
-
-local UnitExists = UnitExists
-local bucketfunc
-function AceEvent:RegisterBucketEvent(event, delay, method, ...)
-	AceEvent:argCheck(event, 2, "string", "table")
-	if type(event) == "table" then
-		for k,v in pairs(event) do
-			if type(k) ~= "number" then
-				AceEvent:error("All keys to argument #2 to `RegisterBucketEvent' must be numbers.")
-			elseif type(v) ~= "string" then
-				AceEvent:error("All values to argument #2 to `RegisterBucketEvent' must be strings.")
-			end
-		end
-	end
-	AceEvent:argCheck(delay, 3, "number")
-	if AceEvent == self then
-		AceEvent:argCheck(method, 4, "function")
-		self = method
-	else
-		if type(event) == "string" then
-			AceEvent:argCheck(method, 4, "string", "function", "nil")
-			if not method then
-				method = event
-			end
-		else
-			AceEvent:argCheck(method, 4, "string", "function")
-		end
-
-		if type(method) == "string" and type(self[method]) ~= "function" then
-			AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
-		end
-	end
-	local buckets = AceEvent.buckets
-	if not buckets[event] then
-		buckets[event] = new()
-	end
-	if not buckets[event][self] then
-		local t = {}
-		t.current = {}
-		t.self = self
-		buckets[event][self] = t
-	else
-		AceEvent.CancelScheduledEvent(self, buckets[event][self].id)
-	end
-	local bucket = buckets[event][self]
-	bucket.method = method
-
-	local n = select('#', ...)
-	if n > 0 then
-		for i = 1, n do
-			bucket[i] = select(i, ...)
-		end
-	end
-	bucket.n = n
-
-	local func = function(arg1)
-		bucket.run = true
-		if arg1 then
-			bucket.current[arg1] = true
-		end
-	end
-	buckets[event][self].func = func
-	local isUnitBucket = true
-	if type(event) == "string" then
-		AceEvent.RegisterEvent(self, event, func)
-		if not event:find("^UNIT_") then
-			isUnitBucket = nil
-		end
-	else
-		for _,v in ipairs(event) do
-			AceEvent.RegisterEvent(self, v, func)
-			if isUnitBucket and not v:find("^UNIT_") then
-				isUnitBucket = nil
-			end
-		end
-	end
-	bucket.unit = isUnitBucket
-	if not bucketfunc then
-		bucketfunc = function(bucket)
-			if bucket.run then
-				local current = bucket.current
-				local method = bucket.method
-				local self = bucket.self
-				if bucket.unit then
-					for unit in pairs(current) do
-						if not UnitExists(unit) then
-							current[unit] = nil
-						end
-					end
-				end
-				if type(method) == "string" then
-					self[method](self, current, unpack(bucket, 1, bucket.n))
-				elseif method then -- function
-					method(current, unpack(bucket, 1, bucket.n))
-				end
-				for k in pairs(current) do
-					current[k] = nil
-					k = nil
-				end
-				bucket.run = nil
-			end
-		end
-	end
-	bucket.id = "AceEvent-Bucket-" .. tostring(bucket)
-	AceEvent.ScheduleRepeatingEvent(self, bucket.id, bucketfunc, delay, bucket)
-end
-
-function AceEvent:IsBucketEventRegistered(event)
-	AceEvent:argCheck(event, 2, "string", "table")
-	return AceEvent.buckets and AceEvent.buckets[event] and AceEvent.buckets[event][self]
-end
-
-function AceEvent:UnregisterBucketEvent(event)
-	AceEvent:argCheck(event, 2, "string", "table")
-	if not AceEvent.buckets or not AceEvent.buckets[event] or not AceEvent.buckets[event][self] then
-		AceEvent:error("Cannot unregister bucket event %q. %q is not registered with it.", event, self)
-	end
-
-	local bucket = AceEvent.buckets[event][self]
-
-	if type(event) == "string" then
-		AceEvent.UnregisterEvent(self, event)
-	else
-		for _,v in ipairs(event) do
-			AceEvent.UnregisterEvent(self, v)
-		end
-	end
-	AceEvent:CancelScheduledEvent(bucket.id)
-
-	bucket.current = nil
-	AceEvent.buckets[event][self] = nil
-	if not next(AceEvent.buckets[event]) then
-		AceEvent.buckets[event] = del(AceEvent.buckets[event])
-	end
-end
-
-function AceEvent:UnregisterAllBucketEvents()
-	if not AceEvent.buckets or not next(AceEvent.buckets) then
-		return
-	end
-	for k,v in pairs(AceEvent.buckets) do
-		if v == self then
-			AceEvent.UnregisterBucketEvent(self, k)
-			k = nil
-		end
-	end
-end
-
-local combatSchedules
-function AceEvent:CancelAllCombatSchedules()
-	local i = 0
-	while true do
-		i = i + 1
-		if not combatSchedules[i] then
-			break
-		end
-		local v = combatSchedules[i]
-		if v.self == self then
-			v = del(v)
-			table.remove(combatSchedules, i)
-			i = i - 1
-		end
-	end
-end
-
-local inCombat = false
-
-function AceEvent:PLAYER_REGEN_DISABLED()
-	inCombat = true
-end
-
-do
-	local tmp = {}
-	function AceEvent:PLAYER_REGEN_ENABLED()
-		inCombat = false
-		for i, v in ipairs(combatSchedules) do
-			tmp[i] = v
-			combatSchedules[i] = nil
-		end
-		for i, v in ipairs(tmp) do
-			local func = v.func
-			if func then
-				local success, err = pcall(func, unpack(v, 1, v.n))
-				if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
-			else
-				local obj = v.obj or v.self
-				local method = v.method
-				local obj_method = obj[method]
-				if obj_method then
-					local success, err = pcall(obj_method, obj, unpack(v, 1, v.n))
-					if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
-				end
-			end
-			tmp[i] = del(v)
-		end
-	end
-end
-
-function AceEvent:ScheduleLeaveCombatAction(method, ...)
-	local style = type(method)
-	if self == AceEvent then
-		if style == "table" then
-			local func = (...)
-			AceEvent:argCheck(func, 3, "string")
-			if type(method[func]) ~= "function" then
-				AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", func)
-			end
-		else
-			AceEvent:argCheck(method, 2, "function", --[[so message is right]] "table")
-		end
-		self = method
-	else
-		AceEvent:argCheck(method, 2, "function", "string", "table")
-		if style == "string" and type(self[method]) ~= "function" then
-			AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", method)
-		elseif style == "table" then
-			local func = (...)
-			AceEvent:argCheck(func, 3, "string")
-			if type(method[func]) ~= "function" then
-				AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", func)
-			end
-		end
-	end
-
-	if not inCombat then
-		local success, err
-		if type(method) == "function" then
-			success, err = pcall(method, ...)
-		elseif type(method) == "table" then
-			local func = (...)
-			success, err = pcall(method[func], method, select(2, ...))
-		else
-			success, err = pcall(self[method], self, ...)
-		end
-		if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
-		return
-	end
-	local t
-	local n = select('#', ...)
-	if style == "table" then
-		t = new(select(2, ...))
-		t.obj = method
-		t.method = (...)
-		t.n = n-1
-	else
-		t = new(...)
-		t.n = n
-		if style == "function" then
-			t.func = method
-		else
-			t.method = method
-		end
-	end
-	t.self = self
-	table.insert(combatSchedules, t)
-end
-
-function AceEvent:OnEmbedDisable(target)
-	self.UnregisterAllEvents(target)
-
-	self.CancelAllScheduledEvents(target)
-
-	self.UnregisterAllBucketEvents(target)
-
-	self.CancelAllCombatSchedules(target)
-end
-
-function AceEvent:IsFullyInitialized()
-	return self.postInit or false
-end
-
-local function activate(self, oldLib, oldDeactivate)
-	AceEvent = self
-
-	self.onceRegistry = oldLib and oldLib.onceRegistry or {}
-	self.throttleRegistry = oldLib and oldLib.throttleRegistry or {}
-	self.delayRegistry = oldLib and oldLib.delayRegistry or {}
-	self.buckets = oldLib and oldLib.buckets or {}
-	self.registry = oldLib and oldLib.registry or {}
-	self.frame = oldLib and oldLib.frame or CreateFrame("Frame", "AceEvent20Frame")
-	self.playerLogin = IsLoggedIn() and true
-	self.postInit = oldLib and oldLib.postInit or self.playerLogin and ChatTypeInfo and ChatTypeInfo.WHISPER and ChatTypeInfo.WHISPER.r and true
-	self.ALL_EVENTS = oldLib and oldLib.ALL_EVENTS or _G.newproxy()
-	self.FAKE_NIL = oldLib and oldLib.FAKE_NIL or _G.newproxy()
-	self.RATE = oldLib and oldLib.RATE or _G.newproxy()
-	self.combatSchedules = oldLib and oldLib.combatSchedules or {}
-	self.UID_NUM = oldLib and oldLib.UID_NUM or 0
-
-	combatSchedules = self.combatSchedules
-	ALL_EVENTS = self.ALL_EVENTS
-	FAKE_NIL = self.FAKE_NIL
-	RATE = self.RATE
-	local inPlw = false
-	local blacklist = {
-		UNIT_INVENTORY_CHANGED = true,
-		BAG_UPDATE = true,
-		ITEM_LOCK_CHANGED = true,
-		ACTIONBAR_SLOT_CHANGED = true,
-	}
-	self.frame:SetScript("OnEvent", function(_, event, ...)
-		if event == "PLAYER_ENTERING_WORLD" then
-			inPlw = false
-		elseif event == "PLAYER_LEAVING_WORLD" then
-			inPlw = true
-		end
-		if event and (not inPlw or not blacklist[event]) then
-			self:TriggerEvent(event, ...)
-		end
-	end)
-	if self.delayRegistry then
-		delayRegistry = self.delayRegistry
-		self.frame:SetScript("OnUpdate", OnUpdate)
-	end
-
-	self:UnregisterAllEvents()
-	self:CancelAllScheduledEvents()
-
-	local function handleFullInit()
-		if not self.postInit then
-			local function func()
-				self.postInit = true
-				self:TriggerEvent("AceEvent_FullyInitialized")
-				if self.registry["CHAT_MSG_CHANNEL_NOTICE"] and self.registry["CHAT_MSG_CHANNEL_NOTICE"][self] then
-					self:UnregisterEvent("CHAT_MSG_CHANNEL_NOTICE")
-				end
-				if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then
-					self:UnregisterEvent("MEETINGSTONE_CHANGED")
-				end
-			end
-			registeringFromAceEvent = true
-			self:RegisterEvent("MEETINGSTONE_CHANGED", func, true)
-			self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE", func, true)
-
-			self:ScheduleEvent("AceEvent_FullyInitialized", func, 10)
-			registeringFromAceEvent = nil
-		end
-	end
-
-	if not self.playerLogin then
-		registeringFromAceEvent = true
-		self:RegisterEvent("PLAYER_LOGIN", function()
-			self.playerLogin = true
-			handleFullInit()
-			handleFullInit = nil
-		end, true)
-		registeringFromAceEvent = nil
-	else
-		handleFullInit()
-		handleFullInit = nil
-	end
-
-	if not AceEvent20EditBox then
-	    CreateFrame("Editbox", "AceEvent20EditBox")
-	end
-	local editbox = AceEvent20EditBox
-	function editbox:Execute(line)
-		local defaulteditbox = DEFAULT_CHAT_FRAME.editBox
-		self:SetAttribute("chatType", defaulteditbox:GetAttribute("chatType"))
-		self:SetAttribute("tellTarget", defaulteditbox:GetAttribute("tellTarget"))
-		self:SetAttribute("channelTarget", defaulteditbox:GetAttribute("channelTarget"))
-		self:SetText(line)
-		ChatEdit_SendText(self)
-	end
-	editbox:Hide()
-	_G["SLASH_IN1"] = "/in"
-	SlashCmdList["IN"] = function(msg)
-		local seconds, command, rest = msg:match("^([^%s]+)%s+(/[^%s]+)(.*)$")
-		seconds = tonumber(seconds)
-		if not seconds then
-			DEFAULT_CHAT_FRAME:AddMessage("Error, bad arguments to /in. Must be in the form of `/in 5 /say hi'")
-			return
-		end
-		if IsSecureCmd(command) then
-			DEFAULT_CHAT_FRAME:AddMessage(("Error, /in cannot call secure command: %s"):format(command))
-			return
-		end
-		self:ScheduleEvent("AceEventSlashIn-" .. math.random(1, 1000000000), editbox.Execute, seconds, editbox, command .. rest)
-	end
-
-	registeringFromAceEvent = true
-	self:RegisterEvent("PLAYER_REGEN_ENABLED")
-	self:RegisterEvent("PLAYER_REGEN_DISABLED")
-	self:RegisterEvent("LOOT_OPENED", function()
-		SendAddonMessage("LOOT_OPENED", "", "RAID")
-	end)
-	inCombat = InCombatLockdown()
-	registeringFromAceEvent = nil
-
-	self:activate(oldLib, oldDeactivate)
-	if oldLib then
-		oldDeactivate(oldLib)
-	end
-end
-
-AceLibrary:Register(AceEvent, MAJOR_VERSION, MINOR_VERSION, activate)
+--[[
+Name: AceEvent-2.0
+Revision: $Rev: 1091 $
+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/AceEvent-2.0
+SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceEvent-2.0
+Description: Mixin to allow for event handling, scheduling, and inter-addon
+             communication.
+Dependencies: AceLibrary, AceOO-2.0
+License: LGPL v2.1
+]]
+
+local MAJOR_VERSION = "AceEvent-2.0"
+local MINOR_VERSION = 90000 + tonumber(("$Revision: 1091 $"):match("(%d+)"))
+
+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 AceOO = AceLibrary:GetInstance("AceOO-2.0")
+local Mixin = AceOO.Mixin
+local AceEvent = Mixin {
+	"RegisterEvent",
+	"RegisterAllEvents",
+	"UnregisterEvent",
+	"UnregisterAllEvents",
+	"TriggerEvent",
+	"ScheduleEvent",
+	"ScheduleRepeatingEvent",
+	"CancelScheduledEvent",
+	"CancelAllScheduledEvents",
+	"IsEventRegistered",
+	"IsEventScheduled",
+	"RegisterBucketEvent",
+	"UnregisterBucketEvent",
+	"UnregisterAllBucketEvents",
+	"IsBucketEventRegistered",
+	"ScheduleLeaveCombatAction",
+	"CancelAllCombatSchedules",
+}
+
+local weakKey = {__mode="k"}
+
+local FAKE_NIL
+local RATE
+
+local eventsWhichHappenOnce = {
+	PLAYER_LOGIN = true,
+	AceEvent_FullyInitialized = true,
+	VARIABLES_LOADED = true,
+	PLAYER_LOGOUT = true,
+}
+local next = next
+local pairs = pairs
+local pcall = pcall
+local type = type
+local GetTime = GetTime
+local gcinfo = gcinfo
+local unpack = unpack
+local geterrorhandler = geterrorhandler
+
+local new, del
+do
+	local cache = setmetatable({}, {__mode='k'})
+	function new(...)
+		local t = next(cache)
+		if t then
+			cache[t] = nil
+			for i = 1, select('#', ...) do
+				t[i] = select(i, ...)
+			end
+			return t
+		else
+			return { ... }
+		end
+	end
+	function del(t)
+		for k in pairs(t) do
+			t[k] = nil
+		end
+		cache[t] = true
+		return nil
+	end
+end
+
+local registeringFromAceEvent
+--[[----------------------------------------------------------------------------------
+Notes:
+	* Registers the addon with a Blizzard event or a custom AceEvent, which will cause the given method to be called when that is triggered.
+Arguments:
+	string - name of the event to register
+	[optional] string or function - name of the method or function to call. Default: same name as "event".
+	[optional] boolean - whether to have method called only once. Default: false
+------------------------------------------------------------------------------------]]
+function AceEvent:RegisterEvent(event, method, once)
+	AceEvent:argCheck(event, 2, "string")
+	if self == AceEvent and not registeringFromAceEvent then
+		AceEvent:argCheck(method, 3, "function")
+		self = method
+	else
+		AceEvent:argCheck(method, 3, "string", "function", "nil", "boolean", "number")
+		if type(method) == "boolean" or type(method) == "number" then
+			AceEvent:argCheck(once, 4, "nil")
+			once, method = method, event
+		end
+	end
+	AceEvent:argCheck(once, 4, "number", "boolean", "nil")
+	if eventsWhichHappenOnce[event] then
+		once = true
+	end
+	local throttleRate
+	if type(once) == "number" then
+		throttleRate, once = once
+	end
+	if not method then
+		method = event
+	end
+	if type(method) == "string" and type(self[method]) ~= "function" then
+		AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
+	else
+		assert(type(method) == "function" or type(method) == "string")
+	end
+
+	local AceEvent_registry = AceEvent.registry
+	if not AceEvent_registry[event] then
+		AceEvent_registry[event] = new()
+		AceEvent.frame:RegisterEvent(event)
+	end
+
+	local remember = true
+	if AceEvent_registry[event][self] then
+		remember = false
+	end
+	AceEvent_registry[event][self] = method
+
+	local AceEvent_onceRegistry = AceEvent.onceRegistry
+	if once then
+		if not AceEvent_onceRegistry then
+			AceEvent.onceRegistry = {}
+			AceEvent_onceRegistry = AceEvent.onceRegistry
+		end
+		if not AceEvent_onceRegistry[event] then
+			AceEvent_onceRegistry[event] = new()
+		end
+		AceEvent_onceRegistry[event][self] = true
+	else
+		if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
+			AceEvent_onceRegistry[event][self] = nil
+			if not next(AceEvent_onceRegistry[event]) then
+				AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
+			end
+		end
+	end
+
+	local AceEvent_throttleRegistry = AceEvent.throttleRegistry
+	if throttleRate then
+		if not AceEvent_throttleRegistry then
+			AceEvent.throttleRegistry = {}
+			AceEvent_throttleRegistry = AceEvent.throttleRegistry
+		end
+		if not AceEvent_throttleRegistry[event] then
+			AceEvent_throttleRegistry[event] = new()
+		end
+		if AceEvent_throttleRegistry[event][self] then
+			AceEvent_throttleRegistry[event][self] = nil
+		end
+		AceEvent_throttleRegistry[event][self] = setmetatable(new(), weakKey)
+		local t = AceEvent_throttleRegistry[event][self]
+		t[RATE] = throttleRate
+	else
+		if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] then
+			if AceEvent_throttleRegistry[event][self] then
+				AceEvent_throttleRegistry[event][self] = nil
+			end
+			if not next(AceEvent_throttleRegistry[event]) then
+				AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
+			end
+		end
+	end
+
+	if remember then
+		AceEvent:TriggerEvent("AceEvent_EventRegistered", self, event)
+	end
+end
+
+local ALL_EVENTS
+
+--[[----------------------------------------------------------------------------------
+Notes:
+	* Registers all events to the given method
+	* To access the current event, check AceEvent.currentEvent
+	* To access the current event's unique identifier, check AceEvent.currentEventUID
+	* This is only for debugging purposes.
+Arguments:
+	[optional] string or function - name of the method or function to call. Default: same name as "event".
+------------------------------------------------------------------------------------]]
+function AceEvent:RegisterAllEvents(method)
+	if self == AceEvent then
+		AceEvent:argCheck(method, 1, "function")
+		self = method
+	else
+		AceEvent:argCheck(method, 1, "string", "function")
+		if type(method) == "string" and type(self[method]) ~= "function" then
+			AceEvent:error("Cannot register all events to method %q, it does not exist", method)
+		end
+	end
+
+	local AceEvent_registry = AceEvent.registry
+	if not AceEvent_registry[ALL_EVENTS] then
+		AceEvent_registry[ALL_EVENTS] = new()
+		AceEvent.frame:RegisterAllEvents()
+	end
+
+	local remember = not AceEvent_registry[ALL_EVENTS][self]
+	AceEvent_registry[ALL_EVENTS][self] = method
+	if remember then
+		AceEvent:TriggerEvent("AceEvent_EventRegistered", self, "all")
+	end
+end
+
+--[[----------------------------------------------------------------------------------
+Notes:
+	* Trigger a custom AceEvent.
+	* This should never be called to simulate fake Blizzard events.
+	* Custom events should be in the form of AddonName_SpecificEvent
+Arguments:
+	string - name of the event
+	tuple - list of arguments to pass along
+------------------------------------------------------------------------------------]]
+function AceEvent:TriggerEvent(event, ...)
+	AceEvent:argCheck(event, 2, "string")
+	local AceEvent_registry = AceEvent.registry
+	if (not AceEvent_registry[event] or not next(AceEvent_registry[event])) and (not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS])) then
+		return
+	end
+	local lastEvent = AceEvent.currentEvent
+	AceEvent.currentEvent = event
+	local lastEventUID = AceEvent.currentEventUID
+	local uid = AceEvent.UID_NUM + 1
+	AceEvent.UID_NUM = uid
+	AceEvent.currentEventUID = uid
+
+	local tmp = new()
+
+	local AceEvent_onceRegistry = AceEvent.onceRegistry
+	if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
+		for obj, method in pairs(AceEvent_onceRegistry[event]) do
+			tmp[obj] = AceEvent_registry[event] and AceEvent_registry[event][obj] or nil
+		end
+		local obj = next(tmp)
+		while obj do
+			local method = tmp[obj]
+			AceEvent.UnregisterEvent(obj, event)
+			if type(method) == "string" then
+				local obj_method = obj[method]
+				if obj_method then
+					local success, err = pcall(obj_method, obj, ...)
+					if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
+				end
+			elseif method then -- function
+				local success, err = pcall(method, ...)
+				if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
+			end
+			tmp[obj] = nil
+			obj = next(tmp)
+		end
+	end
+
+	local AceEvent_throttleRegistry = AceEvent.throttleRegistry
+	local throttleTable = AceEvent_throttleRegistry and AceEvent_throttleRegistry[event]
+	if AceEvent_registry[event] then
+		for obj, method in pairs(AceEvent_registry[event]) do
+			tmp[obj] = method
+		end
+		local obj = next(tmp)
+		while obj do
+			local cont = nil
+			if throttleTable and throttleTable[obj] then
+				local a1 = ...
+				if a1 == nil then
+					a1 = FAKE_NIL
+				end
+				if not throttleTable[obj][a1] or GetTime() - throttleTable[obj][a1] >= throttleTable[obj][RATE] then
+					throttleTable[obj][a1] = GetTime()
+				else
+					cont = true
+				end
+			end
+			if not cont then
+				local method = tmp[obj]
+				local t = type(method)
+				if t == "string" then
+					local obj_method = obj[method]
+					if obj_method then
+						local success, err = pcall(obj_method, obj, ...)
+						if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
+					end
+				elseif t == "function" then -- function
+					local success, err = pcall(method, ...)
+					if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
+				else
+					AceEvent:error("Cannot trigger event %q. %q's handler, %q, is not a method or function (%s).", event, obj, method, t)
+				end
+			end
+			tmp[obj] = nil
+			obj = next(tmp)
+		end
+	end
+	if AceEvent_registry[ALL_EVENTS] then
+		for obj, method in pairs(AceEvent_registry[ALL_EVENTS]) do
+			tmp[obj] = method
+		end
+		local obj = next(tmp)
+		while obj do
+			local method = tmp[obj]
+			local t = type(method)
+			if t == "string" then
+				local obj_method = obj[method]
+				if obj_method then
+					local success, err = pcall(obj_method, obj, ...)
+					if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
+				end
+			elseif t == "function" then
+				local success, err = pcall(method, ...)
+				if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
+			else
+				AceEvent:error("Cannot trigger event %q. %q's handler, %q, is not a method or function (%s).", event, obj, method, t)
+			end
+			tmp[obj] = nil
+			obj = next(tmp)
+		end
+	end
+	tmp = del(tmp)
+	AceEvent.currentEvent = lastEvent
+	AceEvent.currentEventUID = lastEventUID
+end
+
+local delayRegistry
+local OnUpdate
+do
+	local tmp = {}
+	OnUpdate = function()
+		local t = GetTime()
+		for k,v in pairs(delayRegistry) do
+			tmp[k] = true
+		end
+		for k in pairs(tmp) do
+			local v = delayRegistry[k]
+			if v then
+				local v_time = v.time
+				if not v_time then
+					delayRegistry[k] = nil
+				elseif v_time <= t then
+					local v_repeatDelay = v.repeatDelay
+					if v_repeatDelay then
+						-- use the event time, not the current time, else timing inaccuracies add up over time
+						v.time = v_time + v_repeatDelay
+					end
+					local event = v.event
+					local t = type(event)
+					if t == "function" then
+						local uid = AceEvent.UID_NUM + 1
+						AceEvent.UID_NUM = uid
+						AceEvent.currentEventUID = uid
+						local success, err = pcall(event, unpack(v, 1, v.n))
+						if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
+						AceEvent.currentEventUID = nil
+					elseif t == "string" then
+						AceEvent:TriggerEvent(event, unpack(v, 1, v.n))
+					else
+						AceEvent:error("Cannot trigger event %q, it's not a method or function (%s).", event, t)
+					end
+					if not v_repeatDelay then
+						local x = delayRegistry[k]
+						if x and x.time == v_time then -- check if it was manually reset
+							if type(k) == "string" then
+								del(delayRegistry[k])
+							end
+							delayRegistry[k] = nil
+						end
+					end
+				end
+			end
+		end
+		for k in pairs(tmp) do
+			tmp[k] = nil
+		end
+		if not next(delayRegistry) then
+			AceEvent.frame:Hide()
+		end
+	end
+end
+
+local function ScheduleEvent(self, repeating, event, delay, ...)
+	local id
+	if type(event) == "string" and type(delay) ~= "number" then
+		id, event, delay = event, delay, ...
+		AceEvent:argCheck(event, 3, "string", "function", --[[ so message is right ]] "number")
+		AceEvent:argCheck(delay, 4, "number")
+		self:CancelScheduledEvent(id)
+	else
+		AceEvent:argCheck(event, 2, "string", "function")
+		AceEvent:argCheck(delay, 3, "number")
+	end
+
+	if not delayRegistry then
+		AceEvent.delayRegistry = {}
+		delayRegistry = AceEvent.delayRegistry
+		AceEvent.frame:SetScript("OnUpdate", OnUpdate)
+	end
+	local t
+	if id then
+		t = new(select(2, ...))
+		t.n = select('#', ...) - 1
+	else
+		t = new(...)
+		t.n = select('#', ...)
+	end
+	t.event = event
+	t.time = GetTime() + delay
+	t.self = self
+	t.id = id or t
+	t.repeatDelay = repeating and delay
+	delayRegistry[t.id] = t
+	AceEvent.frame:Show()
+end
+
+--[[----------------------------------------------------------------------------------
+Notes:
+	* Schedule an event to fire.
+	* To fire on the next frame, specify a delay of 0.
+Arguments:
+	string or function - name of the event to fire, or a function to call.
+	number - the amount of time to wait until calling.
+	tuple - a list of arguments to pass along.
+------------------------------------------------------------------------------------]]
+function AceEvent:ScheduleEvent(event, delay, ...)
+	if type(event) == "string" and type(delay) ~= "number" then
+		AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
+		AceEvent:argCheck(..., 4, "number")
+	else
+		AceEvent:argCheck(event, 2, "string", "function")
+		AceEvent:argCheck(delay, 3, "number")
+	end
+
+	return ScheduleEvent(self, false, event, delay, ...)
+end
+
+function AceEvent:ScheduleRepeatingEvent(event, delay, ...)
+	if type(event) == "string" and type(delay) ~= "number" then
+		AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
+		AceEvent:argCheck(..., 4, "number")
+	else
+		AceEvent:argCheck(event, 2, "string", "function")
+		AceEvent:argCheck(delay, 3, "number")
+	end
+
+	return ScheduleEvent(self, true, event, delay, ...)
+end
+
+function AceEvent:CancelScheduledEvent(t)
+	AceEvent:argCheck(t, 2, "string")
+	if delayRegistry then
+		local v = delayRegistry[t]
+		if v then
+			if type(t) == "string" then
+				del(delayRegistry[t])
+			end
+			delayRegistry[t] = nil
+			if not next(delayRegistry) then
+				AceEvent.frame:Hide()
+			end
+			return true
+		end
+	end
+	return false
+end
+
+function AceEvent:IsEventScheduled(t)
+	AceEvent:argCheck(t, 2, "string")
+	if delayRegistry then
+		local v = delayRegistry[t]
+		if v then
+			return true, v.time - GetTime()
+		end
+	end
+	return false, nil
+end
+
+function AceEvent:UnregisterEvent(event)
+	AceEvent:argCheck(event, 2, "string")
+	local AceEvent_registry = AceEvent.registry
+	if AceEvent_registry[event] and AceEvent_registry[event][self] then
+		AceEvent_registry[event][self] = nil
+		local AceEvent_onceRegistry = AceEvent.onceRegistry
+		if AceEvent_onceRegistry and AceEvent_onceRegistry[event] and AceEvent_onceRegistry[event][self] then
+			AceEvent_onceRegistry[event][self] = nil
+			if not next(AceEvent_onceRegistry[event]) then
+				AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
+			end
+		end
+		local AceEvent_throttleRegistry = AceEvent.throttleRegistry
+		if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] and AceEvent_throttleRegistry[event][self] then
+			AceEvent_throttleRegistry[event][self] = nil
+			if not next(AceEvent_throttleRegistry[event]) then
+				AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
+			end
+		end
+		if not next(AceEvent_registry[event]) then
+			AceEvent_registry[event] = del(AceEvent_registry[event])
+			if not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS]) then
+				AceEvent.frame:UnregisterEvent(event)
+			end
+		end
+	else
+		if self == AceEvent then
+			error(("Cannot unregister event %q. Improperly unregistering from AceEvent-2.0."):format(event), 2)
+		else
+			AceEvent:error("Cannot unregister event %q. %q is not registered with it.", event, self)
+		end
+	end
+	AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
+end
+
+function AceEvent:UnregisterAllEvents()
+	local AceEvent_registry = AceEvent.registry
+	if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then
+		AceEvent_registry[ALL_EVENTS][self] = nil
+		if not next(AceEvent_registry[ALL_EVENTS]) then
+			AceEvent_registry[ALL_EVENTS] = del(AceEvent_registry[ALL_EVENTS])
+			AceEvent.frame:UnregisterAllEvents()
+			for k,v in pairs(AceEvent_registry) do
+				AceEvent.frame:RegisterEvent(k)
+			end
+		end
+	end
+	if AceEvent_registry.AceEvent_EventUnregistered then
+		local event, data = "AceEvent_EventUnregistered", AceEvent_registry.AceEvent_EventUnregistered
+		local x = data[self]
+		data[self] = nil
+		if x then
+			if not next(data) then
+				if not AceEvent_registry[ALL_EVENTS] then
+					AceEvent.frame:UnregisterEvent(event)
+				end
+				AceEvent_registry[event] = del(AceEvent_registry[event])
+			end
+			AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
+		end
+	end
+	for event, data in pairs(AceEvent_registry) do
+		local x = data[self]
+		data[self] = nil
+		if x and event ~= ALL_EVENTS then
+			if not next(data) then
+				if not AceEvent_registry[ALL_EVENTS] then
+					AceEvent.frame:UnregisterEvent(event)
+				end
+				AceEvent_registry[event] = del(AceEvent_registry[event])
+			end
+			AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
+		end
+	end
+	if AceEvent.onceRegistry then
+		for event, data in pairs(AceEvent.onceRegistry) do
+			data[self] = nil
+		end
+	end
+end
+
+function AceEvent:CancelAllScheduledEvents()
+	if delayRegistry then
+		for k,v in pairs(delayRegistry) do
+			if v.self == self then
+				if type(k) == "string" then
+					del(delayRegistry[k])
+				end
+				delayRegistry[k] = nil
+			end
+		end
+		if not next(delayRegistry) then
+			AceEvent.frame:Hide()
+		end
+	end
+end
+
+function AceEvent:IsEventRegistered(event)
+	AceEvent:argCheck(event, 2, "string")
+	local AceEvent_registry = AceEvent.registry
+	if self == AceEvent then
+		return AceEvent_registry[event] and next(AceEvent_registry[event]) or AceEvent_registry[ALL_EVENTS] and next(AceEvent_registry[ALL_EVENTS]) and true or false
+	end
+	if AceEvent_registry[event] and AceEvent_registry[event][self] then
+		return true, AceEvent_registry[event][self]
+	end
+	if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then
+		return true, AceEvent_registry[ALL_EVENTS][self]
+	end
+	return false, nil
+end
+
+local UnitExists = UnitExists
+local bucketfunc
+function AceEvent:RegisterBucketEvent(event, delay, method, ...)
+	AceEvent:argCheck(event, 2, "string", "table")
+	if type(event) == "table" then
+		for k,v in pairs(event) do
+			if type(k) ~= "number" then
+				AceEvent:error("All keys to argument #2 to `RegisterBucketEvent' must be numbers.")
+			elseif type(v) ~= "string" then
+				AceEvent:error("All values to argument #2 to `RegisterBucketEvent' must be strings.")
+			end
+		end
+	end
+	AceEvent:argCheck(delay, 3, "number")
+	if AceEvent == self then
+		AceEvent:argCheck(method, 4, "function")
+		self = method
+	else
+		if type(event) == "string" then
+			AceEvent:argCheck(method, 4, "string", "function", "nil")
+			if not method then
+				method = event
+			end
+		else
+			AceEvent:argCheck(method, 4, "string", "function")
+		end
+
+		if type(method) == "string" and type(self[method]) ~= "function" then
+			AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
+		end
+	end
+	local buckets = AceEvent.buckets
+	if not buckets[event] then
+		buckets[event] = new()
+	end
+	if not buckets[event][self] then
+		local t = {}
+		t.current = {}
+		t.self = self
+		buckets[event][self] = t
+	else
+		AceEvent.CancelScheduledEvent(self, buckets[event][self].id)
+	end
+	local bucket = buckets[event][self]
+	bucket.method = method
+
+	local n = select('#', ...)
+	if n > 0 then
+		for i = 1, n do
+			bucket[i] = select(i, ...)
+		end
+	end
+	bucket.n = n
+
+	local func = function(arg1)
+		bucket.run = true
+		if arg1 then
+			bucket.current[arg1] = true
+		end
+	end
+	buckets[event][self].func = func
+	local isUnitBucket = true
+	if type(event) == "string" then
+		AceEvent.RegisterEvent(self, event, func)
+		if not event:find("^UNIT_") then
+			isUnitBucket = nil
+		end
+	else
+		for _,v in ipairs(event) do
+			AceEvent.RegisterEvent(self, v, func)
+			if isUnitBucket and not v:find("^UNIT_") then
+				isUnitBucket = nil
+			end
+		end
+	end
+	bucket.unit = isUnitBucket
+	if not bucketfunc then
+		bucketfunc = function(bucket)
+			if bucket.run then
+				local current = bucket.current
+				local method = bucket.method
+				local self = bucket.self
+				if bucket.unit then
+					for unit in pairs(current) do
+						if not UnitExists(unit) then
+							current[unit] = nil
+						end
+					end
+				end
+				if type(method) == "string" then
+					self[method](self, current, unpack(bucket, 1, bucket.n))
+				elseif method then -- function
+					method(current, unpack(bucket, 1, bucket.n))
+				end
+				for k in pairs(current) do
+					current[k] = nil
+					k = nil
+				end
+				bucket.run = nil
+			end
+		end
+	end
+	bucket.id = "AceEvent-Bucket-" .. tostring(bucket)
+	AceEvent.ScheduleRepeatingEvent(self, bucket.id, bucketfunc, delay, bucket)
+end
+
+function AceEvent:IsBucketEventRegistered(event)
+	AceEvent:argCheck(event, 2, "string", "table")
+	return AceEvent.buckets and AceEvent.buckets[event] and AceEvent.buckets[event][self]
+end
+
+function AceEvent:UnregisterBucketEvent(event)
+	AceEvent:argCheck(event, 2, "string", "table")
+	if not AceEvent.buckets or not AceEvent.buckets[event] or not AceEvent.buckets[event][self] then
+		AceEvent:error("Cannot unregister bucket event %q. %q is not registered with it.", event, self)
+	end
+
+	local bucket = AceEvent.buckets[event][self]
+
+	if type(event) == "string" then
+		AceEvent.UnregisterEvent(self, event)
+	else
+		for _,v in ipairs(event) do
+			AceEvent.UnregisterEvent(self, v)
+		end
+	end
+	AceEvent:CancelScheduledEvent(bucket.id)
+
+	bucket.current = nil
+	AceEvent.buckets[event][self] = nil
+	if not next(AceEvent.buckets[event]) then
+		AceEvent.buckets[event] = del(AceEvent.buckets[event])
+	end
+end
+
+function AceEvent:UnregisterAllBucketEvents()
+	if not AceEvent.buckets or not next(AceEvent.buckets) then
+		return
+	end
+	for k,v in pairs(AceEvent.buckets) do
+		if v == self then
+			AceEvent.UnregisterBucketEvent(self, k)
+			k = nil
+		end
+	end
+end
+
+local combatSchedules
+function AceEvent:CancelAllCombatSchedules()
+	local i = 0
+	while true do
+		i = i + 1
+		if not combatSchedules[i] then
+			break
+		end
+		local v = combatSchedules[i]
+		if v.self == self then
+			v = del(v)
+			table.remove(combatSchedules, i)
+			i = i - 1
+		end
+	end
+end
+
+local inCombat = false
+
+function AceEvent:PLAYER_REGEN_DISABLED()
+	inCombat = true
+end
+
+do
+	local tmp = {}
+	function AceEvent:PLAYER_REGEN_ENABLED()
+		inCombat = false
+		for i, v in ipairs(combatSchedules) do
+			tmp[i] = v
+			combatSchedules[i] = nil
+		end
+		for i, v in ipairs(tmp) do
+			local func = v.func
+			if func then
+				local success, err = pcall(func, unpack(v, 1, v.n))
+				if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
+			else
+				local obj = v.obj or v.self
+				local method = v.method
+				local obj_method = obj[method]
+				if obj_method then
+					local success, err = pcall(obj_method, obj, unpack(v, 1, v.n))
+					if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
+				end
+			end
+			tmp[i] = del(v)
+		end
+	end
+end
+
+function AceEvent:ScheduleLeaveCombatAction(method, ...)
+	local style = type(method)
+	if self == AceEvent then
+		if style == "table" then
+			local func = (...)
+			AceEvent:argCheck(func, 3, "string")
+			if type(method[func]) ~= "function" then
+				AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", func)
+			end
+		else
+			AceEvent:argCheck(method, 2, "function", --[[so message is right]] "table")
+		end
+		self = method
+	else
+		AceEvent:argCheck(method, 2, "function", "string", "table")
+		if style == "string" and type(self[method]) ~= "function" then
+			AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", method)
+		elseif style == "table" then
+			local func = (...)
+			AceEvent:argCheck(func, 3, "string")
+			if type(method[func]) ~= "function" then
+				AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", func)
+			end
+		end
+	end
+
+	if not inCombat then
+		local success, err
+		if type(method) == "function" then
+			success, err = pcall(method, ...)
+		elseif type(method) == "table" then
+			local func = (...)
+			success, err = pcall(method[func], method, select(2, ...))
+		else
+			success, err = pcall(self[method], self, ...)
+		end
+		if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
+		return
+	end
+	local t
+	local n = select('#', ...)
+	if style == "table" then
+		t = new(select(2, ...))
+		t.obj = method
+		t.method = (...)
+		t.n = n-1
+	else
+		t = new(...)
+		t.n = n
+		if style == "function" then
+			t.func = method
+		else
+			t.method = method
+		end
+	end
+	t.self = self
+	table.insert(combatSchedules, t)
+end
+
+function AceEvent:OnEmbedDisable(target)
+	self.UnregisterAllEvents(target)
+
+	self.CancelAllScheduledEvents(target)
+
+	self.UnregisterAllBucketEvents(target)
+
+	self.CancelAllCombatSchedules(target)
+end
+
+function AceEvent:IsFullyInitialized()
+	return self.postInit or false
+end
+
+local function activate(self, oldLib, oldDeactivate)
+	AceEvent = self
+
+	self.onceRegistry = oldLib and oldLib.onceRegistry or {}
+	self.throttleRegistry = oldLib and oldLib.throttleRegistry or {}
+	self.delayRegistry = oldLib and oldLib.delayRegistry or {}
+	self.buckets = oldLib and oldLib.buckets or {}
+	self.registry = oldLib and oldLib.registry or {}
+	self.frame = oldLib and oldLib.frame or CreateFrame("Frame", "AceEvent20Frame")
+	self.playerLogin = IsLoggedIn() and true
+	self.postInit = oldLib and oldLib.postInit or self.playerLogin and ChatTypeInfo and ChatTypeInfo.WHISPER and ChatTypeInfo.WHISPER.r and true
+	self.ALL_EVENTS = oldLib and oldLib.ALL_EVENTS or _G.newproxy()
+	self.FAKE_NIL = oldLib and oldLib.FAKE_NIL or _G.newproxy()
+	self.RATE = oldLib and oldLib.RATE or _G.newproxy()
+	self.combatSchedules = oldLib and oldLib.combatSchedules or {}
+	self.UID_NUM = oldLib and oldLib.UID_NUM or 0
+
+	combatSchedules = self.combatSchedules
+	ALL_EVENTS = self.ALL_EVENTS
+	FAKE_NIL = self.FAKE_NIL
+	RATE = self.RATE
+	local inPlw = false
+	local blacklist = {
+		UNIT_INVENTORY_CHANGED = true,
+		BAG_UPDATE = true,
+		ITEM_LOCK_CHANGED = true,
+		ACTIONBAR_SLOT_CHANGED = true,
+	}
+	self.frame:SetScript("OnEvent", function(_, event, ...)
+		if event == "PLAYER_ENTERING_WORLD" then
+			inPlw = false
+		elseif event == "PLAYER_LEAVING_WORLD" then
+			inPlw = true
+		end
+		if event and (not inPlw or not blacklist[event]) then
+			self:TriggerEvent(event, ...)
+		end
+	end)
+	if self.delayRegistry then
+		delayRegistry = self.delayRegistry
+		self.frame:SetScript("OnUpdate", OnUpdate)
+	end
+
+	self:UnregisterAllEvents()
+	self:CancelAllScheduledEvents()
+
+	local function handleFullInit()
+		if not self.postInit then
+			local function func()
+				self.postInit = true
+				self:TriggerEvent("AceEvent_FullyInitialized")
+				if self.registry["CHAT_MSG_CHANNEL_NOTICE"] and self.registry["CHAT_MSG_CHANNEL_NOTICE"][self] then
+					self:UnregisterEvent("CHAT_MSG_CHANNEL_NOTICE")
+				end
+				if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then
+					self:UnregisterEvent("MEETINGSTONE_CHANGED")
+				end
+			end
+			registeringFromAceEvent = true
+			self:RegisterEvent("MEETINGSTONE_CHANGED", func, true)
+			self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE", func, true)
+
+			self:ScheduleEvent("AceEvent_FullyInitialized", func, 10)
+			registeringFromAceEvent = nil
+		end
+	end
+
+	if not self.playerLogin then
+		registeringFromAceEvent = true
+		self:RegisterEvent("PLAYER_LOGIN", function()
+			self.playerLogin = true
+			handleFullInit()
+			handleFullInit = nil
+		end, true)
+		registeringFromAceEvent = nil
+	else
+		handleFullInit()
+		handleFullInit = nil
+	end
+
+	if not AceEvent20EditBox then
+	    CreateFrame("Editbox", "AceEvent20EditBox")
+	end
+	local editbox = AceEvent20EditBox
+	function editbox:Execute(line)
+		local defaulteditbox = DEFAULT_CHAT_FRAME.editBox
+		self:SetAttribute("chatType", defaulteditbox:GetAttribute("chatType"))
+		self:SetAttribute("tellTarget", defaulteditbox:GetAttribute("tellTarget"))
+		self:SetAttribute("channelTarget", defaulteditbox:GetAttribute("channelTarget"))
+		self:SetText(line)
+		ChatEdit_SendText(self)
+	end
+	editbox:Hide()
+	_G["SLASH_IN1"] = "/in"
+	SlashCmdList["IN"] = function(msg)
+		local seconds, command, rest = msg:match("^([^%s]+)%s+(/[^%s]+)(.*)$")
+		seconds = tonumber(seconds)
+		if not seconds then
+			DEFAULT_CHAT_FRAME:AddMessage("Error, bad arguments to /in. Must be in the form of `/in 5 /say hi'")
+			return
+		end
+		if IsSecureCmd(command) then
+			DEFAULT_CHAT_FRAME:AddMessage(("Error, /in cannot call secure command: %s"):format(command))
+			return
+		end
+		self:ScheduleEvent("AceEventSlashIn-" .. math.random(1, 1000000000), editbox.Execute, seconds, editbox, command .. rest)
+	end
+
+	registeringFromAceEvent = true
+	self:RegisterEvent("PLAYER_REGEN_ENABLED")
+	self:RegisterEvent("PLAYER_REGEN_DISABLED")
+	self:RegisterEvent("LOOT_OPENED", function()
+		SendAddonMessage("LOOT_OPENED", "", "RAID")
+	end)
+	inCombat = InCombatLockdown()
+	registeringFromAceEvent = nil
+
+	self:activate(oldLib, oldDeactivate)
+	if oldLib then
+		oldDeactivate(oldLib)
+	end
+end
+
+AceLibrary:Register(AceEvent, MAJOR_VERSION, MINOR_VERSION, activate)
diff --git a/Libs/AceEvent-2.0/AceEvent-2.0.toc b/Libs/AceEvent-2.0/AceEvent-2.0.toc
index 8a39b37..89f9e71 100644
--- a/Libs/AceEvent-2.0/AceEvent-2.0.toc
+++ b/Libs/AceEvent-2.0/AceEvent-2.0.toc
@@ -1,16 +1,16 @@
-## Interface: 30000
-## X-Curse-Packaged-Version: r1094
-## X-Curse-Project-Name: Ace2
-## X-Curse-Project-ID: ace2
-## X-Curse-Repository-ID: wow/ace2/mainline
-
-## Title: Lib: AceEvent-2.0
-## Notes: AddOn development framework
-## Author: Ace Development Team
-## LoadOnDemand: 1
-## X-Website: http://www.wowace.com
-## X-Category: Library
-## X-License: LGPL v2.1 + MIT for AceOO-2.0
-## Dependencies: AceLibrary, AceOO-2.0
-
-AceEvent-2.0.lua
+## Interface: 30000
+## X-Curse-Packaged-Version: r1094
+## X-Curse-Project-Name: Ace2
+## X-Curse-Project-ID: ace2
+## X-Curse-Repository-ID: wow/ace2/mainline
+
+## Title: Lib: AceEvent-2.0
+## Notes: AddOn development framework
+## Author: Ace Development Team
+## LoadOnDemand: 1
+## X-Website: http://www.wowace.com
+## X-Category: Library
+## X-License: LGPL v2.1 + MIT for AceOO-2.0
+## Dependencies: AceLibrary, AceOO-2.0
+
+AceEvent-2.0.lua
diff --git a/Libs/AceHook-2.1/AceHook-2.1.lua b/Libs/AceHook-2.1/AceHook-2.1.lua
index 87f2420..4c5a38b 100644
--- a/Libs/AceHook-2.1/AceHook-2.1.lua
+++ b/Libs/AceHook-2.1/AceHook-2.1.lua
@@ -1,554 +1,554 @@
---[[
-Name: AceHook-2.1
-Revision: $Rev: 1091 $
-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/AceHook-2.1
-SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceHook-2.1
-Description: Mixin to allow for safe hooking of functions, methods, and scripts.
-Dependencies: AceLibrary, AceOO-2.0
-License: LGPL v2.1
-]]
-
-local MAJOR_VERSION = "AceHook-2.1"
-local MINOR_VERSION = 90000 + tonumber(("$Revision: 1091 $"):match("(%d+)"))
-
--- This ensures the code is only executed if the libary doesn't already exist, or is a newer version
-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
-
---[[---------------------------------------------------------------------------------
-  Create the library object
-----------------------------------------------------------------------------------]]
-
-local AceOO = AceLibrary:GetInstance("AceOO-2.0")
-local AceHook = AceOO.Mixin {
-								"Hook",
-								"HookScript",
-								"SecureHook",
-								"SecureHookScript",
-								"Unhook",
-								"UnhookAll",
-								"HookReport",
-								"IsHooked",
-							}
-
---[[---------------------------------------------------------------------------------
-  Library Definitions
-----------------------------------------------------------------------------------]]
-
-local protectedScripts = {
-	OnClick = true,
-}
-
-local _G = getfenv(0)
-
-local handlers, scripts, actives, registry, onceSecure
-
---[[---------------------------------------------------------------------------------
-  Private definitions (Not exposed)
-----------------------------------------------------------------------------------]]
-
-local new, del
-do
-	local list = setmetatable({}, {__mode = "k"})
-	function new()
-		local t = next(list)
-		if not t then
-			return {}
-		end
-		list[t] = nil
-		return t
-	end
-
-	function del(t)
-		setmetatable(t, nil)
-		for k in pairs(t) do
-			t[k] = nil
-		end
-		list[t] = true
-	end
-end
-
-local function createFunctionHook(self, func, handler, orig, secure)
-	if not secure then
-		if type(handler) == "string" then
-			-- The handler is a method, need to self it
-			local uid
-			uid = function(...)
-				if actives[uid] then
-					return self[handler](self, ...)
-				else
-					return orig(...)
-				end
-			end
-			return uid
-		else
-			-- The handler is a function, just call it
-			local uid
-			uid = function(...)
-				if actives[uid] then
-					return handler(...)
-				else
-					return orig(...)
-				end
-			end
-			return uid
-		end
-	else
-		-- secure hooks don't call the original method
-		if type(handler) == "string" then
-			-- The handler is a method, need to self it
-			local uid
-			uid = function(...)
-				if actives[uid] then
-					return self[handler](self, ...)
-				end
-			end
-			return uid
-		else
-			-- The handler is a function, just call it
-			local uid
-			uid = function(...)
-				if actives[uid] then
-					return handler(...)
-				end
-			end
-			return uid
-		end
-	end
-end
-
-local function createMethodHook(self, object, method, handler, orig, secure)
-	if not secure then
-		if type(handler) == "string" then
-			local uid
-			uid = function(...)
-				if actives[uid] then
-					return self[handler](self, ...)
-				else
-					return orig(...)
-				end
-			end
-			return uid
-		else
-			-- The handler is a function, just call it
-			local uid
-			uid = function(...)
-				if actives[uid] then
-					return handler(...)
-				else
-					return orig(...)
-				end
-			end
-			return uid
-		end
-	else
-		-- secure hooks don't call the original method
-		if type(handler) == "string" then
-			local uid
-			uid = function(...)
-				if actives[uid] then
-					return self[handler](self, ...)
-				end
-			end
-			return uid
-		else
-			-- The handler is a function, just call it
-			local uid
-			uid = function(...)
-				if actives[uid] then
-					return handler(...)
-				end
-			end
-			return uid
-		end
-	end
-end
-
-local function hookFunction(self, func, handler, secure)
-	local orig = _G[func]
-
-	if not orig or type(orig) ~= "function" then
-		AceHook:error("Attempt to hook a non-existant function %q", func)
-	end
-
-	if not handler then
-		handler = func
-	end
-
-	local uid = registry[self][func]
-	if uid then
-		if actives[uid] then
-			-- We have an active hook from this source.  Don't multi-hook
-			AceHook:error("%q already has an active hook from this source.", func)
-		end
-
-		if handlers[uid] == handler then
-			-- The hook is inactive, so reactivate it
-			actives[uid] = true
-			return
-		else
-			self.hooks[func] = nil
-			registry[self][func] = nil
-			handlers[uid] = nil
-			uid = nil
-		end
-	end
-
-	if type(handler) == "string" then
-		if type(self[handler]) ~= "function" then
-			AceHook:error("Could not find the the handler %q when hooking function %q", handler, func)
-		end
-	elseif type(handler) ~= "function" then
-		AceHook:error("Could not find the handler you supplied when hooking %q", func)
-	end
-
-	uid = createFunctionHook(self, func, handler, orig, secure)
-	registry[self][func] = uid
-	actives[uid] = true
-	handlers[uid] = handler
-
-	if not secure then
-		_G[func] = uid
-		self.hooks[func] = orig
-	else
-		hooksecurefunc(func, uid)
-	end
-end
-
-local function unhookFunction(self, func)
-	if not registry[self][func] then
-		AceHook:error("Tried to unhook %q which is not currently hooked.", func)
-	end
-
-	local uid = registry[self][func]
-
-	if actives[uid] then
-		-- See if we own the global function
-		if self.hooks[func] and _G[func] == uid then
-			_G[func] = self.hooks[func]
-			self.hooks[func] = nil
-			registry[self][func] = nil
-			handlers[uid] = nil
-			actives[uid] = nil
-			-- Magically all-done
-		else
-			actives[uid] = nil
-		end
-	end
-end
-
-local donothing = function() end
-
-local function hookMethod(self, obj, method, handler, script, secure)
-	if not handler then
-		handler = method
-	end
-
-	if not obj or type(obj) ~= "table" then
-		AceHook:error("The object you supplied could not be found, or isn't a table.")
-	end
-
-	local uid = registry[self][obj] and registry[self][obj][method]
-	if uid then
-		if actives[uid] then
-			-- We have an active hook from this source.  Don't multi-hook
-			AceHook:error("%q already has an active hook from this source.", method)
-		end
-
-		if handlers[uid] == handler then
-			-- The hook is inactive, reactivate it.
-			actives[uid] = true
-			return
-		else
-			if self.hooks[obj] then
-				self.hooks[obj][method] = nil
-			end
-			registry[self][obj][method] = nil
-			handlers[uid] = nil
-			actives[uid] = nil
-			scripts[uid] = nil
-			uid = nil
-		end
-	end
-
-	if type(handler) == "string" then
-		if type(self[handler]) ~= "function" then
-			AceHook:error("Could not find the handler %q you supplied when hooking method %q", handler, method)
-		end
-	elseif type(handler) ~= "function" then
-		AceHook:error("Could not find the handler you supplied when hooking method %q", method)
-	end
-
-	local orig
-	if script then
-		if not obj.GetScript then
-			AceHook:error("The object you supplied does not have a GetScript method.")
-		end
-		if not obj:HasScript(method) then
-			AceHook:error("The object you supplied doesn't allow the %q method.", method)
-		end
-
-		orig = obj:GetScript(method)
-		if type(orig) ~= "function" then
-			-- Sometimes there is not a original function for a script.
-			orig = donothing
-		end
-	else
-		orig = obj[method]
-	end
-	if not orig then
-		AceHook:error("Could not find the method or script %q you are trying to hook.", method)
-	end
-
-	if not self.hooks[obj] then
-		self.hooks[obj] = new()
-	end
-	if not registry[self][obj] then
-		registry[self][obj] = new()
-	end
-
-	local uid = createMethodHook(self, obj, method, handler, orig, secure)
-	registry[self][obj][method] = uid
-	actives[uid] = true
-	handlers[uid] = handler
-	scripts[uid] = script and true or nil
-
-	if script then
-		if not secure then
-			obj:SetScript(method, uid)
-			self.hooks[obj][method] = orig
-		else
-			obj:HookScript(method, uid)
-		end
-	else
-		if not secure then
-			obj[method] = uid
-			self.hooks[obj][method] = orig
-		else
-			hooksecurefunc(obj, method, uid)
-		end
-	end
-end
-
-local function unhookMethod(self, obj, method)
-	if not registry[self][obj] or not registry[self][obj][method] then
-		AceHook:error("Attempt to unhook a method %q that is not currently hooked.", method)
-		return
-	end
-
-	local uid = registry[self][obj][method]
-
-	if actives[uid] then
-		if scripts[uid] then -- If this is a script
-			if obj:GetScript(method) == uid then
-				-- We own the script.  Revert to normal.
-				if self.hooks[obj][method] == donothing then
-					obj:SetScript(method, nil)
-				else
-					obj:SetScript(method, self.hooks[obj][method])
-				end
-				self.hooks[obj][method] = nil
-				registry[self][obj][method] = nil
-				handlers[uid] = nil
-				scripts[uid] = nil
-				actives[uid] = nil
-			else
-				actives[uid] = nil
-			end
-		else
-			if self.hooks[obj] and self.hooks[obj][method] and obj[method] == uid then
-				-- We own the method.  Revert to normal.
-				obj[method] = self.hooks[obj][method]
-				self.hooks[obj][method] = nil
-				registry[self][obj][method] = nil
-				handlers[uid] = nil
-				actives[uid] = nil
-			else
-				actives[uid] = nil
-			end
-		end
-	end
-	if self.hooks[obj] and not next(self.hooks[obj]) then
-		self.hooks[obj] = del(self.hooks[obj])
-	end
-	if not next(registry[self][obj]) then
-		registry[self][obj] = del(registry[self][obj])
-	end
-end
-
--- ("function" [, handler] [, hookSecure]) or (object, "method" [, handler] [, hookSecure])
-function AceHook:Hook(object, method, handler, hookSecure)
-	if type(object) == "string" then
-		method, handler, hookSecure = object, method, handler
-		if handler == true then
-			handler, hookSecure = nil, true
-		end
-		AceHook:argCheck(handler, 3, "function", "string", "nil")
-		AceHook:argCheck(hookSecure, 4, "boolean", "nil")
-		if issecurevariable(method) or onceSecure[method] then
-			if hookSecure then
-				onceSecure[method] = true
-			else
-				AceHook:error("Attempt to hook secure function %q. Use `SecureHook' or add `true' to the argument list to override.", method)
-			end
-		end
-		hookFunction(self, method, handler, false)
-	else
-		if handler == true then
-			handler, hookSecure = nil, true
-		end
-		AceHook:argCheck(object, 2, "table")
-		AceHook:argCheck(method, 3, "string")
-		AceHook:argCheck(handler, 4, "function", "string", "nil")
-		AceHook:argCheck(hookSecure, 5, "boolean", "nil")
-		if not object[method] then
-			AceHook:error("Attempt to hook method %q failed, it does not exist in the given object %q.", method, object)
-		end
-		if not hookSecure and issecurevariable(object, method) then
-			AceHook:error("Attempt to hook secure method %q. Use `SecureHook' or add `true' to the argument list to override.", method)
-		end
-		hookMethod(self, object, method, handler, false, false)
-	end
-end
-
--- ("function", handler) or (object, "method", handler)
-function AceHook:SecureHook(object, method, handler)
-	if type(object) == "string" then
-		method, handler = object, method
-		AceHook:argCheck(handler, 3, "function", "string", "nil")
-		hookFunction(self, method, handler, true)
-	else
-		AceHook:argCheck(object, 2, "table")
-		AceHook:argCheck(method, 3, "string")
-		AceHook:argCheck(handler, 4, "function", "string", "nil")
-		if not object[method] then
-			AceHook:error("Attempt to hook method %q failed, it does not exist in the given object %q.", method, object)
-		end
-		hookMethod(self, object, method, handler, false, true)
-	end
-end
-
-function AceHook:HookScript(frame, script, handler)
-	AceHook:argCheck(frame, 2, "table")
-	if not frame[0] or type(frame.IsProtected) ~= "function" then
-		AceHook:error("Bad argument #2 to `HookScript'. Expected frame.")
-	end
-	AceHook:argCheck(script, 3, "string")
-	AceHook:argCheck(handler, 4, "function", "string", "nil")
-	if frame:IsProtected() and protectedScripts[script] then
-		AceHook:error("Cannot hook secure script %q.", script)
-	end
-	hookMethod(self, frame, script, handler, true, false)
-end
-
-function AceHook:SecureHookScript(frame, script, handler)
-	AceHook:argCheck(frame, 2, "table")
-	if not frame[0] or type(frame.IsProtected) ~= "function" then
-		AceHook:error("Bad argument #2 to `HookScript'. Expected frame.")
-	end
-	AceHook:argCheck(script, 3, "string")
-	AceHook:argCheck(handler, 4, "function", "string", "nil")
-	hookMethod(self, frame, script, handler, true, true)
-end
-
--- ("function") or (object, "method")
-function AceHook:IsHooked(obj, method)
-	if type(obj) == "string" then
-		if registry[self][obj] and actives[registry[self][obj]] then
-			return true, handlers[registry[self][obj]]
-		end
-	else
-		AceHook:argCheck(obj, 2, "string", "table")
-		AceHook:argCheck(method, 3, "string")
-		if registry[self][obj] and registry[self][obj][method] and actives[registry[self][obj][method]] then
-			return true, handlers[registry[self][obj][method]]
-		end
-	end
-
-	return false, nil
-end
-
--- ("function") or (object, "method")
-function AceHook:Unhook(obj, method)
-	if type(obj) == "string" then
-		unhookFunction(self, obj)
-	else
-		AceHook:argCheck(obj, 2, "string", "table")
-		AceHook:argCheck(method, 3, "string")
-		unhookMethod(self, obj, method)
-	end
-end
-
-function AceHook:UnhookAll()
-	if type(registry[self]) ~= "table" then return end
-	for key, value in pairs(registry[self]) do
-		if type(key) == "table" then
-			for method in pairs(value) do
-				self:Unhook(key, method)
-			end
-		else
-			self:Unhook(key)
-		end
-	end
-end
-
-function AceHook:HookReport()
-	DEFAULT_CHAT_FRAME:AddMessage("This is a list of all active hooks for this object:")
-	if not next(registry[self]) then
-		DEFAULT_CHAT_FRAME:AddMessage("No hooks")
-	end
-
-	for key, value in pairs(registry[self]) do
-		if type(value) == "table" then
-			for method, uid in pairs(value) do
-				DEFAULT_CHAT_FRAME:AddMessage(("object: %s method: %q |cff%s|r%s"):format(tostring(key), method, actives[uid] and "00ff00Active" or "ffff00Inactive", not self.hooks[key][method] and " |cff7f7fff-Secure-|r" or ""))
-			end
-		else
-			DEFAULT_CHAT_FRAME:AddMessage(("function: %q |cff%s|r%s"):format(tostring(key), actives[value] and "00ff00Active" or "ffff00Inactive", not self.hooks[key] and " |cff7f7fff-Secure-|r" or ""))
-		end
-	end
-end
-
-function AceHook:OnInstanceInit(object)
-	if not object.hooks then
-		object.hooks = new()
-	end
-	if not registry[object] then
-		registry[object] = new()
-	end
-end
-
-AceHook.OnManualEmbed = AceHook.OnInstanceInit
-
-function AceHook:OnEmbedDisable(target)
-	self.UnhookAll(target)
-end
-
-local function activate(self, oldLib, oldDeactivate)
-	AceHook = self
-
-	self.handlers = oldLib and oldLib.handlers or {}
-	self.registry = oldLib and oldLib.registry or {}
-	self.scripts = oldLib and oldLib.scripts or {}
-	self.actives = oldLib and oldLib.actives or {}
-	self.onceSecure = oldLib and oldLib.onceSecure or {}
-
-	handlers = self.handlers
-	registry = self.registry
-	scripts = self.scripts
-	actives = self.actives
-	onceSecure = self.onceSecure
-
-	self:activate(oldLib, oldDeactivate)
-
-	if oldDeactivate then
-		oldDeactivate(oldLib)
-	end
-end
-
-AceLibrary:Register(AceHook, MAJOR_VERSION, MINOR_VERSION, activate)
+--[[
+Name: AceHook-2.1
+Revision: $Rev: 1091 $
+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/AceHook-2.1
+SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceHook-2.1
+Description: Mixin to allow for safe hooking of functions, methods, and scripts.
+Dependencies: AceLibrary, AceOO-2.0
+License: LGPL v2.1
+]]
+
+local MAJOR_VERSION = "AceHook-2.1"
+local MINOR_VERSION = 90000 + tonumber(("$Revision: 1091 $"):match("(%d+)"))
+
+-- This ensures the code is only executed if the libary doesn't already exist, or is a newer version
+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
+
+--[[---------------------------------------------------------------------------------
+  Create the library object
+----------------------------------------------------------------------------------]]
+
+local AceOO = AceLibrary:GetInstance("AceOO-2.0")
+local AceHook = AceOO.Mixin {
+								"Hook",
+								"HookScript",
+								"SecureHook",
+								"SecureHookScript",
+								"Unhook",
+								"UnhookAll",
+								"HookReport",
+								"IsHooked",
+							}
+
+--[[---------------------------------------------------------------------------------
+  Library Definitions
+----------------------------------------------------------------------------------]]
+
+local protectedScripts = {
+	OnClick = true,
+}
+
+local _G = getfenv(0)
+
+local handlers, scripts, actives, registry, onceSecure
+
+--[[---------------------------------------------------------------------------------
+  Private definitions (Not exposed)
+----------------------------------------------------------------------------------]]
+
+local new, del
+do
+	local list = setmetatable({}, {__mode = "k"})
+	function new()
+		local t = next(list)
+		if not t then
+			return {}
+		end
+		list[t] = nil
+		return t
+	end
+
+	function del(t)
+		setmetatable(t, nil)
+		for k in pairs(t) do
+			t[k] = nil
+		end
+		list[t] = true
+	end
+end
+
+local function createFunctionHook(self, func, handler, orig, secure)
+	if not secure then
+		if type(handler) == "string" then
+			-- The handler is a method, need to self it
+			local uid
+			uid = function(...)
+				if actives[uid] then
+					return self[handler](self, ...)
+				else
+					return orig(...)
+				end
+			end
+			return uid
+		else
+			-- The handler is a function, just call it
+			local uid
+			uid = function(...)
+				if actives[uid] then
+					return handler(...)
+				else
+					return orig(...)
+				end
+			end
+			return uid
+		end
+	else
+		-- secure hooks don't call the original method
+		if type(handler) == "string" then
+			-- The handler is a method, need to self it
+			local uid
+			uid = function(...)
+				if actives[uid] then
+					return self[handler](self, ...)
+				end
+			end
+			return uid
+		else
+			-- The handler is a function, just call it
+			local uid
+			uid = function(...)
+				if actives[uid] then
+					return handler(...)
+				end
+			end
+			return uid
+		end
+	end
+end
+
+local function createMethodHook(self, object, method, handler, orig, secure)
+	if not secure then
+		if type(handler) == "string" then
+			local uid
+			uid = function(...)
+				if actives[uid] then
+					return self[handler](self, ...)
+				else
+					return orig(...)
+				end
+			end
+			return uid
+		else
+			-- The handler is a function, just call it
+			local uid
+			uid = function(...)
+				if actives[uid] then
+					return handler(...)
+				else
+					return orig(...)
+				end
+			end
+			return uid
+		end
+	else
+		-- secure hooks don't call the original method
+		if type(handler) == "string" then
+			local uid
+			uid = function(...)
+				if actives[uid] then
+					return self[handler](self, ...)
+				end
+			end
+			return uid
+		else
+			-- The handler is a function, just call it
+			local uid
+			uid = function(...)
+				if actives[uid] then
+					return handler(...)
+				end
+			end
+			return uid
+		end
+	end
+end
+
+local function hookFunction(self, func, handler, secure)
+	local orig = _G[func]
+
+	if not orig or type(orig) ~= "function" then
+		AceHook:error("Attempt to hook a non-existant function %q", func)
+	end
+
+	if not handler then
+		handler = func
+	end
+
+	local uid = registry[self][func]
+	if uid then
+		if actives[uid] then
+			-- We have an active hook from this source.  Don't multi-hook
+			AceHook:error("%q already has an active hook from this source.", func)
+		end
+
+		if handlers[uid] == handler then
+			-- The hook is inactive, so reactivate it
+			actives[uid] = true
+			return
+		else
+			self.hooks[func] = nil
+			registry[self][func] = nil
+			handlers[uid] = nil
+			uid = nil
+		end
+	end
+
+	if type(handler) == "string" then
+		if type(self[handler]) ~= "function" then
+			AceHook:error("Could not find the the handler %q when hooking function %q", handler, func)
+		end
+	elseif type(handler) ~= "function" then
+		AceHook:error("Could not find the handler you supplied when hooking %q", func)
+	end
+
+	uid = createFunctionHook(self, func, handler, orig, secure)
+	registry[self][func] = uid
+	actives[uid] = true
+	handlers[uid] = handler
+
+	if not secure then
+		_G[func] = uid
+		self.hooks[func] = orig
+	else
+		hooksecurefunc(func, uid)
+	end
+end
+
+local function unhookFunction(self, func)
+	if not registry[self][func] then
+		AceHook:error("Tried to unhook %q which is not currently hooked.", func)
+	end
+
+	local uid = registry[self][func]
+
+	if actives[uid] then
+		-- See if we own the global function
+		if self.hooks[func] and _G[func] == uid then
+			_G[func] = self.hooks[func]
+			self.hooks[func] = nil
+			registry[self][func] = nil
+			handlers[uid] = nil
+			actives[uid] = nil
+			-- Magically all-done
+		else
+			actives[uid] = nil
+		end
+	end
+end
+
+local donothing = function() end
+
+local function hookMethod(self, obj, method, handler, script, secure)
+	if not handler then
+		handler = method
+	end
+
+	if not obj or type(obj) ~= "table" then
+		AceHook:error("The object you supplied could not be found, or isn't a table.")
+	end
+
+	local uid = registry[self][obj] and registry[self][obj][method]
+	if uid then
+		if actives[uid] then
+			-- We have an active hook from this source.  Don't multi-hook
+			AceHook:error("%q already has an active hook from this source.", method)
+		end
+
+		if handlers[uid] == handler then
+			-- The hook is inactive, reactivate it.
+			actives[uid] = true
+			return
+		else
+			if self.hooks[obj] then
+				self.hooks[obj][method] = nil
+			end
+			registry[self][obj][method] = nil
+			handlers[uid] = nil
+			actives[uid] = nil
+			scripts[uid] = nil
+			uid = nil
+		end
+	end
+
+	if type(handler) == "string" then
+		if type(self[handler]) ~= "function" then
+			AceHook:error("Could not find the handler %q you supplied when hooking method %q", handler, method)
+		end
+	elseif type(handler) ~= "function" then
+		AceHook:error("Could not find the handler you supplied when hooking method %q", method)
+	end
+
+	local orig
+	if script then
+		if not obj.GetScript then
+			AceHook:error("The object you supplied does not have a GetScript method.")
+		end
+		if not obj:HasScript(method) then
+			AceHook:error("The object you supplied doesn't allow the %q method.", method)
+		end
+
+		orig = obj:GetScript(method)
+		if type(orig) ~= "function" then
+			-- Sometimes there is not a original function for a script.
+			orig = donothing
+		end
+	else
+		orig = obj[method]
+	end
+	if not orig then
+		AceHook:error("Could not find the method or script %q you are trying to hook.", method)
+	end
+
+	if not self.hooks[obj] then
+		self.hooks[obj] = new()
+	end
+	if not registry[self][obj] then
+		registry[self][obj] = new()
+	end
+
+	local uid = createMethodHook(self, obj, method, handler, orig, secure)
+	registry[self][obj][method] = uid
+	actives[uid] = true
+	handlers[uid] = handler
+	scripts[uid] = script and true or nil
+
+	if script then
+		if not secure then
+			obj:SetScript(method, uid)
+			self.hooks[obj][method] = orig
+		else
+			obj:HookScript(method, uid)
+		end
+	else
+		if not secure then
+			obj[method] = uid
+			self.hooks[obj][method] = orig
+		else
+			hooksecurefunc(obj, method, uid)
+		end
+	end
+end
+
+local function unhookMethod(self, obj, method)
+	if not registry[self][obj] or not registry[self][obj][method] then
+		AceHook:error("Attempt to unhook a method %q that is not currently hooked.", method)
+		return
+	end
+
+	local uid = registry[self][obj][method]
+
+	if actives[uid] then
+		if scripts[uid] then -- If this is a script
+			if obj:GetScript(method) == uid then
+				-- We own the script.  Revert to normal.
+				if self.hooks[obj][method] == donothing then
+					obj:SetScript(method, nil)
+				else
+					obj:SetScript(method, self.hooks[obj][method])
+				end
+				self.hooks[obj][method] = nil
+				registry[self][obj][method] = nil
+				handlers[uid] = nil
+				scripts[uid] = nil
+				actives[uid] = nil
+			else
+				actives[uid] = nil
+			end
+		else
+			if self.hooks[obj] and self.hooks[obj][method] and obj[method] == uid then
+				-- We own the method.  Revert to normal.
+				obj[method] = self.hooks[obj][method]
+				self.hooks[obj][method] = nil
+				registry[self][obj][method] = nil
+				handlers[uid] = nil
+				actives[uid] = nil
+			else
+				actives[uid] = nil
+			end
+		end
+	end
+	if self.hooks[obj] and not next(self.hooks[obj]) then
+		self.hooks[obj] = del(self.hooks[obj])
+	end
+	if not next(registry[self][obj]) then
+		registry[self][obj] = del(registry[self][obj])
+	end
+end
+
+-- ("function" [, handler] [, hookSecure]) or (object, "method" [, handler] [, hookSecure])
+function AceHook:Hook(object, method, handler, hookSecure)
+	if type(object) == "string" then
+		method, handler, hookSecure = object, method, handler
+		if handler == true then
+			handler, hookSecure = nil, true
+		end
+		AceHook:argCheck(handler, 3, "function", "string", "nil")
+		AceHook:argCheck(hookSecure, 4, "boolean", "nil")
+		if issecurevariable(method) or onceSecure[method] then
+			if hookSecure then
+				onceSecure[method] = true
+			else
+				AceHook:error("Attempt to hook secure function %q. Use `SecureHook' or add `true' to the argument list to override.", method)
+			end
+		end
+		hookFunction(self, method, handler, false)
+	else
+		if handler == true then
+			handler, hookSecure = nil, true
+		end
+		AceHook:argCheck(object, 2, "table")
+		AceHook:argCheck(method, 3, "string")
+		AceHook:argCheck(handler, 4, "function", "string", "nil")
+		AceHook:argCheck(hookSecure, 5, "boolean", "nil")
+		if not object[method] then
+			AceHook:error("Attempt to hook method %q failed, it does not exist in the given object %q.", method, object)
+		end
+		if not hookSecure and issecurevariable(object, method) then
+			AceHook:error("Attempt to hook secure method %q. Use `SecureHook' or add `true' to the argument list to override.", method)
+		end
+		hookMethod(self, object, method, handler, false, false)
+	end
+end
+
+-- ("function", handler) or (object, "method", handler)
+function AceHook:SecureHook(object, method, handler)
+	if type(object) == "string" then
+		method, handler = object, method
+		AceHook:argCheck(handler, 3, "function", "string", "nil")
+		hookFunction(self, method, handler, true)
+	else
+		AceHook:argCheck(object, 2, "table")
+		AceHook:argCheck(method, 3, "string")
+		AceHook:argCheck(handler, 4, "function", "string", "nil")
+		if not object[method] then
+			AceHook:error("Attempt to hook method %q failed, it does not exist in the given object %q.", method, object)
+		end
+		hookMethod(self, object, method, handler, false, true)
+	end
+end
+
+function AceHook:HookScript(frame, script, handler)
+	AceHook:argCheck(frame, 2, "table")
+	if not frame[0] or type(frame.IsProtected) ~= "function" then
+		AceHook:error("Bad argument #2 to `HookScript'. Expected frame.")
+	end
+	AceHook:argCheck(script, 3, "string")
+	AceHook:argCheck(handler, 4, "function", "string", "nil")
+	if frame:IsProtected() and protectedScripts[script] then
+		AceHook:error("Cannot hook secure script %q.", script)
+	end
+	hookMethod(self, frame, script, handler, true, false)
+end
+
+function AceHook:SecureHookScript(frame, script, handler)
+	AceHook:argCheck(frame, 2, "table")
+	if not frame[0] or type(frame.IsProtected) ~= "function" then
+		AceHook:error("Bad argument #2 to `HookScript'. Expected frame.")
+	end
+	AceHook:argCheck(script, 3, "string")
+	AceHook:argCheck(handler, 4, "function", "string", "nil")
+	hookMethod(self, frame, script, handler, true, true)
+end
+
+-- ("function") or (object, "method")
+function AceHook:IsHooked(obj, method)
+	if type(obj) == "string" then
+		if registry[self][obj] and actives[registry[self][obj]] then
+			return true, handlers[registry[self][obj]]
+		end
+	else
+		AceHook:argCheck(obj, 2, "string", "table")
+		AceHook:argCheck(method, 3, "string")
+		if registry[self][obj] and registry[self][obj][method] and actives[registry[self][obj][method]] then
+			return true, handlers[registry[self][obj][method]]
+		end
+	end
+
+	return false, nil
+end
+
+-- ("function") or (object, "method")
+function AceHook:Unhook(obj, method)
+	if type(obj) == "string" then
+		unhookFunction(self, obj)
+	else
+		AceHook:argCheck(obj, 2, "string", "table")
+		AceHook:argCheck(method, 3, "string")
+		unhookMethod(self, obj, method)
+	end
+end
+
+function AceHook:UnhookAll()
+	if type(registry[self]) ~= "table" then return end
+	for key, value in pairs(registry[self]) do
+		if type(key) == "table" then
+			for method in pairs(value) do
+				self:Unhook(key, method)
+			end
+		else
+			self:Unhook(key)
+		end
+	end
+end
+
+function AceHook:HookReport()
+	DEFAULT_CHAT_FRAME:AddMessage("This is a list of all active hooks for this object:")
+	if not next(registry[self]) then
+		DEFAULT_CHAT_FRAME:AddMessage("No hooks")
+	end
+
+	for key, value in pairs(registry[self]) do
+		if type(value) == "table" then
+			for method, uid in pairs(value) do
+				DEFAULT_CHAT_FRAME:AddMessage(("object: %s method: %q |cff%s|r%s"):format(tostring(key), method, actives[uid] and "00ff00Active" or "ffff00Inactive", not self.hooks[key][method] and " |cff7f7fff-Secure-|r" or ""))
+			end
+		else
+			DEFAULT_CHAT_FRAME:AddMessage(("function: %q |cff%s|r%s"):format(tostring(key), actives[value] and "00ff00Active" or "ffff00Inactive", not self.hooks[key] and " |cff7f7fff-Secure-|r" or ""))
+		end
+	end
+end
+
+function AceHook:OnInstanceInit(object)
+	if not object.hooks then
+		object.hooks = new()
+	end
+	if not registry[object] then
+		registry[object] = new()
+	end
+end
+
+AceHook.OnManualEmbed = AceHook.OnInstanceInit
+
+function AceHook:OnEmbedDisable(target)
+	self.UnhookAll(target)
+end
+
+local function activate(self, oldLib, oldDeactivate)
+	AceHook = self
+
+	self.handlers = oldLib and oldLib.handlers or {}
+	self.registry = oldLib and oldLib.registry or {}
+	self.scripts = oldLib and oldLib.scripts or {}
+	self.actives = oldLib and oldLib.actives or {}
+	self.onceSecure = oldLib and oldLib.onceSecure or {}
+
+	handlers = self.handlers
+	registry = self.registry
+	scripts = self.scripts
+	actives = self.actives
+	onceSecure = self.onceSecure
+
+	self:activate(oldLib, oldDeactivate)
+
+	if oldDeactivate then
+		oldDeactivate(oldLib)
+	end
+end
+
+AceLibrary:Register(AceHook, MAJOR_VERSION, MINOR_VERSION, activate)
diff --git a/Libs/AceHook-2.1/AceHook-2.1.toc b/Libs/AceHook-2.1/AceHook-2.1.toc
index ff215fc..98be011 100644
--- a/Libs/AceHook-2.1/AceHook-2.1.toc
+++ b/Libs/AceHook-2.1/AceHook-2.1.toc
@@ -1,16 +1,16 @@
-## Interface: 30000
-## X-Curse-Packaged-Version: r1094
-## X-Curse-Project-Name: Ace2
-## X-Curse-Project-ID: ace2
-## X-Curse-Repository-ID: wow/ace2/mainline
-
-## Title: Lib: AceHook-2.1
-## Notes: AddOn development framework
-## Author: Ace Development Team
-## LoadOnDemand: 1
-## X-Website: http://www.wowace.com
-## X-Category: Library
-## X-License: LGPL v2.1 + MIT for AceOO-2.0
-## Dependencies: AceLibrary, AceOO-2.0
-
-AceHook-2.1.lua
+## Interface: 30000
+## X-Curse-Packaged-Version: r1094
+## X-Curse-Project-Name: Ace2
+## X-Curse-Project-ID: ace2
+## X-Curse-Repository-ID: wow/ace2/mainline
+
+## Title: Lib: AceHook-2.1
+## Notes: AddOn development framework
+## Author: Ace Development Team
+## LoadOnDemand: 1
+## X-Website: http://www.wowace.com
+## X-Category: Library
+## X-License: LGPL v2.1 + MIT for AceOO-2.0
+## Dependencies: AceLibrary, AceOO-2.0
+
+AceHook-2.1.lua
diff --git a/Libs/AceLibrary/AceLibrary.lua b/Libs/AceLibrary/AceLibrary.lua
index 8ff1742..26901ca 100644
--- a/Libs/AceLibrary/AceLibrary.lua
+++ b/Libs/AceLibrary/AceLibrary.lua
@@ -1,799 +1,799 @@
---[[
-Name: AceLibrary
-Revision: $Rev: 1091 $
-Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
-Inspired By: Iriel (iriel@vigilance-committee.org)
-             Tekkub (tekkub@gmail.com)
-             Revision: $Rev: 1091 $
-Website: http://www.wowace.com/
-Documentation: http://www.wowace.com/index.php/AceLibrary
-SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceLibrary
-Description: Versioning library to handle other library instances, upgrading,
-             and proper access.
-             It also provides a base for libraries to work off of, providing
-             proper error tools. It is handy because all the errors occur in the
-             file that called it, not in the library file itself.
-Dependencies: None
-License: LGPL v2.1
-]]
-
-local ACELIBRARY_MAJOR = "AceLibrary"
-local ACELIBRARY_MINOR = 90000 + tonumber(("$Revision: 1091 $"):match("(%d+)"))
-
-local _G = getfenv(0)
-local previous = _G[ACELIBRARY_MAJOR]
-if previous and not previous:IsNewVersion(ACELIBRARY_MAJOR, ACELIBRARY_MINOR) then return end
-
-do
-	-- LibStub is a simple versioning stub meant for use in Libraries.  http://www.wowace.com/wiki/LibStub for more info
-	-- LibStub is hereby placed in the Public Domain -- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
-	local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2  -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
-	local LibStub = _G[LIBSTUB_MAJOR]
-
-	if not LibStub or LibStub.minor < LIBSTUB_MINOR then
-		LibStub = LibStub or {libs = {}, minors = {} }
-		_G[LIBSTUB_MAJOR] = LibStub
-		LibStub.minor = LIBSTUB_MINOR
-
-		function LibStub:NewLibrary(major, minor)
-			assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
-			minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
-			local oldminor = self.minors[major]
-			if oldminor and oldminor >= minor then return nil end
-			self.minors[major], self.libs[major] = minor, self.libs[major] or {}
-			return self.libs[major], oldminor
-		end
-
-		function LibStub:GetLibrary(major, silent)
-			if not self.libs[major] and not silent then
-				error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
-			end
-			return self.libs[major], self.minors[major]
-		end
-
-		function LibStub:IterateLibraries() return pairs(self.libs) end
-		setmetatable(LibStub, { __call = LibStub.GetLibrary })
-	end
-end
-local LibStub = _G.LibStub
-
--- If you don't want AceLibrary to enable libraries that are LoadOnDemand but
--- disabled in the addon screen, set this to true.
-local DONT_ENABLE_LIBRARIES = nil
-
-local function safecall(func,...)
-    local success, err = pcall(func,...)
-    if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("\n(.-: )in.-\n") or "") .. err) end
-end
-
--- @table AceLibrary
--- @brief System to handle all versioning of libraries.
-local AceLibrary = {}
-local AceLibrary_mt = {}
-setmetatable(AceLibrary, AceLibrary_mt)
-
-local function error(self, message, ...)
-	if type(self) ~= "table" then
-		return _G.error(("Bad argument #1 to `error' (table expected, got %s)"):format(type(self)), 2)
-	end
-
-	local stack = debugstack()
-	if not message then
-		local second = stack:match("\n(.-)\n")
-		message = "error raised! " .. second
-	else
-		local arg = { ... } -- not worried about table creation, as errors don't happen often
-
-		for i = 1, #arg do
-			arg[i] = tostring(arg[i])
-		end
-		for i = 1, 10 do
-			table.insert(arg, "nil")
-		end
-		message = message:format(unpack(arg))
-	end
-
-	if getmetatable(self) and getmetatable(self).__tostring then
-		message = ("%s: %s"):format(tostring(self), message)
-	elseif type(rawget(self, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self:GetLibraryVersion()) then
-		message = ("%s: %s"):format(self:GetLibraryVersion(), message)
-	elseif type(rawget(self, 'class')) == "table" and type(rawget(self.class, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self.class:GetLibraryVersion()) then
-		message = ("%s: %s"):format(self.class:GetLibraryVersion(), message)
-	end
-
-	local first = stack:gsub("\n.*", "")
-	local file = first:gsub(".*\\(.*).lua:%d+: .*", "%1")
-	file = file:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
-
-
-	local i = 0
-	for s in stack:gmatch("\n([^\n]*)") do
-		i = i + 1
-		if not s:find(file .. "%.lua:%d+:") and not s:find("%(tail call%)") then
-			file = s:gsub("^.*\\(.*).lua:%d+: .*", "%1")
-			file = file:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
-			break
-		end
-	end
-	local j = 0
-	for s in stack:gmatch("\n([^\n]*)") do
-		j = j + 1
-		if j > i and not s:find(file .. "%.lua:%d+:") and not s:find("%(tail call%)") then
-			return _G.error(message, j+1)
-		end
-	end
-	return _G.error(message, 2)
-end
-
-local type = type
-local function argCheck(self, arg, num, kind, kind2, kind3, kind4, kind5)
-	if type(num) ~= "number" then
-		return error(self, "Bad argument #3 to `argCheck' (number expected, got %s)", type(num))
-	elseif type(kind) ~= "string" then
-		return error(self, "Bad argument #4 to `argCheck' (string expected, got %s)", type(kind))
-	end
-	arg = type(arg)
-	if arg ~= kind and arg ~= kind2 and arg ~= kind3 and arg ~= kind4 and arg ~= kind5 then
-		local stack = debugstack()
-		local func = stack:match("`argCheck'.-([`<].-['>])")
-		if not func then
-			func = stack:match("([`<].-['>])")
-		end
-		if kind5 then
-			return error(self, "Bad argument #%s to %s (%s, %s, %s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, kind4, kind5, arg)
-		elseif kind4 then
-			return error(self, "Bad argument #%s to %s (%s, %s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, kind4, arg)
-		elseif kind3 then
-			return error(self, "Bad argument #%s to %s (%s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, arg)
-		elseif kind2 then
-			return error(self, "Bad argument #%s to %s (%s or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, arg)
-		else
-			return error(self, "Bad argument #%s to %s (%s expected, got %s)", tonumber(num) or 0/0, func, kind, arg)
-		end
-	end
-end
-
-local pcall
-do
-	local function check(self, ret, ...)
-		if not ret then
-			local s = ...
-			return error(self, (s:gsub(".-%.lua:%d-: ", "")))
-		else
-			return ...
-		end
-	end
-
-	function pcall(self, func, ...)
-		return check(self, _G.pcall(func, ...))
-	end
-end
-
-local recurse = {}
-local function addToPositions(t, major)
-	if not AceLibrary.positions[t] or AceLibrary.positions[t] == major then
-		rawset(t, recurse, true)
-		AceLibrary.positions[t] = major
-		for k,v in pairs(t) do
-			if type(v) == "table" and not rawget(v, recurse) then
-				addToPositions(v, major)
-			end
-			if type(k) == "table" and not rawget(k, recurse) then
-				addToPositions(k, major)
-			end
-		end
-		local mt = getmetatable(t)
-		if mt and not rawget(mt, recurse) then
-			addToPositions(mt, major)
-		end
-		rawset(t, recurse, nil)
-	end
-end
-
-local function svnRevisionToNumber(text)
-	local kind = type(text)
-	if kind == "number" or tonumber(text) then
-		return tonumber(text)
-	elseif kind == "string" then
-		if text:find("^%$Revision: (%d+) %$$") then
-			return tonumber((text:match("^%$Revision: (%d+) %$$")))
-		elseif text:find("^%$Rev: (%d+) %$$") then
-			return tonumber((text:match("^%$Rev: (%d+) %$$")))
-		elseif text:find("^%$LastChangedRevision: (%d+) %$$") then
-			return tonumber((text:match("^%$LastChangedRevision: (%d+) %$$")))
-		end
-	end
-	return nil
-end
-
-local crawlReplace
-do
-	local recurse = {}
-	local function func(t, to, from)
-		if recurse[t] then
-			return
-		end
-		recurse[t] = true
-		local mt = getmetatable(t)
-		setmetatable(t, nil)
-		rawset(t, to, rawget(t, from))
-		rawset(t, from, nil)
-		for k,v in pairs(t) do
-			if v == from then
-				t[k] = to
-			elseif type(v) == "table" then
-				if not recurse[v] then
-					func(v, to, from)
-				end
-			end
-
-			if type(k) == "table" then
-				if not recurse[k] then
-					func(k, to, from)
-				end
-			end
-		end
-		setmetatable(t, mt)
-		if mt then
-			if mt == from then
-				setmetatable(t, to)
-			elseif not recurse[mt] then
-				func(mt, to, from)
-			end
-		end
-	end
-	function crawlReplace(t, to, from)
-		func(t, to, from)
-		for k in pairs(recurse) do
-			recurse[k] = nil
-		end
-	end
-end
-
--- @function destroyTable
--- @brief    remove all the contents of a table
--- @param t  table to destroy
-local function destroyTable(t)
-	setmetatable(t, nil)
-	for k,v in pairs(t) do
-		t[k] = nil
-	end
-end
-
-local function isFrame(frame)
-	return type(frame) == "table" and type(rawget(frame, 0)) == "userdata" and type(rawget(frame, 'IsFrameType')) == "function" and getmetatable(frame) and type(rawget(getmetatable(frame), '__index')) == "function"
-end
-
--- @function   copyTable
--- @brief      Create a shallow copy of a table and return it.
--- @param from The table to copy from
--- @return     A shallow copy of the table
-local function copyTable(from, to)
-	if not to then
-		to = {}
-	end
-	for k,v in pairs(from) do
-		to[k] = v
-	end
-	setmetatable(to, getmetatable(from))
-	return to
-end
-
--- @function         deepTransfer
--- @brief            Fully transfer all data, keeping proper previous table
---                   backreferences stable.
--- @param to         The table with which data is to be injected into
--- @param from       The table whose data will be injected into the first
--- @param saveFields If available, a shallow copy of the basic data is saved
---                   in here.
--- @param list       The account of table references
--- @param list2      The current status on which tables have been traversed.
-local deepTransfer
-do
-	-- @function   examine
-	-- @brief      Take account of all the table references to be shared
-	--             between the to and from tables.
-	-- @param to   The table with which data is to be injected into
-	-- @param from The table whose data will be injected into the first
-	-- @param list An account of the table references
-	local function examine(to, from, list, major)
-		list[from] = to
-		for k,v in pairs(from) do
-			if rawget(to, k) and type(from[k]) == "table" and type(to[k]) == "table" and not list[from[k]] then
-				if from[k] == to[k] then
-					list[from[k]] = to[k]
-				elseif AceLibrary.positions[from[v]] ~= major and AceLibrary.positions[from[v]] then
-					list[from[k]] = from[k]
-				elseif not list[from[k]] then
-					examine(to[k], from[k], list, major)
-				end
-			end
-		end
-		return list
-	end
-
-	function deepTransfer(to, from, saveFields, major, list, list2)
-		setmetatable(to, nil)
-		if not list then
-			list = {}
-			list2 = {}
-			examine(to, from, list, major)
-		end
-		list2[to] = to
-		for k,v in pairs(to) do
-			if type(rawget(from, k)) ~= "table" or type(v) ~= "table" or isFrame(v) then
-				if saveFields then
-					saveFields[k] = v
-				end
-				to[k] = nil
-			elseif v ~= _G then
-				if saveFields then
-					saveFields[k] = copyTable(v)
-				end
-			end
-		end
-		for k in pairs(from) do
-			if rawget(to, k) and to[k] ~= from[k] and AceLibrary.positions[to[k]] == major and from[k] ~= _G then
-				if not list2[to[k]] then
-					deepTransfer(to[k], from[k], nil, major, list, list2)
-				end
-				to[k] = list[to[k]] or list2[to[k]]
-			else
-				rawset(to, k, from[k])
-			end
-		end
-		setmetatable(to, getmetatable(from))
-		local mt = getmetatable(to)
-		if mt then
-			if list[mt] then
-				setmetatable(to, list[mt])
-			elseif mt.__index and list[mt.__index] then
-				mt.__index = list[mt.__index]
-			end
-		end
-		destroyTable(from)
-	end
-end
-
-local function TryToEnable(addon)
-	if DONT_ENABLE_LIBRARIES then return end
-	local isondemand = IsAddOnLoadOnDemand(addon)
-	if isondemand then
-		local _, _, _, enabled = GetAddOnInfo(addon)
-		EnableAddOn(addon)
-		local _, _, _, _, loadable = GetAddOnInfo(addon)
-		if not loadable and not enabled then
-			DisableAddOn(addon)
-		end
-
-		return loadable
-	end
-end
-
--- @method      TryToLoadStandalone
--- @brief       Attempt to find and load a standalone version of the requested library
--- @param major A string representing the major version
--- @return      If library is found and loaded, true is return. If not loadable, false is returned.
---              If the library has been requested previously, nil is returned.
-local function TryToLoadStandalone(major)
-	if not AceLibrary.scannedlibs then AceLibrary.scannedlibs = {} end
-	if AceLibrary.scannedlibs[major] then return end
-
-	AceLibrary.scannedlibs[major] = true
-
-	local name, _, _, enabled, loadable = GetAddOnInfo(major)
-
-	loadable = (enabled and loadable) or TryToEnable(name)
-
-	local loaded = false
-	if loadable then
-		loaded = true
-		LoadAddOn(name)
-	end
-
-	local field = "X-AceLibrary-" .. major
-	for i = 1, GetNumAddOns() do
-		if GetAddOnMetadata(i, field) then
-			name, _, _, enabled, loadable = GetAddOnInfo(i)
-
-			loadable = (enabled and loadable) or TryToEnable(name)
-			if loadable then
-				loaded = true
-				LoadAddOn(name)
-			end
-		end
-	end
-	return loaded
-end
-
--- @method      IsNewVersion
--- @brief       Obtain whether the supplied version would be an upgrade to the
---              current version. This allows for bypass code in library
---              declaration.
--- @param major A string representing the major version
--- @param minor An integer or an svn revision string representing the minor version
--- @return      whether the supplied version would be newer than what is
---              currently available.
-function AceLibrary:IsNewVersion(major, minor)
-	argCheck(self, major, 2, "string")
-	TryToLoadStandalone(major)
-
-	if type(minor) == "string" then
-		local m = svnRevisionToNumber(minor)
-		if m then
-			minor = m
-		else
-			_G.error(("Bad argument #3 to  `IsNewVersion'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
-		end
-	end
-	argCheck(self, minor, 3, "number")
-	local lib, oldMinor = LibStub:GetLibrary(major, true)
-	if lib then
-		return oldMinor < minor
-	end
-	local data = self.libs[major]
-	if not data then
-		return true
-	end
-	return data.minor < minor
-end
-
--- @method      HasInstance
--- @brief       Returns whether an instance exists. This allows for optional support of a library.
--- @param major A string representing the major version.
--- @param minor (optional) An integer or an svn revision string representing the minor version.
--- @return      Whether an instance exists.
-function AceLibrary:HasInstance(major, minor)
-	argCheck(self, major, 2, "string")
-	if minor ~= false then
-		TryToLoadStandalone(major)
-	end
-
-	local lib, ver = LibStub:GetLibrary(major, true)
-	if not lib and self.libs[major] then
-		lib, ver = self.libs[major].instance, self.libs[major].minor
-	end
-	if minor then
-		if type(minor) == "string" then
-			local m = svnRevisionToNumber(minor)
-			if m then
-				minor = m
-			else
-				_G.error(("Bad argument #3 to  `HasInstance'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
-			end
-		end
-		argCheck(self, minor, 3, "number")
-		if not lib then
-			return false
-		end
-		return ver == minor
-	end
-	return not not lib
-end
-
--- @method      GetInstance
--- @brief       Returns the library with the given major/minor version.
--- @param major A string representing the major version.
--- @param minor (optional) An integer or an svn revision string representing the minor version.
--- @return      The library with the given major/minor version.
-function AceLibrary:GetInstance(major, minor)
-	argCheck(self, major, 2, "string")
-	if minor ~= false then
-		TryToLoadStandalone(major)
-	end
-
-	local data, ver = LibStub:GetLibrary(major, true)
-	if not data then
-		if self.libs[major] then
-			data, ver = self.libs[major].instance, self.libs[major].minor
-		else
-			_G.error(("Cannot find a library instance of %s."):format(major), 2)
-			return
-		end
-	end
-	if minor then
-		if type(minor) == "string" then
-			local m = svnRevisionToNumber(minor)
-			if m then
-				minor = m
-			else
-				_G.error(("Bad argument #3 to  `GetInstance'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
-			end
-		end
-		argCheck(self, minor, 2, "number")
-		if ver ~= minor then
-			_G.error(("Cannot find a library instance of %s, minor version %d."):format(major, minor), 2)
-		end
-	end
-	return data
-end
-
--- Syntax sugar.  AceLibrary("FooBar-1.0")
-AceLibrary_mt.__call = AceLibrary.GetInstance
-
-local donothing = function() end
-
-local AceEvent
-
-local tmp = {}
-
--- @method               Register
--- @brief                Registers a new version of a given library.
--- @param newInstance    the library to register
--- @param major          the major version of the library
--- @param minor          the minor version of the library
--- @param activateFunc   (optional) A function to be called when the library is
---                       fully activated. Takes the arguments
---                       (newInstance [, oldInstance, oldDeactivateFunc]). If
---                       oldInstance is given, you should probably call
---                       oldDeactivateFunc(oldInstance).
--- @param deactivateFunc (optional) A function to be called by a newer library's
---                       activateFunc.
--- @param externalFunc   (optional) A function to be called whenever a new
---                       library is registered.
-function AceLibrary:Register(newInstance, major, minor, activateFunc, deactivateFunc, externalFunc)
-	argCheck(self, newInstance, 2, "table")
-	argCheck(self, major, 3, "string")
-	if major ~= ACELIBRARY_MAJOR then
-		for k,v in pairs(_G) do
-			if v == newInstance then
-				geterrorhandler()((debugstack():match("(.-: )in.-\n") or "") .. ("Cannot register library %q. It is part of the global table in _G[%q]."):format(major, k))
-			end
-		end
-	end
-	if major ~= ACELIBRARY_MAJOR and not major:find("^[%a%-][%a%d%-]*%-%d+%.%d+$") then
-		_G.error(string.format("Bad argument #3 to `Register'. Must be in the form of \"Name-1.0\". %q is not appropriate", major), 2)
-	end
-	if type(minor) == "string" then
-		local m = svnRevisionToNumber(minor)
-		if m then
-			minor = m
-		else
-			_G.error(("Bad argument #4 to `Register'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
-		end
-	end
-	argCheck(self, minor, 4, "number")
-	if math.floor(minor) ~= minor or minor < 0 then
-		error(self, "Bad argument #4 to `Register' (integer >= 0 expected, got %s)", minor)
-	end
-	argCheck(self, activateFunc, 5, "function", "nil")
-	argCheck(self, deactivateFunc, 6, "function", "nil")
-	argCheck(self, externalFunc, 7, "function", "nil")
-	if not deactivateFunc then
-		deactivateFunc = donothing
-	end
-	local data = self.libs[major]
-	if not data then
-		-- This is new
-		if LibStub:GetLibrary(major, true) then
-			error(self, "Cannot register library %q. It is already registered with LibStub.", major)
-		end
-		local instance = LibStub:NewLibrary(major, minor)
-		copyTable(newInstance, instance)
-		crawlReplace(instance, instance, newInstance)
-		destroyTable(newInstance)
-		if AceLibrary == newInstance then
-			self = instance
-			AceLibrary = instance
-		end
-		self.libs[major] = {
-			instance = instance,
-			minor = minor,
-			deactivateFunc = deactivateFunc,
-			externalFunc = externalFunc,
-		}
-		rawset(instance, 'GetLibraryVersion', function(self)
-			return major, minor
-		end)
-		if not rawget(instance, 'error') then
-			rawset(instance, 'error', error)
-		end
-		if not rawget(instance, 'argCheck') then
-			rawset(instance, 'argCheck', argCheck)
-		end
-		if not rawget(instance, 'pcall') then
-			rawset(instance, 'pcall', pcall)
-		end
-		addToPositions(instance, major)
-		if activateFunc then
-			safecall(activateFunc, instance, nil, nil) -- no old version, so explicit nil
-		end
-
-		if externalFunc then
-			for k, data_instance in LibStub:IterateLibraries() do -- all libraries
-				tmp[k] = data_instance
-			end
-			for k, data in pairs(self.libs) do -- Ace libraries which may not have been registered with LibStub
-				tmp[k] = data.instance
-			end
-			for k, data_instance in pairs(tmp) do
-				if k ~= major then
-					safecall(externalFunc, instance, k, data_instance)
-				end
-				tmp[k] = nil
-			end
-		end
-
-		for k,data in pairs(self.libs) do -- only Ace libraries
-			if k ~= major and data.externalFunc then
-				safecall(data.externalFunc, data.instance, major, instance)
-			end
-		end
-		if major == "AceEvent-2.0" then
-			AceEvent = instance
-		end
-		if AceEvent then
-			AceEvent.TriggerEvent(self, "AceLibrary_Register", major, instance)
-		end
-
-		return instance
-	end
-	if minor <= data.minor then
-		-- This one is already obsolete, raise an error.
-		_G.error(("Obsolete library registered. %s is already registered at version %d. You are trying to register version %d. Hint: if not AceLibrary:IsNewVersion(%q, %d) then return end"):format(major, data.minor, minor, major, minor), 2)
-		return
-	end
-	local instance = data.instance
-	-- This is an update
-	local oldInstance = {}
-
-	local libStubInstance = LibStub:GetLibrary(major, true)
-	if not libStubInstance then -- non-LibStub AceLibrary registered the library
-		-- pass
-	elseif libStubInstance ~= instance then
-		error(self, "Cannot register library %q. It is already registered with LibStub.", major)
-	else
-		LibStub:NewLibrary(major, minor) -- upgrade the minor version
-	end
-
-	addToPositions(newInstance, major)
-	local isAceLibrary = (AceLibrary == newInstance)
-	local old_error, old_argCheck, old_pcall
-	if isAceLibrary then
-		self = instance
-		AceLibrary = instance
-
-		old_error = instance.error
-		old_argCheck = instance.argCheck
-		old_pcall = instance.pcall
-
-		self.error = error
-		self.argCheck = argCheck
-		self.pcall = pcall
-	end
-	deepTransfer(instance, newInstance, oldInstance, major)
-	crawlReplace(instance, instance, newInstance)
-	local oldDeactivateFunc = data.deactivateFunc
-	data.minor = minor
-	data.deactivateFunc = deactivateFunc
-	data.externalFunc = externalFunc
-	rawset(instance, 'GetLibraryVersion', function()
-		return major, minor
-	end)
-	if not rawget(instance, 'error') then
-		rawset(instance, 'error', error)
-	end
-	if not rawget(instance, 'argCheck') then
-		rawset(instance, 'argCheck', argCheck)
-	end
-	if not rawget(instance, 'pcall') then
-		rawset(instance, 'pcall', pcall)
-	end
-	if isAceLibrary then
-		for _,v in pairs(self.libs) do
-			local i = type(v) == "table" and v.instance
-			if type(i) == "table" then
-				if not rawget(i, 'error') or i.error == old_error then
-					rawset(i, 'error', error)
-				end
-				if not rawget(i, 'argCheck') or i.argCheck == old_argCheck then
-					rawset(i, 'argCheck', argCheck)
-				end
-				if not rawget(i, 'pcall') or i.pcall == old_pcall then
-					rawset(i, 'pcall', pcall)
-				end
-			end
-		end
-	end
-	if activateFunc then
-		safecall(activateFunc, instance, oldInstance, oldDeactivateFunc)
-	else
-		safecall(oldDeactivateFunc, oldInstance)
-	end
-	oldInstance = nil
-
-	if externalFunc then
-		for k, data_instance in LibStub:IterateLibraries() do -- all libraries
-			tmp[k] = data_instance
-		end
-		for k, data in pairs(self.libs) do -- Ace libraries which may not have been registered with LibStub
-			tmp[k] = data.instance
-		end
-		for k, data_instance in pairs(tmp) do
-			if k ~= major then
-				safecall(externalFunc, instance, k, data_instance)
-			end
-			tmp[k] = nil
-		end
-	end
-
-	return instance
-end
-
-function AceLibrary:IterateLibraries()
-	local t = {}
-	for major, instance in LibStub:IterateLibraries() do
-		t[major] = instance
-	end
-	for major, data in pairs(self.libs) do
-		t[major] = data.instance
-	end
-	return pairs(t)
-end
-
-local function manuallyFinalize(major, instance)
-	if AceLibrary.libs[major] then
-		-- don't work on Ace libraries
-		return
-	end
-	local finalizedExternalLibs = AceLibrary.finalizedExternalLibs
-	if finalizedExternalLibs[major] then
-		return
-	end
-	finalizedExternalLibs[major] = true
-
-	for k,data in pairs(AceLibrary.libs) do -- only Ace libraries
-		if k ~= major and data.externalFunc then
-			safecall(data.externalFunc, data.instance, major, instance)
-		end
-	end
-end
-
--- @function            Activate
--- @brief               The activateFunc for AceLibrary itself. Called when
---                      AceLibrary properly registers.
--- @param self          Reference to AceLibrary
--- @param oldLib        (optional) Reference to an old version of AceLibrary
--- @param oldDeactivate (optional) Function to deactivate the old lib
-local function activate(self, oldLib, oldDeactivate)
-	AceLibrary = self
-	if not self.libs then
-		self.libs = oldLib and oldLib.libs or {}
-		self.scannedlibs = oldLib and oldLib.scannedlibs or {}
-	end
-	if not self.positions then
-		self.positions = oldLib and oldLib.positions or setmetatable({}, { __mode = "k" })
-	end
-	self.finalizedExternalLibs = oldLib and oldLib.finalizedExternalLibs or {}
-	self.frame = oldLib and oldLib.frame or CreateFrame("Frame")
-	self.frame:UnregisterAllEvents()
-	self.frame:RegisterEvent("ADDON_LOADED")
-	self.frame:SetScript("OnEvent", function()
-		for major, instance in LibStub:IterateLibraries() do
-			manuallyFinalize(major, instance)
-		end
-	end)
-	for major, instance in LibStub:IterateLibraries() do
-		manuallyFinalize(major, instance)
-	end
-
-	-- Expose the library in the global environment
-	_G[ACELIBRARY_MAJOR] = self
-
-	if oldDeactivate then
-		oldDeactivate(oldLib)
-	end
-end
-
-if not previous then
-	previous = AceLibrary
-end
-if not previous.libs then
-	previous.libs = {}
-end
-AceLibrary.libs = previous.libs
-if not previous.positions then
-	previous.positions = setmetatable({}, { __mode = "k" })
-end
-AceLibrary.positions = previous.positions
-AceLibrary:Register(AceLibrary, ACELIBRARY_MAJOR, ACELIBRARY_MINOR, activate, nil)
+--[[
+Name: AceLibrary
+Revision: $Rev: 1091 $
+Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
+Inspired By: Iriel (iriel@vigilance-committee.org)
+             Tekkub (tekkub@gmail.com)
+             Revision: $Rev: 1091 $
+Website: http://www.wowace.com/
+Documentation: http://www.wowace.com/index.php/AceLibrary
+SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceLibrary
+Description: Versioning library to handle other library instances, upgrading,
+             and proper access.
+             It also provides a base for libraries to work off of, providing
+             proper error tools. It is handy because all the errors occur in the
+             file that called it, not in the library file itself.
+Dependencies: None
+License: LGPL v2.1
+]]
+
+local ACELIBRARY_MAJOR = "AceLibrary"
+local ACELIBRARY_MINOR = 90000 + tonumber(("$Revision: 1091 $"):match("(%d+)"))
+
+local _G = getfenv(0)
+local previous = _G[ACELIBRARY_MAJOR]
+if previous and not previous:IsNewVersion(ACELIBRARY_MAJOR, ACELIBRARY_MINOR) then return end
+
+do
+	-- LibStub is a simple versioning stub meant for use in Libraries.  http://www.wowace.com/wiki/LibStub for more info
+	-- LibStub is hereby placed in the Public Domain -- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
+	local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2  -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
+	local LibStub = _G[LIBSTUB_MAJOR]
+
+	if not LibStub or LibStub.minor < LIBSTUB_MINOR then
+		LibStub = LibStub or {libs = {}, minors = {} }
+		_G[LIBSTUB_MAJOR] = LibStub
+		LibStub.minor = LIBSTUB_MINOR
+
+		function LibStub:NewLibrary(major, minor)
+			assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
+			minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
+			local oldminor = self.minors[major]
+			if oldminor and oldminor >= minor then return nil end
+			self.minors[major], self.libs[major] = minor, self.libs[major] or {}
+			return self.libs[major], oldminor
+		end
+
+		function LibStub:GetLibrary(major, silent)
+			if not self.libs[major] and not silent then
+				error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
+			end
+			return self.libs[major], self.minors[major]
+		end
+
+		function LibStub:IterateLibraries() return pairs(self.libs) end
+		setmetatable(LibStub, { __call = LibStub.GetLibrary })
+	end
+end
+local LibStub = _G.LibStub
+
+-- If you don't want AceLibrary to enable libraries that are LoadOnDemand but
+-- disabled in the addon screen, set this to true.
+local DONT_ENABLE_LIBRARIES = nil
+
+local function safecall(func,...)
+    local success, err = pcall(func,...)
+    if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("\n(.-: )in.-\n") or "") .. err) end
+end
+
+-- @table AceLibrary
+-- @brief System to handle all versioning of libraries.
+local AceLibrary = {}
+local AceLibrary_mt = {}
+setmetatable(AceLibrary, AceLibrary_mt)
+
+local function error(self, message, ...)
+	if type(self) ~= "table" then
+		return _G.error(("Bad argument #1 to `error' (table expected, got %s)"):format(type(self)), 2)
+	end
+
+	local stack = debugstack()
+	if not message then
+		local second = stack:match("\n(.-)\n")
+		message = "error raised! " .. second
+	else
+		local arg = { ... } -- not worried about table creation, as errors don't happen often
+
+		for i = 1, #arg do
+			arg[i] = tostring(arg[i])
+		end
+		for i = 1, 10 do
+			table.insert(arg, "nil")
+		end
+		message = message:format(unpack(arg))
+	end
+
+	if getmetatable(self) and getmetatable(self).__tostring then
+		message = ("%s: %s"):format(tostring(self), message)
+	elseif type(rawget(self, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self:GetLibraryVersion()) then
+		message = ("%s: %s"):format(self:GetLibraryVersion(), message)
+	elseif type(rawget(self, 'class')) == "table" and type(rawget(self.class, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self.class:GetLibraryVersion()) then
+		message = ("%s: %s"):format(self.class:GetLibraryVersion(), message)
+	end
+
+	local first = stack:gsub("\n.*", "")
+	local file = first:gsub(".*\\(.*).lua:%d+: .*", "%1")
+	file = file:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
+
+
+	local i = 0
+	for s in stack:gmatch("\n([^\n]*)") do
+		i = i + 1
+		if not s:find(file .. "%.lua:%d+:") and not s:find("%(tail call%)") then
+			file = s:gsub("^.*\\(.*).lua:%d+: .*", "%1")
+			file = file:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
+			break
+		end
+	end
+	local j = 0
+	for s in stack:gmatch("\n([^\n]*)") do
+		j = j + 1
+		if j > i and not s:find(file .. "%.lua:%d+:") and not s:find("%(tail call%)") then
+			return _G.error(message, j+1)
+		end
+	end
+	return _G.error(message, 2)
+end
+
+local type = type
+local function argCheck(self, arg, num, kind, kind2, kind3, kind4, kind5)
+	if type(num) ~= "number" then
+		return error(self, "Bad argument #3 to `argCheck' (number expected, got %s)", type(num))
+	elseif type(kind) ~= "string" then
+		return error(self, "Bad argument #4 to `argCheck' (string expected, got %s)", type(kind))
+	end
+	arg = type(arg)
+	if arg ~= kind and arg ~= kind2 and arg ~= kind3 and arg ~= kind4 and arg ~= kind5 then
+		local stack = debugstack()
+		local func = stack:match("`argCheck'.-([`<].-['>])")
+		if not func then
+			func = stack:match("([`<].-['>])")
+		end
+		if kind5 then
+			return error(self, "Bad argument #%s to %s (%s, %s, %s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, kind4, kind5, arg)
+		elseif kind4 then
+			return error(self, "Bad argument #%s to %s (%s, %s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, kind4, arg)
+		elseif kind3 then
+			return error(self, "Bad argument #%s to %s (%s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, arg)
+		elseif kind2 then
+			return error(self, "Bad argument #%s to %s (%s or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, arg)
+		else
+			return error(self, "Bad argument #%s to %s (%s expected, got %s)", tonumber(num) or 0/0, func, kind, arg)
+		end
+	end
+end
+
+local pcall
+do
+	local function check(self, ret, ...)
+		if not ret then
+			local s = ...
+			return error(self, (s:gsub(".-%.lua:%d-: ", "")))
+		else
+			return ...
+		end
+	end
+
+	function pcall(self, func, ...)
+		return check(self, _G.pcall(func, ...))
+	end
+end
+
+local recurse = {}
+local function addToPositions(t, major)
+	if not AceLibrary.positions[t] or AceLibrary.positions[t] == major then
+		rawset(t, recurse, true)
+		AceLibrary.positions[t] = major
+		for k,v in pairs(t) do
+			if type(v) == "table" and not rawget(v, recurse) then
+				addToPositions(v, major)
+			end
+			if type(k) == "table" and not rawget(k, recurse) then
+				addToPositions(k, major)
+			end
+		end
+		local mt = getmetatable(t)
+		if mt and not rawget(mt, recurse) then
+			addToPositions(mt, major)
+		end
+		rawset(t, recurse, nil)
+	end
+end
+
+local function svnRevisionToNumber(text)
+	local kind = type(text)
+	if kind == "number" or tonumber(text) then
+		return tonumber(text)
+	elseif kind == "string" then
+		if text:find("^%$Revision: (%d+) %$$") then
+			return tonumber((text:match("^%$Revision: (%d+) %$$")))
+		elseif text:find("^%$Rev: (%d+) %$$") then
+			return tonumber((text:match("^%$Rev: (%d+) %$$")))
+		elseif text:find("^%$LastChangedRevision: (%d+) %$$") then
+			return tonumber((text:match("^%$LastChangedRevision: (%d+) %$$")))
+		end
+	end
+	return nil
+end
+
+local crawlReplace
+do
+	local recurse = {}
+	local function func(t, to, from)
+		if recurse[t] then
+			return
+		end
+		recurse[t] = true
+		local mt = getmetatable(t)
+		setmetatable(t, nil)
+		rawset(t, to, rawget(t, from))
+		rawset(t, from, nil)
+		for k,v in pairs(t) do
+			if v == from then
+				t[k] = to
+			elseif type(v) == "table" then
+				if not recurse[v] then
+					func(v, to, from)
+				end
+			end
+
+			if type(k) == "table" then
+				if not recurse[k] then
+					func(k, to, from)
+				end
+			end
+		end
+		setmetatable(t, mt)
+		if mt then
+			if mt == from then
+				setmetatable(t, to)
+			elseif not recurse[mt] then
+				func(mt, to, from)
+			end
+		end
+	end
+	function crawlReplace(t, to, from)
+		func(t, to, from)
+		for k in pairs(recurse) do
+			recurse[k] = nil
+		end
+	end
+end
+
+-- @function destroyTable
+-- @brief    remove all the contents of a table
+-- @param t  table to destroy
+local function destroyTable(t)
+	setmetatable(t, nil)
+	for k,v in pairs(t) do
+		t[k] = nil
+	end
+end
+
+local function isFrame(frame)
+	return type(frame) == "table" and type(rawget(frame, 0)) == "userdata" and type(rawget(frame, 'IsFrameType')) == "function" and getmetatable(frame) and type(rawget(getmetatable(frame), '__index')) == "function"
+end
+
+-- @function   copyTable
+-- @brief      Create a shallow copy of a table and return it.
+-- @param from The table to copy from
+-- @return     A shallow copy of the table
+local function copyTable(from, to)
+	if not to then
+		to = {}
+	end
+	for k,v in pairs(from) do
+		to[k] = v
+	end
+	setmetatable(to, getmetatable(from))
+	return to
+end
+
+-- @function         deepTransfer
+-- @brief            Fully transfer all data, keeping proper previous table
+--                   backreferences stable.
+-- @param to         The table with which data is to be injected into
+-- @param from       The table whose data will be injected into the first
+-- @param saveFields If available, a shallow copy of the basic data is saved
+--                   in here.
+-- @param list       The account of table references
+-- @param list2      The current status on which tables have been traversed.
+local deepTransfer
+do
+	-- @function   examine
+	-- @brief      Take account of all the table references to be shared
+	--             between the to and from tables.
+	-- @param to   The table with which data is to be injected into
+	-- @param from The table whose data will be injected into the first
+	-- @param list An account of the table references
+	local function examine(to, from, list, major)
+		list[from] = to
+		for k,v in pairs(from) do
+			if rawget(to, k) and type(from[k]) == "table" and type(to[k]) == "table" and not list[from[k]] then
+				if from[k] == to[k] then
+					list[from[k]] = to[k]
+				elseif AceLibrary.positions[from[v]] ~= major and AceLibrary.positions[from[v]] then
+					list[from[k]] = from[k]
+				elseif not list[from[k]] then
+					examine(to[k], from[k], list, major)
+				end
+			end
+		end
+		return list
+	end
+
+	function deepTransfer(to, from, saveFields, major, list, list2)
+		setmetatable(to, nil)
+		if not list then
+			list = {}
+			list2 = {}
+			examine(to, from, list, major)
+		end
+		list2[to] = to
+		for k,v in pairs(to) do
+			if type(rawget(from, k)) ~= "table" or type(v) ~= "table" or isFrame(v) then
+				if saveFields then
+					saveFields[k] = v
+				end
+				to[k] = nil
+			elseif v ~= _G then
+				if saveFields then
+					saveFields[k] = copyTable(v)
+				end
+			end
+		end
+		for k in pairs(from) do
+			if rawget(to, k) and to[k] ~= from[k] and AceLibrary.positions[to[k]] == major and from[k] ~= _G then
+				if not list2[to[k]] then
+					deepTransfer(to[k], from[k], nil, major, list, list2)
+				end
+				to[k] = list[to[k]] or list2[to[k]]
+			else
+				rawset(to, k, from[k])
+			end
+		end
+		setmetatable(to, getmetatable(from))
+		local mt = getmetatable(to)
+		if mt then
+			if list[mt] then
+				setmetatable(to, list[mt])
+			elseif mt.__index and list[mt.__index] then
+				mt.__index = list[mt.__index]
+			end
+		end
+		destroyTable(from)
+	end
+end
+
+local function TryToEnable(addon)
+	if DONT_ENABLE_LIBRARIES then return end
+	local isondemand = IsAddOnLoadOnDemand(addon)
+	if isondemand then
+		local _, _, _, enabled = GetAddOnInfo(addon)
+		EnableAddOn(addon)
+		local _, _, _, _, loadable = GetAddOnInfo(addon)
+		if not loadable and not enabled then
+			DisableAddOn(addon)
+		end
+
+		return loadable
+	end
+end
+
+-- @method      TryToLoadStandalone
+-- @brief       Attempt to find and load a standalone version of the requested library
+-- @param major A string representing the major version
+-- @return      If library is found and loaded, true is return. If not loadable, false is returned.
+--              If the library has been requested previously, nil is returned.
+local function TryToLoadStandalone(major)
+	if not AceLibrary.scannedlibs then AceLibrary.scannedlibs = {} end
+	if AceLibrary.scannedlibs[major] then return end
+
+	AceLibrary.scannedlibs[major] = true
+
+	local name, _, _, enabled, loadable = GetAddOnInfo(major)
+
+	loadable = (enabled and loadable) or TryToEnable(name)
+
+	local loaded = false
+	if loadable then
+		loaded = true
+		LoadAddOn(name)
+	end
+
+	local field = "X-AceLibrary-" .. major
+	for i = 1, GetNumAddOns() do
+		if GetAddOnMetadata(i, field) then
+			name, _, _, enabled, loadable = GetAddOnInfo(i)
+
+			loadable = (enabled and loadable) or TryToEnable(name)
+			if loadable then
+				loaded = true
+				LoadAddOn(name)
+			end
+		end
+	end
+	return loaded
+end
+
+-- @method      IsNewVersion
+-- @brief       Obtain whether the supplied version would be an upgrade to the
+--              current version. This allows for bypass code in library
+--              declaration.
+-- @param major A string representing the major version
+-- @param minor An integer or an svn revision string representing the minor version
+-- @return      whether the supplied version would be newer than what is
+--              currently available.
+function AceLibrary:IsNewVersion(major, minor)
+	argCheck(self, major, 2, "string")
+	TryToLoadStandalone(major)
+
+	if type(minor) == "string" then
+		local m = svnRevisionToNumber(minor)
+		if m then
+			minor = m
+		else
+			_G.error(("Bad argument #3 to  `IsNewVersion'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
+		end
+	end
+	argCheck(self, minor, 3, "number")
+	local lib, oldMinor = LibStub:GetLibrary(major, true)
+	if lib then
+		return oldMinor < minor
+	end
+	local data = self.libs[major]
+	if not data then
+		return true
+	end
+	return data.minor < minor
+end
+
+-- @method      HasInstance
+-- @brief       Returns whether an instance exists. This allows for optional support of a library.
+-- @param major A string representing the major version.
+-- @param minor (optional) An integer or an svn revision string representing the minor version.
+-- @return      Whether an instance exists.
+function AceLibrary:HasInstance(major, minor)
+	argCheck(self, major, 2, "string")
+	if minor ~= false then
+		TryToLoadStandalone(major)
+	end
+
+	local lib, ver = LibStub:GetLibrary(major, true)
+	if not lib and self.libs[major] then
+		lib, ver = self.libs[major].instance, self.libs[major].minor
+	end
+	if minor then
+		if type(minor) == "string" then
+			local m = svnRevisionToNumber(minor)
+			if m then
+				minor = m
+			else
+				_G.error(("Bad argument #3 to  `HasInstance'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
+			end
+		end
+		argCheck(self, minor, 3, "number")
+		if not lib then
+			return false
+		end
+		return ver == minor
+	end
+	return not not lib
+end
+
+-- @method      GetInstance
+-- @brief       Returns the library with the given major/minor version.
+-- @param major A string representing the major version.
+-- @param minor (optional) An integer or an svn revision string representing the minor version.
+-- @return      The library with the given major/minor version.
+function AceLibrary:GetInstance(major, minor)
+	argCheck(self, major, 2, "string")
+	if minor ~= false then
+		TryToLoadStandalone(major)
+	end
+
+	local data, ver = LibStub:GetLibrary(major, true)
+	if not data then
+		if self.libs[major] then
+			data, ver = self.libs[major].instance, self.libs[major].minor
+		else
+			_G.error(("Cannot find a library instance of %s."):format(major), 2)
+			return
+		end
+	end
+	if minor then
+		if type(minor) == "string" then
+			local m = svnRevisionToNumber(minor)
+			if m then
+				minor = m
+			else
+				_G.error(("Bad argument #3 to  `GetInstance'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
+			end
+		end
+		argCheck(self, minor, 2, "number")
+		if ver ~= minor then
+			_G.error(("Cannot find a library instance of %s, minor version %d."):format(major, minor), 2)
+		end
+	end
+	return data
+end
+
+-- Syntax sugar.  AceLibrary("FooBar-1.0")
+AceLibrary_mt.__call = AceLibrary.GetInstance
+
+local donothing = function() end
+
+local AceEvent
+
+local tmp = {}
+
+-- @method               Register
+-- @brief                Registers a new version of a given library.
+-- @param newInstance    the library to register
+-- @param major          the major version of the library
+-- @param minor          the minor version of the library
+-- @param activateFunc   (optional) A function to be called when the library is
+--                       fully activated. Takes the arguments
+--                       (newInstance [, oldInstance, oldDeactivateFunc]). If
+--                       oldInstance is given, you should probably call
+--                       oldDeactivateFunc(oldInstance).
+-- @param deactivateFunc (optional) A function to be called by a newer library's
+--                       activateFunc.
+-- @param externalFunc   (optional) A function to be called whenever a new
+--                       library is registered.
+function AceLibrary:Register(newInstance, major, minor, activateFunc, deactivateFunc, externalFunc)
+	argCheck(self, newInstance, 2, "table")
+	argCheck(self, major, 3, "string")
+	if major ~= ACELIBRARY_MAJOR then
+		for k,v in pairs(_G) do
+			if v == newInstance then
+				geterrorhandler()((debugstack():match("(.-: )in.-\n") or "") .. ("Cannot register library %q. It is part of the global table in _G[%q]."):format(major, k))
+			end
+		end
+	end
+	if major ~= ACELIBRARY_MAJOR and not major:find("^[%a%-][%a%d%-]*%-%d+%.%d+$") then
+		_G.error(string.format("Bad argument #3 to `Register'. Must be in the form of \"Name-1.0\". %q is not appropriate", major), 2)
+	end
+	if type(minor) == "string" then
+		local m = svnRevisionToNumber(minor)
+		if m then
+			minor = m
+		else
+			_G.error(("Bad argument #4 to `Register'. Must be a number or SVN revision string. %q is not appropriate"):format(minor), 2)
+		end
+	end
+	argCheck(self, minor, 4, "number")
+	if math.floor(minor) ~= minor or minor < 0 then
+		error(self, "Bad argument #4 to `Register' (integer >= 0 expected, got %s)", minor)
+	end
+	argCheck(self, activateFunc, 5, "function", "nil")
+	argCheck(self, deactivateFunc, 6, "function", "nil")
+	argCheck(self, externalFunc, 7, "function", "nil")
+	if not deactivateFunc then
+		deactivateFunc = donothing
+	end
+	local data = self.libs[major]
+	if not data then
+		-- This is new
+		if LibStub:GetLibrary(major, true) then
+			error(self, "Cannot register library %q. It is already registered with LibStub.", major)
+		end
+		local instance = LibStub:NewLibrary(major, minor)
+		copyTable(newInstance, instance)
+		crawlReplace(instance, instance, newInstance)
+		destroyTable(newInstance)
+		if AceLibrary == newInstance then
+			self = instance
+			AceLibrary = instance
+		end
+		self.libs[major] = {
+			instance = instance,
+			minor = minor,
+			deactivateFunc = deactivateFunc,
+			externalFunc = externalFunc,
+		}
+		rawset(instance, 'GetLibraryVersion', function(self)
+			return major, minor
+		end)
+		if not rawget(instance, 'error') then
+			rawset(instance, 'error', error)
+		end
+		if not rawget(instance, 'argCheck') then
+			rawset(instance, 'argCheck', argCheck)
+		end
+		if not rawget(instance, 'pcall') then
+			rawset(instance, 'pcall', pcall)
+		end
+		addToPositions(instance, major)
+		if activateFunc then
+			safecall(activateFunc, instance, nil, nil) -- no old version, so explicit nil
+		end
+
+		if externalFunc then
+			for k, data_instance in LibStub:IterateLibraries() do -- all libraries
+				tmp[k] = data_instance
+			end
+			for k, data in pairs(self.libs) do -- Ace libraries which may not have been registered with LibStub
+				tmp[k] = data.instance
+			end
+			for k, data_instance in pairs(tmp) do
+				if k ~= major then
+					safecall(externalFunc, instance, k, data_instance)
+				end
+				tmp[k] = nil
+			end
+		end
+
+		for k,data in pairs(self.libs) do -- only Ace libraries
+			if k ~= major and data.externalFunc then
+				safecall(data.externalFunc, data.instance, major, instance)
+			end
+		end
+		if major == "AceEvent-2.0" then
+			AceEvent = instance
+		end
+		if AceEvent then
+			AceEvent.TriggerEvent(self, "AceLibrary_Register", major, instance)
+		end
+
+		return instance
+	end
+	if minor <= data.minor then
+		-- This one is already obsolete, raise an error.
+		_G.error(("Obsolete library registered. %s is already registered at version %d. You are trying to register version %d. Hint: if not AceLibrary:IsNewVersion(%q, %d) then return end"):format(major, data.minor, minor, major, minor), 2)
+		return
+	end
+	local instance = data.instance
+	-- This is an update
+	local oldInstance = {}
+
+	local libStubInstance = LibStub:GetLibrary(major, true)
+	if not libStubInstance then -- non-LibStub AceLibrary registered the library
+		-- pass
+	elseif libStubInstance ~= instance then
+		error(self, "Cannot register library %q. It is already registered with LibStub.", major)
+	else
+		LibStub:NewLibrary(major, minor) -- upgrade the minor version
+	end
+
+	addToPositions(newInstance, major)
+	local isAceLibrary = (AceLibrary == newInstance)
+	local old_error, old_argCheck, old_pcall
+	if isAceLibrary then
+		self = instance
+		AceLibrary = instance
+
+		old_error = instance.error
+		old_argCheck = instance.argCheck
+		old_pcall = instance.pcall
+
+		self.error = error
+		self.argCheck = argCheck
+		self.pcall = pcall
+	end
+	deepTransfer(instance, newInstance, oldInstance, major)
+	crawlReplace(instance, instance, newInstance)
+	local oldDeactivateFunc = data.deactivateFunc
+	data.minor = minor
+	data.deactivateFunc = deactivateFunc
+	data.externalFunc = externalFunc
+	rawset(instance, 'GetLibraryVersion', function()
+		return major, minor
+	end)
+	if not rawget(instance, 'error') then
+		rawset(instance, 'error', error)
+	end
+	if not rawget(instance, 'argCheck') then
+		rawset(instance, 'argCheck', argCheck)
+	end
+	if not rawget(instance, 'pcall') then
+		rawset(instance, 'pcall', pcall)
+	end
+	if isAceLibrary then
+		for _,v in pairs(self.libs) do
+			local i = type(v) == "table" and v.instance
+			if type(i) == "table" then
+				if not rawget(i, 'error') or i.error == old_error then
+					rawset(i, 'error', error)
+				end
+				if not rawget(i, 'argCheck') or i.argCheck == old_argCheck then
+					rawset(i, 'argCheck', argCheck)
+				end
+				if not rawget(i, 'pcall') or i.pcall == old_pcall then
+					rawset(i, 'pcall', pcall)
+				end
+			end
+		end
+	end
+	if activateFunc then
+		safecall(activateFunc, instance, oldInstance, oldDeactivateFunc)
+	else
+		safecall(oldDeactivateFunc, oldInstance)
+	end
+	oldInstance = nil
+
+	if externalFunc then
+		for k, data_instance in LibStub:IterateLibraries() do -- all libraries
+			tmp[k] = data_instance
+		end
+		for k, data in pairs(self.libs) do -- Ace libraries which may not have been registered with LibStub
+			tmp[k] = data.instance
+		end
+		for k, data_instance in pairs(tmp) do
+			if k ~= major then
+				safecall(externalFunc, instance, k, data_instance)
+			end
+			tmp[k] = nil
+		end
+	end
+
+	return instance
+end
+
+function AceLibrary:IterateLibraries()
+	local t = {}
+	for major, instance in LibStub:IterateLibraries() do
+		t[major] = instance
+	end
+	for major, data in pairs(self.libs) do
+		t[major] = data.instance
+	end
+	return pairs(t)
+end
+
+local function manuallyFinalize(major, instance)
+	if AceLibrary.libs[major] then
+		-- don't work on Ace libraries
+		return
+	end
+	local finalizedExternalLibs = AceLibrary.finalizedExternalLibs
+	if finalizedExternalLibs[major] then
+		return
+	end
+	finalizedExternalLibs[major] = true
+
+	for k,data in pairs(AceLibrary.libs) do -- only Ace libraries
+		if k ~= major and data.externalFunc then
+			safecall(data.externalFunc, data.instance, major, instance)
+		end
+	end
+end
+
+-- @function            Activate
+-- @brief               The activateFunc for AceLibrary itself. Called when
+--                      AceLibrary properly registers.
+-- @param self          Reference to AceLibrary
+-- @param oldLib        (optional) Reference to an old version of AceLibrary
+-- @param oldDeactivate (optional) Function to deactivate the old lib
+local function activate(self, oldLib, oldDeactivate)
+	AceLibrary = self
+	if not self.libs then
+		self.libs = oldLib and oldLib.libs or {}
+		self.scannedlibs = oldLib and oldLib.scannedlibs or {}
+	end
+	if not self.positions then
+		self.positions = oldLib and oldLib.positions or setmetatable({}, { __mode = "k" })
+	end
+	self.finalizedExternalLibs = oldLib and oldLib.finalizedExternalLibs or {}
+	self.frame = oldLib and oldLib.frame or CreateFrame("Frame")
+	self.frame:UnregisterAllEvents()
+	self.frame:RegisterEvent("ADDON_LOADED")
+	self.frame:SetScript("OnEvent", function()
+		for major, instance in LibStub:IterateLibraries() do
+			manuallyFinalize(major, instance)
+		end
+	end)
+	for major, instance in LibStub:IterateLibraries() do
+		manuallyFinalize(major, instance)
+	end
+
+	-- Expose the library in the global environment
+	_G[ACELIBRARY_MAJOR] = self
+
+	if oldDeactivate then
+		oldDeactivate(oldLib)
+	end
+end
+
+if not previous then
+	previous = AceLibrary
+end
+if not previous.libs then
+	previous.libs = {}
+end
+AceLibrary.libs = previous.libs
+if not previous.positions then
+	previous.positions = setmetatable({}, { __mode = "k" })
+end
+AceLibrary.positions = previous.positions
+AceLibrary:Register(AceLibrary, ACELIBRARY_MAJOR, ACELIBRARY_MINOR, activate, nil)
diff --git a/Libs/AceLibrary/AceLibrary.toc b/Libs/AceLibrary/AceLibrary.toc
index 2b0bf2d..967e00f 100644
--- a/Libs/AceLibrary/AceLibrary.toc
+++ b/Libs/AceLibrary/AceLibrary.toc
@@ -1,14 +1,14 @@
-## Interface: 30000
-## X-Curse-Packaged-Version: r1094
-## X-Curse-Project-Name: Ace2
-## X-Curse-Project-ID: ace2
-## X-Curse-Repository-ID: wow/ace2/mainline
-
-## Title: Lib: AceLibrary
-## Notes: AddOn development framework
-## Author: Ace Development Team
-## X-Website: http://www.wowace.com
-## X-Category: Library
-## X-License: LGPL v2.1 + MIT for AceOO-2.0
-
-AceLibrary.lua
+## Interface: 30000
+## X-Curse-Packaged-Version: r1094
+## X-Curse-Project-Name: Ace2
+## X-Curse-Project-ID: ace2
+## X-Curse-Repository-ID: wow/ace2/mainline
+
+## Title: Lib: AceLibrary
+## Notes: AddOn development framework
+## Author: Ace Development Team
+## X-Website: http://www.wowace.com
+## X-Category: Library
+## X-License: LGPL v2.1 + MIT for AceOO-2.0
+
+AceLibrary.lua
diff --git a/Libs/AceOO-2.0/AceOO-2.0.lua b/Libs/AceOO-2.0/AceOO-2.0.lua
index 4a540f8..7161ee4 100644
--- a/Libs/AceOO-2.0/AceOO-2.0.lua
+++ b/Libs/AceOO-2.0/AceOO-2.0.lua
@@ -1,980 +1,980 @@
---[[
-Name: AceOO-2.0
-Revision: $Rev: 1091 $
-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/AceOO-2.0
-SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceOO-2.0
-Description: Library to provide an object-orientation framework.
-Dependencies: AceLibrary
-License: MIT
-]]
-
-local MAJOR_VERSION = "AceOO-2.0"
-local MINOR_VERSION = 90000 + tonumber(("$Revision: 1091 $"):match("(%d+)"))
-
--- This ensures the code is only executed if the libary doesn't already exist, or is a newer version
-if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
-if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
-
-local AceOO = {
-	error = AceLibrary.error,
-	argCheck = AceLibrary.argCheck
-}
-
--- @function	getuid
--- @brief		Obtain a unique string identifier for the object in question.
--- @param t		The object to obtain the uid for.
--- @return		The uid string.
-local function getuid(t)
-	local mt = getmetatable(t)
-	setmetatable(t, nil)
-	local str = tostring(t)
-	setmetatable(t, mt)
-	local cap = str:match("[^:]*: 0x(.*)$") or str:match("[^:]*: (.*)$")
-	if cap then
-		return ("0"):rep(8 - #cap) .. cap
-	end
-end
-
-local function getlibrary(o)
-	if type(o) == "table" then
-		return o
-	elseif type(o) == "string" then
-		if not AceLibrary:HasInstance(o) then
-			AceOO:error("Library %q does not exist.", o)
-		end
-		return AceLibrary(o)
-	end
-end
-
-local function deeprawget(self, k)
-	while true do
-		local v = rawget(self, k)
-		if v ~= nil then
-			return v
-		end
-		local mt = getmetatable(self)
-		if not mt or type(mt.__index) ~= "table" then
-			return nil
-		end
-		self = mt.__index
-	end
-end
-
--- @function		Factory
--- @brief			Construct a factory for the creation of objects.
--- @param obj		The object whose init method will be called on the new factory
---					object.
--- @param newobj	The object whose init method will be called on the new
---					objects that the Factory creates, to initialize them.
--- @param (...) Arguments which will be passed to obj.init() in addition
---					to the Factory object.
--- @return			The new factory which creates a newobj when its new method is called,
---					or when it is called directly (__call metamethod).
-local Factory
-do
-	local function getlibraries(...)
-		if select('#', ...) == 0 then
-			return
-		end
-		return getlibrary((select(1, ...))), getlibraries(select(2, ...))
-	end
-	local arg = {}
-	local function new(obj, ...)
-		local t = {}
-		local uid = getuid(t)
-		obj:init(t, getlibraries(...))
-		t.uid = uid
-		return t
-	end
-
-	local function createnew(self, ...)
-		local o = self.prototype
-		local x = new(o, getlibraries(...))
-		return x
-	end
-
-	function Factory(obj, newobj, ...)
-		local t = new(obj, ...)
-		t.prototype = newobj
-		t.new = createnew
-		getmetatable(t).__call = t.new
-		return t
-	end
-end
-
-
-local function objtostring(self)
-	if self.ToString then
-		return self:ToString()
-	elseif self.GetLibraryVersion then
-		return (self:GetLibraryVersion())
-	elseif self.super then
-		local s = "Sub-" .. tostring(self.super)
-		local first = true
-		if self.interfaces then
-			for interface in pairs(self.interfaces) do
-				if first then
-					s = s .. "(" .. tostring(interface)
-					first = false
-				else
-					s = s .. ", " .. tostring(interface)
-				end
-			end
-		end
-		if self.mixins then
-			for mixin in pairs(self.mixins) do
-				if first then
-					s = s .. tostring(mixin)
-					first = false
-				else
-					s = s .. ", " .. tostring(mixin)
-				end
-			end
-		end
-		if first then
-			if self.uid then
-				return s .. ":" .. self.uid
-			else
-				return s
-			end
-		else
-			return s .. ")"
-		end
-	else
-		return self.uid and 'Subclass:' .. self.uid or 'Subclass'
-	end
-end
-
--- @table			Object
--- @brief			Base of all objects, including Class.
---
--- @method			init
--- @brief			Initialize a new object.
--- @param newobject The object to initialize
--- @param class		The class to make newobject inherit from
-local Object
-do
-	Object = {}
-	function Object:init(newobject, class)
-		local parent = class or self
-		if not rawget(newobject, 'uid') then
-			newobject.uid = getuid(newobject)
-		end
-		local mt = {
-			__index = parent,
-			__tostring = objtostring,
-		}
-		setmetatable(newobject, mt)
-	end
-	Object.uid = getuid(Object)
-	setmetatable(Object, { __tostring = function() return 'Object' end })
-end
-
-local Interface
-
-local function validateInterface(object, interface)
-	if not object.class and object.prototype then
-		object = object.prototype
-	end
-	for k,v in pairs(interface.interface) do
-		if tostring(type(object[k])) ~= v then
-			return false
-		end
-	end
-	if interface.superinterfaces then
-		for superinterface in pairs(interface.superinterfaces) do
-			if not validateInterface(object, superinterface) then
-				return false
-			end
-		end
-	end
-	if type(object.class) == "table" and rawequal(object.class.prototype, object) then
-		if not object.class.interfaces then
-			rawset(object.class, 'interfaces', {})
-		end
-		object.class.interfaces[interface] = true
-	elseif type(object.class) == "table" and type(object.class.prototype) == "table" then
-		validateInterface(object.class.prototype, interface)
-		-- check if class is proper, thus preventing future checks.
-	end
-	return true
-end
-
--- @function		inherits
--- @brief			Return whether an Object or Class inherits from a given
---					parent.
--- @param object	Object or Class to check
--- @param parent	Parent to test inheritance from
--- @return			whether an Object or Class inherits from a given
---					parent.
-local function inherits(object, parent)
-	object = getlibrary(object)
-	if type(parent) == "string" then
-		if not AceLibrary:HasInstance(parent) then
-			return false
-		else
-			parent = AceLibrary(parent)
-		end
-	end
-	AceOO:argCheck(parent, 2, "table")
-	if type(object) ~= "table" then
-		return false
-	end
-	local current
-	local class = deeprawget(object, 'class')
-	if class then
-		current = class
-	else
-		current = object
-	end
-	if type(current) ~= "table" then
-		return false
-	end
-	if rawequal(current, parent) then
-		return true
-	end
-	if parent.class then
-		while true do
-			if rawequal(current, Object) then
-				break
-			end
-			if current.mixins then
-				for mixin in pairs(current.mixins) do
-					if rawequal(mixin, parent) then
-						return true
-					end
-				end
-			end
-			if current.interfaces then
-				for interface in pairs(current.interfaces) do
-					if rawequal(interface, parent) then
-						return true
-					end
-				end
-			end
-			current = deeprawget(current, 'super')
-			if type(current) ~= "table" then
-				break
-			end
-		end
-
-		local isInterface = false
-		local curr = parent.class
-		while true do
-			if rawequal(curr, Object) then
-				break
-			elseif rawequal(curr, Interface) then
-				isInterface = true
-				break
-			end
-			curr = deeprawget(curr, 'super')
-			if type(curr) ~= "table" then
-				break
-			end
-		end
-		return isInterface and validateInterface(object, parent)
-	else
-		while true do
-			if rawequal(current, parent) then
-				return true
-			elseif rawequal(current, Object) then
-				return false
-			end
-			current = deeprawget(current, 'super')
-			if type(current) ~= "table" then
-				return false
-			end
-		end
-	end
-end
-
--- @table			Class
--- @brief			An object factory which sets up inheritence and supports
---					'mixins'.
---
--- @metamethod		Class call
--- @brief			Call ClassFactory:new() to create a new class.
---
--- @method			Class new
--- @brief			Construct a new object.
--- @param (...) Arguments to pass to the object init function.
--- @return			The new object.
---
--- @method			Class init
--- @brief			Initialize a new class.
--- @param parent	Superclass.
--- @param (...) Mixins.
---
--- @method			Class ToString
--- @return			A string representing the object, in this case 'Class'.
-local initStatus
-local Class
-local Mixin
-local autoEmbed = false
-local function traverseInterfaces(bit, total)
-	if bit.superinterfaces then
-		for interface in pairs(bit.superinterfaces) do
-			if not total[interface] then
-				total[interface] = true
-				traverseInterfaces(interface, total)
-			end
-		end
-	end
-end
-local class_new
-do
-	Class = Factory(Object, setmetatable({}, {__index = Object}), Object)
-	Class.super = Object
-
-	local function protostring(t)
-		return '<' .. tostring(t.class) .. ' prototype>'
-	end
-	local function classobjectstring(t)
-		if t.ToString then
-			return t:ToString()
-		elseif t.GetLibraryVersion then
-			return (t:GetLibraryVersion())
-		else
-			return '<' .. tostring(t.class) .. ' instance>'
-		end
-	end
-	local function classobjectequal(self, other)
-		if type(self) == "table" and self.Equals then
-			return self:Equals(other)
-		elseif type(other) == "table" and other.Equals then
-			return other:Equals(self)
-		elseif type(self) == "table" and self.CompareTo then
-			return self:CompareTo(other) == 0
-		elseif type(other) == "table" and other.CompareTo then
-			return other:CompareTo(self) == 0
-		else
-			return rawequal(self, other)
-		end
-	end
-	local function classobjectlessthan(self, other)
-		if type(self) == "table" and self.IsLessThan then
-			return self:IsLessThan(other)
-		elseif type(other) == "table" and other.IsLessThanOrEqualTo then
-			return not other:IsLessThanOrEqualTo(self)
-		elseif type(self) == "table" and self.CompareTo then
-			return self:CompareTo(other) < 0
-		elseif type(other) == "table" and other.CompareTo then
-			return other:CompareTo(self) > 0
-		elseif type(other) == "table" and other.IsLessThan and other.Equals then
-			return other:Equals(self) or other:IsLessThan(self)
-		else
-			AceOO:error("cannot compare two objects")
-		end
-	end
-	local function classobjectlessthanequal(self, other)
-		if type(self) == "table" and self.IsLessThanOrEqualTo then
-			return self:IsLessThanOrEqualTo(other)
-		elseif type(other) == "table" and other.IsLessThan then
-			return not other:IsLessThan(self)
-		elseif type(self) == "table" and self.CompareTo then
-			return self:CompareTo(other) <= 0
-		elseif type(other) == "table" and other.CompareTo then
-			return other:CompareTo(self) >= 0
-		elseif type(self) == "table" and self.IsLessThan and self.Equals then
-			return self:Equals(other) or self:IsLessThan(other)
-		else
-			AceOO:error("cannot compare two incompatible objects")
-		end
-	end
-	local function classobjectadd(self, other)
-		if type(self) == "table" and self.Add then
-			return self:Add(other)
-		else
-			AceOO:error("cannot add two incompatible objects")
-		end
-	end
-	local function classobjectsub(self, other)
-		if type(self) == "table" and self.Subtract then
-			return self:Subtract(other)
-		else
-			AceOO:error("cannot subtract two incompatible objects")
-		end
-	end
-	local function classobjectunm(self, other)
-		if type(self) == "table" and self.UnaryNegation then
-			return self:UnaryNegation(other)
-		else
-			AceOO:error("attempt to negate an incompatible object")
-		end
-	end
-	local function classobjectmul(self, other)
-		if type(self) == "table" and self.Multiply then
-			return self:Multiply(other)
-		else
-			AceOO:error("cannot multiply two incompatible objects")
-		end
-	end
-	local function classobjectdiv(self, other)
-		if type(self) == "table" and self.Divide then
-			return self:Divide(other)
-		else
-			AceOO:error("cannot divide two incompatible objects")
-		end
-	end
-	local function classobjectpow(self, other)
-		if type(self) == "table" and self.Exponent then
-			return self:Exponent(other)
-		else
-			AceOO:error("cannot exponentiate two incompatible objects")
-		end
-	end
-	local function classobjectconcat(self, other)
-		if type(self) == "table" and self.Concatenate then
-			return self:Concatenate(other)
-		else
-			AceOO:error("cannot concatenate two incompatible objects")
-		end
-	end
-	function class_new(self, ...)
-		if self.virtual then
-			AceOO:error("Cannot instantiate a virtual class.")
-		end
-
-		local o = self.prototype
-		local newobj = {}
-		if o.class and o.class.instancemeta then
-			setmetatable(newobj, o.class.instancemeta)
-		else
-			Object:init(newobj, o)
-		end
-
-		if self.interfaces and not self.interfacesVerified then
-			-- Verify the interfaces
-
-			for interface in pairs(self.interfaces) do
-				for field,kind in pairs(interface.interface) do
-					if tostring(type(newobj[field])) ~= kind then
-						AceOO:error("Class did not satisfy all interfaces. %q is required to be a %s. It is a %s", field, kind, tostring(type(newobj[field])))
-					end
-				end
-			end
-			self.interfacesVerified = true
-		end
-		local tmp = initStatus
-		initStatus = newobj
-		newobj:init(...)
-		if initStatus then
-			initStatus = tmp
-			AceOO:error("Initialization not completed, be sure to call the superclass's init method.")
-			return
-		end
-		initStatus = tmp
-		return newobj
-	end
-	local classmeta = {
-		__tostring = objtostring,
-		__call = function(self, ...)
-			return self:new(...)
-		end,
-	}
-	function Class:init(newclass, parent, ...)
-		parent = parent or self
-
-		local total
-
-		if parent.class then
-			total = { parent, ... }
-			parent = self
-		else
-			total = { ... }
-		end
-		if not inherits(parent, Class) then
-			AceOO:error("Classes must inherit from a proper class")
-		end
-		if parent.sealed then
-			AceOO:error("Cannot inherit from a sealed class")
-		end
-		for i,v in ipairs(total) do
-			if inherits(v, Mixin) and v.class then
-				if v.__deprecated then
-					AceOO:error(v.__deprecated)
-				end
-				if not newclass.mixins then
-					newclass.mixins = {}
-				end
-				if newclass.mixins[v] then
-					AceOO:error("Cannot explicitly inherit from the same mixin twice")
-				end
-				newclass.mixins[v] = true
-			elseif inherits(v, Interface) and v.class then
-				if not newclass.interfaces then
-					newclass.interfaces = {}
-				end
-				if newclass.interfaces[v] then
-					AceOO:error("Cannot explicitly inherit from the same interface twice")
-				end
-				newclass.interfaces[v] = true
-			else
-				AceOO:error("Classes can only inherit from one or zero classes and any number of mixins or interfaces")
-			end
-		end
-		if parent.interfaces then
-			if not newclass.interfaces then
-				newclass.interfaces = {}
-			end
-			for interface in pairs(parent.interfaces) do
-				newclass.interfaces[interface] = true
-			end
-		end
-		for k in pairs(total) do
-			total[k] = nil
-		end
-
-		newclass.super = parent
-
-		newclass.prototype = setmetatable(total, {
-			__index = parent.prototype,
-			__tostring = protostring,
-		})
-		total = nil
-
-		newclass.instancemeta = {
-			__index = newclass.prototype,
-			__tostring = classobjectstring,
-			__eq = classobjectequal,
-			__lt = classobjectlessthan,
-			__le = classobjectlessthanequal,
-			__add = classobjectadd,
-			__sub = classobjectsub,
-			__unm = classobjectunm,
-			__mul = classobjectmul,
-			__div = classobjectdiv,
-			__pow = classobjectpow,
-			__concat = classobjectconcat,
-		}
-
-		setmetatable(newclass, classmeta)
-
-		newclass.new = class_new
-
-		if newclass.mixins then
-			-- Fold in the mixins
-			local err, msg
-			for mixin in pairs(newclass.mixins) do
-				local ret
-				autoEmbed = true
-				ret, msg = pcall(mixin.embed, mixin, newclass.prototype)
-				autoEmbed = false
-				if not ret then
-					err = true
-					break
-				end
-			end
-
-			if err then
-				local pt = newclass.prototype
-				for k,v in pairs(pt) do
-					pt[k] = nil
-				end
-
-				-- method conflict
-				AceOO:error(msg)
-			end
-		end
-
-		newclass.prototype.class = newclass
-
-		if newclass.interfaces then
-			for interface in pairs(newclass.interfaces) do
-				traverseInterfaces(interface, newclass.interfaces)
-			end
-		end
-		if newclass.mixins then
-			for mixin in pairs(newclass.mixins) do
-				if mixin.interfaces then
-					if not newclass.interfaces then
-						newclass.interfaces = {}
-					end
-					for interface in pairs(mixin.interfaces) do
-						newclass.interfaces[interface] = true
-					end
-				end
-			end
-		end
-	end
-	function Class:ToString()
-		if type(self.GetLibraryVersion) == "function" then
-			return (self:GetLibraryVersion())
-		else
-			return "Class"
-		end
-	end
-
-	local tmp
-	function Class.prototype:init()
-		if rawequal(self, initStatus) then
-			initStatus = nil
-		else
-			AceOO:error("Improper self passed to init. You must do MyClass.super.prototype.init(self, ...)", 2)
-		end
-		self.uid = getuid(self)
-		local current = self.class
-		while true do
-			if current == Class then
-				break
-			end
-			if current.mixins then
-				for mixin in pairs(current.mixins) do
-					if type(mixin.OnInstanceInit) == "function" then
-						mixin:OnInstanceInit(self)
-					end
-				end
-			end
-			current = current.super
-		end
-	end
-end
-
-
--- @object	ClassFactory
--- @brief	A factory for creating classes.	Rarely used directly.
-local ClassFactory = Factory(Object, Class, Object)
-
-function Class:new(...)
-	local x = ClassFactory:new(...)
-	if AceOO.classes then
-		AceOO.classes[x] = true
-	end
-	return x
-end
-getmetatable(Class).__call = Class.new
-
--- @class	Mixin
--- @brief	A class to create mixin objects, which contain methods that get
--- "mixed in" to class prototypes.
---
--- @object	Mixin prototype
--- @brief	The prototype that mixin objects inherit their methods from.
---
--- @method	Mixin prototype embed
--- @brief	Mix in the methods of our object which are listed in our interface
---		 to the supplied target table.
---
--- @method	Mixin prototype init
--- @brief	Initialize the mixin object.
--- @param	newobj	 The new object we're initializing.
--- @param	interface	The interface we implement (the list of methods our
---					prototype provides which should be mixed into the target
---					table by embed).
-do
-	Mixin = Class()
-	function Mixin:ToString()
-		if self.GetLibraryVersion then
-			return (self:GetLibraryVersion())
-		else
-			return 'Mixin'
-		end
-	end
-	local function _Embed(state, field, target)
-		field = next(state.export, field)
-		if field == nil then
-			return
-		end
-
-		if rawget(target, field) or (target[field] and target[field] ~= state[field]) then
-			AceOO:error("Method conflict in attempt to mixin. Field %q", field)
-		end
-
-		target[field] = state[field]
-
-		local ret,msg = pcall(_Embed, state, field, target)
-		if not ret then
-			-- Mix in the next method according to the defined interface.	If that
-			-- fails due to a conflict, re-raise to back out the previous mixed
-			-- methods.
-
-			target[field] = nil
-			AceOO:error(msg)
-		end
-	end
-	function Mixin.prototype:embed(target)
-		if self.__deprecated then
-			AceOO:error(self.__deprecated)
-		end
-		local mt = getmetatable(target)
-		setmetatable(target, nil)
-		local err, msg = pcall(_Embed, self, nil, target)
-		if not err then
-			setmetatable(target, mt)
-			AceOO:error(msg)
-			return
-		end
-		if type(self.embedList) == "table" then
-			self.embedList[target] = true
-		end
-		if type(target.class) ~= "table" then
-			target[self] = true
-		end
-		if not autoEmbed and type(self.OnManualEmbed) == "function" then
-			self:OnManualEmbed(target)
-		end
-		setmetatable(target, mt)
-	end
-
-	function Mixin.prototype:activate(oldLib, oldDeactivate)
-		if oldLib and oldLib.embedList then
-			for target in pairs(oldLib.embedList) do
-				local mt = getmetatable(target)
-				setmetatable(target, nil)
-				for field in pairs(oldLib.export) do
-					target[field] = nil
-				end
-				setmetatable(target, mt)
-			end
-			self.embedList = oldLib.embedList
-			for target in pairs(self.embedList) do
-				self:embed(target)
-			end
-		else
-			self.embedList = setmetatable({}, {__mode="k"})
-		end
-	end
-
-	function Mixin.prototype:init(export, ...)
-		AceOO:argCheck(export, 2, "table")
-		for k,v in pairs(export) do
-			if type(k) ~= "number" then
-				AceOO:error("All keys to argument #2 must be numbers.")
-			elseif type(v) ~= "string" then
-				AceOO:error("All values to argument #2 must be strings.")
-			end
-		end
-		local num = #export
-		for i = 1, num do
-			local v = export[i]
-			export[i] = nil
-			export[v] = true
-		end
-
-		local interfaces
-		if select('#', ...) >= 1 then
-			interfaces = { ... }
-			for i,v in ipairs(interfaces) do
-				v = getlibrary(v)
-				interfaces[i] = v
-				if not v.class or not inherits(v, Interface) then
-					AceOO:error("Mixins can inherit only from interfaces")
-				end
-			end
-			local num = #interfaces
-			for i = 1, num do
-				local v = interfaces[i]
-				interfaces[i] = nil
-				interfaces[v] = true
-			end
-			for interface in pairs(interfaces) do
-				traverseInterfaces(interface, interfaces)
-			end
-			for interface in pairs(interfaces) do
-				for field,kind in pairs(interface.interface) do
-					if kind ~= "nil" then
-						local good = false
-						for bit in pairs(export) do
-							if bit == field then
-								good = true
-								break
-							end
-						end
-						if not good then
-							AceOO:error("Mixin does not fully accommodate field %q", field)
-						end
-					end
-				end
-			end
-		end
-		self.super = Mixin.prototype
-		Mixin.super.prototype.init(self)
-		self.export = export
-		self.interfaces = interfaces
-	end
-end
-
--- @class Interface
--- @brief A class to create interfaces, which contain contracts that classes
---			which inherit from this must comply with.
---
--- @object Interface prototype
--- @brief	The prototype that interface objects must adhere to.
---
--- @method Interface prototype init
--- @brief	Initialize the mixin object.
--- @param	interface	The interface we contract (the hash of fields forced).
--- @param	(...)	Superinterfaces
-do
-	Interface = Class()
-	function Interface:ToString()
-		if self.GetLibraryVersion then
-			return (self:GetLibraryVersion())
-		else
-			return 'Instance'
-		end
-	end
-	function Interface.prototype:init(interface, ...)
-		Interface.super.prototype.init(self)
-		AceOO:argCheck(interface, 2, "table")
-		for k,v in pairs(interface) do
-			if type(k) ~= "string" then
-				AceOO:error("All keys to argument #2 must be numbers.")
-			elseif type(v) ~= "string" then
-				AceOO:error("All values to argument #2 must be strings.")
-			elseif v ~= "nil" and v ~= "string" and v ~= "number" and v ~= "table" and v ~= "function" then
-				AceOO:error('All values to argument #2 must either be "nil", "string", "number", "table", or "function".')
-			end
-		end
-		if select('#', ...) >= 1 then
-			self.superinterfaces = { ... }
-			for i,v in ipairs(self.superinterfaces) do
-				v = getlibrary(v)
-				self.superinterfaces[i] = v
-				if not inherits(v, Interface) or not v.class then
-					AceOO:error('Cannot provide a non-Interface to inherit from')
-				end
-			end
-			local num = #self.superinterfaces
-			for i = 1, num do
-				local v = self.superinterfaces[i]
-				self.superinterfaces[i] = nil
-				self.superinterfaces[v] = true
-			end
-		end
-		self.interface = interface
-	end
-end
-
--- @function Classpool
--- @brief	Obtain a read only class from our pool of classes, indexed by the
---		 superclass and mixins.
--- @param	sc		 The superclass of the class we want.
--- @param	(m1..m20)	Mixins of the class we want's objects.
--- @return A read only class from the class pool.
-local Classpool
-do
-	local pool = setmetatable({}, {__mode = 'v'})
-	local function newindex(k, v)
-		AceOO:error('Attempt to modify a read-only class.')
-	end
-	local function protonewindex(k, v)
-		AceOO:error('Attempt to modify a read-only class prototype.')
-	end
-	local function ts(bit)
-		if type(bit) ~= "table" then
-			return tostring(bit)
-		elseif getmetatable(bit) and bit.__tostring then
-			return tostring(bit)
-		elseif type(bit.GetLibraryVersion) == "function" then
-			return bit:GetLibraryVersion()
-		else
-			return tostring(bit)
-		end
-	end
-	local t = {}
-	local function getcomplexuid(sc, ...)
-		if sc then
-			if sc.uid then
-				table.insert(t, sc.uid)
-			else
-				AceOO:error("%s is not an appropriate class/mixin", ts(sc))
-			end
-		end
-		for i = 1, select('#', ...) do
-			local m = select(i, ...)
-			if m.uid then
-				table.insert(t, m.uid)
-			else
-				AceOO:error("%s is not an appropriate mixin", ts(m))
-			end
-		end
-		table.sort(t)
-		local uid = table.concat(t, '')
-		local num = #t
-		for i = 1, num do
-			t[i] = nil
-		end
-		return uid
-	end
-	local classmeta
-	local arg = {}
-	function Classpool(superclass, ...)
-		local l = getlibrary
-		superclass = getlibrary(superclass)
-		arg = { ... }
-		for i, v in ipairs(arg) do
-			arg[i] = getlibrary(v)
-		end
-		if superclass then
-			if superclass.class then -- mixin
-				table.insert(arg, 1, superclass)
-				superclass = Class
-			end
-		else
-			superclass = Class
-		end
-		local key = getcomplexuid(superclass, unpack(arg))
-		if not pool[key] then
-			local class = Class(superclass, unpack(arg))
-			if not classmeta then
-				classmeta = {}
-				local mt = getmetatable(class)
-				for k,v in pairs(mt) do
-					classmeta[k] = v
-				end
-				classmeta.__newindex = newindex
-			end
-			-- Prevent the user from adding methods to this class.
-			-- NOTE: I'm not preventing modifications of existing class members,
-			-- but it's likely that only a truly malicious user will be doing so.
-			class.sealed = true
-			setmetatable(class, classmeta)
-			getmetatable(class.prototype).__newindex = protonewindex
-			pool[key] = class
-		end
-		return pool[key]
-	end
-end
-
-AceOO.Factory = Factory
-AceOO.Object = Object
-AceOO.Class = Class
-AceOO.Mixin = Mixin
-AceOO.Interface = Interface
-AceOO.Classpool = Classpool
-AceOO.inherits = inherits
-
--- Library handling bits
-
-local function activate(self, oldLib, oldDeactivate)
-	AceOO = self
-	Factory = self.Factory
-	Object = self.Object
-	Class = self.Class
-	ClassFactory.prototype = Class
-	Mixin = self.Mixin
-	Interface = self.Interface
-	Classpool = self.Classpool
-
-	if oldLib then
-		self.classes = oldLib.classes
-	end
-	if not self.classes then
-		self.classes = setmetatable({}, {__mode="k"})
-	else
-		for class in pairs(self.classes) do
-			class.new = class_new
-		end
-	end
-
-	if oldDeactivate then
-		oldDeactivate(oldLib)
-	end
-end
-
-AceLibrary:Register(AceOO, MAJOR_VERSION, MINOR_VERSION, activate)
-AceOO = AceLibrary(MAJOR_VERSION)
+--[[
+Name: AceOO-2.0
+Revision: $Rev: 1091 $
+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/AceOO-2.0
+SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceOO-2.0
+Description: Library to provide an object-orientation framework.
+Dependencies: AceLibrary
+License: MIT
+]]
+
+local MAJOR_VERSION = "AceOO-2.0"
+local MINOR_VERSION = 90000 + tonumber(("$Revision: 1091 $"):match("(%d+)"))
+
+-- This ensures the code is only executed if the libary doesn't already exist, or is a newer version
+if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
+if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
+
+local AceOO = {
+	error = AceLibrary.error,
+	argCheck = AceLibrary.argCheck
+}
+
+-- @function	getuid
+-- @brief		Obtain a unique string identifier for the object in question.
+-- @param t		The object to obtain the uid for.
+-- @return		The uid string.
+local function getuid(t)
+	local mt = getmetatable(t)
+	setmetatable(t, nil)
+	local str = tostring(t)
+	setmetatable(t, mt)
+	local cap = str:match("[^:]*: 0x(.*)$") or str:match("[^:]*: (.*)$")
+	if cap then
+		return ("0"):rep(8 - #cap) .. cap
+	end
+end
+
+local function getlibrary(o)
+	if type(o) == "table" then
+		return o
+	elseif type(o) == "string" then
+		if not AceLibrary:HasInstance(o) then
+			AceOO:error("Library %q does not exist.", o)
+		end
+		return AceLibrary(o)
+	end
+end
+
+local function deeprawget(self, k)
+	while true do
+		local v = rawget(self, k)
+		if v ~= nil then
+			return v
+		end
+		local mt = getmetatable(self)
+		if not mt or type(mt.__index) ~= "table" then
+			return nil
+		end
+		self = mt.__index
+	end
+end
+
+-- @function		Factory
+-- @brief			Construct a factory for the creation of objects.
+-- @param obj		The object whose init method will be called on the new factory
+--					object.
+-- @param newobj	The object whose init method will be called on the new
+--					objects that the Factory creates, to initialize them.
+-- @param (...) Arguments which will be passed to obj.init() in addition
+--					to the Factory object.
+-- @return			The new factory which creates a newobj when its new method is called,
+--					or when it is called directly (__call metamethod).
+local Factory
+do
+	local function getlibraries(...)
+		if select('#', ...) == 0 then
+			return
+		end
+		return getlibrary((select(1, ...))), getlibraries(select(2, ...))
+	end
+	local arg = {}
+	local function new(obj, ...)
+		local t = {}
+		local uid = getuid(t)
+		obj:init(t, getlibraries(...))
+		t.uid = uid
+		return t
+	end
+
+	local function createnew(self, ...)
+		local o = self.prototype
+		local x = new(o, getlibraries(...))
+		return x
+	end
+
+	function Factory(obj, newobj, ...)
+		local t = new(obj, ...)
+		t.prototype = newobj
+		t.new = createnew
+		getmetatable(t).__call = t.new
+		return t
+	end
+end
+
+
+local function objtostring(self)
+	if self.ToString then
+		return self:ToString()
+	elseif self.GetLibraryVersion then
+		return (self:GetLibraryVersion())
+	elseif self.super then
+		local s = "Sub-" .. tostring(self.super)
+		local first = true
+		if self.interfaces then
+			for interface in pairs(self.interfaces) do
+				if first then
+					s = s .. "(" .. tostring(interface)
+					first = false
+				else
+					s = s .. ", " .. tostring(interface)
+				end
+			end
+		end
+		if self.mixins then
+			for mixin in pairs(self.mixins) do
+				if first then
+					s = s .. tostring(mixin)
+					first = false
+				else
+					s = s .. ", " .. tostring(mixin)
+				end
+			end
+		end
+		if first then
+			if self.uid then
+				return s .. ":" .. self.uid
+			else
+				return s
+			end
+		else
+			return s .. ")"
+		end
+	else
+		return self.uid and 'Subclass:' .. self.uid or 'Subclass'
+	end
+end
+
+-- @table			Object
+-- @brief			Base of all objects, including Class.
+--
+-- @method			init
+-- @brief			Initialize a new object.
+-- @param newobject The object to initialize
+-- @param class		The class to make newobject inherit from
+local Object
+do
+	Object = {}
+	function Object:init(newobject, class)
+		local parent = class or self
+		if not rawget(newobject, 'uid') then
+			newobject.uid = getuid(newobject)
+		end
+		local mt = {
+			__index = parent,
+			__tostring = objtostring,
+		}
+		setmetatable(newobject, mt)
+	end
+	Object.uid = getuid(Object)
+	setmetatable(Object, { __tostring = function() return 'Object' end })
+end
+
+local Interface
+
+local function validateInterface(object, interface)
+	if not object.class and object.prototype then
+		object = object.prototype
+	end
+	for k,v in pairs(interface.interface) do
+		if tostring(type(object[k])) ~= v then
+			return false
+		end
+	end
+	if interface.superinterfaces then
+		for superinterface in pairs(interface.superinterfaces) do
+			if not validateInterface(object, superinterface) then
+				return false
+			end
+		end
+	end
+	if type(object.class) == "table" and rawequal(object.class.prototype, object) then
+		if not object.class.interfaces then
+			rawset(object.class, 'interfaces', {})
+		end
+		object.class.interfaces[interface] = true
+	elseif type(object.class) == "table" and type(object.class.prototype) == "table" then
+		validateInterface(object.class.prototype, interface)
+		-- check if class is proper, thus preventing future checks.
+	end
+	return true
+end
+
+-- @function		inherits
+-- @brief			Return whether an Object or Class inherits from a given
+--					parent.
+-- @param object	Object or Class to check
+-- @param parent	Parent to test inheritance from
+-- @return			whether an Object or Class inherits from a given
+--					parent.
+local function inherits(object, parent)
+	object = getlibrary(object)
+	if type(parent) == "string" then
+		if not AceLibrary:HasInstance(parent) then
+			return false
+		else
+			parent = AceLibrary(parent)
+		end
+	end
+	AceOO:argCheck(parent, 2, "table")
+	if type(object) ~= "table" then
+		return false
+	end
+	local current
+	local class = deeprawget(object, 'class')
+	if class then
+		current = class
+	else
+		current = object
+	end
+	if type(current) ~= "table" then
+		return false
+	end
+	if rawequal(current, parent) then
+		return true
+	end
+	if parent.class then
+		while true do
+			if rawequal(current, Object) then
+				break
+			end
+			if current.mixins then
+				for mixin in pairs(current.mixins) do
+					if rawequal(mixin, parent) then
+						return true
+					end
+				end
+			end
+			if current.interfaces then
+				for interface in pairs(current.interfaces) do
+					if rawequal(interface, parent) then
+						return true
+					end
+				end
+			end
+			current = deeprawget(current, 'super')
+			if type(current) ~= "table" then
+				break
+			end
+		end
+
+		local isInterface = false
+		local curr = parent.class
+		while true do
+			if rawequal(curr, Object) then
+				break
+			elseif rawequal(curr, Interface) then
+				isInterface = true
+				break
+			end
+			curr = deeprawget(curr, 'super')
+			if type(curr) ~= "table" then
+				break
+			end
+		end
+		return isInterface and validateInterface(object, parent)
+	else
+		while true do
+			if rawequal(current, parent) then
+				return true
+			elseif rawequal(current, Object) then
+				return false
+			end
+			current = deeprawget(current, 'super')
+			if type(current) ~= "table" then
+				return false
+			end
+		end
+	end
+end
+
+-- @table			Class
+-- @brief			An object factory which sets up inheritence and supports
+--					'mixins'.
+--
+-- @metamethod		Class call
+-- @brief			Call ClassFactory:new() to create a new class.
+--
+-- @method			Class new
+-- @brief			Construct a new object.
+-- @param (...) Arguments to pass to the object init function.
+-- @return			The new object.
+--
+-- @method			Class init
+-- @brief			Initialize a new class.
+-- @param parent	Superclass.
+-- @param (...) Mixins.
+--
+-- @method			Class ToString
+-- @return			A string representing the object, in this case 'Class'.
+local initStatus
+local Class
+local Mixin
+local autoEmbed = false
+local function traverseInterfaces(bit, total)
+	if bit.superinterfaces then
+		for interface in pairs(bit.superinterfaces) do
+			if not total[interface] then
+				total[interface] = true
+				traverseInterfaces(interface, total)
+			end
+		end
+	end
+end
+local class_new
+do
+	Class = Factory(Object, setmetatable({}, {__index = Object}), Object)
+	Class.super = Object
+
+	local function protostring(t)
+		return '<' .. tostring(t.class) .. ' prototype>'
+	end
+	local function classobjectstring(t)
+		if t.ToString then
+			return t:ToString()
+		elseif t.GetLibraryVersion then
+			return (t:GetLibraryVersion())
+		else
+			return '<' .. tostring(t.class) .. ' instance>'
+		end
+	end
+	local function classobjectequal(self, other)
+		if type(self) == "table" and self.Equals then
+			return self:Equals(other)
+		elseif type(other) == "table" and other.Equals then
+			return other:Equals(self)
+		elseif type(self) == "table" and self.CompareTo then
+			return self:CompareTo(other) == 0
+		elseif type(other) == "table" and other.CompareTo then
+			return other:CompareTo(self) == 0
+		else
+			return rawequal(self, other)
+		end
+	end
+	local function classobjectlessthan(self, other)
+		if type(self) == "table" and self.IsLessThan then
+			return self:IsLessThan(other)
+		elseif type(other) == "table" and other.IsLessThanOrEqualTo then
+			return not other:IsLessThanOrEqualTo(self)
+		elseif type(self) == "table" and self.CompareTo then
+			return self:CompareTo(other) < 0
+		elseif type(other) == "table" and other.CompareTo then
+			return other:CompareTo(self) > 0
+		elseif type(other) == "table" and other.IsLessThan and other.Equals then
+			return other:Equals(self) or other:IsLessThan(self)
+		else
+			AceOO:error("cannot compare two objects")
+		end
+	end
+	local function classobjectlessthanequal(self, other)
+		if type(self) == "table" and self.IsLessThanOrEqualTo then
+			return self:IsLessThanOrEqualTo(other)
+		elseif type(other) == "table" and other.IsLessThan then
+			return not other:IsLessThan(self)
+		elseif type(self) == "table" and self.CompareTo then
+			return self:CompareTo(other) <= 0
+		elseif type(other) == "table" and other.CompareTo then
+			return other:CompareTo(self) >= 0
+		elseif type(self) == "table" and self.IsLessThan and self.Equals then
+			return self:Equals(other) or self:IsLessThan(other)
+		else
+			AceOO:error("cannot compare two incompatible objects")
+		end
+	end
+	local function classobjectadd(self, other)
+		if type(self) == "table" and self.Add then
+			return self:Add(other)
+		else
+			AceOO:error("cannot add two incompatible objects")
+		end
+	end
+	local function classobjectsub(self, other)
+		if type(self) == "table" and self.Subtract then
+			return self:Subtract(other)
+		else
+			AceOO:error("cannot subtract two incompatible objects")
+		end
+	end
+	local function classobjectunm(self, other)
+		if type(self) == "table" and self.UnaryNegation then
+			return self:UnaryNegation(other)
+		else
+			AceOO:error("attempt to negate an incompatible object")
+		end
+	end
+	local function classobjectmul(self, other)
+		if type(self) == "table" and self.Multiply then
+			return self:Multiply(other)
+		else
+			AceOO:error("cannot multiply two incompatible objects")
+		end
+	end
+	local function classobjectdiv(self, other)
+		if type(self) == "table" and self.Divide then
+			return self:Divide(other)
+		else
+			AceOO:error("cannot divide two incompatible objects")
+		end
+	end
+	local function classobjectpow(self, other)
+		if type(self) == "table" and self.Exponent then
+			return self:Exponent(other)
+		else
+			AceOO:error("cannot exponentiate two incompatible objects")
+		end
+	end
+	local function classobjectconcat(self, other)
+		if type(self) == "table" and self.Concatenate then
+			return self:Concatenate(other)
+		else
+			AceOO:error("cannot concatenate two incompatible objects")
+		end
+	end
+	function class_new(self, ...)
+		if self.virtual then
+			AceOO:error("Cannot instantiate a virtual class.")
+		end
+
+		local o = self.prototype
+		local newobj = {}
+		if o.class and o.class.instancemeta then
+			setmetatable(newobj, o.class.instancemeta)
+		else
+			Object:init(newobj, o)
+		end
+
+		if self.interfaces and not self.interfacesVerified then
+			-- Verify the interfaces
+
+			for interface in pairs(self.interfaces) do
+				for field,kind in pairs(interface.interface) do
+					if tostring(type(newobj[field])) ~= kind then
+						AceOO:error("Class did not satisfy all interfaces. %q is required to be a %s. It is a %s", field, kind, tostring(type(newobj[field])))
+					end
+				end
+			end
+			self.interfacesVerified = true
+		end
+		local tmp = initStatus
+		initStatus = newobj
+		newobj:init(...)
+		if initStatus then
+			initStatus = tmp
+			AceOO:error("Initialization not completed, be sure to call the superclass's init method.")
+			return
+		end
+		initStatus = tmp
+		return newobj
+	end
+	local classmeta = {
+		__tostring = objtostring,
+		__call = function(self, ...)
+			return self:new(...)
+		end,
+	}
+	function Class:init(newclass, parent, ...)
+		parent = parent or self
+
+		local total
+
+		if parent.class then
+			total = { parent, ... }
+			parent = self
+		else
+			total = { ... }
+		end
+		if not inherits(parent, Class) then
+			AceOO:error("Classes must inherit from a proper class")
+		end
+		if parent.sealed then
+			AceOO:error("Cannot inherit from a sealed class")
+		end
+		for i,v in ipairs(total) do
+			if inherits(v, Mixin) and v.class then
+				if v.__deprecated then
+					AceOO:error(v.__deprecated)
+				end
+				if not newclass.mixins then
+					newclass.mixins = {}
+				end
+				if newclass.mixins[v] then
+					AceOO:error("Cannot explicitly inherit from the same mixin twice")
+				end
+				newclass.mixins[v] = true
+			elseif inherits(v, Interface) and v.class then
+				if not newclass.interfaces then
+					newclass.interfaces = {}
+				end
+				if newclass.interfaces[v] then
+					AceOO:error("Cannot explicitly inherit from the same interface twice")
+				end
+				newclass.interfaces[v] = true
+			else
+				AceOO:error("Classes can only inherit from one or zero classes and any number of mixins or interfaces")
+			end
+		end
+		if parent.interfaces then
+			if not newclass.interfaces then
+				newclass.interfaces = {}
+			end
+			for interface in pairs(parent.interfaces) do
+				newclass.interfaces[interface] = true
+			end
+		end
+		for k in pairs(total) do
+			total[k] = nil
+		end
+
+		newclass.super = parent
+
+		newclass.prototype = setmetatable(total, {
+			__index = parent.prototype,
+			__tostring = protostring,
+		})
+		total = nil
+
+		newclass.instancemeta = {
+			__index = newclass.prototype,
+			__tostring = classobjectstring,
+			__eq = classobjectequal,
+			__lt = classobjectlessthan,
+			__le = classobjectlessthanequal,
+			__add = classobjectadd,
+			__sub = classobjectsub,
+			__unm = classobjectunm,
+			__mul = classobjectmul,
+			__div = classobjectdiv,
+			__pow = classobjectpow,
+			__concat = classobjectconcat,
+		}
+
+		setmetatable(newclass, classmeta)
+
+		newclass.new = class_new
+
+		if newclass.mixins then
+			-- Fold in the mixins
+			local err, msg
+			for mixin in pairs(newclass.mixins) do
+				local ret
+				autoEmbed = true
+				ret, msg = pcall(mixin.embed, mixin, newclass.prototype)
+				autoEmbed = false
+				if not ret then
+					err = true
+					break
+				end
+			end
+
+			if err then
+				local pt = newclass.prototype
+				for k,v in pairs(pt) do
+					pt[k] = nil
+				end
+
+				-- method conflict
+				AceOO:error(msg)
+			end
+		end
+
+		newclass.prototype.class = newclass
+
+		if newclass.interfaces then
+			for interface in pairs(newclass.interfaces) do
+				traverseInterfaces(interface, newclass.interfaces)
+			end
+		end
+		if newclass.mixins then
+			for mixin in pairs(newclass.mixins) do
+				if mixin.interfaces then
+					if not newclass.interfaces then
+						newclass.interfaces = {}
+					end
+					for interface in pairs(mixin.interfaces) do
+						newclass.interfaces[interface] = true
+					end
+				end
+			end
+		end
+	end
+	function Class:ToString()
+		if type(self.GetLibraryVersion) == "function" then
+			return (self:GetLibraryVersion())
+		else
+			return "Class"
+		end
+	end
+
+	local tmp
+	function Class.prototype:init()
+		if rawequal(self, initStatus) then
+			initStatus = nil
+		else
+			AceOO:error("Improper self passed to init. You must do MyClass.super.prototype.init(self, ...)", 2)
+		end
+		self.uid = getuid(self)
+		local current = self.class
+		while true do
+			if current == Class then
+				break
+			end
+			if current.mixins then
+				for mixin in pairs(current.mixins) do
+					if type(mixin.OnInstanceInit) == "function" then
+						mixin:OnInstanceInit(self)
+					end
+				end
+			end
+			current = current.super
+		end
+	end
+end
+
+
+-- @object	ClassFactory
+-- @brief	A factory for creating classes.	Rarely used directly.
+local ClassFactory = Factory(Object, Class, Object)
+
+function Class:new(...)
+	local x = ClassFactory:new(...)
+	if AceOO.classes then
+		AceOO.classes[x] = true
+	end
+	return x
+end
+getmetatable(Class).__call = Class.new
+
+-- @class	Mixin
+-- @brief	A class to create mixin objects, which contain methods that get
+-- "mixed in" to class prototypes.
+--
+-- @object	Mixin prototype
+-- @brief	The prototype that mixin objects inherit their methods from.
+--
+-- @method	Mixin prototype embed
+-- @brief	Mix in the methods of our object which are listed in our interface
+--		 to the supplied target table.
+--
+-- @method	Mixin prototype init
+-- @brief	Initialize the mixin object.
+-- @param	newobj	 The new object we're initializing.
+-- @param	interface	The interface we implement (the list of methods our
+--					prototype provides which should be mixed into the target
+--					table by embed).
+do
+	Mixin = Class()
+	function Mixin:ToString()
+		if self.GetLibraryVersion then
+			return (self:GetLibraryVersion())
+		else
+			return 'Mixin'
+		end
+	end
+	local function _Embed(state, field, target)
+		field = next(state.export, field)
+		if field == nil then
+			return
+		end
+
+		if rawget(target, field) or (target[field] and target[field] ~= state[field]) then
+			AceOO:error("Method conflict in attempt to mixin. Field %q", field)
+		end
+
+		target[field] = state[field]
+
+		local ret,msg = pcall(_Embed, state, field, target)
+		if not ret then
+			-- Mix in the next method according to the defined interface.	If that
+			-- fails due to a conflict, re-raise to back out the previous mixed
+			-- methods.
+
+			target[field] = nil
+			AceOO:error(msg)
+		end
+	end
+	function Mixin.prototype:embed(target)
+		if self.__deprecated then
+			AceOO:error(self.__deprecated)
+		end
+		local mt = getmetatable(target)
+		setmetatable(target, nil)
+		local err, msg = pcall(_Embed, self, nil, target)
+		if not err then
+			setmetatable(target, mt)
+			AceOO:error(msg)
+			return
+		end
+		if type(self.embedList) == "table" then
+			self.embedList[target] = true
+		end
+		if type(target.class) ~= "table" then
+			target[self] = true
+		end
+		if not autoEmbed and type(self.OnManualEmbed) == "function" then
+			self:OnManualEmbed(target)
+		end
+		setmetatable(target, mt)
+	end
+
+	function Mixin.prototype:activate(oldLib, oldDeactivate)
+		if oldLib and oldLib.embedList then
+			for target in pairs(oldLib.embedList) do
+				local mt = getmetatable(target)
+				setmetatable(target, nil)
+				for field in pairs(oldLib.export) do
+					target[field] = nil
+				end
+				setmetatable(target, mt)
+			end
+			self.embedList = oldLib.embedList
+			for target in pairs(self.embedList) do
+				self:embed(target)
+			end
+		else
+			self.embedList = setmetatable({}, {__mode="k"})
+		end
+	end
+
+	function Mixin.prototype:init(export, ...)
+		AceOO:argCheck(export, 2, "table")
+		for k,v in pairs(export) do
+			if type(k) ~= "number" then
+				AceOO:error("All keys to argument #2 must be numbers.")
+			elseif type(v) ~= "string" then
+				AceOO:error("All values to argument #2 must be strings.")
+			end
+		end
+		local num = #export
+		for i = 1, num do
+			local v = export[i]
+			export[i] = nil
+			export[v] = true
+		end
+
+		local interfaces
+		if select('#', ...) >= 1 then
+			interfaces = { ... }
+			for i,v in ipairs(interfaces) do
+				v = getlibrary(v)
+				interfaces[i] = v
+				if not v.class or not inherits(v, Interface) then
+					AceOO:error("Mixins can inherit only from interfaces")
+				end
+			end
+			local num = #interfaces
+			for i = 1, num do
+				local v = interfaces[i]
+				interfaces[i] = nil
+				interfaces[v] = true
+			end
+			for interface in pairs(interfaces) do
+				traverseInterfaces(interface, interfaces)
+			end
+			for interface in pairs(interfaces) do
+				for field,kind in pairs(interface.interface) do
+					if kind ~= "nil" then
+						local good = false
+						for bit in pairs(export) do
+							if bit == field then
+								good = true
+								break
+							end
+						end
+						if not good then
+							AceOO:error("Mixin does not fully accommodate field %q", field)
+						end
+					end
+				end
+			end
+		end
+		self.super = Mixin.prototype
+		Mixin.super.prototype.init(self)
+		self.export = export
+		self.interfaces = interfaces
+	end
+end
+
+-- @class Interface
+-- @brief A class to create interfaces, which contain contracts that classes
+--			which inherit from this must comply with.
+--
+-- @object Interface prototype
+-- @brief	The prototype that interface objects must adhere to.
+--
+-- @method Interface prototype init
+-- @brief	Initialize the mixin object.
+-- @param	interface	The interface we contract (the hash of fields forced).
+-- @param	(...)	Superinterfaces
+do
+	Interface = Class()
+	function Interface:ToString()
+		if self.GetLibraryVersion then
+			return (self:GetLibraryVersion())
+		else
+			return 'Instance'
+		end
+	end
+	function Interface.prototype:init(interface, ...)
+		Interface.super.prototype.init(self)
+		AceOO:argCheck(interface, 2, "table")
+		for k,v in pairs(interface) do
+			if type(k) ~= "string" then
+				AceOO:error("All keys to argument #2 must be numbers.")
+			elseif type(v) ~= "string" then
+				AceOO:error("All values to argument #2 must be strings.")
+			elseif v ~= "nil" and v ~= "string" and v ~= "number" and v ~= "table" and v ~= "function" then
+				AceOO:error('All values to argument #2 must either be "nil", "string", "number", "table", or "function".')
+			end
+		end
+		if select('#', ...) >= 1 then
+			self.superinterfaces = { ... }
+			for i,v in ipairs(self.superinterfaces) do
+				v = getlibrary(v)
+				self.superinterfaces[i] = v
+				if not inherits(v, Interface) or not v.class then
+					AceOO:error('Cannot provide a non-Interface to inherit from')
+				end
+			end
+			local num = #self.superinterfaces
+			for i = 1, num do
+				local v = self.superinterfaces[i]
+				self.superinterfaces[i] = nil
+				self.superinterfaces[v] = true
+			end
+		end
+		self.interface = interface
+	end
+end
+
+-- @function Classpool
+-- @brief	Obtain a read only class from our pool of classes, indexed by the
+--		 superclass and mixins.
+-- @param	sc		 The superclass of the class we want.
+-- @param	(m1..m20)	Mixins of the class we want's objects.
+-- @return A read only class from the class pool.
+local Classpool
+do
+	local pool = setmetatable({}, {__mode = 'v'})
+	local function newindex(k, v)
+		AceOO:error('Attempt to modify a read-only class.')
+	end
+	local function protonewindex(k, v)
+		AceOO:error('Attempt to modify a read-only class prototype.')
+	end
+	local function ts(bit)
+		if type(bit) ~= "table" then
+			return tostring(bit)
+		elseif getmetatable(bit) and bit.__tostring then
+			return tostring(bit)
+		elseif type(bit.GetLibraryVersion) == "function" then
+			return bit:GetLibraryVersion()
+		else
+			return tostring(bit)
+		end
+	end
+	local t = {}
+	local function getcomplexuid(sc, ...)
+		if sc then
+			if sc.uid then
+				table.insert(t, sc.uid)
+			else
+				AceOO:error("%s is not an appropriate class/mixin", ts(sc))
+			end
+		end
+		for i = 1, select('#', ...) do
+			local m = select(i, ...)
+			if m.uid then
+				table.insert(t, m.uid)
+			else
+				AceOO:error("%s is not an appropriate mixin", ts(m))
+			end
+		end
+		table.sort(t)
+		local uid = table.concat(t, '')
+		local num = #t
+		for i = 1, num do
+			t[i] = nil
+		end
+		return uid
+	end
+	local classmeta
+	local arg = {}
+	function Classpool(superclass, ...)
+		local l = getlibrary
+		superclass = getlibrary(superclass)
+		arg = { ... }
+		for i, v in ipairs(arg) do
+			arg[i] = getlibrary(v)
+		end
+		if superclass then
+			if superclass.class then -- mixin
+				table.insert(arg, 1, superclass)
+				superclass = Class
+			end
+		else
+			superclass = Class
+		end
+		local key = getcomplexuid(superclass, unpack(arg))
+		if not pool[key] then
+			local class = Class(superclass, unpack(arg))
+			if not classmeta then
+				classmeta = {}
+				local mt = getmetatable(class)
+				for k,v in pairs(mt) do
+					classmeta[k] = v
+				end
+				classmeta.__newindex = newindex
+			end
+			-- Prevent the user from adding methods to this class.
+			-- NOTE: I'm not preventing modifications of existing class members,
+			-- but it's likely that only a truly malicious user will be doing so.
+			class.sealed = true
+			setmetatable(class, classmeta)
+			getmetatable(class.prototype).__newindex = protonewindex
+			pool[key] = class
+		end
+		return pool[key]
+	end
+end
+
+AceOO.Factory = Factory
+AceOO.Object = Object
+AceOO.Class = Class
+AceOO.Mixin = Mixin
+AceOO.Interface = Interface
+AceOO.Classpool = Classpool
+AceOO.inherits = inherits
+
+-- Library handling bits
+
+local function activate(self, oldLib, oldDeactivate)
+	AceOO = self
+	Factory = self.Factory
+	Object = self.Object
+	Class = self.Class
+	ClassFactory.prototype = Class
+	Mixin = self.Mixin
+	Interface = self.Interface
+	Classpool = self.Classpool
+
+	if oldLib then
+		self.classes = oldLib.classes
+	end
+	if not self.classes then
+		self.classes = setmetatable({}, {__mode="k"})
+	else
+		for class in pairs(self.classes) do
+			class.new = class_new
+		end
+	end
+
+	if oldDeactivate then
+		oldDeactivate(oldLib)
+	end
+end
+
+AceLibrary:Register(AceOO, MAJOR_VERSION, MINOR_VERSION, activate)
+AceOO = AceLibrary(MAJOR_VERSION)
diff --git a/Libs/AceOO-2.0/AceOO-2.0.toc b/Libs/AceOO-2.0/AceOO-2.0.toc
index 3879748..d9ffd38 100644
--- a/Libs/AceOO-2.0/AceOO-2.0.toc
+++ b/Libs/AceOO-2.0/AceOO-2.0.toc
@@ -1,16 +1,16 @@
-## Interface: 30000
-## X-Curse-Packaged-Version: r1094
-## X-Curse-Project-Name: Ace2
-## X-Curse-Project-ID: ace2
-## X-Curse-Repository-ID: wow/ace2/mainline
-
-## Title: Lib: AceOO-2.0
-## Notes: AddOn development framework
-## Author: Ace Development Team
-## LoadOnDemand: 1
-## X-Website: http://www.wowace.com
-## X-Category: Library
-## X-License: LGPL v2.1 + MIT for AceOO-2.0
-## Dependencies: AceLibrary
-
-AceOO-2.0.lua
+## Interface: 30000
+## X-Curse-Packaged-Version: r1094
+## X-Curse-Project-Name: Ace2
+## X-Curse-Project-ID: ace2
+## X-Curse-Repository-ID: wow/ace2/mainline
+
+## Title: Lib: AceOO-2.0
+## Notes: AddOn development framework
+## Author: Ace Development Team
+## LoadOnDemand: 1
+## X-Website: http://www.wowace.com
+## X-Category: Library
+## X-License: LGPL v2.1 + MIT for AceOO-2.0
+## Dependencies: AceLibrary
+
+AceOO-2.0.lua