changeset 9:5362e308c3eb

renamed the old DependencyLoader module to DependencyLoader_Bootstrap renamed DependencyLoader_Core to DependencyLoader
author mckenziemc
date Sun, 05 Dec 2010 00:12:57 -0800
parents 930871e163bc
children e0a4a8b5b389
files DependencyLoader/Ace3.xml DependencyLoader/Addon.lua DependencyLoader/Core.lua DependencyLoader/DependencyLoader.toc DependencyLoader/DependencyLoader_Core.toc DependencyLoader/Tree.lua DependencyLoader/bootstrap.lua DependencyLoader/class.lua DependencyLoader/embeds.xml DependencyLoader/frontend.lua DependencyLoader/load.xml DependencyLoader/start.lua DependencyLoader_Bootstrap/Ace3.xml DependencyLoader_Bootstrap/DependencyLoader.toc DependencyLoader_Bootstrap/bootstrap.lua DependencyLoader_Bootstrap/embeds.xml DependencyLoader_Bootstrap/load.xml DependencyLoader_Core/Addon.lua DependencyLoader_Core/Core.lua DependencyLoader_Core/DependencyLoader_Core.toc DependencyLoader_Core/Tree.lua DependencyLoader_Core/class.lua DependencyLoader_Core/frontend.lua DependencyLoader_Core/load.xml DependencyLoader_Core/start.lua
diffstat 25 files changed, 1044 insertions(+), 1044 deletions(-) [+]
line wrap: on
line diff
--- a/DependencyLoader/Ace3.xml	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
-  <Script file="libs\Ace3\LibStub\LibStub.lua"/>
-  
-  <Include file="libs\Ace3\CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
-  <Include file="libs\Ace3\AceAddon-3.0\AceAddon-3.0.xml"/>
-  <Include file="libs\Ace3\AceEvent-3.0\AceEvent-3.0.xml"/>
-  <Include file="libs\Ace3\AceTimer-3.0\AceTimer-3.0.xml"/>
-  <Include file="libs\Ace3\AceBucket-3.0\AceBucket-3.0.xml"/>
-  <Include file="libs\Ace3\AceHook-3.0\AceHook-3.0.xml"/>
-  <Include file="libs\Ace3\AceDB-3.0\AceDB-3.0.xml"/>
-  <Include file="libs\Ace3\AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
-  <Include file="libs\Ace3\AceLocale-3.0\AceLocale-3.0.xml"/>
-  <Include file="libs\Ace3\AceConsole-3.0\AceConsole-3.0.xml"/>
-  <Include file="libs\Ace3\AceGUI-3.0\AceGUI-3.0.xml"/>
-  <Include file="libs\Ace3\AceConfig-3.0\AceConfig-3.0.xml"/>
-  <Include file="libs\Ace3\AceComm-3.0\AceComm-3.0.xml"/>
-  <Include file="libs\Ace3\AceTab-3.0\AceTab-3.0.xml"/>
-  <Include file="libs\Ace3\AceSerializer-3.0\AceSerializer-3.0.xml"/>
-</Ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader/Addon.lua	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,248 @@
+--	Addon
+--	Represents individual addon modules
+
+
+local addonName, addonTable = ...
+
+
+--	NOTE: I assume that the API addon functions are 
+--	slightly quicker with an index than with a number.
+
+--	TODO: modify the dependency stuff to use the Errata module if available
+
+local Addon, addon = addonTable:NewClass("Addon")
+
+
+--	load ability masks
+Addon.loadMasks = {
+	reload = 		bit.lshift(1, 0),	--	can load after reloadui
+	ondemand = 		bit.lshift(1, 1),	--	can load on demand
+	forceafter = 	bit.lshift(1, 2),	--	force load after it would normally be loaded
+	forcebefore = 	bit.lshift(1, 3),	--	force load before it would normally be loaded
+}
+
+
+Addon.addons = {}
+Addon.nameToIndex = {}
+
+
+--	Internal function
+--	Creates a new Addon object
+--	@param	id		Name or index of the addon.
+function Addon:New(id)
+	local instance = {}
+	setmetatable(instance, self.instanceMetatable)
+	
+	if type(id) == "number" then
+		--	TODO: make sure it's in range
+		instance.index = id
+		instance.name = GetAddOnInfo(id)
+	else
+		--	FIXME: allow blizzard addons?
+		local index
+		
+		for i=1,GetNumAddOns() do
+			if GetAddOnInfo(i) == id then
+				index = i
+				break
+			end
+		end
+		
+		if index then
+			instance.name = GetAddOnInfo(id)
+			instance.index = index
+		else
+			error("Addon not found")
+		end
+	end
+	
+	return instance
+end
+
+
+---	Retrieves an Addon object.
+--	@param	id	Name or index of the addon to retrieve.
+--	@return 	The Addon object, or nil if not found.
+function Addon:Get(id)
+	if not self:Exists(id) then
+		return nil
+	end
+	
+	if type(id) == "number" then
+		if self.addons[id] ~= nil then
+			return self.addons[id]
+		end
+		
+		local new = self:New(id)
+		self.addons[new:GetIndex()] = new
+		self.nameToIndex[new:GetName()] = id
+		
+		return new
+	elseif type(id) == "string" then
+		if self.nameToIndex[id] then
+			return self.addons[self.nameToIndex[id] ]
+		end
+		
+		local new = self:New(id)
+		self.addons[new:GetIndex()] = new
+		self.nameToIndex[id] = new:GetIndex()
+		
+		return new
+	end
+end	
+
+--	Checks if an addon exists with the specified name.
+--	@param	addon	Name of the addon.
+--	@return			True if the addon is present, false otherwise.
+function Addon:Exists(addon)
+	if type(addon) == "number" then
+		if addon >= 1 and addon <= GetNumAddOns() then
+			return true
+		else
+			return false
+		end
+	elseif type(addon) == "string" then
+		local status = select(6, GetAddOnInfo(addon))
+		
+		if status == "MISSING" then
+			return false
+		else
+			return true
+		end
+	else
+		error()
+	end
+end
+
+
+function Addon:GetLoadMasks()
+	return self.masks
+end
+
+
+function addon:GetName()
+	return self.name
+end
+
+
+function addon:GetIndex()
+	return self.index
+end
+
+
+function addon:IsEnabled()
+	--	FIXME: written while tired; review later
+	local status = select(6, GetAddOnInfo(self.index))
+	
+	if status == "DISABLED"	then
+		return false
+	else
+		return true
+	end
+end
+
+
+function addon:GetLoadBitfield()
+	local bitfield = 0
+	
+	if self:CanLoad() then
+		bitfield = bitfield + self.masks.reload
+	end
+	
+	if self:CanLoD() then
+		bitfield = bitfield + self.masks.ondemand
+	end
+	
+	if self:CanForceLoadAfter() then
+		bitfield = bitfield + self.masks.forceafter
+	end
+	
+	if self:CanForceLoadBefore() then
+		bitfield = bitfield + self.masks.forcebefore
+	end
+	
+	return bitfield
+end
+
+
+---	Checks if the addon is loadable.
+--	Considers interface issues, missing, etc. (NYI)
+--	Does not check dependencies.
+function addon:CanLoad()
+	--	FIXME: an addon may be present but unloadable if loading out of date addons is disabled.
+	return true
+end
+
+
+function addon:CanLoD()
+	--	FIXME: what will the client say about addons using LoadManagers if the LM was force-loaded?
+	if IsAddOnLoadOnDemand(self.name) then
+		return true
+	else
+		return false
+	end
+end
+
+
+function addon:CanForceLoadAfter()
+	--	TODO: check Errata module
+	return false
+end
+
+
+function addon:CanForceLoadBefore()
+	--	TODO: check Errata module
+	return false		--	TODO: check if there's any reason addons can't be forceloaded
+end
+
+
+function addon:Enable()
+	--	FIXME: delay this till after PLAYER_LOGIN or it'll get force-loaded
+	EnableAddOn(self.name)
+end
+
+
+--	NOTE: only call for LoD, not force-loading
+function addon:Load()
+	assert(self:CanLoD())
+	
+	EnableAddOn(self.name)
+	LoadAddOn(self.name)
+end
+
+
+function addon:ForceLoad()
+	assert(self:CanForceLoad())
+	--	TODO: make sure force-loading is available at this time
+	
+	EnableAddOn(self.name)	--	This should cause the game to also load this addon
+end
+
+
+function addon:GetDependencies()
+	--	TODO: consider no-lib embeds as deps?
+	return GetAddOnDependencies(self.index)
+end
+
+
+function addon:GetEmbeds()
+	local embeds = {}
+	
+	local embedString = GetAddOnMetadata(self.name, "X-Embeds")
+	
+	if embedString then
+		for match in string.gmatch(embedString, "[^,%s]+") do
+			table.insert(embeds, match)
+		end
+	end
+	
+	return unpack(embeds)
+end
+
+function addon:IsLoaded()
+	if IsAddOnLoaded(self.index) then
+		return true
+	else
+		return false
+	end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader/Core.lua	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,293 @@
+
+
+
+local addonName, addonTable = ...
+
+
+local Core, core = addonTable:NewClass("Core")
+
+
+function Core:New()
+	local instance = {}
+	setmetatable(instance, self.instanceMetatable)
+	
+	instance.addons = {}
+	instance.nameToIndex = {}
+	
+	for i=1,GetNumAddOns() do
+		local newAddon = Addon:New(i)
+		
+		instance.addons[i] = newAddon
+		instance.nameToIndex[newAddon:GetName()] = i
+	end
+	
+	--	TODO: enable dependencies for any addons that have already loaded
+	
+	return instance
+end
+
+
+--	@param	addon	Name or index of the addon to retrieve.
+--	@return 		The addon object, or nil if not found
+function core:GetAddon(addon)
+	if not Addon:Exists(addon) then
+		return nil
+	end
+	
+	local index
+
+	if type(addon) == "string" then
+		index = self.nameToIndex[addon]
+	elseif type(addon) == "number" then
+		index = addon
+	end
+	
+	return self.addons[index]
+end	
+
+
+--	Checks if the tree rooted at the specified addon can be force-loaded.
+--	@param	root	The name or index of the root addon.
+function core:CanForceLoadTree(root)
+	--	convert root to an Addon object
+	root = self:GetAddon(root)
+	assert(root)
+	
+	if root:IsLoaded() then
+		return true
+	end
+	
+	--	check if the root itself can be force-loaded
+	if not root:CanForceLoad() then
+		return false
+	end
+	
+	--	now check dependencies recursively
+	--	FIXME: prevent infinite recursion
+
+	local dependencies = {root:GetDependencies()}
+	for i, depName in pairs(dependencies) do
+		local dep = self:GetAddon(depName)
+		
+		if dep == nil then
+			return false		--	missing dependency
+		end
+		
+		--	if it's already loaded then skip to next one
+		if not dep:IsLoaded() then
+			if not self:CanForceLoadTree(depName) then
+				return false
+			end
+		end
+	end
+	
+	return true
+end
+
+--	NOTE: any tree that can be loaded on demand is also eligible for force-loading
+--	Checks if the tree rooted at the specified addon can be loaded on demand.
+--	@param	root	The name or index of the root addon.
+function core:CanLoDTree(root)
+	root = self:GetAddon(root)
+	assert(root)
+
+	--	since this will be used recursively, return true if 
+	--	this is already loaded.
+	if root:IsLoaded() then
+		return true
+	end
+	
+	--	true if all dependencies are loaded or LoD
+	
+	if not root:CanLoD() then
+		return false
+	end
+	
+	--	now check dependencies recursively
+	local dependencies = {root:GetDependencies()}
+	for i, depName in pairs(dependencies) do
+		local dep = self:GetAddon(depName)
+		
+		if not dep then
+			return false		--	missing
+		end
+		
+		if not dep:IsLoaded() then
+			if not self:CanLoDTree(depName) then
+				return false
+			end
+		end
+	end
+	
+	return true
+end
+
+
+--	Checks if the tree rooted at the specified addon 
+--	can be loaded if all dependencies are enabled 
+--	the UI is reloaded.
+--	Basically makes sure all dependencies are installed.
+function core:CanReloadTree(root)
+	--	convert root to an Addon object
+	root = self:GetAddon(root)
+	assert(root)
+	
+	if root:IsLoaded() then
+		return true
+		--	FIXME: 	deps may have been disabled
+	end
+	
+	--	TODO: make sure the root isn't incompatible
+	
+	--	now check dependencies recursively
+	--	FIXME: prevent infinite recursion
+
+	local dependencies = {root:GetDependencies()}
+	for i, depName in pairs(dependencies) do
+		local dep = self:GetAddon(depName)
+		
+		if dep == nil then
+			return false		--	missing dependency
+		end
+
+		--	TODO: make sure it's compatible
+	end
+	
+	return true
+end
+
+--	Loads the tree rooted at the specified addon.
+--	FIXME: load the root too or not?
+--	Supports both LoD addons and those that require force-loading.
+function core:LoadTree(addon)
+	--	don't check if the tree can actually be loaded.
+	--	external code should do that itself to check if it 
+	--	should even call this at all.
+
+	if self:ForceLoadAvailable() then
+		--	LoD trees can also be force-loaded
+		self:ForceLoadTree(addon)
+	else
+		self:LoadLoDTree(addon)
+	end
+end
+
+
+--	load the root too, since it may actually be a leaf
+function core:ForceLoadTree(root)
+	root = self:GetAddon(root)
+	assert(root)
+	
+	--	load dependencies
+	local dependencies = {root:GetDependencies(addon)}
+	for i, depName in pairs(dependencies) do
+		self:ForceLoadTree(depName)
+	end
+
+	--	load embeds, if they are available separately
+	local embeds = {root:GetEmbeds(addon)}
+	for i, embedName in pairs(embeds) do
+		if Addon:Exists(embedName) then
+			self:ForceLoadTree(embedName)
+		end
+	end
+	
+	root:ForceLoad()
+end
+
+
+function core:LoadLoDTree(root)
+	root = self:GetAddon(root)
+	assert(root)
+	
+	--	load dependencies
+	local dependencies = {root:GetDependencies(addon)}
+	for i, depName in pairs(dependencies) do
+		self:LoadLoDTree(depName)
+	end
+
+	--	load embeds, if they are available separately
+	local embeds = {root:GetEmbeds(addon)}
+	for i, embedName in pairs(embeds) do
+		if Addon:Exists(embedName) then
+			self:LoadLoDTree(embedName)
+		end
+	end
+	
+	root:LoD()
+end
+
+
+--	I think the problem this solves is a major issue with 
+--	migrating to separate libs. think about it more and document 
+--	here and in project description
+function core:PrepareLoDTree(root)
+	root = self:GetAddon(root)
+	assert(root)
+	
+	--	assume root is LoD
+	
+	--	check dependencies
+	local dependencies = {root:GetDependencies(addon)}
+	for i, depName in pairs(dependencies) do
+		local dep = self:GetAddon(depName)
+		
+		--	assume external code made sure it exists
+		
+		if dep:CanLoD() then
+			--	don't load it now but make sure its dependencies are prepared
+			self:PrepareLoDTree(depName)
+		else
+			--	FIXME: if it's already loaded
+			--	force-load it now so we can load the parent on demand
+			self:ForceLoadTree(depName)
+		end
+	end
+
+	--	prepare embeds, if they are available separately
+	local embeds = {root:GetEmbeds(addon)}	--	FIXME: addon?
+	for i, embedName in pairs(embeds) do
+		local embed = self:GetAddon(embedName)
+		
+		if embed then
+			if embed:CanLoD() then
+				--	don't load it now but make sure its dependencies are prepared
+				self:PrepareLoDTree(embedName)
+			else
+				--	FIXME: if it's already loaded
+				--	force-load it now so we can load the parent on demand
+				self:ForceLoadTree(depName)
+			end
+		end
+	end
+end
+
+
+function Core:PrepareReloadTree(addon)
+	root = self:GetAddon(root)
+	assert(root)
+	
+	root:Enable()
+	
+	--	check dependencies
+	local dependencies = {root:GetDependencies()}
+	for i, depName in pairs(dependencies) do
+		self:PrepareReloadTree(depName)
+	end
+
+	--	prepare embeds, if they are available separately
+	local embeds = {root:GetEmbeds(addon)}
+	for i, embedName in pairs(embeds) do
+		local embed = self:GetAddon(embedName)
+		
+		if embed then
+			self:PrepareReloadTree(embedName)
+		end
+	end
+end
+
+
+function Core:ForceLoadAvailable()
+	return true
+	--	FIXME: use field and a frame registered for PLAYER_LOGIN
+end
--- a/DependencyLoader/DependencyLoader.toc	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-## Interface: 40000
-
-## Notes: Bootstrap for DependencyLoader_Core
-## Author: mckenziemc
-
-## LoadManagers: !!!LoadFirst, AddonLoader
-## X-LoadFirst: true
-## X-LoadOn-Always: true
-
-
-load.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader/DependencyLoader_Core.toc	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,14 @@
+## Interface: 40000
+
+#  TODO: actually explain what DependencyLoader does.
+## Notes: Core module of DependencyLoader
+## Author: mckenziemc
+
+#  TODO: figure out some way to allow AddonLoader 
+#  to work with DependencyLoader
+## Dependencies: DependencyLoader, LibStub, LibPrint-1.0, Ace3
+
+## LoadOnDemand: 1
+
+
+load.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader/Tree.lua	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,287 @@
+--	Tree
+--	Represents a recursive "tree" of addon 
+--	dependencies rooted at a specific addon.
+
+
+local addonName, addonTable = ...
+
+
+--	TODO: prevent infinite loops in the recursive functions
+
+
+local Tree, tree = addonTable:NewClass("Tree")
+
+
+Tree.trees = {}
+
+--	internal
+--	Creates a new tree object
+--	@param	root	Name, index, or Addon object of the root addon.
+function Tree:New(root)
+	if type(root) ~= "table" then
+		root = addonTable.classes.Addon:Get(root)
+	end
+	
+	local instance = {}
+	setmetatable(instance, self.instanceMetatable)
+	
+	instance.root = root
+	
+	return instance
+end
+
+
+---	Retrieves the tree rooted at the specified addon
+--	@param	root	Name, index, or Addon object of the root.
+function Tree:Get(root)
+	if type(root) ~= "table" then
+		root = addonTable.classes.Addon:Get(root)
+	end
+	
+	local tree = self.trees[root]
+	
+	if tree then
+		return tree
+	else
+		tree = self:New(root)
+		self.trees[root] = tree
+		return tree
+	end
+end
+
+
+function tree:GetLoadBitfield()
+	local bitfield = self.root:GetLoadBitfield()
+	
+	local dependencies = {self.root:GetDependencies()}
+	for i, depName in pairs(dependencies) do
+		local depTree = Tree:Get(depName)
+		
+		if depTree == nil then
+			return 0
+		end
+		
+		bitfield = bit.band(bitfield, depTree:GetLoadBitfield())
+	end
+	
+	return bitfield
+end
+
+
+--	Checks if the tree rooted at the specified addon can be force-loaded.
+--	@param	root	The name or index of the root addon.
+function core:CanForceLoadTree(root)
+	--	TODO: if some addons have already loaded, we have to check 
+	--	forceafter for those and forcebefore for the others
+	return false
+end
+
+
+--	NOTE: any tree that can be loaded on demand is also eligible for force-loading
+--	Checks if the tree rooted at the specified addon can be loaded on demand.
+--	@param	root	The name or index of the root addon.
+function core:CanLoDTree(root)
+	local bitfield = self:GetLoadBitfield()
+	root = self:GetAddon(root)
+	assert(root)
+
+	--	since this will be used recursively, return true if 
+	--	this is already loaded.
+	if root:IsLoaded() then
+		return true
+	end
+	
+	--	true if all dependencies are loaded or LoD
+	
+	if not root:CanLoD() then
+		return false
+	end
+	
+	--	now check dependencies recursively
+	local dependencies = {root:GetDependencies()}
+	for i, depName in pairs(dependencies) do
+		local dep = self:GetAddon(depName)
+		
+		if not dep then
+			return false		--	missing
+		end
+		
+		if not dep:IsLoaded() then
+			if not self:CanLoDTree(depName) then
+				return false
+			end
+		end
+	end
+	
+	return true
+end
+
+
+--	Checks if the tree rooted at the specified addon 
+--	can be loaded if all dependencies are enabled 
+--	the UI is reloaded.
+--	Basically makes sure all dependencies are installed.
+function core:CanReloadTree(root)
+	--	convert root to an Addon object
+	root = self:GetAddon(root)
+	assert(root)
+	
+	if root:IsLoaded() then
+		return true
+		--	FIXME: 	deps may have been disabled
+	end
+	
+	--	TODO: make sure the root isn't incompatible
+	
+	--	now check dependencies recursively
+	--	FIXME: prevent infinite recursion
+
+	local dependencies = {root:GetDependencies()}
+	for i, depName in pairs(dependencies) do
+		local dep = self:GetAddon(depName)
+		
+		if dep == nil then
+			return false		--	missing dependency
+		end
+
+		--	TODO: make sure it's compatible
+	end
+	
+	return true
+end
+
+--	Loads the tree rooted at the specified addon.
+--	FIXME: load the root too or not?
+--	Supports both LoD addons and those that require force-loading.
+function core:LoadTree(addon)
+	--	don't check if the tree can actually be loaded.
+	--	external code should do that itself to check if it 
+	--	should even call this at all.
+
+	if self:ForceLoadAvailable() then
+		--	LoD trees can also be force-loaded
+		self:ForceLoadTree(addon)
+	else
+		self:LoadLoDTree(addon)
+	end
+end
+
+
+--	load the root too, since it may actually be a leaf
+function core:ForceLoadTree(root)
+	root = self:GetAddon(root)
+	assert(root)
+	
+	--	load dependencies
+	local dependencies = {root:GetDependencies(addon)}
+	for i, depName in pairs(dependencies) do
+		self:ForceLoadTree(depName)
+	end
+
+	--	load embeds, if they are available separately
+	local embeds = {root:GetEmbeds(addon)}
+	for i, embedName in pairs(embeds) do
+		if Addon:Exists(embedName) then
+			self:ForceLoadTree(embedName)
+		end
+	end
+	
+	root:ForceLoad()
+end
+
+
+function core:LoadLoDTree(root)
+	root = self:GetAddon(root)
+	assert(root)
+	
+	--	load dependencies
+	local dependencies = {root:GetDependencies(addon)}
+	for i, depName in pairs(dependencies) do
+		self:LoadLoDTree(depName)
+	end
+
+	--	load embeds, if they are available separately
+	local embeds = {root:GetEmbeds(addon)}
+	for i, embedName in pairs(embeds) do
+		if Addon:Exists(embedName) then
+			self:LoadLoDTree(embedName)
+		end
+	end
+	
+	root:LoD()
+end
+
+
+--	I think the problem this solves is a major issue with 
+--	migrating to separate libs. think about it more and document 
+--	here and in project description
+function core:PrepareLoDTree(root)
+	root = self:GetAddon(root)
+	assert(root)
+	
+	--	assume root is LoD
+	
+	--	check dependencies
+	local dependencies = {root:GetDependencies(addon)}
+	for i, depName in pairs(dependencies) do
+		local dep = self:GetAddon(depName)
+		
+		--	assume external code made sure it exists
+		
+		if dep:CanLoD() then
+			--	don't load it now but make sure its dependencies are prepared
+			self:PrepareLoDTree(depName)
+		else
+			--	FIXME: if it's already loaded
+			--	force-load it now so we can load the parent on demand
+			self:ForceLoadTree(depName)
+		end
+	end
+
+	--	prepare embeds, if they are available separately
+	local embeds = {root:GetEmbeds(addon)}	--	FIXME: addon?
+	for i, embedName in pairs(embeds) do
+		local embed = self:GetAddon(embedName)
+		
+		if embed then
+			if embed:CanLoD() then
+				--	don't load it now but make sure its dependencies are prepared
+				self:PrepareLoDTree(embedName)
+			else
+				--	FIXME: if it's already loaded
+				--	force-load it now so we can load the parent on demand
+				self:ForceLoadTree(depName)
+			end
+		end
+	end
+end
+
+
+function Core:PrepareReloadTree(addon)
+	root = self:GetAddon(root)
+	assert(root)
+	
+	root:Enable()
+	
+	--	check dependencies
+	local dependencies = {root:GetDependencies()}
+	for i, depName in pairs(dependencies) do
+		self:PrepareReloadTree(depName)
+	end
+
+	--	prepare embeds, if they are available separately
+	local embeds = {root:GetEmbeds(addon)}
+	for i, embedName in pairs(embeds) do
+		local embed = self:GetAddon(embedName)
+		
+		if embed then
+			self:PrepareReloadTree(embedName)
+		end
+	end
+end
+
+
+function Core:ForceLoadAvailable()
+	return true
+	--	FIXME: use field and a frame registered for PLAYER_LOGIN
+end
--- a/DependencyLoader/bootstrap.lua	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
---	bootstrap.lua
---	Bootstrap code for DependencyLoader, allowing 
---	the user to successfully load it without 
---	explicitly enabling its own dependencies.
-
-
-local addonName, addonTable = ...
-
---	TODO: move and use dependency parsing function here?
-local dependencies = {"LibStub", "LibPrint-1.0", "Ace3"}
-
-local canLoad = true
-for _, addon in pairs(dependencies) do
-	local reason = select(6, GetAddOnInfo(addon))
-	
-	if reason ~= nil and reason ~= "DISABLED" then
-		canLoad = false
-		break
-	end
-end
-
-if not canLoad then
-	print("Can't load DependencyLoader")
-	return
-end
-
-
-print("Loading DependencyLoader")
-
-for _, addon in pairs(dependencies) do
-	EnableAddOn(addon)
-end
-
-EnableAddOn("DependencyLoader_Core")
-LoadAddOn("DependencyLoader_Core")
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader/class.lua	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,24 @@
+--	class.lua
+--	Implements a generic class builder.
+
+
+local addonName, addonTable = ...
+
+--	FIXME: prevent duplicate class definitions
+
+print( string.format([[running %s\class.lua]], addonName) )
+
+addonTable.classes = {}
+
+function addonTable:NewClass(name)
+	local class, prototype, metatable = {}, {}, {}
+	
+	class.prototype = prototype
+	
+	metatable.__index = prototype
+	class.instanceMetatable = metatable
+	
+	self.classes[name] = class
+	
+	return class, prototype
+end
--- a/DependencyLoader/embeds.xml	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
-  <script file="libs\LibStub\LibStub.lua"/>
-  <include file="Ace3.xml"/>
-  <include file="libs\LibBuilder-1.0\load.xml"/>
-  <include file="libs\LibPrint-1.0\load.xml"/>  
-</Ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader/frontend.lua	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,83 @@
+--	main.lua
+--	
+
+local addonName, addonTable = ...
+
+
+local DependencyLoader = LibStub("AceAddon-3.0"):NewAddon(addonName)
+_G[addonName] = DependencyLoader
+
+local libPrint = LibStub("LibPrint-1.0")
+DependencyLoader.printStream = libPrint:NewStream("DependencyLoader", "DpLdr", print)
+DependencyLoader.debugStream = libPrint:NewStream("DependencyLoader", "DpLdr", "mcm")
+
+--	temp
+DependencyLoader.classes = addonTable.classes
+
+function DependencyLoader:Print(...)
+	self.printStream:Print(...)
+end
+
+
+function DependencyLoader:Debug(...)
+	self.debugStream:Print(...)
+end
+
+
+function DependencyLoader:OnInitialize()
+	self:Debug("Initializing and enabling", addonName)
+	self:Enable()
+end
+
+
+function DependencyLoader:OnEnable()
+	self.core = addonTable.classes.Core:New()
+	
+	self:Print("Enabled", addonName)
+	
+	self:FixCurrentAddons()
+end
+
+function DependencyLoader:OnDisable()
+	self:Print("Disabled", addonName)
+end
+
+
+--	TODO: move this into core?
+
+--	Enables any dependencies needed by the addons 
+--	that have already been enabled
+function DependencyLoader:FixCurrentAddons()
+	local core = self.core
+
+	for i=1, GetNumAddOns() do
+		local addon = self.core:GetAddon(i)
+		
+		if addon:IsEnabled() then
+			if addon:IsLoaded() then
+				--	TODO: it might still help to enable its embeds
+			else
+				self:Debug("Checking", addon:GetName())
+				
+				if addonTable.classes.Core:ForceLoadAvailable() then
+					if core:CanForceLoadTree(addon:GetName()) then
+						core:ForceLoadTree(addon:GetName())
+					else
+						print("Can't force load", addon:GetName())
+					end
+				else
+					if core:CanLoDTree(addon:GetName()) then
+						core:PrepareLoDTree(addon:GetName())
+					else
+						print("Couldn't load", addon:GetName(), "on demand.")
+					end
+				end
+			end
+		end
+	end
+end
+		
+		
+		
+		
+		
\ No newline at end of file
--- a/DependencyLoader/load.xml	Sat Dec 04 23:05:34 2010 -0800
+++ b/DependencyLoader/load.xml	Sun Dec 05 00:12:57 2010 -0800
@@ -1,1 +1,1 @@
-<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
	<include file="embeds.xml"/>

  <Script file="bootstrap.lua"/>
