EXPANSION_LEVEL = GetExpansionLevel(); --This can change while logged in, when an expansion releases
 
 LFD_MAX_REWARDS = 2;
 
 NUM_LFD_CHOICE_BUTTONS = 15;
 
 NUM_LFD_MEMBERS = 5;
 
 LFD_STATISTIC_CHANGE_TIME = 10; --In secs.
 
 LFD_PROPOSAL_FAILED_CLOSE_TIME = 5;
 
 LFD_NUM_ROLES = 3;
 
 LFD_MAX_SHOWN_LEVEL_DIFF = 15;
 
 -------------------------------------
 -----------LFD Frame--------------
 -------------------------------------
 
 --General functions
 function LFDFrame_OnLoad(self)
 	--self:RegisterEvent("LFG_PROPOSAL_UPDATE");
 	--self:RegisterEvent("LFG_PROPOSAL_SHOW");
 	--self:RegisterEvent("LFG_PROPOSAL_FAILED");
 	--self:RegisterEvent("LFG_PROPOSAL_SUCCEEDED");
 	--self:RegisterEvent("LFG_UPDATE");
 	self:RegisterEvent("PLAYER_ENTERING_WORLD");
 	self:RegisterEvent("LFG_ROLE_CHECK_SHOW");
 	self:RegisterEvent("LFG_ROLE_CHECK_HIDE");
 	self:RegisterEvent("LFG_BOOT_PROPOSAL_UPDATE");
 	self:RegisterEvent("VOTE_KICK_REASON_NEEDED");
 	self:RegisterEvent("LFG_UPDATE_RANDOM_INFO");
 	self:RegisterEvent("LFG_OPEN_FROM_GOSSIP");
 	self:RegisterEvent("UPDATE_EXPANSION_LEVEL");
 	
 	ButtonFrameTemplate_HideAttic(self);
 	self.Inset:SetPoint("TOPLEFT", self, "BOTTOMLEFT", 2, 284);
 	self.Inset:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -2, 26);
 end
 
 function LFDFrame_OnEvent(self, event, ...)
 	if ( event == "LFG_ROLE_CHECK_SHOW" ) then
 		StaticPopupSpecial_Show(LFDRoleCheckPopup);
 		LFDQueueFrameSpecificList_Update();
 	elseif ( event == "LFG_ROLE_CHECK_HIDE" ) then
 		StaticPopupSpecial_Hide(LFDRoleCheckPopup);
 		LFDQueueFrameSpecificList_Update();
 	elseif ( event == "LFG_BOOT_PROPOSAL_UPDATE" ) then
 		local voteInProgress, didVote, myVote, targetName, totalVotes, bootVotes, timeLeft, reason = GetLFGBootProposal();
 		if ( voteInProgress and not didVote and targetName ) then
 			StaticPopup_Show("VOTE_BOOT_PLAYER", targetName, reason);
 		else
 			StaticPopup_Hide("VOTE_BOOT_PLAYER");
 		end
 	elseif ( event == "VOTE_KICK_REASON_NEEDED" ) then
 		local targetName, targetGUID = ...;
 		StaticPopup_Show("VOTE_BOOT_REASON_REQUIRED", targetName, nil, targetGUID);
 	elseif ( event == "LFG_UPDATE_RANDOM_INFO" ) then
 		if ( not LFDQueueFrame.type or (type(LFDQueueFrame.type) == "number" and not IsLFGDungeonJoinable(LFDQueueFrame.type)) ) then
 			local bestChoice = GetRandomDungeonBestChoice();
 			if ( bestChoice ) then
 				LFDQueueFrame_SetType(bestChoice);
 			end
 		end
 		--If we still don't have a value, we should go to specific.
 		if ( not LFDQueueFrame.type ) then
 			LFDQueueFrame_SetType("specific");
 		end
 	elseif ( event == "LFG_OPEN_FROM_GOSSIP" ) then
 		local dungeonID = ...;
 		PVEFrame_ShowFrame("GroupFinderFrame", LFDParentFrame);
 		LFDQueueFrame_SetType(dungeonID);
 	elseif ( event == "UPDATE_EXPANSION_LEVEL" ) then
 		EXPANSION_LEVEL = GetExpansionLevel();
 	end
 end
 
 function LFDFrame_OnShow(self)
 	LFGBackfillCover_Update(LFDQueueFrame.PartyBackfill, true);
 end
 
 --Role-related functions
 
 function LFDQueueFrame_SetRoles()
