diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp
index 4d694c1be053861e8485c22832f545bd7ec51bdf..c51ec91b66de43a0a29b8c9024b48eab9cbd065d 100644
--- a/indra/newview/llpanelvoiceeffect.cpp
+++ b/indra/newview/llpanelvoiceeffect.cpp
@@ -107,7 +107,7 @@ void LLPanelVoiceEffect::onCommitVoiceEffect()
 }
 
 // virtual
-void LLPanelVoiceEffect::onVoiceEffectChanged()
+void LLPanelVoiceEffect::onVoiceEffectChanged(bool new_effects)
 {
 	update();
 }
diff --git a/indra/newview/llpanelvoiceeffect.h b/indra/newview/llpanelvoiceeffect.h
index f1a746e288e6018354e51c48bc812c262e666640..3ecdcb0d8a5b6a0e35d5a39bebe10764b1c58957 100644
--- a/indra/newview/llpanelvoiceeffect.h
+++ b/indra/newview/llpanelvoiceeffect.h
@@ -56,7 +56,7 @@ private:
 	void update();
 
 	/// Called by voice effect provider when voice effect list is changed.
-	virtual void onVoiceEffectChanged();
+	virtual void onVoiceEffectChanged(bool new_effects);
 
 	// Fixed entries in the voice effect list
 	typedef enum e_voice_effect_combo_items
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 44da7bcf93eb6893b5b51fd8a57c3b9229375188..d4f1423f00f94d579901f998447932b2646fc84c 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -266,7 +266,7 @@ class LLVoiceEffectObserver
 {
 public:
 	virtual ~LLVoiceEffectObserver() { }
-	virtual void onVoiceEffectChanged() = 0;
+	virtual void onVoiceEffectChanged(bool new_effects) = 0;
 };
 
 typedef std::multimap<const std::string, const LLUUID, LLDictionaryLess> voice_effect_list_t;
@@ -290,6 +290,7 @@ public:
 	virtual bool setVoiceEffect(const LLUUID& id) = 0;
 	virtual const LLUUID getVoiceEffect() = 0;
 
+	virtual void refreshVoiceEffectLists(bool clear_lists) = 0;
 	virtual const voice_effect_list_t &getVoiceEffectList() const = 0;
 	virtual const voice_effect_list_t &getVoiceEffectTemplateList() const = 0;
 	//@}
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index a2ea21056d3dd09282621e47b3cb58d8eab958c1..aa2fa45b6d0840269b9a45eaf3e46d42ad787d85 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -337,10 +337,10 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 	mVoiceEnabled(false),
 	mWriteInProgress(false),
 
-	mLipSyncEnabled(false)
-
-
+	mLipSyncEnabled(false),
 