</Ui>
\ No newline at end of file
+<ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
  <script file="start.lua"/>
  <script file="class.lua"/>
  
  <script file="Addon.lua"/>
  <script file="Core.lua"/>
  
  <script file="frontend.lua"/>
</ui>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader/start.lua	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,21 @@
+--	start.lua
+--	Initializes components of DependencyLoader
+
+
+local addonName, addonTable = ...
+
+
+print( string.format([[running %s\start.lua]], addonName) )
+
+--	NOTE: We don't have to check if this module's dependencies 
+--	are available: it lists them normally in its .toc file and 
+--	the bootstrap module will take care of enabling them first.
+
+--	prepare output functions
+local lp = LibStub("LibPrint-1.0")
+local printStream = lp:NewStream("DependencyLoader", "DepLoader", "DepLdr", print)
+local debugStream = lp:NewStream("DependencyLoader", "DepLoader", "DepLdr", "mcm")
+
+addonTable.print = function(...) printStream:Print(...) end
+addonTable.debug = function(...) debugStream:Print(...) end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader_Bootstrap/Ace3.xml	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,19 @@
+<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
+  <Script file="libs\Ace3\LibStub\LibStub.lua"/>
+  
+  <Include file="libs\Ace3\CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
+  <Include file="libs\Ace3\AceAddon-3.0\AceAddon-3.0.xml"/>
+  <Include file="libs\Ace3\AceEvent-3.0\AceEvent-3.0.xml"/>
+  <Include file="libs\Ace3\AceTimer-3.0\AceTimer-3.0.xml"/>
+  <Include file="libs\Ace3\AceBucket-3.0\AceBucket-3.0.xml"/>
+  <Include file="libs\Ace3\AceHook-3.0\AceHook-3.0.xml"/>
+  <Include file="libs\Ace3\AceDB-3.0\AceDB-3.0.xml"/>
+  <Include file="libs\Ace3\AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
+  <Include file="libs\Ace3\AceLocale-3.0\AceLocale-3.0.xml"/>
+  <Include file="libs\Ace3\AceConsole-3.0\AceConsole-3.0.xml"/>
+  <Include file="libs\Ace3\AceGUI-3.0\AceGUI-3.0.xml"/>
+  <Include file="libs\Ace3\AceConfig-3.0\AceConfig-3.0.xml"/>
+  <Include file="libs\Ace3\AceComm-3.0\AceComm-3.0.xml"/>
+  <Include file="libs\Ace3\AceTab-3.0\AceTab-3.0.xml"/>
+  <Include file="libs\Ace3\AceSerializer-3.0\AceSerializer-3.0.xml"/>
+</Ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader_Bootstrap/DependencyLoader.toc	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,11 @@
+## Interface: 40000
+
+## Notes: Bootstrap for DependencyLoader_Core
+## Author: mckenziemc
+
+## LoadManagers: !!!LoadFirst, AddonLoader
+## X-LoadFirst: true
+## X-LoadOn-Always: true
+
+
+load.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader_Bootstrap/bootstrap.lua	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,36 @@
+--	bootstrap.lua
+--	Bootstrap code for DependencyLoader, allowing 
+--	the user to successfully load it without 
+--	explicitly enabling its own dependencies.
+
+
+local addonName, addonTable = ...
+
+--	TODO: move and use dependency parsing function here?
+local dependencies = {"LibStub", "LibPrint-1.0", "Ace3"}
+
+local canLoad = true
+for _, addon in pairs(dependencies) do
+	local reason = select(6, GetAddOnInfo(addon))
+	
+	if reason ~= nil and reason ~= "DISABLED" then
+		canLoad = false
+		break
+	end
+end
+
+if not canLoad then
+	print("Can't load DependencyLoader")
+	return
+end
+
+
+print("Loading DependencyLoader")
+
+for _, addon in pairs(dependencies) do
+	EnableAddOn(addon)
+end
+
+EnableAddOn("DependencyLoader_Core")
+LoadAddOn("DependencyLoader_Core")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader_Bootstrap/embeds.xml	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,6 @@
+<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
+  <script file="libs\LibStub\LibStub.lua"/>
+  <include file="Ace3.xml"/>
+  <include file="libs\LibBuilder-1.0\load.xml"/>
+  <include file="libs\LibPrint-1.0\load.xml"/>  
+</Ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader_Bootstrap/load.xml	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,1 @@
+<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
	<include file="embeds.xml"/>

  <Script file="bootstrap.lua"/>