-	SetLFGRoles(LFDQueueFrameRoleButtonLeader.checkButton:GetChecked(), 
-		LFDQueueFrameRoleButtonTank.checkButton:GetChecked(),
-		LFDQueueFrameRoleButtonHealer.checkButton:GetChecked(),
-		LFDQueueFrameRoleButtonDPS.checkButton:GetChecked());
+	SetLFGRoles(LFGRole_GetChecked(LFDQueueFrameRoleButtonLeader), 
+		LFGRole_GetChecked(LFDQueueFrameRoleButtonTank),
+		LFGRole_GetChecked(LFDQueueFrameRoleButtonHealer),
+		LFGRole_GetChecked(LFDQueueFrameRoleButtonDPS));
 end
 
 function LFDQueueFrame_GetRoles()
-	return LFDQueueFrameRoleButtonLeader.checkButton:GetChecked(), 
-		LFDQueueFrameRoleButtonTank.checkButton:GetChecked(),
-		LFDQueueFrameRoleButtonHealer.checkButton:GetChecked(),
-		LFDQueueFrameRoleButtonDPS.checkButton:GetChecked();
+	return LFGRole_GetChecked(LFDQueueFrameRoleButtonLeader), 
+		LFGRole_GetChecked(LFDQueueFrameRoleButtonTank),
+		LFGRole_GetChecked(LFDQueueFrameRoleButtonHealer),
+		LFGRole_GetChecked(LFDQueueFrameRoleButtonDPS);
 end
 
 function LFDFrameRoleCheckButton_OnClick(self)
 	LFDQueueFrame_SetRoles();
 	LFDQueueFrameRandom_UpdateFrame();	--We may show or hide shortage rewards.
 end
 
-function LFDQueueFrame_UpdateRoleIncentives()
+function LFDQueueFrame_UpdateRoleButtons()
 	local dungeonID = LFDQueueFrame.type;
 	LFG_SetRoleIconIncentive(LFDQueueFrameRoleButtonTank, nil);
 	LFG_SetRoleIconIncentive(LFDQueueFrameRoleButtonHealer, nil);
 	LFG_SetRoleIconIncentive(LFDQueueFrameRoleButtonDPS, nil);
-	
+
+	local tankLocked, healerLocked, dpsLocked;
+	local restrictedRoles = {[1]={count=0, alert=false}, -- tank
+							 [2]={count=0, alert=false}, -- healer
+							 [3]={count=0, alert=false}} -- dps
 	if ( type(dungeonID) == "number" ) then
+		tankLocked, healerLocked, dpsLocked = GetLFDRoleRestrictions(dungeonID);
 		for i=1, LFG_ROLE_NUM_SHORTAGE_TYPES do
 			local eligible, forTank, forHealer, forDamage, itemCount, money, xp = GetLFGRoleShortageRewards(dungeonID, i);
 			if ( eligible and (itemCount ~= 0 or money ~= 0 or xp ~= 0) ) then	--Only show the icon if there is actually a reward.
 				if ( forTank ) then
 					LFG_SetRoleIconIncentive(LFDQueueFrameRoleButtonTank, i);
 				end
 				if ( forHealer ) then
 					LFG_SetRoleIconIncentive(LFDQueueFrameRoleButtonHealer, i);
 				end
 				if ( forDamage ) then
 					LFG_SetRoleIconIncentive(LFDQueueFrameRoleButtonDPS, i);
 				end
 			end
 		end
