Quantcast

Redesign OvaleCondition so that it is a registry for script conditions.

Johnny C. Lam [11-10-13 - 00:30]
Redesign OvaleCondition so that it is a registry for script conditions.

Split out the various script conditions into their own files.

git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1140 d5049fe3-3747-40f7-a4b5-f36d6801af5f
Filename
Ovale.toc
OvaleBestAction.lua
OvaleCompile.lua
OvaleCondition.lua
compiler.pl
conditions/AfterWhiteHit.lua
conditions/ArmorSetParts.lua
conditions/BuffDamageMultiplier.lua
conditions/BuffDuration.lua
conditions/BuffExpires.lua
conditions/BuffGain.lua
conditions/BuffRemains.lua
conditions/BuffSnapshot.lua
conditions/BuffStacks.lua
conditions/BuffStealable.lua
conditions/CanCast.lua
conditions/CastTime.lua
conditions/Casting.lua
conditions/CheckBox.lua
conditions/Class.lua
conditions/Classification.lua
conditions/ComboPoints.lua
conditions/Counter.lua
conditions/CreatureFamily.lua
conditions/CreatureType.lua
conditions/Damage.lua
conditions/DamageMultiplier.lua
conditions/DamageTaken.lua
conditions/Distance.lua
conditions/Eclipse.lua
conditions/EclipseDir.lua
conditions/Enemies.lua
conditions/EnergyRegen.lua
conditions/Exists.lua
conditions/False.lua
conditions/FocusRegen.lua
conditions/GCD.lua
conditions/Glyph.lua
conditions/HasEquippedItem.lua
conditions/HasFullControl.lua
conditions/HasShield.lua
conditions/HasTrinket.lua
conditions/HasWeapon.lua
conditions/Health.lua
conditions/InCombat.lua
conditions/InFlightToTarget.lua
conditions/InRange.lua
conditions/IsAggroed.lua
conditions/IsFeared.lua
conditions/IsFriend.lua
conditions/IsIncapacitated.lua
conditions/IsInterruptible.lua
conditions/IsPVP.lua
conditions/IsRooted.lua
conditions/IsStunned.lua
conditions/ItemCharges.lua
conditions/ItemCooldown.lua
conditions/ItemCount.lua
conditions/LastDamage.lua
conditions/LastDamageMultiplier.lua
conditions/LastEstimatedDamage.lua
conditions/LastSnapshot.lua
conditions/Latency.lua
conditions/Level.lua
conditions/List.lua
conditions/ManaPercent.lua
conditions/NextTick.lua
conditions/PTR.lua
conditions/PaperDoll.lua
conditions/PetPresent.lua
conditions/Power.lua
conditions/PowerCost.lua
conditions/Present.lua
conditions/PreviousSpell.lua
conditions/RelativeLevel.lua
conditions/RemainingCastTime.lua
conditions/RuneCount.lua
conditions/Runes.lua
conditions/Speed.lua
conditions/SpellChargeCooldown.lua
conditions/SpellCharges.lua
conditions/SpellCooldown.lua
conditions/SpellData.lua
conditions/SpellKnown.lua
conditions/SpellUsable.lua
conditions/StaggerRemains.lua
conditions/Stance.lua
conditions/Stealthed.lua
conditions/Swing.lua
conditions/TalentPoints.lua
conditions/TargetIsPlayer.lua
conditions/Threat.lua
conditions/TickTime.lua
conditions/Ticks.lua
conditions/TicksAdded.lua
conditions/TicksRemain.lua
conditions/TimeInCombat.lua
conditions/TimeToMaxEnergy.lua
conditions/TimeToPowerFor.lua
conditions/TimeWithHaste.lua
conditions/TotemExpires.lua
conditions/Tracking.lua
conditions/True.lua
conditions/WeaponDamage.lua
conditions/WeaponEnchantExpires.lua
conditions/conditions.xml
diff --git a/Ovale.toc b/Ovale.toc
index def5151..3759be6 100644
--- a/Ovale.toc
+++ b/Ovale.toc
@@ -20,6 +20,7 @@ Ovale.lua

 # Modules with no dependencies
 OvaleActionBar.lua
+OvaleCondition.lua
 OvaleData.lua
 OvaleEnemies.lua
 OvaleEquipement.lua
@@ -50,8 +51,8 @@ OvaleOptions.lua
 OvaleFuture.lua
 #
 OvaleState.lua
+conditions\conditions.xml
 #
-OvaleCondition.lua
 OvaleIcone.lua
 OvaleIcone.xml
 #
diff --git a/OvaleBestAction.lua b/OvaleBestAction.lua
index 2311a13..6f2239e 100644
--- a/OvaleBestAction.lua
+++ b/OvaleBestAction.lua
@@ -413,13 +413,12 @@ local function ComputeFunction(element)
 	local timeSpan = element.timeSpan
 	timeSpan:Reset()

-	local condition = OvaleCondition.conditions[element.func]
-	if not condition then
+	if not OvaleCondition:IsCondition(element.func) then
 		Ovale:Errorf("Condition %s not found", element.func)
 		return timeSpan
 	end

-	local start, ending, value, origin, rate = condition(element.params)
+	local start, ending, value, origin, rate = OvaleCondition:EvaluateCondition(element.func, element.params)
 	if Ovale.trace then
 		local conditionCall = element.func .. "("
 		for k, v in pairs(element.params) do
diff --git a/OvaleCompile.lua b/OvaleCompile.lua
index 2d53696..7df6cfa 100644
--- a/OvaleCompile.lua
+++ b/OvaleCompile.lua
@@ -257,7 +257,7 @@ local function ParseFunction(prefix, func, params)
 		-- For the conditions that refer to player's spells, check if the spell ID
 		-- is a variant of a spell with the same name as one already in the
 		-- spellbook.  If it is, then add that variant spell ID to our spellList.
-		if OvaleCondition.spellbookConditions[func] then
+		if OvaleCondition:IsSpellbookCondition(func) then
 			if not OvaleSpellBook:IsKnownSpell(spellId) and not self_missingSpellList[spellId] then
 				local spellName
 				if type(spellId) == "number" then
@@ -817,7 +817,7 @@ local function CompileScript(text)
 	-- Not an error if a function is undefined (might be unreachable code), but complain
 	-- at run-time during compilation.
 	for p, v in pairs(self_functionCalls) do
-		if not (OVALE_FUNCTIONS[p] or self_customFunctions[p] or OvaleCondition.conditions[p]) then
+		if not (OVALE_FUNCTIONS[p] or self_customFunctions[p] or OvaleCondition:IsCondition(p)) then
 			Ovale:DebugPrintf(OVALE_UNKNOWN_FUNCTION_DEBUG, "Unknown function call: %s (node%s)", p, v.nodeId)
 		end
 	end
diff --git a/OvaleCondition.lua b/OvaleCondition.lua
index b9d44d2..c9d71cb 100644
--- a/OvaleCondition.lua
+++ b/OvaleCondition.lua
@@ -8,145 +8,131 @@
     file accompanying this program.
 --]]--------------------------------------------------------------------

+--[[----------------------------------------------------------------------------
+	Script conditions.
+
+	A script condition must have a name that is lowercase.
+
+	A script condition can return in two different ways:
+
+	(1) start, ending
+		This returns a time interval representing when the condition is true
+		and is used by conditions that return only a time interval.
+
+	(2) start, ending, value, origin, rate
+		This returns a function f(t) = value + (t - origin) * rate that is
+		valid for start < t < ending.  This return method is used by
+		conditions that return a value that is used in numerical comparisons
+		or operations.
+
+	The endpoint of a time interval must be between 0 and infinity, where
+	infinity is represented by math.huge.  Time is a value such as returned by
+	the API function GetTime().
+
+	Examples:
+
+	(1)	(0, math.huge) means the condition is always true.
+
+	(2)	nil is the empty set and means the condition is always false.
+
+	(3)	(0, math.huge, constant, 0, 0) means the condition has a constant value.
+
+	(4)	(start, ending, ending - start, start, -1) means the condition has a
+		value of f(t) = ending - t, at time t between start and ending.  This
+		basically returns how much time is left within the time interval.
+--]]----------------------------------------------------------------------------
+
 local _, Ovale = ...
 local OvaleCondition = Ovale:NewModule("OvaleCondition")
 Ovale.OvaleCondition = OvaleCondition

 --<private-static-properties>
-local LBCT = LibStub("LibBabble-CreatureType-3.0"):GetLookupTable()
-local LRC = LibStub("LibRangeCheck-2.0", true)
-local OvaleAura = Ovale.OvaleAura
-local OvaleDamageTaken = Ovale.OvaleDamageTaken
-local OvaleData = Ovale.OvaleData
-local OvaleEnemies = Ovale.OvaleEnemies
-local OvaleEquipement = Ovale.OvaleEquipement
-local OvaleFuture = Ovale.OvaleFuture
-local OvaleGUID = Ovale.OvaleGUID
-local OvaleLatency = Ovale.OvaleLatency
-local OvalePaperDoll = Ovale.OvalePaperDoll
-local OvalePower = Ovale.OvalePower
-local OvaleSpellBook = Ovale.OvaleSpellBook
-local OvaleSpellDamage = Ovale.OvaleSpellDamage
-local OvaleStance = Ovale.OvaleStance
-local OvaleState = Ovale.OvaleState
-local OvaleSwing = Ovale.OvaleSwing
-
-local floor = floor
-local pairs = pairs
-local select = select
-local tostring = tostring
+local type = type
 local wipe = table.wipe
-local API_GetBuildInfo = GetBuildInfo
-local API_GetItemCooldown = GetItemCooldown
-local API_GetItemCount = GetItemCount
-local API_GetNumTrackingTypes = GetNumTrackingTypes
-local API_GetSpellCharges = GetSpellCharges
-local API_GetSpellInfo = GetSpellInfo
-local API_GetTotemInfo = GetTotemInfo
-local API_GetTrackingInfo = GetTrackingInfo
-local API_GetUnitSpeed = GetUnitSpeed
-local API_GetWeaponEnchantInfo = GetWeaponEnchantInfo
-local API_HasFullControl = HasFullControl
-local API_IsHarmfulSpell = IsHarmfulSpell
-local API_IsHelpfulSpell = IsHelpfulSpell
-local API_IsSpellInRange = IsSpellInRange
-local API_IsStealthed = IsStealthed
-local API_IsUsableSpell = IsUsableSpell
-local API_UnitCastingInfo = UnitCastingInfo
-local API_UnitChannelInfo = UnitChannelInfo
-local API_UnitClass = UnitClass
-local API_UnitClassification = UnitClassification
-local API_UnitCreatureFamily = UnitCreatureFamily
-local API_UnitCreatureType = UnitCreatureType
-local API_UnitDebuff = UnitDebuff
-local API_UnitDetailedThreatSituation = UnitDetailedThreatSituation
-local API_UnitExists = UnitExists
-local API_UnitHealth = UnitHealth
-local API_UnitHealthMax = UnitHealthMax
-local API_UnitIsDead = UnitIsDead
-local API_UnitIsFriend = UnitIsFriend
-local API_UnitIsPVP = UnitIsPVP
-local API_UnitIsUnit = UnitIsUnit
-local API_UnitLevel = UnitLevel
-local API_UnitPower = UnitPower
-local API_UnitPowerMax = UnitPowerMax
-local API_UnitStagger = UnitStagger
-local SPELL_POWER_MANA = SPELL_POWER_MANA

--- static property for GetRunesCooldown(), indexed by rune name
-local self_runes = {}
+-- Table of script conditions.
+self_condition = {}
+-- List of script conditions that refer to a castable spell from the player's spellbook.
+self_spellbookCondition = {}
+do
+	-- Spell(spellId) can be used as a condition instead of an action.
+	self_spellbookCondition["spell"] = true
+end
+--</private-static-properties>

--- static properties for TimeToDie(), indexed by unit ID
-local self_lastTTDTime = {}
-local self_lastTTDHealth = {}
-local self_lastTTDguid = {}
-local self_lastTTDdps = {}
+--<public-static-properties>
+--[[
+	The actual target referenced when the "target" parameter is used in a condition.
+	This is to support setting a different target in an AddIcon "target" parameter,
+	e.g., target=focus, while re-using the same script.
+--]]
+OvaleCondition.defaultTarget = "target"
+OvaleCondition.Compare = nil
+OvaleCondition.ParseCondition = nil
+OvaleCondition.ParseRuneCondition = nil
+OvaleCondition.TestBoolean = nil
+OvaleCondition.TestValue = nil
+--</public-static-properties>

--- static property for conditions that use GetAura()
-local self_auraFound = {}
+--<public-static-methods>
+function OvaleCondition:RegisterCondition(name, isSpellbookCondition, func, arg)
+	if arg then
+		if type(func) == "string" then
+			func = arg[func]
+		end
+		self_condition[name] = function(...) func(arg, ...) end
+	else
+		self_condition[name] = func
+	end
+	if isSpellbookCondition then
+		self_spellbookCondition[name] = true
+	end
+end

-local OVALE_RUNETYPE =
-{
-	blood = 1,
-	unholy = 2,
-	frost = 3,
-	death = 4
-}
+function OvaleCondition:UnregisterCondition(name)
+	self_condition[name] = nil
+end

-local OVALE_TOTEMTYPE =
-{
-	-- Death Knights
-	ghoul = 1,
-	-- Monks
-	statue = 1,
-	-- Shamans
-	fire = 1,
-	earth = 2,
-	water = 3,
-	air = 4
-}
+function OvaleCondition:IsCondition(name)
+	return (self_condition[name] ~= nil)
+end

-local DEFAULT_CRIT_CHANCE = 0.01
+function OvaleCondition:IsSpellbookCondition(name)
+	return (self_spellbookCondition[name] ~= nil)
+end

--- Comparison words used in conditions, e.g., ComboPoints(more 4).
-local OVALE_COMPARATOR = {
-	["atLeast"] = true,
-	["atMost"] = true,
-	["equal"] = true,
-	["less"] = true,
-	["more"] = true,
-}
---</private-static-properties>
+function OvaleCondition:EvaluateCondition(name, ...)
+	return self_condition[name](...)
+end

---<private-static-methods>
-local function IsSameSpell(spellIdA, spellIdB, spellNameB)
-	if spellIdB then
-		return spellIdA == spellIdB
-	elseif spellIdA and spellNameB then
-		return OvaleSpellBook:GetSpellName(spellIdA) == spellNameB
-	else
-		return false
+OvaleCondition.ParseCondition = function(condition, defaultTarget)
+	defaultTarget = defaultTarget or "player"
+	local target = condition.target and condition.target or defaultTarget
+	if target == "target" then
+		target = OvaleCondition.defaultTarget
 	end
-end

-local function TimeWithHaste(time1, haste)
-	if not time1 then
-		time1 = 0
+	local filter
+	if condition.filter then
+		if condition.filter == "debuff" then
+			filter = "HARMFUL"
+		elseif condition.filter == "buff" then
+			filter = "HELPFUL"
+		end
 	end
-	if not haste then
-		return time1
-	elseif haste == "spell" then
-		return time1 / OvalePaperDoll:GetSpellHasteMultiplier()
-	elseif haste == "melee" then
-		return time1 / OvalePaperDoll:GetMeleeHasteMultiplier()
-	else
-		Ovale:Logf("Unknown haste parameter haste=%s", haste)
-		return time1
+
+	local mine = true
+	if condition.any and condition.any == 1 then
+		mine = false
+	elseif condition.mine and condition.mine ~= 1 then
+		mine = false
 	end
+
+	return target, filter, mine
 end

 -- Returns whether "a" matches "yesno".
-local function TestBoolean(a, yesno)
+OvaleCondition.TestBoolean = function(a, yesno)
 	if not yesno or yesno == "yes" then
 		if a then
 			return 0, math.huge
@@ -162,22 +148,28 @@ end
 -- Returns either an "Ovale value" or a boolean, depending on whether "comparator" is given.
 -- An "Ovale value" is a quintuplet (start, ending, value, origin, rate) that determines a
 -- linear function A(t) = value + (t - origin)*rate, with domain (start, ending).
-local function TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
+OvaleCondition.TestValue = function(start, ending, value, origin, rate, comparator, limit)
 	--[[
-		                     A(t) = limit
+							 A(t) = limit
 		value + (t - origin)*rate = limit
-		        (t - origin)*rate = limit - value
+				(t - origin)*rate = limit - value
 	--]]
 	if not value or not origin or not rate then
 		return nil
-	elseif not comparator then
+	end
+
+	start = start and start or 0
+	ending = (start and ending) and ending or math.huge
+
+	if not comparator then
 		if start < ending then
 			return start, ending, value, origin, rate
 		else
 			return 0, math.huge, 0, 0, 0
 		end
-	elseif not OVALE_COMPARATOR[comparator] then
-		Ovale:Errorf("unknown compare term %s (should be less, equal, or more)", comparator)
+	elseif comparator ~= "atLeast" and comparator ~= "atMost" and comparator ~= "equal"
+			and comparator ~= "less" and comparator ~= "more" then
+		Ovale:Errorf("unknown compare term %s", comparator)
 	elseif not limit then
 		Ovale:Errorf("comparator %s missing limit", comparator)
 	elseif rate == 0 then
