Quantcast

Build 5.4.1

Jennifer [02-01-18 - 12:05]
Build 5.4.1
Filename
Jamba-AdvancedLoot/Jamba-AdvancedLoot.toc
Jamba-AdvancedLoot/JambaAdvancedLoot.lua
Jamba-Curr/Jamba-Curr.toc
Jamba-Curr/JambaCurr.lua
Jamba-Curr/Locales/JambaCurr-Locale-enUS.lua
Jamba-Curr/Locales/Locales.xml
Jamba-DisplayTeam/Jamba-DisplayTeam.toc
Jamba-DisplayTeam/JambaDisplayTeam.lua
Jamba-DisplayTeam/JambaDisplayTeam.lua.old
Jamba-DisplayTeam/Locales/JambaDisplayTeam-Locale-enUS.lua
Jamba-DisplayTeam/Locales/Locales.xml
Jamba-FTL/Jamba-FTL.toc
Jamba-Follow/Jamba-Follow.toc
Jamba-Follow/JambaFollow.lua
Jamba-Follow/Locales/JambaFollow-Locale-enUS.lua
Jamba-Follow/Locales/Locales.xml
Jamba-ItemUse/Bindings.xml
Jamba-ItemUse/Jamba-ItemUse.toc
Jamba-ItemUse/JambaItemUse.lua
Jamba-ItemUse/Locales/JambaItemUse-Locale-enUS.lua
Jamba-ItemUse/Locales/Locales.xml
Jamba-Macro/Jamba-Macro.toc
Jamba-Macro/JambaMacro.lua
Jamba-Macro/Locales/Jamba-Macro-Locale-enUS.lua
Jamba-Macro/Locales/Locales.xml
Jamba-Mount/Jamba-Mount.toc
Jamba-Mount/JambaMount.lua
Jamba-Mount/Locales/JambaMount-Locale-enUS.lua
Jamba-Mount/Locales/Locales.xml
Jamba-Purchase/Jamba-Purchase.toc
Jamba-Purchase/JambaPurchase.lua
Jamba-Purchase/Locales/JambaPurchase-Locale-enUS.lua
Jamba-Purchase/Locales/Locales.xml
Jamba-Quest/Jamba-Quest.toc
Jamba-Quest/JambaQuest.lua
Jamba-Quest/Locales/JambaQuest-Locale-enUS.lua
Jamba-Quest/Locales/Locales.xml
Jamba-QuestWatcher/Jamba-QuestWatcher.toc
Jamba-QuestWatcher/JambaQuestWatcher.lua
Jamba-QuestWatcher/Locales/JambaQuestWatcher-Locale-enUS.lua
Jamba-QuestWatcher/Locales/Locales.xml
Jamba-Sell/Jamba-Sell.toc
Jamba-Sell/JambaSell.lua
Jamba-Sell/Locales/JambaSell-Locale-enUS.lua
Jamba-Sell/Locales/Locales.xml
Jamba-Talk/Jamba-Talk.toc
Jamba-Talk/JambaTalk.lua
Jamba-Talk/Locales/JambaTalk-Locale-enUS.lua
Jamba-Talk/Locales/Locales.xml
Jamba-Target/Bindings.xml
Jamba-Target/Jamba-Target.toc
Jamba-Target/JambaTarget.lua
Jamba-Target/Locales/JambaTarget-Locale-enUS.lua
Jamba-Target/Locales/Locales.xml
Jamba-Taxi/Jamba-Taxi.toc
Jamba-Taxi/JambaTaxi.lua
Jamba-Taxi/Locales/JambaTaxi-Locale-enUS.lua
Jamba-Taxi/Locales/Locales.xml
Jamba-Toon/Jamba-Toon.toc
Jamba-Toon/JambaToon.lua
Jamba-Toon/Locales/JambaToon-Locale-enUS.lua
Jamba-Toon/Locales/Locales.xml
Jamba-Trade/Jamba-Trade.toc
Jamba-Trade/JambaTrade.lua
Jamba-Trade/Locales/JambaTrade-Locale-enUS.lua
Jamba-Trade/Locales/Locales.xml
Jamba/.pkgmeta
Jamba/AceGUIContainer-JambaWindow.lua
Jamba/AceGUIWidget-JambaContinueLabel.lua
Jamba/AceGUIWidget-JambaNormalLabel.lua
Jamba/Bindings.xml
Jamba/CHANGELOG.txt
Jamba/Jamba.toc
Jamba/JambaEmbeds.xml
Jamba/JambaMessage.lua
Jamba/JambaModule.lua
Jamba/JambaTag.lua
Jamba/JambaTeam.lua
Jamba/JambaUtilities.lua
Jamba/LICENSE
Jamba/LibActionButton-1.0.lua
Jamba/LibActionButtonJamba-1.0-57.lua
Jamba/LibActionButtonJamba-1.0-66.lua
Jamba/LibActionButtonJamba-1.0.lua
Jamba/LibActionButtonJamba-1.00.lua
Jamba/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
Jamba/Libs/LibButtonGlow-1.0/LibButtonGlow-1.0.toc
Jamba/Libs/LibStub/LibStub.toc
Jamba/Locales/JambaCore-Locale-enUS.lua
Jamba/Locales/JambaMessage-Locale-enUS.lua
Jamba/Locales/JambaTag-Locale-enUS.lua
Jamba/Locales/JambaTeam-Locale-enUS.lua
Jamba/Locales/Locales.xml
diff --git a/Jamba-AdvancedLoot/Jamba-AdvancedLoot.toc b/Jamba-AdvancedLoot/Jamba-AdvancedLoot.toc
index 5e3882a..e69d96a 100644
--- a/Jamba-AdvancedLoot/Jamba-AdvancedLoot.toc
+++ b/Jamba-AdvancedLoot/Jamba-AdvancedLoot.toc
@@ -2,7 +2,7 @@
 ## Title: Jamba-AdvancedLoot
 ## Notes: Jamba-AdvancedLoot
 ## Author: Ebony, Former Author: Jafula & Max Schilling
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-AdvancedLoot/JambaAdvancedLoot.lua b/Jamba-AdvancedLoot/JambaAdvancedLoot.lua
index 4883952..efe0845 100644
--- a/Jamba-AdvancedLoot/JambaAdvancedLoot.lua
+++ b/Jamba-AdvancedLoot/JambaAdvancedLoot.lua
@@ -558,9 +558,8 @@ end
 -- Called when the addon is enabled.
 function AJM:OnEnable()
 	AJM:SetAutoLoot()
-	--AJM:RegisterEvent( "LOOT_OPENED" )
+	AJM:RegisterEvent( "LOOT_OPENED" )
 	AJM:RegisterEvent( "GROUP_ROSTER_UPDATE" )
-	AJM:RegisterEvent( "LOOT_READY" )
 	AJM:RegisterMessage( JambaApi.MESSAGE_MESSAGE_AREAS_CHANGED, "OnMessageAreasChanged" )
 end

@@ -648,14 +647,6 @@ function AJM:GROUP_ROSTER_UPDATE( event, ... )
 	AJM:SetAutoLoot()
 end

-function AJM:LOOT_READY()
-	if AJM.db.advancedLoot == true then
-		if IsInGroup() then
-			AJM:DoAdvancedLoot()
-		end
-	end
-end
-

 function AJM:LOOT_OPENED()
 	if AJM.db.advancedLoot == true then
diff --git a/Jamba-Curr/Jamba-Curr.toc b/Jamba-Curr/Jamba-Curr.toc
index 2a8c06a..52e7602 100644
--- a/Jamba-Curr/Jamba-Curr.toc
+++ b/Jamba-Curr/Jamba-Curr.toc
@@ -2,7 +2,7 @@
 ## Title: JambaCurr
 ## Notes: JambaCurr
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Curr/JambaCurr.lua b/Jamba-Curr/JambaCurr.lua
index a030892..7815393 100644
--- a/Jamba-Curr/JambaCurr.lua
+++ b/Jamba-Curr/JambaCurr.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

@@ -66,8 +66,7 @@ AJM.currTypes.LegionfallWarSupplies = 1342
 --7.2.5
 AJM.currTypes.CoinsOfAir = 1416
 --7.3
-AJM.currTypes.WrithingEssence = 1501
-AJM.currTypes.ArgusWaystone = 1506
+AJM.currTypes.WakeningEssence = 1533
 AJM.currTypes.VeiledArgunite = 1508

 -------------------------------------- End of edit --------------------------------------------------------------
diff --git a/Jamba-Curr/Locales/JambaCurr-Locale-enUS.lua b/Jamba-Curr/Locales/JambaCurr-Locale-enUS.lua
index ef49c98..a7681c3 100644
--- a/Jamba-Curr/Locales/JambaCurr-Locale-enUS.lua
+++ b/Jamba-Curr/Locales/JambaCurr-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Curr/Locales/Locales.xml b/Jamba-Curr/Locales/Locales.xml
index c60cd2b..a8aa115 100644
--- a/Jamba-Curr/Locales/Locales.xml
+++ b/Jamba-Curr/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-DisplayTeam/Jamba-DisplayTeam.toc b/Jamba-DisplayTeam/Jamba-DisplayTeam.toc
index beae5c3..017424a 100644
--- a/Jamba-DisplayTeam/Jamba-DisplayTeam.toc
+++ b/Jamba-DisplayTeam/Jamba-DisplayTeam.toc
@@ -2,7 +2,7 @@
 ## Title: Jamba-DisplayTeam
 ## Notes: Jamba-DisplayTeam
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-DisplayTeam/JambaDisplayTeam.lua b/Jamba-DisplayTeam/JambaDisplayTeam.lua
index 8a4d81b..3d81bb2 100644
--- a/Jamba-DisplayTeam/JambaDisplayTeam.lua
+++ b/Jamba-DisplayTeam/JambaDisplayTeam.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

@@ -1318,18 +1318,7 @@ local function SettingsCreateDisplayOptions( top )
 		L["Show Team List Title"]
 	)
 	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsCharactersPerBar = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Characters Per Bar"]
-	)
-	AJM.settingsControl.displayOptionsCharactersPerBar:SetSliderValues( 1, 10, 1 )
-	AJM.settingsControl.displayOptionsCharactersPerBar:SetCallback( "OnValueChanged", AJM.SettingsChangeCharactersPerBar )
-	--movingTop = movingTop - sliderHeight - sectionSpacing
-
---[[	AJM.settingsControl.displayOptionsCheckBoxStackVertically = JambaHelperSettings:CreateCheckBox(
+	AJM.settingsControl.displayOptionsCheckBoxStackVertically = JambaHelperSettings:CreateCheckBox(
 		AJM.settingsControl,
 		headingWidth,
 		left,
@@ -1339,6 +1328,9 @@ local function SettingsCreateDisplayOptions( top )
 		L["Stack Bars Vertically"]
 	)
 	movingTop = movingTop - checkBoxHeight - verticalSpacing
+
+--[[	movingTop = movingTop - sliderHeight - sectionSpacing
+
 	AJM.settingsControl.displayOptionsCheckBoxTeamHorizontal = JambaHelperSettings:CreateCheckBox(
 		AJM.settingsControl,
 		headingWidth,
@@ -1348,10 +1340,21 @@ local function SettingsCreateDisplayOptions( top )
 		AJM.SettingsToggleTeamHorizontal,
 		L["Display Team List Horizontally"]
 	)
+
 	movingTop = movingTop - checkBoxHeight - verticalSpacing
-]]
+ ]]
+
+	AJM.settingsControl.displayOptionsCharactersPerBar = JambaHelperSettings:CreateSlider(
+		AJM.settingsControl,
+		halfWidthSlider,
+		left,
+		movingTop,
+		L["Characters Per Bar"]
+	)
+	AJM.settingsControl.displayOptionsCharactersPerBar:SetSliderValues( 1, 10, 1 )
+	AJM.settingsControl.displayOptionsCharactersPerBar:SetCallback( "OnValueChanged", AJM.SettingsChangeCharactersPerBar )

-	--movingTop = movingTop - checkBoxHeight - verticalSpacing
+
 	AJM.settingsControl.displayOptionsTeamListScaleSlider = JambaHelperSettings:CreateSlider(
 		AJM.settingsControl,
 		halfWidthSlider,
@@ -1362,6 +1365,7 @@ local function SettingsCreateDisplayOptions( top )
 	AJM.settingsControl.displayOptionsTeamListScaleSlider:SetSliderValues( 0.5, 2, 0.01 )
 	AJM.settingsControl.displayOptionsTeamListScaleSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeScale )
 	movingTop = movingTop - sliderHeight - verticalSpacing
+
 	AJM.settingsControl.displayOptionsTeamListTransparencySlider = JambaHelperSettings:CreateSlider(
 		AJM.settingsControl,
 		halfWidthSlider,
@@ -1806,7 +1810,7 @@ function AJM:SettingsRefresh()
 	AJM.settingsControl.displayOptionsCheckBoxHideTeamListInCombat:SetValue( AJM.db.hideTeamListInCombat )
 	AJM.settingsControl.displayOptionsCheckBoxEnableClique:SetValue( AJM.db.enableClique )
 	AJM.settingsControl.displayOptionsCharactersPerBar:SetValue( AJM.db.charactersPerRow )
---	AJM.settingsControl.displayOptionsCheckBoxStackVertically:SetValue( AJM.db.barsAreStackedVertically )
+	AJM.settingsControl.displayOptionsCheckBoxStackVertically:SetValue( AJM.db.barsAreStackedVertically )
 --	AJM.settingsControl.displayOptionsCheckBoxTeamHorizontal:SetValue( AJM.db.teamListHorizontal )
 	AJM.settingsControl.displayOptionsCheckBoxShowListTitle:SetValue( AJM.db.showListTitle )
 	AJM.settingsControl.displayOptionsCheckBoxOlnyShowInParty:SetValue( AJM.db.olnyShowInParty )
@@ -1863,7 +1867,7 @@ function AJM:SettingsRefresh()
 		AJM.settingsControl.displayOptionsCheckBoxHideTeamListInCombat:SetDisabled( not AJM.db.showTeamList )
 		AJM.settingsControl.displayOptionsCheckBoxEnableClique:SetDisabled( not AJM.db.showTeamList )
 		AJM.settingsControl.displayOptionsCharactersPerBar:SetDisabled(not AJM.db.showTeamList )
-		--AJM.settingsControl.displayOptionsCheckBoxStackVertically:SetDisabled( not AJM.db.showTeamList )
+		AJM.settingsControl.displayOptionsCheckBoxStackVertically:SetDisabled( not AJM.db.showTeamList )
 		--AJM.settingsControl.displayOptionsCheckBoxTeamHorizontal:SetDisabled( not AJM.db.showTeamList )
 		AJM.settingsControl.displayOptionsCheckBoxShowListTitle:SetDisabled( not AJM.db.showTeamList )
 		AJM.settingsControl.displayOptionsCheckBoxOlnyShowInParty:SetDisabled( not AJM.db.showTeamList )
@@ -1940,8 +1944,8 @@ function AJM:JambaOnSettingsReceived( characterName, settings )
 		AJM.db.hideTeamListInCombat = settings.hideTeamListInCombat
 		AJM.db.enableClique = settings.enableClique
 		AJM.db.charactersPerRow = settings.charactersPerRow
-		--AJM.db.barsAreStackedVertically = settings.barsAreStackedVertically
-		--AJM.db.teamListHorizontal = settings.teamListHorizontal
+		AJM.db.barsAreStackedVertically = settings.barsAreStackedVertically
+		AJM.db.teamListHorizontal = settings.teamListHorizontal
 		AJM.db.showListTitle = settings.showListTitle
 		AJM.db.olnyShowInParty = settings.olnyShowInParty
 		AJM.db.healthManaOutOfParty = settings.healthManaOutOfParty
@@ -2039,12 +2043,13 @@ function AJM:SettingsChangeCharactersPerBar( event, value )
 	AJM:SettingsRefresh()
 end

---[[
+
 function AJM:SettingsToggleStackVertically( event, checked )
-	AJM.db.barsAreStackedVertically = checked
-	AJM:SettingsRefresh()
+	AJM.db.barsAreStackedVertically = checked;
+	AJM.db.teamListHorizontal = checked;
+	AJM:SettingsRefresh();
 end
-
+--[[
 function AJM:SettingsToggleTeamHorizontal( event, checked )
 	AJM.db.teamListHorizontal = checked
 	AJM:SettingsRefresh()
@@ -2710,6 +2715,7 @@ function AJM:SendExperienceStatusUpdateCommand()
 			artifactPointsSpent	= pointsSpent
 			end
 		local honorXP = UnitHonor("player")
+		local prestigeLevel = UnitPrestige("Player")
 		local honorMax = UnitHonorMax("player")
 		-- A DityDityHack if capped --Ebony
 		if honorMax == 0 then
@@ -2723,29 +2729,29 @@ function AJM:SendExperienceStatusUpdateCommand()
 	--	AJM:Print("testSend", honorXP, honorMax, HonorLevel, honorExhaustionStateID)
 		if AJM.db.showTeamListOnMasterOnly == true then
 				--AJM:Print("Test", characterName, name, xp, xpForNextPoint, numPointsAvailableToSpend)
-				AJM:JambaSendCommandToMaster( AJM.COMMAND_EXPERIENCE_STATUS_UPDATE, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel, artifactName, artifactPointsSpent, artifactXP, artifactForNextPoint, artifactPointsAvailable, honorXP, honorMax, HonorLevel, honorExhaustionStateID )
+				AJM:JambaSendCommandToMaster( AJM.COMMAND_EXPERIENCE_STATUS_UPDATE, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel, artifactName, artifactPointsSpent, artifactXP, artifactForNextPoint, artifactPointsAvailable, honorXP, honorMax, HonorLevel, prestigeLevel, honorExhaustionStateID )
 			else
 				AJM:DebugMessage( "SendExperienceStatusUpdateCommand TO TEAM!" )
 				--AJM:Print("Test", characterName, name, xp, xpForNextPoint, numPointsAvailableToSpend)
-				AJM:JambaSendCommandToTeam( AJM.COMMAND_EXPERIENCE_STATUS_UPDATE, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel, artifactName, artifactXP, artifactPointsSpent, artifactForNextPoint, artifactPointsAvailable, honorXP, honorMax, HonorLevel, honorExhaustionStateID)
+				AJM:JambaSendCommandToTeam( AJM.COMMAND_EXPERIENCE_STATUS_UPDATE, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel, artifactName, artifactXP, artifactPointsSpent, artifactForNextPoint, artifactPointsAvailable, honorXP, honorMax, HonorLevel, prestigeLevel, honorExhaustionStateID)
 			end
 	end
 end

-function AJM:ProcessUpdateExperienceStatusMessage( characterName, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel, artifactName, artifactXP, artifactForNextPoint, artifactPointsSpent, artifactPointsAvailable, honorXP, honorMax, HonorLevel, honorExhaustionStateID)
-	AJM:UpdateExperienceStatus( characterName, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel, artifactName, artifactXP, artifactForNextPoint, artifactPointsSpent, artifactPointsAvailable, honorXP, honorMax, HonorLevel, honorExhaustionStateID )
+function AJM:ProcessUpdateExperienceStatusMessage( characterName, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel, artifactName, artifactXP, artifactForNextPoint, artifactPointsSpent, artifactPointsAvailable, honorXP, honorMax, HonorLevel, prestigeLevel, honorExhaustionStateID)
+	AJM:UpdateExperienceStatus( characterName, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel, artifactName, artifactXP, artifactForNextPoint, artifactPointsSpent, artifactPointsAvailable, honorXP, honorMax, HonorLevel, prestigeLevel, honorExhaustionStateID )
 end

 function AJM:SettingsUpdateExperienceAll()
 	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		AJM:UpdateExperienceStatus( characterName, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil )
+		AJM:UpdateExperienceStatus( characterName, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil )
 	end
 end

-function AJM:UpdateExperienceStatus( characterName, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel, artifactName, artifactXP, artifactPointsSpent, artifactForNextPoint, artifactPointsAvailable, honorXP, honorMax, HonorLevel, honorExhaustionStateID )
+function AJM:UpdateExperienceStatus( characterName, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel, artifactName, artifactXP, artifactPointsSpent, artifactForNextPoint, artifactPointsAvailable, honorXP, honorMax, HonorLevel, prestigeLevel, honorExhaustionStateID )
 --AJM:Print( "UpdateExperienceStatus", characterName, playerExperience, playerMaxExperience, exhaustionStateID, playerLevel)
 --	AJM:Print("ArtTest", characterName, "name", artifactName, "xp", artifactXP, "Points", artifactForNextPoint, artifactPointsAvailable)
---	AJM:Print("honorTest", characterName, honorXP, honorMax, HonorLevel, honorExhaustionStateID)
+--	AJM:Print("honorTest", characterName, honorXP, honorMax, HonorLevel, prestigeLevel, honorExhaustionStateID)
 	if CanDisplayTeamList() == false then
 		return
 	end
@@ -2839,17 +2845,10 @@ function AJM:UpdateExperienceStatus( characterName, playerExperience, playerMaxE
 	experienceHonorBarText.honorExhaustionStateID = honorExhaustionStateID
 	local min, max = math.min(0, playerExperience), playerMaxExperience

-	--experienceBar:SetMinMaxValues( 0, tonumber( playerMaxExperience ) )
-	--experienceBar:SetValue( tonumber( playerExperience ) )
 	experienceBar:SetAnimatedValues(playerExperience, min, max , playerLevel)
-

-	--experienceArtBar:SetMinMaxValues( 0, tonumber( artifactForNextPoint ) )
-	--experienceArtBar:SetValue( tonumber( artifactXP ) )
 	experienceArtBar:SetAnimatedValues(artifactXP, 0, artifactForNextPoint, artifactPointsAvailable + artifactPointsSpent)

-	--experienceHonorBar:SetMinMaxValues( 0, tonumber( honorMax ) )
-	--experienceHonorBar:SetValue( tonumber( honorXP ) )
 	experienceHonorBar:SetAnimatedValues(honorXP, 0, honorMax, honorLevel)


@@ -2885,17 +2884,24 @@ function AJM:UpdateExperienceStatus( characterName, playerExperience, playerMaxE
 		experienceBar.backgroundTexture:SetColorTexture( 0.58, 0.0, 0.55, 0.15 )
 	end

-	--ArtText
+--ArtText
 	local artText = ""
+	if AJM.db.showExpInfo == true then
+		if artifactPointsAvailable > 0 then
+			artText = artText.."+"..artifactPointsAvailable..L[" "]
+		else
+			artText = artText..artifactPointsSpent..L[" "]
+		end
+	end
 	--AJM:Print("TextTest", artifactXP, artifactForNextPoint)
-	if AJM.db.experienceStatusShowValues == true then
+	if AJM.db.experienceStatusShowValues == true and AJM.db.experienceStatusShowPercentage == false then
 		artText = artText..tostring( AbbreviateLargeNumbers(artifactXP ) )..L[" / "]..tostring( AbbreviateLargeNumbers(artifactForNextPoint) )..L[" "]
 	end
 	if AJM.db.experienceStatusShowPercentage == true then
 		if AJM.db.experienceStatusShowValues == true then
-			artText = tostring( AbbreviateLargeNumbers(artifactXP ) )..L[" "]..L["("]..tostring( floor( (artifactXP/artifactForNextPoint)*100) )..L["%"]..L[")"]
+			artText = artText..L["("]..tostring( AbbreviateLargeNumbers(artifactXP ) )..L[" "]..tostring( floor( (artifactXP/artifactForNextPoint)*100) )..L["%"]..L[")"]
 		else
-			artText = tostring( floor( (artifactXP/artifactForNextPoint)*100) )..L["%"]
+			artText = artText..L["("]..tostring( floor( (artifactXP/artifactForNextPoint)*100) )..L["%"]..L[")"]
 		end
 	end
 		--AJM:Print("arttest", artText)
@@ -2906,14 +2912,21 @@ function AJM:UpdateExperienceStatus( characterName, playerExperience, playerMaxE

 	--HonorText
 	local honorText = ""
+	if AJM.db.showExpInfo == true then
+		if prestigeLevel > 0 then
+			honorText = honorText..prestigeLevel.."-"..honorLevel..L[" "]
+		else
+			honorText = honorText..honorLevel..L[" "]
+		end
+	end
 	if AJM.db.experienceStatusShowValues == true then
 		honorText = honorText..tostring( AbbreviateLargeNumbers(honorXP) )..L[" / "]..tostring( AbbreviateLargeNumbers(honorMax) )..L[" "]
 	end
 	if AJM.db.experienceStatusShowPercentage == true then
 		if AJM.db.experienceStatusShowValues == true then
-			honorText = tostring( AbbreviateLargeNumbers(honorXP) )..L[" "]..L["("]..tostring( floor( (honorXP/honorMax)*100) )..L["%"]..L[")"]
+			honorText = honorText..tostring( AbbreviateLargeNumbers(honorXP) )..L[" "]..L["("]..tostring( floor( (honorXP/honorMax)*100) )..L["%"]..L[")"]
 		else
-			honorText = tostring( floor( (honorXP/honorMax)*100) )..L["%"]
+			honorText = honorText..L["("]..tostring( floor( (honorXP/honorMax)*100) )..L["%"]..L[")"]
 		end
 	end
 	experienceHonorBarText:SetText( honorText )
@@ -3408,19 +3421,19 @@ function AJM:SendComboStatusUpdateCommand()
 		end


-		--AJM:Print ("PowerType", PowerType, playerCombo, playerMaxCombo)
+		--AJM:Print ("PowerType", PowerType, playerCombo, playerMaxCombo, class)
 		if AJM.db.showTeamListOnMasterOnly == true then
 			AJM:DebugMessage( "SendComboStatusUpdateCommand TO Master!" )
-			AJM:JambaSendCommandToMaster( AJM.COMMAND_COMBO_STATUS_UPDATE, playerCombo, playerMaxCombo )
+			AJM:JambaSendCommandToMaster( AJM.COMMAND_COMBO_STATUS_UPDATE, playerCombo, playerMaxCombo, class )
 		else
 			AJM:DebugMessage( "SendComboStatusUpdateCommand TO TEAM!" )
-			AJM:JambaSendCommandToTeam( AJM.COMMAND_COMBO_STATUS_UPDATE, playerCombo, playerMaxCombo )
+			AJM:JambaSendCommandToTeam( AJM.COMMAND_COMBO_STATUS_UPDATE, playerCombo, playerMaxCombo, class )
 		end
 	end
 end

-function AJM:ProcessUpdateComboStatusMessage( characterName, playerCombo, playerMaxCombo )
-	AJM:UpdateComboStatus( characterName, playerCombo , playerMaxCombo)
+function AJM:ProcessUpdateComboStatusMessage( characterName, playerCombo, playerMaxCombo, class )
+	AJM:UpdateComboStatus( characterName, playerCombo , playerMaxCombo, class)
 end

 function AJM:SettingsUpdateComboAll()
@@ -3429,7 +3442,7 @@ function AJM:SettingsUpdateComboAll()
 	end
 end

-function AJM:UpdateComboStatus( characterName, playerCombo, playerMaxCombo )
+function AJM:UpdateComboStatus( characterName, playerCombo, playerMaxCombo, class )
 	if CanDisplayTeamList() == false then
 		return
 	end
@@ -3485,12 +3498,11 @@ function AJM:UpdateComboStatus( characterName, playerCombo, playerMaxCombo )
 		end
 	end
 	comboBarText:SetText( text )
-	AJM:SetStatusBarColourForCombo( comboBar )
+	AJM:SetStatusBarColourForCombo( comboBar, class )
 end


-function AJM:SetStatusBarColourForCombo( comboBar )
-	local Class = select(2, UnitClass("player"))
+function AJM:SetStatusBarColourForCombo( comboBar, Class )
 	if Class == "WARLOCK" then
 		-- Purple
 		comboBar:SetStatusBarColor( 0.58, 0.51, 0.79, 1 )
@@ -3656,4 +3668,3 @@ function AJM:OnCharactersChanged()
 	AJM:RefreshTeamListControls()
 end

-
diff --git a/Jamba-DisplayTeam/JambaDisplayTeam.lua.old b/Jamba-DisplayTeam/JambaDisplayTeam.lua.old
deleted file mode 100644
index 604920b..0000000
--- a/Jamba-DisplayTeam/JambaDisplayTeam.lua.old
+++ /dev/null
@@ -1,3065 +0,0 @@
---[[
-Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2016 Michael "Jafula" Miller
-License: The MIT License
-]]--
-
--- Create the addon using AceAddon-3.0 and embed some libraries.
-local AJM = LibStub( "AceAddon-3.0" ):NewAddon(
-	"JambaDisplayTeam",
-	"JambaModule-1.0",
-	"AceConsole-3.0",
-	"AceEvent-3.0",
-	"AceHook-3.0",
-	"AceTimer-3.0"
-)
-
--- Load libraries.
-local JambaUtilities = LibStub:GetLibrary( "JambaUtilities-1.0" )
-local JambaHelperSettings = LibStub:GetLibrary( "JambaHelperSettings-1.0" )
-local LibBagUtils = LibStub:GetLibrary( "LibBagUtils-1.0" )
-AJM.SharedMedia = LibStub( "LibSharedMedia-3.0" )
-
--- Constants required by JambaModule and Locale for this module.
-AJM.moduleName = "JmbDspTm"
-AJM.settingsDatabaseName = "JambaDisplayTeamProfileDB"
-AJM.chatCommand = "jamba-display-team"
-local L = LibStub( "AceLocale-3.0" ):GetLocale( AJM.moduleName )
-AJM.parentDisplayName = L["Team"]
-AJM.moduleDisplayName = L["Display: Team"]
-
--- Settings - the values to store and their defaults for the settings database.
-AJM.settings = {
-	profile = {
-		showTeamList = true,
-		showTeamListOnMasterOnly = true,
-		hideTeamListInCombat = false,
-		enableClique = false,
-		statusBarTexture = L["Blizzard"],
-		borderStyle = L["Blizzard Tooltip"],
-		backgroundStyle = L["Blizzard Dialog Background"],
-		teamListScale = 1,
-		teamListTitleHeight = 15,
-		teamListVerticalSpacing = 4,
-		teamListHorizontalSpacing = 4,
-		barVerticalSpacing = 2,
-		barHorizontalSpacing = 2,
-		barsAreStackedVertically = false,
-		teamListHorizontal = false,
-		showListTitle = true,
-		showCharacterPortrait = true,
-		characterPortraitWidth = 20,
-		showFollowStatus = true,
-		followStatusWidth = 80,
-		followStatusHeight = 20,
-		followStatusShowName = true,
-		followStatusShowLevel = true,
-		showExperienceStatus = true,
-		experienceStatusWidth = 80,
-		experienceStatusHeight = 20,
-		experienceStatusShowValues = false,
-		experienceStatusShowPercentage = true,
-		showReputationStatus = true,
-		showReputationName = true,
-		reputationStatusWidth = 80,
-		reputationStatusHeight = 20,
-		reputationStatusShowValues = false,
-		reputationStatusShowPercentage = true,
-		showHealthStatus = false,
-		healthStatusWidth = 80,
-		healthStatusHeight = 20,
-		healthStatusShowValues = true,
-		healthStatusShowPercentage = true,
-		showPowerStatus = false,
-		powerStatusWidth = 80,
-		powerStatusHeight = 20,
-		powerStatusShowValues = true,
-		powerStatusShowPercentage = true,
-		showComboStatus = false,
-		comboStatusWidth = 80,
-		comboStatusHeight = 20,
-		comboStatusShowValues = true,
-		comboStatusShowPercentage = true,
---		showBagInformation = true,
---		showBagFreeSlotsOnly = true,
---		bagInformationWidth = 80,
---		bagInformationHeight = 25,
-		--EbonyTest
-		stackName = false,
-		showIlvlInformation = true,
-		ShowEquippedOnly = false,
-		--ilvlInformationWidth = 80,
-		--ilvlInformationHeight = 20,
-		framePoint = "CENTER",
-		frameRelativePoint = "CENTER",
-		frameXOffset = 0,
-		frameYOffset = 0,
-		frameAlpha = 1.0,
-		frameBackgroundColourR = 1.0,
-		frameBackgroundColourG = 1.0,
-		frameBackgroundColourB = 1.0,
-		frameBackgroundColourA = 1.0,
-		frameBorderColourR = 1.0,
-		frameBorderColourG = 1.0,
-		frameBorderColourB = 1.0,
-		frameBorderColourA = 1.0,
-		timerCount = 1
-	},
-}
-
--- Debug message.
-function AJM:DebugMessage( ... )
-	--AJM:Print( ... )
-end
-
--- Configuration.
-function AJM:GetConfiguration()
-	local configuration = {
-		name = AJM.moduleDisplayName,
-		handler = AJM,
-		type = "group",
-		get = "JambaConfigurationGetSetting",
-		set = "JambaConfigurationSetSetting",
-		args = {
-			push = {
-				type = "input",
-				name = L["Push Settings"],
-				desc = L["Push the display team settings to all characters in the team."],
-				usage = "/jamba-display-team push",
-				get = false,
-				set = "JambaSendSettings",
-			},
-			hide = {
-				type = "input",
-				name = L["Hide Team Display"],
-				desc = L["Hide the display team panel."],
-				usage = "/jamba-display-team hide",
-				get = false,
-				set = "HideTeamListCommand",
-			},
-			show = {
-				type = "input",
-				name = L["Show Team Display"],
-				desc = L["Show the display team panel."],
-				usage = "/jamba-display-team show",
-				get = false,
-				set = "ShowTeamListCommand",
-			},
-		},
-	}
-	return configuration
-end
-
--------------------------------------------------------------------------------------------------------------
--- Command this module sends.
--------------------------------------------------------------------------------------------------------------
-
-AJM.COMMAND_FOLLOW_STATUS_UPDATE = "FlwStsUpd"
-AJM.COMMAND_EXPERIENCE_STATUS_UPDATE = "ExpStsUpd"
---AJM.COMMAND_BAGINFORMATION_UPDATE = "BagInfoUpd"
-AJM.COMMAND_ITEMLEVELINFORMATION_UPDATE = "IlvlInfoUpd"
-AJM.COMMAND_REPUTATION_STATUS_UPDATE = "RepStsUpd"
-AJM.COMMAND_COMBO_STATUS_UPDATE = "CboStsUpd"
-
--------------------------------------------------------------------------------------------------------------
--- Messages module sends.
--------------------------------------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------------------------------------
--- Constants used by module.
--------------------------------------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------------------------------------
--- Variables used by module.
--------------------------------------------------------------------------------------------------------------
-
--- Team display variables.
-AJM.globalFramePrefix = "JambaDisplayTeam"
-AJM.characterStatusBar = {}
-AJM.totalMembersDisplayed = 0
-AJM.teamListCreated = false
-AJM.refreshHideTeamListControlsPending = false
-AJM.refreshShowTeamListControlsPending = false
-AJM.updateSettingsAfterCombat = false
-
--------------------------------------------------------------------------------------------------------------
--- Team Frame.
--------------------------------------------------------------------------------------------------------------
-
-local function GetCharacterHeight()
-	local height = 0
-	local heightPortrait = 0
-	local heightFollowStatus = 0
-	local heightExperienceStatus = 0
-	local heightReputationStatus = 0
-	local heightHealthStatus = 0
-	local heightPowerStatus = 0
-	local heightComboStatus = 0
---	local heightBagInformation = 0
-	--local heightIlvlInformation = 0
-	local heightAllBars = 0
-	if AJM.db.showCharacterPortrait == true then
-		heightPortrait = AJM.db.characterPortraitWidth + AJM.db.teamListVerticalSpacing
-	end
---	if AJM.db.showBagInformation == true then
---		heightBagInformation = AJM.db.bagInformationHeight + AJM.db.teamListVerticalSpacing
---		heightAllBars = heightAllBars + heightBagInformation
---	end
-	--if AJM.db.showIlvlInformation == true then
-	--	heightIlvlInformation = AJM.db.ilvlInformationHeight + AJM.db.teamListVerticalSpacing
-	--	heightAllBars = heightAllBars + heightIlvlInformation
-	--end
-	if AJM.db.showFollowStatus == true then
-		heightFollowStatus = AJM.db.followStatusHeight + AJM.db.barVerticalSpacing
-		heightAllBars = heightAllBars + heightFollowStatus
-	end
-	if AJM.db.showExperienceStatus == true then
-		heightExperienceStatus = AJM.db.experienceStatusHeight + AJM.db.barVerticalSpacing
-		heightAllBars = heightAllBars + heightExperienceStatus
-	end
-	if AJM.db.showReputationStatus == true then
-		heightReputationStatus = AJM.db.reputationStatusHeight + AJM.db.barVerticalSpacing
-		heightAllBars = heightAllBars + heightReputationStatus
-	end
-	if AJM.db.showHealthStatus == true then
-		heightHealthStatus = AJM.db.healthStatusHeight + AJM.db.barVerticalSpacing
-		heightAllBars = heightAllBars + heightHealthStatus
-	end
-	if AJM.db.showPowerStatus == true then
-		heightPowerStatus = AJM.db.powerStatusHeight + AJM.db.barVerticalSpacing
-		heightAllBars = heightAllBars + heightPowerStatus
-	end
-	if AJM.db.showComboStatus == true then
-		heightComboStatus = AJM.db.comboStatusHeight + AJM.db.barVerticalSpacing
-		heightAllBars = heightAllBars + heightComboStatus
-	end
-	if AJM.db.barsAreStackedVertically == true then
-		height = max( heightPortrait, heightAllBars )
-	else
-		--height = max( heightPortrait, heightBagInformation, heightFollowStatus, heightExperienceStatus, heightReputationStatus, heightHealthStatus, heightPowerStatus, heightComboStatus )
-		height = max( heightPortrait, heightFollowStatus, heightExperienceStatus, heightReputationStatus, heightHealthStatus, heightPowerStatus, heightComboStatus )
-	end
-	return height
-end
-
-local function GetCharacterWidth()
-	local width = 0
-	local widthPortrait = 0
-	local widthFollowStatus = 0
-	local widthExperienceStatus = 0
-	local widthReputationStatus = 0
-	local widthHealthStatus = 0
-	local widthPowerStatus = 0
-	local widthComboStatus = 0
---	local widthBagInformation = 0
-	local widthIvlInformation = 0
-	local widthAllBars = 0
-	if AJM.db.showCharacterPortrait == true then
-		widthPortrait = AJM.db.characterPortraitWidth + AJM.db.teamListHorizontalSpacing
-	end
---	if AJM.db.showBagInformation == true then
---		widthBagInformation = AJM.db.bagInformationWidth + AJM.db.teamListHorizontalSpacing
---		widthAllBars = widthAllBars + widthBagInformation
---	end
-	--if AJM.db.showIlvlInformation == true then
-	--	widthIlvlInformation = AJM.db.ilvlInformationWidth + AJM.db.teamListHorizontalSpacing
-	--	widthAllBars = widthAllBars + widthIlvlInformation
-	--end
-	if AJM.db.showFollowStatus == true then
-		widthFollowStatus = AJM.db.followStatusWidth + AJM.db.barHorizontalSpacing
-		widthAllBars = widthAllBars + widthFollowStatus
-	end
-	if AJM.db.showExperienceStatus == true then
-		widthExperienceStatus = AJM.db.experienceStatusWidth + AJM.db.barHorizontalSpacing
-		widthAllBars = widthAllBars + widthExperienceStatus
-	end
-	if AJM.db.showReputationStatus == true then
-		widthReputationStatus = AJM.db.reputationStatusWidth + AJM.db.barHorizontalSpacing
-		widthAllBars = widthAllBars + widthReputationStatus
-	end
-	if AJM.db.showHealthStatus == true then
-		widthHealthStatus = AJM.db.healthStatusWidth + AJM.db.barHorizontalSpacing
-		widthAllBars = widthAllBars + widthHealthStatus
-	end
-	if AJM.db.showPowerStatus == true then
-		widthPowerStatus = AJM.db.powerStatusWidth + AJM.db.barHorizontalSpacing
-		widthAllBars = widthAllBars + widthPowerStatus
-	end
-	if AJM.db.showComboStatus == true then
-		widthComboStatus = AJM.db.comboStatusWidth + AJM.db.barHorizontalSpacing
-		widthAllBars = widthAllBars + widthComboStatus
-	end
-	if AJM.db.barsAreStackedVertically == true then
-		--width = widthPortrait + max( widthBagInformation, widthFollowStatus, widthExperienceStatus, widthReputationStatus, widthHealthStatus, widthPowerStatus, widthComboStatus )
-		width = widthPortrait + max( widthFollowStatus, widthExperienceStatus, widthReputationStatus, widthHealthStatus, widthPowerStatus, widthComboStatus )
-
-	else
-		width = widthPortrait + widthAllBars
-	end
-	return width
-end
-
-local function UpdateJambaTeamListDimensions()
-	local frame = JambaDisplayTeamListFrame
-	if AJM.db.showListTitle == true then
-		AJM.db.teamListTitleHeight = 15
-		JambaDisplayTeamListFrame.titleName:SetText( L["Jamba Team"] )
-	else
-		AJM.db.teamListTitleHeight = 0
-		JambaDisplayTeamListFrame.titleName:SetText( "" )
-	end
-	if AJM.db.teamListHorizontal == true then
-		frame:SetWidth( (AJM.db.teamListVerticalSpacing * 3) + (GetCharacterWidth() * AJM.totalMembersDisplayed) )
-		frame:SetHeight( AJM.db.teamListTitleHeight + (AJM.db.teamListVerticalSpacing * 3) + GetCharacterHeight() )
-	else
-		frame:SetWidth( (AJM.db.teamListHorizontalSpacing * 3) + GetCharacterWidth() )
-		frame:SetHeight( AJM.db.teamListTitleHeight + (GetCharacterHeight() * AJM.totalMembersDisplayed) + (AJM.db.teamListVerticalSpacing * 3) )
-	end
-	frame:SetScale( AJM.db.teamListScale )
-end
-
-local function CreateJambaTeamListFrame()
-	-- The frame.
-	local frame = CreateFrame( "Frame", "JambaDisplayTeamListWindowFrame", UIParent )
-	frame.obj = AJM
-	frame:SetFrameStrata( "LOW" )
-	frame:SetToplevel( true )
-	frame:SetClampedToScreen( true )
-	frame:EnableMouse( true )
-	frame:SetMovable( true )
-	frame:RegisterForDrag( "LeftButton" )
-	frame:SetScript( "OnDragStart",
-		function( this )
-			if IsAltKeyDown() then
-				if not UnitAffectingCombat("player") then
-					this:StartMoving()
-				end
-			end
-		end )
-	frame:SetScript( "OnDragStop",
-		function( this )
-			this:StopMovingOrSizing()
-			local point, relativeTo, relativePoint, xOffset, yOffset = this:GetPoint()
-			AJM.db.framePoint = point
-			AJM.db.frameRelativePoint = relativePoint
-			AJM.db.frameXOffset = xOffset
-			AJM.db.frameYOffset = yOffset
-		end	)
-	frame:ClearAllPoints()
-	frame:SetPoint( AJM.db.framePoint, UIParent, AJM.db.frameRelativePoint, AJM.db.frameXOffset, AJM.db.frameYOffset )
-	frame:SetBackdrop( {
-		bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
-		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
-		tile = true, tileSize = 10, edgeSize = 10,
-		insets = { left = 3, right = 3, top = 3, bottom = 3 }
-	} )
-
-	-- Create the title for the team list frame.
-	local titleName = frame:CreateFontString( "JambaDisplayTeamListWindowFrameTitleText", "OVERLAY", "GameFontNormal" )
-	titleName:SetPoint( "TOP", frame, "TOP", 0, -5 )
-	titleName:SetTextColor( 1.00, 1.00, 1.00 )
-	titleName:SetText( L["Jamba Team"] )
-	frame.titleName = titleName
-
-	-- Set transparency of the the frame (and all its children).
-	frame:SetAlpha(AJM.db.frameAlpha)
-
-	-- Set the global frame reference for this frame.
-	JambaDisplayTeamListFrame = frame
-
-	AJM:SettingsUpdateBorderStyle()
-	AJM.teamListCreated = true
-
---[[
-	-- Draw the title.
-	if AJM.db.teamListStatusWidth >= 90 then
-		JambaDisplayTeamListFrame.titleName:SetText( L["Jamba Team"] )
-	else
-		JambaDisplayTeamListFrame.titleName:SetText( L["Team"] )
-	end
-]]--
-end
-
-local function CanDisplayTeamList()
-	local canShow = false
-	if AJM.db.showTeamList == true then
-		if AJM.db.showTeamListOnMasterOnly == true then
-			if JambaApi.IsCharacterTheMaster( AJM.characterName ) == true then
-				canShow = true
-			end
-		else
-			canShow = true
-		end
-	end
-	return canShow
-end
-
-function AJM:ShowTeamListCommand()
-	AJM.db.showTeamList = true
-	AJM:SetTeamListVisibility()
-end
-
-function AJM:HideTeamListCommand()
-	AJM.db.showTeamList = false
-	AJM:SetTeamListVisibility()
-end
-
-function AJM:SetTeamListVisibility()
-	if CanDisplayTeamList() == true then
-		JambaDisplayTeamListFrame:ClearAllPoints()
-		JambaDisplayTeamListFrame:SetPoint( AJM.db.framePoint, UIParent, AJM.db.frameRelativePoint, AJM.db.frameXOffset, AJM.db.frameYOffset )
-		JambaDisplayTeamListFrame:SetAlpha( AJM.db.frameAlpha )
-		JambaDisplayTeamListFrame:Show()
-	else
-		JambaDisplayTeamListFrame:Hide()
-	end
-end
-
-function AJM:RefreshTeamListControlsHide()
-	if InCombatLockdown() then
-		AJM.refreshHideTeamListControlsPending = true
-		return
-	end
-	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		characterName = JambaUtilities:AddRealmToNameIfMissing ( characterName )
-		-- Hide their status bar.
-		AJM:HideJambaTeamStatusBar( characterName )
-	end
-	UpdateJambaTeamListDimensions()
-end
-
-function AJM:RefreshTeamListControlsShow()
-	if InCombatLockdown() then
-		AJM.refreshShowTeamListControlsPending = true
-		return
-	end
-	-- Iterate all the team members.
-	AJM.totalMembersDisplayed = 0
-	for index, characterName in JambaApi.TeamListOrdered() do
-		characterName = JambaUtilities:AddRealmToNameIfMissing ( characterName )
-		-- Is the team member online?
-		if JambaApi.GetCharacterOnlineStatus( characterName ) == true then
-			-- Yes, the team member is online, draw their status bars.
-			AJM:UpdateJambaTeamStatusBar( characterName, AJM.totalMembersDisplayed )
-			AJM.totalMembersDisplayed = AJM.totalMembersDisplayed + 1
-		end
-	end
-	UpdateJambaTeamListDimensions()
-end
-
-function AJM:RefreshTeamListControls()
-	AJM:RefreshTeamListControlsHide()
-	AJM:RefreshTeamListControlsShow()
-end
-
-function AJM:SettingsUpdateStatusBarTexture()
-	local statusBarTexture = AJM.SharedMedia:Fetch( "statusbar", AJM.db.statusBarTexture )
-	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		characterStatusBar["followBar"]:SetStatusBarTexture( statusBarTexture )
-		characterStatusBar["followBar"]:GetStatusBarTexture():SetHorizTile( false )
-		characterStatusBar["followBar"]:GetStatusBarTexture():SetVertTile( false )
-		characterStatusBar["experienceBar"]:SetStatusBarTexture( statusBarTexture )
-		characterStatusBar["experienceBar"]:GetStatusBarTexture():SetHorizTile( false )
-		characterStatusBar["experienceBar"]:GetStatusBarTexture():SetVertTile( false )
-		characterStatusBar["reputationBar"]:SetStatusBarTexture( statusBarTexture )
-		characterStatusBar["reputationBar"]:GetStatusBarTexture():SetHorizTile( false )
-		characterStatusBar["reputationBar"]:GetStatusBarTexture():SetVertTile( false )
-		characterStatusBar["healthBar"]:SetStatusBarTexture( statusBarTexture )
-		characterStatusBar["healthBar"]:GetStatusBarTexture():SetHorizTile( false )
-		characterStatusBar["healthBar"]:GetStatusBarTexture():SetVertTile( false )
-		characterStatusBar["powerBar"]:SetStatusBarTexture( statusBarTexture )
-		characterStatusBar["powerBar"]:GetStatusBarTexture():SetHorizTile( false )
-		characterStatusBar["powerBar"]:GetStatusBarTexture():SetVertTile( false )
-		characterStatusBar["comboBar"]:SetStatusBarTexture( statusBarTexture )
-		characterStatusBar["comboBar"]:GetStatusBarTexture():SetHorizTile( false )
-		characterStatusBar["comboBar"]:GetStatusBarTexture():SetVertTile( false )
-	end
-end
-
-function AJM:SettingsUpdateBorderStyle()
-	local borderStyle = AJM.SharedMedia:Fetch( "border", AJM.db.borderStyle )
-	local backgroundStyle = AJM.SharedMedia:Fetch( "background", AJM.db.backgroundStyle )
-	local frame = JambaDisplayTeamListFrame
-	frame:SetBackdrop( {
-		bgFile = backgroundStyle,
-		edgeFile = borderStyle,
-		tile = true, tileSize = frame:GetWidth(), edgeSize = 10,
-		insets = { left = 3, right = 3, top = 3, bottom = 3 }
-	} )
-	frame:SetBackdropColor( AJM.db.frameBackgroundColourR, AJM.db.frameBackgroundColourG, AJM.db.frameBackgroundColourB, AJM.db.frameBackgroundColourA )
-	frame:SetBackdropBorderColor( AJM.db.frameBorderColourR, AJM.db.frameBorderColourG, AJM.db.frameBorderColourB, AJM.db.frameBorderColourA )
-end
-
-function AJM:CreateJambaTeamStatusBar( characterName, parentFrame )
-	local statusBarTexture = AJM.SharedMedia:Fetch( "statusbar", AJM.db.statusBarTexture )
-	-- Create the table to hold the status bars for this character.
-	AJM.characterStatusBar[characterName] = {}
-	-- Get the status bars table.
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	-- Set the portrait.
-	local portraitName = AJM.globalFramePrefix.."PortraitButton"
-	local portraitButton = CreateFrame( "PlayerModel", portraitName, parentFrame )
-	--portraitButton.Texture = portraitButton:CreateTexture( portraitName.."NormalTexture", "ARTWORK" )
-	--SetPortraitTexture( portraitButton.Texture, characterName )
-	--portraitButton.Texture:SetAllPoints()
-	portraitButton:ClearModel()
-	portraitButton:SetUnit( Ambiguate( characterName, "short" ) )
-	portraitButton:SetPortraitZoom( 1 )
-    portraitButton:SetCamDistanceScale( 1 )
-    portraitButton:SetPosition( 0, 0, 0 )
-	local portraitButtonClick = CreateFrame( "CheckButton", portraitName.."Click", parentFrame, "SecureActionButtonTemplate" )
-	portraitButtonClick:SetAttribute( "unit", Ambiguate( characterName, "all" ) )
-	characterStatusBar["portraitButton"] = portraitButton
-	characterStatusBar["portraitButtonClick"] = portraitButtonClick
-	-- Set the bag information.
---[[
-	local bagInformationFrameName = AJM.globalFramePrefix.."BagInformationFrame"
-	local bagInformationFrame = CreateFrame( "Frame", bagInformationFrameName, parentFrame )
-	local bagInformationFrameText = bagInformationFrame:CreateFontString( bagInformationFrameName.."Text", "OVERLAY", "GameFontNormal" )
-	bagInformationFrameText:SetText( "999/999" )
-	bagInformationFrame:SetAlpha( 1 )
-	--bagInformationFrameText:SetPoint( "CENTER", bagInformationFrame, "CENTER", 0, 0 )
-	bagInformationFrameText:SetAllPoints()
-	bagInformationFrameText:SetJustifyH( "CENTER" )
-	bagInformationFrameText:SetJustifyV( "MIDDLE" )
-	bagInformationFrameText:SetTextColor( 1.00, 1.00, 1.00, 1.00 )
-	bagInformationFrame.slotsFree = 999
-	bagInformationFrame.totalSlots = 999
-	bagInformationFrame.durability = 100
-	characterStatusBar["bagInformationFrame"] = bagInformationFrame
-	characterStatusBar["bagInformationFrameText"] = bagInformationFrameText
---]]
-	--set the ilevel Information.
-	local ilvlInformationFrameName = AJM.globalFramePrefix.."IlvlInformationFrame"
-	local ilvlInformationFrame = CreateFrame( "Frame", ilvlInformationFrameName, parentFrame )
-	local ilvlInformationFrameText = ilvlInformationFrame:CreateFontString( ilvlInformationFrameName.."Text", "OVERLAY", "GameFontNormal" )
-	ilvlInformationFrameText:SetText( "999/999" )
-	ilvlInformationFrameText:SetAllPoints()
-	ilvlInformationFrameText:SetJustifyH( "CENTER" )
-	ilvlInformationFrameText:SetJustifyV( "MIDDLE" )
-	ilvlInformationFrameText:SetTextColor( 1.00, 1.00, 1.00, 1.00 )
-	ilvlInformationFrame.overall = 999
-	ilvlInformationFrame.equipped = 999
-	ilvlInformationFrame.characterLevel = 0
-	characterStatusBar["ilvlInformationFrame"] = ilvlInformationFrame
-	characterStatusBar["ilvlInformationFrameText"] = ilvlInformationFrameText
-	-- Set the follow bar.
-	local followName = AJM.globalFramePrefix.."FollowBar"
-	local followBar = CreateFrame( "StatusBar", followName, parentFrame, "TextStatusBar,SecureActionButtonTemplate" )
-	followBar.backgroundTexture = followBar:CreateTexture( followName.."BackgroundTexture", "ARTWORK" )
-	followBar.backgroundTexture:SetTexture( 0.58, 0.0, 0.55, 0.15 )
-	followBar:SetStatusBarTexture( statusBarTexture )
-	followBar:GetStatusBarTexture():SetHorizTile( false )
-	followBar:GetStatusBarTexture():SetVertTile( false )
-	followBar:SetStatusBarColor( 0.55, 0.15, 0.15, 0.25 )
-	followBar:SetMinMaxValues( 0, 100 )
-	followBar:SetValue( 100 )
-	followBar:SetFrameStrata( "LOW" )
-	followBar:SetAlpha( 1 )
-	local followBarClick = CreateFrame( "CheckButton", followName.."Click", parentFrame, "SecureActionButtonTemplate" )
-	followBarClick:SetAttribute( "unit", Ambiguate( characterName, "all" ) )
-	--followBarClick:SetAttribute( "macrotext", "/targetexact "..characterName )
-	followBarClick:SetFrameStrata( "MEDIUM" )
-	characterStatusBar["followBar"] = followBar
-	characterStatusBar["followBarClick"] = followBarClick
-	local followBarText = followBar:CreateFontString( followName.."Text", "OVERLAY", "GameFontNormal" )
-	followBarText:SetTextColor( 1.00, 1.00, 1.00, 1.00 )
-	followBarText:SetAllPoints()
-	characterStatusBar["followBarText"] = followBarText
-	AJM:SettingsUpdateFollowText( characterName, UnitLevel( Ambiguate( characterName, "none" ) ), nil, nil )
-	-- Set the experience bar.
-	local experienceName = AJM.globalFramePrefix.."ExperienceBar"
-	local experienceBar = CreateFrame( "StatusBar", experienceName, parentFrame, "TextStatusBar,SecureActionButtonTemplate" )
-	experienceBar.backgroundTexture = experienceBar:CreateTexture( experienceName.."BackgroundTexture", "ARTWORK" )
-	experienceBar.backgroundTexture:SetTexture( 0.0, 0.39, 0.88, 0.15 )
-	experienceBar:SetStatusBarTexture( statusBarTexture )
-	experienceBar:GetStatusBarTexture():SetHorizTile( false )
-	experienceBar:GetStatusBarTexture():SetVertTile( false )
-	experienceBar:SetMinMaxValues( 0, 100 )
-	experienceBar:SetValue( 100 )
-	experienceBar:SetFrameStrata( "LOW" )
-	local experienceBarClick = CreateFrame( "CheckButton", experienceName.."Click", parentFrame, "SecureActionButtonTemplate" )
-	experienceBarClick:SetAttribute( "unit", Ambiguate( characterName, "all" ) )
-	experienceBarClick:SetFrameStrata( "MEDIUM" )
-	characterStatusBar["experienceBar"] = experienceBar
-	characterStatusBar["experienceBarClick"] = experienceBarClick
-	local experienceBarText = experienceBar:CreateFontString( experienceName.."Text", "OVERLAY", "GameFontNormal" )
-	experienceBarText:SetTextColor( 1.00, 1.00, 1.00, 1.00 )
-	experienceBarText:SetAllPoints()
-	experienceBarText.playerExperience = 100
-	experienceBarText.playerMaxExperience = 100
-	experienceBarText.exhaustionStateID = 1
-	characterStatusBar["experienceBarText"] = experienceBarText
-	AJM:UpdateExperienceStatus( characterName, nil, nil, nil )
-	-- Set the reputation bar.
-	local reputationName = AJM.globalFramePrefix.."ReputationBar"
-	local reputationBar = CreateFrame( "StatusBar", reputationName, parentFrame, "TextStatusBar,SecureActionButtonTemplate" )
-	reputationBar.backgroundTexture = reputationBar:CreateTexture( reputationName.."BackgroundTexture", "ARTWORK" )
-	reputationBar.backgroundTexture:SetTexture( 0.0, 0.39, 0.88, 0.15 )
-	reputationBar:SetStatusBarTexture( statusBarTexture )
-	reputationBar:GetStatusBarTexture():SetHorizTile( false )
-	reputationBar:GetStatusBarTexture():SetVertTile( false )
-	reputationBar:SetMinMaxValues( 0, 100 )
-	reputationBar:SetValue( 100 )
-	reputationBar:SetFrameStrata( "LOW" )
-	reputationBar:SetAlpha( 1 )
-	local reputationBarClick = CreateFrame( "CheckButton", reputationName.."Click", parentFrame, "SecureActionButtonTemplate" )
-	reputationBarClick:SetAttribute( "unit", Ambiguate( characterName, "all" ) )
-	reputationBarClick:SetFrameStrata( "MEDIUM" )
-	characterStatusBar["reputationBar"] = reputationBar
-	characterStatusBar["reputationBarClick"] = reputationBarClick
-	local reputationBarText = reputationBar:CreateFontString( reputationName.."Text", "OVERLAY", "GameFontNormal" )
-	reputationBarText:SetTextColor( 1.00, 1.00, 1.00, 1.00 )
-	reputationBarText:SetAllPoints()
-	reputationBarText.reputationName = "Faction"
-	reputationBarText.reputationStandingID = 4
-	reputationBarText.reputationBarMin = 0
-	reputationBarText.reputationBarMax = 100
-	reputationBarText.reputationBarValue = 100
-	characterStatusBar["reputationBarText"] = reputationBarText
-	AJM:UpdateReputationStatus( characterName, nil, nil, nil )
-	-- Set the health bar.
-	local healthName = AJM.globalFramePrefix.."HealthBar"
-	local healthBar = CreateFrame( "StatusBar", healthName, parentFrame, "TextStatusBar,SecureActionButtonTemplate" )
-	healthBar.backgroundTexture = healthBar:CreateTexture( healthName.."BackgroundTexture", "ARTWORK" )
-	healthBar.backgroundTexture:SetTexture( 0.58, 0.0, 0.55, 0.15 )
-	healthBar:SetStatusBarTexture( statusBarTexture )
-	healthBar:GetStatusBarTexture():SetHorizTile( false )
-	healthBar:GetStatusBarTexture():SetVertTile( false )
-	healthBar:SetMinMaxValues( 0, 100 )
-	healthBar:SetValue( 100 )
-	healthBar:SetFrameStrata( "LOW" )
-	healthBar:SetAlpha( 1 )
-	local healthBarClick = CreateFrame( "CheckButton", healthName.."Click"..characterName, parentFrame, "SecureActionButtonTemplate" )
-	healthBarClick:SetAttribute( "unit", Ambiguate( characterName, "all" ) )
-	healthBarClick:SetFrameStrata( "MEDIUM" )
-	characterStatusBar["healthBar"] = healthBar
-	characterStatusBar["healthBarClick"] = healthBarClick
-	local healthBarText = healthBar:CreateFontString( healthName.."Text", "OVERLAY", "GameFontNormal" )
-	healthBarText:SetTextColor( 1.00, 1.00, 1.00, 1.00 )
-	healthBarText:SetAllPoints()
-	healthBarText.playerHealth = 100
-	healthBarText.playerMaxHealth = 100
-	characterStatusBar["healthBarText"] = healthBarText
-	AJM:UpdateHealthStatus( characterName, nil, nil )
-	-- Set the power bar.
-	local powerName = AJM.globalFramePrefix.."PowerBar"
-	local powerBar = CreateFrame( "StatusBar", powerName, parentFrame, "TextStatusBar,SecureActionButtonTemplate" )
-	powerBar.backgroundTexture = powerBar:CreateTexture( powerName.."BackgroundTexture", "ARTWORK" )
-	powerBar.backgroundTexture:SetTexture( 0.58, 0.0, 0.55, 0.15 )
-	powerBar:SetStatusBarTexture( statusBarTexture )
-	powerBar:GetStatusBarTexture():SetHorizTile( false )
-	powerBar:GetStatusBarTexture():SetVertTile( false )
-	powerBar:SetMinMaxValues( 0, 100 )
-	powerBar:SetValue( 100 )
-	powerBar:SetFrameStrata( "LOW" )
-	powerBar:SetAlpha( 1 )
-	local powerBarClick = CreateFrame( "CheckButton", powerName.."Click"..characterName, parentFrame, "SecureActionButtonTemplate" )
-	powerBarClick:SetAttribute( "unit", Ambiguate( characterName, "all" ) )
-	powerBarClick:SetFrameStrata( "MEDIUM" )
-	characterStatusBar["powerBar"] = powerBar
-	characterStatusBar["powerBarClick"] = powerBarClick
-	local powerBarText = powerBar:CreateFontString( powerName.."Text", "OVERLAY", "GameFontNormal" )
-	powerBarText:SetTextColor( 1.00, 1.00, 1.00, 1.00 )
-	powerBarText:SetAllPoints()
-	powerBarText.playerPower = 100
-	powerBarText.playerMaxPower = 100
-	characterStatusBar["powerBarText"] = powerBarText
-	AJM:UpdatePowerStatus( characterName, nil, nil, nil )
-	-- Set the Combo Points bar.
-	local comboName = AJM.globalFramePrefix.."ComboBar"
-	local comboBar = CreateFrame( "StatusBar", comboName, parentFrame, "TextStatusBar,SecureActionButtonTemplate" )
-	comboBar.backgroundTexture = comboBar:CreateTexture( comboName.."BackgroundTexture", "ARTWORK" )
-	comboBar.backgroundTexture:SetTexture( 0.58, 0.0, 0.55, 0.15 )
-	comboBar:SetStatusBarTexture( statusBarTexture )
-	comboBar:GetStatusBarTexture():SetHorizTile( false )
-	comboBar:GetStatusBarTexture():SetVertTile( false )
-	comboBar:SetStatusBarColor( 1.00, 0.0, 0.0, 1.00 )
-	comboBar:SetMinMaxValues( 0, 5 )
-	comboBar:SetValue( 5 )
-	comboBar:SetFrameStrata( "LOW" )
-	comboBar:SetAlpha( 1 )
-	local comboBarClick = CreateFrame( "CheckButton", comboName.."Click"..characterName, parentFrame, "SecureActionButtonTemplate" )
-	comboBarClick:SetAttribute( "unit", characterName )
-	comboBarClick:SetFrameStrata( "MEDIUM" )
-	characterStatusBar["comboBar"] = comboBar
-	characterStatusBar["comboBarClick"] = comboBarClick
-	local comboBarText = comboBar:CreateFontString( comboName.."Text", "OVERLAY", "GameFontNormal" )
-	comboBarText:SetTextColor( 1.00, 1.00, 0.0, 1.00 )
-	comboBarText:SetAllPoints()
-	comboBarText.playerCombo = 0
-	comboBarText.playerMaxCombo = 5
-	characterStatusBar["comboBarText"] = comboBarText
-	AJM:UpdateComboStatus( characterName, nil, nil )
-	-- Add the health and power click bars to ClickCastFrames for addons like Clique to use.
-	--Ebony if Support for Clique if not on then default to target unit
-	--TODO there got to be a better way to doing this for sure but right now i can not be assed to do this for now you need to reload the UI when turning off and on clique support.
-	ClickCastFrames = ClickCastFrames or {}
-	if AJM.db.enableClique == true then
-		ClickCastFrames[portraitButtonClick] = true
-		ClickCastFrames[followBarClick] = true
-		ClickCastFrames[experienceBarClick] = true
-		ClickCastFrames[reputationBarClick] = true
-		ClickCastFrames[healthBarClick] = true
-		ClickCastFrames[powerBarClick] = true
-		ClickCastFrames[comboBarClick] = true
-	else
-		portraitButtonClick:SetAttribute( "type1", "target")
-		followBarClick:SetAttribute( "type1", "target")
-		experienceBarClick:SetAttribute( "type1", "target")
-		reputationBarClick:SetAttribute( "type1", "target")
-		healthBarClick:SetAttribute( "type1", "target")
-		powerBarClick:SetAttribute( "type1", "target")
-		comboBarClick:SetAttribute( "type1", "target")
-	end
-end
-
-function AJM:HideJambaTeamStatusBar( characterName )
-	local parentFrame = JambaDisplayTeamListFrame
-	-- Get (or create and get) the character status bar information.
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	if characterStatusBar == nil then
-		AJM:CreateJambaTeamStatusBar( characterName, parentFrame )
-		characterStatusBar = AJM.characterStatusBar[characterName]
-	end
-	-- Hide the bars.
-	characterStatusBar["portraitButton"]:Hide()
-	characterStatusBar["portraitButtonClick"]:Hide()
---	characterStatusBar["bagInformationFrame"]:Hide()
-	characterStatusBar["ilvlInformationFrame"]:Hide()
-	characterStatusBar["followBar"]:Hide()
-	characterStatusBar["followBarClick"]:Hide()
-	characterStatusBar["experienceBar"]:Hide()
-	characterStatusBar["experienceBarClick"]:Hide()
-	characterStatusBar["reputationBar"]:Hide()
-	characterStatusBar["reputationBarClick"]:Hide()
-	characterStatusBar["healthBar"]:Hide()
-	characterStatusBar["healthBarClick"]:Hide()
-	characterStatusBar["powerBar"]:Hide()
-	characterStatusBar["powerBarClick"]:Hide()
-	characterStatusBar["comboBar"]:Hide()
-	characterStatusBar["comboBarClick"]:Hide()
-end
-
-function AJM:UpdateJambaTeamStatusBar( characterName, characterPosition )
-	local parentFrame = JambaDisplayTeamListFrame
-	-- Get (or create and get) the character status bar information.
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	if characterStatusBar == nil then
-		AJM:CreateJambaTeamStatusBar( characterName, parentFrame )
-		characterStatusBar = AJM.characterStatusBar[characterName]
-	end
-	-- Set the positions.
-	local characterHeight = GetCharacterHeight()
-	local characterWidth = GetCharacterWidth()
-	local positionLeft = 0
-	local positionTop = -AJM.db.teamListTitleHeight - (AJM.db.teamListVerticalSpacing * 2)
-	if AJM.db.teamListHorizontal == true then
-		positionLeft = -6 + (characterPosition * characterWidth) + (AJM.db.teamListHorizontalSpacing * 3)
-	else
-		positionLeft = 6
-		positionTop = positionTop - (characterPosition * characterHeight)
-	end
-	-- Display the portrait.
-	local portraitButton = characterStatusBar["portraitButton"]
-	local portraitButtonClick = characterStatusBar["portraitButtonClick"]
-	if AJM.db.showCharacterPortrait == true then
-		portraitButton:ClearModel()
-		portraitButton:SetUnit( characterName )
-		portraitButton:SetPortraitZoom( 1 )
-        portraitButton:SetCamDistanceScale( 1 )
-        portraitButton:SetPosition( 0, 0, 0 )
-        portraitButton:SetWidth( AJM.db.characterPortraitWidth )
-		portraitButton:SetHeight( AJM.db.characterPortraitWidth )
-		portraitButton:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		portraitButtonClick:SetWidth( AJM.db.characterPortraitWidth )
-		portraitButtonClick:SetHeight( AJM.db.characterPortraitWidth )
-		portraitButtonClick:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		--SetPortraitTexture( portraitButton.Texture, characterName )
-		--portraitButton.Texture:SetAllPoints()
-		portraitButton:Show()
-		portraitButtonClick:Show()
-		positionLeft = positionLeft + AJM.db.characterPortraitWidth + AJM.db.teamListHorizontalSpacing
-	else
-		portraitButton:Hide()
-		portraitButtonClick:Hide()
-	end
-	-- Display the follow bar.
-	local followBar	= characterStatusBar["followBar"]
-	local followBarClick = characterStatusBar["followBarClick"]
-	if AJM.db.showFollowStatus == true then
-		followBar.backgroundTexture:SetAllPoints()
-		followBar:SetWidth( AJM.db.followStatusWidth )
-		followBar:SetHeight( AJM.db.followStatusHeight )
-		followBar:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		followBarClick:SetWidth( AJM.db.followStatusWidth )
-		followBarClick:SetHeight( AJM.db.followStatusHeight )
-		followBarClick:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		followBar:Show()
-		followBarClick:Show()
-		if AJM.db.barsAreStackedVertically == true then
-			positionTop = positionTop - AJM.db.followStatusHeight - AJM.db.barVerticalSpacing
-		else
-			positionLeft = positionLeft + AJM.db.followStatusWidth + AJM.db.teamListHorizontalSpacing
-		end
-	else
-		followBar:Hide()
-		followBarClick:Hide()
-	end
-	-- Display the experience bar.
-	local experienceBar	= characterStatusBar["experienceBar"]
-	local experienceBarClick	= characterStatusBar["experienceBarClick"]
-	if AJM.db.showExperienceStatus == true then
-		experienceBar.backgroundTexture:SetAllPoints()
-		experienceBar:SetWidth( AJM.db.experienceStatusWidth )
-		experienceBar:SetHeight( AJM.db.experienceStatusHeight )
-		experienceBar:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		experienceBarClick:SetWidth( AJM.db.experienceStatusWidth )
-		experienceBarClick:SetHeight( AJM.db.experienceStatusHeight )
-		experienceBarClick:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		experienceBar:Show()
-		experienceBarClick:Show()
-		if AJM.db.barsAreStackedVertically == true then
-			positionTop = positionTop - AJM.db.experienceStatusHeight - AJM.db.barVerticalSpacing
-		else
-			positionLeft = positionLeft + AJM.db.experienceStatusWidth + AJM.db.teamListHorizontalSpacing
-		end
-	else
-		experienceBar:Hide()
-		experienceBarClick:Hide()
-	end
-	-- Display the reputation bar.
-	local reputationBar	= characterStatusBar["reputationBar"]
-	local reputationBarClick = characterStatusBar["reputationBarClick"]
-	if AJM.db.showReputationStatus == true then
-		reputationBar.backgroundTexture:SetAllPoints()
-		reputationBar:SetWidth( AJM.db.reputationStatusWidth )
-		reputationBar:SetHeight( AJM.db.reputationStatusHeight )
-		reputationBar:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		reputationBarClick:SetWidth( AJM.db.reputationStatusWidth )
-		reputationBarClick:SetHeight( AJM.db.reputationStatusHeight )
-		reputationBarClick:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		reputationBar:Show()
-		reputationBarClick:Show()
-		if AJM.db.barsAreStackedVertically == true then
-			positionTop = positionTop - AJM.db.reputationStatusHeight - AJM.db.barVerticalSpacing
-		else
-			positionLeft = positionLeft + AJM.db.reputationStatusWidth + AJM.db.teamListHorizontalSpacing
-		end
-	else
-		reputationBar:Hide()
-		reputationBarClick:Hide()
-	end
-	-- Display the health bar.
-	local healthBar	= characterStatusBar["healthBar"]
-	local healthBarClick = characterStatusBar["healthBarClick"]
-	if AJM.db.showHealthStatus == true then
-		healthBar.backgroundTexture:SetAllPoints()
-		healthBar:SetWidth( AJM.db.healthStatusWidth )
-		healthBar:SetHeight( AJM.db.healthStatusHeight )
-		healthBar:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		healthBarClick:SetWidth( AJM.db.healthStatusWidth )
-		healthBarClick:SetHeight( AJM.db.healthStatusHeight )
-		healthBarClick:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		healthBar:Show()
-		healthBarClick:Show()
-		if AJM.db.barsAreStackedVertically == true then
-			positionTop = positionTop - AJM.db.healthStatusHeight - AJM.db.barVerticalSpacing
-		else
-			positionLeft = positionLeft + AJM.db.healthStatusWidth + AJM.db.teamListHorizontalSpacing
-		end
-	else
-		healthBar:Hide()
-		healthBarClick:Hide()
-	end
-	-- Display the power bar.
-	local powerBar = characterStatusBar["powerBar"]
-	local powerBarClick = characterStatusBar["powerBarClick"]
-	if AJM.db.showPowerStatus == true then
-		powerBar.backgroundTexture:SetAllPoints()
-		powerBar:SetWidth( AJM.db.powerStatusWidth )
-		powerBar:SetHeight( AJM.db.powerStatusHeight )
-		powerBar:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		powerBarClick:SetWidth( AJM.db.powerStatusWidth )
-		powerBarClick:SetHeight( AJM.db.powerStatusHeight )
-		powerBarClick:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		powerBar:Show()
-		powerBarClick:Show()
-		if AJM.db.barsAreStackedVertically == true then
-			positionTop = positionTop - AJM.db.powerStatusHeight - AJM.db.barVerticalSpacing
-		else
-			positionLeft = positionLeft + AJM.db.powerStatusWidth + AJM.db.teamListHorizontalSpacing
-		end
-	else
-		powerBar:Hide()
-		powerBarClick:Hide()
-	end
-	-- Display the Combo Point bar.
-	local comboBar = characterStatusBar["comboBar"]
-	local comboBarClick = characterStatusBar["comboBarClick"]
-	if AJM.db.showComboStatus == true then
-		comboBar.backgroundTexture:SetAllPoints()
-		comboBar:SetWidth( AJM.db.comboStatusWidth )
-		comboBar:SetHeight( AJM.db.comboStatusHeight )
-		comboBar:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		comboBarClick:SetWidth( AJM.db.comboStatusWidth )
-		comboBarClick:SetHeight( AJM.db.comboStatusHeight )
-		comboBarClick:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		comboBar:Show()
-		comboBarClick:Show()
-		if AJM.db.barsAreStackedVertically == true then
-			positionTop = positionTop - AJM.db.comboStatusHeight - AJM.db.barVerticalSpacing
-		else
-			positionLeft = positionLeft + AJM.db.comboStatusWidth + AJM.db.teamListHorizontalSpacing
-		end
-	else
-		comboBar:Hide()
-		comboBarClick:Hide()
-	end
---[[
-	-- Display the bag information
-	local bagInformationFrame = characterStatusBar["bagInformationFrame"]
-	local bagInformationFrameText = characterStatusBar["bagInformationFrameText"]
-	if AJM.db.showBagInformation == true then
-		bagInformationFrame:SetWidth( AJM.db.bagInformationWidth )
-		bagInformationFrame:SetHeight( AJM.db.bagInformationHeight )
-		bagInformationFrame:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		bagInformationFrame:Show()
-		if AJM.db.barsAreStackedVertically == true then
-			positionTop = positionTop - AJM.db.bagInformationHeight - AJM.db.barVerticalSpacing
-		else
-			positionLeft = positionLeft + AJM.db.bagInformationWidth + AJM.db.teamListHorizontalSpacing
-		end
-	else
-		bagInformationFrame:Hide()
-	end
-	--]]
-	--[[
-	-- Display the ilevel information
-	local ilvlInformationFrame = characterStatusBar["ilvlInformationFrame"]
-	local ilvlInformationFrameText = characterStatusBar["ilvlInformationFrameText"]
-	if AJM.db.showIlvlInformation == true then
-		ilvlInformationFrame:SetWidth( AJM.db.ilvlInformationWidth )
-		ilvlInformationFrame:SetHeight( AJM.db.ilvlInformationHeight )
-		ilvlInformationFrame:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-		ilvlInformationFrame:Show()
-		if AJM.db.barsAreStackedVertically == true then
-			positionTop = positionTop - AJM.db.ilvlInformationHeight - AJM.db.barVerticalSpacing
-		else
-			positionLeft = positionLeft + AJM.db.ilvlInformationWidth + AJM.db.teamListHorizontalSpacing
-		end
-	else
-		ilvlInformationFrame:Hide()
-	end
-	--]]
-end
-
--------------------------------------------------------------------------------------------------------------
--- Settings Dialogs.
--------------------------------------------------------------------------------------------------------------
-
-local function SettingsCreateDisplayOptions( top )
-	-- Get positions.
-	local checkBoxHeight = JambaHelperSettings:GetCheckBoxHeight()
-	local labelContinueHeight = JambaHelperSettings:GetContinueLabelHeight()
-	local sliderHeight = JambaHelperSettings:GetSliderHeight()
-	local mediaHeight = JambaHelperSettings:GetMediaHeight()
-	local left = JambaHelperSettings:LeftOfSettings()
-	local headingHeight = JambaHelperSettings:HeadingHeight()
-	local headingWidth = JambaHelperSettings:HeadingWidth( true )
-	local horizontalSpacing = JambaHelperSettings:GetHorizontalSpacing()
-	local verticalSpacing = JambaHelperSettings:GetVerticalSpacing()
-	local sectionSpacing = verticalSpacing * 4
-	local halfWidthSlider = (headingWidth - horizontalSpacing) / 2
-	local thirdWidth = (headingWidth - (horizontalSpacing * 2)) / 3
-	local column2left = left + halfWidthSlider
-	local left2 = left + thirdWidth
-	local left3 = left + (thirdWidth * 2)
-	local movingTop = top
-	-- Create show.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Show"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxShowTeamList = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Show Team List"],
-		AJM.SettingsToggleShowTeamList
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsCheckBoxShowTeamListOnlyOnMaster = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Only On Master"],
-		AJM.SettingsToggleShowTeamListOnMasterOnly
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsCheckBoxHideTeamListInCombat = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Hide Team List In Combat"],
-		AJM.SettingsToggleHideTeamListInCombat
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsCheckBoxEnableClique = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Enable Clique Support - **reload UI to take effect**"],
-		AJM.SettingsToggleEnableClique
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	-- Create appearance & layout.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Appearance & Layout"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxStackVertically = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Stack Bars Vertically"],
-		AJM.SettingsToggleStackVertically
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsCheckBoxTeamHorizontal = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Display Team List Horizontally"],
-		AJM.SettingsToggleTeamHorizontal
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsCheckBoxShowListTitle = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Show Team List Title"],
-		AJM.SettingsToggleShowTeamListTitle
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsTeamListScaleSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Scale"]
-	)
-	AJM.settingsControl.displayOptionsTeamListScaleSlider:SetSliderValues( 0.5, 2, 0.01 )
-	AJM.settingsControl.displayOptionsTeamListScaleSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeScale )
-	movingTop = movingTop - sliderHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsTeamListTransparencySlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Transparency"]
-	)
-	AJM.settingsControl.displayOptionsTeamListTransparencySlider:SetSliderValues( 0, 1, 0.01 )
-	AJM.settingsControl.displayOptionsTeamListTransparencySlider:SetCallback( "OnValueChanged", AJM.SettingsChangeTransparency )
-	movingTop = movingTop - sliderHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsTeamListMediaStatus = JambaHelperSettings:CreateMediaStatus(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Status Bar Texture"]
-	)
-	AJM.settingsControl.displayOptionsTeamListMediaStatus:SetCallback( "OnValueChanged", AJM.SettingsChangeStatusBarTexture )
-	movingTop = movingTop - mediaHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsTeamListMediaBorder = JambaHelperSettings:CreateMediaBorder(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Border Style"]
-	)
-	AJM.settingsControl.displayOptionsTeamListMediaBorder:SetCallback( "OnValueChanged", AJM.SettingsChangeBorderStyle )
-	AJM.settingsControl.displayOptionsBorderColourPicker = JambaHelperSettings:CreateColourPicker(
-		AJM.settingsControl,
-		halfWidthSlider,
-		column2left + 15,
-		movingTop - 15,
-		L["Border Colour"]
-	)
-	AJM.settingsControl.displayOptionsBorderColourPicker:SetHasAlpha( true )
-	AJM.settingsControl.displayOptionsBorderColourPicker:SetCallback( "OnValueConfirmed", AJM.SettingsBorderColourPickerChanged )
-	movingTop = movingTop - mediaHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsTeamListMediaBackground = JambaHelperSettings:CreateMediaBackground(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Background"]
-	)
-	AJM.settingsControl.displayOptionsTeamListMediaBackground:SetCallback( "OnValueChanged", AJM.SettingsChangeBackgroundStyle )
-	AJM.settingsControl.displayOptionsBackgroundColourPicker = JambaHelperSettings:CreateColourPicker(
-		AJM.settingsControl,
-		halfWidthSlider,
-		column2left + 15,
-		movingTop - 15,
-		L["Background Colour"]
-	)
-	AJM.settingsControl.displayOptionsBackgroundColourPicker:SetHasAlpha( true )
-	AJM.settingsControl.displayOptionsBackgroundColourPicker:SetCallback( "OnValueConfirmed", AJM.SettingsBackgroundColourPickerChanged )
-	movingTop = movingTop - mediaHeight - sectionSpacing
-	-- Create portrait.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Portrait"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxShowPortrait = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Show"],
-		AJM.SettingsToggleShowPortrait
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsPortraitWidthSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Width"]
-	)
-	AJM.settingsControl.displayOptionsPortraitWidthSlider:SetSliderValues( 5, 200, 1 )
-	AJM.settingsControl.displayOptionsPortraitWidthSlider:SetCallback( "OnValueChanged", AJM.SettingsChangePortraitWidth )
-	movingTop = movingTop - sliderHeight - sectionSpacing
-	-- Create follow status.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Follow Status Bar"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxShowFollowStatus = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left,
-		movingTop,
-		L["Show"],
-		AJM.SettingsToggleShowFollowStatus
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowFollowStatusName = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left2,
-		movingTop,
-		L["Name"],
-		AJM.SettingsToggleShowFollowStatusName
-	)
-	AJM.settingsControl.displayOptionsCheckBoxstackName = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left3,
-		movingTop,
-		L["Stack Text"],
-		AJM.SettingsTogglestackName
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsCheckBoxShowFollowStatusLevel = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left,
-		movingTop,
-		L["Level"],
-		AJM.SettingsToggleShowFollowStatusLevel
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowIlvlInformation = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left2,
-		movingTop,
-		L["Show Item Level"],
-		AJM.SettingsToggleShowIlvlInformation
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowEquippedOnly = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth + thirdWidth,
-		left3,
-		movingTop,
-		L["Equipped iLvl Only"],
-		AJM.SettingsToggleShowEquippedOnly
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsFollowStatusWidthSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Width"]
-	)
-	AJM.settingsControl.displayOptionsFollowStatusWidthSlider:SetSliderValues( 5, 200, 1 )
-	AJM.settingsControl.displayOptionsFollowStatusWidthSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeFollowStatusWidth )
-	AJM.settingsControl.displayOptionsFollowStatusHeightSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		column2left,
-		movingTop,
-		L["Height"]
-	)
-	AJM.settingsControl.displayOptionsFollowStatusHeightSlider:SetSliderValues( 5, 50, 1 )
-	AJM.settingsControl.displayOptionsFollowStatusHeightSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeFollowStatusHeight )
-	movingTop = movingTop - sliderHeight - sectionSpacing
-	-- Create experience status.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Experience Bar"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxShowExperienceStatus = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left,
-		movingTop,
-		L["Show"],
-		AJM.SettingsToggleShowExperienceStatus
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowExperienceStatusValues = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left2,
-		movingTop,
-		L["Values"],
-		AJM.SettingsToggleShowExperienceStatusValues
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowExperienceStatusPercentage = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left3,
-		movingTop,
-		L["Percentage"],
-		AJM.SettingsToggleShowExperienceStatusPercentage
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsExperienceStatusWidthSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Width"]
-	)
-	AJM.settingsControl.displayOptionsExperienceStatusWidthSlider:SetSliderValues( 5, 200, 1 )
-	AJM.settingsControl.displayOptionsExperienceStatusWidthSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeExperienceStatusWidth )
-	AJM.settingsControl.displayOptionsExperienceStatusHeightSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		column2left,
-		movingTop,
-		L["Height"]
-	)
-	AJM.settingsControl.displayOptionsExperienceStatusHeightSlider:SetSliderValues( 5, 50, 1 )
-	AJM.settingsControl.displayOptionsExperienceStatusHeightSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeExperienceStatusHeight )
-	movingTop = movingTop - sliderHeight - sectionSpacing
-	-- Create reputation status.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Reputation Bar"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxShowReputationStatus = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left,
-		movingTop,
-		L["Show"],
-		AJM.SettingsToggleShowReputationStatus
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowReputationStatusValues = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left2,
-		movingTop,
-		L["Values"],
-		AJM.SettingsToggleShowReputationStatusValues
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowReputationStatusPercentage = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left3,
-		movingTop,
-		L["Percentage"],
-		AJM.SettingsToggleShowReputationStatusPercentage
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsCheckBoxShowReputationName = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth + thirdWidth,
-		left,
-		movingTop,
-		L["Show Faction Name"],
-		AJM.SettingsToggleShowReputationName
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsReputationStatusWidthSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Width"]
-	)
-	AJM.settingsControl.displayOptionsReputationStatusWidthSlider:SetSliderValues( 5, 400, 1 )
-	AJM.settingsControl.displayOptionsReputationStatusWidthSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeReputationStatusWidth )
-	AJM.settingsControl.displayOptionsReputationStatusHeightSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		column2left,
-		movingTop,
-		L["Height"]
-	)
-	AJM.settingsControl.displayOptionsReputationStatusHeightSlider:SetSliderValues( 5, 50, 1 )
-	AJM.settingsControl.displayOptionsReputationStatusHeightSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeReputationStatusHeight )
-	movingTop = movingTop - sliderHeight - sectionSpacing
-	-- Create health status.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Health Bar"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxShowHealthStatus = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left,
-		movingTop,
-		L["Show"],
-		AJM.SettingsToggleShowHealthStatus
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowHealthStatusValues = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left2,
-		movingTop,
-		L["Values"],
-		AJM.SettingsToggleShowHealthStatusValues
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowHealthStatusPercentage = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left3,
-		movingTop,
-		L["Percentage"],
-		AJM.SettingsToggleShowHealthStatusPercentage
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsHealthStatusWidthSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Width"]
-	)
-	AJM.settingsControl.displayOptionsHealthStatusWidthSlider:SetSliderValues( 5, 200, 1 )
-	AJM.settingsControl.displayOptionsHealthStatusWidthSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeHealthStatusWidth )
-	AJM.settingsControl.displayOptionsHealthStatusHeightSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		column2left,
-		movingTop,
-		L["Height"]
-	)
-	AJM.settingsControl.displayOptionsHealthStatusHeightSlider:SetSliderValues( 5, 50, 1 )
-	AJM.settingsControl.displayOptionsHealthStatusHeightSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeHealthStatusHeight )
-	movingTop = movingTop - sliderHeight - sectionSpacing
-	-- Create power status.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Power Bar"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxShowPowerStatus = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left,
-		movingTop,
-		L["Show"],
-		AJM.SettingsToggleShowPowerStatus
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowPowerStatusValues = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left2,
-		movingTop,
-		L["Values"],
-		AJM.SettingsToggleShowPowerStatusValues
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowPowerStatusPercentage = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left3,
-		movingTop,
-		L["Percentage"],
-		AJM.SettingsToggleShowPowerStatusPercentage
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsPowerStatusWidthSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Width"]
-	)
-	AJM.settingsControl.displayOptionsPowerStatusWidthSlider:SetSliderValues( 5, 200, 1 )
-	AJM.settingsControl.displayOptionsPowerStatusWidthSlider:SetCallback( "OnValueChanged", AJM.SettingsChangePowerStatusWidth )
-	AJM.settingsControl.displayOptionsPowerStatusHeightSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		column2left,
-		movingTop,
-		L["Height"]
-	)
-	AJM.settingsControl.displayOptionsPowerStatusHeightSlider:SetSliderValues( 5, 50, 1 )
-	AJM.settingsControl.displayOptionsPowerStatusHeightSlider:SetCallback( "OnValueChanged", AJM.SettingsChangePowerStatusHeight )
-	movingTop = movingTop - sliderHeight - sectionSpacing
-	-- Create Combo Point status.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Combo Point Bar"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxShowComboStatus = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left,
-		movingTop,
-		L["Show"],
-		AJM.SettingsToggleShowComboStatus
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowComboStatusValues = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left2,
-		movingTop,
-		L["Values"],
-		AJM.SettingsToggleShowComboStatusValues
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowComboStatusPercentage = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left3,
-		movingTop,
-		L["Percentage"],
-		AJM.SettingsToggleShowComboStatusPercentage
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsComboStatusWidthSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Width"]
-	)
-	AJM.settingsControl.displayOptionsComboStatusWidthSlider:SetSliderValues( 5, 200, 1 )
-	AJM.settingsControl.displayOptionsComboStatusWidthSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeComboStatusWidth )
-	AJM.settingsControl.displayOptionsComboStatusHeightSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		column2left,
-		movingTop,
-		L["Height"]
-	)
-	AJM.settingsControl.displayOptionsComboStatusHeightSlider:SetSliderValues( 5, 50, 1 )
-	AJM.settingsControl.displayOptionsComboStatusHeightSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeComboStatusHeight )
-	movingTop = movingTop - sliderHeight - sectionSpacing
---[[
-	-- Create bag information status.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Bag Information"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxShowBagInformation = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left,
-		movingTop,
-		L["Show"],
-		AJM.SettingsToggleShowBagInformation
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowFreeBagSlotsOnly = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth + thirdWidth,
-		left2,
-		movingTop,
-		L["Only Show Free Bag Slots"],
-		AJM.SettingsToggleShowFreeBagSlotsOnly
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsBagInformationWidthSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Width"]
-	)
-	AJM.settingsControl.displayOptionsBagInformationWidthSlider:SetSliderValues( 5, 200, 1 )
-	AJM.settingsControl.displayOptionsBagInformationWidthSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeBagInformationWidth )
-	AJM.settingsControl.displayOptionsBagInformationHeightSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		column2left,
-		movingTop,
-		L["Height"]
-	)
-	AJM.settingsControl.displayOptionsBagInformationHeightSlider:SetSliderValues( 5, 50, 1 )
-	AJM.settingsControl.displayOptionsBagInformationHeightSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeBagInformationHeight )
-	movingTop = movingTop - sliderHeight - verticalSpacing
---]]
-	--[[
-	-- Create Ilvl information status.
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Players Item Level Information"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.displayOptionsCheckBoxShowIlvlInformation = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth,
-		left,
-		movingTop,
-		L["Show"],
-		AJM.SettingsToggleShowIlvlInformation
-	)
-	AJM.settingsControl.displayOptionsCheckBoxShowEquippedOnly = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		thirdWidth + thirdWidth,
-		left2,
-		movingTop,
-		L["Only Show Equipped Item Level Only"],
-		AJM.SettingsToggleShowEquippedOnly
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.displayOptionsIlvlInformationWidthSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		left,
-		movingTop,
-		L["Width"]
-	)
-	AJM.settingsControl.displayOptionsIlvlInformationWidthSlider:SetSliderValues( 5, 200, 1 )
-	AJM.settingsControl.displayOptionsIlvlInformationWidthSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeIlvlInformationWidth )
-	AJM.settingsControl.displayOptionsIlvlInformationHeightSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		halfWidthSlider,
-		column2left,
-		movingTop,
-		L["Height"]
-	)
-	AJM.settingsControl.displayOptionsIlvlInformationHeightSlider:SetSliderValues( 5, 50, 1 )
-	AJM.settingsControl.displayOptionsIlvlInformationHeightSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeIlvlInformationHeight )
-	movingTop = movingTop - sliderHeight - verticalSpacing
-	--]]
-	return movingTop
-end
-
-local function SettingsCreate()
-	AJM.settingsControl = {}
-	-- Create the settings panel.
-	JambaHelperSettings:CreateSettings(
-		AJM.settingsControl,
-		AJM.moduleDisplayName,
-		AJM.parentDisplayName,
-		AJM.SettingsPushSettingsClick
-	)
-	local bottomOfDisplayOptions = SettingsCreateDisplayOptions( JambaHelperSettings:TopOfSettings() )
-	AJM.settingsControl.widgetSettings.content:SetHeight( -bottomOfDisplayOptions )
-	-- Help
-	local helpTable = {}
-	JambaHelperSettings:CreateHelp( AJM.settingsControl, helpTable, AJM:GetConfiguration() )
-end
-
--------------------------------------------------------------------------------------------------------------
--- Settings Populate.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:BeforeJambaProfileChanged()
-	AJM:RefreshTeamListControlsHide()
-end
-
-function AJM:OnJambaProfileChanged()
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsRefresh()
-	AJM.settingsControl.displayOptionsCheckBoxShowTeamList:SetValue( AJM.db.showTeamList )
-	AJM.settingsControl.displayOptionsCheckBoxShowTeamListOnlyOnMaster:SetValue( AJM.db.showTeamListOnMasterOnly )
-	AJM.settingsControl.displayOptionsCheckBoxHideTeamListInCombat:SetValue( AJM.db.hideTeamListInCombat )
-	AJM.settingsControl.displayOptionsCheckBoxEnableClique:SetValue( AJM.db.enableClique )
-	AJM.settingsControl.displayOptionsCheckBoxStackVertically:SetValue( AJM.db.barsAreStackedVertically )
-	AJM.settingsControl.displayOptionsCheckBoxTeamHorizontal:SetValue( AJM.db.teamListHorizontal )
-	AJM.settingsControl.displayOptionsCheckBoxShowListTitle:SetValue( AJM.db.showListTitle )
-	AJM.settingsControl.displayOptionsTeamListTransparencySlider:SetValue( AJM.db.frameAlpha )
-	AJM.settingsControl.displayOptionsTeamListScaleSlider:SetValue( AJM.db.teamListScale )
-	AJM.settingsControl.displayOptionsTeamListMediaStatus:SetValue( AJM.db.statusBarTexture )
-	AJM.settingsControl.displayOptionsTeamListMediaBorder:SetValue( AJM.db.borderStyle )
-	AJM.settingsControl.displayOptionsTeamListMediaBackground:SetValue( AJM.db.backgroundStyle )
-	AJM.settingsControl.displayOptionsCheckBoxShowPortrait:SetValue( AJM.db.showCharacterPortrait )
-	AJM.settingsControl.displayOptionsPortraitWidthSlider:SetValue( AJM.db.characterPortraitWidth )
-	AJM.settingsControl.displayOptionsCheckBoxShowFollowStatus:SetValue( AJM.db.showFollowStatus )
-	AJM.settingsControl.displayOptionsCheckBoxShowFollowStatusName:SetValue( AJM.db.followStatusShowName )
-	AJM.settingsControl.displayOptionsCheckBoxShowFollowStatusLevel:SetValue( AJM.db.followStatusShowLevel )
-	AJM.settingsControl.displayOptionsFollowStatusWidthSlider:SetValue( AJM.db.followStatusWidth )
-	AJM.settingsControl.displayOptionsFollowStatusHeightSlider:SetValue( AJM.db.followStatusHeight )
-	AJM.settingsControl.displayOptionsCheckBoxShowExperienceStatus:SetValue( AJM.db.showExperienceStatus )
-	AJM.settingsControl.displayOptionsCheckBoxShowExperienceStatusValues:SetValue( AJM.db.experienceStatusShowValues )
-	AJM.settingsControl.displayOptionsCheckBoxShowExperienceStatusPercentage:SetValue( AJM.db.experienceStatusShowPercentage )
-	AJM.settingsControl.displayOptionsExperienceStatusWidthSlider:SetValue( AJM.db.experienceStatusWidth )
-	AJM.settingsControl.displayOptionsExperienceStatusHeightSlider:SetValue( AJM.db.experienceStatusHeight )
-	AJM.settingsControl.displayOptionsCheckBoxShowReputationStatus:SetValue( AJM.db.showReputationStatus )
-	AJM.settingsControl.displayOptionsCheckBoxShowReputationName:SetValue( AJM.db.showReputationName )
-	AJM.settingsControl.displayOptionsCheckBoxShowReputationStatusValues:SetValue( AJM.db.reputationStatusShowValues )
-	AJM.settingsControl.displayOptionsCheckBoxShowReputationStatusPercentage:SetValue( AJM.db.reputationStatusShowPercentage )
-	AJM.settingsControl.displayOptionsReputationStatusWidthSlider:SetValue( AJM.db.reputationStatusWidth )
-	AJM.settingsControl.displayOptionsReputationStatusHeightSlider:SetValue( AJM.db.reputationStatusHeight )
-	AJM.settingsControl.displayOptionsCheckBoxShowHealthStatus:SetValue( AJM.db.showHealthStatus )
-	AJM.settingsControl.displayOptionsCheckBoxShowHealthStatusValues:SetValue( AJM.db.healthStatusShowValues )
-	AJM.settingsControl.displayOptionsCheckBoxShowHealthStatusPercentage:SetValue( AJM.db.healthStatusShowPercentage )
-	AJM.settingsControl.displayOptionsHealthStatusWidthSlider:SetValue( AJM.db.healthStatusWidth )
-	AJM.settingsControl.displayOptionsHealthStatusHeightSlider:SetValue( AJM.db.healthStatusHeight )
-	AJM.settingsControl.displayOptionsCheckBoxShowPowerStatus:SetValue( AJM.db.showPowerStatus )
-	AJM.settingsControl.displayOptionsCheckBoxShowPowerStatusValues:SetValue( AJM.db.powerStatusShowValues )
-	AJM.settingsControl.displayOptionsCheckBoxShowPowerStatusPercentage:SetValue( AJM.db.powerStatusShowPercentage )
-	AJM.settingsControl.displayOptionsPowerStatusWidthSlider:SetValue( AJM.db.powerStatusWidth )
-	AJM.settingsControl.displayOptionsPowerStatusHeightSlider:SetValue( AJM.db.powerStatusHeight )
-	AJM.settingsControl.displayOptionsCheckBoxShowComboStatus:SetValue( AJM.db.showComboStatus )
-	AJM.settingsControl.displayOptionsCheckBoxShowComboStatusValues:SetValue( AJM.db.comboStatusShowValues )
-	AJM.settingsControl.displayOptionsCheckBoxShowComboStatusPercentage:SetValue( AJM.db.comboStatusShowPercentage )
-	AJM.settingsControl.displayOptionsComboStatusWidthSlider:SetValue( AJM.db.comboStatusWidth )
-	AJM.settingsControl.displayOptionsComboStatusHeightSlider:SetValue( AJM.db.comboStatusHeight )
-	AJM.settingsControl.displayOptionsBackgroundColourPicker:SetColor( AJM.db.frameBackgroundColourR, AJM.db.frameBackgroundColourG, AJM.db.frameBackgroundColourB, AJM.db.frameBackgroundColourA )
-	AJM.settingsControl.displayOptionsBorderColourPicker:SetColor( AJM.db.frameBorderColourR, AJM.db.frameBorderColourG, AJM.db.frameBorderColourB, AJM.db.frameBorderColourA )
---	AJM.settingsControl.displayOptionsCheckBoxShowBagInformation:SetValue( AJM.db.showBagInformation )
---	AJM.settingsControl.displayOptionsCheckBoxShowFreeBagSlotsOnly:SetValue( AJM.db.showBagFreeSlotsOnly )
---	AJM.settingsControl.displayOptionsBagInformationWidthSlider:SetValue( AJM.db.bagInformationWidth )
---	AJM.settingsControl.displayOptionsBagInformationHeightSlider:SetValue( AJM.db.bagInformationHeight )
-	--Ebony
-	AJM.settingsControl.displayOptionsCheckBoxShowIlvlInformation:SetValue( AJM.db.showIlvlInformation )
-	AJM.settingsControl.displayOptionsCheckBoxShowEquippedOnly:SetValue( AJM.db.ShowEquippedOnly )
-	AJM.settingsControl.displayOptionsCheckBoxstackName:SetValue( AJM.db.stackName )
-	--AJM.settingsControl.displayOptionsIlvlInformationWidthSlider:SetValue( AJM.db.ilvlInformationWidth )
-	--AJM.settingsControl.displayOptionsIlvlInformationHeightSlider:SetValue( AJM.db.ilvlInformationHeight )
-	-- State.
-	-- Trying to change state in combat lockdown causes taint. Let's not do that. Eventually it would be nice to have a "proper state driven team display",
-	-- but this workaround is enough for now.
-	if not InCombatLockdown() then
-		AJM.settingsControl.displayOptionsCheckBoxShowTeamListOnlyOnMaster:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxHideTeamListInCombat:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxEnableClique:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxStackVertically:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxTeamHorizontal:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowListTitle:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsTeamListScaleSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsTeamListTransparencySlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsTeamListMediaStatus:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsTeamListMediaBorder:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsTeamListMediaBackground:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowPortrait:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsPortraitWidthSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowFollowStatus:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowFollowStatusName:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowFollowStatusLevel:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsFollowStatusWidthSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsFollowStatusHeightSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowExperienceStatus:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowExperienceStatusValues:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowExperienceStatusPercentage:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsExperienceStatusWidthSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsExperienceStatusHeightSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowReputationStatus:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowReputationName:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowReputationStatusValues:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowReputationStatusPercentage:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsReputationStatusWidthSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsReputationStatusHeightSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowHealthStatus:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowHealthStatusValues:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowHealthStatusPercentage:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsHealthStatusWidthSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsHealthStatusHeightSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowPowerStatus:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowPowerStatusValues:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowPowerStatusPercentage:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsPowerStatusWidthSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsPowerStatusHeightSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowComboStatus:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowComboStatusValues:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowComboStatusPercentage:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsComboStatusWidthSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsComboStatusHeightSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsBackgroundColourPicker:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsBorderColourPicker:SetDisabled( not AJM.db.showTeamList )
---		AJM.settingsControl.displayOptionsCheckBoxShowBagInformation:SetDisabled( not AJM.db.showTeamList )
---		AJM.settingsControl.displayOptionsCheckBoxShowFreeBagSlotsOnly:SetDisabled( not AJM.db.showTeamList )
---		AJM.settingsControl.displayOptionsBagInformationWidthSlider:SetDisabled( not AJM.db.showTeamList )
---		AJM.settingsControl.displayOptionsBagInformationHeightSlider:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowIlvlInformation:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxShowEquippedOnly:SetDisabled( not AJM.db.showTeamList )
-		AJM.settingsControl.displayOptionsCheckBoxstackName:SetDisabled( not AJM.db.showTeamList )
-		--AJM.settingsControl.displayOptionsIlvlInformationWidthSlider:SetDisabled( not AJM.db.showTeamList )
-		--AJM.settingsControl.displayOptionsIlvlInformationHeightSlider:SetDisabled( not AJM.db.showTeamList )
-		if AJM.teamListCreated == true then
-			AJM:RefreshTeamListControls()
-			AJM:SettingsUpdateBorderStyle()
-			AJM:SettingsUpdateStatusBarTexture()
-			AJM:SetTeamListVisibility()
-			AJM:SettingsUpdateFollowTextAll()
-			AJM:SettingsUpdateExperienceAll()
-			AJM:SettingsUpdateReputationAll()
-			AJM:SettingsUpdateHealthAll()
-			AJM:SettingsUpdatePowerAll()
-			AJM:SettingsUpdateComboAll()
---			AJM:SettingsUpdateBagInformationAll()
-			--AJM:SettingsUpdateIlvlInformationAll()
-		end
-	else
-		AJM.updateSettingsAfterCombat = true
-	end
-end
-
--- Settings received.
-function AJM:JambaOnSettingsReceived( characterName, settings )
-	if characterName ~= AJM.characterName then
-		-- Update the settings.
-		AJM.db.showTeamList = settings.showTeamList
-		AJM.db.showTeamListOnMasterOnly = settings.showTeamListOnMasterOnly
-		AJM.db.hideTeamListInCombat = settings.hideTeamListInCombat
-		AJM.db.enableClique = settings.enableClique
-		AJM.db.barsAreStackedVertically = settings.barsAreStackedVertically
-		AJM.db.teamListHorizontal = settings.teamListHorizontal
-		AJM.db.showListTitle = settings.showListTitle
-		AJM.db.teamListScale = settings.teamListScale
-		AJM.db.statusBarTexture = settings.statusBarTexture
-		AJM.db.borderStyle = settings.borderStyle
-		AJM.db.backgroundStyle = settings.backgroundStyle
-		AJM.db.showCharacterPortrait = settings.showCharacterPortrait
-		AJM.db.characterPortraitWidth = settings.characterPortraitWidth
-		AJM.db.showFollowStatus = settings.showFollowStatus
-		AJM.db.followStatusWidth = settings.followStatusWidth
-		AJM.db.followStatusHeight = settings.followStatusHeight
-		AJM.db.followStatusShowName = settings.followStatusShowName
-		AJM.db.followStatusShowLevel = settings.followStatusShowLevel
-		AJM.db.showExperienceStatus = settings.showExperienceStatus
-		AJM.db.experienceStatusWidth = settings.experienceStatusWidth
-		AJM.db.experienceStatusHeight = settings.experienceStatusHeight
-		AJM.db.experienceStatusShowValues = settings.experienceStatusShowValues
-		AJM.db.experienceStatusShowPercentage = settings.experienceStatusShowPercentage
-		AJM.db.showReputationStatus = settings.showReputationStatus
-		AJM.db.showReputationName = settings.showReputationName
-		AJM.db.reputationStatusWidth = settings.reputationStatusWidth
-		AJM.db.reputationStatusHeight = settings.reputationStatusHeight
-		AJM.db.reputationStatusShowValues = settings.reputationStatusShowValues
-		AJM.db.reputationStatusShowPercentage = settings.reputationStatusShowPercentage
-		AJM.db.showHealthStatus = settings.showHealthStatus
-		AJM.db.healthStatusWidth = settings.healthStatusWidth
-		AJM.db.healthStatusHeight = settings.healthStatusHeight
-		AJM.db.healthStatusShowValues = settings.healthStatusShowValues
-		AJM.db.healthStatusShowPercentage = settings.healthStatusShowPercentage
-		AJM.db.showPowerStatus = settings.showPowerStatus
-		AJM.db.powerStatusWidth = settings.powerStatusWidth
-		AJM.db.powerStatusHeight = settings.powerStatusHeight
-		AJM.db.powerStatusShowValues = settings.powerStatusShowValues
-		AJM.db.powerStatusShowPercentage = settings.powerStatusShowPercentage
-		AJM.db.showComboStatus = settings.showComboStatus
-		AJM.db.comboStatusWidth = settings.comboStatusWidth
-		AJM.db.comboStatusHeight = settings.comboStatusHeight
-		AJM.db.comboStatusShowValues = settings.comboStatusShowValues
-		AJM.db.comboStatusShowPercentage = settings.comboStatusShowPercentage
---		AJM.db.showBagInformation = settings.showBagInformation
---		AJM.db.showBagFreeSlotsOnly = settings.showBagFreeSlotsOnly
---		AJM.db.bagInformationWidth = settings.bagInformationWidth
---		AJM.db.bagInformationHeight = settings.bagInformationHeight
-		--EBS
-		AJM.db.showIlvlInformation = settings.showIlvlInformation
-		AJM.db.ShowEquippedOnly = settings.ShowEquippedOnly
-		AJM.db.stackName = settings.stackName
-		--AJM.db.ilvlInformationWidth = settings.ilvlInformationWidth
-		--AJM.db.ilvlInformationHeight = settings.ilvlInformationHeight
-		AJM.db.frameAlpha = settings.frameAlpha
-		AJM.db.framePoint = settings.framePoint
-		AJM.db.frameRelativePoint = settings.frameRelativePoint
-		AJM.db.frameXOffset = settings.frameXOffset
-		AJM.db.frameYOffset = settings.frameYOffset
-		AJM.db.frameBackgroundColourR = settings.frameBackgroundColourR
-		AJM.db.frameBackgroundColourG = settings.frameBackgroundColourG
-		AJM.db.frameBackgroundColourB = settings.frameBackgroundColourB
-		AJM.db.frameBackgroundColourA = settings.frameBackgroundColourA
-		AJM.db.frameBorderColourR = settings.frameBorderColourR
-		AJM.db.frameBorderColourG = settings.frameBorderColourG
-		AJM.db.frameBorderColourB = settings.frameBorderColourB
-		AJM.db.frameBorderColourA = settings.frameBorderColourA
-		-- Refresh the settings.
-		AJM:SettingsRefresh()
-		-- Tell the player.
-		AJM:Print( L["Settings received from A."]( characterName ) )
-		-- Tell the team?
-		--AJM:JambaSendMessageToTeam( AJM.db.messageArea,  L["Settings received from A."]( characterName ), false )
-	end
-end
-
--------------------------------------------------------------------------------------------------------------
--- Settings Callbacks.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:SettingsPushSettingsClick( event )
-	AJM:JambaSendSettings()
-end
-
-function AJM:SettingsToggleShowTeamList( event, checked )
-	AJM.db.showTeamList = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowTeamListOnMasterOnly( event, checked )
-	AJM.db.showTeamListOnMasterOnly = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleHideTeamListInCombat( event, checked )
-	AJM.db.hideTeamListInCombat = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleEnableClique( event, checked )
-	AJM.db.enableClique = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleStackVertically( event, checked )
-	AJM.db.barsAreStackedVertically = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleTeamHorizontal( event, checked )
-	AJM.db.teamListHorizontal = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowTeamListTitle( event, checked )
-	AJM.db.showListTitle = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeScale( event, value )
-	AJM.db.teamListScale = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeTransparency( event, value )
-	AJM.db.frameAlpha = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeStatusBarTexture( event, value )
-	AJM.db.statusBarTexture = value
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeBorderStyle( event, value )
-	AJM.db.borderStyle = value
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeBackgroundStyle( event, value )
-	AJM.db.backgroundStyle = value
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowPortrait( event, checked )
-	AJM.db.showCharacterPortrait = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangePortraitWidth( event, value )
-	AJM.db.characterPortraitWidth = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowFollowStatus( event, checked )
-	AJM.db.showFollowStatus = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowFollowStatusName( event, checked )
-	AJM.db.followStatusShowName = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowFollowStatusLevel( event, checked )
-	AJM.db.followStatusShowLevel = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeFollowStatusWidth( event, value )
-	AJM.db.followStatusWidth = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeFollowStatusHeight( event, value )
-	AJM.db.followStatusHeight = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowExperienceStatus( event, checked )
-	AJM.db.showExperienceStatus = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowExperienceStatusValues( event, checked )
-	AJM.db.experienceStatusShowValues = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowExperienceStatusPercentage( event, checked )
-	AJM.db.experienceStatusShowPercentage = checked
-	AJM.SettingsRefresh()
-end
-
-function AJM:SettingsChangeExperienceStatusWidth( event, value )
-	AJM.db.experienceStatusWidth = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeExperienceStatusHeight( event, value )
-	AJM.db.experienceStatusHeight = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowReputationStatus( event, checked )
-	AJM.db.showReputationStatus = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowReputationName( event, checked )
-	AJM.db.showReputationName = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowReputationStatusValues( event, checked )
-	AJM.db.reputationStatusShowValues = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowReputationStatusPercentage( event, checked )
-	AJM.db.reputationStatusShowPercentage = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeReputationStatusWidth( event, value )
-	AJM.db.reputationStatusWidth = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeReputationStatusHeight( event, value )
-	AJM.db.reputationStatusHeight = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowHealthStatus( event, checked )
-	AJM.db.showHealthStatus = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowHealthStatusValues( event, checked )
-	AJM.db.healthStatusShowValues = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowHealthStatusPercentage( event, checked )
-	AJM.db.healthStatusShowPercentage = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeHealthStatusWidth( event, value )
-	AJM.db.healthStatusWidth = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeHealthStatusHeight( event, value )
-	AJM.db.healthStatusHeight = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowPowerStatus( event, checked )
-	AJM.db.showPowerStatus = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowPowerStatusValues( event, checked )
-	AJM.db.powerStatusShowValues = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowPowerStatusPercentage( event, checked )
-	AJM.db.powerStatusShowPercentage = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangePowerStatusWidth( event, value )
-	AJM.db.powerStatusWidth = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangePowerStatusHeight( event, value )
-	AJM.db.powerStatusHeight = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowComboStatus( event, checked )
-	AJM.db.showComboStatus = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowComboStatusValues( event, checked )
-	AJM.db.comboStatusShowValues = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowComboStatusPercentage( event, checked )
-	AJM.db.comboStatusShowPercentage = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeComboStatusWidth( event, value )
-	AJM.db.comboStatusWidth = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeComboStatusHeight( event, value )
-	AJM.db.comboStatusHeight = tonumber( value )
-	AJM:SettingsRefresh()
-end
-function AJM:SettingsBackgroundColourPickerChanged( event, r, g, b, a )
-	AJM.db.frameBackgroundColourR = r
-	AJM.db.frameBackgroundColourG = g
-	AJM.db.frameBackgroundColourB = b
-	AJM.db.frameBackgroundColourA = a
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsBorderColourPickerChanged( event, r, g, b, a )
-	AJM.db.frameBorderColourR = r
-	AJM.db.frameBorderColourG = g
-	AJM.db.frameBorderColourB = b
-	AJM.db.frameBorderColourA = a
-	AJM:SettingsRefresh()
-end
-
---[[
-function AJM:SettingsToggleShowBagInformation( event, checked )
-	AJM.db.showBagInformation = checked
-	AJM:SettingsRefresh()
-end
-
-
-function AJM:SettingsToggleShowFreeBagSlotsOnly( event, checked )
-	AJM.db.showBagFreeSlotsOnly = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeBagInformationWidth( event, value )
-	AJM.db.bagInformationWidth = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeBagInformationHeight( event, value )
-	AJM.db.bagInformationHeight = tonumber( value )
-	AJM:SettingsRefresh()
-end
---]]
-
---ilvl
-function AJM:SettingsToggleShowIlvlInformation( event, checked )
-	AJM.db.showIlvlInformation = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowEquippedOnly( event, checked )
-	AJM.db.ShowEquippedOnly = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsTogglestackName( event, checked )
-	AJM.db.stackName = checked
-	AJM:SettingsRefresh()
-end
-
---[[
-function AJM:SettingsChangeIlvlInformationWidth( event, value )
-	AJM.db.ilvlInformationWidth = tonumber( value )
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsChangeIlvlInformationHeight( event, value )
-	AJM.db.ilvlInformationHeight = tonumber( value )
-	AJM:SettingsRefresh()
-end
---]]
-
--------------------------------------------------------------------------------------------------------------
--- Commands.
--------------------------------------------------------------------------------------------------------------
-
--- A Jamba command has been recieved.
-function AJM:JambaOnCommandReceived( characterName, commandName, ... )
-	AJM:DebugMessage( "JambaOnCommandReceived", characterName )
-	if commandName == AJM.COMMAND_FOLLOW_STATUS_UPDATE then
-		AJM:ProcessUpdateFollowStatusMessage( characterName, ... )
-	end
-	if commandName == AJM.COMMAND_EXPERIENCE_STATUS_UPDATE then
-		AJM:ProcessUpdateExperienceStatusMessage( characterName, ... )
-	end
-	if commandName == AJM.COMMAND_REPUTATION_STATUS_UPDATE then
-		AJM:ProcessUpdateReputationStatusMessage( characterName, ... )
-	end
---	if commandName == AJM.COMMAND_BAGINFORMATION_UPDATE then
---		AJM:ProcessUpdateBagInformationMessage( characterName, ... )
---	end
-if commandName == AJM.COMMAND_ITEMLEVELINFORMATION_UPDATE then
-		AJM:ProcessUpdateIlvlInformationMessage( characterName, ... )
-	end
-	if commandName == AJM.COMMAND_COMBO_STATUS_UPDATE then
-		AJM:ProcessUpdateComboStatusMessage( characterName, ... )
-	end
-end
-
--------------------------------------------------------------------------------------------------------------
--- Shared Media Callbacks
--------------------------------------------------------------------------------------------------------------
-
-function AJM:LibSharedMedia_Registered()
-end
-
-function AJM:LibSharedMedia_SetGlobal()
-end
-
--------------------------------------------------------------------------------------------------------------
--- Status Bar Updates.
--------------------------------------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------------------------------------
--- Range Status Bar Updates.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:RangeUpdateCommand()
-	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		--AJM:Print("name", characterName )
-		local name = Ambiguate( characterName, "none" )
-		local range = UnitInRange( name )
-		AJM:UpdateHealthStatus( name, nil, nil, range, nil )
-		AJM:UpdatePowerStatus( name, nil, nil, range )
-		AJM:UpdateComboStatus( name, nil, nil, range )
-		AJM:UpdateReputationStatus( name, nil, nil, nil, nil, nil, range )
-		AJM:UpdateExperienceStatus( name, nil, nil, nil, range )
-		--AJM:ProcessUpdateBagInformationMessage( name, nil, nil, nil, range )
-	end
-end
-
-
--------------------------------------------------------------------------------------------------------------
--- Bag Information Updates.
--------------------------------------------------------------------------------------------------------------
---[[
-function AJM:ITEM_PUSH( event, ... )
-	AJM:SendBagInformationUpdateCommand()
-end
-
-function AJM:SendBagInformationUpdateCommand()
-	if AJM.db.showTeamList == true and AJM.db.showBagInformation == true then
-		if UnitIsGhost( "player" ) then
-			return
-		end
-		if UnitIsDead( "player" ) then
-			return
-		end
-		local slotsFree, totalSlots = LibBagUtils:CountSlots( "BAGS", 0 )
-		local curTotal, maxTotal, broken = 0, 0, 0
-
-		for i = 1, 18 do
-			local curItemDurability, maxItemDurability = GetInventoryItemDurability(i)
-		if curItemDurability and maxItemDurability then
-			curTotal = curTotal + curItemDurability
-			maxTotal = maxTotal + maxItemDurability
-			if maxItemDurability > 0 and curItemDurability == 0 then
-				broken = broken + 1
-			end
-		end
-		end
-		local percent = curTotal / maxTotal * 100
-		--return percent, broken
-		--AJM:Print("Durability", percent, broken)
-		--if AJM.previousSlotsFree ~= slotsFree or AJM.previousTotalSlots ~= totalSlots then
-
-			if AJM.db.showTeamListOnMasterOnly == true then
-				AJM:JambaSendCommandToMaster( AJM.COMMAND_BAGINFORMATION_UPDATE, slotsFree, totalSlots, range )
-			else
-				AJM:JambaSendCommandToTeam( AJM.COMMAND_BAGINFORMATION_UPDATE, slotsFree, totalSlots, range)
-			end
-		--end
-	end
-end
-
-function AJM:ProcessUpdateBagInformationMessage( characterName, slotsFree, totalSlots, range)
-	AJM:UpdateBagInformation( characterName, slotsFree, totalSlots, range)
-end
-
-function AJM:SettingsUpdateBagInformationAll()
-	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		AJM:UpdateBagInformation( characterName, nil, nil, nil, nil )
-	end
-end
-
-function AJM:UpdateBagInformation( characterName, slotsFree, totalSlots, range)
-	AJM:Print("Data", characterName, slotsFree, totalSlots, percent )
-	if CanDisplayTeamList() == false then
-		return
-	end
-	if AJM.db.showBagInformation == false then
-		return
-	end
-	characterName = JambaUtilities:AddRealmToNameIfMissing( characterName )
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	if characterStatusBar == nil then
-		return
-	end
-	local bagInformationFrame = characterStatusBar["bagInformationFrame"]
-	local bagInformationFrameText = characterStatusBar["bagInformationFrameText"]
-	if slotsFree == nil then
-		slotsFree = bagInformationFrame.slotsFree
-	end
-	if totalSlots == nil then
-		totalSlots = bagInformationFrame.totalSlots
-	end
-	--if percent == nil or percent == false then
-	--	percent = bagInformationFrame.durability
-	--end
-	bagInformationFrame.slotsFree = slotsFree
-	bagInformationFrame.totalSlots = totalSlots
-	--bagInformationFrame.durability = percent
-	if 	UnitInParty(Ambiguate( characterName, "none" ) ) == true then
-		if range == false then
-			bagInformationFrame:SetAlpha( 0.5 )
-		else
-			bagInformationFrame:SetAlpha( 1 )
-		end
-	else
-		bagInformationFrame:SetAlpha( 1 )
-	end
-	local text = ""
-	--AJM:Print("test", percent)
-	--local durability = gsub(percent, "%.[^|]+", "")
-	--AJM:Print("hello", durability)
-	--text = text..L["Dura"]..L[" "]..tostring(gsub(percent, "%.[^|]+", "") )..L["%"]
-
-	if AJM.db.showBagFreeSlotsOnly == true then
-		text = text..("\n")..L["BgS"]..L[" "]..tostring(slotsFree)
-	else
-		text = text..("\n")..L["BgS"]..L[" "]..tostring((totalSlots - slotsFree)).."/"..tostring(totalSlots)
-	end
-	bagInformationFrameText:SetText( text )
-	--AJM:Print("freespace", slotsFree, totalSlots) --Debug
-end
---]]
-
--------------------------------------------------------------------------------------------------------------
--- Ilvl Information Updates.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:ITEMLVL_PUSH( event, ... )
-	AJM:SendIlvlInformationUpdateCommand()
-end
-
-function AJM:PLAYER_EQUIPMENT_CHANGED( event, ... )
-	AJM:SendIlvlInformationUpdateCommand()
-end
-
-
-function AJM:SendIlvlInformationUpdateCommand()
-	if AJM.db.showTeamList == true and AJM.db.showIlvlInformation == true or AJM.db.followStatusShowLevel == true then
-		if UnitIsGhost( "player" ) then
-			return
-		end
-		if UnitIsDead( "player" ) then
-			return
-		end
-		local overall, equipped = GetAverageItemLevel()
-		local characterLevel = UnitLevel("player")
-		--if AJM.previousIlvl ~= overall then ---or AJM.previousTotalSlots ~= totalSlots then
-			if AJM.db.showTeamListOnMasterOnly == true then
-				AJM:JambaSendCommandToMaster( AJM.COMMAND_ITEMLEVELINFORMATION_UPDATE, characterLevel, overall, equipped )
-			else
-				AJM:JambaSendCommandToTeam( AJM.COMMAND_ITEMLEVELINFORMATION_UPDATE, characterLevel, overall, equipped )
-			end
-		--end
-	end
-end
-
--------------------------------------------------------------------------------------------------------------
--- Follow Status Bar Updates.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:AUTOFOLLOW_BEGIN( event, ... )
-	AJM:SendFollowStatusUpdateCommand( true )
-end
-
-function AJM:AUTOFOLLOW_END( event, followEndedReason, ... )
-	AJM:SendFollowStatusUpdateCommand( false )
-end
-
-function AJM:SendFollowStatusUpdateCommand( isFollowing )
-	if AJM.db.showTeamList == true and AJM.db.showFollowStatus == true then
-		-- Check to see if JambaFollow is enabled and follow strobing is on.  If this is the case then
-		-- do not send the follow update.
-		local canSend = true
-		if JambaApi.Follow ~= nil then
-			if JambaApi.Follow.IsFollowingStrobing() == true then
-				canSend = false
-			end
-		end
-		if canSend == true then
-			if AJM.db.showTeamListOnMasterOnly == true then
-				AJM:JambaSendCommandToMaster( AJM.COMMAND_FOLLOW_STATUS_UPDATE, isFollowing )
-			else
-				AJM:JambaSendCommandToTeam( AJM.COMMAND_FOLLOW_STATUS_UPDATE, isFollowing )
-			end
-		end
-	end
-end
-
-function AJM:ProcessUpdateFollowStatusMessage( characterName, isFollowing )
-	AJM:UpdateFollowStatus( characterName, isFollowing, false )
-end
-
---TODO: Ebony,-- See if this code could be cleaned up a little as when in combat takes a few mins after to catch up. Sending add-on msg with combat?
-function AJM:UpdateFollowStatus( characterName, isFollowing, isFollowLeader )
-	if CanDisplayTeamList() == false then
-		return
-	end
-	if AJM.db.showFollowStatus == false then
-		return
-	end
-	characterName = JambaUtilities:AddRealmToNameIfMissing( characterName )
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	if characterStatusBar == nil then
-		return
-	end
-	local followBar = characterStatusBar["followBar"]
-	if isFollowing == true then
-		-- Following.
-		followBar:SetStatusBarColor( 0.05, 0.85, 0.05, 1.00 )
-	else
-		if isFollowLeader == true then
-			-- Follow leader.
-			followBar:SetStatusBarColor( 0.55, 0.15, 0.15, 0.25 )
-		else
-			-- Not following.
-			followBar:SetStatusBarColor( 0.85, 0.05, 0.05, 1.00 )
-		end
-	end
-end
-
-function AJM:ProcessUpdateIlvlInformationMessage( characterName, characterLevel, overall, equipped )
-	AJM:SettingsUpdateFollowText( characterName, characterLevel, overall, equipped )
-end
-
-
-function AJM:SettingsUpdateFollowTextAll()
-	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		AJM:SettingsUpdateFollowText( characterName, nil, nil, nil )
-		--AJM:SettingsUpdateFollowText( characterName, nil, nil, nil )
-	end
-end
-
-
-function AJM:SettingsUpdateFollowText( characterName, characterLevel, overall, equipped )
-	--AJM:Print("Info", characterName, characterLevel,overall, equipped) -- debug
-	if CanDisplayTeamList() == false then
-		return
-	end
-	if AJM.db.showFollowStatus == false then
-		return
-	end
-	characterName = JambaUtilities:AddRealmToNameIfMissing( characterName )
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	if characterStatusBar == nil then
-		return
-	end
-	local ilvlInformationFrame = characterStatusBar["ilvlInformationFrame"]
-	local ilvlInformationFrameText = characterStatusBar["ilvlInformationFrameText"]
-	if overall == nil then
-		overall = ilvlInformationFrame.overall
-	end
-	if equipped == nil then
-		equipped = ilvlInformationFrame.equipped
-	end
-	if characterLevel == nil then
-		characterLevel = ilvlInformationFrame.characterLevel
-	end
-	ilvlInformationFrame.overall = overall
-	ilvlInformationFrame.equipped = equipped
-	ilvlInformationFrame.characterLevel = characterLevel
-	local followBarText = characterStatusBar["followBarText"]
-	local text = ""
-	if AJM.db.followStatusShowName == true then
-		text = text..Ambiguate( characterName, "none" )
-	end
-	if AJM.db.followStatusShowLevel == true then
-		if AJM.db.followStatusShowName == true then
-			if AJM.db.stackName == true then
-				text = text..L[" "]..("\n")..L["("]..tostring( characterLevel )..L[")"]
-			else
-				text = text..L[" "]..L["("]..tostring( characterLevel )..L[")"]
-			end
-		else
-			text = tostring( characterLevel )
-		end
-	end
-	if AJM.db.showIlvlInformation == true then
-		if AJM.db.ShowEquippedOnly == true then
-			if AJM.db.stackName == true then
-				text = text..L[" "]..("\n")..L["("]..tostring (format("%.0f", equipped ))..L[")"]
-			else
-				text = text..L[" "]..L["("]..tostring (format("%.0f", equipped ))..L[")"]
-			end
-		else
-			if AJM.db.stackName == true then
-				text = text..L[" "]..("\n")..L["("]..tostring(format("%.0f", equipped )).."/"..tostring(format("%.0f", overall ))..L[")"]
-			else
-				text = text..L[" "]..L["("]..tostring(format("%.0f", equipped )).."/"..tostring(format("%.0f", overall ))..L[")"]
-			end
-		end
-	end
-	followBarText:SetText( text )
-end
-
--------------------------------------------------------------------------------------------------------------
--- Experience Status Bar Updates.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:PLAYER_XP_UPDATE( event, ... )
-	AJM:SendExperienceStatusUpdateCommand()
-end
-
-function AJM:UPDATE_EXHAUSTION( event, ... )
-	AJM:SendExperienceStatusUpdateCommand()
-end
-
-function AJM:PLAYER_LEVEL_UP( event, ... )
-	AJM:SendExperienceStatusUpdateCommand()
-	--AJM:SettingsUpdateFollowTextAll()
-	AJM:SendIlvlInformationUpdateCommand()
-end
-
-function AJM:SendExperienceStatusUpdateCommand()
-	if AJM.db.showTeamList == true and AJM.db.showExperienceStatus == true then
-		-- Hide the xp bar at max level as its nolonger needed.
-		local uLevel = UnitLevel("player")
-		local maxLevel = GetMaxPlayerLevel()
-		--[[
-		if uLevel == maxLevel then
-			--AJM:Print("maxLevel", uLevel, maxLevel) --debug
-			AJM.db.showExperienceStatus = false
-			AJM.SettingsRefresh()
-			AJM:JambaSendSettings()
-		end
-		--]]
-		local playerExperience = UnitXP( "player" )
-		local playerMaxExperience = UnitXPMax( "player" )
-		local playerMaxLevel = GetMaxPlayerLevel()
-		local playerLevel = UnitLevel("player")
-		local exhaustionStateID, exhaustionStateName, exhaustionStateMultiplier = GetRestState()
-			if AJM.db.showTeamListOnMasterOnly == true then
-				AJM:JambaSendCommandToMaster( AJM.COMMAND_EXPERIENCE_STATUS_UPDATE, playerExperience, playerMaxExperience, exhaustionStateID)
-			else
-				AJM:DebugMessage( "SendExperienceStatusUpdateCommand TO TEAM!" )
-				AJM:JambaSendCommandToTeam( AJM.COMMAND_EXPERIENCE_STATUS_UPDATE, playerExperience, playerMaxExperience, exhaustionStateID)
-			end
-	end
-end
-
-function AJM:ProcessUpdateExperienceStatusMessage( characterName, playerExperience, playerMaxExperience, exhaustionStateID, range )
-	AJM:UpdateExperienceStatus( characterName, playerExperience, playerMaxExperience, exhaustionStateID, range )
-end
-
-function AJM:SettingsUpdateExperienceAll()
-	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		AJM:UpdateExperienceStatus( characterName, nil, nil, nil, nil )
-	end
-end
-
-function AJM:UpdateExperienceStatus( characterName, playerExperience, playerMaxExperience, exhaustionStateID, range )
-	--AJM:Print( "UpdateExperienceStatus", characterName, playerExperience, playerMaxExperience, exhaustionStateID, range)
-
-	if CanDisplayTeamList() == false then
-		return
-	end
-	if AJM.db.showExperienceStatus == false then
-		return
-	end
-
-	characterName = JambaUtilities:AddRealmToNameIfMissing( characterName )
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	if characterStatusBar == nil then
-		return
-	end
-	local experienceBarText = characterStatusBar["experienceBarText"]
-	local experienceBar = characterStatusBar["experienceBar"]
-	if playerExperience == nil then
-		playerExperience = experienceBarText.playerExperience
-	end
-	if playerMaxExperience == nil then
-		playerMaxExperience = experienceBarText.playerMaxExperience
-	end
-	if exhaustionStateID == nil then
-		exhaustionStateID = experienceBarText.exhaustionStateID
-	end
-
-	experienceBarText.playerExperience = playerExperience
-	experienceBarText.playerMaxExperience = playerMaxExperience
-	experienceBarText.exhaustionStateID = exhaustionStateID
-	experienceBar:SetMinMaxValues( 0, tonumber( playerMaxExperience ) )
-	experienceBar:SetValue( tonumber( playerExperience ) )
-	if 	UnitInParty(Ambiguate( characterName, "none" ) ) == true then
-		if range == false then
-			experienceBar:SetAlpha( 0.5 )
-		else
-			experienceBar:SetAlpha( 1 )
-		end
-	else
-		experienceBar:SetAlpha( 1 )
-	end
-	local text = ""
-	if AJM.db.experienceStatusShowValues == true then
-		text = text..tostring( playerExperience )..L[" / "]..tostring( playerMaxExperience )..L[" "]
-	end
-	if AJM.db.experienceStatusShowPercentage == true then
-		if AJM.db.experienceStatusShowValues == true then
-			text = text..L["("]..tostring( floor( (playerExperience/playerMaxExperience)*100) )..L["%"]..L[")"]
-		else
-			text = tostring( floor( (playerExperience/playerMaxExperience)*100) )..L["%"]
-		end
-	end
-	experienceBarText:SetText( text )
-	if exhaustionStateID == 1 then
-		experienceBar:SetStatusBarColor( 0.0, 0.39, 0.88, 1.0 )
-		experienceBar.backgroundTexture:SetTexture( 0.0, 0.39, 0.88, 0.15 )
-	else
-		experienceBar:SetStatusBarColor( 0.58, 0.0, 0.55, 1.0 )
-		experienceBar.backgroundTexture:SetTexture( 0.58, 0.0, 0.55, 0.15 )
-	end
-end
-
--------------------------------------------------------------------------------------------------------------
--- Reputation Status Bar Updates.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:CHAT_MSG_COMBAT_FACTION_CHANGE( event, ... )
-	AJM:SendReputationStatusUpdateCommand()
-end
-
-function AJM:SetWatchedFactionIndex( index )
-	AJM:ScheduleTimer( "SendReputationStatusUpdateCommand", 5 )
-end
-
-function AJM:SendReputationStatusUpdateCommand()
-	if AJM.db.showTeamList == true and AJM.db.showReputationStatus == true then
-		local reputationName, reputationStandingID, reputationBarMin, reputationBarMax, reputationBarValue = GetWatchedFactionInfo()
-		if AJM.db.showTeamListOnMasterOnly == true then
-			AJM:JambaSendCommandToMaster( AJM.COMMAND_REPUTATION_STATUS_UPDATE, reputationName, reputationStandingID, reputationBarMin, reputationBarMax, reputationBarValue )
-		else
-			AJM:JambaSendCommandToTeam( AJM.COMMAND_REPUTATION_STATUS_UPDATE, reputationName, reputationStandingID, reputationBarMin, reputationBarMax, reputationBarValue )
-		end
-	end
-end
-
-function AJM:ProcessUpdateReputationStatusMessage( characterName, reputationName, reputationStandingID, reputationBarMin, reputationBarMax, reputationBarValue, range )
-	AJM:UpdateReputationStatus( characterName, reputationName, reputationStandingID, reputationBarMin, reputationBarMax, reputationBarValue, range )
-end
-
-function AJM:SettingsUpdateReputationAll()
-	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		AJM:UpdateReputationStatus( characterName, nil, nil, nil, nil, nil, nil )
-	end
-end
-
-function AJM:UpdateReputationStatus( characterName, reputationName, reputationStandingID, reputationBarMin, reputationBarMax, reputationBarValue, range )
-	if CanDisplayTeamList() == false then
-		return
-	end
-	if AJM.db.showReputationStatus == false then
-		return
-	end
-	characterName = JambaUtilities:AddRealmToNameIfMissing( characterName )
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	if characterStatusBar == nil then
-		return
-	end
-	local reputationBarText = characterStatusBar["reputationBarText"]
-	local reputationBar = characterStatusBar["reputationBar"]
-	if reputationName == nil then
-		reputationName = reputationBarText.reputationName
-	end
-	if reputationStandingID == nil then
-		reputationStandingID = reputationBarText.reputationStandingID
-	end
-	if reputationBarMin == nil then
-		reputationBarMin = reputationBarText.reputationBarMin
-	end
-	if reputationBarMax == nil then
-		reputationBarMax = reputationBarText.reputationBarMax
-	end
-	if reputationBarValue == nil then
-		reputationBarValue = reputationBarText.reputationBarValue
-	end
-	reputationBarText.reputationName = reputationName
-	reputationBarText.reputationStandingID = reputationStandingID
-	reputationBarText.reputationBarMin = reputationBarMin
-	reputationBarText.reputationBarMax = reputationBarMax
-	reputationBarText.reputationBarValue = reputationBarValue
-	reputationBar:SetMinMaxValues( tonumber( reputationBarMin ), tonumber( reputationBarMax ) )
-	reputationBar:SetValue( tonumber( reputationBarValue ) )
-    if reputationName == 0 then
-        reputationBarMin = 0
-        reputationBarMax = 100
-        reputationBarValue = 100
-        reputationStandingID = 1
-    end
-	if 	UnitInParty(Ambiguate( characterName, "none" ) ) == true then
-		if range == false then
-			reputationBar:SetAlpha( 0.5 )
-		else
-			reputationBar:SetAlpha( 1 )
-		end
-	else
-		reputationBar:SetAlpha( 1 )
-	end
-	local text = ""
-	if AJM.db.showReputationName == true then
-        if reputationName == 0 then
-		    text = text..L["No Faction Selected"].." "
-        else
-            text = text..reputationName.." "
-        end
-	end
-	-- TODO: do we need to hook SetWatchedFactionIndex for when a watched faction changes?
-	if AJM.db.reputationStatusShowValues == true then
-		text = text..tostring( reputationBarValue-reputationBarMin )..L[" / "]..tostring( reputationBarMax-reputationBarMin )..L[" "]
-	end
-	if AJM.db.reputationStatusShowPercentage == true then
-		local textPercentage = tostring( floor( (reputationBarValue-reputationBarMin)/(reputationBarMax-reputationBarMin)*100 ) )..L["%"]
-		if AJM.db.reputationStatusShowValues == true then
-			text = text..L["("]..textPercentage..L[")"]
-		else
-			text = text..textPercentage
-		end
-	end
-	reputationBarText:SetText( text )
-	local barColor = _G.FACTION_BAR_COLORS[reputationStandingID]
-	if barColor ~= nil then
-		reputationBar:SetStatusBarColor( barColor.r, barColor.g, barColor.b, 1.0 )
-		reputationBar.backgroundTexture:SetTexture( barColor.r, barColor.g, barColor.b, 0.15 )
-	end
-end
-
--------------------------------------------------------------------------------------------------------------
--- Health Status Bar Updates.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:UNIT_HEALTH( event, unit, ... )
-	AJM:SendHealthStatusUpdateCommand( unit,nil )
-	--AJM:Print("test2", unit)
-end
-
-function AJM:UNIT_MAXHEALTH( event, unit, ... )
-	AJM:SendHealthStatusUpdateCommand( unit, nil )
-end
-
-
-function AJM:SendHealthStatusUpdateCommand( unit, range )
-	if AJM.db.showTeamList == true and AJM.db.showHealthStatus == true then
-		local playerHealth = UnitHealth( unit )
-		local playerMaxHealth = UnitHealthMax( unit )
-		local isDead = UnitIsDeadOrGhost( unit )
-		local characterName, characterRealm = UnitName( unit )
-		local character = JambaUtilities:AddRealmToNameIfNotNil( characterName, characterRealm )
-		--AJM:Print("HeathStats", character, playerHealth, playerMaxHealth, range)
-		AJM:UpdateHealthStatus( character, playerHealth, playerMaxHealth, range, isDead )
-	end
-end
-
-function AJM:SettingsUpdateHealthAll()
-	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		AJM:UpdateHealthStatus( characterName, nil, nil, nil, nil )
-	end
-end
-
-function AJM:UpdateHealthStatus( characterName, playerHealth, playerMaxHealth, range, isDead )
-	if CanDisplayTeamList() == false then
-		return
-	end
-	if AJM.db.showHealthStatus == false then
-		return
-	end
-	characterName = JambaUtilities:AddRealmToNameIfMissing( characterName )
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	if characterStatusBar == nil then
-		return
-	end
-	local healthBarText = characterStatusBar["healthBarText"]
-	local healthBar = characterStatusBar["healthBar"]
-	if playerHealth == nil then
-		playerHealth = healthBarText.playerHealth
-	end
-	if playerMaxHealth == nil then
-		playerMaxHealth = healthBarText.playerMaxHealth
-	end
-	if 	UnitInParty(Ambiguate( characterName, "none" ) ) == true then
-		if range == false then
-			healthBar:SetAlpha( 0.5 )
-		else
-			healthBar:SetAlpha( 1 )
-		end
-	else
-		healthBar:SetAlpha( 1 )
-	end
-	healthBarText.playerHealth = playerHealth
-	healthBarText.playerMaxHealth = playerMaxHealth
-	healthBar:SetMinMaxValues( 0, tonumber( playerMaxHealth ) )
-	healthBar:SetValue( tonumber( playerHealth ) )
-	local text = ""
-	if UnitIsDeadOrGhost(Ambiguate( characterName, "none" ) ) == true then
-	--if isDead == true then
-		--AJM:Print("dead", characterName)
-		text = text..L["DEAD"]
-	else
-		if AJM.db.healthStatusShowValues == true then
-			text = text..tostring( playerHealth )..L[" / "]..tostring( playerMaxHealth )..L[" "]
-		end
-		if AJM.db.healthStatusShowPercentage == true then
-			if AJM.db.healthStatusShowValues == true then
-				text = text..L["("]..tostring( floor( (playerHealth/playerMaxHealth)*100) )..L["%"]..L[")"]
-			else
-				text = tostring( floor( (playerHealth/playerMaxHealth)*100) )..L["%"]
-			end
-		end
-	end
-	healthBarText:SetText( text )
-	AJM:SetStatusBarColourForHealth( healthBar, floor((playerHealth/playerMaxHealth)*100) )
-end
-
-function AJM:SetStatusBarColourForHealth( statusBar, statusValue )
-	local r, g, b = 0, 0, 0
-	statusValue = statusValue / 100
-	if( statusValue > 0.5 ) then
-		r = (1.0 - statusValue) * 2
-		g = 1.0
-	else
-		r = 1.0
-		g = statusValue * 2
-	end
-	b = 0.0
-	statusBar:SetStatusBarColor( r, g, b )
-end
-
--------------------------------------------------------------------------------------------------------------
--- Power Status Bar Updates.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:UNIT_POWER( event, unit, ... )
-	AJM:SendPowerStatusUpdateCommand( unit )
-end
-
-function AJM:UNIT_DISPLAYPOWER( event, unit, ... )
-	AJM:SendPowerStatusUpdateCommand( unit )
-end
-
-function AJM:SendPowerStatusUpdateCommand( unit )
-	if AJM.db.showTeamList == true and AJM.db.showPowerStatus == true then
-		local playerPower = UnitPower( unit )
-		local playerMaxPower = UnitPowerMax( unit )
-		local characterName, characterRealm = UnitName( unit )
-		local character = JambaUtilities:AddRealmToNameIfNotNil( characterName, characterRealm )
-		--AJM:Print("power", character, playerPower, playerMaxPower )
-		AJM:UpdatePowerStatus( character, playerPower, playerMaxPower)
-	end
-end
-
-function AJM:SettingsUpdatePowerAll()
-	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		AJM:UpdatePowerStatus( characterName, nil, nil, nil )
-	end
-end
-
-function AJM:UpdatePowerStatus( characterName, playerPower, playerMaxPower, range )
-	if CanDisplayTeamList() == false then
-		return
-	end
-	if AJM.db.showPowerStatus == false then
-		return
-	end
-	local originalChatacterName = characterName
-	characterName = JambaUtilities:AddRealmToNameIfMissing( characterName )
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	if characterStatusBar == nil then
-		return
-	end
-	local powerBarText = characterStatusBar["powerBarText"]
-	local powerBar = characterStatusBar["powerBar"]
-	if playerPower == nil then
-		playerPower = powerBarText.playerPower
-	end
-	if playerMaxPower == nil then
-		playerMaxPower = powerBarText.playerMaxPower
-	end
-	if 	UnitInParty(Ambiguate( characterName, "none" ) ) == true then
-		if range == false then
-			powerBar:SetAlpha( 0.5 )
-		else
-			powerBar:SetAlpha( 1 )
-		end
-	else
-		powerBar:SetAlpha( 1 )
-	end
-	powerBarText.playerPower = playerPower
-	powerBarText.playerMaxPower = playerMaxPower
-	powerBar:SetMinMaxValues( 0, tonumber( playerMaxPower ) )
-	powerBar:SetValue( tonumber( playerPower ) )
-	local text = ""
-	if AJM.db.powerStatusShowValues == true then
-		text = text..tostring( playerPower )..L[" / "]..tostring( playerMaxPower )..L[" "]
-	end
-	if AJM.db.powerStatusShowPercentage == true then
-		if AJM.db.powerStatusShowValues == true then
-			text = text..L["("]..tostring( floor( (playerPower/playerMaxPower)*100) )..L["%"]..L[")"]
-		else
-			text = tostring( floor( (playerPower/playerMaxPower)*100) )..L["%"]
-		end
-	end
-	powerBarText:SetText( text )
-	AJM:SetStatusBarColourForPower( powerBar, originalChatacterName )
-end
-
-function AJM:SetStatusBarColourForPower( statusBar, unit )
-	unit =  Ambiguate( unit, "none" )
-	local powerIndex, powerString, altR, altG, altB = UnitPowerType( unit )
-	if powerString ~= nil and powerString ~= "" then
-		local r = PowerBarColor[powerString].r
-		local g = PowerBarColor[powerString].g
-		local b = PowerBarColor[powerString].b
-		statusBar:SetStatusBarColor( r, g, b, 1 )
-		statusBar.backgroundTexture:SetTexture( r, g, b, 0.25 )
-	end
-end
-
--------------------------------------------------------------------------------------------------------------
--- Combo Points Status Bar Updates.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:UNIT_COMBO_POINTS( event, ... )
-	--AJM:Print("hello")
-	AJM:SendComboStatusUpdateCommand()
-end
-
-
---function AJM:UNIT_DISPLAYCOMBO( event, unit, ... )
---	AJM:SendComboStatusUpdateCommand( unit )
---end
-
-function AJM:SendComboStatusUpdateCommand()
-	if AJM.db.showTeamList == true and AJM.db.showComboStatus == true then
-		if select(2, UnitClass("player")) ~= "DRUID" and select(2, UnitClass("player")) ~= "ROGUE" == true then
-			return
-		end
-
-		local playerCombo = UnitPower ( "player", 4)
-		local playerMaxCombo = UnitPowerMax( "player", 4)
-		--AJM:Print ("combo", playerCombo, playerMaxCombo)
-		if AJM.db.showTeamListOnMasterOnly == true then
-			AJM:JambaSendCommandToMaster( AJM.COMMAND_COMBO_STATUS_UPDATE, playerCombo, playerMaxCombo )
-		else
-			AJM:DebugMessage( "SendComboStatusUpdateCommand TO TEAM!" )
-			AJM:JambaSendCommandToTeam( AJM.COMMAND_COMBO_STATUS_UPDATE, playerCombo, playerMaxCombo )
-		end
-	end
-end
-
-function AJM:ProcessUpdateComboStatusMessage( characterName, playerCombo, playerMaxCombo, range )
-	AJM:UpdateComboStatus( characterName, playerCombo , playerMaxCombo, range )
-end
-
-function AJM:SettingsUpdateComboAll()
-	for characterName, characterStatusBar in pairs( AJM.characterStatusBar ) do
-		AJM:UpdateComboStatus( characterName, nil, nil, nil )
-	end
-end
-
-function AJM:UpdateComboStatus( characterName, playerCombo, playerMaxCombon, range )
-	if CanDisplayTeamList() == false then
-		return
-	end
-
-	if AJM.db.showComboStatus == false then
-		return
-	end
-
-	local characterStatusBar = AJM.characterStatusBar[characterName]
-	if characterStatusBar == nil then
-		return
-	end
-
-	local comboBarText = characterStatusBar["comboBarText"]
-	local comboBar = characterStatusBar["comboBar"]
-
-	if playerCombo == nil then
-		playerCombo = comboBarText.playerCombo
-	end
-
-	if playerMaxCombo == nil then
-		playerMaxCombo = comboBarText.playerMaxCombo
-	end
-
-	comboBarText.playerCombo = playerCombo
-	comboBarText.playerMaxCombo = playerMaxCombo
-	comboBar:SetMinMaxValues( 0, tonumber( playerMaxCombo ) )
-	comboBar:SetValue( tonumber( playerCombo ) )
-	if 	UnitInParty(Ambiguate( characterName, "none" ) ) == true then
-		if range == false then
-			comboBar:SetAlpha( 0.5 )
-		else
-			comboBar:SetAlpha( 1 )
-		end
-	else
-		comboBar:SetAlpha( 1 )
-	end
-	local text = ""
-
-	if AJM.db.comboStatusShowValues == true then
-		text = text..tostring( playerCombo )..L[" / "]..tostring( playerMaxCombo )..L[" "]
-	end
-
-	if AJM.db.ComboStatusShowPercentage == true then
-		if AJM.db.comboStatusShowValues == true then
-			text = text..L["("]..tostring( floor( (playerCombo/playerMaxCombo)*100) )..L["%"]..L[")"]
-		else
-			text = tostring( floor( (playerCombo/playerMaxCombo)*100) )..L["%"]
-		end
-	end
-	comboBarText:SetText( text )
-end
-
---[[
-function AJM:SetStatusBarColourForCombo( statusBar, unit )
-	local powerIndex, powerString, altR, altG, altB = UnitPowerType( unit )
-	if comboString ~= nil and comboString ~= "" then
-		local r = ComboBarColor[powerString].r
-		local g = ComboBarColor[powerString].g
-		local b = ComboBarColor[powerString].b
-		statusBar:SetStatusBarColor( r, g, b, 1 )
-		statusBar.backgroundTexture:SetTexture( r, g, b, 0.25 )
-	end
-
-end
---]]
-
--------------------------------------------------------------------------------------------------------------
--- Addon initialization, enabling and disabling.
--------------------------------------------------------------------------------------------------------------
-
--- Initialise the module.
-function AJM:OnInitialize()
-	AJM.previousSlotsFree = 0
-	AJM.previousTotalSlots = 0
-	-- Create the settings control.
-	SettingsCreate()
-	-- Initialise the JambaModule part of this module.
-	AJM:JambaModuleInitialize( AJM.settingsControl.widgetSettings.frame )
-	-- Populate the settings.
-	AJM:SettingsRefresh()
-	-- Create the team list frame.
-	CreateJambaTeamListFrame()
-	AJM:SetTeamListVisibility()
-end
-
--- Called when the addon is enabled.
-function AJM:OnEnable()
-	AJM:RegisterEvent( "PLAYER_REGEN_ENABLED" )
-	AJM:RegisterEvent( "PLAYER_REGEN_DISABLED" )
-	AJM:RegisterEvent( "AUTOFOLLOW_BEGIN" )
-	AJM:RegisterEvent( "AUTOFOLLOW_END" )
-	AJM:RegisterEvent( "PLAYER_XP_UPDATE" )
-	AJM:RegisterEvent( "UPDATE_EXHAUSTION" )
-	AJM:RegisterEvent( "PLAYER_LEVEL_UP" )
-	AJM:RegisterEvent( "UNIT_HEALTH" )
-	AJM:RegisterEvent( "UNIT_MAXHEALTH" )
-	AJM:RegisterEvent( "UNIT_POWER", "UNIT_POWER" )
-	AJM:RegisterEvent( "UNIT_MAXPOWER", "UNIT_POWER" )
-	AJM:RegisterEvent( "PLAYER_EQUIPMENT_CHANGED" )
-	AJM:RegisterEvent( "PLAYER_ENTERING_WORLD")
-	AJM:RegisterEvent( "UNIT_DISPLAYPOWER" )
-	AJM:RegisterEvent( "UNIT_LEVEL" )
-	AJM:RegisterEvent( "ITEMLVL_PUSH" )
-	AJM:RegisterEvent( "GROUP_ROSTER_UPDATE" )
---	AJM:RegisterEvent( "ITEM_PUSH" )
-	AJM:RegisterEvent( "CHAT_MSG_COMBAT_FACTION_CHANGE" )
-	AJM:RegisterEvent( "UNIT_COMBO_POINTS" )
-	--Updating Bag information -- Chaneged again 4.1  this event fires even for bank bags. When moving an item in your inventory, this fires multiple times: once each for the source and destination bag
---	AJM:RegisterEvent( "BAG_UPDATE", "ITEM_PUSH" )
-	--Updates everytime jamba Reads the UI_ERROR_MESSAGE Are This is not very good for me using a spambar! Need's a better system.
-	--AJM:RegisterEvent( "UI_ERROR_MESSAGE", "ITEM_PUSH" )
-    --TODO: Clean up code
-	--AJM:RegisterEvent( "UNIT_PORTRAIT_UPDATE" )
-	AJM.SharedMedia.RegisterCallback( AJM, "LibSharedMedia_Registered" )
-    AJM.SharedMedia.RegisterCallback( AJM, "LibSharedMedia_SetGlobal" )
-	AJM:RegisterMessage( JambaApi.MESSAGE_TEAM_CHARACTER_ADDED, "OnCharactersChanged" )
-	AJM:RegisterMessage( JambaApi.MESSAGE_TEAM_CHARACTER_REMOVED, "OnCharactersChanged" )
-	AJM:RegisterMessage( JambaApi.MESSAGE_TEAM_ORDER_CHANGED, "OnCharactersChanged" )
-	AJM:RegisterMessage( JambaApi.MESSAGE_TEAM_MASTER_CHANGED, "OnMasterChanged" )
-	AJM:RegisterMessage( JambaApi.MESSAGE_CHARACTER_ONLINE, "OnCharactersChanged")
-	AJM:RegisterMessage( JambaApi.MESSAGE_CHARACTER_OFFLINE, "OnCharactersChanged")
-	AJM:SecureHook( "SetWatchedFactionIndex" )
-	AJM:ScheduleTimer( "RefreshTeamListControls", 20 )
-	AJM:ScheduleTimer( "SendExperienceStatusUpdateCommand", 5 )
-	AJM:ScheduleTimer( "SendReputationStatusUpdateCommand", 5 )
---	AJM:ScheduleTimer( "SendBagInformationUpdateCommand", 5 )
-	AJM:ScheduleTimer( "SendIlvlInformationUpdateCommand", 5 )
-	--AJM:timerCount = ( 0 )
-    --AJM:testTimer =
-	--self.timerCount = 0
-	AJM:ScheduleRepeatingTimer("RangeUpdateCommand", 5)
-end
-
--- Called when the addon is disabled.
-function AJM:OnDisable()
-end
-
--- this is not needed as the range timer would do this.
-function AJM:PLAYER_ENTERING_WORLD( event, ... )
---	AJM:SendBagInformationUpdateCommand()
-	AJM:SendExperienceStatusUpdateCommand()
-	AJM:SendIlvlInformationUpdateCommand()
-	AJM:SendReputationStatusUpdateCommand()
-end
-
-function AJM:OnMasterChanged( message, characterName )
-	AJM:SettingsRefresh()
-end
-
-function AJM:UNIT_LEVEL( event, ... )
-	--AJM:SettingsUpdateFollowTextAll()
-	AJM:SendIlvlInformationUpdateCommand()
-end
-
-function AJM:GROUP_ROSTER_UPDATE( event, ... )
-	--AJM:SettingsUpdateFollowTextAll()
-	AJM:SendIlvlInformationUpdateCommand()
---	AJM:SendBagInformationUpdateCommand()
-end
-
-function AJM:PLAYER_REGEN_ENABLED( event, ... )
-	if AJM.db.hideTeamListInCombat == true then
-		AJM:SetTeamListVisibility()
-	end
-	if AJM.refreshHideTeamListControlsPending == true then
-		AJM:RefreshTeamListControlsHide()
-		AJM.refreshHideTeamListControlsPending = false
-	end
-	if AJM.refreshShowTeamListControlsPending == true then
-		AJM:RefreshTeamListControlsShow()
-		AJM.refreshShowTeamListControlsPending = false
-	end
-	if AJM.updateSettingsAfterCombat == true then
-		AJM:SettingsRefresh()
-		AJM.updateSettingsAfterCombat = false
-	end
-end
-
-function AJM:PLAYER_REGEN_DISABLED( event, ... )
-	if AJM.db.hideTeamListInCombat == true then
-		JambaDisplayTeamListFrame:Hide()
-	end
-end
-
-function AJM:OnCharactersChanged()
-	AJM:RefreshTeamListControls()
-	AJM:SendIlvlInformationUpdateCommand()
-end
\ No newline at end of file
diff --git a/Jamba-DisplayTeam/Locales/JambaDisplayTeam-Locale-enUS.lua b/Jamba-DisplayTeam/Locales/JambaDisplayTeam-Locale-enUS.lua
index 7ac5d76..ac39fdf 100644
--- a/Jamba-DisplayTeam/Locales/JambaDisplayTeam-Locale-enUS.lua
+++ b/Jamba-DisplayTeam/Locales/JambaDisplayTeam-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

@@ -85,7 +85,11 @@ L["Only Show in Party"] = true
 L["Only Show Display-Team\nIn Party or Raid"] = true
 L["Health & Power Out of Group"] = true
 L["Show Class Colors"] = true
-
+L["Threat Status Bar"] = true
+L["Pet Status Bar"] = true
+L["Show Name"] = true
+L["Show Pet Power"] = true
+L["Extra Info"] = true

 --Help System

@@ -123,4 +127,8 @@ L["ShowReputation"] = true
 L["Show the Team Reputation Bar"] = true
 L["Update Health and Power out of Groups\nUse Guild Communications!"] = true
 L["Show class Coulor on Health Bar"] = true
-
+L["Show the Teams Threat Bar"] = true
+L["Show the Teams Pet Bars"] = true
+L["Show the Teams Pet Name"] = true
+L["Show the Teams Pet Power"] = true
+L["Show Extra Infomation on Bars"] = true
diff --git a/Jamba-DisplayTeam/Locales/Locales.xml b/Jamba-DisplayTeam/Locales/Locales.xml
index 3ac59fd..8ca0dc1 100644
--- a/Jamba-DisplayTeam/Locales/Locales.xml
+++ b/Jamba-DisplayTeam/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-FTL/Jamba-FTL.toc b/Jamba-FTL/Jamba-FTL.toc
index 17231cb..849a245 100644
--- a/Jamba-FTL/Jamba-FTL.toc
+++ b/Jamba-FTL/Jamba-FTL.toc
@@ -2,7 +2,7 @@
 ## Title: JambaFTL
 ## Notes: JambaFTL
 ## Author: olipcs (although most of the code is originaly from Jafula) (any changes added to support 4.0.5 from ebony!)
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Follow/Jamba-Follow.toc b/Jamba-Follow/Jamba-Follow.toc
index 1ee30eb..b9f75a7 100644
--- a/Jamba-Follow/Jamba-Follow.toc
+++ b/Jamba-Follow/Jamba-Follow.toc
@@ -2,7 +2,7 @@
 ## Title: JambaFollow
 ## Notes: JambaFollow
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Follow/JambaFollow.lua b/Jamba-Follow/JambaFollow.lua
index 9df113b..50d53d8 100644
--- a/Jamba-Follow/JambaFollow.lua
+++ b/Jamba-Follow/JambaFollow.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

@@ -1090,6 +1090,10 @@ function AJM:FollowTarget( target )
 				-- Have eating buff, do not allow follow.
 				canFollowTarget = false
 			end
+			if JambaUtilities:DoesThisCharacterHaveBuff( L["Refreshment"] ) == true then
+				-- Eating Mage food Yum Yum Yum.
+				canFollowTarget = false
+			end
 		end
 	end
 	-- If follow strobing and strobing paused.
diff --git a/Jamba-Follow/Locales/JambaFollow-Locale-enUS.lua b/Jamba-Follow/Locales/JambaFollow-Locale-enUS.lua
index c71ef63..4cfebfe 100644
--- a/Jamba-Follow/Locales/JambaFollow-Locale-enUS.lua
+++ b/Jamba-Follow/Locales/JambaFollow-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

@@ -55,6 +55,7 @@ L["on"] = true
 L["off"] = true
 L["Drink"] = true
 L["Food"] = true
+L["Refreshment"] = true
 L["In A Vehicle"] = true
 L["Train"] = true
 L["Build a train of followers behind the master."] = true
diff --git a/Jamba-Follow/Locales/Locales.xml b/Jamba-Follow/Locales/Locales.xml
index 2fa029f..7daec5f 100644
--- a/Jamba-Follow/Locales/Locales.xml
+++ b/Jamba-Follow/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-ItemUse/Bindings.xml b/Jamba-ItemUse/Bindings.xml
index 70d5933..1a3862a 100644
--- a/Jamba-ItemUse/Bindings.xml
+++ b/Jamba-ItemUse/Bindings.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2016 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-ItemUse/Jamba-ItemUse.toc b/Jamba-ItemUse/Jamba-ItemUse.toc
index d64ddae..f11ace4 100644
--- a/Jamba-ItemUse/Jamba-ItemUse.toc
+++ b/Jamba-ItemUse/Jamba-ItemUse.toc
@@ -2,7 +2,7 @@
 ## Title: JambaItemUse
 ## Notes: JambaItemUse
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-ItemUse/JambaItemUse.lua b/Jamba-ItemUse/JambaItemUse.lua
index d38ddd6..81b3be4 100644
--- a/Jamba-ItemUse/JambaItemUse.lua
+++ b/Jamba-ItemUse/JambaItemUse.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

@@ -489,6 +489,7 @@ end
 function AJM:CheckForSatchelsItemAndAddToBar()
 	for bag = 0, NUM_BAG_SLOTS do
 		for slot = 1, GetContainerNumSlots(bag) do
+			local texture, count, locked, quality, readable, lootable, link, isFiltered, hasNoValue, itemID = GetContainerItemInfo(bag, slot)
 			if link and lootable then
 				--AJM:Print("test", link)
 				tooltipScanner:SetOwner(UIParent, "ANCHOR_NONE")
diff --git a/Jamba-ItemUse/Locales/JambaItemUse-Locale-enUS.lua b/Jamba-ItemUse/Locales/JambaItemUse-Locale-enUS.lua
index 0db9021..e0a28a5 100644
--- a/Jamba-ItemUse/Locales/JambaItemUse-Locale-enUS.lua
+++ b/Jamba-ItemUse/Locales/JambaItemUse-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-ItemUse/Locales/Locales.xml b/Jamba-ItemUse/Locales/Locales.xml
index 6fca106..319b1bc 100644
--- a/Jamba-ItemUse/Locales/Locales.xml
+++ b/Jamba-ItemUse/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-Macro/Jamba-Macro.toc b/Jamba-Macro/Jamba-Macro.toc
deleted file mode 100644
index a28eba0..0000000
--- a/Jamba-Macro/Jamba-Macro.toc
+++ /dev/null
@@ -1,12 +0,0 @@
-## Interface: 70100
-## Title: Jamba-Macro
-## Notes: Jamba-Macro
-## Author: Ebony, Former Author: Jafula
-## Version: 7.1.5-5.1.7
-## X-Category: Interface Enhancements
-## X-Child-Of: Jamba
-## Dependencies: Jamba
-## SavedVariables: JambaMacroProfileDB
-## LoadOnDemand: 1
-Locales\Locales.xml
-JambaMacro.lua
diff --git a/Jamba-Macro/JambaMacro.lua b/Jamba-Macro/JambaMacro.lua
deleted file mode 100644
index 4c6d016..0000000
--- a/Jamba-Macro/JambaMacro.lua
+++ /dev/null
@@ -1,1808 +0,0 @@
---[[
-Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
-License: The MIT License
-]]--
-
--- Create the addon using AceAddon-3.0 and embed some libraries.
-local AJM = LibStub( "AceAddon-3.0" ):NewAddon(
-	"JambaMacro",
-	"JambaModule-1.0",
-	"AceConsole-3.0",
-	"AceEvent-3.0"
-)
-
--- Load libraries.
-local JambaUtilities = LibStub:GetLibrary( "JambaUtilities-1.0" )
-local JambaHelperSettings = LibStub:GetLibrary( "JambaHelperSettings-1.0" )
-
---  Constants and Locale for this module.
-AJM.moduleName = "Jamba-Macro"
-AJM.settingsDatabaseName = "JambaMacroProfileDB"
-AJM.chatCommand = "jamba-macro"
-local L = LibStub( "AceLocale-3.0" ):GetLocale( AJM.moduleName )
-AJM.parentDisplayName = L["Macro"]
-AJM.moduleDisplayName = L["Macro"]
-
--- Settings - the values to store and their defaults for the settings database.
-AJM.settings = {
-	profile = {
-		variableSets = {},
-		macroSets = {},
-		currentVariableSetName = "",
-		currentMacroSetName = "",
-	},
-}
-
--- Configuration.
-function AJM:GetConfiguration()
-	local configuration = {
-		name = AJM.moduleDisplayName,
-		handler = AJM,
-		type = 'group',
-		childGroups  = "tab",
-		get = "JambaConfigurationGetSetting",
-		set = "JambaConfigurationSetSetting",
-		args = {
-			use = {
-				type = "input",
-				name = L["Use Macro and Variable Set"],
-				desc = L["Update the macros to use the specified macro and variable sets."],
-				usage = "/jamba-macro use",
-				get = false,
-				set = "UpdateMacrosUseSetCommand",
-			},
-			push = {
-				type = "input",
-				name = L["Push Settings"],
-				desc = L["Push the macro settings to all characters in the team."],
-				usage = "/jamba-macro push",
-				get = false,
-				set = "JambaSendSettings",
-			},
-		},
-	}
-	return configuration
-end
-
--------------------------------------------------------------------------------------------------------------
--- Command this module sends.
--------------------------------------------------------------------------------------------------------------
-
-AJM.COMMAND_MACROSET_USE = "MacroSetUse"
-
--------------------------------------------------------------------------------------------------------------
--- Messages module sends.
--------------------------------------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------------------------------------
--- Module variables.
--------------------------------------------------------------------------------------------------------------
-
---AJM.storedMacroFrames = {}
---AJM.frameCount = 0
-AJM.pendingMacroUpdate = false
-AJM.macroFrames = {}
---AJM.previousMacroSetName = ""
-AJM.currentVariables = {}
-AJM.currentMacros = {}
-AJM.currentControlMacroSet = {}
-
--------------------------------------------------------------------------------------------------------------
--- Settings Management.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:BeforeJambaProfileChanged()
-	AJM:CheckForEmptySets()
-end
-
-function AJM:OnJambaProfileChanged()
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsRefresh()
-	AJM:SettingsMacroControlScrollRefresh()
-	AJM:SettingsVariableSetsScrollRefresh()
-	AJM:SettingsVariablesScrollRefresh()
-	AJM:SettingsMacroSetsScrollRefresh()
-	AJM:SettingsMacrosScrollRefresh()
-end
-
-function AJM:SettingsPushSettingsClick( event )
-	AJM:JambaSendSettings()
-end
-
--- Settings received.
-function AJM:JambaOnSettingsReceived( characterName, settings )
-	if characterName ~= AJM.characterName then
-		-- Update the settings.
-		AJM.db.variableSets = JambaUtilities:CopyTable( settings.variableSets )
-		AJM.db.macroSets = JambaUtilities:CopyTable( settings.macroSets )
-		-- Refresh the settings.
-		AJM:ClearMacroFrames()
-		AJM:CheckForEmptySets()
-		AJM:SettingsRefresh()
-		AJM:SettingsMacroControlRowClick( 1, 1 )
-		AJM:SettingsVariableSetsRowClick( 1, 1 )
-		AJM:SettingsMacroSetsRowClick( 1, 1 )
-		-- Tell the player.
-		AJM:Print( L["Settings received from A."]( characterName ) )
-		-- Tell the team?
-		--AJM:JambaSendMessageToTeam( AJM.db.messageArea,  L["Settings received from A."]( characterName ), false )
-	end
-end
-
-function AJM:CheckForEmptySets()
-	if #AJM.db.variableSets == 0 then
-		AJM.currentVariables = {}
-	end
-	if #AJM.db.macroSets == 0 then
-		AJM.currentMacros = {}
-	end
-end
-
-function AJM:ClearMacroFrames()
-	for index, macroSet in ipairs( AJM.db.macroSets ) do
-		for position, macro in pairs( macroSet.macros ) do
-			macro.frame = nil
-		end
-	end
-end
-
--------------------------------------------------------------------------------------------------------------
--- Macro Management - Variable Sets.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:GetVariableSetsMaxPosition()
-	return #AJM.db.variableSets
-end
-
-function AJM:GetVariableSetAtPosition( position )
-	return AJM.db.variableSets[position]
-end
-
-function AJM:SetVariableSetAtPosition( position, variableSet )
-	AJM.db.variableSets[position] = variableSet
-end
-
-function AJM:GetVariableSetByName( variableSetName )
-	local variableSetIndex = 0
-	for index, variableSet in ipairs( AJM.db.variableSets ) do
-		if variableSet.name == variableSetName then
-			variableSetIndex = index
-			break
-		end
-	end
-	if variableSetIndex ~= 0 then
-		return AJM.db.variableSets[variableSetIndex]
-	end
-	return nil
-end
-
-function AJM:AddVariableSet( variableSetName, variables )
-	local newVariableSet = {}
-	newVariableSet.name = variableSetName
-	newVariableSet.variables = variables or {}
-	table.insert( AJM.db.variableSets, newVariableSet )
-	AJM:SettingsRefresh()
-	AJM:SettingsVariableSetsRowClick( 1, 1 )
-end
-
-function AJM:RemoveVariableSet( variableSetName )
-	local variableSetIndex = 0
-	for index, variableSet in ipairs( AJM.db.variableSets ) do
-		if variableSet.name == variableSetName then
-			variableSetIndex = index
-			break
-		end
-	end
-	if variableSetIndex ~= 0 then
-		table.remove( AJM.db.variableSets, variableSetIndex )
-	end
-	AJM:SettingsVariableSetsRowClick( 1, 1 )
-end
-
-function AJM:AddVariableSetGUI( name )
-	AJM:AddVariableSet( name, nil )
-	AJM:SettingsVariableSetsScrollRefresh()
-end
-
-function AJM:CopyVariableSetGUI( name )
-	local variableSetToCopy = AJM:GetVariableSetAtPosition( AJM.settingsControlVariables.variableSetsHighlightRow )
-	local variables = JambaUtilities:CopyTable( variableSetToCopy.variables )
-	AJM:AddVariableSet( name, variables )
-	AJM:SettingsVariableSetsScrollRefresh()
-end
-
-function AJM:RemoveVariableSetGUI()
-	local variableSet = AJM:GetVariableSetAtPosition( AJM.settingsControlVariables.variableSetsHighlightRow )
-	AJM:RemoveVariableSet( variableSet.name )
-	AJM.settingsControlVariables.variableSetsHighlightRow = 1
-	AJM:SettingsVariableSetsScrollRefresh()
-end
-
--------------------------------------------------------------------------------------------------------------
--- Macro Management - Variables.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:GetVariablesMaxPosition()
-	return #AJM.currentVariables
-end
-
-function AJM:GetVariableAtPosition( position )
-	return AJM.currentVariables[position]
-end
-
-function AJM:SetVariableAtPosition( position, variableInformation )
-	AJM.currentVariables[position] = variableInformation
-end
-
-function AJM:AddVariable( variableName )
-	local newVariable = {}
-	newVariable.name = variableName
-	newVariable.value = ""
-	newVariable.tag = JambaApi.AllTag()
-	table.insert( AJM.currentVariables, newVariable )
-	AJM:SettingsRefresh()
-	AJM:SettingsVariablesRowClick( 1, 1 )
-end
-
-function AJM:RemoveVariable( variableName, variableTag )
-	local variableIndex = 0
-	for index, variable in ipairs( AJM.currentVariables ) do
-		if variable.name == variableName and variable.tag == variableTag then
-			variableIndex = index
-			break
-		end
-	end
-	if variableIndex ~= 0 then
-		table.remove( AJM.currentVariables, variableIndex )
-	end
-	AJM:SettingsVariablesRowClick( 1, 1 )
-end
-
-function AJM:AddVariableGUI( name )
-	AJM:AddVariable( name )
-	AJM:SettingsVariablesScrollRefresh()
-end
-
-function AJM:RemoveVariableGUI()
-	local variable = AJM:GetVariableAtPosition( AJM.settingsControlVariables.variablesHighlightRow )
-	AJM:RemoveVariable( variable.name, variable.tag )
-	AJM.settingsControlVariables.variablesHighlightRow = 1
-	AJM:SettingsVariablesScrollRefresh()
-end
-
--------------------------------------------------------------------------------------------------------------
--- Macro Management - Macro Sets.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:GetMacroSetsMaxPosition()
-	return #AJM.db.macroSets
-end
-
-function AJM:GetMacroSetAtPosition( position )
-	return AJM.db.macroSets[position]
-end
-
-function AJM:SetMacroSetAtPosition( position, macroSet )
-	AJM.db.macroSets[position] = macroSet
-end
-
-function AJM:GetMacroSetByName( macroSetName )
-	local macroSetIndex = 0
-	for index, macroSet in ipairs( AJM.db.macroSets ) do
-		if macroSet.name == macroSetName then
-			macroSetIndex = index
-			break
-		end
-	end
-	if macroSetIndex ~= 0 then
-		return AJM.db.macroSets[macroSetIndex]
-	end
-	return nil
-end
-
-function AJM:AddMacroSet( macroSetName, macros )
-	local newMacroSet = {}
-	newMacroSet.name = macroSetName
-	newMacroSet.macros = macros or {}
-	newMacroSet.variableSet = ""
-	newMacroSet.tag = JambaApi.AllTag()
-	newMacroSet.enabled = false
-	table.insert( AJM.db.macroSets, newMacroSet )
-	AJM:SettingsRefresh()
-	AJM:SettingsMacroControlRowClick( 1, 1 )
-	AJM:SettingsMacroSetsRowClick( 1, 1 )
-end
-
-function AJM:RemoveMacroSet( macroSetName )
-	local macroSetIndex = 0
-	for index, macroSet in ipairs( AJM.db.macroSets ) do
-		if macroSet.name == macroSetName then
-			macroSetIndex = index
-			break
-		end
-	end
-	if macroSetIndex ~= 0 then
-		table.remove( AJM.db.macroSets, macroSetIndex )
-	end
-	AJM:SettingsMacroControlRowClick( 1, 1 )
-	AJM:SettingsMacroSetsRowClick( 1, 1 )
-end
-
-function AJM:AddMacroSetGUI( name )
-	AJM:AddMacroSet( name, nil )
-	AJM:SettingsMacroSetsScrollRefresh()
-end
-
-function AJM:CopyMacroSetGUI( name )
-	local macroSetToCopy = AJM:GetMacroSetAtPosition( AJM.settingsControlMacros.macroSetsHighlightRow )
-	local macros = JambaUtilities:CopyTable( macroSetToCopy.macros )
-	AJM:AddMacroSet( name, macros )
-	AJM:SettingsMacroSetsScrollRefresh()
-end
-
-function AJM:RemoveMacroSetGUI()
-	local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControlMacros.macroSetsHighlightRow )
-	AJM:ClearMacroSetKeyBindings( macroSet.name )
-	AJM:RemoveMacroSet( macroSet.name )
-	AJM.settingsControlMacros.macroSetsHighlightRow = 1
-	AJM:SettingsMacroSetsScrollRefresh()
-end
-
--------------------------------------------------------------------------------------------------------------
--- Macro Management - Macros.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:GetMacrosMaxPosition()
-	return #AJM.currentMacros
-end
-
-function AJM:GetMacroAtPosition( position )
-	return AJM.currentMacros[position]
-end
-
-function AJM:SetMacroAtPosition( position, macro )
-	AJM.currentMacros[position] = macro
-end
-
-function AJM:AddMacro( macroName )
-	local newMacro = {}
-	newMacro.name = macroName
-	newMacro.key = ""
-	newMacro.text = ""
-	newMacro.tag = JambaApi.AllTag()
-	table.insert( AJM.currentMacros, newMacro )
-	AJM:SettingsRefresh()
-	AJM:SettingsMacrosRowClick( 1, 1 )
-end
-
-function AJM:RemoveMacro( macroName, macroTag )
-	local macroIndex = 0
-	for index, macro in ipairs( AJM.currentMacros ) do
-		if macro.name == macroName and macro.tag == macroTag then
-			macroIndex = index
-			break
-		end
-	end
-	if macroIndex ~= 0 then
-		local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControlMacros.macroSetsHighlightRow )
-		AJM:ClearMacroKeyBinding( macroSet.name, macroName )
-		table.remove( AJM.currentMacros, macroIndex )
-	end
-	AJM:SettingsMacrosRowClick( 1, 1 )
-end
-
-function AJM:AddMacroGUI( name )
-	AJM:AddMacro( name )
-	AJM:SettingsMacrosScrollRefresh()
-end
-
-function AJM:RemoveMacroGUI()
-	local macro = AJM:GetMacroAtPosition( AJM.settingsControlMacros.macrosHighlightRow )
-	AJM:RemoveMacro( macro.name, macro.tag )
-	AJM.settingsControlMacros.macrosHighlightRow = 1
-	AJM:SettingsMacrosScrollRefresh()
-end
-
--------------------------------------------------------------------------------------------------------------
--- Settings Dialogs.
--------------------------------------------------------------------------------------------------------------
-
-local function SettingsCreateMacroControl( top )
-	-- Position and size constants.
-	local buttonControlWidth = 125
-	local buttonHeight = JambaHelperSettings:GetButtonHeight()
-	local editBoxHeight = JambaHelperSettings:GetEditBoxHeight()
-	local left = JambaHelperSettings:LeftOfSettings()
-	local headingHeight = JambaHelperSettings:HeadingHeight()
-	local headingWidth = JambaHelperSettings:HeadingWidth( false )
-	local horizontalSpacing = JambaHelperSettings:GetHorizontalSpacing()
-	local verticalSpacing = JambaHelperSettings:GetVerticalSpacing()
-	local macroControlWidth = headingWidth
-	local halfWidth = (headingWidth/2) - horizontalSpacing
-	local left2 = left + halfWidth
-	local movingTop = top
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Macro Sets Control"], movingTop, false )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.macroControlHighlightRow = 1
-	AJM.settingsControl.macroControlOffset = 1
-	local list = {}
-	list.listFrameName = "JambaMacroSettingsMacroControlFrame"
-	list.parentFrame = AJM.settingsControl.widgetSettings.content
-	list.listTop = movingTop
-	list.listLeft = left
-	list.listWidth = macroControlWidth
-	list.rowHeight = 20
-	list.rowsToDisplay = 9
-	list.columnsToDisplay = 4
-	list.columnInformation = {}
-	list.columnInformation[1] = {}
-	list.columnInformation[1].width = 40
-	list.columnInformation[1].alignment = "LEFT"
-	list.columnInformation[2] = {}
-	list.columnInformation[2].width = 30
-	list.columnInformation[2].alignment = "LEFT"
-	list.columnInformation[3] = {}
-	list.columnInformation[3].width = 20
-	list.columnInformation[3].alignment = "LEFT"
-	list.columnInformation[4] = {}
-	list.columnInformation[4].width = 10
-	list.columnInformation[4].alignment = "CENTER"
-	list.scrollRefreshCallback = AJM.SettingsMacroControlScrollRefresh
-	list.rowClickCallback = AJM.SettingsMacroControlRowClick
-	AJM.settingsControl.macroControl = list
-	JambaHelperSettings:CreateScrollList( AJM.settingsControl.macroControl )
-	movingTop = movingTop - list.listHeight - verticalSpacing
-	AJM.settingsControl.macroControlButtonEnable = JambaHelperSettings:CreateButton(
-		AJM.settingsControl,
-		buttonControlWidth,
-		left,
-		movingTop,
-		L["Enable"],
-		AJM.SettingsMacroControlEnableClick
-	)
-	AJM.settingsControl.macroControlButtonDisable = JambaHelperSettings:CreateButton(
-		AJM.settingsControl,
-		buttonControlWidth,
-		left + buttonControlWidth + horizontalSpacing,
-		movingTop,
-		L["Disable"],
-		AJM.SettingsMacroControlDisableClick
-	)
-	movingTop = movingTop -	buttonHeight - verticalSpacing
-	AJM.settingsControl.macroControlButtonBuildMacros = JambaHelperSettings:CreateButton(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Build Macros (Team)"],
-		AJM.SettingsMacroControlBuildMacrosClick
-	)
-	movingTop = movingTop -	buttonHeight - verticalSpacing
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Configure Macro Set"], movingTop, false )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.macroControlEditBoxVariableSetName = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControl,
-		macroControlWidth,
-		left,
-		movingTop,
-		L["Variable Set"]
-	)
-	AJM.settingsControl.macroControlEditBoxVariableSetName:SetCallback( "OnEnterPressed", AJM.SettingsEditBoxChangedMacroControlVariableSet )
-	movingTop = movingTop - editBoxHeight
-	AJM.settingsControl.macroControlEditBoxTagName = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControl,
-		macroControlWidth,
-		left,
-		movingTop,
-		L["Tag"]
-	)
-	AJM.settingsControl.macroControlEditBoxTagName:SetCallback( "OnEnterPressed", AJM.SettingsEditBoxChangedMacroControlTag )
-	movingTop = movingTop - editBoxHeight
-	return movingTop
-end
-
-local function SettingsCreateVariableSets( top )
-	-- Position and size constants.
-	local buttonControlWidth = 105
-	local buttonHeight = JambaHelperSettings:GetButtonHeight()
-	local editBoxHeight = JambaHelperSettings:GetEditBoxHeight()
-	local left = JambaHelperSettings:LeftOfSettings()
-	local headingHeight = JambaHelperSettings:HeadingHeight()
-	local headingWidth = JambaHelperSettings:HeadingWidth( false )
-	local horizontalSpacing = JambaHelperSettings:GetHorizontalSpacing()
-	local verticalSpacing = JambaHelperSettings:GetVerticalSpacing()
-	local variableSetsWidth = headingWidth - buttonControlWidth - horizontalSpacing
-	local halfWidth = (headingWidth/2) - horizontalSpacing
-	local left2 = left + halfWidth
-	local movingTop = top
-	JambaHelperSettings:CreateHeading( AJM.settingsControlVariables, L["Variable Sets"], movingTop, false )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlVariables.variableSetsHighlightRow = 1
-	AJM.settingsControlVariables.variableSetsOffset = 1
-	local list = {}
-	list.listFrameName = "JambaMacroSettingsVariableSetsFrame"
-	list.parentFrame = AJM.settingsControlVariables.widgetSettings.content
-	list.listTop = movingTop
-	list.listLeft = left
-	list.listWidth = variableSetsWidth
-	list.rowHeight = 20
-	list.rowsToDisplay = 4
-	list.columnsToDisplay = 1
-	list.columnInformation = {}
-	list.columnInformation[1] = {}
-	list.columnInformation[1].width = 100
-	list.columnInformation[1].alignment = "LEFT"
-	list.scrollRefreshCallback = AJM.SettingsVariableSetsScrollRefresh
-	list.rowClickCallback = AJM.SettingsVariableSetsRowClick
-	AJM.settingsControlVariables.variableSets = list
-	JambaHelperSettings:CreateScrollList( AJM.settingsControlVariables.variableSets )
-	--[[
-	AJM.settingsControlVariables.variableSetsButtonUse = JambaHelperSettings:CreateButton(
-		AJM.settingsControlVariables,
-		buttonControlWidth,
-		left + variableSetsWidth + horizontalSpacing,
-		movingTop,
-		L["Use"],
-		AJM.SettingsVariableSetsUseClick
-	)
-	movingTop = movingTop -	buttonHeight - verticalSpacing
-	]]--
-	AJM.settingsControlVariables.variableSetsButtonAdd = JambaHelperSettings:CreateButton(
-		AJM.settingsControlVariables,
-		buttonControlWidth,
-		left + variableSetsWidth + horizontalSpacing,
-		movingTop,
-		L["Add"],
-		AJM.SettingsVariableSetsAddClick
-	)
-	movingTop = movingTop -	buttonHeight - verticalSpacing
-	AJM.settingsControlVariables.variableSetsButtonRemove = JambaHelperSettings:CreateButton(
-		AJM.settingsControlVariables,
-		buttonControlWidth,
-		left + variableSetsWidth + horizontalSpacing,
-		movingTop,
-		L["Remove"],
-		AJM.SettingsVariableSetsRemoveClick
-	)
-	movingTop = movingTop -	buttonHeight - verticalSpacing
-	AJM.settingsControlVariables.variableSetsButtonCopy = JambaHelperSettings:CreateButton(
-		AJM.settingsControlVariables,
-		buttonControlWidth,
-		left + variableSetsWidth + horizontalSpacing,
-		movingTop,
-		L["Copy"],
-		AJM.SettingsVariableSetsCopyClick
-	)
-	movingTop = movingTop -	buttonHeight - verticalSpacing
-	movingTop = movingTop -	verticalSpacing - verticalSpacing - verticalSpacing
-	JambaHelperSettings:CreateHeading( AJM.settingsControlVariables, L["Variables"], movingTop, false )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlVariables.variablesHighlightRow = 1
-	AJM.settingsControlVariables.variablesOffset = 1
-	list = {}
-	list.listFrameName = "JambaMacroSettingsVariablesFrame"
-	list.parentFrame = AJM.settingsControlVariables.widgetSettings.content
-	list.listTop = movingTop
-	list.listLeft = left
-	list.listWidth = headingWidth
-	list.rowHeight = 20
-	list.rowsToDisplay = 4
-	list.columnsToDisplay = 3
-	list.columnInformation = {}
-	list.columnInformation[1] = {}
-	list.columnInformation[1].width = 36
-	list.columnInformation[1].alignment = "LEFT"
-	list.columnInformation[2] = {}
-	list.columnInformation[2].width = 33
-	list.columnInformation[2].alignment = "LEFT"
-	list.columnInformation[3] = {}
-	list.columnInformation[3].width = 33
-	list.columnInformation[3].alignment = "LEFT"
-	list.scrollRefreshCallback = AJM.SettingsVariablesScrollRefresh
-	list.rowClickCallback = AJM.SettingsVariablesRowClick
-	AJM.settingsControlVariables.variables = list
-	JambaHelperSettings:CreateScrollList( AJM.settingsControlVariables.variables )
-	movingTop = movingTop - list.listHeight - verticalSpacing
-	AJM.settingsControlVariables.variablesButtonAdd = JambaHelperSettings:CreateButton(
-		AJM.settingsControlVariables,
-		buttonControlWidth,
-		left,
-		movingTop,
-		L["Add"],
-		AJM.SettingsVariablesAddClick
-	)
-	AJM.settingsControlVariables.variablesButtonRemove = JambaHelperSettings:CreateButton(
-		AJM.settingsControlVariables,
-		buttonControlWidth,
-		left + horizontalSpacing + buttonControlWidth,
-		movingTop,
-		L["Remove"],
-		AJM.SettingsVariablesRemoveClick
-	)
-	movingTop = movingTop -	buttonHeight
-	JambaHelperSettings:CreateHeading( AJM.settingsControlVariables, L["Edit Variable"], movingTop, false )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlVariables.variablesEditBoxVariableName = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlVariables,
-		headingWidth,
-		left,
-		movingTop,
-		L["Variable Name"]
-	)
-	AJM.settingsControlVariables.variablesEditBoxVariableName:SetCallback( "OnEnterPressed", AJM.SettingsEditBoxChangedVariableName )
-	movingTop = movingTop - editBoxHeight
-	AJM.settingsControlVariables.variablesEditBoxVariableTag = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlVariables,
-		headingWidth,
-		left,
-		movingTop,
-		L["Variable Tag (prefix ! for not this tag)"]
-	)
-	AJM.settingsControlVariables.variablesEditBoxVariableTag:SetCallback( "OnEnterPressed", AJM.SettingsEditBoxChangedVariableTag )
-	movingTop = movingTop - editBoxHeight
-	AJM.settingsControlVariables.variablesEditBoxVariableValue = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlVariables,
-		headingWidth,
-		left,
-		movingTop,
-		L["Variable Value"]
-	)
-	AJM.settingsControlVariables.variablesEditBoxVariableValue:SetCallback( "OnEnterPressed", AJM.SettingsEditBoxChangedVariableValue )
-	movingTop = movingTop - editBoxHeight
-	return movingTop
-end
-
-local function SettingsCreateMacroSets( top )
-	-- Position and size constants.
-	local buttonControlWidth = 105
-	local buttonHeight = JambaHelperSettings:GetButtonHeight()
-	local editBoxHeight = JambaHelperSettings:GetEditBoxHeight()
-	local keyBindingHeight = JambaHelperSettings:GetKeyBindingHeight()
-	local left = JambaHelperSettings:LeftOfSettings()
-	local headingHeight = JambaHelperSettings:HeadingHeight()
-	local headingWidth = JambaHelperSettings:HeadingWidth( false )
-	local horizontalSpacing = JambaHelperSettings:GetHorizontalSpacing()
-	local verticalSpacing = JambaHelperSettings:GetVerticalSpacing()
-	local macroSetsWidth = headingWidth - buttonControlWidth - horizontalSpacing
-	local halfWidth = (headingWidth/2) - horizontalSpacing
-	local left2 = left + halfWidth
-	local movingTop = top
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Macro Sets"], movingTop, false )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.macroSetsHighlightRow = 1
-	AJM.settingsControlMacros.macroSetsOffset = 1
-	local list = {}
-	list.listFrameName = "JambaMacroSettingsMacroSetsFrame"
-	list.parentFrame = AJM.settingsControlMacros.widgetSettings.content
-	list.listTop = movingTop
-	list.listLeft = left
-	list.listWidth = macroSetsWidth
-	list.rowHeight = 20
-	list.rowsToDisplay = 4
-	list.columnsToDisplay = 1
-	list.columnInformation = {}
-	list.columnInformation[1] = {}
-	list.columnInformation[1].width = 100
-	list.columnInformation[1].alignment = "LEFT"
-	list.scrollRefreshCallback = AJM.SettingsMacroSetsScrollRefresh
-	list.rowClickCallback = AJM.SettingsMacroSetsRowClick
-	AJM.settingsControlMacros.macroSets = list
-	JambaHelperSettings:CreateScrollList( AJM.settingsControlMacros.macroSets )
-	--[[
-	AJM.settingsControlMacros.macroSetsButtonUse = JambaHelperSettings:CreateButton(
-		AJM.settingsControlMacros,
-		buttonControlWidth,
-		left + macroSetsWidth + horizontalSpacing,
-		movingTop,
-		L["Use"],
-		AJM.SettingsMacroSetsUseClick
-	)
-	movingTop = movingTop -	buttonHeight - verticalSpacing
-	]]--
-	AJM.settingsControlMacros.macroSetsButtonAdd = JambaHelperSettings:CreateButton(
-		AJM.settingsControlMacros,
-		buttonControlWidth,
-		left + macroSetsWidth + horizontalSpacing,
-		movingTop,
-		L["Add"],
-		AJM.SettingsMacroSetsAddClick
-	)
-	movingTop = movingTop -	buttonHeight - verticalSpacing
-	AJM.settingsControlMacros.macroSetsButtonRemove = JambaHelperSettings:CreateButton(
-		AJM.settingsControlMacros,
-		buttonControlWidth,
-		left + macroSetsWidth + horizontalSpacing,
-		movingTop,
-		L["Remove"],
-		AJM.SettingsMacroSetsRemoveClick
-	)
-	movingTop = movingTop -	buttonHeight - verticalSpacing
-	AJM.settingsControlMacros.macroSetsButtonCopy = JambaHelperSettings:CreateButton(
-		AJM.settingsControlMacros,
-		buttonControlWidth,
-		left + macroSetsWidth + horizontalSpacing,
-		movingTop,
-		L["Copy"],
-		AJM.SettingsMacroSetsCopyClick
-	)
-	movingTop = movingTop -	buttonHeight - verticalSpacing
-	movingTop = movingTop -	verticalSpacing - verticalSpacing - verticalSpacing
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Macros"], movingTop, false )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.macrosHighlightRow = 1
-	AJM.settingsControlMacros.macrosOffset = 1
-	list = {}
-	list.listFrameName = "JambaMacroSettingsMacrosFrame"
-	list.parentFrame = AJM.settingsControlMacros.widgetSettings.content
-	list.listTop = movingTop
-	list.listLeft = left
-	list.listWidth = macroSetsWidth
-	list.rowHeight = 20
-	list.rowsToDisplay = 5
-	list.columnsToDisplay = 2
-	list.columnInformation = {}
-	list.columnInformation[1] = {}
-	list.columnInformation[1].width = 50
-	list.columnInformation[1].alignment = "LEFT"
-	list.columnInformation[2] = {}
-	list.columnInformation[2].width = 50
-	list.columnInformation[2].alignment = "LEFT"
-	list.scrollRefreshCallback = AJM.SettingsMacrosScrollRefresh
-	list.rowClickCallback = AJM.SettingsMacrosRowClick
-	AJM.settingsControlMacros.macros = list
-	JambaHelperSettings:CreateScrollList( AJM.settingsControlMacros.macros )
-	AJM.settingsControlMacros.macrosButtonAdd = JambaHelperSettings:CreateButton(
-		AJM.settingsControlMacros,
-		buttonControlWidth,
-		left + macroSetsWidth + horizontalSpacing,
-		movingTop,
-		L["Add"],
-		AJM.SettingsMacrosAddClick
-	)
-	AJM.settingsControlMacros.macrosButtonRemove = JambaHelperSettings:CreateButton(
-		AJM.settingsControlMacros,
-		buttonControlWidth,
-		left + macroSetsWidth + horizontalSpacing,
-		movingTop - buttonHeight - verticalSpacing,
-		L["Remove"],
-		AJM.SettingsMacrosRemoveClick
-	)
-	AJM.settingsControlMacros.macrosButtonShow = JambaHelperSettings:CreateButton(
-		AJM.settingsControlMacros,
-		buttonControlWidth,
-		left + macroSetsWidth + horizontalSpacing,
-		movingTop - buttonHeight - verticalSpacing - buttonHeight - verticalSpacing,
-		L["Show"],
-		AJM.SettingsMacrosShowClick
-	)
-	movingTop = movingTop - list.listHeight - verticalSpacing
-	AJM.settingsControlMacros.macrosEditBoxMacroUsage = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro Usage - press key assigned or copy /click below."]
-	)
-	movingTop = movingTop - editBoxHeight
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Edit Macro"], movingTop, false )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.macrosEditBoxMacroName = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro Name"]
-	)
-	AJM.settingsControlMacros.macrosEditBoxMacroName:SetCallback( "OnEnterPressed", AJM.SettingsEditBoxChangedMacroName )
-	movingTop = movingTop - editBoxHeight
-	AJM.settingsControlMacros.macrosEditBoxMacroTag = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro Tag (prefix ! for not this tag)"]
-	)
-	AJM.settingsControlMacros.macrosEditBoxMacroTag:SetCallback( "OnEnterPressed", AJM.SettingsEditBoxChangedMacroTag )
-	movingTop = movingTop - editBoxHeight
-	AJM.settingsControlMacros.macrosMultiEditBoxMacroText = JambaHelperSettings:CreateMultiEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro Text"],
-		4
-	)
-	AJM.settingsControlMacros.macrosMultiEditBoxMacroText:SetCallback( "OnEnterPressed", AJM.SettingsMultiEditBoxChangedMacroText )
-	local multiEditBoxHeightMacroText = 100
-	movingTop = movingTop - multiEditBoxHeightMacroText
-	AJM.settingsControlMacros.macrosKeyBindingMacroKey = JambaHelperSettings:CreateKeyBinding(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro Key"]
-	)
-	AJM.settingsControlMacros.macrosKeyBindingMacroKey:SetCallback( "OnKeyChanged", AJM.SettingsKeyBindingChangedMacroKey )
-	movingTop = movingTop - keyBindingHeight
-	return movingTop
-end
-
-local function SettingsCreate()
-	AJM.settingsControl = {}
-	AJM.settingsControlVariables = {}
-	AJM.settingsControlMacros = {}
-	JambaHelperSettings:CreateSettings(
-		AJM.settingsControl,
-		AJM.moduleDisplayName,
-		AJM.parentDisplayName,
-		AJM.SettingsPushSettingsClick
-	)
-	JambaHelperSettings:CreateSettings(
-		AJM.settingsControlVariables,
-		L["Macro: Variables"],
-		AJM.parentDisplayName,
-		AJM.SettingsPushSettingsClick
-	)
-	JambaHelperSettings:CreateSettings(
-		AJM.settingsControlMacros,
-		L["Macro: Macros"],
-		AJM.parentDisplayName,
-		AJM.SettingsPushSettingsClick
-	)
-	local bottomOfMacroControl = SettingsCreateMacroControl( JambaHelperSettings:TopOfSettings() )
-	AJM.settingsControl.widgetSettings.content:SetHeight( -bottomOfMacroControl )
-	local bottomOfVariableSets = SettingsCreateVariableSets( JambaHelperSettings:TopOfSettings() )
-	AJM.settingsControlVariables.widgetSettings.content:SetHeight( -bottomOfVariableSets )
-	local bottomOfMacroSets = SettingsCreateMacroSets( JambaHelperSettings:TopOfSettings() )
-	AJM.settingsControlMacros.widgetSettings.content:SetHeight( -bottomOfMacroSets )
-	-- Help
-	local helpTable = {}
-	JambaHelperSettings:CreateHelp( AJM.settingsControl, helpTable, AJM:GetConfiguration() )
-end
-
--------------------------------------------------------------------------------------------------------------
--- Settings Callbacks.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:SettingsMacroControlScrollRefresh()
-	FauxScrollFrame_Update(
-		AJM.settingsControl.macroControl.listScrollFrame,
-		AJM:GetMacroSetsMaxPosition(),
-		AJM.settingsControl.macroControl.rowsToDisplay,
-		AJM.settingsControl.macroControl.rowHeight
-	)
-	AJM.settingsControl.macroControlOffset = FauxScrollFrame_GetOffset( AJM.settingsControl.macroControl.listScrollFrame )
-	for iterateDisplayRows = 1, AJM.settingsControl.macroControl.rowsToDisplay do
-		-- Reset.
-		AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[1].textString:SetText( "" )
-		AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[1].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[2].textString:SetText( "" )
-		AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[2].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[3].textString:SetText( "" )
-		AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[3].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[4].textString:SetText( "" )
-		AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[4].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControl.macroControl.rows[iterateDisplayRows].highlight:SetColorTexture( 0.0, 0.0, 0.0, 0.0 )
-		-- Get data.
-		local dataRowNumber = iterateDisplayRows + AJM.settingsControl.macroControlOffset
-		if dataRowNumber <= AJM:GetMacroSetsMaxPosition() then
-			-- Put data information into columns.
-			local macroSetsInformation = AJM:GetMacroSetAtPosition( dataRowNumber )
-			AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[1].textString:SetText( macroSetsInformation.name )
-			AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[2].textString:SetText( macroSetsInformation.variableSet )
-			AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[3].textString:SetText( macroSetsInformation.tag )
-			if (macroSetsInformation.enabled == nil) or (macroSetsInformation.enabled == false) then
-				AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[4].textString:SetText( L["Off"] )
-				AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[4].textString:SetTextColor( 1.0, 0.0, 0.0, 1.0 )
-			else
-				AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[4].textString:SetText( L["On"] )
-				AJM.settingsControl.macroControl.rows[iterateDisplayRows].columns[4].textString:SetTextColor( 0.0, 1.0, 0.0, 1.0 )
-			end
-			-- Highlight the selected row.
-			if dataRowNumber == AJM.settingsControl.macroControlHighlightRow then
-				AJM.settingsControl.macroControl.rows[iterateDisplayRows].highlight:SetColorTexture( 1.0, 1.0, 0.0, 0.5 )
-			end
-		end
-	end
-	local disabled = false
-	if AJM:GetMacroSetsMaxPosition() == 0 then
-		disabled = true
-	end
-	AJM.settingsControl.macroControlButtonEnable:SetDisabled( disabled )
-	AJM.settingsControl.macroControlButtonDisable:SetDisabled( disabled )
-	AJM.settingsControl.macroControlEditBoxVariableSetName:SetDisabled( disabled )
-	AJM.settingsControl.macroControlEditBoxTagName:SetDisabled( disabled )
-end
-
-function AJM:SettingsVariableSetsScrollRefresh()
-	FauxScrollFrame_Update(
-		AJM.settingsControlVariables.variableSets.listScrollFrame,
-		AJM:GetVariableSetsMaxPosition(),
-		AJM.settingsControlVariables.variableSets.rowsToDisplay,
-		AJM.settingsControlVariables.variableSets.rowHeight
-	)
-	AJM.settingsControlVariables.variableSetsOffset = FauxScrollFrame_GetOffset( AJM.settingsControlVariables.variableSets.listScrollFrame )
-	for iterateDisplayRows = 1, AJM.settingsControlVariables.variableSets.rowsToDisplay do
-		-- Reset.
-		AJM.settingsControlVariables.variableSets.rows[iterateDisplayRows].columns[1].textString:SetText( "" )
-		AJM.settingsControlVariables.variableSets.rows[iterateDisplayRows].columns[1].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControlVariables.variableSets.rows[iterateDisplayRows].highlight:SetColorTexture( 0.0, 0.0, 0.0, 0.0 )
-		-- Get data.
-		local dataRowNumber = iterateDisplayRows + AJM.settingsControlVariables.variableSetsOffset
-		if dataRowNumber <= AJM:GetVariableSetsMaxPosition() then
-			-- Put data information into columns.
-			local variableSetsInformation = AJM:GetVariableSetAtPosition( dataRowNumber )
-			AJM.settingsControlVariables.variableSets.rows[iterateDisplayRows].columns[1].textString:SetText( variableSetsInformation.name )
-			-- Highlight the selected row.
-			if dataRowNumber == AJM.settingsControlVariables.variableSetsHighlightRow then
-				AJM.settingsControlVariables.variableSets.rows[iterateDisplayRows].highlight:SetColorTexture( 1.0, 1.0, 0.0, 0.5 )
-			end
-		end
-	end
-	local disabled = false
-	if AJM:GetVariableSetsMaxPosition() == 0 then
-		disabled = true
-	end
-	-- Variable Sets.
-	--AJM.settingsControlVariables.variableSetsButtonUse:SetDisabled( disabled )
-	AJM.settingsControlVariables.variableSetsButtonRemove:SetDisabled( disabled )
-	AJM.settingsControlVariables.variableSetsButtonCopy:SetDisabled( disabled )
-	-- Variables.
-	AJM.settingsControlVariables.variablesButtonAdd:SetDisabled( disabled )
-end
-
-function AJM:SettingsVariablesScrollRefresh()
-	FauxScrollFrame_Update(
-		AJM.settingsControlVariables.variables.listScrollFrame,
-		AJM:GetVariablesMaxPosition(),
-		AJM.settingsControlVariables.variables.rowsToDisplay,
-		AJM.settingsControlVariables.variables.rowHeight
-	)
-	AJM.settingsControlVariables.variablesOffset = FauxScrollFrame_GetOffset( AJM.settingsControlVariables.variables.listScrollFrame )
-	for iterateDisplayRows = 1, AJM.settingsControlVariables.variables.rowsToDisplay do
-		-- Reset.
-		AJM.settingsControlVariables.variables.rows[iterateDisplayRows].columns[1].textString:SetText( "" )
-		AJM.settingsControlVariables.variables.rows[iterateDisplayRows].columns[2].textString:SetText( "" )
-		AJM.settingsControlVariables.variables.rows[iterateDisplayRows].columns[3].textString:SetText( "" )
-		AJM.settingsControlVariables.variables.rows[iterateDisplayRows].columns[1].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControlVariables.variables.rows[iterateDisplayRows].columns[2].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControlVariables.variables.rows[iterateDisplayRows].columns[3].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControlVariables.variables.rows[iterateDisplayRows].highlight:SetColorTexture( 0.0, 0.0, 0.0, 0.0 )
-		-- Get data.
-		local dataRowNumber = iterateDisplayRows + AJM.settingsControlVariables.variablesOffset
-		if dataRowNumber <= AJM:GetVariablesMaxPosition() then
-			-- Put data information into columns.
-			local variablesInformation = AJM:GetVariableAtPosition( dataRowNumber )
-			AJM.settingsControlVariables.variables.rows[iterateDisplayRows].columns[1].textString:SetText( variablesInformation.name )
-			AJM.settingsControlVariables.variables.rows[iterateDisplayRows].columns[2].textString:SetText( variablesInformation.tag )
-			AJM.settingsControlVariables.variables.rows[iterateDisplayRows].columns[3].textString:SetText( variablesInformation.value )
-			-- Highlight the selected row.
-			if dataRowNumber == AJM.settingsControlVariables.variablesHighlightRow then
-				AJM.settingsControlVariables.variables.rows[iterateDisplayRows].highlight:SetColorTexture( 1.0, 1.0, 0.0, 0.5 )
-			end
-		end
-	end
-	local disabled = false
-	if AJM:GetVariablesMaxPosition() == 0 then
-		disabled = true
-		AJM.settingsControlVariables.variablesEditBoxVariableName:SetText( "" )
-		AJM.settingsControlVariables.variablesEditBoxVariableTag:SetText( "" )
-		AJM.settingsControlVariables.variablesEditBoxVariableValue:SetText( "" )
-	end
-	AJM.settingsControlVariables.variablesButtonRemove:SetDisabled( disabled )
-	AJM.settingsControlVariables.variablesEditBoxVariableName:SetDisabled( disabled )
-	AJM.settingsControlVariables.variablesEditBoxVariableTag:SetDisabled( disabled )
-	AJM.settingsControlVariables.variablesEditBoxVariableValue:SetDisabled( disabled )
-	if AJM:GetVariableSetsMaxPosition() == 0 then
-		AJM.settingsControlVariables.variablesButtonAdd:SetDisabled( true )
-	else
-		AJM.settingsControlVariables.variablesButtonAdd:SetDisabled( false )
-	end
-end
-
-function AJM:SettingsMacroSetsScrollRefresh()
-	FauxScrollFrame_Update(
-		AJM.settingsControlMacros.macroSets.listScrollFrame,
-		AJM:GetMacroSetsMaxPosition(),
-		AJM.settingsControlMacros.macroSets.rowsToDisplay,
-		AJM.settingsControlMacros.macroSets.rowHeight
-	)
-	AJM.settingsControlMacros.macroSetsOffset = FauxScrollFrame_GetOffset( AJM.settingsControlMacros.macroSets.listScrollFrame )
-	for iterateDisplayRows = 1, AJM.settingsControlMacros.macroSets.rowsToDisplay do
-		-- Reset.
-		AJM.settingsControlMacros.macroSets.rows[iterateDisplayRows].columns[1].textString:SetText( "" )
-		AJM.settingsControlMacros.macroSets.rows[iterateDisplayRows].columns[1].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControlMacros.macroSets.rows[iterateDisplayRows].highlight:SetColorTexture( 0.0, 0.0, 0.0, 0.0 )
-		-- Get data.
-		local dataRowNumber = iterateDisplayRows + AJM.settingsControlMacros.macroSetsOffset
-		if dataRowNumber <= AJM:GetMacroSetsMaxPosition() then
-			-- Put data information into columns.
-			local macroSetsInformation = AJM:GetMacroSetAtPosition( dataRowNumber )
-			AJM.settingsControlMacros.macroSets.rows[iterateDisplayRows].columns[1].textString:SetText( macroSetsInformation.name )
-			-- Highlight the selected row.
-			if dataRowNumber == AJM.settingsControlMacros.macroSetsHighlightRow then
-				AJM.settingsControlMacros.macroSets.rows[iterateDisplayRows].highlight:SetColorTexture( 1.0, 1.0, 0.0, 0.5 )
-			end
-		end
-	end
-	local disabled = false
-	if AJM:GetMacroSetsMaxPosition() == 0 then
-		disabled = true
-	end
-	-- Macro sets.
-	--AJM.settingsControlMacros.macroSetsButtonUse:SetDisabled( disabled )
-	AJM.settingsControlMacros.macroSetsButtonRemove:SetDisabled( disabled )
-	AJM.settingsControlMacros.macroSetsButtonCopy:SetDisabled( disabled )
-	-- Macro.
-	AJM.settingsControlMacros.macrosButtonAdd:SetDisabled( disabled )
-end
-
-function AJM:SettingsMacrosScrollRefresh()
-	FauxScrollFrame_Update(
-		AJM.settingsControlMacros.macros.listScrollFrame,
-		AJM:GetMacrosMaxPosition(),
-		AJM.settingsControlMacros.macros.rowsToDisplay,
-		AJM.settingsControlMacros.macros.rowHeight
-	)
-	AJM.settingsControlMacros.macrosOffset = FauxScrollFrame_GetOffset( AJM.settingsControlMacros.macros.listScrollFrame )
-	for iterateDisplayRows = 1, AJM.settingsControlMacros.macros.rowsToDisplay do
-		-- Reset.
-		AJM.settingsControlMacros.macros.rows[iterateDisplayRows].columns[1].textString:SetText( "" )
-		AJM.settingsControlMacros.macros.rows[iterateDisplayRows].columns[2].textString:SetText( "" )
-		AJM.settingsControlMacros.macros.rows[iterateDisplayRows].columns[1].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControlMacros.macros.rows[iterateDisplayRows].columns[2].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
-		AJM.settingsControlMacros.macros.rows[iterateDisplayRows].highlight:SetColorTexture( 0.0, 0.0, 0.0, 0.0 )
-		-- Get data.
-		local dataRowNumber = iterateDisplayRows + AJM.settingsControlMacros.macrosOffset
-		if dataRowNumber <= AJM:GetMacrosMaxPosition() then
-			-- Put data information into columns.
-			local macrosInformation = AJM:GetMacroAtPosition( dataRowNumber )
-			AJM.settingsControlMacros.macros.rows[iterateDisplayRows].columns[1].textString:SetText( macrosInformation.name )
-			AJM.settingsControlMacros.macros.rows[iterateDisplayRows].columns[2].textString:SetText( macrosInformation.key )
-			-- Highlight the selected row.
-			if dataRowNumber == AJM.settingsControlMacros.macrosHighlightRow then
-				AJM.settingsControlMacros.macros.rows[iterateDisplayRows].highlight:SetColorTexture( 1.0, 1.0, 0.0, 0.5 )
-			end
-		end
-	end
-	local disabled = false
-	if AJM:GetMacrosMaxPosition() == 0 then
-		disabled = true
-		AJM.settingsControlMacros.macrosEditBoxMacroName:SetText( "" )
-		AJM.settingsControlMacros.macrosEditBoxMacroTag:SetText( "" )
-		AJM.settingsControlMacros.macrosMultiEditBoxMacroText:SetText( "" )
-		AJM.settingsControlMacros.macrosKeyBindingMacroKey:SetKey( "" )
-	end
-	AJM.settingsControlMacros.macrosButtonRemove:SetDisabled( disabled )
-	AJM.settingsControlMacros.macrosButtonShow:SetDisabled( disabled )
-	AJM.settingsControlMacros.macrosEditBoxMacroUsage:SetDisabled( disabled )
-	AJM.settingsControlMacros.macrosEditBoxMacroName:SetDisabled( disabled )
-	AJM.settingsControlMacros.macrosEditBoxMacroTag:SetDisabled( disabled )
-	AJM.settingsControlMacros.macrosMultiEditBoxMacroText:SetDisabled( disabled )
-	AJM.settingsControlMacros.macrosKeyBindingMacroKey:SetDisabled( disabled )
-end
-
-function AJM:UpdateVariableSetInformation()
-	local variableSet = AJM:GetVariableSetAtPosition( AJM.settingsControlVariables.variableSetsHighlightRow )
-	AJM.currentVariables = variableSet.variables
-	AJM:SettingsVariablesScrollRefresh()
-	AJM:SettingsVariablesRowClick( 1, 1 )
-end
-
-function AJM:UpdateVariableInformation()
-	local variable = AJM:GetVariableAtPosition( AJM.settingsControlVariables.variablesHighlightRow )
-	AJM.settingsControlVariables.variablesEditBoxVariableName:SetText( variable.name )
-	AJM.settingsControlVariables.variablesEditBoxVariableTag:SetText( variable.tag )
-	AJM.settingsControlVariables.variablesEditBoxVariableValue:SetText( variable.value )
-end
-
-function AJM:UpdateMacroSetInformation()
-	local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControlMacros.macroSetsHighlightRow )
-	AJM.currentMacros = macroSet.macros
-	AJM:SettingsMacrosScrollRefresh()
-	AJM:SettingsMacrosRowClick( 1, 1 )
-end
-
-function AJM:UpdateMacroControlInformation()
-	local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControl.macroControlHighlightRow )
-	AJM.currentControlMacroSet = macroSet
-	-- New additions to macro sets in Jamba 0.5c, make sure there are workable defaults in place.
-	-- Begin.
-	if macroSet.variableSet == nil then
-		macroSet.variableSet = ""
-	end
-	if macroSet.tag == nil then
-		macroSet.tag = JambaApi.AllTag()
-	end
-	if macroSet.enabled == nil then
-		macroSet.enabled = false
-	end
-	-- End.
-	AJM.settingsControl.macroControlEditBoxVariableSetName:SetText( macroSet.variableSet )
-	AJM.settingsControl.macroControlEditBoxTagName:SetText( macroSet.tag )
-end
-
-function AJM:UpdateMacroInformation()
-	local macro = AJM:GetMacroAtPosition( AJM.settingsControlMacros.macrosHighlightRow )
-	AJM.settingsControlMacros.macrosEditBoxMacroUsage:SetText( L["/click JMB_"]..macro.name )
-	AJM.settingsControlMacros.macrosEditBoxMacroName:SetText( macro.name )
-	AJM.settingsControlMacros.macrosMultiEditBoxMacroText:SetText( macro.text )
-	AJM.settingsControlMacros.macrosEditBoxMacroTag:SetText( macro.tag )
-	AJM.settingsControlMacros.macrosKeyBindingMacroKey:SetKey( macro.key )
-end
-
-function AJM:SettingsMacroControlRowClick( rowNumber, columnNumber )
-	if AJM.settingsControl.macroControlOffset + rowNumber <= AJM:GetMacroSetsMaxPosition() then
-		AJM.settingsControl.macroControlHighlightRow = AJM.settingsControl.macroControlOffset + rowNumber
-		AJM:UpdateMacroControlInformation()
-		AJM:SettingsMacroControlScrollRefresh()
-	end
-end
-
-function AJM:SettingsVariableSetsRowClick( rowNumber, columnNumber )
-	if AJM.settingsControlVariables.variableSetsOffset + rowNumber <= AJM:GetVariableSetsMaxPosition() then
-		AJM.settingsControlVariables.variableSetsHighlightRow = AJM.settingsControlVariables.variableSetsOffset + rowNumber
-		AJM:UpdateVariableSetInformation()
-		AJM:SettingsVariableSetsScrollRefresh()
-	end
-end
-
-function AJM:SettingsVariablesRowClick( rowNumber, columnNumber )
-	if AJM.settingsControlVariables.variablesOffset + rowNumber <= AJM:GetVariablesMaxPosition() then
-		AJM.settingsControlVariables.variablesHighlightRow = AJM.settingsControlVariables.variablesOffset + rowNumber
-		AJM:UpdateVariableInformation()
-		AJM:SettingsVariablesScrollRefresh()
-	end
-end
-
-function AJM:SettingsMacroSetsRowClick( rowNumber, columnNumber )
-	if AJM.settingsControlMacros.macroSetsOffset + rowNumber <= AJM:GetMacroSetsMaxPosition() then
-		AJM.settingsControlMacros.macroSetsHighlightRow = AJM.settingsControlMacros.macroSetsOffset + rowNumber
-		AJM:UpdateMacroSetInformation()
-		AJM:SettingsMacroSetsScrollRefresh()
-	end
-end
-
-function AJM:SettingsMacrosRowClick( rowNumber, columnNumber )
-	if AJM.settingsControlMacros.macrosOffset + rowNumber <= AJM:GetMacrosMaxPosition() then
-		AJM.settingsControlMacros.macrosHighlightRow = AJM.settingsControlMacros.macrosOffset + rowNumber
-		AJM:UpdateMacroInformation()
-		AJM:SettingsMacrosScrollRefresh()
-	end
-end
-
-function AJM:SettingsEditBoxChangedVariableName( event, text )
-	if not text or text:trim() == "" or text:find( "%W" ) ~= nil then
-		AJM:Print( L["Variable names must only be made up of letters and numbers."] )
-		return
-	end
-	local variable = AJM:GetVariableAtPosition( AJM.settingsControlVariables.variablesHighlightRow )
-	variable.name = text
-	AJM:SettingsVariablesScrollRefresh()
-end
-
-function AJM:SettingsEditBoxChangedVariableTag( event, text )
-	if AJM:CheckForValidTag( text ) == false then
-		return
-	end
-	local variable = AJM:GetVariableAtPosition( AJM.settingsControlVariables.variablesHighlightRow )
-	variable.tag = text
-	AJM:SettingsVariablesScrollRefresh()
-end
-
-function AJM:SettingsEditBoxChangedVariableValue( event, text )
-	local variable = AJM:GetVariableAtPosition( AJM.settingsControlVariables.variablesHighlightRow )
-	variable.value = text
-	AJM:SettingsVariablesScrollRefresh()
-end
-
-function AJM:SettingsEditBoxChangedMacroName( event, text )
-	if not text or text:trim() == "" or text:find( "%W" ) ~= nil then
-		AJM:Print( L["Macro names must only be made up of letters and numbers."] )
-		return
-	end
-	local macro = AJM:GetMacroAtPosition( AJM.settingsControlMacros.macrosHighlightRow )
-	macro.name = text
-	AJM.settingsControlMacros.macrosEditBoxMacroUsage:SetText( L["/click JMB_"]..macro.name )
-	AJM:SettingsMacrosScrollRefresh()
-end
-
-function AJM:CheckForValidTag( text )
-	if not text or text:trim() == "" then
-		return false
-	end
-	if text:sub( 1, 1 ) == "!" then
-		text = text:sub( 2 )
-	end
-	if text:find( "%W" ) ~= nil then
-		AJM:Print( L["Macro tags must only be made up of letters and numbers."] )
-		return false
-	end
-	return true
-end
-
-function AJM:SettingsEditBoxChangedMacroTag( event, text )
-	if AJM:CheckForValidTag( text ) == false then
-		return
-	end
-	local macro = AJM:GetMacroAtPosition( AJM.settingsControlMacros.macrosHighlightRow )
-	macro.tag = text
-	AJM:SettingsMacrosScrollRefresh()
-end
-
-function AJM:SettingsMultiEditBoxChangedMacroText( event, text )
-	local macro = AJM:GetMacroAtPosition( AJM.settingsControlMacros.macrosHighlightRow )
-	macro.text = text
-	AJM:SettingsMacrosScrollRefresh()
-end
-
-function AJM:SettingsKeyBindingChangedMacroKey( event, key )
-	local macro = AJM:GetMacroAtPosition( AJM.settingsControlMacros.macrosHighlightRow )
-	macro.key = key
-	AJM:SettingsMacrosScrollRefresh()
-end
-
-function AJM:SettingsVariableSetsAddClick( event )
-	StaticPopup_Show( "JAMBAMACRO_ASK_VARIABLE_SET_NAME" )
-end
-
-function AJM:SettingsVariableSetsRemoveClick( event )
-	local variableSet = AJM:GetVariableSetAtPosition( AJM.settingsControlVariables.variableSetsHighlightRow )
-	StaticPopup_Show( "JAMBAMACRO_CONFIRM_REMOVE_VARIABLE_SET", variableSet.name )
-end
-
-function AJM:SettingsVariableSetsCopyClick( event )
-	StaticPopup_Show( "JAMBAMACRO_ASK_VARIABLE_SET_COPY_NAME" )
-end
-
-function AJM:SettingsVariablesAddClick( event )
-	StaticPopup_Show( "JAMBAMACRO_ASK_VARIABLE_NAME" )
-end
-
-function AJM:SettingsVariablesRemoveClick( event )
-	local variable = AJM:GetVariableAtPosition( AJM.settingsControlVariables.variablesHighlightRow )
-	StaticPopup_Show( "JAMBAMACRO_CONFIRM_REMOVE_VARIABLE", variable.name )
-end
-
-function AJM:SettingsMacroSetsAddClick( event )
-	StaticPopup_Show( "JAMBAMACRO_ASK_MACRO_SET_NAME" )
-end
-
-function AJM:SettingsMacroSetsRemoveClick( event )
-	local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControlMacros.macroSetsHighlightRow )
-	StaticPopup_Show( "JAMBAMACRO_CONFIRM_REMOVE_MACRO_SET", macroSet.name )
-end
-
-function AJM:SettingsMacroSetsCopyClick( event )
-	StaticPopup_Show( "JAMBAMACRO_ASK_MACRO_SET_COPY_NAME" )
-end
-
-function AJM:SettingsMacrosAddClick( event )
-	StaticPopup_Show( "JAMBAMACRO_ASK_MACRO_NAME" )
-end
-
-function AJM:SettingsMacrosRemoveClick( event )
-	local macro = AJM:GetMacroAtPosition( AJM.settingsControlMacros.macrosHighlightRow )
-	StaticPopup_Show( "JAMBAMACRO_CONFIRM_REMOVE_MACRO", macro.name )
-end
-
-function AJM:SettingsMacroControlEnableClick( event )
-	local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControl.macroControlHighlightRow )
-	macroSet.enabled = true
-	AJM:SettingsMacroControlScrollRefresh()
-end
-
-function AJM:SettingsMacroControlDisableClick( event )
-	local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControl.macroControlHighlightRow )
-	macroSet.enabled = false
-	AJM:SettingsMacroControlScrollRefresh()
-end
-
-function AJM:SettingsEditBoxChangedMacroControlVariableSet( event, text )
-	local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControl.macroControlHighlightRow )
-	macroSet.variableSet = text
-	AJM:SettingsMacroControlScrollRefresh()
-end
-
-function AJM:SettingsEditBoxChangedMacroControlTag( event, text )
-	local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControl.macroControlHighlightRow )
-	macroSet.tag = text
-	AJM:SettingsMacroControlScrollRefresh()
-end
-
---[[
-function AJM:SettingsVariableSetsUseClick( event )
-	local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControlMacros.macroSetsHighlightRow )
-	local variableSet = AJM:GetVariableSetAtPosition( AJM.settingsControlVariables.variableSetsHighlightRow )
-	AJM:UpdateInternalMacros( macroSet, variableSet, false )
-end
-]]--
-
---[[
-function AJM:SettingsMacroSetsUseClick( event )
-	local macroSet = AJM:GetMacroSetAtPosition( AJM.settingsControlMacros.macroSetsHighlightRow )
-	local variableSet = AJM:GetVariableSetAtPosition( AJM.settingsControlVariables.variableSetsHighlightRow )
-	AJM:UpdateInternalMacros( macroSet, variableSet, false )
-end
-]]--
-
-function AJM:SettingsMacroControlBuildMacrosClick( event )
-	AJM:JambaSendCommandToTeam( AJM.COMMAND_MACROSET_USE )
-	-- Sort this out.
-	--AJM:UpdateMacrosUseSetCommandAction( false )
-end
-
-function AJM:UpdateMacrosUseSetCommandReceive()
-	AJM:UpdateMacrosUseSetCommandAction( false )
-end
-
-function AJM:UpdateMacrosUseSetCommandAction( silent )
-	-- Iterate all the macro sets and remove keybindings.
-	for index, macroSet in ipairs( AJM.db.macroSets ) do
-		AJM:ClearMacroSetKeyBindings( macroSet.name )
-	end
-	-- Iterate all the enabled macro sets.
-	-- Check that the toon has the tag for the macro set.  If so, use that macro set.
-	local variableSetName
-	local variableSet
-	for index, macroSet in ipairs( AJM.db.macroSets ) do
-		-- Macro set enabled?
-		if macroSet.enabled == true then
-			-- Character has macro set tag?
-			if JambaApi.DoesCharacterHaveTag( AJM.characterName, macroSet.tag ) == true then
-				-- Variable set exists?
-				variableSetName = macroSet.variableSet
-				if variableSetName ~= nil and variableSetName:trim() ~= "" then
-					variableSet = AJM:GetVariableSetByName( variableSetName )
-					if variableSet == nil then
-						AJM:Print( L["Can not find variable set: X"]( variableSetName ) )
-					else
-						-- Lets go make macros!
-						AJM:UpdateInternalMacros( macroSet, variableSet, silent )
-					end
-				else
-					AJM:Print( L["Can not find variable set: X"]( "" ) )
-				end
-
-			end
-		end
-	end
-end
-
-function AJM:UpdateMacrosUseSetCommand( info, parameters )
-	AJM:JambaSendCommandToTeam( AJM.COMMAND_MACROSET_USE )
-end
-
-function AJM:SubstituteVariablesAndTagsForValues( originalMacroText, variables )
-	local macroText = originalMacroText
-	-- Substitute tags.
-	for index, tag in JambaApi.AllTagsListIterator() do
-		local characterName = JambaApi.GetCharacterWithTag( tag )
-		if characterName ~= "" then
-			-- 4.0 tag fix ebony realm name to add if from same server.
-			--macroText = macroText:gsub( "#"..tag.."#", characterName )
-			macroText = macroText:gsub( "#"..tag.."#", ( Ambiguate( characterName, "none" ) ) )
-		end
-	end
-	-- Substitute variables.
-	for position, variable in pairs( variables ) do
-		-- Check to see if this variable is to be used if the character has a tag
-		-- or if the character does not have a tag (tag prefixed by !).
-		local tag = variable.tag
-		local hasTag = true
-		if tag:sub( 1, 1 ) == "!" then
-			tag = tag:sub( 2 )
-			hasTag = false
-		end
-		if JambaApi.DoesCharacterHaveTag( AJM.characterName, tag ) == hasTag then
-			macroText = macroText:gsub( "#"..variable.name.."#", variable.value )
-		end
-	end
-	return macroText
-end
-
-function AJM:ClearMacroKeyBinding( macroSetName, macroName )
-	local frameKey = macroSetName..macroName
-	if AJM.macroFrames[frameKey] ~= nil then
-		ClearOverrideBindings( AJM.macroFrames[frameKey] )
-		AJM.macroFrames[frameKey]:SetAttribute( "macrotext", "" )
-	end
-end
-
-function AJM:ClearMacroSetKeyBindings( macroSetName )
-	local macroSetToClear = AJM:GetMacroSetByName( macroSetName )
-	if macroSetToClear ~= nil then
-		for positionToClear, macroToClear in pairs( macroSetToClear.macros ) do
-			local frameKeyToClear = macroSetToClear.name..macroToClear.name
-			if AJM.macroFrames[frameKeyToClear] ~= nil then
-				ClearOverrideBindings( AJM.macroFrames[frameKeyToClear] )
-				AJM.macroFrames[frameKeyToClear]:SetAttribute( "macrotext", "" )
-			end
-		end
-	end
-end
-
---[[
-function AJM:UpdateCurrentMacroSet( silent )
-	local variableSet = AJM:GetVariableSetByName( AJM.db.currentVariableSetName )
-	local macroSet = AJM:GetMacroSetByName( AJM.db.currentMacroSetName )
-	if macroSet ~= nil and variableSet ~= nil then
-		AJM:UpdateInternalMacros( macroSet, variableSet, silent )
-	end
-end
-]]--
-
-function AJM:UpdateInternalMacros( macroSet, variableSet, silent )
-	if macroSet == nil then
-		if silent == false then
-			AJM:Print( L["Please choose a macro set to use."] )
-		end
-		return
-	end
-	if variableSet == nil then
-		if silent == false then
-			AJM:Print( L["Please choose a variable set to use."] )
-		end
-		return
-	end
-	if silent == false then
-		AJM:Print( L["Using macros set: X"]( macroSet.name ) )
-		AJM:Print( L["Using variables set: X"]( variableSet.name ) )
-	end
-	AJM.db.currentVariableSetName = variableSet.name
-	AJM.db.currentMacroSetName = macroSet.name
-	if InCombatLockdown() then
-		AJM:Print( L["In combat, waiting until after combat to update the macros."] )
-		AJM.pendingMacroUpdate = true
-		return
-	end
-	--[[
-	-- Clear the previous macros.
-	AJM:ClearMacroSetKeyBindings( AJM.previousMacroSetName )
-	AJM.previousMacroSetName = macroSet.name
-	]]--
-	-- Create a new set of macros based on this macro set.
-	for position, macro in pairs( macroSet.macros ) do
-		-- Check to see if this is macro is to be used if the character has a tag
-		-- or if the character does not have a tag (tag prefixed by !).
-		local tag = macro.tag
-		local hasTag = true
-		if tag:sub( 1, 1 ) == "!" then
-			tag = tag:sub( 2 )
-			hasTag = false
-		end
-		if JambaApi.DoesCharacterHaveTag( AJM.characterName, tag ) == hasTag then
-			local macroText = AJM:SubstituteVariablesAndTagsForValues( macro.text, variableSet.variables )
-			local frameKey = macroSet.name..macro.name
-			if AJM.macroFrames[frameKey] == nil then
-				AJM.macroFrames[frameKey] = CreateFrame( "Button", "JMB_"..macro.name, nil, "SecureActionButtonTemplate" )
-			end
-			-- Set the macro text and key binding.
-			AJM.macroFrames[frameKey]:SetAttribute( "type", "macro" )
-			AJM.macroFrames[frameKey]:SetAttribute( "macrotext", macroText )
-			SetOverrideBindingClick( AJM.macroFrames[frameKey], true, macro.key, AJM.macroFrames[frameKey]:GetName() )
-			-- Show the player.
-			if silent == false then
-				AJM:Print( macro.name, macro.key )
-				AJM:Print( macroText )
-			end
-		end
-	end
-end
-
-function AJM:SettingsMacrosShowClick( event )
-	local macro = AJM:GetMacroAtPosition( AJM.settingsControlMacros.macrosHighlightRow )
-	local variableSet = AJM:GetVariableSetAtPosition( AJM.settingsControlVariables.variableSetsHighlightRow )
-	local macroText = AJM:SubstituteVariablesAndTagsForValues( macro.text, variableSet.variables )
-	AJM:Print( macro.name, macro.key )
-	AJM:Print( macroText )
-end
-
---[[
--------------------------------------------------------------------------------------------------------------
--- Frame storage.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:GetMacroFrame()
-	local freeFrameAtIndex = #AJM.storedMacroFrames
-	local frame = nil
-	if freeFrameAtIndex == 0 then
-		AJM.frameCount = AJM.frameCount + 1
-		frame = CreateFrame( "Button", "JambaMacroFrame"..AJM.frameCount, nil, "SecureActionButtonTemplate" )
-		frame:SetAttribute( "type", "macro" )
-		frame:SetAttribute( "macrotext", "" )
-	else
-		frame = table.remove( AJM.storedMacroFrames, freeFrameAtIndex )
-	end
-	return frame
-end
-
-function AJM:FreeMacroFrame( frame )
-	-- Clean the frame by removing the key bindings and macro text.
-	ClearOverrideBindings( frame )
-	frame:SetAttribute( "macrotext", "" )
-	table.insert( AJM.storedMacroFrames, frame )
-end
-]]--
-
--------------------------------------------------------------------------------------------------------------
--- Popup Dialogs.
--------------------------------------------------------------------------------------------------------------
-
--- Initialize Popup Dialogs.
-local function InitializePopupDialogs()
-   StaticPopupDialogs["JAMBAMACRO_ASK_VARIABLE_SET_NAME"] = {
-        text = L["Enter name for this SET of variables:"],
-        button1 = ACCEPT,
-        button2 = CANCEL,
-        hasEditBox = 1,
-        timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1,
-		OnShow = function( self )
-			self.editBox:SetText("")
-            self.button1:Disable()
-            self.editBox:SetFocus()
-        end,
-		OnAccept = function( self )
-			AJM:AddVariableSetGUI( self.editBox:GetText() )
-		end,
-        EditBoxOnTextChanged = function( self )
-            if not self:GetText() or self:GetText():trim() == "" or self:GetText():find( "%W" ) ~= nil then
-				self:GetParent().button1:Disable()
-            else
-                self:GetParent().button1:Enable()
-            end
-        end,
-		EditBoxOnEnterPressed = function( self )
-            if self:GetParent().button1:IsEnabled() then
-				AJM:AddVariableSetGUI( self:GetText() )
-            end
-            self:GetParent():Hide()
-        end,
-    }
-   StaticPopupDialogs["JAMBAMACRO_CONFIRM_REMOVE_VARIABLE_SET"] = {
-        text = L['Are you sure you wish to remove "%s" from the variable SET list?'],
-        button1 = YES,
-        button2 = NO,
-        timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1,
-        OnAccept = function( self )
-			AJM:RemoveVariableSetGUI()
-		end,
-    }
-   StaticPopupDialogs["JAMBAMACRO_ASK_VARIABLE_NAME"] = {
-        text = L["Enter name for this variable:"],
-        button1 = ACCEPT,
-        button2 = CANCEL,
-        hasEditBox = 1,
-        timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1,
-		OnShow = function( self )
-			self.editBox:SetText("")
-            self.button1:Disable()
-            self.editBox:SetFocus()
-        end,
-		OnAccept = function( self )
-			AJM:AddVariableGUI( self.editBox:GetText() )
-		end,
-        EditBoxOnTextChanged = function( self )
-            if not self:GetText() or self:GetText():trim() == "" or self:GetText():find( "%W" ) ~= nil then
-				self:GetParent().button1:Disable()
-            else
-                self:GetParent().button1:Enable()
-            end
-        end,
-		EditBoxOnEnterPressed = function( self )
-            if self:GetParent().button1:IsEnabled() then
-				AJM:AddVariableGUI( self:GetText() )
-            end
-            self:GetParent():Hide()
-        end,
-    }
-   StaticPopupDialogs["JAMBAMACRO_CONFIRM_REMOVE_VARIABLE"] = {
-        text = L['Are you sure you wish to remove "%s" from the variable list?'],
-        button1 = YES,
-        button2 = NO,
-        timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1,
-        OnAccept = function( self )
-			AJM:RemoveVariableGUI()
-		end,
-    }
-	StaticPopupDialogs["JAMBAMACRO_ASK_MACRO_SET_NAME"] = {
-        text = L["Enter name for this SET of macros:"],
-        button1 = ACCEPT,
-        button2 = CANCEL,
-        hasEditBox = 1,
-        timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1,
-		OnShow = function( self )
-			self.editBox:SetText("")
-            self.button1:Disable()
-            self.editBox:SetFocus()
-        end,
-		OnAccept = function( self )
-			AJM:AddMacroSetGUI( self.editBox:GetText() )
-		end,
-        EditBoxOnTextChanged = function( self )
-            if not self:GetText() or self:GetText():trim() == "" or self:GetText():find( "%W" ) ~= nil then
-				self:GetParent().button1:Disable()
-            else
-                self:GetParent().button1:Enable()
-            end
-        end,
-		EditBoxOnEnterPressed = function( self )
-            if self:GetParent().button1:IsEnabled() then
-				AJM:AddMacroSetGUI( self:GetText() )
-            end
-            self:GetParent():Hide()
-        end,
-    }
-   StaticPopupDialogs["JAMBAMACRO_CONFIRM_REMOVE_MACRO_SET"] = {
-        text = L['Are you sure you wish to remove "%s" from the macro SET list?'],
-        button1 = YES,
-        button2 = NO,
-        timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1,
-        OnAccept = function( self )
-			AJM:RemoveMacroSetGUI()
-		end,
-    }
-   StaticPopupDialogs["JAMBAMACRO_ASK_MACRO_NAME"] = {
-        text = L["Enter name for this macro:"],
-        button1 = ACCEPT,
-        button2 = CANCEL,
-        hasEditBox = 1,
-        timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1,
-		OnShow = function( self )
-			self.editBox:SetText("")
-            self.button1:Disable()
-            self.editBox:SetFocus()
-        end,
-		OnAccept = function( self )
-			AJM:AddMacroGUI( self.editBox:GetText() )
-		end,
-        EditBoxOnTextChanged = function( self )
-            if not self:GetText() or self:GetText():trim() == "" or self:GetText():find( "%W" ) ~= nil then
-				self:GetParent().button1:Disable()
-            else
-                self:GetParent().button1:Enable()
-            end
-        end,
-		EditBoxOnEnterPressed = function( self )
-            if self:GetParent().button1:IsEnabled() then
-				AJM:AddMacroGUI( self:GetText() )
-            end
-            self:GetParent():Hide()
-        end,
-    }
-   StaticPopupDialogs["JAMBAMACRO_CONFIRM_REMOVE_MACRO"] = {
-        text = L['Are you sure you wish to remove "%s" from the macro list?'],
-        button1 = YES,
-        button2 = NO,
-        timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1,
-        OnAccept = function( self )
-			AJM:RemoveMacroGUI()
-		end,
-    }
-   StaticPopupDialogs["JAMBAMACRO_ASK_VARIABLE_SET_COPY_NAME"] = {
-        text = L["Enter name for the copy of this SET of variables:"],
-        button1 = ACCEPT,
-        button2 = CANCEL,
-        hasEditBox = 1,
-        timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1,
-		OnShow = function( self )
-			self.editBox:SetText("")
-            self.button1:Disable()
-            self.editBox:SetFocus()
-        end,
-		OnAccept = function( self )
-			AJM:CopyVariableSetGUI( self.editBox:GetText() )
-		end,
-        EditBoxOnTextChanged = function( self )
-            if not self:GetText() or self:GetText():trim() == "" or self:GetText():find( "%W" ) ~= nil then
-				self:GetParent().button1:Disable()
-            else
-                self:GetParent().button1:Enable()
-            end
-        end,
-		EditBoxOnEnterPressed = function( self )
-            if self:GetParent().button1:IsEnabled() then
-				AJM:CopyVariableSetGUI( self:GetText() )
-            end
-            self:GetParent():Hide()
-        end,
-    }
-   StaticPopupDialogs["JAMBAMACRO_ASK_MACRO_SET_COPY_NAME"] = {
-        text = L["Enter name for the copy of this SET of macros:"],
-        button1 = ACCEPT,
-        button2 = CANCEL,
-        hasEditBox = 1,
-        timeout = 0,
-		whileDead = 1,
-		hideOnEscape = 1,
-		OnShow = function( self )
-			self.editBox:SetText("")
-            self.button1:Disable()
-            self.editBox:SetFocus()
-        end,
-		OnAccept = function( self )
-			AJM:CopyMacroSetGUI( self.editBox:GetText() )
-		end,
-        EditBoxOnTextChanged = function( self )
-            if not self:GetText() or self:GetText():trim() == "" or self:GetText():find( "%W" ) ~= nil then
-				self:GetParent().button1:Disable()
-            else
-                self:GetParent().button1:Enable()
-            end
-        end,
-		EditBoxOnEnterPressed = function( self )
-            if self:GetParent().button1:IsEnabled() then
-				AJM:CopyMacroSetGUI( self:GetText() )
-            end
-            self:GetParent():Hide()
-        end,
-    }
-end
-
--------------------------------------------------------------------------------------------------------------
--- Addon initialization, enabling and disabling.
--------------------------------------------------------------------------------------------------------------
-
--- Initialise the module.
-function AJM:OnInitialize()
-	-- Create the settings control.
-	SettingsCreate()
-	-- Initialise the JambaModule part of this module.
-	AJM:JambaModuleInitialize( AJM.settingsControlVariables.widgetSettings.frame )
-	-- Populate the settings.
-	AJM:SettingsRefresh()
-	-- Initialise the popup dialogs.
-	InitializePopupDialogs()
-	-- Click the first row, column to set the child controls on the lists.
-	AJM:SettingsMacroControlRowClick( 1, 1 )
-	AJM:SettingsVariableSetsRowClick( 1, 1 )
-	AJM:SettingsMacroSetsRowClick( 1, 1 )
-	-- Clear existing macro frames.
-	AJM:ClearMacroFrames()
-	-- Update the macros.
-	AJM:UpdateMacrosUseSetCommandAction( true )
-end
-
--- Called when the addon is enabled.
-function AJM:OnEnable()
-	AJM:RegisterEvent( "PLAYER_REGEN_ENABLED" )
-end
-
--- Called when the addon is disabled.
-function AJM:OnDisable()
-end
-
-function AJM:PLAYER_REGEN_ENABLED()
-	if AJM.pendingMacroUpdate == true then
-		AJM.pendingMacroUpdate = false
-		AJM:UpdateMacrosUseSetCommandAction( false )
-	end
-end
-
--- A Jamba command has been recieved.
-function AJM:JambaOnCommandReceived( characterName, commandName, ... )
-	if commandName == AJM.COMMAND_MACROSET_USE then
-		AJM:UpdateMacrosUseSetCommandReceive( ... )
-	end
-end
diff --git a/Jamba-Macro/Locales/Jamba-Macro-Locale-enUS.lua b/Jamba-Macro/Locales/Jamba-Macro-Locale-enUS.lua
deleted file mode 100644
index a30a082..0000000
--- a/Jamba-Macro/Locales/Jamba-Macro-Locale-enUS.lua
+++ /dev/null
@@ -1,75 +0,0 @@
---[[
-Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
-License: The MIT License
-]]--
-
-local L = LibStub("AceLocale-3.0"):NewLocale( "Jamba-Macro", "enUS", true )
-L["Slash Commands"] = true
-L["Macro"] = true
-L["Push Settings"] = true
-L["Push the macro settings to all characters in the team."] = true
-L["Settings received from A."] = function( characterName )
-	return string.format( "Settings received from %s.", characterName )
-end
-L["Use"] = true
-L["Add"] = true
-L["Remove"] = true
-L["Copy"] = true
-L["Show"] = true
-L["Variable Sets"] = true
-L["Variables"] = true
-L["Macro Sets"] = true
-L["Macros"] = true
-L["Edit Variable"] = true
-L["Variable Name"] = true
-L["Variable Value"] = true
-L["Variable Tag (prefix ! for not this tag)"] = true
-L["Edit Macro"] = true
-L["Macro Name"] = true
-L["Macro Text"] = true
-L["Macro Key"] = true
-L["Macro Tag (prefix ! for not this tag)"] = true
-L["Macro: Macros"] = true
-L["Macro: Variables"] = true
-L["Macro Sets Control"] = true
-L["Enable"] = true
-L["Disable"] = true
-L["Configure Macro Set"] = true
-L["Variable Set"] = true
-L["Tag"] = true
-L["On"] = true
-L["Off"] = true
-L["Build Macros (Team)"] = true
-L["Enter name for this SET of variables:"] = true
-L['Are you sure you wish to remove "%s" from the variable SET list?'] = true
-L["Enter name for this variable:"] = true
-L['Are you sure you wish to remove "%s" from the variable list?'] = true
-L["Enter name for this SET of macros:"] = true
-L['Are you sure you wish to remove "%s" from the macro SET list?'] = true
-L["Enter name for this macro:"] = true
-L['Are you sure you wish to remove "%s" from the macro list?'] = true
-L["Enter name for the copy of this SET of variables:"] = true
-L["Enter name for the copy of this SET of macros:"] = true
-L["/click JMB_"] = true
-L["Macro Usage - press key assigned or copy /click below."] = true
-L["Use Macro and Variable Set"] = true
-L["Update the macros to use the specified macro and variable sets."] = true
-L["Can not find macro set: X"] = function( macroSetName )
-	return string.format( "Can not find macro set: %s", macroSetName )
-end
-L["Can not find variable set: X"] = function( variableSetName )
-	return string.format( "Can not find variable set: %s", variableSetName )
-end
-L["Variable names must only be made up of letters and numbers."] = true
-L["Macro names must only be made up of letters and numbers."] = true
-L["Macro tags must only be made up of letters and numbers."] = true
-L["Please choose a macro set to use."] = true
-L["Please choose a variable set to use."] = true
-L["Using macros set: X"] = function( macroSetName )
-	return string.format( "Using macros set: %s", macroSetName )
-end
-L["Using variables set: X"] = function( variableSetName )
-	return string.format( "Using variables set: %s", variableSetName )
-end
-L["In combat, waiting until after combat to update the macros."] = true
diff --git a/Jamba-Macro/Locales/Locales.xml b/Jamba-Macro/Locales/Locales.xml
deleted file mode 100644
index 079efe2..0000000
--- a/Jamba-Macro/Locales/Locales.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<!--
-Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
-License: The MIT License
--->
-
-<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd" xmlns="http://www.blizzard.com/wow/ui/">
-	<Script file="Jamba-Macro-Locale-enUS.lua" />
-</Ui>
diff --git a/Jamba-Mount/Jamba-Mount.toc b/Jamba-Mount/Jamba-Mount.toc
index 70e6ae2..21d9a6c 100644
--- a/Jamba-Mount/Jamba-Mount.toc
+++ b/Jamba-Mount/Jamba-Mount.toc
@@ -2,7 +2,7 @@
 ## Title: Jamba-Mount
 ## Notes: Jamba-Mount
 ## Author: Ebony
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Mount/JambaMount.lua b/Jamba-Mount/JambaMount.lua
index d141145..cb63e02 100644
--- a/Jamba-Mount/JambaMount.lua
+++ b/Jamba-Mount/JambaMount.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License

 This is was made by Ebony with the idea from Hydra
@@ -367,28 +367,34 @@ function AJM:TeamMount(characterName, name, mountID)
 	--Do i have the same mount as master?
 	hasMount = false
 	local creatureName, spellID, icon, active, isUsable, sourceType, isFavorite, isFactionSpecific, faction, hideOnChar, isCollected, mountID = C_MountJournal.GetMountInfoByID(mountID)
+	local x_creatureDisplayID, x_descriptionText, x_sourceText, x_isSelfMount, x_mountTypeID, x_uiModelSceneID = C_MountJournal.GetMountInfoExtraByID(mountID)
 	if isUsable == true then
 		--AJM:Print("i have this Mount", creatureName)
 		hasMount = true
 		mount = mountID
 	else
-		--AJM:Print("i Do not have Mount", creatureName)
+		--AJM:Print("i DO NOT have Mount", creatureName)
 		for i = 1, C_MountJournal.GetNumMounts() do
-		local creatureName, spellID, icon, active, isUsable, sourceType, isFavorite, isFactionSpecific, faction, hideOnChar, isCollected, mountID = C_MountJournal.GetMountInfoByID(i)
+			local creatureName, spellID, icon, active, isUsable, sourceType, isFavorite, isFactionSpecific, faction, hideOnChar, isCollected,   mountID = C_MountJournal.GetMountInfoByID(i)
 			--AJM:Print("looking for a mount i can use", i)
 			if isUsable == true then
-				mount = mountID
-				hasMount = true
-				break
+				local creatureDisplayID, descriptionText, sourceText, isSelfMount, mountTypeID, uiModelSceneID = C_MountJournal.GetMountInfoExtraByID(mountID)
+				-- AJM:Print("looking for a mount i can use of type", x_mountTypeID, mountTypeID, i, creatureName, spellID)
+				-- mount a similar type of mount, e.g. if mounting a flying mount, also mount a flying mount
+				if x_mountTypeID == mountTypeID then
+					mount = mountID
+					hasMount = true
+					break
+				end
 			end
 		end
 	end

---AJM:Print("test1420", mount, name)
+	--AJM:Print("test1420", mount, name)
 	-- for unsupported mounts.
 	if hasMount == true then
 		--AJM:Print("test14550", mount, name )
-		if name == "Random" then
+		if name == "Random" then  -- name doesn't seem to be set anywhere...
 			C_MountJournal.SummonByID(0)
 		else
 			--AJM:Print("test1054" )
diff --git a/Jamba-Mount/Locales/JambaMount-Locale-enUS.lua b/Jamba-Mount/Locales/JambaMount-Locale-enUS.lua
index f225e7e..2b58ac2 100644
--- a/Jamba-Mount/Locales/JambaMount-Locale-enUS.lua
+++ b/Jamba-Mount/Locales/JambaMount-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Mount/Locales/Locales.xml b/Jamba-Mount/Locales/Locales.xml
index 828b3fa..59e8fa6 100644
--- a/Jamba-Mount/Locales/Locales.xml
+++ b/Jamba-Mount/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-Purchase/Jamba-Purchase.toc b/Jamba-Purchase/Jamba-Purchase.toc
index 266def3..34e7aec 100644
--- a/Jamba-Purchase/Jamba-Purchase.toc
+++ b/Jamba-Purchase/Jamba-Purchase.toc
@@ -2,7 +2,7 @@
 ## Title: Jamba-Purchase
 ## Notes: Jamba-Purchase
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Purchase/JambaPurchase.lua b/Jamba-Purchase/JambaPurchase.lua
index 569c4ec..f0913b4 100644
--- a/Jamba-Purchase/JambaPurchase.lua
+++ b/Jamba-Purchase/JambaPurchase.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Purchase/Locales/JambaPurchase-Locale-enUS.lua b/Jamba-Purchase/Locales/JambaPurchase-Locale-enUS.lua
index 6528163..f05cc5b 100644
--- a/Jamba-Purchase/Locales/JambaPurchase-Locale-enUS.lua
+++ b/Jamba-Purchase/Locales/JambaPurchase-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Purchase/Locales/Locales.xml b/Jamba-Purchase/Locales/Locales.xml
index 072ec06..d8840c1 100644
--- a/Jamba-Purchase/Locales/Locales.xml
+++ b/Jamba-Purchase/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-Quest/Jamba-Quest.toc b/Jamba-Quest/Jamba-Quest.toc
index 903e1c5..6e2d511 100644
--- a/Jamba-Quest/Jamba-Quest.toc
+++ b/Jamba-Quest/Jamba-Quest.toc
@@ -2,7 +2,7 @@
 ## Title: JambaQuest
 ## Notes: JambaQuest
 ## Author: Ebony, DropDownchanges by Schilm, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Quest/JambaQuest.lua b/Jamba-Quest/JambaQuest.lua
index aa9e687..e54760c 100644
--- a/Jamba-Quest/JambaQuest.lua
+++ b/Jamba-Quest/JambaQuest.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba -- Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 --]]

diff --git a/Jamba-Quest/Locales/JambaQuest-Locale-enUS.lua b/Jamba-Quest/Locales/JambaQuest-Locale-enUS.lua
index b310a4c..5774296 100644
--- a/Jamba-Quest/Locales/JambaQuest-Locale-enUS.lua
+++ b/Jamba-Quest/Locales/JambaQuest-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba -- Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Quest/Locales/Locales.xml b/Jamba-Quest/Locales/Locales.xml
index f632b18..f10595e 100644
--- a/Jamba-Quest/Locales/Locales.xml
+++ b/Jamba-Quest/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-QuestWatcher/Jamba-QuestWatcher.toc b/Jamba-QuestWatcher/Jamba-QuestWatcher.toc
index c3f79e4..e48dc01 100644
--- a/Jamba-QuestWatcher/Jamba-QuestWatcher.toc
+++ b/Jamba-QuestWatcher/Jamba-QuestWatcher.toc
@@ -2,7 +2,7 @@
 ## Title: JambaQuestWatcher
 ## Notes: JambaQuestWatcher
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-QuestWatcher/JambaQuestWatcher.lua b/Jamba-QuestWatcher/JambaQuestWatcher.lua
index 88d5737..2b75027 100644
--- a/Jamba-QuestWatcher/JambaQuestWatcher.lua
+++ b/Jamba-QuestWatcher/JambaQuestWatcher.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-QuestWatcher/Locales/JambaQuestWatcher-Locale-enUS.lua b/Jamba-QuestWatcher/Locales/JambaQuestWatcher-Locale-enUS.lua
index 520d0d2..6196e39 100644
--- a/Jamba-QuestWatcher/Locales/JambaQuestWatcher-Locale-enUS.lua
+++ b/Jamba-QuestWatcher/Locales/JambaQuestWatcher-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-QuestWatcher/Locales/Locales.xml b/Jamba-QuestWatcher/Locales/Locales.xml
index 13afb9d..58aa96a 100644
--- a/Jamba-QuestWatcher/Locales/Locales.xml
+++ b/Jamba-QuestWatcher/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-Sell/Jamba-Sell.toc b/Jamba-Sell/Jamba-Sell.toc
index b68ca66..ae17869 100644
--- a/Jamba-Sell/Jamba-Sell.toc
+++ b/Jamba-Sell/Jamba-Sell.toc
@@ -2,7 +2,7 @@
 ## Title: JambaSell
 ## Notes: JambaSell
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Sell/JambaSell.lua b/Jamba-Sell/JambaSell.lua
index 39ff131..257867a 100644
--- a/Jamba-Sell/JambaSell.lua
+++ b/Jamba-Sell/JambaSell.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

@@ -936,17 +936,26 @@ function AJM:DoSellItem( itemlink )
 		numSlots = GetContainerNumSlots( bag )
 		for slot = 1, numSlots do
 			-- Get the item link for the item in this slot.
-			local bagItemLink = GetContainerItemLink( bag, slot )
+		--	local bagItemLink = GetContainerItemLink( bag, slot )
+			local _, _, locked, _, _, _, bagItemLink, _, hasNoValue = GetContainerItemInfo(bag, slot)
 			-- If there is an item...
 			if bagItemLink ~= nil then
 				-- Does it match the item to sell?
 				if JambaUtilities:DoItemLinksContainTheSameItem( bagItemLink, itemlink ) then
 					-- Yes, sell this item.
-					if MerchantFrame:IsVisible() == true then
-						UseContainerItem( bag, slot )
-					end
-					-- Tell the boss.
-					AJM:JambaSendMessageToTeam( AJM.db.messageArea, L["I have sold: X"]( bagItemLink ), false )
+					if 	hasNoValue == false then
+						if MerchantFrame:IsVisible() == true then
+							UseContainerItem( bag, slot )
+							-- Tell the boss.
+							AJM:JambaSendMessageToTeam( AJM.db.messageArea, L["I have sold: X"]( bagItemLink ), false )
+						end
+					else
+						if 	locked == false then
+							PickupContainerItem(bag,slot)
+							DeleteCursorItem()
+							AJM:JambaSendMessageToTeam( AJM.db.messageArea, L["I have deleted: X"]( bagItemLink ), false )
+						end
+					end
 				end
 			end
 		end
@@ -1056,6 +1065,7 @@ function AJM:DoMerchantSellItems()
 			if link ~= nil then
 			local canSell = false
 			local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, iconFileDataID, itemSellPrice = GetItemInfo( link )
+			local _, itemCount = GetContainerItemInfo( bag, slot )
 			--AJM:Print("Test", itemLink, itemRarity )
 				if AJM.db.autoSellPoor == true then
 					if itemRarity == AJM.ITEM_QUALITY_POOR then
@@ -1072,13 +1082,15 @@ function AJM:DoMerchantSellItems()
 				-- Green
 				if AJM.db.autoSellUncommon == true then
 					if itemRarity == AJM.ITEM_QUALITY_UNCOMMON then
-						if itemType == WEAPON or itemType == ARMOR then
+						if itemType == WEAPON or itemType == ARMOR or itemSubType == EJ_LOOT_SLOT_FILTER_ARTIFACT_RELIC then
 							--AJM:Print("testGreen", link, itemRarity, "a", AJM.ITEM_QUALITY_UNCOMMON )
 							local num = tonumber( AJM.db.autoSellIlvlUncommon )
 							local iLvl = ItemUpgradeInfo:GetUpgradedItemLevel(link)
-							--AJM:Print("test", iLvl, "vs", num, "item", link )
-							if num ~= nil and iLvl ~= nil and (itemLevel > AJM.MIN_ITEM_LEVEL ) then
-								if iLvl >= num then
+							--AJM:Print("test", num , "vs", iLvl, "item", link )
+							if num ~= nil and iLvl ~= nil and ( itemLevel > AJM.MIN_ITEM_LEVEL ) then
+								--if iLvl >= num then
+								if num >= iLvl then
+									--AJM:Print("ture", link )
 									canSell = true
 								end
 							end
@@ -1095,12 +1107,12 @@ function AJM:DoMerchantSellItems()
 					--Blue
 					if AJM.db.autoSellRare == true then
 						if itemRarity == AJM.ITEM_QUALITY_RARE then
-							if itemType == WEAPON or itemType == ARMOR then
+							if itemType == WEAPON or itemType == ARMOR or itemSubType == EJ_LOOT_SLOT_FILTER_ARTIFACT_RELIC then
 								local num = tonumber( AJM.db.autoSellIlvlRare )
 								local iLvl = ItemUpgradeInfo:GetUpgradedItemLevel(link)
 								--AJM:Print("test", iLvl, "vs", num )
 								if num ~= nil and iLvl ~= nil and (itemLevel > AJM.MIN_ITEM_LEVEL ) then
-									if iLvl >= num then
+									if num >= iLvl then
 										canSell = true
 									end
 								end
@@ -1117,12 +1129,12 @@ function AJM:DoMerchantSellItems()
 					-- Epic
 					if AJM.db.autoSellEpic == true then
 						if itemRarity == AJM.ITEM_QUALITY_EPIC then
-							if itemType == WEAPON or itemType == ARMOR then
+							if itemType == WEAPON or itemType == ARMOR or itemSubType == EJ_LOOT_SLOT_FILTER_ARTIFACT_RELIC then
 								local num = tonumber( AJM.db.autoSellIlvlEpic )
 								local iLvl = ItemUpgradeInfo:GetUpgradedItemLevel(link)
 								--AJM:Print("test", iLvl, "vs", num )
-									if num ~= nil and iLvl ~= nil and (itemLevel > AJM.MIN_ITEM_LEVEL ) then
-									if iLvl >= num then
+								if num ~= nil and iLvl ~= nil and (itemLevel > AJM.MIN_ITEM_LEVEL ) then
+									if num >= iLvl then
 										canSell = true
 									end
 								end
@@ -1139,8 +1151,13 @@ function AJM:DoMerchantSellItems()
 					if canSell == true then
 						if itemSellPrice ~= nil and itemSellPrice > 0 then
 							if MerchantFrame:IsVisible() == true then
-								count = count + 1
-								gold = gold + itemSellPrice
+								if itemCount > 1 then
+									count = count + itemCount
+									gold = gold + itemSellPrice * itemCount
+								else
+									count = count + 1
+									gold = gold + itemSellPrice
+								end
 								UseContainerItem( bag, slot )
 							end
 						end
@@ -1280,16 +1297,24 @@ function AJM:DoMerchantSellOtherItems()
 				for slot = 1, GetContainerNumSlots( bag ) do
 					-- Get the item link for the item in this slot.
 					local bagItemLink = GetContainerItemLink( bag, slot )
+					local _, _, locked, _, _, _, bagItemLink, _, hasNoValue = GetContainerItemInfo(bag, slot)
 					-- If there is an item...
 					if bagItemLink ~= nil then
 						-- Does it match the item to sell?
 						if JambaUtilities:DoItemLinksContainTheSameItem( bagItemLink, itemInformation.link ) then
 							-- Yes, sell this item.
-							if MerchantFrame:IsVisible() == true then
-								UseContainerItem( bag, slot )
-								-- Tell the boss.
-								--AJM:JambaSendMessageToTeam( AJM.db.messageArea, L["I have sold: X"]( bagItemLink ), false )
-							end
+							if 	hasNoValue == false then
+								if MerchantFrame:IsVisible() == true then
+									UseContainerItem( bag, slot )
+									-- Tell the boss.
+									--AJM:JambaSendMessageToTeam( AJM.db.messageArea, L["I have sold: X"]( bagItemLink ), false )
+								end
+							else
+								if 	locked == false then
+									PickupContainerItem(bag,slot)
+									DeleteCursorItem()
+								end
+							end
 						end
 					end
 				end
diff --git a/Jamba-Sell/Locales/JambaSell-Locale-enUS.lua b/Jamba-Sell/Locales/JambaSell-Locale-enUS.lua
index 9b0f83f..358d5ca 100644
--- a/Jamba-Sell/Locales/JambaSell-Locale-enUS.lua
+++ b/Jamba-Sell/Locales/JambaSell-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

@@ -18,12 +18,16 @@ L["Are you sure you wish to remove the selected item from the auto sell other it
 L["I have sold: X"] = function( itemLink )
 	return string.format( "I have sold: %s", itemLink )
 end
+L["I have deleted: X"] = function( itemLink )
+	return string.format( "I have DELETED: %s", itemLink )
+end
 L["DID NOT SELL: X"] = function( itemLink )
 	return string.format( "DID NOT SELL: %s", itemLink )
 end
 L["I have sold: X Items And Made:"] = function( count )
 	return string.format( "I have sold: %s Items And Made: ", count )
 end
+
 L["Items"] = true
 L["Sell: Others"] = true
 --L["Sell Greys"] = true
diff --git a/Jamba-Sell/Locales/Locales.xml b/Jamba-Sell/Locales/Locales.xml
index de2c799..453da6d 100644
--- a/Jamba-Sell/Locales/Locales.xml
+++ b/Jamba-Sell/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-Talk/Jamba-Talk.toc b/Jamba-Talk/Jamba-Talk.toc
index d5907de..034a585 100644
--- a/Jamba-Talk/Jamba-Talk.toc
+++ b/Jamba-Talk/Jamba-Talk.toc
@@ -2,7 +2,7 @@
 ## Title: JambaTalk
 ## Notes: JambaTalk
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Talk/JambaTalk.lua b/Jamba-Talk/JambaTalk.lua
index da15327..2c5a8cb 100644
--- a/Jamba-Talk/JambaTalk.lua
+++ b/Jamba-Talk/JambaTalk.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Talk/Locales/JambaTalk-Locale-enUS.lua b/Jamba-Talk/Locales/JambaTalk-Locale-enUS.lua
index 068a91e..8e6c397 100644
--- a/Jamba-Talk/Locales/JambaTalk-Locale-enUS.lua
+++ b/Jamba-Talk/Locales/JambaTalk-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Talk/Locales/Locales.xml b/Jamba-Talk/Locales/Locales.xml
index 0b257ac..3295144 100644
--- a/Jamba-Talk/Locales/Locales.xml
+++ b/Jamba-Talk/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-Target/Bindings.xml b/Jamba-Target/Bindings.xml
deleted file mode 100644
index 2b1eedb..0000000
--- a/Jamba-Target/Bindings.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<Bindings>
-
-  <Binding name="JAMBATARGETMARK" header="JAMBA_TARGET" category="Jamba" runOnUp="true">
-    JambaTargetMarkTargetKeyPress( keystate )
-  </Binding>
-  <Binding name="JAMBACLEARTARGET" category="Jamba">
-    --[[dummy]]
-  </Binding>
-  <Binding name="JAMBATARGET1" category="Jamba">
-    --[[dummy]]
-  </Binding>
-  <Binding name="JAMBATARGET2" category="Jamba">
-    --[[dummy]]
-  </Binding>
-  <Binding name="JAMBATARGET3" category="Jamba">
-    --[[dummy]]
-  </Binding>
-  <Binding name="JAMBATARGET4" category="Jamba">
-    --[[dummy]]
-  </Binding>
-  <Binding name="JAMBATARGET5" category="Jamba">
-    --[[dummy]]
-  </Binding>
-  <Binding name="JAMBATARGET6" category="Jamba">
-    --[[dummy]]
-  </Binding>
-  <Binding name="JAMBATARGET7" category="Jamba">
-    --[[dummy]]
-  </Binding>
-  <Binding name="JAMBATARGET8" category="Jamba">
-    --[[dummy]]
-  </Binding>
-
-</Bindings>
diff --git a/Jamba-Target/Jamba-Target.toc b/Jamba-Target/Jamba-Target.toc
deleted file mode 100644
index 62a7b79..0000000
--- a/Jamba-Target/Jamba-Target.toc
+++ /dev/null
@@ -1,12 +0,0 @@
-## Interface: 70100
-## Title: JambaTarget
-## Notes: JambaTarget
-## Author: Ebony, Former Author: Jafula
-## Version: 7.1.5-5.1.7
-## X-Category: Interface Enhancements
-## X-Child-Of: Jamba
-## Dependencies: Jamba
-## SavedVariables: JambaTargetProfileDB
-## LoadOnDemand: 1
-Locales\Locales.xml
-JambaTarget.lua
diff --git a/Jamba-Target/JambaTarget.lua b/Jamba-Target/JambaTarget.lua
deleted file mode 100644
index 949ee0e..0000000
--- a/Jamba-Target/JambaTarget.lua
+++ /dev/null
@@ -1,1411 +0,0 @@
---[[
-Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
-License: The MIT License
-]]--
-
--- Create the addon using AceAddon-3.0 and embed some libraries.
-local AJM = LibStub( "AceAddon-3.0" ):NewAddon(
-	"JambaTarget",
-	"JambaModule-1.0",
-	"AceConsole-3.0",
-	"AceEvent-3.0",
-	"AceTimer-3.0"
-)
-
--- Get the Jamba Utilities Library.
-local JambaUtilities = LibStub:GetLibrary( "JambaUtilities-1.0" )
-local JambaHelperSettings = LibStub:GetLibrary( "JambaHelperSettings-1.0" )
-AJM.SharedMedia = LibStub( "LibSharedMedia-3.0" )
-
---  Constants and Locale for this module.
-AJM.moduleName = "Jamba-Target"
-AJM.settingsDatabaseName = "JambaTargetProfileDB"
-AJM.chatCommand = "jamba-target"
-local L = LibStub( "AceLocale-3.0" ):GetLocale( AJM.moduleName )
-AJM.parentDisplayName = L["Combat"]
-AJM.moduleDisplayName = L["Target"]
-
--- Jamba key bindings.
-BINDING_HEADER_JAMBA_TARGET = L["Jamba-Target"]
-BINDING_NAME_JAMBATARGETMARK = L["Mark Targets (Press & Hold)"]
-BINDING_NAME_JAMBACLEARTARGET = L["Clear Target"]
-BINDING_NAME_JAMBATARGET1 = L["Target 1 (Star)"]
-BINDING_NAME_JAMBATARGET2 = L["Target 2 (Circle)"]
-BINDING_NAME_JAMBATARGET3 = L["Target 3 (Diamond)"]
-BINDING_NAME_JAMBATARGET4 = L["Target 4 (Triangle)"]
-BINDING_NAME_JAMBATARGET5 = L["Target 5 (Moon)"]
-BINDING_NAME_JAMBATARGET6 = L["Target 6 (Square)"]
-BINDING_NAME_JAMBATARGET7 = L["Target 7 (Cross)"]
-BINDING_NAME_JAMBATARGET8 = L["Target 8 (Skull)"]
-
--- Settings - the values to store and their defaults for the settings database.
-AJM.settings = {
-	profile = {
-		framePoint = "CENTER",
-		frameRelativePoint = "CENTER",
-		frameXOffset = 0,
-		frameYOffset = 0,
-		frameAlpha = 1.0,
-		borderStyle = L["Blizzard Tooltip"],
-		backgroundStyle = L["Blizzard Dialog Background"],
-		frameBackgroundColourR = 1.0,
-		frameBackgroundColourG = 1.0,
-		frameBackgroundColourB = 1.0,
-		frameBackgroundColourA = 1.0,
-		frameBorderColourR = 1.0,
-		frameBorderColourG = 1.0,
-		frameBorderColourB = 1.0,
-		frameBorderColourA = 1.0,
-		frameScale = 1,
-		markTargetsWithRaidIcons = true,
-		showTargetList = true,
-		targetListHealthHeight = 15,
-		targetListHealthWidth = 180,
-		holdTargets = {
-			["1"] = false,
-			["2"] = false,
-			["3"] = false,
-			["4"] = false,
-			["5"] = false,
-			["6"] = false,
-			["7"] = false,
-			["8"] = false,
-		},
-		targetTag = {
-			["1"] = L["all"],
-			["2"] = L["all"],
-			["3"] = L["all"],
-			["4"] = L["all"],
-			["5"] = L["all"],
-			["6"] = L["all"],
-			["7"] = L["all"],
-			["8"] = L["all"],
-		},
-		targetMacro = {
-			["1"] = "/targetexact #MOB#",
-			["2"] = "/targetexact #MOB#",
-			["3"] = "/targetexact #MOB#",
-			["4"] = "/targetexact #MOB#",
-			["5"] = "/targetexact #MOB#",
-			["6"] = "/targetexact #MOB#",
-			["7"] = "/targetexact #MOB#",
-			["8"] = "/targetexact #MOB#",
-		},
-		messageArea = JambaApi.DefaultMessageArea(),
-	},
-}
-
--- Configuration.
-function AJM:GetConfiguration()
-	local configuration = {
-		name = AJM.moduleDisplayName,
-		handler = AJM,
-		type = 'group',
-		childGroups  = "tab",
-		get = "JambaConfigurationGetSetting",
-		set = "JambaConfigurationSetSetting",
-		args = {
-			push = {
-				type = "input",
-				name = L["Push Settings"],
-				desc = L["Push the target settings to all characters in the team."],
-				usage = "/jamba-target push",
-				get = false,
-				set = "JambaSendSettings",
-				order = 4,
-				guiHidden = true,
-			},
-		},
-	}
-	return configuration
-end
-
--------------------------------------------------------------------------------------------------------------
--- Command this module sends.
--------------------------------------------------------------------------------------------------------------
-
-AJM.COMMAND_SET_MOB_TARGET = "SetTargetToMob"
-AJM.COMMAND_CLEAR_MOB_TARGET = "SetTargetToMobClear"
-
--------------------------------------------------------------------------------------------------------------
--- Messages module sends.
--------------------------------------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------------------------------------
--- Addon initialization, enabling and disabling.
--------------------------------------------------------------------------------------------------------------
-
-function AJM:CreateJambaTargetListFrame()
-	-- The frame.
-	local frame = CreateFrame( "Frame", "JambaTargetListWindowFrame", UIParent )
-	frame.obj = self
-	frame:SetWidth( AJM.db.targetListHealthWidth )
-	frame:SetHeight( AJM.listTargetsTitleHeight + (AJM.db.targetListHealthHeight * 8) + (AJM.listTargetsVerticalSpacing * (8 + 3)) )
-	frame:SetFrameStrata( "MEDIUM" )
-	frame:SetToplevel( true )
-	frame:SetClampedToScreen( true )
-	frame:EnableMouse( true )
-	frame:SetMovable( true )
-	frame:SetUserPlaced( true )
-	frame:RegisterForDrag( "LeftButton" )
-	frame:SetScript( "OnDragStart",
-		function( this )
-			if IsAltKeyDown() then
-				this:StartMoving()
-			end
-		end )
-	frame:SetScript( "OnDragStop",
-		function( this )
-			this:StopMovingOrSizing()
-			local point, relativeTo, relativePoint, xOffset, yOffset = this:GetPoint()
-			AJM.db.framePoint = point
-			AJM.db.frameRelativePoint = relativePoint
-			AJM.db.frameXOffset = xOffset
-			AJM.db.frameYOffset = yOffset
-		end	)
-	frame:ClearAllPoints()
-	frame:SetPoint( AJM.db.framePoint, UIParent, AJM.db.frameRelativePoint, AJM.db.frameXOffset, AJM.db.frameYOffset )
-	frame:SetBackdrop( {
-		bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
-		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
-		tile = true, tileSize = 10, edgeSize = 10,
-		insets = { left = 3, right = 3, top = 3, bottom = 3 }
-	} )
-	JambaTargetListFrame = frame
-	-- Create the title for the target list frame.
-	local titleName = frame:CreateFontString( "JambaTargetListWindowFrameTitleText", "OVERLAY", "GameFontNormal" )
-	titleName:SetPoint( "TOP", frame, "TOP", 0, -5 )
-	titleName:SetTextColor( 1.00, 1.00, 1.00 )
-	titleName:SetText( L["Jamba-Target"] )
-	-- Secure action button targets 1-8.
-	local heightAddition = AJM.db.targetListHealthHeight + AJM.listTargetsVerticalSpacing
-	local topPosition = -AJM.listTargetsTitleHeight + -AJM.listTargetsVerticalSpacing * 2
-	local leftPosition = 6
-	for target = 1, 8, 1 do
-		AJM:CreateJambaTargetTargetButton(
-			target,
-			"JambaTargetSecureButtonTarget"..tostring( target ),
-			frame,
-			leftPosition,
-			topPosition + ((target - 1) * -heightAddition)
-		)
-	end
-	frame:SetAlpha( AJM.db.frameAlpha )
-	frame:SetScale( AJM.db.frameScale )
-	AJM:SettingsUpdateBorderStyle()
-	frame:Hide()
-end
-
-function AJM:SettingsUpdateBorderStyle()
-	local borderStyle = AJM.SharedMedia:Fetch( "border", AJM.db.borderStyle )
-	local backgroundStyle = AJM.SharedMedia:Fetch( "background", AJM.db.backgroundStyle )
-	local frame = JambaTargetListFrame
-	frame:SetBackdrop( {
-		bgFile = backgroundStyle,
-		edgeFile = borderStyle,
-		tile = true, tileSize = frame:GetWidth(), edgeSize = 10,
-		insets = { left = 3, right = 3, top = 3, bottom = 3 }
-	} )
-	frame:SetBackdropColor( AJM.db.frameBackgroundColourR, AJM.db.frameBackgroundColourG, AJM.db.frameBackgroundColourB, AJM.db.frameBackgroundColourA )
-	frame:SetBackdropBorderColor( AJM.db.frameBorderColourR, AJM.db.frameBorderColourG, AJM.db.frameBorderColourB, AJM.db.frameBorderColourA )
-end
-
-function AJM:CreateJambaTargetTargetButton( targetNumber, buttonName, parentFrame, positionLeft, positionTop )
-	-- Create the target button that holds the macro (and the corresponding raid icon).
-	local targetButton = CreateFrame( "CheckButton", buttonName, parentFrame, "SecureActionButtonTemplate" )
-	targetButton:SetWidth( AJM.db.targetListHealthHeight )
-	targetButton:SetHeight( AJM.db.targetListHealthHeight )
-	targetButton:SetID( targetNumber )
-	targetButton.Texture = targetButton:CreateTexture( targetButton:GetName().."NormalTexture", "ARTWORK" )
-	targetButton.Texture:SetTexture( "Interface\\TargetingFrame\\UI-RaidTargetingIcons" )
-	targetButton.Texture:SetAllPoints()
-	SetRaidTargetIconTexture( targetButton.Texture, targetNumber )
-	targetButton:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
-	targetButton:SetAttribute( "type", "macro" )
-	targetButton:SetAttribute( "macrotext", "" )
-	-- Create a status bar for the targets health.
-	local targetStatusHealth = CreateFrame( "StatusBar", buttonName.."StatusHealth", parentFrame, "TextStatusBar" )
-	targetStatusHealth:SetWidth( AJM.db.targetListHealthWidth - (AJM.db.targetListHealthHeight * 2) )
-	targetStatusHealth:SetHeight( AJM.db.targetListHealthHeight )
-	targetStatusHealth:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft + AJM.db.targetListHealthHeight + 4, positionTop )
-	targetStatusHealth:SetStatusBarTexture( "Interface\\TargetingFrame\\UI-StatusBar" )
-	targetStatusHealth:SetMinMaxValues( 0, 100 )
-	AJM:UpdateHealthStatusBar( targetStatusHealth, 100, 100 )
-	-- Create a text string for the targets name.
-	local targetName = targetStatusHealth:CreateFontString( buttonName.."NameText", "OVERLAY", "GameFontNormal" )
-	targetName:SetWidth( (AJM.db.targetListHealthWidth - (AJM.db.targetListHealthHeight * 2)) - 4 )
-	targetName:SetHeight( AJM.db.targetListHealthHeight )
-	targetName:SetPoint( "TOPLEFT", targetStatusHealth, "TOPLEFT", 2, 0 )
-	targetName:SetTextColor( 1.00, 1.00, 1.00, 1.00 )
-	targetName:SetText( "" )
-	targetButton:Hide()
-	targetStatusHealth:Hide()
-end
-
-function AJM:UpdateHealthStatusBar( statusBar, statusValue, statusMaxValue )
-	statusBar:SetMinMaxValues( 0, statusMaxValue )
-	statusBar:SetValue( statusValue )
-	local r, g, b = 0, 0, 0
-	statusValue = statusValue / statusMaxValue
-	if( statusValue > 0.5 ) then
-		r = (1.0 - statusValue) * 2
-		g = 1.0
-	else
-		r = 1.0
-		g = statusValue * 2
-	end
-	b = 0.0
-	statusBar:SetStatusBarColor( r, g, b )
-end
-
-function AJM:CreateJambaTargetMarkFrame()
-	-- The frame.
-	local frame = CreateFrame( "Frame", "JambaTargetMarkWindowFrame", UIParent )
-	frame.obj = self
-	frame:SetWidth( 100 )
-	frame:SetHeight( 100 )
-	frame:SetFrameStrata( "DIALOG" )
-	frame:SetToplevel( true )
-	frame:SetClampedToScreen( true )
-	frame:EnableMouse( true )
-	frame:ClearAllPoints()
-	frame:SetPoint( "CENTER", UIParent )
-	JambaTargetMarkFrame = frame
-	-- The 8 raid icons to use as targets.
-	for raidIcon = 1, 8, 1 do
-		-- Create the button.
-		local targetButton = CreateFrame( "Button", "JambaTargetMarkRaidIconButton"..tostring( raidIcon ), frame )
-		targetButton:SetWidth( 30 )
-		targetButton:SetHeight( 30 )
-		targetButton:SetID( raidIcon )
-		targetButton.Texture = targetButton:CreateTexture( targetButton:GetName().."NormalTexture", "ARTWORK" )
-		targetButton.Texture:SetTexture( "Interface\\TargetingFrame\\UI-RaidTargetingIcons" )
-		targetButton.Texture:SetAllPoints()
-		SetRaidTargetIconTexture( targetButton.Texture, raidIcon )
-		local relocateIcon = raidIcon - 1
-		if relocateIcon == 0 then
-			relocateIcon = 8
-		end
-		targetButton:SetPoint( "CENTER", sin( 360 / 8 * relocateIcon ) * 50, cos( 360 / 8 * relocateIcon ) * 50)
-		-- Events.
-		targetButton:RegisterForClicks( "LeftButtonUp", "RightButtonUp" )
-		targetButton:SetScript( "OnClick", AJM.JambaTargetMarkTargetClick )
-		targetButton:SetScript( "OnEnter",
-			function( this )
-				this.Texture:ClearAllPoints();
-				this.Texture:SetPoint( "TOPLEFT", -5, 5 )
-				this.Texture:SetPoint( "BOTTOMRIGHT", 5, -5 )
-			end )
-		targetButton:SetScript( "OnLeave",
-			function( this )
-				this.Texture:SetAllPoints()
-			end )
-	end
-	frame:Hide()
-end
-
--------------------------------------------------------------------------------------------------------------
--- Addon initialization, enabling and disabling.
--------------------------------------------------------------------------------------------------------------
-
--- Initialise the module.
-function AJM:OnInitialize()
-	-- Create the settings control.
-	AJM:SettingsCreate()
-	-- Initialse the JambaModule part of this module.
-	AJM:JambaModuleInitialize( AJM.settingsControl.widgetSettings.frame )
-	-- Populate the settings.
-	AJM:SettingsRefresh()
-	-- Variables.
-	AJM.refreshUpdateBindingsPending = false
-	-- Size of items on target list frame.
-	AJM.listTargetsVerticalSpacing = 4
-	AJM.listTargetsTitleHeight = 15
-	-- Timer handle for refreshing the targets list.
-	AJM.updateTargetListTimer = nil
-	-- Create a target list.
-	AJM.targetList = {}
-	for targetNumber = 1, 8 do
-		local targetInformation = {}
-		targetInformation["set"] = false
-		targetInformation["name"] = ""
-		targetInformation["guid"] = ""
-		AJM.targetList[targetNumber] = targetInformation
-	end
-	-- A secure action button for clear target.
-	JambaTargetSecureButtonClearTarget = CreateFrame( "CheckButton", "JambaTargetSecureButtonClearTarget", nil, "SecureActionButtonTemplate" );
-	JambaTargetSecureButtonClearTarget:SetAttribute( "type", "macro" )
-	JambaTargetSecureButtonClearTarget:SetAttribute( "macrotext", "/cleartarget" )
-	JambaTargetSecureButtonClearTarget:Hide()
-	-- Create the jamba target list frame.
-	AJM:CreateJambaTargetListFrame()
-	-- Create the jamba mark target frame.
-	AJM:CreateJambaTargetMarkFrame()
-end
-
--- Called when the addon is enabled.
-function AJM:OnEnable()
-	AJM.keyBindingFrame = CreateFrame( "Frame", nil, UIParent )
-	AJM:RegisterEvent( "UPDATE_BINDINGS" )
-	AJM:UPDATE_BINDINGS()
-	AJM:RegisterEvent( "PLAYER_REGEN_ENABLED" )
-	AJM:RegisterEvent( "PLAYER_REGEN_DISABLED" )
-	AJM:RegisterEvent( "COMBAT_LOG_EVENT_UNFILTERED" )
-	AJM:RegisterEvent( "UNIT_COMBAT" )
-	AJM.updateTargetListTimer = AJM:ScheduleRepeatingTimer( "RefreshTargetList", 3 )
-	AJM:RegisterMessage( JambaApi.MESSAGE_MESSAGE_AREAS_CHANGED, "OnMessageAreasChanged" )
-end
-
--- Called when the addon is disabled.
-function AJM:OnDisable()
-	AJM:CancelTimer( AJM.updateTargetListTimer )
-end
-
-function AJM:SettingsCreate()
-	AJM.settingsControl = {}
-	AJM.settingsControlMacros = {}
-	-- Create the settings panel.
-	JambaHelperSettings:CreateSettings(
-		AJM.settingsControl,
-		AJM.moduleDisplayName,
-		AJM.parentDisplayName,
-		AJM.SettingsPushSettingsClick
-	)
-	JambaHelperSettings:CreateSettings(
-		AJM.settingsControlMacros,
-		AJM.moduleDisplayName..L[": "]..L["Macros"],
-		AJM.parentDisplayName,
-		AJM.SettingsPushSettingsClick
-	)
-	local bottomOfInfo = AJM:SettingsCreateTarget( JambaHelperSettings:TopOfSettings() )
-	AJM.settingsControl.widgetSettings.content:SetHeight( -bottomOfInfo )
-	local bottomOfMacros = AJM:SettingsCreateMacros( JambaHelperSettings:TopOfSettings() )
-	AJM.settingsControlMacros.widgetSettings.content:SetHeight( -bottomOfMacros )
-	-- Help
-	local helpTable = {}
-	JambaHelperSettings:CreateHelp( AJM.settingsControl, helpTable, AJM:GetConfiguration() )
-end
-
-function AJM:SettingsPushSettingsClick( event )
-	AJM:JambaSendSettings()
-end
-
-function AJM:SettingsCreateMacros( top )
-	local checkBoxHeight = JambaHelperSettings:GetCheckBoxHeight()
-	local left = JambaHelperSettings:LeftOfSettings()
-	local headingHeight = JambaHelperSettings:HeadingHeight()
-	local headingWidth = JambaHelperSettings:HeadingWidth( true )
-	local dropdownHeight = JambaHelperSettings:GetDropdownHeight()
-	local verticalSpacing = JambaHelperSettings:GetVerticalSpacing()
-	local horizontalSpacing = JambaHelperSettings:GetHorizontalSpacing()
-	local labelContinueHeight = JambaHelperSettings:GetContinueLabelHeight()
-	local editBoxHeight = JambaHelperSettings:GetEditBoxHeight()
-	local multiEditBoxHeightMacroText = 100
-	local halfWidth = (headingWidth - horizontalSpacing) / 2
-	local column2left = left + halfWidth
-	local movingTop = top
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Target Macros"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.labelHoldInformation = JambaHelperSettings:CreateContinueLabel(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["The macro to use for each target.  Use #MOB# for the actual target."]
-	)
-	movingTop = movingTop - (labelContinueHeight * 1.5)
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Target 1 (Star)"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.editMacro1Star = JambaHelperSettings:CreateMultiEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro for Target 1 (Star)"],
-		4
-	)
-	AJM.settingsControlMacros.editMacro1Star:SetCallback( "OnEnterPressed", AJM.SettingsEditMacro1Star )
-	movingTop = movingTop - multiEditBoxHeightMacroText
-	AJM.settingsControlMacros.editTag1Star = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Tag for Target 1 (Star)"]
-	)
-	AJM.settingsControlMacros.editTag1Star:SetCallback( "OnEnterPressed", AJM.SettingsEditTag1Star )
-	movingTop = movingTop - editBoxHeight
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Target 2 (Circle)"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.editMacro2Circle = JambaHelperSettings:CreateMultiEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro for Target 2 (Circle)"],
-		4
-	)
-	AJM.settingsControlMacros.editMacro2Circle:SetCallback( "OnEnterPressed", AJM.SettingsEditMacro2Circle )
-	movingTop = movingTop - multiEditBoxHeightMacroText
-	AJM.settingsControlMacros.editTag2Circle = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Tag for Target 2 (Circle)"]
-	)
-	AJM.settingsControlMacros.editTag2Circle:SetCallback( "OnEnterPressed", AJM.SettingsEditTag2Circle )
-	movingTop = movingTop - editBoxHeight
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Target 3 (Diamond)"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.editMacro3Diamond = JambaHelperSettings:CreateMultiEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro for Target 3 (Diamond)"],
-		4
-	)
-	AJM.settingsControlMacros.editMacro3Diamond:SetCallback( "OnEnterPressed", AJM.SettingsEditMacro3Diamond )
-	movingTop = movingTop - multiEditBoxHeightMacroText
-	AJM.settingsControlMacros.editTag3Diamond = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Tag for Target 3 (Diamond)"]
-	)
-	AJM.settingsControlMacros.editTag3Diamond:SetCallback( "OnEnterPressed", AJM.SettingsEditTag3Diamond )
-	movingTop = movingTop - editBoxHeight
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Target 4 (Triangle)"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.editMacro4Triangle = JambaHelperSettings:CreateMultiEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro for Target 4 (Triangle)"],
-		4
-	)
-	AJM.settingsControlMacros.editMacro4Triangle:SetCallback( "OnEnterPressed", AJM.SettingsEditMacro4Triangle )
-	movingTop = movingTop - multiEditBoxHeightMacroText
-	AJM.settingsControlMacros.editTag4Triangle = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Tag for Target 4 (Triangle)"]
-	)
-	AJM.settingsControlMacros.editTag4Triangle:SetCallback( "OnEnterPressed", AJM.SettingsEditTag4Triangle )
-	movingTop = movingTop - editBoxHeight
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Target 5 (Moon)"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.editMacro5Moon = JambaHelperSettings:CreateMultiEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro for Target 5 (Moon)"],
-		4
-	)
-	AJM.settingsControlMacros.editMacro5Moon:SetCallback( "OnEnterPressed", AJM.SettingsEditMacro5Moon )
-	movingTop = movingTop - multiEditBoxHeightMacroText
-	AJM.settingsControlMacros.editTag5Moon = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Tag for Target 5 (Moon)"]
-	)
-	AJM.settingsControlMacros.editTag5Moon:SetCallback( "OnEnterPressed", AJM.SettingsEditTag5Moon )
-	movingTop = movingTop - editBoxHeight
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Target 6 (Square)"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.editMacro6Square = JambaHelperSettings:CreateMultiEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro for Target 6 (Square)"],
-		4
-	)
-	AJM.settingsControlMacros.editMacro6Square:SetCallback( "OnEnterPressed", AJM.SettingsEditMacro6Square )
-	movingTop = movingTop - multiEditBoxHeightMacroText
-	AJM.settingsControlMacros.editTag6Square = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Tag for Target 6 (Square)"]
-	)
-	AJM.settingsControlMacros.editTag6Square:SetCallback( "OnEnterPressed", AJM.SettingsEditTag6Square )
-	movingTop = movingTop - editBoxHeight
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Target 7 (Cross)"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.editMacro7Cross = JambaHelperSettings:CreateMultiEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro for Target 7 (Cross)"],
-		4
-	)
-	AJM.settingsControlMacros.editMacro7Cross:SetCallback( "OnEnterPressed", AJM.SettingsEditMacro7Cross )
-	movingTop = movingTop - multiEditBoxHeightMacroText
-	AJM.settingsControlMacros.editTag7Cross = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Tag for Target 7 (Cross)"]
-	)
-	AJM.settingsControlMacros.editTag7Cross:SetCallback( "OnEnterPressed", AJM.SettingsEditTag7Cross )
-	movingTop = movingTop - editBoxHeight
-	JambaHelperSettings:CreateHeading( AJM.settingsControlMacros, L["Target 8 (Skull)"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControlMacros.editMacro8Skull = JambaHelperSettings:CreateMultiEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Macro for Target 8 (Skull)"],
-		4
-	)
-	AJM.settingsControlMacros.editMacro8Skull:SetCallback( "OnEnterPressed", AJM.SettingsEditMacro8Skull )
-	movingTop = movingTop - multiEditBoxHeightMacroText
-	AJM.settingsControlMacros.editTag8Skull = JambaHelperSettings:CreateEditBox(
-		AJM.settingsControlMacros,
-		headingWidth,
-		left,
-		movingTop,
-		L["Tag for Target 8 (Skull)"]
-	)
-	AJM.settingsControlMacros.editTag8Skull:SetCallback( "OnEnterPressed", AJM.SettingsEditTag8Skull )
-	movingTop = movingTop - editBoxHeight
-	return movingTop
-end
-
-function AJM:SettingsCreateTarget( top )
-	local checkBoxHeight = JambaHelperSettings:GetCheckBoxHeight()
-	local left = JambaHelperSettings:LeftOfSettings()
-	local headingHeight = JambaHelperSettings:HeadingHeight()
-	local headingWidth = JambaHelperSettings:HeadingWidth( true )
-	local dropdownHeight = JambaHelperSettings:GetDropdownHeight()
-	local mediaHeight = JambaHelperSettings:GetMediaHeight()
-	local verticalSpacing = JambaHelperSettings:GetVerticalSpacing()
-	local sliderHeight = JambaHelperSettings:GetSliderHeight()
-	local horizontalSpacing = JambaHelperSettings:GetHorizontalSpacing()
-	local labelContinueHeight = JambaHelperSettings:GetContinueLabelHeight()
-	local halfWidth = (headingWidth - horizontalSpacing) / 2
-	local column2left = left + halfWidth
-	local movingTop = top
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Target Options"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.targetCheckBoxMarkTargetsWithRaidIcons = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Mark Targets With Raid Icons"],
-		AJM.SettingsToggleMarkTargetsWithRaidIcons
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.targetCheckBoxShowTargetList = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Show Target List"],
-		AJM.SettingsToggleShowTargetList
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Targets To Hold"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.labelHoldInformation = JambaHelperSettings:CreateContinueLabel(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Do not track health for a particular unit.  Leave name in list for targeting purposes."]
-	)
-	movingTop = movingTop - (labelContinueHeight * 1.5)
-	AJM.settingsControl.targetCheckBoxHold1Star = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		halfWidth,
-		left,
-		movingTop,
-		L["Hold 1 (Star)"],
-		AJM.SettingsToggleHold1Star
-	)
-	AJM.settingsControl.targetCheckBoxHold5Moon = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		halfWidth,
-		column2left,
-		movingTop,
-		L["Hold 5 (Moon)"],
-		AJM.SettingsToggleHold5Moon
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.targetCheckBoxHold2Circle = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		halfWidth,
-		left,
-		movingTop,
-		L["Hold 2 (Circle)"],
-		AJM.SettingsToggleHold2Circle
-	)
-	AJM.settingsControl.targetCheckBoxHold6Square = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		halfWidth,
-		column2left,
-		movingTop,
-		L["Hold 6 (Square)"],
-		AJM.SettingsToggleHold6Square
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.targetCheckBoxHold3Diamond = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		halfWidth,
-		left,
-		movingTop,
-		L["Hold 3 (Diamond)"],
-		AJM.SettingsToggleHold3Diamond
-	)
-	AJM.settingsControl.targetCheckBoxHold7Cross = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		halfWidth,
-		column2left,
-		movingTop,
-		L["Hold 7 (Cross)"],
-		AJM.SettingsToggleHold7Cross
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	AJM.settingsControl.targetCheckBoxHold4Triangle = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		halfWidth,
-		left,
-		movingTop,
-		L["Hold 4 (Triangle)"],
-		AJM.SettingsToggleHold4Triangle
-	)
-	AJM.settingsControl.targetCheckBoxHold8Skull = JambaHelperSettings:CreateCheckBox(
-		AJM.settingsControl,
-		halfWidth,
-		column2left,
-		movingTop,
-		L["Hold 8 (Skull)"],
-		AJM.SettingsToggleHold8Skull
-	)
-	movingTop = movingTop - checkBoxHeight - verticalSpacing
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Appearance & Layout"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.targetListHealthWidth = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["List Health Bars Width"]
-	)
-	AJM.settingsControl.targetListHealthWidth:SetSliderValues( 80, 400, 5 )
-	AJM.settingsControl.targetListHealthWidth:SetCallback( "OnValueChanged", AJM.SettingsChangeTargetListHealthWidth )
-	movingTop = movingTop - sliderHeight - verticalSpacing
-	AJM.settingsControl.targetListHealthHeight = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["List Health Bars Height"]
-	)
-	AJM.settingsControl.targetListHealthHeight:SetSliderValues( 10, 100, 1 )
-	AJM.settingsControl.targetListHealthHeight:SetCallback( "OnValueChanged", AJM.SettingsChangeTargetListHealthHeight )
-	movingTop = movingTop - sliderHeight - verticalSpacing
-	AJM.settingsControl.targetListTransparencySlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Transparency"]
-	)
-	AJM.settingsControl.targetListTransparencySlider:SetSliderValues( 0, 1, 0.01 )
-	AJM.settingsControl.targetListTransparencySlider:SetCallback( "OnValueChanged", AJM.SettingsChangeTransparency )
-	movingTop = movingTop - sliderHeight - verticalSpacing
-	AJM.settingsControl.targetListMediaBorder = JambaHelperSettings:CreateMediaBorder(
-		AJM.settingsControl,
-		halfWidth,
-		left,
-		movingTop,
-		L["Border Style"]
-	)
-	AJM.settingsControl.targetListMediaBorder:SetCallback( "OnValueChanged", AJM.SettingsChangeBorderStyle )
-	AJM.settingsControl.targetListBorderColourPicker = JambaHelperSettings:CreateColourPicker(
-		AJM.settingsControl,
-		halfWidth,
-		column2left + 15,
-		movingTop - 15,
-		L["Border Colour"]
-	)
-	AJM.settingsControl.targetListBorderColourPicker:SetHasAlpha( true )
-	AJM.settingsControl.targetListBorderColourPicker:SetCallback( "OnValueConfirmed", AJM.SettingsBorderColourPickerChanged )
-	movingTop = movingTop - mediaHeight - verticalSpacing
-	AJM.settingsControl.targetListMediaBackground = JambaHelperSettings:CreateMediaBackground(
-		AJM.settingsControl,
-		halfWidth,
-		left,
-		movingTop,
-		L["Background"]
-	)
-	AJM.settingsControl.targetListMediaBackground:SetCallback( "OnValueChanged", AJM.SettingsChangeBackgroundStyle )
-	AJM.settingsControl.targetListBackgroundColourPicker = JambaHelperSettings:CreateColourPicker(
-		AJM.settingsControl,
-		halfWidth,
-		column2left + 15,
-		movingTop - 15,
-		L["Background Colour"]
-	)
-	AJM.settingsControl.targetListBackgroundColourPicker:SetHasAlpha( true )
-	AJM.settingsControl.targetListBackgroundColourPicker:SetCallback( "OnValueConfirmed", AJM.SettingsBackgroundColourPickerChanged )
-	movingTop = movingTop - mediaHeight - verticalSpacing
-	AJM.settingsControl.targetListScaleSlider = JambaHelperSettings:CreateSlider(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Scale"]
-	)
-	AJM.settingsControl.targetListScaleSlider:SetSliderValues( 0.5, 2, 0.01 )
-	AJM.settingsControl.targetListScaleSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeScale )
-	movingTop = movingTop - sliderHeight - verticalSpacing
-	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Target Messages"], movingTop, true )
-	movingTop = movingTop - headingHeight
-	AJM.settingsControl.dropdownMessageArea = JambaHelperSettings:CreateDropdown(
-		AJM.settingsControl,
-		headingWidth,
-		left,
-		movingTop,
-		L["Message Area"]
-	)
-	AJM.settingsControl.dropdownMessageArea:SetList( JambaApi.MessageAreaList() )
-	AJM.settingsControl.dropdownMessageArea:SetCallback( "OnValueChanged", AJM.SettingsSetMessageArea )
-	movingTop = movingTop - dropdownHeight - verticalSpacing
-	return movingTop
-end
-
-function AJM:OnMessageAreasChanged( message )
-	AJM.settingsControl.dropdownMessageArea:SetList( JambaApi.MessageAreaList() )
-end
-
-function AJM:SettingsChangeTransparency( event, value )
-	AJM.db.frameAlpha = tonumber( value )
-	AJM:SettingsRefresh()
-	AJM:RefreshTargetList()
-end
-
-function AJM:SettingsChangeBorderStyle( event, value )
-	AJM.db.borderStyle = value
-	AJM:SettingsRefresh()
-	AJM:RefreshTargetList()
-end
-
-function AJM:SettingsChangeBackgroundStyle( event, value )
-	AJM.db.backgroundStyle = value
-	AJM:SettingsRefresh()
-	AJM:RefreshTargetList()
-end
-
-function AJM:SettingsBackgroundColourPickerChanged( event, r, g, b, a )
-	AJM.db.frameBackgroundColourR = r
-	AJM.db.frameBackgroundColourG = g
-	AJM.db.frameBackgroundColourB = b
-	AJM.db.frameBackgroundColourA = a
-	AJM:SettingsRefresh()
-	AJM:RefreshTargetList()
-end
-
-function AJM:SettingsBorderColourPickerChanged( event, r, g, b, a )
-	AJM.db.frameBorderColourR = r
-	AJM.db.frameBorderColourG = g
-	AJM.db.frameBorderColourB = b
-	AJM.db.frameBorderColourA = a
-	AJM:SettingsRefresh()
-	AJM:RefreshTargetList()
-end
-
-function AJM:SettingsChangeScale( event, value )
-	AJM.db.frameScale = tonumber( value )
-	AJM:SettingsRefresh()
-	AJM:RefreshTargetList()
-end
-
-function AJM:SettingsChangeTargetListHealthWidth( event, value )
-	AJM.db.targetListHealthWidth = tonumber( value )
-	AJM:SettingsRefresh()
-	AJM:RefreshTargetList()
-end
-
-function AJM:SettingsChangeTargetListHealthHeight( event, value )
-	AJM.db.targetListHealthHeight = tonumber( value )
-	AJM:SettingsRefresh()
-	AJM:RefreshTargetList()
-end
-
-function AJM:SettingsToggleMarkTargetsWithRaidIcons( event, checked )
-	AJM.db.markTargetsWithRaidIcons = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleShowTargetList( event, checked )
-	AJM.db.showTargetList = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleHold1Star( event, checked )
-	AJM.db.holdTargets["1"] = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleHold2Circle( event, checked )
-	AJM.db.holdTargets["2"] = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleHold3Diamond( event, checked )
-	AJM.db.holdTargets["3"] = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleHold4Triangle( event, checked )
-	AJM.db.holdTargets["4"] = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleHold5Moon( event, checked )
-	AJM.db.holdTargets["5"] = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleHold6Square( event, checked )
-	AJM.db.holdTargets["6"] = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleHold7Cross( event, checked )
-	AJM.db.holdTargets["7"] = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsToggleHold8Skull( event, checked )
-	AJM.db.holdTargets["8"] = checked
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsSetMessageArea( event, value )
-	AJM.db.messageArea = value
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditMacro1Star( event, text )
-	AJM.db.targetMacro["1"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditTag1Star( event, text )
-	AJM.db.targetTag["1"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditMacro2Circle( event, text )
-	AJM.db.targetMacro["2"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditTag2Circle( event, text )
-	AJM.db.targetTag["2"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditMacro3Diamond( event, text )
-	AJM.db.targetMacro["3"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditTag3Diamond( event, text )
-	AJM.db.targetTag["3"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditMacro4Triangle( event, text )
-	AJM.db.targetMacro["4"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditTag4Triangle( event, text )
-	AJM.db.targetTag["4"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditMacro5Moon( event, text )
-	AJM.db.targetMacro["5"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditTag5Moon( event, text )
-	AJM.db.targetTag["5"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditMacro6Square( event, text )
-	AJM.db.targetMacro["6"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditTag6Square( event, text )
-	AJM.db.targetTag["6"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditMacro7Cross( event, text )
-	AJM.db.targetMacro["7"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditTag7Cross( event, text )
-	AJM.db.targetTag["7"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditMacro8Skull( event, text )
-	AJM.db.targetMacro["8"] = text
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsEditTag8Skull( event, text )
-	AJM.db.targetTag["8"] = text
-	AJM:SettingsRefresh()
-end
-
--- Settings received.
-function AJM:JambaOnSettingsReceived( characterName, settings )
-	if characterName ~= AJM.characterName then
-		-- Update the settings.
-		AJM.db.framePoint = settings.framePoint
-		AJM.db.frameRelativePoint = settings.frameRelativePoint
-		AJM.db.frameXOffset = settings.frameXOffset
-		AJM.db.frameYOffset = settings.frameYOffset
-		AJM.db.messageArea = settings.messageArea
-		AJM.db.markTargetsWithRaidIcons = settings.markTargetsWithRaidIcons
-		AJM.db.showTargetList = settings.showTargetList
-		AJM.db.targetListHealthHeight = settings.targetListHealthHeight
-		AJM.db.targetListHealthWidth = settings.targetListHealthWidth
-		AJM.db.frameAlpha = settings.frameAlpha
-		AJM.db.frameScale = settings.frameScale
-		AJM.db.borderStyle = settings.borderStyle
-		AJM.db.backgroundStyle = settings.backgroundStyle
-		AJM.db.frameBackgroundColourR = settings.frameBackgroundColourR
-		AJM.db.frameBackgroundColourG = settings.frameBackgroundColourG
-		AJM.db.frameBackgroundColourB = settings.frameBackgroundColourB
-		AJM.db.frameBackgroundColourA = settings.frameBackgroundColourA
-		AJM.db.frameBorderColourR = settings.frameBorderColourR
-		AJM.db.frameBorderColourG = settings.frameBorderColourG
-		AJM.db.frameBorderColourB = settings.frameBorderColourB
-		AJM.db.frameBorderColourA = settings.frameBorderColourA
-		AJM.db.holdTargets["1"] = settings.holdTargets["1"]
-		AJM.db.holdTargets["2"] = settings.holdTargets["2"]
-		AJM.db.holdTargets["3"] = settings.holdTargets["3"]
-		AJM.db.holdTargets["4"] = settings.holdTargets["4"]
-		AJM.db.holdTargets["5"] = settings.holdTargets["5"]
-		AJM.db.holdTargets["6"] = settings.holdTargets["6"]
-		AJM.db.holdTargets["7"] = settings.holdTargets["7"]
-		AJM.db.holdTargets["8"] = settings.holdTargets["8"]
-		AJM.db.targetTag["1"] = settings.targetTag["1"]
-		AJM.db.targetTag["2"] = settings.targetTag["2"]
-		AJM.db.targetTag["3"] = settings.targetTag["3"]
-		AJM.db.targetTag["4"] = settings.targetTag["4"]
-		AJM.db.targetTag["5"] = settings.targetTag["5"]
-		AJM.db.targetTag["6"] = settings.targetTag["6"]
-		AJM.db.targetTag["7"] = settings.targetTag["7"]
-		AJM.db.targetTag["8"] = settings.targetTag["8"]
-		AJM.db.targetMacro["1"] = settings.targetMacro["1"]
-		AJM.db.targetMacro["2"] = settings.targetMacro["2"]
-		AJM.db.targetMacro["3"] = settings.targetMacro["3"]
-		AJM.db.targetMacro["4"] = settings.targetMacro["4"]
-		AJM.db.targetMacro["5"] = settings.targetMacro["5"]
-		AJM.db.targetMacro["6"] = settings.targetMacro["6"]
-		AJM.db.targetMacro["7"] = settings.targetMacro["7"]
-		AJM.db.targetMacro["8"] = settings.targetMacro["8"]
-		-- Refresh the settings.
-		AJM:SettingsRefresh()
-		AJM:RefreshTargetList()
-		-- Tell the player.
-		AJM:Print( L["Settings received from A."]( characterName ) )
-		-- Tell the team?
-		--AJM:JambaSendMessageToTeam( AJM.db.messageArea,  L["Settings received from A."]( characterName ), false )
-	end
-end
-
-function AJM:BeforeJambaProfileChanged()
-end
-
-function AJM:OnJambaProfileChanged()
-	AJM:SettingsRefresh()
-end
-
-function AJM:SettingsRefresh()
-	AJM.settingsControl.targetCheckBoxMarkTargetsWithRaidIcons:SetValue( AJM.db.markTargetsWithRaidIcons )
-	AJM.settingsControl.targetCheckBoxShowTargetList:SetValue( AJM.db.showTargetList )
-	AJM.settingsControl.targetCheckBoxHold1Star:SetValue( AJM.db.holdTargets["1"] )
-	AJM.settingsControl.targetCheckBoxHold2Circle:SetValue( AJM.db.holdTargets["2"] )
-	AJM.settingsControl.targetCheckBoxHold3Diamond:SetValue( AJM.db.holdTargets["3"] )
-	AJM.settingsControl.targetCheckBoxHold4Triangle:SetValue( AJM.db.holdTargets["4"] )
-	AJM.settingsControl.targetCheckBoxHold5Moon:SetValue( AJM.db.holdTargets["5"] )
-	AJM.settingsControl.targetCheckBoxHold6Square:SetValue( AJM.db.holdTargets["6"] )
-	AJM.settingsControl.targetCheckBoxHold7Cross:SetValue( AJM.db.holdTargets["7"] )
-	AJM.settingsControl.targetCheckBoxHold8Skull:SetValue( AJM.db.holdTargets["8"] )
-	AJM.settingsControl.targetListHealthWidth:SetValue( AJM.db.targetListHealthWidth )
-	AJM.settingsControl.targetListHealthHeight:SetValue( AJM.db.targetListHealthHeight )
-	AJM.settingsControl.targetListTransparencySlider:SetValue( AJM.db.frameAlpha )
-	AJM.settingsControl.targetListScaleSlider:SetValue( AJM.db.frameScale )
-	AJM.settingsControl.targetListMediaBorder:SetValue( AJM.db.borderStyle )
-	AJM.settingsControl.targetListMediaBackground:SetValue( AJM.db.backgroundStyle )
-	AJM.settingsControl.targetListBackgroundColourPicker:SetColor( AJM.db.frameBackgroundColourR, AJM.db.frameBackgroundColourG, AJM.db.frameBackgroundColourB, AJM.db.frameBackgroundColourA )
-	AJM.settingsControl.targetListBorderColourPicker:SetColor( AJM.db.frameBorderColourR, AJM.db.frameBorderColourG, AJM.db.frameBorderColourB, AJM.db.frameBorderColourA )
-	AJM.settingsControlMacros.editMacro1Star:SetText( AJM.db.targetMacro["1"] )
-	AJM.settingsControlMacros.editMacro2Circle:SetText( AJM.db.targetMacro["2"] )
-	AJM.settingsControlMacros.editMacro3Diamond:SetText( AJM.db.targetMacro["3"] )
-	AJM.settingsControlMacros.editMacro4Triangle:SetText( AJM.db.targetMacro["4"] )
-	AJM.settingsControlMacros.editMacro5Moon:SetText( AJM.db.targetMacro["5"] )
-	AJM.settingsControlMacros.editMacro6Square:SetText( AJM.db.targetMacro["6"] )
-	AJM.settingsControlMacros.editMacro7Cross:SetText( AJM.db.targetMacro["7"] )
-	AJM.settingsControlMacros.editMacro8Skull:SetText( AJM.db.targetMacro["8"] )
-	AJM.settingsControlMacros.editTag1Star:SetText( AJM.db.targetTag["1"] )
-	AJM.settingsControlMacros.editTag2Circle:SetText( AJM.db.targetTag["2"] )
-	AJM.settingsControlMacros.editTag3Diamond:SetText( AJM.db.targetTag["3"] )
-	AJM.settingsControlMacros.editTag4Triangle:SetText( AJM.db.targetTag["4"] )
-	AJM.settingsControlMacros.editTag5Moon:SetText( AJM.db.targetTag["5"] )
-	AJM.settingsControlMacros.editTag6Square:SetText( AJM.db.targetTag["6"] )
-	AJM.settingsControlMacros.editTag7Cross:SetText( AJM.db.targetTag["7"] )
-	AJM.settingsControlMacros.editTag8Skull:SetText( AJM.db.targetTag["8"] )
-	AJM.settingsControl.dropdownMessageArea:SetText( AJM.db.messageArea )
-end
-
-function AJM:UPDATE_BINDINGS()
-	if InCombatLockdown() then
-		AJM.refreshUpdateBindingsPending = true
-		return
-	end
-	local containerButtonName, key1, key2
-	ClearOverrideBindings( AJM.keyBindingFrame )
-	-- Targets 1 to 8.
-	for iterateItems = 1, 8, 1 do
-		containerButtonName = "JambaTargetSecureButtonTarget"..iterateItems
-		key1, key2 = GetBindingKey( "JAMBATARGET"..iterateItems )
-		if key1 then
-			SetOverrideBindingClick( AJM.keyBindingFrame, false, key1, containerButtonName )
-		end
-		if key2 then
-			SetOverrideBindingClick( AJM.keyBindingFrame, false, key2, containerButtonName )
-		end
-	end
-	-- Clear target button.
-	containerButtonName = "JambaTargetSecureButtonClearTarget"
-	key1, key2 = GetBindingKey( "JAMBACLEARTARGET" )
-	if key1 then
-		SetOverrideBindingClick( AJM.keyBindingFrame, false, key1, containerButtonName )
-	end
-	if key2 then
-		SetOverrideBindingClick( AJM.keyBindingFrame, false, key2, containerButtonName )
-	end
-end
-
-function AJM:PLAYER_REGEN_ENABLED()
-	if AJM.refreshUpdateBindingsPending == true then
-		AJM:UPDATE_BINDINGS()
-		AJM.refreshUpdateBindingsPending = false
-	end
-	AJM:RefreshTargetList()
-end
-
-function AJM:PLAYER_REGEN_DISABLED()
-end
-
-function AJM:COMBAT_LOG_EVENT_UNFILTERED( ... )
-	if AJM.db.showTargetList == false then
-		return
-	end
-	-- Get the combat log information.
-	local wowEvent, timestamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, param1, param2, param3, param4, param5, param6, param7, param8, param9 = ...
-	if event == "UNIT_DIED" or event == "UNIT_DESTROYED" then
-		-- Iterate all our targets looking for a match.
-		for iterateTarget = 1, 8, 1 do
-			-- Get this target information.
-			local targetInformation = AJM.targetList[iterateTarget]
-			local isActive = targetInformation["set"]
-			local targetGuid = targetInformation["guid"]
-			local targetName = targetInformation["name"]
-			-- Did one of our targets die?
-			if isActive == true and targetGuid == destGUID then
-				-- Yes, set the active flag to false.
-				targetInformation["set"] = false
-				targetInformation["guid"] = ""
-				targetInformation["name"] = ""
-				-- Update their health bar to 0.
-				local targetStatusHealth = _G["JambaTargetSecureButtonTarget"..iterateTarget.."StatusHealth"]
-				AJM:UpdateHealthStatusBar( targetStatusHealth, 0, 100 )
-			end
-		end
-	end
-end
-
-function AJM:UNIT_COMBAT( ... )
-	if AJM.db.showTargetList == false then
-		return
-	end
-	local event, unitAffected, action, descriptor, damage, damageType = ...
-	local currentTargetGuid = UnitGUID( unitAffected )
-	for iterateTarget = 1, 8, 1 do
-		local targetInformation = AJM.targetList[iterateTarget]
-		local isActive = targetInformation["set"]
-		local targetGuid = targetInformation["guid"]
-		local targetName = targetInformation["name"]
-		if isActive == true and currentTargetGuid == targetGuid then
-			local targetStatusHealth = _G["JambaTargetSecureButtonTarget"..iterateTarget.."StatusHealth"]
-			AJM:UpdateHealthStatusBar( targetStatusHealth, UnitHealth( unitAffected ), UnitHealthMax( unitAffected ) )
-		end
-	end
-end
-
--------------------------------------------------------------------------------------------------------------
--- JambaTarget functionality.
--------------------------------------------------------------------------------------------------------------
-
-function AJM.JambaTargetMarkTargetClick( button, ... )
-	-- Cannot mark if in combat.
-	if not InCombatLockdown() then
-		-- What mouse button was clicked.
-		local mouseButton = ...
-		-- Was this a clear target action.
-		local clearTarget = false
-		if mouseButton == "RightButton" then
-			clearTarget = true
-		end
-		-- Get the target number.
-		local targetNumber = button:GetID()
-		-- Get the target.
-		if UnitExists( "target" ) then
-			-- Update the list targets and tell the all about this target.
-			AJM:TargetListSetActiveTarget( targetNumber, not clearTarget )
-		end
-	end
-end
-
--- Global
-function JambaTargetMarkTargetKeyPress( keyState )
-	-- Cannot mark if in combat.
-	if not InCombatLockdown() then
-		-- Only show the mark target frame if this player is the master.
-		if JambaApi.IsCharacterTheMaster( AJM.characterName ) then
-			if keyState == "down" then
-				local cursorX, cursorY = GetCursorPosition()
-				local uiScale = UIParent:GetEffectiveScale()
-				JambaTargetMarkFrame:SetPoint( "CENTER", UIParent, "BOTTOMLEFT", cursorX / uiScale, cursorY / uiScale )
-				JambaTargetMarkFrame:Show()
-			else
-				JambaTargetMarkFrame:Hide()
-			end
-		end
-	end
-end
-
-function AJM:TargetListSetActiveTarget( targetNumber, isActive )
-	-- Update this target information.
-	local targetName = UnitName( "target" )
-	local targetGuid = UnitGUID( "target" )
-	-- Set or clear?
-	if isActive then
-		-- If there is a player target...
-		if targetName:trim() ~= "" then
-			-- Tell everyone to set this target.
-			AJM:TargetUpdateSetCommand( tostring( targetNumber ), targetGuid, targetName, AJM.db.targetTag[tostring( targetNumber )] )
-			-- Set a raid icon?
-			if AJM.db.markTargetsWithRaidIcons == true then
-				SetRaidTarget( "target", targetNumber )
-			end
-		end
-	else
-		-- Tell everyone to clear this target.
-		AJM:TargetUpdateClearCommand( nil, tostring( targetNumber ).." "..AJM.db.targetTag[tostring( targetNumber )] )
-		-- Clear a raid icon?
-		if AJM.db.markTargetsWithRaidIcons == true then
-			SetRaidTarget( "target", 0 )
-		end
-	end
-end
-
-function AJM:RefreshTargetList()
-	if AJM.db.showTargetList == true then
-		if not InCombatLockdown() then
-			AJM:DoRefreshTargetList()
-		end
-	end
-end
-
-function AJM:DoRefreshTargetList()
-	local topPosition = -AJM.listTargetsTitleHeight + -AJM.listTargetsVerticalSpacing * 2
-	local leftPosition = 5
-	local heightAddition = AJM.db.targetListHealthHeight + AJM.listTargetsVerticalSpacing
-	-- Count the active targets.
-	local activeTargetCount = 0
-	-- Iterate each target and if active, draw it, one under the other.
-	for iterateTarget = 1, 8, 1 do
-		local targetInformation = AJM.targetList[iterateTarget]
-		local targetIsActive = targetInformation["set"]
-		-- Count the number of actice targets.
-		if targetIsActive == true then
-			activeTargetCount = activeTargetCount + 1
-		end
-		-- Position and draw the targets.
-		local positionTop = topPosition + ((activeTargetCount - 1) * -heightAddition)
-		local positionLeft = leftPosition
-		local targetButton = _G["JambaTargetSecureButtonTarget"..iterateTarget]
-		local targetStatusHealth = _G["JambaTargetSecureButtonTarget"..iterateTarget.."StatusHealth"]
-		local targetName = _G["JambaTargetSecureButtonTarget"..iterateTarget.."NameText"]
-		-- Make sure the width and heights are correct based on the user settings.
-		targetButton:SetWidth( AJM.db.targetListHealthHeight )
-		targetButton:SetHeight( AJM.db.targetListHealthHeight )
-		targetStatusHealth:SetWidth( AJM.db.targetListHealthWidth - (AJM.db.targetListHealthHeight + 16) )
-		targetStatusHealth:SetHeight( AJM.db.targetListHealthHeight )
-		targetName:SetWidth( (AJM.db.targetListHealthWidth - (AJM.db.targetListHealthHeight * 2)) - 4 )
-		targetName:SetHeight( AJM.db.targetListHealthHeight )
-		-- Show or hide the particular target based on whether or not it is active.
-		if targetIsActive == true then
-			targetButton:SetPoint( "TOPLEFT", JambaTargetListFrame, "TOPLEFT", positionLeft, positionTop )
-			targetButton:Show()
-			targetStatusHealth:SetPoint( "TOPLEFT", JambaTargetListFrame, "TOPLEFT", positionLeft + AJM.db.targetListHealthHeight + 4, positionTop )
-			targetStatusHealth:Show()
-		else
-			targetStatusHealth:SetMinMaxValues( 0, 100 )
-			targetStatusHealth:SetValue( 0 )
-			targetButton:Hide()
-			targetStatusHealth:Hide()
-		end
-	end
-	-- If no active targets...
-	if activeTargetCount == 0 then
-		-- Hide the frame.
-		JambaTargetListFrame:Hide()
-	else
-		-- Show the frame with the correct width and height.
-		JambaTargetListFrame:ClearAllPoints()
-		JambaTargetListFrame:SetPoint( AJM.db.framePoint, UIParent, AJM.db.frameRelativePoint, AJM.db.frameXOffset, AJM.db.frameYOffset )
-		JambaTargetListFrame:SetWidth( AJM.db.targetListHealthWidth )
-		JambaTargetListFrame:SetHeight( AJM.listTargetsTitleHeight + (AJM.db.targetListHealthHeight * activeTargetCount) + (AJM.listTargetsVerticalSpacing * (activeTargetCount + 3)) )
-		JambaTargetListFrame:SetAlpha( AJM.db.frameAlpha )
-		JambaTargetListFrame:SetScale( AJM.db.frameScale )
-		AJM:SettingsUpdateBorderStyle()
-		JambaTargetListFrame:Show()
-	end
-end
-
-function AJM:TargetUpdateSetCommand( targetNumber, targetGuid, targetName, tag )
-	if tag ~= nil and tag:trim() ~= "" then
-		self:TargetUpdateSendCommand( targetNumber, targetGuid, targetName, tag )
-	else
-		self:TargetUpdateMacroText( targetNumber, targetGuid, targetName )
-	end
-end
-
-function AJM:TargetUpdateSendCommand( targetNumber, targetGuid, targetName, tag )
-	AJM:JambaSendCommandToTeam( AJM.COMMAND_SET_MOB_TARGET, targetNumber, targetGuid, targetName, tag )
-end
-
-function AJM:TargetUpdateReceiveCommand( targetNumber, targetGuid, targetName, tag )
-	-- If this character responds to this tag...
-	if JambaApi.DoesCharacterHaveTag( AJM.characterName, tag ) == true then
-		-- Then update the macro text for the target specified.
-		AJM:TargetUpdateMacroText( targetNumber, targetGuid, targetName )
-	end
-end
-
-function AJM:TargetUpdateMacroText( targetNumber, targetGuid, targetName )
-	-- Was a target provided?
-	if targetName then
-		-- If not in combat then...
-		if not InCombatLockdown() then
-			-- Clearing or setting the target?
-			local clearTarget = true
-			if targetName:trim() ~= "" then
-				clearTarget = false
-			end
-			-- Change the macro text on the secure button to set target.  Set the name of the target
-			-- into the target list.  Update the target information as well.
-			local secureButton = _G["JambaTargetSecureButtonTarget"..targetNumber]
-			local targetNameText = _G["JambaTargetSecureButtonTarget"..targetNumber.."NameText"]
-			local targetStatusHealth = _G["JambaTargetSecureButtonTarget"..targetNumber.."StatusHealth"]
-			local targetInformation = AJM.targetList[tonumber( targetNumber )]
-			local targetHealthMax = 100
-			if not clearTarget then
-				-- Get the macro to use.
-				local macroToUse = AJM.db.targetMacro[targetNumber]
-				-- Substitue the #MOB# for the mobname.
-				macroToUse = macroToUse:gsub( "#MOB#", targetName )
-AJM:Print( macroToUse )
-				secureButton:SetAttribute( "macrotext", macroToUse ) --"/targetexact "..targetName
-				targetNameText:SetText( targetName )
-				targetStatusHealth:SetMinMaxValues( 0, targetHealthMax )
-				AJM:UpdateHealthStatusBar( targetStatusHealth, targetHealthMax, targetHealthMax )
-				targetInformation["set"] = true
-				targetInformation["name"] = targetName
-				-- If this target is not held...
-				if AJM.db.holdTargets[targetNumber] == false then
-					-- Then set the unit guid.
-					targetInformation["guid"] = targetGuid
-				else
-					-- Otherwise display the held colour.
-					targetInformation["guid"] = ""
-					targetStatusHealth:SetStatusBarColor( 0.2, 0.2, 1.0, 0.75 )
-				end
-			else
-				secureButton:SetAttribute( "macrotext", "" )
-				targetNameText:SetText( "" )
-				targetInformation["set"] = false
-				targetInformation["name"] = ""
-				targetInformation["guid"] = ""
-			end
-			-- Refresh all the targets.
-			AJM:RefreshTargetList()
-		end
-	end
-end
-
-function AJM:TargetUpdateClearCommand( info, parameters )
-	local targetNumber, tag = strsplit( " ", parameters )
-	if tag ~= nil and tag:trim() ~= "" then
-		AJM:TargetUpdateClearSendCommand( targetNumber, tag )
-	else
-		AJM:TargetUpdateMacroText( targetNumber, "", "" )
-	end
-end
-
-function AJM:TargetUpdateClearSendCommand( targetNumber, tag )
-	AJM:JambaSendCommandToTeam( AJM.COMMAND_CLEAR_MOB_TARGET, targetNumber, tag )
-end
-
-function AJM:TargetUpdateClearReceiveCommand( targetNumber, tag )
-	-- If this character responds to this tag...
-	if JambaApi.DoesCharacterHaveTag( AJM.characterName, tag ) == true then
-		-- Then update the macro text for the target specified.
-		AJM:TargetUpdateMacroText( targetNumber, "", "" )
-	end
-end
-
--- A Jamba command has been received.
-function AJM:JambaOnCommandReceived( characterName, commandName, ... )
-	if commandName == AJM.COMMAND_SET_MOB_TARGET then
-		AJM:TargetUpdateReceiveCommand( ... )
-	end
-	if commandName == AJM.COMMAND_CLEAR_MOB_TARGET then
-		AJM:TargetUpdateClearReceiveCommand( ... )
-	end
-end
-
-JambaApi.Target = {}
diff --git a/Jamba-Target/Locales/JambaTarget-Locale-enUS.lua b/Jamba-Target/Locales/JambaTarget-Locale-enUS.lua
deleted file mode 100644
index 7f5919d..0000000
--- a/Jamba-Target/Locales/JambaTarget-Locale-enUS.lua
+++ /dev/null
@@ -1,74 +0,0 @@
---[[
-Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
-License: The MIT License
-]]--
-
-local L = LibStub("AceLocale-3.0"):NewLocale( "Jamba-Target", "enUS", true )
-L["all"] = true
-L["Target Messages"] = true
-L["Message Area"] = true
-L["Slash Commands"] = true
-L["Combat"] = true
-L["Target"] = true
-L["Push Settings"] = true
-L["Push the target settings to all characters in the team."] = true
-L["Settings received from A."] = function( characterName )
-	return string.format( "Settings received from %s.", characterName )
-end
-L["Target Options"] = true
-L["Jamba-Target"] = true
-L["Targets To Hold"] = true
-L[": "] = true
-L["Macros"] = true
-L["Target Macros"] = true
-L["Mark Targets (Press & Hold)"] = true
-L["Clear Target"] = true
-L["Target 1 (Star)"] = true
-L["Target 2 (Circle)"] = true
-L["Target 3 (Diamond)"] = true
-L["Target 4 (Triangle)"] = true
-L["Target 5 (Moon)"] = true
-L["Target 6 (Square)"] = true
-L["Target 7 (Cross)"] = true
-L["Target 8 (Skull)"] = true
-L["Hold 1 (Star)"] = true
-L["Hold 2 (Circle)"] = true
-L["Hold 3 (Diamond)"] = true
-L["Hold 4 (Triangle)"] = true
-L["Hold 5 (Moon)"] = true
-L["Hold 6 (Square)"] = true
-L["Hold 7 (Cross)"] = true
-L["Hold 8 (Skull)"] = true
-L["Mark Targets With Raid Icons"] = true
-L["Show Target List"] = true
-L["The macro to use for each target.  Use #MOB# for the actual target."] = true
-L["Macro for Target 1 (Star)"] = true
-L["Macro for Target 2 (Circle)"] = true
-L["Macro for Target 3 (Diamond)"] = true
-L["Macro for Target 4 (Triangle)"] = true
-L["Macro for Target 5 (Moon)"] = true
-L["Macro for Target 6 (Square)"] = true
-L["Macro for Target 7 (Cross)"] = true
-L["Macro for Target 8 (Skull)"] = true
-L["Tag for Target 1 (Star)"] = true
-L["Tag for Target 2 (Circle)"] = true
-L["Tag for Target 3 (Diamond)"] = true
-L["Tag for Target 4 (Triangle)"] = true
-L["Tag for Target 5 (Moon)"] = true
-L["Tag for Target 6 (Square)"] = true
-L["Tag for Target 7 (Cross)"] = true
-L["Tag for Target 8 (Skull)"] = true
-L["List Health Bars Width"] = true
-L["List Health Bars Height"] = true
-L["Hold Target Name"] = true
-L["Do not track health for a particular unit.  Leave name in list for targeting purposes."] = true
-L["Appearance & Layout"] = true
-L["Transparency"] = true
-L["Border Style"] = true
-L["Border Colour"] = true
-L["Background"] = true
-L["Background Colour"] = true
-L["Blizzard Tooltip"] = true
-L["Blizzard Dialog Background"] = true
-L["Scale"] = true
diff --git a/Jamba-Target/Locales/Locales.xml b/Jamba-Target/Locales/Locales.xml
deleted file mode 100644
index c4fd6e8..0000000
--- a/Jamba-Target/Locales/Locales.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<!--
-Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
-License: The MIT License
--->
-
-<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd" xmlns="http://www.blizzard.com/wow/ui/">
-	<Script file="JambaTarget-Locale-enUS.lua" />
-</Ui>
diff --git a/Jamba-Taxi/Jamba-Taxi.toc b/Jamba-Taxi/Jamba-Taxi.toc
index a153f44..333b96f 100644
--- a/Jamba-Taxi/Jamba-Taxi.toc
+++ b/Jamba-Taxi/Jamba-Taxi.toc
@@ -2,7 +2,7 @@
 ## Title: Jamba-Taxi
 ## Notes: Jamba-Taxi
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Taxi/JambaTaxi.lua b/Jamba-Taxi/JambaTaxi.lua
index 086a451..45ab53c 100644
--- a/Jamba-Taxi/JambaTaxi.lua
+++ b/Jamba-Taxi/JambaTaxi.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Taxi/Locales/JambaTaxi-Locale-enUS.lua b/Jamba-Taxi/Locales/JambaTaxi-Locale-enUS.lua
index 8ad147e..61ee2f6 100644
--- a/Jamba-Taxi/Locales/JambaTaxi-Locale-enUS.lua
+++ b/Jamba-Taxi/Locales/JambaTaxi-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Taxi/Locales/Locales.xml b/Jamba-Taxi/Locales/Locales.xml
index cdccdd0..386f401 100644
--- a/Jamba-Taxi/Locales/Locales.xml
+++ b/Jamba-Taxi/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-Toon/Jamba-Toon.toc b/Jamba-Toon/Jamba-Toon.toc
index 8028fb0..e7c1d8b 100644
--- a/Jamba-Toon/Jamba-Toon.toc
+++ b/Jamba-Toon/Jamba-Toon.toc
@@ -2,7 +2,7 @@
 ## Title: JambaToon
 ## Notes: JambaToon
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Toon/JambaToon.lua b/Jamba-Toon/JambaToon.lua
index 715f350..d139118 100644
--- a/Jamba-Toon/JambaToon.lua
+++ b/Jamba-Toon/JambaToon.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Toon/Locales/JambaToon-Locale-enUS.lua b/Jamba-Toon/Locales/JambaToon-Locale-enUS.lua
index b37ddf5..2d5b0e7 100644
--- a/Jamba-Toon/Locales/JambaToon-Locale-enUS.lua
+++ b/Jamba-Toon/Locales/JambaToon-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Toon/Locales/Locales.xml b/Jamba-Toon/Locales/Locales.xml
index 935b20b..da9d182 100644
--- a/Jamba-Toon/Locales/Locales.xml
+++ b/Jamba-Toon/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba-Trade/Jamba-Trade.toc b/Jamba-Trade/Jamba-Trade.toc
index 9984212..9f2ebc4 100644
--- a/Jamba-Trade/Jamba-Trade.toc
+++ b/Jamba-Trade/Jamba-Trade.toc
@@ -2,7 +2,7 @@
 ## Title: JambaTrade
 ## Notes: JambaTrade
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## X-Category: Interface Enhancements
 ## X-Child-Of: Jamba
 ## Dependencies: Jamba
diff --git a/Jamba-Trade/JambaTrade.lua b/Jamba-Trade/JambaTrade.lua
index 0cad26c..95182a0 100644
--- a/Jamba-Trade/JambaTrade.lua
+++ b/Jamba-Trade/JambaTrade.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

@@ -608,28 +608,37 @@ function AJM:TradeBoEItems()
 	if JambaApi.IsCharacterTheMaster( AJM.characterName ) == true then
 		return
 	end
-	for bag,slot,link in LibBagUtils:Iterate("BAGS") do
-		if bag ~= nil then
-			local _, _, locked, quality = GetContainerItemInfo(bag, slot)
-			-- quality is Uncommon (green) to  Epic (purple) 2 - 3 - 4
-			if quality ~= nil and locked == false then
-				if quality >= 2 and quality <= 4 then
-					-- tooltips scan is the olny way to find if the item is BoE in bags!
-					local isBoe = JambaUtilities:ToolTipBagScaner(link, bag, slot)
-					-- if the item is boe then add it to the trade list!
-					if isBoe ~= ITEM_SOULBOUND then
-						--AJM:Print("test21", link, locked)
-						for iterateTradeSlots = 1, (MAX_TRADE_ITEMS - 1) do
-							if GetTradePlayerItemLink( iterateTradeSlots ) == nil then
-								PickupContainerItem( bag, slot )
-								ClickTradeButton( iterateTradeSlots )
+	for index, character in JambaApi.TeamListOrderedOnline() do
+		--AJM:Print("Team", character )
+		local teamCharacterName = ( Ambiguate( character, "short" ) )
+		local tradePlayersName = GetUnitName("NPC")
+		if tradePlayersName == teamCharacterName then
+			if JambaApi.IsCharacterTheMaster(character) == true and JambaUtilities:CheckIsFromMyRealm(character) == true then
+				for bag,slot,link in LibBagUtils:Iterate("BAGS") do
+					if bag ~= nil then
+						local _, _, locked, quality = GetContainerItemInfo(bag, slot)
+						-- quality is Uncommon (green) to  Epic (purple) 2 - 3 - 4
+						if quality ~= nil and locked == false then
+							if quality >= 2 and quality <= 4 then
+								-- tooltips scan is the olny way to find if the item is BoE in bags!
+								local isBoe = JambaUtilities:ToolTipBagScaner(link, bag, slot)
+								-- if the item is boe then add it to the trade list!
+								if isBoe ~= ITEM_SOULBOUND then
+									--AJM:Print("test21", link, locked)
+									for iterateTradeSlots = 1, (MAX_TRADE_ITEMS - 1) do
+										if GetTradePlayerItemLink( iterateTradeSlots ) == nil then
+											PickupContainerItem( bag, slot )
+											ClickTradeButton( iterateTradeSlots )
+										end
+									end
+								end
 							end
-						end
+						end
 					end
-				end
-			end
-		end
-	end
+				end
+			end
+		end
+	end
 end


@@ -637,27 +646,36 @@ function AJM:TradeCRItems()
 	if JambaApi.IsCharacterTheMaster( AJM.characterName ) == true then
 		return
 	end
-	for bag,slot,itemLink in LibBagUtils:Iterate("BAGS") do
-		if itemLink then
-			-- using legion CraftingReagent API, as tooltip massess up some "items"
-			local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,isCraftingReagent = GetItemInfo(itemLink)
-			if isCraftingReagent == true then
-				--AJM:Print("TradeCraftingGoods", isCraftingReagent, itemLink)
-				-- tooltips scan is the olny way to find if the item is BOP in bags!
-				local isBop = JambaUtilities:TooltipScaner(itemLink)
-				--AJM:Print("testBOP", itemLink, isBop)
-				if isBop ~= ITEM_BIND_ON_PICKUP then
-				--AJM:Print("AddToTrade", itemLink)
-					for iterateTradeSlots = 1, (MAX_TRADE_ITEMS - 1) do
-						if GetTradePlayerItemLink( iterateTradeSlots ) == nil then
-							PickupContainerItem( bag, slot )
-							ClickTradeButton( iterateTradeSlots )
+	for index, character in JambaApi.TeamListOrderedOnline() do
+		--AJM:Print("Team", character )
+		local teamCharacterName = ( Ambiguate( character, "short" ) )
+		local tradePlayersName = GetUnitName("NPC")
+		if tradePlayersName == teamCharacterName then
+			if JambaApi.IsCharacterTheMaster(character) == true and JambaUtilities:CheckIsFromMyRealm(character) == true then
+				for bag,slot,itemLink in LibBagUtils:Iterate("BAGS") do
+					if itemLink then
+						-- using legion CraftingReagent API, as tooltip massess up some "items"
+						local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,isCraftingReagent = GetItemInfo(itemLink)
+						if isCraftingReagent == true then
+							--AJM:Print("TradeCraftingGoods", isCraftingReagent, itemLink)
+							-- tooltips scan is the olny way to find if the item is BOP in bags!
+							local isBop = JambaUtilities:TooltipScaner(itemLink)
+							--AJM:Print("testBOP", itemLink, isBop)
+							if isBop ~= ITEM_BIND_ON_PICKUP then
+							--AJM:Print("AddToTrade", itemLink)
+								for iterateTradeSlots = 1, (MAX_TRADE_ITEMS - 1) do
+									if GetTradePlayerItemLink( iterateTradeSlots ) == nil then
+										PickupContainerItem( bag, slot )
+										ClickTradeButton( iterateTradeSlots )
+									end
+								end
+							end
 						end
 					end
-				end
-			end
-		end
-	end
+				end
+			end
+		end
+	end
 end


@@ -667,6 +685,7 @@ end
 -- Guild bank stuff keep TEMP!

 function AJM:GUILDBANKFRAME_OPENED()
+	--AJM:Print("guildBankOpen")
 	if AJM.db.adjustMoneyWithGuildBank == false then
 		return
 	end
@@ -676,12 +695,25 @@ function AJM:GUILDBANKFRAME_OPENED()
 	local moneyToKeepOnToon = tonumber( AJM.db.goldAmountToKeepOnToon ) * 10000
 	local moneyOnToon = GetMoney()
 	local moneyToDepositOrWithdraw = moneyOnToon - moneyToKeepOnToon
+	--AJM:Print(" testa", moneyToDepositOrWithdraw )
 	if moneyToDepositOrWithdraw == 0 then
 		return
 	end
 	if moneyToDepositOrWithdraw > 0 then
-		DepositGuildBankMoney( moneyToDepositOrWithdraw )
+	--	AJM:Print(" test", moneyToDepositOrWithdraw )
+		--DepositGuildBankMoney( moneyToDepositOrWithdraw )
+		AJM:ScheduleTimer("SendMoneyToGuild", 0.5, moneyToDepositOrWithdraw)
 	else
-		WithdrawGuildBankMoney( -1 * moneyToDepositOrWithdraw )
+		local takeoutmoney = -1 * moneyToDepositOrWithdraw
+	--	AJM:Print("takeout", takeoutmoney)
+		AJM:ScheduleTimer("TakeMoneyOut", 0.5, takeoutmoney )
 	end
 end
+
+function AJM:SendMoneyToGuild( money )
+	DepositGuildBankMoney( money )
+end
+
+function AJM:TakeMoneyOut( money )
+	WithdrawGuildBankMoney( money )
+end
\ No newline at end of file
diff --git a/Jamba-Trade/Locales/JambaTrade-Locale-enUS.lua b/Jamba-Trade/Locales/JambaTrade-Locale-enUS.lua
index 275dab9..1e2351b 100644
--- a/Jamba-Trade/Locales/JambaTrade-Locale-enUS.lua
+++ b/Jamba-Trade/Locales/JambaTrade-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba-Trade/Locales/Locales.xml b/Jamba-Trade/Locales/Locales.xml
index e819376..af643ef 100644
--- a/Jamba-Trade/Locales/Locales.xml
+++ b/Jamba-Trade/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba/.pkgmeta b/Jamba/.pkgmeta
new file mode 100644
index 0000000..802f083
--- /dev/null
+++ b/Jamba/.pkgmeta
@@ -0,0 +1,23 @@
+package-as: Jamba
+
+manual-changelog: CHANGELOG.txt
+
+enable-nolib-creation: no
+
+move-folders:
+    Jamba/Modules/Jamba-DisplayTeam: Jamba-DisplayTeam
+    Jamba/Modules/Jamba-Follow: Jamba-Follow
+    Jamba/Modules/Jamba-FTL: Jamba-FTL
+    Jamba/Modules/Jamba-ItemUse: Jamba-ItemUse
+    Jamba/Modules/Jamba-Proc: Jamba-Proc
+    Jamba/Modules/Jamba-Purchase: Jamba-Purchase
+    Jamba/Modules/Jamba-Quest: Jamba-Quest
+	Jamba/Modules/Jamba-QuestWatcher: Jamba-QuestWatcher
+    Jamba/Modules/Jamba-Sell: Jamba-Sell
+    Jamba/Modules/Jamba-Talk: Jamba-Talk
+    Jamba/Modules/Jamba-Taxi: Jamba-Taxi
+    Jamba/Modules/Jamba-Toon: Jamba-Toon
+    Jamba/Modules/Jamba-Trade: Jamba-Trade
+    Jamba/Modules/Jamba-AdvancedLoot: Jamba-AdvancedLoot
+	Jamba/Modules/Jamba-Curr: Jamba-Curr
+	Jamba/Modules/Jamba-Mount: Jamba-Mount
\ No newline at end of file
diff --git a/Jamba/AceGUIContainer-JambaWindow.lua b/Jamba/AceGUIContainer-JambaWindow.lua
index 9b84543..ddc387e 100644
--- a/Jamba/AceGUIContainer-JambaWindow.lua
+++ b/Jamba/AceGUIContainer-JambaWindow.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba4 - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License

 Changed to a Newer Ace3 By Ebony
diff --git a/Jamba/AceGUIWidget-JambaContinueLabel.lua b/Jamba/AceGUIWidget-JambaContinueLabel.lua
index 7be5993..00b934a 100644
--- a/Jamba/AceGUIWidget-JambaContinueLabel.lua
+++ b/Jamba/AceGUIWidget-JambaContinueLabel.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License


diff --git a/Jamba/AceGUIWidget-JambaNormalLabel.lua b/Jamba/AceGUIWidget-JambaNormalLabel.lua
index ab55d07..6ca9bf1 100644
--- a/Jamba/AceGUIWidget-JambaNormalLabel.lua
+++ b/Jamba/AceGUIWidget-JambaNormalLabel.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller

 License: The MIT License
 ]]--
diff --git a/Jamba/Bindings.xml b/Jamba/Bindings.xml
index 017fcf7..84424df 100644
--- a/Jamba/Bindings.xml
+++ b/Jamba/Bindings.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->

diff --git a/Jamba/CHANGELOG.txt b/Jamba/CHANGELOG.txt
index d168679..2efce1f 100644
--- a/Jamba/CHANGELOG.txt
+++ b/Jamba/CHANGELOG.txt
@@ -1,6 +1,105 @@
 ---------------------------
 ChangeLogs:
 ---------------------------
+Jamba Version: 5.4.1
+WoW Game Version: 7.3.5
+File Version: 7.3.5-5.4.1
+Release Date: 1/2/2018
+Modules Changed: Follow
+
+*Jamba-Follow
+	- Does not follow if your eating or drinking Mage food. If food/drink option is ticked
+
+*Core
+	- Fixed the sound problem and now runs on "soundChannel" Ambience from Master.
+
+
+---------------------------
+ChangeLogs:
+---------------------------
+Jamba Version: 5.4.0/a
+WoW Game Version: 7.3.5
+File Version: 7.3.5-5.4.0
+Release Date: 26/1/2018
+Modules Changed: Core, Jamba-item-use, Jamba-Mount, Jamba-Sell, jamba-Currency
+
+*Core	- Happy New year! Updated Copyright Dates!
+	- UpDated Ace3
+	- Updated LibActionButton (rev 72)
+	- Lowered Default Warning Sound.
+
+*Jamba-Item-Use
+	- Fixed missing code form Satchel items not on ItemBar
+	- Updated LibActionButton
+
+*Jamba-Mount
+	- Mount changes should pick the mount better.
+
+*Team-Display
+	- Vertical Character List Is Back! Some help from Jabberie.
+
+*Jamba-Sell
+	- Now Deletes item if does not have a vender price if (part of Alt click sell item on all toons)
+
+*Jamba-Currency
+	- Removed Writhig Essence
+	- Added Wakening-Essence
+
+---------------------------
+Jamba Version: 5.3.3
+WoW Game Version: 7.3
+File Version: 7.3.0-5.3.0
+Release Date: 6/10/2017
+Modules Changed: Jamba-Sell
+
+*Jamba-Advanced_Loot
+	- removed event LOOT_READY was making some players DC when the loot window was getting opened.
+
+*Jamba-Sell
+	- If item does not have sell price on sell:Other then deletes the item from bag. (helpful for stuff that does not sell thats junk)
+
+
+---------------------------
+Jamba Version: 5.3.2
+WoW Game Version: 7.3
+File Version: 7.3.0-5.3.0
+Release Date: 16/9/2017
+Modules Changed: Jamba-Sell, jamba-display_team, Jamba-trade
+
+
+*Jamba-sell
+	- Should sell Ilvl items right.
+	- Should now sell Artifact Relics.
+	- fixed a bug where it was not counting gold and items sold in a stack.
+
+*Jamba-Display_Team
+	- Fixed a bug where the colour on the class power Bar was not showen right.
+	- Added Extra infomation to the Artifact Bar  how many points ready to spend +Number , and points spent. ( no + )
+		--And to Show Honor Bar prestigeLevel and Honor levels.
+
+*Jamba-trade
+	- money to and from the GuildBank should work again ( 7.3 add somekinda delay )
+
+
+*jamba-Currency
+	- Removed Argus Waystone was removed as a Currency.
+
+
+
+---------------------------
+Jamba Version: 5.3.1
+WoW Game Version: 7.3
+File Version: 7.3.0-5.3.0
+Release Date: 31/8/2017
+Modules Changed: Jamba-Trade
+
+*Jamba-Trade
+	- fixed a bug where BoE and Crafting Reagents was not get checking against the team list.
+
+
+
+
+---------------------------
 Jamba Version: 5.3.0
 WoW Game Version: 7.3
 File Version: 7.3.0-5.3.0
@@ -41,7 +140,7 @@ Modules Removed: Macros, Target
 	- Updated Trade BoE to support the new tooltip Scanner

 *jamba-Currency
-	- if the minion is Maxed on a currency type (EG can not have anymore of that currency ) then the text will show red.
+	- if the minion is Maxed on a currency type (EG can not have anymore of that currency ) then the Click will show red.
 	- Changed FrameStrata from "BACKGROUND" to "LOW" (ticket #182) ((PS: I guess a dropdown list would be better))
 	- Added 7.3 currencies:
 		- Writhing Essence
@@ -87,8 +186,8 @@ Modules Changed: Core, Display-Team, Quest-Watcher, Jamba-Team, Jamba-Trade, Jam
 	- Fixed bug #117

 *Jamba-ItemUse
-	- Fixed a buged where Emissary quest items Nolonger would show on bar.
-	- Nolonger adds LockBox to the Item-Bar
+	- Fixed a buged where Emissary quest items No longer would show on bar.
+	- No longer adds LockBox to the Item-Bar

 *Jamba-Team
 	- added Enhancement #179*
@@ -172,11 +271,11 @@ Modules Changed: Core, Toon, Trade, Team, Mount, Trade, Currency, Taxi, Quest, F
 *Jamba-Team
 	- Added a option to set all members to assistant when you join a raid group.
 	- Remove command "/jamba-team InviteTag".
-	- "/Jamba-Team Invite" now support's <Tag>
+	- "/Jamba-Team Invite" now supports <Tag>
 	- If Tag is Unknown it will tell you.

 *Jamba-Taxi
-	- Changed default Taxi dely to 2 sec, added in 0.5sec max 5 sec now.
+	- Changed default Taxi delay to 2 sec, added in 0.5sec max 5 sec now.
 	- When Closing out the Taxi Frame the Team will close as well.

 *Jamba-Mount
@@ -189,7 +288,7 @@ Modules Changed: Core, Toon, Trade, Team, Mount, Trade, Currency, Taxi, Quest, F
 	- Updated the speed the follow message gets sent by 0.5 secs.

 *Jamba-Team_Display
-	- Added a glow effect when follow brecks on the Display-team bar.
+	- Added a glow effect when follow breaks on the Display-team bar.

 ---------------------------
 Jamba Version: 5.1.7
@@ -350,7 +449,7 @@ Modules: AdvancedLoot, Core, Display-Team, Follow, FTL, ItemUse, Macro, Purchase
 	- Updated Ace3 to the newest and lastest

 *Jamba-Quest-Tracker
-	-No Longer Spams Quest objective Text.
+	-No Longer Spams Quest objective Click.

 *Jamba-Display-Team
 	-Will Now Send Font Size with team settings.
@@ -379,7 +478,7 @@ Initial Legion Release.

 *Jamba-Core
     - Some Back-End Work for Legion/7.0.x
-    - New tooltips on the options config to help make it easier to understand what some buttons to do and to clean up some of the long line texts.
+    - New tooltips on the options config to help make it easier to understand what some buttons to do and to clean up some of the long line Clicks.
     - Changed Help to Commands - as it shows more of the command Line stuff.
     - If a Module is not loaded on all characters then it no longer Lua-Error and tells the client what Module will need to be loaded.
     - Updated LibActionButton
@@ -401,7 +500,7 @@ Initial Legion Release.
         - Shows Bouns Scenario Objective.
         - Fixed with Broken Shore QuestLines a % bar needed coding in.
         - Only Show stage if there is more the one stage (so does not show in dungeons.)
-        - Added support to change the font And text size
+        - Added support to change the font And Click size
 		- Now automatically sets the frame to the Right Hand Side of the UI.

 * Jamba-Quest
@@ -424,7 +523,7 @@ Initial Legion Release.
 *Jamba-Display-Team
     - Values are now Abbreviated to smaller Numbers.
     - No longer Shows max Value when showing Percentage
-    - Added support to change the font And text size
+    - Added support to change the font And Click size
     - Added a NewTooltip when you hover over Follow bar to show
         - Level of minion If not level capped.
         - ItemLevel of minion.
@@ -462,17 +561,17 @@ Initial Legion Release.
     **- You can now add Currency IDs with one line in the config file if you need to.
     - There is a now a DropDown Box to show the Currency's you like to show
     - You can Have a max of 6 Currencies.
-    - Now shows Currency Icon Then The Three Letters of text.
+    - Now shows Currency Icon Then The Three Letters of Click.
     - Now shows the Currency Gold Icons when showing gold/Sliver/Copper
     - No Longer Shows Currency for Offline minions.
     - Should Now Order minions That are Offline/Online correctly.
-    - Added support to change the font And text size.
+    - Added support to change the font And Click size.

 * Jamba-Taxi
     - Fixed a Frame Bug with The new flight maps in broken island (Legion Zones)

 * Jamba-AdvancedLoot
-    - Fixed a text bug that was not working with trade goods. (cloth)
+    - Fixed a Click bug that was not working with trade goods. (cloth)
     - Personal-Loot OverRights The Advanced Loot list.

 * Jamba-ItemUse
@@ -529,7 +628,7 @@ Modules: AdvancedLoot, Core, Display-Team, Follow, FTL, ItemUse, Macro, Proc, Pu
 *Jamba-Toon
  - new Currency's
 	- Added Valor points back.
-	- Fixed timewalker Currency to show the right Text.
+	- Fixed timewalker Currency to show the right Click.

 *Jamba-team-display
 	- Now Displays the word "DEAD" when the character is DEAD! and not 0%
@@ -578,7 +677,7 @@ Modules: AdvancedLoot, Core, Display-Team, Follow, FTL, ItemUse, Macro, Proc, Pu

 *Jamba-Display-Team
  - Player/Minions Level should once again update When the player levels.
- - Added a Option to stack the text on Jamba-Display Follow Text (Level & ilvl).
+ - Added a Option to stack the Click on Jamba-Display Follow Click (Level & ilvl).

 Jamba-Toon
  - Added 6.2.0 Currency's
@@ -782,12 +881,12 @@ Jamba-Team:
 *Sometimes invite is from XREALM even though Your on the same realm and have already joined the party no longer will the StaticPopup stay.

 Jamba-Quest:
-*Cleared up quest Text from clones when in fact they have not even picked up a quest they still said Accepted Quest:.
+*Cleared up quest Click from clones when in fact they have not even picked up a quest they still said Accepted Quest:.
 *Fixed AutoPickUpQuests (quests at starting zones) Should now work like normal quests! -- did not make it to live build.
 *Fixed a Lua error that sometimes was showing on clones screen when using the jamba-quest-bar.

 Jamba-Toon:
-* Added: Auto Accept Summon No Longer do you need to Click that summon box. With cool text that says the PlayerName and where the clone went.
+* Added: Auto Accept Summon No Longer do you need to Click that summon box. With cool Click that says the PlayerName and where the clone went.

 Jamba-Communications:
 *Added Party Communications again when your in a party if not in own party with member of the team should send that char a /w.
@@ -1453,7 +1552,7 @@ Modules: Core, Display-Team, Follow, FTL, ItemUse, Macro, Proc, Purchase, Quest,

 General

-	* Text boxes associated with sliders will now cause the slider to update its value when enter is pressed.
+	* Click boxes associated with sliders will now cause the slider to update its value when enter is pressed.

 Jamba-Proc

@@ -1502,14 +1601,14 @@ Modules: Core, Display-Team, Follow, FTL, ItemUse, Macro, Proc, Purchase, Quest,

 Jamba-Proc

-    * Overhauled - can now move location of bars, set bar texture, font, size.
+    * Overhauled - can now move location of bars, set bar Clickure, font, size.
     * Procs are now based on spell ID rather than name.
     * Can specify proc colour / sound on a per tag basis.
     * Way better, check it out!

 Jamba General Bug Fix

-    * Fixed an issue with textures no longer stretching due to a change in the wow api for 3.3.3.
+    * Fixed an issue with Clickures no longer stretching due to a change in the wow api for 3.3.3.

 Jamba-Team

@@ -1525,7 +1624,7 @@ Modules: Core, Display-Team, Follow, FTL, ItemUse, Macro, Proc, Purchase, Quest,

 Jamba-Talk

-    * Chat snippets now need to be enabled, by checking the check box that says "Enable Chat Snippets".  Chat snippets can be whispered without need to reply to someone.  For example a chat snippet called "mb" with the text explaining about multiboxing can be whispered by typing: /w toon !mb
+    * Chat snippets now need to be enabled, by checking the check box that says "Enable Chat Snippets".  Chat snippets can be whispered without need to reply to someone.  For example a chat snippet called "mb" with the Click explaining about multiboxing can be whispered by typing: /w toon !mb

 Jamba-Quest

@@ -1934,7 +2033,7 @@ Target & Focus
 New: Jamba-Follow

     * Move follow breaking warning from Jamba-Warning to Jamba-Follow.
-    * Add an option to specify the text when follow breaks - default to "Follow Broken".
+    * Add an option to specify the Click when follow breaks - default to "Follow Broken".
     * Automatic /follow from the slaves to the master when exiting combat.
     * /jamba-follow master <tag>
     * /jamba-follow target <target> <tag>
@@ -1954,7 +2053,7 @@ Jamba-Group
 New: Jamba-Me

     * Moved health, mana, hit warnings configuration from Jamba-Warning.
-    * Add option to specific messages when hit,health, etc in text fields.
+    * Add option to specific messages when hit,health, etc in Click fields.
     * Automatically accept resurrection requests (from members).

 Jamba-Merchant
diff --git a/Jamba/Jamba.toc b/Jamba/Jamba.toc
index 46c8952..530f256 100644
--- a/Jamba/Jamba.toc
+++ b/Jamba/Jamba.toc
@@ -2,7 +2,7 @@
 ## Title: Jamba
 ## Notes: Jamba
 ## Author: Ebony, Former Author: Jafula
-## Version: 5.3.0
+## Version: 5.4.1
 ## SavedVariables: JambaCoreProfileDB, JambaCommunicationsProfileDB, JambaTeamProfileDB, JambaTagProfileDB, JambaMessageProfileDB
 JambaEmbeds.xml
 JambaUtilities.lua
diff --git a/Jamba/JambaEmbeds.xml b/Jamba/JambaEmbeds.xml
index 9788a46..31f4030 100644
--- a/Jamba/JambaEmbeds.xml
+++ b/Jamba/JambaEmbeds.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 http://jafula.com/jamba/
 -->
diff --git a/Jamba/JambaMessage.lua b/Jamba/JambaMessage.lua
index db70abc..666779d 100644
--- a/Jamba/JambaMessage.lua
+++ b/Jamba/JambaMessage.lua
@@ -925,7 +925,7 @@ local function DisplayMessageMikSBT( sender, message, areaOnScreenName, suppress
 end

 local function PlayMessageSound( soundToPlay )
-	PlaySoundFile( Media:Fetch( 'sound', soundToPlay ), "Master" )
+	PlaySoundFile( Media:Fetch( 'sound', soundToPlay ), "Ambience" )
 end

 local function ProcessReceivedMessage( sender, areaName, message, suppressSender, ... )
@@ -1033,4 +1033,4 @@ JambaPrivate.Message.SendMessage = SendMessage
 JambaApi.MessageAreaList = MessageAreaList
 JambaApi.DefaultMessageArea = DefaultMessageArea
 JambaApi.DefaultWarningArea = DefaultWarningArea
-JambaApi.MESSAGE_MESSAGE_AREAS_CHANGED = AJM.MESSAGE_MESSAGE_AREAS_CHANGED
\ No newline at end of file
+JambaApi.MESSAGE_MESSAGE_AREAS_CHANGED = AJM.MESSAGE_MESSAGE_AREAS_CHANGED
diff --git a/Jamba/JambaModule.lua b/Jamba/JambaModule.lua
index 35ee227..70136ae 100644
--- a/Jamba/JambaModule.lua
+++ b/Jamba/JambaModule.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba/JambaTag.lua b/Jamba/JambaTag.lua
index 1dc7b49..02eb6d2 100644
--- a/Jamba/JambaTag.lua
+++ b/Jamba/JambaTag.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License


diff --git a/Jamba/JambaTeam.lua b/Jamba/JambaTeam.lua
index 32fc934..988d25c 100644
--- a/Jamba/JambaTeam.lua
+++ b/Jamba/JambaTeam.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller


 License: The MIT License
diff --git a/Jamba/JambaUtilities.lua b/Jamba/JambaUtilities.lua
index 682ae3d..d66627a 100644
--- a/Jamba/JambaUtilities.lua
+++ b/Jamba/JambaUtilities.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2017 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

@@ -60,6 +60,9 @@ end

 --AddRealmToNameIfMissing Blizzard Code does not like spaces in the realm name GetRealmName() pulls back the name with a Space Unwanted for most of the stuff we need to do.
 function JambaUtilities:AddRealmToNameIfMissing( name )
+	if name == nil then
+		return
+	end
 	Name = name:gsub("^%l", string.upper )
 	fullName = Name:gsub( "%s+", "")
 	local matchDash = fullName:find( "-" )
@@ -272,4 +275,23 @@ function JambaUtilities:ToolTipBagScaner(item, bag, slot)
 	    tooltipbagScanner:Hide()
 		return boe
 	end
-end
\ No newline at end of file
+end
+
+-- GetPetOwner
+function JambaUtilities:getPetOwner( petName )
+	--print(petName)
+	if petName ~= nil then
+		local tooltipName = "AJMPetScanner"
+		local tooltipScanner = CreateFrame("GameTooltip", tooltipName, nil, "GameTooltipTemplate")
+		tooltipScanner:ClearLines()
+		tooltipScanner:SetOwner(WorldFrame, "ANCHOR_NONE")
+		tooltipScanner:SetUnit( petName )
+		local ownerName = _G[tooltipName.."TextLeft2"]:GetText() -- This is the line with <[Player]'s Pet>
+		if not ownerName then
+			 return nil
+		end
+		local owner, _ = string.split("'",ownerName)
+		return owner -- This is the pet's owner
+	--	print(owner)
+	end
+end
diff --git a/Jamba/LICENSE b/Jamba/LICENSE
index 46eaad7..e5b9691 100644
--- a/Jamba/LICENSE
+++ b/Jamba/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)

-Copyright (c) 2008-2017  Michael "Jafula" Miller
+Copyright (c) 2008-2018  Michael "Jafula" Miller

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/Jamba/LibActionButton-1.0.lua b/Jamba/LibActionButton-1.0.lua
deleted file mode 100644
index 4c85882..0000000
--- a/Jamba/LibActionButton-1.0.lua
+++ /dev/null
@@ -1,1542 +0,0 @@
---[[
-Copyright (c) 2010-2014, Hendrik "nevcairiel" Leppkes <h.leppkes@gmail.com>
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of the developer nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-]]
-local MAJOR_VERSION = "LibActionButton-1.0"
-local MINOR_VERSION = 53
-
-if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
-local lib, oldversion = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
-if not lib then return end
-
--- Lua functions
-local _G = _G
-local type, error, tostring, tonumber, assert, select = type, error, tostring, tonumber, assert, select
-local setmetatable, wipe, unpack, pairs, next = setmetatable, wipe, unpack, pairs, next
-local str_match, format, tinsert, tremove = string.match, format, tinsert, tremove
-
--- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
--- List them here for Mikk's FindGlobals script
--- Note: No WoW API function get upvalued to allow proper interaction with any addons that try to hook them.
--- GLOBALS: LibStub, CreateFrame, InCombatLockdown, ClearCursor, GetCursorInfo, GameTooltip, GameTooltip_SetDefaultAnchor
--- GLOBALS: GetBindingKey, GetBindingText, SetBinding, SetBindingClick, GetCVar, GetMacroInfo
--- GLOBALS: PickupAction, PickupItem, PickupMacro, PickupPetAction, PickupSpell, PickupCompanion, PickupEquipmentSet
--- GLOBALS: CooldownFrame_SetTimer, UIParent, IsSpellOverlayed, SpellFlyout, GetMouseFocus, SetClampedTextureRotation
--- GLOBALS: GetActionInfo, GetActionTexture, HasAction, GetActionText, GetActionCount, GetActionCooldown, IsAttackAction
--- GLOBALS: IsAutoRepeatAction, IsEquippedAction, IsCurrentAction, IsConsumableAction, IsUsableAction, IsStackableAction, IsActionInRange
--- GLOBALS: GetSpellLink, GetMacroSpell, GetSpellTexture, GetSpellCount, GetSpellCooldown, IsAttackSpell, IsCurrentSpell
--- GLOBALS: FindSpellBookSlotBySpellID, IsUsableSpell, IsConsumableSpell, IsSpellInRange, IsAutoRepeatSpell
--- GLOBALS: GetItemIcon, GetItemCount, GetItemCooldown, IsEquippedItem, IsCurrentItem, IsUsableItem, IsConsumableItem, IsItemInRange
--- GLOBALS: GetActionCharges, IsItemAction, GetSpellCharges
--- GLOBALS: RANGE_INDICATOR, ATTACK_BUTTON_FLASH_TIME, TOOLTIP_UPDATE_TIME
-
-local KeyBound = LibStub("LibKeyBound-1.0", true)
-local CBH = LibStub("CallbackHandler-1.0")
-
-lib.eventFrame = lib.eventFrame or CreateFrame("Frame")
-lib.eventFrame:UnregisterAllEvents()
-
-lib.buttonRegistry = lib.buttonRegistry or {}
-lib.activeButtons = lib.activeButtons or {}
-lib.actionButtons = lib.actionButtons or {}
-lib.nonActionButtons = lib.nonActionButtons or {}
-
-lib.unusedOverlayGlows = lib.unusedOverlayGlows or {}
-lib.numOverlays = lib.numOverlays or 0
-
-lib.ACTION_HIGHLIGHT_MARKS = lib.ACTION_HIGHLIGHT_MARKS or setmetatable({}, { __index = ACTION_HIGHLIGHT_MARKS })
-
-lib.callbacks = lib.callbacks or CBH:New(lib)
-
-local Generic = CreateFrame("CheckButton")
-local Generic_MT = {__index = Generic}
-
-local Action = setmetatable({}, {__index = Generic})
-local Action_MT = {__index = Action}
-
-local PetAction = setmetatable({}, {__index = Generic})
-local PetAction_MT = {__index = PetAction}
-
-local Spell = setmetatable({}, {__index = Generic})
-local Spell_MT = {__index = Spell}
-
-local Item = setmetatable({}, {__index = Generic})
-local Item_MT = {__index = Item}
-
-local Macro = setmetatable({}, {__index = Generic})
-local Macro_MT = {__index = Macro}
-
-local Custom = setmetatable({}, {__index = Generic})
-local Custom_MT = {__index = Custom}
-
-local type_meta_map = {
-	empty  = Generic_MT,
-	action = Action_MT,
-	--pet    = PetAction_MT,
-	spell  = Spell_MT,
-	item   = Item_MT,
-	macro  = Macro_MT,
-	custom = Custom_MT
-}
-
-local ButtonRegistry, ActiveButtons, ActionButtons, NonActionButtons = lib.buttonRegistry, lib.activeButtons, lib.actionButtons, lib.nonActionButtons
-
-local Update, UpdateButtonState, UpdateUsable, UpdateCount, UpdateCooldown, UpdateTooltip, UpdateNewAction
-local StartFlash, StopFlash, UpdateFlash, UpdateHotkeys, UpdateRangeTimer, UpdateOverlayGlow
-local UpdateFlyout, ShowGrid, HideGrid, UpdateGrid, SetupSecureSnippets, WrapOnClick
-local ShowOverlayGlow, HideOverlayGlow, GetOverlayGlow, OverlayGlowAnimOutFinished
-
-local InitializeEventHandler, OnEvent, ForAllButtons, OnUpdate
-
-local DefaultConfig = {
-	outOfRangeColoring = "button",
-	tooltip = "enabled",
-	showGrid = false,
-	colors = {
-		range = { 0.8, 0.1, 0.1 },
-		mana = { 0.5, 0.5, 1.0 }
-	},
-	hideElements = {
-		macro = false,
-		hotkey = false,
-		equipped = false,
-	},
-	keyBoundTarget = false,
-	clickOnDown = false,
-	flyoutDirection = "UP",
-}
-
---- Create a new action button.
--- @param id Internal id of the button (not used by LibActionButton-1.0, only for tracking inside the calling addon)
--- @param name Name of the button frame to be created (not used by LibActionButton-1.0 aside from naming the frame)
--- @param header Header that drives these action buttons (if any)
-function lib:CreateButton(id, name, header, config)
-	if type(name) ~= "string" then
-		error("Usage: CreateButton(id, name. header): Buttons must have a valid name!", 2)
-	end
-	if not header then
-		error("Usage: CreateButton(id, name, header): Buttons without a secure header are not yet supported!", 2)
-	end
-
-	if not KeyBound then
-		KeyBound = LibStub("LibKeyBound-1.0", true)
-	end
-
-	local button = setmetatable(CreateFrame("CheckButton", name, header, "SecureActionButtonTemplate, ActionButtonTemplate"), Generic_MT)
-	button:RegisterForDrag("LeftButton", "RightButton")
-	button:RegisterForClicks("AnyUp")
-
-	-- Frame Scripts
-	button:SetScript("OnEnter", Generic.OnEnter)
-	button:SetScript("OnLeave", Generic.OnLeave)
-	button:SetScript("PreClick", Generic.PreClick)
-	button:SetScript("PostClick", Generic.PostClick)
-
-	button.id = id
-	button.header = header
-	-- Mapping of state -> action
-	button.state_types = {}
-	button.state_actions = {}
-
-	-- Store the LAB Version that created this button for debugging
-	button.__LAB_Version = MINOR_VERSION
-
-	-- just in case we're not run by a header, default to state 0
-	button:SetAttribute("state", 0)
-
-	SetupSecureSnippets(button)
-	WrapOnClick(button)
-
-	-- adjust hotkey style for better readability
-	button.HotKey:SetFont(button.HotKey:GetFont(), 13, "OUTLINE")
-	button.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-
-	-- Store the button in the registry, needed for event and OnUpdate handling
-	if not next(ButtonRegistry) then
-		InitializeEventHandler()
-	end
-	ButtonRegistry[button] = true
-
-	button:UpdateConfig(config)
-
-	-- run an initial update
-	button:UpdateAction()
-	UpdateHotkeys(button)
-
-	-- somewhat of a hack for the Flyout buttons to not error.
-	button.action = 0
-
-	lib.callbacks:Fire("OnButtonCreated", button)
-
-	return button
-end
-
-function SetupSecureSnippets(button)
-	button:SetAttribute("_custom", Custom.RunCustom)
-	-- secure UpdateState(self, state)
-	-- update the type and action of the button based on the state
-	button:SetAttribute("UpdateState", [[
-		local state = ...
-		self:SetAttribute("state", state)
-		local type, action = (self:GetAttribute(format("labtype-%s", state)) or "empty"), self:GetAttribute(format("labaction-%s", state))
-
-		self:SetAttribute("type", type)
-		if type ~= "empty" and type ~= "custom" then
-			local action_field = (type == "pet") and "action" or type
-			self:SetAttribute(action_field, action)
-			self:SetAttribute("action_field", action_field)
-		end
-		local onStateChanged = self:GetAttribute("OnStateChanged")
-		if onStateChanged then
-			self:Run(onStateChanged, state, type, action)
-		end
-	]])
-
-	-- this function is invoked by the header when the state changes
-	button:SetAttribute("_childupdate-state", [[
-		self:RunAttribute("UpdateState", message)
-		self:CallMethod("UpdateAction")
-	]])
-
-	-- secure PickupButton(self, kind, value, ...)
-	-- utility function to place a object on the cursor
-	button:SetAttribute("PickupButton", [[
-		local kind, value = ...
-		if kind == "empty" then
-			return "clear"
-		elseif kind == "action" or kind == "pet" then
-			local actionType = (kind == "pet") and "petaction" or kind
-			return actionType, value
-		elseif kind == "spell" or kind == "item" or kind == "macro" then
-			return "clear", kind, value
-		else
-			print("LibActionButton-1.0: Unknown type: " .. tostring(kind))
-			return false
-		end
-	]])
-
-	button:SetAttribute("OnDragStart", [[
-		if (self:GetAttribute("buttonlock") and not IsModifiedClick("PICKUPACTION")) or self:GetAttribute("LABdisableDragNDrop") then return false end
-		local state = self:GetAttribute("state")
-		local type = self:GetAttribute("type")
-		-- if the button is empty, we can't drag anything off it
-		if type == "empty" or type == "custom" then
-			return false
-		end
-		-- Get the value for the action attribute
-		local action_field = self:GetAttribute("action_field")
-		local action = self:GetAttribute(action_field)
-
-		-- non-action fields need to change their type to empty
-		if type ~= "action" and type ~= "pet" then
-			self:SetAttribute(format("labtype-%s", state), "empty")
-			self:SetAttribute(format("labaction-%s", state), nil)
-			-- update internal state
-			self:RunAttribute("UpdateState", state)
-			-- send a notification to the insecure code
-			self:CallMethod("ButtonContentsChanged", state, "empty", nil)
-		end
-		-- return the button contents for pickup
-		return self:RunAttribute("PickupButton", type, action)
-	]])
-
-	button:SetAttribute("OnReceiveDrag", [[
-		if self:GetAttribute("LABdisableDragNDrop") then return false end
-		local kind, value, subtype, extra = ...
-		if not kind or not value then return false end
-		local state = self:GetAttribute("state")
-		local buttonType, buttonAction = self:GetAttribute("type"), nil
-		if buttonType == "custom" then return false end
-		-- action buttons can do their magic themself
-		-- for all other buttons, we'll need to update the content now
-		if buttonType ~= "action" and buttonType ~= "pet" then
-			-- with "spell" types, the 4th value contains the actual spell id
-			if kind == "spell" then
-				if extra then
-					value = extra
-				else
-					print("no spell id?", ...)
-				end
-			elseif kind == "item" and value then
-				value = format("item:%d", value)
-			end
-
-			-- Get the action that was on the button before
-			if buttonType ~= "empty" then
-				buttonAction = self:GetAttribute(self:GetAttribute("action_field"))
-			end
-
-			-- TODO: validate what kind of action is being fed in here
-			-- We can only use a handful of the possible things on the cursor
-			-- return false for all those we can't put on buttons
-
-			self:SetAttribute(format("labtype-%s", state), kind)
-			self:SetAttribute(format("labaction-%s", state), value)
-			-- update internal state
-			self:RunAttribute("UpdateState", state)
-			-- send a notification to the insecure code
-			self:CallMethod("ButtonContentsChanged", state, kind, value)
-		else
-			-- get the action for (pet-)action buttons
-			buttonAction = self:GetAttribute("action")
-		end
-		return self:RunAttribute("PickupButton", buttonType, buttonAction)
-	]])
-
-	button:SetScript("OnDragStart", nil)
-	-- Wrapped OnDragStart(self, button, kind, value, ...)
-	button.header:WrapScript(button, "OnDragStart", [[
-		return self:RunAttribute("OnDragStart")
-	]])
-	-- Wrap twice, because the post-script is not run when the pre-script causes a pickup (doh)
-	-- we also need some phony message, or it won't work =/
-	button.header:WrapScript(button, "OnDragStart", [[
-		return "message", "update"
-	]], [[
-		self:RunAttribute("UpdateState", self:GetAttribute("state"))
-	]])
-
-	button:SetScript("OnReceiveDrag", nil)
-	-- Wrapped OnReceiveDrag(self, button, kind, value, ...)
-	button.header:WrapScript(button, "OnReceiveDrag", [[
-		return self:RunAttribute("OnReceiveDrag", kind, value, ...)
-	]])
-	-- Wrap twice, because the post-script is not run when the pre-script causes a pickup (doh)
-	-- we also need some phony message, or it won't work =/
-	button.header:WrapScript(button, "OnReceiveDrag", [[
-		return "message", "update"
-	]], [[
-		self:RunAttribute("UpdateState", self:GetAttribute("state"))
-	]])
-end
-
-function WrapOnClick(button)
-	-- Wrap OnClick, to catch changes to actions that are applied with a click on the button.
-	button.header:WrapScript(button, "OnClick", [[
-		if self:GetAttribute("type") == "action" then
-			local type, action = GetActionInfo(self:GetAttribute("action"))
-			return nil, format("%s|%s", tostring(type), tostring(action))
-		end
-	]], [[
-		local type, action = GetActionInfo(self:GetAttribute("action"))
-		if message ~= format("%s|%s", tostring(type), tostring(action)) then
-			self:RunAttribute("UpdateState", self:GetAttribute("state"))
-		end
-	]])
-end
-
------------------------------------------------------------
---- utility
-
-function lib:GetAllButtons()
-	local buttons = {}
-	for button in next, ButtonRegistry do
-		buttons[button] = true
-	end
-	return buttons
-end
-
-function Generic:ClearSetPoint(...)
-	self:ClearAllPoints()
-	self:SetPoint(...)
-end
-
-function Generic:NewHeader(header)
-	self.header = header
-	self:SetParent(header)
-	SetupSecureSnippets(self)
-	WrapOnClick(self)
-end
-
-
------------------------------------------------------------
---- state management
-
-function Generic:ClearStates()
-	for state in pairs(self.state_types) do
-		self:SetAttribute(format("labtype-%s", state), nil)
-		self:SetAttribute(format("labaction-%s", state), nil)
-	end
-	wipe(self.state_types)
-	wipe(self.state_actions)
-end
-
-function Generic:SetState(state, kind, action)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	-- we allow a nil kind for setting a empty state
-	if not kind then kind = "empty" end
-	if not type_meta_map[kind] then
-		error("SetStateAction: unknown action type: " .. tostring(kind), 2)
-	end
-	if kind ~= "empty" and action == nil then
-		error("SetStateAction: an action is required for non-empty states", 2)
-	end
-	if kind ~= "custom" and action ~= nil and type(action) ~= "number" and type(action) ~= "string" or (kind == "custom" and type(action) ~= "table") then
-		error("SetStateAction: invalid action data type, only strings and numbers allowed", 2)
-	end
-
-	if kind == "item" then
-		if tonumber(action) then
-			action = format("item:%s", action)
-		else
-			local itemString = str_match(action, "^|c%x+|H(item[%d:]+)|h%[")
-			if itemString then
-				action = itemString
-			end
-		end
-	end
-
-	self.state_types[state] = kind
-	self.state_actions[state] = action
-	self:UpdateState(state)
-end
-
-function Generic:UpdateState(state)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	self:SetAttribute(format("labtype-%s", state), self.state_types[state])
-	self:SetAttribute(format("labaction-%s", state), self.state_actions[state])
-	if state ~= tostring(self:GetAttribute("state")) then return end
-	if self.header then
-		self.header:SetFrameRef("updateButton", self)
-		self.header:Execute([[
-			local frame = self:GetFrameRef("updateButton")
-			control:RunFor(frame, frame:GetAttribute("UpdateState"), frame:GetAttribute("state"))
-		]])
-	else
-	-- TODO
-	end
-	self:UpdateAction()
-end
-
-function Generic:GetAction(state)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	return self.state_types[state] or "empty", self.state_actions[state]
-end
-
-function Generic:UpdateAllStates()
-	for state in pairs(self.state_types) do
-		self:UpdateState(state)
-	end
-end
-
-function Generic:ButtonContentsChanged(state, kind, value)
-	state = tostring(state)
-	self.state_types[state] = kind or "empty"
-	self.state_actions[state] = value
-	lib.callbacks:Fire("OnButtonContentsChanged", self, state, self.state_types[state], self.state_actions[state])
-	self:UpdateAction(self)
-end
-
-function Generic:DisableDragNDrop(flag)
-	if InCombatLockdown() then
-		error("LibActionButton-1.0: You can only toggle DragNDrop out of combat!", 2)
-	end
-	if flag then
-		self:SetAttribute("LABdisableDragNDrop", true)
-	else
-		self:SetAttribute("LABdisableDragNDrop", nil)
-	end
-end
-
-function Generic:AddToButtonFacade(group)
-	if type(group) ~= "table" or type(group.AddButton) ~= "function" then
-		error("LibActionButton-1.0:AddToButtonFacade: You need to supply a proper group to use!", 2)
-	end
-	group:AddButton(self)
-	self.LBFSkinned = true
-end
-
-function Generic:AddToMasque(group)
-	if type(group) ~= "table" or type(group.AddButton) ~= "function" then
-		error("LibActionButton-1.0:AddToMasque: You need to supply a proper group to use!", 2)
-	end
-	group:AddButton(self)
-	self.MasqueSkinned = true
-end
-
-function Generic:UpdateAlpha()
-	UpdateCooldown(self)
-end
-
------------------------------------------------------------
---- frame scripts
-
--- copied (and adjusted) from SecureHandlers.lua
-local function PickupAny(kind, target, detail, ...)
-	if kind == "clear" then
-		ClearCursor()
-		kind, target, detail = target, detail, ...
-	end
-
-	if kind == 'action' then
-		PickupAction(target)
-	elseif kind == 'item' then
-		PickupItem(target)
-	elseif kind == 'macro' then
-		PickupMacro(target)
-	elseif kind == 'petaction' then
-		PickupPetAction(target)
-	elseif kind == 'spell' then
-		PickupSpell(target)
-	elseif kind == 'companion' then
-		PickupCompanion(target, detail)
-	elseif kind == 'equipmentset' then
-		PickupEquipmentSet(target)
-	end
-end
-
-function Generic:OnEnter()
-	if self.config.tooltip ~= "disabled" and (self.config.tooltip ~= "nocombat" or not InCombatLockdown()) then
-		UpdateTooltip(self)
-	end
-	if KeyBound then
-		KeyBound:Set(self)
-	end
-
-	if self._state_type == "action" and self.NewActionTexture then
-		lib.ACTION_HIGHLIGHT_MARKS[self._state_action] = false
-		UpdateNewAction(self)
-	end
-end
-
-function Generic:OnLeave()
-	GameTooltip:Hide()
-end
-
--- Insecure drag handler to allow clicking on the button with an action on the cursor
--- to place it on the button. Like action buttons work.
-function Generic:PreClick()
-	if self._state_type == "action" or self._state_type == "pet"
-	   or InCombatLockdown() or self:GetAttribute("LABdisableDragNDrop")
-	then
-		return
-	end
-	-- check if there is actually something on the cursor
-	local kind, value, subtype = GetCursorInfo()
-	if not (kind and value) then return end
-	self._old_type = self._state_type
-	if self._state_type and self._state_type ~= "empty" then
-		self._old_type = self._state_type
-		self:SetAttribute("type", "empty")
-		--self:SetState(nil, "empty", nil)
-	end
-	self._receiving_drag = true
-end
-
-local function formatHelper(input)
-	if type(input) == "string" then
-		return format("%q", input)
-	else
-		return tostring(input)
-	end
-end
-
-function Generic:PostClick()
-	UpdateButtonState(self)
-	if self._receiving_drag and not InCombatLockdown() then
-		if self._old_type then
-			self:SetAttribute("type", self._old_type)
-			self._old_type = nil
-		end
-		local oldType, oldAction = self._state_type, self._state_action
-		local kind, data, subtype, extra = GetCursorInfo()
-		self.header:SetFrameRef("updateButton", self)
-		self.header:Execute(format([[
-			local frame = self:GetFrameRef("updateButton")
-			control:RunFor(frame, frame:GetAttribute("OnReceiveDrag"), %s, %s, %s, %s)
-			control:RunFor(frame, frame:GetAttribute("UpdateState"), %s)
-		]], formatHelper(kind), formatHelper(data), formatHelper(subtype), formatHelper(extra), formatHelper(self:GetAttribute("state"))))
-		PickupAny("clear", oldType, oldAction)
-	end
-	self._receiving_drag = nil
-end
-
------------------------------------------------------------
---- configuration
-
-local function merge(target, source, default)
-	for k,v in pairs(default) do
-		if type(v) ~= "table" then
-			if source and source[k] ~= nil then
-				target[k] = source[k]
-			else
-				target[k] = v
-			end
-		else
-			if type(target[k]) ~= "table" then target[k] = {} else wipe(target[k]) end
-			merge(target[k], type(source) == "table" and source[k], v)
-		end
-	end
-	return target
-end
-
-function Generic:UpdateConfig(config)
-	if config and type(config) ~= "table" then
-		error("LibActionButton-1.0: UpdateConfig requires a valid configuration!", 2)
-	end
-	local oldconfig = self.config
-	if not self.config then self.config = {} end
-	-- merge the two configs
-	merge(self.config, config, DefaultConfig)
-
-	if self.config.outOfRangeColoring == "button" or (oldconfig and oldconfig.outOfRangeColoring == "button") then
-		UpdateUsable(self)
-	end
-	if self.config.outOfRangeColoring == "hotkey" then
-		self.outOfRange = nil
-	elseif oldconfig and oldconfig.outOfRangeColoring == "hotkey" then
-		self.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-	end
-
-	if self.config.hideElements.macro then
-		self.Name:Hide()
-	else
-		self.Name:Show()
-	end
-
-	self:SetAttribute("flyoutDirection", self.config.flyoutDirection)
-
-	UpdateHotkeys(self)
-	UpdateGrid(self)
-	Update(self)
-	self:RegisterForClicks(self.config.clickOnDown and "AnyDown" or "AnyUp")
-end
-
------------------------------------------------------------
---- event handler
-
-function ForAllButtons(method, onlyWithAction)
-	assert(type(method) == "function")
-	for button in next, (onlyWithAction and ActiveButtons or ButtonRegistry) do
-		method(button)
-	end
-end
-
-function InitializeEventHandler()
-	lib.eventFrame:SetScript("OnEvent", OnEvent)
-	lib.eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_SHOWGRID")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_HIDEGRID")
-	--lib.eventFrame:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
-	--lib.eventFrame:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
-	lib.eventFrame:RegisterEvent("UPDATE_BINDINGS")
-	lib.eventFrame:RegisterEvent("UPDATE_SHAPESHIFT_FORM")
-	lib.eventFrame:RegisterEvent("UPDATE_VEHICLE_ACTIONBAR")
-
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_STATE")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
-	lib.eventFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
-	lib.eventFrame:RegisterEvent("TRADE_SKILL_SHOW")
-	lib.eventFrame:RegisterEvent("TRADE_SKILL_CLOSE")
-	lib.eventFrame:RegisterEvent("ARCHAEOLOGY_CLOSED")
-	lib.eventFrame:RegisterEvent("PLAYER_ENTER_COMBAT")
-	lib.eventFrame:RegisterEvent("PLAYER_LEAVE_COMBAT")
-	lib.eventFrame:RegisterEvent("START_AUTOREPEAT_SPELL")
-	lib.eventFrame:RegisterEvent("STOP_AUTOREPEAT_SPELL")
-	lib.eventFrame:RegisterEvent("UNIT_ENTERED_VEHICLE")
-	lib.eventFrame:RegisterEvent("UNIT_EXITED_VEHICLE")
-	lib.eventFrame:RegisterEvent("COMPANION_UPDATE")
-	lib.eventFrame:RegisterEvent("UNIT_INVENTORY_CHANGED")
-	lib.eventFrame:RegisterEvent("LEARNED_SPELL_IN_TAB")
-	lib.eventFrame:RegisterEvent("PET_STABLE_UPDATE")
-	lib.eventFrame:RegisterEvent("PET_STABLE_SHOW")
-	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_SHOW")
-	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_HIDE")
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_CHARGES")
-	lib.eventFrame:RegisterEvent("UPDATE_SUMMONPETS_ACTION")
-
-	-- With those two, do we still need the ACTIONBAR equivalents of them?
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_COOLDOWN")
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_USABLE")
-	lib.eventFrame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
-
-	lib.eventFrame:RegisterEvent("LOSS_OF_CONTROL_ADDED")
-	lib.eventFrame:RegisterEvent("LOSS_OF_CONTROL_UPDATE")
-
-	lib.eventFrame:Show()
-	lib.eventFrame:SetScript("OnUpdate", OnUpdate)
-end
-
-function OnEvent(frame, event, arg1, ...)
-	if (event == "UNIT_INVENTORY_CHANGED" and arg1 == "player") or event == "LEARNED_SPELL_IN_TAB" then
-		local tooltipOwner = GameTooltip:GetOwner()
-		if ButtonRegistry[tooltipOwner] then
-			tooltipOwner:SetTooltip()
-		end
-	elseif event == "ACTIONBAR_SLOT_CHANGED" then
-		for button in next, ButtonRegistry do
-			if button._state_type == "action" and (arg1 == 0 or arg1 == tonumber(button._state_action)) then
-				Update(button)
-			end
-		end
-	elseif event == "PLAYER_ENTERING_WORLD" or event == "UPDATE_SHAPESHIFT_FORM" or event == "UPDATE_VEHICLE_ACTIONBAR" then
-		ForAllButtons(Update)
-	elseif event == "ACTIONBAR_PAGE_CHANGED" or event == "UPDATE_BONUS_ACTIONBAR" then
-		-- TODO: Are these even needed?
-	elseif event == "ACTIONBAR_SHOWGRID" then
-		ShowGrid()
-	elseif event == "ACTIONBAR_HIDEGRID" then
-		HideGrid()
-	elseif event == "UPDATE_BINDINGS" then
-		ForAllButtons(UpdateHotkeys)
-	elseif event == "PLAYER_TARGET_CHANGED" then
-		UpdateRangeTimer()
-	elseif (event == "ACTIONBAR_UPDATE_STATE") or
-		((event == "UNIT_ENTERED_VEHICLE" or event == "UNIT_EXITED_VEHICLE") and (arg1 == "player")) or
-		((event == "COMPANION_UPDATE") and (arg1 == "MOUNT")) then
-		ForAllButtons(UpdateButtonState, true)
-	elseif event == "ACTIONBAR_UPDATE_USABLE" then
-		for button in next, ActionButtons do
-			UpdateUsable(button)
-		end
-	elseif event == "SPELL_UPDATE_USABLE" then
-		for button in next, NonActionButtons do
-			UpdateUsable(button)
-		end
-	elseif event == "ACTIONBAR_UPDATE_COOLDOWN" then
-		for button in next, ActionButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "SPELL_UPDATE_COOLDOWN" then
-		for button in next, NonActionButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "LOSS_OF_CONTROL_ADDED" then
-		for button in next, ActiveButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "LOSS_OF_CONTROL_UPDATE" then
-		for button in next, ActiveButtons do
-			UpdateCooldown(button)
-		end
-	elseif event == "TRADE_SKILL_SHOW" or event == "TRADE_SKILL_CLOSE"  or event == "ARCHAEOLOGY_CLOSED" then
-		ForAllButtons(UpdateButtonState, true)
-	elseif event == "PLAYER_ENTER_COMBAT" then
-		for button in next, ActiveButtons do
-			if button:IsAttack() then
-				StartFlash(button)
-			end
-		end
-	elseif event == "PLAYER_LEAVE_COMBAT" then
-		for button in next, ActiveButtons do
-			if button:IsAttack() then
-				StopFlash(button)
-			end
-		end
-	elseif event == "START_AUTOREPEAT_SPELL" then
-		for button in next, ActiveButtons do
-			if button:IsAutoRepeat() then
-				StartFlash(button)
-			end
-		end
-	elseif event == "STOP_AUTOREPEAT_SPELL" then
-		for button in next, ActiveButtons do
-			if button.flashing == 1 and not button:IsAttack() then
-				StopFlash(button)
-			end
-		end
-	elseif event == "PET_STABLE_UPDATE" or event == "PET_STABLE_SHOW" then
-		ForAllButtons(Update)
-	elseif event == "SPELL_ACTIVATION_OVERLAY_GLOW_SHOW" then
-		for button in next, ActiveButtons do
-			local spellId = button:GetSpellId()
-			if spellId and spellId == arg1 then
-				ShowOverlayGlow(button)
-			else
-				if button._state_type == "action" then
-					local actionType, id = GetActionInfo(button._state_action)
-					if actionType == "flyout" and FlyoutHasSpell(id, arg1) then
-						ShowOverlayGlow(button)
-					end
-				end
-			end
-		end
-	elseif event == "SPELL_ACTIVATION_OVERLAY_GLOW_HIDE" then
-		for button in next, ActiveButtons do
-			local spellId = button:GetSpellId()
-			if spellId and spellId == arg1 then
-				HideOverlayGlow(button)
-			else
-				if button._state_type == "action" then
-					local actionType, id = GetActionInfo(button._state_action)
-					if actionType == "flyout" and FlyoutHasSpell(id, arg1) then
-						HideOverlayGlow(button)
-					end
-				end
-			end
-		end
-	elseif event == "PLAYER_EQUIPMENT_CHANGED" then
-		for button in next, ActiveButtons do
-			if button._state_type == "item" then
-				Update(button)
-			end
-		end
-	elseif event == "SPELL_UPDATE_CHARGES" then
-		ForAllButtons(UpdateCount, true)
-	elseif event == "UPDATE_SUMMONPETS_ACTION" then
-		for button in next, ActiveButtons do
-			if button._state_type == "action" then
-				local actionType, id = GetActionInfo(button._state_action)
-				if actionType == "summonpet" then
-					local texture = GetActionTexture(button._state_action)
-					if texture then
-						button.icon:SetTexture(texture)
-					end
-				end
-			end
-		end
-	end
-end
-
-local flashTime = 0
-local rangeTimer = -1
-function OnUpdate(_, elapsed)
-	flashTime = flashTime - elapsed
-	rangeTimer = rangeTimer - elapsed
-	-- Run the loop only when there is something to update
-	if rangeTimer <= 0 or flashTime <= 0 then
-		for button in next, ActiveButtons do
-			-- Flashing
-			if button.flashing == 1 and flashTime <= 0 then
-				if button.Flash:IsShown() then
-					button.Flash:Hide()
-				else
-					button.Flash:Show()
-				end
-			end
-
-			-- Range
-			if rangeTimer <= 0 then
-				local inRange = button:IsInRange()
-				local oldRange = button.outOfRange
-				button.outOfRange = (inRange == false)
-				if oldRange ~= button.outOfRange then
-					if button.config.outOfRangeColoring == "button" then
-						UpdateUsable(button)
-					elseif button.config.outOfRangeColoring == "hotkey" then
-						local hotkey = button.HotKey
-						if hotkey:GetText() == RANGE_INDICATOR then
-							if inRange ~= nil then
-								hotkey:Show()
-							else
-								hotkey:Hide()
-							end
-						end
-						if inRange == false then
-							hotkey:SetVertexColor(unpack(button.config.colors.range))
-						else
-							hotkey:SetVertexColor(0.75, 0.75, 0.75)
-						end
-					end
-				end
-			end
-		end
-
-		-- Update values
-		if flashTime <= 0 then
-			flashTime = flashTime + ATTACK_BUTTON_FLASH_TIME
-		end
-		if rangeTimer <= 0 then
-			rangeTimer = TOOLTIP_UPDATE_TIME
-		end
-	end
-end
-
-local gridCounter = 0
-function ShowGrid()
-	gridCounter = gridCounter + 1
-	if gridCounter >= 1 then
-		for button in next, ButtonRegistry do
-			if button:IsShown() then
-				button:SetAlpha(1.0)
-			end
-		end
-	end
-end
-
-function HideGrid()
-	if gridCounter > 0 then
-		gridCounter = gridCounter - 1
-	end
-	if gridCounter == 0 then
-		for button in next, ButtonRegistry do
-			if button:IsShown() and not button:HasAction() and not button.config.showGrid then
-				button:SetAlpha(0.0)
-			end
-		end
-	end
-end
-
-function UpdateGrid(self)
-	if self.config.showGrid then
-		self:SetAlpha(1.0)
-	elseif gridCounter == 0 and self:IsShown() and not self:HasAction() then
-		self:SetAlpha(0.0)
-	end
-end
-
------------------------------------------------------------
---- KeyBound integration
-
-function Generic:GetBindingAction()
-	return self.config.keyBoundTarget or "CLICK "..self:GetName()..":LeftButton"
-end
-
-function Generic:GetHotkey()
-	local name = "CLICK "..self:GetName()..":LeftButton"
-	local key = GetBindingKey(self.config.keyBoundTarget or name)
-	if not key and self.config.keyBoundTarget then
-		key = GetBindingKey(name)
-	end
-	if key then
-		return KeyBound and KeyBound:ToShortKey(key) or key
-	end
-end
-
-local function getKeys(binding, keys)
-	keys = keys or ""
-	for i = 1, select("#", GetBindingKey(binding)) do
-		local hotKey = select(i, GetBindingKey(binding))
-		if keys ~= "" then
-			keys = keys .. ", "
-		end
-		keys = keys .. GetBindingText(hotKey, "KEY_")
-	end
-	return keys
-end
-
-function Generic:GetBindings()
-	local keys, binding
-
-	if self.config.keyBoundTarget then
-		keys = getKeys(self.config.keyBoundTarget)
-	end
-
-	keys = getKeys("CLICK "..self:GetName()..":LeftButton")
-
-	return keys
-end
-
-function Generic:SetKey(key)
-	if self.config.keyBoundTarget then
-		SetBinding(key, self.config.keyBoundTarget)
-	else
-		SetBindingClick(key, self:GetName(), "LeftButton")
-	end
-	lib.callbacks:Fire("OnKeybindingChanged", self, key)
-end
-
-local function clearBindings(binding)
-	while GetBindingKey(binding) do
-		SetBinding(GetBindingKey(binding), nil)
-	end
-end
-
-function Generic:ClearBindings()
-	if self.config.keyBoundTarget then
-		clearBindings(self.config.keyBoundTarget)
-	end
-	clearBindings("CLICK "..self:GetName()..":LeftButton")
-	lib.callbacks:Fire("OnKeybindingChanged", self, nil)
-end
-
------------------------------------------------------------
---- button management
-
-function Generic:UpdateAction(force)
-	local type, action = self:GetAction()
-	if force or type ~= self._state_type or action ~= self._state_action then
-		-- type changed, update the metatable
-		if force or self._state_type ~= type then
-			local meta = type_meta_map[type] or type_meta_map.empty
-			setmetatable(self, meta)
-			self._state_type = type
-		end
-		self._state_action = action
-		Update(self)
-	end
-end
-
-function Update(self)
-	if self:HasAction() then
-		ActiveButtons[self] = true
-		if self._state_type == "action" then
-			ActionButtons[self] = true
-			NonActionButtons[self] = nil
-		else
-			ActionButtons[self] = nil
-			NonActionButtons[self] = true
-		end
-		self:SetAlpha(1.0)
-		UpdateButtonState(self)
-		UpdateUsable(self)
-		UpdateCooldown(self)
-		UpdateFlash(self)
-	else
-		ActiveButtons[self] = nil
-		ActionButtons[self] = nil
-		NonActionButtons[self] = nil
-		if gridCounter == 0 and not self.config.showGrid then
-			self:SetAlpha(0.0)
-		end
-		self.cooldown:Hide()
-		self:SetChecked(false)
-	end
-
-	-- Add a green border if button is an equipped item
-	if self:IsEquipped() and not self.config.hideElements.equipped then
-		self.Border:SetVertexColor(0, 1.0, 0, 0.35)
-		self.Border:Show()
-	else
-		self.Border:Hide()
-	end
-
-	-- Update Action Text
-	if not self:IsConsumableOrStackable() then
-		self.Name:SetText(self:GetActionText())
-	else
-		self.Name:SetText("")
-	end
-
-	-- Update icon and hotkey
-	local texture = self:GetTexture()
-	if texture then
-		self.icon:SetTexture(texture)
-		self.icon:Show()
-		self.rangeTimer = - 1
-		self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
-		if not self.LBFSkinned and not self.MasqueSkinned then
-			self.NormalTexture:SetTexCoord(0, 0, 0, 0)
-		end
-	else
-		self.icon:Hide()
-		self.cooldown:Hide()
-		self.rangeTimer = nil
-		self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
-		if self.HotKey:GetText() == RANGE_INDICATOR then
-			self.HotKey:Hide()
-		else
-			self.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-		end
-		if not self.LBFSkinned and not self.MasqueSkinned then
-			self.NormalTexture:SetTexCoord(-0.15, 1.15, -0.15, 1.17)
-		end
-	end
-
-	self:UpdateLocal()
-
-	UpdateCount(self)
-
-	UpdateFlyout(self)
-
-	UpdateOverlayGlow(self)
-
-	UpdateNewAction(self)
-
-	if GameTooltip:GetOwner() == self then
-		UpdateTooltip(self)
-	end
-
-	-- this could've been a spec change, need to call OnStateChanged for action buttons, if present
-	if not InCombatLockdown() and self._state_type == "action" then
-		local onStateChanged = self:GetAttribute("OnStateChanged")
-		if onStateChanged then
-			self.header:SetFrameRef("updateButton", self)
-			self.header:Execute(([[
-				local frame = self:GetFrameRef("updateButton")
-				control:RunFor(frame, frame:GetAttribute("OnStateChanged"), %s, %s, %s)
-			]]):format(formatHelper(self:GetAttribute("state")), formatHelper(self._state_type), formatHelper(self._state_action)))
-		end
-	end
-	lib.callbacks:Fire("OnButtonUpdate", self)
-end
-
-function Generic:UpdateLocal()
--- dummy function the other button types can override for special updating
-end
-
-function UpdateButtonState(self)
-	if self:IsCurrentlyActive() or self:IsAutoRepeat() then
-		self:SetChecked(true)
-	else
-		self:SetChecked(false)
-	end
-	lib.callbacks:Fire("OnButtonState", self)
-end
-
-function UpdateUsable(self)
-	-- TODO: make the colors configurable
-	-- TODO: allow disabling of the whole recoloring
-	if self.config.outOfRangeColoring == "button" and self.outOfRange then
-		self.icon:SetVertexColor(unpack(self.config.colors.range))
-	else
-		local isUsable, notEnoughMana = self:IsUsable()
-		if isUsable then
-			self.icon:SetVertexColor(1.0, 1.0, 1.0)
-			--self.NormalTexture:SetVertexColor(1.0, 1.0, 1.0)
-		elseif notEnoughMana then
-			self.icon:SetVertexColor(unpack(self.config.colors.mana))
-			--self.NormalTexture:SetVertexColor(0.5, 0.5, 1.0)
-		else
-			self.icon:SetVertexColor(0.4, 0.4, 0.4)
-			--self.NormalTexture:SetVertexColor(1.0, 1.0, 1.0)
-		end
-	end
-	lib.callbacks:Fire("OnButtonUsable", self)
-end
-
-function UpdateCount(self)
-	if not self:HasAction() then
-		self.Count:SetText("")
-		return
-	end
-	if self:IsConsumableOrStackable() then
-		local count = self:GetCount()
-		if count > (self.maxDisplayCount or 9999) then
-			self.Count:SetText("*")
-		else
-			self.Count:SetText(count)
-		end
-	else
-		local charges, maxCharges, chargeStart, chargeDuration = self:GetCharges()
-		if charges and maxCharges and maxCharges > 0 then
-			self.Count:SetText(charges)
-		else
-			self.Count:SetText("")
-		end
-	end
-end
-
-function OnCooldownDone(self)
-	self:SetScript("OnCooldownDone", nil)
-	UpdateCooldown(self:GetParent())
-end
-
-function UpdateCooldown(self)
-	local locStart, locDuration = self:GetLossOfControlCooldown()
-	local start, duration, enable, charges, maxCharges = self:GetCooldown()
-
-	local effectiveAlpha = self:GetEffectiveAlpha()
-	-- HACK: only draw "bling" when button sufficiently visible
-	-- this stuff used to inherit alpha....
-	self.cooldown:SetDrawBling(effectiveAlpha > 0.5)
-
-	if (locStart + locDuration) > (start + duration) then
-		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_LOSS_OF_CONTROL then
-			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge-LoC")
-			self.cooldown:SetHideCountdownNumbers(true)
-			self.cooldown.currentCooldownType = COOLDOWN_TYPE_LOSS_OF_CONTROL
-		end
-		-- set swipe color and alpha
-		self.cooldown:SetSwipeColor(0.17, 0, 0, effectiveAlpha * 0.8)
-
-		CooldownFrame_SetTimer(self.cooldown, locStart, locDuration, 1, nil, nil, true)
-	else
-		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_NORMAL then
-			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge")
-			self.cooldown:SetHideCountdownNumbers(false)
-			self.cooldown.currentCooldownType = COOLDOWN_TYPE_NORMAL
-		end
-		-- set swipe color and alpha
-		self.cooldown:SetSwipeColor(0, 0, 0, effectiveAlpha * 0.8)
-		if locStart > 0 then
-			self.cooldown:SetScript("OnCooldownDone", OnCooldownDone)
-		end
-		CooldownFrame_SetTimer(self.cooldown, start, duration, enable, charges, maxCharges)
-
-		if effectiveAlpha < 0.5 then
-			self.cooldown:SetDrawEdge(false)
-		end
-	end
-end
-
-function StartFlash(self)
-	self.flashing = 1
-	flashTime = 0
-	UpdateButtonState(self)
-end
-
-function StopFlash(self)
-	self.flashing = 0
-	self.Flash:Hide()
-	UpdateButtonState(self)
-end
-
-function UpdateFlash(self)
-	if (self:IsAttack() and self:IsCurrentlyActive()) or self:IsAutoRepeat() then
-		StartFlash(self)
-	else
-		StopFlash(self)
-	end
-end
-
-function UpdateTooltip(self)
-	if (GetCVar("UberTooltips") == "1") then
-		GameTooltip_SetDefaultAnchor(GameTooltip, self);
-	else
-		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
-	end
-	if self:SetTooltip() then
-		self.UpdateTooltip = UpdateTooltip
-	else
-		self.UpdateTooltip = nil
-	end
-end
-
-function UpdateHotkeys(self)
-	local key = self:GetHotkey()
-	if not key or key == "" or self.config.hideElements.hotkey then
-		self.HotKey:SetText(RANGE_INDICATOR)
-		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", 1, - 2)
-		self.HotKey:Hide()
-	else
-		self.HotKey:SetText(key)
-		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", - 2, - 2)
-		self.HotKey:Show()
-	end
-end
-
-local function OverlayGlow_OnHide(self)
-	if self.animOut:IsPlaying() then
-		self.animOut:Stop()
-		OverlayGlowAnimOutFinished(self.animOut)
-	end
-end
-
-function GetOverlayGlow()
-	local overlay = tremove(lib.unusedOverlayGlows);
-	if not overlay then
-		lib.numOverlays = lib.numOverlays + 1
-		overlay = CreateFrame("Frame", "LAB10ActionButtonOverlay"..lib.numOverlays, UIParent, "ActionBarButtonSpellActivationAlert")
-		overlay.animOut:SetScript("OnFinished", OverlayGlowAnimOutFinished)
-		overlay:SetScript("OnHide", OverlayGlow_OnHide)
-	end
-	return overlay
-end
-
-function ShowOverlayGlow(self)
-	if self.overlay then
-		if self.overlay.animOut:IsPlaying() then
-			self.overlay.animOut:Stop()
-			self.overlay.animIn:Play()
-		end
-	else
-		self.overlay = GetOverlayGlow()
-		local frameWidth, frameHeight = self:GetSize()
-		self.overlay:SetParent(self)
-		self.overlay:ClearAllPoints()
-		--Make the height/width available before the next frame:
-		self.overlay:SetSize(frameWidth * 1.4, frameHeight * 1.4)
-		self.overlay:SetPoint("TOPLEFT", self, "TOPLEFT", -frameWidth * 0.2, frameHeight * 0.2)
-		self.overlay:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", frameWidth * 0.2, -frameHeight * 0.2)
-		self.overlay.animIn:Play()
-	end
-end
-
-function HideOverlayGlow(self)
-	if self.overlay then
-		if self.overlay.animIn:IsPlaying() then
-			self.overlay.animIn:Stop()
-		end
-		if self:IsVisible() then
-			self.overlay.animOut:Play()
-		else
-			OverlayGlowAnimOutFinished(self.overlay.animOut)
-		end
-	end
-end
-
-function OverlayGlowAnimOutFinished(animGroup)
-	local overlay = animGroup:GetParent()
-	local actionButton = overlay:GetParent()
-	overlay:Hide()
-	tinsert(lib.unusedOverlayGlows, overlay)
-	actionButton.overlay = nil
-end
-
-function UpdateOverlayGlow(self)
-	local spellId = self:GetSpellId()
-	if spellId and IsSpellOverlayed(spellId) then
-		ShowOverlayGlow(self)
-	else
-		HideOverlayGlow(self)
-	end
-end
-
-hooksecurefunc("MarkNewActionHighlight", function(action, flag)
-	lib.ACTION_HIGHLIGHT_MARKS[action] = flag
-	for button in next, ButtonRegistry do
-		if button._state_type == "action" and action == tonumber(button._state_action) then
-			UpdateNewAction(button)
-		end
-	end
-end)
-
-function UpdateNewAction(self)
-	-- special handling for "New Action" markers
-	if self.NewActionTexture then
-		if self._state_type == "action" and lib.ACTION_HIGHLIGHT_MARKS[self._state_action] then
-			self.NewActionTexture:Show()
-		else
-			self.NewActionTexture:Hide()
-		end
-	end
-end
-
--- Hook UpdateFlyout so we can use the blizzy templates
-hooksecurefunc("ActionButton_UpdateFlyout", function(self, ...)
-	if ButtonRegistry[self] then
-		UpdateFlyout(self)
-	end
-end)
-
-function UpdateFlyout(self)
-	-- disabled FlyoutBorder/BorderShadow, those are not handled by LBF and look terrible
-	self.FlyoutBorder:Hide()
-	self.FlyoutBorderShadow:Hide()
-	if self._state_type == "action" then
-		-- based on ActionButton_UpdateFlyout in ActionButton.lua
-		local actionType = GetActionInfo(self._state_action)
-		if actionType == "flyout" then
-			-- Update border and determine arrow position
-			local arrowDistance
-			if (SpellFlyout and SpellFlyout:IsShown() and SpellFlyout:GetParent() == self) or GetMouseFocus() == self then
-				arrowDistance = 5
-			else
-				arrowDistance = 2
-			end
-
-			-- Update arrow
-			self.FlyoutArrow:Show()
-			self.FlyoutArrow:ClearAllPoints()
-			local direction = self:GetAttribute("flyoutDirection");
-			if direction == "LEFT" then
-				self.FlyoutArrow:SetPoint("LEFT", self, "LEFT", -arrowDistance, 0)
-				SetClampedTextureRotation(self.FlyoutArrow, 270)
-			elseif direction == "RIGHT" then
-				self.FlyoutArrow:SetPoint("RIGHT", self, "RIGHT", arrowDistance, 0)
-				SetClampedTextureRotation(self.FlyoutArrow, 90)
-			elseif direction == "DOWN" then
-				self.FlyoutArrow:SetPoint("BOTTOM", self, "BOTTOM", 0, -arrowDistance)
-				SetClampedTextureRotation(self.FlyoutArrow, 180)
-			else
-				self.FlyoutArrow:SetPoint("TOP", self, "TOP", 0, arrowDistance)
-				SetClampedTextureRotation(self.FlyoutArrow, 0)
-			end
-
-			-- return here, otherwise flyout is hidden
-			return
-		end
-	end
-	self.FlyoutArrow:Hide()
-end
-
-function UpdateRangeTimer()
-	rangeTimer = -1
-end
-
-local function GetSpellIdByName(spellName)
-	if not spellName then return end
-	local spellLink = GetSpellLink(spellName)
-	if spellLink then
-		return tonumber(spellLink:match("spell:(%d+)"))
-	end
-	return nil
-end
-
------------------------------------------------------------
---- WoW API mapping
---- Generic Button
-Generic.HasAction               = function(self) return nil end
-Generic.GetActionText           = function(self) return "" end
-Generic.GetTexture              = function(self) return nil end
-Generic.GetCharges              = function(self) return nil end
-Generic.GetCount                = function(self) return 0 end
-Generic.GetCooldown             = function(self) return 0, 0, 0 end
-Generic.IsAttack                = function(self) return nil end
-Generic.IsEquipped              = function(self) return nil end
-Generic.IsCurrentlyActive       = function(self) return nil end
-Generic.IsAutoRepeat            = function(self) return nil end
-Generic.IsUsable                = function(self) return nil end
-Generic.IsConsumableOrStackable = function(self) return nil end
-Generic.IsUnitInRange           = function(self, unit) return nil end
-Generic.IsInRange               = function(self)
-	local unit = self:GetAttribute("unit")
-	if unit == "player" then
-		unit = nil
-	end
-	local val = self:IsUnitInRange(unit)
-	-- map 1/0 to true false, since the return values are inconsistent between actions and spells
-	if val == 1 then val = true elseif val == 0 then val = false end
-	return val
-end
-Generic.SetTooltip              = function(self) return nil end
-Generic.GetSpellId              = function(self) return nil end
-Generic.GetLossOfControlCooldown = function(self) return 0, 0 end
-
------------------------------------------------------------
---- Action Button
-Action.HasAction               = function(self) return HasAction(self._state_action) end
-Action.GetActionText           = function(self) return GetActionText(self._state_action) end
-Action.GetTexture              = function(self) return GetActionTexture(self._state_action) end
-Action.GetCharges              = function(self) return GetActionCharges(self._state_action) end
-Action.GetCount                = function(self) return GetActionCount(self._state_action) end
-Action.GetCooldown             = function(self) return GetActionCooldown(self._state_action) end
-Action.IsAttack                = function(self) return IsAttackAction(self._state_action) end
-Action.IsEquipped              = function(self) return IsEquippedAction(self._state_action) end
-Action.IsCurrentlyActive       = function(self) return IsCurrentAction(self._state_action) end
-Action.IsAutoRepeat            = function(self) return IsAutoRepeatAction(self._state_action) end
-Action.IsUsable                = function(self) return IsUsableAction(self._state_action) end
-Action.IsConsumableOrStackable = function(self) return IsConsumableAction(self._state_action) or IsStackableAction(self._state_action) or (not IsItemAction(self._state_action) and GetActionCount(self._state_action) > 0) end
-Action.IsUnitInRange           = function(self, unit) return IsActionInRange(self._state_action, unit) end
-Action.SetTooltip              = function(self) return GameTooltip:SetAction(self._state_action) end
-Action.GetSpellId              = function(self)
-	local actionType, id, subType = GetActionInfo(self._state_action)
-	if actionType == "spell" then
-		return id
-	elseif actionType == "macro" then
-		local _, _, spellId = GetMacroSpell(id)
-		return spellId
-	end
-end
-Action.GetLossOfControlCooldown = function(self) return GetActionLossOfControlCooldown(self._state_action) end
-
------------------------------------------------------------
---- Spell Button
-Spell.HasAction               = function(self) return true end
-Spell.GetActionText           = function(self) return "" end
-Spell.GetTexture              = function(self) return GetSpellTexture(self._state_action) end
-Spell.GetCharges              = function(self) return GetSpellCharges(self._state_action) end
-Spell.GetCount                = function(self) return GetSpellCount(self._state_action) end
-Spell.GetCooldown             = function(self) return GetSpellCooldown(self._state_action) end
-Spell.IsAttack                = function(self) return IsAttackSpell(FindSpellBookSlotBySpellID(self._state_action), "spell") end -- needs spell book id as of 4.0.1.13066
-Spell.IsEquipped              = function(self) return nil end
-Spell.IsCurrentlyActive       = function(self) return IsCurrentSpell(self._state_action) end
-Spell.IsAutoRepeat            = function(self) return IsAutoRepeatSpell(FindSpellBookSlotBySpellID(self._state_action), "spell") end -- needs spell book id as of 4.0.1.13066
-Spell.IsUsable                = function(self) return IsUsableSpell(self._state_action) end
-Spell.IsConsumableOrStackable = function(self) return IsConsumableSpell(self._state_action) end
-Spell.IsUnitInRange           = function(self, unit) return IsSpellInRange(FindSpellBookSlotBySpellID(self._state_action), "spell", unit) end -- needs spell book id as of 4.0.1.13066
-Spell.SetTooltip              = function(self) return GameTooltip:SetSpellByID(self._state_action) end
-Spell.GetSpellId              = function(self) return self._state_action end
-
------------------------------------------------------------
---- Item Button
-local function getItemId(input)
-	return input:match("^item:(%d+)")
-end
-
-Item.HasAction               = function(self) return true end
-Item.GetActionText           = function(self) return "" end
-Item.GetTexture              = function(self) return GetItemIcon(self._state_action) end
-Item.GetCharges              = function(self) return nil end
-Item.GetCount                = function(self) return GetItemCount(self._state_action, nil, true) end
-Item.GetCooldown             = function(self) return GetItemCooldown(getItemId(self._state_action)) end
-Item.IsAttack                = function(self) return nil end
-Item.IsEquipped              = function(self) return IsEquippedItem(self._state_action) end
-Item.IsCurrentlyActive       = function(self) return IsCurrentItem(self._state_action) end
-Item.IsAutoRepeat            = function(self) return nil end
-Item.IsUsable                = function(self) return IsUsableItem(self._state_action) end
-Item.IsConsumableOrStackable = function(self) return IsConsumableItem(self._state_action) end
-Item.IsUnitInRange           = function(self, unit) return IsItemInRange(self._state_action, unit) end
-Item.SetTooltip              = function(self) return GameTooltip:SetHyperlink(self._state_action) end
-Item.GetSpellId              = function(self) return nil end
-
------------------------------------------------------------
---- Macro Button
--- TODO: map results of GetMacroSpell/GetMacroItem to proper results
-Macro.HasAction               = function(self) return true end
-Macro.GetActionText           = function(self) return (GetMacroInfo(self._state_action)) end
-Macro.GetTexture              = function(self) return (select(2, GetMacroInfo(self._state_action))) end
-Macro.GetCharges              = function(self) return nil end
-Macro.GetCount                = function(self) return 0 end
-Macro.GetCooldown             = function(self) return 0, 0, 0 end
-Macro.IsAttack                = function(self) return nil end
-Macro.IsEquipped              = function(self) return nil end
-Macro.IsCurrentlyActive       = function(self) return nil end
-Macro.IsAutoRepeat            = function(self) return nil end
-Macro.IsUsable                = function(self) return nil end
-Macro.IsConsumableOrStackable = function(self) return nil end
-Macro.IsUnitInRange           = function(self, unit) return nil end
-Macro.SetTooltip              = function(self) return nil end
-Macro.GetSpellId              = function(self) return nil end
-
------------------------------------------------------------
---- Custom Button
-Custom.HasAction               = function(self) return true end
-Custom.GetActionText           = function(self) return "" end
-Custom.GetTexture              = function(self) return self._state_action.texture end
-Custom.GetCharges              = function(self) return nil end
-Custom.GetCount                = function(self) return 0 end
-Custom.GetCooldown             = function(self) return 0, 0, 0 end
-Custom.IsAttack                = function(self) return nil end
-Custom.IsEquipped              = function(self) return nil end
-Custom.IsCurrentlyActive       = function(self) return nil end
-Custom.IsAutoRepeat            = function(self) return nil end
-Custom.IsUsable                = function(self) return true end
-Custom.IsConsumableOrStackable = function(self) return nil end
-Custom.IsUnitInRange           = function(self, unit) return nil end
-Custom.SetTooltip              = function(self) return GameTooltip:SetText(self._state_action.tooltip) end
-Custom.GetSpellId              = function(self) return nil end
-Custom.RunCustom               = function(self, unit, button) return self._state_action.func(self, unit, button) end
-
------------------------------------------------------------
---- Update old Buttons
-if oldversion and next(lib.buttonRegistry) then
-	InitializeEventHandler()
-	for button in next, lib.buttonRegistry do
-		-- this refreshes the metatable on the button
-		Generic.UpdateAction(button, true)
-		SetupSecureSnippets(button)
-		if oldversion < 12 then
-			WrapOnClick(button)
-		end
-		if oldversion < 23 then
-			if button.overlay then
-				button.overlay:Hide()
-				ActionButton_HideOverlayGlow(button)
-				button.overlay = nil
-				UpdateOverlayGlow(button)
-			end
-		end
-	end
-end
diff --git a/Jamba/LibActionButtonJamba-1.0-57.lua b/Jamba/LibActionButtonJamba-1.0-57.lua
deleted file mode 100644
index aa883b4..0000000
--- a/Jamba/LibActionButtonJamba-1.0-57.lua
+++ /dev/null
@@ -1,1576 +0,0 @@
---[[
-Copyright (c) 2010-2017, Hendrik "nevcairiel" Leppkes <h.leppkes@gmail.com>
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of the developer nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-]]
-local MAJOR_VERSION = "LibActionButtonJamba-1.0"
-local MINOR_VERSION = 57
-
-if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
-local lib, oldversion = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
-if not lib then return end
-
--- Lua functions
-local _G = _G
-local type, error, tostring, tonumber, assert, select = type, error, tostring, tonumber, assert, select
-local setmetatable, wipe, unpack, pairs, next = setmetatable, wipe, unpack, pairs, next
-local str_match, format, tinsert, tremove = string.match, format, tinsert, tremove
-
--- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
--- List them here for Mikk's FindGlobals script
--- Note: No WoW API function get upvalued to allow proper interaction with any addons that try to hook them.
--- GLOBALS: LibStub, CreateFrame, InCombatLockdown, ClearCursor, GetCursorInfo, GameTooltip, GameTooltip_SetDefaultAnchor
--- GLOBALS: GetBindingKey, GetBindingText, SetBinding, SetBindingClick, GetCVar, GetMacroInfo
--- GLOBALS: PickupAction, PickupItem, PickupMacro, PickupPetAction, PickupSpell, PickupCompanion, PickupEquipmentSet
--- GLOBALS: CooldownFrame_SetTimer, UIParent, IsSpellOverlayed, SpellFlyout, GetMouseFocus, SetClampedTextureRotation
--- GLOBALS: GetActionInfo, GetActionTexture, HasAction, GetActionText, GetActionCount, GetActionCooldown, IsAttackAction
--- GLOBALS: IsAutoRepeatAction, IsEquippedAction, IsCurrentAction, IsConsumableAction, IsUsableAction, IsStackableAction, IsActionInRange
--- GLOBALS: GetSpellLink, GetMacroSpell, GetSpellTexture, GetSpellCount, GetSpellCooldown, IsAttackSpell, IsCurrentSpell
--- GLOBALS: FindSpellBookSlotBySpellID, IsUsableSpell, IsConsumableSpell, IsSpellInRange, IsAutoRepeatSpell
--- GLOBALS: GetItemIcon, GetItemCount, GetItemCooldown, IsEquippedItem, IsCurrentItem, IsUsableItem, IsConsumableItem, IsItemInRange
--- GLOBALS: GetActionCharges, IsItemAction, GetSpellCharges
--- GLOBALS: RANGE_INDICATOR, ATTACK_BUTTON_FLASH_TIME, TOOLTIP_UPDATE_TIME
-
-local KeyBound = LibStub("LibKeyBound-1.0", true)
-local CBH = LibStub("CallbackHandler-1.0")
-
-lib.eventFrame = lib.eventFrame or CreateFrame("Frame")
-lib.eventFrame:UnregisterAllEvents()
-
-lib.buttonRegistry = lib.buttonRegistry or {}
-lib.activeButtons = lib.activeButtons or {}
-lib.actionButtons = lib.actionButtons or {}
-lib.nonActionButtons = lib.nonActionButtons or {}
-
-lib.unusedOverlayGlows = lib.unusedOverlayGlows or {}
-lib.numOverlays = lib.numOverlays or 0
-
-lib.ACTION_HIGHLIGHT_MARKS = lib.ACTION_HIGHLIGHT_MARKS or setmetatable({}, { __index = ACTION_HIGHLIGHT_MARKS })
-
-lib.callbacks = lib.callbacks or CBH:New(lib)
-
-local Generic = CreateFrame("CheckButton")
-local Generic_MT = {__index = Generic}
-
-local Action = setmetatable({}, {__index = Generic})
-local Action_MT = {__index = Action}
-
-local PetAction = setmetatable({}, {__index = Generic})
-local PetAction_MT = {__index = PetAction}
-
-local Spell = setmetatable({}, {__index = Generic})
-local Spell_MT = {__index = Spell}
-
-local Item = setmetatable({}, {__index = Generic})
-local Item_MT = {__index = Item}
-
-local Macro = setmetatable({}, {__index = Generic})
-local Macro_MT = {__index = Macro}
-
-local Custom = setmetatable({}, {__index = Generic})
-local Custom_MT = {__index = Custom}
-
-local type_meta_map = {
-	empty  = Generic_MT,
-	action = Action_MT,
-	--pet    = PetAction_MT,
-	spell  = Spell_MT,
-	item   = Item_MT,
-	macro  = Macro_MT,
-	custom = Custom_MT
-}
-
-local ButtonRegistry, ActiveButtons, ActionButtons, NonActionButtons = lib.buttonRegistry, lib.activeButtons, lib.actionButtons, lib.nonActionButtons
-
-local Update, UpdateButtonState, UpdateUsable, UpdateCount, UpdateCooldown, UpdateTooltip, UpdateNewAction
-local StartFlash, StopFlash, UpdateFlash, UpdateHotkeys, UpdateRangeTimer, UpdateOverlayGlow
-local UpdateFlyout, ShowGrid, HideGrid, UpdateGrid, SetupSecureSnippets, WrapOnClick
-local ShowOverlayGlow, HideOverlayGlow, GetOverlayGlow, OverlayGlowAnimOutFinished
-local HookCooldown
-
-local InitializeEventHandler, OnEvent, ForAllButtons, OnUpdate
-
-local DefaultConfig = {
-	outOfRangeColoring = "button",
-	tooltip = "enabled",
-	showGrid = false,
-	colors = {
-		range = { 0.8, 0.1, 0.1 },
-		mana = { 0.5, 0.5, 1.0 }
-	},
-	hideElements = {
-		macro = false,
-		hotkey = false,
-		equipped = false,
-	},
-	keyBoundTarget = false,
-	clickOnDown = false,
-	flyoutDirection = "UP",
-}
-
---- Create a new action button.
--- @param id Internal id of the button (not used by LibActionButton-1.0, only for tracking inside the calling addon)
--- @param name Name of the button frame to be created (not used by LibActionButton-1.0 aside from naming the frame)
--- @param header Header that drives these action buttons (if any)
-function lib:CreateButton(id, name, header, config)
-	if type(name) ~= "string" then
-		error("Usage: CreateButton(id, name. header): Buttons must have a valid name!", 2)
-	end
-	if not header then
-		error("Usage: CreateButton(id, name, header): Buttons without a secure header are not yet supported!", 2)
-	end
-
-	if not KeyBound then
-		KeyBound = LibStub("LibKeyBound-1.0", true)
-	end
-
-	local button = setmetatable(CreateFrame("CheckButton", name, header, "SecureActionButtonTemplate, ActionButtonTemplate"), Generic_MT)
-	button:RegisterForDrag("LeftButton", "RightButton")
-	button:RegisterForClicks("AnyUp")
-
-	-- Frame Scripts
-	button:SetScript("OnEnter", Generic.OnEnter)
-	button:SetScript("OnLeave", Generic.OnLeave)
-	button:SetScript("PreClick", Generic.PreClick)
-	button:SetScript("PostClick", Generic.PostClick)
-
-	button.id = id
-	button.header = header
-	-- Mapping of state -> action
-	button.state_types = {}
-	button.state_actions = {}
-
-	-- Store the LAB Version that created this button for debugging
-	button.__LAB_Version = MINOR_VERSION
-
-	-- just in case we're not run by a header, default to state 0
-	button:SetAttribute("state", 0)
-
-	SetupSecureSnippets(button)
-	WrapOnClick(button)
-
-	-- adjust hotkey style for better readability
-	button.HotKey:SetFont(button.HotKey:GetFont(), 13, "OUTLINE")
-	button.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-
-	-- adjust count/stack size
-	button.Count:SetFont(button.Count:GetFont(), 16, "OUTLINE")
-
-	-- hook Cooldown stuff for alpha fix in 6.0
-	HookCooldown(button)
-
-	-- Store the button in the registry, needed for event and OnUpdate handling
-	if not next(ButtonRegistry) then
-		InitializeEventHandler()
-	end
-	ButtonRegistry[button] = true
-
-	button:UpdateConfig(config)
-
-	-- run an initial update
-	button:UpdateAction()
-	UpdateHotkeys(button)
-
-	-- somewhat of a hack for the Flyout buttons to not error.
-	button.action = 0
-
-	lib.callbacks:Fire("OnButtonCreated", button)
-
-	return button
-end
-
-function SetupSecureSnippets(button)
-	button:SetAttribute("_custom", Custom.RunCustom)
-	-- secure UpdateState(self, state)
-	-- update the type and action of the button based on the state
-	button:SetAttribute("UpdateState", [[
-		local state = ...
-		self:SetAttribute("state", state)
-		local type, action = (self:GetAttribute(format("labtype-%s", state)) or "empty"), self:GetAttribute(format("labaction-%s", state))
-
-		self:SetAttribute("type", type)
-		if type ~= "empty" and type ~= "custom" then
-			local action_field = (type == "pet") and "action" or type
-			self:SetAttribute(action_field, action)
-			self:SetAttribute("action_field", action_field)
-		end
-		local onStateChanged = self:GetAttribute("OnStateChanged")
-		if onStateChanged then
-			self:Run(onStateChanged, state, type, action)
-		end
-	]])
-
-	-- this function is invoked by the header when the state changes
-	button:SetAttribute("_childupdate-state", [[
-		self:RunAttribute("UpdateState", message)
-		self:CallMethod("UpdateAction")
-	]])
-
-	-- secure PickupButton(self, kind, value, ...)
-	-- utility function to place a object on the cursor
-	button:SetAttribute("PickupButton", [[
-		local kind, value = ...
-		if kind == "empty" then
-			return "clear"
-		elseif kind == "action" or kind == "pet" then
-			local actionType = (kind == "pet") and "petaction" or kind
-			return actionType, value
-		elseif kind == "spell" or kind == "item" or kind == "macro" then
-			return "clear", kind, value
-		else
-			print("LibActionButton-1.0: Unknown type: " .. tostring(kind))
-			return false
-		end
-	]])
-
-	button:SetAttribute("OnDragStart", [[
-		if (self:GetAttribute("buttonlock") and not IsModifiedClick("PICKUPACTION")) or self:GetAttribute("LABdisableDragNDrop") then return false end
-		local state = self:GetAttribute("state")
-		local type = self:GetAttribute("type")
-		-- if the button is empty, we can't drag anything off it
-		if type == "empty" or type == "custom" then
-			return false
-		end
-		-- Get the value for the action attribute
-		local action_field = self:GetAttribute("action_field")
-		local action = self:GetAttribute(action_field)
-
-		-- non-action fields need to change their type to empty
-		if type ~= "action" and type ~= "pet" then
-			self:SetAttribute(format("labtype-%s", state), "empty")
-			self:SetAttribute(format("labaction-%s", state), nil)
-			-- update internal state
-			self:RunAttribute("UpdateState", state)
-			-- send a notification to the insecure code
-			self:CallMethod("ButtonContentsChanged", state, "empty", nil)
-		end
-		-- return the button contents for pickup
-		return self:RunAttribute("PickupButton", type, action)
-	]])
-
-	button:SetAttribute("OnReceiveDrag", [[
-		if self:GetAttribute("LABdisableDragNDrop") then return false end
-		local kind, value, subtype, extra = ...
-		if not kind or not value then return false end
-		local state = self:GetAttribute("state")
-		local buttonType, buttonAction = self:GetAttribute("type"), nil
-		if buttonType == "custom" then return false end
-		-- action buttons can do their magic themself
-		-- for all other buttons, we'll need to update the content now
-		if buttonType ~= "action" and buttonType ~= "pet" then
-			-- with "spell" types, the 4th value contains the actual spell id
-			if kind == "spell" then
-				if extra then
-					value = extra
-				else
-					print("no spell id?", ...)
-				end
-			elseif kind == "item" and value then
-				value = format("item:%d", value)
-			end
-
-			-- Get the action that was on the button before
-			if buttonType ~= "empty" then
-				buttonAction = self:GetAttribute(self:GetAttribute("action_field"))
-			end
-
-			-- TODO: validate what kind of action is being fed in here
-			-- We can only use a handful of the possible things on the cursor
-			-- return false for all those we can't put on buttons
-
-			self:SetAttribute(format("labtype-%s", state), kind)
-			self:SetAttribute(format("labaction-%s", state), value)
-			-- update internal state
-			self:RunAttribute("UpdateState", state)
-			-- send a notification to the insecure code
-			self:CallMethod("ButtonContentsChanged", state, kind, value)
-		else
-			-- get the action for (pet-)action buttons
-			buttonAction = self:GetAttribute("action")
-		end
-		return self:RunAttribute("PickupButton", buttonType, buttonAction)
-	]])
-
-	button:SetScript("OnDragStart", nil)
-	-- Wrapped OnDragStart(self, button, kind, value, ...)
-	button.header:WrapScript(button, "OnDragStart", [[
-		return self:RunAttribute("OnDragStart")
-	]])
-	-- Wrap twice, because the post-script is not run when the pre-script causes a pickup (doh)
-	-- we also need some phony message, or it won't work =/
-	button.header:WrapScript(button, "OnDragStart", [[
-		return "message", "update"
-	]], [[
-		self:RunAttribute("UpdateState", self:GetAttribute("state"))
-	]])
-
-	button:SetScript("OnReceiveDrag", nil)
-	-- Wrapped OnReceiveDrag(self, button, kind, value, ...)
-	button.header:WrapScript(button, "OnReceiveDrag", [[
-		return self:RunAttribute("OnReceiveDrag", kind, value, ...)
-	]])
-	-- Wrap twice, because the post-script is not run when the pre-script causes a pickup (doh)
-	-- we also need some phony message, or it won't work =/
-	button.header:WrapScript(button, "OnReceiveDrag", [[
-		return "message", "update"
-	]], [[
-		self:RunAttribute("UpdateState", self:GetAttribute("state"))
-	]])
-end
-
-function WrapOnClick(button)
-	-- Wrap OnClick, to catch changes to actions that are applied with a click on the button.
-	button.header:WrapScript(button, "OnClick", [[
-		if self:GetAttribute("type") == "action" then
-			local type, action = GetActionInfo(self:GetAttribute("action"))
-			return nil, format("%s|%s", tostring(type), tostring(action))
-		end
-	]], [[
-		local type, action = GetActionInfo(self:GetAttribute("action"))
-		if message ~= format("%s|%s", tostring(type), tostring(action)) then
-			self:RunAttribute("UpdateState", self:GetAttribute("state"))
-		end
-	]])
-end
-
------------------------------------------------------------
---- utility
-
-function lib:GetAllButtons()
-	local buttons = {}
-	for button in next, ButtonRegistry do
-		buttons[button] = true
-	end
-	return buttons
-end
-
-function Generic:ClearSetPoint(...)
-	self:ClearAllPoints()
-	self:SetPoint(...)
-end
-
-function Generic:NewHeader(header)
-	self.header = header
-	self:SetParent(header)
-	SetupSecureSnippets(self)
-	WrapOnClick(self)
-end
-
-
------------------------------------------------------------
---- state management
-
-function Generic:ClearStates()
-	for state in pairs(self.state_types) do
-		self:SetAttribute(format("labtype-%s", state), nil)
-		self:SetAttribute(format("labaction-%s", state), nil)
-	end
-	wipe(self.state_types)
-	wipe(self.state_actions)
-end
-
-function Generic:SetState(state, kind, action)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	-- we allow a nil kind for setting a empty state
-	if not kind then kind = "empty" end
-	if not type_meta_map[kind] then
-		error("SetStateAction: unknown action type: " .. tostring(kind), 2)
-	end
-	if kind ~= "empty" and action == nil then
-		error("SetStateAction: an action is required for non-empty states", 2)
-	end
-	if kind ~= "custom" and action ~= nil and type(action) ~= "number" and type(action) ~= "string" or (kind == "custom" and type(action) ~= "table") then
-		error("SetStateAction: invalid action data type, only strings and numbers allowed", 2)
-	end
-
-	if kind == "item" then
-		if tonumber(action) then
-			action = format("item:%s", action)
-		else
-			local itemString = str_match(action, "^|c%x+|H(item[%d:]+)|h%[")
-			if itemString then
-				action = itemString
-			end
-		end
-	end
-
-	self.state_types[state] = kind
-	self.state_actions[state] = action
-	self:UpdateState(state)
-end
-
-function Generic:UpdateState(state)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	self:SetAttribute(format("labtype-%s", state), self.state_types[state])
-	self:SetAttribute(format("labaction-%s", state), self.state_actions[state])
-	if state ~= tostring(self:GetAttribute("state")) then return end
-	if self.header then
-		self.header:SetFrameRef("updateButton", self)
-		self.header:Execute([[
-			local frame = self:GetFrameRef("updateButton")
-			control:RunFor(frame, frame:GetAttribute("UpdateState"), frame:GetAttribute("state"))
-		]])
-	else
-		-- TODO
-	end
-	self:UpdateAction()
-end
-
-function Generic:GetAction(state)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	return self.state_types[state] or "empty", self.state_actions[state]
-end
-
-function Generic:UpdateAllStates()
-	for state in pairs(self.state_types) do
-		self:UpdateState(state)
-	end
-end
-
-function Generic:ButtonContentsChanged(state, kind, value)
-	state = tostring(state)
-	self.state_types[state] = kind or "empty"
-	self.state_actions[state] = value
-	lib.callbacks:Fire("OnButtonContentsChanged", self, state, self.state_types[state], self.state_actions[state])
-	self:UpdateAction(self)
-end
-
-function Generic:DisableDragNDrop(flag)
-	if InCombatLockdown() then
-		error("LibActionButton-1.0: You can only toggle DragNDrop out of combat!", 2)
-	end
-	if flag then
-		self:SetAttribute("LABdisableDragNDrop", true)
-	else
-		self:SetAttribute("LABdisableDragNDrop", nil)
-	end
-end
-
-function Generic:AddToButtonFacade(group)
-	if type(group) ~= "table" or type(group.AddButton) ~= "function" then
-		error("LibActionButton-1.0:AddToButtonFacade: You need to supply a proper group to use!", 2)
-	end
-	group:AddButton(self)
-	self.LBFSkinned = true
-end
-
-function Generic:AddToMasque(group)
-	if type(group) ~= "table" or type(group.AddButton) ~= "function" then
-		error("LibActionButton-1.0:AddToMasque: You need to supply a proper group to use!", 2)
-	end
-	group:AddButton(self)
-	self.MasqueSkinned = true
-end
-
-function Generic:UpdateAlpha()
-	UpdateCooldown(self)
-end
-
------------------------------------------------------------
---- frame scripts
-
--- copied (and adjusted) from SecureHandlers.lua
-local function PickupAny(kind, target, detail, ...)
-	if kind == "clear" then
-		ClearCursor()
-		kind, target, detail = target, detail, ...
-	end
-
-	if kind == 'action' then
-		PickupAction(target)
-	elseif kind == 'item' then
-		PickupItem(target)
-	elseif kind == 'macro' then
-		PickupMacro(target)
-	elseif kind == 'petaction' then
-		PickupPetAction(target)
-	elseif kind == 'spell' then
-		PickupSpell(target)
-	elseif kind == 'companion' then
-		PickupCompanion(target, detail)
-	elseif kind == 'equipmentset' then
-		PickupEquipmentSet(target)
-	end
-end
-
-function Generic:OnEnter()
-	if self.config.tooltip ~= "disabled" and (self.config.tooltip ~= "nocombat" or not InCombatLockdown()) then
-		UpdateTooltip(self)
-	end
-	if KeyBound then
-		KeyBound:Set(self)
-	end
-
-	if self._state_type == "action" and self.NewActionTexture then
-		lib.ACTION_HIGHLIGHT_MARKS[self._state_action] = false
-		UpdateNewAction(self)
-	end
-end
-
-function Generic:OnLeave()
-	GameTooltip:Hide()
-end
-
--- Insecure drag handler to allow clicking on the button with an action on the cursor
--- to place it on the button. Like action buttons work.
-function Generic:PreClick()
-	if self._state_type == "action" or self._state_type == "pet"
-			or InCombatLockdown() or self:GetAttribute("LABdisableDragNDrop")
-	then
-		return
-	end
-	-- check if there is actually something on the cursor
-	local kind, value, subtype = GetCursorInfo()
-	if not (kind and value) then return end
-	self._old_type = self._state_type
-	if self._state_type and self._state_type ~= "empty" then
-		self._old_type = self._state_type
-		self:SetAttribute("type", "empty")
-		--self:SetState(nil, "empty", nil)
-	end
-	self._receiving_drag = true
-end
-
-local function formatHelper(input)
-	if type(input) == "string" then
-		return format("%q", input)
-	else
-		return tostring(input)
-	end
-end
-
-function Generic:PostClick()
-	UpdateButtonState(self)
-	if self._receiving_drag and not InCombatLockdown() then
-		if self._old_type then
-			self:SetAttribute("type", self._old_type)
-			self._old_type = nil
-		end
-		local oldType, oldAction = self._state_type, self._state_action
-		local kind, data, subtype, extra = GetCursorInfo()
-		self.header:SetFrameRef("updateButton", self)
-		self.header:Execute(format([[
-			local frame = self:GetFrameRef("updateButton")
-			control:RunFor(frame, frame:GetAttribute("OnReceiveDrag"), %s, %s, %s, %s)
-			control:RunFor(frame, frame:GetAttribute("UpdateState"), %s)
-		]], formatHelper(kind), formatHelper(data), formatHelper(subtype), formatHelper(extra), formatHelper(self:GetAttribute("state"))))
-		PickupAny("clear", oldType, oldAction)
-	end
-	self._receiving_drag = nil
-end
-
------------------------------------------------------------
---- configuration
-
-local function merge(target, source, default)
-	for k,v in pairs(default) do
-		if type(v) ~= "table" then
-			if source and source[k] ~= nil then
-				target[k] = source[k]
-			else
-				target[k] = v
-			end
-		else
-			if type(target[k]) ~= "table" then target[k] = {} else wipe(target[k]) end
-			merge(target[k], type(source) == "table" and source[k], v)
-		end
-	end
-	return target
-end
-
-function Generic:UpdateConfig(config)
-	if config and type(config) ~= "table" then
-		error("LibActionButton-1.0: UpdateConfig requires a valid configuration!", 2)
-	end
-	local oldconfig = self.config
-	if not self.config then self.config = {} end
-	-- merge the two configs
-	merge(self.config, config, DefaultConfig)
-
-	if self.config.outOfRangeColoring == "button" or (oldconfig and oldconfig.outOfRangeColoring == "button") then
-		UpdateUsable(self)
-	end
-	if self.config.outOfRangeColoring == "hotkey" then
-		self.outOfRange = nil
-	elseif oldconfig and oldconfig.outOfRangeColoring == "hotkey" then
-		self.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-	end
-
-	if self.config.hideElements.macro then
-		self.Name:Hide()
-	else
-		self.Name:Show()
-	end
-
-	self:SetAttribute("flyoutDirection", self.config.flyoutDirection)
-
-	UpdateHotkeys(self)
-	UpdateGrid(self)
-	Update(self)
-	self:RegisterForClicks(self.config.clickOnDown and "AnyDown" or "AnyUp")
-end
-
------------------------------------------------------------
---- event handler
-
-function ForAllButtons(method, onlyWithAction)
-	assert(type(method) == "function")
-	for button in next, (onlyWithAction and ActiveButtons or ButtonRegistry) do
-		method(button)
-	end
-end
-
-function InitializeEventHandler()
-	lib.eventFrame:SetScript("OnEvent", OnEvent)
-	lib.eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_SHOWGRID")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_HIDEGRID")
-	--lib.eventFrame:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
-	--lib.eventFrame:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
-	lib.eventFrame:RegisterEvent("UPDATE_BINDINGS")
-	lib.eventFrame:RegisterEvent("UPDATE_SHAPESHIFT_FORM")
-	lib.eventFrame:RegisterEvent("UPDATE_VEHICLE_ACTIONBAR")
-
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_STATE")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
-	lib.eventFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
-	lib.eventFrame:RegisterEvent("TRADE_SKILL_SHOW")
-	lib.eventFrame:RegisterEvent("TRADE_SKILL_CLOSE")
-	lib.eventFrame:RegisterEvent("ARCHAEOLOGY_CLOSED")
-	lib.eventFrame:RegisterEvent("PLAYER_ENTER_COMBAT")
-	lib.eventFrame:RegisterEvent("PLAYER_LEAVE_COMBAT")
-	lib.eventFrame:RegisterEvent("START_AUTOREPEAT_SPELL")
-	lib.eventFrame:RegisterEvent("STOP_AUTOREPEAT_SPELL")
-	lib.eventFrame:RegisterEvent("UNIT_ENTERED_VEHICLE")
-	lib.eventFrame:RegisterEvent("UNIT_EXITED_VEHICLE")
-	lib.eventFrame:RegisterEvent("COMPANION_UPDATE")
-	lib.eventFrame:RegisterEvent("UNIT_INVENTORY_CHANGED")
-	lib.eventFrame:RegisterEvent("LEARNED_SPELL_IN_TAB")
-	lib.eventFrame:RegisterEvent("PET_STABLE_UPDATE")
-	lib.eventFrame:RegisterEvent("PET_STABLE_SHOW")
-	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_SHOW")
-	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_HIDE")
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_CHARGES")
-	lib.eventFrame:RegisterEvent("UPDATE_SUMMONPETS_ACTION")
-
-	-- With those two, do we still need the ACTIONBAR equivalents of them?
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_COOLDOWN")
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_USABLE")
-	lib.eventFrame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
-
-	lib.eventFrame:RegisterEvent("LOSS_OF_CONTROL_ADDED")
-	lib.eventFrame:RegisterEvent("LOSS_OF_CONTROL_UPDATE")
-
-	lib.eventFrame:Show()
-	lib.eventFrame:SetScript("OnUpdate", OnUpdate)
-end
-
-function OnEvent(frame, event, arg1, ...)
-	if (event == "UNIT_INVENTORY_CHANGED" and arg1 == "player") or event == "LEARNED_SPELL_IN_TAB" then
-		local tooltipOwner = GameTooltip:GetOwner()
-		if ButtonRegistry[tooltipOwner] then
-			tooltipOwner:SetTooltip()
-		end
-	elseif event == "ACTIONBAR_SLOT_CHANGED" then
-		for button in next, ButtonRegistry do
-			if button._state_type == "action" and (arg1 == 0 or arg1 == tonumber(button._state_action)) then
-				Update(button)
-			end
-		end
-	elseif event == "PLAYER_ENTERING_WORLD" or event == "UPDATE_SHAPESHIFT_FORM" or event == "UPDATE_VEHICLE_ACTIONBAR" then
-		ForAllButtons(Update)
-	elseif event == "ACTIONBAR_PAGE_CHANGED" or event == "UPDATE_BONUS_ACTIONBAR" then
-		-- TODO: Are these even needed?
-	elseif event == "ACTIONBAR_SHOWGRID" then
-		ShowGrid()
-	elseif event == "ACTIONBAR_HIDEGRID" then
-		HideGrid()
-	elseif event == "UPDATE_BINDINGS" then
-		ForAllButtons(UpdateHotkeys)
-	elseif event == "PLAYER_TARGET_CHANGED" then
-		UpdateRangeTimer()
-	elseif (event == "ACTIONBAR_UPDATE_STATE") or
-			((event == "UNIT_ENTERED_VEHICLE" or event == "UNIT_EXITED_VEHICLE") and (arg1 == "player")) or
-			((event == "COMPANION_UPDATE") and (arg1 == "MOUNT")) then
-		ForAllButtons(UpdateButtonState, true)
-	elseif event == "ACTIONBAR_UPDATE_USABLE" then
-		for button in next, ActionButtons do
-			UpdateUsable(button)
-		end
-	elseif event == "SPELL_UPDATE_USABLE" then
-		for button in next, NonActionButtons do
-			UpdateUsable(button)
-		end
-	elseif event == "ACTIONBAR_UPDATE_COOLDOWN" then
-		for button in next, ActionButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "SPELL_UPDATE_COOLDOWN" then
-		for button in next, NonActionButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "LOSS_OF_CONTROL_ADDED" then
-		for button in next, ActiveButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "LOSS_OF_CONTROL_UPDATE" then
-		for button in next, ActiveButtons do
-			UpdateCooldown(button)
-		end
-	elseif event == "TRADE_SKILL_SHOW" or event == "TRADE_SKILL_CLOSE"  or event == "ARCHAEOLOGY_CLOSED" then
-		ForAllButtons(UpdateButtonState, true)
-	elseif event == "PLAYER_ENTER_COMBAT" then
-		for button in next, ActiveButtons do
-			if button:IsAttack() then
-				StartFlash(button)
-			end
-		end
-	elseif event == "PLAYER_LEAVE_COMBAT" then
-		for button in next, ActiveButtons do
-			if button:IsAttack() then
-				StopFlash(button)
-			end
-		end
-	elseif event == "START_AUTOREPEAT_SPELL" then
-		for button in next, ActiveButtons do
-			if button:IsAutoRepeat() then
-				StartFlash(button)
-			end
-		end
-	elseif event == "STOP_AUTOREPEAT_SPELL" then
-		for button in next, ActiveButtons do
-			if button.flashing == 1 and not button:IsAttack() then
-				StopFlash(button)
-			end
-		end
-	elseif event == "PET_STABLE_UPDATE" or event == "PET_STABLE_SHOW" then
-		ForAllButtons(Update)
-	elseif event == "SPELL_ACTIVATION_OVERLAY_GLOW_SHOW" then
-		for button in next, ActiveButtons do
-			local spellId = button:GetSpellId()
-			if spellId and spellId == arg1 then
-				ShowOverlayGlow(button)
-			else
-				if button._state_type == "action" then
-					local actionType, id = GetActionInfo(button._state_action)
-					if actionType == "flyout" and FlyoutHasSpell(id, arg1) then
-						ShowOverlayGlow(button)
-					end
-				end
-			end
-		end
-	elseif event == "SPELL_ACTIVATION_OVERLAY_GLOW_HIDE" then
-		for button in next, ActiveButtons do
-			local spellId = button:GetSpellId()
-			if spellId and spellId == arg1 then
-				HideOverlayGlow(button)
-			else
-				if button._state_type == "action" then
-					local actionType, id = GetActionInfo(button._state_action)
-					if actionType == "flyout" and FlyoutHasSpell(id, arg1) then
-						HideOverlayGlow(button)
-					end
-				end
-			end
-		end
-	elseif event == "PLAYER_EQUIPMENT_CHANGED" then
-		for button in next, ActiveButtons do
-			if button._state_type == "item" then
-				Update(button)
-			end
-		end
-	elseif event == "SPELL_UPDATE_CHARGES" then
-		ForAllButtons(UpdateCount, true)
-	elseif event == "UPDATE_SUMMONPETS_ACTION" then
-		for button in next, ActiveButtons do
-			if button._state_type == "action" then
-				local actionType, id = GetActionInfo(button._state_action)
-				if actionType == "summonpet" then
-					local texture = GetActionTexture(button._state_action)
-					if texture then
-						button.icon:SetTexture(texture)
-					end
-				end
-			end
-		end
-	end
-end
-
-local flashTime = 0
-local rangeTimer = -1
-function OnUpdate(_, elapsed)
-	flashTime = flashTime - elapsed
-	rangeTimer = rangeTimer - elapsed
-	-- Run the loop only when there is something to update
-	if rangeTimer <= 0 or flashTime <= 0 then
-		for button in next, ActiveButtons do
-			-- Flashing
-			if button.flashing == 1 and flashTime <= 0 then
-				if button.Flash:IsShown() then
-					button.Flash:Hide()
-				else
-					button.Flash:Show()
-				end
-			end
-
-			-- Range
-			if rangeTimer <= 0 then
-				local inRange = button:IsInRange()
-				local oldRange = button.outOfRange
-				button.outOfRange = (inRange == false)
-				if oldRange ~= button.outOfRange then
-					if button.config.outOfRangeColoring == "button" then
-						UpdateUsable(button)
-					elseif button.config.outOfRangeColoring == "hotkey" then
-						local hotkey = button.HotKey
-						if hotkey:GetText() == RANGE_INDICATOR then
-							if inRange == false then
-								hotkey:Show()
-							else
-								hotkey:Hide()
-							end
-						end
-						if inRange == false then
-							hotkey:SetVertexColor(unpack(button.config.colors.range))
-						else
-							hotkey:SetVertexColor(0.75, 0.75, 0.75)
-						end
-					end
-				end
-			end
-		end
-
-		-- Update values
-		if flashTime <= 0 then
-			flashTime = flashTime + ATTACK_BUTTON_FLASH_TIME
-		end
-		if rangeTimer <= 0 then
-			rangeTimer = TOOLTIP_UPDATE_TIME
-		end
-	end
-end
-
-local gridCounter = 0
-function ShowGrid()
-	gridCounter = gridCounter + 1
-	if gridCounter >= 1 then
-		for button in next, ButtonRegistry do
-			if button:IsShown() then
-				button:SetAlpha(1.0)
-			end
-		end
-	end
-end
-
-function HideGrid()
-	if gridCounter > 0 then
-		gridCounter = gridCounter - 1
-	end
-	if gridCounter == 0 then
-		for button in next, ButtonRegistry do
-			if button:IsShown() and not button:HasAction() and not button.config.showGrid then
-				button:SetAlpha(0.0)
-			end
-		end
-	end
-end
-
-function UpdateGrid(self)
-	if self.config.showGrid then
-		self:SetAlpha(1.0)
-	elseif gridCounter == 0 and self:IsShown() and not self:HasAction() then
-		self:SetAlpha(0.0)
-	end
-end
-
------------------------------------------------------------
---- KeyBound integration
-
-function Generic:GetBindingAction()
-	return self.config.keyBoundTarget or "CLICK "..self:GetName()..":LeftButton"
-end
-
-function Generic:GetHotkey()
-	local name = "CLICK "..self:GetName()..":LeftButton"
-	local key = GetBindingKey(self.config.keyBoundTarget or name)
-	if not key and self.config.keyBoundTarget then
-		key = GetBindingKey(name)
-	end
-	if key then
-		return KeyBound and KeyBound:ToShortKey(key) or key
-	end
-end
-
-local function getKeys(binding, keys)
-	keys = keys or ""
-	for i = 1, select("#", GetBindingKey(binding)) do
-		local hotKey = select(i, GetBindingKey(binding))
-		if keys ~= "" then
-			keys = keys .. ", "
-		end
-		keys = keys .. GetBindingText(hotKey, "KEY_")
-	end
-	return keys
-end
-
-function Generic:GetBindings()
-	local keys, binding
-
-	if self.config.keyBoundTarget then
-		keys = getKeys(self.config.keyBoundTarget)
-	end
-
-	keys = getKeys("CLICK "..self:GetName()..":LeftButton")
-
-	return keys
-end
-
-function Generic:SetKey(key)
-	if self.config.keyBoundTarget then
-		SetBinding(key, self.config.keyBoundTarget)
-	else
-		SetBindingClick(key, self:GetName(), "LeftButton")
-	end
-	lib.callbacks:Fire("OnKeybindingChanged", self, key)
-end
-
-local function clearBindings(binding)
-	while GetBindingKey(binding) do
-		SetBinding(GetBindingKey(binding), nil)
-	end
-end
-
-function Generic:ClearBindings()
-	if self.config.keyBoundTarget then
-		clearBindings(self.config.keyBoundTarget)
-	end
-	clearBindings("CLICK "..self:GetName()..":LeftButton")
-	lib.callbacks:Fire("OnKeybindingChanged", self, nil)
-end
-
------------------------------------------------------------
---- button management
-
-function Generic:UpdateAction(force)
-	local type, action = self:GetAction()
-	if force or type ~= self._state_type or action ~= self._state_action then
-		-- type changed, update the metatable
-		if force or self._state_type ~= type then
-			local meta = type_meta_map[type] or type_meta_map.empty
-			setmetatable(self, meta)
-			self._state_type = type
-		end
-		self._state_action = action
-		Update(self)
-	end
-end
-
-function Update(self)
-	if self:HasAction() then
-		ActiveButtons[self] = true
-		if self._state_type == "action" then
-			ActionButtons[self] = true
-			NonActionButtons[self] = nil
-		else
-			ActionButtons[self] = nil
-			NonActionButtons[self] = true
-		end
-		self:SetAlpha(1.0)
-		UpdateButtonState(self)
-		UpdateUsable(self)
-		UpdateCooldown(self)
-		UpdateFlash(self)
-	else
-		ActiveButtons[self] = nil
-		ActionButtons[self] = nil
-		NonActionButtons[self] = nil
-		if gridCounter == 0 and not self.config.showGrid then
-			self:SetAlpha(0.0)
-		end
-		self.cooldown:Hide()
-		self:SetChecked(false)
-	end
-
-	-- Add a green border if button is an equipped item
-	if self:IsEquipped() and not self.config.hideElements.equipped then
-		self.Border:SetVertexColor(0, 1.0, 0, 0.35)
-		self.Border:Show()
-	else
-		self.Border:Hide()
-	end
-
-	-- Update Action Text
-	if not self:IsConsumableOrStackable() then
-		self.Name:SetText(self:GetActionText())
-	else
-		self.Name:SetText("")
-	end
-
-	-- Update icon and hotkey
-	local texture = self:GetTexture()
-	if texture then
-		self.icon:SetTexture(texture)
-		self.icon:Show()
-		self.rangeTimer = - 1
-		self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
-		if not self.LBFSkinned and not self.MasqueSkinned then
-			self.NormalTexture:SetTexCoord(0, 0, 0, 0)
-		end
-	else
-		self.icon:Hide()
-		self.cooldown:Hide()
-		self.rangeTimer = nil
-		self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
-		if self.HotKey:GetText() == RANGE_INDICATOR then
-			self.HotKey:Hide()
-		else
-			self.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-		end
-		if not self.LBFSkinned and not self.MasqueSkinned then
-			self.NormalTexture:SetTexCoord(-0.15, 1.15, -0.15, 1.17)
-		end
-	end
-
-	self:UpdateLocal()
-
-	UpdateCount(self)
-
-	UpdateFlyout(self)
-
-	UpdateOverlayGlow(self)
-
-	UpdateNewAction(self)
-
-	if GameTooltip:GetOwner() == self then
-		UpdateTooltip(self)
-	end
-
-	-- this could've been a spec change, need to call OnStateChanged for action buttons, if present
-	if not InCombatLockdown() and self._state_type == "action" then
-		local onStateChanged = self:GetAttribute("OnStateChanged")
-		if onStateChanged then
-			self.header:SetFrameRef("updateButton", self)
-			self.header:Execute(([[
-				local frame = self:GetFrameRef("updateButton")
-				control:RunFor(frame, frame:GetAttribute("OnStateChanged"), %s, %s, %s)
-			]]):format(formatHelper(self:GetAttribute("state")), formatHelper(self._state_type), formatHelper(self._state_action)))
-		end
-	end
-	lib.callbacks:Fire("OnButtonUpdate", self)
-end
-
-function Generic:UpdateLocal()
-	-- dummy function the other button types can override for special updating
-end
-
-function UpdateButtonState(self)
-	if self:IsCurrentlyActive() or self:IsAutoRepeat() then
-		self:SetChecked(true)
-	else
-		self:SetChecked(false)
-	end
-	lib.callbacks:Fire("OnButtonState", self)
-end
-
-function UpdateUsable(self)
-	-- TODO: make the colors configurable
-	-- TODO: allow disabling of the whole recoloring
-	if self.config.outOfRangeColoring == "button" and self.outOfRange then
-		self.icon:SetVertexColor(unpack(self.config.colors.range))
-	else
-		local isUsable, notEnoughMana = self:IsUsable()
-		if isUsable then
-			self.icon:SetVertexColor(1.0, 1.0, 1.0)
-			--self.NormalTexture:SetVertexColor(1.0, 1.0, 1.0)
-		elseif notEnoughMana then
-			self.icon:SetVertexColor(unpack(self.config.colors.mana))
-			--self.NormalTexture:SetVertexColor(0.5, 0.5, 1.0)
-		else
-			self.icon:SetVertexColor(0.4, 0.4, 0.4)
-			--self.NormalTexture:SetVertexColor(1.0, 1.0, 1.0)
-		end
-	end
-	lib.callbacks:Fire("OnButtonUsable", self)
-end
-
-function UpdateCount(self)
-	if not self:HasAction() then
-		self.Count:SetText("")
-		return
-	end
-	if self:IsConsumableOrStackable() then
-		local count = self:GetCount()
-		if count > (self.maxDisplayCount or 9999) then
-			self.Count:SetText("*")
-		else
-			self.Count:SetText(count)
-		end
-	else
-		local charges, maxCharges, chargeStart, chargeDuration = self:GetCharges()
-		if charges and maxCharges and maxCharges > 0 then
-			self.Count:SetText(charges)
-		else
-			self.Count:SetText("")
-		end
-	end
-end
-
-local function SetCooldownHook(cooldown, ...)
-	local effectiveAlpha = cooldown:GetEffectiveAlpha()
-	local start, duration = ...
-
-	if start ~= 0 or duration ~= 0 then
-		-- update swipe alpha
-		cooldown.__metaLAB.SetSwipeColor(cooldown, cooldown.__SwipeR, cooldown.__SwipeG, cooldown.__SwipeB, cooldown.__SwipeA * effectiveAlpha)
-
-		-- only draw bling and edge if alpha is over 50%
-		cooldown:SetDrawBling(effectiveAlpha > 0.5)
-		if effectiveAlpha < 0.5 then
-			cooldown:SetDrawEdge(false)
-		end
-
-		-- ensure the swipe isn't drawn on fully faded bars
-		if effectiveAlpha <= 0.0 then
-			cooldown:SetDrawSwipe(false)
-		end
-	end
-
-	return cooldown.__metaLAB.SetCooldown(cooldown, ...)
-end
-
-local function SetSwipeColorHook(cooldown, r, g, b, a)
-	local effectiveAlpha = cooldown:GetEffectiveAlpha()
-	cooldown.__SwipeR, cooldown.__SwipeG, cooldown.__SwipeB, cooldown.__SwipeA = r, g, b, (a or 1)
-	return cooldown.__metaLAB.SetSwipeColor(cooldown, r, g, b, a * effectiveAlpha)
-end
-
-function HookCooldown(button)
-	if not button.cooldown.__metaLAB then
-		button.cooldown.__metaLAB = getmetatable(button.cooldown).__index
-		button.cooldown.__SwipeR, button.cooldown.__SwipeG, button.cooldown.__SwipeB, button.cooldown.__SwipeA = 0, 0, 0, 0.8
-
-		button.cooldown.SetCooldown = SetCooldownHook
-		button.cooldown.SetSwipeColor = SetSwipeColorHook
-	end
-end
-
-function OnCooldownDone(self)
-	self:SetScript("OnCooldownDone", nil)
-	UpdateCooldown(self:GetParent())
-end
-
-function UpdateCooldown(self)
-	local locStart, locDuration = self:GetLossOfControlCooldown()
-	local start, duration, enable, charges, maxCharges = self:GetCooldown()
-
-	if (locStart + locDuration) > (start + duration) then
-		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_LOSS_OF_CONTROL then
-			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge-LoC")
-			self.cooldown:SetHideCountdownNumbers(true)
-			self.cooldown.currentCooldownType = COOLDOWN_TYPE_LOSS_OF_CONTROL
-			self.cooldown:SetSwipeColor(0.17, 0, 0, 0.8)
-		end
-		CooldownFrame_SetTimer(self.cooldown, locStart, locDuration, 1, nil, nil, true)
-	else
-		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_NORMAL then
-			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge")
-			self.cooldown:SetHideCountdownNumbers(false)
-			self.cooldown.currentCooldownType = COOLDOWN_TYPE_NORMAL
-			self.cooldown:SetSwipeColor(0, 0, 0, 0.8)
-		end
-		if locStart > 0 then
-			self.cooldown:SetScript("OnCooldownDone", OnCooldownDone)
-		end
-		CooldownFrame_SetTimer(self.cooldown, start, duration, enable, charges, maxCharges)
-	end
-end
-
-function StartFlash(self)
-	self.flashing = 1
-	flashTime = 0
-	UpdateButtonState(self)
-end
-
-function StopFlash(self)
-	self.flashing = 0
-	self.Flash:Hide()
-	UpdateButtonState(self)
-end
-
-function UpdateFlash(self)
-	if (self:IsAttack() and self:IsCurrentlyActive()) or self:IsAutoRepeat() then
-		StartFlash(self)
-	else
-		StopFlash(self)
-	end
-end
-
-function UpdateTooltip(self)
-	if (GetCVar("UberTooltips") == "1") then
-		GameTooltip_SetDefaultAnchor(GameTooltip, self);
-	else
-		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
-	end
-	if self:SetTooltip() then
-		self.UpdateTooltip = UpdateTooltip
-	else
-		self.UpdateTooltip = nil
-	end
-end
-
-function UpdateHotkeys(self)
-	local key = self:GetHotkey()
-	if not key or key == "" or self.config.hideElements.hotkey then
-		self.HotKey:SetText(RANGE_INDICATOR)
-		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", 1, - 2)
-		self.HotKey:Hide()
-	else
-		self.HotKey:SetText(key)
-		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", - 2, - 2)
-		self.HotKey:Show()
-	end
-end
-
-local function OverlayGlow_OnHide(self)
-	if self.animOut:IsPlaying() then
-		self.animOut:Stop()
-		OverlayGlowAnimOutFinished(self.animOut)
-	end
-end
-
-function GetOverlayGlow()
-	local overlay = tremove(lib.unusedOverlayGlows);
-	if not overlay then
-		lib.numOverlays = lib.numOverlays + 1
-		overlay = CreateFrame("Frame", "LAB10ActionButtonOverlay"..lib.numOverlays, UIParent, "ActionBarButtonSpellActivationAlert")
-		overlay.animOut:SetScript("OnFinished", OverlayGlowAnimOutFinished)
-		overlay:SetScript("OnHide", OverlayGlow_OnHide)
-	end
-	return overlay
-end
-
-function ShowOverlayGlow(self)
-	if self.overlay then
-		if self.overlay.animOut:IsPlaying() then
-			self.overlay.animOut:Stop()
-			self.overlay.animIn:Play()
-		end
-	else
-		self.overlay = GetOverlayGlow()
-		local frameWidth, frameHeight = self:GetSize()
-		self.overlay:SetParent(self)
-		self.overlay:ClearAllPoints()
-		--Make the height/width available before the next frame:
-		self.overlay:SetSize(frameWidth * 1.4, frameHeight * 1.4)
-		self.overlay:SetPoint("TOPLEFT", self, "TOPLEFT", -frameWidth * 0.2, frameHeight * 0.2)
-		self.overlay:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", frameWidth * 0.2, -frameHeight * 0.2)
-		self.overlay.animIn:Play()
-	end
-end
-
-function HideOverlayGlow(self)
-	if self.overlay then
-		if self.overlay.animIn:IsPlaying() then
-			self.overlay.animIn:Stop()
-		end
-		if self:IsVisible() then
-			self.overlay.animOut:Play()
-		else
-			OverlayGlowAnimOutFinished(self.overlay.animOut)
-		end
-	end
-end
-
-function OverlayGlowAnimOutFinished(animGroup)
-	local overlay = animGroup:GetParent()
-	local actionButton = overlay:GetParent()
-	overlay:Hide()
-	tinsert(lib.unusedOverlayGlows, overlay)
-	actionButton.overlay = nil
-end
-
-function UpdateOverlayGlow(self)
-	local spellId = self:GetSpellId()
-	if spellId and IsSpellOverlayed(spellId) then
-		ShowOverlayGlow(self)
-	else
-		HideOverlayGlow(self)
-	end
-end
-
-hooksecurefunc("MarkNewActionHighlight", function(action, flag)
-	lib.ACTION_HIGHLIGHT_MARKS[action] = flag
-	for button in next, ButtonRegistry do
-		if button._state_type == "action" and action == tonumber(button._state_action) then
-			UpdateNewAction(button)
-		end
-	end
-end)
-
-function UpdateNewAction(self)
-	-- special handling for "New Action" markers
-	if self.NewActionTexture then
-		if self._state_type == "action" and lib.ACTION_HIGHLIGHT_MARKS[self._state_action] then
-			self.NewActionTexture:Show()
-		else
-			self.NewActionTexture:Hide()
-		end
-	end
-end
-
--- Hook UpdateFlyout so we can use the blizzy templates
-hooksecurefunc("ActionButton_UpdateFlyout", function(self, ...)
-	if ButtonRegistry[self] then
-		UpdateFlyout(self)
-	end
-end)
-
-function UpdateFlyout(self)
-	-- disabled FlyoutBorder/BorderShadow, those are not handled by LBF and look terrible
-	self.FlyoutBorder:Hide()
-	self.FlyoutBorderShadow:Hide()
-	if self._state_type == "action" then
-		-- based on ActionButton_UpdateFlyout in ActionButton.lua
-		local actionType = GetActionInfo(self._state_action)
-		if actionType == "flyout" then
-			-- Update border and determine arrow position
-			local arrowDistance
-			if (SpellFlyout and SpellFlyout:IsShown() and SpellFlyout:GetParent() == self) or GetMouseFocus() == self then
-				arrowDistance = 5
-			else
-				arrowDistance = 2
-			end
-
-			-- Update arrow
-			self.FlyoutArrow:Show()
-			self.FlyoutArrow:ClearAllPoints()
-			local direction = self:GetAttribute("flyoutDirection");
-			if direction == "LEFT" then
-				self.FlyoutArrow:SetPoint("LEFT", self, "LEFT", -arrowDistance, 0)
-				SetClampedTextureRotation(self.FlyoutArrow, 270)
-			elseif direction == "RIGHT" then
-				self.FlyoutArrow:SetPoint("RIGHT", self, "RIGHT", arrowDistance, 0)
-				SetClampedTextureRotation(self.FlyoutArrow, 90)
-			elseif direction == "DOWN" then
-				self.FlyoutArrow:SetPoint("BOTTOM", self, "BOTTOM", 0, -arrowDistance)
-				SetClampedTextureRotation(self.FlyoutArrow, 180)
-			else
-				self.FlyoutArrow:SetPoint("TOP", self, "TOP", 0, arrowDistance)
-				SetClampedTextureRotation(self.FlyoutArrow, 0)
-			end
-
-			-- return here, otherwise flyout is hidden
-			return
-		end
-	end
-	self.FlyoutArrow:Hide()
-end
-
-function UpdateRangeTimer()
-	rangeTimer = -1
-end
-
-local function GetSpellIdByName(spellName)
-	if not spellName then return end
-	local spellLink = GetSpellLink(spellName)
-	if spellLink then
-		return tonumber(spellLink:match("spell:(%d+)"))
-	end
-	return nil
-end
-
------------------------------------------------------------
---- WoW API mapping
---- Generic Button
-Generic.HasAction               = function(self) return nil end
-Generic.GetActionText           = function(self) return "" end
-Generic.GetTexture              = function(self) return nil end
-Generic.GetCharges              = function(self) return nil end
-Generic.GetCount                = function(self) return 0 end
-Generic.GetCooldown             = function(self) return 0, 0, 0 end
-Generic.IsAttack                = function(self) return nil end
-Generic.IsEquipped              = function(self) return nil end
-Generic.IsCurrentlyActive       = function(self) return nil end
-Generic.IsAutoRepeat            = function(self) return nil end
-Generic.IsUsable                = function(self) return nil end
-Generic.IsConsumableOrStackable = function(self) return nil end
-Generic.IsUnitInRange           = function(self, unit) return nil end
-Generic.IsInRange               = function(self)
-	local unit = self:GetAttribute("unit")
-	if unit == "player" then
-		unit = nil
-	end
-	local val = self:IsUnitInRange(unit)
-	-- map 1/0 to true false, since the return values are inconsistent between actions and spells
-	if val == 1 then val = true elseif val == 0 then val = false end
-	return val
-end
-Generic.SetTooltip              = function(self) return nil end
-Generic.GetSpellId              = function(self) return nil end
-Generic.GetLossOfControlCooldown = function(self) return 0, 0 end
-
------------------------------------------------------------
---- Action Button
-Action.HasAction               = function(self) return HasAction(self._state_action) end
-Action.GetActionText           = function(self) return GetActionText(self._state_action) end
-Action.GetTexture              = function(self) return GetActionTexture(self._state_action) end
-Action.GetCharges              = function(self) return GetActionCharges(self._state_action) end
-Action.GetCount                = function(self) return GetActionCount(self._state_action) end
-Action.GetCooldown             = function(self) return GetActionCooldown(self._state_action) end
-Action.IsAttack                = function(self) return IsAttackAction(self._state_action) end
-Action.IsEquipped              = function(self) return IsEquippedAction(self._state_action) end
-Action.IsCurrentlyActive       = function(self) return IsCurrentAction(self._state_action) end
-Action.IsAutoRepeat            = function(self) return IsAutoRepeatAction(self._state_action) end
-Action.IsUsable                = function(self) return IsUsableAction(self._state_action) end
-Action.IsConsumableOrStackable = function(self) return IsConsumableAction(self._state_action) or IsStackableAction(self._state_action) or (not IsItemAction(self._state_action) and GetActionCount(self._state_action) > 0) end
-Action.IsUnitInRange           = function(self, unit) return IsActionInRange(self._state_action, unit) end
-Action.SetTooltip              = function(self) return GameTooltip:SetAction(self._state_action) end
-Action.GetSpellId              = function(self)
-	local actionType, id, subType = GetActionInfo(self._state_action)
-	if actionType == "spell" then
-		return id
-	elseif actionType == "macro" then
-		local _, _, spellId = GetMacroSpell(id)
-		return spellId
-	end
-end
-Action.GetLossOfControlCooldown = function(self) return GetActionLossOfControlCooldown(self._state_action) end
-
------------------------------------------------------------
---- Spell Button
-Spell.HasAction               = function(self) return true end
-Spell.GetActionText           = function(self) return "" end
-Spell.GetTexture              = function(self) return GetSpellTexture(self._state_action) end
-Spell.GetCharges              = function(self) return GetSpellCharges(self._state_action) end
-Spell.GetCount                = function(self) return GetSpellCount(self._state_action) end
-Spell.GetCooldown             = function(self) return GetSpellCooldown(self._state_action) end
-Spell.IsAttack                = function(self) return IsAttackSpell(FindSpellBookSlotBySpellID(self._state_action), "spell") end -- needs spell book id as of 4.0.1.13066
-Spell.IsEquipped              = function(self) return nil end
-Spell.IsCurrentlyActive       = function(self) return IsCurrentSpell(self._state_action) end
-Spell.IsAutoRepeat            = function(self) return IsAutoRepeatSpell(FindSpellBookSlotBySpellID(self._state_action), "spell") end -- needs spell book id as of 4.0.1.13066
-Spell.IsUsable                = function(self) return IsUsableSpell(self._state_action) end
-Spell.IsConsumableOrStackable = function(self) return IsConsumableSpell(self._state_action) end
-Spell.IsUnitInRange           = function(self, unit) return IsSpellInRange(FindSpellBookSlotBySpellID(self._state_action), "spell", unit) end -- needs spell book id as of 4.0.1.13066
-Spell.SetTooltip              = function(self) return GameTooltip:SetSpellByID(self._state_action) end
-Spell.GetSpellId              = function(self) return self._state_action end
-
------------------------------------------------------------
---- Item Button
-local function getItemId(input)
-	return input:match("^item:(%d+)")
-end
-
-Item.HasAction               = function(self) return true end
-Item.GetActionText           = function(self) return "" end
-Item.GetTexture              = function(self) return GetItemIcon(self._state_action) end
-Item.GetCharges              = function(self) return nil end
-Item.GetCount                = function(self) return GetItemCount(self._state_action, nil, true) end
-Item.GetCooldown             = function(self) return GetItemCooldown(getItemId(self._state_action)) end
-Item.IsAttack                = function(self) return nil end
-Item.IsEquipped              = function(self) return IsEquippedItem(self._state_action) end
-Item.IsCurrentlyActive       = function(self) return IsCurrentItem(self._state_action) end
-Item.IsAutoRepeat            = function(self) return nil end
-Item.IsUsable                = function(self) return IsUsableItem(self._state_action) end
-Item.IsConsumableOrStackable = function(self) return IsConsumableItem(self._state_action) end
-Item.IsUnitInRange           = function(self, unit) return IsItemInRange(self._state_action, unit) end
-Item.SetTooltip              = function(self) return GameTooltip:SetHyperlink(self._state_action) end
-Item.GetSpellId              = function(self) return nil end
-
------------------------------------------------------------
---- Macro Button
--- TODO: map results of GetMacroSpell/GetMacroItem to proper results
-Macro.HasAction               = function(self) return true end
-Macro.GetActionText           = function(self) return (GetMacroInfo(self._state_action)) end
-Macro.GetTexture              = function(self) return (select(2, GetMacroInfo(self._state_action))) end
-Macro.GetCharges              = function(self) return nil end
-Macro.GetCount                = function(self) return 0 end
-Macro.GetCooldown             = function(self) return 0, 0, 0 end
-Macro.IsAttack                = function(self) return nil end
-Macro.IsEquipped              = function(self) return nil end
-Macro.IsCurrentlyActive       = function(self) return nil end
-Macro.IsAutoRepeat            = function(self) return nil end
-Macro.IsUsable                = function(self) return nil end
-Macro.IsConsumableOrStackable = function(self) return nil end
-Macro.IsUnitInRange           = function(self, unit) return nil end
-Macro.SetTooltip              = function(self) return nil end
-Macro.GetSpellId              = function(self) return nil end
-
------------------------------------------------------------
---- Custom Button
-Custom.HasAction               = function(self) return true end
-Custom.GetActionText           = function(self) return "" end
-Custom.GetTexture              = function(self) return self._state_action.texture end
-Custom.GetCharges              = function(self) return nil end
-Custom.GetCount                = function(self) return 0 end
-Custom.GetCooldown             = function(self) return 0, 0, 0 end
-Custom.IsAttack                = function(self) return nil end
-Custom.IsEquipped              = function(self) return nil end
-Custom.IsCurrentlyActive       = function(self) return nil end
-Custom.IsAutoRepeat            = function(self) return nil end
-Custom.IsUsable                = function(self) return true end
-Custom.IsConsumableOrStackable = function(self) return nil end
-Custom.IsUnitInRange           = function(self, unit) return nil end
-Custom.SetTooltip              = function(self) return GameTooltip:SetText(self._state_action.tooltip) end
-Custom.GetSpellId              = function(self) return nil end
-Custom.RunCustom               = function(self, unit, button) return self._state_action.func(self, unit, button) end
-
------------------------------------------------------------
---- Update old Buttons
-if oldversion and next(lib.buttonRegistry) then
-	InitializeEventHandler()
-	for button in next, lib.buttonRegistry do
-		-- this refreshes the metatable on the button
-		Generic.UpdateAction(button, true)
-		SetupSecureSnippets(button)
-		if oldversion < 12 then
-			WrapOnClick(button)
-		end
-		if oldversion < 23 then
-			if button.overlay then
-				button.overlay:Hide()
-				ActionButton_HideOverlayGlow(button)
-				button.overlay = nil
-				UpdateOverlayGlow(button)
-			end
-		end
-	end
-end
diff --git a/Jamba/LibActionButtonJamba-1.0-66.lua b/Jamba/LibActionButtonJamba-1.0-66.lua
deleted file mode 100644
index 8f28d61..0000000
--- a/Jamba/LibActionButtonJamba-1.0-66.lua
+++ /dev/null
@@ -1,1585 +0,0 @@
---[[
-Copyright (c) 2010-2017, Hendrik "nevcairiel" Leppkes <h.leppkes@gmail.com>
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of the developer nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-]]
-local MAJOR_VERSION = "LibActionButtonJamba-1.0"
-local MINOR_VERSION = 68
-
-if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
-local lib, oldversion = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
-if not lib then return end
-
--- Lua functions
-local _G = _G
-local type, error, tostring, tonumber, assert, select = type, error, tostring, tonumber, assert, select
-local setmetatable, wipe, unpack, pairs, next = setmetatable, wipe, unpack, pairs, next
-local str_match, format, tinsert, tremove = string.match, format, tinsert, tremove
-
--- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
--- List them here for Mikk's FindGlobals script
--- Note: No WoW API function get upvalued to allow proper interaction with any addons that try to hook them.
--- GLOBALS: LibStub, CreateFrame, InCombatLockdown, ClearCursor, GetCursorInfo, GameTooltip, GameTooltip_SetDefaultAnchor
--- GLOBALS: GetBindingKey, GetBindingText, SetBinding, SetBindingClick, GetCVar, GetMacroInfo
--- GLOBALS: PickupAction, PickupItem, PickupMacro, PickupPetAction, PickupSpell, PickupCompanion, PickupEquipmentSet
--- GLOBALS: CooldownFrame_SetTimer, UIParent, IsSpellOverlayed, SpellFlyout, GetMouseFocus, SetClampedTextureRotation
--- GLOBALS: GetActionInfo, GetActionTexture, HasAction, GetActionText, GetActionCount, GetActionCooldown, IsAttackAction
--- GLOBALS: IsAutoRepeatAction, IsEquippedAction, IsCurrentAction, IsConsumableAction, IsUsableAction, IsStackableAction, IsActionInRange
--- GLOBALS: GetSpellLink, GetMacroSpell, GetSpellTexture, GetSpellCount, GetSpellCooldown, IsAttackSpell, IsCurrentSpell
--- GLOBALS: FindSpellBookSlotBySpellID, IsUsableSpell, IsConsumableSpell, IsSpellInRange, IsAutoRepeatSpell
--- GLOBALS: GetItemIcon, GetItemCount, GetItemCooldown, IsEquippedItem, IsCurrentItem, IsUsableItem, IsConsumableItem, IsItemInRange
--- GLOBALS: GetActionCharges, IsItemAction, GetSpellCharges
--- GLOBALS: RANGE_INDICATOR, ATTACK_BUTTON_FLASH_TIME, TOOLTIP_UPDATE_TIME
--- GLOBALS: ZoneAbilityFrame, HasZoneAbility, GetLastZoneAbilitySpellTexture
-
-local KeyBound = LibStub("LibKeyBound-1.0", true)
-local CBH = LibStub("CallbackHandler-1.0")
-local LBG = LibStub("LibButtonGlow-1.0", true)
-local Masque = LibStub("Masque", true)
-
-lib.eventFrame = lib.eventFrame or CreateFrame("Frame")
-lib.eventFrame:UnregisterAllEvents()
-
-lib.buttonRegistry = lib.buttonRegistry or {}
-lib.activeButtons = lib.activeButtons or {}
-lib.actionButtons = lib.actionButtons or {}
-lib.nonActionButtons = lib.nonActionButtons or {}
-
-lib.ChargeCooldowns = lib.ChargeCooldowns or {}
-lib.NumChargeCooldowns = lib.NumChargeCooldowns or 0
-
-lib.ACTION_HIGHLIGHT_MARKS = lib.ACTION_HIGHLIGHT_MARKS or setmetatable({}, { __index = ACTION_HIGHLIGHT_MARKS })
-
-lib.callbacks = lib.callbacks or CBH:New(lib)
-
-local Generic = CreateFrame("CheckButton")
-local Generic_MT = {__index = Generic}
-
-local Action = setmetatable({}, {__index = Generic})
-local Action_MT = {__index = Action}
-
-local PetAction = setmetatable({}, {__index = Generic})
-local PetAction_MT = {__index = PetAction}
-
-local Spell = setmetatable({}, {__index = Generic})
-local Spell_MT = {__index = Spell}
-
-local Item = setmetatable({}, {__index = Generic})
-local Item_MT = {__index = Item}
-
-local Macro = setmetatable({}, {__index = Generic})
-local Macro_MT = {__index = Macro}
-
-local Custom = setmetatable({}, {__index = Generic})
-local Custom_MT = {__index = Custom}
-
-local type_meta_map = {
-	empty  = Generic_MT,
-	action = Action_MT,
-	--pet    = PetAction_MT,
-	spell  = Spell_MT,
-	item   = Item_MT,
-	macro  = Macro_MT,
-	custom = Custom_MT
-}
-
-local ButtonRegistry, ActiveButtons, ActionButtons, NonActionButtons = lib.buttonRegistry, lib.activeButtons, lib.actionButtons, lib.nonActionButtons
-
-local Update, UpdateButtonState, UpdateUsable, UpdateCount, UpdateCooldown, UpdateTooltip, UpdateNewAction, ClearNewActionHighlight
-local StartFlash, StopFlash, UpdateFlash, UpdateHotkeys, UpdateRangeTimer, UpdateOverlayGlow
-local UpdateFlyout, ShowGrid, HideGrid, UpdateGrid, SetupSecureSnippets, WrapOnClick
-local ShowOverlayGlow, HideOverlayGlow
-local EndChargeCooldown
-
-local InitializeEventHandler, OnEvent, ForAllButtons, OnUpdate
-
-local DefaultConfig = {
-	outOfRangeColoring = "button",
-	tooltip = "enabled",
-	showGrid = false,
-	colors = {
-		range = { 0.8, 0.1, 0.1 },
-		mana = { 0.5, 0.5, 1.0 }
-	},
-	hideElements = {
-		macro = false,
-		hotkey = false,
-		equipped = false,
-	},
-	keyBoundTarget = false,
-	clickOnDown = false,
-	flyoutDirection = "UP",
-}
-
---- Create a new action button.
--- @param id Internal id of the button (not used by LibActionButton-1.0, only for tracking inside the calling addon)
--- @param name Name of the button frame to be created (not used by LibActionButton-1.0 aside from naming the frame)
--- @param header Header that drives these action buttons (if any)
-function lib:CreateButton(id, name, header, config)
-	if type(name) ~= "string" then
-		error("Usage: CreateButton(id, name. header): Buttons must have a valid name!", 2)
-	end
-	if not header then
-		error("Usage: CreateButton(id, name, header): Buttons without a secure header are not yet supported!", 2)
-	end
-
-	if not KeyBound then
-		KeyBound = LibStub("LibKeyBound-1.0", true)
-	end
-
-	local button = setmetatable(CreateFrame("CheckButton", name, header, "SecureActionButtonTemplate, ActionButtonTemplate"), Generic_MT)
-	button:RegisterForDrag("LeftButton", "RightButton")
-	button:RegisterForClicks("AnyUp")
-
-	-- Frame Scripts
-	button:SetScript("OnEnter", Generic.OnEnter)
-	button:SetScript("OnLeave", Generic.OnLeave)
-	button:SetScript("PreClick", Generic.PreClick)
-	button:SetScript("PostClick", Generic.PostClick)
-
-	button.id = id
-	button.header = header
-	-- Mapping of state -> action
-	button.state_types = {}
-	button.state_actions = {}
-
-	-- Store the LAB Version that created this button for debugging
-	button.__LAB_Version = MINOR_VERSION
-
-	-- just in case we're not run by a header, default to state 0
-	button:SetAttribute("state", 0)
-
-	SetupSecureSnippets(button)
-	WrapOnClick(button)
-
-	-- adjust hotkey style for better readability
-	button.HotKey:SetFont(button.HotKey:GetFont(), 13, "OUTLINE")
-	button.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-
-	-- adjust count/stack size
-	button.Count:SetFont(button.Count:GetFont(), 16, "OUTLINE")
-
-	-- Store the button in the registry, needed for event and OnUpdate handling
-	if not next(ButtonRegistry) then
-		InitializeEventHandler()
-	end
-	ButtonRegistry[button] = true
-
-	button:UpdateConfig(config)
-
-	-- run an initial update
-	button:UpdateAction()
-	UpdateHotkeys(button)
-
-	-- somewhat of a hack for the Flyout buttons to not error.
-	button.action = 0
-
-	lib.callbacks:Fire("OnButtonCreated", button)
-
-	return button
-end
-
-function SetupSecureSnippets(button)
-	button:SetAttribute("_custom", Custom.RunCustom)
-	-- secure UpdateState(self, state)
-	-- update the type and action of the button based on the state
-	button:SetAttribute("UpdateState", [[
-		local state = ...
-		self:SetAttribute("state", state)
-		local type, action = (self:GetAttribute(format("labtype-%s", state)) or "empty"), self:GetAttribute(format("labaction-%s", state))
-
-		self:SetAttribute("type", type)
-		if type ~= "empty" and type ~= "custom" then
-			local action_field = (type == "pet") and "action" or type
-			self:SetAttribute(action_field, action)
-			self:SetAttribute("action_field", action_field)
-		end
-		local onStateChanged = self:GetAttribute("OnStateChanged")
-		if onStateChanged then
-			self:Run(onStateChanged, state, type, action)
-		end
-	]])
-
-	-- this function is invoked by the header when the state changes
-	button:SetAttribute("_childupdate-state", [[
-		self:RunAttribute("UpdateState", message)
-		self:CallMethod("UpdateAction")
-	]])
-
-	-- secure PickupButton(self, kind, value, ...)
-	-- utility function to place a object on the cursor
-	button:SetAttribute("PickupButton", [[
-		local kind, value = ...
-		if kind == "empty" then
-			return "clear"
-		elseif kind == "action" or kind == "pet" then
-			local actionType = (kind == "pet") and "petaction" or kind
-			return actionType, value
-		elseif kind == "spell" or kind == "item" or kind == "macro" then
-			return "clear", kind, value
-		else
-			print("LibActionButton-1.0: Unknown type: " .. tostring(kind))
-			return false
-		end
-	]])
-
-	button:SetAttribute("OnDragStart", [[
-		if (self:GetAttribute("buttonlock") and not IsModifiedClick("PICKUPACTION")) or self:GetAttribute("LABdisableDragNDrop") then return false end
-		local state = self:GetAttribute("state")
-		local type = self:GetAttribute("type")
-		-- if the button is empty, we can't drag anything off it
-		if type == "empty" or type == "custom" then
-			return false
-		end
-		-- Get the value for the action attribute
-		local action_field = self:GetAttribute("action_field")
-		local action = self:GetAttribute(action_field)
-
-		-- non-action fields need to change their type to empty
-		if type ~= "action" and type ~= "pet" then
-			self:SetAttribute(format("labtype-%s", state), "empty")
-			self:SetAttribute(format("labaction-%s", state), nil)
-			-- update internal state
-			self:RunAttribute("UpdateState", state)
-			-- send a notification to the insecure code
-			self:CallMethod("ButtonContentsChanged", state, "empty", nil)
-		end
-		-- return the button contents for pickup
-		return self:RunAttribute("PickupButton", type, action)
-	]])
-
-	button:SetAttribute("OnReceiveDrag", [[
-		if self:GetAttribute("LABdisableDragNDrop") then return false end
-		local kind, value, subtype, extra = ...
-		if not kind or not value then return false end
-		local state = self:GetAttribute("state")
-		local buttonType, buttonAction = self:GetAttribute("type"), nil
-		if buttonType == "custom" then return false end
-		-- action buttons can do their magic themself
-		-- for all other buttons, we'll need to update the content now
-		if buttonType ~= "action" and buttonType ~= "pet" then
-			-- with "spell" types, the 4th value contains the actual spell id
-			if kind == "spell" then
-				if extra then
-					value = extra
-				else
-					print("no spell id?", ...)
-				end
-			elseif kind == "item" and value then
-				value = format("item:%d", value)
-			end
-
-			-- Get the action that was on the button before
-			if buttonType ~= "empty" then
-				buttonAction = self:GetAttribute(self:GetAttribute("action_field"))
-			end
-
-			-- TODO: validate what kind of action is being fed in here
-			-- We can only use a handful of the possible things on the cursor
-			-- return false for all those we can't put on buttons
-
-			self:SetAttribute(format("labtype-%s", state), kind)
-			self:SetAttribute(format("labaction-%s", state), value)
-			-- update internal state
-			self:RunAttribute("UpdateState", state)
-			-- send a notification to the insecure code
-			self:CallMethod("ButtonContentsChanged", state, kind, value)
-		else
-			-- get the action for (pet-)action buttons
-			buttonAction = self:GetAttribute("action")
-		end
-		return self:RunAttribute("PickupButton", buttonType, buttonAction)
-	]])
-
-	button:SetScript("OnDragStart", nil)
-	-- Wrapped OnDragStart(self, button, kind, value, ...)
-	button.header:WrapScript(button, "OnDragStart", [[
-		return self:RunAttribute("OnDragStart")
-	]])
-	-- Wrap twice, because the post-script is not run when the pre-script causes a pickup (doh)
-	-- we also need some phony message, or it won't work =/
-	button.header:WrapScript(button, "OnDragStart", [[
-		return "message", "update"
-	]], [[
-		self:RunAttribute("UpdateState", self:GetAttribute("state"))
-	]])
-
-	button:SetScript("OnReceiveDrag", nil)
-	-- Wrapped OnReceiveDrag(self, button, kind, value, ...)
-	button.header:WrapScript(button, "OnReceiveDrag", [[
-		return self:RunAttribute("OnReceiveDrag", kind, value, ...)
-	]])
-	-- Wrap twice, because the post-script is not run when the pre-script causes a pickup (doh)
-	-- we also need some phony message, or it won't work =/
-	button.header:WrapScript(button, "OnReceiveDrag", [[
-		return "message", "update"
-	]], [[
-		self:RunAttribute("UpdateState", self:GetAttribute("state"))
-	]])
-end
-
-function WrapOnClick(button)
-	-- Wrap OnClick, to catch changes to actions that are applied with a click on the button.
-	button.header:WrapScript(button, "OnClick", [[
-		if self:GetAttribute("type") == "action" then
-			local type, action = GetActionInfo(self:GetAttribute("action"))
-			return nil, format("%s|%s", tostring(type), tostring(action))
-		end
-	]], [[
-		local type, action = GetActionInfo(self:GetAttribute("action"))
-		if message ~= format("%s|%s", tostring(type), tostring(action)) then
-			self:RunAttribute("UpdateState", self:GetAttribute("state"))
-		end
-	]])
-end
-
------------------------------------------------------------
---- utility
-
-function lib:GetAllButtons()
-	local buttons = {}
-	for button in next, ButtonRegistry do
-		buttons[button] = true
-	end
-	return buttons
-end
-
-function Generic:ClearSetPoint(...)
-	self:ClearAllPoints()
-	self:SetPoint(...)
-end
-
-function Generic:NewHeader(header)
-	self.header = header
-	self:SetParent(header)
-	SetupSecureSnippets(self)
-	WrapOnClick(self)
-end
-
-
------------------------------------------------------------
---- state management
-
-function Generic:ClearStates()
-	for state in pairs(self.state_types) do
-		self:SetAttribute(format("labtype-%s", state), nil)
-		self:SetAttribute(format("labaction-%s", state), nil)
-	end
-	wipe(self.state_types)
-	wipe(self.state_actions)
-end
-
-function Generic:SetState(state, kind, action)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	-- we allow a nil kind for setting a empty state
-	if not kind then kind = "empty" end
-	if not type_meta_map[kind] then
-		error("SetStateAction: unknown action type: " .. tostring(kind), 2)
-	end
-	if kind ~= "empty" and action == nil then
-		error("SetStateAction: an action is required for non-empty states", 2)
-	end
-	if kind ~= "custom" and action ~= nil and type(action) ~= "number" and type(action) ~= "string" or (kind == "custom" and type(action) ~= "table") then
-		error("SetStateAction: invalid action data type, only strings and numbers allowed", 2)
-	end
-
-	if kind == "item" then
-		if tonumber(action) then
-			action = format("item:%s", action)
-		else
-			local itemString = str_match(action, "^|c%x+|H(item[%d:]+)|h%[")
-			if itemString then
-				action = itemString
-			end
-		end
-	end
-
-	self.state_types[state] = kind
-	self.state_actions[state] = action
-	self:UpdateState(state)
-end
-
-function Generic:UpdateState(state)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	self:SetAttribute(format("labtype-%s", state), self.state_types[state])
-	self:SetAttribute(format("labaction-%s", state), self.state_actions[state])
-	if state ~= tostring(self:GetAttribute("state")) then return end
-	if self.header then
-		self.header:SetFrameRef("updateButton", self)
-		self.header:Execute([[
-			local frame = self:GetFrameRef("updateButton")
-			control:RunFor(frame, frame:GetAttribute("UpdateState"), frame:GetAttribute("state"))
-		]])
-	else
-	-- TODO
-	end
-	self:UpdateAction()
-end
-
-function Generic:GetAction(state)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	return self.state_types[state] or "empty", self.state_actions[state]
-end
-
-function Generic:UpdateAllStates()
-	for state in pairs(self.state_types) do
-		self:UpdateState(state)
-	end
-end
-
-function Generic:ButtonContentsChanged(state, kind, value)
-	state = tostring(state)
-	self.state_types[state] = kind or "empty"
-	self.state_actions[state] = value
-	lib.callbacks:Fire("OnButtonContentsChanged", self, state, self.state_types[state], self.state_actions[state])
-	self:UpdateAction(self)
-end
-
-function Generic:DisableDragNDrop(flag)
-	if InCombatLockdown() then
-		error("LibActionButton-1.0: You can only toggle DragNDrop out of combat!", 2)
-	end
-	if flag then
-		self:SetAttribute("LABdisableDragNDrop", true)
-	else
-		self:SetAttribute("LABdisableDragNDrop", nil)
-	end
-end
-
-function Generic:AddToButtonFacade(group)
-	if type(group) ~= "table" or type(group.AddButton) ~= "function" then
-		error("LibActionButton-1.0:AddToButtonFacade: You need to supply a proper group to use!", 2)
-	end
-	group:AddButton(self)
-	self.LBFSkinned = true
-end
-
-function Generic:AddToMasque(group)
-	if type(group) ~= "table" or type(group.AddButton) ~= "function" then
-		error("LibActionButton-1.0:AddToMasque: You need to supply a proper group to use!", 2)
-	end
-	group:AddButton(self)
-	self.MasqueSkinned = true
-end
-
-function Generic:UpdateAlpha()
-	UpdateCooldown(self)
-end
-
------------------------------------------------------------
---- frame scripts
-
--- copied (and adjusted) from SecureHandlers.lua
-local function PickupAny(kind, target, detail, ...)
-	if kind == "clear" then
-		ClearCursor()
-		kind, target, detail = target, detail, ...
-	end
-
-	if kind == 'action' then
-		PickupAction(target)
-	elseif kind == 'item' then
-		PickupItem(target)
-	elseif kind == 'macro' then
-		PickupMacro(target)
-	elseif kind == 'petaction' then
-		PickupPetAction(target)
-	elseif kind == 'spell' then
-		PickupSpell(target)
-	elseif kind == 'companion' then
-		PickupCompanion(target, detail)
-	elseif kind == 'equipmentset' then
-		PickupEquipmentSet(target)
-	end
-end
-
-function Generic:OnEnter()
-	if self.config.tooltip ~= "disabled" and (self.config.tooltip ~= "nocombat" or not InCombatLockdown()) then
-		UpdateTooltip(self)
-	end
-	if KeyBound then
-		KeyBound:Set(self)
-	end
-
-	if self._state_type == "action" and self.NewActionTexture then
-		ClearNewActionHighlight(self._state_action, false, false)
-		UpdateNewAction(self)
-	end
-end
-
-function Generic:OnLeave()
-	GameTooltip:Hide()
-end
-
--- Insecure drag handler to allow clicking on the button with an action on the cursor
--- to place it on the button. Like action buttons work.
-function Generic:PreClick()
-	if self._state_type == "action" or self._state_type == "pet"
-	   or InCombatLockdown() or self:GetAttribute("LABdisableDragNDrop")
-	then
-		return
-	end
-	-- check if there is actually something on the cursor
-	local kind, value, subtype = GetCursorInfo()
-	if not (kind and value) then return end
-	self._old_type = self._state_type
-	if self._state_type and self._state_type ~= "empty" then
-		self._old_type = self._state_type
-		self:SetAttribute("type", "empty")
-		--self:SetState(nil, "empty", nil)
-	end
-	self._receiving_drag = true
-end
-
-local function formatHelper(input)
-	if type(input) == "string" then
-		return format("%q", input)
-	else
-		return tostring(input)
-	end
-end
-
-function Generic:PostClick()
-	UpdateButtonState(self)
-	if self._receiving_drag and not InCombatLockdown() then
-		if self._old_type then
-			self:SetAttribute("type", self._old_type)
-			self._old_type = nil
-		end
-		local oldType, oldAction = self._state_type, self._state_action
-		local kind, data, subtype, extra = GetCursorInfo()
-		self.header:SetFrameRef("updateButton", self)
-		self.header:Execute(format([[
-			local frame = self:GetFrameRef("updateButton")
-			control:RunFor(frame, frame:GetAttribute("OnReceiveDrag"), %s, %s, %s, %s)
-			control:RunFor(frame, frame:GetAttribute("UpdateState"), %s)
-		]], formatHelper(kind), formatHelper(data), formatHelper(subtype), formatHelper(extra), formatHelper(self:GetAttribute("state"))))
-		PickupAny("clear", oldType, oldAction)
-	end
-	self._receiving_drag = nil
-
-	if self._state_type == "action" and lib.ACTION_HIGHLIGHT_MARKS[self._state_action] then
-		ClearNewActionHighlight(self._state_action, false, false)
-	end
-end
-
------------------------------------------------------------
---- configuration
-
-local function merge(target, source, default)
-	for k,v in pairs(default) do
-		if type(v) ~= "table" then
-			if source and source[k] ~= nil then
-				target[k] = source[k]
-			else
-				target[k] = v
-			end
-		else
-			if type(target[k]) ~= "table" then target[k] = {} else wipe(target[k]) end
-			merge(target[k], type(source) == "table" and source[k], v)
-		end
-	end
-	return target
-end
-
-function Generic:UpdateConfig(config)
-	if config and type(config) ~= "table" then
-		error("LibActionButton-1.0: UpdateConfig requires a valid configuration!", 2)
-	end
-	local oldconfig = self.config
-	if not self.config then self.config = {} end
-	-- merge the two configs
-	merge(self.config, config, DefaultConfig)
-
-	if self.config.outOfRangeColoring == "button" or (oldconfig and oldconfig.outOfRangeColoring == "button") then
-		UpdateUsable(self)
-	end
-	if self.config.outOfRangeColoring == "hotkey" then
-		self.outOfRange = nil
-	elseif oldconfig and oldconfig.outOfRangeColoring == "hotkey" then
-		self.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-	end
-
-	if self.config.hideElements.macro then
-		self.Name:Hide()
-	else
-		self.Name:Show()
-	end
-
-	self:SetAttribute("flyoutDirection", self.config.flyoutDirection)
-
-	UpdateHotkeys(self)
-	UpdateGrid(self)
-	Update(self)
-	self:RegisterForClicks(self.config.clickOnDown and "AnyDown" or "AnyUp")
-end
-
------------------------------------------------------------
---- event handler
-
-function ForAllButtons(method, onlyWithAction)
-	assert(type(method) == "function")
-	for button in next, (onlyWithAction and ActiveButtons or ButtonRegistry) do
-		method(button)
-	end
-end
-
-function InitializeEventHandler()
-	lib.eventFrame:SetScript("OnEvent", OnEvent)
-	lib.eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_SHOWGRID")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_HIDEGRID")
-	--lib.eventFrame:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
-	--lib.eventFrame:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
-	lib.eventFrame:RegisterEvent("UPDATE_BINDINGS")
-	lib.eventFrame:RegisterEvent("UPDATE_SHAPESHIFT_FORM")
-	lib.eventFrame:RegisterEvent("UPDATE_VEHICLE_ACTIONBAR")
-
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_STATE")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
-	lib.eventFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
-	lib.eventFrame:RegisterEvent("TRADE_SKILL_SHOW")
-	lib.eventFrame:RegisterEvent("TRADE_SKILL_CLOSE")
-	lib.eventFrame:RegisterEvent("ARCHAEOLOGY_CLOSED")
-	lib.eventFrame:RegisterEvent("PLAYER_ENTER_COMBAT")
-	lib.eventFrame:RegisterEvent("PLAYER_LEAVE_COMBAT")
-	lib.eventFrame:RegisterEvent("START_AUTOREPEAT_SPELL")
-	lib.eventFrame:RegisterEvent("STOP_AUTOREPEAT_SPELL")
-	lib.eventFrame:RegisterEvent("UNIT_ENTERED_VEHICLE")
-	lib.eventFrame:RegisterEvent("UNIT_EXITED_VEHICLE")
-	lib.eventFrame:RegisterEvent("COMPANION_UPDATE")
-	lib.eventFrame:RegisterEvent("UNIT_INVENTORY_CHANGED")
-	lib.eventFrame:RegisterEvent("LEARNED_SPELL_IN_TAB")
-	lib.eventFrame:RegisterEvent("PET_STABLE_UPDATE")
-	lib.eventFrame:RegisterEvent("PET_STABLE_SHOW")
-	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_SHOW")
-	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_HIDE")
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_CHARGES")
-	lib.eventFrame:RegisterEvent("UPDATE_SUMMONPETS_ACTION")
-
-	-- With those two, do we still need the ACTIONBAR equivalents of them?
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_COOLDOWN")
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_USABLE")
-	lib.eventFrame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
-
-	lib.eventFrame:RegisterEvent("LOSS_OF_CONTROL_ADDED")
-	lib.eventFrame:RegisterEvent("LOSS_OF_CONTROL_UPDATE")
-
-	lib.eventFrame:Show()
-	lib.eventFrame:SetScript("OnUpdate", OnUpdate)
-end
-
-function OnEvent(frame, event, arg1, ...)
-	if (event == "UNIT_INVENTORY_CHANGED" and arg1 == "player") or event == "LEARNED_SPELL_IN_TAB" then
-		local tooltipOwner = GameTooltip:GetOwner()
-		if ButtonRegistry[tooltipOwner] then
-			tooltipOwner:SetTooltip()
-		end
-	elseif event == "ACTIONBAR_SLOT_CHANGED" then
-		for button in next, ButtonRegistry do
-			if button._state_type == "action" and (arg1 == 0 or arg1 == tonumber(button._state_action)) then
-				ClearNewActionHighlight(button._state_action, true, false)
-				Update(button)
-			end
-		end
-	elseif event == "PLAYER_ENTERING_WORLD" or event == "UPDATE_SHAPESHIFT_FORM" or event == "UPDATE_VEHICLE_ACTIONBAR" then
-		ForAllButtons(Update)
-	elseif event == "ACTIONBAR_PAGE_CHANGED" or event == "UPDATE_BONUS_ACTIONBAR" then
-		-- TODO: Are these even needed?
-	elseif event == "ACTIONBAR_SHOWGRID" then
-		ShowGrid()
-	elseif event == "ACTIONBAR_HIDEGRID" then
-		HideGrid()
-	elseif event == "UPDATE_BINDINGS" then
-		ForAllButtons(UpdateHotkeys)
-	elseif event == "PLAYER_TARGET_CHANGED" then
-		UpdateRangeTimer()
-	elseif (event == "ACTIONBAR_UPDATE_STATE") or
-		((event == "UNIT_ENTERED_VEHICLE" or event == "UNIT_EXITED_VEHICLE") and (arg1 == "player")) or
-		((event == "COMPANION_UPDATE") and (arg1 == "MOUNT")) then
-		ForAllButtons(UpdateButtonState, true)
-	elseif event == "ACTIONBAR_UPDATE_USABLE" then
-		for button in next, ActionButtons do
-			UpdateUsable(button)
-		end
-	elseif event == "SPELL_UPDATE_USABLE" then
-		for button in next, NonActionButtons do
-			UpdateUsable(button)
-		end
-	elseif event == "ACTIONBAR_UPDATE_COOLDOWN" then
-		for button in next, ActionButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "SPELL_UPDATE_COOLDOWN" then
-		for button in next, NonActionButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "LOSS_OF_CONTROL_ADDED" then
-		for button in next, ActiveButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "LOSS_OF_CONTROL_UPDATE" then
-		for button in next, ActiveButtons do
-			UpdateCooldown(button)
-		end
-	elseif event == "TRADE_SKILL_SHOW" or event == "TRADE_SKILL_CLOSE"  or event == "ARCHAEOLOGY_CLOSED" then
-		ForAllButtons(UpdateButtonState, true)
-	elseif event == "PLAYER_ENTER_COMBAT" then
-		for button in next, ActiveButtons do
-			if button:IsAttack() then
-				StartFlash(button)
-			end
-		end
-	elseif event == "PLAYER_LEAVE_COMBAT" then
-		for button in next, ActiveButtons do
-			if button:IsAttack() then
-				StopFlash(button)
-			end
-		end
-	elseif event == "START_AUTOREPEAT_SPELL" then
-		for button in next, ActiveButtons do
-			if button:IsAutoRepeat() then
-				StartFlash(button)
-			end
-		end
-	elseif event == "STOP_AUTOREPEAT_SPELL" then
-		for button in next, ActiveButtons do
-			if button.flashing == 1 and not button:IsAttack() then
-				StopFlash(button)
-			end
-		end
-	elseif event == "PET_STABLE_UPDATE" or event == "PET_STABLE_SHOW" then
-		ForAllButtons(Update)
-	elseif event == "SPELL_ACTIVATION_OVERLAY_GLOW_SHOW" then
-		for button in next, ActiveButtons do
-			local spellId = button:GetSpellId()
-			if spellId and spellId == arg1 then
-				ShowOverlayGlow(button)
-			else
-				if button._state_type == "action" then
-					local actionType, id = GetActionInfo(button._state_action)
-					if actionType == "flyout" and FlyoutHasSpell(id, arg1) then
-						ShowOverlayGlow(button)
-					end
-				end
-			end
-		end
-	elseif event == "SPELL_ACTIVATION_OVERLAY_GLOW_HIDE" then
-		for button in next, ActiveButtons do
-			local spellId = button:GetSpellId()
-			if spellId and spellId == arg1 then
-				HideOverlayGlow(button)
-			else
-				if button._state_type == "action" then
-					local actionType, id = GetActionInfo(button._state_action)
-					if actionType == "flyout" and FlyoutHasSpell(id, arg1) then
-						HideOverlayGlow(button)
-					end
-				end
-			end
-		end
-	elseif event == "PLAYER_EQUIPMENT_CHANGED" then
-		for button in next, ActiveButtons do
-			if button._state_type == "item" then
-				Update(button)
-			end
-		end
-	elseif event == "SPELL_UPDATE_CHARGES" then
-		ForAllButtons(UpdateCount, true)
-	elseif event == "UPDATE_SUMMONPETS_ACTION" then
-		for button in next, ActiveButtons do
-			if button._state_type == "action" then
-				local actionType, id = GetActionInfo(button._state_action)
-				if actionType == "summonpet" then
-					local texture = GetActionTexture(button._state_action)
-					if texture then
-						button.icon:SetTexture(texture)
-					end
-				end
-			end
-		end
-	end
-end
-
-local flashTime = 0
-local rangeTimer = -1
-function OnUpdate(_, elapsed)
-	flashTime = flashTime - elapsed
-	rangeTimer = rangeTimer - elapsed
-	-- Run the loop only when there is something to update
-	if rangeTimer <= 0 or flashTime <= 0 then
-		for button in next, ActiveButtons do
-			-- Flashing
-			if button.flashing == 1 and flashTime <= 0 then
-				if button.Flash:IsShown() then
-					button.Flash:Hide()
-				else
-					button.Flash:Show()
-				end
-			end
-
-			-- Range
-			if rangeTimer <= 0 then
-				local inRange = button:IsInRange()
-				local oldRange = button.outOfRange
-				button.outOfRange = (inRange == false)
-				if oldRange ~= button.outOfRange then
-					if button.config.outOfRangeColoring == "button" then
-						UpdateUsable(button)
-					elseif button.config.outOfRangeColoring == "hotkey" then
-						local hotkey = button.HotKey
-						if hotkey:GetText() == RANGE_INDICATOR then
-							if inRange == false then
-								hotkey:Show()
-							else
-								hotkey:Hide()
-							end
-						end
-						if inRange == false then
-							hotkey:SetVertexColor(unpack(button.config.colors.range))
-						else
-							hotkey:SetVertexColor(0.75, 0.75, 0.75)
-						end
-					end
-				end
-			end
-		end
-
-		-- Update values
-		if flashTime <= 0 then
-			flashTime = flashTime + ATTACK_BUTTON_FLASH_TIME
-		end
-		if rangeTimer <= 0 then
-			rangeTimer = TOOLTIP_UPDATE_TIME
-		end
-	end
-end
-
-local gridCounter = 0
-function ShowGrid()
-	gridCounter = gridCounter + 1
-	if gridCounter >= 1 then
-		for button in next, ButtonRegistry do
-			if button:IsShown() then
-				button:SetAlpha(1.0)
-			end
-		end
-	end
-end
-
-function HideGrid()
-	if gridCounter > 0 then
-		gridCounter = gridCounter - 1
-	end
-	if gridCounter == 0 then
-		for button in next, ButtonRegistry do
-			if button:IsShown() and not button:HasAction() and not button.config.showGrid then
-				button:SetAlpha(0.0)
-			end
-		end
-	end
-end
-
-function UpdateGrid(self)
-	if self.config.showGrid then
-		self:SetAlpha(1.0)
-	elseif gridCounter == 0 and self:IsShown() and not self:HasAction() then
-		self:SetAlpha(0.0)
-	end
-end
-
------------------------------------------------------------
---- KeyBound integration
-
-function Generic:GetBindingAction()
-	return self.config.keyBoundTarget or "CLICK "..self:GetName()..":LeftButton"
-end
-
-function Generic:GetHotkey()
-	local name = "CLICK "..self:GetName()..":LeftButton"
-	local key = GetBindingKey(self.config.keyBoundTarget or name)
-	if not key and self.config.keyBoundTarget then
-		key = GetBindingKey(name)
-	end
-	if key then
-		return KeyBound and KeyBound:ToShortKey(key) or key
-	end
-end
-
-local function getKeys(binding, keys)
-	keys = keys or ""
-	for i = 1, select("#", GetBindingKey(binding)) do
-		local hotKey = select(i, GetBindingKey(binding))
-		if keys ~= "" then
-			keys = keys .. ", "
-		end
-		keys = keys .. GetBindingText(hotKey, "KEY_")
-	end
-	return keys
-end
-
-function Generic:GetBindings()
-	local keys, binding
-
-	if self.config.keyBoundTarget then
-		keys = getKeys(self.config.keyBoundTarget)
-	end
-
-	keys = getKeys("CLICK "..self:GetName()..":LeftButton")
-
-	return keys
-end
-
-function Generic:SetKey(key)
-	if self.config.keyBoundTarget then
-		SetBinding(key, self.config.keyBoundTarget)
-	else
-		SetBindingClick(key, self:GetName(), "LeftButton")
-	end
-	lib.callbacks:Fire("OnKeybindingChanged", self, key)
-end
-
-local function clearBindings(binding)
-	while GetBindingKey(binding) do
-		SetBinding(GetBindingKey(binding), nil)
-	end
-end
-
-function Generic:ClearBindings()
-	if self.config.keyBoundTarget then
-		clearBindings(self.config.keyBoundTarget)
-	end
-	clearBindings("CLICK "..self:GetName()..":LeftButton")
-	lib.callbacks:Fire("OnKeybindingChanged", self, nil)
-end
-
------------------------------------------------------------
---- button management
-
-function Generic:UpdateAction(force)
-	local type, action = self:GetAction()
-	if force or type ~= self._state_type or action ~= self._state_action then
-		-- type changed, update the metatable
-		if force or self._state_type ~= type then
-			local meta = type_meta_map[type] or type_meta_map.empty
-			setmetatable(self, meta)
-			self._state_type = type
-		end
-		self._state_action = action
-		Update(self)
-	end
-end
-
-function Update(self)
-	if self:HasAction() then
-		ActiveButtons[self] = true
-		if self._state_type == "action" then
-			ActionButtons[self] = true
-			NonActionButtons[self] = nil
-		else
-			ActionButtons[self] = nil
-			NonActionButtons[self] = true
-		end
-		self:SetAlpha(1.0)
-		UpdateButtonState(self)
-		UpdateUsable(self)
-		UpdateCooldown(self)
-		UpdateFlash(self)
-	else
-		ActiveButtons[self] = nil
-		ActionButtons[self] = nil
-		NonActionButtons[self] = nil
-		if gridCounter == 0 and not self.config.showGrid then
-			self:SetAlpha(0.0)
-		end
-		self.cooldown:Hide()
-		self:SetChecked(false)
-
-		if self.chargeCooldown then
-			EndChargeCooldown(self.chargeCooldown)
-		end
-	end
-
-	-- Add a green border if button is an equipped item
-	if self:IsEquipped() and not self.config.hideElements.equipped then
-		self.Border:SetVertexColor(0, 1.0, 0, 0.35)
-		self.Border:Show()
-	else
-		self.Border:Hide()
-	end
-
-	-- Update Action Text
-	if not self:IsConsumableOrStackable() then
-		self.Name:SetText(self:GetActionText())
-	else
-		self.Name:SetText("")
-	end
-
-	-- Update icon and hotkey
-	local texture = self:GetTexture()
-
-	-- Zone ability button handling
-	self.zoneAbilityDisabled = false
-	self.icon:SetDesaturated(false)
-	if self._state_type == "action" then
-		local action_type, id = GetActionInfo(self._state_action)
-		if ((action_type == "spell" or action_type == "companion") and ZoneAbilityFrame and ZoneAbilityFrame.baseName and not HasZoneAbility()) then
-			local name = GetSpellInfo(ZoneAbilityFrame.baseName)
-			local abilityName = GetSpellInfo(id)
-			if name == abilityName then
-				texture = GetLastZoneAbilitySpellTexture()
-				self.zoneAbilityDisabled = true
-				self.icon:SetDesaturated(true)
-			end
-		end
-	end
-
-	if texture then
-		self.icon:SetTexture(texture)
-		self.icon:Show()
-		self.rangeTimer = - 1
-		self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
-		if not self.LBFSkinned and not self.MasqueSkinned then
-			self.NormalTexture:SetTexCoord(0, 0, 0, 0)
-		end
-	else
-		self.icon:Hide()
-		self.cooldown:Hide()
-		self.rangeTimer = nil
-		self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
-		if self.HotKey:GetText() == RANGE_INDICATOR then
-			self.HotKey:Hide()
-		else
-			self.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-		end
-		if not self.LBFSkinned and not self.MasqueSkinned then
-			self.NormalTexture:SetTexCoord(-0.15, 1.15, -0.15, 1.17)
-		end
-	end
-
-	self:UpdateLocal()
-
-	UpdateCount(self)
-
-	UpdateFlyout(self)
-
-	UpdateOverlayGlow(self)
-
-	UpdateNewAction(self)
-
-	if GameTooltip:GetOwner() == self then
-		UpdateTooltip(self)
-	end
-
-	-- this could've been a spec change, need to call OnStateChanged for action buttons, if present
-	if not InCombatLockdown() and self._state_type == "action" then
-		local onStateChanged = self:GetAttribute("OnStateChanged")
-		if onStateChanged then
-			self.header:SetFrameRef("updateButton", self)
-			self.header:Execute(([[
-				local frame = self:GetFrameRef("updateButton")
-				control:RunFor(frame, frame:GetAttribute("OnStateChanged"), %s, %s, %s)
-			]]):format(formatHelper(self:GetAttribute("state")), formatHelper(self._state_type), formatHelper(self._state_action)))
-		end
-	end
-	lib.callbacks:Fire("OnButtonUpdate", self)
-end
-
-function Generic:UpdateLocal()
--- dummy function the other button types can override for special updating
-end
-
-function UpdateButtonState(self)
-	if self:IsCurrentlyActive() or self:IsAutoRepeat() then
-		self:SetChecked(true)
-	else
-		self:SetChecked(false)
-	end
-	lib.callbacks:Fire("OnButtonState", self)
-end
-
-function UpdateUsable(self)
-	-- TODO: make the colors configurable
-	-- TODO: allow disabling of the whole recoloring
-	if self.config.outOfRangeColoring == "button" and self.outOfRange then
-		self.icon:SetVertexColor(unpack(self.config.colors.range))
-	else
-		local isUsable, notEnoughMana = self:IsUsable()
-		if isUsable then
-			self.icon:SetVertexColor(1.0, 1.0, 1.0)
-			--self.NormalTexture:SetVertexColor(1.0, 1.0, 1.0)
-		elseif notEnoughMana then
-			self.icon:SetVertexColor(unpack(self.config.colors.mana))
-			--self.NormalTexture:SetVertexColor(0.5, 0.5, 1.0)
-		else
-			self.icon:SetVertexColor(0.4, 0.4, 0.4)
-			--self.NormalTexture:SetVertexColor(1.0, 1.0, 1.0)
-		end
-	end
-	lib.callbacks:Fire("OnButtonUsable", self)
-end
-
-function UpdateCount(self)
-	if not self:HasAction() then
-		self.Count:SetText("")
-		return
-	end
-	if self:IsConsumableOrStackable() then
-		local count = self:GetCount()
-		if count > (self.maxDisplayCount or 9999) then
-			self.Count:SetText("*")
-		else
-			self.Count:SetText(count)
-		end
-	else
-		local charges, maxCharges, chargeStart, chargeDuration = self:GetCharges()
-		if charges and maxCharges and maxCharges > 1 then
-			self.Count:SetText(charges)
-		else
-			self.Count:SetText("")
-		end
-	end
-end
-
-function EndChargeCooldown(self)
-	self:Hide()
-	self:SetParent(UIParent)
-	self.parent.chargeCooldown = nil
-	self.parent = nil
-	tinsert(lib.ChargeCooldowns, self)
-end
-
-local function StartChargeCooldown(parent, chargeStart, chargeDuration, chargeModRate)
-	if not parent.chargeCooldown then
-		local cooldown = tremove(lib.ChargeCooldowns)
-		if not cooldown then
-			lib.NumChargeCooldowns = lib.NumChargeCooldowns + 1
-			cooldown = CreateFrame("Cooldown", "LAB10ChargeCooldown"..lib.NumChargeCooldowns, parent, "CooldownFrameTemplate");
-			cooldown:SetScript("OnCooldownDone", EndChargeCooldown)
-			cooldown:SetHideCountdownNumbers(true)
-			cooldown:SetDrawSwipe(false)
-		end
-		cooldown:SetParent(parent)
-		cooldown:SetAllPoints(parent)
-		cooldown:SetFrameStrata("TOOLTIP")
-		cooldown:Show()
-		parent.chargeCooldown = cooldown
-		cooldown.parent = parent
-	end
-	-- set cooldown
-	parent.chargeCooldown:SetDrawBling(parent.chargeCooldown:GetEffectiveAlpha() > 0.5)
-	CooldownFrame_Set(parent.chargeCooldown, chargeStart, chargeDuration, true, true, chargeModRate)
-
-	-- update charge cooldown skin when masque is used
-	if Masque and Masque.UpdateCharge then
-		Masque:UpdateCharge(parent)
-	end
-
-	if not chargeStart or chargeStart == 0 then
-		EndChargeCooldown(parent.chargeCooldown)
-	end
-end
-
-local function OnCooldownDone(self)
-	self:SetScript("OnCooldownDone", nil)
-	UpdateCooldown(self:GetParent())
-end
-
-function UpdateCooldown(self)
-	local locStart, locDuration = self:GetLossOfControlCooldown()
-	local start, duration, enable, modRate = self:GetCooldown()
-	local charges, maxCharges, chargeStart, chargeDuration, chargeModRate = self:GetCharges()
-
-	self.cooldown:SetDrawBling(self.cooldown:GetEffectiveAlpha() > 0.5)
-
-	if (locStart + locDuration) > (start + duration) then
-		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_LOSS_OF_CONTROL then
-			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge-LoC")
-			self.cooldown:SetSwipeColor(0.17, 0, 0)
-			self.cooldown:SetHideCountdownNumbers(true)
-			self.cooldown.currentCooldownType = COOLDOWN_TYPE_LOSS_OF_CONTROL
-		end
-		CooldownFrame_Set(self.cooldown, locStart, locDuration, true, true, modRate)
-	else
-		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_NORMAL then
-			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge")
-			self.cooldown:SetSwipeColor(0, 0, 0)
-			self.cooldown:SetHideCountdownNumbers(false)
-			self.cooldown.currentCooldownType = COOLDOWN_TYPE_NORMAL
-		end
-		if locStart > 0 then
-			self.cooldown:SetScript("OnCooldownDone", OnCooldownDone)
-		end
-
-		if charges and maxCharges and charges > 0 and charges < maxCharges then
-			StartChargeCooldown(self, chargeStart, chargeDuration, chargeModRate)
-		elseif self.chargeCooldown then
-			EndChargeCooldown(self.chargeCooldown)
-		end
-		CooldownFrame_Set(self.cooldown, start, duration, enable, false, modRate)
-	end
-end
-
-function StartFlash(self)
-	self.flashing = 1
-	flashTime = 0
-	UpdateButtonState(self)
-end
-
-function StopFlash(self)
-	self.flashing = 0
-	self.Flash:Hide()
-	UpdateButtonState(self)
-end
-
-function UpdateFlash(self)
-	if (self:IsAttack() and self:IsCurrentlyActive()) or self:IsAutoRepeat() then
-		StartFlash(self)
-	else
-		StopFlash(self)
-	end
-end
-
-function UpdateTooltip(self)
-	if (GetCVar("UberTooltips") == "1") then
-		GameTooltip_SetDefaultAnchor(GameTooltip, self);
-	else
-		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
-	end
-	if self:SetTooltip() then
-		self.UpdateTooltip = UpdateTooltip
-	else
-		self.UpdateTooltip = nil
-	end
-end
-
-function UpdateHotkeys(self)
-	local key = self:GetHotkey()
-	if not key or key == "" or self.config.hideElements.hotkey then
-		self.HotKey:SetText(RANGE_INDICATOR)
-		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", 1, - 2)
-		self.HotKey:Hide()
-	else
-		self.HotKey:SetText(key)
-		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", - 2, - 2)
-		self.HotKey:Show()
-	end
-end
-
-function ShowOverlayGlow(self)
-	if LBG then
-		LBG.ShowOverlayGlow(self)
-	end
-end
-
-function HideOverlayGlow(self)
-	if LBG then
-		LBG.HideOverlayGlow(self)
-	end
-end
-
-function UpdateOverlayGlow(self)
-	local spellId = self:GetSpellId()
-	if spellId and IsSpellOverlayed(spellId) then
-		ShowOverlayGlow(self)
-	else
-		HideOverlayGlow(self)
-	end
-end
-
-function ClearNewActionHighlight(action, preventIdenticalActionsFromClearing, value)
-	lib.ACTION_HIGHLIGHT_MARKS[action] = value
-
-	for button in next, ButtonRegistry do
-		if button._state_type == "action" and action == tonumber(button._state_action) then
-			UpdateNewAction(button)
-		end
-	end
-
-	if preventIdenticalActionsFromClearing then
-		return
-	end
-
-	-- iterate through actions and unmark all that are the same type
-	local unmarkedType, unmarkedID = GetActionInfo(action)
-	for actionKey, markValue in pairs(lib.ACTION_HIGHLIGHT_MARKS) do
-		if markValue then
-			local actionType, actionID = GetActionInfo(actionKey)
-			if actionType == unmarkedType and actionID == unmarkedID then
-				ClearNewActionHighlight(actionKey, true, value)
-			end
-		end
-	end
-end
-
-hooksecurefunc("MarkNewActionHighlight", function(action)
-	lib.ACTION_HIGHLIGHT_MARKS[action] = true
-	for button in next, ButtonRegistry do
-		if button._state_type == "action" and action == tonumber(button._state_action) then
-			UpdateNewAction(button)
-		end
-	end
-end)
-
-hooksecurefunc("ClearNewActionHighlight", function(action, preventIdenticalActionsFromClearing)
-	ClearNewActionHighlight(action, preventIdenticalActionsFromClearing, nil)
-end)
-
-function UpdateNewAction(self)
-	-- special handling for "New Action" markers
-	if self.NewActionTexture then
-		if self._state_type == "action" and lib.ACTION_HIGHLIGHT_MARKS[self._state_action] then
-			self.NewActionTexture:Show()
-		else
-			self.NewActionTexture:Hide()
-		end
-	end
-end
-
--- Hook UpdateFlyout so we can use the blizzy templates
-hooksecurefunc("ActionButton_UpdateFlyout", function(self, ...)
-	if ButtonRegistry[self] then
-		UpdateFlyout(self)
-	end
-end)
-
-function UpdateFlyout(self)
-	-- disabled FlyoutBorder/BorderShadow, those are not handled by LBF and look terrible
-	self.FlyoutBorder:Hide()
-	self.FlyoutBorderShadow:Hide()
-	if self._state_type == "action" then
-		-- based on ActionButton_UpdateFlyout in ActionButton.lua
-		local actionType = GetActionInfo(self._state_action)
-		if actionType == "flyout" then
-			-- Update border and determine arrow position
-			local arrowDistance
-			if (SpellFlyout and SpellFlyout:IsShown() and SpellFlyout:GetParent() == self) or GetMouseFocus() == self then
-				arrowDistance = 5
-			else
-				arrowDistance = 2
-			end
-
-			-- Update arrow
-			self.FlyoutArrow:Show()
-			self.FlyoutArrow:ClearAllPoints()
-			local direction = self:GetAttribute("flyoutDirection");
-			if direction == "LEFT" then
-				self.FlyoutArrow:SetPoint("LEFT", self, "LEFT", -arrowDistance, 0)
-				SetClampedTextureRotation(self.FlyoutArrow, 270)
-			elseif direction == "RIGHT" then
-				self.FlyoutArrow:SetPoint("RIGHT", self, "RIGHT", arrowDistance, 0)
-				SetClampedTextureRotation(self.FlyoutArrow, 90)
-			elseif direction == "DOWN" then
-				self.FlyoutArrow:SetPoint("BOTTOM", self, "BOTTOM", 0, -arrowDistance)
-				SetClampedTextureRotation(self.FlyoutArrow, 180)
-			else
-				self.FlyoutArrow:SetPoint("TOP", self, "TOP", 0, arrowDistance)
-				SetClampedTextureRotation(self.FlyoutArrow, 0)
-			end
-
-			-- return here, otherwise flyout is hidden
-			return
-		end
-	end
-	self.FlyoutArrow:Hide()
-end
-
-function UpdateRangeTimer()
-	rangeTimer = -1
-end
-
------------------------------------------------------------
---- WoW API mapping
---- Generic Button
-Generic.HasAction               = function(self) return nil end
-Generic.GetActionText           = function(self) return "" end
-Generic.GetTexture              = function(self) return nil end
-Generic.GetCharges              = function(self) return nil end
-Generic.GetCount                = function(self) return 0 end
-Generic.GetCooldown             = function(self) return 0, 0, 0 end
-Generic.IsAttack                = function(self) return nil end
-Generic.IsEquipped              = function(self) return nil end
-Generic.IsCurrentlyActive       = function(self) return nil end
-Generic.IsAutoRepeat            = function(self) return nil end
-Generic.IsUsable                = function(self) return nil end
-Generic.IsConsumableOrStackable = function(self) return nil end
-Generic.IsUnitInRange           = function(self, unit) return nil end
-Generic.IsInRange               = function(self)
-	local unit = self:GetAttribute("unit")
-	if unit == "player" then
-		unit = nil
-	end
-	local val = self:IsUnitInRange(unit)
-	-- map 1/0 to true false, since the return values are inconsistent between actions and spells
-	if val == 1 then val = true elseif val == 0 then val = false end
-	return val
-end
-Generic.SetTooltip              = function(self) return nil end
-Generic.GetSpellId              = function(self) return nil end
-Generic.GetLossOfControlCooldown = function(self) return 0, 0 end
-
------------------------------------------------------------
---- Action Button
-Action.HasAction               = function(self) return HasAction(self._state_action) end
-Action.GetActionText           = function(self) return GetActionText(self._state_action) end
-Action.GetTexture              = function(self) return GetActionTexture(self._state_action) end
-Action.GetCharges              = function(self) return GetActionCharges(self._state_action) end
-Action.GetCount                = function(self) return GetActionCount(self._state_action) end
-Action.GetCooldown             = function(self) return GetActionCooldown(self._state_action) end
-Action.IsAttack                = function(self) return IsAttackAction(self._state_action) end
-Action.IsEquipped              = function(self) return IsEquippedAction(self._state_action) end
-Action.IsCurrentlyActive       = function(self) return IsCurrentAction(self._state_action) end
-Action.IsAutoRepeat            = function(self) return IsAutoRepeatAction(self._state_action) end
-Action.IsUsable                = function(self) return IsUsableAction(self._state_action) end
-Action.IsConsumableOrStackable = function(self) return IsConsumableAction(self._state_action) or IsStackableAction(self._state_action) or (not IsItemAction(self._state_action) and GetActionCount(self._state_action) > 0) end
-Action.IsUnitInRange           = function(self, unit) return IsActionInRange(self._state_action, unit) end
-Action.SetTooltip              = function(self) return GameTooltip:SetAction(self._state_action) end
-Action.GetSpellId              = function(self)
-	local actionType, id, subType = GetActionInfo(self._state_action)
-	if actionType == "spell" then
-		return id
-	elseif actionType == "macro" then
-		local _, _, spellId = GetMacroSpell(id)
-		return spellId
-	end
-end
-Action.GetLossOfControlCooldown = function(self) return GetActionLossOfControlCooldown(self._state_action) end
-
------------------------------------------------------------
---- Spell Button
-Spell.HasAction               = function(self) return true end
-Spell.GetActionText           = function(self) return "" end
-Spell.GetTexture              = function(self) return GetSpellTexture(self._state_action) end
-Spell.GetCharges              = function(self) return GetSpellCharges(self._state_action) end
-Spell.GetCount                = function(self) return GetSpellCount(self._state_action) end
-Spell.GetCooldown             = function(self) return GetSpellCooldown(self._state_action) end
-Spell.IsAttack                = function(self) return IsAttackSpell(FindSpellBookSlotBySpellID(self._state_action), "spell") end -- needs spell book id as of 4.0.1.13066
-Spell.IsEquipped              = function(self) return nil end
-Spell.IsCurrentlyActive       = function(self) return IsCurrentSpell(self._state_action) end
-Spell.IsAutoRepeat            = function(self) return IsAutoRepeatSpell(FindSpellBookSlotBySpellID(self._state_action), "spell") end -- needs spell book id as of 4.0.1.13066
-Spell.IsUsable                = function(self) return IsUsableSpell(self._state_action) end
-Spell.IsConsumableOrStackable = function(self) return IsConsumableSpell(self._state_action) end
-Spell.IsUnitInRange           = function(self, unit) return IsSpellInRange(FindSpellBookSlotBySpellID(self._state_action), "spell", unit) end -- needs spell book id as of 4.0.1.13066
-Spell.SetTooltip              = function(self) return GameTooltip:SetSpellByID(self._state_action) end
-Spell.GetSpellId              = function(self) return self._state_action end
-
------------------------------------------------------------
---- Item Button
-local function getItemId(input)
-	return input:match("^item:(%d+)")
-end
-
-Item.HasAction               = function(self) return true end
-Item.GetActionText           = function(self) return "" end
-Item.GetTexture              = function(self) return GetItemIcon(self._state_action) end
-Item.GetCharges              = function(self) return nil end
-Item.GetCount                = function(self) return GetItemCount(self._state_action, nil, true) end
-Item.GetCooldown             = function(self) return GetItemCooldown(getItemId(self._state_action)) end
-Item.IsAttack                = function(self) return nil end
-Item.IsEquipped              = function(self) return IsEquippedItem(self._state_action) end
-Item.IsCurrentlyActive       = function(self) return IsCurrentItem(self._state_action) end
-Item.IsAutoRepeat            = function(self) return nil end
-Item.IsUsable                = function(self) return IsUsableItem(self._state_action) end
-Item.IsConsumableOrStackable = function(self) return IsConsumableItem(self._state_action) end
-Item.IsUnitInRange           = function(self, unit) return IsItemInRange(self._state_action, unit) end
-Item.SetTooltip              = function(self) return GameTooltip:SetHyperlink(self._state_action) end
-Item.GetSpellId              = function(self) return nil end
-
------------------------------------------------------------
---- Macro Button
--- TODO: map results of GetMacroSpell/GetMacroItem to proper results
-Macro.HasAction               = function(self) return true end
-Macro.GetActionText           = function(self) return (GetMacroInfo(self._state_action)) end
-Macro.GetTexture              = function(self) return (select(2, GetMacroInfo(self._state_action))) end
-Macro.GetCharges              = function(self) return nil end
-Macro.GetCount                = function(self) return 0 end
-Macro.GetCooldown             = function(self) return 0, 0, 0 end
-Macro.IsAttack                = function(self) return nil end
-Macro.IsEquipped              = function(self) return nil end
-Macro.IsCurrentlyActive       = function(self) return nil end
-Macro.IsAutoRepeat            = function(self) return nil end
-Macro.IsUsable                = function(self) return nil end
-Macro.IsConsumableOrStackable = function(self) return nil end
-Macro.IsUnitInRange           = function(self, unit) return nil end
-Macro.SetTooltip              = function(self) return nil end
-Macro.GetSpellId              = function(self) return nil end
-
------------------------------------------------------------
---- Custom Button
-Custom.HasAction               = function(self) return true end
-Custom.GetActionText           = function(self) return "" end
-Custom.GetTexture              = function(self) return self._state_action.texture end
-Custom.GetCharges              = function(self) return nil end
-Custom.GetCount                = function(self) return 0 end
-Custom.GetCooldown             = function(self) return 0, 0, 0 end
-Custom.IsAttack                = function(self) return nil end
-Custom.IsEquipped              = function(self) return nil end
-Custom.IsCurrentlyActive       = function(self) return nil end
-Custom.IsAutoRepeat            = function(self) return nil end
-Custom.IsUsable                = function(self) return true end
-Custom.IsConsumableOrStackable = function(self) return nil end
-Custom.IsUnitInRange           = function(self, unit) return nil end
-Custom.SetTooltip              = function(self) return GameTooltip:SetText(self._state_action.tooltip) end
-Custom.GetSpellId              = function(self) return nil end
-Custom.RunCustom               = function(self, unit, button) return self._state_action.func(self, unit, button) end
-
------------------------------------------------------------
---- Update old Buttons
-if oldversion and next(lib.buttonRegistry) then
-	InitializeEventHandler()
-	for button in next, lib.buttonRegistry do
-		-- this refreshes the metatable on the button
-		Generic.UpdateAction(button, true)
-		SetupSecureSnippets(button)
-		if oldversion < 12 then
-			WrapOnClick(button)
-		end
-		if oldversion < 23 then
-			if button.overlay then
-				button.overlay:Hide()
-				ActionButton_HideOverlayGlow(button)
-				button.overlay = nil
-				UpdateOverlayGlow(button)
-			end
-		end
-	end
-end
diff --git a/Jamba/LibActionButtonJamba-1.0.lua b/Jamba/LibActionButtonJamba-1.0.lua
index 8f28d61..2ccb01d 100644
--- a/Jamba/LibActionButtonJamba-1.0.lua
+++ b/Jamba/LibActionButtonJamba-1.0.lua
@@ -1,5 +1,5 @@
 --[[
-Copyright (c) 2010-2017, Hendrik "nevcairiel" Leppkes <h.leppkes@gmail.com>
+Copyright (c) 2010-2018, Hendrik "nevcairiel" Leppkes <h.leppkes@gmail.com>

 All rights reserved.

@@ -29,7 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 ]]
 local MAJOR_VERSION = "LibActionButtonJamba-1.0"
-local MINOR_VERSION = 68
+local MINOR_VERSION = 71

 if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
 local lib, oldversion = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
@@ -118,6 +118,13 @@ local EndChargeCooldown

 local InitializeEventHandler, OnEvent, ForAllButtons, OnUpdate

+local function GameTooltip_GetOwnerForbidden()
+	if GameTooltip:IsForbidden() then
+		return nil
+	end
+	return GameTooltip:GetOwner()
+end
+
 local DefaultConfig = {
 	outOfRangeColoring = "button",
 	tooltip = "enabled",
@@ -536,6 +543,7 @@ function Generic:OnEnter()
 end

 function Generic:OnLeave()
+	if GameTooltip:IsForbidden() then return end
 	GameTooltip:Hide()
 end

@@ -663,6 +671,7 @@ function InitializeEventHandler()
 	lib.eventFrame:RegisterEvent("UPDATE_BINDINGS")
 	lib.eventFrame:RegisterEvent("UPDATE_SHAPESHIFT_FORM")
 	lib.eventFrame:RegisterEvent("UPDATE_VEHICLE_ACTIONBAR")
+	lib.eventFrame:RegisterEvent("PLAYER_MOUNT_DISPLAY_CHANGED")

 	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_STATE")
 	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
@@ -686,6 +695,7 @@ function InitializeEventHandler()
 	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_HIDE")
 	lib.eventFrame:RegisterEvent("SPELL_UPDATE_CHARGES")
 	lib.eventFrame:RegisterEvent("UPDATE_SUMMONPETS_ACTION")
+	lib.eventFrame:RegisterEvent("SPELL_UPDATE_ICON")

 	-- With those two, do we still need the ACTIONBAR equivalents of them?
 	lib.eventFrame:RegisterEvent("SPELL_UPDATE_COOLDOWN")
@@ -701,8 +711,8 @@ end

 function OnEvent(frame, event, arg1, ...)
 	if (event == "UNIT_INVENTORY_CHANGED" and arg1 == "player") or event == "LEARNED_SPELL_IN_TAB" then
-		local tooltipOwner = GameTooltip:GetOwner()
-		if ButtonRegistry[tooltipOwner] then
+		local tooltipOwner = GameTooltip_GetOwnerForbidden()
+		if tooltipOwner and ButtonRegistry[tooltipOwner] then
 			tooltipOwner:SetTooltip()
 		end
 	elseif event == "ACTIONBAR_SLOT_CHANGED" then
@@ -736,6 +746,10 @@ function OnEvent(frame, event, arg1, ...)
 		for button in next, NonActionButtons do
 			UpdateUsable(button)
 		end
+	elseif event == "PLAYER_MOUNT_DISPLAY_CHANGED" then
+		for button in next, ActiveButtons do
+			UpdateUsable(button)
+		end
 	elseif event == "ACTIONBAR_UPDATE_COOLDOWN" then
 		for button in next, ActionButtons do
 			UpdateCooldown(button)
@@ -746,14 +760,14 @@ function OnEvent(frame, event, arg1, ...)
 	elseif event == "SPELL_UPDATE_COOLDOWN" then
 		for button in next, NonActionButtons do
 			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
+			if GameTooltip_GetOwnerForbidden() == button then
 				UpdateTooltip(button)
 			end
 		end
 	elseif event == "LOSS_OF_CONTROL_ADDED" then
 		for button in next, ActiveButtons do
 			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
+			if GameTooltip_GetOwnerForbidden() == button then
 				UpdateTooltip(button)
 			end
 		end
@@ -837,6 +851,8 @@ function OnEvent(frame, event, arg1, ...)
 				end
 			end
 		end
+	elseif event == "SPELL_UPDATE_ICON" then
+		ForAllButtons(Update, true)
 	end
 end

@@ -1106,7 +1122,7 @@ function Update(self)

 	UpdateNewAction(self)

-	if GameTooltip:GetOwner() == self then
+	if GameTooltip_GetOwnerForbidden() == self then
 		UpdateTooltip(self)
 	end

@@ -1280,6 +1296,7 @@ function UpdateFlash(self)
 end

 function UpdateTooltip(self)
+	if GameTooltip:IsForbidden() then return end
 	if (GetCVar("UberTooltips") == "1") then
 		GameTooltip_SetDefaultAnchor(GameTooltip, self);
 	else
diff --git a/Jamba/LibActionButtonJamba-1.00.lua b/Jamba/LibActionButtonJamba-1.00.lua
deleted file mode 100644
index 74c144b..0000000
--- a/Jamba/LibActionButtonJamba-1.00.lua
+++ /dev/null
@@ -1,1576 +0,0 @@
---[[
-Copyright (c) 2010-2014, Hendrik "nevcairiel" Leppkes <h.leppkes@gmail.com>
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of the developer nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-]]
-local MAJOR_VERSION = "LibActionButtonJamba-1.0"
-local MINOR_VERSION = 57
-
-if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
-local lib, oldversion = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
-if not lib then return end
-
--- Lua functions
-local _G = _G
-local type, error, tostring, tonumber, assert, select = type, error, tostring, tonumber, assert, select
-local setmetatable, wipe, unpack, pairs, next = setmetatable, wipe, unpack, pairs, next
-local str_match, format, tinsert, tremove = string.match, format, tinsert, tremove
-
--- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
--- List them here for Mikk's FindGlobals script
--- Note: No WoW API function get upvalued to allow proper interaction with any addons that try to hook them.
--- GLOBALS: LibStub, CreateFrame, InCombatLockdown, ClearCursor, GetCursorInfo, GameTooltip, GameTooltip_SetDefaultAnchor
--- GLOBALS: GetBindingKey, GetBindingText, SetBinding, SetBindingClick, GetCVar, GetMacroInfo
--- GLOBALS: PickupAction, PickupItem, PickupMacro, PickupPetAction, PickupSpell, PickupCompanion, PickupEquipmentSet
--- GLOBALS: CooldownFrame_SetTimer, UIParent, IsSpellOverlayed, SpellFlyout, GetMouseFocus, SetClampedTextureRotation
--- GLOBALS: GetActionInfo, GetActionTexture, HasAction, GetActionText, GetActionCount, GetActionCooldown, IsAttackAction
--- GLOBALS: IsAutoRepeatAction, IsEquippedAction, IsCurrentAction, IsConsumableAction, IsUsableAction, IsStackableAction, IsActionInRange
--- GLOBALS: GetSpellLink, GetMacroSpell, GetSpellTexture, GetSpellCount, GetSpellCooldown, IsAttackSpell, IsCurrentSpell
--- GLOBALS: FindSpellBookSlotBySpellID, IsUsableSpell, IsConsumableSpell, IsSpellInRange, IsAutoRepeatSpell
--- GLOBALS: GetItemIcon, GetItemCount, GetItemCooldown, IsEquippedItem, IsCurrentItem, IsUsableItem, IsConsumableItem, IsItemInRange
--- GLOBALS: GetActionCharges, IsItemAction, GetSpellCharges
--- GLOBALS: RANGE_INDICATOR, ATTACK_BUTTON_FLASH_TIME, TOOLTIP_UPDATE_TIME
-
-local KeyBound = LibStub("LibKeyBound-1.0", true)
-local CBH = LibStub("CallbackHandler-1.0")
-
-lib.eventFrame = lib.eventFrame or CreateFrame("Frame")
-lib.eventFrame:UnregisterAllEvents()
-
-lib.buttonRegistry = lib.buttonRegistry or {}
-lib.activeButtons = lib.activeButtons or {}
-lib.actionButtons = lib.actionButtons or {}
-lib.nonActionButtons = lib.nonActionButtons or {}
-
-lib.unusedOverlayGlows = lib.unusedOverlayGlows or {}
-lib.numOverlays = lib.numOverlays or 0
-
-lib.ACTION_HIGHLIGHT_MARKS = lib.ACTION_HIGHLIGHT_MARKS or setmetatable({}, { __index = ACTION_HIGHLIGHT_MARKS })
-
-lib.callbacks = lib.callbacks or CBH:New(lib)
-
-local Generic = CreateFrame("CheckButton")
-local Generic_MT = {__index = Generic}
-
-local Action = setmetatable({}, {__index = Generic})
-local Action_MT = {__index = Action}
-
-local PetAction = setmetatable({}, {__index = Generic})
-local PetAction_MT = {__index = PetAction}
-
-local Spell = setmetatable({}, {__index = Generic})
-local Spell_MT = {__index = Spell}
-
-local Item = setmetatable({}, {__index = Generic})
-local Item_MT = {__index = Item}
-
-local Macro = setmetatable({}, {__index = Generic})
-local Macro_MT = {__index = Macro}
-
-local Custom = setmetatable({}, {__index = Generic})
-local Custom_MT = {__index = Custom}
-
-local type_meta_map = {
-	empty  = Generic_MT,
-	action = Action_MT,
-	--pet    = PetAction_MT,
-	spell  = Spell_MT,
-	item   = Item_MT,
-	macro  = Macro_MT,
-	custom = Custom_MT
-}
-
-local ButtonRegistry, ActiveButtons, ActionButtons, NonActionButtons = lib.buttonRegistry, lib.activeButtons, lib.actionButtons, lib.nonActionButtons
-
-local Update, UpdateButtonState, UpdateUsable, UpdateCount, UpdateCooldown, UpdateTooltip, UpdateNewAction
-local StartFlash, StopFlash, UpdateFlash, UpdateHotkeys, UpdateRangeTimer, UpdateOverlayGlow
-local UpdateFlyout, ShowGrid, HideGrid, UpdateGrid, SetupSecureSnippets, WrapOnClick
-local ShowOverlayGlow, HideOverlayGlow, GetOverlayGlow, OverlayGlowAnimOutFinished
-local HookCooldown
-
-local InitializeEventHandler, OnEvent, ForAllButtons, OnUpdate
-
-local DefaultConfig = {
-	outOfRangeColoring = "button",
-	tooltip = "enabled",
-	showGrid = false,
-	colors = {
-		range = { 0.8, 0.1, 0.1 },
-		mana = { 0.5, 0.5, 1.0 }
-	},
-	hideElements = {
-		macro = false,
-		hotkey = false,
-		equipped = false,
-	},
-	keyBoundTarget = false,
-	clickOnDown = false,
-	flyoutDirection = "UP",
-}
-
---- Create a new action button.
--- @param id Internal id of the button (not used by LibActionButton-1.0, only for tracking inside the calling addon)
--- @param name Name of the button frame to be created (not used by LibActionButton-1.0 aside from naming the frame)
--- @param header Header that drives these action buttons (if any)
-function lib:CreateButton(id, name, header, config)
-	if type(name) ~= "string" then
-		error("Usage: CreateButton(id, name. header): Buttons must have a valid name!", 2)
-	end
-	if not header then
-		error("Usage: CreateButton(id, name, header): Buttons without a secure header are not yet supported!", 2)
-	end
-
-	if not KeyBound then
-		KeyBound = LibStub("LibKeyBound-1.0", true)
-	end
-
-	local button = setmetatable(CreateFrame("CheckButton", name, header, "SecureActionButtonTemplate, ActionButtonTemplate"), Generic_MT)
-	button:RegisterForDrag("LeftButton", "RightButton")
-	button:RegisterForClicks("AnyUp")
-
-	-- Frame Scripts
-	button:SetScript("OnEnter", Generic.OnEnter)
-	button:SetScript("OnLeave", Generic.OnLeave)
-	button:SetScript("PreClick", Generic.PreClick)
-	button:SetScript("PostClick", Generic.PostClick)
-
-	button.id = id
-	button.header = header
-	-- Mapping of state -> action
-	button.state_types = {}
-	button.state_actions = {}
-
-	-- Store the LAB Version that created this button for debugging
-	button.__LAB_Version = MINOR_VERSION
-
-	-- just in case we're not run by a header, default to state 0
-	button:SetAttribute("state", 0)
-
-	SetupSecureSnippets(button)
-	WrapOnClick(button)
-
-	-- adjust hotkey style for better readability
-	button.HotKey:SetFont(button.HotKey:GetFont(), 13, "OUTLINE")
-	button.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-
-	-- adjust count/stack size
-	button.Count:SetFont(button.Count:GetFont(), 16, "OUTLINE")
-
-	-- hook Cooldown stuff for alpha fix in 6.0
-	HookCooldown(button)
-
-	-- Store the button in the registry, needed for event and OnUpdate handling
-	if not next(ButtonRegistry) then
-		InitializeEventHandler()
-	end
-	ButtonRegistry[button] = true
-
-	button:UpdateConfig(config)
-
-	-- run an initial update
-	button:UpdateAction()
-	UpdateHotkeys(button)
-
-	-- somewhat of a hack for the Flyout buttons to not error.
-	button.action = 0
-
-	lib.callbacks:Fire("OnButtonCreated", button)
-
-	return button
-end
-
-function SetupSecureSnippets(button)
-	button:SetAttribute("_custom", Custom.RunCustom)
-	-- secure UpdateState(self, state)
-	-- update the type and action of the button based on the state
-	button:SetAttribute("UpdateState", [[
-		local state = ...
-		self:SetAttribute("state", state)
-		local type, action = (self:GetAttribute(format("labtype-%s", state)) or "empty"), self:GetAttribute(format("labaction-%s", state))
-
-		self:SetAttribute("type", type)
-		if type ~= "empty" and type ~= "custom" then
-			local action_field = (type == "pet") and "action" or type
-			self:SetAttribute(action_field, action)
-			self:SetAttribute("action_field", action_field)
-		end
-		local onStateChanged = self:GetAttribute("OnStateChanged")
-		if onStateChanged then
-			self:Run(onStateChanged, state, type, action)
-		end
-	]])
-
-	-- this function is invoked by the header when the state changes
-	button:SetAttribute("_childupdate-state", [[
-		self:RunAttribute("UpdateState", message)
-		self:CallMethod("UpdateAction")
-	]])
-
-	-- secure PickupButton(self, kind, value, ...)
-	-- utility function to place a object on the cursor
-	button:SetAttribute("PickupButton", [[
-		local kind, value = ...
-		if kind == "empty" then
-			return "clear"
-		elseif kind == "action" or kind == "pet" then
-			local actionType = (kind == "pet") and "petaction" or kind
-			return actionType, value
-		elseif kind == "spell" or kind == "item" or kind == "macro" then
-			return "clear", kind, value
-		else
-			print("LibActionButton-1.0: Unknown type: " .. tostring(kind))
-			return false
-		end
-	]])
-
-	button:SetAttribute("OnDragStart", [[
-		if (self:GetAttribute("buttonlock") and not IsModifiedClick("PICKUPACTION")) or self:GetAttribute("LABdisableDragNDrop") then return false end
-		local state = self:GetAttribute("state")
-		local type = self:GetAttribute("type")
-		-- if the button is empty, we can't drag anything off it
-		if type == "empty" or type == "custom" then
-			return false
-		end
-		-- Get the value for the action attribute
-		local action_field = self:GetAttribute("action_field")
-		local action = self:GetAttribute(action_field)
-
-		-- non-action fields need to change their type to empty
-		if type ~= "action" and type ~= "pet" then
-			self:SetAttribute(format("labtype-%s", state), "empty")
-			self:SetAttribute(format("labaction-%s", state), nil)
-			-- update internal state
-			self:RunAttribute("UpdateState", state)
-			-- send a notification to the insecure code
-			self:CallMethod("ButtonContentsChanged", state, "empty", nil)
-		end
-		-- return the button contents for pickup
-		return self:RunAttribute("PickupButton", type, action)
-	]])
-
-	button:SetAttribute("OnReceiveDrag", [[
-		if self:GetAttribute("LABdisableDragNDrop") then return false end
-		local kind, value, subtype, extra = ...
-		if not kind or not value then return false end
-		local state = self:GetAttribute("state")
-		local buttonType, buttonAction = self:GetAttribute("type"), nil
-		if buttonType == "custom" then return false end
-		-- action buttons can do their magic themself
-		-- for all other buttons, we'll need to update the content now
-		if buttonType ~= "action" and buttonType ~= "pet" then
-			-- with "spell" types, the 4th value contains the actual spell id
-			if kind == "spell" then
-				if extra then
-					value = extra
-				else
-					print("no spell id?", ...)
-				end
-			elseif kind == "item" and value then
-				value = format("item:%d", value)
-			end
-
-			-- Get the action that was on the button before
-			if buttonType ~= "empty" then
-				buttonAction = self:GetAttribute(self:GetAttribute("action_field"))
-			end
-
-			-- TODO: validate what kind of action is being fed in here
-			-- We can only use a handful of the possible things on the cursor
-			-- return false for all those we can't put on buttons
-
-			self:SetAttribute(format("labtype-%s", state), kind)
-			self:SetAttribute(format("labaction-%s", state), value)
-			-- update internal state
-			self:RunAttribute("UpdateState", state)
-			-- send a notification to the insecure code
-			self:CallMethod("ButtonContentsChanged", state, kind, value)
-		else
-			-- get the action for (pet-)action buttons
-			buttonAction = self:GetAttribute("action")
-		end
-		return self:RunAttribute("PickupButton", buttonType, buttonAction)
-	]])
-
-	button:SetScript("OnDragStart", nil)
-	-- Wrapped OnDragStart(self, button, kind, value, ...)
-	button.header:WrapScript(button, "OnDragStart", [[
-		return self:RunAttribute("OnDragStart")
-	]])
-	-- Wrap twice, because the post-script is not run when the pre-script causes a pickup (doh)
-	-- we also need some phony message, or it won't work =/
-	button.header:WrapScript(button, "OnDragStart", [[
-		return "message", "update"
-	]], [[
-		self:RunAttribute("UpdateState", self:GetAttribute("state"))
-	]])
-
-	button:SetScript("OnReceiveDrag", nil)
-	-- Wrapped OnReceiveDrag(self, button, kind, value, ...)
-	button.header:WrapScript(button, "OnReceiveDrag", [[
-		return self:RunAttribute("OnReceiveDrag", kind, value, ...)
-	]])
-	-- Wrap twice, because the post-script is not run when the pre-script causes a pickup (doh)
-	-- we also need some phony message, or it won't work =/
-	button.header:WrapScript(button, "OnReceiveDrag", [[
-		return "message", "update"
-	]], [[
-		self:RunAttribute("UpdateState", self:GetAttribute("state"))
-	]])
-end
-
-function WrapOnClick(button)
-	-- Wrap OnClick, to catch changes to actions that are applied with a click on the button.
-	button.header:WrapScript(button, "OnClick", [[
-		if self:GetAttribute("type") == "action" then
-			local type, action = GetActionInfo(self:GetAttribute("action"))
-			return nil, format("%s|%s", tostring(type), tostring(action))
-		end
-	]], [[
-		local type, action = GetActionInfo(self:GetAttribute("action"))
-		if message ~= format("%s|%s", tostring(type), tostring(action)) then
-			self:RunAttribute("UpdateState", self:GetAttribute("state"))
-		end
-	]])
-end
-
------------------------------------------------------------
---- utility
-
-function lib:GetAllButtons()
-	local buttons = {}
-	for button in next, ButtonRegistry do
-		buttons[button] = true
-	end
-	return buttons
-end
-
-function Generic:ClearSetPoint(...)
-	self:ClearAllPoints()
-	self:SetPoint(...)
-end
-
-function Generic:NewHeader(header)
-	self.header = header
-	self:SetParent(header)
-	SetupSecureSnippets(self)
-	WrapOnClick(self)
-end
-
-
------------------------------------------------------------
---- state management
-
-function Generic:ClearStates()
-	for state in pairs(self.state_types) do
-		self:SetAttribute(format("labtype-%s", state), nil)
-		self:SetAttribute(format("labaction-%s", state), nil)
-	end
-	wipe(self.state_types)
-	wipe(self.state_actions)
-end
-
-function Generic:SetState(state, kind, action)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	-- we allow a nil kind for setting a empty state
-	if not kind then kind = "empty" end
-	if not type_meta_map[kind] then
-		error("SetStateAction: unknown action type: " .. tostring(kind), 2)
-	end
-	if kind ~= "empty" and action == nil then
-		error("SetStateAction: an action is required for non-empty states", 2)
-	end
-	if kind ~= "custom" and action ~= nil and type(action) ~= "number" and type(action) ~= "string" or (kind == "custom" and type(action) ~= "table") then
-		error("SetStateAction: invalid action data type, only strings and numbers allowed", 2)
-	end
-
-	if kind == "item" then
-		if tonumber(action) then
-			action = format("item:%s", action)
-		else
-			local itemString = str_match(action, "^|c%x+|H(item[%d:]+)|h%[")
-			if itemString then
-				action = itemString
-			end
-		end
-	end
-
-	self.state_types[state] = kind
-	self.state_actions[state] = action
-	self:UpdateState(state)
-end
-
-function Generic:UpdateState(state)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	self:SetAttribute(format("labtype-%s", state), self.state_types[state])
-	self:SetAttribute(format("labaction-%s", state), self.state_actions[state])
-	if state ~= tostring(self:GetAttribute("state")) then return end
-	if self.header then
-		self.header:SetFrameRef("updateButton", self)
-		self.header:Execute([[
-			local frame = self:GetFrameRef("updateButton")
-			control:RunFor(frame, frame:GetAttribute("UpdateState"), frame:GetAttribute("state"))
-		]])
-	else
-		-- TODO
-	end
-	self:UpdateAction()
-end
-
-function Generic:GetAction(state)
-	if not state then state = self:GetAttribute("state") end
-	state = tostring(state)
-	return self.state_types[state] or "empty", self.state_actions[state]
-end
-
-function Generic:UpdateAllStates()
-	for state in pairs(self.state_types) do
-		self:UpdateState(state)
-	end
-end
-
-function Generic:ButtonContentsChanged(state, kind, value)
-	state = tostring(state)
-	self.state_types[state] = kind or "empty"
-	self.state_actions[state] = value
-	lib.callbacks:Fire("OnButtonContentsChanged", self, state, self.state_types[state], self.state_actions[state])
-	self:UpdateAction(self)
-end
-
-function Generic:DisableDragNDrop(flag)
-	if InCombatLockdown() then
-		error("LibActionButton-1.0: You can only toggle DragNDrop out of combat!", 2)
-	end
-	if flag then
-		self:SetAttribute("LABdisableDragNDrop", true)
-	else
-		self:SetAttribute("LABdisableDragNDrop", nil)
-	end
-end
-
-function Generic:AddToButtonFacade(group)
-	if type(group) ~= "table" or type(group.AddButton) ~= "function" then
-		error("LibActionButton-1.0:AddToButtonFacade: You need to supply a proper group to use!", 2)
-	end
-	group:AddButton(self)
-	self.LBFSkinned = true
-end
-
-function Generic:AddToMasque(group)
-	if type(group) ~= "table" or type(group.AddButton) ~= "function" then
-		error("LibActionButton-1.0:AddToMasque: You need to supply a proper group to use!", 2)
-	end
-	group:AddButton(self)
-	self.MasqueSkinned = true
-end
-
-function Generic:UpdateAlpha()
-	UpdateCooldown(self)
-end
-
------------------------------------------------------------
---- frame scripts
-
--- copied (and adjusted) from SecureHandlers.lua
-local function PickupAny(kind, target, detail, ...)
-	if kind == "clear" then
-		ClearCursor()
-		kind, target, detail = target, detail, ...
-	end
-
-	if kind == 'action' then
-		PickupAction(target)
-	elseif kind == 'item' then
-		PickupItem(target)
-	elseif kind == 'macro' then
-		PickupMacro(target)
-	elseif kind == 'petaction' then
-		PickupPetAction(target)
-	elseif kind == 'spell' then
-		PickupSpell(target)
-	elseif kind == 'companion' then
-		PickupCompanion(target, detail)
-	elseif kind == 'equipmentset' then
-		PickupEquipmentSet(target)
-	end
-end
-
-function Generic:OnEnter()
-	if self.config.tooltip ~= "disabled" and (self.config.tooltip ~= "nocombat" or not InCombatLockdown()) then
-		UpdateTooltip(self)
-	end
-	if KeyBound then
-		KeyBound:Set(self)
-	end
-
-	if self._state_type == "action" and self.NewActionTexture then
-		lib.ACTION_HIGHLIGHT_MARKS[self._state_action] = false
-		UpdateNewAction(self)
-	end
-end
-
-function Generic:OnLeave()
-	GameTooltip:Hide()
-end
-
--- Insecure drag handler to allow clicking on the button with an action on the cursor
--- to place it on the button. Like action buttons work.
-function Generic:PreClick()
-	if self._state_type == "action" or self._state_type == "pet"
-			or InCombatLockdown() or self:GetAttribute("LABdisableDragNDrop")
-	then
-		return
-	end
-	-- check if there is actually something on the cursor
-	local kind, value, subtype = GetCursorInfo()
-	if not (kind and value) then return end
-	self._old_type = self._state_type
-	if self._state_type and self._state_type ~= "empty" then
-		self._old_type = self._state_type
-		self:SetAttribute("type", "empty")
-		--self:SetState(nil, "empty", nil)
-	end
-	self._receiving_drag = true
-end
-
-local function formatHelper(input)
-	if type(input) == "string" then
-		return format("%q", input)
-	else
-		return tostring(input)
-	end
-end
-
-function Generic:PostClick()
-	UpdateButtonState(self)
-	if self._receiving_drag and not InCombatLockdown() then
-		if self._old_type then
-			self:SetAttribute("type", self._old_type)
-			self._old_type = nil
-		end
-		local oldType, oldAction = self._state_type, self._state_action
-		local kind, data, subtype, extra = GetCursorInfo()
-		self.header:SetFrameRef("updateButton", self)
-		self.header:Execute(format([[
-			local frame = self:GetFrameRef("updateButton")
-			control:RunFor(frame, frame:GetAttribute("OnReceiveDrag"), %s, %s, %s, %s)
-			control:RunFor(frame, frame:GetAttribute("UpdateState"), %s)
-		]], formatHelper(kind), formatHelper(data), formatHelper(subtype), formatHelper(extra), formatHelper(self:GetAttribute("state"))))
-		PickupAny("clear", oldType, oldAction)
-	end
-	self._receiving_drag = nil
-end
-
------------------------------------------------------------
---- configuration
-
-local function merge(target, source, default)
-	for k,v in pairs(default) do
-		if type(v) ~= "table" then
-			if source and source[k] ~= nil then
-				target[k] = source[k]
-			else
-				target[k] = v
-			end
-		else
-			if type(target[k]) ~= "table" then target[k] = {} else wipe(target[k]) end
-			merge(target[k], type(source) == "table" and source[k], v)
-		end
-	end
-	return target
-end
-
-function Generic:UpdateConfig(config)
-	if config and type(config) ~= "table" then
-		error("LibActionButton-1.0: UpdateConfig requires a valid configuration!", 2)
-	end
-	local oldconfig = self.config
-	if not self.config then self.config = {} end
-	-- merge the two configs
-	merge(self.config, config, DefaultConfig)
-
-	if self.config.outOfRangeColoring == "button" or (oldconfig and oldconfig.outOfRangeColoring == "button") then
-		UpdateUsable(self)
-	end
-	if self.config.outOfRangeColoring == "hotkey" then
-		self.outOfRange = nil
-	elseif oldconfig and oldconfig.outOfRangeColoring == "hotkey" then
-		self.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-	end
-
-	if self.config.hideElements.macro then
-		self.Name:Hide()
-	else
-		self.Name:Show()
-	end
-
-	self:SetAttribute("flyoutDirection", self.config.flyoutDirection)
-
-	UpdateHotkeys(self)
-	UpdateGrid(self)
-	Update(self)
-	self:RegisterForClicks(self.config.clickOnDown and "AnyDown" or "AnyUp")
-end
-
------------------------------------------------------------
---- event handler
-
-function ForAllButtons(method, onlyWithAction)
-	assert(type(method) == "function")
-	for button in next, (onlyWithAction and ActiveButtons or ButtonRegistry) do
-		method(button)
-	end
-end
-
-function InitializeEventHandler()
-	lib.eventFrame:SetScript("OnEvent", OnEvent)
-	lib.eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_SHOWGRID")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_HIDEGRID")
-	--lib.eventFrame:RegisterEvent("ACTIONBAR_PAGE_CHANGED")
-	--lib.eventFrame:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
-	lib.eventFrame:RegisterEvent("UPDATE_BINDINGS")
-	lib.eventFrame:RegisterEvent("UPDATE_SHAPESHIFT_FORM")
-	lib.eventFrame:RegisterEvent("UPDATE_VEHICLE_ACTIONBAR")
-
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_STATE")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
-	lib.eventFrame:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
-	lib.eventFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
-	lib.eventFrame:RegisterEvent("TRADE_SKILL_SHOW")
-	lib.eventFrame:RegisterEvent("TRADE_SKILL_CLOSE")
-	lib.eventFrame:RegisterEvent("ARCHAEOLOGY_CLOSED")
-	lib.eventFrame:RegisterEvent("PLAYER_ENTER_COMBAT")
-	lib.eventFrame:RegisterEvent("PLAYER_LEAVE_COMBAT")
-	lib.eventFrame:RegisterEvent("START_AUTOREPEAT_SPELL")
-	lib.eventFrame:RegisterEvent("STOP_AUTOREPEAT_SPELL")
-	lib.eventFrame:RegisterEvent("UNIT_ENTERED_VEHICLE")
-	lib.eventFrame:RegisterEvent("UNIT_EXITED_VEHICLE")
-	lib.eventFrame:RegisterEvent("COMPANION_UPDATE")
-	lib.eventFrame:RegisterEvent("UNIT_INVENTORY_CHANGED")
-	lib.eventFrame:RegisterEvent("LEARNED_SPELL_IN_TAB")
-	lib.eventFrame:RegisterEvent("PET_STABLE_UPDATE")
-	lib.eventFrame:RegisterEvent("PET_STABLE_SHOW")
-	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_SHOW")
-	lib.eventFrame:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_HIDE")
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_CHARGES")
-	lib.eventFrame:RegisterEvent("UPDATE_SUMMONPETS_ACTION")
-
-	-- With those two, do we still need the ACTIONBAR equivalents of them?
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_COOLDOWN")
-	lib.eventFrame:RegisterEvent("SPELL_UPDATE_USABLE")
-	lib.eventFrame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
-
-	lib.eventFrame:RegisterEvent("LOSS_OF_CONTROL_ADDED")
-	lib.eventFrame:RegisterEvent("LOSS_OF_CONTROL_UPDATE")
-
-	lib.eventFrame:Show()
-	lib.eventFrame:SetScript("OnUpdate", OnUpdate)
-end
-
-function OnEvent(frame, event, arg1, ...)
-	if (event == "UNIT_INVENTORY_CHANGED" and arg1 == "player") or event == "LEARNED_SPELL_IN_TAB" then
-		local tooltipOwner = GameTooltip:GetOwner()
-		if ButtonRegistry[tooltipOwner] then
-			tooltipOwner:SetTooltip()
-		end
-	elseif event == "ACTIONBAR_SLOT_CHANGED" then
-		for button in next, ButtonRegistry do
-			if button._state_type == "action" and (arg1 == 0 or arg1 == tonumber(button._state_action)) then
-				Update(button)
-			end
-		end
-	elseif event == "PLAYER_ENTERING_WORLD" or event == "UPDATE_SHAPESHIFT_FORM" or event == "UPDATE_VEHICLE_ACTIONBAR" then
-		ForAllButtons(Update)
-	elseif event == "ACTIONBAR_PAGE_CHANGED" or event == "UPDATE_BONUS_ACTIONBAR" then
-		-- TODO: Are these even needed?
-	elseif event == "ACTIONBAR_SHOWGRID" then
-		ShowGrid()
-	elseif event == "ACTIONBAR_HIDEGRID" then
-		HideGrid()
-	elseif event == "UPDATE_BINDINGS" then
-		ForAllButtons(UpdateHotkeys)
-	elseif event == "PLAYER_TARGET_CHANGED" then
-		UpdateRangeTimer()
-	elseif (event == "ACTIONBAR_UPDATE_STATE") or
-			((event == "UNIT_ENTERED_VEHICLE" or event == "UNIT_EXITED_VEHICLE") and (arg1 == "player")) or
-			((event == "COMPANION_UPDATE") and (arg1 == "MOUNT")) then
-		ForAllButtons(UpdateButtonState, true)
-	elseif event == "ACTIONBAR_UPDATE_USABLE" then
-		for button in next, ActionButtons do
-			UpdateUsable(button)
-		end
-	elseif event == "SPELL_UPDATE_USABLE" then
-		for button in next, NonActionButtons do
-			UpdateUsable(button)
-		end
-	elseif event == "ACTIONBAR_UPDATE_COOLDOWN" then
-		for button in next, ActionButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "SPELL_UPDATE_COOLDOWN" then
-		for button in next, NonActionButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "LOSS_OF_CONTROL_ADDED" then
-		for button in next, ActiveButtons do
-			UpdateCooldown(button)
-			if GameTooltip:GetOwner() == button then
-				UpdateTooltip(button)
-			end
-		end
-	elseif event == "LOSS_OF_CONTROL_UPDATE" then
-		for button in next, ActiveButtons do
-			UpdateCooldown(button)
-		end
-	elseif event == "TRADE_SKILL_SHOW" or event == "TRADE_SKILL_CLOSE"  or event == "ARCHAEOLOGY_CLOSED" then
-		ForAllButtons(UpdateButtonState, true)
-	elseif event == "PLAYER_ENTER_COMBAT" then
-		for button in next, ActiveButtons do
-			if button:IsAttack() then
-				StartFlash(button)
-			end
-		end
-	elseif event == "PLAYER_LEAVE_COMBAT" then
-		for button in next, ActiveButtons do
-			if button:IsAttack() then
-				StopFlash(button)
-			end
-		end
-	elseif event == "START_AUTOREPEAT_SPELL" then
-		for button in next, ActiveButtons do
-			if button:IsAutoRepeat() then
-				StartFlash(button)
-			end
-		end
-	elseif event == "STOP_AUTOREPEAT_SPELL" then
-		for button in next, ActiveButtons do
-			if button.flashing == 1 and not button:IsAttack() then
-				StopFlash(button)
-			end
-		end
-	elseif event == "PET_STABLE_UPDATE" or event == "PET_STABLE_SHOW" then
-		ForAllButtons(Update)
-	elseif event == "SPELL_ACTIVATION_OVERLAY_GLOW_SHOW" then
-		for button in next, ActiveButtons do
-			local spellId = button:GetSpellId()
-			if spellId and spellId == arg1 then
-				ShowOverlayGlow(button)
-			else
-				if button._state_type == "action" then
-					local actionType, id = GetActionInfo(button._state_action)
-					if actionType == "flyout" and FlyoutHasSpell(id, arg1) then
-						ShowOverlayGlow(button)
-					end
-				end
-			end
-		end
-	elseif event == "SPELL_ACTIVATION_OVERLAY_GLOW_HIDE" then
-		for button in next, ActiveButtons do
-			local spellId = button:GetSpellId()
-			if spellId and spellId == arg1 then
-				HideOverlayGlow(button)
-			else
-				if button._state_type == "action" then
-					local actionType, id = GetActionInfo(button._state_action)
-					if actionType == "flyout" and FlyoutHasSpell(id, arg1) then
-						HideOverlayGlow(button)
-					end
-				end
-			end
-		end
-	elseif event == "PLAYER_EQUIPMENT_CHANGED" then
-		for button in next, ActiveButtons do
-			if button._state_type == "item" then
-				Update(button)
-			end
-		end
-	elseif event == "SPELL_UPDATE_CHARGES" then
-		ForAllButtons(UpdateCount, true)
-	elseif event == "UPDATE_SUMMONPETS_ACTION" then
-		for button in next, ActiveButtons do
-			if button._state_type == "action" then
-				local actionType, id = GetActionInfo(button._state_action)
-				if actionType == "summonpet" then
-					local texture = GetActionTexture(button._state_action)
-					if texture then
-						button.icon:SetTexture(texture)
-					end
-				end
-			end
-		end
-	end
-end
-
-local flashTime = 0
-local rangeTimer = -1
-function OnUpdate(_, elapsed)
-	flashTime = flashTime - elapsed
-	rangeTimer = rangeTimer - elapsed
-	-- Run the loop only when there is something to update
-	if rangeTimer <= 0 or flashTime <= 0 then
-		for button in next, ActiveButtons do
-			-- Flashing
-			if button.flashing == 1 and flashTime <= 0 then
-				if button.Flash:IsShown() then
-					button.Flash:Hide()
-				else
-					button.Flash:Show()
-				end
-			end
-
-			-- Range
-			if rangeTimer <= 0 then
-				local inRange = button:IsInRange()
-				local oldRange = button.outOfRange
-				button.outOfRange = (inRange == false)
-				if oldRange ~= button.outOfRange then
-					if button.config.outOfRangeColoring == "button" then
-						UpdateUsable(button)
-					elseif button.config.outOfRangeColoring == "hotkey" then
-						local hotkey = button.HotKey
-						if hotkey:GetText() == RANGE_INDICATOR then
-							if inRange == false then
-								hotkey:Show()
-							else
-								hotkey:Hide()
-							end
-						end
-						if inRange == false then
-							hotkey:SetVertexColor(unpack(button.config.colors.range))
-						else
-							hotkey:SetVertexColor(0.75, 0.75, 0.75)
-						end
-					end
-				end
-			end
-		end
-
-		-- Update values
-		if flashTime <= 0 then
-			flashTime = flashTime + ATTACK_BUTTON_FLASH_TIME
-		end
-		if rangeTimer <= 0 then
-			rangeTimer = TOOLTIP_UPDATE_TIME
-		end
-	end
-end
-
-local gridCounter = 0
-function ShowGrid()
-	gridCounter = gridCounter + 1
-	if gridCounter >= 1 then
-		for button in next, ButtonRegistry do
-			if button:IsShown() then
-				button:SetAlpha(1.0)
-			end
-		end
-	end
-end
-
-function HideGrid()
-	if gridCounter > 0 then
-		gridCounter = gridCounter - 1
-	end
-	if gridCounter == 0 then
-		for button in next, ButtonRegistry do
-			if button:IsShown() and not button:HasAction() and not button.config.showGrid then
-				button:SetAlpha(0.0)
-			end
-		end
-	end
-end
-
-function UpdateGrid(self)
-	if self.config.showGrid then
-		self:SetAlpha(1.0)
-	elseif gridCounter == 0 and self:IsShown() and not self:HasAction() then
-		self:SetAlpha(0.0)
-	end
-end
-
------------------------------------------------------------
---- KeyBound integration
-
-function Generic:GetBindingAction()
-	return self.config.keyBoundTarget or "CLICK "..self:GetName()..":LeftButton"
-end
-
-function Generic:GetHotkey()
-	local name = "CLICK "..self:GetName()..":LeftButton"
-	local key = GetBindingKey(self.config.keyBoundTarget or name)
-	if not key and self.config.keyBoundTarget then
-		key = GetBindingKey(name)
-	end
-	if key then
-		return KeyBound and KeyBound:ToShortKey(key) or key
-	end
-end
-
-local function getKeys(binding, keys)
-	keys = keys or ""
-	for i = 1, select("#", GetBindingKey(binding)) do
-		local hotKey = select(i, GetBindingKey(binding))
-		if keys ~= "" then
-			keys = keys .. ", "
-		end
-		keys = keys .. GetBindingText(hotKey, "KEY_")
-	end
-	return keys
-end
-
-function Generic:GetBindings()
-	local keys, binding
-
-	if self.config.keyBoundTarget then
-		keys = getKeys(self.config.keyBoundTarget)
-	end
-
-	keys = getKeys("CLICK "..self:GetName()..":LeftButton")
-
-	return keys
-end
-
-function Generic:SetKey(key)
-	if self.config.keyBoundTarget then
-		SetBinding(key, self.config.keyBoundTarget)
-	else
-		SetBindingClick(key, self:GetName(), "LeftButton")
-	end
-	lib.callbacks:Fire("OnKeybindingChanged", self, key)
-end
-
-local function clearBindings(binding)
-	while GetBindingKey(binding) do
-		SetBinding(GetBindingKey(binding), nil)
-	end
-end
-
-function Generic:ClearBindings()
-	if self.config.keyBoundTarget then
-		clearBindings(self.config.keyBoundTarget)
-	end
-	clearBindings("CLICK "..self:GetName()..":LeftButton")
-	lib.callbacks:Fire("OnKeybindingChanged", self, nil)
-end
-
------------------------------------------------------------
---- button management
-
-function Generic:UpdateAction(force)
-	local type, action = self:GetAction()
-	if force or type ~= self._state_type or action ~= self._state_action then
-		-- type changed, update the metatable
-		if force or self._state_type ~= type then
-			local meta = type_meta_map[type] or type_meta_map.empty
-			setmetatable(self, meta)
-			self._state_type = type
-		end
-		self._state_action = action
-		Update(self)
-	end
-end
-
-function Update(self)
-	if self:HasAction() then
-		ActiveButtons[self] = true
-		if self._state_type == "action" then
-			ActionButtons[self] = true
-			NonActionButtons[self] = nil
-		else
-			ActionButtons[self] = nil
-			NonActionButtons[self] = true
-		end
-		self:SetAlpha(1.0)
-		UpdateButtonState(self)
-		UpdateUsable(self)
-		UpdateCooldown(self)
-		UpdateFlash(self)
-	else
-		ActiveButtons[self] = nil
-		ActionButtons[self] = nil
-		NonActionButtons[self] = nil
-		if gridCounter == 0 and not self.config.showGrid then
-			self:SetAlpha(0.0)
-		end
-		self.cooldown:Hide()
-		self:SetChecked(false)
-	end
-
-	-- Add a green border if button is an equipped item
-	if self:IsEquipped() and not self.config.hideElements.equipped then
-		self.Border:SetVertexColor(0, 1.0, 0, 0.35)
-		self.Border:Show()
-	else
-		self.Border:Hide()
-	end
-
-	-- Update Action Text
-	if not self:IsConsumableOrStackable() then
-		self.Name:SetText(self:GetActionText())
-	else
-		self.Name:SetText("")
-	end
-
-	-- Update icon and hotkey
-	local texture = self:GetTexture()
-	if texture then
-		self.icon:SetTexture(texture)
-		self.icon:Show()
-		self.rangeTimer = - 1
-		self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
-		if not self.LBFSkinned and not self.MasqueSkinned then
-			self.NormalTexture:SetTexCoord(0, 0, 0, 0)
-		end
-	else
-		self.icon:Hide()
-		self.cooldown:Hide()
-		self.rangeTimer = nil
-		self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
-		if self.HotKey:GetText() == RANGE_INDICATOR then
-			self.HotKey:Hide()
-		else
-			self.HotKey:SetVertexColor(0.75, 0.75, 0.75)
-		end
-		if not self.LBFSkinned and not self.MasqueSkinned then
-			self.NormalTexture:SetTexCoord(-0.15, 1.15, -0.15, 1.17)
-		end
-	end
-
-	self:UpdateLocal()
-
-	UpdateCount(self)
-
-	UpdateFlyout(self)
-
-	UpdateOverlayGlow(self)
-
-	UpdateNewAction(self)
-
-	if GameTooltip:GetOwner() == self then
-		UpdateTooltip(self)
-	end
-
-	-- this could've been a spec change, need to call OnStateChanged for action buttons, if present
-	if not InCombatLockdown() and self._state_type == "action" then
-		local onStateChanged = self:GetAttribute("OnStateChanged")
-		if onStateChanged then
-			self.header:SetFrameRef("updateButton", self)
-			self.header:Execute(([[
-				local frame = self:GetFrameRef("updateButton")
-				control:RunFor(frame, frame:GetAttribute("OnStateChanged"), %s, %s, %s)
-			]]):format(formatHelper(self:GetAttribute("state")), formatHelper(self._state_type), formatHelper(self._state_action)))
-		end
-	end
-	lib.callbacks:Fire("OnButtonUpdate", self)
-end
-
-function Generic:UpdateLocal()
-	-- dummy function the other button types can override for special updating
-end
-
-function UpdateButtonState(self)
-	if self:IsCurrentlyActive() or self:IsAutoRepeat() then
-		self:SetChecked(true)
-	else
-		self:SetChecked(false)
-	end
-	lib.callbacks:Fire("OnButtonState", self)
-end
-
-function UpdateUsable(self)
-	-- TODO: make the colors configurable
-	-- TODO: allow disabling of the whole recoloring
-	if self.config.outOfRangeColoring == "button" and self.outOfRange then
-		self.icon:SetVertexColor(unpack(self.config.colors.range))
-	else
-		local isUsable, notEnoughMana = self:IsUsable()
-		if isUsable then
-			self.icon:SetVertexColor(1.0, 1.0, 1.0)
-			--self.NormalTexture:SetVertexColor(1.0, 1.0, 1.0)
-		elseif notEnoughMana then
-			self.icon:SetVertexColor(unpack(self.config.colors.mana))
-			--self.NormalTexture:SetVertexColor(0.5, 0.5, 1.0)
-		else
-			self.icon:SetVertexColor(0.4, 0.4, 0.4)
-			--self.NormalTexture:SetVertexColor(1.0, 1.0, 1.0)
-		end
-	end
-	lib.callbacks:Fire("OnButtonUsable", self)
-end
-
-function UpdateCount(self)
-	if not self:HasAction() then
-		self.Count:SetText("")
-		return
-	end
-	if self:IsConsumableOrStackable() then
-		local count = self:GetCount()
-		if count > (self.maxDisplayCount or 9999) then
-			self.Count:SetText("*")
-		else
-			self.Count:SetText(count)
-		end
-	else
-		local charges, maxCharges, chargeStart, chargeDuration = self:GetCharges()
-		if charges and maxCharges and maxCharges > 0 then
-			self.Count:SetText(charges)
-		else
-			self.Count:SetText("")
-		end
-	end
-end
-
-local function SetCooldownHook(cooldown, ...)
-	local effectiveAlpha = cooldown:GetEffectiveAlpha()
-	local start, duration = ...
-
-	if start ~= 0 or duration ~= 0 then
-		-- update swipe alpha
-		cooldown.__metaLAB.SetSwipeColor(cooldown, cooldown.__SwipeR, cooldown.__SwipeG, cooldown.__SwipeB, cooldown.__SwipeA * effectiveAlpha)
-
-		-- only draw bling and edge if alpha is over 50%
-		cooldown:SetDrawBling(effectiveAlpha > 0.5)
-		if effectiveAlpha < 0.5 then
-			cooldown:SetDrawEdge(false)
-		end
-
-		-- ensure the swipe isn't drawn on fully faded bars
-		if effectiveAlpha <= 0.0 then
-			cooldown:SetDrawSwipe(false)
-		end
-	end
-
-	return cooldown.__metaLAB.SetCooldown(cooldown, ...)
-end
-
-local function SetSwipeColorHook(cooldown, r, g, b, a)
-	local effectiveAlpha = cooldown:GetEffectiveAlpha()
-	cooldown.__SwipeR, cooldown.__SwipeG, cooldown.__SwipeB, cooldown.__SwipeA = r, g, b, (a or 1)
-	return cooldown.__metaLAB.SetSwipeColor(cooldown, r, g, b, a * effectiveAlpha)
-end
-
-function HookCooldown(button)
-	if not button.cooldown.__metaLAB then
-		button.cooldown.__metaLAB = getmetatable(button.cooldown).__index
-		button.cooldown.__SwipeR, button.cooldown.__SwipeG, button.cooldown.__SwipeB, button.cooldown.__SwipeA = 0, 0, 0, 0.8
-
-		button.cooldown.SetCooldown = SetCooldownHook
-		button.cooldown.SetSwipeColor = SetSwipeColorHook
-	end
-end
-
-function OnCooldownDone(self)
-	self:SetScript("OnCooldownDone", nil)
-	UpdateCooldown(self:GetParent())
-end
-
-function UpdateCooldown(self)
-	local locStart, locDuration = self:GetLossOfControlCooldown()
-	local start, duration, enable, charges, maxCharges = self:GetCooldown()
-
-	if (locStart + locDuration) > (start + duration) then
-		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_LOSS_OF_CONTROL then
-			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge-LoC")
-			self.cooldown:SetHideCountdownNumbers(true)
-			self.cooldown.currentCooldownType = COOLDOWN_TYPE_LOSS_OF_CONTROL
-			self.cooldown:SetSwipeColor(0.17, 0, 0, 0.8)
-		end
-		CooldownFrame_SetTimer(self.cooldown, locStart, locDuration, 1, nil, nil, true)
-	else
-		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_NORMAL then
-			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge")
-			self.cooldown:SetHideCountdownNumbers(false)
-			self.cooldown.currentCooldownType = COOLDOWN_TYPE_NORMAL
-			self.cooldown:SetSwipeColor(0, 0, 0, 0.8)
-		end
-		if locStart > 0 then
-			self.cooldown:SetScript("OnCooldownDone", OnCooldownDone)
-		end
-		CooldownFrame_SetTimer(self.cooldown, start, duration, enable, charges, maxCharges)
-	end
-end
-
-function StartFlash(self)
-	self.flashing = 1
-	flashTime = 0
-	UpdateButtonState(self)
-end
-
-function StopFlash(self)
-	self.flashing = 0
-	self.Flash:Hide()
-	UpdateButtonState(self)
-end
-
-function UpdateFlash(self)
-	if (self:IsAttack() and self:IsCurrentlyActive()) or self:IsAutoRepeat() then
-		StartFlash(self)
-	else
-		StopFlash(self)
-	end
-end
-
-function UpdateTooltip(self)
-	if (GetCVar("UberTooltips") == "1") then
-		GameTooltip_SetDefaultAnchor(GameTooltip, self);
-	else
-		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
-	end
-	if self:SetTooltip() then
-		self.UpdateTooltip = UpdateTooltip
-	else
-		self.UpdateTooltip = nil
-	end
-end
-
-function UpdateHotkeys(self)
-	local key = self:GetHotkey()
-	if not key or key == "" or self.config.hideElements.hotkey then
-		self.HotKey:SetText(RANGE_INDICATOR)
-		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", 1, - 2)
-		self.HotKey:Hide()
-	else
-		self.HotKey:SetText(key)
-		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", - 2, - 2)
-		self.HotKey:Show()
-	end
-end
-
-local function OverlayGlow_OnHide(self)
-	if self.animOut:IsPlaying() then
-		self.animOut:Stop()
-		OverlayGlowAnimOutFinished(self.animOut)
-	end
-end
-
-function GetOverlayGlow()
-	local overlay = tremove(lib.unusedOverlayGlows);
-	if not overlay then
-		lib.numOverlays = lib.numOverlays + 1
-		overlay = CreateFrame("Frame", "LAB10ActionButtonOverlay"..lib.numOverlays, UIParent, "ActionBarButtonSpellActivationAlert")
-		overlay.animOut:SetScript("OnFinished", OverlayGlowAnimOutFinished)
-		overlay:SetScript("OnHide", OverlayGlow_OnHide)
-	end
-	return overlay
-end
-
-function ShowOverlayGlow(self)
-	if self.overlay then
-		if self.overlay.animOut:IsPlaying() then
-			self.overlay.animOut:Stop()
-			self.overlay.animIn:Play()
-		end
-	else
-		self.overlay = GetOverlayGlow()
-		local frameWidth, frameHeight = self:GetSize()
-		self.overlay:SetParent(self)
-		self.overlay:ClearAllPoints()
-		--Make the height/width available before the next frame:
-		self.overlay:SetSize(frameWidth * 1.4, frameHeight * 1.4)
-		self.overlay:SetPoint("TOPLEFT", self, "TOPLEFT", -frameWidth * 0.2, frameHeight * 0.2)
-		self.overlay:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", frameWidth * 0.2, -frameHeight * 0.2)
-		self.overlay.animIn:Play()
-	end
-end
-
-function HideOverlayGlow(self)
-	if self.overlay then
-		if self.overlay.animIn:IsPlaying() then
-			self.overlay.animIn:Stop()
-		end
-		if self:IsVisible() then
-			self.overlay.animOut:Play()
-		else
-			OverlayGlowAnimOutFinished(self.overlay.animOut)
-		end
-	end
-end
-
-function OverlayGlowAnimOutFinished(animGroup)
-	local overlay = animGroup:GetParent()
-	local actionButton = overlay:GetParent()
-	overlay:Hide()
-	tinsert(lib.unusedOverlayGlows, overlay)
-	actionButton.overlay = nil
-end
-
-function UpdateOverlayGlow(self)
-	local spellId = self:GetSpellId()
-	if spellId and IsSpellOverlayed(spellId) then
-		ShowOverlayGlow(self)
-	else
-		HideOverlayGlow(self)
-	end
-end
-
-hooksecurefunc("MarkNewActionHighlight", function(action, flag)
-	lib.ACTION_HIGHLIGHT_MARKS[action] = flag
-	for button in next, ButtonRegistry do
-		if button._state_type == "action" and action == tonumber(button._state_action) then
-			UpdateNewAction(button)
-		end
-	end
-end)
-
-function UpdateNewAction(self)
-	-- special handling for "New Action" markers
-	if self.NewActionTexture then
-		if self._state_type == "action" and lib.ACTION_HIGHLIGHT_MARKS[self._state_action] then
-			self.NewActionTexture:Show()
-		else
-			self.NewActionTexture:Hide()
-		end
-	end
-end
-
--- Hook UpdateFlyout so we can use the blizzy templates
-hooksecurefunc("ActionButton_UpdateFlyout", function(self, ...)
-	if ButtonRegistry[self] then
-		UpdateFlyout(self)
-	end
-end)
-
-function UpdateFlyout(self)
-	-- disabled FlyoutBorder/BorderShadow, those are not handled by LBF and look terrible
-	self.FlyoutBorder:Hide()
-	self.FlyoutBorderShadow:Hide()
-	if self._state_type == "action" then
-		-- based on ActionButton_UpdateFlyout in ActionButton.lua
-		local actionType = GetActionInfo(self._state_action)
-		if actionType == "flyout" then
-			-- Update border and determine arrow position
-			local arrowDistance
-			if (SpellFlyout and SpellFlyout:IsShown() and SpellFlyout:GetParent() == self) or GetMouseFocus() == self then
-				arrowDistance = 5
-			else
-				arrowDistance = 2
-			end
-
-			-- Update arrow
-			self.FlyoutArrow:Show()
-			self.FlyoutArrow:ClearAllPoints()
-			local direction = self:GetAttribute("flyoutDirection");
-			if direction == "LEFT" then
-				self.FlyoutArrow:SetPoint("LEFT", self, "LEFT", -arrowDistance, 0)
-				SetClampedTextureRotation(self.FlyoutArrow, 270)
-			elseif direction == "RIGHT" then
-				self.FlyoutArrow:SetPoint("RIGHT", self, "RIGHT", arrowDistance, 0)
-				SetClampedTextureRotation(self.FlyoutArrow, 90)
-			elseif direction == "DOWN" then
-				self.FlyoutArrow:SetPoint("BOTTOM", self, "BOTTOM", 0, -arrowDistance)
-				SetClampedTextureRotation(self.FlyoutArrow, 180)
-			else
-				self.FlyoutArrow:SetPoint("TOP", self, "TOP", 0, arrowDistance)
-				SetClampedTextureRotation(self.FlyoutArrow, 0)
-			end
-
-			-- return here, otherwise flyout is hidden
-			return
-		end
-	end
-	self.FlyoutArrow:Hide()
-end
-
-function UpdateRangeTimer()
-	rangeTimer = -1
-end
-
-local function GetSpellIdByName(spellName)
-	if not spellName then return end
-	local spellLink = GetSpellLink(spellName)
-	if spellLink then
-		return tonumber(spellLink:match("spell:(%d+)"))
-	end
-	return nil
-end
-
------------------------------------------------------------
---- WoW API mapping
---- Generic Button
-Generic.HasAction               = function(self) return nil end
-Generic.GetActionText           = function(self) return "" end
-Generic.GetTexture              = function(self) return nil end
-Generic.GetCharges              = function(self) return nil end
-Generic.GetCount                = function(self) return 0 end
-Generic.GetCooldown             = function(self) return 0, 0, 0 end
-Generic.IsAttack                = function(self) return nil end
-Generic.IsEquipped              = function(self) return nil end
-Generic.IsCurrentlyActive       = function(self) return nil end
-Generic.IsAutoRepeat            = function(self) return nil end
-Generic.IsUsable                = function(self) return nil end
-Generic.IsConsumableOrStackable = function(self) return nil end
-Generic.IsUnitInRange           = function(self, unit) return nil end
-Generic.IsInRange               = function(self)
-	local unit = self:GetAttribute("unit")
-	if unit == "player" then
-		unit = nil
-	end
-	local val = self:IsUnitInRange(unit)
-	-- map 1/0 to true false, since the return values are inconsistent between actions and spells
-	if val == 1 then val = true elseif val == 0 then val = false end
-	return val
-end
-Generic.SetTooltip              = function(self) return nil end
-Generic.GetSpellId              = function(self) return nil end
-Generic.GetLossOfControlCooldown = function(self) return 0, 0 end
-
------------------------------------------------------------
---- Action Button
-Action.HasAction               = function(self) return HasAction(self._state_action) end
-Action.GetActionText           = function(self) return GetActionText(self._state_action) end
-Action.GetTexture              = function(self) return GetActionTexture(self._state_action) end
-Action.GetCharges              = function(self) return GetActionCharges(self._state_action) end
-Action.GetCount                = function(self) return GetActionCount(self._state_action) end
-Action.GetCooldown             = function(self) return GetActionCooldown(self._state_action) end
-Action.IsAttack                = function(self) return IsAttackAction(self._state_action) end
-Action.IsEquipped              = function(self) return IsEquippedAction(self._state_action) end
-Action.IsCurrentlyActive       = function(self) return IsCurrentAction(self._state_action) end
-Action.IsAutoRepeat            = function(self) return IsAutoRepeatAction(self._state_action) end
-Action.IsUsable                = function(self) return IsUsableAction(self._state_action) end
-Action.IsConsumableOrStackable = function(self) return IsConsumableAction(self._state_action) or IsStackableAction(self._state_action) or (not IsItemAction(self._state_action) and GetActionCount(self._state_action) > 0) end
-Action.IsUnitInRange           = function(self, unit) return IsActionInRange(self._state_action, unit) end
-Action.SetTooltip              = function(self) return GameTooltip:SetAction(self._state_action) end
-Action.GetSpellId              = function(self)
-	local actionType, id, subType = GetActionInfo(self._state_action)
-	if actionType == "spell" then
-		return id
-	elseif actionType == "macro" then
-		local _, _, spellId = GetMacroSpell(id)
-		return spellId
-	end
-end
-Action.GetLossOfControlCooldown = function(self) return GetActionLossOfControlCooldown(self._state_action) end
-
------------------------------------------------------------
---- Spell Button
-Spell.HasAction               = function(self) return true end
-Spell.GetActionText           = function(self) return "" end
-Spell.GetTexture              = function(self) return GetSpellTexture(self._state_action) end
-Spell.GetCharges              = function(self) return GetSpellCharges(self._state_action) end
-Spell.GetCount                = function(self) return GetSpellCount(self._state_action) end
-Spell.GetCooldown             = function(self) return GetSpellCooldown(self._state_action) end
-Spell.IsAttack                = function(self) return IsAttackSpell(FindSpellBookSlotBySpellID(self._state_action), "spell") end -- needs spell book id as of 4.0.1.13066
-Spell.IsEquipped              = function(self) return nil end
-Spell.IsCurrentlyActive       = function(self) return IsCurrentSpell(self._state_action) end
-Spell.IsAutoRepeat            = function(self) return IsAutoRepeatSpell(FindSpellBookSlotBySpellID(self._state_action), "spell") end -- needs spell book id as of 4.0.1.13066
-Spell.IsUsable                = function(self) return IsUsableSpell(self._state_action) end
-Spell.IsConsumableOrStackable = function(self) return IsConsumableSpell(self._state_action) end
-Spell.IsUnitInRange           = function(self, unit) return IsSpellInRange(FindSpellBookSlotBySpellID(self._state_action), "spell", unit) end -- needs spell book id as of 4.0.1.13066
-Spell.SetTooltip              = function(self) return GameTooltip:SetSpellByID(self._state_action) end
-Spell.GetSpellId              = function(self) return self._state_action end
-
------------------------------------------------------------
---- Item Button
-local function getItemId(input)
-	return input:match("^item:(%d+)")
-end
-
-Item.HasAction               = function(self) return true end
-Item.GetActionText           = function(self) return "" end
-Item.GetTexture              = function(self) return GetItemIcon(self._state_action) end
-Item.GetCharges              = function(self) return nil end
-Item.GetCount                = function(self) return GetItemCount(self._state_action, nil, true) end
-Item.GetCooldown             = function(self) return GetItemCooldown(getItemId(self._state_action)) end
-Item.IsAttack                = function(self) return nil end
-Item.IsEquipped              = function(self) return IsEquippedItem(self._state_action) end
-Item.IsCurrentlyActive       = function(self) return IsCurrentItem(self._state_action) end
-Item.IsAutoRepeat            = function(self) return nil end
-Item.IsUsable                = function(self) return IsUsableItem(self._state_action) end
-Item.IsConsumableOrStackable = function(self) return IsConsumableItem(self._state_action) end
-Item.IsUnitInRange           = function(self, unit) return IsItemInRange(self._state_action, unit) end
-Item.SetTooltip              = function(self) return GameTooltip:SetHyperlink(self._state_action) end
-Item.GetSpellId              = function(self) return nil end
-
------------------------------------------------------------
---- Macro Button
--- TODO: map results of GetMacroSpell/GetMacroItem to proper results
-Macro.HasAction               = function(self) return true end
-Macro.GetActionText           = function(self) return (GetMacroInfo(self._state_action)) end
-Macro.GetTexture              = function(self) return (select(2, GetMacroInfo(self._state_action))) end
-Macro.GetCharges              = function(self) return nil end
-Macro.GetCount                = function(self) return 0 end
-Macro.GetCooldown             = function(self) return 0, 0, 0 end
-Macro.IsAttack                = function(self) return nil end
-Macro.IsEquipped              = function(self) return nil end
-Macro.IsCurrentlyActive       = function(self) return nil end
-Macro.IsAutoRepeat            = function(self) return nil end
-Macro.IsUsable                = function(self) return nil end
-Macro.IsConsumableOrStackable = function(self) return nil end
-Macro.IsUnitInRange           = function(self, unit) return nil end
-Macro.SetTooltip              = function(self) return nil end
-Macro.GetSpellId              = function(self) return nil end
-
------------------------------------------------------------
---- Custom Button
-Custom.HasAction               = function(self) return true end
-Custom.GetActionText           = function(self) return "" end
-Custom.GetTexture              = function(self) return self._state_action.texture end
-Custom.GetCharges              = function(self) return nil end
-Custom.GetCount                = function(self) return 0 end
-Custom.GetCooldown             = function(self) return 0, 0, 0 end
-Custom.IsAttack                = function(self) return nil end
-Custom.IsEquipped              = function(self) return nil end
-Custom.IsCurrentlyActive       = function(self) return nil end
-Custom.IsAutoRepeat            = function(self) return nil end
-Custom.IsUsable                = function(self) return true end
-Custom.IsConsumableOrStackable = function(self) return nil end
-Custom.IsUnitInRange           = function(self, unit) return nil end
-Custom.SetTooltip              = function(self) return GameTooltip:SetText(self._state_action.tooltip) end
-Custom.GetSpellId              = function(self) return nil end
-Custom.RunCustom               = function(self, unit, button) return self._state_action.func(self, unit, button) end
-
------------------------------------------------------------
---- Update old Buttons
-if oldversion and next(lib.buttonRegistry) then
-	InitializeEventHandler()
-	for button in next, lib.buttonRegistry do
-		-- this refreshes the metatable on the button
-		Generic.UpdateAction(button, true)
-		SetupSecureSnippets(button)
-		if oldversion < 12 then
-			WrapOnClick(button)
-		end
-		if oldversion < 23 then
-			if button.overlay then
-				button.overlay:Hide()
-				ActionButton_HideOverlayGlow(button)
-				button.overlay = nil
-				UpdateOverlayGlow(button)
-			end
-		end
-	end
-end
diff --git a/Jamba/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua b/Jamba/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
index f2d5266..3fc592a 100644
--- a/Jamba/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
+++ b/Jamba/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
@@ -1,13 +1,13 @@
 --- AceConfigDialog-3.0 generates AceGUI-3.0 based windows based on option tables.
 -- @class file
 -- @name AceConfigDialog-3.0
--- @release $Id: AceConfigDialog-3.0.lua 1163 2017-08-14 14:04:39Z nevcairiel $
+-- @release $Id: AceConfigDialog-3.0.lua 1168 2017-10-01 08:05:04Z nevcairiel $

 local LibStub = LibStub
 local gui = LibStub("AceGUI-3.0")
 local reg = LibStub("AceConfigRegistry-3.0")

-local MAJOR, MINOR = "AceConfigDialog-3.0", 64
+local MAJOR, MINOR = "AceConfigDialog-3.0", 65
 local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR)

 if not AceConfigDialog then return end
@@ -740,7 +740,7 @@ local function ActivateControl(widget, event, ...)
 		else
 			validationErrorPopup(validated)
 		end
-		PlaySound(PlaySoundKitID and "igPlayerInviteDecline" or 882) -- SOUNDKIT.IG_PLAYER_INVITE_DECLINE || XXX _DECLINE is actually missing from the table
+		PlaySound(882) -- SOUNDKIT.IG_PLAYER_INVITE_DECLINE || _DECLINE is actually missing from the table
 		del(info)
 		return true
 	else
@@ -1034,6 +1034,7 @@ local function BuildGroups(group, options, path, appName, recurse)
 				entry.value = k
 				entry.text = GetOptionsMemberValue("name", v, options, path, appName)
 				entry.icon = GetOptionsMemberValue("icon", v, options, path, appName)
+				entry.iconCoords = GetOptionsMemberValue("iconCoords", v, options, path, appName)
 				entry.disabled = CheckOptionDisabled(v, options, path, appName)
 				tinsert(tree,entry)
 				if recurse and (v.childGroups or "tree") == "tree" then
diff --git a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
index 020eaf6..80fd582 100644
--- a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
+++ b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
@@ -21,7 +21,7 @@ local CreateFrame, UIParent = CreateFrame, UIParent
 Scripts
 -------------------------------------------------------------------------------]]
 local function Button_OnClick(frame)
-	PlaySound(PlaySoundKitID and "gsTitleOptionExit" or 799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
+	PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
 	frame.obj:Hide()
 end

diff --git a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
index d00470e..95544c5 100644
--- a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
+++ b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
@@ -63,7 +63,7 @@ Scripts
 -------------------------------------------------------------------------------]]
 local function Tab_OnClick(frame)
 	if not (frame.selected or frame.disabled) then
-		PlaySound(PlaySoundKitID and "igCharacterInfoTab" or 841) -- SOUNDKIT.IG_CHARACTER_INFO_TAB
+		PlaySound(841) -- SOUNDKIT.IG_CHARACTER_INFO_TAB
 		frame.obj:SelectTab(frame.value)
 	end
 end
diff --git a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
index 6c36aca..6825420 100644
--- a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
+++ b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
@@ -32,7 +32,7 @@ do
 	end

 	local function closeOnClick(this)
-		PlaySound(PlaySoundKitID and "gsTitleOptionExit" or 799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
+		PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
 		this.obj:Hide()
 	end

diff --git a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
index 55b7bc8..0a23be4 100644
--- a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
+++ b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
@@ -18,7 +18,7 @@ Scripts
 -------------------------------------------------------------------------------]]
 local function Button_OnClick(frame, ...)
 	AceGUI:ClearFocus()
-	PlaySound(PlaySoundKitID and "igMainMenuOption" or 852) -- SOUNDKIT.IG_MAINMENU_OPTION
+	PlaySound(852) -- SOUNDKIT.IG_MAINMENU_OPTION
 	frame.obj:Fire("OnClick", ...)
 end

diff --git a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
index b8426e3..b96ac59 100644
--- a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
+++ b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
@@ -60,9 +60,9 @@ local function CheckBox_OnMouseUp(frame)
 		self:ToggleChecked()

 		if self.checked then
-			PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+			PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
 		else -- for both nil and false (tristate)
-			PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOff" or 857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
+			PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
 		end

 		self:Fire("OnValueChanged", self.checked)
diff --git a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
index cb9c14c..5748e4f 100644
--- a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
+++ b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
@@ -1,4 +1,4 @@
---[[ $Id: AceGUIWidget-DropDown-Items.lua 1161 2017-08-12 14:30:16Z funkydude $ ]]--
+--[[ $Id: AceGUIWidget-DropDown-Items.lua 1167 2017-08-29 22:08:48Z funkydude $ ]]--

 local AceGUI = LibStub("AceGUI-3.0")

@@ -343,9 +343,9 @@ do
 		if self.disabled then return end
 		self.value = not self.value
 		if self.value then
-			PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+			PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
 		else
-			PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOff" or 857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
+			PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
 		end
 		UpdateToggle(self)
 		self:Fire("OnValueChanged", self.value)
diff --git a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
index 37a365b..cf0b0aa 100644
--- a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
+++ b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
@@ -1,4 +1,4 @@
---[[ $Id: AceGUIWidget-DropDown.lua 1161 2017-08-12 14:30:16Z funkydude $ ]]--
+--[[ $Id: AceGUIWidget-DropDown.lua 1167 2017-08-29 22:08:48Z funkydude $ ]]--
 local AceGUI = LibStub("AceGUI-3.0")

 -- Lua APIs
@@ -381,7 +381,7 @@ do

 	local function Dropdown_TogglePullout(this)
 		local self = this.obj
-		PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+		PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
 		if self.open then
 			self.open = nil
 			self.pullout:Close()
diff --git a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
index 6594684..b0b00f9 100644
--- a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
+++ b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
@@ -73,7 +73,7 @@ local function EditBox_OnEnterPressed(frame)
 	local value = frame:GetText()
 	local cancel = self:Fire("OnEnterPressed", value)
 	if not cancel then
-		PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+		PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
 		HideButton(self)
 	end
 end
diff --git a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
index 5946d8d..20d0887 100644
--- a/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
+++ b/Jamba/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
@@ -108,7 +108,7 @@ local function EditBox_OnEnterPressed(frame)
 	end

 	if value then
-		PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+		PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
 		self.slider:SetValue(value)
 		self:Fire("OnMouseUp", value)
 	end
diff --git a/Jamba/Libs/LibButtonGlow-1.0/LibButtonGlow-1.0.toc b/Jamba/Libs/LibButtonGlow-1.0/LibButtonGlow-1.0.toc
index 1dbd3ab..9a80be3 100644
--- a/Jamba/Libs/LibButtonGlow-1.0/LibButtonGlow-1.0.toc
+++ b/Jamba/Libs/LibButtonGlow-1.0/LibButtonGlow-1.0.toc
@@ -1,4 +1,4 @@
-## Interface: 70100
+## Interface: 70300
 ## Title: Lib: ButtonGlow-1.0
 ## Notes: Replacement for ActionButton_Show/HideOverlayGlow APIs
 ## Author: Nevcairiel
@@ -6,7 +6,7 @@
 ## X-Category: Library
 ## X-License: BSD
 ## X-Website: http://www.wowace.com/addons/libbuttonglow-1-0/
-## Version: 1.2.6
+## Version: @project-version@
 ## OptionalDeps: Masque

 LibStub\LibStub.lua
diff --git a/Jamba/Libs/LibStub/LibStub.toc b/Jamba/Libs/LibStub/LibStub.toc
new file mode 100644
index 0000000..4d9130c
--- /dev/null
+++ b/Jamba/Libs/LibStub/LibStub.toc
@@ -0,0 +1,9 @@
+## Interface: 20400
+## Title: Lib: LibStub
+## Notes: Universal Library Stub
+## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
+## X-Website: http://jira.wowace.com/browse/LS
+## X-Category: Library
+## X-License: Public Domain
+
+LibStub.lua
diff --git a/Jamba/Locales/JambaCore-Locale-enUS.lua b/Jamba/Locales/JambaCore-Locale-enUS.lua
index 991572e..bdde035 100644
--- a/Jamba/Locales/JambaCore-Locale-enUS.lua
+++ b/Jamba/Locales/JambaCore-Locale-enUS.lua
@@ -1,12 +1,12 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2015 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

 local L = LibStub("AceLocale-3.0"):NewLocale( "Jamba-Core", "enUS", true )
 --Change ME when update version
-L["Version"] = "5.3"
+L["Version"] = "5.4.1"
 --End of Changeme
 L["Slash Commands"] = true
 L["Team"] = true
diff --git a/Jamba/Locales/JambaMessage-Locale-enUS.lua b/Jamba/Locales/JambaMessage-Locale-enUS.lua
index ed282d2..a06916d 100644
--- a/Jamba/Locales/JambaMessage-Locale-enUS.lua
+++ b/Jamba/Locales/JambaMessage-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2015 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba/Locales/JambaTag-Locale-enUS.lua b/Jamba/Locales/JambaTag-Locale-enUS.lua
index bd05fc3..d130d7a 100644
--- a/Jamba/Locales/JambaTag-Locale-enUS.lua
+++ b/Jamba/Locales/JambaTag-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2015 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba/Locales/JambaTeam-Locale-enUS.lua b/Jamba/Locales/JambaTeam-Locale-enUS.lua
index 1f8843d..5313d18 100644
--- a/Jamba/Locales/JambaTeam-Locale-enUS.lua
+++ b/Jamba/Locales/JambaTeam-Locale-enUS.lua
@@ -1,6 +1,6 @@
 --[[
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2015 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 ]]--

diff --git a/Jamba/Locales/Locales.xml b/Jamba/Locales/Locales.xml
index 95b38f9..306f9f0 100644
--- a/Jamba/Locales/Locales.xml
+++ b/Jamba/Locales/Locales.xml
@@ -1,6 +1,6 @@
 <!--
 Jamba - Jafula's Awesome Multi-Boxer Assistant
-Copyright 2008 - 2015 Michael "Jafula" Miller
+Copyright 2008 - 2018 Michael "Jafula" Miller
 License: The MIT License
 -->