vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
---------------------------------------------------------------------------
-- You MUST update the major version whenever you make an incompatible
-- change
---------------------------------------------------------------------------
-- You MUST update the minor version whenever you make a compatible
-- change (And check LibActivate is still valid!)
---------------------------------------------------------------------------
-- Set usedebug = true if you want to see output
-- ** THIS ONLY APPLIES TO THIS INSTANCE OF THE LIBRARY **
---------------------------------------------------------------------------

local vmajor, vminor = "1.1", 15                -- Set your version numbers here
local stubvarname = "TekLibStub"       -- Change this to your library stub's global name
local libvarname = "ParserLib"    -- Change this to your library's global name




-- ************************************* --
-- ** This embed requires CompostLib! ** --
-- ************************************* --
if not CompostLib then ChatFrame1:AddMessage("<ParserLib> CompostLib is not installed!", 1, 0, 0) return end
compost = CompostLib:GetInstance("compost-1")



---------------------------------------------------------------------------
-- **************************************************************
-- **** YOU DON'T NEED TO EDIT ANYTHING BELOW UNTIL LINE 146 ****
-- **************************************************************
---------------------------------------------------------------------------

-- Check to see if an update is needed
-- if not then just return out now before we do anything
local libobj = getglobal(libvarname)
if libobj and not libobj:NeedsUpgraded(vmajor, vminor) then return end


---------------------------------------------------------------------------
-- Embedded Library Registration Stub
-- Written by Iriel <iriel@vigilance-committee.org>
-- Version 0.1 - 2006-03-05
-- Modified by Tekkub <tekkub@gmail.com>
---------------------------------------------------------------------------

local stubobj = getglobal(stubvarname)
if not stubobj then
        stubobj = {}
        setglobal(stubvarname, stubobj)


        -- Instance replacement method, replace contents of old with that of new
        function stubobj:ReplaceInstance(old, new)
                 for k,v in pairs(old) do old[k]=nil end
                 for k,v in pairs(new) do old[k]=v end
        end


        -- Get a new copy of the stub
        function stubobj:NewStub(name)
                local newStub = {}
                self:ReplaceInstance(newStub, self)
                newStub.libName = name
                newStub.lastVersion = ''
                newStub.versions = {}
                return newStub
        end


        -- Get instance version
        function stubobj:NeedsUpgraded(vmajor, vminor)
                local versionData = self.versions[vmajor]
                if not versionData or versionData.minor < vminor then return true end
        end


        -- Get instance version
        function stubobj:GetInstance(version)
                if not version then version = self.lastVersion end
                local versionData = self.versions[version]
                if not versionData then print(string.format("<%s> Cannot find library version: %s", self.libName, version or "")) return end
                return versionData.instance
        end


        -- Register new instance
        function stubobj:Register(newInstance)
                 local version,minor = newInstance:GetLibraryVersion()
                 self.lastVersion = version
                 local versionData = self.versions[version]
                 if not versionData then
                                -- This one is new!
                                versionData = {
                                        instance = newInstance,
                                        minor = minor,
                                        old = {},
                                }
                                self.versions[version] = versionData
                                newInstance:LibActivate(self)
                                return newInstance
                 end
                 -- This is an update
                 local oldInstance = versionData.instance
                 local oldList = versionData.old
                 versionData.instance = newInstance
                 versionData.minor = minor
                 local skipCopy = newInstance:LibActivate(self, oldInstance, oldList)
                 table.insert(oldList, oldInstance)
                 if not skipCopy then
                                for i, old in ipairs(oldList) do self:ReplaceInstance(old, newInstance) end
                 end
                 return newInstance
        end
end


if not libobj then
        libobj = stubobj:NewStub(libvarname)
        setglobal(libvarname, libobj)
end




























local lib = {}


-- Return the library's current version
function lib:GetLibraryVersion()
        return vmajor, vminor
end


-- Activate a new instance of this library
function lib:LibActivate(stub, oldLib, oldList)
        local maj, min = self:GetLibraryVersion()

        if oldLib then
                local omaj, omin = oldLib:GetLibraryVersion()
                ----------------------------------------------------
                -- ********************************************** --
                -- **** Copy over any old data you need here **** --
                -- ********************************************** --
                ----------------------------------------------------
                self.frame = oldLib.frame
                self:OnLoad()

                if omin < 11 and oldLib.clients then
                        for event in oldLib.clients do
                                for i in oldLib.clients[event] do
                                        if type(oldLib.clients[event][i]["func"]) == "string" then
                                                oldLib.clients[event][i]["func"] = getglobal(oldLib.clients[event][i]["func"])
                                        end
                                end
                        end
                end
                self.clients = oldLib.clients

                
        else
                ---------------------------------------------------
                -- ********************************************* --
                -- **** Do any initialization you need here **** --
                -- ********************************************* --
                ---------------------------------------------------
                self:OnLoad()
        end
        -- nil return makes stub do object copy
end


-------------------------------------
-- ******************************* --
-- **** Add your methods here **** --
-- ******************************* --
-------------------------------------



-- Constants
ParserLib_SELF = 103
ParserLib_MELEE = 112
ParserLib_DAMAGESHIELD = 113


-- Public Methods

function lib:RegisterEvent(addonID, event, handler)

        local eventExist
        for i, v in self.supportedEvents do
                if v == event then
                        eventExist = true
                        break
                end
        end
        
        if not eventExist then
                self:Print( string.format("Event %s is not supported. (AddOnID %s)", event, addonID), 1, 0, 0 )
                return
        end
        

        self:Debug(string.format("Registering %s for addon %s.", event, addonID) );     

        if type(handler) == "string" then handler = getglobal(handler) end
        
        if not handler then self:Print("nil handler from " .. addonID, 1, 0, 0) return end


        if self.clients[event] == nil then
                self.clients[event] = {};       
        end
        
        table.insert(self.clients[event], { ["id"]=addonID, ["func"]=handler } );
        self.frame:RegisterEvent(event);

end

function lib:IsEventRegistered(addonID, event)
        if self.clients[event] then
                for i, v in self.clients[event] do
                        if v.id == addonID then return true end
                end
        end
end

function lib:UnregisterEvent(addonID, event)
        local empty = true
        
        
        if not self.clients[event] then return end
        
        for i, v in self.clients[event] do
                if v.id == addonID then
                        self:Debug( format("Removing %s from %s", v.id, event) )                
                        table.remove(self.clients[event], i)
                else
                        empty = false
                end
        end
        
        if empty then
                self:Debug("Unregistering event " .. event)
                self.frame:UnregisterEvent(event)
                self.clients[event] = nil
        end
end

function lib:UnregisterAllEvents(addonID)
        local event, index, empty;
        
        for event in self.clients do
                empty = true;
                
                for i, v in self.clients[event] do
                        if v.id == addonID then
                                self:Debug( format("Removing %s for %s", v.id, event) )
                                table.remove(self.clients[event], i)
--                              self.clients[event][index] = nil;
                        else
                                empty = false;
                        end
                end
                
                if empty then
                        self:Debug("Unregistering event " .. event)
                        self.frame:UnregisterEvent(event);
                        self.clients[event] = nil;
                end
                
        end     

end


function lib:Deformat(text, pattern)
        if not self.customPatterns then self.customPatterns = {} end            
        if not self.customPatterns[pattern] then
                self.customPatterns[pattern] = self:Curry(pattern)
        end
        return self.customPatterns[pattern](text)
end


-- Convert "%s hits %s for %d." to "(.+) hits (.+) for (%d+)."
-- Will additionaly return the sequence of tokens, for example:                     
--  "%2$s reflects %3$d %4$s damage to %1$s."   will return: 
--    "(.-) reflects (%+) (.-) damage to (.-)%.",  4 1 2 3. 
--  (    [1]=2,[2]=3,[3]=4,[4]=1  Reverting indexes and become  [1]=4, [2]=[1],[3]=2,[4]=3. )
function lib:ConvertPattern(pattern, anchor)

        local seq

        -- Add % to escape all magic characters used in LUA pattern matching, except $ and %
        pattern = string.gsub(pattern,"([%^%(%)%.%[%]%*%+%-%?])","%%%1");
        
        -- Do these AFTER escaping the magic characters.
        pattern = string.gsub(pattern,"%%s","(.-)"); -- %s to (.-)
        pattern = string.gsub(pattern,"%%d","(%%d+)"); -- %d to (%d+)                   

        if string.find(pattern,"%$") then
                seq = {}; -- fills with ordered list of $s as they appear
                local idx = 1; -- incremental index into field[]

                local tmpSeq = {}
                for i in string.gfind(pattern,"%%(%d)%$.") do
                        tmpSeq[idx] = tonumber(i);
                        idx = idx + 1
                end
                for i, j in ipairs(tmpSeq) do
                        seq[j] = i
                end
                table.setn(seq, table.getn(tmpSeq))
                pattern = string.gsub(pattern,"%%%d%$s","(.-)"); -- %1$s to (.-)
                pattern = string.gsub(pattern,"%%%d%$d","(%%d+)"); -- %1$d to (%d+)
        end

        -- Escape $ now.
        pattern = string.gsub(pattern,"%$","%%$");

        -- Anchor tag can improve string.find() performance by 100%.
        if anchor then pattern = "^"..pattern end       
        
        -- If the pattern ends with (.-), replace it with (.+), or the capsule will be lost.
        if string.sub(pattern, -4) == "(.-)" then
                pattern = string.sub(pattern, 0, -5) .. "(.+)";
        end
        
        if not seq then return pattern end
        
        return pattern, seq[1], seq[2], seq[3], seq[4], seq[5], seq[6], seq[7], seq[8], seq[9], seq[10]
end

lib.debug = nil
local function ParserOnEvent() lib:OnEvent() end


-- Currently supported event list.
lib.supportedEvents = {

        "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS",
        "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES",
        "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS",
        "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES",
        "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS",
        "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES",
        "CHAT_MSG_COMBAT_FACTION_CHANGE",
        "CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
        "CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
        "CHAT_MSG_COMBAT_FRIENDLY_DEATH",
        "CHAT_MSG_COMBAT_HONOR_GAIN",
        "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS",
        "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES",
        "CHAT_MSG_COMBAT_HOSTILE_DEATH",
        "CHAT_MSG_COMBAT_PARTY_HITS",
        "CHAT_MSG_COMBAT_PARTY_MISSES",
        "CHAT_MSG_COMBAT_PET_HITS",
        "CHAT_MSG_COMBAT_PET_MISSES",
        "CHAT_MSG_COMBAT_SELF_HITS",
        "CHAT_MSG_COMBAT_SELF_MISSES",
        "CHAT_MSG_COMBAT_XP_GAIN",
        "CHAT_MSG_SPELL_AURA_GONE_OTHER",
        "CHAT_MSG_SPELL_AURA_GONE_SELF",
        "CHAT_MSG_SPELL_AURA_GONE_PARTY",
        "CHAT_MSG_SPELL_BREAK_AURA",
        "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF",
        "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE",
        "CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF",
        "CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE",
        "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF",
        "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE",
        "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS",
        "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF",
        "CHAT_MSG_SPELL_FAILED_LOCALPLAYER",
        "CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF",
        "CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
        "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF",
        "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE",
        "CHAT_MSG_SPELL_ITEM_ENCHANTMENTS",
        "CHAT_MSG_SPELL_PARTY_BUFF",
        "CHAT_MSG_SPELL_PARTY_DAMAGE",
        "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS",
        "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE",
        "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS",
        "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE",
        "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS",
        "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE",
        "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS",
        "CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE",
        "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS",
        "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE",
        "CHAT_MSG_SPELL_PET_BUFF",
        "CHAT_MSG_SPELL_PET_DAMAGE",
        "CHAT_MSG_SPELL_SELF_BUFF",
        "CHAT_MSG_SPELL_SELF_DAMAGE",
        "CHAT_MSG_SPELL_TRADESKILLS",

}

-- Sort the pattern so that they can be parsed in a correct sequence, will only do once for each registered event.
local function PatternCompare(a, b)
        
        local pa = getglobal(a)
        local pb = getglobal(b)
        
        if not pa then ChatFrame1:AddMessage("|cffff0000Nil pattern: ".. a.."|r") end
        if not pb then ChatFrame1:AddMessage("|cffff0000Nil pattern: ".. b.."|r") end
                
        local ca=0
        for _ in string.gfind(pa, "%%%d?%$?[sd]") do ca=ca+1 end
        local cb=0
        for _ in string.gfind(pb, "%%%d?%$?[sd]") do cb=cb+1 end

        pa = string.gsub(pa, "%%%d?%$?[sd]", "")        
        pb = string.gsub(pb, "%%%d?%$?[sd]", "")
        
        if string.len(pa) == string.len(pb) then
                return  ca < cb;
        else
                return string.len(pa) > string.len(pb)
        end
        
end


-- local timing = true -- timer


function lib:OnLoad()

        -- Both table starts out empty, and load the data only when required.
        self.eventTable = {}
        self.patternTable = {}


        if timing then
                ctimer = {
                        acquire = 0,
                        recycle = 0,
                        reclaim = 0,
                }
                        
                self.time = {
                        find = 0,
                        list = 0,
                        parse = 0,
                        trailer = 0,
                        notify = 0,
                        LoadPatternInfo = 0
                }
        end

        if not self.clients then self.clients = {} end
        
        if not self.frame then
                self.frame = CreateFrame("FRAME", "ParserLibFrame")
                self.frame:SetScript("OnEvent", ParserOnEvent );                
        end
        
        
end
        
        
function lib:OnEvent(e, a1)
        local info, infoBackup, func;
        
        if not e then e = event end
        if not a1 then a1 = arg1 end


        self:Debug("Event: |cff3333ff"..e.."|r")
        
--      local timer = GetTime() -- timer
        info = compost:Acquire()
--      ctimer.acquire = GetTime() - timer + ctimer.acquire -- timer
        
        if self:ParseMessage(a1, e, info) then
                
--              currTime = GetTime() -- timer
                self:NotifyClients(e, info)
--              self.time.notify = self.time.notify + GetTime() - currTime -- timer
                                
        end
        
--      local timer = GetTime() -- timer
        compost:Reclaim(info)
--      ctimer.reclaim = GetTime() - timer + ctimer.reclaim -- timer

end

function lib:NotifyClients(event, info)

--      local timer = GetTime() -- timer
        local infoBackup = compost:Acquire()    
--      ctimer.acquire = GetTime() - timer + ctimer.acquire -- timer

        -- Backup info, because clients may modify it.
        for i in info do
                infoBackup[i] = info[i]
        end
        

        if not self.clients[event] then 
                self:Debug(event .. " has no client to notify.")
                return 
        end
        
        for i in self.clients[event] do
        
                self:Debug(event .. ",Calling " .. self.clients[event][i].id)
                local func = self.clients[event][i].func

                func(event, info)
                