@@ -206,3989 +198,7 @@ local function TestOvaleValue(start, ending, value, origin, rate, comparator, li
 	return nil
 end

-local function Compare(value, comparator, limit)
-	return TestOvaleValue(0, math.huge, value, 0, 0, comparator, limit)
-end
-
-local function TestValue(comparator, limit, value, origin, rate)
-	return TestOvaleValue(0, math.huge, value, origin, rate, comparator, limit)
-end
-
-local function GetFilter(condition)
-	if condition.filter then
-		if condition.filter == "debuff" then
-			return "HARMFUL"
-		elseif condition.filter == "buff" then
-			return "HELPFUL"
-		end
-	end
-	return nil
-end
-
-local function GetMine(condition)
-	if condition.any then
-		if condition.any == 1 then
-			return false
-		else
-			return true
-		end
-	elseif condition.mine then
-		-- Use of "mine=1" is deprecated.
-		if condition.mine == 1 then
-			return true
-		else
-			return false
-		end
-	end
-	return true
-end
-
-local function GetTarget(condition, defaultTarget)
-	local target = condition.target
-	defaultTarget = defaultTarget or "player"
-	if not target then
-		return defaultTarget
-	elseif target == "target" then
-		return OvaleCondition.defaultTarget
-	else
-		return target
-	end
-end
-
-local function GetRuneCount(type, death)
-	local ret = 0
-	local origin = nil
-	local rate = nil
-	type = OVALE_RUNETYPE[type]
-	for i=1,6 do
-		local rune = OvaleState.state.rune[i]
-		if rune and (rune.type == type or (rune.type == 4 and death==1)) then
-			if rune.cd > OvaleState.currentTime then
-				if not origin or rune.cd < origin then
-					origin = rune.cd
-					rate = 1/rune.duration
-				end
-			else
-				ret = ret + 1
-			end
-		end
-	end
-	if origin then
-		return ret + 1, origin, rate
-	else
-		return ret, 0, 0
-	end
-end
-
-local function GetRunesCooldown(condition)
-	for k in pairs(OVALE_RUNETYPE) do
-		self_runes[k] = 0
-	end
-
-	local k = 1
-	while true do
-		local type = condition[2 * k - 1]
-		if not OVALE_RUNETYPE[type] then break end
-		self_runes[type] = self_runes[type] + condition[2 * k]
-		k = k + 1
-	end
-	return OvaleState:GetRunesCooldown(self_runes.blood, self_runes.frost, self_runes.unholy, self_runes.death, condition.nodeath)
-end
-
--- Front-end for OvaleState:GetAura() using condition parameters.
--- return start, ending, stacks, gain
-local function GetAura(condition, auraFound)
-	local unitId = GetTarget(condition)
-	local spellId = condition[1]
-	local filter = GetFilter(condition)
-	local mine = GetMine(condition)
-
-	if not spellId then
-		Ovale:Log("GetAura: nil spellId")
-		return nil
-	end
-	local start, ending, stacks, gain = OvaleState:GetAura(unitId, spellId, filter, mine, auraFound)
-
-	if not start then
-		Ovale:Logf("GetAura: aura %s not found on %s filter=%s mine=%s", spellId, unitId, filter, mine)
-		return nil
-	end
-	local conditionStacks = condition.stacks or 1
-	if stacks and stacks < conditionStacks then
-		Ovale:Logf("GetAura: aura %s found on %s but stacks %d < %d", spellId, unitId, stacks, conditionStacks)
-		return nil
-	end
-	Ovale:Logf("GetAura: aura %s found on %s start=%s ending=%s stacks=%s/%d", spellId, unitId, start, ending, stacks, conditionStacks)
-	return start, ending, stacks, gain
-end
-
--- Front-end for OvaleState:GetAuraOnAnyTarget() using condition parameters.
--- return start, ending, count
-local function GetAuraOnAnyTarget(condition, excludingUnit)
-	local spellId = condition[1]
-	local filter = GetFilter(condition)
-	local mine = GetMine(condition)
-	if excludingUnit then
-		excludingUnit = OvaleGUID:GetGUID(excludingUnit)
-	end
-	if not spellId then
-		Ovale:Log("GetAura: nil spellId")
-		return nil
-	end
-	local start, ending, count = OvaleState:GetAuraOnAnyTarget(spellId, filter, mine, excludingUnit)
-
-	if not start then
-		Ovale:Logf("GetAuraOnAnyTarget: aura %s not found, filter=%s mine=%s excludingUnit=%s", spellId, filter, mine, excludingUnit)
-		return nil
-	end
-	Ovale:Logf("GetAuraOnAnyTarget: aura %s found, start=%s ending=%s count=%d", spellId, start, ending, stacks, count)
-	return start, ending, count
-end
-
--- Return the non-critical-strike damage of a spell, given the player's current stats.
-local function GetDamage(spellId)
-	-- TODO: Use target's debuffs in this calculation.
-	local ap = OvalePaperDoll.stat.attackPower or 0
-	local sp = OvalePaperDoll.stat.spellBonusDamage or 0
-	local mh = OvalePaperDoll.stat.mainHandWeaponDamage or 0
-	local oh = OvalePaperDoll.stat.offHandWeaponDamage or 0
-	local bdm = OvalePaperDoll.stat.baseDamageMultiplier or 1
-	local dm = OvaleState:GetDamageMultiplier(spellId) or 1
-	local combo = OvaleState.state.combo or 1
-	return OvaleData:GetDamage(spellId, ap, sp, mh, oh, combo) * bdm * dm
-end
-
--- Return the maximum power of the given power type on the target.
-local function MaxPower(target, powerType)
-	local maxi
-	if target == "player" then
-		maxi = OvalePower.maxPower[powerType]
-	else
-		local powerInfo = OvalePower.POWER_INFO[powerType]
-		maxi = API_UnitPowerMax(target, powerInfo.id, powerInfo.segments)
-	end
-	return maxi
-end
-
--- Returns:
---     Estimated number of seconds before the specified unit reaches zero health
---     Unit's current health
---     Unit's maximum health
-local function TimeToDie(unitId)
-	if self_lastTTDguid[unitId] ~= OvaleGUID:GetGUID(unitId) then
-		self_lastTTDguid[unitId] = OvaleGUID:GetGUID(unitId)
-		self_lastTTDTime[unitId] = nil
-		if self_lastTTDHealth[unitId] then
-			wipe(self_lastTTDHealth[unitId])
-		else
-			self_lastTTDHealth[unitId] = {}
-		end
-		self_lastTTDdps[unitId] = nil
-	end
-	local timeToDie
-	local health = API_UnitHealth(unitId)
-	local maxHealth = API_UnitHealthMax(unitId) or 1
-	if health then
-		Ovale:Logf("target = %s, health = %d, maxHealth = %d", self_lastTTDguid[unitId], health, maxHealth)
-	end
-	if maxHealth < health then
-		maxHealth = health
-	end
-	-- Clamp maxHealth to always be at least 1.
-	if maxHealth < 1 then
-		maxHealth = 1
-	end
-	if health == 0 then
-		timeToDie = 0
-	elseif maxHealth <= 2 then
-		Ovale:Log("Training Dummy, return in the future")
-		timeToDie = math.huge
-	else
-		local now = floor(OvaleState.maintenant)
-		if (not self_lastTTDTime[unitId] or self_lastTTDTime[unitId] < now) and self_lastTTDguid[unitId] then
-			self_lastTTDTime[unitId] = now
-			local mod10, prevHealth
-			for delta = 10, 1, -1 do
-				mod10 = (now - delta) % 10
-				prevHealth = self_lastTTDHealth[unitId][mod10]
-				if delta == 10 then
-					self_lastTTDHealth[unitId][mod10] = health
-				end
-				if prevHealth and prevHealth > health then
-					self_lastTTDdps[unitId] = (prevHealth - health) / delta
-					Ovale:Logf("prevHealth = %d, health = %d, delta = %d, dps = %d", prevHealth, health, delta, self_lastTTDdps[unitId])
-					break
-				end
-			end
-		end
-		local dps = self_lastTTDdps[unitId]
-		if dps and dps > 0 then
-			timeToDie = health / dps
-		else
-			timeToDie = math.huge
-		end
-	end
-	-- Clamp time to die at a finite number.
-	if timeToDie == math.huge then
-		-- Return time to die in the far-off future (one week).
-		timeToDie = 3600 * 24 * 7
-	end
-	return timeToDie, health, maxHealth
-end
---</private-static-methods>
-
---<public-static-properties>
-
--- The actual target referenced when the "target" parameter is used in a condition.
--- This is to support setting a different target in an AddIcon "target" parameter,
--- e.g., target=focus, while re-using the same script.
-OvaleCondition.defaultTarget = "target"
-
---[[----------------------------------------------------------------------------
-	Script conditions.
-
-	A script condition must have a name that is lowercase.  Script function
-	names are always converted to lowercase before comparing against the
-	conditions in the OvaleCondition.conditions table.
-
-	A script condition can return in two different ways:
-
-	(1) start, ending
-		This returns a time interval representing when the condition is true
-		and is used by conditions that return only a time interval.
-
-	(2) start, ending, value, origin, rate
-		This returns a function f(t) = value + (t - origin) * rate that is
-		valid for start < t < ending.  This return method is used by
-		conditions that return a value that is used in numerical comparisons
-		or operations.
-
-	The endpoint of a time interval must be between 0 and infinity, where
-	infinity is represented by math.huge.  Time is a value such as returned by
-	the API function GetTime().
-
-	Examples:
-
-	(1)	(0, math.huge) means the condition is always true.
-
-	(2)	nil is the empty set and means the condition is always false.
-
-	(3)	(0, math.huge, constant, 0, 0) means the condition has a constant value.
-
-	(4)	(start, ending, ending - start, start, -1) means the condition has a
-		value of f(t) = ending - t, at time t between start and ending.  This
-		basically returns how much time is left within the time interval.
---]]----------------------------------------------------------------------------
-
-OvaleCondition.conditions = {}
--- List of script conditions that refer to a castable spell from the player's spellbook.
-OvaleCondition.spellbookConditions = {}
-
-do
-	-- Spell(spellId) can be used as a condition instead of an action.
-	OvaleCondition.spellbookConditions.spell = true
-end
-
-	-- Test if a white hit just occured
-	-- 1 : maximum time after a white hit
-	-- Not useful anymore. No widely used spell reset swing timer anyway
-	--[[AfterWhiteHit = function(condition)
-		local debut = OvaleSwing.starttime
-		local fin = OvaleSwing.duration + debut
-		local maintenant = API_GetTime()
-		if (maintenant-debut<condition[1]) then
-			return 0
-		elseif (maintenant<fin-0.1) then
-			return fin-maintenant
-		else
-			return 0.1
-		end
-	end,]]
-
---- Get the current agility of the player.
--- @name Agility
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current agility.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.agility = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvalePaperDoll.stat.agility, comparator, limit)
-end
-
---- Get how many pieces of an armor set, e.g., Tier 14 set, are equipped by the player.
--- @name ArmorSetParts
--- @paramsig number or boolean
--- @param name The name of the armor set.
---     Valid names: T11, T12, T13, T14, T15.
---     Valid names for hybrid classes: append _caster, _heal, _melee, _tank.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of pieces of the named set that are equipped by the player.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if ArmorSetParts(T13) >=2 and target.HealthPercent() <60
---     Spell(ferocious_bite)
--- if ArmorSetParts(T13 more 1) and TargetHealthPercent(less 60)
---     Spell(ferocious_bite)
-
-OvaleCondition.conditions.armorsetparts = function(condition)
-	local armorSet, comparator, limit = condition[1], condition[2], condition[3]
-	return Compare(OvaleEquipement:GetArmorSetCount(armorSet), comparator, limit)
-end
-
---- Get the current attack power of the player.
--- @name AttackPower
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current attack power.
--- @return A boolean value for the result of the comparison.
--- @see LastAttackPower
--- @usage
--- if AttackPower() >10000 Spell(rake)
--- if AttackPower(more 10000) Spell(rake)
-
-OvaleCondition.conditions.attackpower = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvalePaperDoll.stat.attackPower, comparator, limit)
-end
-
---- Get the value of a buff as a number.  Not all buffs return an amount.
--- @name BuffAmount
--- @paramsig number
--- @param id The spell ID of the aura or the name of a spell list.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
---     Defaults to any=0.
---     Valid values: 0, 1.
--- @param value Optional. Sets which aura value to return from UnitAura().
---     Defaults to value=1.
---     Valid values: 1, 2, 3.
--- @return The value of the buff as a number.
--- @see DebuffAmount
--- @see TickValue
--- @usage
--- if DebuffAmount(stagger) >10000 Spell(purifying_brew)
--- if DebuffAmount(stagger more 10000) Spell(purifying_brew)
-
-OvaleCondition.conditions.buffamount = function(condition)
-	self_auraFound.value1, self_auraFound.value2, self_auraFound.value3 = nil, nil, nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local value = condition.value or 1
-	local amount
-	if value == 1 then
-		amount = self_auraFound.value1 or 0
-	elseif value == 2 then
-		amount = self_auraFound.value2 or 0
-	elseif value == 3 then
-		amount = self_auraFound.value3 or 0
-	else
-		amount = 0
-	end
-	return Compare(amount, comparator, limit)
-end
-OvaleCondition.conditions.debuffamount = OvaleCondition.conditions.buffamount
-OvaleCondition.conditions.tickvalue = OvaleCondition.conditions.buffamount
-
---- Get the player's attack power at the time the given aura was applied on the target.
--- @name BuffAttackPower
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The attack power.
--- @return A boolean value for the result of the comparison.
--- @see DebuffAttackPower
--- @usage
--- if AttackPower() >target.DebuffAttackPower(rake) Spell(rake)
-
-OvaleCondition.conditions.buffattackpower = function(condition)
-	self_auraFound.attackPower = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local attackPower = self_auraFound.attackPower or 0
-	return TestOvaleValue(start, ending, attackPower, start, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffattackpower = OvaleCondition.conditions.buffattackpower
-
---- Get the player's combo points for the given aura at the time the aura was applied on the target.
--- @name BuffComboPoints
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of combo points.
--- @return A boolean value for the result of the comparison.
--- @see DebuffComboPoints
--- @usage
--- if target.DebuffComboPoints(rip) <5 Spell(rip)
-
-OvaleCondition.conditions.buffcombopoints = function(condition)
-	self_auraFound.comboPoints = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local comboPoints = self_auraFound.comboPoints or 1
-	return TestOvaleValue(start, ending, comboPoints, start, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffcombopoints = OvaleCondition.conditions.buffcombopoints
-
---- Get the total count of the given aura applied by the player across all targets.
--- @name BuffCount
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The total aura count.
--- @return A boolean value for the result of the comparison.
--- @see DebuffCount
-
-OvaleCondition.conditions.buffcount = function(condition)
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending, count = GetAuraOnAnyTarget(condition)
-	return TestOvaleValue(start, ending, count, start, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffcount = OvaleCondition.conditions.buffcount
-
---- Get the player's damage multiplier for the given aura at the time the aura was applied on the target.
--- @name BuffDamageMultiplier
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The damage multiplier.
--- @return A boolean value for the result of the comparison.
--- @see DebuffDamageMultiplier
--- @usage
--- if target.DebuffDamageMultiplier(rake) <1 Spell(rake)
-
-OvaleCondition.conditions.buffdamagemultiplier = function(condition)
-	self_auraFound.baseDamageMultiplier = nil
-	self_auraFound.damageMultiplier = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local baseDamageMultiplier = self_auraFound.baseDamageMultiplier or 1
-	local damageMultiplier = self_auraFound.damageMultiplier or 1
-	return TestOvaleValue(start, ending, baseDamageMultiplier * damageMultiplier, start, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffdamagemultiplier = OvaleCondition.conditions.buffdamagemultiplier
-
---- Get the total duration of the aura from when it was first applied to when it ended.
--- @name BuffDuration
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The total duration of the aura.
--- @return A boolean value for the result of the comparison.
--- @see DebuffDuration
-
-OvaleCondition.conditions.buffduration = function(condition)
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition)
-	start = start or 0
-	ending = ending or math.huge
-	return TestOvaleValue(start, ending, ending - start, 0, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffduration = OvaleCondition.conditions.buffduration
-
---- Test if an aura is expired, or will expire after a given number of seconds.
--- @name BuffExpires
--- @paramsig boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param seconds Optional. The maximum number of seconds before the buff should expire.
---     Defaults to 0 (zero).
--- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
---     Defaults to any=0.
---     Valid values: 0, 1.
--- @param haste Optional. Sets whether "seconds" should be lengthened or shortened due to haste.
---     Defaults to haste=none.
---     Valid values: melee, spell, none.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @see DebuffExpires
--- @usage
--- if BuffExpires(stamina any=1)
---     Spell(power_word_fortitude)
--- if target.DebuffExpires(rake 2)
---     Spell(rake)
-
-OvaleCondition.conditions.buffexpires = function(condition)
-	local auraId, seconds = condition[1], condition[2]
-	seconds = seconds or 0
-
-	local start, ending = GetAura(condition)
-	if not start or not ending then
-		return TestBoolean(true)
-	end
-
-	local timeBefore = TimeWithHaste(seconds, condition.haste)
-	Ovale:Logf("timeBefore = %s, ending = %s", timeBefore, ending)
-	if ending - timeBefore <= start then
-		return start, math.huge
-	else
-		return ending - timeBefore, math.huge
-	end
-end
-OvaleCondition.conditions.debuffexpires = OvaleCondition.conditions.buffexpires
-
---- Get the time elapsed since the aura was last gained on the target.
--- @paramsig number or boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
---     Defaults to any=0.
---     Valid values: 0, 1.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @see DebuffGain
-
-OvaleCondition.conditions.buffgain = function(condition)
-	if true then
-		Ovale:Error("not implemented")
-		return nil
-	end
-	self_auraFound.gain = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local gain = self_auraFound.gain or 0
-	return TestOvaleValue(gain, math.huge, 0, gain, 1, comparator, limit)
-end
-OvaleCondition.conditions.debuffgain = OvaleCondition.conditions.buffgain
-
---- Get the player's mastery effect at the time the given aura was applied on the target.
--- @name BuffMastery
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The mastery effect.
--- @return A boolean value for the result of the comparison.
--- @see DebuffMastery
--- @usage
--- if Mastery() >target.DebuffMastery(rip) Spell(rip)
-
-OvaleCondition.conditions.buffmastery = function(condition)
-	self_auraFound.masteryEffect = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local masteryEffect = self_auraFound.masteryEffect or 0
-	return TestOvaleValue(start, ending, masteryEffect, start, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffmastery = OvaleCondition.conditions.buffmastery
-
---- Get the player's melee critical strike chance at the time the given aura was applied on the target.
--- @name BuffMeleeCritChance
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
---     Defaults to unlimited=0.
---     Valid values: 0, 1
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The critical strike chance.
--- @return A boolean value for the result of the comparison.
--- @see DebuffMeleeCritChance
--- @usage
--- if MeleeCritChance() >target.DebuffMeleeCritChance(rake) Spell(rake)
-
-OvaleCondition.conditions.buffmeleecritchance = function(condition)
-	self_auraFound.meleeCrit = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local critChance = self_auraFound.meleeCrit or DEFAULT_CRIT_CHANCE
-	if condition.unlimited ~= 1 and critChance > 100 then
-		critChance = 100
-	end
-	return TestOvaleValue(start, ending, critChance, start, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffmeleecritchance = OvaleCondition.conditions.buffmeleecritchance
-
---- Test if an aura is present or if the remaining time on the aura is more than the given number of seconds.
--- @name BuffPresent
--- @paramsig boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param seconds Optional. The mininum number of seconds before the buff should expire.
---     Defaults to 0 (zero).
--- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
---     Defaults to any=0.
---     Valid values: 0, 1.
--- @param haste Optional. Sets whether "seconds" should be lengthened or shortened due to haste.
---     Defaults to haste=none.
---     Valid values: melee, spell, none.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @see DebuffPresent
--- @usage
--- if not BuffPresent(stamina any=1)
---     Spell(power_word_fortitude)
--- if not target.DebuffPresent(rake 2)
---     Spell(rake)
-
-OvaleCondition.conditions.buffpresent = function(condition)
-	local auraId, seconds = condition[1], condition[2]
-	seconds = seconds or 0
-
-	local start, ending = GetAura(condition)
-	if not start or not ending then
-		return nil
-	end
-
-	local timeBefore = TimeWithHaste(seconds, condition.haste)
-	if ending - timeBefore <= start then
-		return nil
-	else
-		return start, ending - timeBefore
-	end
-end
-OvaleCondition.conditions.debuffpresent = OvaleCondition.conditions.buffpresent
-
---- Get the player's ranged attack power at the time the given aura was applied on the target.
--- @name BuffRangedAttackPower
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The ranged attack power.
--- @return A boolean value for the result of the comparison.
--- @see DebuffRangedAttackPower
--- @usage
--- if RangedAttackPower() >target.DebuffRangedAttackPower(serpent_sting_dot)
---     Spell(serpent_sting)
-
-OvaleCondition.conditions.buffrangedattackpower = function(condition)
-	self_auraFound.rangedAttackPower = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local rangedAttackPower = self_auraFound.rangedAttackPower or 0
-	return TestOvaleValue(start, ending, rangedAttackPower, start, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffrangedattackpower = OvaleCondition.conditions.buffrangedattackpower
-
---- Get the remaining time in seconds on an aura.
--- @name BuffRemains
--- @paramsig number or boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
---     Defaults to any=0.
---     Valid values: 0, 1.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of seconds remaining on the aura.
--- @return A boolean value for the result of the comparison.
--- @see DebuffRemains
--- @usage
--- if BuffRemains(slice_and_dice) <2
---     Spell(slice_and_dice)
-
-OvaleCondition.conditions.buffremains = function(condition)
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition)
-	if not start or not ending then
-		return Compare(0, comparator, limit)
-	else
-		return TestOvaleValue(start, ending, ending - start, start, -1, comparator, limit)
-	end
-end
-OvaleCondition.conditions.debuffremains = OvaleCondition.conditions.buffremains
-
---- Get the player's ranged critical strike chance at the time the given aura was applied on the target.
--- @name BuffRangedCritChance
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
---     Defaults to unlimited=0.
---     Valid values: 0, 1
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The critical strike chance.
--- @return A boolean value for the result of the comparison.
--- @see DebuffRangedCritChance
--- @usage
--- if RangedCritChance() >target.DebuffRangedCritChance(serpent_sting_dot)
---     Spell(serpent_sting)
-
-OvaleCondition.conditions.buffrangedcritchance = function(condition)
-	self_auraFound.rangedCrit = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local critChance = self_auraFound.rangedCrit or DEFAULT_CRIT_CHANCE
-	if condition.unlimited ~= 1 and critChance > 100 then
-		critChance = 100
-	end
-	return TestOvaleValue(start, ending, critChance, start, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffrangedcritchance = OvaleCondition.conditions.buffrangedcritchance
-
---- Get the player's spell critical strike chance at the time the given aura was applied on the target.
--- @name BuffSpellCritChance
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
---     Defaults to unlimited=0.
---     Valid values: 0, 1
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The critical strike chance.
--- @return A boolean value for the result of the comparison.
--- @see DebuffSpellCritChance
--- @usage
--- if SpellCritChance() >target.DebuffSpellCritChance(moonfire) Spell(moonfire)
-
-OvaleCondition.conditions.buffspellcritchance = function(condition)
-	self_auraFound.spellCrit = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local critChance = self_auraFound.spellCrit or DEFAULT_CRIT_CHANCE
-	if condition.unlimited ~= 1 and critChance > 100 then
-		critChance = 100
-	end
-	return TestOvaleValue(start, ending, critChance, start, 0, comparator, limit)
+OvaleCondition.Compare = function(value, comparator, limit)
+	return OvaleCondition.TestValue(0, math.huge, value, 0, 0, comparator, limit)
 end
-OvaleCondition.conditions.debuffspellcritchance = OvaleCondition.conditions.buffspellcritchance
-
---- Get the player's spell haste at the time the given aura was applied on the target.
--- @name BuffSpellHaste
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param id The aura spell ID.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The percent increase to spell haste.
--- @return A boolean value for the result of the comparison.
--- @see DebuffSpellHaste
--- @usage
--- if SpellHaste() >target.DebuffSpellHaste(moonfire) Spell(moonfire)
-
-OvaleCondition.conditions.buffspellhaste = function(condition)
-	self_auraFound.spellHaste = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local spellHaste = self_auraFound.spellHaste or 0
-	return TestOvaleValue(start, ending, spellHaste, start, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffspellhaste = OvaleCondition.conditions.buffspellhaste
-
---- Get the player's spellpower at the time the given aura was applied on the target.
--- @name BuffSpellpower
--- @paramsig number or boolean
--- @param id The aura spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The spellpower.
--- @return A boolean value for the result of the comparison.
--- @see DebuffSpellpower
--- @usage
--- if Spellpower() >target.DebuffSpellpower(moonfire) Spell(moonfire)
-
-OvaleCondition.conditions.buffspellpower = function(condition)
-	self_auraFound.spellBonusDamage = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local spellBonusDamage = self_auraFound.spellBonusDamage or 0
-	return TestOvaleValue(start, ending, spellBonusDamage, start, 0, comparator, limit)
-end
-OvaleCondition.conditions.debuffspellpower = OvaleCondition.conditions.buffspellpower
-
---- Get the number of stacks of an aura on the target.
--- @name BuffStacks
--- @paramsig number or boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
---     Defaults to any=0.
---     Valid values: 0, 1.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of stacks of the aura.
--- @return A boolean value for the result of the comparison.
--- @see DebuffStacks
--- @usage
--- if BuffStacks(pet_frenzy any=1) ==5
---     Spell(focus_fire)
--- if target.DebuffStacks(weakened_armor) <3
---     Spell(faerie_fire)
-
-OvaleCondition.conditions.buffstacks = function(condition)
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending, stacks = GetAura(condition)
-	if not start or not ending then
-		return Compare(0, comparator, limit)
-	else
-		stacks = stacks or 0
-		return TestOvaleValue(start, ending, stacks, 0, 0, comparator, limit)
-	end
-end
-OvaleCondition.conditions.debuffstacks = OvaleCondition.conditions.buffstacks
-
---- Test if there is a stealable buff on the target.
--- @name BuffStealable
--- @paramsig boolean
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- if target.BuffStealable()
---     Spell(spellsteal)
-
-OvaleCondition.conditions.buffstealable = function(condition)
-	-- TODO: This should really be checked only against OvaleState.
-	local target = GetTarget(condition)
-	return OvaleAura:GetStealable(target)
-end
-
---- Get the current number of Burning Embers for destruction warlocks.
--- @name BurningEmbers
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of Burning Embers.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if BurningEmbers() >10 Spell(chaos_bolt)
--- if BurningEmbers(more 10) Spell(chaos_bolt)
-
-OvaleCondition.conditions.burningembers = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local value, origin, rate = OvaleState.state.burningembers, OvaleState.currentTime, OvaleState.powerRate.burningembers
-	local start, ending = OvaleState.currentTime, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-
---- Check if the player can cast the given spell (not on cooldown).
--- @name CanCast
--- @paramsig boolean
--- @param id The spell ID to check.
--- @return True if the spell cast be cast; otherwise, false.
-
-OvaleCondition.conditions.cancast = function(condition)
-	local spellId = condition[1]
-	local actionCooldownStart, actionCooldownDuration = OvaleState:GetComputedSpellCD(spellId)
-	return actionCooldownStart + actionCooldownDuration, math.huge
-end
-
---- Test if the target is casting the given spell.
--- The spell may be specified either by spell ID, localized spell name, spell list name (as defined in SpellList),
--- "harmful" for any harmful spell, or "helpful" for any helpful spell.
--- @name Casting
--- @paramsig boolean
--- @param spell The spell to check.
---     Valid values: spell ID, spell name, spell list name, harmful, helpful
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- Define(maloriak_release_aberrations 77569)
--- if target.Casting(maloriak_release_aberrations)
---     Spell(pummel)
-
-OvaleCondition.conditions.casting = function(condition)
-	local spellId = condition[1]
-	local target = GetTarget(condition)
-	local start, ending, castSpellId, castSpellName, _
-	if target == "player" then
-		start = OvaleState.startCast
-		ending = OvaleState.endCast
-		castSpellId = OvaleState.currentSpellId
-	else
-		castSpellName, _, _, _, start, ending = API_UnitCastingInfo(target)
-		if not castSpellName then
-			castSpellName, _, _, _, start, ending = API_UnitChannelInfo(target)
-		end
-	end
-	if not castSpellId and not castSpellName then
-		return nil
-	end
-	if not spellId then
-		return start, ending
-	elseif type(spellId) == "number" then
-		if IsSameSpell(spellId, castSpellId, castSpellName) then
-			return start, ending
-		else
-			return nil
-		end
-	elseif OvaleData.buffSpellList[spellId] then
-		local found = false
-		for auraId in pairs(OvaleData.buffSpellList[spellId]) do
-			if IsSameSpell(auraId, castSpellId, castSpellName) then
-				return start, ending
-			end
-		end
-		return nil
-	elseif spellId == "harmful" then
-		if not castSpellName then
-			castSpellName = OvaleSpellBook:GetSpellName(castSpellId)
-		end
-		if API_IsHarmfulSpell(castSpellName) then
-			return start, ending
-		else
-			return nil
-		end
-	elseif spellId == "helpful" then
-		if not castSpellName then
-			castSpellName = OvaleSpellBook:GetSpellName(castSpellId)
-		end
-		if API_IsHelpfulSpell(castSpellName) then
-			return start, ending
-		else
-			return nil
-		end
-	end
-end
-
---- Get the cast time in seconds of the spell for the player, taking into account current haste effects.
--- @name CastTime
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @see RemainingCastTime
--- @usage
--- if target.DebuffRemains(flame_shock) < CastTime(lava_burst)
---     Spell(lava_burst)
-
-OvaleCondition.conditions.casttime = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local castTime = 0
-	if spellId then
-		castTime = select(7, API_GetSpellInfo(spellId))
-		if castTime then
-			castTime = castTime / 1000
-			Ovale:Logf("castTime = %f %s %s", castTime, comparator, limit)
-		end
-	end
-	return Compare(castTime, comparator, limit)
-end
-
---- Get the number of charges on a spell with multiple charges.
--- @name Charges
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of charges
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.charges = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local currentCharges = API_GetSpellCharges(spellId)
-	return Compare(currentCharges, comparator, limit)
-end
-
---- Test if all of the listed checkboxes are off.
--- @name CheckBoxOff
--- @paramsig boolean
--- @param id The name of a checkbox. It should match one defined by AddCheckBox(...).
--- @param ... Optional. Additional checkbox names.
--- @return A boolean value.
--- @see CheckBoxOn
--- @usage
--- AddCheckBox(opt_black_arrow "Black Arrow" default)
--- if CheckBoxOff(opt_black_arrow) Spell(explosive_trap)
-
-OvaleCondition.conditions.checkboxoff = function(condition)
-	for k,v in pairs(condition) do
-		if (Ovale:IsChecked(v)) then
-			return nil
-		end
-	end
-	return TestBoolean(true)
-end
-
---- Test if all of the listed checkboxes are on.
--- @name CheckBoxOn
--- @paramsig boolean
--- @param id The name of a checkbox. It should match one defined by AddCheckBox(...).
--- @param ... Optional. Additional checkbox names.
--- @return A boolean value.
--- @see CheckBoxOff
--- @usage
--- AddCheckBox(opt_black_arrow "Black Arrow" default)
--- if CheckBoxOn(opt_black_arrow) Spell(black_arrow)
-
-OvaleCondition.conditions.checkboxon = function(condition)
-	for k,v in pairs(condition) do
-		if (not Ovale:IsChecked(v)) then
-			return nil
-		end
-	end
-	return TestBoolean(true)
-end
-
---- Get the current amount of stored Chi for monks.
--- @name Chi
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The amount of stored Chi.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if Chi() ==4 Spell(chi_burst)
--- if Chi(more 3) Spell(chi_burst)
-
-OvaleCondition.conditions.chi = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleState.state.chi, comparator, limit)
-end
-
---- Test whether the target's class matches the given class.
--- @name Class
--- @paramsig boolean
--- @param class The class to check.
---     Valid values: DEATHKNIGHT, DRUID, HUNTER, MAGE, MONK, PALADIN, PRIEST, ROGUE, SHAMAN, WARLOCK, WARRIOR.
--- @param yesno Optional. If yes, then return true if it matches. If no, then return true if it doesn't match.
---     Default is yes.
---     Valid values: yes, no.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- if target.Class(PRIEST) Spell(cheap_shot)
-
-OvaleCondition.conditions.class = function(condition)
-	local class, yesno = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local classToken = select(2, API_UnitClass(target))
-	return TestBoolean(classToken == class, yesno)
-end
-
---- Test whether the target's classification matches the given classification.
--- @name Classification
--- @paramsig boolean
--- @param classification The unit classification to check.
---     Valid values: normal, elite, worldboss.
--- @param yesno Optional. If yes, then return true if it matches. If no, then return true if it doesn't match.
---     Default is yes.
---     Valid values: yes, no.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- if target.Classification(worldboss) Item(virmens_bite_potion)
-
-OvaleCondition.conditions.classification = function(condition)
-	local classification, yesno = condition[1], condition[2]
-	local targetClassification
-	local target = GetTarget(condition)
-	if API_UnitLevel(target) < 0 then
-		targetClassification = "worldboss"
-	else
-		targetClassification = API_UnitClassification(target)
-		if targetClassification == "rareelite" then
-			targetClassification = "elite"
-		elseif targetClassification == "rare" then
-			targetClassification = "normal"
-		end
-	end
-	return TestBoolean(targetClassification == classification, yesno)
-end
-
---- Get the number of combo points on the currently selected target for a feral druid or a rogue.
--- @name ComboPoints
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of combo points.
--- @return A boolean value for the result of the comparison.
--- @see LastComboPoints
--- @usage
--- if ComboPoints() >=1 Spell(savage_roar)
--- if ComboPoints(more 0) Spell(savage_roar)
-
-OvaleCondition.conditions.combopoints = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleState.state.combo, comparator, limit)
-end
-
---- Get the current value of a script counter.
--- @name Counter
--- @paramsig number or boolean
--- @param id The name of the counter. It should match one that's defined by inccounter=xxx in SpellInfo(...).
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current value the counter.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.counter = function(condition)
-	local counter, comparator, limit = condition[1], condition[2], condition[3]
-	return Compare(OvaleState:GetCounterValue(counter), comparator, limit)
-end
-
---- Test whether the target's creature family matches the given name.
--- Applies only to beasts that can be taken as hunter pets (e.g., cats, worms, and ravagers but not zhevras, talbuks and pterrordax),
--- demons that can be summoned by Warlocks (e.g., imps and felguards, but not demons that require enslaving such as infernals
--- and doomguards or world demons such as pit lords and armored voidwalkers), and Death Knight's pets (ghouls)
--- @name CreatureFamily
--- @paramsig boolean
--- @param name The English name of the creature family to check.
---     Valid values: Bat, Beast, Felguard, Imp, Ravager, etc.
--- @param yesno Optional. If yes, then return true if it matches. If no, then return true if it doesn't match.
---     Default is yes.
---     Valid values: yes, no.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- if pet.CreatureFamily(Felguard)
---     Spell(summon_felhunter)
--- if target.CreatureFamily(Dragonkin)
---     Spell(hibernate)
-
-OvaleCondition.conditions.creaturefamily = function(condition)
-	local name, yesno = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local family = API_UnitCreatureFamily(target)
-	return TestBoolean(family == LBCT[name], yesno)
-end
-
---- Test if the target is any of the listed creature types.
--- @name CreatureType
--- @paramsig boolean
--- @param name The English name of a creature type.
---     Valid values: Beast, Humanoid, Undead, etc.
--- @param ... Optional. Additional creature types.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- if target.CreatureType(Humanoid Critter)
---     Spell(polymorph)
-
-OvaleCondition.conditions.creaturetype = function(condition)
-	local target = GetTarget(condition)
-	local creatureType = API_UnitCreatureType(target)
-	for _, v in pairs(condition) do
-		if creatureType == LBCT[v] then
-			return TestBoolean(true)
-		end
-	end
-	return nil
-end
-
---- Get the current estimated damage of a spell on the target if it is a critical strike.
--- @name CritDamage
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The estimated critical strike damage of the given spell.
--- @return A boolean value for the result of the comparison.
--- @see Damage, LastDamage, LastEstimatedDamage
-
-OvaleCondition.conditions.critdamage = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	-- TODO: Need to account for increased crit effect from meta-gems.
-	local critFactor = 2
-	return Compare(critFactor * GetDamage(spellId), comparator, limit)
-end
-
---- Get the current estimated damage of a spell on the target.
--- The calculated damage takes into account the current attack power, spellpower, weapon damage and combo points (if used).
--- The damage is computed from information for the spell set via SpellInfo(...):
---
--- damage = base + bonusmainhand * MH + bonusoffhand * OH + bonusap * AP + bonuscp * CP + bonusapcp * AP * CP + bonussp * SP
--- @name Damage
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The estimated damage of the given spell on the target.
--- @return A boolean value for the result of the comparison.
--- @see CritDamage, LastDamage, LastEstimatedDamage
--- @usage
--- if {target.Damage(rake) / target.LastEstimateDamage(rake)} >1.1
---     Spell(rake)
-
-OvaleCondition.conditions.damage = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	return Compare(GetDamage(spellId), comparator, limit)
-end
-
---- Get the current damage multiplier of a spell.
--- This currently does not take into account increased damage due to mastery.
--- @name DamageMultiplier
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current damage multiplier of the given spell.
--- @return A boolean value for the result of the comparison.
--- @see LastDamageMultiplier
--- @usage
--- if {DamageMultiplier(rupture) / LastDamageMultiplier(rupture)} >1.1
---     Spell(rupture)
-
-OvaleCondition.conditions.damagemultiplier = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local bdm = OvalePaperDoll.stat.baseDamageMultiplier
-	local dm = OvaleState:GetDamageMultiplier(spellId)
-	return Compare(bdm * dm, comparator, limit)
-end
-
---- Get the damage taken by the player in the previous time interval.
--- @name DamageTaken
--- @paramsig number or boolean
--- @param interval The number of seconds before now.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The amount of damage taken in the previous interval.
--- @return A boolean value for the result of the comparison.
--- @see IncomingDamage
--- @usage
--- if DamageTaken(5) > 50000 Spell(death_strike)
-
-OvaleCondition.conditions.damagetaken = function(condition)
-	-- Damage taken shouldn't be smoothed since spike damage is important data.
-	-- Just present damage taken as a constant value.
-	local interval, comparator, limit = condition[1], condition[2], condition[3]
-	local damage = 0
-	if interval > 0 then
-		damage = OvaleDamageTaken:GetRecentDamage(interval)
-	end
-	return Compare(damage, comparator, limit)
-end
-OvaleCondition.conditions.incomingdamage = OvaleCondition.conditions.damagetaken
-
---- Get the current amount of demonic fury for demonology warlocks.
--- @name DemonicFury
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The amount of demonic fury.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if DemonicFury() >=1000 Spell(metamorphosis)
--- if DemonicFury(more 999) Spell(metamorphosis)
-
-OvaleCondition.conditions.demonicfury = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local value, origin, rate = OvaleState.state.demonicfury, OvaleState.currentTime, OvaleState.powerRate.demonicfury
-	local start, ending = OvaleState.currentTime, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-
---- Get the distance in yards to the target.
--- The distances are from LibRangeCheck-2.0, which determines distance based on spell range checks, so results are approximate.
--- You should not test for equality.
--- @name Distance
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The distance to the target.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if target.Distance(less 25)
---     Texture(ability_rogue_sprint)
-
-OvaleCondition.conditions.distance = function(condition)
-	if LRC then
-		local comparator, limit = condition[1], condition[2]
-		local target = GetTarget(condition)
-		return Compare(LRC:GetRange(target), comparator, limit)
-	end
-	return nil
-end
-
---- Get the current amount of Eclipse power for balance druids.
--- A negative amount of power signifies being closer to Lunar Eclipse.
--- A positive amount of power signifies being closer to Solar Eclipse.
--- @name Eclipse
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The amount of Eclipse power.
--- @return A boolean value for the result of the comparison.
--- @see EclipseDir
--- @usage
--- if Eclipse() < 0-70 and EclipseDir() <0 Spell(wrath)
--- if Eclipse(less -70) and EclipseDir(less 0) Spell(wrath)
-
-OvaleCondition.conditions.eclipse = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleState.state.eclipse, comparator, limit)
-end
-
---- Get the current direction of the Eclipse status on the Eclipse bar for balance druids.
--- A negative number means heading toward Lunar Eclipse.
--- A positive number means heading toward Solar Eclipse.
--- @name EclipseDir
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current direction.
--- @return A boolean value for the result of the comparison.
--- @see Eclipse
--- @usage
--- if Eclipse() < 0-70 and EclipseDir() <0 Spell(wrath)
--- if Eclipse(less -70) and EclipseDir(less 0) Spell(wrath)
-
-OvaleCondition.conditions.eclipsedir = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleState:GetEclipseDir(), comparator, limit)
-end
-
---- Get the number of hostile enemies on the battlefield.
--- @name Enemies
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of enemies.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if Enemies() >4 Spell(fan_of_knives)
--- if Enemies(more 4) Spell(fan_of_knives)
-
-OvaleCondition.conditions.enemies = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleEnemies.activeEnemies, comparator, limit)
-end
-
---- Get the current amount of energy for feral druids, non-mistweaver monks, and rogues.
--- @name Energy
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current energy.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if Energy() >70 Spell(vanish)
--- if Energy(more 70) Spell(vanish)
-
-OvaleCondition.conditions.energy = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local value, origin, rate = OvaleState.state.energy, OvaleState.currentTime, OvaleState.powerRate.energy
-	local start, ending = OvaleState.currentTime, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-
---- Get the amount of regenerated energy per second for feral druids, non-mistweaver monks, and rogues.
--- @name EnergyRegen
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current rate of energy regeneration.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if EnergyRegen() >11 Spell(stance_of_the_sturdy_ox)
-
-OvaleCondition.conditions.energyregen = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleState.powerRate.energy, comparator, limit)
-end
-
---- Test if the target exists. The target may be alive or dead.
--- @name Exists
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if the target exists. If no, then return true if it doesn't exist.
---     Default is yes.
---     Valid values: yes, no.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @see Present
--- @usage
--- if pet.Exists(no) Spell(summon_imp)
-
-OvaleCondition.conditions.exists = function(condition)
-	local yesno = condition[1]
-	local target = GetTarget(condition)
-	return TestBoolean(API_UnitExists(target) == 1, yesno)
-end
-
---- A condition that always returns false.
--- @name False
--- @paramsig boolean
--- @return A boolean value.
-
-OvaleCondition.conditions["false"] = function(condition)
-	return nil
-end
-
---- Get the current amount of focus for hunters.
--- @name Focus
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current focus.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if Focus() >70 Spell(arcane_shot)
--- if Focus(more 70) Spell(arcane_shot)
-
-OvaleCondition.conditions.focus = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local value, origin, rate = OvaleState.state.focus, OvaleState.currentTime, OvaleState.powerRate.focus
-	local start, ending = OvaleState.currentTime, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-
---- Get the amount of regenerated focus per second for hunters.
--- @name FocusRegen
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current rate of focus regeneration.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if FocusRegen() >20 Spell(arcane_shot)
--- if FocusRegen(more 20) Spell(arcane_shot)
-
-OvaleCondition.conditions.focusregen = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleState.powerRate.focus, comparator, limit)
-end
-
---- Get the player's global cooldown in seconds.
--- @name GCD
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if GCD() <1.1 Spell(frostfire_bolt)
--- if GCD(less 1.1) Spell(frostfire_bolt)
-
-OvaleCondition.conditions.gcd = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleState.gcd, comparator, limit)
-end
-
---- Test if the given glyph is active.
--- @name Glyph
--- @paramsig boolean
--- @param id The glyph spell ID.
--- @param yesno Optional. If yes, then return true if the glyph is active. If no, then return true if it isn't active.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if InCombat(no) and Glyph(glyph_of_savagery)
---     Spell(savage_roar)
-
-OvaleCondition.conditions.glyph = function(condition)
-	local glyph, yesno = condition[1], condition[2]
-	return TestBoolean(OvaleSpellBook:IsActiveGlyph(glyph), yesno)
-end
-
---- Test if the player has a particular item equipped.
--- @name HasEquippedItem
--- @paramsig boolean
--- @param item Item to be checked whether it is equipped.
--- @param yesno Optional. If yes, then return true if the item is equipped. If no, then return true if it isn't equipped.
---     Default is yes.
---     Valid values: yes, no.
--- @param ilevel Optional.  Checks the item level of the equipped item.  If not specified, then any item level is valid.
---     Defaults to not specified.
---     Valid values: ilevel=N, where N is any number.
--- @param slot Optional. Sets the inventory slot to check.  If not specified, then all slots are checked.
---     Defaults to not specified.
---     Valid values: slot=SLOTNAME, where SLOTNAME is a valid slot name, e.g., HandSlot.
-
-OvaleCondition.conditions.hasequippeditem = function(condition)
-	local itemId, yesno = condition[1], condition[2]
-	local ilevel, slot = condition.ilevel, condition.slot
-	local slotId
-	if type(itemId) == "number" then
-		slotId = OvaleEquipement:HasEquippedItem(itemId, slot)
-		if slotId then
-			if ilevel then
-				if ilevel == OvaleEquipement:GetEquippedItemLevel(slotId) then
-					return TestBoolean(true, yesno)
-				end
-			else
-				return TestBoolean(true, yesno)
-			end
-		end
-	elseif OvaleData.itemList[itemId] then
-		for _, v in pairs(OvaleData.itemList[itemId]) do
-			slotId = OvaleEquipement:HasEquippedItem(v, slot)
-			if slotId then
-				if ilevel then
-					if ilevel == OvaleEquipement:GetEquippedItemLevel(slotId) then
-						return TestBoolean(true, yesno)
-					end
-				else
-					return TestBoolean(true, yesno)
-				end
-			end
-		end
-	end
-	return TestBoolean(false, yesno)
-end
-
---- Test if the player has full control, i.e., isn't feared, charmed, etc.
--- @name HasFullControl
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if the target exists. If no, then return true if it doesn't exist.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if HasFullControl(no) Spell(barkskin)
-
-OvaleCondition.conditions.hasfullcontrol = function(condition)
-	local yesno = condition[1]
-	return TestBoolean(API_HasFullControl(), yesno)
-end
-
---- Test if the player has a shield equipped.
--- @name HasShield
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if a shield is equipped. If no, then return true if it isn't equipped.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if HasShield() Spell(shield_wall)
-
-OvaleCondition.conditions.hasshield = function(condition)
-	local yesno = condition[1]
-	return TestBoolean(OvaleEquipement:HasShield(), yesno)
-end
-
---- Test if the player has a particular trinket equipped.
--- @name HasTrinket
--- @paramsig boolean
--- @param id The item ID of the trinket or the name of an item list.
--- @param yesno Optional. If yes, then return true if the trinket is equipped. If no, then return true if it isn't equipped.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- ItemList(rune_of_reorigination 94532 95802 96546)
--- if HasTrinket(rune_of_reorigination) and BuffPresent(rune_of_reorigination_buff)
---     Spell(rake)
-
-OvaleCondition.conditions.hastrinket = function(condition)
-	local trinketId, yesno = condition[1], condition[2]
-	if type(trinketId) == "number" then
-		return TestBoolean(OvaleEquipement:HasTrinket(trinketId), yesno)
-	elseif OvaleData.itemList[trinketId] then
-		for _, v in pairs(OvaleData.itemList[trinketId]) do
-			if OvaleEquipement:HasTrinket(v) then
-				return TestBoolean(true, yesno)
-			end
-		end
-	end
-	return TestBoolean(false, yesno)
-end
-
---- Test if the player has a weapon equipped.
--- @name HasWeapon
--- @paramsig boolean
--- @param hand Sets which hand weapon.
---     Valid values: main, off
--- @param yesno Optional. If yes, then return true if the weapon is equipped. If no, then return true if it isn't equipped.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if HasWeapon(offhand) and BuffStacks(killing_machine) Spell(frost_strike)
-
-OvaleCondition.conditions.hasweapon = function(condition)
-	local hand, yesno = condition[1], condition[2]
-	if hand == "offhand" or hand == "off" then
-		return TestBoolean(OvaleEquipement:HasOffHandWeapon(), yesno)
-	elseif hand == "mainhand" or hand == "main" then
-		return TestBoolean(OvaleEquipement:HasMainHandWeapon(), yesno)
-	else
-		return TestBoolean(false, yesno)
-	end
-end
-
---- Get the current amount of health points of the target.
--- @name Health
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The current health.
--- @return A boolean value for the result of the comparison.
--- @see Life
--- @usage
--- if Health() <10000 Spell(last_stand)
--- if Health(less 10000) Spell(last_stand)
-
-OvaleCondition.conditions.health = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local timeToDie, health, maxHealth = TimeToDie(target)
-	if not timeToDie or timeToDie == 0 then
-		return nil
-	end
-	local value, origin, rate = health, OvaleState.maintenant, -1 * health / timeToDie
-	local start, ending = OvaleState.maintenant, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-OvaleCondition.conditions.life = OvaleCondition.conditions.health
-
---- Get the number of health points away from full health of the target.
--- @name HealthMissing
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The current missing health.
--- @return A boolean value for the result of the comparison.
--- @see LifeMissing
--- @usage
--- if HealthMissing() <20000 Item(healthstone)
--- if HealthMissing(less 20000) Item(healthstone)
-
-OvaleCondition.conditions.healthmissing = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local timeToDie, health, maxHealth = TimeToDie(target)
-	if not timeToDie or timeToDie == 0 then
-		return nil
-	end
-	local missing = maxHealth - health
-	local value, origin, rate = missing, OvaleState.maintenant, health / timeToDie
-	local start, ending = OvaleState.maintenant, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-OvaleCondition.conditions.lifemissing = OvaleCondition.conditions.healthmissing
-
---- Get the current percent level of health of the target.
--- @name HealthPercent
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The current health percent.
--- @return A boolean value for the result of the comparison.
--- @see LifePercent
--- @usage
--- if HealthPercent() <20 Spell(last_stand)
--- if target.HealthPercent(less 25) Spell(kill_shot)
-
-OvaleCondition.conditions.healthpercent = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local timeToDie, health, maxHealth = TimeToDie(target)
-	if not timeToDie or timeToDie == 0 then
-		return nil
-	end
-	local healthPercent = health / maxHealth * 100
-	local value, origin, rate = healthPercent, OvaleState.maintenant, -1 * healthPercent / timeToDie
-	local start, ending = OvaleState.maintenant, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-OvaleCondition.conditions.lifepercent = OvaleCondition.conditions.healthpercent
-
---- Get the current amount of holy power for a paladin.
--- @name HolyPower
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The amount of holy power.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if HolyPower() >=3 Spell(word_of_glory)
--- if HolyPower(more 2) Spell(word_of_glory)
-
-OvaleCondition.conditions.holypower = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleState.state.holy, comparator, limit)
-end
-
---- Test if the player is in combat.
--- @name InCombat
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if the player is in combat. If no, then return true if the player isn't in combat.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if InCombat(no) and Stealthed(no) Spell(stealth)
-
-OvaleCondition.conditions.incombat = function(condition)
-	local yesno = condition[1]
-	return TestBoolean(Ovale.enCombat, yesno)
-end
-
---- Test if the given spell is in flight for spells that have a flight time after cast, e.g., Lava Burst.
--- @name InFlightToTarget
--- @paramsig boolean
--- @param id The spell ID.
--- @param yesno Optional. If yes, then return true if the spell is in flight. If no, then return true if it isn't in flight.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if target.DebuffRemains(haunt) <3 and not InFlightToTarget(haunt)
---     Spell(haunt)
-
-OvaleCondition.conditions.inflighttotarget = function(condition)
-	local spellId, yesno = condition[1], condition[2]
-	return TestBoolean(OvaleState.currentSpellId == spellId or OvaleFuture:InFlight(spellId), yesno)
-end
-
---- Test if the distance from the player to the target is within the spell's range.
--- @name InRange
--- @paramsig boolean
--- @param id The spell ID.
--- @param yesno Optional. If yes, then return true if the target is in range. If no, then return true if it isn't in range.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if target.IsInterruptible() and target.InRange(kick)
---     Spell(kick)
-
-OvaleCondition.conditions.inrange = function(condition)
-	local spellId, yesno = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local spellName = OvaleSpellBook:GetSpellName(spellId)
-	return TestBoolean(API_IsSpellInRange(spellName, target) == 1, yesno)
-end
-
---- Get the current intellect of the player.
--- @name Intellect
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current intellect.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.intellect = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvalePaperDoll.stat.intellect, comparator, limit)
-end
-
---- Test if the target's primary aggro is on the player.
--- Even if the target briefly targets and casts a spell on another raid member,
--- this condition returns true as long as the player is highest on the threat table.
--- @name IsAggroed
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if the target is aggroed. If no, then return true if it isn't aggroed.
---     Default is yes.
---     Valid values: yes, no.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- if target.IsAggroed() Spell(feign_death)
-
-OvaleCondition.conditions.isaggroed = function(condition)
-	local target = GetTarget(condition)
-	return TestBoolean(API_UnitDetailedThreatSituation("player", target), condition[1])
-end
-
---- Test if the player is feared.
--- @name IsFeared
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if feared. If no, then return true if it not feared.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if IsFeared() Spell(every_man_for_himself)
-
-OvaleCondition.conditions.isfeared = function(condition)
-	local yesno = condition[1]
-	return TestBoolean(not API_HasFullControl() and OvaleState:GetAura("player", "fear", "HARMFUL"), yesno)
-end
-
---- Test if the target is friendly to the player.
--- @name IsFriend
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if the target is friendly (able to help in combat). If no, then return true if it isn't friendly.
---     Default is yes.
---     Valid values: yes, no.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- if target.IsFriend() Spell(healing_touch)
-
-OvaleCondition.conditions.isfriend = function(condition)
-	local yesno = condition[1]
-	local target = GetTarget(condition)
-	return TestBoolean(API_UnitIsFriend("player", target), yesno)
-end
-
---- Test if the player is incapacitated.
--- @name IsIncapacitated
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if incapacitated. If no, then return true if it not incapacitated.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if IsIncapacitated() Spell(every_man_for_himself)
-
-OvaleCondition.conditions.isincapacitated = function(condition)
-	return TestBoolean(not API_HasFullControl() and OvaleState:GetAura("player", "incapacitate", "HARMFUL"), condition[1])
-end
-
---- Test if the target is currently casting an interruptible spell.
--- @name IsInterruptible
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if the target is interruptible. If no, then return true if it isn't interruptible.
---     Default is yes.
---     Valid values: yes, no.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- if target.IsInterruptible() Spell(kick)
-
-OvaleCondition.conditions.isinterruptible = function(condition)
-	local yesno = condition[1]
-	local target = GetTarget(condition)
-	local spell, _, _, _, _, _, _, _, protected = API_UnitCastingInfo(target)
-	if not spell then
-		spell, _, _, _, _, _, _, protected = API_UnitChannelInfo(target)
-	end
-	return TestBoolean(protected ~= nil and not protected, yesno)
-end
-
---- Test if the target is flagged for PvP activity.
--- @name IsPVP
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if the target is flagged for PvP activity. If no, then return true if it isn't PvP-flagged.
---     Default is yes.
---     Valid values: yes, no.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- if not target.IsFriend() and target.IsPVP() Spell(sap)
-
-OvaleCondition.conditions.ispvp = function(condition)
-	local yesno = condition[1]
-	local target = GetTarget(condition)
-	return TestBoolean(API_UnitIsPVP(target), yesno)
-end
-
---- Test if the player is rooted.
--- @name IsRooted
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if rooted. If no, then return true if it not rooted.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if IsRooted() Item(Trinket0Slot usable=1)
-
-OvaleCondition.conditions.isrooted = function(condition)
-	local yesno = condition[1]
-	return TestBoolean(OvaleState:GetAura("player", "root", "HARMFUL"), yesno)
-end
-
---- Test if the player is stunned.
--- @name IsStunned
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if stunned. If no, then return true if it not stunned.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if IsStunned() Item(Trinket0Slot usable=1)
-
-OvaleCondition.conditions.isstunned = function(condition)
-	local yesno = condition[1]
-	return TestBoolean(not API_HasFullControl() and OvaleState:GetAura("player", "stun", "HARMFUL"), yesno)
-end
-
---- Get the current number of charges of the given item in the player's inventory.
--- @name ItemCharges
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of charges.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if ItemCount(mana_gem) ==0 or ItemCharges(mana_gem) <3
---     Spell(conjure_mana_gem)
--- if ItemCount(mana_gem equal 0) or ItemCharges(mana_gem less 3)
---     Spell(conjure_mana_gem)
-
-OvaleCondition.conditions.itemcharges = function(condition)
-	local itemId, comparator, limit = condition[1], condition[2], condition[3]
-	return Compare(API_GetItemCount(itemId, false, true), comparator, limit)
-end
-
---- Get the cooldown time in seconds of an item, e.g., trinket.
--- @name ItemCooldown
--- @paramsig number or boolean
--- @param id The item ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if not ItemCooldown(ancient_petrified_seed) >0
---     Spell(berserk_cat)
-
-OvaleCondition.conditions.itemcooldown = function(condition)
-	local itemId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, duration = API_GetItemCooldown(itemId)
-	if start + duration > OvaleState.currentTime then
-		return TestOvaleValue(start, start + duration, duration, start, -1, comparator, limit)
-	else
-		return Compare(0, comparator, limit)
-	end
-end
-
---- Get the current number of the given item in the player's inventory.
--- Items with more than one charge count as one item.
--- @name ItemCount
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The count of the item.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if ItemCount(mana_gem) ==0 Spell(conjure_mana_gem)
--- if ItemCount(mana_gem equal 0) Spell(conjure_mana_gem)
-
-OvaleCondition.conditions.itemcount = function(condition)
-	local itemId, comparator, limit = condition[1], condition[2], condition[3]
-	return Compare(API_GetItemCount(itemId), comparator, limit)
-end
-
---- Get the attack power of the player during the most recent cast of a spell on the target.
--- @name LastAttackPower
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=target.
---     Valid values: player, target, focus, pet.
--- @return The previous attack power.
--- @return A boolean value for the result of the comparison.
--- @see AttackPower
--- @usage
--- if {AttackPower() / target.LastAttackPower(hemorrhage)} >1.25
---     Spell(hemorrhage)
-
-OvaleCondition.conditions.lastattackpower = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local target = GetTarget(condition, "target")
-	local guid = OvaleGUID:GetGUID(target)
-	local ap = OvaleFuture:GetLastSpellInfo(guid, spellId, "attackPower") or 1
-	return Compare(ap, comparator, limit)
-end
-OvaleCondition.conditions.lastspellattackpower = OvaleCondition.conditions.lastattackpower
-
---- Get the number of combo points consumed by the most recent cast of a spell on the target for a feral druid or a rogue.
--- @name LastComboPoints
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=target.
---     Valid values: player, target, focus, pet.
--- @return The number of combo points.
--- @return A boolean value for the result of the comparison.
--- @see ComboPoints
--- @usage
--- if ComboPoints() >3 and target.LastComboPoints(rip) <3
---     Spell(rip)
-
-OvaleCondition.conditions.lastcombopoints = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local target = GetTarget(condition, "target")
-	local guid = OvaleGUID:GetGUID(target)
-	local combo = OvaleFuture:GetLastSpellInfo(guid, spellId, "comboPoints") or 1
-	return Compare(combo, comparator, limit)
-end
-OvaleCondition.conditions.lastspellcombopoints = OvaleCondition.conditions.lastcombopoints
-
---- Get the damage done by the most recent damage event for the given spell.
--- If the spell is a periodic aura, then it gives the damage done by the most recent tick.
--- @name LastDamage
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The damage done.
--- @return A boolean value for the result of the comparison.
--- @see Damage, LastEstimatedDamage
--- @usage
--- if LastDamage(ignite) >10000 Spell(combustion)
--- if LastDamage(ignite more 10000) Spell(combustion)
-
-OvaleCondition.conditions.lastdamage = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	if not OvaleSpellDamage:Get(spellId) then
-		return nil
-	end
-	return Compare(OvaleSpellDamage:Get(spellId), comparator, limit)
-end
-OvaleCondition.conditions.lastspelldamage = OvaleCondition.conditions.lastdamage
-
---- Get the damage multiplier of the most recent cast of a spell on the target.
--- This currently does not take into account increased damage due to mastery.
--- @name LastDamageMultiplier
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=target.
---     Valid values: player, target, focus, pet.
--- @return The previous damage multiplier.
--- @return A boolean value for the result of the comparison.
--- @see DamageMultiplier
--- @usage
--- if {DamageMultiplier(rupture) / target.LastDamageMultiplier(rupture)} >1.1
---     Spell(rupture)
-
-OvaleCondition.conditions.lastdamagemultiplier = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local target = GetTarget(condition, "target")
-	local guid = OvaleGUID:GetGUID(target)
-	local bdm = OvaleFuture:GetLastSpellInfo(guid, spellId, "baseDamageMultiplier") or 1
-	local dm = OvaleFuture:GetLastSpellInfo(guid, spellId, "damageMultiplier") or 1
-	return Compare(bdm * dm, comparator, limit)
-end
-OvaleCondition.conditions.lastspelldamagemultiplier = OvaleCondition.conditions.lastdamagemultiplier
-
---- Get the estimated damage of the most recent cast of the player's spell on the target.
--- The calculated damage takes into account the values of attack power, spellpower, weapon damage and combo points (if used)
--- at the time the spell was most recent cast.
--- The damage is computed from information for the spell set via SpellInfo(...):
---
--- damage = base + bonusmainhand * MH + bonusoffhand * OH + bonusap * AP + bonuscp * CP + bonusapcp * AP * CP + bonussp * SP
--- @name LastEstimatedDamage
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=target.
---     Valid values: player, target, focus, pet.
--- @return The estimated damage of the most recent cast of the given spell by the player.
--- @return A boolean value for the result of the comparison.
--- @see Damage, LastDamage
--- @usage
--- if {Damage(rake) / target.LastEstimateDamage(rake)} >1.1
---     Spell(rake)
-
-OvaleCondition.conditions.lastestimateddamage = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local target = GetTarget(condition, "target")
-	local guid = OvaleGUID:GetGUID(target)
-	local ap = OvaleFuture:GetLastSpellInfo(guid, spellId, "attackPower") or 1
-	local sp = OvaleFuture:GetLastSpellInfo(guid, spellId, "spellBonusDamage") or 1
-	local mh = OvaleFuture:GetLastSpellInfo(guid, spellId, "mainHandWeaponDamage") or 1
-	local oh = OvaleFuture:GetLastSpellInfo(guid, spellId, "offHandWeaponDamage") or 1
-	local combo = OvaleFuture:GetLastSpellInfo(guid, spellId, "comboPoints") or 1
-	local bdm = OvaleFuture:GetLastSpellInfo(guid, spellId, "baseDamageMultiplier") or 1
-	local dm = OvaleFuture:GetLastSpellInfo(guid, spellId, "damageMultiplier") or 1
-	return Compare(OvaleData:GetDamage(spellId, ap, sp, mh, oh, combo) * bdm * dm, comparator, limit)
-end
-OvaleCondition.conditions.lastspellestimateddamage = OvaleCondition.conditions.lastestimateddamage
-
---- Get the mastery effect of the player during the most recent cast of a spell on the target.
--- Mastery effect is the effect of the player's mastery, typically a percent-increase to damage
--- or a percent-increase to chance to trigger some effect.
--- @name LastMastery
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=target.
---     Valid values: player, target, focus, pet.
--- @return The previous mastery effect.
--- @return A boolean value for the result of the comparison.
--- @see Mastery
--- @usage
--- if {Mastery(shadow_bolt) - LastMastery(shadow_bolt)} > 1000
---     Spell(metamorphosis)
-
-OvaleCondition.conditions.lastmastery = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local target = GetTarget(condition, "target")
-	local guid = OvaleGUID:GetGUID(target)
-	local mastery = OvaleFuture:GetLastSpellInfo(guid, spellId, "masteryEffect") or 0
-	return Compare(mastery, comparator, limit)
-end
-OvaleCondition.conditions.lastspellmastery = OvaleCondition.conditions.lastmastery
-
---- Get the melee critical strike chance of the player during the most recent cast of a spell on the target.
--- @name LastMeleeCritChance
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
---     Defaults to unlimited=0.
---     Valid values: 0, 1
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=target.
---     Valid values: player, target, focus, pet.
--- @return The previous critical strike chance.
--- @return A boolean value for the result of the comparison.
--- @see MeleeCritChance
--- @usage
--- if MeleeCritChance() > target.LastMeleeCritChance(rip)
---     Spell(rip)
-
-OvaleCondition.conditions.lastmeleecritchance = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local target = GetTarget(condition, "target")
-	local guid = OvaleGUID:GetGUID(target)
-	local critChance = OvaleFuture:GetLastSpellInfo(guid, spellId, "meleeCrit") or DEFAULT_CRIT_CHANCE
-	if condition.unlimited ~= 1 and critChance > 100 then
-		critChance = 100
-	end
-	return Compare(critChance, comparator, limit)
-end
-OvaleCondition.conditions.lastspellmeleecritchance = OvaleCondition.conditions.lastmeleecritchance
-
---- Get the ranged critical strike chance of the player during the most recent cast of a spell on the target.
--- @name LastRangedCritChance
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
---     Defaults to unlimited=0.
---     Valid values: 0, 1
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=target.
---     Valid values: player, target, focus, pet.
--- @return The previous critical strike chance.
--- @return A boolean value for the result of the comparison.
--- @see RangedCritChance
--- @usage
--- if RangedCritChance() > target.LastRangedCritChance(serpent_sting_dot)
---     Spell(serpent_sting)
-
-OvaleCondition.conditions.lastrangedcritchance = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local target = GetTarget(condition, "target")
-	local guid = OvaleGUID:GetGUID(target)
-	local critChance = OvaleFuture:GetLastSpellInfo(guid, spellId, "rangedCrit") or DEFAULT_CRIT_CHANCE
-	if condition.unlimited ~= 1 and critChance > 100 then
-		critChance = 100
-	end
-	return Compare(critChance, comparator, limit)
-end
-OvaleCondition.conditions.lastspellrangedcritchance = OvaleCondition.conditions.lastrangedcritchance
-
---- Get the spell critical strike chance of the player during the most recent cast of a spell on the target.
--- @name LastSpellCritChance
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
---     Defaults to unlimited=0.
---     Valid values: 0, 1
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=target.
---     Valid values: player, target, focus, pet.
--- @return The previous critical strike chance.
--- @return A boolean value for the result of the comparison.
--- @see SpellCritChance
--- @usage
--- if SpellCritChance() > target.LastSpellCritChance(shadow_bolt)
---     Spell(metamorphosis)
-
-OvaleCondition.conditions.lastspellcritchance = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local target = GetTarget(condition, "target")
-	local guid = OvaleGUID:GetGUID(target)
-	local critChance = OvaleFuture:GetLastSpellInfo(guid, spellId, "spellCrit") or DEFAULT_CRIT_CHANCE
-	if condition.unlimited ~= 1 and critChance > 100 then
-		critChance = 100
-	end
-	return Compare(critChance, comparator, limit)
-end
-OvaleCondition.conditions.lastspellspellcritchance = OvaleCondition.conditions.lastspellcritchance
-
---- Get the spellpower of the player during the most recent cast of a spell on the target.
--- @name LastSpellpower
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=target.
---     Valid values: player, target, focus, pet.
--- @return The previous spellpower.
--- @return A boolean value for the result of the comparison.
--- @see Spellpower
--- @usage
--- if {Spellpower() / target.LastSpellpower(living_bomb)} >1.25
---     Spell(living_bomb)
-
-OvaleCondition.conditions.lastspellpower = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local target = GetTarget(condition, "target")
-	local guid = OvaleGUID:GetGUID(target)
-	local sp = OvaleFuture:GetLastSpellInfo(guid, spellId, "spellBonusDamage") or 1
-	return Compare(sp, comparator, limit)
-end
-OvaleCondition.conditions.lastspellspellpower = OvaleCondition.conditions.lastspellpower
-
---- Get the time elapsed in seconds since the player's previous melee swing (white attack).
--- @name LastSwing
--- @paramsig number or boolean
--- @param hand Optional. Sets which hand weapon's melee swing.
---     If no hand is specified, then return the time elapsed since the previous swing of either hand's weapon.
---     Valid values: main, off.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @see NextSwing
-
-OvaleCondition.conditions.lastswing = function(condition)
-	local swing = condition[1]
-	local comparator, limit
-	if swing and OVALE_COMPARATOR[swing] then
-		comparator, limit = condition[1], condition[2]
-		swing = OvaleSwing:GetLast()
-	else
-		comparator, limit = condition[2], condition[3]
-		swing = OvaleSwing:GetLast(swing)
-	end
-	return TestOvaleValue(swing, math.huge, 0, swing, 1, comparator, limit)
-end
-
---- Get the most recent estimate of roundtrip latency in milliseconds.
--- @name Latency
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number of milliseconds to compare against.
--- @return The most recent estimate of latency.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if Latency() >1000 Spell(sinister_strike)
--- if Latency(more 1000) Spell(sinister_strike)
-
-OvaleCondition.conditions.latency = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleLatency:GetLatency() * 1000, comparator, limit)
-end
-
---- Get the level of the target.
--- @name Level
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The level of the target.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if Level() >=34 Spell(tiger_palm)
--- if Level(more 33) Spell(tiger_palm)
-
-OvaleCondition.conditions.level = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local level
-	if target == "player" then
-		level = OvalePaperDoll.level
-	else
-		level = API_UnitLevel(target)
-	end
-	return Compare(level, comparator, limit)
-end
-
---- Test if a list is currently set to the given value.
--- @name List
--- @paramsig boolean
--- @param id The name of a list. It should match one defined by AddListItem(...).
--- @param value The value to test.
--- @return A boolean value.
--- @usage
--- AddListItem(opt_curse coe "Curse of the Elements" default)
--- AddListItem(opt_curse cot "Curse of Tongues")
--- if List(opt_curse coe) Spell(curse_of_the_elements)
-
-OvaleCondition.conditions.list = function(condition)
-	local name, value = condition[1], condition[2]
-	if name then
-		return TestBoolean(Ovale:GetListValue(name) == value)
-	end
-	return nil
-end
-
---- Get the current level of mana of the target.
--- @name Mana
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The current mana.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if {MaxMana() - Mana()} > 12500 Item(mana_gem)
-
-OvaleCondition.conditions.mana = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	if target == "player" then
-		local value, origin, rate = OvaleState.state.mana, OvaleState.currentTime, OvaleState.powerRate.mana
-		local start, ending = OvaleState.currentTime, math.huge
-		return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-	else
-		return Compare(API_UnitPower(target, SPELL_POWER_MANA), comparator, limit)
-	end
-end
-
---- Get the current percent level of mana (between 0 and 100) of the target.
--- @name ManaPercent
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The current mana percent.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if ManaPercent() >90 Spell(arcane_blast)
--- if ManaPercent(more 90) Spell(arcane_blast)
-
-OvaleCondition.conditions.manapercent = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	if target == "player" then
-		local powerMax = OvalePower.maxPower.mana or 0
-		if powerMax > 0 then
-			local conversion = 100 / powerMax
-			local value, origin, rate = OvaleState.state.mana * conversion, OvaleState.currentTime, OvaleState.powerRate.mana * conversion
-			local start, ending = OvaleState.currentTime, math.huge
-			return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-		end
-	else
-		local powerMax = API_UnitPowerMax(target, SPELL_POWER_MANA) or 0
-		if powerMax > 0 then
-			local conversion = 100 / powerMax
-			return Compare(API_UnitPower(target, SPELL_POWER_MANA) * conversion, comparator, limit)
-		end
-	end
-end
-
---- Get the current mastery effect of the player.
--- Mastery effect is the effect of the player's mastery, typically a percent-increase to damage
--- or a percent-increase to chance to trigger some effect.
--- @name Mastery
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current mastery effect.
--- @return A boolean value for the result of the comparison.
--- @see LastMastery
--- @usage
--- if {DamageMultiplier(rake) * {1 + Mastery()/100}} >1.8
---     Spell(rake)
-
-OvaleCondition.conditions.mastery = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvalePaperDoll.stat.masteryEffect, comparator, limit)
-end
-
---- Get the maximum amount of alternate power of the target.
--- Alternate power is the resource tracked by the alternate power bar in certain boss fights.
--- @name MaxAlternatePower
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxalternatepower = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "alternate")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the maximum amount of burning embers of the target.
--- @name MaxBurningEmbers
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxburningembers = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "burningembers")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the maximum amount of Chi of the target.
--- @name MaxChi
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxchi = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "chi")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the maximum amount of Demonic Fury of the target.
--- @name MaxDemonicFury
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxdemonicfury = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "demonicfury")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the maximum amount of energy of the target.
--- @name MaxEnergy
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxenergy = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "energy")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the maximum amount of focus of the target.
--- @name MaxFocus
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxfocus = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "focus")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the amount of health points of the target when it is at full health.
--- @name MaxHealth
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum health.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if target.MaxHealth() >10000000 Item(mogu_power_potion)
--- if target.MaxHealth(more 10000000) Item(mogu_power_potion)
-
-OvaleCondition.conditions.maxhealth = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	return Compare(API_UnitHealthMax(target), comparator, limit)
-end
-
---- Get the maximum amount of Holy Power of the target.
--- @name MaxHolyPower
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxholypower = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "holy")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the maximum amount of mana of the target.
--- @name MaxMana
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if {MaxMana() - Mana()} > 12500 Item(mana_gem)
-
-OvaleCondition.conditions.maxmana = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "mana")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the maximum amount of rage of the target.
--- @name MaxRage
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxrage = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "rage")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the maximum amount of Runic Power of the target.
--- @name MaxRunicPower
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxrunicpower = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "runicpower")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the maximum amount of Shadow Orbs of the target.
--- @name MaxShadowOrbs
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxshadoworbs = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "shadoworbs")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the maximum amount of Soul Shards of the target.
--- @name MaxSoulShards
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The maximum value.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.maxsoulshards = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local maxi = MaxPower(target, "shards")
-	return Compare(maxi, comparator, limit)
-end
-
---- Get the current melee critical strike chance of the player.
--- @name MeleeCritChance
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
---     Defaults to unlimited=0.
---     Valid values: 0, 1
--- @return The current critical strike chance (in percent).
--- @return A boolean value for the result of the comparison.
--- @see LastMeleeCritChance
--- @usage
--- if MeleeCritChance() >90 Spell(rip)
-
-OvaleCondition.conditions.meleecritchance = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local critChance = OvalePaperDoll.stat.meleeCrit or DEFAULT_CRIT_CHANCE
-	if condition.unlimited ~= 1 and critChance > 100 then
-		critChance = 100
-	end
-	return Compare(critChance, comparator, limit)
-end
-
---- Get the time in seconds until the player's next melee swing (white attack).
--- @name NextSwing
--- @paramsig number or boolean
--- @param hand Optional. Sets which hand weapon's melee swing.
---     If no hand is specified, then return the time until the next swing of either hand's weapon.
---     Valid values: main, off.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of seconds
--- @return A boolean value for the result of the comparison.
--- @see LastSwing
-
-OvaleCondition.conditions.nextswing = function(condition)
-	local swing = condition[1]
-	local comparator, limit
-	if swing and OVALE_COMPARATOR[swing] then
-		comparator, limit = condition[1], condition[2]
-		swing = OvaleSwing:GetNext()
-	else
-		comparator, limit = condition[2], condition[3]
-		swing = OvaleSwing:GetNext(swing)
-	end
-	return TestOvaleValue(0, swing, 0, swing, -1, comparator, limit)
-end
-
---- Get the number of seconds until the next tick of a periodic aura on the target.
--- @name NextTick
--- @paramsig number or boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param filter Optional. The type of aura to check.
---     Default is any.
---     Valid values: any, buff, debuff
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @see Ticks, TicksRemain, TickTime
-
-OvaleCondition.conditions.nexttick = function(condition)
-	self_auraFound.tick = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local tick = self_auraFound.tick
-	if ending and ending < math.huge and tick then
-		while ending - tick > OvaleState.currentTime do
-			ending = ending - tick
-		end
-		return TestOvaleValue(0, ending, 0, ending, -1, comparator, limit)
-	end
-	return nil
-end
-
---- Test if an aura applied by the player is expired, or will expire after a given number of seconds, on every unit other than the current target.
--- @name OtherDebuffExpires
--- @paramsig boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param seconds Optional. The maximum number of seconds before the aura should expire.
---     Defaults to 0 (zero).
--- @param haste Optional. Sets whether "seconds" should be lengthened or shortened due to haste.
---     Defaults to haste=none.
---     Valid values: melee, spell, none.
--- @return A boolean value.
--- @see OtherBuffExpires
--- @usage
--- if OtherDebuffExpires(deep_wounds)
---     Spell(thunder_clap)
-
-OvaleCondition.conditions.otherdebuffexpires = function(condition)
-	local auraId, seconds = condition[1], condition[2]
-	seconds = seconds or 0
-
-	local start, ending = GetAuraOnAnyTarget(condition, "target")
-	if not start or not ending then
-		return nil
-	end
-
-	local timeBefore = TimeWithHaste(seconds, condition.haste)
-	return ending - timeBefore, math.huge
-end
-OvaleCondition.conditions.otherbuffexpires = OvaleCondition.conditions.otherdebuffexpires
-
---- Test if an aura applied by the player is present, or if the remaining time on the aura is more than the given number of seconds, on at least one unit other than the current target.
--- @name OtherDebuffPresent
--- @paramsig boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param seconds Optional. The mininum number of seconds before the aura should expire.
---     Defaults to 0 (zero).
--- @param haste Optional. Sets whether "seconds" should be lengthened or shortened due to haste.
---     Defaults to haste=none.
---     Valid values: melee, spell, none.
--- @return A boolean value.
--- @see OtherBuffPresent
--- @usage
--- if not OtherDebuffPresent(devouring_plague)
---     Spell(devouring_plague)
-
-OvaleCondition.conditions.otherdebuffpresent = function(condition)
-	local auraId, seconds = condition[1], condition[2]
-	seconds = seconds or 0
-
-	local start, ending = GetAuraOnAnyTarget(condition, "target")
-	if not start or not ending then
-		return nil
-	end
-
-	local timeBefore = TimeWithHaste(seconds, condition.haste)
-	return start, ending - timeBefore
-end
-OvaleCondition.conditions.otherbuffpresent = OvaleCondition.conditions.otherdebuffpresent
-
---- Get the remaining time in seconds on an aura applied by the player across every unit other than the current target.
--- @name OtherDebuffRemains
--- @paramsig number or boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of seconds remaining on the aura.
--- @return A boolean value for the result of the comparison.
--- @see OtherBuffRemains
--- @usage
--- if OtherDebuffRemains(devouring_plague) <2
---     Spell(devouring_plague)
-
-OvaleCondition.conditions.otherdebuffremains = function(condition)
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAuraOnAnyTarget(condition, "target")
-	if not start or not ending then
-		return Compare(0, comparator, limit)
-	else
-		return TestOvaleValue(start, ending, ending - start, start, -1, comparator, limit)
-	end
-end
-OvaleCondition.conditions.otherbuffremains = OvaleCondition.conditions.otherdebuffremains
-
---- Test if the pet exists and is alive.
--- PetPresent() is equivalent to pet.Present().
--- @name PetPresent
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if the target exists. If no, then return true if it doesn't exist.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @see Present
--- @usage
--- if target.IsInterruptible() and PetPresent(yes)
---     Spell(pet_pummel)
-
-OvaleCondition.conditions.petpresent = function(condition)
-	local yesno = condition[1]
-	return TestBoolean(API_UnitExists("pet") and not API_UnitIsDead("pet"), yesno)
-end
-
---- Get the resource cost of the given spell.
--- This returns zero for spells that use either mana or another resource based on stance/specialization, e.g., Monk's Jab.
--- @name PowerCost
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The amount of power (energy, focus, rage, etc.).
--- @return A boolean value for the result of the comparison.
--- @see EnergyCost, FocusCost, ManaCost, RageCost
--- @usage
--- if Energy() > PowerCost(rake) Spell(rake)
-
-OvaleCondition.conditions.powercost = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local cost = select(4, API_GetSpellInfo(spellId)) or 0
-	return Compare(cost, comparator, limit)
-end
-OvaleCondition.conditions.energycost = OvaleCondition.conditions.powercost
-OvaleCondition.conditions.focuscost = OvaleCondition.conditions.powercost
-OvaleCondition.conditions.manacost = OvaleCondition.conditions.powercost
-OvaleCondition.conditions.ragecost = OvaleCondition.conditions.powercost
-OvaleCondition.spellbookConditions.energycost = true
-OvaleCondition.spellbookConditions.focuscost = true
-OvaleCondition.spellbookConditions.manacost = true
-OvaleCondition.spellbookConditions.ragecost = true
-OvaleCondition.spellbookConditions.powercost = true
-
---- Test if the target exists and is alive.
--- @name Present
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if the target exists. If no, then return true if it doesn't exist.
---     Default is yes.
---     Valid values: yes, no.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @see Exists
--- @usage
--- if target.IsInterruptible() and pet.Present(yes)
---     Spell(pet_pummel)
-
-OvaleCondition.conditions.present = function(condition)
-	local yesno = condition[1]
-	local target = GetTarget(condition)
-	return TestBoolean(API_UnitExists(target) and not API_UnitIsDead(target), yesno)
-end
-
---- Test if the previous spell cast matches the given spell.
--- @name PreviousSpell
--- @paramsig boolean
--- @param id The spell ID.
--- @param yesno Optional. If yes, then return true if there is a match. If no, then return true if it doesn't match.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
-
-OvaleCondition.conditions.previousspell = function(condition)
-	local spellId, yesno = condition[1], condition[2]
-	return TestBoolean(spellId == OvaleState.lastSpellId, yesno)
-end
-
---- Test if the game is on a PTR server
--- @paramsig boolean
--- @param yesno Optional. If yes, then returns true if it is a PTR realm. If no, return true if it is a live realm.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value
-OvaleCondition.conditions.ptr = function(condition)
-	local yesno = condition[1]
-	local uiVersion = select(4, API_GetBuildInfo())
-	return TestBoolean(uiVersion > 50400, yesno)
-end
-
---- Get the current amount of rage for guardian druids and warriors.
--- @name Rage
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current rage.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if Rage() >70 Spell(heroic_strike)
--- if Rage(more 70) Spell(heroic_strike)
-
-OvaleCondition.conditions.rage = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local value, origin, rate = OvaleState.state.rage, OvaleState.currentTime, OvaleState.powerRate.rage
-	local start, ending = OvaleState.currentTime, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-
---- Get the current ranged critical strike chance of the player.
--- @name RangedCritChance
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
---     Defaults to unlimited=0.
---     Valid values: 0, 1
--- @return The current critical strike chance (in percent).
--- @return A boolean value for the result of the comparison.
--- @see LastRangedCritChance
--- @usage
--- if RangedCritChance() >90 Spell(serpent_sting)
-
-OvaleCondition.conditions.rangedcritchance = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local critChance = OvalePaperDoll.stat.rangedCrit or DEFAULT_CRIT_CHANCE
-	if condition.unlimited ~= 1 and critChance > 100 then
-		critChance = 100
-	end
-	return Compare(critChance, comparator, limit)
-end
-
---- Get the result of the target's level minus the player's level. This number may be negative.
--- @name RelativeLevel
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The difference in levels.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if target.RelativeLevel() >3
---     Texture(ability_rogue_sprint)
--- if target.RelativeLevel(more 3)
---     Texture(ability_rogue_sprint)
-
-OvaleCondition.conditions.relativelevel = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local difference, level
-	if target == "player" then
-		level = OvalePaperDoll.level
-	else
-		level = API_UnitLevel(target)
-	end
-	if level < 0 then
-		difference = 3
-	else
-		difference = level - OvalePaperDoll.level
-	end
-	return Compare(difference, comparator, limit)
-end
-
---- Get the remaining cast time in seconds of the target's current spell cast.
--- @name RemainingCastTime
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @see CastTime
--- @usage
--- if target.Casting(hour_of_twilight) and target.RemainingCastTime() <2
---     Spell(cloak_of_shadows)
-
-OvaleCondition.conditions.remainingcasttime = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local startTime, endTime = select(5, API_UnitCastingInfo(target))
-	if not startTime or not endTime then
-		return nil
-	end
-	startTime = startTime / 1000
-	endTime = endTime / 1000
-	return TestOvaleValue(startTime, endTime, 0, endTime, -1, comparator, limit)
-end
-
---- Get the current number of runes of the given type for death knights.
--- @name RuneCount
--- @paramsig number or boolean
--- @param type The type of rune.
---     Valid values: blood, frost, unholy, death
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param death Sets whether death runes can fulfill the rune count requirements. If set to 1, then death runes are allowed.
---     Defaults to death=0 (zero).
---     Valid values: 0, 1.
--- @return The number of runes.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if RuneCount(unholy) ==2 or RuneCount(frost) ==2 or RuneCount(death) ==2
---     Spell(obliterate)
-
-OvaleCondition.conditions.runecount = function(condition)
-	local rune, comparator, limit = condition[1], condition[2], condition[3]
-	local value, origin, rate = GetRuneCount(rune, condition.death)
-	local start, ending = OvaleState.currentTime, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-
---- Test if the current rune count meets the minimum rune requirements set out in the parameters.
--- This condition takes pairs of "type number" to mean that there must be a minimum of number runes of the named type.
--- E.g., Runes(blood 1 frost 1 unholy 1) means at least one blood, one frost, and one unholy rune is available, death runes included.
--- @name Runes
--- @paramsig boolean
--- @param type The type of rune.
---     Valid values: blood, frost, unholy, death
--- @param number The number of runes
--- @param ... Optional. Additional "type number" pairs for minimum rune requirements.
--- @param nodeath Sets whether death runes can fulfill the rune count requirements. If set to 0, then death runes are allowed.
---     Defaults to nodeath=0 (zero).
---     Valid values: 0, 1.
--- @return A boolean value.
--- @usage
--- if Runes(frost 1) Spell(howling_blast)
-
-OvaleCondition.conditions.runes = function(condition)
-	return GetRunesCooldown(condition)
-end
-
---- Get the number of seconds before the rune conditions are met.
--- This condition takes pairs of "type number" to mean that there must be a minimum of number runes of the named type.
--- E.g., RunesCooldown(blood 1 frost 1 unholy 1) returns the number of seconds before
--- there are at least one blood, one frost, and one unholy rune, death runes included.
--- @name RunesCooldown
--- @paramsig number
--- @param type The type of rune.
---     Valid values: blood, frost, unholy, death
--- @param number The number of runes
--- @param ... Optional. Additional "type number" pairs for minimum rune requirements.
--- @param nodeath Sets whether death runes can fulfill the rune count requirements. If set to 0, then death runes are allowed.
---     Defaults to nodeath=0 (zero).
---     Valid values: 0, 1.
--- @return The number of seconds.
-
-OvaleCondition.conditions.runescooldown = function(condition)
-	local ret = GetRunesCooldown(condition)
-	if not ret then
-		return nil
-	end
-	if ret < OvaleState.maintenant then
-		ret = OvaleState.maintenant
-	end
-	return 0, math.huge, 0, ret, -1
-end
-
---- Get the current amount of runic power for death knights.
--- @name RunicPower
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current runic power.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if RunicPower() >70 Spell(frost_strike)
--- if RunicPower(more 70) Spell(frost_strike)
-
-OvaleCondition.conditions.runicpower = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local value, origin, rate = OvaleState.state.runicpower, OvaleState.currentTime, OvaleState.powerRate.runicpower
-	local start, ending = OvaleState.currentTime, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-
---- Get the current number of Shadow Orbs for shadow priests.
--- @name ShadowOrbs
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of Shadow Orbs.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if ShadowOrbs() >2 Spell(mind_blast)
--- if ShadowOrbs(more 2) Spell(mind_blast)
-
-OvaleCondition.conditions.shadoworbs = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local value, origin, rate = OvaleState.state.shadoworbs, OvaleState.currentTime, OvaleState.powerRate.shadoworbs
-	local start, ending = OvaleState.currentTime, math.huge
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-
---- Get the current number of Soul Shards for warlocks.
--- @name SoulShards
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of Soul Shards.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if SoulShards() >0 Spell(summon_felhunter)
--- if SoulShards(more 0) Spell(summon_felhunter)
-
-OvaleCondition.conditions.soulshards = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvaleState.state.shards, comparator, limit)
-end
-
---- Get the current speed of the target.
--- If the target is not moving, then this condition returns 0 (zero).
--- If the target is at running speed, then this condition returns 100.
--- @name Speed
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The speed of the target.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if Speed(more 0) and not BuffPresent(aspect_of_the_fox)
---     Spell(aspect_of_the_fox)
-
-OvaleCondition.conditions.speed = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	return Compare(API_GetUnitSpeed(target) * 100 / 7, comparator, limit)
-end
-
---- Get the number of charges of the spell.
--- @name SpellCharges
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of charges.
--- @return A boolean value for the result of the comparison.
--- @see SpellChargeCooldown
--- @usage
--- if SpellCharges(savage_defense) >1
---     Spell(savage_defense)
-
-OvaleCondition.conditions.spellcharges = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local charges = API_GetSpellCharges(spellId)
-	return Compare(charges, comparator, limit)
-end
-OvaleCondition.spellbookConditions.spellcharges = true
-
---- Get the cooldown in seconds on a spell before it gains another charge.
--- @name SpellChargeCooldown
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @see SpellCharges
--- @usage
--- if SpellChargeCooldown(roll) <2
---     Spell(roll usable=1)
-
-OvaleCondition.conditions.spellchargecooldown = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local charges, maxCharges, cooldownStart, cooldownDuration = API_GetSpellCharges(spellId)
-	if charges < maxCharges then
-		return TestOvaleValue(cooldownStart, cooldownStart + cooldownDuration, cooldownDuration, cooldownStart, -1, comparator, limit)
-	else
-		return Compare(0, comparator, limit)
-	end
-end
-OvaleCondition.spellbookConditions.spellchargecooldown = true
-
---- Get the cooldown in seconds before a spell is ready for use.
--- @name SpellCooldown
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if ShadowOrbs() ==3 and SpellCooldown(mind_blast) <2
---     Spell(devouring_plague)
-
-OvaleCondition.conditions.spellcooldown = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, duration
-	if type(spellId) == "string" then
-		local sharedCd = OvaleState.state.cd[spellId]
-		if not sharedCd then
-			return nil
-		end
-		start, duration = sharedCd.start, sharedCd.duration
-	elseif not OvaleSpellBook:IsKnownSpell(spellId) then
-		return nil
-	else
-		start, duration = OvaleState:GetComputedSpellCD(spellId)
-	end
-	if start + duration > OvaleState.currentTime then
-		return TestOvaleValue(start, start + duration, duration, start, -1, comparator, limit)
-	else
-		return Compare(0, comparator, limit)
-	end
-end
--- OvaleCondition.spellbookConditions.spellcooldown = true / may be a sharedcd
-
---- Get the current spell critical strike chance of the player.
--- @name SpellCritChance
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
---     Defaults to unlimited=0.
---     Valid values: 0, 1
--- @return The current critical strike chance (in percent).
--- @return A boolean value for the result of the comparison.
--- @see CritChance, LastSpellCritChance
--- @usage
--- if SpellCritChance() >30 Spell(immolate)
-
-OvaleCondition.conditions.spellcritchance = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local critChance = OvalePaperDoll.stat.spellCrit or DEFAULT_CRIT_CHANCE
-	if condition.unlimited ~= 1 and critChance > 100 then
-		critChance = 100
-	end
-	return Compare(critChance, comparator, limit)
-end
-OvaleCondition.conditions.critchance = OvaleCondition.conditions.spellcritchance
-
---- Get data for the given spell defined by SpellInfo(...)
--- @name SpellData
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param key The name of the data set by SpellInfo(...).
---     Valid values are any alphanumeric string.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number data associated with the given key.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if BuffRemains(slice_and_dice) >= SpellData(shadow_blades duration)
---     Spell(shadow_blades)
-
-OvaleCondition.conditions.spelldata = function(condition)
-	local spellId, key, comparator, limit = condition[1], condition[2], condition[3], condition[4]
-	local si = OvaleData.spellInfo[spellId]
-	if si then
-		local data = si[key]
-		if data then
-			return Compare(data, comparator, limit)
-		end
-	end
-	return nil
-end
-
---- Get the current percent increase to spell haste of the player.
--- @name SpellHaste
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current percent increase to spell haste.
--- @return A boolean value for the result of the comparison.
--- @see BuffSpellHaste
--- @usage
--- if SpellHaste() >target.DebuffSpellHaste(moonfire) Spell(moonfire)
-
-OvaleCondition.conditions.spellhaste = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvalePaperDoll.stat.spellHaste, comparator, limit)
-end
-
---- Test if the given spell is in the spellbook.
--- A spell is known if the player has learned the spell and it is in the spellbook.
--- @name SpellKnown
--- @paramsig boolean
--- @param id The spell ID.
--- @param yesno Optional. If yes, then return true if the spell has been learned.
---     If no, then return true if the player hasn't learned the spell.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @see SpellUsable
--- @usage
--- if SpellKnown(avenging_wrath) and SpellCooldown(avenging_wrath) <10
---     Spell(guardian_of_ancient_kings_retribution)
-
-OvaleCondition.conditions.spellknown = function(condition)
-	local spellId, yesno = condition[1], condition[2]
-	return TestBoolean(OvaleSpellBook:IsKnownSpell(spellId), yesno)
-end
-OvaleCondition.spellbookConditions.spellknown = true
-
---- Get the current spellpower of the player.
--- @name Spellpower
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current spellpower.
--- @return A boolean value for the result of the comparison.
--- @see LastSpellpower
--- @usage
--- if {Spellpower() / LastSpellpower(living_bomb)} >1.25
---     Spell(living_bomb)
-
-OvaleCondition.conditions.spellpower = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvalePaperDoll.stat.spellBonusDamage, comparator, limit)
-end
-
---- Test if the given spell is usable.
--- A spell is usable if the player has learned the spell and has the resources required to cast the spell.
--- @name SpellUsable
--- @paramsig boolean
--- @param id The spell ID.
--- @param yesno Optional. If yes, then return true if the spell has been learned and the player has enough resources to cast it.
---     If no, then return true if the player can't cast the spell for one of the above reasons.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @see SpellKnown
--- @usage
--- if SpellUsable(avenging_wrath) and SpellCooldown(avenging_wrath) <10
---     Spell(guardian_of_ancient_kings_retribution)
-
-OvaleCondition.conditions.spellusable = function(condition)
-	local spellId, yesno = condition[1], condition[2]
-	return TestBoolean(API_IsUsableSpell(spellId), yesno)
-end
-OvaleCondition.spellbookConditions.spellusable = true
-
---- Get the current spirit of the player.
--- @name Spirit
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current spirit.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.spirit = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvalePaperDoll.stat.spirit, comparator, limit)
-end
-
---- Get the remaining amount of damage Stagger will cause to the target.
--- @name StaggerRemains
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The amount of damage.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if StaggerRemains() / MaxHealth() >0.4 Spell(purifying_brew)
-
-OvaleCondition.conditions.staggerremains = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local start, ending, stacks
-	-- Heavy Stagger
-	start, ending, stacks = OvaleState:GetAura(target, 124273, "HARMFUL")
-	if not stacks or stacks == 0 then
-		-- Moderate Stagger
-		start, ending, stacks = OvaleState:GetAura(target, 124274, "HARMFUL")
-	end
-	if not stacks or stacks == 0 then
-		-- Light Stagger
-		start, ending, stacks = OvaleState:GetAura(target, 124275, "HARMFUL")
-	end
-	if not start or not ending then
-		return Compare(0, comparator, limit)
-	else
-		local stagger = API_UnitStagger(target)
-		return TestOvaleValue(start, ending, 0, ending, -1 * stagger / (ending - start), comparator, limit)
-	end
-end
-
---- Get the current stamina of the player.
--- @name Stamina
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current stamina.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.stamina = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvalePaperDoll.stat.stamina, comparator, limit)
-end
-
---- Test if the player is in a given stance.
--- @name Stance
--- @paramsig boolean
--- @param stance The stance name or a number representing the stance index.
--- @param yesno Optional. If yes, then return true if the player is in the given stance. If no, then return true otherwise.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- unless Stance(druid_bear_form) Spell(bear_form)
-
-OvaleCondition.conditions.stance = function(condition)
-	local stance, yesno = condition[1], condition[2]
-	return TestBoolean(OvaleStance:IsStance(stance), yesno)
-end
-
---- Test if the player is currently stealthed.
--- The player is stealthed if rogue Stealth, druid Prowl, or a similar ability is active.
--- Note that the rogue Vanish buff causes this condition to return false,
--- but as soon as the buff disappears and the rogue is stealthed, this condition will return true.
--- @name Stealthed
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if stealthed. If no, then return true if it not stealthed.
---     Default is yes.
---     Valid values: yes, no.
--- @return A boolean value.
--- @usage
--- if Stealthed() or BuffPresent(vanish_buff) or BuffPresent(shadow_dance)
---     Spell(ambush)
-
-OvaleCondition.conditions.stealthed = function(condition)
-	local yesno = condition[1]
-	return TestBoolean(API_IsStealthed(), yesno)
-end
-
---- Get the current strength of the player.
--- @name Strength
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The current strength.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.strength = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	return Compare(OvalePaperDoll.stat.strength, comparator, limit)
-end
-
---- Get the number of points spent in a talent (0 or 1)
--- @name TalentPoints
--- @paramsig number or boolean
--- @param talent Talent to inspect.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of talent points.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if TalentPoints(blood_tap_talent) Spell(blood_tap)
-
-OvaleCondition.conditions.talentpoints = function(condition)
-	local talent, comparator, limit = condition[1], condition[2], condition[3]
-	return Compare(OvaleSpellBook:GetTalentPoints(talent), comparator, limit)
-end
-
---- Test if the player is the in-game target of the target.
--- @name TargetIsPlayer
--- @paramsig boolean
--- @param yesno Optional. If yes, then return true if it matches. If no, then return true if it doesn't match.
---     Default is yes.
---     Valid values: yes, no.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return A boolean value.
--- @usage
--- if target.TargetIsPlayer() Spell(feign_death)
-
-OvaleCondition.conditions.targetisplayer = function(condition)
-	local yesno = condition[1]
-	local target = GetTarget(condition)
-	return TestBoolean(API_UnitIsUnit("player", target .. "target"), yesno)
-end
-
---- Get the amount of threat on the current target relative to the its primary aggro target, scaled to between 0 (zero) and 100.
--- This is a number between 0 (no threat) and 100 (will become the primary aggro target).
--- @name Threat
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=target.
---     Valid values: player, target, focus, pet.
--- @return The amount of threat.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if Threat() >90 Spell(fade)
--- if Threat(more 90) Spell(fade)
-
-OvaleCondition.conditions.threat = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition, "target")
-	local threatpct = select(3, API_UnitDetailedThreatSituation("player", target))
-	return Compare(threatpct, comparator, limit)
-end
-
---- Get the total number of ticks of a periodic aura.
--- @name Ticks
--- @paramsig number or boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of ticks.
--- @return A boolean value for the result of the comparison.
--- @see NextTick, TicksRemain, TickTime
-
-OvaleCondition.conditions.ticks = function(condition)
-	self_auraFound.tick = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local tick = self_auraFound.tick
-	local duration, numTicks
-	if start then
-		-- Aura exists on the target
-		if ending and tick and tick > 0 then
-			duration = ending - start
-			numTicks = floor(duration / tick + 0.5)
-		end
-	else
-		duration, tick, numTicks = OvaleState:GetDuration(auraId)
-	end
-	if numTicks then
-		return Compare(numTicks, comparator, limit)
-	else
-		return nil
-	end
-end
-
---- Get the number of ticks that would be added if the dot is refreshed.
--- Not implemented, always returns 0.
--- @name TicksAdded
--- @paramsig number or boolean
--- @param id The aura spell ID
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of added ticks.
--- @return A boolean value for the result of the comparison.
-
-OvaleCondition.conditions.ticksadded = function(condition)
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	return Compare(0, comparator, limit)
-end
-
---- Get the remaining number of ticks of a periodic aura on a target.
--- @name TicksRemain
--- @paramsig number or boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param filter Optional. The type of aura to check.
---     Default is any.
---     Valid values: any, buff, debuff
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of ticks.
--- @return A boolean value for the result of the comparison.
--- @see NextTick, Ticks, TickTime
--- @usage
--- if target.TicksRemain(shadow_word_pain) <2
---     Spell(shadow_word_pain)
-
-OvaleCondition.conditions.ticksremain = function(condition)
-	self_auraFound.tick = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local tick = self_auraFound.tick
-	if ending and tick and tick > 0 then
-		return TestOvaleValue(start, ending, 1, ending, -1/tick, comparator, limit)
-	end
-	return Compare(0, comparator, limit)
-end
-
---- Get the number of seconds between ticks of a periodic aura on a target.
--- @name TickTime
--- @paramsig number or boolean
--- @param id The spell ID of the aura or the name of a spell list.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param filter Optional. The type of aura to check.
---     Default is any.
---     Valid values: any, buff, debuff
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @see NextTick, Ticks, TicksRemain
-
-OvaleCondition.conditions.ticktime = function(condition)
-	self_auraFound.tick = nil
-	local auraId, comparator, limit = condition[1], condition[2], condition[3]
-	local start, ending = GetAura(condition, self_auraFound)
-	local tick = self_auraFound.tick
-	if not tick then
-		tick = OvaleAura:GetTickLength(auraId)
-	end
-	if tick then
-		return Compare(tick, comparator, limit)
-	else
-		return nil
-	end
-end
-
---- Get the number of seconds elapsed since the player entered combat.
--- @name TimeInCombat
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if TimeInCombat(more 5) Spell(bloodlust)
-
-OvaleCondition.conditions.timeincombat = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	if Ovale.enCombat then
-		return TestOvaleValue(Ovale.combatStartTime, math.huge, 0, Ovale.combatStartTime, 1, comparator, limit)
-	else
-		return Compare(0, comparator, limit)
-	end
-end
-
---- Get the estimated number of seconds remaining before the target is dead.
--- @name TimeToDie
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @see DeadIn
--- @usage
--- if target.TimeToDie() <2 and ComboPoints() >0 Spell(eviscerate)
-
-OvaleCondition.conditions.timetodie = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local target = GetTarget(condition)
-	local timeToDie = TimeToDie(target)
-	local value, origin, rate = timeToDie, OvaleState.maintenant, -1
-	local start, ending = OvaleState.maintenant, OvaleState.maintenant + timeToDie
-	return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-end
-OvaleCondition.conditions.deadin = OvaleCondition.conditions.timetodie
-
---- Get the estimated number of seconds remaining before the target is reaches the given percent of max health.
--- @name TimeToHealthPercent
--- @paramsig number or boolean
--- @param percent The percent of maximum health of the target.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
---     Defaults to target=player.
---     Valid values: player, target, focus, pet.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @see TimeToDie
--- @usage
--- if target.TimeToHealthPercent(25) <15 Item(virmens_bite_potion)
-
-OvaleCondition.conditions.timetohealthpercent = function(condition)
-	local percent, comparator, limit = condition[1], condition[2], condition[3]
-	local target = GetTarget(condition)
-	local timeToDie, health, maxHealth = TimeToDie(target)
-	local healthPercent = health / maxHealth * 100
-	if healthPercent >= percent then
-		local t = timeToDie * (healthPercent - percent) / healthPercent
-		local value, origin, rate = t, OvaleState.maintenant, -1
-		local start, ending = OvaleState.maintenant, OvaleState.maintenant + t
-		return TestOvaleValue(start, ending, value, origin, rate, comparator, limit)
-	end
-	return Compare(0, comparator, limit)
-end
-OvaleCondition.conditions.timetolifepercent = OvaleCondition.conditions.timetohealthpercent
-
---- Get the number of seconds before the player reaches maximum energy for feral druids, non-mistweaver monks and rogues.
--- @name TimeToMaxEnergy
--- @paramsig number or boolean
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of seconds.
--- @see TimeToEnergyFor
--- @return A boolean value for the result of the comparison.
--- @usage
--- if TimeToMaxEnergy() < 1.2 Spell(sinister_strike)
-
-OvaleCondition.conditions.timetomaxenergy = function(condition)
-	local comparator, limit = condition[1], condition[2]
-	local maxEnergy = OvalePower.maxPower.energy or 0
-	local t = (maxEnergy - OvaleState.state.energy)/OvaleState.powerRate.energy
-	if t > 0 then
-		return TestOvaleValue(0, OvaleState.currentTime + t, t, OvaleState.currentTime, -1, comparator, limit)
-	else
-		return Compare(0, comparator, limit)
-	end
-end
-
---- Get the number of seconds before the player has enough primary resources to cast the given spell.
--- @name TimeToPowerFor
--- @paramsig number or boolean
--- @param id The spell ID.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The number of seconds.
--- @return A boolean value for the result of the comparison.
--- @see TimeToEnergyFor, TimeToFocusFor, TimeToMaxEnergy
-
-OvaleCondition.conditions.timetopowerfor = function(condition)
-	local spellId, comparator, limit = condition[1], condition[2], condition[3]
-	local cost, _, powerToken = select(4, API_GetSpellInfo(spellId))
-	local powerType = OvalePower.POWER_TYPE[powerToken]
-	local currentPower = OvaleState.state[powerType]
-	local powerRate = OvaleState.powerRate[powerType]
-	cost = cost or 0
-	if currentPower < cost then
-		if powerRate > 0 then
-			local t = (cost - currentPower)/powerRate
-			return TestOvaleValue(0, OvaleState.currentTime + t, t, OvaleState.currentTime, -1, comparator, limit)
-		else
-			return Compare(math.huge, comparator, limit)
-		end
-	else
-		return Compare(0, comparator, limit)
-	end
-end
-OvaleCondition.conditions.timetoenergyfor = OvaleCondition.conditions.timetopowerfor
-OvaleCondition.conditions.timetofocusfor = OvaleCondition.conditions.timetopowerfor
-OvaleCondition.spellbookConditions.timetoenergyfor = true
-OvaleCondition.spellbookConditions.timetofocusfor = true
-OvaleCondition.spellbookConditions.timetopowerfor = true
-
---- Get the time scaled by the specified haste type, defaulting to spell haste.
---- For example, if a DoT normally ticks every 3 seconds and is scaled by spell haste, then it ticks every TimeWithHaste(3 haste=spell) seconds.
--- @name TimeWithHaste
--- @paramsig number or boolean
--- @param time The time in seconds.
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @param haste Optional. Sets whether "time" should be lengthened or shortened due to haste.
---     Defaults to haste=spell.
---     Valid values: melee, spell.
--- @return The time in seconds scaled by haste.
--- @return A boolean value for the result of the comparison.
--- @usage
--- if target.DebuffRemains(flame_shock) < TimeWithHaste(3)
---     Spell(flame_shock)
-
-OvaleCondition.conditions.timewithhaste = function(condition)
-	local seconds, comparator, limit = condition[1], condition[2], condition[3]
-	local haste = condition.haste or "spell"
-	return Compare(TimeWithHaste(seconds, haste), comparator, limit)
-end
-
---- Test if the totem for shamans, the ghoul for death knights, or the statue for monks has expired.
--- @name TotemExpires
--- @paramsig boolean
--- @param id The totem ID of the totem, ghoul or statue, or the type of totem.
---     Valid types: fire, water, air, earth, ghoul, statue.
--- @param seconds Optional. The maximum number of seconds before the totem should expire.
---     Defaults to 0 (zero).
--- @param totem Optional. Sets the specific totem to check of given totem ID type.
---     Valid values: any totem spell ID
--- @return A boolean value.
--- @see TotemPresent
--- @usage
--- if TotemExpires(fire) Spell(searing_totem)
--- if TotemPresent(water totem=healing_stream_totem) and TotemExpires(water 3) Spell(totemic_recall)
-
-OvaleCondition.conditions.totemexpires = function(condition)
-	local totemId, seconds = condition[1], condition[2]
-	seconds = seconds or 0
-	if type(totemId) ~= "number" then
-		totemId = OVALE_TOTEMTYPE[totemId]
-	end
-	local totemName, startTime, duration = select(2, API_GetTotemInfo(totemId))
-	if not startTime then
-		return TestBoolean(true)
-	end
-	if condition.totem and OvaleSpellBook:GetSpellName(condition.totem) ~= totemName then
-		return TestBoolean(true)
-	end
-	return startTime + duration - seconds, math.huge
-end
-
---- Test if the totem for shamans, the ghoul for death knights, or the statue for monks is present.
--- @name TotemPresent
--- @paramsig boolean
--- @param id The totem ID of the totem, ghoul or statue, or the type of totem.
---     Valid types: fire, water, air, earth, ghoul, statue.
--- @param totem Optional. Sets the specific totem to check of given totem ID type.
---     Valid values: any totem spell ID
--- @return A boolean value.
--- @see TotemExpires
--- @usage
--- if not TotemPresent(fire) Spell(searing_totem)
--- if TotemPresent(water totem=healing_stream_totem) and TotemExpires(water 3) Spell(totemic_recall)
-
-OvaleCondition.conditions.totempresent = function(condition)
-	local totemId = condition[1]
-	if type(totemId) ~= "number" then
-		totemId = OVALE_TOTEMTYPE[totemId]
-	end
-	local totemName, startTime, duration = select(2, API_GetTotemInfo(totemId))
-	if not startTime then
-		return nil
-	end
-	if condition.totem and OvaleSpellBook:GetSpellName(condition.totem) ~= totemName then
-		return nil
-	end
-	return startTime, startTime + duration
-end
-
-	-- Check if a tracking is enabled
-	-- 1: the spell id
-	-- return bool
-OvaleCondition.conditions.tracking = function(condition)
-	local spellId, yesno = condition[1], condition[2]
-	local spellName = OvaleSpellBook:GetSpellName(spellId)
-	local numTrackingTypes = API_GetNumTrackingTypes()
-	local present = false
-	for i = 1, numTrackingTypes do
-		local name, _, active = API_GetTrackingInfo(i)
-		if name and name == spellName then
-			return TestBoolean(active == 1, yesno)
-		end
-	end
-	return TestBoolean(false, yesno)
-end
-
---- A condition that always returns true.
--- @name True
--- @paramsig boolean
--- @return A boolean value.
-
-OvaleCondition.conditions["true"] = function(condition)
-	return TestBoolean(true)
-end
-
---- The normalized weapon damage of the weapon in the given hand.
--- @name WeaponDamage
--- @paramsig number or boolean
--- @param hand Optional. Sets which hand weapon.
---     Defaults to main.
---     Valid values: main, off
--- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
--- @param number Optional. The number to compare against.
--- @return The normalized weapon damage.
--- @return A boolean value for the result of the comparison.
--- @usage
--- AddFunction MangleDamage {
---     WeaponDamage() * 5 + 78
--- }
-
-OvaleCondition.conditions.weapondamage = function(condition)
-	local hand = condition[1] or "main"
-	local comparator, limit
-	local damage = 0
-	if hand == "offhand" or hand == "off" then
-		damage = OvalePaperDoll.stat.offHandWeaponDamage
-	elseif hand == "mainhand" or hand == "main" then
-		damage = OvalePaperDoll.stat.mainHandWeaponDamage
-	end
-	if OVALE_COMPARATOR[hand] then
-		comparator, limit = condition[1], condition[2]
-	else
-		comparator, limit = condition[2], condition[3]
-	end
-	return Compare(damage, comparator, limit)
-end
-
---- Test if the weapon imbue on the given weapon has expired or will expire after a given number of seconds.
--- @name WeaponEnchantExpires
--- @paramsig boolean
--- @param hand Sets which hand weapon.
---     Valid values: main, off.
--- @param seconds Optional. The maximum number of seconds before the weapon imbue should expire.
---     Defaults to 0 (zero).
--- @return A boolean value.
--- @usage
--- if WeaponEnchantExpires(main) Spell(windfury_weapon)
-
-OvaleCondition.conditions.weaponenchantexpires = function(condition)
-	local hand, seconds = condition[1], condition[2]
-	seconds = seconds or 0
-	local hasMainHandEnchant, mainHandExpiration, _, hasOffHandEnchant, offHandExpiration = API_GetWeaponEnchantInfo()
-	if hand == "mainhand" or hand == "main" then
-		if not hasMainHandEnchant then
-			return TestBoolean(true)
-		end
-		mainHandExpiration = mainHandExpiration/1000
-		return OvaleState.maintenant + mainHandExpiration - seconds, math.huge
-	else
-		if not hasOffHandEnchant then
-			return TestBoolean(true)
-		end
-		offHandExpiration = offHandExpiration/1000
-		return OvaleState.maintenant + offHandExpiration - seconds, math.huge
-	end
-end
---</public-static-properties>
+--</public-static-methods>
diff --git a/compiler.pl b/compiler.pl
index 483ca61..2399aee 100644
--- a/compiler.pl
+++ b/compiler.pl
@@ -40,6 +40,8 @@ $m{AceGUI}{ClearFocus} = true;
 $m{AceGUI}{RegisterAsContainer} = true;
 $m{AceGUI}{RegisterWidgetType} = true;

