diff --git a/.hgtags b/.hgtags
index 74f20668861182485ea8f3cf1f47b920d6c25392..95194e8df59c2c28525c21b366927b43228a4e67 100755
--- a/.hgtags
+++ b/.hgtags
@@ -360,3 +360,4 @@ e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243
 73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4
 5e4e4128b256525bafc07a62e35ae8527aaa9c9d DRTVWR-241
 f1d3b3fcab28ed9ea532bf50db0ba96f5c8cc8e9 DRTVWR-232
+4918b150e75df6b516fb6c2616d32043fa6b4cac DRTVWR-245
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 32d9d8bfc3d6cd8ed827fc3a0d81dc89415653a1..700525e1fa1924eafc92308c3228c967b4277a59 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -334,8 +334,9 @@ void LLAvatarNameCache::requestNamesViaCapability()
 	// http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0
 	//
 	// Apache can handle URLs of 4096 chars, but let's be conservative
-	const U32 NAME_URL_MAX = 4096;
-	const U32 NAME_URL_SEND_THRESHOLD = 3000;
+	static const U32 NAME_URL_MAX = 4096;
+	static const U32 NAME_URL_SEND_THRESHOLD = 3500;
+
 	std::string url;
 	url.reserve(NAME_URL_MAX);
 
@@ -343,10 +344,12 @@ void LLAvatarNameCache::requestNamesViaCapability()
 	agent_ids.reserve(128);
 	
 	U32 ids = 0;
-	ask_queue_t::const_iterator it = sAskQueue.begin();
-	for ( ; it != sAskQueue.end(); ++it)
+	ask_queue_t::const_iterator it;
+	while(!sAskQueue.empty())
 	{
+		it = sAskQueue.begin();
 		const LLUUID& agent_id = *it;
+		sAskQueue.erase(it);
 
 		if (url.empty())
 		{
@@ -369,27 +372,17 @@ void LLAvatarNameCache::requestNamesViaCapability()
 
 		if (url.size() > NAME_URL_SEND_THRESHOLD)
 		{
-			LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability first "
-									 << ids << " ids"
-									 << LL_ENDL;
-			LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
-			url.clear();
-			agent_ids.clear();
+			break;
 		}
 	}
 
 	if (!url.empty())
 	{
-		LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability all "
+		LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested "
 								 << ids << " ids"
 								 << LL_ENDL;
 		LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
-		url.clear();
-		agent_ids.clear();
 	}
-
-	// We've moved all asks to the pending request queue
-	sAskQueue.clear();
 }
 
 void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
@@ -416,12 +409,15 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
 
 void LLAvatarNameCache::requestNamesViaLegacy()
 {
+	static const S32 MAX_REQUESTS = 100;
 	F64 now = LLFrameTimer::getTotalSeconds();
 	std::string full_name;
-	ask_queue_t::const_iterator it = sAskQueue.begin();
-	for (; it != sAskQueue.end(); ++it)
+	ask_queue_t::const_iterator it;
+	for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests)
 	{
+		it = sAskQueue.begin();
 		const LLUUID& agent_id = *it;
+		sAskQueue.erase(it);
 
 		// Mark as pending first, just in case the callback is immediately
 		// invoked below.  This should never happen in practice.
@@ -433,10 +429,6 @@ void LLAvatarNameCache::requestNamesViaLegacy()
 			boost::bind(&LLAvatarNameCache::legacyNameCallback,
 				_1, _2, _3));
 	}
-
-	// We've either answered immediately or moved all asks to the
-	// pending queue
-	sAskQueue.clear();
 }
 
 void LLAvatarNameCache::initClass(bool running)
@@ -513,11 +505,11 @@ void LLAvatarNameCache::idle()
 	// *TODO: Possibly re-enabled this based on People API load measurements
 	// 100 ms is the threshold for "user speed" operations, so we can
 	// stall for about that long to batch up requests.
-	//const F32 SECS_BETWEEN_REQUESTS = 0.1f;
-	//if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS))
-	//{
-	//	return;
-	//}
+	const F32 SECS_BETWEEN_REQUESTS = 0.1f;
+	if (!sRequestTimer.hasExpired())
+	{
+		return;
+	}
 
 	if (!sAskQueue.empty())
 	{
@@ -532,6 +524,12 @@ void LLAvatarNameCache::idle()
         }
 	}
 
+	if (sAskQueue.empty())
+	{
+		// cleared the list, reset the request timer.
+		sRequestTimer.resetWithExpiry(SECS_BETWEEN_REQUESTS);
+	}
+
     // erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME
     eraseUnrefreshed();
 }
@@ -743,12 +741,6 @@ void LLAvatarNameCache::erase(const LLUUID& agent_id)
 	sCache.erase(agent_id);
 }
 