-- --           local timer = GetTime()  -- timer
                info = compost:Recycle(info) 
--              ctimer.recycle = GetTime() - timer + ctimer.recycle -- timer
                
                -- Copy back old info
                for j in infoBackup do
                        info[j] = infoBackup[j]
                end
                        
                        
        end
        
--      timer = GetTime() -- timer
        compost:Reclaim(infoBackup)
--      ctimer.reclaim = GetTime() - timer + ctimer.reclaim -- timer

end


function lib:Print(msg, r, g, b)        
        ChatFrame1:AddMessage(string.format("<%s-%s-%s> %s", libvarname, vmajor, vminor, msg), r, g, b)
end

function lib:Debug(msg, r, g, b)
        if self.debug then
                ChatFrame1:AddMessage(string.format("<%s-%s-%s>(Debug) %s", libvarname, vmajor, vminor, msg), r, g, b)
        end
end


-- message : the arg1 in the event
-- event : name says it all.
-- info : the table which will store the passed result, so THIS IS THE OUTPUT.
-- return : true if pattern found and parsed, nil otherwise.
function lib:ParseMessage(message, event, info)

        local currTime
        
--      currTime = GetTime() -- timer
        if not self.eventTable[event] then self.eventTable[event] = self:LoadPatternList(event) end
        local list = self.eventTable[event] --:LoadPatternList(event)
--      self.time.list = self.time.list + GetTime() - currTime -- timer
        
        if not list then return end
        
--      currTime = GetTime() -- timer
        local pattern = self:FindPattern(message, list, info)
--      self.time.find = GetTime() - currTime + self.time.find -- timer

        
        if not pattern then 
                self:Print(message .. " -> not found in event " .. event, 1, 0.3, 0.3)
                return false 
        end
        
--      currTime = GetTime() -- timer
        self:ParseInformation(pattern, info)
--      self.time.parse = GetTime() - currTime + self.time.parse -- timer
        
        
--      currTime = GetTime() -- timer
        if info.type == "hit" or info.type == "environment" then
                self:ParseTrailers(message, info)
        end
--      self.time.trailer = GetTime() - currTime + self.time.trailer -- timer
        
        self:ConvertTypes(info)

        return true

        
end

-- Search for pattern in 'patternList' which matches 'message', parsed tokens will be stored in 'info'
function lib:FindPattern(message, patternList, info)
        
        local pattern, patternName, found, n

        local n = table.getn(patternList)
        for i=1, n do
        
                patternName = patternList[i]
                
--              timer = GetTime() -- timer
                if not self.patternTable[patternName] then self.patternTable[patternName] = self:LoadPatternInfo(patternName) end
--              self.time.LoadPatternInfo = GetTime() - timer + self.time.LoadPatternInfo -- timer
                
                if not self.patternTable[patternName] then
                        self:Print(patternName .. " cannot be found in the pattern table.", 1, 0, 0)
                        return
                end

--              timer = GetTime() -- timer
                info = compost:Recycle(info)
--              ctimer.recycle = GetTime() - timer + ctimer.recycle -- timer
                
                pattern = self.patternTable[patternName].pattern
                n = self.patternTable[patternName].tc
                found = false
                if self:OptimizerCheck(message, patternName) then
                        if n == 0 then
                                found = string.find(message, pattern)
                        elseif n == 1 then
                                found, _, info[1] = string.find(message, pattern)
                        elseif n == 2 then
                                found, _, info[1], info[2] = string.find(message, pattern)
                        elseif n == 3 then
                                found, _, info[1], info[2], info[3]= string.find(message, pattern)
                        elseif n == 4 then
                                found, _, info[1], info[2], info[3], info[4] = string.find(message, pattern)
                        elseif n == 5 then
                                found, _, info[1], info[2], info[3], info[4], info[5] = string.find(message, pattern)
                        elseif n == 6 then
                                found, _, info[1], info[2], info[3], info[4], info[5], info[6] = string.find(message, pattern)
                        elseif n == 7 then
                                found, _, info[1], info[2], info[3], info[4], info[5], info[6], info[7] = string.find(message, pattern)
                        elseif n == 8 then
                                found, _, info[1], info[2], info[3], info[4], info[5], info[6], info[7], info[8] = string.find(message, pattern)
                        elseif n == 9 then
                                found, _, info[1], info[2], info[3], info[4], info[5], info[6], info[7], info[8], info[9] = string.find(message, pattern)
                        end
                                
                                
--                      found, _, info[1], info[2], info[3], info[4], info[5], info[6], info[7], info[8] = string.find(message, pattern)
                end
                if found then
                        self:Debug(message.." -> |cff3333ff" .. self.patternTable[patternName].pattern .. "|r")
                        return patternName                              
                end
        end     
end


-- Parses for trailors.
function lib:ParseTrailers(message, info)
        local found, amount
        
        
        if not self.trailers then 
                self.trailers = {
                        CRUSHING_TRAILER = self:ConvertPattern(CRUSHING_TRAILER),
                        GLANCING_TRAILER = self:ConvertPattern(GLANCING_TRAILER),
                        ABSORB_TRAILER = self:ConvertPattern(ABSORB_TRAILER),
                        BLOCK_TRAILER = self:ConvertPattern(BLOCK_TRAILER),
                        RESIST_TRAILER = self:ConvertPattern(RESIST_TRAILER),
                        VULNERABLE_TRAILER = self:ConvertPattern(VULNERABLE_TRAILER),
                }
        end
        
        found = string.find(message, self.trailers.CRUSHING_TRAILER)
        if found then 
                info.isCrushing = true
        end
        found = string.find(message, self.trailers.GLANCING_TRAILER)
        if found then 
                info.isGlancing = true
        end
        found, _, amount = string.find(message, self.trailers.ABSORB_TRAILER)
        if found then 
                info.amountAbsorb = amount
        end
        found, _, amount = string.find(message, self.trailers.BLOCK_TRAILER)
        if found then 
                info.amountBlock = amount
        end
        found, _, amount = string.find(message, self.trailers.RESIST_TRAILER)
        if found then 
                info.amountResist = amount
        end
        found, _, amount = string.find(message, self.trailers.VULNERABLE_TRAILER)
        if found then 
                info.amountVulnerable = amount
        end

end
        


function lib:ParseInformation(patternName, info)

        -- Create an info table from pattern table, copies everything except the pattern string.
        for i, v in self.patternTable[patternName] do   
                if i ~= "pattern" and i ~= 'tc' then
                        if type(v) == "number" and v < 100 then
                                info[i] = info[v]                               
                        else
                                info[i] = v
                        end
                end
        end
        
        
        for i in ipairs(info) do
                info[i] = nil
        end
        
end

function lib:ConvertTypes(info)
        for i in info do
                if string.find(i, "^amount") then info[i] = tonumber(info[i]) end
        end
end

function lib:OptimizerCheck(message, patternName)

        if not ParserLibOptimizer then return true end
        
        if not ParserLibOptimizer[patternName] then return true end
        
        if string.find(message, ParserLibOptimizer[patternName], 1, true) then return true end
        
        return false
end


-- Most of the parts were learnt from BabbleLib by chknight, so credits goes to him.
function lib:Curry(pattern)
        local cp, tt, n, f, o
        local DoNothing = function(tok) return tok end  
        
        tt = {}
        for tk in string.gfind(pattern, "%%%d?%$?([sd])") do
                table.insert(tt, tk)
        end     
        
        cp = { self:ConvertPattern(pattern, true) }
        cp.p = cp[1]
        
        n = table.getn(cp)
        for i=1,n-1 do
                cp[i] = cp[i+1]
        end
        table.remove(cp, n)
        
        f = {}
        o = {}
        n = table.getn(tt)
        for i=1, n do
                if tt[i] == "s" then
                        f[i] = DoNothing
                else
                        f[i] = tonumber
                end
        end

        if not cp[1] then
                if n == 0 then
                        return function() end
                elseif n == 1 then
                        return function(text)
                                _, _, o[1] = string.find(text, cp.p)
                                if o[1] then
                                        return f[1](o[1])
                                end
                        end
                elseif n == 2 then
                        return function(text)
                                _, _, o[1], o[2]= string.find(text, cp.p)
                                if o[1] then
                                        return f[1](o[1]), f[2](o[2])
                                end
                        end
                elseif n == 3 then
                        return function(text)
                                _, _, o[1], o[2], o[3] = string.find(text, cp.p)
                                if o[1] then
                                        return f[1](o[1]), f[2](o[2]), f[3](o[3])
                                end
                        end
                elseif n == 4 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4] = string.find(text, cp.p)
                                if o[1] then
                                        return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4])
                                end
                        end
                elseif n == 5 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4], o[5] = string.find(text, cp.p)
                                if o[1] then
                                        return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5])
                                end
                        end
                elseif n == 6 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4], o[5], o[6] = string.find(text, cp.p)
                                if o[1] then
                                        return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6])
                                end
                        end
                elseif n == 7 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7] = string.find(text, cp.p)
                                if o[1] then
                                        return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6]), f[7](o[7])
                                end
                        end
                elseif n == 8 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8] = string.find(text, cp.p)
                                if o[1] then
                                        return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6]), f[7](o[7]), f[8](o[8])
                                end
                        end
                elseif n == 9 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9] = string.find(text, cp.p)
                                if o[1] then
                                        return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6]), f[7](o[7]), f[8](o[8]), f[9](o[9])
                                end
                        end
                end
        else    
                if n == 0 then
                        return function() end
                elseif n == 1 then
                        return function(text)
                                _, _, o[1] = string.find(text, cp.p)
                                if o[1] then
                                        return f[cp[1]](o[cp[1]])
                                end
                        end                             elseif n == 2 then
                        return function(text)
                                _, _, o[1], o[2] = string.find(text, cp.p)
                                if o[1] then
                                        return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]])
                                end
                        end                             elseif n == 3 then
                        return function(text)
                                _, _, o[1], o[2], o[3] = string.find(text, cp.p)
                                if o[1] then
                                        return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]])
                                end
                        end             
                elseif n == 4 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4] = string.find(text, cp.p)
                                if o[1] then
                                        return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]])
                                end
                        end                             elseif n == 5 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4], o[5] = string.find(text, cp.p)
                                if o[1] then
                                        return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]])
                                end
                        end                             elseif n == 6 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4], o[5], o[6] = string.find(text, cp.p)
                                if o[1] then
                                        return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]])
                                end
                        end                             elseif n == 7 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7] = string.find(text, cp.p)
                                if o[1] then
                                        return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]]), f[cp[7]](o[cp[7]])
                                end
                        end                             elseif n == 8 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8] = string.find(text, cp.p)
                                if o[1] then
                                        return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]]), f[cp[7]](o[cp[7]]), f[cp[8]](o[cp[8]])
                                end
                        end                             elseif n == 9 then
                        return function(text)
                                _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9] = string.find(text, cp.p)
                                if o[1] then
                                        return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]]), f[cp[7]](o[cp[7]]), f[cp[8]](o[cp[8]]), f[cp[9]](o[cp[9]])
                                end
                        end             
                end             
        end
end


-- Used to test the correcteness of ParserLib on different languages.
function lib:TestPatterns(sendToClients)
        
        self:LoadEverything()
        
        
        -- Check for valid variable types.
        local pattern
        local cnt = 1
        for i, v in self.patternTable do
                pattern = getglobal(i)
                cnt = 1
                for tok in string.gfind(pattern, "%%%d?%$?([sd])") do
                        for j, w in v do
                                if j ~= "tc"
                                and w == cnt 
                                and ( ( string.find(j, "^amount") and tok ~= "d" )
                                or ( not string.find(j, "^amount") and tok == "d") )then
                                        self:Print(pattern..","..j..","..cnt..","..tok)
                                end
                        end
                        cnt = cnt+1
                end
        end
        
        
        
        
        
        -- Creating the combat messages.        
        local messages = compost:Acquire();     
        for patternName in self.patternTable do         
                messages[patternName] = getglobal(patternName)
        end
        
        local testString = "<s>";
        local testNumber = "123";

        for i in messages do
                messages[i] = string.gsub(messages[i], "%%%d?%$?s", testString); 
                messages[i] = string.gsub(messages[i], "%%%d?%$?d", testNumber);        
        end     
        


        -- Begin the test.
        
        testNumber = tonumber(testNumber)
--      local timer = GetTime() -- timer
        local info = compost:Acquire()
--      ctimer.acquire = GetTime() - timer + ctimer.acquire -- timer

        local startTime = GetTime() 
        local startMem = gcinfo()

        for _, event in self.supportedEvents do

                for _, pattern in self:LoadPatternList(event) do
                
                        local msg = messages[pattern]
                        
                        if sendToClients then self:OnEvent(event, msg)  end
                        
                        if self:ParseMessage(msg, event, info) then

                                for i, v in info do
                                
                                        if type(i) ~= "number" then
                                                if type(v) == "number" and ( v == ParserLib_SELF or v == ParserLib_MELEE or v == ParserLib_DAMAGESHIELD ) then
                                                        v = testString
                                                end
                                                
                                                if i == "type" or i == "missType"  or i == "damageType" then v = testString end                                 
                                                
                                                if ( type(v) == "string" and v ~= testString )
                                                or ( type(v) == "number" and v ~= testNumber )
                                                then
                                                        self:Print(string.format("E[%s],M[%s],[%s]=[%s]", event, msg, i, v), 1, 0.3, 0)
                                                end
                                        end
                                end
                        end
                        
                        info = compost:Recycle(info)

                end
        end

        
        self:Print( string.format("Test completed in %.4fs, memory cost %.2fKB.", GetTime() - startTime, gcinfo() - startMem) )

        -- Cleaning up.
        compost:Reclaim(info)
        compost:Reclaim(messages)
        
end