+$m{AceLocale}{NewLocale} = true;
+
 $m{"AceTimer-3.0"}{CancelTimer} = true;
 $m{"AceTimer-3.0"}{ScheduleRepeatingTimer} = true;

@@ -73,6 +75,8 @@ $m{GameTooltip}{Show} = true;
 $m{LibDualSpec}{EnhanceDatabase} = true;
 $m{LibDualSpec}{EnhanceOptions} = true;

+$m{LibStub}{GetLibrary} = true;
+
 $m{LRC}{GetRange} = true;

 $m{Masque}{Group} = true;
@@ -92,6 +96,11 @@ $p{Skada}{total} = true;

 $sp{Ovale}{OvaleSkada} = true;

+$sp{OvaleCondition}{Compare} = true;
+$sp{OvaleCondition}{ParseCondition} = true;
+$sp{OvaleCondition}{ParseRuneCondition} = true;
+$sp{OvaleCondition}{TestValue} = true;
+
 $sp{OvaleQueue}{Front} = true;
 $sp{OvaleQueue}{FrontToBackIterator} = true;
 $sp{OvaleQueue}{InsertBack} = true;
@@ -107,172 +116,185 @@ $sp{OvaleTimeSpan}{IntersectInterval} = true;
 $sp{OvaleTimeSpan}{Measure} = true;
 $sp{OvaleTimeSpan}{Union} = true;