+	elseif( dungeonID == "specific" and LFGEnabledList )then
+		-- count the number of dungeons a role is locked
+		local dungeonCount = 0;
+		for id, isChecked in pairs(LFGEnabledList) do
+			if( not LFGIsIDHeader(id) and isChecked and not LFGLockList[id] ) then
+				tankLocked, healerLocked, dpsLocked = GetLFDRoleRestrictions(id);
+				restrictedRoles[1].count = restrictedRoles[1].count + ((tankLocked and 1) or 0);
+				restrictedRoles[2].count = restrictedRoles[2].count + ((healerLocked and 1) or 0);
+				restrictedRoles[3].count = restrictedRoles[3].count + ((dpsLocked and 1) or 0);
+				dungeonCount = dungeonCount + 1;
+			end
+		end
+		if( dungeonCount > 0 ) then
+			tankLocked = restrictedRoles[1].count == dungeonCount;
+			healerLocked = restrictedRoles[2].count == dungeonCount;
+			dpsLocked = restrictedRoles[3].count == dungeonCount;
+		end
+		restrictedRoles[1].alert = not tankLocked and restrictedRoles[1].count > 0;
+		restrictedRoles[2].alert = not healerLocked and restrictedRoles[2].count > 0;
+		restrictedRoles[3].alert = not dpsLocked and restrictedRoles[3].count > 0;
+	end
+
+	LFDQueueFrame_UpdateRoleButton(LFDQueueFrameRoleButtonTank, tankLocked, restrictedRoles[1].alert);
+	LFDQueueFrame_UpdateRoleButton(LFDQueueFrameRoleButtonHealer, healerLocked, restrictedRoles[2].alert);
+	LFDQueueFrame_UpdateRoleButton(LFDQueueFrameRoleButtonDPS, dpsLocked, restrictedRoles[3].alert);
+end
+
+function LFDQueueFrame_UpdateRoleButton( button, locked, alert )
+	if( button.permDisabled )then
+		return;
+	end
+	
+	if( locked ) then
+		button.lockedIndicator:Show();
+		button.checkButton:Hide();
+		button.checkButton:Disable();
+		button.alert:Hide();
+	else
+		button.lockedIndicator:Hide();
+		button.checkButton:Show();
+		button.checkButton:Enable();
+		
+		if( alert ) then
+			button.alert:Show();
+		else
+			button.alert:Hide();
+		end
 	end
 end
 
 --Role-check popup functions
 function LFDRoleCheckPopupAccept_OnClick()
 	PlaySound("igCharacterInfoTab");
 
 	--Check if the role check is for a BG or not.
 	local _, _, _, _, _, isBGRoleCheck = GetLFGRoleUpdate();
 	if ( isBGRoleCheck ) then
-		SetPVPRoles(LFDRoleCheckPopupRoleButtonTank.checkButton:GetChecked(),
-					LFDRoleCheckPopupRoleButtonHealer.checkButton:GetChecked(),
-					LFDRoleCheckPopupRoleButtonDPS.checkButton:GetChecked());
+		SetPVPRoles(LFGRole_GetChecked(LFDRoleCheckPopupRoleButtonTank),
+					LFGRole_GetChecked(LFDRoleCheckPopupRoleButtonHealer),
+					LFGRole_GetChecked(LFDRoleCheckPopupRoleButtonDPS));
 	else
 		local oldLeader = GetLFGRoles();
 		SetLFGRoles(oldLeader, 
-			LFDRoleCheckPopupRoleButtonTank.checkButton:GetChecked(),
-			LFDRoleCheckPopupRoleButtonHealer.checkButton:GetChecked(),
-			LFDRoleCheckPopupRoleButtonDPS.checkButton:GetChecked());
+			LFGRole_GetChecked(LFDRoleCheckPopupRoleButtonTank),
+			LFGRole_GetChecked(LFDRoleCheckPopupRoleButtonHealer),
+			LFGRole_GetChecked(LFDRoleCheckPopupRoleButtonDPS) );
 	end
 	
 	if ( CompleteLFGRoleCheck(true) ) then
 		StaticPopupSpecial_Hide(LFDRoleCheckPopup);
 	end
 end
 
 function LFDRoleCheckPopupDecline_OnClick()
 	PlaySound("igCharacterInfoTab");
 	StaticPopupSpecial_Hide(LFDRoleCheckPopup);
 	CompleteLFGRoleCheck(false);
 end
 
 function LFDRoleCheckPopup_Update()
 	LFGDungeonList_Setup();
 	
 	LFG_UpdateAllRoleCheckboxes();
 	
 	local inProgress, slots, members, category, lfgID, bgQueue = GetLFGRoleUpdate();