</Ui>
\ No newline at end of file
--- a/DependencyLoader_Core/Addon.lua	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,248 +0,0 @@
---	Addon
---	Represents individual addon modules
-
-
-local addonName, addonTable = ...
-
-
---	NOTE: I assume that the API addon functions are 
---	slightly quicker with an index than with a number.
-
---	TODO: modify the dependency stuff to use the Errata module if available
-
-local Addon, addon = addonTable:NewClass("Addon")
-
-
---	load ability masks
-Addon.loadMasks = {
-	reload = 		bit.lshift(1, 0),	--	can load after reloadui
-	ondemand = 		bit.lshift(1, 1),	--	can load on demand
-	forceafter = 	bit.lshift(1, 2),	--	force load after it would normally be loaded
-	forcebefore = 	bit.lshift(1, 3),	--	force load before it would normally be loaded
-}
-
-
-Addon.addons = {}
-Addon.nameToIndex = {}
-
-
---	Internal function
---	Creates a new Addon object
---	@param	id		Name or index of the addon.
-function Addon:New(id)
-	local instance = {}
-	setmetatable(instance, self.instanceMetatable)
-	
-	if type(id) == "number" then
-		--	TODO: make sure it's in range
-		instance.index = id
-		instance.name = GetAddOnInfo(id)
-	else
-		--	FIXME: allow blizzard addons?
-		local index
-		
-		for i=1,GetNumAddOns() do
-			if GetAddOnInfo(i) == id then
-				index = i
-				break
-			end
-		end
-		
-		if index then
-			instance.name = GetAddOnInfo(id)
-			instance.index = index
-		else
-			error("Addon not found")
-		end
-	end
-	
-	return instance
-end
-
-
----	Retrieves an Addon object.
---	@param	id	Name or index of the addon to retrieve.
---	@return 	The Addon object, or nil if not found.
-function Addon:Get(id)
-	if not self:Exists(id) then
-		return nil
-	end
-	
-	if type(id) == "number" then
-		if self.addons[id] ~= nil then
-			return self.addons[id]
-		end
-		
-		local new = self:New(id)
-		self.addons[new:GetIndex()] = new
-		self.nameToIndex[new:GetName()] = id
-		
-		return new
-	elseif type(id) == "string" then
-		if self.nameToIndex[id] then
-			return self.addons[self.nameToIndex[id] ]
-		end
-		
-		local new = self:New(id)
-		self.addons[new:GetIndex()] = new
-		self.nameToIndex[id] = new:GetIndex()
-		
-		return new
-	end
-end	
-
---	Checks if an addon exists with the specified name.
---	@param	addon	Name of the addon.
---	@return			True if the addon is present, false otherwise.
-function Addon:Exists(addon)
-	if type(addon) == "number" then
-		if addon >= 1 and addon <= GetNumAddOns() then
-			return true
-		else
-			return false
-		end
-	elseif type(addon) == "string" then
-		local status = select(6, GetAddOnInfo(addon))
-		
-		if status == "MISSING" then
-			return false
-		else
-			return true
-		end
-	else
-		error()
-	end
-end
-
-
-function Addon:GetLoadMasks()
-	return self.masks
-end
-
-
-function addon:GetName()
-	return self.name
-end
-
-
-function addon:GetIndex()
-	return self.index
-end
-
-
-function addon:IsEnabled()
-	--	FIXME: written while tired; review later
-	local status = select(6, GetAddOnInfo(self.index))
-	
-	if status == "DISABLED"	then
-		return false
-	else
-		return true
-	end
-end
-
-
-function addon:GetLoadBitfield()
-	local bitfield = 0
-	
-	if self:CanLoad() then
-		bitfield = bitfield + self.masks.reload
-	end
-	
-	if self:CanLoD() then
-		bitfield = bitfield + self.masks.ondemand
-	end
-	
-	if self:CanForceLoadAfter() then
-		bitfield = bitfield + self.masks.forceafter
-	end
-	
-	if self:CanForceLoadBefore() then
-		bitfield = bitfield + self.masks.forcebefore
-	end
-	
-	return bitfield
-end
-
-
----	Checks if the addon is loadable.
---	Considers interface issues, missing, etc. (NYI)
---	Does not check dependencies.
-function addon:CanLoad()
-	--	FIXME: an addon may be present but unloadable if loading out of date addons is disabled.
-	return true
-end
-
-
-function addon:CanLoD()
-	--	FIXME: what will the client say about addons using LoadManagers if the LM was force-loaded?
-	if IsAddOnLoadOnDemand(self.name) then
-		return true
-	else
-		return false
-	end
-end
-
-
-function addon:CanForceLoadAfter()
-	--	TODO: check Errata module
-	return false
-end
-
-
-function addon:CanForceLoadBefore()
-	--	TODO: check Errata module
-	return false		--	TODO: check if there's any reason addons can't be forceloaded
-end
-
-
-function addon:Enable()
-	--	FIXME: delay this till after PLAYER_LOGIN or it'll get force-loaded
-	EnableAddOn(self.name)
-end
-
-
---	NOTE: only call for LoD, not force-loading
-function addon:Load()
-	assert(self:CanLoD())
-	
-	EnableAddOn(self.name)
-	LoadAddOn(self.name)
-end
-
-
-function addon:ForceLoad()
-	assert(self:CanForceLoad())
-	--	TODO: make sure force-loading is available at this time
-	
-	EnableAddOn(self.name)	--	This should cause the game to also load this addon
-end
-
-
-function addon:GetDependencies()
-	--	TODO: consider no-lib embeds as deps?
-	return GetAddOnDependencies(self.index)
-end
-
-
-function addon:GetEmbeds()
-	local embeds = {}
-	
-	local embedString = GetAddOnMetadata(self.name, "X-Embeds")
-	
-	if embedString then
-		for match in string.gmatch(embedString, "[^,%s]+") do
-			table.insert(embeds, match)
-		end
-	end
-	
-	return unpack(embeds)
-end
-
-function addon:IsLoaded()
-	if IsAddOnLoaded(self.index) then
-		return true
-	else
-		return false
-	end
-end
--- a/DependencyLoader_Core/Core.lua	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,293 +0,0 @@
-
-
-
-local addonName, addonTable = ...
-
-
-local Core, core = addonTable:NewClass("Core")
-
-
-function Core:New()
-	local instance = {}
-	setmetatable(instance, self.instanceMetatable)
-	
-	instance.addons = {}
-	instance.nameToIndex = {}
-	
-	for i=1,GetNumAddOns() do
-		local newAddon = Addon:New(i)
-		
-		instance.addons[i] = newAddon
-		instance.nameToIndex[newAddon:GetName()] = i
-	end
-	
-	--	TODO: enable dependencies for any addons that have already loaded
-	
-	return instance
-end
-
-
---	@param	addon	Name or index of the addon to retrieve.
---	@return 		The addon object, or nil if not found
-function core:GetAddon(addon)
-	if not Addon:Exists(addon) then
-		return nil
-	end
-	
-	local index
-
-	if type(addon) == "string" then
-		index = self.nameToIndex[addon]
-	elseif type(addon) == "number" then
-		index = addon
-	end
-	
-	return self.addons[index]
-end	
-
-
---	Checks if the tree rooted at the specified addon can be force-loaded.
---	@param	root	The name or index of the root addon.
-function core:CanForceLoadTree(root)
-	--	convert root to an Addon object
-	root = self:GetAddon(root)
-	assert(root)
-	
-	if root:IsLoaded() then
-		return true
-	end
-	
-	--	check if the root itself can be force-loaded
-	if not root:CanForceLoad() then
-		return false
-	end
-	
-	--	now check dependencies recursively
-	--	FIXME: prevent infinite recursion
-
-	local dependencies = {root:GetDependencies()}
-	for i, depName in pairs(dependencies) do
-		local dep = self:GetAddon(depName)
-		
-		if dep == nil then
-			return false		--	missing dependency
-		end
-		
-		--	if it's already loaded then skip to next one
-		if not dep:IsLoaded() then
-			if not self:CanForceLoadTree(depName) then
-				return false
-			end
-		end
-	end
-	
-	return true
-end
-
---	NOTE: any tree that can be loaded on demand is also eligible for force-loading
---	Checks if the tree rooted at the specified addon can be loaded on demand.
---	@param	root	The name or index of the root addon.
-function core:CanLoDTree(root)
-	root = self:GetAddon(root)
-	assert(root)
-
-	--	since this will be used recursively, return true if 
-	--	this is already loaded.
-	if root:IsLoaded() then
-		return true
-	end
-	
-	--	true if all dependencies are loaded or LoD
-	
-	if not root:CanLoD() then
-		return false
-	end
-	
-	--	now check dependencies recursively
-	local dependencies = {root:GetDependencies()}
-	for i, depName in pairs(dependencies) do
-		local dep = self:GetAddon(depName)
-		
-		if not dep then
-			return false		--	missing
-		end
-		
-		if not dep:IsLoaded() then
-			if not self:CanLoDTree(depName) then
-				return false
-			end
-		end
-	end
-	
-	return true
-end
-
-
---	Checks if the tree rooted at the specified addon 
---	can be loaded if all dependencies are enabled 
---	the UI is reloaded.
---	Basically makes sure all dependencies are installed.
-function core:CanReloadTree(root)
-	--	convert root to an Addon object
-	root = self:GetAddon(root)
-	assert(root)
-	
-	if root:IsLoaded() then
-		return true
-		--	FIXME: 	deps may have been disabled
-	end
-	
-	--	TODO: make sure the root isn't incompatible
-	
-	--	now check dependencies recursively
-	--	FIXME: prevent infinite recursion
-
-	local dependencies = {root:GetDependencies()}
-	for i, depName in pairs(dependencies) do
-		local dep = self:GetAddon(depName)
-		
-		if dep == nil then
-			return false		--	missing dependency
-		end
-
-		--	TODO: make sure it's compatible
-	end
-	
-	return true
-end
-
---	Loads the tree rooted at the specified addon.
---	FIXME: load the root too or not?
---	Supports both LoD addons and those that require force-loading.
-function core:LoadTree(addon)
-	--	don't check if the tree can actually be loaded.
-	--	external code should do that itself to check if it 
-	--	should even call this at all.
-
-	if self:ForceLoadAvailable() then
-		--	LoD trees can also be force-loaded
-		self:ForceLoadTree(addon)
-	else
-		self:LoadLoDTree(addon)
-	end
-end
-
-
---	load the root too, since it may actually be a leaf
-function core:ForceLoadTree(root)
-	root = self:GetAddon(root)
-	assert(root)
-	
-	--	load dependencies
-	local dependencies = {root:GetDependencies(addon)}
-	for i, depName in pairs(dependencies) do
-		self:ForceLoadTree(depName)
-	end
-
-	--	load embeds, if they are available separately
-	local embeds = {root:GetEmbeds(addon)}
-	for i, embedName in pairs(embeds) do
-		if Addon:Exists(embedName) then
-			self:ForceLoadTree(embedName)
-		end
-	end
-	
-	root:ForceLoad()
-end
-
-
-function core:LoadLoDTree(root)
-	root = self:GetAddon(root)
-	assert(root)
-	
-	--	load dependencies
-	local dependencies = {root:GetDependencies(addon)}
-	for i, depName in pairs(dependencies) do
-		self:LoadLoDTree(depName)
-	end
-
-	--	load embeds, if they are available separately
-	local embeds = {root:GetEmbeds(addon)}
-	for i, embedName in pairs(embeds) do
-		if Addon:Exists(embedName) then
-			self:LoadLoDTree(embedName)
-		end
-	end
-	
-	root:LoD()
-end
-
-
---	I think the problem this solves is a major issue with 
---	migrating to separate libs. think about it more and document 
---	here and in project description
-function core:PrepareLoDTree(root)
-	root = self:GetAddon(root)
-	assert(root)
-	
-	--	assume root is LoD
-	
-	--	check dependencies
-	local dependencies = {root:GetDependencies(addon)}
-	for i, depName in pairs(dependencies) do
-		local dep = self:GetAddon(depName)
-		
-		--	assume external code made sure it exists
-		
-		if dep:CanLoD() then
-			--	don't load it now but make sure its dependencies are prepared
-			self:PrepareLoDTree(depName)
-		else
-			--	FIXME: if it's already loaded
-			--	force-load it now so we can load the parent on demand
-			self:ForceLoadTree(depName)
-		end
-	end
-
-	--	prepare embeds, if they are available separately
-	local embeds = {root:GetEmbeds(addon)}	--	FIXME: addon?
-	for i, embedName in pairs(embeds) do
-		local embed = self:GetAddon(embedName)
-		
-		if embed then
-			if embed:CanLoD() then
-				--	don't load it now but make sure its dependencies are prepared
-				self:PrepareLoDTree(embedName)
-			else
-				--	FIXME: if it's already loaded
-				--	force-load it now so we can load the parent on demand
-				self:ForceLoadTree(depName)
-			end
-		end
-	end
-end
-
-
-function Core:PrepareReloadTree(addon)
-	root = self:GetAddon(root)
-	assert(root)
-	
-	root:Enable()
-	
-	--	check dependencies
-	local dependencies = {root:GetDependencies()}
-	for i, depName in pairs(dependencies) do
-		self:PrepareReloadTree(depName)
-	end
-
-	--	prepare embeds, if they are available separately
-	local embeds = {root:GetEmbeds(addon)}
-	for i, embedName in pairs(embeds) do
-		local embed = self:GetAddon(embedName)
-		
-		if embed then
-			self:PrepareReloadTree(embedName)
-		end
-	end
-end
-
-
-function Core:ForceLoadAvailable()
-	return true
-	--	FIXME: use field and a frame registered for PLAYER_LOGIN
-end
--- a/DependencyLoader_Core/DependencyLoader_Core.toc	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-## Interface: 40000
-
-#  TODO: actually explain what DependencyLoader does.
-## Notes: Core module of DependencyLoader
-## Author: mckenziemc
-
-#  TODO: figure out some way to allow AddonLoader 
-#  to work with DependencyLoader
-## Dependencies: DependencyLoader, LibStub, LibPrint-1.0, Ace3
-
-## LoadOnDemand: 1
-
-
-load.xml
--- a/DependencyLoader_Core/Tree.lua	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,287 +0,0 @@
---	Tree
---	Represents a recursive "tree" of addon 
---	dependencies rooted at a specific addon.
-
-
-local addonName, addonTable = ...
-
-
---	TODO: prevent infinite loops in the recursive functions
-
-
-local Tree, tree = addonTable:NewClass("Tree")
-
-
-Tree.trees = {}
-
---	internal
---	Creates a new tree object
---	@param	root	Name, index, or Addon object of the root addon.
-function Tree:New(root)
-	if type(root) ~= "table" then
-		root = addonTable.classes.Addon:Get(root)
-	end
-	
-	local instance = {}
-	setmetatable(instance, self.instanceMetatable)
-	
-	instance.root = root
-	
-	return instance
-end
-
-
----	Retrieves the tree rooted at the specified addon
---	@param	root	Name, index, or Addon object of the root.
-function Tree:Get(root)
-	if type(root) ~= "table" then
-		root = addonTable.classes.Addon:Get(root)
-	end
-	
-	local tree = self.trees[root]
-	
-	if tree then
-		return tree
-	else
-		tree = self:New(root)
-		self.trees[root] = tree
-		return tree
-	end
-end
-
-
-function tree:GetLoadBitfield()
-	local bitfield = self.root:GetLoadBitfield()
-	
-	local dependencies = {self.root:GetDependencies()}
-	for i, depName in pairs(dependencies) do
-		local depTree = Tree:Get(depName)
-		
-		if depTree == nil then
-			return 0
-		end
-		
-		bitfield = bit.band(bitfield, depTree:GetLoadBitfield())
-	end
-	
-	return bitfield
-end
-
-
---	Checks if the tree rooted at the specified addon can be force-loaded.
---	@param	root	The name or index of the root addon.
-function core:CanForceLoadTree(root)
-	--	TODO: if some addons have already loaded, we have to check 
-	--	forceafter for those and forcebefore for the others
-	return false
-end
-
-
---	NOTE: any tree that can be loaded on demand is also eligible for force-loading
---	Checks if the tree rooted at the specified addon can be loaded on demand.
---	@param	root	The name or index of the root addon.
-function core:CanLoDTree(root)
-	local bitfield = self:GetLoadBitfield()
-	root = self:GetAddon(root)
-	assert(root)
-
-	--	since this will be used recursively, return true if 
-	--	this is already loaded.
-	if root:IsLoaded() then
-		return true
-	end
-	
-	--	true if all dependencies are loaded or LoD
-	
-	if not root:CanLoD() then
-		return false
-	end
-	
-	--	now check dependencies recursively
-	local dependencies = {root:GetDependencies()}
-	for i, depName in pairs(dependencies) do
-		local dep = self:GetAddon(depName)
-		
-		if not dep then
-			return false		--	missing
-		end
-		
-		if not dep:IsLoaded() then
-			if not self:CanLoDTree(depName) then
-				return false
-			end
-		end
-	end
-	
-	return true
-end
-
-
---	Checks if the tree rooted at the specified addon 
---	can be loaded if all dependencies are enabled 
---	the UI is reloaded.
---	Basically makes sure all dependencies are installed.
-function core:CanReloadTree(root)
-	--	convert root to an Addon object
-	root = self:GetAddon(root)
-	assert(root)
-	
-	if root:IsLoaded() then
-		return true
-		--	FIXME: 	deps may have been disabled
-	end
-	
-	--	TODO: make sure the root isn't incompatible
-	
-	--	now check dependencies recursively
-	--	FIXME: prevent infinite recursion
-
-	local dependencies = {root:GetDependencies()}
-	for i, depName in pairs(dependencies) do
-		local dep = self:GetAddon(depName)
-		
-		if dep == nil then
-			return false		--	missing dependency
-		end
-
-		--	TODO: make sure it's compatible
-	end
-	
-	return true
-end
-
---	Loads the tree rooted at the specified addon.
---	FIXME: load the root too or not?
---	Supports both LoD addons and those that require force-loading.
-function core:LoadTree(addon)
-	--	don't check if the tree can actually be loaded.
-	--	external code should do that itself to check if it 
-	--	should even call this at all.
-
-	if self:ForceLoadAvailable() then
-		--	LoD trees can also be force-loaded
-		self:ForceLoadTree(addon)
-	else
-		self:LoadLoDTree(addon)
-	end
-end
-
-
---	load the root too, since it may actually be a leaf
-function core:ForceLoadTree(root)
-	root = self:GetAddon(root)
-	assert(root)
-	
-	--	load dependencies
-	local dependencies = {root:GetDependencies(addon)}
-	for i, depName in pairs(dependencies) do
-		self:ForceLoadTree(depName)
-	end
-
-	--	load embeds, if they are available separately
-	local embeds = {root:GetEmbeds(addon)}
-	for i, embedName in pairs(embeds) do
-		if Addon:Exists(embedName) then
-			self:ForceLoadTree(embedName)
-		end
-	end
-	
-	root:ForceLoad()
-end
-
-
-function core:LoadLoDTree(root)
-	root = self:GetAddon(root)
-	assert(root)
-	
-	--	load dependencies
-	local dependencies = {root:GetDependencies(addon)}
-	for i, depName in pairs(dependencies) do
-		self:LoadLoDTree(depName)
-	end
-
-	--	load embeds, if they are available separately
-	local embeds = {root:GetEmbeds(addon)}
-	for i, embedName in pairs(embeds) do
-		if Addon:Exists(embedName) then
-			self:LoadLoDTree(embedName)
-		end
-	end
-	
-	root:LoD()
-end
-
-
---	I think the problem this solves is a major issue with 
---	migrating to separate libs. think about it more and document 
---	here and in project description
-function core:PrepareLoDTree(root)
-	root = self:GetAddon(root)
-	assert(root)
-	
-	--	assume root is LoD
-	
-	--	check dependencies
-	local dependencies = {root:GetDependencies(addon)}
-	for i, depName in pairs(dependencies) do
-		local dep = self:GetAddon(depName)
-		
-		--	assume external code made sure it exists
-		
-		if dep:CanLoD() then
-			--	don't load it now but make sure its dependencies are prepared
-			self:PrepareLoDTree(depName)
-		else
-			--	FIXME: if it's already loaded
-			--	force-load it now so we can load the parent on demand
-			self:ForceLoadTree(depName)
-		end
-	end
-
-	--	prepare embeds, if they are available separately
-	local embeds = {root:GetEmbeds(addon)}	--	FIXME: addon?
-	for i, embedName in pairs(embeds) do
-		local embed = self:GetAddon(embedName)
-		
-		if embed then
-			if embed:CanLoD() then
-				--	don't load it now but make sure its dependencies are prepared
-				self:PrepareLoDTree(embedName)
-			else
-				--	FIXME: if it's already loaded
-				--	force-load it now so we can load the parent on demand
-				self:ForceLoadTree(depName)
-			end
-		end
-	end
-end
-
-
-function Core:PrepareReloadTree(addon)
-	root = self:GetAddon(root)
-	assert(root)
-	
-	root:Enable()
-	
-	--	check dependencies
-	local dependencies = {root:GetDependencies()}
-	for i, depName in pairs(dependencies) do
-		self:PrepareReloadTree(depName)
-	end
-
-	--	prepare embeds, if they are available separately
-	local embeds = {root:GetEmbeds(addon)}
-	for i, embedName in pairs(embeds) do
-		local embed = self:GetAddon(embedName)
-		
-		if embed then
-			self:PrepareReloadTree(embedName)
-		end
-	end
-end
-
-
-function Core:ForceLoadAvailable()
-	return true
-	--	FIXME: use field and a frame registered for PLAYER_LOGIN
-end
--- a/DependencyLoader_Core/class.lua	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
---	class.lua
---	Implements a generic class builder.
-
-
-local addonName, addonTable = ...
-
---	FIXME: prevent duplicate class definitions
-
-print( string.format([[running %s\class.lua]], addonName) )
-
-addonTable.classes = {}
-
-function addonTable:NewClass(name)
-	local class, prototype, metatable = {}, {}, {}
-	
-	class.prototype = prototype
-	
-	metatable.__index = prototype
-	class.instanceMetatable = metatable
-	
-	self.classes[name] = class
-	
-	return class, prototype
-end
--- a/DependencyLoader_Core/frontend.lua	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
---	main.lua
---	
-
-local addonName, addonTable = ...
-
-
-local DependencyLoader = LibStub("AceAddon-3.0"):NewAddon(addonName)
-_G[addonName] = DependencyLoader
-
-local libPrint = LibStub("LibPrint-1.0")
-DependencyLoader.printStream = libPrint:NewStream("DependencyLoader", "DpLdr", print)
-DependencyLoader.debugStream = libPrint:NewStream("DependencyLoader", "DpLdr", "mcm")
-
---	temp
-DependencyLoader.classes = addonTable.classes
-
-function DependencyLoader:Print(...)
-	self.printStream:Print(...)
-end
-
-
-function DependencyLoader:Debug(...)
-	self.debugStream:Print(...)
-end
-
-
-function DependencyLoader:OnInitialize()
-	self:Debug("Initializing and enabling", addonName)
-	self:Enable()
-end
-
-
-function DependencyLoader:OnEnable()
-	self.core = addonTable.classes.Core:New()
-	
-	self:Print("Enabled", addonName)
-	
-	self:FixCurrentAddons()
-end
-
-function DependencyLoader:OnDisable()
-	self:Print("Disabled", addonName)
-end
-
-
---	TODO: move this into core?
-
---	Enables any dependencies needed by the addons 
---	that have already been enabled
-function DependencyLoader:FixCurrentAddons()
-	local core = self.core
-
-	for i=1, GetNumAddOns() do
-		local addon = self.core:GetAddon(i)
-		
-		if addon:IsEnabled() then
-			if addon:IsLoaded() then
-				--	TODO: it might still help to enable its embeds
-			else
-				self:Debug("Checking", addon:GetName())
-				
-				if addonTable.classes.Core:ForceLoadAvailable() then
-					if core:CanForceLoadTree(addon:GetName()) then
-						core:ForceLoadTree(addon:GetName())
-					else
-						print("Can't force load", addon:GetName())
-					end
-				else
-					if core:CanLoDTree(addon:GetName()) then
-						core:PrepareLoDTree(addon:GetName())
-					else
-						print("Couldn't load", addon:GetName(), "on demand.")
-					end
-				end
-			end
-		end
-	end
-end
-		
-		
-		
-		
-		
\ No newline at end of file
--- a/DependencyLoader_Core/load.xml	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-<ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
  <script file="start.lua"/>
  <script file="class.lua"/>
  
  <script file="Addon.lua"/>
  <script file="Core.lua"/>
  
  <script file="frontend.lua"/>
</ui>
\ No newline at end of file
--- a/DependencyLoader_Core/start.lua	Sat Dec 04 23:05:34 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
---	start.lua
---	Initializes components of DependencyLoader
-
-
-local addonName, addonTable = ...
-
-
-print( string.format([[running %s\start.lua]], addonName) )
-
---	NOTE: We don't have to check if this module's dependencies 
---	are available: it lists them normally in its .toc file and 
---	the bootstrap module will take care of enabling them first.
-
---	prepare output functions
-local lp = LibStub("LibPrint-1.0")
-local printStream = lp:NewStream("DependencyLoader", "DepLoader", "DepLdr", print)
-local debugStream = lp:NewStream("DependencyLoader", "DepLoader", "DepLdr", "mcm")
-
-addonTable.print = function(...) printStream:Print(...) end
-addonTable.debug = function(...) debugStream:Print(...) end
-