-opendir(DIR, ".");
-while (defined($r = readdir(DIR)))
+sub ParseDirectory
 {
-	if ($r =~ m/(Ovale.*)\.lua$/)
+	my $dh = shift;
+	while (defined($r = readdir($dh)))
 	{
-		my $class = $1;
-		open(F, "<", $r);
-		undef $/;
-		my $content = <F>;
-		close(F);
-
-		my %psp = {};
-		my %psm = {};
-		my %pp = {};
-		my %pm = {};
-
-		if ($content =~ m/--inherits (\w+)/)
-		{
-			my $parent = $1;
-			for my $prop (keys %{$sp{$parent}})
-			{
-				$sp{$class}{$prop} = $sp{$parent}{$prop}
-			}
-			for my $method (keys %{$sm{$parent}})
-			{
-				$sm{$class}{$method} = $sm{$parent}{$method}
-			}
-			for my $method (keys %{$m{$parent}})
-			{
-				$m{$class}{$method} = $m{$parent}{$method}
-			}
-		}
-
-		if ($content =~ m/$class\s*=\s*LibStub\("([^)]+)"\):NewAddon\(([^)]+)\)/)
+		if ($r =~ m/(.*)\.lua$/)
 		{
-			my $factory = $1;
-			my $mixins = $2;
-			for my $method (keys %{$m{$factory}})
+			my $class = $1;
+			open(F, "<", $r);
+			undef $/;
+			my $content = <F>;
+			close(F);
+
+			my %psp = {};
+			my %psm = {};
+			my %pp = {};
+			my %pm = {};
+
+			if ($content =~ m/--inherits (\w+)/)
 			{
-				$m{$class}{$method} = $m{$factory}{$method}
+				my $parent = $1;
+				for my $prop (keys %{$sp{$parent}})
+				{
+					$sp{$class}{$prop} = $sp{$parent}{$prop}
+				}
+				for my $method (keys %{$sm{$parent}})
+				{
+					$sm{$class}{$method} = $sm{$parent}{$method}
+				}
+				for my $method (keys %{$m{$parent}})
+				{
+					$m{$class}{$method} = $m{$parent}{$method}
+				}
 			}
-			while ($mixins =~ m/"([^",]+)"/g)
+
+			if ($content =~ m/$class\s*=\s*LibStub\("([^)]+)"\):NewAddon\(([^)]+)\)/)
 			{
-				my $parent = $1;
-				if ($parent ne $class)
+				my $factory = $1;
+				my $mixins = $2;
+				for my $method (keys %{$m{$factory}})
 				{
-					for my $method (keys %{$m{$parent}})
+					$m{$class}{$method} = $m{$factory}{$method}
+				}
+				while ($mixins =~ m/"([^",]+)"/g)
+				{
+					my $parent = $1;
+					if ($parent ne $class)
 					{
-						$m{$class}{$method} = $m{$parent}{$method}
+						for my $method (keys %{$m{$parent}})
+						{
+							$m{$class}{$method} = $m{$parent}{$method}
+						}
 					}
 				}
 			}
-		}
-
-		if ($content =~ m/$class\s*=\s*([^:]+):NewModule\(([^)]+)\)/)
-		{
-			my $parent = $1;
-			my $mixins = $2;
-			$sp{$parent}{$class} = true;
-			while ($mixins =~ m/"([^",]+)"/g)
+
+			if ($content =~ m/$class\s*=\s*([^:]+):NewModule\(([^)]+)\)/)
 			{
 				my $parent = $1;
-				if ($parent ne $class)
+				my $mixins = $2;
+				$sp{$parent}{$class} = true;
+				while ($mixins =~ m/"([^",]+)"/g)
 				{
-					for my $method (keys %{$m{$parent}})
+					my $parent = $1;
+					if ($parent ne $class)
 					{
-						$m{$class}{$method} = $m{$parent}{$method}
+						for my $method (keys %{$m{$parent}})
+						{
+							$m{$class}{$method} = $m{$parent}{$method}
+						}
 					}
 				}
 			}
-		}