+	local isLFGList, activityID = C_LFGList.GetRoleCheckInfo();
 	
 	local displayName;
-	if ( bgQueue ) then
+	if( isLFGList ) then
+		displayName = C_LFGList.GetActivityInfo(activityID);
+	elseif ( bgQueue ) then
 		displayName = GetLFGRoleUpdateBattlegroundInfo();
 	elseif ( slots == 1 ) then
 		local dungeonID, dungeonType, dungeonSubType = GetLFGRoleUpdateSlot(1);
 		if ( dungeonSubType == LFG_SUBTYPEID_HEROIC ) then
 			displayName = format(HEROIC_PREFIX, select(LFG_RETURN_VALUES.name, GetLFGDungeonInfo(dungeonID)));
 		else
 			displayName = select(LFG_RETURN_VALUES.name, GetLFGDungeonInfo(dungeonID));
 		end
 	else
 		displayName = MULTIPLE_DUNGEONS;
 	end
 	displayName = NORMAL_FONT_COLOR_CODE..displayName.."|r";
 	
-	LFDRoleCheckPopupDescriptionText:SetFormattedText(QUEUED_FOR, displayName);
+	if ( isLFGList ) then
+		LFDRoleCheckPopupDescriptionText:SetFormattedText(LFG_LIST_APPLYING_TO, displayName);
+	else
+		LFDRoleCheckPopupDescriptionText:SetFormattedText(QUEUED_FOR, displayName);
+	end
 	
 	LFDRoleCheckPopupDescription:SetWidth(LFDRoleCheckPopupDescriptionText:GetWidth()+10);
 	LFDRoleCheckPopupDescription:SetHeight(LFDRoleCheckPopupDescriptionText:GetHeight());
+	
+	LFGRoleCheckPopup_UpdateRoleButton(LFDRoleCheckPopupRoleButtonTank);
+	LFGRoleCheckPopup_UpdateRoleButton(LFDRoleCheckPopupRoleButtonHealer);
+	LFGRoleCheckPopup_UpdateRoleButton(LFDRoleCheckPopupRoleButtonDPS);
+end
+
+function LFGRoleCheckPopup_UpdateRoleButton(button)
+	if( button:IsEnabled() )then
+		local unlocked, alert = GetLFGInviteRoleAvailability(button:GetID());
+		if(unlocked)then
+			LFG_EnableRoleButton(button);
+			button.lockedIndicator:Hide();
+			button.checkButton:Show();
+			if(alert) then
+				button.alert:Show();
+			else
+				button.alert:Hide();
+			end
+		else
+			button.lockedIndicator:Show();
+			LFG_DisableRoleButton(button);
+			button.checkButton:Hide();
+			button.alert:Hide();
+		end
+	end
 end
 
 function LFDRoleCheckPopupDescription_OnEnter(self)
 	local inProgress, slots, members = GetLFGRoleUpdate();
 	
 	if ( slots <= 1 ) then
 		return;
 	end
 	
 	GameTooltip:SetOwner(self, "ANCHOR_BOTTOM");
 	GameTooltip:AddLine(QUEUED_FOR_SHORT);
 	
 	for i=1, slots do
 		local dungeonID, dungeonType, dungeonSubType = GetLFGRoleUpdateSlot(i);
 		local displayName;
 		if ( dungeonSubType == LFG_SUBTYPEID_HEROIC ) then
 			displayName = format(HEROIC_PREFIX, select(LFG_RETURN_VALUES.name, GetLFGDungeonInfo(dungeonID)));
 		else
 			displayName = select(LFG_RETURN_VALUES.name, GetLFGDungeonInfo(dungeonID));
 		end
 		GameTooltip:AddLine("    "..displayName);
 	end
 	GameTooltip:Show();
 end
 