-- Not working.
function lib:TestDeformat()
        
        self:LoadEverything()
        
        
        -- Creating the combat messages.
        
        local messages = compost:Acquire();     
        for patternName in self.patternTable do         
                messages[patternName] = getglobal(patternName)
        end
        
        local testString = "<s>";
        local testNumber = "123";

        for i in messages do
                messages[i] = string.gsub(messages[i], "%%%d?%$?s", testString); 
                messages[i] = string.gsub(messages[i], "%%%d?%$?d", testNumber);        
        end     
        


        -- Begin the test.
        local o = compost:Acquire()
        local tt = compost:Acquire()
        
        testNumber = tonumber(testNumber)

        local startTime = GetTime() 
        local startMem = gcinfo()

        for _, event in self.supportedEvents do

                for _, pattern in self:LoadPatternList(event) do
                

                        for i, v in self.patternTable[pattern] do
                                if i ~= 'pattern' and i ~= 'tc' then
                                        if string.find(i, "^amount") then
                                                tt[v] = "number"
                                        else
                                                tt[v] = "string"
                                        end
                                end
                        end
                
                        local msg = messages[pattern]
                        
                        o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9] = self:Deformat(msg, getglobal(pattern))
                        for i=1, self.patternTable[pattern].tc do
                                if type(o[i]) ~= tt[i] 
                                or ( type(o[i]) == "string" and not o[i] == testString) 
                                or ( type(o[i]) == "number" and not o[i] == testNumber) then
                                        self:Print(string.format("E[%s],M[%s],[%s]=%s (%s)", event, msg, o[i], type(o[i]), tt[i]), 1, 0.3, 0)
                                        PrintTable(o)
                                        PrintTable(tt)
                                        print(pattern)
                                        PrintTable(self.patternTable[pattern])
                                end
                        end
                        compost:Recycle(o)
                        compost:Recycle(tt)

                end
        end

        
        self:Print( string.format("Test completed in %.4fs, memory cost %.2fKB.", GetTime() - startTime, gcinfo() - startMem) )

        -- Cleaning up.
--      compost:Reclaim(info)
        compost:Reclaim(messages)
        
end

function lib:LoadEverything()

        -- Load all patterns and events.
        for _, v in self.supportedEvents do     
                for _, w in self:LoadPatternList(v) do
                        if not self.patternTable[w] then
                                self.patternTable[w] = self:LoadPatternInfo(w)
                        end
                end
        end
        
end



-- Used to load patternTable elements on demand.
function lib:LoadPatternInfo(patternName)

        local patternInfo
        
        -- DebuffOther
        if patternName == "AURAADDEDOTHERHARMFUL" then patternInfo = { -- %s is afflicted by %s."; -- Combat log text for aura even
                type = "debuff",
                victim = 1,
                skill = 2
        }
        elseif patternName == "AURAAPPLICATIONADDEDOTHERHARMFUL" then patternInfo = { -- %s is afflicted by %s (%d).
                type = "debuff",
                victim = 1,
                skill = 2,
                amountRank = 3,
        }

        
        -- DebuffSelf
        elseif patternName == "AURAADDEDSELFHARMFUL" then patternInfo = { -- You are afflicted by %s."; -- Combat log text for aura even
                type = "debuff",
                victim = ParserLib_SELF,
                skill = 1,
        }
        elseif patternName == "AURAAPPLICATIONADDEDSELFHARMFUL" then patternInfo = { -- You are afflicted by %s (%d).
                type = "debuff",
                victim = ParserLib_SELF,
                skill = 1,
                amountRank = 2,
        }

        -- BuffOther
        elseif patternName == "AURAADDEDOTHERHELPFUL" then patternInfo = { -- %s gains %s."; -- Combat log text for aura even
                type = "buff",
                victim = 1,
                skill = 2,              
        }
        elseif patternName == "AURAAPPLICATIONADDEDOTHERHELPFUL" then patternInfo = { -- %s gains %s (%d).
                type = "buff",
                victim = 1,
                skill = 2,
                amountRank = 3,
        }

        -- BuffSelf
        elseif patternName == "AURAADDEDSELFHELPFUL" then patternInfo = { -- You gain %s."; -- Combat log text for aura even
                type = "buff",
                victim = ParserLib_SELF,
                skill = 1,
        }
        elseif patternName == "AURAAPPLICATIONADDEDSELFHELPFUL" then patternInfo = { -- You gain %s (%d).
                type  = "buff",
                victim = ParserLib_SELF,
                skill = 1,
                amountRank = 2,
        }

        -- AuraDispell
        elseif patternName == "AURADISPELOTHER" then patternInfo = { -- %s's %s is removed.
                type = "dispel",
                victim = 1,
                skill = 2,              
        }
        elseif patternName == "AURADISPELSELF" then patternInfo = { -- Your %s is removed.
                type = "dispel",
                victim = ParserLib_SELF,
                skill = 1,              
        }

        -- Fade
        elseif patternName == "AURAREMOVEDOTHER" then patternInfo = { -- %s fades from %s."; -- Combat log text for aura even
                type = "fade",
                victim = 2,
                skill = 1,              
        }
        elseif patternName == "AURAREMOVEDSELF" then patternInfo = { -- %s fades from you."; -- Combat log text for aura even
                type = "fade",
                victim = ParserLib_SELF,
                skill = 1,              
        }

        
        -- HitOther
        elseif patternName == "COMBATHITCRITOTHEROTHER" then patternInfo = {    -- %s crits %s for %d.
                type = "hit",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                amount = 3,
                isCrit = true,
        }
        elseif patternName == "COMBATHITCRITOTHERSELF" then patternInfo = { -- %s crits you for %d.
                type = "hit",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                amount = 2,
                isCrit = true,          
        }
        elseif patternName == "COMBATHITCRITSCHOOLOTHEROTHER" then patternInfo = { -- %s crits %s for %d %s damage.
                type = "hit",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                amount = 3,
                element = 4,
                isCrit = true
        }
        elseif patternName == "COMBATHITCRITSCHOOLOTHERSELF" then patternInfo = { -- %s crits you for %d %s damage.
                type = "hit",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                amount = 2,
                element = 3,
                isCrit = true   
        }
        elseif patternName == "COMBATHITOTHEROTHER" then patternInfo = { -- %s hits %s for %d.
                type = "hit",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                amount = 3,
        }
        elseif patternName == "COMBATHITOTHERSELF" then patternInfo = { -- %s hits you for %d.
                type = "hit",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                amount = 2,             
        }
        elseif patternName == "COMBATHITSCHOOLOTHEROTHER" then patternInfo = { -- %s hits %s for %d %s damage.
                type = "hit",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                amount = 3,
                element = 4
        }
        elseif patternName == "COMBATHITSCHOOLOTHERSELF" then patternInfo = { -- %s hits you for %d %s damage.
                type = "hit",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                amount = 2,
                element = 3
        }

        -- HitSelf
        elseif patternName == "COMBATHITSCHOOLSELFOTHER" then patternInfo = { -- You hit %s for %d %s damage.
                type = "hit",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                amount = 2,
                element = 3
        }
        elseif patternName == "COMBATHITSELFOTHER" then patternInfo = { -- You hit %s for %d.
                type = "hit",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                amount = 2,     
        }
        elseif patternName == "COMBATHITCRITSCHOOLSELFOTHER" then patternInfo = { -- You crit %s for %d %s damage.
                type = "hit",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                amount = 2,
                element = 3,
                isCrit = true   
        }
        elseif patternName == "COMBATHITCRITSELFOTHER" then patternInfo = { -- You crit %s for %d.
                type = "hit",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                amount = 2,
                isCrit = true,  
        }

        -- Honor
        elseif patternName == "COMBATLOG_DISHONORGAIN" then patternInfo = { -- %s dies, dishonorable kill.
                type = "honor", 
                source = 1,
                isDishonor = true
        }
        elseif patternName == "COMBATLOG_HONORAWARD" then patternInfo = { -- You have been awarded %d honor points.
                type = "honor", 
                amount = 1,
        }
        elseif patternName == "COMBATLOG_HONORGAIN" then patternInfo = { -- "%s dies, honorable kill Rank: %s (Estimated Honor Points: %d)";
                type = "honor",
                source = 1,
                sourceRank = 2,
                amount = 3,
                
        }
        elseif patternName == "COMBATLOG_XPGAIN" then patternInfo = { -- %s gains %d experience.
                type = "experience",
                amount = 2,     
                victim = 1,
        }

        
        -- Exp
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION1" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s bonus)
                type = "experience",
                amount = 2,     
                source = 1,
                bonusAmount = 3,
                bonusType = 4,
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION1_GROUP" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s bonus, +%d group bonus)
                type = "experience",
                amount = 2,     
                source = 1,
                bonusAmount = 3,
                bonusType = 4,
                amountGroupBonus = 5    
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION1_RAID" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s bonus, -%d raid penalty)
                type = "experience",
                amount = 2,     
                source = 1,
                bonusAmount = 3,
                bonusType = 4,
                amountRaidPenalty = 5
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION2" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s bonus)
                type = "experience",
                amount = 2,     
                source = 1,
                bonusAmount = 3,
                bonusType = 4,
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION2_GROUP" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s bonus, +%d group bonus)
                type = "experience",
                amount = 2,     
                source = 1,
                bonusAmount = 3,
                bonusType = 4,
                amountGroupBonus = 5    
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION2_RAID" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s bonus, -%d raid penalty)
                type = "experience",
                amount = 2,     
                source = 1,
                bonusAmount = 3,
                bonusType = 4,
                amountRaidPenalty = 5
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION4" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s penalty)
                type = "experience",
                amount = 2,     
                source = 1,
                penaltyAmount = 3,
                penaltyType = 4,
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION4_GROUP" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s penalty, +%d group bonus)
                type = "experience",
                amount = 2,     
                source = 1,
                penaltyAmount = 3,
                penaltyType = 4,
                amountGroupBonus = 5
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION4_RAID" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s penalty, -%d raid penalty)
                type = "experience",
                amount = 2,     
                source = 1,
                penaltyAmount = 3,
                penaltyType = 4,
                amountGroupBonus = 5
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION5" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s penalty)
                type = "experience",
                amount = 2,     
                source = 1,
                penaltyAmount = 3,
                penaltyType = 4,
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION5_GROUP" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s penalty, +%d group bonus)
                type = "experience",
                amount = 2,     
                source = 1,
                penaltyAmount = 3,
                penaltyType = 4,
                amountGroupBonus = 5
        }
        elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION5_RAID" then patternInfo = { -- %s dies, you gain %d experience. (%s exp %s penalty, -%d raid penalty)
                type = "experience",
                amount = 2,     
                source = 1,
                penaltyAmount = 3,
                penaltyType = 4,
                amountRaidPenalty = 5
        }
        elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON" then patternInfo = { -- %s dies, you gain %d experience.
                type = "experience",
                amount = 2,
                source = 1,
        }
        elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_GROUP" then patternInfo = { -- %s dies, you gain %d experience. (+%d group bonus)
                type = "experience",
                amount = 2,     
                source = 1,
                amountGroupBonus = 3
        }
        elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_RAID" then patternInfo = { -- %s dies, you gain %d experience. (-%d raid penalty)
                type = "experience",
                amount = 2,             
                source = 1,
                amountRaidPenalty = 3
        }
        elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED" then patternInfo = { -- You gain %d experience.
                type = "experience",
                amount = 1,             
        }
        elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_GROUP" then patternInfo = { -- You gain %d experience. (+%d group bonus)
                type = "experience",
                amount = 1,
                amountGroupBonus = 2
        }
        elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_RAID" then patternInfo = { -- You gain %d experience. (-%d raid penalty)
                type = "experience",
                amount = 1,
                amountRaidPenalty = 2
        }
        elseif patternName == "COMBATLOG_XPLOSS_FIRSTPERSON_UNNAMED" then patternInfo = { -- You lose %d experience.
                type = "experience",
                amount = 1,
                isNegative = true
        }


        -- DmgShieldOther
        elseif patternName == "DAMAGESHIELDOTHEROTHER" then patternInfo = { -- %s reflects %d %s damage to %s.
                type = "hit",
                source = 1,
                victim = 4,
                skill = ParserLib_DAMAGESHIELD,
                amount = 2,
                element = 3,
        }
        elseif patternName == "DAMAGESHIELDOTHERSELF" then patternInfo = { -- %s reflects %d %s damage to you.
                type = "hit",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_DAMAGESHIELD,
                amount = 2,
                element = 3,    
        }

        -- DmgShieldSelf
        elseif patternName == "DAMAGESHIELDSELFOTHER" then patternInfo = { -- You reflect %d %s damage to %s.
                type = "hit",
                source = ParserLib_SELF,
                victim = 3,
                skill = ParserLib_DAMAGESHIELD,
                amount = 1,
                element = 2,            
        }
        
        -- DispellFailOther
        elseif patternName == "DISPELFAILEDOTHEROTHER" then patternInfo = { -- %s fails to dispel %s's %s.
                type = "dispel",
                source = 1,
                victim = 2,
                skill = 3,
                isFailed = true
        }
        elseif patternName == "DISPELFAILEDOTHERSELF" then patternInfo = { -- %s fails to dispel your %s.
                type = "dispel",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                isFailed = true
        }

        -- DispellFailSelf
        elseif patternName == "DISPELFAILEDSELFOTHER" then patternInfo = { -- You fail to dispel %s's %s.
                type = "dispel",
                source = ParserLib_SELF,
                victim = 1,
                skill = 2,
                isFailed = true
        }
        
        -- WoW 1.11 new pattern.
        elseif patternName == "DISPELFAILEDSELFSELF" then patternInfo = { -- You fail to dispel your %s.
                type = "dispel",
                source = ParserLib_SELF,
                victim = ParserLb_SELF,
                skill = 1,
                isFailed = true
        }

        --[[   Seems no longer used
        elseif patternName == "DISPELLEDOTHEROTHER" then patternInfo = { -- %s casts %s on %s.
                type = "dispel",
                source = 1,
                victim = 3,
                skill = 2
        }
        elseif patternName == "DISPELLEDOTHERSELF" then patternInfo = { -- %s casts %s on you.
                type = "dispel",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2
        }
        elseif patternName == "DISPELLEDSELFOTHER" then patternInfo = { -- You cast %s on %s.
                type = "dispel",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1
        }
        elseif patternName == "DISPELLEDSELFSELF" then patternInfo = { -- You cast %s.
                type = "dispel",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1
        }
]]
        
        -- Rep
        elseif patternName == "FACTION_STANDING_CHANGED" then patternInfo = { -- You are now %s with %s.
                type = "reputation",
                rank = 1,
                faction = 2
        }
        
        -- These will be removed in WoW 1.11.
        elseif patternName == "FACTION_STANDING_DECREASED2" then patternInfo = { -- Your reputation with %s has slightly decreased. (%d reputation lost)
                type = "reputation",
                faction = 1,
                amount = 2,
                isNegative = true
        }
        elseif patternName == "FACTION_STANDING_DECREASED4" then patternInfo = { -- Your reputation with %s has greatly decreased. (%d reputation lost)
                type = "reputation",
                faction = 1,
                amount = 2,
                isNegative = true,
        }
        elseif patternName == "FACTION_STANDING_DECREASED3" then patternInfo = { -- Your reputation with %s has decreased. (%d reputation lost)
                type = "reputation",
                faction = 1,
                amount = 2,
                isNegative = true,
        }
        elseif patternName == "FACTION_STANDING_DECREASED1" then patternInfo = { -- Your reputation with %s has very slightly decreased. (%d reputation lost)
                type = "reputation",
                faction = 1,
                amount = 2,
                isNegative = true,
        }
        elseif patternName == "FACTION_STANDING_INCREASED1" then patternInfo = { -- Your reputation with %s has very slightly increased. (%d reputation gained)
                type = "reputation",
                faction = 1,
                amount = 2,
        }
        elseif patternName == "FACTION_STANDING_INCREASED2" then patternInfo = { -- Your reputation with %s has slightly increased. (%d reputation gained)
                type = "reputation",
                faction = 1,
                amount = 2,
        }
        elseif patternName == "FACTION_STANDING_INCREASED3" then patternInfo = { -- Your reputation with %s has increased. (%d reputation gained)
                type = "reputation",
                faction = 1,
                amount = 2,
        }
        elseif patternName == "FACTION_STANDING_INCREASED4" then patternInfo = { -- Your reputation with %s has greatly increased. (%d reputation gained)
                type = "reputation",
                faction = 1,
                amount = 2,
        }
        
        -- These 2 are WoW 1.11 new  patterns.
        elseif patternName == "FACTION_STANDING_DECREASED" then patternInfo = { -- "Your %s reputation has decreased by %d.";
                type = "reputation",
                faction = 1,
                amount = 2,
                isNegative = true,
        }
        elseif patternName == "FACTION_STANDING_INCREASED" then patternInfo = { -- "Your %s reputation has increased by %d.";
                type = "reputation",
                faction = 1,
                amount = 2,     
        }
        
        
        elseif patternName == "FEEDPET_LOG_FIRSTPERSON" then patternInfo = { -- Your pet begins eating the %s.
                type = "feedpet",
                victim = ParserLib_SELF,
                item = 1
        }
        elseif patternName == "FEEDPET_LOG_THIRDPERSON" then patternInfo = { -- %s's pet begins eating a %s."
                type = "feedpet",
                victim = 1,
                item = 2
        }

        -- HealOther
        elseif patternName == "HEALEDCRITOTHEROTHER" then patternInfo = { -- %s's %s critically heals %s for %d.
                type = "heal",
                source = 1,
                victim = 3,
                skill = 2,
                amount = 4,
                isCrit = true,
        }
        elseif patternName == "HEALEDCRITOTHERSELF" then patternInfo = { -- %s's %s critically heals you for %d.
                type = "heal",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                amount = 3,
                isCrit = true,
        }
        elseif patternName == "HEALEDOTHEROTHER" then patternInfo = { -- %s's %s heals %s for %d.
                type = "heal",
                source = 1,
                victim = 3,
                skill = 2,
                amount = 4,
        }
        elseif patternName == "HEALEDOTHERSELF" then patternInfo = { -- %s's %s heals you for %d.
                type = "heal",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                amount = 3,
        }

        -- HealSelf
        elseif patternName == "HEALEDCRITSELFOTHER" then patternInfo = { -- Your %s critically heals %s for %d.
                type = "heal",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                amount = 3,
                isCrit = true,
        }
        elseif patternName == "HEALEDCRITSELFSELF" then patternInfo = { -- Your %s critically heals you for %d.
                type = "heal",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                amount = 2,
                isCrit = true,
        }
        elseif patternName == "HEALEDSELFOTHER" then patternInfo = { -- Your %s heals %s for %d.
                type = "heal",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                amount = 3,
        }
        elseif patternName == "HEALEDSELFSELF" then patternInfo = { -- Your %s heals you for %d.
                type = "heal",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                amount = 2,
        }

        --[[
        elseif patternName == "IMMUNEDAMAGECLASSOTHEROTHER" then patternInfo = { -- %s is immune to %s's %s damage.
                type = "miss",
                source = 2,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "immune",
                element = 3
        }
        elseif patternName == "IMMUNEDAMAGECLASSOTHERSELF" then patternInfo = { -- You are immune to %s's %s damage.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "immune",
                element = 2
        }
        elseif patternName == "IMMUNEDAMAGECLASSSELFOTHER" then patternInfo = { -- %s is immune to your %s damage.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "immune",
                element = 2
        }
        elseif patternName == "IMMUNEOTHEROTHER" then patternInfo = { -- %s hits %s, who is  immune.
                type = "miss",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                missType =  "immune",
        }
        elseif patternName == "IMMUNEOTHERSELF" then patternInfo = { -- %s hits you, but you are immune.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "immune",
        }       
        elseif patternName == "IMMUNESELFOTHER" then patternInfo = { -- You hit %s, who is immune.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "immune",
        }
        elseif patternName == "IMMUNESELFSELF" then patternInfo = { -- You hit yourself, but you are immune.
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "immune",
        }
        ]]




        -- EnchantOther
        elseif patternName == "ITEMENCHANTMENTADDOTHEROTHER" then patternInfo = { -- %s casts %s on %s's %s.
                type = "enchant",
                source = 1,
                victim = 3,
                skill = 2,
                item = 4                
        }       
        elseif patternName == "ITEMENCHANTMENTADDOTHERSELF" then patternInfo = { -- %s casts %s on your %s.
                type = "enchant",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                item = 3                
        }

        -- EnchantSelf
        elseif patternName == "ITEMENCHANTMENTADDSELFOTHER" then patternInfo = { -- You cast %s on %s's %s.
                type = "enchant",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                item = 3        
        }
        elseif patternName == "ITEMENCHANTMENTADDSELFSELF" then patternInfo = { -- You cast %s on your %s.
                type = "enchant",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                item = 2
        }