-void LLAvatarNameCache::fetch(const LLUUID& agent_id)
-{
-	// re-request, even if request is already pending
-	sAskQueue.insert(agent_id);
-}
-
 void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name)
 {
 	// *TODO: update timestamp if zero?
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 064942fe53d2c4a206a83f52185094b7e88ba450..79f170f7c8718b6485445f6c308c0dbcfbd9017a 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -86,10 +86,6 @@ namespace LLAvatarNameCache
     /// Provide some fallback for agents that return errors
 	void handleAgentError(const LLUUID& agent_id);
 
-	// Force a re-fetch of the most recent data, but keep the current
-	// data in cache
-	void fetch(const LLUUID& agent_id);
-
 	void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
 
 	// Compute name expiration time from HTTP Cache-Control header,
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 806d2ef3f65d6b1e0aa6993e537fc2e42eaa8414..41e5d74042f112f8eae50ea0af3c250442d21e5c 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -563,8 +563,7 @@ void LLComboBox::showList()
 	S32 min_width = getRect().getWidth();
 	S32 max_width = llmax(min_width, MAX_COMBO_WIDTH);
 	// make sure we have up to date content width metrics
-	mList->calcColumnWidths();
-	S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width);
+	S32 list_width = llclamp(mList->calcMaxContentWidth(), min_width, max_width);
 
 	if (mListPosition == BELOW)
 	{
diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp
index 07a6dfaa102c92a6cd9ad6f0ab73209bb498587d..af124d9826a5cc335ef4f6519b4e7cfeab5f2105 100644
--- a/indra/llui/llscrolllistcolumn.cpp
+++ b/indra/llui/llscrolllistcolumn.cpp
@@ -98,6 +98,7 @@ BOOL LLScrollColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask)
 	if (canResize() && mResizeBar->getRect().pointInRect(x, y))
 	{
 		// reshape column to max content width
+		mColumn->mParentCtrl->calcMaxContentWidth();
 		LLRect column_rect = getRect();
 		column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth;
 		setShape(column_rect, true);
@@ -127,6 +128,8 @@ LLView*	LLScrollColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& m
 
 	LLRect snap_rect = getSnapRect();
 
+	mColumn->mParentCtrl->calcMaxContentWidth();
+
 	S32 snap_delta = mColumn->mMaxContentWidth - snap_rect.getWidth();
 
 	// x coord growing means column growing, so same signs mean we're going in right direction
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index b3499693dd15433b7450dd6f9ed17252f68f1618..3e0653e9a483decf905f64d87f5c8ef0ddfbdc9e 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -35,6 +35,7 @@
 #include "llboost.h"
 //#include "indra_constants.h"
 
+#include "llavatarnamecache.h"
 #include "llcheckboxctrl.h"
 #include "llclipboard.h"
 #include "llfocusmgr.h"
@@ -158,15 +159,14 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	mMouseWheelOpaque(p.mouse_wheel_opaque),
 	mPageLines(p.page_lines),
 	mMaxSelectable(0),
-	mAllowKeyboardMovement(TRUE),
+	mAllowKeyboardMovement(true),
 	mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
-	mCommitOnSelectionChange(FALSE),
-	mSelectionChanged(FALSE),
-	mNeedsScroll(FALSE),
-	mCanSelect(TRUE),
-	mColumnsDirty(FALSE),
+	mCommitOnSelectionChange(false),
+	mSelectionChanged(false),
+	mNeedsScroll(false),
+	mCanSelect(true),
+	mColumnsDirty(false),
 	mMaxItemCount(INT_MAX), 
-	mMaxContentWidth(0),
 	mBorderThickness( 2 ),
 	mOnDoubleClickCallback( NULL ),
 	mOnMaximumSelectCallback( NULL ),
@@ -180,7 +180,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	mTotalStaticColumnWidth(0),
 	mTotalColumnPadding(0),
 	mSorted(false),
-	mDirty(FALSE),
+	mDirty(false),
 	mOriginalSelection(-1),
 	mLastSelected(NULL),
 	mHeadingHeight(p.heading_height),
@@ -356,7 +356,7 @@ void LLScrollListCtrl::clearRows()
 	mScrollLines = 0;
 	mLastSelected = NULL;
 	updateLayout();
-	mDirty = FALSE; 
+	mDirty = false; 
 }
 
 
@@ -591,15 +591,42 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
 // NOTE: This is *very* expensive for large lists, especially when we are dirtying the list every frame
 //  while receiving a long list of names.
 // *TODO: Use bookkeeping to make this an incramental cost with item additions
-void LLScrollListCtrl::calcColumnWidths()
+S32 LLScrollListCtrl::calcMaxContentWidth()
 {
 	const S32 HEADING_TEXT_PADDING = 25;
 	const S32 COLUMN_TEXT_PADDING = 10;
 
-	mMaxContentWidth = 0;
-
 	S32 max_item_width = 0;
 
+	ordered_columns_t::iterator column_itor;
+	for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor)
+	{
+		LLScrollListColumn* column = *column_itor;
+		if (!column) continue;
+
+		if (mColumnWidthsDirty)
+		{
+			mColumnWidthsDirty = false;
+			// update max content width for this column, by looking at all items
+			column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
+			item_list::iterator iter;
+			for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+			{
+				LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex);
+				if (!cellp) continue;
+
+				column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth);
+			}
+		}
+		max_item_width += column->mMaxContentWidth;
+	}
+
+	return max_item_width;
+}
+
+bool LLScrollListCtrl::updateColumnWidths()
+{
+	bool width_changed = false;
 	ordered_columns_t::iterator column_itor;
 	for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor)
 	{
@@ -617,23 +644,13 @@ void LLScrollListCtrl::calcColumnWidths()
 			new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns;
 		}
 