+	mVoiceFontsReceived(false),
+	mVoiceFontsNew(false)
 {	
 	mSpeakerVolume = scale_speaker_volume(0);
 
@@ -1220,13 +1220,12 @@ void LLVivoxVoiceClient::stateMachine()
 			{
 				// request the set of available voice fonts
 				setState(stateVoiceFontsWait);
-				accountGetSessionFontsSendMessage();
+				refreshVoiceEffectLists(true);
 			}
 			else
 			{
 				setState(stateVoiceFontsReceived);
 			}
-			accountGetTemplateFontsSendMessage(); // *TODO: Maybe better to do this only when opening preview rather than on login
 
 			// request the current set of block rules (we'll need them when updating the friends list)
 			accountListBlockRulesSendMessage();
@@ -6317,7 +6316,8 @@ LLVivoxVoiceClient::voiceFontEntry::voiceFontEntry(LLUUID& id) :
 	mFontIndex(0),
 	mHasExpired(false),
 	mFontType(VOICE_FONT_TYPE_NONE),
-	mFontStatus(VOICE_FONT_STATUS_NONE)
+	mFontStatus(VOICE_FONT_STATUS_NONE),
+	mIsNew(false)
 {
 }
 
@@ -6325,6 +6325,19 @@ LLVivoxVoiceClient::voiceFontEntry::~voiceFontEntry()
 {
 }
 
+void LLVivoxVoiceClient::refreshVoiceEffectLists(bool clear_lists)
+{
+	if (clear_lists)
+	{
+		mVoiceFontsReceived = false;
+		deleteVoiceFonts();
+		deleteVoiceFontTemplates();
+	}
+
+	accountGetSessionFontsSendMessage();
+	accountGetTemplateFontsSendMessage();
+}
+
 void LLVivoxVoiceClient::addVoiceFont(const S32 font_index,
 								 const std::string &name,
 								 const std::string &description,
@@ -6337,7 +6350,7 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index,
 	// Vivox SessionFontIDs are not guaranteed to remain the same between
 	// sessions or grids so use a UUID for the name.
 
-	// If received name is not a UUID, fudge one by hashing the name and type
+	// If received name is not a UUID, fudge one by hashing the name and type.
 	LLUUID font_id;
 	if (LLUUID::validate(name))
 	{
@@ -6353,38 +6366,36 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index,
 	voice_font_map_t& font_map = template_font ? mVoiceFontTemplateMap : mVoiceFontMap;
 	voice_effect_list_t& font_list = template_font ? mVoiceFontTemplateList : mVoiceFontList;
 
-	// Hopefully won't happen, but behave gracefully if there is a duplicate
-	// by Replacing the previous one unless this one has expired.
-	// *TODO: Should maybe check for the later expiry date if neither has
-	// expired, and favour user fonts over root fonts? But as we shouldn't
-	// have duplicates anyway, it's probably not worth the effort.
+	// Check whether we've seen this font before and create an entry for it if not.
 	voice_font_map_t::iterator iter = font_map.find(font_id);
-	bool duplicate = (iter != font_map.end());
-	if (duplicate)
+	bool new_font = (iter == font_map.end());
+	if (new_font)
 	{
-		LL_DEBUGS("Voice") << "Voice font " << font_index << " duplicates " << iter->second->mFontIndex << "!" << LL_ENDL;
-
-		if (!has_expired)
-		{
-			font = iter->second;
-		}
+		font = new voiceFontEntry(font_id);
 	}
 	else
 	{
-		font = new voiceFontEntry(font_id);
+		font = iter->second;
 	}
 
 	if (font)
 	{
 		font->mFontIndex = font_index;
 		// Use the description for the human readable name if available, as the
-		// "name" will probably be a UUID.
+		// "name" may be a UUID.
 		font->mName = description.empty() ? name : description;
 		font->mExpirationDate = expiration_date;
 		font->mHasExpired = has_expired;
 		font->mFontType = font_type;
 		font->mFontStatus = font_status;
 
+		 // Only flag it as a new font if we have already seen the font list.
+		if (!template_font && mVoiceFontsReceived && new_font)
+		{
+			font->mIsNew = true;
+			mVoiceFontsNew = true;
+		}
+
 		LL_DEBUGS("Voice") << (template_font?"Template: ":"") << font_id
 			<< " (" << font_index << ") : " << name << (has_expired?" (Expired)":"")
 			<< LL_ENDL;
@@ -6398,7 +6409,7 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index,
 			LL_DEBUGS("Voice") << "Unknown voice font status: " << font_status << LL_ENDL;
 		}
 
-		if (!duplicate)
+		if (new_font)
 		{
 			font_map.insert(voice_font_map_t::value_type(font->mID, font));
 			font_list.insert(voice_effect_list_t::value_type(font->mName, font->mID));
@@ -6507,7 +6518,10 @@ void LLVivoxVoiceClient::accountGetSessionFontsResponse(int statusCode, const st
 	{
 		setState(stateVoiceFontsReceived);
 	}
-	notifyVoiceFontObservers();
+	mVoiceFontsReceived = true;
+
+	notifyVoiceFontObservers(mVoiceFontsNew);
+	mVoiceFontsNew = false;
 }
 
 void LLVivoxVoiceClient::accountGetTemplateFontsResponse(int statusCode, const std::string &statusString)
@@ -6525,14 +6539,14 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceEffectObserver* observer)
 	mVoiceFontObservers.erase(observer);
 }
 
-void LLVivoxVoiceClient::notifyVoiceFontObservers()
+void LLVivoxVoiceClient::notifyVoiceFontObservers(bool new_fonts)
 {
 	for (voice_font_observer_set_t::iterator it = mVoiceFontObservers.begin();
 		 it != mVoiceFontObservers.end();
 		 )
 	{
 		LLVoiceEffectObserver* observer = *it;
-		observer->onVoiceEffectChanged();
+		observer->onVoiceEffectChanged(new_fonts);
 		// In case onVoiceEffectChanged() deleted an entry.
 		it = mVoiceFontObservers.upper_bound(observer);
 	}
@@ -6755,10 +6769,6 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)
 			{
 				LLVivoxVoiceClient::getInstance()->deleteAllAutoAcceptRules();
 			}
-			else if (!stricmp("SessionFonts", tag))
-			{
-				LLVivoxVoiceClient::getInstance()->deleteVoiceFonts();
-			}
 			else if (!stricmp("SessionFont", tag))
 			{
 				id = 0;
@@ -6769,10 +6779,6 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)
 				fontType = 0;
 				fontStatus = 0;
 			}
-			else if (!stricmp("TemplateFonts", tag))
-			{
-				LLVivoxVoiceClient::getInstance()->deleteVoiceFontTemplates();
-			}
 			else if (!stricmp("TemplateFont", tag))
 			{
 				id = 0;
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 4d18a897c7de0f32c16700e6da1ed4dcc9558404..fcf8eaf3e92a5a16dce564e99b1abeb0f60fdea7 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -241,6 +241,7 @@ public:
 	virtual bool setVoiceEffect(const LLUUID& id);
 	virtual const LLUUID getVoiceEffect();
 
+	virtual void refreshVoiceEffectLists(bool clear_lists);
 	virtual const voice_effect_list_t &getVoiceEffectList() const { return mVoiceFontList; };
 	virtual const voice_effect_list_t &getVoiceEffectTemplateList() const { return mVoiceFontTemplateList; };
 	//@}
@@ -848,7 +849,7 @@ private:
 	void accountGetTemplateFontsSendMessage();
 	void sessionSetVoiceFontSendMessage(sessionState *session);
 
-	void notifyVoiceFontObservers();
+	void notifyVoiceFontObservers(bool new_fonts = false);
 
 	typedef enum e_voice_font_type
 	{
@@ -878,8 +879,11 @@ private:
 		bool		mHasExpired;
 		S32			mFontType;
 		S32			mFontStatus;
+		bool		mIsNew;
 	};
 
+	bool mVoiceFontsReceived;
+	bool mVoiceFontsNew;
 	voice_effect_list_t	mVoiceFontList;
 	voice_effect_list_t	mVoiceFontTemplateList;