+function LFDPopupRoleCheckButton_OnEnter(self)
+	GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
+	GameTooltip:SetText(_G["ROLE_DESCRIPTION_"..self.role], nil, nil, nil, nil, true);
+	if ( self.permDisabled ) then
+		if(self.permDisabledTip)then
+			GameTooltip:AddLine(self.permDisabledTip, 1, 0, 0, true);
+		end
+	elseif ( self.disabledTooltip and not self:IsEnabled() ) then
+		GameTooltip:AddLine(self.disabledTooltip, 1, 0, 0, true);
+	elseif ( not self:IsEnabled() ) then
+		local dungeonID = LFDQueueFrame.type;
+		local roleID = self:GetID();
+		GameTooltip:SetText(ERR_ROLE_UNAVAILABLE, 1.0, 1.0, 1.0);
+		local reasons = GetLFGInviteRoleRestrictions(roleID);
+		for i = 1, #reasons do
+			local text = _G["INSTANCE_UNAVAILABLE_SELF_"..(LFG_INSTANCE_INVALID_CODES[reasons[i]])];
+			if( text ) then
+				GameTooltip:AddLine(text);
+			end
+		end
+		GameTooltip:Show();
+		return;
+	elseif( self.alert:IsShown() ) then
+		GameTooltip:SetText(INSTANCE_ROLE_WARNING_TITLE, 1.0, 1.0, 1.0, true);
+		GameTooltip:AddLine(INSTANCE_ROLE_WARNING_TEXT, nil, nil, nil, true);
+	end
+	GameTooltip:Show();
+	LFGFrameRoleCheckButton_OnEnter(self);
+end
+
 --List functions
 function LFDQueueFrameSpecificList_Update()
 	if ( LFGDungeonList_Setup() ) then
 		return;	--Setup will update the list.
 	end
 	FauxScrollFrame_Update(LFDQueueFrameSpecificListScrollFrame, LFDGetNumDungeons(), NUM_LFD_CHOICE_BUTTONS, 16);
 	
 	local offset = FauxScrollFrame_GetOffset(LFDQueueFrameSpecificListScrollFrame);
 	
 	local areButtonsBig = not LFDQueueFrameSpecificListScrollFrame:IsShown();
 	
 	local enabled, queued = LFGDungeonList_EvaluateListState(LE_LFG_CATEGORY_LFD);
 	
 	local checkedList;
 	if ( queued ) then
 		checkedList = LFGQueuedForList[LE_LFG_CATEGORY_LFD];
 	else
 		checkedList = LFGEnabledList;
 	end
 
 	for i = 1, NUM_LFD_CHOICE_BUTTONS do
 		local button = _G["LFDQueueFrameSpecificListButton"..i];
 		local dungeonID = LFDDungeonList[i+offset];
 		if ( dungeonID ) then
 			button:Show();
 			if ( areButtonsBig ) then
 				button:SetWidth(315);
 			else
 				button:SetWidth(295);
 			end
 			LFGDungeonListButton_SetDungeon(button, dungeonID, enabled, checkedList);
 		else
 			button:Hide();
 		end
 	end
 end
 
 function LFDQueueFrame_Join()
 	LFG_JoinDungeon(LE_LFG_CATEGORY_LFD, LFDQueueFrame.type, LFDDungeonList, LFDHiddenByCollapseList);
 end
 
 function LFDQueueFrameDungeonChoiceEnableButton_OnClick(self, button)
 	LFGDungeonListCheckButton_OnClick(self, LE_LFG_CATEGORY_LFD, LFDDungeonList, LFDHiddenByCollapseList);
 	LFDQueueFrameSpecificList_Update();