-		column->setWidth(new_width);
-
-		// update max content width for this column, by looking at all items
-		column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
-		item_list::iterator iter;
-		for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+		if (column->getWidth() != new_width)
 		{
-			LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex);
-			if (!cellp) continue;
-
-			column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth);
+			column->setWidth(new_width);
+			width_changed = true;
 		}
-
-		max_item_width += column->mMaxContentWidth;
 	}
-
-	mMaxContentWidth = max_item_width;
+	return width_changed;
 }
 
 const S32 SCROLL_LIST_ROW_PAD = 2;
@@ -669,7 +686,12 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp)
 
 void LLScrollListCtrl::updateColumns()
 {
-	calcColumnWidths();
+	if (!mColumnsDirty)
+		return;
+
+	mColumnsDirty = false;
+
+	bool columns_changed_width = updateColumnWidths();
 
 	// update column headers
 	std::vector<LLScrollListColumn*>::iterator column_ordered_it;
@@ -718,20 +740,22 @@ void LLScrollListCtrl::updateColumns()
 	}
 
 	// propagate column widths to individual cells
-	item_list::iterator iter;
-	for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+	if (columns_changed_width)
 	{
-		LLScrollListItem *itemp = *iter;
-		S32 num_cols = itemp->getNumColumns();
-		S32 i = 0;
-		for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
+		item_list::iterator iter;
+		for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
 		{
-			if (i >= (S32)mColumnsIndexed.size()) break;
+			LLScrollListItem *itemp = *iter;
+			S32 num_cols = itemp->getNumColumns();
+			S32 i = 0;
+			for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
+			{
+				if (i >= (S32)mColumnsIndexed.size()) break;
 
-			cell->setWidth(mColumnsIndexed[i]->getWidth());
+				cell->setWidth(mColumnsIndexed[i]->getWidth());
+			}
 		}
 	}
-
 }
 
 void LLScrollListCtrl::setHeadingHeight(S32 heading_height)
@@ -772,7 +796,7 @@ BOOL LLScrollListCtrl::selectFirstItem()
 		{
 			deselectItem(itemp);
 		}
-		first_item = FALSE;
+		first_item = false;
 	}
 	if (mCommitOnSelectionChange)
 	{
@@ -1406,17 +1430,23 @@ void LLScrollListCtrl::drawItems()
 
 		S32 cur_y = y;
 		
-		S32 line = 0;
 		S32 max_columns = 0;
 
 		LLColor4 highlight_color = LLColor4::white;
 		static LLUICachedControl<F32> type_ahead_timeout ("TypeAheadTimeout", 0);
 		highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f);
 
+		S32 first_line = mScrollLines;
+		S32 last_line = llmin((S32)mItemList.size() - 1, mScrollLines + getLinesPerPage());
+
+		if (first_line >= mItemList.size())
+		{
+			return;
+		}
 		item_list::iterator iter;
-		for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+		for (S32 line = first_line; line <= last_line; line++)
 		{
-			LLScrollListItem* item = *iter;
+			LLScrollListItem* item = mItemList[line];
 			
 			item_rect.setOriginAndSize( 
 				x, 
@@ -1480,7 +1510,6 @@ void LLScrollListCtrl::drawItems()
 
 				cur_y -= mLineHeight;
 			}
-			line++;
 		}
 	}
 }
@@ -1496,7 +1525,7 @@ void LLScrollListCtrl::draw()
 	if (mNeedsScroll)
 	{
 		scrollToShowSelected();
-		mNeedsScroll = FALSE;
+		mNeedsScroll = false;
 	}
 	LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0);
 	// Draw background
@@ -1507,11 +1536,7 @@ void LLScrollListCtrl::draw()
 		gl_rect_2d(background, getEnabled() ? mBgWriteableColor.get() % alpha : mBgReadOnlyColor.get() % alpha );
 	}
 
-	if (mColumnsDirty)
-	{
-		updateColumns();
-		mColumnsDirty = FALSE;
-	}
+	updateColumns();
 
 	getChildView("comment_text")->setVisible(mItemList.empty());
 
@@ -1719,7 +1744,7 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
 		setFocus(TRUE);
 
 		// clear selection changed flag because user is starting a selection operation
-		mSelectionChanged = FALSE;
+		mSelectionChanged = false;
 
 		handleClick(x, y, mask);
 	}
@@ -1737,15 +1762,15 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
 		if(mask == MASK_NONE)
 		{
 			selectItemAt(x, y, mask);
-			mNeedsScroll = TRUE;
+			mNeedsScroll = true;
 		}
 	}
 
 	// always commit when mouse operation is completed inside list
 	if (mItemListRect.pointInRect(x,y))
 	{
-		mDirty |= mSelectionChanged;
-		mSelectionChanged = FALSE;
+		mDirty = mDirty || mSelectionChanged;
+		mSelectionChanged = false;
 		onCommit();
 	}
 
@@ -1805,7 +1830,9 @@ void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group)
 	}
 	else
 	{
-		gCacheName->getFullName(LLUUID(id), name);
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(LLUUID(id), &av_name);
+		name = av_name.getLegacyName();
 	}
 	LLUrlAction::copyURLToClipboard(name);
 }
