diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index e9f6288f44c94aa87469a1548885f3bbdb196a69..9ce8ce8d55db843777197d0b1c11540132d805a8 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -1022,6 +1022,20 @@ void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign a
 	}
 }
 
+void LLButton::setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment, const LLColor4& color)
+{
+	if (image_id.isNull())
+	{
+		mImageOverlay = NULL;
+	}
+	else
+	{
+		mImageOverlay = LLUI::getUIImageByID(image_id);
+		mImageOverlayAlignment = alignment;
+		mImageOverlayColor = color;
+	}
+}
+
 void LLButton::onMouseCaptureLost()
 {
 	resetMouseDownTimer();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 5e28b8cdff5a14e8fd02951c27f4565af35f40d1..cd149e31131b2ba57bd7ac413d24ba54376c8f23 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -200,6 +200,7 @@ class LLButton
 	void			setDisabledSelectedLabelColor( const LLColor4& c )	{ mDisabledSelectedLabelColor = c; }
 
 	void			setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
+	void 			setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
 	LLPointer<LLUIImage> getImageOverlay() { return mImageOverlay; }
 
 	void            autoResize();	// resize with label of current btn state 
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 327dd01612b18c3cf20f87faa2249d84da61434a..43c44f2253e649097dce30ddc6b914b04ea3188f 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1507,6 +1507,37 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L
 	}
 }
 
+void LLTabContainer::setTabImage(LLPanel* child, const LLUUID& image_id, const LLColor4& color)
+{
+	static LLUICachedControl<S32> tab_padding ("UITabPadding", 0);
+	LLTabTuple* tuple = getTabByPanel(child);
+	if( tuple )
+	{
+		tuple->mButton->setImageOverlay(image_id, LLFontGL::RIGHT, color);
+
+		if (!mIsVertical)
+		{
+			// remove current width from total tab strip width
+			mTotalTabWidth -= tuple->mButton->getRect().getWidth();
+
+			S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ?
+				tuple->mButton->getImageOverlay()->getImage()->getWidth(0) :
+				0;
+
+			tuple->mPadding = image_overlay_width;
+
+			tuple->mButton->setRightHPad(6);
+			tuple->mButton->reshape(llclamp(mFont->getWidth(tuple->mButton->getLabelSelected()) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth),
+									tuple->mButton->getRect().getHeight());
+			// add back in button width to total tab strip width
+			mTotalTabWidth += tuple->mButton->getRect().getWidth();
+
+			// tabs have changed size, might need to scroll to see current tab
+			updateMaxScrollPos();
+		}
+	}
+}
+
 void LLTabContainer::setTitle(const std::string& title)
 {	
 	if (mTitleBox)
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index 5d0f194bf965dc29713f43b2271efcde386cf51c..33c49e0d6faff7250349c2f20835fdbe0505a8b3 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -172,6 +172,7 @@ class LLTabContainer : public LLPanel
 	BOOL        getTabPanelFlashing(LLPanel* child);
 	void		setTabPanelFlashing(LLPanel* child, BOOL state);
 	void 		setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white);
+	void 		setTabImage(LLPanel* child, const LLUUID& img_id, const LLColor4& color = LLColor4::white);
 	void		setTitle( const std::string& title );
 	const std::string getPanelTitle(S32 index);
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 6cc985aef494dbefd9d63593336e734a84a86860..06a7b4a29c235fc5246821a1ad48e89b4550b05d 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -35,19 +35,22 @@
 
 #include "llimfloatercontainer.h"
 #include "llfloaterreg.h"
+#include "llimview.h"
+#include "llavatariconctrl.h"
+#include "llagent.h"
 
 //
 // LLIMFloaterContainer
 //
 LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
-:	LLMultiFloater(seed),
-	mActiveVoiceFloater(NULL)
+:	LLMultiFloater(seed)
 {
 	mAutoResize = FALSE;
 }
 
 LLIMFloaterContainer::~LLIMFloaterContainer()
 {
+	LLGroupMgr::getInstance()->removeObserver(this);
 }
 
 BOOL LLIMFloaterContainer::postBuild()
@@ -87,13 +90,84 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 
 	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
 