--[[
        elseif patternName == "ITEMENCHANTMENTREMOVEOTHER" then patternInfo = { -- %s has faded from %s's %s.
                type = "enchant",
                victim = 2,
                skill = 1,
                item = 3,
                isFade = true
        }
        elseif patternName == "ITEMENCHANTMENTREMOVESELF" then patternInfo = { -- %s has faded from your %s.
                type = "enchant",
                victim = ParserLib_SELF,
                skill = 1,
                item = 2,
                isFade = true
        }
]]

        

        elseif patternName == "PARTYKILLOTHER" then patternInfo = { -- %s is slain by %s!
                type = "death",
                source = 2,
                victim = 1,             
        }
        
        -- WoW 1.11 Pattern.
        elseif patternName == "SELFKILLOTHER" then patternInfo = { -- "You have slain %s!";
                type = "death",
                source = ParserLib_SELF,
                victim = 1,
        }

        -- DotOther
        elseif patternName == "PERIODICAURADAMAGEOTHEROTHER" then patternInfo = { -- %s suffers %d %s damage from %s's %s.
                type = "hit",
                source = 4,
                victim = 1,
                skill = 5,
                amount = 2,
                element = 3,
                isDOT = true,
        }
        elseif patternName == "PERIODICAURADAMAGEOTHERSELF" then patternInfo = { -- You suffer %d %s damage from %s's %s.
                type = "hit",
                source = 3,
                victim = ParserLib_SELF,
                skill = 4,
                amount = 1,
                element = 2,
                isDOT = true,
        }

        -- DotSelf
        elseif patternName == "PERIODICAURADAMAGESELFOTHER" then patternInfo = { -- %s suffers %d %s damage from your %s.
                type = "hit",
                source = ParserLib_SELF,
                victim = 1,
                skill = 4,
                amount = 2,
                element = 3,
                isDOT = true,
        }
        elseif patternName == "PERIODICAURADAMAGESELFSELF" then patternInfo = { -- You suffer %d %s damage from your %s.
                type = "hit",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 3,
                amount = 1,
                element = 2,
                isDOT = true,
        }

        -- HotOther
        elseif patternName == "PERIODICAURAHEALOTHEROTHER" then patternInfo = { -- %s gains %d health from %s's %s.
                type = "heal",
                source = 3,
                victim = 1,
                skill = 4,
                amount = 2,
                isDOT = true,
        }
        elseif patternName == "PERIODICAURAHEALOTHERSELF" then patternInfo = { -- You gain %d health from %s's %s.
                type = "heal",
                source = 2,
                victim = ParserLib_SELF,
                skill = 3,
                amount = 1,
                isDOT = true,
        }
        -- HotSelf
        elseif patternName == "PERIODICAURAHEALSELFOTHER" then patternInfo = { -- %s gains %d health from your %s.
                type = "heal",
                source = ParserLib_SELF,
                victim = 1,
                skill = 3,
                amount = 2,
                isDOT = true,
        }
        elseif patternName == "PERIODICAURAHEALSELFSELF" then patternInfo = { -- You gain %d health from %s.
                type = "heal",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 2,
                amount = 1,
                isDOT = true,
        }

        
        -- PowerGainOther
        elseif patternName == "POWERGAINOTHEROTHER" then patternInfo = { -- %s gains %d %s from %s's %s.
                type = "gain",
                source = 4,
                victim = 1,
                skill = 5,
                amount = 2,
                attribute = 3,
        }
        elseif patternName == "POWERGAINOTHERSELF" then patternInfo = { -- You gain %d %s from %s's %s.
                type = "gain",
                source = 3,
                victim = ParserLib_SELF,
                skill = 4,
                amount = 1,
                attribute = 2,  
        }

        -- PowerGainSelf
        elseif patternName == "POWERGAINSELFOTHER" then patternInfo = { -- %s gains %d %s from %s.
                type = "gain",
                source = ParserLib_SELF,
                victim = 1,
                skill = 4,
                amount = 2,
                attribute = 3,  
        }
        elseif patternName == "POWERGAINSELFSELF" then patternInfo = { -- You gain %d %s from %s.
                type = "gain",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 3,
                amount = 1,
                attribute = 2,  
        }

        -- ProcResistOther
        elseif patternName == "PROCRESISTOTHEROTHER" then patternInfo = { -- %s resists %s's %s.
                type = "miss",
                source = 2,
                victim = 1,
                skill = 3,
                missType =  "resist",
                isProc = true,
        }
        elseif patternName == "PROCRESISTOTHERSELF" then patternInfo = { -- You resist %s's %s.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "resist",
                isProc = true,
        }

        -- ProcResistSelf
        elseif patternName == "PROCRESISTSELFOTHER" then patternInfo = { -- %s resists your %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = 2,
                missType =  "resist",
                isProc = true,
        }
        elseif patternName == "PROCRESISTSELFSELF" then patternInfo = { -- You resist your %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                missType =  "resist",
                isProc = true,
        }       

        

--[[
        elseif patternName == "SPELLDISMISSPETOTHER" then patternInfo = { -- %s's %s is dismissed.
        }
        elseif patternName == "SPELLDISMISSPETSELF" then patternInfo = { -- Your %s is dismissed.
        }
]]