@@ -1859,7 +1886,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask)
 		{
 			selectItemAt(x, y, mask);
 			gFocusMgr.setMouseCapture(this);
-			mNeedsScroll = TRUE;
+			mNeedsScroll = true;
 		}
 		
 		// propagate state of cell to rest of selected column
@@ -1888,7 +1915,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask)
 		// treat this as a normal single item selection
 		selectItemAt(x, y, mask);
 		gFocusMgr.setMouseCapture(this);
-		mNeedsScroll = TRUE;
+		mNeedsScroll = true;
 		// do not eat click (allow double click callback)
 		return FALSE;
 	}
@@ -1994,7 +2021,7 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
 		if(mask == MASK_NONE)
 		{
 			selectItemAt(x, y, mask);
-			mNeedsScroll = TRUE;
+			mNeedsScroll = true;
 		}
 	}
 	else 
@@ -2041,7 +2068,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
 				{
 					// commit implicit in call
 					selectPrevItem(FALSE);
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					handled = TRUE;
 				}
 				break;
@@ -2050,7 +2077,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
 				{
 					// commit implicit in call
 					selectNextItem(FALSE);
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					handled = TRUE;
 				}
 				break;
@@ -2058,7 +2085,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
 				if (mAllowKeyboardMovement || hasFocus())
 				{
 					selectNthItem(getFirstSelectedIndex() - (mScrollbar->getPageSize() - 1));
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					if (mCommitOnKeyboardMovement
 						&& !mCommitOnSelectionChange) 
 					{
@@ -2071,7 +2098,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
 				if (mAllowKeyboardMovement || hasFocus())
 				{
 					selectNthItem(getFirstSelectedIndex() + (mScrollbar->getPageSize() - 1));
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					if (mCommitOnKeyboardMovement
 						&& !mCommitOnSelectionChange) 
 					{
@@ -2084,7 +2111,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
 				if (mAllowKeyboardMovement || hasFocus())
 				{
 					selectFirstItem();
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					if (mCommitOnKeyboardMovement
 						&& !mCommitOnSelectionChange) 
 					{
@@ -2097,7 +2124,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
 				if (mAllowKeyboardMovement || hasFocus())
 				{
 					selectNthItem(getItemCount() - 1);
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					if (mCommitOnKeyboardMovement
 						&& !mCommitOnSelectionChange) 
 					{
@@ -2136,7 +2163,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
 				}
 				else if (selectItemByPrefix(wstring_to_utf8str(mSearchString), FALSE))
 				{
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					// update search string only on successful match
 					mSearchTimer.reset();
 
@@ -2177,7 +2204,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
 	if (selectItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE))
 	{
 		// update search string only on successful match
-		mNeedsScroll = TRUE;
+		mNeedsScroll = true;
 		mSearchString += uni_char;
 		mSearchTimer.reset();
 
@@ -2223,7 +2250,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
 				if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char)
 				{
 					selectItem(item);
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					cellp->highlightText(0, 1);
 					mSearchTimer.reset();
 
@@ -2294,7 +2321,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it
 		}
 		itemp->setSelected(TRUE);
 		mLastSelected = itemp;
-		mSelectionChanged = TRUE;
+		mSelectionChanged = true;
 	}
 }
 
@@ -2315,7 +2342,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp)
 		{
 			cellp->highlightText(0, 0);	
 		}
-		mSelectionChanged = TRUE;
+		mSelectionChanged = true;
 	}
 }
 
@@ -2323,7 +2350,7 @@ void LLScrollListCtrl::commitIfChanged()
 {
 	if (mSelectionChanged)
 	{
-		mDirty = TRUE;
+		mDirty = true;
 		mSelectionChanged = FALSE;
 		onCommit();
 	}
@@ -2434,7 +2461,8 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending)
 
 void LLScrollListCtrl::dirtyColumns() 
 { 
-	mColumnsDirty = TRUE; 
+	mColumnsDirty = true; 
+	mColumnWidthsDirty = true;
 
 	// need to keep mColumnsIndexed up to date
 	// just in case someone indexes into it immediately
@@ -3003,7 +3031,7 @@ void LLScrollListCtrl::resetDirty()
 void LLScrollListCtrl::onFocusReceived()
 {
 	// forget latent selection changes when getting focus
-	mSelectionChanged = FALSE;
+	mSelectionChanged = false;
 	LLUICtrl::onFocusReceived();
 }
 
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index e83794e173130f6ec145adf8617595aad9f81969..38450b6313baa4a330e516f1b554e9dc65607ef6 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -343,8 +343,8 @@ public:
 	static void onClickColumn(void *userdata);
 
 	virtual void updateColumns();
-	void calcColumnWidths();
-	S32 getMaxContentWidth() { return mMaxContentWidth; }
+	S32 calcMaxContentWidth();
+	bool updateColumnWidths();
 
 	void setHeadingHeight(S32 heading_height);
 	/**
@@ -440,16 +440,17 @@ private:
 	S32				mHeadingHeight;	// the height of the column header buttons, if visible
 	U32				mMaxSelectable; 
 	LLScrollbar*	mScrollbar;
-	BOOL 			mAllowMultipleSelection;
-	BOOL			mAllowKeyboardMovement;
-	BOOL			mCommitOnKeyboardMovement;
-	BOOL			mCommitOnSelectionChange;
-	BOOL			mSelectionChanged;
-	BOOL			mNeedsScroll;
-	BOOL			mMouseWheelOpaque;
-	BOOL			mCanSelect;
-	const BOOL		mDisplayColumnHeaders;
-	BOOL			mColumnsDirty;
+	bool 			mAllowMultipleSelection;
+	bool			mAllowKeyboardMovement;
+	bool			mCommitOnKeyboardMovement;
+	bool			mCommitOnSelectionChange;
+	bool			mSelectionChanged;
+	bool			mNeedsScroll;
+	bool			mMouseWheelOpaque;
+	bool			mCanSelect;
+	bool			mDisplayColumnHeaders;
+	bool			mColumnsDirty;
+	bool			mColumnWidthsDirty;
 
 	mutable item_list	mItemList;
 
@@ -458,7 +459,6 @@ private:
 	S32				mMaxItemCount; 
 
 	LLRect			mItemListRect;
-	S32				mMaxContentWidth;
 	S32             mColumnPadding;
 
 	BOOL			mBackgroundVisible;
@@ -498,7 +498,7 @@ private:
 	typedef std::map<std::string, LLScrollListColumn*> column_map_t;
 	column_map_t mColumns;
 
-	BOOL			mDirty;
+	bool			mDirty;
 	S32				mOriginalSelection;
 
 	ContextMenuType mContextMenuType;
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 54843227b74c4f99263a5dcbd4d70d7dfba9629a..ad9bec9f61e1e10d9b2e51de5a1c31662b5fa133 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1549,16 +1549,18 @@ void LLView::screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* l
 
 void LLView::localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const
 {
-	*screen_x = local_x + getRect().mLeft;
-	*screen_y = local_y + getRect().mBottom;
+	*screen_x = local_x;
+	*screen_y = local_y;
 
 	const LLView* cur = this;
-	while( cur->mParentView )
+	do
 	{
+		LLRect cur_rect = cur->getRect();
+		*screen_x += cur_rect.mLeft;
+		*screen_y += cur_rect.mBottom;
 		cur = cur->mParentView;
-		*screen_x += cur->getRect().mLeft;
-		*screen_y += cur->getRect().mBottom;
 	}
+	while( cur );
 }
 
 void LLView::screenRectToLocal(const LLRect& screen, LLRect* local) const
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 472c26e22da16fcd1cf1aa27ff9a2afdb1271fed..b0fbad33b004a9166cb291b96d8c875a500b43d3 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -68,7 +68,7 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
 {}
 
 // public
-void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
+LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
 								 BOOL enabled, const std::string& suffix)
 {
 	//llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl;
@@ -78,7 +78,7 @@ void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
 	item.enabled = enabled;
 	item.target = INDIVIDUAL;
 
-	addNameItemRow(item, pos, suffix);
+	return addNameItemRow(item, pos, suffix);
 }
 
 // virtual, public
@@ -204,7 +204,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
 {
 	BOOL handled = FALSE;
 	S32 column_index = getColumnIndexFromOffset(x);
-	LLScrollListItem* hit_item = hitItem(x, y);
+	LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y));
 	if (hit_item
 		&& column_index == mNameColumnIndex)
 	{
@@ -228,7 +228,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
 				LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 );
 
 				// Should we show a group or an avatar inspector?
-				bool is_group = hit_item->getValue()["is_group"].asBoolean();
+				bool is_group = hit_item->isGroup();
 
 				LLToolTip::Params params;
 				params.background_visible( false );
@@ -271,10 +271,10 @@ void LLNameListCtrl::addGroupNameItem(LLNameListCtrl::NameItem& item, EAddPositi
 	addNameItemRow(item, pos);
 }
 
-void LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos)
+LLScrollListItem* LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos)
 {
 	item.target = INDIVIDUAL;
-	addNameItemRow(item, pos);
+	return addNameItemRow(item, pos);
 }
 
 LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata)
@@ -293,19 +293,12 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
 	const std::string& suffix)
 {
 	LLUUID id = name_item.value().asUUID();
-	LLNameListItem* item = NULL;
-
-	// Store item type so that we can invoke the proper inspector.
-	// *TODO Vadim: Is there a more proper way of storing additional item data?
-	{
-		LLNameListCtrl::NameItem item_p(name_item);
-		item_p.value = LLSD().with("uuid", id).with("is_group", name_item.target() == GROUP);
-		item = new LLNameListItem(item_p);
-		LLScrollListCtrl::addRow(item, item_p, pos);
-	}
+	LLNameListItem* item = new LLNameListItem(name_item,name_item.target() == GROUP);
 
 	if (!item) return NULL;
 
+	LLScrollListCtrl::addRow(item, name_item, pos);
+
 	// use supplied name by default
 	std::string fullname = name_item.name;
 	switch(name_item.target)
@@ -411,7 +404,7 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
 			setNeedsSort();
 		}
 	}
-
+	
 	dirtyColumns();
 }
 
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index ba85e77c656849eed058386bf01b639ecc3c5f2f..3ac0565761f6678c283fb4cc10de266d76344cce 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -42,14 +42,24 @@ class LLAvatarName;
 class LLNameListItem : public LLScrollListItem, public LLHandleProvider<LLNameListItem>
 {
 public:
-	LLUUID	getUUID() const		{ return getValue()["uuid"].asUUID(); }
+	bool isGroup() const { return mIsGroup; }
+	void setIsGroup(bool is_group) { mIsGroup = is_group; }
+
 protected:
 	friend class LLNameListCtrl;
 
 	LLNameListItem( const LLScrollListItem::Params& p )
-	:	LLScrollListItem(p)
+	:	LLScrollListItem(p), mIsGroup(false)
+	{
+	}
+
+	LLNameListItem( const LLScrollListItem::Params& p, bool is_group )
+	:	LLScrollListItem(p), mIsGroup(is_group)
 	{
 	}
+
+private:
+	bool mIsGroup;
 };
 
 
@@ -105,9 +115,9 @@ protected:
 public:
 	// Add a user to the list by name.  It will be added, the name
 	// requested from the cache, and updated as necessary.
-	void addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM,
+	LLScrollListItem* addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM,
 					 BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null);
-	void addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);
+	LLScrollListItem* addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);
 
 	/*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
 	LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null);
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index b494c7d403deb7e633aa347abc485e255bb75439..0e6f5b89247d1c4f9fa9385bc2de2b5ab98f553a 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -33,7 +33,7 @@
 
 class LLOfferInfo;
 
-const S32 UPDATE_MEMBERS_PER_FRAME = 500;
+const F32 UPDATE_MEMBERS_SECONDS_PER_FRAME = 0.005; // 5ms
 
 // Forward declares
 class LLPanelGroupTab;
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index f6ce7de47e09d608381d7fc066d0f349d2559d0d..51b4d2ea65f51a96221a8574ad08fc739935a70e 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -28,8 +28,10 @@
 
 #include "llpanelgroupgeneral.h"
 
-#include "lluictrlfactory.h"
+#include "llavatarnamecache.h"
 #include "llagent.h"
+#include "llsdparam.h"
+#include "lluictrlfactory.h"
 #include "roles_constants.h"
 
 // UI elements
@@ -668,6 +670,7 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
 		{
 			mMemberProgress = gdatap->mMembers.begin();
 			mPendingMemberUpdate = TRUE;
+			mUdpateSessionID.generate();
 
 			sSDTime = 0.0f;
 			sElementTime = 0.0f;
@@ -696,76 +699,45 @@ void LLPanelGroupGeneral::updateMembers()
 
 	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
 
-	if (!mListVisibleMembers || !gdatap 
+	if (!mListVisibleMembers 
+		|| !gdatap 
 		|| !gdatap->isMemberDataComplete()
 		|| gdatap->mMembers.empty())
 	{
 		return;
 	}
 
-	static LLTimer all_timer;
-	static LLTimer sd_timer;
-	static LLTimer element_timer;
+	LLTimer update_time;
+	update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME);
 
-	all_timer.reset();
-	S32 i = 0;
+	LLAvatarName av_name;
 
-	for( ; mMemberProgress != gdatap->mMembers.end() && i<UPDATE_MEMBERS_PER_FRAME; 
-			++mMemberProgress, ++i)
+	for( ; mMemberProgress != gdatap->mMembers.end() && !update_time.hasExpired(); 
+			++mMemberProgress)
 	{
-		lldebugs << "Adding " << mMemberProgress->first << ", " << mMemberProgress->second->getTitle() << llendl;
 		LLGroupMemberData* member = mMemberProgress->second;
 		if (!member)
 		{
 			continue;
 		}
-		// Owners show up in bold.
-		std::string style = "NORMAL";
-		sd_timer.reset();
-		LLSD row;
-		row["id"] = member->getID();
-
-		row["columns"][0]["column"] = "name";
-		row["columns"][0]["font"]["name"] = "SANSSERIF_SMALL";
-		row["columns"][0]["font"]["style"] = style;
-		// value is filled in by name list control
-
-		row["columns"][1]["column"] = "title";
-		row["columns"][1]["value"] = member->getTitle();
-		row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL";
-		row["columns"][1]["font"]["style"] = style;
-
-		std::string status = member->getOnlineStatus();
-		
-		row["columns"][2]["column"] = "status";
-		row["columns"][2]["value"] = status;
-		row["columns"][2]["font"]["name"] = "SANSSERIF_SMALL";
-		row["columns"][2]["font"]["style"] = style;
 
-		sSDTime += sd_timer.getElapsedTimeF32();
-
-		element_timer.reset();
-		LLScrollListItem* member_row = mListVisibleMembers->addElement(row);
-		
-		if ( member->isOwner() )
+		if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
+		{
+			addMember(mMemberProgress->second);
+		}
+		else
 		{
-			LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0));
-			if (name_textp)
-				name_textp->setFontStyle(LLFontGL::BOLD);
+			// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
+			LLAvatarNameCache::get(mMemberProgress->first, 
+									boost::bind(&LLPanelGroupGeneral::onNameCache,
+												this, mUdpateSessionID, member, _1, _2));
 		}
-		sElementTime += element_timer.getElapsedTimeF32();
 	}
-	sAllTime += all_timer.getElapsedTimeF32();
 
-	lldebugs << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl;
 	if (mMemberProgress == gdatap->mMembers.end())
 	{
 		lldebugs << "   member list completed." << llendl;
 		mListVisibleMembers->setEnabled(TRUE);
-
-		lldebugs << "All Time: " << sAllTime << llendl;
-		lldebugs << "SD Time: " << sSDTime << llendl;
-		lldebugs << "Element Time: " << sElementTime << llendl;
 	}
 	else
 	{
@@ -774,6 +746,39 @@ void LLPanelGroupGeneral::updateMembers()
 	}
 }
 
+void LLPanelGroupGeneral::addMember(LLGroupMemberData* member)
+{
+	LLNameListCtrl::NameItem item_params;
+	item_params.value = member->getID();
+
+	LLScrollListCell::Params column;
+	item_params.columns.add().column("name").font.name("SANSSERIF_SMALL");
+
+	item_params.columns.add().column("title").value(member->getTitle()).font.name("SANSSERIF_SMALL");
+
+	item_params.columns.add().column("status").value(member->getOnlineStatus()).font.name("SANSSERIF_SMALL");
+
+	LLScrollListItem* member_row = mListVisibleMembers->addNameItemRow(item_params);
+
+	if ( member->isOwner() )
+	{
+		LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0));
+		if (name_textp)
+			name_textp->setFontStyle(LLFontGL::BOLD);
+	}
+}
+
+void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name)
+{
+	if (!member 
+		|| update_id != mUdpateSessionID)
+	{
+		return;
+	}
+
+	addMember(member);
+}
+
 void LLPanelGroupGeneral::updateChanged()
 {
 	// List all the controls we want to check for changes...
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index 88c092c461bc9c88dc47a6f67aae19acd9abbe30..b179f78c56781336107387a3416404507e1a8579 100644
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -38,6 +38,7 @@ class LLNameListCtrl;
 class LLCheckBoxCtrl;
 class LLComboBox;
 class LLSpinCtrl;
+class LLAvatarName;
 
 class LLPanelGroupGeneral : public LLPanelGroupTab
 {
@@ -62,6 +63,7 @@ public:
 
 	virtual void setupCtrls	(LLPanel* parent);
 
+	void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name);
 private:
 	void	reset();
 
@@ -75,7 +77,8 @@ private:
 	static void onReceiveNotices(LLUICtrl* ctrl, void* data);
 	static void openProfile(void* data);
 
-	S32		sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*);
+	S32	 sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*);
+	void addMember(LLGroupMemberData* member);
 
     static bool joinDlgCB(const LLSD& notification, const LLSD& response);
 
@@ -87,6 +90,7 @@ private:
 	BOOL			mChanged;
 	BOOL			mFirstUse;
 	std::string		mIncompleteMemberDataStr;
+	LLUUID			mUdpateSessionID;
 
 	// Group information (include any updates in updateChanged)
 	LLLineEditor		*mGroupNameEditor;
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 1ed8d8cf038aaf7369db85dc64d62f72914c6617..b9b347d4bea0eab4ca116d782a4f0fadb711627e 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -467,10 +467,11 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
 			//so we need to do this additional search in avatar tracker, see EXT-4732
 			if (LLAvatarTracker::instance().isBuddy(agent_id))
 			{
-				if (!gCacheName->getFullName(agent_id, fullname))
+				LLAvatarName av_name;
+				if (!LLAvatarNameCache::get(agent_id, &av_name))
 				{
 					// actually it should happen, just in case
-					gCacheName->get(LLUUID(agent_id), false, boost::bind(
+					LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(
 							&LLPanelGroupInvite::addUserCallback, this, _1, _2));
 					// for this special case!
 					//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence
@@ -479,7 +480,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
 				}
 				else
 				{
-					names.push_back(fullname);
+					names.push_back(av_name.getLegacyName());
 				}
 			}
 		}
@@ -487,12 +488,12 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
 	mImplementation->addUsers(names, agent_ids);
 }
 
-void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const std::string& full_name)
+void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& av_name)
 {
 	std::vector<std::string> names;
 	uuid_vec_t agent_ids;
 	agent_ids.push_back(id);
-	names.push_back(full_name);
+	names.push_back(av_name.getLegacyName());
 
 	mImplementation->addUsers(names, agent_ids);
 }
diff --git a/indra/newview/llpanelgroupinvite.h b/indra/newview/llpanelgroupinvite.h
index a7bfd2226e8ebe2b93a8caf3add33b9767151dff..9f7b5ae9be17790f243e260de9d51114d186a922 100644
--- a/indra/newview/llpanelgroupinvite.h
+++ b/indra/newview/llpanelgroupinvite.h
@@ -29,6 +29,8 @@
 #include "llpanel.h"
 #include "lluuid.h"
 
+class LLAvatarName;
+
 class LLPanelGroupInvite
 : public LLPanel
 {
@@ -40,7 +42,7 @@ public:
 	/**
 	 * this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers().
 	 */  
-	void addUserCallback(const LLUUID& id, const std::string& full_name);
+	void addUserCallback(const LLUUID& id, const LLAvatarName& av_name);
 	void clear();
 	void update();
 
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 363443646d567d5c51c6c97b3e40df4b78978efa..37755fb851a5b75e7b8154d898d072b260cd5e46 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -517,7 +517,7 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg)
 			
 			row["columns"][3]["column"] = "type";
 			row["columns"][3]["value"] = land_type;
-			row["columns"][3]["font"] = "SANSSERIFSMALL";
+			row["columns"][3]["font"] = "SANSSERIF_SMALL";
 			
 			// hidden is always last column
 			row["columns"][4]["column"] = "hidden";
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index bbe47ae94395ae26b9e4b941cab080986915eba7..5720168f8122f52a6c02535050f0d96f998dd0a7 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -29,6 +29,7 @@
 #include "llcheckboxctrl.h"
 
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llbutton.h"
 #include "llfiltereditor.h"
 #include "llfloatergroupinvite.h"
@@ -1584,25 +1585,22 @@ void LLPanelGroupMembersSubTab::addMemberToList(LLUUID id, LLGroupMemberData* da
 	LLUIString donated = getString("donation_area");
 	donated.setArg("[AREA]", llformat("%d", data->getContribution()));
 
-	LLSD row;
-	row["id"] = id;
+	LLNameListCtrl::NameItem item_params;
+	item_params.value = id;
 
-	row["columns"][0]["column"] = "name";
-	// value is filled in by name list control
+	item_params.columns.add().column("name").font.name("SANSSERIF_SMALL").style("NORMAL");
 
-	row["columns"][1]["column"] = "donated";
-	row["columns"][1]["value"] = donated.getString();
+	item_params.columns.add().column("donated").value(donated.getString())
+			.font.name("SANSSERIF_SMALL").style("NORMAL");
 
-	row["columns"][2]["column"] = "online";
-	row["columns"][2]["value"] = data->getOnlineStatus();
-	row["columns"][2]["font"] = "SANSSERIF_SMALL";
-
-	mMembersList->addElement(row);
+	item_params.columns.add().column("online").value(data->getOnlineStatus())
+			.font.name("SANSSERIF_SMALL").style("NORMAL");
+	mMembersList->addNameItemRow(item_params);
 
 	mHasMatch = TRUE;
 }
 
-void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, const LLUUID& id)
+void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name)
 {
 	// Update ID is used to determine whether member whose id is passed
 	// into onNameCache() was passed after current or previous user-initiated update.
@@ -1612,21 +1610,15 @@ void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, const LLUUI
 	// we do nothing.
 	if (mUdpateSessionID != update_id) return;
 	
-	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
-		if (!gdatap) 
+	if (!member)
 	{
-		llwarns << "LLPanelGroupMembersSubTab::updateMembers() -- No group data!" << llendl;
 		return;
 	}
 	
-	std::string fullname;
-	gCacheName->getFullName(id, fullname);
-
-	LLGroupMemberData* data;
 	// trying to avoid unnecessary hash lookups
-	if (matchesSearchFilter(fullname) && ((data = gdatap->mMembers[id]) != NULL))
+	if (matchesSearchFilter(av_name.getLegacyName()))
 	{
-		addMemberToList(id, data);
+		addMemberToList(id, member);
 		if(!mMembersList->getEnabled())
 		{
 			mMembersList->setEnabled(TRUE);
@@ -1665,18 +1657,20 @@ void LLPanelGroupMembersSubTab::updateMembers()
 
 
 	LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end();
-	
-	S32 i = 0;
-	for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME; 
-			++mMemberProgress, ++i)
+
+	LLTimer update_time;
+	update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME);
+
+	for( ; mMemberProgress != end && !update_time.hasExpired(); ++mMemberProgress)
 	{
 		if (!mMemberProgress->second)
 			continue;
+
 		// Do filtering on name if it is already in the cache.
-		std::string fullname;
-		if (gCacheName->getFullName(mMemberProgress->first, fullname))
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
 		{
-			if (matchesSearchFilter(fullname))
+			if (matchesSearchFilter(av_name.getLegacyName()))
 			{
 				addMemberToList(mMemberProgress->first, mMemberProgress->second);
 			}
@@ -1684,8 +1678,8 @@ void LLPanelGroupMembersSubTab::updateMembers()
 		else
 		{
 			// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
-			gCacheName->get(mMemberProgress->first, FALSE, boost::bind(&LLPanelGroupMembersSubTab::onNameCache,
-																	   this, mUdpateSessionID, _1));
+			LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache,
+																	   this, mUdpateSessionID, mMemberProgress->second, _1, _2));
 		}
 	}
 
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index a55e26415077d169adc18333384aeee57b546403..8b454e020aec016f89b15521cfb2389ecda1d47d 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -188,7 +188,7 @@ public:
 	virtual void setGroupID(const LLUUID& id);
 
 	void addMemberToList(LLUUID id, LLGroupMemberData* data);
-	void onNameCache(const LLUUID& update_id, const LLUUID& id);
+	void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name);
 
 protected:
 	typedef std::map<LLUUID, LLRoleMemberChangeType> role_change_data_map_t;