-	// make sure active voice icon shows up for new tab
-	if (floaterp == mActiveVoiceFloater)
+	LLUUID session_id = floaterp->getKey();
+
+	if(gAgent.isInGroup(session_id))
+	{
+		mSessions[session_id] = floaterp;
+		mID = session_id;
+		mGroupID.push_back(session_id);
+		LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(session_id);
+		LLGroupMgr* gm = LLGroupMgr::getInstance();
+		gm->addObserver(this);
+
+		if (group_data && group_data->mInsigniaID.notNull())
+		{
+			mTabContainer->setTabImage(get_ptr_in_map(mSessions, session_id), group_data->mInsigniaID);
+		}
+		else
+		{
+			gm->sendGroupPropertiesRequest(session_id);
+		}
+	}
+	else
+	{
+		LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id);
+		LLAvatarPropertiesProcessor& app = LLAvatarPropertiesProcessor::instance();
+		app.addObserver(avatar_id, this);
+		floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, avatar_id));
+		mSessions[avatar_id] = floaterp;
+
+		LLUUID* icon_id_ptr = LLAvatarIconIDCache::getInstance()->get(avatar_id);
+		if(!icon_id_ptr)
+		{
+			app.sendAvatarPropertiesRequest(avatar_id);
+		}
+		else
+		{
+			mTabContainer->setTabImage(floaterp, *icon_id_ptr);
+		}
+	}
+}
+
+void LLIMFloaterContainer::processProperties(void* data, enum EAvatarProcessorType type)
+{
+	if (APT_PROPERTIES == type)
+	{
+			LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
+			if (avatar_data)
+			{
+				LLUUID avatar_id = avatar_data->avatar_id;
+				if(avatar_data->image_id != *LLAvatarIconIDCache::getInstance()->get(avatar_id))
+				{
+					LLAvatarIconIDCache::getInstance()->add(avatar_id,avatar_data->image_id);
+				}
+				mTabContainer->setTabImage(get_ptr_in_map(mSessions, avatar_id), avatar_data->image_id);
+			}
+	}
+}
+
+void LLIMFloaterContainer::changed(LLGroupChange gc)
+{
+	if (GC_PROPERTIES == gc)
 	{
-		mTabContainer->setTabImage(floaterp, "active_voice_tab.tga");	
+		for(groupIDs_t::iterator it = mGroupID.begin(); it!=mGroupID.end(); it++)
+		{
+			LLUUID group_id = *it;
+			LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(group_id);
+			if (group_data && group_data->mInsigniaID.notNull())
+			{
+				mTabContainer->setTabImage(get_ptr_in_map(mSessions, group_id), group_data->mInsigniaID);
+			}
+		}
 	}
 }
 
+void LLIMFloaterContainer::onCloseFloater(LLUUID id)
+{
+	LLAvatarPropertiesProcessor::instance().removeObserver(id, this);
+}
+
 LLIMFloaterContainer* LLIMFloaterContainer::findInstance()
 {
 	return LLFloaterReg::findTypedInstance<LLIMFloaterContainer>("im_container");
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index d4a542dfc22c449da8d184b3ca3254cb422b5175..1333b098bc28143d13c0d9240f9873239471441e 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -33,12 +33,17 @@
 #ifndef LL_LLIMFLOATERCONTAINER_H
 #define LL_LLIMFLOATERCONTAINER_H
 
+#include <map>
+#include <vector>
+
 #include "llfloater.h"
 #include "llmultifloater.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llgroupmgr.h"
 
 class LLTabContainer;
 
-class LLIMFloaterContainer : public LLMultiFloater
+class LLIMFloaterContainer : public LLMultiFloater, public LLAvatarPropertiesObserver, public LLGroupMgrObserver
 {
 public:
 	LLIMFloaterContainer(const LLSD& seed);
@@ -51,15 +56,23 @@ class LLIMFloaterContainer : public LLMultiFloater
 								BOOL select_added_floater, 
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
 
+	void processProperties(void* data, EAvatarProcessorType type);
+	void changed(LLGroupChange gc);
+
 	static LLFloater* getCurrentVoiceFloater();
 
 	static LLIMFloaterContainer* findInstance();
 
 	static LLIMFloaterContainer* getInstance();
 
-protected:
-	
-	LLFloater* mActiveVoiceFloater;
+private:
+	typedef std::map<LLUUID,LLPanel*> avatarID_panel_map_t;
+	avatarID_panel_map_t mSessions;
+
+	typedef std::vector<LLUUID> groupIDs_t;
+	groupIDs_t mGroupID;
+
+	void onCloseFloater(LLUUID avatar_id);
 };
 
 #endif // LL_LLIMFLOATERCONTAINER_H