--[[
        elseif patternName == "SPELLCASTGOOTHER" then patternInfo = { -- %s casts %s.
                type = "cast",
                source = 1,
                skill = 2
        }
        elseif patternName == "SPELLCASTGOOTHERTARGETTED" then patternInfo = { -- %s casts %s on %s.
                type = "cast",
                source = 1,
                victim = 3,
                skill = 2
        }

        elseif patternName == "SPELLCASTGOSELF" then patternInfo = { -- You cast %s.
                type = "cast",          
                source = ParserLib_SELF,
                skill = 1
        }
        elseif patternName == "SPELLCASTGOSELFTARGETTED" then patternInfo = { -- You cast %s on %s.
                type = "cast",          
                source = ParserLib_SELF,
                victim = 2,
                skill = 1
        }
]]
        -- SpellMissSelf
        elseif patternName == "IMMUNESPELLSELFOTHER" then patternInfo = { -- %s is immune to your %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = 2,
                missType =  "immune",
        }
        elseif patternName == "IMMUNESPELLSELFSELF" then patternInfo = { -- You are immune to your %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                missType =  "immune",
        }
        elseif patternName == "SPELLBLOCKEDSELFOTHER" then patternInfo = { -- Your %s was blocked by %s."
                type = "miss",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                missType =  "block",
        }
        elseif patternName == "SPELLDEFLECTEDSELFOTHER" then patternInfo = { -- "Your %s was deflected by %s.";
                type = "miss",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                missType =  "deflect"
        }
        elseif patternName == "SPELLDEFLECTEDSELFSELF" then patternInfo = { -- "You deflected your %s.";
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                missType =  "deflect"
        }
        elseif patternName == "SPELLDODGEDSELFOTHER" then patternInfo = { -- Your %s was dodged by %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                missType =  "dodge",    
        }
        elseif patternName == "SPELLDODGEDSELFSELF" then patternInfo = { -- "You dodged your %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                missType =  "dodge",            
        }
        elseif patternName == "SPELLEVADEDSELFOTHER" then patternInfo = { -- Your %s was evaded by %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                missType =  "evade",    
        }
        elseif patternName == "SPELLEVADEDSELFSELF" then patternInfo = { -- You evaded your %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                missType =  "evade",    
        }
        elseif patternName == "SPELLIMMUNESELFOTHER" then patternInfo = { -- Your %s failed. %s is immune.      
                type = "miss",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                missType =  "immune",   
        }
        elseif patternName == "SPELLIMMUNESELFSELF" then patternInfo = { -- Your %s failed.  You are immune.    
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                missType =  "immune",   
        }
        elseif patternName == "SPELLLOGABSORBSELFOTHER" then patternInfo = { -- Your %s is absorbed by %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                missType =  "absorb",   
        }
        elseif patternName == "SPELLLOGABSORBSELFSELF" then patternInfo = { -- You absorb your %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                missType =  "absorb",   
        }
        elseif patternName == "SPELLMISSSELFOTHER" then patternInfo = { -- Your %s missed %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                missType =  "miss",
        }
        elseif patternName == "SPELLMISSSELFSELF" then patternInfo = { -- Your %s misses you.
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                missType =  "miss",
        }
        elseif patternName == "SPELLPARRIEDSELFOTHER" then patternInfo = { -- Your %s is parried by %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                missType =  "parry",
        }
        elseif patternName == "SPELLPARRIEDSELFSELF" then patternInfo = { -- You parried your %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                missType =  "parry",
        }
        elseif patternName == "SPELLREFLECTSELFOTHER" then patternInfo = { -- Your %s is reflected back by %s.
                type = "miss",
                source = 1,
                skill = 2,
                victim = ParserLib_SELF,
                missType =  "reflect"
        }
        elseif patternName == "SPELLREFLECTSELFSELF" then patternInfo = { -- You reflected your %s.
                type = "miss",
                source = ParserLib_SELF,
                skill = 1,
                victim = ParserLib_SELF,
                missType =  "reflect"
        }
        elseif patternName == "SPELLRESISTSELFOTHER" then patternInfo = { -- Your %s was resisted by %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                missType =  "resist",   
        }
        elseif patternName == "SPELLRESISTSELFSELF" then patternInfo = { -- You resisted your %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                missType =  "resist",   
        }


        
        elseif patternName == "SPELLCASTOTHERSTART" then patternInfo = { -- %s begins to cast %s.
                type = "cast",  
                source = 1,
                skill = 2,
                isBegin = true
        }
        elseif patternName == "SPELLCASTSELFSTART" then patternInfo = { -- You begin to cast %s.
                type = "cast",
                source = ParserLib_SELF,
                skill = 1,
                isBegin = true
        }
        
        
        
        elseif patternName == "SPELLDURABILITYDAMAGEALLOTHEROTHER" then patternInfo = { -- "%s casts %s on %s: all items damaged.
                type = 'durability',
                source = 1,
                skill = 2,
                victim = 3,
                isAllItems = true
        }
        elseif patternName == "SPELLDURABILITYDAMAGEALLOTHERSELF" then patternInfo = { -- "%s casts %s on you: all items damaged.
                type = 'durability',
                source = 1,
                skill = 2,
                victim = ParserLib_SELF,
                isAllItems = true
        }
        elseif patternName == "SPELLDURABILITYDAMAGEALLSELFOTHER" then patternInfo = { -- "You cast %s on %s: all items damaged.
                type = 'durability',
                source = ParserLib_SELF,
                skill = 1,
                victim = 2,
                isAllItems = true
        }
        elseif patternName == "SPELLDURABILITYDAMAGEOTHEROTHER" then patternInfo = { -- "%s casts %s on %s: %s damaged.
                type = 'durability',
                source = 1,
                skill = 2,
                victim = 3,
                item = 4,
        }
        elseif patternName == "SPELLDURABILITYDAMAGEOTHERSELF" then patternInfo = { -- "%s casts %s on you: %s damaged.
                type = 'durability',
                source = 1,
                skill = 2,
                victim = ParserLib_SELF,
                item = 3,
        }
        elseif patternName == "SPELLDURABILITYDAMAGESELFOTHER" then patternInfo = { -- "You cast %s on %s: %s damaged."; -- Example:  You cast Destruction on Fred: helmet damage
                type = 'durability',
                source = ParserLib_SELF,
                skill = 1,
                victim = 2,
                item = 3,       
        }

        
                -- SpellMissOther
        elseif patternName == "IMMUNESPELLOTHEROTHER" then patternInfo = { -- %s is immune to %s's %s.
                type = "miss",
                source = 2,
                victim = 1,
                skill = 3,
                missType =  "immune",
        }
        elseif patternName == "IMMUNESPELLOTHERSELF" then patternInfo = { -- You are immune to %s's %s.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "immune",
        }
        elseif patternName == "SPELLBLOCKEDOTHEROTHER" then patternInfo = { -- %s's %s was blocked by %s.
                type = "miss",
                source = 1,
                victim = 3,
                skill = 2,
                missType =  "block",
        }
        elseif patternName == "SPELLBLOCKEDOTHERSELF" then patternInfo = { -- %s's %s was blocked.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "block",
        }
        elseif patternName == "SPELLDODGEDOTHEROTHER" then patternInfo = { -- %s's %s was dodged by %s.
                type = "miss",
                source = 1,
                victim = 3,
                skill = 2,
                missType =  "dodge",
        }
        elseif patternName == "SPELLDODGEDOTHERSELF" then patternInfo = { -- %s's %s was dodged.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "dodge",
        }
        elseif patternName == "SPELLDEFLECTEDOTHEROTHER" then patternInfo = { -- "%s's %s was deflected by %s.";
                type = "miss",
                source = 1,
                victim = 3,
                skill = 2,
                missType =  "deflect"
        }
        elseif patternName == "SPELLDEFLECTEDOTHERSELF" then patternInfo = { -- "%s's %s was deflected.";
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "deflect"
        }
        elseif patternName == "SPELLEVADEDOTHEROTHER" then patternInfo = { -- %s's %s was evaded by %s.
                type = "miss",
                source = 1,
                victim = 3,
                skill = 2,
                missType =  "evade",    
        }
        elseif patternName == "SPELLEVADEDOTHERSELF" then patternInfo = { -- %s's %s was evaded.        
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "evade",    
        }
        elseif patternName == "SPELLIMMUNEOTHEROTHER" then patternInfo = { -- %s's %s fails. %s is immune.      
                type = "miss",
                source = 1,
                victim = 3,
                skill = 2,
                missType =  "immune",   
        }
        elseif patternName == "SPELLIMMUNEOTHERSELF" then patternInfo = { -- %s's %s failed. You are immune.    
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "immune",   
        }
        elseif patternName == "SPELLLOGABSORBOTHEROTHER" then patternInfo = { -- %s's %s is absorbed by %s.
                type = "miss",
                source = 1,
                victim = 3,
                skill = 2,
                missType =  "absorb",   
        }
        elseif patternName == "SPELLLOGABSORBOTHERSELF" then patternInfo = { -- You absorb %s's %s.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "absorb",   
        }
        elseif patternName == "SPELLMISSOTHEROTHER" then patternInfo = { -- %s's %s missed %s.
                type = "miss",
                source = 1,
                victim = 3,
                skill = 2,
                missType =  "miss",
        }
        elseif patternName == "SPELLMISSOTHERSELF" then patternInfo = { -- %s's %s misses you.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "miss",
        }
        elseif patternName == "SPELLPARRIEDOTHEROTHER" then patternInfo = { -- %s's %s was parried by %s.
                type = "miss",
                source = 1,
                victim = 3,
                skill = 2,
                missType =  "parry",
        }
        elseif patternName == "SPELLPARRIEDOTHERSELF" then patternInfo = { -- %s's %s was parried.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "parry",
        }
        elseif patternName == "SPELLREFLECTOTHEROTHER" then patternInfo = { -- %s's %s is reflected back by %s.
                type = "miss",
                source = 1,
                skill = 2,
                victim = 3,
                missType =  "reflect"
        }
        elseif patternName == "SPELLREFLECTOTHERSELF" then patternInfo = { -- You reflect %s's %s.
                type = "miss",
                source = 1,
                skill = 2,
                victim = ParserLib_SELF,
                missType =  "reflect"
        }
        elseif patternName == "SPELLRESISTOTHEROTHER" then patternInfo = { -- %s's %s was resisted by %s.
                type = "miss",
                source = 1,
                victim = 3,
                skill = 2,
                missType =  "resist",   
        }
        elseif patternName == "SPELLRESISTOTHERSELF" then patternInfo = { -- %s's %s was resisted.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                missType =  "resist",   
        }



        -- ExtraAttackOther
        elseif patternName == "SPELLEXTRAATTACKSOTHER" then patternInfo = { -- %s gains %d extra attacks through %s."; -- Victim gains 3 extra attacks through Thras
                type = "extraattack",
                victim = 1,
                skill = 3,
                amount = 2
        }
        elseif patternName == "SPELLEXTRAATTACKSOTHER_SINGULAR" then patternInfo = { -- %s gains %d extra attack through %s.
                type = "extraattack",
                victim = 1,
                skill = 3,
                amount = 2
        }
        
        -- ExtraAttackSelf
        elseif patternName == "SPELLEXTRAATTACKSSELF" then patternInfo = { -- You gain %d extra attacks through %s."; -- You gain 3 extra attacks through Thras
                type = "extraattack",
                victim = ParserLib_SELF,
                skill = 2,
                amount = 1
        }
        elseif patternName == "SPELLEXTRAATTACKSSELF_SINGULAR" then patternInfo = { -- You gain %d extra attack through %s.
                type = "extraattack",
                victim = ParserLib_SELF,
                skill = 2,
                amount = 1
        }

        
        elseif patternName == "SPELLFAILCASTOTHER" then patternInfo = { -- %s fails to cast %s: %s.
                type = "fail",
                source = 1,
                skill = 2,
                reason = 3,
        }
        elseif patternName == "SPELLFAILCASTSELF" then patternInfo = { -- You fail to cast %s: %s.
                type = "fail",
                source = ParserLib_SELF,
                skill = 1,
                reason = 2,
        }
        
        elseif patternName == "SPELLFAILPERFORMOTHER" then patternInfo = { -- %s fails to perform %s: %s.
                type = "fail",
                source = 1,
                skill = 2,
                reason = 3,
                isPerform = true,
        }
        elseif patternName == "SPELLFAILPERFORMSELF" then patternInfo = { -- You fail to perform %s: %s.
                type = "fail",
                source = ParserLib_SELF,
                skill = 1,
                reason = 2,
                isPerform = true
        }

        elseif patternName == "SPELLHAPPINESSDRAINOTHER" then patternInfo = { -- %s's %s loses %d happiness.
        }
        elseif patternName == "SPELLHAPPINESSDRAINSELF" then patternInfo = { -- Your %s loses %d happiness.
        }

        elseif patternName == "SPELLINTERRUPTOTHEROTHER" then patternInfo = { -- %s interrupts %s's %s.
                type = "interrupt",
                source = 1,
                victim = 2,
                skill = 3
        }
        elseif patternName == "SPELLINTERRUPTOTHERSELF" then patternInfo = { -- %s interrupts your %s.
                type = "interrupt",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2
        }
        elseif patternName == "SPELLINTERRUPTSELFOTHER" then patternInfo = { -- You interrupt %s's %s.
                type = "interrupt",
                source = ParserLib_SELF,
                victim = 1,
                skill = 2
        }

        -- SpellHitOther
        elseif patternName == "SPELLLOGCRITOTHEROTHER" then patternInfo = { -- %s's %s crits %s for %d.
                type = "hit",
                source = 1,
                victim = 3,
                skill = 2,
                amount = 4,
                isCrit = true,
        }
        elseif patternName == "SPELLLOGCRITOTHERSELF" then patternInfo = { -- %s's %s crits you for %d.
                type = "hit",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                amount = 3,
                isCrit = true,
        }
        elseif patternName == "SPELLLOGCRITSCHOOLOTHEROTHER" then patternInfo = { -- %s's %s crits %s for %d %s damage.
                type = "hit",
                source = 1,
                victim = 3,
                skill = 2,
                amount = 4,
                element = 5,
                isCrit = true,
        }
        elseif patternName == "SPELLLOGCRITSCHOOLOTHERSELF" then patternInfo = { -- %s's %s crits you for %d %s damage.
                type = "hit",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                amount = 3,
                element = 4,
                isCrit = true,
        }
        elseif patternName == "SPELLLOGOTHEROTHER" then patternInfo = { -- %s's %s hits %s for %d.
                type = "hit",
                source = 1,
                victim = 3,
                skill = 2,
                amount = 4,
        }
        elseif patternName == "SPELLLOGOTHERSELF" then patternInfo = { -- %s's %s hits you for %d.
                type = "hit",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                amount = 3,
        }
        elseif patternName == "SPELLLOGSCHOOLOTHEROTHER" then patternInfo = { -- %s's %s hits %s for %d %s damage.
                type = "hit",
                source = 1,
                victim = 3,
                skill = 2,
                amount = 4,
                element = 5,
        }
        elseif patternName == "SPELLLOGSCHOOLOTHERSELF" then patternInfo = { -- %s's %s hits you for %d %s damage.
                type = "hit",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                amount = 3,
                element = 4,
        }


        
        -- SpellHitSelf
        elseif patternName == "SPELLLOGCRITSCHOOLSELFOTHER" then patternInfo = { -- Your %s crits %s for %d %s damage.
                type = "hit",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                amount = 3,
                element = 4,
                isCrit = true,
        }
        elseif patternName == "SPELLLOGCRITSCHOOLSELFSELF" then patternInfo = { -- Your %s crits you for %d %s damage.
                type = "hit",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                amount = 2,
                element = 3,
                isCrit = true,
        }
        elseif patternName == "SPELLLOGCRITSELFOTHER" then patternInfo = { -- Your %s crits %s for %d.
                type = "hit",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                amount = 3,
                isCrit = true,
        }
        elseif patternName == "SPELLLOGCRITSELFSELF" then patternInfo = { -- Your %s crits you for %d.
                type = "hit",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                amount = 2,
                isCrit = true,
        }
        elseif patternName == "SPELLLOGSCHOOLSELFOTHER" then patternInfo = { -- Your %s hits %s for %d %s damage.
                type = "hit",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                amount = 3,
                element = 4,
        }
        elseif patternName == "SPELLLOGSCHOOLSELFSELF" then patternInfo = { -- Your %s hits you for %d %s damage.
                type = "hit",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                amount = 2,
                element = 3,
        }
        elseif patternName == "SPELLLOGSELFOTHER" then patternInfo = { -- Your %s hits %s for %d.
                type = "hit",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                amount = 3,
        }
        elseif patternName == "SPELLLOGSELFSELF" then patternInfo = { -- Your %s hits you for %d.
                type = "hit",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                amount = 2,
        }


