diff --git a/LibGuildInfo.lua b/LibGuildInfo.lua
new file mode 100644
index 0000000..d665400
--- /dev/null
+++ b/LibGuildInfo.lua
@@ -0,0 +1,169 @@
+local MAJOR, MINOR = "LibGuildInfo-1.0", 1
+local LibGuildInfo, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+if not LibGuildInfo then return end --the same or newer version of this lib is already loaded into memory
+
+local Classes = {[1] = "Dragon Knight", [2]="Sorcerer", [3]="Nightblade", [6]="Templar"}
+local Alliances = {[1] = "Aldmeri Dominion", [2] = "Ebonhart Pact", [3] = "Daggerfall Convenant"}
+-- API --
+
+-- If the table for the name is empty, that means the member has left the guild (thus the 'next' usage)
+-- All future API should funnel through this function, or be aware of the limitations
+function LibGuildInfo:GetGuildMemberByMemberName(name)
+ local member = name:find("@") and self.DisplayNames[name:lower()] or self.CharacterNames[name:lower()]
+ if member and next(member) then return member end
+end
+
+function LibGuildInfo:GetClassNumByMemberName(name)
+ local member = self:GetGuildMemberByMemberName(name)
+ if member then return member.class end
+end
+
+function LibGuildInfo:GetClassNameByMemberName(name)
+ local classNum = self:GetClassNumByMemberName(name)
+ if classNum and Classes[classNum] then return Classes[classNum] end
+end
+
+function LibGuildInfo:GetLevelByMemberName(name)
+ local member = self:GetGuildMemberByMemberName(name)
+ if member then
+ if member.level < 50 then return member.level end
+ return "v" .. member.veteranRank
+ end
+end
+
+function LibGuildInfo:GetAllianceNumByMemberName(name)
+ local member = self:GetGuildMemberByMemberName(name)
+ if member then return member.alliance end
+end
+
+function LibGuildInfo:GetAllianceNameByMemberName(name)
+ local allianceNum = self:GetAllianceNumByMemberName(name)
+ if allianceNum and Alliances[allianceNum] then return Alliances[allianceNum] end
+end
+
+function LibGuildInfo:GetGuildRankIndexByMemberName(name)
+ local member = self:GetGuildMemberByMemberName(name)
+ if member then return member.rankIndex end
+end
+
+function LibGuildInfo:GetGuildRankByMemberName(name)
+ local rankIndex = self:GetGuildRankIndexByMemberName(name)
+ if rankIndex == 1 then
+ return "GL"
+ else
+ return "R"..rankIndex
+ end
+end
+
+-- Setup functions --
+
+-- This is my deep table copy function, that bypasses previously copied tables
+-- to avoid infinite loops when it comes to recursive copying. Essentially a copy
+-- of the ZO_DeepCopyTable, but without the game locking
+
+local visitedTables = {}
+
+function LibGuildInfo:DeepTableCopy(source, subCall)
+ local dest = {}
+
+ for k, v in pairs(source) do
+ if type(v) == "table" and not visitedTables[v] then
+ visitedTables[v] = true
+ dest[k] = self:DeepTableCopy(v, true)
+ else
+ dest[k] = v
+ end
+ end
+
+ if not subCall then visitedTables = {} end
+
+ return dest
+end
+
+
+function LibGuildInfo:DataLoaded()
+ if self.GuildDataLoaded then return end
+
+ self.GuildDataLoaded = true
+
+ local currentGuildId = GUILD_ROSTER.guildId
+
+ self.GuildRoster = {}
+
+ for i=1, GetNumGuilds() do
+ GUILD_ROSTER:SetGuildId(i)
+ self.GuildRoster[i] = self:DeepTableCopy(GUILD_ROSTER["masterList"])
+ end
+
+ GUILD_ROSTER:SetGuildId(currentGuildId)
+ self:ProcessData()
+end
+
+function LibGuildInfo:ProcessData()
+ self.DisplayNames = self.DisplayNames or {}
+
+ ZO_ClearTable(self.DisplayNames)
+
+ for i,roster in pairs(self.GuildRoster) do
+ for i,v in pairs(roster) do
+ self.DisplayNames[v.displayName:lower()] = v
+ end
+ end
+
+ self.CharacterNames = self.CharacterNames or {}
+
+ ZO_ClearTable(self.CharacterNames)
+
+ for i, roster in pairs(self.GuildRoster) do
+ for i,v in pairs(roster) do
+ self.CharacterNames[v.characterName:lower()] = v
+ end
+ end
+end
+
+function LibGuildInfo:FindInCurrentRoster(name)
+ for i,v in pairs(GUILD_ROSTER["masterList"]) do
+ if name:find("@") and v.displayName:lower() == name:lower() or v.characterName == name:lower() then
+ return v
+ end
+ end
+end
+
+function LibGuildInfo:OnGuildMemberAdded(guildId, displayName)
+ if not self.GuildDataLoaded then return end
+ local currentGuildId = GUILD_ROSTER.guildId
+
+ GUILD_ROSTER:SetGuildId(guildId)
+ local v = self:DeepTableCopy(self:FindInCurrentRoster(displayName))
+ table.insert(self.GuildRoster[guildId], v)
+ self.DisplayNames[v.displayName:lower()] = v
+ self.CharacterNames[v.characterName:lower()] = v
+
+ GUILD_ROSTER:SetGuildId(currentGuildId)
+end
+
+-- If they're removed from the guild, empty the table out
+function LibGuildInfo:OnGuildMemberRemoved(guildId, displayName)
+ if not self.GuildDataLoaded then return end
+ local v = self.DisplayNames[displayName:lower()]
+ ZO_ClearTable(v)
+end
+
+-- We just shallow copy into the existing table so as not to lose the
+-- table references everywhere by replacing it
+function LibGuildInfo:OnGuildMemberCharacterUpdated(guildId, displayName)
+ if not self.GuildDataLoaded then return end
+ local currentGuildId = GUILD_ROSTER.guildId
+
+ GUILD_ROSTER:SetGuildId(guildId)
+ local v = self:FindInCurrentRoster(displayName)
+ ZO_ShallowTableCopy(v,self.DisplayNames[displayName:lower()])
+ GUILD_ROSTER:SetGuildId(currentGuildId)
+end
+
+EVENT_MANAGER:RegisterForEvent("LGI_EVENT_PLAYER_ACTIVATED", EVENT_PLAYER_ACTIVATED, function() LibGuildInfo:DataLoaded() end)
+EVENT_MANAGER:RegisterForEvent("LGI_EVENT_GUILD_MEMBER_ADDED", EVENT_GUILD_MEMBER_ADDED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberAdded(guildId, displayName) end)
+EVENT_MANAGER:RegisterForEvent("LGI_EVENT_GUILD_MEMBER_REMOVED", EVENT_GUILD_MEMBER_REMOVED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberRemoved(guildId, displayName) end)
+EVENT_MANAGER:RegisterForEvent("LGI_EVENT_GUILD_MEMBER_CHARACTER_UPDATED", EVENT_GUILD_MEMBER_CHARACTER_UPDATED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberCharacterUpdated(guildId, displayName) end)
+EVENT_MANAGER:RegisterForEvent("LGI_EVENT_GUILD_MEMBER_CHARACTER_LEVEL_CHANGED", EVENT_GUILD_MEMBER_CHARACTER_LEVEL_CHANGED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberCharacterUpdated(guildId, displayName) end)
+EVENT_MANAGER:RegisterForEvent("LGI_EVENT_GUILD_MEMBER_CHARACTER_VETERAN_RANK_CHANGED", EVENT_GUILD_MEMBER_CHARACTER_VETERAN_RANK_CHANGED, function(_, guildId, displayName) LibGuildInfo:OnGuildMemberCharacterUpdated(guildId, displayName) end)
\ No newline at end of file
diff --git a/LibStub/LibStub.lua b/LibStub/LibStub.lua
new file mode 100644
index 0000000..bfd96df
--- /dev/null
+++ b/LibStub/LibStub.lua
@@ -0,0 +1,34 @@
+-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
+-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
+-- LibStub developed for World of Warcraft by above members of the WowAce community.
+-- Ported to Elder Scrolls Online by Seerah
+
+local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 1 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
+local LibStub = _G[LIBSTUB_MAJOR]
+
+local strformat = string.format
+if not LibStub or LibStub.minor < LIBSTUB_MINOR then
+ LibStub = LibStub or {libs = {}, minors = {} }
+ _G[LIBSTUB_MAJOR] = LibStub
+ LibStub.minor = LIBSTUB_MINOR
+
+ function LibStub:NewLibrary(major, minor)
+ assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
+ minor = assert(tonumber(zo_strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
+
+ local oldminor = self.minors[major]
+ if oldminor and oldminor >= minor then return nil end
+ self.minors[major], self.libs[major] = minor, self.libs[major] or {}
+ return self.libs[major], oldminor
+ end
+
+ function LibStub:GetLibrary(major, silent)
+ if not self.libs[major] and not silent then
+ error(("Cannot find a library instance of %q."):strformat(tostring(major)), 2)
+ end
+ return self.libs[major], self.minors[major]
+ end
+
+ function LibStub:IterateLibraries() return pairs(self.libs) end
+ setmetatable(LibStub, { __call = LibStub.GetLibrary })
+end
diff --git a/README.md b/README.md
index c9f336f..2ba2892 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,97 @@
-LibGuildInfo
-============
+#LibGuildInfo
+**Author** - Wobin
+**Date** - 25/05/2014
+**Game** - *Elder Scrolls Online*
-LibStub library for ESO Guild member information
+This library will retrieve and store guild member information for easy access via account name or character name
+
+##Setup
+
+1. Place the library in your addon folder
+2. Reference `LibStub` in your manifest
+3. Reference `LibGuildInfo` in your manifest
+4. Reference `LibGuildInfo` in your code:
+
+ local LibGuildInfo = LibStub("LibGuildInfo-1.0")
+
+##API
+The following API is defined:
+
+###GetGuildMemberByMemberName
+
+ LibGuildInfo:GetGuildMemberByMemberName(name)
+
+- *name* - being either the account name with the @ symbol or the character name
+
+**Returns**
+- *guildInfo* - an object that contains all guild info used in the guild panel
+
+###GetClassNumByMemberName
+
+ LibGuildInfo:GetClassNumByMemberName(name)
+
+- *name* - as above
+
+**Returns**
+- *classNum* - a number representing the class
+ - [1] = "Dragon Knight"
+ - [2] = "Sorcerer"
+ - [3] = "Nightblade"
+ - [6] = "Templar"
+
+###GetClassNameByMemberName
+
+ LibGuildInfo:GetClassNameByMemberName(name)
+
+- *name* - as above
+
+**Returns***
+- *className* - The english representation of the class
+
+###GetLevelByMemberName
+
+ GetLevelByMemberName(name)
+
+- *name* - as above
+
+**Returns***
+- *level* - Numerical representation of the player character's level. Veteren ranks represented by 'Vx'
+
+###GetAllianceNumByMemberName
+
+ GetAllianceNumByMemberName(name)
+
+- *name* as above
+
+**Returns**
+- *allianceNum* - Numerical representation of the alliance the currently logged in player is a member of
+ - [1] = "Aldmeri Dominion"
+ - [2] = "Ebonhart Pact"
+ - [3] = "Daggerfall Convenant"
+
+###GetAllianceNameByMemberName
+
+ GetAllianceNameByMemberName(name)
+
+- *name* as above
+
+**Returns**
+- *allianceName* - The english representation of the Alliance
+
+###GetGuildRankIndexByMemberName
+
+ GetGuildRankIndexByMemberName(name)
+
+- *name* as above
+
+**Returns**
+- *rankIndex* - Numerical representation of the account's guild rank (1 is Guild Leader)
+
+###GetGuildRankByMemberName
+
+ GetGuildRankByMemberName(name)
+
+- *name* as above
+
+**Returns**
+- *rank* - A more textual representation 'GL' for Guild leader and 'Rx' for subsequent membership