+	LFDQueueFrame_UpdateRoleButtons();
 end
 
 function LFDQueueFrameDungeonListButton_OnEnter(self)
 	LFGDungeonListButton_OnEnter(self, YOU_MAY_NOT_QUEUE_FOR_DUNGEON);
 end
 
 function LFDQueueFrameExpandOrCollapseButton_OnClick(self, button)
 	LFGDungeonList_SetHeaderCollapsed(self:GetParent(), LFDDungeonList, LFDHiddenByCollapseList);
 	LFDQueueFrame_Update();
 end
 
 function LFDQueueFrameTypeDropDown_SetUp(self)
 	UIDropDownMenu_SetWidth(self, 180);
 	UIDropDownMenu_Initialize(self, LFDQueueFrameTypeDropDown_Initialize);
 	UIDropDownMenu_SetSelectedValue(LFDQueueFrameTypeDropDown, LFDQueueFrame.type);
 end
 
 function LFDQueueFrameTypeDropDown_Initialize()
 	local info = UIDropDownMenu_CreateInfo();
 	
 	info.text = SPECIFIC_DUNGEONS;
 	info.value = "specific";
 	info.func = LFDQueueFrameTypeDropDownButton_OnClick;
 	info.checked = LFDQueueFrame.type == info.value;
 	UIDropDownMenu_AddButton(info);
 	
 	for i=1, GetNumRandomDungeons() do
 		local id, name = GetLFGRandomDungeonInfo(i);
 		if ( LFG_IsRandomDungeonDisplayable(id) ) then
 			local isAvailable = IsLFGDungeonJoinable(id);
 			if ( isAvailable ) then		
 				info.text = name;
 				info.value = id;
 				info.isTitle = nil;
 				info.func = LFDQueueFrameTypeDropDownButton_OnClick;
 				info.disabled = nil;
 				info.checked = (LFDQueueFrame.type == info.value);
 				info.tooltipWhileDisabled = nil;
 				info.tooltipOnButton = nil;
 				info.tooltipTitle = nil;
 				info.tooltipText = nil;
 				UIDropDownMenu_AddButton(info);
 			else
 				info.text = name;
 				info.value = id;
 				info.isTitle = nil;
 				info.func = nil;
 				info.disabled = 1;
 				info.checked = nil;
 				info.tooltipWhileDisabled = 1;
 				info.tooltipOnButton = 1;
 				info.tooltipTitle = YOU_MAY_NOT_QUEUE_FOR_THIS;
 				info.tooltipText = LFGConstructDeclinedMessage(id);
 				UIDropDownMenu_AddButton(info);
 			end
 		end
 	end
 end
 
 function LFDQueueFrameTypeDropDownButton_OnClick(self)
 	LFDQueueFrame_SetType(self.value);
 end
 
 function LFDQueueFrame_SetType(value)	--"specific" for the list or the record id for a single dungeon
 	LFDQueueFrame.type = value;
 	UIDropDownMenu_SetSelectedValue(LFDQueueFrameTypeDropDown, value);
 	
 	if ( value == "specific" ) then
 		LFDQueueFrame_SetTypeSpecificDungeon();
 	else
 		local name, typeID, subtypeID, minLevel, maxLevel, recLevel, minRecLevel, maxRecLevel, expansionLevel, groupID, textureFilename, difficulty, maxPlayers, description, isHoliday = GetLFGDungeonInfo(value);
 		LFDQueueFrame_SetTypeRandomDungeon(isHoliday);
 		LFDQueueFrameRandom_UpdateFrame();
 	end
-	LFDQueueFrame_UpdateRoleIncentives();
+	LFDQueueFrame_UpdateRoleButtons();
 end
 
 function LFDQueueFrame_SetTypeRandomDungeon(isHoliday)
 	LFDQueueFrameBackground:SetTexture("Interface\\LFGFrame\\UI-LFG-BACKGROUND-QUESTPAPER")
 	LFDQueueFrameSpecific:Hide();
 	LFDQueueFrameRandom:Show();
 	LFGCooldownCover_ChangeSettings(LFDQueueFrame.CooldownFrame, true, not isHoliday);
 end
 
 function LFDQueueFrame_SetTypeSpecificDungeon()
 	LFDQueueFrameBackground:SetTexture("Interface\\LFGFrame\\UI-LFG-BACKGROUND-DUNGEONWALL");
 	LFDQueueFrameRandom:Hide();
 	LFDQueueFrameSpecific:Show();
 	LFGCooldownCover_ChangeSettings(LFDQueueFrame.CooldownFrame, true, false);
 end
 
 function LFDQueueFrameRandom_UpdateFrame()
 	local dungeonID = LFDQueueFrame.type;
 	
 	if ( type(dungeonID) ~= "number" ) then	--We haven't gotten info on available dungeons yet.
 		return;
 	end
 	
 	LFGRewardsFrame_UpdateFrame(LFDQueueFrameRandomScrollFrameChildFrame, dungeonID, LFDQueueFrameBackground);