-		if ($content =~ m/<private-static-properties>(.*)<\/private-static-properties>/s)
-		{
-			my $psp = $1;
-			while ($psp =~ m/local (\w+)\s*=/g)
+			if ($content =~ m/<private-static-properties>(.*)<\/private-static-properties>/s)
 			{
-				$psp{$1} = true;
+				my $psp = $1;
+				while ($psp =~ m/local (\w+)\s*=/g)
+				{
+					$psp{$1} = true;
+				}
 			}
-		}
-
-		if ($content =~ m/<private-static-methods>(.*)<\/private-static-methods>/s)
-		{
-			my $psm = $1;
-			while ($psm =~ m/local function (\w+)\s*=/g)
+
+			if ($content =~ m/<private-static-methods>(.*)<\/private-static-methods>/s)
 			{
-				$psm{$1} = true;
+				my $psm = $1;
+				while ($psm =~ m/local function (\w+)\s*=/g)
+				{
+					$psm{$1} = true;
+				}
 			}
-		}
-
-		if ($content =~ m/<public-static-properties>(.*)<\/public-static-properties>/s)
-		{
-			my $sp = $1;
-			while ($sp =~ m/${class}\.(\w+)\s*=/g)
+
+			if ($content =~ m/<public-static-properties>(.*)<\/public-static-properties>/s)
 			{
-				$sp{$class}{$1} = true;
+				my $sp = $1;
+				while ($sp =~ m/${class}\.(\w+)\s*=/g)
+				{
+					$sp{$class}{$1} = true;
+				}
 			}
-		}
-
-		if ($content =~ m/<public-static-methods>(.*)<\/public-static-methods>/s)
-		{
-			my $sm = $1;
-			while ($sm =~ m/function\s+$class:(\w+)\s*\(/g)
+
+			if ($content =~ m/<public-static-methods>(.*)<\/public-static-methods>/s)
 			{
-				$sm{$class}{$1} = true;
-				delete $m{$class}{$1}
+				my $sm = $1;
+				while ($sm =~ m/function\s+$class:(\w+)\s*\(/g)
+				{
+					$sm{$class}{$1} = true;
+					delete $m{$class}{$1}
+				}
 			}
-		}
-
-		if ($content =~ m/<public-methods>(.*)<\/public-methods>/s)
-		{
-			my $m = $1;
-			while ($m =~ m/local function (\w+)\(self/g)
+
+			if ($content =~ m/<public-methods>(.*)<\/public-methods>/s)
 			{
-				$m{$class}{$1} = true;
-				delete $sm{$class}{$1}
+				my $m = $1;
+				while ($m =~ m/local function (\w+)\(self/g)
+				{
+					$m{$class}{$1} = true;
+					delete $sm{$class}{$1}
+				}
 			}
-		}
-
-		if ($content =~ m/<public-properties>(.*)<\/public-properties>/s)
-		{
-			my $p = $1;
-			while ($p =~ m/self\.(\w+)/g)
+
+			if ($content =~ m/<public-properties>(.*)<\/public-properties>/s)
 			{
-				$p{$class}{$1} = true;
+				my $p = $1;
+				while ($p =~ m/self\.(\w+)/g)
+				{
+					$p{$class}{$1} = true;
+				}
 			}
-		}
-
-		while ($content =~ m/\b([A-Z]\w+)\.(\w+)/g)
-		{
-			unless ($sp{$1}{$2} or $p{$1}{$2})
+
+			while ($content =~ m/\b([A-Z]\w+)\.(\w+)/g)
 			{
-				$sp{$1}{$2} = $class;
+				unless ($sp{$1}{$2} or $p{$1}{$2})
+				{
+					$sp{$1}{$2} = $class;
+				}
 			}
-		}
-
-		while ($content =~ m/\b([A-Z]\w+)\:(\w+)/g)
-		{
-			unless ($sm{$1}{$2} or $m{$1}{$2})
+
+			while ($content =~ m/\b([A-Z]\w+)\:(\w+)/g)
 			{
-				$sm{$1}{$2} = $class;
+				unless ($sm{$1}{$2} or $m{$1}{$2})
+				{
+					$sm{$1}{$2} = $class;
+				}
 			}
-		}
-
-		while ($content =~ m/self\.([a-z]\w*)/g)
-		{
-			#if ($class eq 'OvaleSwing')
-			#{
-			#	print $1," ",$sp{$class}{$1}," ",$pp{$1}, " ", $p{$class}{$1},"\n";
-			#}
-			unless ($sp{$class}{$1} eq true or $pp{$1} eq true or $p{$class}{$1} eq true)
+
+			while ($content =~ m/self\.([a-z]\w*)/g)
 			{
-				print "La classe $class ne contient pas la proprit $1\n";
+				#if ($class eq 'OvaleSwing')
+				#{
+				#	print $1," ",$sp{$class}{$1}," ",$pp{$1}, " ", $p{$class}{$1},"\n";
+				#}
+				unless ($sp{$class}{$1} eq true or $pp{$1} eq true or $p{$class}{$1} eq true)
+				{
+					print "La classe $class ne contient pas la proprit $1\n";
+				}
 			}
-		}
-
-		while ($content =~ m/self\:(\w+)/g)
-		{
-			unless ($sm{$class}{$1} eq true or $pm{$1} eq true or $m{$class}{$1} eq true)
+
+			while ($content =~ m/self\:(\w+)/g)
 			{
-				print "La classe $class ne contient pas la mthode $1\n";
+				unless ($sm{$class}{$1} eq true or $pm{$1} eq true or $m{$class}{$1} eq true)
+				{
+					print "La classe $class ne contient pas la mthode $1\n";
+				}
 			}
 		}
 	}
 }

+opendir(my $dh, ".");
+ParseDirectory($dh);
+closedir($dh);
+opendir($dh, "conditions");
+ParseDirectory($dh);
+closedir($dh);
+opendir($dh, "scripts");
+ParseDirectory($dh);
+closedir($dh);
+
 for my $class (keys %sm)
 {
 	for my $method (keys %{$sm{$class}})
diff --git a/conditions/AfterWhiteHit.lua b/conditions/AfterWhiteHit.lua
new file mode 100644
index 0000000..7c9dfdf
--- /dev/null
+++ b/conditions/AfterWhiteHit.lua
@@ -0,0 +1,40 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleSwing = Ovale.OvaleSwing
+
+	local TestValue = OvaleCondition.TestValue
+
+	-- Test if a white hit just occured
+	-- 1 : maximum time after a white hit
+	-- Not useful anymore. No widely used spell reset swing timer anyway
+
+	local function AfterWhiteHit(condition)
+		local seconds, comparator, limit = condition[1], condition[2], condition[3]
+		local start = OvaleSwing.starttime
+		local ending = start + OvaleSwing.duration
+		local now = OvaleState.maintenant
+		local value
+		if now - start < seconds then
+			value = 0
+		elseif ending - now > 0.1 then
+			value = ending - now
+		else
+			value = 0.1
+		end
+		return TestValue(start, math.huge, value, OvaleState.maintenant, -1, comparator, limit)
+	end
+
+	--OvaleCondition:RegisterCondition("afterwhitehit", false, AfterWhiteHit)
+end
diff --git a/conditions/ArmorSetParts.lua b/conditions/ArmorSetParts.lua
new file mode 100644
index 0000000..6059526
--- /dev/null
+++ b/conditions/ArmorSetParts.lua
@@ -0,0 +1,41 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleEquipement = Ovale.OvaleEquipement
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get how many pieces of an armor set, e.g., Tier 14 set, are equipped by the player.
+	-- @name ArmorSetParts
+	-- @paramsig number or boolean
+	-- @param name The name of the armor set.
+	--     Valid names: T11, T12, T13, T14, T15.
+	--     Valid names for hybrid classes: append _caster, _heal, _melee, _tank.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of pieces of the named set that are equipped by the player.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if ArmorSetParts(T13) >=2 and target.HealthPercent() <60
+	--     Spell(ferocious_bite)
+	-- if ArmorSetParts(T13 more 1) and TargetHealthPercent(less 60)
+	--     Spell(ferocious_bite)
+
+	local function ArmorSetParts(condition)
+		local armorSet, comparator, limit = condition[1], condition[2], condition[3]
+		local value = OvaleEquipement:GetArmorSetCount(armorSet)
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("armorsetparts", false, ArmorSetParts)
+end
diff --git a/conditions/BuffDamageMultiplier.lua b/conditions/BuffDamageMultiplier.lua
new file mode 100644
index 0000000..cde1dac
--- /dev/null
+++ b/conditions/BuffDamageMultiplier.lua
@@ -0,0 +1,49 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	local auraFound = {}
+
+	--- Get the player's damage multiplier for the given aura at the time the aura was applied on the target.
+	-- @name BuffDamageMultiplier
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The damage multiplier.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffDamageMultiplier
+	-- @usage
+	-- if target.DebuffDamageMultiplier(rake) <1 Spell(rake)
+
+	local function BuffDamageMultiplier(condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		auraFound.comboPoints = nil
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine, auraFound)
+		local baseDamageMultiplier = auraFound.baseDamageMultiplier or 1
+		local damageMultiplier = auraFound.damageMultiplier or 1
+		local value = baseDamageMultiplier * damageMultiplier
+		return TestValue(start, ending, value, start, 0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("buffdamagemultiplier", false, BuffDamageMultiplier)
+	OvaleCondition:RegisterCondition("debuffdamagemultiplier", false, BuffDamageMultiplier)
+end
diff --git a/conditions/BuffDuration.lua b/conditions/BuffDuration.lua
new file mode 100644
index 0000000..aee0b10
--- /dev/null
+++ b/conditions/BuffDuration.lua
@@ -0,0 +1,44 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the total duration of the aura from when it was first applied to when it ended.
+	-- @name BuffDuration
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The total duration of the aura.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffDuration
+
+	local function BuffDuration(condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine)
+		start = start or 0
+		ending = ending or math.huge
+		value = ending - start
+		return TestValue(start, ending, value, start, 0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("buffduration", false, BuffDuration)
+	OvaleCondition:RegisterCondition("debuffduration", false, BuffDuration)
+end
diff --git a/conditions/BuffExpires.lua b/conditions/BuffExpires.lua
new file mode 100644
index 0000000..20cc381
--- /dev/null
+++ b/conditions/BuffExpires.lua
@@ -0,0 +1,117 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePaperDoll = Ovale.PaperDoll
+	local OvaleState = Ovale.OvaleState
+
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	local function TimeWithHaste(t, haste)
+		if not t then
+			t = 0
+		end
+		if not haste then
+			return t
+		elseif haste == "spell" then
+			return t / OvalePaperDoll:GetSpellHasteMultiplier()
+		elseif haste == "melee" then
+			return t / OvalePaperDoll:GetMeleeHasteMultiplier()
+		else
+			Ovale:Logf("Unknown haste parameter haste=%s", haste)
+			return t
+		end
+	end
+
+	--- Test if an aura is expired, or will expire after a given number of seconds.
+	-- @name BuffExpires
+	-- @paramsig boolean
+	-- @param id The spell ID of the aura or the name of a spell list.
+	-- @param seconds Optional. The maximum number of seconds before the buff should expire.
+	--     Defaults to 0 (zero).
+	-- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
+	--     Defaults to any=0.
+	--     Valid values: 0, 1.
+	-- @param haste Optional. Sets whether "seconds" should be lengthened or shortened due to haste.
+	--     Defaults to haste=none.
+	--     Valid values: melee, spell, none.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @see DebuffExpires
+	-- @usage
+	-- if BuffExpires(stamina any=1)
+	--     Spell(power_word_fortitude)
+	-- if target.DebuffExpires(rake 2)
+	--     Spell(rake)
+
+	local function BuffExpires(condition)
+		local auraId, seconds = condition[1], condition[2]
+		local target, filter, mine = ParseCondition(condition)
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine)
+		if not start or not ending then
+			return 0, math.huge
+		end
+		seconds = TimeWithHaste(seconds or 0, condition.haste)
+		if ending - seconds <= start then
+			return start, math.huge
+		else
+			return ending - seconds, math.huge
+		end
+	end
+
+	OvaleCondition:RegisterCondition("buffexpires", false, BuffExpires)
+	OvaleCondition:RegisterCondition("debuffexpires", false, BuffExpires)
+
+	--- Test if an aura is present or if the remaining time on the aura is more than the given number of seconds.
+	-- @name BuffPresent
+	-- @paramsig boolean
+	-- @param id The spell ID of the aura or the name of a spell list.
+	-- @param seconds Optional. The mininum number of seconds before the buff should expire.
+	--     Defaults to 0 (zero).
+	-- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
+	--     Defaults to any=0.
+	--     Valid values: 0, 1.
+	-- @param haste Optional. Sets whether "seconds" should be lengthened or shortened due to haste.
+	--     Defaults to haste=none.
+	--     Valid values: melee, spell, none.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @see DebuffPresent
+	-- @usage
+	-- if not BuffPresent(stamina any=1)
+	--     Spell(power_word_fortitude)
+	-- if not target.DebuffPresent(rake 2)
+	--     Spell(rake)
+
+	local function BuffPresent(condition)
+		local auraId, seconds = condition[1], condition[2]
+		local target, filter, mine = ParseCondition(condition)
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine)
+		if not start or not ending then
+			return nil
+		end
+		seconds = TimeWithHaste(seconds or 0, condition.haste)
+		if ending - seconds <= start then
+			return nil
+		else
+			return start, ending - seconds
+		end
+	end
+
+	OvaleCondition:RegisterCondition("buffpresent", false, BuffPresent)
+	OvaleCondition:RegisterCondition("debuffpresent", false, BuffPresent)
+end
diff --git a/conditions/BuffGain.lua b/conditions/BuffGain.lua
new file mode 100644
index 0000000..18e151e
--- /dev/null
+++ b/conditions/BuffGain.lua
@@ -0,0 +1,51 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	local auraFound = {}
+
+	--- Get the time elapsed since the aura was last gained on the target.
+	-- @paramsig number or boolean
+	-- @param id The spell ID of the aura or the name of a spell list.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
+	--     Defaults to any=0.
+	--     Valid values: 0, 1.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffGain
+
+	local function BuffGain(condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		auraFound.gain = nil
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine, auraFound)
+		local gain = auraFound.gain or 0
+		if true then
+			Ovale:Error("not implemented")
+			return nil
+		end
+		return TestValue(gain, math.huge, 0, gain, 1, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("buffgain", false, BuffGain)
+	OvaleCondition:RegisterCondition("debuffgain", false, BuffGain)
+end
\ No newline at end of file
diff --git a/conditions/BuffRemains.lua b/conditions/BuffRemains.lua
new file mode 100644
index 0000000..0ff47ef
--- /dev/null
+++ b/conditions/BuffRemains.lua
@@ -0,0 +1,52 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the remaining time in seconds on an aura.
+	-- @name BuffRemains
+	-- @paramsig number or boolean
+	-- @param id The spell ID of the aura or the name of a spell list.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
+	--     Defaults to any=0.
+	--     Valid values: 0, 1.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of seconds remaining on the aura.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffRemains
+	-- @usage
+	-- if BuffRemains(slice_and_dice) <2
+	--     Spell(slice_and_dice)
+
+	local function BuffRemains(condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine)
+		if not start or not ending then
+			return Compare(0, comparator, limit)
+		else
+			return TestValue(start, ending, ending - start, start, -1, comparator, limit)
+		end
+	end
+
+	OvaleCondition:RegisterCondition("buffremains", false, BuffRemains)
+	OvaleCondition:RegisterCondition("debuffremains", false, BuffRemains)
+end
diff --git a/conditions/BuffSnapshot.lua b/conditions/BuffSnapshot.lua
new file mode 100644
index 0000000..adbd754
--- /dev/null
+++ b/conditions/BuffSnapshot.lua
@@ -0,0 +1,297 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	local auraFound = {}
+
+	-- Return the value of the stat from the aura snapshot at the time the aura was applied.
+	local function BuffSnapshot(statName, defaultValue, condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		auraFound[statName] = nil
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine, auraFound)
+		local value = auraFound[statName]
+		value = value and value or defaultValue
+		return TestValue(start, ending, value, start, 0, comparator, limit)
+	end
+
+	-- Return the value of the given critical strike chance from the aura snapshot at the time the aura was applied.
+	local function BuffSnapshotCritChance(statName, defaultValue, condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		auraFound[statName] = nil
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine, auraFound)
+		local value = auraFound[statName]
+		value = value and value or defaultValue
+		if condition.unlimited ~= 1 and value > 100 then
+			value = 100
+		end
+		return TestValue(start, ending, value, start, 0, comparator, limit)
+	end
+
+	--- Get the value of a buff as a number.  Not all buffs return an amount.
+	-- @name BuffAmount
+	-- @paramsig number
+	-- @param id The spell ID of the aura or the name of a spell list.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
+	--     Defaults to any=0.
+	--     Valid values: 0, 1.
+	-- @param value Optional. Sets which aura value to return from UnitAura().
+	--     Defaults to value=1.
+	--     Valid values: 1, 2, 3.
+	-- @return The value of the buff as a number.
+	-- @see DebuffAmount
+	-- @see TickValue
+	-- @usage
+	-- if DebuffAmount(stagger) >10000 Spell(purifying_brew)
+	-- if DebuffAmount(stagger more 10000) Spell(purifying_brew)
+
+	local function BuffAmount(condition)
+		local value = condition.value or 1
+		local statName
+		if value == 1 then
+			statName = "value1"
+		elseif value == 2 then
+			statName = "value2"
+		elseif value == 3 then
+			statName = "value3"
+		else
+			statName = "value1"
+		end
+		return BuffSnapshot(statName, 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("buffamount", false, BuffAmount)
+	OvaleCondition:RegisterCondition("debuffamount", false, BuffAmount)
+	OvaleCondition:RegisterCondition("tickvalue", false, BuffAmount)
+
+	--- Get the player's attack power at the time the given aura was applied on the target.
+	-- @name BuffAttackPower
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The attack power.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffAttackPower
+	-- @usage
+	-- if AttackPower() >target.DebuffAttackPower(rake) Spell(rake)
+
+	local function BuffAttackPower(condition)
+		return BuffSnapshot("attackPower", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("buffattackpower", false, BuffAttackPower)
+	OvaleCondition:RegisterCondition("debuffattackpower", false, BuffAttackPower)
+
+	--- Get the player's combo points for the given aura at the time the aura was applied on the target.
+	-- @name BuffComboPoints
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of combo points.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffComboPoints
+	-- @usage
+	-- if target.DebuffComboPoints(rip) <5 Spell(rip)
+
+	local function BuffComboPoints(condition)
+		-- If the buff is presetnt, then it had at least one combo point.
+		return BuffSnapshot("comboPoints", 1, condition)
+	end
+
+	OvaleCondition:RegisterCondition("buffcombopoints", false, BuffComboPoints)
+	OvaleCondition:RegisterCondition("debuffcombopoints", false, BuffComboPoints)
+
+	--- Get the player's mastery effect at the time the given aura was applied on the target.
+	-- @name BuffMasteryEffect
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The mastery effect.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffMasteryEffect
+	-- @usage
+	-- if MasteryEffect() >target.DebuffMasteryEffect(rip) Spell(rip)
+
+	local function BuffMasteryEffect(condition)
+		return BuffSnapshot("masteryEffect", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("buffmastery", false, BuffMasteryEffect)
+	OvaleCondition:RegisterCondition("buffmasteryeffect", false, BuffMasteryEffect)
+	OvaleCondition:RegisterCondition("debuffmastery", false, BuffMasteryEffect)
+	OvaleCondition:RegisterCondition("debuffmasteryeffect", false, BuffMasteryEffect)
+
+	--- Get the player's melee critical strike chance at the time the given aura was applied on the target.
+	-- @name BuffMeleeCritChance
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
+	--     Defaults to unlimited=0.
+	--     Valid values: 0, 1
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The critical strike chance.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffMeleeCritChance
+	-- @usage
+	-- if MeleeCritChance() >target.DebuffMeleeCritChance(rake) Spell(rake)
+
+	local function BuffMeleeCritChance(condition)
+		return BuffSnapshotCritChance("meleeCrit", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("buffmeleecritchance", false, BuffMeleeCritChance)
+	OvaleCondition:RegisterCondition("debuffmeleecritchance", false, BuffMeleeCritChance)
+
+	--- Get the player's ranged attack power at the time the given aura was applied on the target.
+	-- @name BuffRangedAttackPower
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The ranged attack power.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffRangedAttackPower
+	-- @usage
+	-- if RangedAttackPower() >target.DebuffRangedAttackPower(serpent_sting_dot)
+	--     Spell(serpent_sting)
+
+	local function BuffRangedAttackPower(condition)
+		return BuffSnapshot("rangedAttackPower", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("buffrangedattackpower", false, BuffRangedAttackPower)
+	OvaleCondition:RegisterCondition("debuffrangedattackpower", false, BuffRangedAttackPower)
+
+	--- Get the player's ranged critical strike chance at the time the given aura was applied on the target.
+	-- @name BuffRangedCritChance
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
+	--     Defaults to unlimited=0.
+	--     Valid values: 0, 1
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The critical strike chance.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffRangedCritChance
+	-- @usage
+	-- if RangedCritChance() >target.DebuffRangedCritChance(serpent_sting_dot)
+	--     Spell(serpent_sting)
+
+	local function BuffRangedCritChance(condition)
+		return BuffSnapshotCritChance("rangedCrit", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("buffrangedcritchance", false, BuffRangedCritChance)
+	OvaleCondition:RegisterCondition("debuffrangedcritchance", false, BuffRangedCritChance)
+
+	--- Get the player's spell critical strike chance at the time the given aura was applied on the target.
+	-- @name BuffSpellCritChance
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
+	--     Defaults to unlimited=0.
+	--     Valid values: 0, 1
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The critical strike chance.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffSpellCritChance
+	-- @usage
+	-- if SpellCritChance() >target.DebuffSpellCritChance(moonfire) Spell(moonfire)
+
+	local function BuffSpellCritChance(condition)
+		return BuffSnapshotCritChance("spellCrit", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("buffspellcritchance", false, BuffSpellCritChance)
+	OvaleCondition:RegisterCondition("debuffspellcritchance", false, BuffSpellCritChance)
+
+	--- Get the player's spell haste at the time the given aura was applied on the target.
+	-- @name BuffSpellHaste
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param id The aura spell ID.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The percent increase to spell haste.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffSpellHaste
+	-- @usage
+	-- if SpellHaste() >target.DebuffSpellHaste(moonfire) Spell(moonfire)
+
+	local function BuffSpellHaste(condition)
+		return BuffSnapshot("spellHaste", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("buffspellhaste", false, BuffSpellHaste)
+	OvaleCondition:RegisterCondition("debuffspellhaste", false, BuffSpellHaste)
+
+	--- Get the player's spellpower at the time the given aura was applied on the target.
+	-- @name BuffSpellpower
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The spellpower.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffSpellpower
+	-- @usage
+	-- if Spellpower() >target.DebuffSpellpower(moonfire) Spell(moonfire)
+
+	local function BuffSpellpower(condition)
+		return BuffSnapshot("spellBonusDamage", 0, condition)
+	end
+	OvaleCondition:RegisterCondition("buffspellpower", false, BuffSpellpower)
+	OvaleCondition:RegisterCondition("debuffspellpower", false, BuffSpellpower)
+end
diff --git a/conditions/BuffStacks.lua b/conditions/BuffStacks.lua
new file mode 100644
index 0000000..06aad2b
--- /dev/null
+++ b/conditions/BuffStacks.lua
@@ -0,0 +1,50 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the number of stacks of an aura on the target.
+	-- @name BuffStacks
+	-- @paramsig number or boolean
+	-- @param id The spell ID of the aura or the name of a spell list.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
+	--     Defaults to any=0.
+	--     Valid values: 0, 1.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of stacks of the aura.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DebuffStacks
+	-- @usage
+	-- if BuffStacks(pet_frenzy any=1) ==5
+	--     Spell(focus_fire)
+	-- if target.DebuffStacks(weakened_armor) <3
+	--     Spell(faerie_fire)
+
+	local function BuffStacks(condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		local start, ending, stacks = OvaleState:GetAura(target, auraId, filter, mine)
+		stacks = stacks or 0
+		return TestValue(start, ending, stacks, start, 0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("buffstacks", false, BuffStacks)
+	OvaleCondition:RegisterCondition("debuffstacks", false, BuffStacks)
+end
diff --git a/conditions/BuffStealable.lua b/conditions/BuffStealable.lua
new file mode 100644
index 0000000..57c5b0f
--- /dev/null
+++ b/conditions/BuffStealable.lua
@@ -0,0 +1,36 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleAura = Ovale.OvaleAura
+
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	--- Test if there is a stealable buff on the target.
+	-- @name BuffStealable
+	-- @paramsig boolean
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- if target.BuffStealable()
+	--     Spell(spellsteal)
+
+	local function BuffStealable(condition)
+		-- TODO: This should really be checked only against OvaleState.
+		local target = ParseCondition(condition)
+		return OvaleAura:GetStealable(target)
+	end
+
+	OvaleCondition:RegisterCondition("buffstealable", false, BuffStealable)
+end
diff --git a/conditions/CanCast.lua b/conditions/CanCast.lua
new file mode 100644
index 0000000..461ca94
--- /dev/null
+++ b/conditions/CanCast.lua
@@ -0,0 +1,30 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	--- Check if the player can cast the given spell (not on cooldown).
+	-- @name CanCast
+	-- @paramsig boolean
+	-- @param id The spell ID to check.
+	-- @return True if the spell cast be cast; otherwise, false.
+
+	local function CanCast(condition)
+		local spellId = condition[1]
+		local actionCooldownStart, actionCooldownDuration = OvaleState:GetComputedSpellCD(spellId)
+		return actionCooldownStart + actionCooldownDuration, math.huge
+	end
+
+	OvaleCondition:RegisterCondition("cancast", true, CanCast)
+end
diff --git a/conditions/CastTime.lua b/conditions/CastTime.lua
new file mode 100644
index 0000000..36a0a50
--- /dev/null
+++ b/conditions/CastTime.lua
@@ -0,0 +1,50 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local select = select
+	local API_GetSpellInfo = GetSpellInfo
+	local Compare = OvaleCondition.Compare
+
+	--- Get the cast time in seconds of the spell for the player, taking into account current haste effects.
+	-- @name CastTime
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see RemainingCastTime
+	-- @usage
+	-- if target.DebuffRemains(flame_shock) < CastTime(lava_burst)
+	--     Spell(lava_burst)
+
+	local function CastTime(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local castTime = 0
+		if spellId then
+			castTime = select(7, API_GetSpellInfo(spellId))
+			if castTime then
+				castTime = castTime / 1000
+				Ovale:Logf("castTime = %f %s %s", castTime, comparator, limit)
+			end
+		end
+		return Compare(castTime, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("casttime", true, CastTime)
+end
diff --git a/conditions/Casting.lua b/conditions/Casting.lua
new file mode 100644
index 0000000..94937b5
--- /dev/null
+++ b/conditions/Casting.lua
@@ -0,0 +1,108 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleData = Ovale.OvaleData
+	local OvaleSpellBook = Ovale.OvaleSpellBook
+	local OvaleState = Ovale.OvaleState
+
+	local pairs = pairs
+	local type = type
+	local API_IsHarmfulSpell = IsHarmfulSpell
+	local API_IsHelpfulSpell = IsHelpfulSpell
+	local API_UnitCastingInfo = UnitCastingInfo
+	local API_UnitChannelInfo = UnitChannelInfo
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	local function IsSameSpell(spellIdA, spellIdB, spellNameB)
+		if spellIdB then
+			return spellIdA == spellIdB
+		elseif spellIdA and spellNameB then
+			return OvaleSpellBook:GetSpellName(spellIdA) == spellNameB
+		else
+			return false
+		end
+	end
+
+	--- Test if the target is casting the given spell.
+	-- The spell may be specified either by spell ID, localized spell name, spell list name (as defined in SpellList),
+	-- "harmful" for any harmful spell, or "helpful" for any helpful spell.
+	-- @name Casting
+	-- @paramsig boolean
+	-- @param spell The spell to check.
+	--     Valid values: spell ID, spell name, spell list name, harmful, helpful
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- Define(maloriak_release_aberrations 77569)
+	-- if target.Casting(maloriak_release_aberrations)
+	--     Spell(pummel)
+
+	local function Casting(condition)
+		local spellId = condition[1]
+		local target = ParseCondition(condition)
+		local start, ending, castSpellId, castSpellName, _
+		if target == "player" then
+			start = OvaleState.startCast
+			ending = OvaleState.endCast
+			castSpellId = OvaleState.currentSpellId
+		else
+			castSpellName, _, _, _, start, ending = API_UnitCastingInfo(target)
+			if not castSpellName then
+				castSpellName, _, _, _, start, ending = API_UnitChannelInfo(target)
+			end
+		end
+		if not castSpellId and not castSpellName then
+			return nil
+		end
+		if not spellId then
+			return start, ending
+		elseif type(spellId) == "number" then
+			if IsSameSpell(spellId, castSpellId, castSpellName) then
+				return start, ending
+			else
+				return nil
+			end
+		elseif OvaleData.buffSpellList[spellId] then
+			local found = false
+			for auraId in pairs(OvaleData.buffSpellList[spellId]) do
+				if IsSameSpell(auraId, castSpellId, castSpellName) then
+					return start, ending
+				end
+			end
+			return nil
+		elseif spellId == "harmful" then
+			if not castSpellName then
+				castSpellName = OvaleSpellBook:GetSpellName(castSpellId)
+			end
+			if API_IsHarmfulSpell(castSpellName) then
+				return start, ending
+			else
+				return nil
+			end
+		elseif spellId == "helpful" then
+			if not castSpellName then
+				castSpellName = OvaleSpellBook:GetSpellName(castSpellId)
+			end
+			if API_IsHelpfulSpell(castSpellName) then
+				return start, ending
+			else
+				return nil
+			end
+		end
+	end
+
+	OvaleCondition:RegisterCondition("casting", false, casting)
+end
diff --git a/conditions/CheckBox.lua b/conditions/CheckBox.lua
new file mode 100644
index 0000000..ece2999
--- /dev/null
+++ b/conditions/CheckBox.lua
@@ -0,0 +1,57 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	--- Test if all of the listed checkboxes are off.
+	-- @name CheckBoxOff
+	-- @paramsig boolean
+	-- @param id The name of a checkbox. It should match one defined by AddCheckBox(...).
+	-- @param ... Optional. Additional checkbox names.
+	-- @return A boolean value.
+	-- @see CheckBoxOn
+	-- @usage
+	-- AddCheckBox(opt_black_arrow "Black Arrow" default)
+	-- if CheckBoxOff(opt_black_arrow) Spell(explosive_trap)
+
+	local function CheckBoxOff(condition)
+		for i = 1, #condition do
+			if Ovale:IsChecked(condition[i]) then
+				return nil
+			end
+		end
+		return 0, math.huge
+	end
+
+	--- Test if all of the listed checkboxes are on.
+	-- @name CheckBoxOn
+	-- @paramsig boolean
+	-- @param id The name of a checkbox. It should match one defined by AddCheckBox(...).
+	-- @param ... Optional. Additional checkbox names.
+	-- @return A boolean value.
+	-- @see CheckBoxOff
+	-- @usage
+	-- AddCheckBox(opt_black_arrow "Black Arrow" default)
+	-- if CheckBoxOn(opt_black_arrow) Spell(black_arrow)
+
+	local function CheckBoxOn(condition)
+		for i = 1, #condition do
+			if not Ovale:IsChecked(condition[i]) then
+				return nil
+			end
+		end
+		return 0, math.huge
+	end
+
+	OvaleCondition:RegisterCondition("checkboxoff", false, CheckBoxOff)
+	OvaleCondition:RegisterCondition("checkboxon", false, CheckBoxOn)
+end
diff --git a/conditions/Class.lua b/conditions/Class.lua
new file mode 100644
index 0000000..2832080
--- /dev/null
+++ b/conditions/Class.lua
@@ -0,0 +1,43 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitClass = UnitClass
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test whether the target's class matches the given class.
+	-- @name Class
+	-- @paramsig boolean
+	-- @param class The class to check.
+	--     Valid values: DEATHKNIGHT, DRUID, HUNTER, MAGE, MONK, PALADIN, PRIEST, ROGUE, SHAMAN, WARLOCK, WARRIOR.
+	-- @param yesno Optional. If yes, then return true if it matches. If no, then return true if it doesn't match.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- if target.Class(PRIEST) Spell(cheap_shot)
+
+	local function Class(condition)
+		local class, yesno = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local _, classToken = API_UnitClass(target)
+		local boolean = (classToken == class)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("class", false, Class)
+end
diff --git a/conditions/Classification.lua b/conditions/Classification.lua
new file mode 100644
index 0000000..d0d2911
--- /dev/null
+++ b/conditions/Classification.lua
@@ -0,0 +1,54 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitClassification = UnitClassification
+	local API_UnitLevel = UnitLevel
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test whether the target's classification matches the given classification.
+	-- @name Classification
+	-- @paramsig boolean
+	-- @param classification The unit classification to check.
+	--     Valid values: normal, elite, worldboss.
+	-- @param yesno Optional. If yes, then return true if it matches. If no, then return true if it doesn't match.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- if target.Classification(worldboss) Item(virmens_bite_potion)
+
+	local function Classification(condition)
+		local classification, yesno = condition[1], condition[2]
+		local targetClassification
+		local target = ParseCondition(condition)
+		if API_UnitLevel(target) < 0 then
+			targetClassification = "worldboss"
+		else
+			targetClassification = API_UnitClassification(target)
+			if targetClassification == "rareelite" then
+				targetClassification = "elite"
+			elseif targetClassification == "rare" then
+				targetClassification = "normal"
+			end
+		end
+		local boolean = (targetClassification == classification)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("classification", false, Classification)
+end
diff --git a/conditions/ComboPoints.lua b/conditions/ComboPoints.lua
new file mode 100644
index 0000000..559ffeb
--- /dev/null
+++ b/conditions/ComboPoints.lua
@@ -0,0 +1,37 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the number of combo points on the currently selected target for a feral druid or a rogue.
+	-- @name ComboPoints
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of combo points.
+	-- @return A boolean value for the result of the comparison.
+	-- @see LastComboPoints
+	-- @usage
+	-- if ComboPoints() >=1 Spell(savage_roar)
+	-- if ComboPoints(more 0) Spell(savage_roar)
+
+	local function ComboPoints(condition)
+		local comparator, limit = condition[1], condition[2]
+		local value = OvaleState.state.combo
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("combopoints", false, ComboPoints)
+end
diff --git a/conditions/Counter.lua b/conditions/Counter.lua
new file mode 100644
index 0000000..b507cdc
--- /dev/null
+++ b/conditions/Counter.lua
@@ -0,0 +1,34 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the current value of a script counter.
+	-- @name Counter
+	-- @paramsig number or boolean
+	-- @param id The name of the counter. It should match one that's defined by inccounter=xxx in SpellInfo(...).
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current value the counter.
+	-- @return A boolean value for the result of the comparison.
+
+	local function Counter(condition)
+		local counter, comparator, limit = condition[1], condition[2], condition[3]
+		local value = OvaleState:GetCounterValue(counter)
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("counter", false, Counter)
+end
diff --git a/conditions/CreatureFamily.lua b/conditions/CreatureFamily.lua
new file mode 100644
index 0000000..45378d8
--- /dev/null
+++ b/conditions/CreatureFamily.lua
@@ -0,0 +1,50 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local LBCT = LibStub("LibBabble-CreatureType-3.0"):GetLookupTable()
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitCreatureFamily = UnitCreatureFamily
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test whether the target's creature family matches the given name.
+	-- Applies only to beasts that can be taken as hunter pets (e.g., cats, worms, and ravagers but not zhevras, talbuks and pterrordax),
+	-- demons that can be summoned by Warlocks (e.g., imps and felguards, but not demons that require enslaving such as infernals
+	-- and doomguards or world demons such as pit lords and armored voidwalkers), and Death Knight's pets (ghouls)
+	-- @name CreatureFamily
+	-- @paramsig boolean
+	-- @param name The English name of the creature family to check.
+	--     Valid values: Bat, Beast, Felguard, Imp, Ravager, etc.
+	-- @param yesno Optional. If yes, then return true if it matches. If no, then return true if it doesn't match.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- if pet.CreatureFamily(Felguard)
+	--     Spell(summon_felhunter)
+	-- if target.CreatureFamily(Dragonkin)
+	--     Spell(hibernate)
+
+	local function CreatureFamily(condition)
+		local name, yesno = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local family = API_UnitCreatureFamily(target)
+		local boolean = (family == LBCT[name])
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("creaturefamily", false, CreatureFamily)
+end
diff --git a/conditions/CreatureType.lua b/conditions/CreatureType.lua
new file mode 100644
index 0000000..9043158
--- /dev/null
+++ b/conditions/CreatureType.lua
@@ -0,0 +1,45 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local LBCT = LibStub("LibBabble-CreatureType-3.0"):GetLookupTable()
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitCreatureType = UnitCreatureType
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	--- Test if the target is any of the listed creature types.
+	-- @name CreatureType
+	-- @paramsig boolean
+	-- @param name The English name of a creature type.
+	--     Valid values: Beast, Humanoid, Undead, etc.
+	-- @param ... Optional. Additional creature types.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- if target.CreatureType(Humanoid Critter)
+	--     Spell(polymorph)
+
+	local function CreatureType(condition)
+		local target = ParseCondition(condition)
+		local creatureType = API_UnitCreatureType(target)
+		for i = 1, #condition do
+			if creatureType == LBCT[condition[i]] then
+				return 0, math.huge
+			end
+		end
+		return nil
+	end
+
+	OvaleCondition:RegisterCondition("creaturetype", false, CreatureType)
+end
diff --git a/conditions/Damage.lua b/conditions/Damage.lua
new file mode 100644
index 0000000..a45c37f
--- /dev/null
+++ b/conditions/Damage.lua
@@ -0,0 +1,83 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleData = Ovale.OvaleData
+	local OvalePaperDoll = Ovale.OvalePaperDoll
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+
+	-- Return the non-critical-strike damage of a spell, given the player's current stats.
+	local function GetDamage(spellId)
+		-- TODO: Use target's debuffs in this calculation.
+		local ap = OvalePaperDoll.stat.attackPower or 0
+		local sp = OvalePaperDoll.stat.spellBonusDamage or 0
+		local mh = OvalePaperDoll.stat.mainHandWeaponDamage or 0
+		local oh = OvalePaperDoll.stat.offHandWeaponDamage or 0
+		local bdm = OvalePaperDoll.stat.baseDamageMultiplier or 1
+		local dm = OvaleState:GetDamageMultiplier(spellId) or 1
+		local combo = OvaleState.state.combo or 0
+		return OvaleData:GetDamage(spellId, ap, sp, mh, oh, combo) * bdm * dm
+	end
+
+	--- Get the current estimated damage of a spell on the target if it is a critical strike.
+	-- @name CritDamage
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The estimated critical strike damage of the given spell.
+	-- @return A boolean value for the result of the comparison.
+	-- @see Damage, LastDamage, LastEstimatedDamage
+
+	local function CritDamage(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		-- TODO: Need to account for increased crit effect from meta-gems.
+		local critFactor = 2
+		local value = critFactor * GetDamage(spellId)
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("critdamage", false, CritDamage)
+
+	--- Get the current estimated damage of a spell on the target.
+	-- The calculated damage takes into account the current attack power, spellpower, weapon damage and combo points (if used).
+	-- The damage is computed from information for the spell set via SpellInfo(...):
+	--
+	-- damage = base + bonusmainhand * MH + bonusoffhand * OH + bonusap * AP + bonuscp * CP + bonusapcp * AP * CP + bonussp * SP
+	-- @name Damage
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The estimated damage of the given spell on the target.
+	-- @return A boolean value for the result of the comparison.
+	-- @see CritDamage, LastDamage, LastEstimatedDamage
+	-- @usage
+	-- if {target.Damage(rake) / target.LastEstimateDamage(rake)} >1.1
+	--     Spell(rake)
+
+	local function Damage(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local value = GetDamage(spellId)
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("damage", false, Damage)
+end
diff --git a/conditions/DamageMultiplier.lua b/conditions/DamageMultiplier.lua
new file mode 100644
index 0000000..2778334
--- /dev/null
+++ b/conditions/DamageMultiplier.lua
@@ -0,0 +1,42 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePaperDoll = Ovale.OvalePaperDoll
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the current damage multiplier of a spell.
+	-- This currently does not take into account increased damage due to mastery.
+	-- @name DamageMultiplier
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current damage multiplier of the given spell.
+	-- @return A boolean value for the result of the comparison.
+	-- @see LastDamageMultiplier
+	-- @usage
+	-- if {DamageMultiplier(rupture) / LastDamageMultiplier(rupture)} >1.1
+	--     Spell(rupture)
+
+	local function DamageMultiplier(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local bdm = OvalePaperDoll.stat.baseDamageMultiplier
+		local dm = OvaleState:GetDamageMultiplier(spellId)
+		local value = bdm * dm
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("damagemultiplier", false, DamageMultiplier)
+end
diff --git a/conditions/DamageTaken.lua b/conditions/DamageTaken.lua
new file mode 100644
index 0000000..63a1720
--- /dev/null
+++ b/conditions/DamageTaken.lua
@@ -0,0 +1,43 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleDamage = Ovale.OvaleDamage
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the damage taken by the player in the previous time interval.
+	-- @name DamageTaken
+	-- @paramsig number or boolean
+	-- @param interval The number of seconds before now.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The amount of damage taken in the previous interval.
+	-- @return A boolean value for the result of the comparison.
+	-- @see IncomingDamage
+	-- @usage
+	-- if DamageTaken(5) > 50000 Spell(death_strike)
+
+	local function DamageTaken(condition)
+		-- Damage taken shouldn't be smoothed since spike damage is important data.
+		-- Just present damage taken as a constant value.
+		local interval, comparator, limit = condition[1], condition[2], condition[3]
+		local value = 0
+		if interval > 0 then
+			value = OvaleDamageTaken:GetRecentDamage(interval)
+		end
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("damagetaken", false, DamageTaken)
+	OvaleCondition:RegisterCondition("incomingdamage", false, DamageTaken)
+end
diff --git a/conditions/Distance.lua b/conditions/Distance.lua
new file mode 100644
index 0000000..a653b69
--- /dev/null
+++ b/conditions/Distance.lua
@@ -0,0 +1,44 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local LRC = LibStub("LibRangeCheck-2.0", true)
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	--- Get the distance in yards to the target.
+	-- The distances are from LibRangeCheck-2.0, which determines distance based on spell range checks, so results are approximate.
+	-- You should not test for equality.
+	-- @name Distance
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The distance to the target.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if target.Distance(less 25)
+	--     Texture(ability_rogue_sprint)
+
+	local function Distance(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local value = LRC and LRC:GetRange(target) or 0
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("distance", false, Distance)
+end
diff --git a/conditions/Eclipse.lua b/conditions/Eclipse.lua
new file mode 100644
index 0000000..ed0a9b3
--- /dev/null
+++ b/conditions/Eclipse.lua
@@ -0,0 +1,39 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the current amount of Eclipse power for balance druids.
+	-- A negative amount of power signifies being closer to Lunar Eclipse.
+	-- A positive amount of power signifies being closer to Solar Eclipse.
+	-- @name Eclipse
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The amount of Eclipse power.
+	-- @return A boolean value for the result of the comparison.
+	-- @see EclipseDir
+	-- @usage
+	-- if Eclipse() < 0-70 and EclipseDir() <0 Spell(wrath)
+	-- if Eclipse(less -70) and EclipseDir(less 0) Spell(wrath)
+
+	local function Eclipse(condition)
+		local comparator, limit = condition[1], condition[2]
+		local value = OvaleState.state.eclipse
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("eclipse", false, Eclipse)
+end
diff --git a/conditions/EclipseDir.lua b/conditions/EclipseDir.lua
new file mode 100644
index 0000000..2cdf664
--- /dev/null
+++ b/conditions/EclipseDir.lua
@@ -0,0 +1,39 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the current direction of the Eclipse status on the Eclipse bar for balance druids.
+	-- A negative number means heading toward Lunar Eclipse.
+	-- A positive number means heading toward Solar Eclipse.
+	-- @name EclipseDir
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current direction.
+	-- @return A boolean value for the result of the comparison.
+	-- @see Eclipse
+	-- @usage
+	-- if Eclipse() < 0-70 and EclipseDir() <0 Spell(wrath)
+	-- if Eclipse(less -70) and EclipseDir(less 0) Spell(wrath)
+
+	local function EclipseDir(condition)
+		local comparator, limit = condition[1], condition[2]
+		local value = OvaleState:GetEclipseDir()
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("eclipsedir", false, EclipseDir)
+end
diff --git a/conditions/Enemies.lua b/conditions/Enemies.lua
new file mode 100644
index 0000000..2d3fe8a
--- /dev/null
+++ b/conditions/Enemies.lua
@@ -0,0 +1,36 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleEnemies = Ovale.OvaleEnemies
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the number of hostile enemies on the battlefield.
+	-- @name Enemies
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of enemies.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if Enemies() >4 Spell(fan_of_knives)
+	-- if Enemies(more 4) Spell(fan_of_knives)
+
+	local function Enemies(condition)
+		local comparator, limit = condition[1], condition[2]
+		local value = OvaleEnemies.activeEnemies
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("enemies", false, Enemies)
+end
diff --git a/conditions/EnergyRegen.lua b/conditions/EnergyRegen.lua
new file mode 100644
index 0000000..70bb7bd
--- /dev/null
+++ b/conditions/EnergyRegen.lua
@@ -0,0 +1,35 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the amount of regenerated energy per second for feral druids, non-mistweaver monks, and rogues.
+	-- @name EnergyRegen
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current rate of energy regeneration.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if EnergyRegen() >11 Spell(stance_of_the_sturdy_ox)
+
+	local function EnergyRegen(condition)
+		local comparator, limit = condition[1], condition[2]
+		local value = OvaleState.powerRate.energy
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("energyregen", false, EnergyRegen)
+end
diff --git a/conditions/Exists.lua b/conditions/Exists.lua
new file mode 100644
index 0000000..9d7ce59
--- /dev/null
+++ b/conditions/Exists.lua
@@ -0,0 +1,41 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitExists = UnitExists
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the target exists. The target may be alive or dead.
+	-- @name Exists
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if the target exists. If no, then return true if it doesn't exist.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @see Present
+	-- @usage
+	-- if pet.Exists(no) Spell(summon_imp)
+
+	local function Exists(condition)
+		local yesno = condition[1]
+		local target = ParseCondition(condition)
+		local boolean = (API_UnitExists(target) == 1)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("exists", false, Exists)
+end
diff --git a/conditions/False.lua b/conditions/False.lua
new file mode 100644
index 0000000..de4ba64
--- /dev/null
+++ b/conditions/False.lua
@@ -0,0 +1,25 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	--- A condition that always returns false.
+	-- @name False
+	-- @paramsig boolean
+	-- @return A boolean value.
+
+	local function False(condition)
+		return nil
+	end
+
+	OvaleCondition:RegisterCondition("false", false, False)
+end
diff --git a/conditions/FocusRegen.lua b/conditions/FocusRegen.lua
new file mode 100644
index 0000000..7fd4318
--- /dev/null
+++ b/conditions/FocusRegen.lua
@@ -0,0 +1,36 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the amount of regenerated focus per second for hunters.
+	-- @name FocusRegen
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current rate of focus regeneration.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if FocusRegen() >20 Spell(arcane_shot)
+	-- if FocusRegen(more 20) Spell(arcane_shot)
+
+	local function FocusRegen(condition)
+		local comparator, limit = condition[1], condition[2]
+		local value = OvaleState.powerRate.focus
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("focusregen", false, FocusRegen)
+end
diff --git a/conditions/GCD.lua b/conditions/GCD.lua
new file mode 100644
index 0000000..266dbe5
--- /dev/null
+++ b/conditions/GCD.lua
@@ -0,0 +1,36 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the player's global cooldown in seconds.
+	-- @name GCD
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if GCD() <1.1 Spell(frostfire_bolt)
+	-- if GCD(less 1.1) Spell(frostfire_bolt)
+
+	local function GCD(condition)
+		local comparator, limit = condition[1], condition[2]
+		local value = OvaleState.gcd
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("gcd", false, GCD)
+end
diff --git a/conditions/Glyph.lua b/conditions/Glyph.lua
new file mode 100644
index 0000000..6affe8c
--- /dev/null
+++ b/conditions/Glyph.lua
@@ -0,0 +1,37 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleSpellBook = Ovale.OvaleSpellBook
+
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the given glyph is active.
+	-- @name Glyph
+	-- @paramsig boolean
+	-- @param id The glyph spell ID.
+	-- @param yesno Optional. If yes, then return true if the glyph is active. If no, then return true if it isn't active.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if InCombat(no) and Glyph(glyph_of_savagery)
+	--     Spell(savage_roar)
+
+	local function Glyph(condition)
+		local glyph, yesno = condition[1], condition[2]
+		local boolean = OvaleSpellBook:IsActiveGlyph(glyph)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("glyph", false, Glyph)
+end
\ No newline at end of file
diff --git a/conditions/HasEquippedItem.lua b/conditions/HasEquippedItem.lua
new file mode 100644
index 0000000..659a17f
--- /dev/null
+++ b/conditions/HasEquippedItem.lua
@@ -0,0 +1,62 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleData = Ovale.OvaleData
+	local OvaleEquipement = Ovale.OvaleEquipement
+
+	local pairs = pairs
+	local type = type
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player has a particular item equipped.
+	-- @name HasEquippedItem
+	-- @paramsig boolean
+	-- @param item Item to be checked whether it is equipped.
+	-- @param yesno Optional. If yes, then return true if the item is equipped. If no, then return true if it isn't equipped.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param ilevel Optional.  Checks the item level of the equipped item.  If not specified, then any item level is valid.
+	--     Defaults to not specified.
+	--     Valid values: ilevel=N, where N is any number.
+	-- @param slot Optional. Sets the inventory slot to check.  If not specified, then all slots are checked.
+	--     Defaults to not specified.
+	--     Valid values: slot=SLOTNAME, where SLOTNAME is a valid slot name, e.g., HandSlot.
+
+	local function HasEquippedItem(condition)
+		local itemId, yesno = condition[1], condition[2]
+		local ilevel, slot = condition.ilevel, condition.slot
+		local boolean = false
+		local slotId
+		if type(itemId) == "number" then
+			slotId = OvaleEquipement:HasEquippedItem(itemId, slot)
+			if slotId then
+				if not ilevel or (ilevel and ilevel == OvaleEquipement:GetEquippedItemLevel(slotId)) then
+					boolean = true
+				end
+			end
+		elseif OvaleData.itemList[itemId] then
+			for _, v in pairs(OvaleData.itemList[itemId]) do
+				slotId = OvaleEquipement:HasEquippedItem(v, slot)
+				if slotId then
+					if not ilevel or (ilevel and ilevel == OvaleEquipement:GetEquippedItemLevel(slotId)) then
+						boolean = true
+						break
+					end
+				end
+			end
+		end
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("hasequippeditem", false, HasEquippedItem)
+end
\ No newline at end of file
diff --git a/conditions/HasFullControl.lua b/conditions/HasFullControl.lua
new file mode 100644
index 0000000..e2c23c0
--- /dev/null
+++ b/conditions/HasFullControl.lua
@@ -0,0 +1,35 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_HasFullControl = HasFullControl
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player has full control, i.e., isn't feared, charmed, etc.
+	-- @name HasFullControl
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if the target exists. If no, then return true if it doesn't exist.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if HasFullControl(no) Spell(barkskin)
+
+	local function HasFullControl(condition)
+		local yesno = condition[1]
+		local boolean = API_HasFullControl()
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("hasfullcontrol", false, HasFullControl)
+end
\ No newline at end of file
diff --git a/conditions/HasShield.lua b/conditions/HasShield.lua
new file mode 100644
index 0000000..eaf1be6
--- /dev/null
+++ b/conditions/HasShield.lua
@@ -0,0 +1,35 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleEquipement = Ovale.OvaleEquipement
+
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player has a shield equipped.
+	-- @name HasShield
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if a shield is equipped. If no, then return true if it isn't equipped.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if HasShield() Spell(shield_wall)
+
+	local function HasShield(condition)
+		local yesno = condition[1]
+		local boolean = OvaleEquipement:HasShield()
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("hasshield", false, HasShield)
+end
\ No newline at end of file
diff --git a/conditions/HasTrinket.lua b/conditions/HasTrinket.lua
new file mode 100644
index 0000000..c887d99
--- /dev/null
+++ b/conditions/HasTrinket.lua
@@ -0,0 +1,50 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleEquipement = Ovale.OvaleEquipement
+
+	local pairs = pairs
+	local type = type
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player has a particular trinket equipped.
+	-- @name HasTrinket
+	-- @paramsig boolean
+	-- @param id The item ID of the trinket or the name of an item list.
+	-- @param yesno Optional. If yes, then return true if the trinket is equipped. If no, then return true if it isn't equipped.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- ItemList(rune_of_reorigination 94532 95802 96546)
+	-- if HasTrinket(rune_of_reorigination) and BuffPresent(rune_of_reorigination_buff)
+	--     Spell(rake)
+
+	local function HasTrinket(condition)
+		local trinketId, yesno = condition[1], condition[2]
+		local boolean = false
+		if type(trinketId) == "number" then
+			boolean = OvaleEquipement:HasTrinket(trinketId)
+		elseif OvaleData.itemList[trinketId] then
+			for _, v in pairs(OvaleData.itemList[trinketId]) do
+				boolean = OvaleEquipement:HasTrinket(v)
+				if boolean then
+					break
+				end
+			end
+		end
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("hastrinket", false, HasTrinket)
+end
diff --git a/conditions/HasWeapon.lua b/conditions/HasWeapon.lua
new file mode 100644
index 0000000..5227dcf
--- /dev/null
+++ b/conditions/HasWeapon.lua
@@ -0,0 +1,42 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleEquipement = Ovale.OvaleEquipement
+
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player has a weapon equipped.
+	-- @name HasWeapon
+	-- @paramsig boolean
+	-- @param hand Sets which hand weapon.
+	--     Valid values: main, off
+	-- @param yesno Optional. If yes, then return true if the weapon is equipped. If no, then return true if it isn't equipped.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if HasWeapon(offhand) and BuffStacks(killing_machine) Spell(frost_strike)
+
+	local function HasWeapon(condition)
+		local hand, yesno = condition[1], condition[2]
+		local boolean = false
+		if hand == "offhand" or hand == "off" then
+			boolean = OvaleEquipement:HasOffHandWeapon()
+		elseif hand == "mainhand" or hand == "main" then
+			boolean = OvaleEquipement:HasMainHandWeapon()
+		end
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("hasweapon", false, HasWeapon)
+end
\ No newline at end of file
diff --git a/conditions/Health.lua b/conditions/Health.lua
new file mode 100644
index 0000000..314132d
--- /dev/null
+++ b/conditions/Health.lua
@@ -0,0 +1,276 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleGUID = Ovale.OvaleGUID
+	local OvaleState = Ovale.OvaleState
+
+	local floor = math.floor
+	local API_UnitHealth = UnitHealth
+	local API_UnitHealthMax = UnitHealthMax
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	-- static properties for TimeToDie(), indexed by unit ID
+	local lastTTDTime = {}
+	local lastTTDHealth = {}
+	local lastTTDguid = {}
+	local lastTTDdps = {}
+
+	--[[
+		Returns:
+			Estimated number of seconds before the specified unit reaches zero health
+			Unit's current health
+			Unit's maximum health
+	--]]
+	local function EstimatedTimeToDie(unitId)
+		-- Check for target switch.
+		if lastTTDguid[unitId] ~= OvaleGUID:GetGUID(unitId) then
+			lastTTDguid[unitId] = OvaleGUID:GetGUID(unitId)
+			lastTTDTime[unitId] = nil
+			if lastTTDHealth[unitId] then
+				wipe(lastTTDHealth[unitId])
+			else
+				lastTTDHealth[unitId] = {}
+			end
+			lastTTDdps[unitId] = nil
+		end
+
+		local timeToDie
+		local health = API_UnitHealth(unitId) or 0
+		local maxHealth = API_UnitHealthMax(unitId) or 1
+
+		-- Clamp maxHealth to always be at least 1.
+		if maxHealth < health then
+			maxHealth = health
+		end
+		if maxHealth < 1 then
+			maxHealth = 1
+		end
+
+		if health == 0 then
+			timeToDie = 0
+		elseif maxHealth <= 5 then
+			Ovale:Log("Training Dummy, return in the future")
+			timeToDie = math.huge
+		else
+			local now = floor(OvaleState.maintenant)
+			if (not lastTTDTime[unitId] or lastTTDTime[unitId] < now) and lastTTDguid[unitId] then
+				lastTTDTime[unitId] = now
+				local mod10, prevHealth
+				for delta = 10, 1, -1 do
+					mod10 = (now - delta) % 10
+					prevHealth = lastTTDHealth[unitId][mod10]
+					if delta == 10 then
+						lastTTDHealth[unitId][mod10] = health
+					end
+					if prevHealth and prevHealth > health then
+						lastTTDdps[unitId] = (prevHealth - health) / delta
+						Ovale:Logf("prevHealth = %d, health = %d, delta = %d, dps = %d", prevHealth, health, delta, lastTTDdps[unitId])
+						break
+					end
+				end
+			end
+			local dps = lastTTDdps[unitId]
+			if dps and dps > 0 then
+				timeToDie = health / dps
+			else
+				timeToDie = math.huge
+			end
+		end
+		-- Clamp time to die at a finite number.
+		if timeToDie == math.huge then
+			-- Return time to die in the far-off future (one week).
+			timeToDie = 3600 * 24 * 7
+		end
+		return timeToDie, health, maxHealth
+	end
+
+	--- Get the current amount of health points of the target.
+	-- @name Health
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The current health.
+	-- @return A boolean value for the result of the comparison.
+	-- @see Life
+	-- @usage
+	-- if Health() <10000 Spell(last_stand)
+	-- if Health(less 10000) Spell(last_stand)
+
+	local function Health(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local timeToDie, health, maxHealth = EstimatedTimeToDie(target)
+		if not timeToDie then
+			return nil
+		elseif timeToDie == 0 then
+			return Compare(0, comparator, limit)
+		end
+		local value, origin, rate = health, OvaleState.maintenant, -1 * health / timeToDie
+		local start, ending = OvaleState.maintenant, math.huge
+		return TestValue(start, ending, value, origin, rate, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("health", false, Health)
+	OvaleCondition:RegisterCondition("life", false, Health)
+
+	--- Get the number of health points away from full health of the target.
+	-- @name HealthMissing
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The current missing health.
+	-- @return A boolean value for the result of the comparison.
+	-- @see LifeMissing
+	-- @usage
+	-- if HealthMissing() <20000 Item(healthstone)
+	-- if HealthMissing(less 20000) Item(healthstone)
+
+	local function HealthMissing(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local timeToDie, health, maxHealth = EstimatedTimeToDie(target)
+		if not timeToDie or timeToDie == 0 then
+			return nil
+		end
+		local missing = maxHealth - health
+		local value, origin, rate = missing, OvaleState.maintenant, health / timeToDie
+		local start, ending = OvaleState.maintenant, math.huge
+		return TestValue(start, ending, value, origin, rate, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("healthmissing", false, Health)
+	OvaleCondition:RegisterCondition("lifemissing", false, Health)
+
+	--- Get the current percent level of health of the target.
+	-- @name HealthPercent
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The current health percent.
+	-- @return A boolean value for the result of the comparison.
+	-- @see LifePercent
+	-- @usage
+	-- if HealthPercent() <20 Spell(last_stand)
+	-- if target.HealthPercent(less 25) Spell(kill_shot)
+
+	local function HealthPercent(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local timeToDie, health, maxHealth = EstimatedTimeToDie(target)
+		if not timeToDie then
+			return nil
+		elseif timeToDie == 0 then
+			return Compare(0, comparator, limit)
+		end
+		local healthPercent = health / maxHealth * 100
+		local value, origin, rate = healthPercent, OvaleState.maintenant, -1 * healthPercent / timeToDie
+		local start, ending = OvaleState.maintenant, math.huge
+		return TestValue(start, ending, value, origin, rate, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("healthpercent", false, HealthPercent)
+	OvaleCondition:RegisterCondition("lifepercent", false, HealthPercent)
+
+	--- Get the amount of health points of the target when it is at full health.
+	-- @name MaxHealth
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum health.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if target.MaxHealth() >10000000 Item(mogu_power_potion)
+	-- if target.MaxHealth(more 10000000) Item(mogu_power_potion)
+
+	local function MaxHealth(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local value = API_UnitHealthMax(target)
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("maxhealth", false, MaxHealth)
+
+	--- Get the estimated number of seconds remaining before the target is dead.
+	-- @name TimeToDie
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DeadIn
+	-- @usage
+	-- if target.TimeToDie() <2 and ComboPoints() >0 Spell(eviscerate)
+
+	local function TimeToDie(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local timeToDie = EstimatedTimeToDie(target)
+		local value, origin, rate = timeToDie, OvaleState.maintenant, -1
+		local start, ending = OvaleState.maintenant, OvaleState.maintenant + timeToDie
+		return TestValue(start, ending, value, origin, rate, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("deadin", false, TimeToDie)
+	OvaleCondition:RegisterCondition("timetodie", false, TimeToDie)
+
+	--- Get the estimated number of seconds remaining before the target reaches the given percent of max health.
+	-- @name TimeToHealthPercent
+	-- @paramsig number or boolean
+	-- @param percent The percent of maximum health of the target.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see TimeToDie
+	-- @usage
+	-- if target.TimeToHealthPercent(25) <15 Item(virmens_bite_potion)
+
+	local function TimeToHealthPercent(condition)
+		local percent, comparator, limit = condition[1], condition[2], condition[3]
+		local target = ParseCondition(condition)
+		local timeToDie, health, maxHealth = EstimatedTimeToDie(target)
+		local healthPercent = health / maxHealth * 100
+		if healthPercent >= percent then
+			local t = timeToDie * (healthPercent - percent) / healthPercent
+			local value, origin, rate = t, OvaleState.maintenant, -1
+			local start, ending = OvaleState.maintenant, OvaleState.maintenant + t
+			return TestValue(start, ending, value, origin, rate, comparator, limit)
+		end
+		return Compare(0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("timetohealthpercent", false, TimeToHealthPercent)
+	OvaleCondition:RegisterCondition("timetolifepercent", false, TimeToHealthPercent)
+end
\ No newline at end of file
diff --git a/conditions/InCombat.lua b/conditions/InCombat.lua
new file mode 100644
index 0000000..eeac64d
--- /dev/null
+++ b/conditions/InCombat.lua
@@ -0,0 +1,34 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player is in combat.
+	-- @name InCombat
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if the player is in combat. If no, then return true if the player isn't in combat.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if InCombat(no) and Stealthed(no) Spell(stealth)
+
+	local function InCombat(condition)
+		local yesno = condition[1]
+		local boolean = Ovale.enCombat
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("incombat", false, InCombat)
+end
\ No newline at end of file
diff --git a/conditions/InFlightToTarget.lua b/conditions/InFlightToTarget.lua
new file mode 100644
index 0000000..631640b
--- /dev/null
+++ b/conditions/InFlightToTarget.lua
@@ -0,0 +1,38 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleFuture = Ovale.OvaleFuture
+	local OvaleState = OvaleState
+
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the given spell is in flight for spells that have a flight time after cast, e.g., Lava Burst.
+	-- @name InFlightToTarget
+	-- @paramsig boolean
+	-- @param id The spell ID.
+	-- @param yesno Optional. If yes, then return true if the spell is in flight. If no, then return true if it isn't in flight.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if target.DebuffRemains(haunt) <3 and not InFlightToTarget(haunt)
+	--     Spell(haunt)
+
+	local function InFlightToTarget(condition)
+		local spellId, yesno = condition[1], condition[2]
+		local boolean = (OvaleState.currentSpellId == spellId) or OvaleFuture:InFlight(spellId)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("inflighttotarget", false, InFlightToTarget)
+end
\ No newline at end of file
diff --git a/conditions/InRange.lua b/conditions/InRange.lua
new file mode 100644
index 0000000..b32fe07
--- /dev/null
+++ b/conditions/InRange.lua
@@ -0,0 +1,41 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleSpellBook = Ovale.OvaleSpellBook
+
+	local API_IsSpellInRange = IsSpellInRange
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the distance from the player to the target is within the spell's range.
+	-- @name InRange
+	-- @paramsig boolean
+	-- @param id The spell ID.
+	-- @param yesno Optional. If yes, then return true if the target is in range. If no, then return true if it isn't in range.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if target.IsInterruptible() and target.InRange(kick)
+	--     Spell(kick)
+
+	local function InRange(condition)
+		local spellId, yesno = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local spellName = OvaleSpellBook:GetSpellName(spellId)
+		local boolean = (API_IsSpellInRange(spellName, target) == 1)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("inrange", false, InRange)
+end
\ No newline at end of file
diff --git a/conditions/IsAggroed.lua b/conditions/IsAggroed.lua
new file mode 100644
index 0000000..0710a6e
--- /dev/null
+++ b/conditions/IsAggroed.lua
@@ -0,0 +1,42 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitDetailedThreatSituation = UnitDetailedThreatSituation
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the target's primary aggro is on the player.
+	-- Even if the target briefly targets and casts a spell on another raid member,
+	-- this condition returns true as long as the player is highest on the threat table.
+	-- @name IsAggroed
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if the target is aggroed. If no, then return true if it isn't aggroed.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- if target.IsAggroed() Spell(feign_death)
+
+	local function IsAggroed(condition)
+		local yesno = condition[1]
+		local target = ParseCondition(condition)
+		local boolean = API_UnitDetailedThreatSituation("player", target)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("isaggroed", false, IsAggroed)
+end
\ No newline at end of file
diff --git a/conditions/IsFeared.lua b/conditions/IsFeared.lua
new file mode 100644
index 0000000..6371c4e
--- /dev/null
+++ b/conditions/IsFeared.lua
@@ -0,0 +1,36 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local API_HasFullControl = HasFullControl
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player is feared.
+	-- @name IsFeared
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if feared. If no, then return true if it not feared.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if IsFeared() Spell(every_man_for_himself)
+
+	local function IsFeared(condition)
+		local yesno = condition[1]
+		local boolean = not API_HasFullControl() and OvaleState:GetAura("player", "fear", "HARMFUL")
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("isfeared", false, IsFeared)
+end
\ No newline at end of file
diff --git a/conditions/IsFriend.lua b/conditions/IsFriend.lua
new file mode 100644
index 0000000..d5b6e65
--- /dev/null
+++ b/conditions/IsFriend.lua
@@ -0,0 +1,40 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitIsFriend = UnitIsFriend
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the target is friendly to the player.
+	-- @name IsFriend
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if the target is friendly (able to help in combat). If no, then return true if it isn't friendly.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- if target.IsFriend() Spell(healing_touch)
+
+	local function IsFriend(condition)
+		local yesno = condition[1]
+		local target = ParseCondition(condition)
+		local boolean = API_UnitIsFriend("player", target)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("isfriend", false, IsFriend)
+end
\ No newline at end of file
diff --git a/conditions/IsIncapacitated.lua b/conditions/IsIncapacitated.lua
new file mode 100644
index 0000000..33d9cda
--- /dev/null
+++ b/conditions/IsIncapacitated.lua
@@ -0,0 +1,36 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local API_HasFullControl = HasFullControl
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player is incapacitated.
+	-- @name IsIncapacitated
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if incapacitated. If no, then return true if it not incapacitated.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if IsIncapacitated() Spell(every_man_for_himself)
+
+	local function IsIncapacitated(condition)
+		local yesno = condition[1]
+		local boolean = not API_HasFullControl() and OvaleState:GetAura("player", "incapacitate", "HARMFUL")
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("isincapacitated", false, IsIncapacitated)
+end
\ No newline at end of file
diff --git a/conditions/IsInterruptible.lua b/conditions/IsInterruptible.lua
new file mode 100644
index 0000000..5b90c59
--- /dev/null
+++ b/conditions/IsInterruptible.lua
@@ -0,0 +1,45 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitCastingInfo = UnitCastingInfo
+	local API_UnitChannelInfo = UnitChannelInfo
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the target is currently casting an interruptible spell.
+	-- @name IsInterruptible
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if the target is interruptible. If no, then return true if it isn't interruptible.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- if target.IsInterruptible() Spell(kick)
+
+	local function IsInterruptible(condition)
+		local yesno = condition[1]
+		local target = ParseCondition(condition)
+		local name, _, _, _, _, _, _, _, notInterruptible = API_UnitCastingInfo(target)
+		if not name then
+			name, _, _, _, _, _, _, notInterruptible = API_UnitChannelInfo(target)
+		end
+		local boolean = notInterruptible ~= nil and not notInterruptible
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("isinterruptible", false, IsInterruptible)
+end
\ No newline at end of file
diff --git a/conditions/IsPVP.lua b/conditions/IsPVP.lua
new file mode 100644
index 0000000..a92ff34
--- /dev/null
+++ b/conditions/IsPVP.lua
@@ -0,0 +1,40 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitIsPVP = UnitIsPVP
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the target is flagged for PvP activity.
+	-- @name IsPVP
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if the target is flagged for PvP activity. If no, then return true if it isn't PvP-flagged.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- if not target.IsFriend() and target.IsPVP() Spell(sap)
+
+	local function IsPVP(condition)
+		local yesno = condition[1]
+		local target = ParseCondition(condition)
+		local boolean = API_UnitIsPVP(target)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("ispvp", false, IsPVP)
+end
\ No newline at end of file
diff --git a/conditions/IsRooted.lua b/conditions/IsRooted.lua
new file mode 100644
index 0000000..11ce741
--- /dev/null
+++ b/conditions/IsRooted.lua
@@ -0,0 +1,35 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player is rooted.
+	-- @name IsRooted
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if rooted. If no, then return true if it not rooted.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if IsRooted() Item(Trinket0Slot usable=1)
+
+	local function IsRooted(condition)
+		local yesno = condition[1]
+		local boolean = OvaleState:GetAura("player", "root", "HARMFUL")
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("isrooted", false, IsRooted)
+end
\ No newline at end of file
diff --git a/conditions/IsStunned.lua b/conditions/IsStunned.lua
new file mode 100644
index 0000000..db64263
--- /dev/null
+++ b/conditions/IsStunned.lua
@@ -0,0 +1,36 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local API_HasFullControl = HasFullControl
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player is stunned.
+	-- @name IsStunned
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if stunned. If no, then return true if it not stunned.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if IsStunned() Item(Trinket0Slot usable=1)
+
+	local function IsStunned(condition)
+		local yesno = condition[1]
+		local boolean = not API_HasFullControl() and OvaleState:GetAura("player", "stun", "HARMFUL")
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("isstunned", false, IsStunned)
+end
\ No newline at end of file
diff --git a/conditions/ItemCharges.lua b/conditions/ItemCharges.lua
new file mode 100644
index 0000000..2b48594
--- /dev/null
+++ b/conditions/ItemCharges.lua
@@ -0,0 +1,38 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_GetItemCount = GetItemCount
+	local Compare = OvaleCondition.Compare
+
+	--- Get the current number of charges of the given item in the player's inventory.
+	-- @name ItemCharges
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of charges.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if ItemCount(mana_gem) ==0 or ItemCharges(mana_gem) <3
+	--     Spell(conjure_mana_gem)
+	-- if ItemCount(mana_gem equal 0) or ItemCharges(mana_gem less 3)
+	--     Spell(conjure_mana_gem)
+
+	local function ItemCharges(condition)
+		local itemId, comparator, limit = condition[1], condition[2], condition[3]
+		local value = API_GetItemCount(itemId, false, true)
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("itemcharges", false, ItemCharges)
+end
\ No newline at end of file
diff --git a/conditions/ItemCooldown.lua b/conditions/ItemCooldown.lua
new file mode 100644
index 0000000..4782085
--- /dev/null
+++ b/conditions/ItemCooldown.lua
@@ -0,0 +1,41 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_GetItemCooldown = GetItemCooldown
+	local Compare = OvaleCondition.Compare
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the cooldown time in seconds of an item, e.g., trinket.
+	-- @name ItemCooldown
+	-- @paramsig number or boolean
+	-- @param id The item ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if not ItemCooldown(ancient_petrified_seed) >0
+	--     Spell(berserk_cat)
+
+	local function ItemCooldown(condition)
+		local itemId, comparator, limit = condition[1], condition[2], condition[3]
+		local start, duration = API_GetItemCooldown(itemId)
+		if start > 0 and duration > 0 then
+			return TestValue(start, start + duration, duration, start, -1, comparator, limit)
+		end
+		return Compare(0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("itemcooldown", false, ItemCooldown)
+end
\ No newline at end of file
diff --git a/conditions/ItemCount.lua b/conditions/ItemCount.lua
new file mode 100644
index 0000000..0b95dd9
--- /dev/null
+++ b/conditions/ItemCount.lua
@@ -0,0 +1,37 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_GetItemCount = GetItemCount
+	local Compare = OvaleCondition.Compare
+
+	--- Get the current number of the given item in the player's inventory.
+	-- Items with more than one charge count as one item.
+	-- @name ItemCount
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The count of the item.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if ItemCount(mana_gem) ==0 Spell(conjure_mana_gem)
+	-- if ItemCount(mana_gem equal 0) Spell(conjure_mana_gem)
+
+	local function ItemCount(condition)
+		local itemId, comparator, limit = condition[1], condition[2], condition[3]
+		local value = API_GetItemCount(itemId)
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("itemcount", false, ItemCount)
+end
\ No newline at end of file
diff --git a/conditions/LastDamage.lua b/conditions/LastDamage.lua
new file mode 100644
index 0000000..44267ca
--- /dev/null
+++ b/conditions/LastDamage.lua
@@ -0,0 +1,43 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the damage done by the most recent damage event for the given spell.
+	-- If the spell is a periodic aura, then it gives the damage done by the most recent tick.
+	-- @name LastDamage
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The damage done.
+	-- @return A boolean value for the result of the comparison.
+	-- @see Damage, LastEstimatedDamage
+	-- @usage
+	-- if LastDamage(ignite) >10000 Spell(combustion)
+	-- if LastDamage(ignite more 10000) Spell(combustion)
+
+	local function LastDamage(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local value = OvaleSpellDamage:Get(spellId)
+		if value then
+			return Compare(value, comparator, limit)
+		end
+		return nil
+	end
+
+	OvaleCondition:RegisterCondition("lastdamage", false, LastDamage)
+	OvaleCondition:RegisterCondition("lastspelldamage", false, LastDamage)
+end
\ No newline at end of file
diff --git a/conditions/LastDamageMultiplier.lua b/conditions/LastDamageMultiplier.lua
new file mode 100644
index 0000000..176cc6a
--- /dev/null
+++ b/conditions/LastDamageMultiplier.lua
@@ -0,0 +1,49 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleGUID = Ovale.OvaleGUID
+	local OvaleFuture = Ovale.OvaleFuture
+
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	--- Get the damage multiplier of the most recent cast of a spell on the target.
+	-- This currently does not take into account increased damage due to mastery.
+	-- @name LastDamageMultiplier
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=target.
+	--     Valid values: player, target, focus, pet.
+	-- @return The previous damage multiplier.
+	-- @return A boolean value for the result of the comparison.
+	-- @see DamageMultiplier
+	-- @usage
+	-- if {DamageMultiplier(rupture) / target.LastDamageMultiplier(rupture)} >1.1
+	--     Spell(rupture)
+
+	local function LastDamageMultiplier(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local target = ParseCondition(condition, "target")
+		local guid = OvaleGUID:GetGUID(target)
+		local bdm = OvaleFuture:GetLastSpellInfo(guid, spellId, "baseDamageMultiplier") or 1
+		local dm = OvaleFuture:GetLastSpellInfo(guid, spellId, "damageMultiplier") or 1
+		local value = bdm * dm
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("lastdamagemultiplier", false, LastDamageMultiplier)
+	OvaleCondition:RegisterCondition("lastspelldamagemultiplier", false, LastDamageMultiplier)
+end
diff --git a/conditions/LastEstimatedDamage.lua b/conditions/LastEstimatedDamage.lua
new file mode 100644
index 0000000..696a60e
--- /dev/null
+++ b/conditions/LastEstimatedDamage.lua
@@ -0,0 +1,59 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleDate = Ovale.OvaleData
+	local OvaleGUID = Ovale.OvaleGUID
+	local OvaleFuture = Ovale.OvaleFuture
+
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	--- Get the estimated damage of the most recent cast of the player's spell on the target.
+	-- The calculated damage takes into account the values of attack power, spellpower, weapon damage and combo points (if used)
+	-- at the time the spell was most recent cast.
+	-- The damage is computed from information for the spell set via SpellInfo(...):
+	--
+	-- damage = base + bonusmainhand * MH + bonusoffhand * OH + bonusap * AP + bonuscp * CP + bonusapcp * AP * CP + bonussp * SP
+	-- @name LastEstimatedDamage
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=target.
+	--     Valid values: player, target, focus, pet.
+	-- @return The estimated damage of the most recent cast of the given spell by the player.
+	-- @return A boolean value for the result of the comparison.
+	-- @see Damage, LastDamage
+	-- @usage
+	-- if {Damage(rake) / target.LastEstimateDamage(rake)} >1.1
+	--     Spell(rake)
+
+	local function LastEstimatedDamage(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local target = ParseCondition(condition, "target")
+		local guid = OvaleGUID:GetGUID(target)
+		local ap = OvaleFuture:GetLastSpellInfo(guid, spellId, "attackPower") or 0
+		local sp = OvaleFuture:GetLastSpellInfo(guid, spellId, "spellBonusDamage") or 0
+		local mh = OvaleFuture:GetLastSpellInfo(guid, spellId, "mainHandWeaponDamage") or 0
+		local oh = OvaleFuture:GetLastSpellInfo(guid, spellId, "offHandWeaponDamage") or 0
+		local combo = OvaleFuture:GetLastSpellInfo(guid, spellId, "comboPoints") or 0
+		local bdm = OvaleFuture:GetLastSpellInfo(guid, spellId, "baseDamageMultiplier") or 1
+		local dm = OvaleFuture:GetLastSpellInfo(guid, spellId, "damageMultiplier") or 1
+		local value = OvaleData:GetDamage(spellId, ap, sp, mh, oh, combo) * bdm * dm
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("lastestimateddamage", false, LastEstimatedDamage)
+	OvaleCondition:RegisterCondition("lastspellestimateddamage", false, LastEstimatedDamage)
+end
\ No newline at end of file
diff --git a/conditions/LastSnapshot.lua b/conditions/LastSnapshot.lua
new file mode 100644
index 0000000..7582ac1
--- /dev/null
+++ b/conditions/LastSnapshot.lua
@@ -0,0 +1,215 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleGUID = Ovale.OvaleGUID
+	local OvaleFuture = Ovale.OvaleFuture
+
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	-- Return the value of the stat from the snapshot at the time the spell was cast.
+	local function LastSnapshot(statName, defaultValue, condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local target = ParseCondition(condition, "target")
+		local guid = OvaleGUID:GetGUID(target)
+		local value = OvaleFuture:GetLastSpellInfo(guid, spellId, statName)
+		value = value and value or defaultValue
+		return Compare(value, comparator, limit)
+	end
+
+	-- Return the value of the given critical strike chance from the aura snapshot at the time the aura was applied.
+	local function LastSnapshotCritChance(statName, defaultValue, condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local target = ParseCondition(condition)
+		local guid = OvaleGUID:GetGUID(target)
+		local value = OvaleFuture:GetLastSpellInfo(guid, spellId, statName)
+		value = value and value or defaultValue
+		if condition.unlimited ~= 1 and value > 100 then
+			value = 100
+		end
+		return Compare(value, comparator, limit)
+	end
+
+	--- Get the attack power of the player during the most recent cast of a spell on the target.
+	-- @name LastAttackPower
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=target.
+	--     Valid values: player, target, focus, pet.
+	-- @return The previous attack power.
+	-- @return A boolean value for the result of the comparison.
+	-- @see AttackPower
+	-- @usage
+	-- if {AttackPower() / target.LastAttackPower(hemorrhage)} >1.25
+	--     Spell(hemorrhage)
+
+	local function LastAttackPower(condition)
+		return LastSnapshot("attackPower", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("lastattackpower", false, LastAttackPower)
+	OvaleCondition:RegisterCondition("lastspellattackpower", false, LastAttackPower)
+
+	--- Get the number of combo points consumed by the most recent cast of a spell on the target for a feral druid or a rogue.
+	-- @name LastComboPoints
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=target.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of combo points.
+	-- @return A boolean value for the result of the comparison.
+	-- @see ComboPoints
+	-- @usage
+	-- if ComboPoints() >3 and target.LastComboPoints(rip) <3
+	--     Spell(rip)
+
+	local function LastComboPoints(condition)
+		return LastSnapshot("comboPoints", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("lastcombopoints", false, LastComboPoints)
+	OvaleCondition:RegisterCondition("lastspellcombopoints", false, LastComboPoints)
+
+	--- Get the mastery effect of the player during the most recent cast of a spell on the target.
+	-- Mastery effect is the effect of the player's mastery, typically a percent-increase to damage
+	-- or a percent-increase to chance to trigger some effect.
+	-- @name LastMastery
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=target.
+	--     Valid values: player, target, focus, pet.
+	-- @return The previous mastery effect.
+	-- @return A boolean value for the result of the comparison.
+	-- @see Mastery
+	-- @usage
+	-- if {Mastery(shadow_bolt) - LastMastery(shadow_bolt)} > 1000
+	--     Spell(metamorphosis)
+
+	local function LastMasteryEffect(condition)
+		return LastSnapshot("masteryEffect", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("lastmastery", false, LastMasteryEffect)
+	OvaleCondition:RegisterCondition("lastmasteryeffect", false, LastMasteryEffect)
+	OvaleCondition:RegisterCondition("lastspellmastery", false, LastMasteryEffect)
+
+	--- Get the melee critical strike chance of the player during the most recent cast of a spell on the target.
+	-- @name LastMeleeCritChance
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
+	--     Defaults to unlimited=0.
+	--     Valid values: 0, 1
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=target.
+	--     Valid values: player, target, focus, pet.
+	-- @return The previous critical strike chance.
+	-- @return A boolean value for the result of the comparison.
+	-- @see MeleeCritChance
+	-- @usage
+	-- if MeleeCritChance() > target.LastMeleeCritChance(rip)
+	--     Spell(rip)
+
+	local function LastMeleeCritChance(condition)
+		return LastSnapshotCritChance("meleeCrit", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("lastmeleecritchance", false, LastMeleeCritChance)
+	OvaleCondition:RegisterCondition("lastspellmeleecritchance", false, LastMeleeCritChance)
+
+	--- Get the ranged critical strike chance of the player during the most recent cast of a spell on the target.
+	-- @name LastRangedCritChance
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
+	--     Defaults to unlimited=0.
+	--     Valid values: 0, 1
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=target.
+	--     Valid values: player, target, focus, pet.
+	-- @return The previous critical strike chance.
+	-- @return A boolean value for the result of the comparison.
+	-- @see RangedCritChance
+	-- @usage
+	-- if RangedCritChance() > target.LastRangedCritChance(serpent_sting_dot)
+	--     Spell(serpent_sting)
+
+	local function LastRangedCritChance(condition)
+		return LastSnapshotCritChance("rangedCrit", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("lastrangedcritchance", false, LastRangedCritChance)
+	OvaleCondition:RegisterCondition("lastspellrangedcritchance", false, LastRangedCritChance)
+
+	--- Get the spell critical strike chance of the player during the most recent cast of a spell on the target.
+	-- @name LastSpellCritChance
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
+	--     Defaults to unlimited=0.
+	--     Valid values: 0, 1
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=target.
+	--     Valid values: player, target, focus, pet.
+	-- @return The previous critical strike chance.
+	-- @return A boolean value for the result of the comparison.
+	-- @see SpellCritChance
+	-- @usage
+	-- if SpellCritChance() > target.LastSpellCritChance(shadow_bolt)
+	--     Spell(metamorphosis)
+
+	local function LastSpellCritChance(condition)
+		return LastSnapshotCritChance("spellCrit", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("lastspellcritchance", false, LastSpellCritChance)
+	OvaleCondition:RegisterCondition("lastspellspellcritchance", false, LastSpellCritChance)
+
+	--- Get the spellpower of the player during the most recent cast of a spell on the target.
+	-- @name LastSpellpower
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=target.
+	--     Valid values: player, target, focus, pet.
+	-- @return The previous spellpower.
+	-- @return A boolean value for the result of the comparison.
+	-- @see Spellpower
+	-- @usage
+	-- if {Spellpower() / target.LastSpellpower(living_bomb)} >1.25
+	--     Spell(living_bomb)
+
+	local function LastSpellpower(condition)
+		return LastSnapshot("spellBonusDamage", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("lastspellpower", false, LastSpellpower)
+	OvaleCondition:RegisterCondition("lastspellspellpower", false, LastSpellpower)
+end
diff --git a/conditions/Latency.lua b/conditions/Latency.lua
new file mode 100644
index 0000000..4b19ec6
--- /dev/null
+++ b/conditions/Latency.lua
@@ -0,0 +1,36 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleLatency = Ovale.OvaleLatency
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the most recent estimate of roundtrip latency in milliseconds.
+	-- @name Latency
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number of milliseconds to compare against.
+	-- @return The most recent estimate of latency.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if Latency() >1000 Spell(sinister_strike)
+	-- if Latency(more 1000) Spell(sinister_strike)
+
+	local function Latency(condition)
+		local comparator, limit = condition[1], condition[2]
+		local value = OvaleLatency:GetLatency() * 1000
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("latency", false, Latency)
+end
\ No newline at end of file
diff --git a/conditions/Level.lua b/conditions/Level.lua
new file mode 100644
index 0000000..0bf816a
--- /dev/null
+++ b/conditions/Level.lua
@@ -0,0 +1,47 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePaperDoll = Ovale.OvalePaperDoll
+
+	local API_UnitLevel = UnitLevel
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	--- Get the level of the target.
+	-- @name Level
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The level of the target.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if Level() >=34 Spell(tiger_palm)
+	-- if Level(more 33) Spell(tiger_palm)
+
+	local function Level(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local value
+		if target == "player" then
+			value = OvalePaperDoll.level
+		else
+			value = API_UnitLevel(target)
+		end
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("level", false, Level)
+end
\ No newline at end of file
diff --git a/conditions/List.lua b/conditions/List.lua
new file mode 100644
index 0000000..47409b9
--- /dev/null
+++ b/conditions/List.lua
@@ -0,0 +1,37 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	--- Test if a list is currently set to the given value.
+	-- @name List
+	-- @paramsig boolean
+	-- @param id The name of a list. It should match one defined by AddListItem(...).
+	-- @param value The value to test.
+	-- @return A boolean value.
+	-- @usage
+	-- AddListItem(opt_curse coe "Curse of the Elements" default)
+	-- AddListItem(opt_curse cot "Curse of Tongues")
+	-- if List(opt_curse coe) Spell(curse_of_the_elements)
+
+	local function List(condition)
+		local name, value = condition[1], condition[2]
+		if name and Ovale:GetListValue(name) == value then
+			return 0, math.huge
+		end
+		return nil
+	end
+
+	OvaleCondition:RegisterCondition("list", false, List)
+end
\ No newline at end of file
diff --git a/conditions/ManaPercent.lua b/conditions/ManaPercent.lua
new file mode 100644
index 0000000..13a774d
--- /dev/null
+++ b/conditions/ManaPercent.lua
@@ -0,0 +1,60 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePower = Ovale.OvalePower
+	local OvaleState = Ovale.OvaleState
+
+	local API_UnitPower = UnitPower
+	local API_UnitPowerMax = UnitPowerMax
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the current percent level of mana (between 0 and 100) of the target.
+	-- @name ManaPercent
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The current mana percent.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if ManaPercent() >90 Spell(arcane_blast)
+	-- if ManaPercent(more 90) Spell(arcane_blast)
+
+	local function ManaPercent(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		if target == "player" then
+			local powerMax = OvalePower.maxPower.mana or 0
+			if powerMax > 0 then
+				local conversion = 100 / powerMax
+				local value, origin, rate = OvaleState.state.mana * conversion, OvaleState.currentTime, OvaleState.powerRate.mana * conversion
+				local start, ending = OvaleState.currentTime, math.huge
+				return TestValue(start, ending, value, origin, rate, comparator, limit)
+			end
+		else
+			local powerInfo = OvalePower.POWER_INFO.mana
+			local powerMax = API_UnitPowerMax(target, powerInfo.id) or 0
+			if powerMax > 0 then
+				local conversion = 100 / powerMax
+				local value = API_UnitPower(target, powerInfo.id) * conversion
+				return Compare(value, comparator, limit)
+			end
+		end
+	end
+
+	OvaleCondition:RegisterCondition("manapercent", false, ManaPercent)
+end
diff --git a/conditions/NextTick.lua b/conditions/NextTick.lua
new file mode 100644
index 0000000..091faca
--- /dev/null
+++ b/conditions/NextTick.lua
@@ -0,0 +1,53 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	local auraFound = {}
+
+	--- Get the number of seconds until the next tick of a periodic aura on the target.
+	-- @name NextTick
+	-- @paramsig number or boolean
+	-- @param id The spell ID of the aura or the name of a spell list.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param filter Optional. The type of aura to check.
+	--     Default is any.
+	--     Valid values: any, buff, debuff
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see Ticks, TicksRemain, TickTime
+
+	local function NextTick(condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		auraFound.tick = nil
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine, auraFound)
+		local tick = auraFound.tick
+		if ending and ending < math.huge and tick then
+			while ending - tick > OvaleState.currentTime do
+				ending = ending - tick
+			end
+			return TestValue(0, ending, 0, ending, -1, comparator, limit)
+		end
+		return nil
+	end
+
+	OvaleCondition:RegisterCondition("nexttick", false, NextTick)
+end
\ No newline at end of file
diff --git a/conditions/PTR.lua b/conditions/PTR.lua
new file mode 100644
index 0000000..19c7bad
--- /dev/null
+++ b/conditions/PTR.lua
@@ -0,0 +1,35 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local select = select
+	local API_GetBuildInfo = GetBuildInfo
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the game is on a PTR server
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then returns true if it is a PTR realm. If no, return true if it is a live realm.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value
+
+	local function PTR(condition)
+		local yesno = condition[1]
+		local uiVersion = select(4, API_GetBuildInfo())
+		local boolean = (uiVersion > 50400)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("ptr", false, PTR)
+end
\ No newline at end of file
diff --git a/conditions/PaperDoll.lua b/conditions/PaperDoll.lua
new file mode 100644
index 0000000..5d472ee
--- /dev/null
+++ b/conditions/PaperDoll.lua
@@ -0,0 +1,229 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePaperDoll = Ovale.OvalePaperDoll
+
+	local Compare = OvaleCondition.Compare
+
+	-- Returns the value of the given paper-doll stat.
+	local function PaperDoll(statName, defaultValue, condition)
+		local comparator, limit = condition[1], condition[2]
+		local value = OvalePaperDoll.stat[statName]
+		value = value and value or defaultValue
+		return Compare(value, comparator, limit)
+	end
+
+	-- Returns the critical strike chance of the given paper-doll stat.
+	local function PaperDollCritChance(statName, defaultValue, condition)
+		local comparator, limit = condition[1], condition[2]
+		local value = OvalePaperDoll.stat[statName]
+		value = value and value or defaultValue
+		if condition.unlimited ~= 1 and value > 100 then
+			value = 100
+		end
+		return Compare(value, comparator, limit)
+	end
+
+	--- Get the current agility of the player.
+	-- @name Agility
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current agility.
+	-- @return A boolean value for the result of the comparison.
+
+	local function Agility(condition)
+		return PaperDoll("agility", 0, condition)
+	end
+
+	--- Get the current attack power of the player.
+	-- @name AttackPower
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current attack power.
+	-- @return A boolean value for the result of the comparison.
+	-- @see LastAttackPower
+	-- @usage
+	-- if AttackPower() >10000 Spell(rake)
+	-- if AttackPower(more 10000) Spell(rake)
+
+	local function AttackPower(condition)
+		return PaperDoll("attackPower", 0, condition)
+	end
+
+	--- Get the current intellect of the player.
+	-- @name Intellect
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current intellect.
+	-- @return A boolean value for the result of the comparison.
+
+	local function Intellect(condition)
+		return PaperDoll("intellect", 0, condition)
+	end
+
+	--- Get the current mastery effect of the player.
+	-- Mastery effect is the effect of the player's mastery, typically a percent-increase to damage
+	-- or a percent-increase to chance to trigger some effect.
+	-- @name MasteryEffect
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current mastery effect.
+	-- @return A boolean value for the result of the comparison.
+	-- @see LastMasteryEffect
+	-- @usage
+	-- if {DamageMultiplier(rake) * {1 + MasteryEffect()/100}} >1.8
+	--     Spell(rake)
+
+	local function MasteryEffect(condition)
+		return PaperDoll("masteryEffect", 0, condition)
+	end
+
+	--- Get the current melee critical strike chance of the player.
+	-- @name MeleeCritChance
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
+	--     Defaults to unlimited=0.
+	--     Valid values: 0, 1
+	-- @return The current critical strike chance (in percent).
+	-- @return A boolean value for the result of the comparison.
+	-- @see LastMeleeCritChance
+	-- @usage
+	-- if MeleeCritChance() >90 Spell(rip)
+
+	local function MeleeCritChance(condition)
+		return PaperDollCritChance("meleeCrit", 0, condition)
+	end
+
+	--- Get the current ranged critical strike chance of the player.
+	-- @name RangedCritChance
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
+	--     Defaults to unlimited=0.
+	--     Valid values: 0, 1
+	-- @return The current critical strike chance (in percent).
+	-- @return A boolean value for the result of the comparison.
+	-- @see LastRangedCritChance
+	-- @usage
+	-- if RangedCritChance() >90 Spell(serpent_sting)
+
+	local function RangedCritChance(condition)
+		return PaperDollCritChance("rangedCrit", 0, condition)
+	end
+
+	--- Get the current spell critical strike chance of the player.
+	-- @name SpellCritChance
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param unlimited Optional. Set unlimited=1 to allow critical strike chance to exceed 100%.
+	--     Defaults to unlimited=0.
+	--     Valid values: 0, 1
+	-- @return The current critical strike chance (in percent).
+	-- @return A boolean value for the result of the comparison.
+	-- @see CritChance, LastSpellCritChance
+	-- @usage
+	-- if SpellCritChance() >30 Spell(immolate)
+
+	local function SpellCritChance(condition)
+		return PaperDollCritChance("spellCrit", 0, condition)
+	end
+
+	--- Get the current percent increase to spell haste of the player.
+	-- @name SpellHaste
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current percent increase to spell haste.
+	-- @return A boolean value for the result of the comparison.
+	-- @see BuffSpellHaste
+	-- @usage
+	-- if SpellHaste() >target.DebuffSpellHaste(moonfire) Spell(moonfire)
+
+	local function SpellHaste(condition)
+		return PaperDoll("spellHaste", 0, condition)
+	end
+
+	--- Get the current spellpower of the player.
+	-- @name Spellpower
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current spellpower.
+	-- @return A boolean value for the result of the comparison.
+	-- @see LastSpellpower
+	-- @usage
+	-- if {Spellpower() / LastSpellpower(living_bomb)} >1.25
+	--     Spell(living_bomb)
+
+	local function Spellpower(condition)
+		return PaperDoll("spellBonusDamage", 0, condition)
+	end
+
+	--- Get the current spirit of the player.
+	-- @name Spirit
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current spirit.
+	-- @return A boolean value for the result of the comparison.
+
+	local function Spirit(condition)
+		return PaperDoll("spirit", 0, condition)
+	end
+
+	--- Get the current stamina of the player.
+	-- @name Stamina
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current stamina.
+	-- @return A boolean value for the result of the comparison.
+
+	local function Stamina(condition)
+		return PaperDoll("stamina", 0, condition)
+	end
+
+	--- Get the current strength of the player.
+	-- @name Strength
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current strength.
+	-- @return A boolean value for the result of the comparison.
+
+	local function Strength(condition)
+		return PaperDoll("strength", 0, condition)
+	end
+
+	OvaleCondition:RegisterCondition("agility", false, Agility)
+	OvaleCondition:RegisterCondition("attackpower", false, AttackPower)
+	OvaleCondition:RegisterCondition("intellect", false, Intellect)
+	OvaleCondition:RegisterCondition("mastery", false, MasteryEffect)
+	OvaleCondition:RegisterCondition("masteryeffect", false, MasteryEffect)
+	OvaleCondition:RegisterCondition("meleecritchance", false, MeleeCritChance)
+	OvaleCondition:RegisterCondition("rangedcritchance", false, RangedCritChance)
+	OvaleCondition:RegisterCondition("spellcritchance", false, SpellCritChance)
+	OvaleCondition:RegisterCondition("spellhaste", false, SpellHaste)
+	OvaleCondition:RegisterCondition("spellpower", false, Spellpower)
+	OvaleCondition:RegisterCondition("spirit", false, Spirit)
+	OvaleCondition:RegisterCondition("stamina", false, Stamina)
+	OvaleCondition:RegisterCondition("strength", false, Strength)
+end
diff --git a/conditions/PetPresent.lua b/conditions/PetPresent.lua
new file mode 100644
index 0000000..3eebe2d
--- /dev/null
+++ b/conditions/PetPresent.lua
@@ -0,0 +1,40 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitExists = UnitExists
+	local API_UnitIsDead = UnitIsDead
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the pet exists and is alive.
+	-- PetPresent() is equivalent to pet.Present().
+	-- @name PetPresent
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if the target exists. If no, then return true if it doesn't exist.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @see Present
+	-- @usage
+	-- if target.IsInterruptible() and PetPresent(yes)
+	--     Spell(pet_pummel)
+
+	local function PetPresent(condition)
+		local yesno = condition[1]
+		local target = "pet"
+		local boolean = API_UnitExists(target) and not API_UnitIsDead(target)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("petpresent", false, PetPresent)
+end
diff --git a/conditions/Power.lua b/conditions/Power.lua
new file mode 100644
index 0000000..38d80ce
--- /dev/null
+++ b/conditions/Power.lua
@@ -0,0 +1,439 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePower = Ovale.OvalePower
+	local OvaleState = Ovale.OvaleState
+
+	local API_UnitPower = UnitPower
+	local API_UnitPowerMax = UnitPowerMax
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	-- Return the maximum power of the given power type on the target.
+	local function MaxPower(powerType, condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local value
+		if target == "player" then
+			value = OvalePower.maxPower[powerType]
+		else
+			local powerInfo = OvalePower.POWER_INFO[powerType]
+			value = API_UnitPowerMax(target, powerInfo.id, powerInfo.segments)
+		end
+		return Compare(value, comparator, limit)
+	end
+
+	-- Return the amount of power of the given power type on the target.
+	local function Power(powerType, condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		if target == "player" then
+			local value, origin, rate = OvaleState.state[powerType], OvaleState.currentTime, OvaleState.powerRate[powerType]
+			local start, ending = OvaleState.currentTime, math.huge
+			return TestValue(start, ending, value, origin, rate, comparator, limit)
+		else
+			local powerInfo = OvalePower.POWER_INFO[powerType]
+			local value = API_UnitPower(target, powerInfo.id)
+			return Compare(value, comparator, limit)
+		end
+	end
+
+	--- Get the current amount of alternate power displayed on the alternate power bar.
+	-- @name AlternatePower
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current alternate power.
+	-- @return A boolean value for the result of the comparison.
+
+	local function AlternatePower(condition)
+		return Power("alternate", condition)
+	end
+
+	--- Get the current number of Burning Embers for destruction warlocks.
+	-- @name BurningEmbers
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of Burning Embers.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if BurningEmbers() >10 Spell(chaos_bolt)
+	-- if BurningEmbers(more 10) Spell(chaos_bolt)
+
+	local function BurningEmbers(condition)
+		return Power("burningembers", condition)
+	end
+
+	--- Get the current amount of stored Chi for monks.
+	-- @name Chi
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The amount of stored Chi.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if Chi() ==4 Spell(chi_burst)
+	-- if Chi(more 3) Spell(chi_burst)
+
+	local function Chi(condition)
+		return Power("chi", condition)
+	end
+
+	--- Get the current amount of demonic fury for demonology warlocks.
+	-- @name DemonicFury
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The amount of demonic fury.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if DemonicFury() >=1000 Spell(metamorphosis)
+	-- if DemonicFury(more 999) Spell(metamorphosis)
+
+	local function DemonicFury(condition)
+		return Power("demonicfury", condition)
+	end
+
+	--- Get the current amount of energy for feral druids, non-mistweaver monks, and rogues.
+	-- @name Energy
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current energy.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if Energy() >70 Spell(vanish)
+	-- if Energy(more 70) Spell(vanish)
+
+	local function Energy(condition)
+		return Power("energy", condition)
+	end
+
+	--- Get the current amount of focus for hunters.
+	-- @name Focus
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current focus.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if Focus() >70 Spell(arcane_shot)
+	-- if Focus(more 70) Spell(arcane_shot)
+
+	local function Focus(condition)
+		return Power("focus", condition)
+	end
+
+	--- Get the current amount of holy power for a paladin.
+	-- @name HolyPower
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The amount of holy power.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if HolyPower() >=3 Spell(word_of_glory)
+	-- if HolyPower(more 2) Spell(word_of_glory)
+
+	local function HolyPower(condition)
+		return Power("holy", condition)
+	end
+
+	--- Get the current level of mana of the target.
+	-- @name Mana
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The current mana.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if {MaxMana() - Mana()} > 12500 Item(mana_gem)
+
+	local function Mana(condition)
+		return Power("mana", condition)
+	end
+
+	--- Get the current amount of rage for guardian druids and warriors.
+	-- @name Rage
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current rage.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if Rage() >70 Spell(heroic_strike)
+	-- if Rage(more 70) Spell(heroic_strike)
+
+	local function Rage(condition)
+		return Power("rage", condition)
+	end
+
+	--- Get the current amount of runic power for death knights.
+	-- @name RunicPower
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The current runic power.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if RunicPower() >70 Spell(frost_strike)
+	-- if RunicPower(more 70) Spell(frost_strike)
+
+	local function RunicPower(condition)
+		return Power("runicpower", condition)
+	end
+
+	--- Get the current number of Shadow Orbs for shadow priests.
+	-- @name ShadowOrbs
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of Shadow Orbs.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if ShadowOrbs() >2 Spell(mind_blast)
+	-- if ShadowOrbs(more 2) Spell(mind_blast)
+
+	local function ShadowOrbs(condition)
+		return Power("shadoworbs", condition)
+	end
+
+	--- Get the current number of Soul Shards for warlocks.
+	-- @name SoulShards
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of Soul Shards.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if SoulShards() >0 Spell(summon_felhunter)
+	-- if SoulShards(more 0) Spell(summon_felhunter)
+
+	local function SoulShards(condition)
+		return Power("shards", condition)
+	end
+
+	OvaleCondition:RegisterCondition("alternatepower", false, AlternatePower)
+	OvaleCondition:RegisterCondition("burningembers", false, BurningEmbers)
+	OvaleCondition:RegisterCondition("chi", false, Chi)
+	OvaleCondition:RegisterCondition("demonicfury", false, DemonicFury)
+	OvaleCondition:RegisterCondition("energy", false, Energy)
+	OvaleCondition:RegisterCondition("focus", false, Focus)
+	OvaleCondition:RegisterCondition("holypower", false, HolyPower)
+	OvaleCondition:RegisterCondition("mana", false, Mana)
+	OvaleCondition:RegisterCondition("rage", false, Rage)
+	OvaleCondition:RegisterCondition("runicpower", false, RunicPower)
+	OvaleCondition:RegisterCondition("shadoworbs", false, ShadowOrbs)
+	OvaleCondition:RegisterCondition("soulshards", false, SoulShards)
+
+	--- Get the maximum amount of alternate power of the target.
+	-- Alternate power is the resource tracked by the alternate power bar in certain boss fights.
+	-- @name MaxAlternatePower
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxAlternatePower(condition)
+		return MaxPower("alternate", condition)
+	end
+
+	--- Get the maximum amount of burning embers of the target.
+	-- @name MaxBurningEmbers
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxBurningEmbers(condition)
+		return MaxPower("burningembers", condition)
+	end
+
+	--- Get the maximum amount of Chi of the target.
+	-- @name MaxChi
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxChi(condition)
+		return MaxPower("chi", condition)
+	end
+
+	--- Get the maximum amount of Demonic Fury of the target.
+	-- @name MaxDemonicFury
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxDemonicFury(condition)
+		return MaxPower("demonicfury", condition)
+	end
+
+	--- Get the maximum amount of energy of the target.
+	-- @name MaxEnergy
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxEnergy(condition)
+		return MaxPower("energy", condition)
+	end
+
+	--- Get the maximum amount of focus of the target.
+	-- @name MaxFocus
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxFocus(condition)
+		return MaxPower("focus", condition)
+	end
+
+	--- Get the maximum amount of Holy Power of the target.
+	-- @name MaxHolyPower
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxHolyPower(condition)
+		return MaxPower("holy", condition)
+	end
+
+	--- Get the maximum amount of mana of the target.
+	-- @name MaxMana
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if {MaxMana() - Mana()} > 12500 Item(mana_gem)
+
+	local function MaxMana(condition)
+		return MaxPower("mana", condition)
+	end
+
+	--- Get the maximum amount of rage of the target.
+	-- @name MaxRage
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxRage(condition)
+		return MaxPower("rage", condition)
+	end
+
+	--- Get the maximum amount of Runic Power of the target.
+	-- @name MaxRunicPower
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxRunicPower(condition)
+		return MaxPower("runicpower", condition)
+	end
+
+	--- Get the maximum amount of Shadow Orbs of the target.
+	-- @name MaxShadowOrbs
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxShadowOrbs(condition)
+		return MaxPower("shadoworbs", condition)
+	end
+
+	--- Get the maximum amount of Soul Shards of the target.
+	-- @name MaxSoulShards
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The maximum value.
+	-- @return A boolean value for the result of the comparison.
+
+	local function MaxSoulShards(condition)
+		return MaxPower("shards", condition)
+	end
+
+	OvaleCondition:RegisterCondition("maxalternatepower", false, MaxAlternatePower)
+	OvaleCondition:RegisterCondition("maxburningembers", false, MaxBurningEmbers)
+	OvaleCondition:RegisterCondition("maxchi", false, MaxChi)
+	OvaleCondition:RegisterCondition("maxdemonicfury", false, MaxDemonicFury)
+	OvaleCondition:RegisterCondition("maxenergy", false, MaxEnergy)
+	OvaleCondition:RegisterCondition("maxfocus", false, MaxFocus)
+	OvaleCondition:RegisterCondition("maxholypower", false, MaxHolyPower)
+	OvaleCondition:RegisterCondition("maxmana", false, MaxMana)
+	OvaleCondition:RegisterCondition("maxrage", false, MaxRage)
+	OvaleCondition:RegisterCondition("maxrunicpower", false, MaxRunicPower)
+	OvaleCondition:RegisterCondition("maxshadoworbs", false, MaxShadowOrbs)
+	OvaleCondition:RegisterCondition("maxsoulshards", false, MaxSoulShards)
+end
diff --git a/conditions/PowerCost.lua b/conditions/PowerCost.lua
new file mode 100644
index 0000000..53b1e05
--- /dev/null
+++ b/conditions/PowerCost.lua
@@ -0,0 +1,43 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local select = select
+	local API_GetSpellInfo = GetSpellInfo
+	local Compare = OvaleCondition.Compare
+
+	--- Get the resource cost of the given spell.
+	-- This returns zero for spells that use either mana or another resource based on stance/specialization, e.g., Monk's Jab.
+	-- @name PowerCost
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The amount of power (energy, focus, rage, etc.).
+	-- @return A boolean value for the result of the comparison.
+	-- @see EnergyCost, FocusCost, ManaCost, RageCost
+	-- @usage
+	-- if Energy() > PowerCost(rake) Spell(rake)
+
+	local function PowerCost(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local value = select(4, API_GetSpellInfo(spellId)) or 0
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("energycost", true, PowerCost)
+	OvaleCondition:RegisterCondition("focuscost", true, PowerCost)
+	OvaleCondition:RegisterCondition("manacost", true, PowerCost)
+	OvaleCondition:RegisterCondition("powercost", true, PowerCost)
+	OvaleCondition:RegisterCondition("ragecost", true, PowerCost)
+end
\ No newline at end of file
diff --git a/conditions/Present.lua b/conditions/Present.lua
new file mode 100644
index 0000000..20202ed
--- /dev/null
+++ b/conditions/Present.lua
@@ -0,0 +1,43 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitExists = UnitExists
+	local API_UnitIsDead = UnitIsDead
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the target exists and is alive.
+	-- @name Present
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if the target exists. If no, then return true if it doesn't exist.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @see Exists
+	-- @usage
+	-- if target.IsInterruptible() and pet.Present(yes)
+	--     Spell(pet_pummel)
+
+	local function Present(condition)
+		local yesno = condition[1]
+		local target = ParseCondition(condition)
+		local boolean = API_UnitExists(target) and not API_UnitIsDead(target)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("present", false, Present)
+end
\ No newline at end of file
diff --git a/conditions/PreviousSpell.lua b/conditions/PreviousSpell.lua
new file mode 100644
index 0000000..521188a
--- /dev/null
+++ b/conditions/PreviousSpell.lua
@@ -0,0 +1,34 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the previous spell cast matches the given spell.
+	-- @name PreviousSpell
+	-- @paramsig boolean
+	-- @param id The spell ID.
+	-- @param yesno Optional. If yes, then return true if there is a match. If no, then return true if it doesn't match.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+
+	local function PreviousSpell(condition)
+		local spellId, yesno = condition[1], condition[2]
+		local boolean = (spellId == OvaleState.lastSpellId)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("previousspell", true, PreviousSpell)
+end
\ No newline at end of file
diff --git a/conditions/RelativeLevel.lua b/conditions/RelativeLevel.lua
new file mode 100644
index 0000000..bfc2430
--- /dev/null
+++ b/conditions/RelativeLevel.lua
@@ -0,0 +1,56 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePaperDoll = Ovale.OvalePaperDoll
+
+	local API_UnitLevel = UnitLevel
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	--- Get the result of the target's level minus the player's level. This number may be negative.
+	-- @name RelativeLevel
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The difference in levels.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if target.RelativeLevel() >3
+	--     Texture(ability_rogue_sprint)
+	-- if target.RelativeLevel(more 3)
+	--     Texture(ability_rogue_sprint)
+
+	local function RelativeLevel(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local value, level
+		if target == "player" then
+			level = OvalePaperDoll.level
+		else
+			level = API_UnitLevel(target)
+		end
+		if level < 0 then
+			-- World boss, so treat it as three levels higher.
+			value = 3
+		else
+			value = level - OvalePaperDoll.level
+		end
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("relativelevel", false, RelativeLevel)
+end
\ No newline at end of file
diff --git a/conditions/RemainingCastTime.lua b/conditions/RemainingCastTime.lua
new file mode 100644
index 0000000..0c39e85
--- /dev/null
+++ b/conditions/RemainingCastTime.lua
@@ -0,0 +1,49 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local select = select
+	local API_UnitCastingInfo = UnitCastingInfo
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the remaining cast time in seconds of the target's current spell cast.
+	-- @name RemainingCastTime
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see CastTime
+	-- @usage
+	-- if target.Casting(hour_of_twilight) and target.RemainingCastTime() <2
+	--     Spell(cloak_of_shadows)
+
+	local function RemainingCastTime(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local startTime, endTime = select(5, API_UnitCastingInfo(target))
+		if not startTime or not endTime then
+			return nil
+		end
+		startTime = startTime / 1000
+		endTime = endTime / 1000
+		return TestValue(startTime, endTime, 0, endTime, -1, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("remainingcasttime", false, RemainingCastTime)
+end
\ No newline at end of file
diff --git a/conditions/RuneCount.lua b/conditions/RuneCount.lua
new file mode 100644
index 0000000..ddabf64
--- /dev/null
+++ b/conditions/RuneCount.lua
@@ -0,0 +1,72 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local TestValue = OvaleCondition.TestValue
+
+	local RUNE_TYPE = {
+		blood = 1,
+		unholy = 2,
+		frost = 3,
+		death = 4,
+	}
+
+	--- Get the current number of runes of the given type for death knights.
+	-- @name RuneCount
+	-- @paramsig number or boolean
+	-- @param type The type of rune.
+	--     Valid values: blood, frost, unholy, death
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param death Sets whether death runes can fulfill the rune count requirements. If set to 1, then death runes are allowed.
+	--     Defaults to death=0 (zero).
+	--     Valid values: 0, 1.
+	-- @return The number of runes.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if RuneCount(unholy) ==2 or RuneCount(frost) ==2 or RuneCount(death) ==2
+	--     Spell(obliterate)
+
+	local function RuneCount(condition)
+		local runeType, comparator, limit = condition[1], condition[2], condition[3]
+		local death = condition.death
+		runeType = RUNE_TYPE[runeType]
+
+		-- Loop through the rune state and count the number of runes that match the given rune type.
+		local value, origin, rate = 0, nil, nil
+		for i = 1, 6 do
+			local rune = OvaleState.state.rune[i]
+			if rune and (rune.type == runeType or (rune.type == 4 and death == 1)) then
+				if rune.cd > OvaleState.currentTime then
+					-- Rune matches but is on cooldown.
+					if not origin or rune.cd < origin then
+						origin = rune.cd
+						rate = 1 / rune.duration
+					end
+				else
+					-- Rune matches and is available, so increment the counter.
+					value = value + 1
+				end
+			end
+		end
+		if not origin then
+			origin, rate = 0, 0
+		end
+		local start, ending = OvaleState.currentTime, math.huge
+		return TestValue(start, ending, value, origin, rate, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("runecount", false, RuneCount)
+end
diff --git a/conditions/Runes.lua b/conditions/Runes.lua
new file mode 100644
index 0000000..6c29b26
--- /dev/null
+++ b/conditions/Runes.lua
@@ -0,0 +1,96 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local wipe = table.wipe
+
+	local RUNE_TYPE = {
+		blood = 1,
+		unholy = 2,
+		frost = 3,
+		death = 4
+	}
+
+	local runes = {}
+
+	local function ParseRuneCondition(condition)
+		wipe(runes)
+
+		local k = 1
+		while true do
+			local runeType, count = condition[2*k - 1], condition[2*k]
+			if not RUNE_TYPE[runeType] then break end
+			runes[runeType] = runes[runeType] + count
+			k = k + 1
+		end
+		return runes.blood, runes.frost, runes.unholy, runes.death, condition.nodeath
+	end
+
+	--- Test if the current rune count meets the minimum rune requirements set out in the parameters.
+	-- This condition takes pairs of "type number" to mean that there must be a minimum of number runes of the named type.
+	-- E.g., Runes(blood 1 frost 1 unholy 1) means at least one blood, one frost, and one unholy rune is available, death runes included.
+	-- @name Runes
+	-- @paramsig boolean
+	-- @param type The type of rune.
+	--     Valid values: blood, frost, unholy, death
+	-- @param number The number of runes
+	-- @param ... Optional. Additional "type number" pairs for minimum rune requirements.
+	-- @param nodeath Sets whether death runes can fulfill the rune count requirements. If set to 0, then death runes are allowed.
+	--     Defaults to nodeath=0 (zero).
+	--     Valid values: 0, 1.
+	-- @return A boolean value.
+	-- @usage
+	-- if Runes(frost 1) Spell(howling_blast)
+
+	local function Runes(condition)
+		local blood, frost, unholy, death, nodeath = ParseRuneCondition(condition)
+		local seconds = OvaleState:GetRunesCooldown(blood, frost, unholy, death, nodeath)
+		local boolean = (seconds == 0)
+		if boolean then
+			return 0, math.huge
+		end
+		return nil
+	end
+
+	--- Get the number of seconds before the rune conditions are met.
+	-- This condition takes pairs of "type number" to mean that there must be a minimum of number runes of the named type.
+	-- E.g., RunesCooldown(blood 1 frost 1 unholy 1) returns the number of seconds before
+	-- there are at least one blood, one frost, and one unholy rune, death runes included.
+	-- @name RunesCooldown
+	-- @paramsig number
+	-- @param type The type of rune.
+	--     Valid values: blood, frost, unholy, death
+	-- @param number The number of runes
+	-- @param ... Optional. Additional "type number" pairs for minimum rune requirements.
+	-- @param nodeath Sets whether death runes can fulfill the rune count requirements. If set to 0, then death runes are allowed.
+	--     Defaults to nodeath=0 (zero).
+	--     Valid values: 0, 1.
+	-- @return The number of seconds.
+
+	local function RunesCooldown(condition)
+		local blood, frost, unholy, death, nodeath = ParseRuneCondition(condition)
+		local seconds = OvaleState:GetRunesCooldown(blood, frost, unholy, death, nodeath)
+		if seconds then
+			if seconds < OvaleState.maintenant then
+				seconds = OvaleState.maintenant
+			end
+			return 0, OvaleState.currentTime + seconds, seconds, OvaleState.currentTime, -1
+		end
+		return nil
+	end
+
+	OvaleCondition:RegisterCondition("runes", false, Runes)
+	OvaleCondition:RegisterCondition("runescooldown", false, RunesCooldown)
+end
\ No newline at end of file
diff --git a/conditions/Speed.lua b/conditions/Speed.lua
new file mode 100644
index 0000000..3b3769b
--- /dev/null
+++ b/conditions/Speed.lua
@@ -0,0 +1,44 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_GetUnitSpeed = GetUnitSpeed
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	--- Get the current speed of the target.
+	-- If the target is not moving, then this condition returns 0 (zero).
+	-- If the target is at running speed, then this condition returns 100.
+	-- @name Speed
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The speed of the target.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if Speed(more 0) and not BuffPresent(aspect_of_the_fox)
+	--     Spell(aspect_of_the_fox)
+
+	local function Speed(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local value = API_GetUnitSpeed(target) * 100 / 7
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("speed", false, Speed)
+end
\ No newline at end of file
diff --git a/conditions/SpellChargeCooldown.lua b/conditions/SpellChargeCooldown.lua
new file mode 100644
index 0000000..723836f
--- /dev/null
+++ b/conditions/SpellChargeCooldown.lua
@@ -0,0 +1,42 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_GetSpellCharges = GetSpellCharges
+	local Compare = OvaleCondition.Compare
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the cooldown in seconds on a spell before it gains another charge.
+	-- @name SpellChargeCooldown
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see SpellCharges
+	-- @usage
+	-- if SpellChargeCooldown(roll) <2
+	--     Spell(roll usable=1)
+
+	local function SpellChargeCooldown(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local charges, maxCharges, start, duration = API_GetSpellCharges(spellId)
+		if charges < maxCharges then
+			return TestValue(start, start + duration, duration, start, -1, comparator, limit)
+		end
+		return Compare(0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("spellchargecooldown", true, SpellChargeCooldown)
+end
\ No newline at end of file
diff --git a/conditions/SpellCharges.lua b/conditions/SpellCharges.lua
new file mode 100644
index 0000000..c7827cd
--- /dev/null
+++ b/conditions/SpellCharges.lua
@@ -0,0 +1,39 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_GetSpellCharges = GetSpellCharges
+	local Compare = OvaleCondition.Compare
+
+	--- Get the number of charges of the spell.
+	-- @name SpellCharges
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of charges.
+	-- @return A boolean value for the result of the comparison.
+	-- @see SpellChargeCooldown
+	-- @usage
+	-- if SpellCharges(savage_defense) >1
+	--     Spell(savage_defense)
+
+	local function SpellCharges(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local value = API_GetSpellCharges(spellId)
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("charges", true, SpellCharges)
+	OvaleCondition:RegisterCondition("spellcharges", true, SpellCharges)
+end
diff --git a/conditions/SpellCooldown.lua b/conditions/SpellCooldown.lua
new file mode 100644
index 0000000..bbb7a59
--- /dev/null
+++ b/conditions/SpellCooldown.lua
@@ -0,0 +1,56 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleSpellBook = Ovale.OvaleSpellBook
+	local OvaleState = Ovale.OvaleState
+
+	local type = type
+	local Compare = OvaleCondition.Compare
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the cooldown in seconds before a spell is ready for use.
+	-- @name SpellCooldown
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if ShadowOrbs() ==3 and SpellCooldown(mind_blast) <2
+	--     Spell(devouring_plague)
+
+	local function SpellCooldown(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local start, duration
+		if type(spellId) == "string" then
+			local sharedCd = OvaleState.state.cd[spellId]
+			if not sharedCd then
+				return nil
+			end
+			start, duration = sharedCd.start, sharedCd.duration
+		elseif not OvaleSpellBook:IsKnownSpell(spellId) then
+			return nil
+		else
+			start, duration = OvaleState:GetComputedSpellCD(spellId)
+		end
+		if start > 0 and duration > 0 then
+			return TestValue(start, start + duration, duration, start, -1, comparator, limit)
+		end
+		return Compare(0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("spellcooldown", true, SpellCooldown)
+end
\ No newline at end of file
diff --git a/conditions/SpellData.lua b/conditions/SpellData.lua
new file mode 100644
index 0000000..8fbd65b
--- /dev/null
+++ b/conditions/SpellData.lua
@@ -0,0 +1,46 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleData = Ovale.OvaleData
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get data for the given spell defined by SpellInfo(...)
+	-- @name SpellData
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param key The name of the data set by SpellInfo(...).
+	--     Valid values are any alphanumeric string.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number data associated with the given key.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if BuffRemains(slice_and_dice) >= SpellData(shadow_blades duration)
+	--     Spell(shadow_blades)
+
+	local function SpellData(condition)
+		local spellId, key, comparator, limit = condition[1], condition[2], condition[3], condition[4]
+		local si = OvaleData.spellInfo[spellId]
+		if si then
+			local value = si[key]
+			if value then
+				return Compare(value, comparator, limit)
+			end
+		end
+		return nil
+	end
+
+	OvaleCondition:RegisterCondition("spelldata", false, SpellData)
+end
\ No newline at end of file
diff --git a/conditions/SpellKnown.lua b/conditions/SpellKnown.lua
new file mode 100644
index 0000000..abcf61c
--- /dev/null
+++ b/conditions/SpellKnown.lua
@@ -0,0 +1,41 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleSpellBook = Ovale.OvaleSpellBook
+
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the given spell is in the spellbook.
+	-- A spell is known if the player has learned the spell and it is in the spellbook.
+	-- @name SpellKnown
+	-- @paramsig boolean
+	-- @param id The spell ID.
+	-- @param yesno Optional. If yes, then return true if the spell has been learned.
+	--     If no, then return true if the player hasn't learned the spell.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @see SpellUsable
+	-- @usage
+	-- if SpellKnown(avenging_wrath) and SpellCooldown(avenging_wrath) <10
+	--     Spell(guardian_of_ancient_kings_retribution)
+
+	local function SpellKnown(condition)
+		local spellId, yesno = condition[1], condition[2]
+		local boolean = OvaleSpellBook:IsKnownSpell(spellId)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("spellknown", true, SpellKnown)
+end
\ No newline at end of file
diff --git a/conditions/SpellUsable.lua b/conditions/SpellUsable.lua
new file mode 100644
index 0000000..ce1843e
--- /dev/null
+++ b/conditions/SpellUsable.lua
@@ -0,0 +1,41 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_IsUsableSpell = IsUsableSpell
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the given spell is usable.
+	-- A spell is usable if the player has learned the spell and has the resources required to cast the spell.
+	-- @name SpellUsable
+	-- @paramsig boolean
+	-- @param id The spell ID.
+	-- @param yesno Optional. If yes, then return true if the spell has been learned and the player has enough resources to cast it.
+	--     If no, then return true if the player can't cast the spell for one of the above reasons.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @see SpellKnown
+	-- @usage
+	-- if SpellUsable(avenging_wrath) and SpellCooldown(avenging_wrath) <10
+	--     Spell(guardian_of_ancient_kings_retribution)
+
+	local function SpellUsable(condition)
+		local spellId, yesno = condition[1], condition[2]
+		local boolean = API_IsUsableSpell(spellId)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("spellusable", true, SpellUsable)
+end
\ No newline at end of file
diff --git a/conditions/StaggerRemains.lua b/conditions/StaggerRemains.lua
new file mode 100644
index 0000000..bdc1a6f
--- /dev/null
+++ b/conditions/StaggerRemains.lua
@@ -0,0 +1,57 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local API_UnitStagger = UnitStagger
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	local LIGHT_STAGGER = 124275
+	local MODERATE_STAGGER = 124274
+	local HEAVY_STAGGER = 124273
+
+	--- Get the remaining amount of damage Stagger will cause to the target.
+	-- @name StaggerRemains
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The amount of damage.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if StaggerRemains() / MaxHealth() >0.4 Spell(purifying_brew)
+
+	local function StaggerRemains(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition)
+		local start, ending, stacks
+		start, ending, stacks = OvaleState:GetAura(target, HEAVY_STAGGER, "HARMFUL")
+		if not stacks or stacks == 0 then
+			start, ending, stacks = OvaleState:GetAura(target, MODERATE_STAGGER, "HARMFUL")
+		end
+		if not stacks or stacks == 0 then
+			start, ending, stacks = OvaleState:GetAura(target, LIGHT_STAGGER, "HARMFUL")
+		end
+		if start and ending then
+			local stagger = API_UnitStagger(target)
+			return TestValue(start, ending, 0, ending, -1 * stagger / (ending - start), comparator, limit)
+		end
+		return Compare(0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("staggerremains", false, StaggerRemains)
+end
\ No newline at end of file
diff --git a/conditions/Stance.lua b/conditions/Stance.lua
new file mode 100644
index 0000000..cfd914c
--- /dev/null
+++ b/conditions/Stance.lua
@@ -0,0 +1,36 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleStance = Ovale.OvaleStance
+
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player is in a given stance.
+	-- @name Stance
+	-- @paramsig boolean
+	-- @param stance The stance name or a number representing the stance index.
+	-- @param yesno Optional. If yes, then return true if the player is in the given stance. If no, then return true otherwise.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- unless Stance(druid_bear_form) Spell(bear_form)
+
+	local function Stance(condition)
+		local stance, yesno = condition[1], condition[2]
+		local boolean = OvaleStance:IsStance(stance)
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("stance", false, Stance)
+end
\ No newline at end of file
diff --git a/conditions/Stealthed.lua b/conditions/Stealthed.lua
new file mode 100644
index 0000000..0123981
--- /dev/null
+++ b/conditions/Stealthed.lua
@@ -0,0 +1,40 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_IsStealthed = IsStealthed
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player is currently stealthed.
+	-- The player is stealthed if rogue Stealth, druid Prowl, or a similar ability is active.
+	-- Note that the rogue Vanish buff causes this condition to return false,
+	-- but as soon as the buff disappears and the rogue is stealthed, this condition will return true.
+	-- @name Stealthed
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if stealthed. If no, then return true if it not stealthed.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @return A boolean value.
+	-- @usage
+	-- if Stealthed() or BuffPresent(vanish_buff) or BuffPresent(shadow_dance)
+	--     Spell(ambush)
+
+	local function Stealthed(condition)
+		local yesno = condition[1]
+		local boolean = API_IsStealthed()
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("isstealthed", false, Stealthed)
+	OvaleCondition:RegisterCondition("stealthed", false, Stealthed)
+end
\ No newline at end of file
diff --git a/conditions/Swing.lua b/conditions/Swing.lua
new file mode 100644
index 0000000..444b565
--- /dev/null
+++ b/conditions/Swing.lua
@@ -0,0 +1,72 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleSwing = Ovale.OvaleSwing
+
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the time elapsed in seconds since the player's previous melee swing (white attack).
+	-- @name LastSwing
+	-- @paramsig number or boolean
+	-- @param hand Optional. Sets which hand weapon's melee swing.
+	--     If no hand is specified, then return the time elapsed since the previous swing of either hand's weapon.
+	--     Valid values: main, off.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see NextSwing
+
+	local function LastSwing(condition)
+		local swing = condition[1]
+		local comparator, limit
+		local start
+		if swing and swing == "main" or swing == "off" then
+			comparator, limit = condition[2], condition[3]
+			start = OvaleSwing:GetLast(swing)
+		else
+			comparator, limit = condition[1], condition[2]
+			start = OvaleSwing:GetLast()
+		end
+		return TestValue(start, math.huge, 0, start, 1, comparator, limit)
+	end
+
+	--- Get the time in seconds until the player's next melee swing (white attack).
+	-- @name NextSwing
+	-- @paramsig number or boolean
+	-- @param hand Optional. Sets which hand weapon's melee swing.
+	--     If no hand is specified, then return the time until the next swing of either hand's weapon.
+	--     Valid values: main, off.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of seconds
+	-- @return A boolean value for the result of the comparison.
+	-- @see LastSwing
+
+	local function NextSwing(condition)
+		local swing = condition[1]
+		local comparator, limit
+		local ending
+		if swing and swing == "main" or swing == "off" then
+			comparator, limit = condition[2], condition[3]
+			ending = OvaleSwing:GetNext(swing)
+		else
+			comparator, limit = condition[1], condition[2]
+			ending = OvaleSwing:GetNext()
+		end
+		return TestValue(0, ending, 0, ending, -1, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("lastswing", false, LastSwing)
+	OvaleCondition:RegisterCondition("nextswing", false, NextSwing)
+end
\ No newline at end of file
diff --git a/conditions/TalentPoints.lua b/conditions/TalentPoints.lua
new file mode 100644
index 0000000..cd69656
--- /dev/null
+++ b/conditions/TalentPoints.lua
@@ -0,0 +1,36 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleSpellBook = Ovale.OvaleSpellBook
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the number of points spent in a talent (0 or 1)
+	-- @name TalentPoints
+	-- @paramsig number or boolean
+	-- @param talent Talent to inspect.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of talent points.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if TalentPoints(blood_tap_talent) Spell(blood_tap)
+
+	local function TalentPoints(condition)
+		local talent, comparator, limit = condition[1], condition[2], condition[3]
+		local value = OvaleSpellBook:GetTalentPoints(talent)
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("talentpoints", false, TalentPoints)
+end
\ No newline at end of file
diff --git a/conditions/TargetIsPlayer.lua b/conditions/TargetIsPlayer.lua
new file mode 100644
index 0000000..2002b72
--- /dev/null
+++ b/conditions/TargetIsPlayer.lua
@@ -0,0 +1,42 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local API_UnitIsUnit = UnitIsUnit
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	--- Test if the player is the in-game target of the target.
+	-- @name TargetIsPlayer
+	-- @paramsig boolean
+	-- @param yesno Optional. If yes, then return true if it matches. If no, then return true if it doesn't match.
+	--     Default is yes.
+	--     Valid values: yes, no.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return A boolean value.
+	-- @usage
+	-- if target.TargetIsPlayer() Spell(feign_death)
+
+	local function TargetIsPlayer(condition)
+		local yesno = condition[1]
+		local target = ParseCondition(condition)
+		local boolean = API_UnitIsUnit("player", target .. "target")
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("istargetingplayer", false, TargetIsPlayer)
+	OvaleCondition:RegisterCondition("targetisplayer", false, TargetIsPlayer)
+end
\ No newline at end of file
diff --git a/conditions/Threat.lua b/conditions/Threat.lua
new file mode 100644
index 0000000..75bfccf
--- /dev/null
+++ b/conditions/Threat.lua
@@ -0,0 +1,44 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local select = select
+	local API_UnitDetailedThreatSituation = UnitDetailedThreatSituation
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	--- Get the amount of threat on the current target relative to the its primary aggro target, scaled to between 0 (zero) and 100.
+	-- This is a number between 0 (no threat) and 100 (will become the primary aggro target).
+	-- @name Threat
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=target.
+	--     Valid values: player, target, focus, pet.
+	-- @return The amount of threat.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if Threat() >90 Spell(fade)
+	-- if Threat(more 90) Spell(fade)
+
+	local function Threat(condition)
+		local comparator, limit = condition[1], condition[2]
+		local target = ParseCondition(condition, "target")
+		local value = select(3, API_UnitDetailedThreatSituation("player", target))
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("threat", false, Threat)
+end
\ No newline at end of file
diff --git a/conditions/TickTime.lua b/conditions/TickTime.lua
new file mode 100644
index 0000000..7712748
--- /dev/null
+++ b/conditions/TickTime.lua
@@ -0,0 +1,53 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleAura = Ovale.OvaleAura
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	local auraFound = {}
+
+	--- Get the number of seconds between ticks of a periodic aura on a target.
+	-- @name TickTime
+	-- @paramsig number or boolean
+	-- @param id The spell ID of the aura or the name of a spell list.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param filter Optional. The type of aura to check.
+	--     Default is any.
+	--     Valid values: any, buff, debuff
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see NextTick, Ticks, TicksRemain
+
+	local function TickTime(condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		auraFound.tick = nil
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine, auraFound)
+		local value = auraFound.tick
+		value = value and value or OvaleAura:GetTickLength(auraId)
+		if value then
+			return Compare(value, comparator, limit)
+		end
+		return nil
+	end
+
+	OvaleCondition:RegisterCondition("ticktime", false, TickTime)
+end
\ No newline at end of file
diff --git a/conditions/Ticks.lua b/conditions/Ticks.lua
new file mode 100644
index 0000000..1d3dcdb
--- /dev/null
+++ b/conditions/Ticks.lua
@@ -0,0 +1,56 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local floor = math.floor
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+
+	local auraFound = {}
+
+	--- Get the total number of ticks of a periodic aura.
+	-- @name Ticks
+	-- @paramsig number or boolean
+	-- @param id The spell ID of the aura or the name of a spell list.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of ticks.
+	-- @return A boolean value for the result of the comparison.
+	-- @see NextTick, TicksRemain, TickTime
+
+	local function Ticks(condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		auraFound.tick = nil
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine, auraFound)
+		local tick = auraFound.tick
+		local duration, numTicks
+		if start then
+			-- Aura exists on the target
+			if ending and tick and tick > 0 then
+				duration = ending - start
+				numTicks = floor(duration / tick + 0.5)
+			end
+		else
+			duration, tick, numTicks = OvaleState:GetDuration(auraId)
+		end
+		if numTicks then
+			return Compare(numTicks, comparator, limit)
+		end
+		return nil
+	end
+
+	OvaleCondition:RegisterCondition("ticks", false, Ticks)
+end
\ No newline at end of file
diff --git a/conditions/TicksAdded.lua b/conditions/TicksAdded.lua
new file mode 100644
index 0000000..200538a
--- /dev/null
+++ b/conditions/TicksAdded.lua
@@ -0,0 +1,42 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	local auraFound = {}
+
+	--- Get the number of ticks that would be added if the dot were refreshed.
+	-- Not implemented, always returns 0.
+	-- @name TicksAdded
+	-- @paramsig number or boolean
+	-- @param id The aura spell ID
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of added ticks.
+	-- @return A boolean value for the result of the comparison.
+
+	local function TicksAdded(condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		auraFound.tick = nil
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine, auraFound)
+		local tick = auraFound.tick
+		return TestValue(start, ending, 0, start, 0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("ticksadded", false, TicksAdded)
+end
\ No newline at end of file
diff --git a/conditions/TicksRemain.lua b/conditions/TicksRemain.lua
new file mode 100644
index 0000000..7c0e2e8
--- /dev/null
+++ b/conditions/TicksRemain.lua
@@ -0,0 +1,55 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+	local ParseCondition = OvaleCondition.ParseCondition
+	local TestValue = OvaleCondition.TestValue
+
+	local auraFound = {}
+
+	--- Get the remaining number of ticks of a periodic aura on a target.
+	-- @name TicksRemain
+	-- @paramsig number or boolean
+	-- @param id The spell ID of the aura or the name of a spell list.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param filter Optional. The type of aura to check.
+	--     Default is any.
+	--     Valid values: any, buff, debuff
+	-- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition.
+	--     Defaults to target=player.
+	--     Valid values: player, target, focus, pet.
+	-- @return The number of ticks.
+	-- @return A boolean value for the result of the comparison.
+	-- @see NextTick, Ticks, TickTime
+	-- @usage
+	-- if target.TicksRemain(shadow_word_pain) <2
+	--     Spell(shadow_word_pain)
+
+	local function TicksRemain(condition)
+		local auraId, comparator, limit = condition[1], condition[2], condition[3]
+		local target, filter, mine = ParseCondition(condition)
+		auraFound.tick = nil
+		local start, ending = OvaleState:GetAura(target, auraId, filter, mine, auraFound)
+		local tick = auraFound.tick
+		if ending and tick and tick > 0 then
+			return TestValue(start, ending, 1, ending, -1/tick, comparator, limit)
+		end
+		return Compare(0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("ticksremain", false, TicksRemain)
+end
\ No newline at end of file
diff --git a/conditions/TimeInCombat.lua b/conditions/TimeInCombat.lua
new file mode 100644
index 0000000..66cd337
--- /dev/null
+++ b/conditions/TimeInCombat.lua
@@ -0,0 +1,38 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	local Compare = OvaleCondition.Compare
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the number of seconds elapsed since the player entered combat.
+	-- @name TimeInCombat
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if TimeInCombat(more 5) Spell(bloodlust)
+
+	local function TimeInCombat(condition)
+		local comparator, limit = condition[1], condition[2]
+		if Ovale.enCombat then
+			local start = Ovale.combatStartTime
+			return TestValue(start, math.huge, 0, start, 1, comparator, limit)
+		end
+		return Compare(0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("timeincombat", false, TimeInCombat)
+end
\ No newline at end of file
diff --git a/conditions/TimeToMaxEnergy.lua b/conditions/TimeToMaxEnergy.lua
new file mode 100644
index 0000000..4c21548
--- /dev/null
+++ b/conditions/TimeToMaxEnergy.lua
@@ -0,0 +1,44 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePower = Ovale.OvalePower
+	local OvaleState = Ovale.OvaleState
+
+	local Compare = OvaleCondition.Compare
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the number of seconds before the player reaches maximum energy for feral druids, non-mistweaver monks and rogues.
+	-- @name TimeToMaxEnergy
+	-- @paramsig number or boolean
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of seconds.
+	-- @see TimeToEnergyFor
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if TimeToMaxEnergy() < 1.2 Spell(sinister_strike)
+
+	local function TimeToMaxEnergy(condition)
+		local comparator, limit = condition[1], condition[2]
+		local maxEnergy = OvalePower.maxPower.energy or 0
+		local energy = OvaleState.state.energy or 0
+		local energyRegen = OvaleState.powerRate.energy or 10
+		local t = (maxEnergy - energy) / energyRegen
+		if t > 0 then
+			return TestValue(0, OvaleState.currentTime + t, t, OvaleState.currentTime, -1, comparator, limit)
+		end
+		return Compare(0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("timetomaxenergy", false, TimeToMaxEnergy)
+end
\ No newline at end of file
diff --git a/conditions/TimeToPowerFor.lua b/conditions/TimeToPowerFor.lua
new file mode 100644
index 0000000..2a0c517
--- /dev/null
+++ b/conditions/TimeToPowerFor.lua
@@ -0,0 +1,53 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePower = Ovale.OvalePower
+	local OvaleState = Ovale.OvaleState
+
+	local select = select
+	local API_GetSpellInfo = GetSpellInfo
+	local Compare = OvaleCondition.Compare
+	local TestValue = OvaleCondition.TestValue
+
+	--- Get the number of seconds before the player has enough primary resources to cast the given spell.
+	-- @name TimeToPowerFor
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see TimeToEnergyFor, TimeToFocusFor, TimeToMaxEnergy
+
+	local function TimeToPowerFor(condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		local cost, _, powerToken = select(4, API_GetSpellInfo(spellId))
+		local powerType = OvalePower.POWER_TYPE[powerToken]
+		local currentPower = OvaleState.state[powerType]
+		local powerRate = OvaleState.powerRate[powerType]
+		cost = cost or 0
+		if currentPower < cost then
+			if powerRate > 0 then
+				local t = (cost - currentPower)/powerRate
+				return TestValue(0, OvaleState.currentTime + t, t, OvaleState.currentTime, -1, comparator, limit)
+			else
+				return Compare(math.huge, comparator, limit)
+			end
+		end
+		return Compare(0, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("timetoenergyfor", true, TimeToPowerFor)
+	OvaleCondition:RegisterCondition("timetofocusfor", true, TimeToPowerFor)
+	OvaleCondition:RegisterCondition("timetopowerfor", true, TimeToPowerFor)
+end
\ No newline at end of file
diff --git a/conditions/TimeWithHaste.lua b/conditions/TimeWithHaste.lua
new file mode 100644
index 0000000..f4b05cb
--- /dev/null
+++ b/conditions/TimeWithHaste.lua
@@ -0,0 +1,50 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePaperDoll = Ovale.OvalePaperDoll
+
+	local Compare = OvaleCondition.Compare
+
+	--- Get the time scaled by the specified haste type, defaulting to spell haste.
+	--- For example, if a DoT normally ticks every 3 seconds and is scaled by spell haste, then it ticks every TimeWithHaste(3 haste=spell) seconds.
+	-- @name TimeWithHaste
+	-- @paramsig number or boolean
+	-- @param time The time in seconds.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @param haste Optional. Sets whether "time" should be lengthened or shortened due to haste.
+	--     Defaults to haste=spell.
+	--     Valid values: melee, spell.
+	-- @return The time in seconds scaled by haste.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- if target.DebuffRemains(flame_shock) < TimeWithHaste(3)
+	--     Spell(flame_shock)
+
+	local function TimeWithHaste(condition)
+		local seconds, comparator, limit = condition[1], condition[2], condition[3]
+		local haste = condition.haste or "spell"
+		seconds = seconds or 0
+		local value = seconds
+		if haste == "spell" then
+			value = seconds / OvalePaperDoll:GetSpellHasteMultiplier()
+		elseif haste == "melee" then
+			value = seconds / OvalePaperDoll:GetMeleeHasteMultiplier()
+		else
+			Ovale:Logf("Unknown haste parameter haste=%s", haste)
+		end
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("timewithhaste", false, TimeWithHaste)
+end
\ No newline at end of file
diff --git a/conditions/TotemExpires.lua b/conditions/TotemExpires.lua
new file mode 100644
index 0000000..c73e184
--- /dev/null
+++ b/conditions/TotemExpires.lua
@@ -0,0 +1,95 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleSpellBook = Ovale.OvaleSpellBook
+
+	local select = select
+	local type = type
+	local API_GetTotemInfo = GetTotemInfo
+
+	local OVALE_TOTEMTYPE =
+	{
+		-- Death Knights
+		ghoul = 1,
+		-- Monks
+		statue = 1,
+		-- Shamans
+		fire = 1,
+		earth = 2,
+		water = 3,
+		air = 4
+	}
+
+	--- Test if the totem for shamans, the ghoul for death knights, or the statue for monks has expired.
+	-- @name TotemExpires
+	-- @paramsig boolean
+	-- @param id The totem ID of the totem, ghoul or statue, or the type of totem.
+	--     Valid types: fire, water, air, earth, ghoul, statue.
+	-- @param seconds Optional. The maximum number of seconds before the totem should expire.
+	--     Defaults to 0 (zero).
+	-- @param totem Optional. Sets the specific totem to check of given totem ID type.
+	--     Valid values: any totem spell ID
+	-- @return A boolean value.
+	-- @see TotemPresent
+	-- @usage
+	-- if TotemExpires(fire) Spell(searing_totem)
+	-- if TotemPresent(water totem=healing_stream_totem) and TotemExpires(water 3) Spell(totemic_recall)
+
+	local function TotemExpires(condition)
+		local totemId, seconds = condition[1], condition[2]
+		seconds = seconds or 0
+		if type(totemId) ~= "number" then
+			totemId = OVALE_TOTEMTYPE[totemId]
+		end
+		local haveTotem, name, startTime, duration = API_GetTotemInfo(totemId)
+		if not haveTotem or not startTime then
+			return 0, math.huge
+		end
+		if condition.totem and OvaleSpellBook:GetSpellName(condition.totem) ~= name then
+			return 0, math.huge
+		end
+		return startTime + duration - seconds, math.huge
+	end
+
+	--- Test if the totem for shamans, the ghoul for death knights, or the statue for monks is present.
+	-- @name TotemPresent
+	-- @paramsig boolean
+	-- @param id The totem ID of the totem, ghoul or statue, or the type of totem.
+	--     Valid types: fire, water, air, earth, ghoul, statue.
+	-- @param totem Optional. Sets the specific totem to check of given totem ID type.
+	--     Valid values: any totem spell ID
+	-- @return A boolean value.
+	-- @see TotemExpires
+	-- @usage
+	-- if not TotemPresent(fire) Spell(searing_totem)
+	-- if TotemPresent(water totem=healing_stream_totem) and TotemExpires(water 3) Spell(totemic_recall)
+
+	local function TotemPresent(condition)
+		local totemId = condition[1]
+		if type(totemId) ~= "number" then
+			totemId = OVALE_TOTEMTYPE[totemId]
+		end
+		local haveTotem, name, startTime, duration = API_GetTotemInfo(totemId)
+		if not haveTotem or not startTime then
+			return nil
+		end
+		if condition.totem and OvaleSpellBook:GetSpellName(condition.totem) ~= name then
+			return nil
+		end
+		return startTime, startTime + duration
+	end
+
+	OvaleCondition:RegisterCondition("totemexpires", false, TotemExpires)
+	OvaleCondition:RegisterCondition("totempresent", false, TotemPresent)
+end
\ No newline at end of file
diff --git a/conditions/Tracking.lua b/conditions/Tracking.lua
new file mode 100644
index 0000000..15fd673
--- /dev/null
+++ b/conditions/Tracking.lua
@@ -0,0 +1,41 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleSpellBook = Ovale.OvaleSpellBook
+
+	local API_GetNumTrackingTypes = GetNumTrackingTypes
+	local API_GetTrackingInfo = GetTrackingInfo
+	local TestBoolean = OvaleCondition.TestBoolean
+
+	-- Check if a tracking is enabled
+	-- 1: the spell id
+	-- return bool
+
+	local function Tracking(condition)
+		local spellId, yesno = condition[1], condition[2]
+		local spellName = OvaleSpellBook:GetSpellName(spellId)
+		local numTrackingTypes = API_GetNumTrackingTypes()
+		local boolean = false
+		for i = 1, numTrackingTypes do
+			local name, _, active = API_GetTrackingInfo(i)
+			if name and name == spellName then
+				boolean = (active == 1)
+				break
+			end
+		end
+		return TestBoolean(boolean, yesno)
+	end
+
+	OvaleCondition:RegisterCondition("tracking", false, Tracking)
+end
\ No newline at end of file
diff --git a/conditions/True.lua b/conditions/True.lua
new file mode 100644
index 0000000..613f451
--- /dev/null
+++ b/conditions/True.lua
@@ -0,0 +1,25 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+
+	--- A condition that always returns true.
+	-- @name True
+	-- @paramsig boolean
+	-- @return A boolean value.
+
+	local function True(condition)
+		return 0, math.huge
+	end
+
+	OvaleCondition:RegisterCondition("true", false, True)
+end
\ No newline at end of file
diff --git a/conditions/WeaponDamage.lua b/conditions/WeaponDamage.lua
new file mode 100644
index 0000000..65c728f
--- /dev/null
+++ b/conditions/WeaponDamage.lua
@@ -0,0 +1,51 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvalePaperDoll = Ovale.OvalePaperDoll
+
+	local Compare = OvaleCondition.Compare
+
+	--- The normalized weapon damage of the weapon in the given hand.
+	-- @name WeaponDamage
+	-- @paramsig number or boolean
+	-- @param hand Optional. Sets which hand weapon.
+	--     Defaults to main.
+	--     Valid values: main, off
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The normalized weapon damage.
+	-- @return A boolean value for the result of the comparison.
+	-- @usage
+	-- AddFunction MangleDamage {
+	--     WeaponDamage() * 5 + 78
+	-- }
+
+	local function WeaponDamage(condition)
+		local hand = condition[1]
+		local comparator, limit
+		local value = 0
+		if hand == "offhand" or hand == "off" then
+			comparator, limit = condition[2], condition[3]
+			value = OvalePaperDoll.stat.offHandWeaponDamage
+		elseif hand == "mainhand" or hand == "main" then
+			comparator, limit = condition[2], condition[3]
+			value = OvalePaperDoll.stat.mainHandWeaponDamage
+		else
+			comparator, limit = condition[1], condition[2]
+			value = OvalePaperDoll.stat.mainHandWeaponDamage
+		end
+		return Compare(value, comparator, limit)
+	end
+
+	OvaleCondition:RegisterCondition("weapondamage", false, WeaponDamage)
+end
\ No newline at end of file
diff --git a/conditions/WeaponEnchantExpires.lua b/conditions/WeaponEnchantExpires.lua
new file mode 100644
index 0000000..7908fcb
--- /dev/null
+++ b/conditions/WeaponEnchantExpires.lua
@@ -0,0 +1,50 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012, 2013 Sidoine
+    Copyright (C) 2012, 2013 Johnny C. Lam
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License in the LICENSE
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+	local OvaleCondition = Ovale.OvaleCondition
+	local OvaleState = Ovale.OvaleState
+
+	local API_GetWeaponEnchantInfo = GetWeaponEnchantInfo
+
+	--- Test if the weapon imbue on the given weapon has expired or will expire after a given number of seconds.
+	-- @name WeaponEnchantExpires
+	-- @paramsig boolean
+	-- @param hand Sets which hand weapon.
+	--     Valid values: main, off.
+	-- @param seconds Optional. The maximum number of seconds before the weapon imbue should expire.
+	--     Defaults to 0 (zero).
+	-- @return A boolean value.
+	-- @usage
+	-- if WeaponEnchantExpires(main) Spell(windfury_weapon)
+
+	local function WeaponEnchantExpires(condition)
+		local hand, seconds = condition[1], condition[2]
+		seconds = seconds or 0
+		local hasMainHandEnchant, mainHandExpiration, _, hasOffHandEnchant, offHandExpiration = API_GetWeaponEnchantInfo()
+		if hand == "mainhand" or hand == "main" then
+			if not hasMainHandEnchant then
+				return 0, math.huge
+			end
+			mainHandExpiration = mainHandExpiration / 1000
+			return OvaleState.maintenant + mainHandExpiration - seconds, math.huge
+		else
+			if not hasOffHandEnchant then
+				return 0, math.huge
+			end
+			offHandExpiration = offHandExpiration / 1000
+			return OvaleState.maintenant + offHandExpiration - seconds, math.huge
+		end
+	end
+
+	OvaleCondition:RegisterCondition("weaponenchantexpires", false, WeaponEnchantExpires)
+end
\ No newline at end of file
diff --git a/conditions/conditions.xml b/conditions/conditions.xml
new file mode 100644
index 0000000..59af71f
--- /dev/null
+++ b/conditions/conditions.xml
@@ -0,0 +1,102 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
+	<Script file="AfterWhiteHit.lua" />
+	<Script file="ArmorSetParts.lua" />
+	<Script file="BuffDamageMultiplier.lua" />
+	<Script file="BuffDuration.lua" />
+	<Script file="BuffExpires.lua" />
+	<Script file="BuffGain.lua" />
+	<Script file="BuffRemains.lua" />
+	<Script file="BuffSnapshot.lua" />
+	<Script file="BuffStacks.lua" />
+	<Script file="BuffStealable.lua" />
+	<Script file="CanCast.lua" />
+	<Script file="CastTime.lua" />
+	<Script file="Casting.lua" />
+	<Script file="CheckBox.lua" />
+	<Script file="Class.lua" />
+	<Script file="Classification.lua" />
+	<Script file="ComboPoints.lua" />
+	<Script file="Counter.lua" />
+	<Script file="CreatureFamily.lua" />
+	<Script file="CreatureType.lua" />
+	<Script file="Damage.lua" />
+	<Script file="DamageMultiplier.lua" />
+	<Script file="DamageTaken.lua" />
+	<Script file="Distance.lua" />
+	<Script file="Eclipse.lua" />
+	<Script file="EclipseDir.lua" />
+	<Script file="Enemies.lua" />
+	<Script file="EnergyRegen.lua" />
+	<Script file="Exists.lua" />
+	<Script file="False.lua" />
+	<Script file="FocusRegen.lua" />
+	<Script file="GCD.lua" />
+	<Script file="Glyph.lua" />
+	<Script file="HasEquippedItem.lua" />
+	<Script file="HasFullControl.lua" />
+	<Script file="HasShield.lua" />
+	<Script file="HasTrinket.lua" />
+	<Script file="HasWeapon.lua" />
+	<Script file="Health.lua" />
+	<Script file="InCombat.lua" />
+	<Script file="InFlightToTarget.lua" />
+	<Script file="InRange.lua" />
+	<Script file="IsAggroed.lua" />
+	<Script file="IsFeared.lua" />
+	<Script file="IsFriend.lua" />
+	<Script file="IsIncapacitated.lua" />
+	<Script file="IsInterruptible.lua" />
+	<Script file="IsPVP.lua" />
+	<Script file="IsRooted.lua" />
+	<Script file="IsStunned.lua" />
+	<Script file="ItemCharges.lua" />
+	<Script file="ItemCooldown.lua" />
+	<Script file="ItemCount.lua" />
+	<Script file="LastDamage.lua" />
+	<Script file="LastDamageMultiplier.lua" />
+	<Script file="LastEstimatedDamage.lua" />
+	<Script file="LastSnapshot.lua" />
+	<Script file="Latency.lua" />
+	<Script file="Level.lua" />
+	<Script file="List.lua" />
+	<Script file="ManaPercent.lua" />
+	<Script file="NextTick.lua" />
+	<Script file="PTR.lua" />
+	<Script file="PaperDoll.lua" />
+	<Script file="PetPresent.lua" />
+	<Script file="Power.lua" />
+	<Script file="PowerCost.lua" />
+	<Script file="Present.lua" />
+	<Script file="PreviousSpell.lua" />
+	<Script file="RelativeLevel.lua" />
+	<Script file="RemainingCastTime.lua" />
+	<Script file="RuneCount.lua" />
+	<Script file="Runes.lua" />
+	<Script file="Speed.lua" />
+	<Script file="SpellChargeCooldown.lua" />
+	<Script file="SpellCharges.lua" />
+	<Script file="SpellCooldown.lua" />
+	<Script file="SpellData.lua" />
+	<Script file="SpellKnown.lua" />
+	<Script file="SpellUsable.lua" />
+	<Script file="StaggerRemains.lua" />
+	<Script file="Stance.lua" />
+	<Script file="Stealthed.lua" />
+	<Script file="Swing.lua" />
+	<Script file="TalentPoints.lua" />
+	<Script file="TargetIsPlayer.lua" />
+	<Script file="Threat.lua" />
+	<Script file="TickTime.lua" />
+	<Script file="Ticks.lua" />
+	<Script file="TicksAdded.lua" />
+	<Script file="TicksRemain.lua" />
+	<Script file="TimeInCombat.lua" />
+	<Script file="TimeToMaxEnergy.lua" />
+	<Script file="TimeToPowerFor.lua" />
+	<Script file="TimeWithHaste.lua" />
+	<Script file="TotemExpires.lua" />
+	<Script file="Tracking.lua" />
+	<Script file="True.lua" />
+	<Script file="WeaponDamage.lua" />
+	<Script file="WeaponEnchantExpires.lua" />
+</Ui>