--[[
        elseif patternName == "SPELLPERFORMGOOTHER" then patternInfo = { -- %s performs %s.
                
        }
        elseif patternName == "SPELLPERFORMGOOTHERTARGETTED" then patternInfo = { -- %s performs %s on %s.
        }
        elseif patternName == "SPELLPERFORMGOSELF" then patternInfo = { -- You perform %s.
        }
        elseif patternName == "SPELLPERFORMGOSELFTARGETTED" then patternInfo = { -- You perform %s on %s.
        }
]]      
        elseif patternName == "SPELLPERFORMOTHERSTART" then patternInfo = { -- %s begins to perform %s.
                type = "cast",
                source = 1,
                skill = 2,
                isBegin = true,
                isPerform = true
        }
        elseif patternName == "SPELLPERFORMSELFSTART" then patternInfo = { -- You begin to perform %s.
                type = "cast",
                source = ParserLib_SELF,
                skill = 1,
                isBegin = true,
                isPerform = true
        }

        
        -- DrainOther
        elseif patternName == "SPELLPOWERDRAINOTHEROTHER" then patternInfo = { -- %s's %s drains %d %s from %s.
                type = "drain",
                source = 1,
                victim = 5,
                skill = 2,
                amount = 3,
                attribute = 4
        }
        elseif patternName == "SPELLPOWERDRAINOTHERSELF" then patternInfo = { -- %s's %s drains %d %s from you.
                type = "drain",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                amount = 3,
                attribute = 4
        }
        elseif patternName == "SPELLPOWERLEECHOTHEROTHER" then patternInfo = { -- %s's %s drains %d %s from %s. %s gains %d %s.
                type = "leech",
                source = 1,
                skill = 2,
                amount = 3,
                attribute = 4,
                victim = 5,
                sourceGained = 6,
                amountGained = 7,
                attributeGained = 8
        }
        elseif patternName == "SPELLPOWERLEECHOTHERSELF" then patternInfo = { -- %s's %s drains %d %s from you. %s gains %d %s.
                type = "leech",
                source = 1,
                skill = 2,
                amount = 3,
                attribute = 4,
                victim = ParserLib_SELF,
                sourceGained = 5,
                amountGained = 6,
                attributeGained = 7
        }
        
        -- DrainSelf
        elseif patternName == "SPELLPOWERDRAINSELFOTHER" then patternInfo = { -- Your %s drains %d %s from %s.
                type = "drain",
                source = ParserLib_SELF,
                victim = 4,
                skill = 1,
                amount = 2,
                attribute = 3
        }
        elseif patternName == "SPELLPOWERLEECHSELFOTHER" then patternInfo = { -- Your %s drains %d %s from %s. You gain %d %s.
                type = "leech",
                source = ParserLib_SELF,
                skill = 1,
                amount = 2,
                attribute = 3,
                victim = 4,
                sourceGained = ParserLib_SELF,
                amountGained = 5,
                attributeGained = 6
        }

        -- SplitDamage
        elseif patternName == "SPELLSPLITDAMAGEOTHEROTHER" then patternInfo = { -- %s's %s causes %s %d damage.
                type = "hit",
                source = 1,
                victim = 3,
                skill = 2,
                amount = 4,
                isSplit = true,
        }
        elseif patternName == "SPELLSPLITDAMAGEOTHERSELF" then patternInfo = { -- %s's %s causes you %d damage.
                type = "hit",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                amount = 3,
                isSplit = true,
        }
        elseif patternName == "SPELLSPLITDAMAGESELFOTHER" then patternInfo = { -- Your %s causes %s %d damage.
                type = "hit",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                amount = 3,
                isSplit = true,
        }

        

        elseif patternName == "TRADESKILL_LOG_FIRSTPERSON" then patternInfo = { -- You create %s.
                type = "create",
                source = ParserLib_SELF,
                item = 1
        }
        elseif patternName == "TRADESKILL_LOG_THIRDPERSON" then patternInfo = { -- %s creates %s.
                type = "create",
                source = 1,
                item = 2
        }

        elseif patternName == "UNITDESTROYEDOTHER" then patternInfo = { -- %s is destroyed.
                type = "death",
                victim = 1,
                isItem = true
        }
        elseif patternName == "UNITDIESOTHER" then patternInfo = { -- %s dies.
                type = "death",
                victim = 1,
        }
        elseif patternName == "UNITDIESSELF" then patternInfo = { -- You die.
                type = "death",
                victim = ParserLib_SELF
        }


        -- MissSelf
        elseif patternName == "MISSEDSELFOTHER" then patternInfo = { -- You miss %s.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "miss",     
        }
        elseif patternName == "VSABSORBSELFOTHER" then patternInfo = { -- You attack. %s absorbs all the damage.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "absorb",   
        }
        elseif patternName == "VSBLOCKSELFOTHER" then patternInfo = { -- You attack. %s blocks.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "block",    
        }
        elseif patternName == "VSDEFLECTSELFOTHER" then patternInfo = { -- You attack. %s deflects.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "deflect",  
        }
        elseif patternName == "VSDODGESELFOTHER" then patternInfo = { -- You attack. %s dodges.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "dodge",    
        }
        elseif patternName == "VSEVADESELFOTHER" then patternInfo = { -- You attack. %s evades.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "evade",    
        }
        elseif patternName == "VSIMMUNESELFOTHER" then patternInfo = { -- You attack but %s is immune.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "immune",   
        }
        elseif patternName == "VSPARRYSELFOTHER" then patternInfo = { -- You attack. %s parries.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "parry",    
        }
        elseif patternName == "VSRESISTSELFOTHER" then patternInfo = { -- You attack. %s resists all the damage.
                type = "miss",
                source = ParserLib_SELF,
                victim = 1,
                skill = ParserLib_MELEE,
                missType =  "resist",   
        }

        
        -- MissOther
        elseif patternName == "MISSEDOTHEROTHER" then patternInfo = { -- %s misses %s.
                type = "miss",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                missType =  "miss",
        }
        elseif patternName == "MISSEDOTHERSELF" then patternInfo = { -- %s misses you.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "miss",     
        }
        elseif patternName == "VSABSORBOTHEROTHER" then patternInfo = { -- %s attacks. %s absorbs all the damage.
                type = "miss",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                missType =  "absorb",   
        }
        elseif patternName == "VSABSORBOTHERSELF" then patternInfo = { -- %s attacks. You absorb all the damage.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "absorb",   
        }
        elseif patternName == "VSBLOCKOTHEROTHER" then patternInfo = { -- %s attacks. %s blocks.
                type = "miss",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                missType =  "block",    
        }
        elseif patternName == "VSBLOCKOTHERSELF" then patternInfo = { -- %s attacks. You block.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "block",    
        }
        elseif patternName == "VSDEFLECTOTHEROTHER" then patternInfo = { -- %s attacks. %s deflects.
                type = "miss",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                missType =  "deflect",  
        }
        elseif patternName == "VSDEFLECTOTHERSELF" then patternInfo = { -- %s attacks. You deflect.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "deflect",  
        }
        elseif patternName == "VSDODGEOTHEROTHER" then patternInfo = { -- %s attacks. %s dodges.
                type = "miss",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                missType =  "dodge",    
        }
        elseif patternName == "VSDODGEOTHERSELF" then patternInfo = { -- %s attacks. You dodge.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "dodge",    
        }
        elseif patternName == "VSEVADEOTHEROTHER" then patternInfo = { -- %s attacks. %s evades.
                type = "miss",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                missType =  "evade",    
        }
        elseif patternName == "VSEVADEOTHERSELF" then patternInfo = { -- %s attacks. You evade.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "evade",    
        }
        elseif patternName == "VSIMMUNEOTHEROTHER" then patternInfo = { -- %s attacks but %s is immune.
                type = "miss",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                missType =  "immune",   
        }
        elseif patternName == "VSIMMUNEOTHERSELF" then patternInfo = { -- %s attacks but you are immune.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "immune",   
        }
        elseif patternName == "VSPARRYOTHEROTHER" then patternInfo = { -- %s attacks. %s parries.
                type = "miss",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                missType =  "parry",    
        }
        elseif patternName == "VSPARRYOTHERSELF" then patternInfo = { -- %s attacks. You parry.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "parry",    
        }
        elseif patternName == "VSRESISTOTHEROTHER" then patternInfo = { -- %s attacks. %s resists all the damage.
                type = "miss",
                source = 1,
                victim = 2,
                skill = ParserLib_MELEE,
                missType =  "resist",   
        }
        elseif patternName == "VSRESISTOTHERSELF" then patternInfo = { -- %s attacks. You resist all the damage.
                type = "miss",
                source = 1,
                victim = ParserLib_SELF,
                skill = ParserLib_MELEE,
                missType =  "resist",   
        }


        -- EnvOther
        elseif patternName == "VSENVIRONMENTALDAMAGE_DROWNING_OTHER" then patternInfo = { -- %s is drowning and loses %d health.
                type = "environment",
                victim = 1,
                amount = 2,
                damageType = "drown",   
        }
        elseif patternName == "VSENVIRONMENTALDAMAGE_FALLING_OTHER" then patternInfo = { -- %s falls and loses %d health.
                type = "environment",
                victim = 1,
                amount = 2,
                damageType = "fall",
        }
        elseif patternName == "VSENVIRONMENTALDAMAGE_FATIGUE_OTHER" then patternInfo = { -- %s is exhausted and loses %d health.
                type = "environment",
                victim = 1,
                amount = 2,
                damageType = "exhaust",
        }
        elseif patternName == "VSENVIRONMENTALDAMAGE_FIRE_OTHER" then patternInfo = { -- %s suffers %d points of fire damage.
                type = "environment",
                victim = 1,
                amount = 2,
                damageType = "fire",
        }
        elseif patternName == "VSENVIRONMENTALDAMAGE_LAVA_OTHER" then patternInfo = { -- %s loses %d health for swimming in lava.
                type = "environment",
                victim = 1,
                amount = 2,
                damageType = "lava",
        }
        elseif patternName == "VSENVIRONMENTALDAMAGE_SLIME_OTHER" then patternInfo = { -- %s loses %d health for swimming in slime.
                type = "environment",
                victim = 1,
                amount = 2,
                damageType = "slime",
        }

        -- EnvSelf
        elseif patternName == "VSENVIRONMENTALDAMAGE_DROWNING_SELF" then patternInfo = { -- You are drowning and lose %d health.
                type = "environment",
                victim = ParserLib_SELF,
                amount = 1,
                damageType = "drown",           
        }
        elseif patternName == "VSENVIRONMENTALDAMAGE_FALLING_SELF" then patternInfo = { -- You fall and lose %d health.
                type = "environment",
                victim = ParserLib_SELF,
                amount = 1,
                damageType = "fall",
        }
        elseif patternName == "VSENVIRONMENTALDAMAGE_FATIGUE_SELF" then patternInfo = { -- You are exhausted and lose %d health.
                type = "environment",
                victim = ParserLib_SELF,
                amount = 1,
                damageType = "exhaust",
        }
        elseif patternName == "VSENVIRONMENTALDAMAGE_FIRE_SELF" then patternInfo = { -- You suffer %d points of fire damage.
                type = "environment",
                victim = ParserLib_SELF,
                amount = 1,
                damageType = "fire",
        }
        elseif patternName == "VSENVIRONMENTALDAMAGE_LAVA_SELF" then patternInfo = { -- You lose %d health for swimming in lava.
                type = "environment",
                victim = ParserLib_SELF,
                amount = 1,
                damageType = "lava",
        }
        elseif patternName == "VSENVIRONMENTALDAMAGE_SLIME_SELF" then patternInfo = { -- You lose %d health for swimming in slime.
                type = "environment",
                victim = ParserLib_SELF,
                amount = 1,
                damageType = "slime",
        }

        
        -- PerformOther
        elseif patternName == "OPEN_LOCK_OTHER" then patternInfo = { -- %s performs %s on %s.
                type = "cast",
                source = 1,
                victim = 3,
                skill = 2,
                isPerform = true
        }       
        elseif patternName == "SIMPLEPERFORMOTHEROTHER" then patternInfo = { -- %s performs %s on %s.
                type = "cast",
                source = 1,
                victim = 3,
                skill = 2,
                isPerform = true
        }
        elseif patternName == "SIMPLEPERFORMOTHERSELF" then patternInfo = { -- %s performs %s on you.
                type = "cast",
                source = 1,
                victim = ParserLib_SELF,
                skill = 2,
                isPerform = true
        }
        elseif patternName == "SPELLTERSEPERFORM_OTHER" then patternInfo = { -- %s performs %s.
                type = "cast",
                source = 1,
                skill = 2,
                isPerform = true
        }

        
        -- PerformSelf
        elseif patternName == "OPEN_LOCK_SELF" then patternInfo = { -- You perform %s on %s.
                type = "cast",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                isPerform = true
        }
        elseif patternName == "SIMPLEPERFORMSELFOTHER" then patternInfo = { -- You perform %s on %s.
                type = "cast",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1,
                isPerform = true
        }
        elseif patternName == "SIMPLEPERFORMSELFSELF" then patternInfo = { -- You perform %s.
                type = "cast",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1,
                isPerform = true
        }
        elseif patternName == "SPELLTERSEPERFORM_SELF" then patternInfo = { -- You perform %s.
                type = "cast",
                source = ParserLib_SELF,
                skill = 1,
                isPerform = true
        }

        
        -- CastOther
        elseif patternName == "SIMPLECASTOTHEROTHER" then patternInfo = { -- %s casts %s on %s.
                type = "cast",
                source = 1,
                victim = 3,
                skill = 2       
        }
        elseif patternName == "SIMPLECASTOTHERSELF" then patternInfo = { -- %s casts %s on you.
                type = "cast",
                source = 1,
                victim = 2,
                skill = ParserLib_SELF          
        }
        elseif patternName == "SPELLTERSE_OTHER" then patternInfo = { -- %s casts %s.
                type = "cast",
                source = 1,
                skill = 2               
        }

        -- CastSelf
        elseif patternName == "SIMPLECASTSELFOTHER" then patternInfo = { -- You cast %s on %s.
                type = "cast",
                source = ParserLib_SELF,
                victim = 2,
                skill = 1               
        }
        elseif patternName == "SIMPLECASTSELFSELF" then patternInfo = { -- "You cast %s.
                type = "cast",
                source = ParserLib_SELF,
                victim = ParserLib_SELF,
                skill = 1       
        }
        elseif patternName == "SPELLTERSE_SELF" then patternInfo = { -- You cast %s.
                type = "cast",
                source = ParserLib_SELF,
                skill = 1
        }



        end

        
        
        if not patternInfo then
                self:Print("LoadPatternInfo(): Cannot find " .. patternName );
                return
        end
        
        local pattern = getglobal(patternName); -- Get the pattern from GlobalStrings.lua
        
        local tc = 0
        for _ in string.gfind(pattern, "%%%d?%$?([sd])") do     tc = tc + 1     end
        
        pattern = { self:ConvertPattern(pattern, true) }        
        local n = table.getn(pattern)   
        if n > 1 then                   
                for j in patternInfo do
                        if type(patternInfo[j]) == "number" and patternInfo[j] < 100 then
                                patternInfo[j] = pattern[patternInfo[j]+1]
                        end
                end
        end     

        patternInfo.tc = tc
        patternInfo.pattern = pattern[1]
        
        
        return patternInfo

end


-- Used to load eventTable elements on demand.
-- 1.1.4 : Now many events share pattern list.
function lib:LoadPatternList(eventName)
        local list
        
--------------- Melee Hits ----------------     

        if eventName == "CHAT_MSG_COMBAT_SELF_HITS" then                
        
                if not self.eventTable["CHAT_MSG_COMBAT_SELF_HITS"] then
                        
                        self.eventTable["CHAT_MSG_COMBAT_SELF_HITS"] = 
                                self:LoadPatternCategoryTree(
                                {
                                        "HitSelf",
                                        "EnvSelf",
                                }
                        )
                        
                end

                list = self.eventTable["CHAT_MSG_COMBAT_SELF_HITS"] 
                
        elseif eventName == "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS" 
        or eventName == "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS" 
        or eventName == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS" 
        or eventName == "CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS" 
        or eventName == "CHAT_MSG_COMBAT_PARTY_HITS" 
        or eventName == "CHAT_MSG_COMBAT_PET_HITS" then

                if not self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"] then 
                        self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"] = 
                                self:LoadPatternCategoryTree( {
                                        "HitOtherOther",
                                        "EnvOther",
                                } )
                end
                list = self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"]
        
        
        elseif eventName == "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS" 
        or eventName == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS"  then

                if not self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"] then 
                        self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"] = 
                                self:LoadPatternCategoryTree( {
                                        {
                                                "HitOtherOther",
                                                "HitOtherSelf",
                                        },
                                        "EnvOther",
                                } )
                end
                list = self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"]

        