-	LFDQueueFrame_UpdateRoleIncentives();
+	LFDQueueFrame_UpdateRoleButtons();
 end
 
 function LFDQueueFrameRandomCooldownFrame_OnLoad(self)
 	self:SetFrameLevel(LFDQueueFrame:GetFrameLevel() + 9);	--This value also needs to be set when SetParent is called in LFDQueueFrameRandomCooldownFrame_Update.
 	
 	self:RegisterEvent("PLAYER_ENTERING_WORLD");	--For logging in/reloading ui
 	self:RegisterEvent("UNIT_AURA");	--The cooldown is still technically a debuff
 	self:RegisterEvent("GROUP_ROSTER_UPDATE");
 end
 
 function LFDQueueFrameRandomCooldownFrame_OnEvent(self, event, ...)
 	local arg1 = ...;
 	if ( event ~= "UNIT_AURA" or arg1 == "player" or strsub(arg1, 1, 5) == "party" ) then
 		LFDQueueFrameRandomCooldownFrame_Update();
 	end
 end
 
 function LFDQueueFrameRandomCooldownFrame_Update()
 	local cooldownFrame = LFDQueueFrameCooldownFrame;
 	local shouldShow = false;
 	local hasDeserter = false; --If we have deserter, we want to show this over the specific frame as well as the random frame.
 	
 	local deserterExpiration = GetLFGDeserterExpiration();
 	
 	local myExpireTime;
 	if ( deserterExpiration ) then
 		myExpireTime = deserterExpiration;
 		hasDeserter = true;
 	else
 		myExpireTime = GetLFGRandomCooldownExpiration();
 	end
 	
 	cooldownFrame.myExpirationTime = myExpireTime;
 	
 	for i = 1, GetNumSubgroupMembers() do
 		local nameLabel = _G["LFDQueueFrameCooldownFrameName"..i];
 		local statusLabel = _G["LFDQueueFrameCooldownFrameStatus"..i];
 		nameLabel:Show();
 		statusLabel:Show();
 		
 		local _, classFilename = UnitClass("party"..i);
 		local classColor = classFilename and RAID_CLASS_COLORS[classFilename] or NORMAL_FONT_COLOR;
 		nameLabel:SetFormattedText("|cff%.2x%.2x%.2x%s|r", classColor.r * 255, classColor.g * 255, classColor.b * 255, GetUnitName("party"..i, true));
 		
 		local gender = UnitSex("party"..i);
 		
 		if ( UnitHasLFGDeserter("party"..i) ) then
 			statusLabel:SetFormattedText(RED_FONT_COLOR_CODE.."%s|r", GetText("DESERTER", gender));
 			shouldShow = true;
 			hasDeserter = true;
 		elseif ( UnitHasLFGRandomCooldown("party"..i) ) then
 			statusLabel:SetFormattedText(RED_FONT_COLOR_CODE.."%s|r", GetText("ON_COOLDOWN", gender));
 			shouldShow = true;
 		else
 			statusLabel:SetFormattedText(GREEN_FONT_COLOR_CODE.."%s|r", GetText("READY", gender));
 		end
 	end
 	for i = GetNumSubgroupMembers() + 1, MAX_PARTY_MEMBERS do
 		local nameLabel = _G["LFDQueueFrameCooldownFrameName"..i];
 		local statusLabel = _G["LFDQueueFrameCooldownFrameStatus"..i];
 		nameLabel:Hide();
 		statusLabel:Hide();
 	end
 	
 	if ( GetNumSubgroupMembers() == 0 ) then
 		cooldownFrame.description:SetPoint("TOP", 0, -85);
 	else
 		cooldownFrame.description:SetPoint("TOP", 0, -30);
 	end
 	
 	if ( hasDeserter ) then
 		cooldownFrame:SetParent(LFDQueueFrame);
 		cooldownFrame:SetFrameLevel(LFDQueueFrame:GetFrameLevel() + 9);	--Setting a new parent changes the frame level, so we need to move it back to what we set in OnLoad.
 	else
 		cooldownFrame:SetParent(LFDQueueFrameRandom);	--If nobody has deserter, the dungeon cooldown only prevents us from queueing for random.
 		cooldownFrame:SetFrameLevel(LFDQueueFrame:GetFrameLevel() + 9);
 	end
 	
 	if ( myExpireTime and GetTime() < myExpireTime ) then
 		shouldShow = true;
 		if ( deserterExpiration ) then
 			cooldownFrame.description:SetText(LFG_DESERTER_YOU);
 		else
 			cooldownFrame.description:SetText(LFG_RANDOM_COOLDOWN_YOU);
 		end
 		cooldownFrame.time:SetText(SecondsToTime(ceil(myExpireTime - GetTime())));
 		cooldownFrame.time:Show();
 		
 		cooldownFrame:SetScript("OnUpdate", LFDQueueFrameRandomCooldownFrame_OnUpdate);
 	else
 		if ( hasDeserter ) then
 			cooldownFrame.description:SetText(LFG_DESERTER_OTHER);
 		else
 			cooldownFrame.description:SetText(LFG_RANDOM_COOLDOWN_OTHER);
 		end
 		cooldownFrame.time:Hide();
 		
 		cooldownFrame:SetScript("OnUpdate", nil);
 	end
 	
 	if ( shouldShow and not LFDQueueFramePartyBackfill:IsShown() ) then
 		cooldownFrame:Show();
 	else
 		cooldownFrame:Hide();
 	end
 end
 
 function LFDQueueFrameRandomCooldownFrame_OnUpdate(self, elapsed)
 	local timeRemaining = self.myExpirationTime - GetTime();
 	if ( timeRemaining > 0 ) then
 		self.time:SetText(SecondsToTime(ceil(timeRemaining)));
 	else
 		LFDQueueFrameRandomCooldownFrame_Update();
 	end
 end
 
 function LFDQueueFrameFindGroupButton_Update()
 	local mode, subMode = GetLFGMode(LE_LFG_CATEGORY_LFD);
 	if ( mode == "queued" or mode == "rolecheck" or mode == "proposal" or mode == "suspended" ) then
 		LFDQueueFrameFindGroupButton:SetText(LEAVE_QUEUE);
 	else
 		if ( IsInGroup() and GetNumGroupMembers() > 1 ) then
 			LFDQueueFrameFindGroupButton:SetText(JOIN_AS_PARTY);
 		else
 			LFDQueueFrameFindGroupButton:SetText(FIND_A_GROUP);
 		end
 	end
 	
 	if ( LFD_IsEmpowered() and mode ~= "proposal" and mode ~= "listed"  ) then --During the proposal, they must use the proposal buttons to leave the queue.
 		if ( (mode == "queued" or mode == "rolecheck" or mode == "suspended")	--The players can dequeue even if one of the two cover panels is up.
 			or (not LFDQueueFramePartyBackfill:IsVisible() and not LFDQueueFrameCooldownFrame:IsVisible()) ) then
 			LFDQueueFrameFindGroupButton:Enable();
 		else
 			LFDQueueFrameFindGroupButton:Disable();
 		end
 		LFRQueueFrameNoLFRWhileLFDLeaveQueueButton:Enable();
 	else
 		LFDQueueFrameFindGroupButton:Disable();
 	end
 	
 	if ( LFD_IsEmpowered() and mode ~= "proposal" and mode ~= "queued" and mode ~= "suspended" and mode ~= "rolecheck" ) then
 		LFDQueueFramePartyBackfillBackfillButton:Enable();
 	else
 		LFDQueueFramePartyBackfillBackfillButton:Disable();
 	end
 end
 
 LFDHiddenByCollapseList = {};
 function LFDQueueFrame_Update()
 	local mode, submode = GetLFGMode(LE_LFG_CATEGORY_LFD);
 	
 	local checkedList;
 	if ( LFD_IsEmpowered() and mode ~= "queued" and mode ~= "suspended") then
 		checkedList = LFGEnabledList;
 	else
 		checkedList = LFGQueuedForList[LE_LFG_CATEGORY_LFD];
 	end
 	
 	LFDDungeonList = GetLFDChoiceOrder(LFDDungeonList);
 	
 	LFGQueueFrame_UpdateLFGDungeonList(LFDDungeonList, LFDHiddenByCollapseList, checkedList, LFD_CURRENT_FILTER, LFD_MAX_SHOWN_LEVEL_DIFF);
 	
 	LFDQueueFrameSpecificList_Update();
 end
 
 LFD_CURRENT_FILTER = LFGList_DefaultFilterFunction;