--------------- Melee Misses ----------------   


                
        elseif eventName == "CHAT_MSG_COMBAT_SELF_MISSES" then
                if not self.eventTable["CHAT_MSG_COMBAT_SELF_MISSES"] then
                        self.eventTable["CHAT_MSG_COMBAT_SELF_MISSES"] = 
                                self:LoadPatternCategoryTree( {
                                        "MissSelf",
                                } )
                end
                list = self.eventTable["CHAT_MSG_COMBAT_SELF_MISSES"]
                
        elseif eventName == "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES"
        or eventName == "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES"
        or eventName == "CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"
        or eventName == "CHAT_MSG_COMBAT_PARTY_MISSES"
        or eventName == "CHAT_MSG_COMBAT_PET_MISSES" then

                if not self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"] then
                        self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"] = 
                        self:LoadPatternCategoryTree( {
                                        "MissOtherOther",
                        } )
                end

                list = self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"] 
        
        
        elseif eventName == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES"
        or eventName == "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES" then

                if not self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"] then
                        self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"] = 
                        self:LoadPatternCategoryTree( {
                                {
                                        "MissOtherOther",
                                        "MissOtherSelf",
                                }
                        } )
                end

                list = self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"]  
                
--------------- Spell Buffs ----------------    
        elseif eventName == "CHAT_MSG_SPELL_SELF_BUFF" then
                if not self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"] then
                        self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"] = 
                        self:LoadPatternCategoryTree(
                                {
                                        "HealSelf",
                                        "EnchantSelf",
                                        "CastSelf",
                                        "PerformSelf",
                                        "DISPELFAILEDSELFOTHER",
                                        "SPELLCASTSELFSTART",
                                        "SPELLPERFORMSELFSTART",
                                        {
                                                "DrainSelf",
                                                "PowerGainSelf",
                                                "ExtraAttackSelf",
                                        },
                                        "SPELLSPLITDAMAGESELFOTHER",
                                        "ProcResistSelf",
                                        "SpellMissSelf",
                                }
                        )
                end             

                list = self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"]

                
        elseif eventName == "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF"
        or eventName == "CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF"  
        or eventName == "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF"  
        or eventName == "CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF"  
        or eventName == "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF" 
        or eventName == "CHAT_MSG_SPELL_PARTY_BUFF" 
        or eventName == "CHAT_MSG_SPELL_PET_BUFF" then
        
                if not self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] then
                        self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] = self:LoadPatternCategoryTree(
                                {
                                        {
                                                "HealOther",
                                                "PowerGainOther",
                                                "ExtraAttackOther",
                                                "DrainOther",
                                        },
                                        "SPELLCASTOTHERSTART",
                                        {
                                                "EnchantOther",
                                                "CastOther",
                                                "PerformOther",
                                        },
                                        "SPELLPERFORMOTHERSTART",
                                        "SpellMissOther",
                                        {
                                                "PROCRESISTOTHEROTHER",
                                                "PROCRESISTOTHERSELF",
                                        },
                                        {
                                                "SPELLSPLITDAMAGEOTHEROTHER",
                                                "SPELLSPLITDAMAGEOTHERSELF",
                                        },
                                        "DispellFailOther",
                                }
                        )
                        
                        
                end
                
                list = self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"]


--------------- Spell Damages ----------------  
                
        elseif eventName == "CHAT_MSG_SPELL_SELF_DAMAGE" then   
                if not self.eventTable["CHAT_MSG_SPELL_SELF_DAMAGE"] then
                        self.eventTable["CHAT_MSG_SPELL_SELF_DAMAGE"] = 
                                self:LoadPatternCategoryTree( {
                                        "SpellHitSelf",
                                        "CastSelf",
                                        "PerformSelf",
                                        "SpellMissSelf",
                                        "SPELLCASTSELFSTART",
                                        "SPELLPERFORMSELFSTART",
                                        "InterruptSelf",
                                        "DISPELFAILEDSELFOTHER",
                                } )

                end             
                list = self.eventTable["CHAT_MSG_SPELL_SELF_DAMAGE"]    


        elseif eventName == "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE" 
        or eventName == "CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE"  
        or eventName == "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE"  
        or eventName == "CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE"  
        or eventName == "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE" 
        or eventName == "CHAT_MSG_SPELL_PARTY_DAMAGE"  
        or eventName == "CHAT_MSG_SPELL_PET_DAMAGE"  then

                if not self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"] then
                        self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"] = 
                                self:LoadPatternCategoryTree( {
                                        "SpellHitOther",
                                        "SPELLCASTOTHERSTART",
                                        "SPELLPERFORMOTHERSTART",
                                        "DrainOther",
                                        "SpellMissOther",
                                        {
                                                "PROCRESISTOTHEROTHER",
                                                "PROCRESISTOTHERSELF",
                                        },
                                        {
                                                "SPELLSPLITDAMAGEOTHEROTHER",
                                                "SPELLSPLITDAMAGEOTHERSELF",
                                        },
                                        {
                                                "CastOther",
                                                "InterruptOther",
                                                {
                                                        "SPELLDURABILITYDAMAGEALLOTHEROTHER",
                                                        "SPELLDURABILITYDAMAGEALLOTHERSELF",
                                                        "SPELLDURABILITYDAMAGEOTHEROTHER",
                                                        "SPELLDURABILITYDAMAGEOTHERSELF",
                                                },
                                        },
                                        "PerformOther",
                                        "ExtraAttackOther",
                                        {
                                                "DISPELFAILEDOTHEROTHER",
                                                "DISPELFAILEDOTHERSELF",                                                
                                        },
                                })

                end
                list = self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"]
        
                
--------------- Periodic Buffs ---------------- 
                
        elseif eventName == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS" then
        
                if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"] then
                
                        self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"] = 
                                self:LoadPatternCategoryTree( {
                                        {
                                                "HotOther",
                                                "HotSelf",
                                        },
                                        {
                                                "BuffSelf",
                                                "BuffOther",
                                                "PowerGainSelf",
                                        },
                                        "DrainSelf",
                                } )
                end             
                list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"]    


        elseif eventName == "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS"
        or eventName == "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS"
        or eventName == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"
        or eventName == "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS" then
                
                if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"] then
                        self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"] = 
                                self:LoadPatternCategoryTree( {
                                        {
                                                "HotOther",
--                                              "DrainOther",   -- Dont think this would happen but add it anyway.
                                        },
                                        {
                                                "BuffOther",
                                                "PowerGainOther",
                                        },
                                        "DebuffOther", -- Was fired on older WoW version.
                                } )
                end
                
                list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"]


                
--------------- Periodic Damages ----------------       
                
        elseif eventName == "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE" then
                if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"] then
                
                        self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"] = 
                                self:LoadPatternCategoryTree( {
                                        {
                                                "DotSelf",
                                                "DotOther",
                                        },
                                        {
                                                "DebuffSelf",
                                                "DebuffOther",
                                        },
                                        {
                                                "SPELLLOGABSORBOTHEROTHER",
                                                "SPELLLOGABSORBOTHERSELF",
                                                "SPELLLOGABSORBSELFSELF",
                                                "SPELLLOGABSORBSELFOTHER",
                                        },
                                        "DrainSelf",
                                }       )
                end     
                list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"]   
                
                

        elseif eventName == "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"
        or eventName == "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE"
        or eventName == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"
        or eventName == "CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE" then
        
                if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"] then
                        self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"] = 
                                self:LoadPatternCategoryTree( {
                                        "DebuffOther",
                                        "DotOther",
                                        {
                                                "SPELLLOGABSORBOTHEROTHER",
                                                "SPELLLOGABSORBSELFOTHER",
                                        },                                      
                                        "DrainOther",
                                        {
                                                "PowerGainOther",
                                                "BuffOther", -- Was fired on older WoW version.                                 
                                        }
                                } )
                end                     
                list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"]

--------------- Damage Shields ---------------- 
                
                
        elseif eventName == "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF" then
                if not self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] then
                        self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] = {
                                "SPELLRESISTOTHEROTHER",
                                "SPELLRESISTSELFOTHER",
                                "DAMAGESHIELDOTHEROTHER",
                                "DAMAGESHIELDSELFOTHER",
                        }
                        table.sort(self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] , PatternCompare)
                end
                list = self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"]  
                
        elseif eventName == "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS" then
                if not self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] then
                        self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] = {
                                "SPELLRESISTOTHEROTHER",
                                "SPELLRESISTOTHERSELF",
                                "DAMAGESHIELDOTHEROTHER",
                                "DAMAGESHIELDOTHERSELF",
                        }
                        table.sort(self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] , PatternCompare)
                end             
                list = self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"]
                
                
                
--------------- Auras ----------------  

        elseif eventName == "CHAT_MSG_SPELL_AURA_GONE_PARTY"
        or eventName == "CHAT_MSG_SPELL_AURA_GONE_OTHER"
        or eventName == "CHAT_MSG_SPELL_AURA_GONE_SELF" then
        
                if not self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"] then
                        self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"] = {
                                "AURAREMOVEDOTHER",
                                "AURAREMOVEDSELF",
                        }
                        table.sort(self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"] , PatternCompare)
                end
                list = self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"]
        elseif eventName == "CHAT_MSG_SPELL_BREAK_AURA" then
        
                if not self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"] then
                        self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"] = {
                                "AURADISPELSELF",
                                "AURADISPELOTHER",
                        }
                        table.sort(self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"] , PatternCompare)
                end             
                list = self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"]                     
        elseif string.find(eventName, "ITEM_ENCHANT", 1, true) then
        
                if not self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"] then
                        self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"] = {
                                "ITEMENCHANTMENTADDSELFSELF",
                                "ITEMENCHANTMENTADDSELFOTHER",
                                "ITEMENCHANTMENTADDOTHEROTHER",
                                "ITEMENCHANTMENTADDOTHERSELF",
                        }
                        table.sort(self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"] , PatternCompare)
                end                     
                list = self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"]      

--------------- Trade Skills ----------------   

                
        elseif eventName == "CHAT_MSG_SPELL_TRADESKILLS" then
                if not self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"] then
                        self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"] = {
                                "TRADESKILL_LOG_FIRSTPERSON",
                                "TRADESKILL_LOG_THIRDPERSON",
                                "FEEDPET_LOG_FIRSTPERSON",
                                "FEEDPET_LOG_THIRDPERSON",
                        }
                        table.sort(self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"], PatternCompare )
                end             
                list = self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"]    
                
        elseif eventName == "CHAT_MSG_SPELL_FAILED_LOCALPLAYER" then
        
                if not self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"] then
                        self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"] = {
                                "SPELLFAILPERFORMSELF",
                                "SPELLFAILCASTSELF",
                        }
                        table.sort(self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"], PatternCompare)
                end             
                list = self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"]     
                        
        
        elseif eventName == "CHAT_MSG_COMBAT_FACTION_CHANGE" then
        
                if not self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"] then
                
                        if FACTION_STANDING_DECREASED then -- WoW 1.11
                                self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"] = {
                                        "FACTION_STANDING_DECREASED",
                                        "FACTION_STANDING_INCREASED",
                                }
                        else    -- WoW 1.10
                        
                                self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"] = {
                                        "FACTION_STANDING_CHANGED",
                                        "FACTION_STANDING_INCREASED1",
                                        "FACTION_STANDING_INCREASED2",
                                        "FACTION_STANDING_INCREASED3",
                                        "FACTION_STANDING_INCREASED4",
                                        "FACTION_STANDING_DECREASED1",
                                        "FACTION_STANDING_DECREASED2",
                                        "FACTION_STANDING_DECREASED3",
                                        "FACTION_STANDING_DECREASED4",          
                                }
                        end
                        table.sort(self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"] , PatternCompare)
                end             
                list = self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"]
                
        elseif eventName == "CHAT_MSG_COMBAT_HONOR_GAIN" then
        
                if not self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"] then
                        self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"] = {
                        "COMBATLOG_HONORAWARD",
                        "COMBATLOG_HONORGAIN",
                        "COMBATLOG_DISHONORGAIN",
                        }
                        table.sort(self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"] , PatternCompare)
                end             
                list = self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"]
        elseif eventName == "CHAT_MSG_COMBAT_XP_GAIN" then
        
                if not self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"] then
                        self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"] = {
                                "COMBATLOG_XPGAIN",
                                "COMBATLOG_XPGAIN_EXHAUSTION1",
                                "COMBATLOG_XPGAIN_EXHAUSTION1_GROUP",
                                "COMBATLOG_XPGAIN_EXHAUSTION1_RAID",
                                "COMBATLOG_XPGAIN_EXHAUSTION2",
                                "COMBATLOG_XPGAIN_EXHAUSTION2_GROUP",
                                "COMBATLOG_XPGAIN_EXHAUSTION2_RAID",
                                "COMBATLOG_XPGAIN_EXHAUSTION4",
                                "COMBATLOG_XPGAIN_EXHAUSTION4_GROUP",
                                "COMBATLOG_XPGAIN_EXHAUSTION4_RAID",
                                "COMBATLOG_XPGAIN_EXHAUSTION5",
                                "COMBATLOG_XPGAIN_EXHAUSTION5_GROUP",
                                "COMBATLOG_XPGAIN_EXHAUSTION5_RAID",
                                "COMBATLOG_XPGAIN_FIRSTPERSON",
                                "COMBATLOG_XPGAIN_FIRSTPERSON_GROUP",
                                "COMBATLOG_XPGAIN_FIRSTPERSON_RAID",
                                "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED",
                                "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_GROUP",
                                "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_RAID",
                                "COMBATLOG_XPLOSS_FIRSTPERSON_UNNAMED",
                        }
                        table.sort(self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"] , PatternCompare)
                end             
                list = self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"]               
                
        elseif eventName == "CHAT_MSG_COMBAT_FRIENDLY_DEATH" 
        or eventName == "CHAT_MSG_COMBAT_HOSTILE_DEATH" then
        
                if not self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"] then
                        self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"] = {
                                "PARTYKILLOTHER",
                                "UNITDESTROYEDOTHER",
                                "UNITDIESOTHER",
                                "UNITDIESSELF",
                        }
                        
                        if SELFKILLOTHER then -- WoW 1.11
                                table.insert(self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"], "SELFKILLOTHER")
                        end
                        
                        table.sort(self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"] , PatternCompare)
                end             
                list = self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"] 

        end


        if not list then
                self:Print("Cannot find event " .. eventName);
        end

        return list

end





function lib:LoadPatternCategory(category)

        local list

        if category == "DebuffOther" then
                list = {
                        "AURAADDEDOTHERHARMFUL",
                        "AURAAPPLICATIONADDEDOTHERHARMFUL",
                }
        elseif category == "DebuffSelf" then
                list = {
                        "AURAADDEDSELFHARMFUL",
                        "AURAAPPLICATIONADDEDSELFHARMFUL",
                }
        elseif category == "BuffOther" then
                list = {
                        "AURAADDEDOTHERHELPFUL",
                        "AURAAPPLICATIONADDEDOTHERHELPFUL",
                }
        elseif category == "BuffSelf" then
                list = {
                        "AURAADDEDSELFHELPFUL",
                        "AURAAPPLICATIONADDEDSELFHELPFUL",
                }
        elseif category == "ExtraAttackOther" then
                list = {
                        "SPELLEXTRAATTACKSOTHER",
                        "SPELLEXTRAATTACKSOTHER_SINGULAR",
                }               

        elseif category == "ExtraAttackSelf" then
                list = {
                        "SPELLEXTRAATTACKSSELF",
                        "SPELLEXTRAATTACKSSELF_SINGULAR",
                }               

        elseif category == "AuraChange" then
                list = {
                        "AURACHANGEDOTHER",
                        "AURACHANGEDSELF",
                }
        elseif category == "AuraDispell" then
                list = {
                        "AURADISPELOTHER",
                        "AURADISPELSELF",
                }
        elseif category == "Fade" then
                list = {
                        "AURAREMOVEDOTHER",
                        "AURAREMOVEDSELF",
                }
        elseif category == "HitOtherOther" then
                list = {
                        "COMBATHITCRITOTHEROTHER",
                        "COMBATHITCRITSCHOOLOTHEROTHER",
                        "COMBATHITOTHEROTHER",
                        "COMBATHITSCHOOLOTHEROTHER",
                }
        elseif category == "HitOtherSelf" then
                list = {
        
                        "COMBATHITCRITOTHERSELF",
                        "COMBATHITCRITSCHOOLOTHERSELF",
                        "COMBATHITOTHERSELF",
                        "COMBATHITSCHOOLOTHERSELF",
                }
        
        elseif category == "HitSelf" then
                list = {
                        "COMBATHITSCHOOLSELFOTHER",
                        "COMBATHITSELFOTHER",
                        "COMBATHITCRITSCHOOLSELFOTHER",
                        "COMBATHITCRITSELFOTHER",
                }
        elseif category == "MissOtherOther" then
                list = {
                        "MISSEDOTHEROTHER",
                        "VSABSORBOTHEROTHER",
                        "VSBLOCKOTHEROTHER",
                        "VSDEFLECTOTHEROTHER",
                        "VSDODGEOTHEROTHER",
                        "VSEVADEOTHEROTHER",
                        "VSIMMUNEOTHEROTHER",
                        "VSPARRYOTHEROTHER",
                        "VSRESISTOTHEROTHER",                           
                }       
        elseif category == "MissOtherSelf" then
                list = {
                        "MISSEDOTHERSELF",
                        "VSABSORBOTHERSELF",
                        "VSBLOCKOTHERSELF",
                        "VSDEFLECTOTHERSELF",
                        "VSDODGEOTHERSELF",
                        "VSEVADEOTHERSELF",
                        "VSIMMUNEOTHERSELF",
                        "VSPARRYOTHERSELF",
                        "VSRESISTOTHERSELF",    
                }       
        
        
        elseif category == "MissSelf" then
        
                list = {
                                "MISSEDSELFOTHER",
                                "VSABSORBSELFOTHER",
                                "VSBLOCKSELFOTHER",
                                "VSDEFLECTSELFOTHER",
                                "VSDODGESELFOTHER",
                                "VSEVADESELFOTHER",
                                "VSIMMUNESELFOTHER",
                                "VSPARRYSELFOTHER",
                                "VSRESISTSELFOTHER",                    
                }
        
        elseif category == "DispellFailOther" then
                
                list = {
                        "DISPELFAILEDOTHEROTHER",
                        "DISPELFAILEDOTHERSELF",
                
                }

        elseif category == "DispellFailSelf" then
                
                list = {
                        "DISPELFAILEDSELFOTHER",
                
                }
        

                
        elseif category == "DmgShieldOther" then
                list = {
                        "DAMAGESHIELDOTHEROTHER",
                        "DAMAGESHIELDOTHERSELF",
                }
        elseif category == "DmgShieldSelf" then
                list = {
                        "DAMAGESHIELDSELFOTHER",
                }
                
        elseif category == "DispelFailOther" then
                list = {
                        "DISPELFAILEDOTHEROTHER",
                        "DISPELFAILEDOTHERSELF",
                }
                
        elseif category == "DispellFailSelf" then
                list = {
                        "DISPELFAILEDSELFOTHER",
                }
        
        elseif category == "HealOther" then
                list = {
                        "HEALEDCRITOTHEROTHER",
                        "HEALEDCRITOTHERSELF",
                        "HEALEDOTHEROTHER",
                        "HEALEDOTHERSELF",
                }
        elseif category == "HealSelf" then
                list = {
                        "HEALEDCRITSELFOTHER",
                        "HEALEDCRITSELFSELF",
                        "HEALEDSELFOTHER",
                        "HEALEDSELFSELF",
                }
                
        elseif category == "SpellMissOther" then
                list = {
                        "IMMUNESPELLOTHEROTHER",
                        "IMMUNESPELLOTHERSELF",
                        "SPELLBLOCKEDOTHEROTHER",
                        "SPELLBLOCKEDOTHERSELF",
                        "SPELLDODGEDOTHEROTHER",
                        "SPELLDODGEDOTHERSELF",
                        "SPELLDEFLECTEDOTHEROTHER",
                        "SPELLDEFLECTEDOTHERSELF",
                        "SPELLEVADEDOTHEROTHER",
                        "SPELLEVADEDOTHERSELF",
                        "SPELLIMMUNEOTHEROTHER",
                        "SPELLIMMUNEOTHERSELF",
                        "SPELLLOGABSORBOTHEROTHER",
                        "SPELLLOGABSORBOTHERSELF",
                        "SPELLMISSOTHEROTHER",
                        "SPELLMISSOTHERSELF",
                        "SPELLPARRIEDOTHEROTHER",
                        "SPELLPARRIEDOTHERSELF",
                        "SPELLREFLECTOTHEROTHER",
                        "SPELLREFLECTOTHERSELF",
                        "SPELLRESISTOTHEROTHER",
                        "SPELLRESISTOTHERSELF",
                }
                        
        elseif category == "SpellMissSelf" then
                list = {
                        "IMMUNESPELLSELFOTHER",
                        "IMMUNESPELLSELFSELF",
                        "SPELLBLOCKEDSELFOTHER",
                        "SPELLDEFLECTEDSELFOTHER",
                        "SPELLDEFLECTEDSELFSELF",
                        "SPELLDODGEDSELFOTHER",
                        "SPELLDODGEDSELFSELF",
                        "SPELLEVADEDSELFOTHER",
                        "SPELLEVADEDSELFSELF",
                        "SPELLIMMUNESELFOTHER",
                        "SPELLIMMUNESELFSELF",
                        "SPELLLOGABSORBSELFOTHER",
                        "SPELLLOGABSORBSELFSELF",
                        "SPELLMISSSELFOTHER",
                        "SPELLMISSSELFSELF",
                        "SPELLPARRIEDSELFOTHER",
                        "SPELLPARRIEDSELFSELF",
                        "SPELLREFLECTSELFOTHER",
                        "SPELLREFLECTSELFSELF",
                        "SPELLRESISTSELFOTHER",
                        "SPELLRESISTSELFSELF",
                }
                        
        elseif category == "PowerGainOther" then
                list = {
                        "POWERGAINOTHEROTHER",
                        "POWERGAINOTHERSELF",
                }
                
        elseif category == "EnchantOther" then
                list  =  {
                        "ITEMENCHANTMENTADDOTHEROTHER",
                        "ITEMENCHANTMENTADDOTHERSELF",
                }
                
        elseif category == "EnchantSelf" then
                list = {
                        "ITEMENCHANTMENTADDSELFOTHER",
                        "ITEMENCHANTMENTADDSELFSELF",
                }
                
        elseif category == "CastOther" then
        
                list = {
                        "SIMPLECASTOTHEROTHER",
                        "SIMPLECASTOTHERSELF",
                        "SPELLTERSE_OTHER",
                }

        elseif category == "CastSelf" then
        
                list = {
                        "SIMPLECASTSELFOTHER",
                        "SIMPLECASTSELFSELF",
                        "SPELLTERSE_SELF",
                }
                
        elseif category == "PerformOther" then

                list = {
                        "OPEN_LOCK_OTHER",
                        "SIMPLEPERFORMOTHEROTHER",
                        "SIMPLEPERFORMOTHERSELF",
                        "SPELLTERSEPERFORM_OTHER",
                }
                
        elseif category == "PerformSelf" then

                list = {
                        "OPEN_LOCK_SELF",
                        "SIMPLEPERFORMSELFOTHER",
                        "SIMPLEPERFORMSELFSELF",
                        "SPELLTERSEPERFORM_SELF",
                }

        
        elseif category == "ProcResistOther" then
        
        elseif category == "ProcResistSelf" then
                list = {
                        "PROCRESISTSELFOTHER",
                        "PROCRESISTSELFSELF",
                }
                

        elseif category == "EnvOther" then
        
                list = {
                        "VSENVIRONMENTALDAMAGE_DROWNING_OTHER",
                        "VSENVIRONMENTALDAMAGE_FALLING_OTHER",
                        "VSENVIRONMENTALDAMAGE_FATIGUE_OTHER",
                        "VSENVIRONMENTALDAMAGE_FIRE_OTHER",
                        "VSENVIRONMENTALDAMAGE_LAVA_OTHER",
                        "VSENVIRONMENTALDAMAGE_SLIME_OTHER",
                }
        
        elseif category == "EnvSelf" then
        
                list = {
                        "VSENVIRONMENTALDAMAGE_DROWNING_SELF",
                        "VSENVIRONMENTALDAMAGE_FALLING_SELF",
                        "VSENVIRONMENTALDAMAGE_FATIGUE_SELF",
                        "VSENVIRONMENTALDAMAGE_FIRE_SELF",
                        "VSENVIRONMENTALDAMAGE_LAVA_SELF",
                        "VSENVIRONMENTALDAMAGE_SLIME_SELF",
                }
        
        -- HoT effects on others. (not casted by others)
        elseif category == "HotOther" then
                list = {
                        "PERIODICAURAHEALOTHEROTHER",
                        "PERIODICAURAHEALSELFOTHER",
                }

        -- HoT effects on you. (not casted by you)
        elseif category == "HotSelf" then
                list = {
                        "PERIODICAURAHEALSELFSELF",
                        "PERIODICAURAHEALOTHERSELF",
                }
        elseif category == "PowerGainSelf" then
                list = {
                        "POWERGAINSELFSELF",
                        "POWERGAINSELFOTHER",
                }
        elseif category == "BuffOther" then
                list = {
                "AURAAPPLICATIONADDEDOTHERHELPFUL",
                "AURAADDEDOTHERHELPFUL",
                }
        elseif category == "BuffSelf" then
                list = {
                        "AURAADDEDSELFHELPFUL",
                        "AURAAPPLICATIONADDEDSELFHELPFUL",
                }
        elseif category == "DrainSelf" then
                list = {        
                        "SPELLPOWERLEECHSELFOTHER",
                        "SPELLPOWERDRAINSELFOTHER",
                }
        elseif category == "DrainOther" then
                list = {        
                        "SPELLPOWERLEECHOTHEROTHER",
                        "SPELLPOWERLEECHOTHERSELF",
                        "SPELLPOWERDRAINOTHEROTHER",
                        "SPELLPOWERDRAINOTHERSELF",
                }

        -- DoT effects on others (not casted by others)
        elseif category == "DotOther" then
                list = {
                        "PERIODICAURADAMAGEOTHEROTHER",
                        "PERIODICAURADAMAGESELFOTHER",
                }
                
        -- DoT effects on you (not casted by you)
        elseif category == "DotSelf" then
                list = {
                        "PERIODICAURADAMAGEOTHERSELF",
                        "PERIODICAURADAMAGESELFSELF",
                }
        elseif category == "SpellHitOther" then
                list = {
                        "SPELLLOGCRITOTHEROTHER",
                        "SPELLLOGCRITOTHERSELF",
                        "SPELLLOGCRITSCHOOLOTHEROTHER",
                        "SPELLLOGCRITSCHOOLOTHERSELF",
                        "SPELLLOGOTHEROTHER",
                        "SPELLLOGOTHERSELF",
                        "SPELLLOGSCHOOLOTHEROTHER",
                        "SPELLLOGSCHOOLOTHERSELF",
                }

                                        
        elseif category == "SpellHitSelf" then
                list = {
                        "SPELLLOGCRITSELFOTHER",
                        "SPELLLOGCRITSELFSELF",
                        "SPELLLOGCRITSCHOOLSELFOTHER",
                        "SPELLLOGCRITSCHOOLSELFSELF",
                        "SPELLLOGSELFOTHER",
                        "SPELLLOGSELFSELF",
                        "SPELLLOGSCHOOLSELFOTHER",
                        "SPELLLOGSCHOOLSELFSELF",
                }
                
        elseif category == "InterruptOther" then
                list = {
                        "SPELLINTERRUPTOTHEROTHER",
                        "SPELLINTERRUPTOTHERSELF",
                }
        elseif category == "InterruptSelf" then
                list = {
                        "SPELLINTERRUPTSELFOTHER",
                }
        else
                
                return { category }
                
        end
        
        return list
        
end


-- Load categories recursively. First layer will not be sorted.
function lib:LoadPatternCategoryTree(catTree, reSort)
        if type(catTree) ~= "table" then return end
        
        local resultList = {}
        local list
        
        for i, v in catTree do
        
                if type(v) == "table" then
                        list = self:LoadPatternCategoryTree(v, true)
                else -- should be string.               
                        list = self:LoadPatternCategory(v)
                        table.sort(list, PatternCompare)
                end
                
                for j, w in list do
                        table.insert(resultList, w)
                end
                
        end
        
        if reSort then
                table.sort(resultList, PatternCompare)
        end
        
        return resultList


end
 

--------------------------------
--      Load this bitch!      --
--------------------------------
libobj:Register(lib)