diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index f56cb2eee7248cbd1ac660645d0d52e1d3fff6a3..c3dd4ae647d9436b85fbde6d9d8b2927ea24373f 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -127,6 +127,10 @@ void LLDockableFloater::setVisible(BOOL visible)
 		mDockControl.get()->repositionDockable();
 	}
 
+	if (visible)
+	{
+		LLFloater::setFrontmost(TRUE);
+	}
 	LLFloater::setVisible(visible);
 }
 
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index f2cdad8854a431a6a888054cb0911fa4f785f9a7..2a0dcaf333655e367d1c300914ac44b76f78bd7f 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1888,41 +1888,50 @@ void LLFloaterView::reshapeFloater(S32 width, S32 height, BOOL called_from_paren
 			// dependents use same follow flags as their "dependee"
 			continue;
 		}
-		LLRect r = floaterp->getRect();
-
-		// Compute absolute distance from each edge of screen
-		S32 left_offset = llabs(r.mLeft - 0);
-		S32 right_offset = llabs(old_width - r.mRight);
-
-		S32 top_offset = llabs(old_height - r.mTop);
-		S32 bottom_offset = llabs(r.mBottom - 0);
 
 		// Make if follow the edge it is closest to
 		U32 follow_flags = 0x0;
 
-		if (left_offset < right_offset)
+		if (floaterp->isMinimized())
 		{
-			follow_flags |= FOLLOWS_LEFT;
+			follow_flags |= (FOLLOWS_LEFT | FOLLOWS_TOP);
 		}
 		else
 		{
-			follow_flags |= FOLLOWS_RIGHT;
-		}
+			LLRect r = floaterp->getRect();
 
-		// "No vertical adjustment" usually means that the bottom of the view
-		// has been pushed up or down.  Hence we want the floaters to follow
-		// the top.
-		if (!adjust_vertical)
-		{
-			follow_flags |= FOLLOWS_TOP;
-		}
-		else if (top_offset < bottom_offset)
-		{
-			follow_flags |= FOLLOWS_TOP;
-		}
-		else
-		{
-			follow_flags |= FOLLOWS_BOTTOM;
+			// Compute absolute distance from each edge of screen
+			S32 left_offset = llabs(r.mLeft - 0);
+			S32 right_offset = llabs(old_width - r.mRight);
+
+			S32 top_offset = llabs(old_height - r.mTop);
+			S32 bottom_offset = llabs(r.mBottom - 0);
+
+
+			if (left_offset < right_offset)
+			{
+				follow_flags |= FOLLOWS_LEFT;
+			}
+			else
+			{
+				follow_flags |= FOLLOWS_RIGHT;
+			}
+
+			// "No vertical adjustment" usually means that the bottom of the view
+			// has been pushed up or down.  Hence we want the floaters to follow
+			// the top.
+			if (!adjust_vertical)
+			{
+				follow_flags |= FOLLOWS_TOP;
+			}
+			else if (top_offset < bottom_offset)
+			{
+				follow_flags |= FOLLOWS_TOP;
+			}
+			else
+			{
+				follow_flags |= FOLLOWS_BOTTOM;
+			}
 		}
 
 		floaterp->setFollows(follow_flags);
@@ -2172,16 +2181,16 @@ void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom)
 	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
 	S32 floater_header_size = default_params.header_height;
 	static LLUICachedControl<S32> minimized_width ("UIMinimizedWidth", 0);
-	S32 col = 0;
 	LLRect snap_rect_local = getLocalSnapRect();
-	for(S32 row = snap_rect_local.mBottom;
-		row < snap_rect_local.getHeight() - floater_header_size;
-		row += floater_header_size ) //loop rows
-	{
-		for(col = snap_rect_local.mLeft;
-			col < snap_rect_local.getWidth() - minimized_width;
-			col += minimized_width)
+	for(S32 col = snap_rect_local.mLeft;
+		col < snap_rect_local.getWidth() - minimized_width;
+		col += minimized_width)
+	{	
+		for(S32 row = snap_rect_local.mTop - floater_header_size;
+		row > floater_header_size;
+		row -= floater_header_size ) //loop rows
 		{
+
 			bool foundGap = TRUE;
 			for(child_list_const_iter_t child_it = getChildList()->begin();
 				child_it != getChildList()->end();
diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp
index f86776384ada0dae375bdc0b913b226a4e4f20af..da2fc7c68b2fb5209536d87456183f0514bf9720 100644
--- a/indra/llui/llslider.cpp
+++ b/indra/llui/llslider.cpp
@@ -47,14 +47,17 @@ static LLDefaultChildRegistry::Register<LLSlider> r1("slider_bar");
 // have ambigious template lookup problem
 
 LLSlider::Params::Params()
-:	track_color("track_color"),
+:	orientation ("orientation", std::string ("horizontal")),
+	track_color("track_color"),
 	thumb_outline_color("thumb_outline_color"),
 	thumb_center_color("thumb_center_color"),
 	thumb_image("thumb_image"),
 	thumb_image_pressed("thumb_image_pressed"),
 	thumb_image_disabled("thumb_image_disabled"),
-	track_image("track_image"),
-	track_highlight_image("track_highlight_image"),
+	track_image_horizontal("track_image_horizontal"),
+	track_image_vertical("track_image_vertical"),
+	track_highlight_horizontal_image("track_highlight_horizontal_image"),
+	track_highlight_vertical_image("track_highlight_vertical_image"),
 	mouse_down_callback("mouse_down_callback"),
 	mouse_up_callback("mouse_up_callback")
 {
@@ -64,14 +67,17 @@ LLSlider::Params::Params()
 LLSlider::LLSlider(const LLSlider::Params& p)
 :	LLF32UICtrl(p),
 	mMouseOffset( 0 ),
+	mOrientation ((p.orientation() == "horizontal") ? HORIZONTAL : VERTICAL),
 	mTrackColor(p.track_color()),
 	mThumbOutlineColor(p.thumb_outline_color()),
 	mThumbCenterColor(p.thumb_center_color()),
 	mThumbImage(p.thumb_image),
 	mThumbImagePressed(p.thumb_image_pressed),
 	mThumbImageDisabled(p.thumb_image_disabled),
-	mTrackImage(p.track_image),
-	mTrackHighlightImage(p.track_highlight_image)
+	mTrackImageHorizontal(p.track_image_horizontal),
+	mTrackImageVertical(p.track_image_vertical),
+	mTrackHighlightHorizontalImage(p.track_highlight_horizontal_image),
+	mTrackHighlightVerticalImage(p.track_highlight_vertical_image)
 {
     mViewModel->setValue(p.initial_value);
 	updateThumbRect();
@@ -111,14 +117,29 @@ void LLSlider::updateThumbRect()
 
 	S32 thumb_width = mThumbImage ? mThumbImage->getWidth() : DEFAULT_THUMB_SIZE;
 	S32 thumb_height = mThumbImage ? mThumbImage->getHeight() : DEFAULT_THUMB_SIZE;
-	S32 left_edge = (thumb_width / 2);
-	S32 right_edge = getRect().getWidth() - (thumb_width / 2);
-
-	S32 x = left_edge + S32( t * (right_edge - left_edge) );
-	mThumbRect.mLeft = x - (thumb_width / 2);
-	mThumbRect.mRight = mThumbRect.mLeft + thumb_width;
-	mThumbRect.mBottom = getLocalRect().getCenterY() - (thumb_height / 2);
-	mThumbRect.mTop = mThumbRect.mBottom + thumb_height;
+
+	if ( mOrientation == HORIZONTAL )
+	{
+		S32 left_edge = (thumb_width / 2);
+		S32 right_edge = getRect().getWidth() - (thumb_width / 2);
+
+		S32 x = left_edge + S32( t * (right_edge - left_edge) );
+		mThumbRect.mLeft = x - (thumb_width / 2);
+		mThumbRect.mRight = mThumbRect.mLeft + thumb_width;
+		mThumbRect.mBottom = getLocalRect().getCenterY() - (thumb_height / 2);
+		mThumbRect.mTop = mThumbRect.mBottom + thumb_height;
+	}
+	else
+	{
+		S32 top_edge = (thumb_height / 2);
+		S32 bottom_edge = getRect().getHeight() - (thumb_height / 2);
+
+		S32 y = top_edge + S32( t * (bottom_edge - top_edge) );
+		mThumbRect.mLeft = getLocalRect().getCenterX() - (thumb_width / 2);
+		mThumbRect.mRight = mThumbRect.mLeft + thumb_width;
+		mThumbRect.mBottom = y  - (thumb_height / 2);
+		mThumbRect.mTop = mThumbRect.mBottom + thumb_height;
+	}
 }
 
 
@@ -138,18 +159,32 @@ BOOL LLSlider::handleHover(S32 x, S32 y, MASK mask)
 {
 	if( hasMouseCapture() )
 	{
-		S32 thumb_half_width = mThumbImage->getWidth()/2;
-		S32 left_edge = thumb_half_width;
-		S32 right_edge = getRect().getWidth() - (thumb_half_width);
+		if ( mOrientation == HORIZONTAL )
+		{
+			S32 thumb_half_width = mThumbImage->getWidth()/2;
+			S32 left_edge = thumb_half_width;
+			S32 right_edge = getRect().getWidth() - (thumb_half_width);
 
-		x += mMouseOffset;
-		x = llclamp( x, left_edge, right_edge );
+			x += mMouseOffset;
+			x = llclamp( x, left_edge, right_edge );
 
-		F32 t = F32(x - left_edge) / (right_edge - left_edge);
-		setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue );
+			F32 t = F32(x - left_edge) / (right_edge - left_edge);
+			setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue );
+		}
+		else // mOrientation == VERTICAL
+		{
+			S32 thumb_half_height = mThumbImage->getHeight()/2;
+			S32 top_edge = thumb_half_height;
+			S32 bottom_edge = getRect().getHeight() - (thumb_half_height);
+
+			y += mMouseOffset;
+			y = llclamp(y, top_edge, bottom_edge);
 
+			F32 t = F32(y - top_edge) / (bottom_edge - top_edge);
+			setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue );
+		}
 		getWindow()->setCursor(UI_CURSOR_ARROW);
-		lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;		
+		lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
 	}
 	else
 	{
@@ -198,7 +233,9 @@ BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask)
 		// Find the offset of the actual mouse location from the center of the thumb.
 		if (mThumbRect.pointInRect(x,y))
 		{
-			mMouseOffset = (mThumbRect.mLeft + mThumbImage->getWidth()/2) - x;
+			mMouseOffset = (mOrientation == HORIZONTAL)
+				? (mThumbRect.mLeft + mThumbImage->getWidth()/2) - x
+				: (mThumbRect.mBottom + mThumbImage->getHeight()/2) - y;
 		}
 		else
 		{
@@ -220,15 +257,12 @@ BOOL LLSlider::handleKeyHere(KEY key, MASK mask)
 	BOOL handled = FALSE;
 	switch(key)
 	{
-	case KEY_UP:
 	case KEY_DOWN:
-		// eat up and down keys to be consistent
-		handled = TRUE;
-		break;
 	case KEY_LEFT:
 		setValueAndCommit(getValueF32() - getIncrement());
 		handled = TRUE;
 		break;
+	case KEY_UP:
 	case KEY_RIGHT:
 		setValueAndCommit(getValueF32() + getIncrement());
 		handled = TRUE;
@@ -239,6 +273,17 @@ BOOL LLSlider::handleKeyHere(KEY key, MASK mask)
 	return handled;
 }
 
+BOOL LLSlider::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+	if ( mOrientation == VERTICAL )
+	{
+		F32 new_val = getValueF32() - clicks * getIncrement();
+		setValueAndCommit(new_val);
+		return TRUE;
+	}
+	return LLF32UICtrl::handleScrollWheel(x,y,clicks);
+}
+
 void LLSlider::draw()
 {
 	F32 alpha = getDrawContext().mAlpha;
@@ -252,13 +297,36 @@ void LLSlider::draw()
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	// Track
-	LLRect track_rect(mThumbImage->getWidth() / 2, 
-						getLocalRect().getCenterY() + (mTrackImage->getHeight() / 2), 
-						getRect().getWidth() - mThumbImage->getWidth() / 2, 
-						getLocalRect().getCenterY() - (mTrackImage->getHeight() / 2) );
-	LLRect highlight_rect(track_rect.mLeft, track_rect.mTop, mThumbRect.getCenterX(), track_rect.mBottom);
-	mTrackImage->draw(track_rect, LLColor4::white % alpha);
-	mTrackHighlightImage->draw(highlight_rect, LLColor4::white % alpha);
+	LLPointer<LLUIImage>& trackImage = ( mOrientation == HORIZONTAL )
+		? mTrackImageHorizontal
+		: mTrackImageVertical;
+
+	LLPointer<LLUIImage>& trackHighlightImage = ( mOrientation == HORIZONTAL )
+		? mTrackHighlightHorizontalImage
+		: mTrackHighlightVerticalImage;
+
+	LLRect track_rect;
+	LLRect highlight_rect;
+
+	if ( mOrientation == HORIZONTAL )
+	{
+		track_rect.set(mThumbImage->getWidth() / 2,
+					   getLocalRect().getCenterY() + (trackImage->getHeight() / 2), 
+					   getRect().getWidth() - mThumbImage->getWidth() / 2,
+					   getLocalRect().getCenterY() - (trackImage->getHeight() / 2) );
+		highlight_rect.set(track_rect.mLeft, track_rect.mTop, mThumbRect.getCenterX(), track_rect.mBottom);
+	}
+	else
+	{
+		track_rect.set(getLocalRect().getCenterX() - (trackImage->getWidth() / 2),
+					   getRect().getHeight(),
+					   getLocalRect().getCenterX() + (trackImage->getWidth() / 2),
+					   0);
+		highlight_rect.set(track_rect.mLeft, track_rect.mTop, track_rect.mRight, track_rect.mBottom);
+	}
+
+	trackImage->draw(track_rect, LLColor4::white % alpha);
+	trackHighlightImage->draw(highlight_rect, LLColor4::white % alpha);
 
 	// Thumb
 	if (hasFocus())
diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h
index e2a94e4d8cf3f0a2bf5533ed8a8f9a56e6cbbb04..6ab0ed79220f8bc9228040944e4ec25a25b6f19c 100644
--- a/indra/llui/llslider.h
+++ b/indra/llui/llslider.h
@@ -39,8 +39,12 @@
 class LLSlider : public LLF32UICtrl
 {
 public:
+	enum ORIENTATION { HORIZONTAL, VERTICAL };
+
 	struct Params : public LLInitParam::Block<Params, LLF32UICtrl::Params>
 	{
+		Optional<std::string> orientation;
+
 		Optional<LLUIColor>	track_color,
 							thumb_outline_color,
 							thumb_center_color;
@@ -48,8 +52,10 @@ class LLSlider : public LLF32UICtrl
 		Optional<LLUIImage*>	thumb_image,
 								thumb_image_pressed,
 								thumb_image_disabled,
-								track_image,
-								track_highlight_image;
+								track_image_horizontal,
+								track_image_vertical,
+								track_highlight_horizontal_image,
+								track_highlight_vertical_image;
 
 		Optional<CommitCallbackParam>	mouse_down_callback,
 										mouse_up_callback;
@@ -77,6 +83,7 @@ class LLSlider : public LLF32UICtrl
 	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleKeyHere(KEY key, MASK mask);
+	virtual BOOL	handleScrollWheel(S32 x, S32 y, S32 clicks);
 	virtual void	draw();
 
 private:
@@ -90,10 +97,14 @@ class LLSlider : public LLF32UICtrl
 	LLPointer<LLUIImage>	mThumbImage;
 	LLPointer<LLUIImage>	mThumbImagePressed;
 	LLPointer<LLUIImage>	mThumbImageDisabled;
-	LLPointer<LLUIImage>	mTrackImage;
-	LLPointer<LLUIImage>	mTrackHighlightImage;
+	LLPointer<LLUIImage>	mTrackImageHorizontal;
+	LLPointer<LLUIImage>	mTrackImageVertical;
+	LLPointer<LLUIImage>	mTrackHighlightHorizontalImage;
+	LLPointer<LLUIImage>	mTrackHighlightVerticalImage;
+
+	const ORIENTATION	mOrientation;
 
-	LLRect			mThumbRect;
+	LLRect		mThumbRect;
 	LLUIColor	mTrackColor;
 	LLUIColor	mThumbOutlineColor;
 	LLUIColor	mThumbCenterColor;
diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp
index 717e135412e2948cf3ad4ee376059da96dcc3e27..5df1d35383241739a64c8c5b8a278bc9d597d1ea 100644
--- a/indra/llui/lltoggleablemenu.cpp
+++ b/indra/llui/lltoggleablemenu.cpp
@@ -40,6 +40,7 @@ static LLDefaultChildRegistry::Register<LLToggleableMenu> r("toggleable_menu");
 
 LLToggleableMenu::LLToggleableMenu(const LLToggleableMenu::Params& p)
 :	LLMenuGL(p),
+	mButtonRect(),
 	mClosedByButtonClick(false)
 {
 }
@@ -56,13 +57,19 @@ void LLToggleableMenu::handleVisibilityChange (BOOL curVisibilityIn)
 	}
 }
 
-void LLToggleableMenu::setButtonRect(const LLRect& rect, LLView* current_view) 
+void LLToggleableMenu::setButtonRect(const LLRect& rect, LLView* current_view)
 {
 	LLRect screen;
 	current_view->localRectToScreen(rect, &screen);
 	mButtonRect = screen;
 }
 
+void LLToggleableMenu::setButtonRect(LLView* current_view)
+{
+	LLRect rect = current_view->getLocalRect();
+	setButtonRect(rect, current_view);
+}
+
 bool LLToggleableMenu::toggleVisibility() 
 {
 	if (mClosedByButtonClick)
diff --git a/indra/llui/lltoggleablemenu.h b/indra/llui/lltoggleablemenu.h
index 3cd66e04a8bfec056eebfe7820d39e39fbe658be..9d8c5261b9ca4de5365b844f4d345937d0281303 100644
--- a/indra/llui/lltoggleablemenu.h
+++ b/indra/llui/lltoggleablemenu.h
@@ -49,8 +49,11 @@ class LLToggleableMenu : public LLMenuGL
 public:
 	virtual void handleVisibilityChange (BOOL curVisibilityIn);
 
+	const LLRect& getButtonRect() const { return mButtonRect; }
+
 	// Converts the given local button rect to a screen rect
 	void setButtonRect(const LLRect& rect, LLView* current_view);
+	void setButtonRect(LLView* current_view);
 
 	// Returns "true" if menu was not closed by button click
 	// and is not still visible. If menu is visible toggles
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b129bca1f3921bf520c497538bb90aebf6685164..9d44f34ea8b0ff451789db792c9fc3fe30d74f4b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -252,6 +252,7 @@ set(viewer_SOURCE_FILES
     llinventoryfilter.cpp
     llinventoryfunctions.cpp
     llinventorymodel.cpp
+    llinventoryobserver.cpp
     llinventorypanel.cpp
     llinventorysubtreepanel.cpp
     lljoystickbutton.cpp
@@ -748,6 +749,7 @@ set(viewer_HEADER_FILES
     llinventoryfilter.h
     llinventoryfunctions.h
     llinventorymodel.h
+    llinventoryobserver.h
     llinventorypanel.h
     llinventorysubtreepanel.h
     lljoystickbutton.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 38f14793d9b53b283b0c292cedcf027aabbd2d9e..8ad52784d33bafdc1f987362e9964a49a7180fae 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4259,7 +4259,29 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>LogMessages</key>
+  <key>LoginSRVTimeout</key>
+  <map>
+    <key>Comment</key>
+    <string>Duration in seconds of the login SRV request timeout</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>10.0</real>
+  </map>
+  <key>LoginSRVPump</key>
+  <map>
+    <key>Comment</key>
+    <string>Name of the message pump that handles SRV request</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>String</string>
+    <key>Value</key>
+    <string>LLAres</string>
+  </map>
+  <key>LogMessages</key>
     <map>
       <key>Comment</key>
       <string>Log network traffic</string>
@@ -5501,7 +5523,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
     <key>QAMode</key>
     <map>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index d2c8558f0b2da2da3ae3460c4bf4ddd39340b982..ca1688ad1f7a463bac899dc3ed437ec6ae408d12 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3080,10 +3080,6 @@ void LLAgent::updateCamera()
 		mOrbitLeftKey > 0.f,	// right
 		mOrbitDownKey > 0.f);	// bottom
 
-		camera_floater->mZoom->setToggleState( 
-		mOrbitInKey > 0.f,		// top
-		mOrbitOutKey > 0.f);	// bottom
-
 		camera_floater->mTrack->setToggleState(
 		mPanLeftKey > 0.f,		// left
 		mPanUpKey > 0.f,		// top
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 9938c3db2bfdf25f68286e3fe8690cd145054d17..9b4986247fd37725d7c8972946e8b91fbfb8c1fc 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -887,9 +887,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
 			lldebugs << "       " << LLWearableDictionary::getTypeLabel(type) << llendl;
 		}
 		
-		// What we do here is get the complete information on the items in
-		// the inventory, and set up an observer that will wait for that to
-		// happen.
+		// Get the complete information on the items in the inventory and set up an observer
+		// that will trigger when the complete information is fetched.
 		LLInventoryFetchDescendentsObserver::folder_ref_t folders;
 		folders.push_back(current_outfit_id);
 		outfit->fetchDescendents(folders);
@@ -2023,6 +2022,8 @@ void LLInitialWearablesFetch::done()
 	else
 	{
 		processWearablesMessage();
+		// Create links for attachments that may have arrived before the COF existed.
+		LLAppearanceManager::linkRegisteredAttachments();
 	}
 	delete this;
 }
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index d14de1c3012440f061c797e203f66e240e53b861..0901289dace7f6e4e85ab676782f0fcfd5599e85 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1123,6 +1123,7 @@ void LLAppearanceManager::wearItem( LLInventoryItem* item, bool do_update )
 	{
 		if (do_update)
 			LLAppearanceManager::updateAppearanceFromCOF();
+		return;
 	}
 	else
 	{
@@ -1134,6 +1135,7 @@ void LLAppearanceManager::wearItem( LLInventoryItem* item, bool do_update )
 							 LLAssetType::AT_LINK,
 							 cb);
 	}
+	return;
 }
 
 /* static */
@@ -1281,3 +1283,22 @@ void LLAppearanceManager::unregisterAttachment(const LLUUID& item_id)
 		   //llinfos << "no link changes, inv link not enabled" << llendl;
 	   }
 }
+
+/* static */
+void LLAppearanceManager::linkRegisteredAttachments()
+{
+	for (std::set<LLUUID>::iterator it = sRegisteredAttachments.begin();
+		 it != sRegisteredAttachments.end();
+		 ++it)
+	{
+		LLUUID item_id = *it;
+		LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		if (item)
+		{
+			wearItem(item, false);
+			gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+			gInventory.notifyObservers();
+		}
+	}
+	sRegisteredAttachments.clear();
+}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 56f54dfc23d095119af9ebf65129f959ab533818..7dea16b6cf0da25213b9f08e2cb3db647addbae6 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -71,6 +71,7 @@ class LLAppearanceManager: public LLSingleton<LLAppearanceManager>
 	static void unregisterAttachment(const LLUUID& item_id);
 	static void registerAttachment(const LLUUID& item_id);
 	static void setAttachmentInvLinkEnable(bool val);
+	static void linkRegisteredAttachments();
 
 private:
 	static void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index f6319785650470bf48113458467826a60b179a61..ee4a9df15fa9a377dd6804709e88fc183aa04927 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -192,7 +192,7 @@ void LLAvatarActions::startIM(const LLUUID& id)
 // static
 void LLAvatarActions::startCall(const LLUUID& id)
 {
-	if (id.isNull() || isCalling(id))
+	if (id.isNull())
 	{
 		return;
 	}
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 7df278d887bf6815d3a17926c3af569eef3a464a..c670a65bcc0e968909ac12dab1fbe1c9ab6d9b62 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -311,3 +311,18 @@ void LLAvatarListItem::onNameCache(const std::string& first_name, const std::str
 	mAvatarName->setValue(name);
 	mAvatarName->setToolTip(name);
 }
+
+void LLAvatarListItem::reshapeAvatarName()
+{
+	S32 width_delta = 0;
+	width_delta += mShowProfileBtn ? mProfileBtnWidth : 0;
+	width_delta += mSpeakingIndicator->getVisible() ? mSpeakingIndicatorWidth : 0;
+	width_delta += mAvatarIcon->getVisible() ? mIconWidth : 0;
+	width_delta += mShowInfoBtn ? mInfoBtnWidth : 0;
+	width_delta += mLastInteractionTime->getVisible() ? mLastInteractionTime->getRect().getWidth() : 0;
+
+	S32 height = mAvatarName->getRect().getHeight();
+	S32 width  = getRect().getWidth() - width_delta;
+
+	mAvatarName->reshape(width, height);
+}
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index d379797a464b8c47206709640e39863d76ca086f..9d48101a44caa63d9dc04ce9ff96f05f6ad75573 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -82,6 +82,8 @@ class LLAvatarListItem : public LLPanel, public LLFriendObserver
 
 	void setContextMenu(ContextMenu* menu) { mContextMenu = menu; }
 
+	void reshapeAvatarName();
+
 private:
 
 	typedef enum e_online_status {
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 291f645ea23fb75a6810a734cccfa6fe93af2387..fd711b72b0e9c06883b7f677e589705403f538f8 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -40,6 +40,7 @@
 #include "llimfloater.h" // for LLIMFloater
 #include "lllayoutstack.h"
 #include "llnearbychatbar.h"
+#include "llspeakbutton.h"
 #include "llsplitbutton.h"
 #include "llsyswellwindow.h"
 #include "llfloatercamera.h"
@@ -51,6 +52,7 @@ LLBottomTray::LLBottomTray(const LLSD&)
 	mNearbyChatBar(NULL),
 	mToolbarStack(NULL)
 ,	mMovementButton(NULL)
+,	mResizeState(RS_NORESIZE)
 // Add more members
 {
 	mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL);
@@ -185,6 +187,28 @@ void LLBottomTray::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID&
 	}
 }
 
+// virtual
+void LLBottomTray::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+	// Time it takes to connect to voice channel might be pretty long,
+	// so don't expect user login or STATUS_VOICE_ENABLED to be followed by STATUS_JOINED.
+	BOOL enable = FALSE;
+
+	switch (status)
+	{
+	// Do not add STATUS_VOICE_ENABLED because voice chat is 
+	// inactive until STATUS_JOINED
+	case STATUS_JOINED:
+		enable = TRUE;
+		break;
+	default:
+		enable = FALSE;
+		break;
+	}
+
+	mSpeakBtn->setEnabled(enable);
+}
+
 //virtual
 void LLBottomTray::onFocusLost()
 {
@@ -238,22 +262,22 @@ void LLBottomTray::showBottomTrayContextMenu(S32 x, S32 y, MASK mask)
 
 void LLBottomTray::showGestureButton(BOOL visible)
 {
-	showTrayButton(RS_BUTTON_GESTURES, visible);
+	setTrayButtonVisibleIfPossible(RS_BUTTON_GESTURES, visible);
 }
 
 void LLBottomTray::showMoveButton(BOOL visible)
 {
-	showTrayButton(RS_BUTTON_MOVEMENT, visible);
+	setTrayButtonVisibleIfPossible(RS_BUTTON_MOVEMENT, visible);
 }
 
 void LLBottomTray::showCameraButton(BOOL visible)
 {
-	showTrayButton(RS_BUTTON_CAMERA, visible);
+	setTrayButtonVisibleIfPossible(RS_BUTTON_CAMERA, visible);
 }
 
 void LLBottomTray::showSnapshotButton(BOOL visible)
 {
-	showTrayButton(RS_BUTTON_SNAPSHOT, visible);
+	setTrayButtonVisibleIfPossible(RS_BUTTON_SNAPSHOT, visible);
 }
 
 namespace
@@ -280,6 +304,19 @@ BOOL LLBottomTray::postBuild()
 	mSnapshotPanel = getChild<LLPanel>("snapshot_panel");
 	setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4));
 
+	mSpeakBtn = getChild<LLSpeakButton>("talk");
+
+	// Speak button should be initially disabled because
+	// it takes some time between logging in to world and connecting to voice channel.
+	mSpeakBtn->setEnabled(FALSE);
+
+	// Localization tool doesn't understand custom buttons like <talk_button>
+	mSpeakBtn->setSpeakToolTip( getString("SpeakBtnToolTip") );
+	mSpeakBtn->setShowToolTip( getString("VoiceControlBtnToolTip") );
+
+	// Registering Chat Bar to receive Voice client status change notifications.
+	gVoiceClient->addObserver(this);
+
 	if (mChicletPanel && mToolbarStack && mNearbyChatBar)
 	{
 		verifyChildControlsSizes();
@@ -331,74 +368,87 @@ void LLBottomTray::verifyChildControlsSizes()
 		mNearbyChatBar->setRect(rect);
 	}
 }
-#define __FEATURE_EXT_991
+
 void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	lldebugs << "****************************************" << llendl;
+	static S32 debug_calling_number = 0;
+	lldebugs << "**************************************** " << ++debug_calling_number << llendl;
 
 	S32 current_width = getRect().getWidth();
+	S32 delta_width = width - current_width;
 	lldebugs << "Reshaping: " 
 		<< ", width: " << width
-		<< ", height: " << height
-		<< ", called_from_parent: " << called_from_parent
 		<< ", cur width: " << current_width
-		<< ", cur height: " << getRect().getHeight()
+		<< ", delta_width: " << delta_width
+		<< ", called_from_parent: " << called_from_parent
 		<< llendl;
 
 	if (mNearbyChatBar)			log(mNearbyChatBar, "before");
 	if (mChicletPanel)			log(mChicletPanel, "before");
 
+	// stores width size on which bottom tray is less than width required by its children. EXT-991
+	static S32 extra_shrink_width = 0;
+	bool should_be_reshaped = true;
+
 	if (mChicletPanel && mToolbarStack && mNearbyChatBar)
 	{
 		mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, TRUE);
  		verifyChildControlsSizes();
- 		updateResizeState(width, current_width);
-	}
-
-	LLPanel::reshape(width, height, called_from_parent);
-
-
-	if (mNearbyChatBar)			log(mNearbyChatBar, "after");
-	if (mChicletPanel)			log(mChicletPanel, "after");
-}
-
-void LLBottomTray::updateResizeState(S32 new_width, S32 cur_width)
-{
-	mResizeState = RS_NORESIZE;
-
-	S32 delta_width = new_width - cur_width;
-//	if (delta_width == 0) return;
-	bool shrink = new_width < cur_width;
-
-	const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth();
-	const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth();
-
-	const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth();
-	const S32 chatbar_panel_min_width = mNearbyChatBar->getMinWidth();
-	const S32 chatbar_panel_max_width = mNearbyChatBar->getMaxWidth();
 
-	lldebugs << "chatbar_panel_width: " << chatbar_panel_width
-		<< ", chatbar_panel_min_width: " << chatbar_panel_min_width
-		<< ", chatbar_panel_max_width: " << chatbar_panel_max_width
-		<< ", chiclet_panel_width: " << chiclet_panel_width
-		<< ", chiclet_panel_min_width: " << chiclet_panel_min_width
-		<< llendl;
+		// bottom tray is narrowed
+		if (delta_width < 0)
+		{
+			if (extra_shrink_width > 0)
+			{
+				// is world rect was extra shrunk and decreasing again only update this value
+				// to delta_width negative
+				extra_shrink_width -= delta_width; // use "-=" because delta_width is negative
+				should_be_reshaped = false;
+			}
+			else
+			{
+				extra_shrink_width = processWidthDecreased(delta_width);
 
-	// bottom tray is narrowed
-	if (shrink)
-	{
-		processWidthDecreased(delta_width);
+				// increase new width to extra_shrink_width value to not reshape less than bottom tray minimum
+				width += extra_shrink_width;
+			}
+		}
+		// bottom tray is widen
+		else
+		{
+			if (extra_shrink_width > delta_width)
+			{
+				// Less than minimum width is more than increasing (delta_width) 
+				// only reduce it value and make no reshape
+				extra_shrink_width -= delta_width;
+				should_be_reshaped = false;
+			}
+			else 
+			{
+				if (extra_shrink_width > 0)
+				{
+					// If we have some extra shrink width let's reduce delta_width & width
+					delta_width -= extra_shrink_width;
+					width -= extra_shrink_width;
+					extra_shrink_width = 0;
+				}
+				processWidthIncreased(delta_width);
+			}
+		}
 	}
-	// bottom tray is widen
-	else
+
+	lldebugs << "There is no enough width to reshape all children: " << extra_shrink_width << llendl;
+	if (should_be_reshaped)
 	{
-		processWidthIncreased(delta_width);
+		lldebugs << "Reshape all children with width: " << width << llendl;
+		LLPanel::reshape(width, height, called_from_parent);
 	}
 
-	lldebugs << "New resize state: " << mResizeState << llendl;
+	if (mNearbyChatBar)			log(mNearbyChatBar, "after");
+	if (mChicletPanel)			log(mChicletPanel, "after");
 }
 
-void LLBottomTray::processWidthDecreased(S32 delta_width)
+S32 LLBottomTray::processWidthDecreased(S32 delta_width)
 {
 	bool still_should_be_processed = true;
 
@@ -409,7 +459,6 @@ void LLBottomTray::processWidthDecreased(S32 delta_width)
 	{
 		// we have some space to decrease chiclet panel
 		S32 panel_delta_min = chiclet_panel_width - chiclet_panel_min_width;
-		mResizeState |= RS_CHICLET_PANEL;
 
 		S32 delta_panel = llmin(-delta_width, panel_delta_min);
 
@@ -437,27 +486,25 @@ void LLBottomTray::processWidthDecreased(S32 delta_width)
 	{
 		// we have some space to decrease chatbar panel
 		S32 panel_delta_min = chatbar_panel_width - chatbar_panel_min_width;
-		mResizeState |= RS_CHATBAR_INPUT;
 
 		S32 delta_panel = llmin(-delta_width, panel_delta_min);
 
-		// is chatbar panel width enough to process resizing?
+		// whether chatbar panel width is enough to process resizing?
 		delta_width += panel_delta_min;
 
-
 		still_should_be_processed = delta_width < 0;
 
 		mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mNearbyChatBar->getRect().getHeight());
 
+		log(mChicletPanel, "after processing panel decreasing via nearby chatbar panel");
+
 		lldebugs << "RS_CHATBAR_INPUT"
 			<< ", delta_panel: " << delta_panel
 			<< ", delta_width: " << delta_width
 			<< llendl;
-
-		log(mChicletPanel, "after nearby was processed");
-
 	}
 
+	S32 extra_shrink_width = 0;
 	S32 buttons_freed_width = 0;
 	if (still_should_be_processed)
 	{
@@ -480,7 +527,9 @@ void LLBottomTray::processWidthDecreased(S32 delta_width)
 
 		if (delta_width < 0)
 		{
-			llwarns << "WARNING: there is no enough room for bottom tray, resizing still should be processed" << llendl;
+			extra_shrink_width = -delta_width;
+			lldebugs << "There is no enough room for bottom tray, resizing still should be processed: " 
+				<< extra_shrink_width << llendl;
 		}
 
 		if (buttons_freed_width > 0)
@@ -491,10 +540,14 @@ void LLBottomTray::processWidthDecreased(S32 delta_width)
 			lldebugs << buttons_freed_width << llendl;
 		}
 	}
+
+	return extra_shrink_width;
 }
 
 void LLBottomTray::processWidthIncreased(S32 delta_width)
 {
+	if (delta_width <= 0) return;
+
 	const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth();
 	const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth();
 
@@ -573,7 +626,6 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
 	S32 chatbar_panel_width_ = mNearbyChatBar->getRect().getWidth();
 	if (delta_width > 0 && chatbar_panel_width_ < chatbar_panel_max_width)
 	{
-		mResizeState |= RS_CHATBAR_INPUT;
 		S32 delta_panel_max = chatbar_panel_max_width - chatbar_panel_width_;
 		S32 delta_panel = llmin(delta_width, delta_panel_max);
 		delta_width -= delta_panel_max;
@@ -589,7 +641,7 @@ bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* availa
 		lldebugs << "There is no object to process for state: " << shown_object_type << llendl;
 		return false;
 	}
-	bool can_be_shown = canButtonBeShown(panel);
+	bool can_be_shown = canButtonBeShown(shown_object_type);
 	if (can_be_shown)
 	{
 		//validate if we have enough room to show this button
@@ -600,22 +652,23 @@ bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* availa
 			*available_width -= required_width;
 			*buttons_required_width += required_width;
 
-			showTrayButton(shown_object_type, true);
+			setTrayButtonVisible(shown_object_type, true);
 
 			lldebugs << "processing object type: " << shown_object_type
 				<< ", buttons_required_width: " << *buttons_required_width
 				<< llendl;
+			mResizeState &= ~shown_object_type;
 		}
 	}
 	return can_be_shown;
 }
 
-void LLBottomTray::processHideButton(EResizeState shown_object_type, S32* required_width, S32* buttons_freed_width)
+void LLBottomTray::processHideButton(EResizeState processed_object_type, S32* required_width, S32* buttons_freed_width)
 {
-	LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
+	LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
 	if (NULL == panel)
 	{
-		lldebugs << "There is no object to process for state: " << shown_object_type << llendl;
+		lldebugs << "There is no object to process for state: " << processed_object_type << llendl;
 		return;
 	}
 
@@ -628,20 +681,41 @@ void LLBottomTray::processHideButton(EResizeState shown_object_type, S32* requir
 			*buttons_freed_width += *required_width;
 		}
 
-		showTrayButton(shown_object_type, false);
+		setTrayButtonVisible(processed_object_type, false);
 
-		lldebugs << "processing object type: " << shown_object_type
+		mResizeState |= processed_object_type;
+
+		lldebugs << "processing object type: " << processed_object_type
 			<< ", buttons_freed_width: " << *buttons_freed_width
 			<< llendl;
 	}
 }
 
-bool LLBottomTray::canButtonBeShown(LLPanel* panel) const
+bool LLBottomTray::canButtonBeShown(EResizeState processed_object_type) const
 {
-	bool can_be_shown = !panel->getVisible();
+	bool can_be_shown = mResizeState & processed_object_type;
 	if (can_be_shown)
 	{
-		// *TODO: mantipov: synchronize with situation when button was hidden via context menu;
+		static MASK MOVEMENT_PREVIOUS_BUTTONS_MASK = RS_BUTTON_GESTURES;
+		static MASK CAMERA_PREVIOUS_BUTTONS_MASK = RS_BUTTON_GESTURES | RS_BUTTON_MOVEMENT;
+		static MASK SNAPSHOT_PREVIOUS_BUTTONS_MASK = RS_BUTTON_GESTURES | RS_BUTTON_MOVEMENT | RS_BUTTON_CAMERA;
+
+		switch(processed_object_type)
+		{
+		case RS_BUTTON_GESTURES: // Gestures should be shown first
+			break;
+		case RS_BUTTON_MOVEMENT: // Move only if gesture is shown
+			can_be_shown = !(MOVEMENT_PREVIOUS_BUTTONS_MASK & mResizeState);
+			break;
+		case RS_BUTTON_CAMERA:
+			can_be_shown = !(CAMERA_PREVIOUS_BUTTONS_MASK & mResizeState);
+			break;
+		case RS_BUTTON_SNAPSHOT:
+			can_be_shown = !(SNAPSHOT_PREVIOUS_BUTTONS_MASK & mResizeState);
+			break;
+		default: // nothing to do here
+			break;
+		}
 	}
 	return can_be_shown;
 }
@@ -654,7 +728,7 @@ void LLBottomTray::initStateProcessedObjectMap()
 	mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SNAPSHOT, mSnapshotPanel));
 }
 
-void LLBottomTray::showTrayButton(EResizeState shown_object_type, bool visible)
+void LLBottomTray::setTrayButtonVisible(EResizeState shown_object_type, bool visible)
 {
 	LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
 	if (NULL == panel)
@@ -665,4 +739,49 @@ void LLBottomTray::showTrayButton(EResizeState shown_object_type, bool visible)
 
 	panel->setVisible(visible);
 }
+
+void LLBottomTray::setTrayButtonVisibleIfPossible(EResizeState shown_object_type, bool visible)
+{
+	bool can_be_set = true;
+
+	if (visible)
+	{
+		LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
+		if (NULL == panel)
+		{
+			lldebugs << "There is no object to process for state: " << shown_object_type << llendl;
+			return;
+		}
+
+		const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth();
+		const S32 chatbar_panel_min_width = mNearbyChatBar->getMinWidth();
+
+		const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth();
+		const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth();
+
+		const S32 available_width = (chatbar_panel_width - chatbar_panel_min_width)
+			+ (chiclet_panel_width - chiclet_panel_min_width);
+
+		const S32 required_width = panel->getRect().getWidth();
+		can_be_set = available_width >= required_width;
+	}
+
+	if (can_be_set)
+	{
+		setTrayButtonVisible(shown_object_type, visible);
+
+		// if we hide the button mark it NOT to show while future bottom tray extending
+		if (!visible)
+		{
+			mResizeState &= ~shown_object_type;
+		}
+	}
+	else
+	{
+		// mark this button to show it while future bottom tray extending
+		mResizeState |= shown_object_type;
+		LLNotifications::instance().add("BottomTrayButtonCanNotBeShown");
+	}
+}
+
 //EOF
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 2972a2b1ac78c515377360e1aef4b6b2a2f10c08..974289d5e0f290baf5c7b54667bdabe2a942bfe1 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -33,7 +33,7 @@
 #ifndef LL_LLBOTTOMPANEL_H
 #define LL_LLBOTTOMPANEL_H
 
-#include <llmenugl.h>
+#include "llmenugl.h"
 
 #include "llpanel.h"
 #include "llimview.h"
@@ -51,6 +51,7 @@ class LLBottomTray
 	: public LLSingleton<LLBottomTray>
 	, public LLPanel
 	, public LLIMSessionObserver
+	, public LLVoiceClientStatusObserver
 {
 	LOG_CLASS(LLBottomTray);
 	friend class LLSingleton<LLBottomTray>;
@@ -75,6 +76,10 @@ class LLBottomTray
 	virtual void onFocusLost();
 	virtual void setVisible(BOOL visible);
 
+	// Implements LLVoiceClientStatusObserver::onChange() to enable the speak
+	// button when voice is available
+	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
 	void showBottomTrayContextMenu(S32 x, S32 y, MASK mask);
 
 	void showGestureButton(BOOL visible);
@@ -98,14 +103,39 @@ class LLBottomTray
 
 	void updateResizeState(S32 new_width, S32 cur_width);
 	void verifyChildControlsSizes();
-	void processWidthDecreased(S32 delta_width);
+	S32 processWidthDecreased(S32 delta_width);
 	void processWidthIncreased(S32 delta_width);
 	void log(LLView* panel, const std::string& descr);
 	bool processShowButton(EResizeState shown_object_type, S32* available_width, S32* buttons_required_width);
-	void processHideButton(EResizeState shown_object_type, S32* required_width, S32* buttons_freed_width);
-	bool canButtonBeShown(LLPanel* panel) const;
+	void processHideButton(EResizeState processed_object_type, S32* required_width, S32* buttons_freed_width);
+
+	/**
+	 * Determines if specified by type object can be shown. It should be hidden by shrink before.
+	 *
+	 * Processes buttons a such way to show buttons in constant order:
+	 *   - Gestures, Move, View, Snapshot
+	 */
+	bool canButtonBeShown(EResizeState processed_object_type) const;
 	void initStateProcessedObjectMap();
-	void showTrayButton(EResizeState shown_object_type, bool visible);
+
+	/**
+	 * Sets passed visibility to object specified by resize type.
+	 */
+	void setTrayButtonVisible(EResizeState shown_object_type, bool visible);
+
+	/**
+	 * Sets passed visibility to object specified by resize type if it is possible.
+	 *
+	 * If it is impossible to show required button due to there is no enough room in bottom tray
+	 * it will no be shown. Is called via context menu commands.
+	 * In this case Alert Dialog will be shown to notify user about that.
+	 *
+	 * Method also stores resize state to be processed while future bottom tray extending:
+	 *  - if hidden while resizing button should be hidden it will not be shown while extending;
+	 *  - if hidden via context menu button should be shown but there is no enough room for now
+	 *    it will be shown while extending.
+	 */
+	void setTrayButtonVisibleIfPossible(EResizeState shown_object_type, bool visible);
 
 	MASK mResizeState;
 
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 4523267eddbaa6342b2af0365850f0d82d2f1b91..442dc660cdb22da74eef0982dc1d13835ec486b6 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -210,8 +210,9 @@ void LLChatBar::refreshGestures()
 
 		// collect list of unique gestures
 		std::map <std::string, BOOL> unique;
-		LLGestureManager::item_map_t::iterator it;
-		for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it)
+		LLGestureManager::item_map_t::const_iterator it;
+		const LLGestureManager::item_map_t& active_gestures = LLGestureManager::instance().getActiveGestures();
+		for (it = active_gestures.begin(); it != active_gestures.end(); ++it)
 		{
 			LLMultiGesture* gesture = (*it).second;
 			if (gesture)
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 43a1aeaefbb3fd2aaa003d04a0732cfd05529224..f2283730636b9a446e980a6938778b92af4e9081 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -53,7 +53,7 @@ std::string formatCurrentTime()
 	time_t utc_time;
 	utc_time = time_corrected();
 	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
-		+LLTrans::getString("TimeMin")+"] ";
+		+LLTrans::getString("TimeMin")+"]";
 
 	LLSD substitution;
 
@@ -84,6 +84,10 @@ class LLChatHistoryHeader: public LLPanel
 
 		if (level == "profile")
 		{
+			LLSD params;
+			params["object_id"] = getAvatarId();
+
+			LLFloaterReg::showInstance("inspect_object", params);
 		}
 		else if (level == "block")
 		{
@@ -167,7 +171,15 @@ class LLChatHistoryHeader: public LLPanel
 
 	void onHeaderPanelClick(S32 x, S32 y, MASK mask)
 	{
-		LLFloaterReg::showInstance("inspect_avatar", LLSD().insert("avatar_id", mAvatarID));
+		if (mSourceType == CHAT_SOURCE_OBJECT)
+		{
+			LLFloaterReg::showInstance("inspect_object", LLSD().insert("object_id", mAvatarID));
+		}
+		else if (mSourceType == CHAT_SOURCE_AGENT)
+		{
+			LLFloaterReg::showInstance("inspect_avatar", LLSD().insert("avatar_id", mAvatarID));
+		}
+		//if chat source is system, you may add "else" here to define behaviour.
 	}
 
 	const LLUUID&		getAvatarId () const { return mAvatarID;}
@@ -336,7 +348,9 @@ LLView* LLChatHistory::getHeader(const LLChat& chat,const LLStyle::Params& style
 void LLChatHistory::appendWidgetMessage(const LLChat& chat, LLStyle::Params& style_params)
 {
 	LLView* view = NULL;
-	std::string view_text = "\n[" + formatCurrentTime() + "] " + chat.mFromName + ": ";
+	std::string view_text = "\n[" + formatCurrentTime() + "] ";
+	if (utf8str_trim(chat.mFromName).size() != 0 && chat.mFromName != SYSTEM_FROM)
+		view_text += chat.mFromName + ": ";
 
 	LLInlineViewSegment::Params p;
 	p.force_newline = true;
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index fd861926509e1df0feea03d25e0cdcb31e5dc98b..9e290c8c046fcd5d0ff4509deee34c27b7b20de6 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -838,11 +838,15 @@ void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
 	LLUUID session_id = data["session_id"].asUUID();
 	LLUUID from_id = data["from_id"].asUUID();
 	const std::string from = data["from"].asString();
+	S32 unread = data["num_unread"].asInteger();
 
-	//we do not show balloon (indicator of new messages) for system messages and our own messages
-	if (from_id.isNull() || from_id == gAgentID || SYSTEM_FROM == from) return;
+	// if new message came
+	if(unread != 0)
+	{
+		//we do not show balloon (indicator of new messages) for system messages and our own messages
+		if (from_id.isNull() || from_id == gAgentID || SYSTEM_FROM == from) return;
+	}
 
-	S32 unread = data["num_unread"].asInteger();
 	LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
 	if (im_floater && im_floater->getVisible())
 	{
@@ -862,7 +866,6 @@ void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
 	    	llwarns << "Unable to set counter for chiclet " << session_id << llendl;
 	    }
 	}
-
 }
 
 
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 18135fc5587e51a762c6c2745e683bbda45d6157..01603f390def7cef46db24861b61bc4a9414e656 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -901,7 +901,10 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 				menu->buildDrawLabels();
 				menu->updateParent(LLMenuGL::sMenuContainer);
 
-				menu->setButtonRect(mChevronRect, this);
+				if (menu->getButtonRect().isEmpty())
+				{
+					menu->setButtonRect(mChevronRect, this);
+				}
 
 				LLMenuGL::showPopup(this, menu, getRect().getWidth() - menu->getRect().getWidth(), 0);
 				return;
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index d1317f7c3681b84f3ca09b1583ed7b004b195bc6..92e958b32de901891afb156bce19b5d79e2d86d5 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -40,10 +40,12 @@
 // Viewer includes
 #include "lljoystickbutton.h"
 #include "llviewercontrol.h"
+#include "llviewercamera.h"
 #include "llbottomtray.h"
 #include "llagent.h"
 #include "lltoolmgr.h"
 #include "lltoolfocus.h"
+#include "llslider.h"
 
 // Constants
 const F32 CAMERA_BUTTON_DELAY = 0.0f;
@@ -54,6 +56,93 @@ const F32 CAMERA_BUTTON_DELAY = 0.0f;
 #define PRESETS "camera_presets"
 #define CONTROLS "controls"
 
+// Zoom the camera in and out
+class LLPanelCameraZoom
+:	public LLPanel
+{
+	LOG_CLASS(LLPanelCameraZoom);
+public:
+	LLPanelCameraZoom();
+
+	/* virtual */ BOOL	postBuild();
+	/* virtual */ void	onOpen(const LLSD& key);
+
+protected:
+	void	onZoomPlusHeldDown();
+	void	onZoomMinusHeldDown();
+	void	onSliderValueChanged();
+
+private:
+	F32			mSavedSliderVal;
+	LLButton*	mPlusBtn;
+	LLButton*	mMinusBtn;
+	LLSlider*	mSlider;
+};
+
+static LLRegisterPanelClassWrapper<LLPanelCameraZoom> t_camera_zoom_panel("camera_zoom_panel");
+
+//-------------------------------------------------------------------------------
+// LLPanelCameraZoom
+//-------------------------------------------------------------------------------
+
+LLPanelCameraZoom::LLPanelCameraZoom()
+:	mPlusBtn( NULL ),
+	mMinusBtn( NULL ),
+	mSlider( NULL ),
+	mSavedSliderVal(0.f)
+{
+	mCommitCallbackRegistrar.add("Zoom.minus", boost::bind(&LLPanelCameraZoom::onZoomPlusHeldDown, this));
+	mCommitCallbackRegistrar.add("Zoom.plus", boost::bind(&LLPanelCameraZoom::onZoomMinusHeldDown, this));
+	mCommitCallbackRegistrar.add("Slider.value_changed", boost::bind(&LLPanelCameraZoom::onSliderValueChanged, this));
+}
+
+BOOL LLPanelCameraZoom::postBuild()
+{
+	mPlusBtn  = getChild <LLButton> ("zoom_plus_btn");
+	mMinusBtn = getChild <LLButton> ("zoom_minus_btn");
+	mSlider   = getChild <LLSlider> ("zoom_slider");
+	mSlider->setMinValue(.0f);
+	mSlider->setMaxValue(8.f);
+	return LLPanel::postBuild();
+}
+
+void LLPanelCameraZoom::onOpen(const LLSD& key)
+{
+	LLVector3d to_focus = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()) - gAgent.calcFocusPositionTargetGlobal();
+	mSavedSliderVal = 8.f - (F32)to_focus.magVec(); // maximum minus current
+	mSlider->setValue( mSavedSliderVal );
+}
+
+void LLPanelCameraZoom::onZoomPlusHeldDown()
+{
+	F32 val = mSlider->getValueF32();
+	F32 inc = mSlider->getIncrement();
+	mSlider->setValue(val - inc);
+	// commit only if value changed
+	if (val != mSlider->getValueF32())
+		mSlider->onCommit();
+}
+
+void LLPanelCameraZoom::onZoomMinusHeldDown()
+{
+	F32 val = mSlider->getValueF32();
+	F32 inc = mSlider->getIncrement();
+	mSlider->setValue(val + inc);
+	// commit only if value changed
+	if (val != mSlider->getValueF32())
+		mSlider->onCommit();
+}
+
+void  LLPanelCameraZoom::onSliderValueChanged()
+{
+	F32 val	 = mSlider->getValueF32();
+	F32 rate = val - mSavedSliderVal;
+
+	gAgent.unlockView();
+	gAgent.cameraOrbitIn(rate);
+
+	mSavedSliderVal = val;
+}
 
 //
 // Member functions
@@ -125,6 +214,7 @@ void LLFloaterCamera::onOpen(const LLSD& key)
 		anchor_panel, this,
 		getDockTongue(), LLDockControl::TOP));
 
+	mZoom->onOpen(key);
 }
 
 void LLFloaterCamera::onClose(bool app_quitting)
@@ -147,7 +237,7 @@ BOOL LLFloaterCamera::postBuild()
 	setIsChrome(TRUE);
 
 	mRotate = getChild<LLJoystickCameraRotate>(ORBIT);
-	mZoom = getChild<LLJoystickCameraZoom>(ZOOM);
+	mZoom = getChild<LLPanelCameraZoom>(ZOOM);
 	mTrack = getChild<LLJoystickCameraTrack>(PAN);
 
 	assignButton2Mode(CAMERA_CTRL_MODE_ORBIT,			"orbit_btn");
diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h
index 583f279e6276c70d181d9a864f22eee54d10dfa4..4873a34e00ba9672d7407cb71d6e2defffcecf8a 100644
--- a/indra/newview/llfloatercamera.h
+++ b/indra/newview/llfloatercamera.h
@@ -39,6 +39,7 @@ class LLJoystickCameraRotate;
 class LLJoystickCameraZoom;
 class LLJoystickCameraTrack;
 class LLFloaterReg;
+class LLPanelCameraZoom;
 
 enum ECameraControlMode
 {
@@ -74,7 +75,7 @@ class LLFloaterCamera
 	virtual void onClose(bool app_quitting);
 
 	LLJoystickCameraRotate* mRotate;
-	LLJoystickCameraZoom*	mZoom;
+	LLPanelCameraZoom*	mZoom;
 	LLJoystickCameraTrack*	mTrack;
 
 private:
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index c114eed4a2485f043893be704ecde429cb3bb16c..ca0ba96a08f4721218749fcf62a0e9d02b29c1f6 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -89,6 +89,52 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
 	//LLUICtrlFactory::getInstance()->buildFloater(this, "floater_gesture.xml");
 }
 
+void LLFloaterGesture::done()
+{
+	//this method can be called twice: for GestureFolder and once after loading all sudir of GestureFolder
+	if (gInventory.isCategoryComplete(mGestureFolderID))
+	{
+		LL_DEBUGS("Gesture")<< "mGestureFolderID loaded" << LL_ENDL;
+		// we load only gesture folder without childred.
+		LLInventoryModel::cat_array_t* categories;
+		LLInventoryModel::item_array_t* items;
+		folder_ref_t unloaded_folders;
+		LL_DEBUGS("Gesture")<< "Get subdirs of Gesture Folder...." << LL_ENDL;
+		gInventory.getDirectDescendentsOf(mGestureFolderID, categories, items);
+		if (categories->empty())
+		{
+			gInventory.removeObserver(this);
+			LL_INFOS("Gesture")<< "Gesture dos NOT contains sub-directories."<< LL_ENDL;
+			return;
+		}
+		LL_DEBUGS("Gesture")<< "There are " << categories->size() << " Folders "<< LL_ENDL;
+		for (LLInventoryModel::cat_array_t::iterator it = categories->begin(); it != categories->end(); it++)
+		{
+			if (!gInventory.isCategoryComplete(it->get()->getUUID()))
+			{
+				unloaded_folders.push_back(it->get()->getUUID());
+				LL_DEBUGS("Gesture")<< it->get()->getName()<< " Folder added to fetchlist"<< LL_ENDL;
+			}
+
+		}
+		if (!unloaded_folders.empty())
+		{
+			LL_DEBUGS("Gesture")<< "Fetching subdirectories....." << LL_ENDL;
+			fetchDescendents(unloaded_folders);
+		}
+		else
+		{
+			LL_DEBUGS("Gesture")<< "All Gesture subdirectories have been loaded."<< LL_ENDL;
+			gInventory.removeObserver(this);
+			buildGestureList();
+		}
+	}
+	else
+	{
+		LL_WARNS("Gesture")<< "Gesture list was NOT loaded"<< LL_ENDL;
+	}
+}
+
 // virtual
 LLFloaterGesture::~LLFloaterGesture()
 {
@@ -121,7 +167,14 @@ BOOL LLFloaterGesture::postBuild()
 	childSetVisible("play_btn", true);
 	childSetVisible("stop_btn", false);
 	setDefaultBtn("play_btn");
-	
+	mGestureFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE, false);
+
+	folder_ref_t folders;
+	folders.push_back(mGestureFolderID);
+	//perform loading Gesture directory anyway to make sure that all subdirectory are loaded too. See method done() for details.
+	gInventory.addObserver(this);
+	fetchDescendents(folders);
+
 	buildGestureList();
 	
 	childSetFocus("gesture_list");
@@ -171,101 +224,125 @@ void LLFloaterGesture::buildGestureList()
 
 	if (! (list && scroll)) return;
 
-	// attempt to preserve scroll position through re-builds
-	// since we do re-build any time anything dirties
-	S32 current_scroll_pos = scroll->getScrollPos();
-	
+	LLUUID selected_item = list->getCurrentID();
+	LL_DEBUGS("Gesture")<< "Rebuilding gesture list "<< LL_ENDL;
 	list->operateOnAll(LLCtrlListInterface::OP_DELETE);
 
-	LLGestureManager::item_map_t::iterator it;
-	for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it)
+	LLGestureManager::item_map_t::const_iterator it;
+	const LLGestureManager::item_map_t& active_gestures = LLGestureManager::instance().getActiveGestures();
+	for (it = active_gestures.begin(); it != active_gestures.end(); ++it)
 	{
-		const LLUUID& item_id = (*it).first;
-		LLMultiGesture* gesture = (*it).second;
+		addGesture(it->first,it->second, list);
+	}
+	if (gInventory.isCategoryComplete(mGestureFolderID))
+	{
+		LLIsType is_gesture(LLAssetType::AT_GESTURE);
+		LLInventoryModel::cat_array_t categories;
+		LLInventoryModel::item_array_t items;
+		gInventory.collectDescendentsIf(mGestureFolderID, categories, items,
+				LLInventoryModel::EXCLUDE_TRASH, is_gesture);
 
-		// Note: Can have NULL item if inventory hasn't arrived yet.
-		std::string item_name = getString("loading");
-		LLInventoryItem* item = gInventory.getItem(item_id);
-		if (item)
+		for (LLInventoryModel::item_array_t::iterator it = items.begin(); it!= items.end(); ++it)
 		{
-			item_name = item->getName();
+			LLInventoryItem* item = it->get();
+			if (active_gestures.find(item->getUUID()) == active_gestures.end())
+			{
+				// if gesture wasn't loaded yet, we can display only name
+				addGesture(item->getUUID(), NULL, list);
+			}
 		}
+	}
+	// attempt to preserve scroll position through re-builds
+	// since we do re-build any time anything dirties
+	if(list->selectByValue(LLSD(selected_item)))
+	{
+		scroll->scrollToShowSelected();
+	}
+}
 
-		std::string font_style = "NORMAL";
-		// If gesture is playing, bold it
+void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gesture,LLCtrlListInterface * list )
+{
+	// Note: Can have NULL item if inventory hasn't arrived yet.
+	static std::string item_name = getString("loading");
+	LLInventoryItem* item = gInventory.getItem(item_id);
+	if (item)
+	{
+		item_name = item->getName();
+	}
+
+	static std::string font_style = "NORMAL";
+	// If gesture is playing, bold it
 
-		LLSD element;
-		element["id"] = item_id;
+	LLSD element;
+	element["id"] = item_id;
 
-		if (gesture)
+	if (gesture)
+	{
+		if (gesture->mPlaying)
 		{
-			if (gesture->mPlaying)
-			{
-				font_style = "BOLD";
-			}
+			font_style = "BOLD";
+		}
 
-			element["columns"][0]["column"] = "trigger";
-			element["columns"][0]["value"] = gesture->mTrigger;
-			element["columns"][0]["font"]["name"] = "SANSSERIF";
-			element["columns"][0]["font"]["style"] = font_style;
+		element["columns"][0]["column"] = "trigger";
+		element["columns"][0]["value"] = gesture->mTrigger;
+		element["columns"][0]["font"]["name"] = "SANSSERIF";
+		element["columns"][0]["font"]["style"] = font_style;
 
-			std::string key_string = LLKeyboard::stringFromKey(gesture->mKey);
-			std::string buffer;
+		std::string key_string = LLKeyboard::stringFromKey(gesture->mKey);
+		std::string buffer;
 
-			if (gesture->mKey == KEY_NONE)
-			{
-				buffer = "---";
-				key_string = "~~~";		// alphabetize to end
-			}
-			else
-			{
-				buffer = LLKeyboard::stringFromAccelerator( gesture->mMask, gesture->mKey );
-			}
+		if (gesture->mKey == KEY_NONE)
+		{
+			buffer = "---";
+			key_string = "~~~"; // alphabetize to end
+		}
+		else
+		{
+			buffer = LLKeyboard::stringFromAccelerator(gesture->mMask,
+					gesture->mKey);
+		}
 
-			element["columns"][1]["column"] = "shortcut";
-			element["columns"][1]["value"] = buffer;
-			element["columns"][1]["font"]["name"] = "SANSSERIF";
-			element["columns"][1]["font"]["style"] = font_style;
+		element["columns"][1]["column"] = "shortcut";
+		element["columns"][1]["value"] = buffer;
+		element["columns"][1]["font"]["name"] = "SANSSERIF";
+		element["columns"][1]["font"]["style"] = font_style;
 
-			// hidden column for sorting
-			element["columns"][2]["column"] = "key";
-			element["columns"][2]["value"] = key_string;
-			element["columns"][2]["font"]["name"] = "SANSSERIF";
-			element["columns"][2]["font"]["style"] = font_style;
+		// hidden column for sorting
+		element["columns"][2]["column"] = "key";
+		element["columns"][2]["value"] = key_string;
+		element["columns"][2]["font"]["name"] = "SANSSERIF";
+		element["columns"][2]["font"]["style"] = font_style;
 
-			// Only add "playing" if we've got the name, less confusing. JC
-			if (item && gesture->mPlaying)
-			{
-				item_name += " " + getString("playing");
-			}
-			element["columns"][3]["column"] = "name";
-			element["columns"][3]["value"] = item_name;
-			element["columns"][3]["font"]["name"] = "SANSSERIF";
-			element["columns"][3]["font"]["style"] = font_style;
-		}
-		else
+		// Only add "playing" if we've got the name, less confusing. JC
+		if (item && gesture->mPlaying)
 		{
-			element["columns"][0]["column"] = "trigger";
-			element["columns"][0]["value"] = "";
-			element["columns"][0]["font"]["name"] = "SANSSERIF";
-			element["columns"][0]["font"]["style"] = font_style;
-			element["columns"][0]["column"] = "trigger";
-			element["columns"][0]["value"] = "---";
-			element["columns"][0]["font"]["name"] = "SANSSERIF";
-			element["columns"][0]["font"]["style"] = font_style;
-			element["columns"][2]["column"] = "key";
-			element["columns"][2]["value"] = "~~~";
-			element["columns"][2]["font"]["name"] = "SANSSERIF";
-			element["columns"][2]["font"]["style"] = font_style;
-			element["columns"][3]["column"] = "name";
-			element["columns"][3]["value"] = item_name;
-			element["columns"][3]["font"]["name"] = "SANSSERIF";
-			element["columns"][3]["font"]["style"] = font_style;
+			item_name += " " + getString("playing");
 		}
-		list->addElement(element, ADD_BOTTOM);
+		element["columns"][3]["column"] = "name";
+		element["columns"][3]["value"] = item_name;
+		element["columns"][3]["font"]["name"] = "SANSSERIF";
+		element["columns"][3]["font"]["style"] = font_style;
 	}
-	
-	scroll->setScrollPos(current_scroll_pos);
+	else
+	{
+		element["columns"][0]["column"] = "trigger";
+		element["columns"][0]["value"] = "";
+		element["columns"][0]["font"]["name"] = "SANSSERIF";
+		element["columns"][0]["font"]["style"] = font_style;
+		element["columns"][0]["column"] = "trigger";
+		element["columns"][0]["value"] = "---";
+		element["columns"][0]["font"]["name"] = "SANSSERIF";
+		element["columns"][0]["font"]["style"] = font_style;
+		element["columns"][2]["column"] = "key";
+		element["columns"][2]["value"] = "~~~";
+		element["columns"][2]["font"]["name"] = "SANSSERIF";
+		element["columns"][2]["font"]["style"] = font_style;
+		element["columns"][3]["column"] = "name";
+		element["columns"][3]["value"] = item_name;
+		element["columns"][3]["font"]["name"] = "SANSSERIF";
+		element["columns"][3]["font"]["style"] = font_style;
+	}
+	list->addElement(element, ADD_BOTTOM);
 }
 
 void LLFloaterGesture::onClickInventory()
@@ -284,14 +361,21 @@ void LLFloaterGesture::onClickPlay()
 	LLCtrlListInterface *list = childGetListInterface("gesture_list");
 	if (!list) return;
 	const LLUUID& item_id = list->getCurrentID();
+	if(item_id.isNull()) return;
 
-	if (LLGestureManager::instance().isGesturePlaying(item_id))
+	LL_DEBUGS("Gesture")<<" Trying to play gesture id: "<< item_id <<LL_ENDL;
+	if(!LLGestureManager::instance().isGestureActive(item_id))
 	{
-		LLGestureManager::instance().stopGesture(item_id);
+		// we need to inform server about gesture activating to be consistent with LLPreviewGesture.
+		BOOL inform_server = TRUE;
+		BOOL deactivate_similar = FALSE;
+		LLGestureManager::instance().activateGestureWithAsset(item_id, gInventory.getItem(item_id)->getAssetUUID(), inform_server, deactivate_similar);
+		LL_DEBUGS("Gesture")<< "Activating gesture with inventory ID: " << item_id <<LL_ENDL;
+		LLGestureManager::instance().setGestureLoadedCallback(item_id, boost::bind(&LLFloaterGesture::playGesture, this, item_id));
 	}
 	else
 	{
-		LLGestureManager::instance().playGesture(item_id);
+		playGesture(item_id);
 	}
 }
 
@@ -345,3 +429,14 @@ void LLFloaterGesture::onCommitList()
 		childSetVisible("stop_btn", false);
 	}
 }
+void LLFloaterGesture::playGesture(LLUUID item_id)
+{
+	if (LLGestureManager::instance().isGesturePlaying(item_id))
+	{
+		LLGestureManager::instance().stopGesture(item_id);
+	}
+	else
+	{
+		LLGestureManager::instance().playGesture(item_id);
+	}
+}
diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h
index 9c1ab27cb0c7389491cb6027fa95a23db61bb4b6..9d047bf1cf8a02030a030667e13ea8aa1eb97d45 100644
--- a/indra/newview/llfloatergesture.h
+++ b/indra/newview/llfloatergesture.h
@@ -38,7 +38,7 @@
 #define LL_LLFLOATERGESTURE_H
 
 #include "llfloater.h"
-
+#include "llinventorymodel.h"
 #include "lldarray.h"
 
 class LLScrollContainer;
@@ -51,31 +51,35 @@ class LLGestureOptions;
 class LLScrollListCtrl;
 class LLFloaterGestureObserver;
 class LLFloaterGestureInventoryObserver;
+class LLMultiGesture;
 
 class LLFloaterGesture
-:	public LLFloater
+:	public LLFloater, LLInventoryFetchDescendentsObserver
 {
+	LOG_CLASS(LLFloaterGesture);
 public:
 	LLFloaterGesture(const LLSD& key);
 	virtual ~LLFloaterGesture();
 
 	virtual BOOL postBuild();
-
+	virtual void done ();
 	void refreshAll();
 
 protected:
 	// Reads from the gesture manager's list of active gestures
 	// and puts them in this list.
 	void buildGestureList();
-
+	void addGesture(const LLUUID& item_id, LLMultiGesture* gesture, LLCtrlListInterface * list);
 	void onClickInventory();
 	void onClickEdit();
 	void onClickPlay();
 	void onClickNew();
 	void onCommitList();
+	void playGesture(LLUUID item_id);
 
 protected:
 	LLUUID mSelectedID;
+	LLUUID mGestureFolderID;
 
 	LLFloaterGestureObserver* mObserver;
 };
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 1ff2566dca235c17fff0b3b7fb726ee0ab60dafd..481b75cf73965b7a04b79eec9e24b2d85cd928ba 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -91,44 +91,39 @@ const LLUUID& get_folder_uuid(const LLUUID& parentFolderUUID, LLInventoryCollect
 	return LLUUID::null;
 }
 
-
-// LLViewerInventoryCategory::fetchDescendents has it own period of fetching.
-// for now it is FETCH_TIMER_EXPIRY = 10.0f; So made our period a bit more.
-const F32 FETCH_FRIENDS_DESCENDENTS_PERIOD = 11.0f;
-
-
 /**
- * Intended to call passed callback after the specified period of time.
+ * Class for fetching initial friend cards data
  *
- * Implemented to fix an issue when Inventory folders are in incomplete state. See EXT-2061, EXT-1935, EXT-813.
- * For now it uses to periodically sync Inventory Friends/All folder with a Agent's Friends List
- * until it is complete.
- */ 
-class FriendListUpdater : public LLEventTimer
+ * Implemented to fix an issue when Inventory folders are in incomplete state.
+ * See EXT-2320, EXT-2061, EXT-1935, EXT-813.
+ * Uses a callback to sync Inventory Friends/All folder with agent's Friends List.
+ */
+class LLInitialFriendCardsFetch : public LLInventoryFetchDescendentsObserver
 {
 public:
-	typedef boost::function<bool()> callback_t;
+	typedef boost::function<void()> callback_t;
 
-	FriendListUpdater(callback_t cb, F32 period)
-		:	LLEventTimer(period)
-		,	mCallback(cb)
-	{
-		mEventTimer.start();
-	}
+	LLInitialFriendCardsFetch(callback_t cb)
+		:	mCheckFolderCallback(cb)	{}
 
-	virtual BOOL tick() // from LLEventTimer
-	{
-		return mCallback();
-	}
+	/* virtual */ void done();
 
 private:
-	callback_t		mCallback;
+	callback_t		mCheckFolderCallback;
 };
 
+void LLInitialFriendCardsFetch::done()
+{
+	// This observer is no longer needed.
+	gInventory.removeObserver(this);
+
+	mCheckFolderCallback();
+
+	delete this;
+}
 
 // LLFriendCardsManager Constructor / Destructor
 LLFriendCardsManager::LLFriendCardsManager()
-: mFriendsAllFolderCompleted(true)
 {
 	LLAvatarTracker::instance().addObserver(this);
 }
@@ -167,30 +162,6 @@ const LLUUID LLFriendCardsManager::extractAvatarID(const LLUUID& avatarID)
 	return rv;
 }
 
-// be sure LLInventoryModel::buildParentChildMap() has been called before it.
-// and this method must be called before any actions with friend list
-void LLFriendCardsManager::ensureFriendFoldersExist()
-{
-	const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
-
-	LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
-
-	if (friendFolderUUID.isNull())
-	{
-		friendFolderUUID = gInventory.createNewCategory(callingCardsFolderID,
-			LLFolderType::FT_CALLINGCARD, get_friend_folder_name());
-	}
-
-	LLUUID friendAllSubfolderUUID = findFriendAllSubfolderUUIDImpl();
-
-	if (friendAllSubfolderUUID.isNull())
-	{
-		friendAllSubfolderUUID = gInventory.createNewCategory(friendFolderUUID,
-			LLFolderType::FT_CALLINGCARD, get_friend_all_subfolder_name());
-	}
-}
-
-
 bool LLFriendCardsManager::isItemInAnyFriendsList(const LLViewerInventoryItem* item)
 {
 	if (item->getType() != LLAssetType::AT_CALLINGCARD)
@@ -305,63 +276,12 @@ bool LLFriendCardsManager::isAnyFriendCategory(const LLUUID& catID) const
 	return TRUE == gInventory.isObjectDescendentOf(catID, friendFolderID);
 }
 
-bool LLFriendCardsManager::syncFriendsFolder()
+void LLFriendCardsManager::syncFriendCardsFolders()
 {
-	//lets create "Friends" and "Friends/All" in the Inventory "Calling Cards" if they are absent
-	LLFriendCardsManager::instance().ensureFriendFoldersExist();
-
-	LLAvatarTracker::buddy_map_t all_buddies;
-	LLAvatarTracker::instance().copyBuddyList(all_buddies);
-
-	// 1. Remove Friend Cards for non-friends
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-
-	gInventory.collectDescendents(findFriendAllSubfolderUUIDImpl(), cats, items, LLInventoryModel::EXCLUDE_TRASH);
-	
-	LLInventoryModel::item_array_t::const_iterator it;
-	for (it = items.begin(); it != items.end(); ++it)
-	{
-		lldebugs << "Check if buddy is in list: " << (*it)->getName() << " " << (*it)->getCreatorUUID() << llendl;
-		if (NULL == get_ptr_in_map(all_buddies, (*it)->getCreatorUUID()))
-		{
-			lldebugs << "NONEXISTS, so remove it" << llendl;
-			removeFriendCardFromInventory((*it)->getCreatorUUID());
-		}
-	}
-
-	// 2. Add missing Friend Cards for friends
-	LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
-	llinfos << "try to build friends, count: " << all_buddies.size() << llendl; 
-	mFriendsAllFolderCompleted = true;
-	for(; buddy_it != all_buddies.end(); ++buddy_it)
-	{
-		const LLUUID& buddy_id = (*buddy_it).first;
-		addFriendCardToInventory(buddy_id);
-	}
-
-	if (!mFriendsAllFolderCompleted)
-	{
-		forceFriendListIsLoaded(findFriendAllSubfolderUUIDImpl());
-
-		static bool timer_started = false;
-		if (!timer_started)
-		{
-			lldebugs << "Create and start timer to sync Inventory Friends All folder with Friends list" << llendl;
-
-			// do not worry about destruction of the FriendListUpdater. 
-			// It will be deleted by LLEventTimer::updateClass when FriendListUpdater::tick() returns true.
-			new FriendListUpdater(boost::bind(&LLFriendCardsManager::syncFriendsFolder, this),
-				FETCH_FRIENDS_DESCENDENTS_PERIOD);
-		}
-		timer_started = true;
-	}
-	else
-	{
-		lldebugs << "Friends/All Inventory folder is synchronized with the Agent's Friends List" << llendl;
-	}
+	const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
 
-	return mFriendsAllFolderCompleted;
+	fetchAndCheckFolderDescendents(callingCardsFolderID,
+			boost::bind(&LLFriendCardsManager::ensureFriendsFolderExists, this));
 }
 
 void LLFriendCardsManager::collectFriendsLists(folderid_buddies_map_t& folderBuddiesMap) const
@@ -482,6 +402,122 @@ void LLFriendCardsManager::findMatchedFriendCards(const LLUUID& avatarID, LLInve
 	}
 }
 
+void LLFriendCardsManager::fetchAndCheckFolderDescendents(const LLUUID& folder_id,  callback_t cb)
+{
+	// This instance will be deleted in LLInitialFriendCardsFetch::done().
+	LLInitialFriendCardsFetch* fetch = new LLInitialFriendCardsFetch(cb);
+
+	LLInventoryFetchDescendentsObserver::folder_ref_t folders;
+	folders.push_back(folder_id);
+
+	fetch->fetchDescendents(folders);
+	if(fetch->isEverythingComplete())
+	{
+		// everything is already here - call done.
+		fetch->done();
+	}
+	else
+	{
+		// it's all on it's way - add an observer, and the inventory
+		// will call done for us when everything is here.
+		gInventory.addObserver(fetch);
+	}
+}
+
+// Make sure LLInventoryModel::buildParentChildMap() has been called before it.
+// This method must be called before any actions with friends list.
+void LLFriendCardsManager::ensureFriendsFolderExists()
+{
+	const LLUUID calling_cards_folder_ID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+
+	// If "Friends" folder exists in "Calling Cards" we should check if "All" sub-folder
+	// exists in "Friends", otherwise we create it.
+	LLUUID friends_folder_ID = findFriendFolderUUIDImpl();
+	if (friends_folder_ID.notNull())
+	{
+		fetchAndCheckFolderDescendents(friends_folder_ID,
+				boost::bind(&LLFriendCardsManager::ensureFriendsAllFolderExists, this));
+	}
+	else
+	{
+		if (!gInventory.isCategoryComplete(calling_cards_folder_ID))
+		{
+			LLViewerInventoryCategory* cat = gInventory.getCategory(calling_cards_folder_ID);
+			std::string cat_name = cat ? cat->getName() : "unknown";
+			llwarns << "Failed to find \"" << cat_name << "\" category descendents in Category Tree." << llendl;
+		}
+
+		friends_folder_ID = gInventory.createNewCategory(calling_cards_folder_ID,
+			LLFolderType::FT_CALLINGCARD, get_friend_folder_name());
+
+		gInventory.createNewCategory(friends_folder_ID,
+			LLFolderType::FT_CALLINGCARD, get_friend_all_subfolder_name());
+
+		// Now when we have all needed folders we can sync their contents with buddies list.
+		syncFriendsFolder();
+	}
+}
+
+// Make sure LLFriendCardsManager::ensureFriendsFolderExists() has been called before it.
+void LLFriendCardsManager::ensureFriendsAllFolderExists()
+{
+	LLUUID friends_all_folder_ID = findFriendAllSubfolderUUIDImpl();
+	if (friends_all_folder_ID.notNull())
+	{
+		fetchAndCheckFolderDescendents(friends_all_folder_ID,
+				boost::bind(&LLFriendCardsManager::syncFriendsFolder, this));
+	}
+	else
+	{
+		LLUUID friends_folder_ID = findFriendFolderUUIDImpl();
+
+		if (!gInventory.isCategoryComplete(friends_folder_ID))
+		{
+			LLViewerInventoryCategory* cat = gInventory.getCategory(friends_folder_ID);
+			std::string cat_name = cat ? cat->getName() : "unknown";
+			llwarns << "Failed to find \"" << cat_name << "\" category descendents in Category Tree." << llendl;
+		}
+
+		friends_all_folder_ID = gInventory.createNewCategory(friends_folder_ID,
+			LLFolderType::FT_CALLINGCARD, get_friend_all_subfolder_name());
+
+		// Now when we have all needed folders we can sync their contents with buddies list.
+		syncFriendsFolder();
+	}
+}
+
+void LLFriendCardsManager::syncFriendsFolder()
+{
+	LLAvatarTracker::buddy_map_t all_buddies;
+	LLAvatarTracker::instance().copyBuddyList(all_buddies);
+
+	// 1. Remove Friend Cards for non-friends
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+
+	gInventory.collectDescendents(findFriendAllSubfolderUUIDImpl(), cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+	LLInventoryModel::item_array_t::const_iterator it;
+	for (it = items.begin(); it != items.end(); ++it)
+	{
+		lldebugs << "Check if buddy is in list: " << (*it)->getName() << " " << (*it)->getCreatorUUID() << llendl;
+		if (NULL == get_ptr_in_map(all_buddies, (*it)->getCreatorUUID()))
+		{
+			lldebugs << "NONEXISTS, so remove it" << llendl;
+			removeFriendCardFromInventory((*it)->getCreatorUUID());
+		}
+	}
+
+	// 2. Add missing Friend Cards for friends
+	LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
+	llinfos << "try to build friends, count: " << all_buddies.size() << llendl;
+	for(; buddy_it != all_buddies.end(); ++buddy_it)
+	{
+		const LLUUID& buddy_id = (*buddy_it).first;
+		addFriendCardToInventory(buddy_id);
+	}
+}
+
 class CreateFriendCardCallback : public LLInventoryCallback
 {
 public:
@@ -494,9 +530,8 @@ class CreateFriendCardCallback : public LLInventoryCallback
 	}
 };
 
-bool LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
+void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
 {
-	LLInventoryModel* invModel = &gInventory;
 
 	bool shouldBeAdded = true;
 	std::string name;
@@ -518,13 +553,6 @@ bool LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
 		lldebugs << "is found in sentRequests: " << name << llendl; 
 	}
 
-	LLUUID friendListFolderID = findFriendAllSubfolderUUIDImpl();
-	if (friendListFolderID.notNull() && shouldBeAdded && !invModel->isCategoryComplete(friendListFolderID))
-	{
-		mFriendsAllFolderCompleted = false;
-		shouldBeAdded = false;
-		lldebugs << "Friends/All category is not completed" << llendl; 
-	}
 	if (shouldBeAdded)
 	{
 		putAvatarData(avatarID);
@@ -533,10 +561,8 @@ bool LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
 		// TODO: mantipov: Is CreateFriendCardCallback really needed? Probably not
 		LLPointer<LLInventoryCallback> cb = new CreateFriendCardCallback();
 
-		create_inventory_callingcard(avatarID, friendListFolderID, cb);
+		create_inventory_callingcard(avatarID, findFriendAllSubfolderUUIDImpl(), cb);
 	}
-
-	return shouldBeAdded;
 }
 
 void LLFriendCardsManager::removeFriendCardFromInventory(const LLUUID& avatarID)
@@ -582,11 +608,4 @@ void LLFriendCardsManager::onFriendListUpdate(U32 changed_mask)
 	}
 }
 
-void LLFriendCardsManager::forceFriendListIsLoaded(const LLUUID& folder_id) const
-{
-	bool fetching_inventory = gInventory.fetchDescendentsOf(folder_id);
-	lldebugs << "Trying to fetch descendants of Friends/All Inventory folder, fetched: "
-		<< fetching_inventory << llendl;
-}
-
 // EOF
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index feea05bc1dcc8cc3df219590686a48c344d2aee4..98dc3153d0de47d2efae46e146a6f46754de1800 100644
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
@@ -57,14 +57,6 @@ class LLFriendCardsManager
 		onFriendListUpdate(mask);
 	}
 
-	/**
-	 *	Ensures that all necessary folders are created in Inventory.
-	 * 
-	 *	For now it processes Calling Card, Calling Card/Friends & Calling Card/Friends/All folders
-	 */
-	void ensureFriendFoldersExist();
-
-
 	/**
 	 *	Determines if specified Inventory Calling Card exists in any of lists 
 	 *	in the Calling Card/Friends/ folder (Default, or Custom)
@@ -88,11 +80,10 @@ class LLFriendCardsManager
 	bool isAnyFriendCategory(const LLUUID& catID) const;
 
 	/**
-	 *	Synchronizes content of the Calling Card/Friends/All Global Inventory folder with Agent's Friend List
-	 *
-	 *	@return true - if folder is already synchronized, false otherwise.
+	 *	Checks whether "Friends" and "Friends/All" folders exist in "Calling Cards" category
+	 *	(creates them otherwise) and fetches their contents to synchronize with Agent's Friends List.
 	 */
-	bool syncFriendsFolder();
+	void syncFriendCardsFolders();
 
 	/*!
 	 * \brief
@@ -108,6 +99,8 @@ class LLFriendCardsManager
 	void collectFriendsLists(folderid_buddies_map_t& folderBuddiesMap) const;
 
 private:
+	typedef boost::function<void()> callback_t;
+
 	LLFriendCardsManager();
 	~LLFriendCardsManager();
 
@@ -133,10 +126,29 @@ class LLFriendCardsManager
 	const LLUUID& findFriendCardInventoryUUIDImpl(const LLUUID& avatarID);
 	void findMatchedFriendCards(const LLUUID& avatarID, LLInventoryModel::item_array_t& items) const;
 
+	void fetchAndCheckFolderDescendents(const LLUUID& folder_id, callback_t cb);
+
+	/**
+	 *	Checks whether "Calling Cards/Friends" folder exists. If not, creates it with "All"
+	 *	sub-folder and synchronizes its contents with buddies list.
+	 */
+	void ensureFriendsFolderExists();
+
+	/**
+	 *	Checks whether "Calling Cards/Friends/All" folder exists. If not, creates it and
+	 *	synchronizes its contents with buddies list.
+	 */
+	void ensureFriendsAllFolderExists();
+
+	/**
+	 *	Synchronizes content of the Calling Card/Friends/All Global Inventory folder with Agent's Friend List
+	 */
+	void syncFriendsFolder();
+
 	/**
 	 *	Adds avatar specified by its UUID into the Calling Card/Friends/All Global Inventory folder
 	 */
-	bool addFriendCardToInventory(const LLUUID& avatarID);
+	void addFriendCardToInventory(const LLUUID& avatarID);
 
 	/**
 	 *	Removes an avatar specified by its UUID from the Calling Card/Friends/All Global Inventory folder
@@ -146,20 +158,11 @@ class LLFriendCardsManager
 
 	void onFriendListUpdate(U32 changed_mask);
 
-	/**
-	 * Force fetching of the Inventory folder specified by passed folder's LLUUID.
-	 *
-	 * It only sends request to server, server reply should be processed in other place.
-	 * Because request can be sent via UDP we need to periodically check if request was completed with success.
-	 */
-	void forceFriendListIsLoaded(const LLUUID& folder_id) const;
-
 
 private:
 	typedef std::set<LLUUID> avatar_uuid_set_t;
 
 	avatar_uuid_set_t mBuddyIDSet;
-	bool mFriendsAllFolderCompleted;
 };
 
 #endif // LL_LLFRIENDCARD_H
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 59274c8638cff9b395f1a8d1b0f2f981015f393a..8e774dc199bb591b3120e28660168627aec95530 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -37,7 +37,6 @@
 // system
 #include <functional>
 #include <algorithm>
-#include <boost/tokenizer.hpp>
 
 // library
 #include "lldatapacker.h"
@@ -206,6 +205,9 @@ struct LLLoadInfo
 
 // If inform_server is true, will send a message upstream to update
 // the user_gesture_active table.
+/**
+ * It will load a gesture from remote storage
+ */
 void LLGestureManager::activateGestureWithAsset(const LLUUID& item_id,
 												const LLUUID& asset_id,
 												BOOL inform_server,
@@ -921,8 +923,8 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,
 
 	delete info;
 	info = NULL;
-
-	LLGestureManager::instance().mLoadingCount--;
+	LLGestureManager& self = LLGestureManager::instance();
+	self.mLoadingCount--;
 
 	if (0 == status)
 	{
@@ -944,15 +946,15 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,
 		{
 			if (deactivate_similar)
 			{
-				LLGestureManager::instance().deactivateSimilarGestures(gesture, item_id);
+				self.deactivateSimilarGestures(gesture, item_id);
 
 				// Display deactivation message if this was the last of the bunch.
-				if (LLGestureManager::instance().mLoadingCount == 0
-					&& LLGestureManager::instance().mDeactivateSimilarNames.length() > 0)
+				if (self.mLoadingCount == 0
+					&& self.mDeactivateSimilarNames.length() > 0)
 				{
 					// we're done with this set of deactivations
 					LLSD args;
-					args["NAMES"] = LLGestureManager::instance().mDeactivateSimilarNames;
+					args["NAMES"] = self.mDeactivateSimilarNames;
 					LLNotifications::instance().add("DeactivatedGesturesTrigger", args);
 				}
 			}
@@ -965,9 +967,9 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,
 			else
 			{
 				// Watch this item and set gesture name when item exists in inventory
-				LLGestureManager::instance().watchItem(item_id);
+				self.watchItem(item_id);
 			}
-			LLGestureManager::instance().mActive[item_id] = gesture;
+			self.mActive[item_id] = gesture;
 
 			// Everything has been successful.  Add to the active list.
 			gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
@@ -989,14 +991,21 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,
 
 				gAgent.sendReliableMessage();
 			}
+			callback_map_t::iterator i_cb = self.mCallbackMap.find(item_id);
+			
+			if(i_cb != self.mCallbackMap.end())
+			{
+				i_cb->second(gesture);
+				self.mCallbackMap.erase(i_cb);
+			}
 
-			LLGestureManager::instance().notifyObservers();
+			self.notifyObservers();
 		}
 		else
 		{
 			llwarns << "Unable to load gesture" << llendl;
 
-			LLGestureManager::instance().mActive.erase(item_id);
+			self.mActive.erase(item_id);
 			
 			delete gesture;
 			gesture = NULL;
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index 947773d66dc18cf973af928df955ae05ba1a744b..7c3b7427808038ccb3d07f971c10d24a5731977b 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -57,6 +57,12 @@ class LLGestureManagerObserver
 class LLGestureManager : public LLSingleton<LLGestureManager>, public LLInventoryCompletionObserver
 {
 public:
+
+	typedef boost::function<void (LLMultiGesture* loaded_gesture)> gesture_loaded_callback_t;
+	// Maps inventory item_id to gesture
+	typedef std::map<LLUUID, LLMultiGesture*> item_map_t;
+	typedef std::map<LLUUID, gesture_loaded_callback_t> callback_map_t;
+
 	LLGestureManager();
 	~LLGestureManager();
 
@@ -97,6 +103,7 @@ class LLGestureManager : public LLSingleton<LLGestureManager>, public LLInventor
 
 	BOOL isGesturePlaying(const LLUUID& item_id);
 
+	const item_map_t& getActiveGestures() const { return mActive; }
 	// Force a gesture to be played, for example, if it is being
 	// previewed.
 	void playGesture(LLMultiGesture* gesture);
@@ -106,7 +113,15 @@ class LLGestureManager : public LLSingleton<LLGestureManager>, public LLInventor
 	// Also remove from playing list
 	void stopGesture(LLMultiGesture* gesture);
 	void stopGesture(const LLUUID& item_id);
-
+	/**
+	 * Add cb into callbackMap.
+	 * Note:
+	 * Manager will call cb after gesture will be loaded and will remove cb automatically. 
+	 */
+	void setGestureLoadedCallback(LLUUID inv_item_id, gesture_loaded_callback_t cb)
+	{
+		mCallbackMap[inv_item_id] = cb;
+	}
 	// Trigger the first gesture that matches this key.
 	// Returns TRUE if it finds a gesture bound to that key.
 	BOOL triggerGesture(KEY key, MASK mask);
@@ -144,13 +159,7 @@ class LLGestureManager : public LLSingleton<LLGestureManager>, public LLInventor
 						   LLAssetType::EType type,
 						   void* user_data, S32 status, LLExtStat ext_status);
 
-public:
-	BOOL mValid;
-	std::vector<LLMultiGesture*> mPlaying;
-
-	// Maps inventory item_id to gesture
-	typedef std::map<LLUUID, LLMultiGesture*> item_map_t;
-
+private:
 	// Active gestures.
 	// NOTE: The gesture pointer CAN BE NULL.  This means that
 	// there is a gesture with that item_id, but the asset data
@@ -159,8 +168,11 @@ class LLGestureManager : public LLSingleton<LLGestureManager>, public LLInventor
 
 	S32 mLoadingCount;
 	std::string mDeactivateSimilarNames;
-
+	
 	std::vector<LLGestureManagerObserver*> mObservers;
+	callback_map_t mCallbackMap;
+	std::vector<LLMultiGesture*> mPlaying;	
+	BOOL mValid;
 };
 
 #endif
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 5ea900e46d9a8fca6eddc041bf711eb98c7cccc9..059912d5d4fc4c95e6a8ba5825b8397f0ffe40e9 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -120,11 +120,7 @@ void LLIMFloater::newIMCallback(const LLSD& data){
 		LLUUID session_id = data["session_id"].asUUID();
 
 		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-		if (floater == NULL)
-		{
-			llwarns << "new_im_callback for non-existent session_id " << session_id << llendl;
-			return;
-		}
+		if (floater == NULL) return;
 
         // update if visible, otherwise will be updated when opened
 		if (floater->getVisible())
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 0b8b5935f874000a0a7f1b3afc31979c830fa917..87b801d73b6b707ccf0f194a31591bbc67e26fd3 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -848,8 +848,11 @@ void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
 		}
 
 
-		//update the speakers dropdown too
-		mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
+		//update the speakers dropdown too, if it's available
+		if (mSpeakerPanel)
+		{
+			mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
+		}
 	}
 }
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 9c38d9c5fc3354f2c6b6437f1e78b4d1fce89f7b..ee785e7ecbb4aa9e288bfc6f33bd65600ff91182 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -46,6 +46,7 @@
 
 #include "llagent.h"
 #include "llavatariconctrl.h"
+#include "llbottomtray.h"
 #include "llcallingcard.h"
 #include "llchat.h"
 #include "llresmgr.h"
@@ -73,6 +74,7 @@
 #include "llvoicechannel.h"
 #include "lltrans.h"
 #include "llrecentpeople.h"
+#include "llsyswellwindow.h"
 
 #include "llfirstuse.h"
 #include "llagentui.h"
@@ -1086,17 +1088,91 @@ LLIMMgr::onConfirmForceCloseError(
 }
 
 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLOutgoingCallDialog
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LLOutgoingCallDialog::LLOutgoingCallDialog(const LLSD& payload) :
+	LLDockableFloater(NULL, false, payload),
+	mPayload(payload)
+{
+}
+
+void LLOutgoingCallDialog::getAllowedRect(LLRect& rect)
+{
+	rect = gViewerWindow->getWorldViewRectRaw();
+}
+
+void LLOutgoingCallDialog::onOpen(const LLSD& key)
+{
+	// tell the user which voice channel they are leaving
+	if (!mPayload["old_channel_name"].asString().empty())
+	{
+		childSetTextArg("leaving", "[CURRENT_CHAT]", mPayload["old_channel_name"].asString());
+	}
+	else
+	{
+		childSetTextArg("leaving", "[CURRENT_CHAT]", getString("localchat"));
+	}
+
+	std::string callee_name = mPayload["session_name"].asString();
+	if (callee_name == "anonymous")
+	{
+		callee_name = getString("anonymous");
+	}
+	
+	setTitle(callee_name);
+
+	LLSD callee_id = mPayload["other_user_id"];
+	childSetTextArg("calling", "[CALLEE_NAME]", callee_name);
+	LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+	icon->setValue(callee_id);
+
+	// dock the dialog to the sys well, where other sys messages appear
+	setDockControl(new LLDockControl(LLBottomTray::getInstance()->getSysWell(),
+					 this, getDockTongue(), LLDockControl::TOP,
+					 boost::bind(&LLOutgoingCallDialog::getAllowedRect, this, _1)));
+}
+
+
+//static
+void LLOutgoingCallDialog::onCancel(void* user_data)
+{
+	LLOutgoingCallDialog* self = (LLOutgoingCallDialog*)user_data;
+
+	if (!gIMMgr)
+		return;
+
+	LLUUID session_id = self->mPayload["session_id"].asUUID();
+	gIMMgr->endCall(session_id);
+	
+	self->closeFloater();
+}
+
+
+BOOL LLOutgoingCallDialog::postBuild()
+{
+	BOOL success = LLDockableFloater::postBuild();
+
+	childSetAction("Cancel", onCancel, this);
+
+	return success;
+}
+
+
+
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLIncomingCallDialog
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
-	LLModalDialog(payload),
+	LLDockableFloater(NULL, false, payload),
 	mPayload(payload)
 {
 }
 
 BOOL LLIncomingCallDialog::postBuild()
 {
+	LLDockableFloater::postBuild();
+
 	LLSD caller_id = mPayload["caller_id"];
 	EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
 
@@ -1115,6 +1191,11 @@ BOOL LLIncomingCallDialog::postBuild()
 		call_type = getString("VoiceInviteAdHoc");
 	}
 
+	// check to see if this is an Avaline call
+	LLUUID session_id = mPayload["session_id"].asUUID();
+	bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
+	childSetVisible("Start IM", is_avatar); // no IM for avaline
+
 	LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name");
 	caller_name_widget->setValue(caller_name + " " + call_type);
 	LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
@@ -1128,6 +1209,30 @@ BOOL LLIncomingCallDialog::postBuild()
 	return TRUE;
 }
 
+void LLIncomingCallDialog::getAllowedRect(LLRect& rect)
+{
+	rect = gViewerWindow->getWorldViewRectRaw();
+}
+
+void LLIncomingCallDialog::onOpen(const LLSD& key)
+{
+	// tell the user which voice channel they would be leaving
+	LLVoiceChannel *voice = LLVoiceChannel::getCurrentVoiceChannel();
+	if (voice && !voice->getSessionName().empty())
+	{
+		childSetTextArg("question", "[CURRENT_CHAT]", voice->getSessionName());
+	}
+	else
+	{
+		childSetTextArg("question", "[CURRENT_CHAT]", getString("localchat"));
+	}
+
+	// dock the dialog to the sys well, where other sys messages appear
+	setDockControl(new LLDockControl(LLBottomTray::getInstance()->getSysWell(),
+									 this, getDockTongue(), LLDockControl::TOP,
+									 boost::bind(&LLIncomingCallDialog::getAllowedRect, this, _1)));
+}
+
 //static
 void LLIncomingCallDialog::onAccept(void* user_data)
 {
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index c566b111ca95cb8a061f3d37ba0f26cc7bb50c6a..62a54bc0815fe2ea3aca2852e8584dd3f617052b 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -34,9 +34,11 @@
 #define LL_LLIMVIEW_H
 
 #include "lldarray.h"
+#include "lldockablefloater.h"
 #include "llspeakers.h" //for LLIMSpeakerMgr
 #include "llimpanel.h" //for voice channels
 #include "llmodaldialog.h"
+#include "lldockablefloater.h"
 #include "llinstantmessage.h"
 #include "lluuid.h"
 #include "llmultifloater.h"
@@ -401,12 +403,13 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 	LLSD mPendingAgentListUpdates;
 };
 
-class LLIncomingCallDialog : public LLModalDialog
+class LLIncomingCallDialog : public LLDockableFloater
 {
 public:
 	LLIncomingCallDialog(const LLSD& payload);
 
 	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void onOpen(const LLSD& key);
 
 	static void onAccept(void* user_data);
 	static void onReject(void* user_data);
@@ -414,6 +417,23 @@ class LLIncomingCallDialog : public LLModalDialog
 
 private:
 	void processCallResponse(S32 response);
+	void getAllowedRect(LLRect& rect);
+
+	LLSD mPayload;
+};
+
+class LLOutgoingCallDialog : public LLDockableFloater
+{
+public:
+	LLOutgoingCallDialog(const LLSD& payload);
+
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void onOpen(const LLSD& key);
+
+	static void onCancel(void* user_data);
+
+private:
+	void getAllowedRect(LLRect& rect);
 
 	LLSD mPayload;
 };
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index e7d7eb19d0ed82167626c5965a18d2a89963cc79..4b0d524906c026753bb5d3371da73cd670fabf02 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -176,6 +176,7 @@ LLInventoryModel::LLInventoryModel()
 	mRootFolderID(),
 	mLibraryRootFolderID(),
 	mLibraryOwnerID(),
+	mIsNotifyObservers(FALSE),
 	mIsAgentInvUsable(false)
 {
 }
@@ -537,7 +538,10 @@ void LLInventoryModel::updateLinkedItems(const LLUUID& object_id)
 						 item_array,
 						 LLInventoryModel::INCLUDE_TRASH,
 						 is_linked_item_match);
-
+	if (cat_array.empty() && item_array.empty())
+	{
+		return;
+	}
 	for (LLInventoryModel::cat_array_t::iterator cat_iter = cat_array.begin();
 		 cat_iter != cat_array.end();
 		 cat_iter++)
@@ -639,6 +643,7 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
 		new_item = old_item;
 		LLUUID old_parent_id = old_item->getParentUUID();
 		LLUUID new_parent_id = item->getParentUUID();
+			
 		if(old_parent_id != new_parent_id)
 		{
 			// need to update the parent-child tree
@@ -1133,6 +1138,15 @@ BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer) const
 // The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
 void LLInventoryModel::notifyObservers(const std::string service_name)
 {
+	if (mIsNotifyObservers)
+	{
+		// Within notifyObservers, something called notifyObservers
+		// again.  This type of recursion is unsafe because it causes items to be 
+		// processed twice, and this can easily lead to infinite loops.
+		llwarns << "Call was made to notifyObservers within notifyObservers!" << llendl;
+		return;
+	}
+	mIsNotifyObservers = TRUE;
 	for (observer_list_t::iterator iter = mObservers.begin();
 		 iter != mObservers.end(); )
 	{
@@ -1154,12 +1168,21 @@ void LLInventoryModel::notifyObservers(const std::string service_name)
 
 	mModifyMask = LLInventoryObserver::NONE;
 	mChangedItemIDs.clear();
+	mIsNotifyObservers = FALSE;
 }
 
 // store flag for change
 // and id of object change applies to
 void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent) 
 { 
+	if (mIsNotifyObservers)
+	{
+		// Something marked an item for change within a call to notifyObservers
+		// (which is in the process of processing the list of items marked for change).
+		// This means the change may fail to be processed.
+		llwarns << "Adding changed mask within notify observers!  Change will likely be lost." << llendl;
+	}
+	
 	mModifyMask |= mask; 
 	if (referent.notNull())
 	{
@@ -1833,13 +1856,13 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
 {
 	//llinfos << "LLInventoryModel::addItem()" << llendl;
 
-	
-	// This can happen if assettype enums change.  This can be a backwards compatibility issue 
-	// in some viewer prototypes prior to when the AT_LINK enum changed from 23 to 24.
+	// This can happen if assettype enums from llassettype.h ever change.
+	// For example, there is a known backwards compatibility issue in some viewer prototypes prior to when 
+	// the AT_LINK enum changed from 23 to 24.
 	if ((item->getType() == LLAssetType::AT_NONE)
 		|| LLAssetType::lookup(item->getType()) == LLAssetType::badLookup())
 	{
-		llwarns << "Got bad asset type for item ( name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ), ignoring." << llendl;
+		llwarns << "Got bad asset type for item [ name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ], ignoring." << llendl;
 		return;
 	}
 	if(item)
@@ -1848,7 +1871,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
 		// The item will show up as a broken link.
 		if (item->getIsBrokenLink())
 		{
-			llinfos << "Adding broken link ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " )  parent: " << item->getParentUUID() << llendl;
+			llinfos << "Adding broken link [ name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " )  parent: " << item->getParentUUID() << llendl;
 		}
 		mItemMap[item->getUUID()] = item;
 	}
@@ -2176,7 +2199,7 @@ bool LLInventoryModel::loadSkeleton(
 
 			// Add all the items loaded which are parented to a
 			// category with a correctly cached parent
-			count = items.count();
+			S32 bad_link_count = 0;
 			cat_map_t::iterator unparented = mCategoryMap.end();
 			for(item_array_t::const_iterator item_iter = items.begin();
 				item_iter != items.end();
@@ -2193,7 +2216,11 @@ bool LLInventoryModel::loadSkeleton(
 						// This can happen if the linked object's baseobj is removed from the cache but the linked object is still in the cache.
 						if (item->getIsBrokenLink())
 						{
-							llinfos << "Attempted to add cached link item without baseobj present ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ).  Ignoring and invalidating " << cat->getName() << " . " << llendl;
+							bad_link_count++;
+							lldebugs << "Attempted to add cached link item without baseobj present ( name: "
+									 << item->getName() << " itemID: " << item->getUUID()
+									 << " assetID: " << item->getAssetUUID()
+									 << " ).  Ignoring and invalidating " << cat->getName() << " . " << llendl;
 							invalid_categories.insert(cit->second);
 							continue;
 						}
@@ -2203,6 +2230,12 @@ bool LLInventoryModel::loadSkeleton(
 					}
 				}
 			}
+			if (bad_link_count > 0)
+			{
+				llinfos << "Attempted to add " << bad_link_count
+						<< " cached link items without baseobj present. "
+						<< "The corresponding categories were invalidated." << llendl;
+			}
 		}
 		else
 		{
@@ -3307,6 +3340,12 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)
 	for(i = 0; i < count; ++i)
 	{
 		titem->unpackMessage(msg, _PREHASH_ItemData, i);
+		// If the item has already been added (e.g. from link prefetch), then it doesn't need to be re-added.
+		if (gInventory.getItem(titem->getUUID()))
+		{
+			llinfos << "Skipping prefetched item [ Name: " << titem->getName() << " | Type: " << titem->getActualType() << " | ItemUUID: " << titem->getUUID() << " ] " << llendl;
+			continue;
+		}
 		gInventory.updateItem(titem);
 	}
 
@@ -3682,513 +3721,6 @@ bool LLNameCategoryCollector::operator()(
 	return false;
 }
 
-
-
-///----------------------------------------------------------------------------
-/// Observers
-///----------------------------------------------------------------------------
-
-void LLInventoryCompletionObserver::changed(U32 mask)
-{
-	// scan through the incomplete items and move or erase them as
-	// appropriate.
-	if(!mIncomplete.empty())
-	{
-		for(item_ref_t::iterator it = mIncomplete.begin(); it < mIncomplete.end(); )
-		{
-			LLViewerInventoryItem* item = gInventory.getItem(*it);
-			if(!item)
-			{
-				it = mIncomplete.erase(it);
-				continue;
-			}
-			if(item->isComplete())
-			{
-				mComplete.push_back(*it);
-				it = mIncomplete.erase(it);
-				continue;
-			}
-			++it;
-		}
-		if(mIncomplete.empty())
-		{
-			done();
-		}
-	}
-}
-
-void LLInventoryCompletionObserver::watchItem(const LLUUID& id)
-{
-	if(id.notNull())
-	{
-		mIncomplete.push_back(id);
-	}
-}
-
-
-void LLInventoryFetchObserver::changed(U32 mask)
-{
-	// scan through the incomplete items and move or erase them as
-	// appropriate.
-	if(!mIncomplete.empty())
-	{
-		for(item_ref_t::iterator it = mIncomplete.begin(); it < mIncomplete.end(); )
-		{
-			LLViewerInventoryItem* item = gInventory.getItem(*it);
-			if(!item)
-			{
-				// BUG: This can cause done() to get called prematurely below.
-				// This happens with the LLGestureInventoryFetchObserver that
-				// loads gestures at startup. JC
-				it = mIncomplete.erase(it);
-				continue;
-			}
-			if(item->isComplete())
-			{
-				mComplete.push_back(*it);
-				it = mIncomplete.erase(it);
-				continue;
-			}
-			++it;
-		}
-		if(mIncomplete.empty())
-		{
-			done();
-		}
-	}
-	//llinfos << "LLInventoryFetchObserver::changed() mComplete size " << mComplete.size() << llendl;
-	//llinfos << "LLInventoryFetchObserver::changed() mIncomplete size " << mIncomplete.size() << llendl;
-}
-
-bool LLInventoryFetchObserver::isEverythingComplete() const
-{
-	return mIncomplete.empty();
-}
-
-void fetch_items_from_llsd(const LLSD& items_llsd)
-{
-	if (!items_llsd.size()) return;
-	LLSD body;
-	body[0]["cap_name"] = "FetchInventory";
-	body[1]["cap_name"] = "FetchLib";
-	for (S32 i=0; i<items_llsd.size();i++)
-	{
-		if (items_llsd[i]["owner_id"].asString() == gAgent.getID().asString())
-		{
-			body[0]["items"].append(items_llsd[i]);
-			continue;
-		}
-		if (items_llsd[i]["owner_id"].asString() == ALEXANDRIA_LINDEN_ID.asString())
-		{
-			body[1]["items"].append(items_llsd[i]);
-			continue;
-		}
-	}
-		
-	for (S32 i=0; i<body.size(); i++)
-	{
-		if (0 >= body[i].size()) continue;
-		std::string url = gAgent.getRegion()->getCapability(body[i]["cap_name"].asString());
-
-		if (!url.empty())
-		{
-			body[i]["agent_id"]	= gAgent.getID();
-			LLHTTPClient::post(url, body[i], new LLInventoryModel::fetchInventoryResponder(body[i]));
-			break;
-		}
-
-		LLMessageSystem* msg = gMessageSystem;
-		BOOL start_new_message = TRUE;
-		for (S32 j=0; j<body[i]["items"].size(); j++)
-		{
-			LLSD item_entry = body[i]["items"][j];
-			if(start_new_message)
-			{
-				start_new_message = FALSE;
-				msg->newMessageFast(_PREHASH_FetchInventory);
-				msg->nextBlockFast(_PREHASH_AgentData);
-				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			}
-			msg->nextBlockFast(_PREHASH_InventoryData);
-			msg->addUUIDFast(_PREHASH_OwnerID, item_entry["owner_id"].asUUID());
-			msg->addUUIDFast(_PREHASH_ItemID, item_entry["item_id"].asUUID());
-			if(msg->isSendFull(NULL))
-			{
-				start_new_message = TRUE;
-				gAgent.sendReliableMessage();
-			}
-		}
-		if(!start_new_message)
-		{
-			gAgent.sendReliableMessage();
-		}
-	}
-}
-
-void LLInventoryFetchObserver::fetchItems(
-	const LLInventoryFetchObserver::item_ref_t& ids)
-{
-	LLUUID owner_id;
-	LLSD items_llsd;
-	for(item_ref_t::const_iterator it = ids.begin(); it < ids.end(); ++it)
-	{
-		LLViewerInventoryItem* item = gInventory.getItem(*it);
-		if(item)
-		{
-			if(item->isComplete())
-			{
-				// It's complete, so put it on the complete container.
-				mComplete.push_back(*it);
-				continue;
-			}
-			else
-			{
-				owner_id = item->getPermissions().getOwner();
-			}
-		}
-		else
-		{
-			// assume it's agent inventory.
-			owner_id = gAgent.getID();
-		}
-		
-		// It's incomplete, so put it on the incomplete container, and
-		// pack this on the message.
-		mIncomplete.push_back(*it);
-		
-		// Prepare the data to fetch
-		LLSD item_entry;
-		item_entry["owner_id"] = owner_id;
-		item_entry["item_id"] = (*it);
-		items_llsd.append(item_entry);
-	}
-	fetch_items_from_llsd(items_llsd);
-}
-
-// virtual
-void LLInventoryFetchDescendentsObserver::changed(U32 mask)
-{
-	for(folder_ref_t::iterator it = mIncompleteFolders.begin(); it < mIncompleteFolders.end();)
-	{
-		LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
-		if(!cat)
-		{
-			it = mIncompleteFolders.erase(it);
-			continue;
-		}
-		if(isComplete(cat))
-		{
-			mCompleteFolders.push_back(*it);
-			it = mIncompleteFolders.erase(it);
-			continue;
-		}
-		++it;
-	}
-	if(mIncompleteFolders.empty())
-	{
-		done();
-	}
-}
-
-void LLInventoryFetchDescendentsObserver::fetchDescendents(
-	const folder_ref_t& ids)
-{
-	for(folder_ref_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
-	{
-		LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
-		if(!cat) continue;
-		if(!isComplete(cat))
-		{
-			cat->fetchDescendents();		//blindly fetch it without seeing if anything else is fetching it.
-			mIncompleteFolders.push_back(*it);	//Add to list of things being downloaded for this observer.
-		}
-		else
-		{
-			mCompleteFolders.push_back(*it);
-		}
-	}
-}
-
-bool LLInventoryFetchDescendentsObserver::isEverythingComplete() const
-{
-	return mIncompleteFolders.empty();
-}
-
-bool LLInventoryFetchDescendentsObserver::isComplete(LLViewerInventoryCategory* cat)
-{
-	S32 version = cat->getVersion();
-	S32 descendents = cat->getDescendentCount();
-	if((LLViewerInventoryCategory::VERSION_UNKNOWN == version)
-	   || (LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN == descendents))
-	{
-		return false;
-	}
-	// it might be complete - check known descendents against
-	// currently available.
-	LLInventoryModel::cat_array_t* cats;
-	LLInventoryModel::item_array_t* items;
-	gInventory.getDirectDescendentsOf(cat->getUUID(), cats, items);
-	if(!cats || !items)
-	{
-		// bit of a hack - pretend we're done if they are gone or
-		// incomplete. should never know, but it would suck if this
-		// kept tight looping because of a corrupt memory state.
-		return true;
-	}
-	S32 known = cats->count() + items->count();
-	if(descendents == known)
-	{
-		// hey - we're done.
-		return true;
-	}
-	return false;
-}
-
-void LLInventoryFetchComboObserver::changed(U32 mask)
-{
-	if(!mIncompleteItems.empty())
-	{
-		for(item_ref_t::iterator it = mIncompleteItems.begin(); it < mIncompleteItems.end(); )
-		{
-			LLViewerInventoryItem* item = gInventory.getItem(*it);
-			if(!item)
-			{
-				it = mIncompleteItems.erase(it);
-				continue;
-			}
-			if(item->isComplete())
-			{
-				mCompleteItems.push_back(*it);
-				it = mIncompleteItems.erase(it);
-				continue;
-			}
-			++it;
-		}
-	}
-	if(!mIncompleteFolders.empty())
-	{
-		for(folder_ref_t::iterator it = mIncompleteFolders.begin(); it < mIncompleteFolders.end();)
-		{
-			LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
-			if(!cat)
-			{
-				it = mIncompleteFolders.erase(it);
-				continue;
-			}
-			if(gInventory.isCategoryComplete(*it))
-			{
-				mCompleteFolders.push_back(*it);
-				it = mIncompleteFolders.erase(it);
-				continue;
-			}
-			++it;
-		}
-	}
-	if(!mDone && mIncompleteItems.empty() && mIncompleteFolders.empty())
-	{
-		mDone = true;
-		done();
-	}
-}
-
-void LLInventoryFetchComboObserver::fetch(
-	const folder_ref_t& folder_ids,
-	const item_ref_t& item_ids)
-{
-	lldebugs << "LLInventoryFetchComboObserver::fetch()" << llendl;
-	for(folder_ref_t::const_iterator fit = folder_ids.begin(); fit != folder_ids.end(); ++fit)
-	{
-		LLViewerInventoryCategory* cat = gInventory.getCategory(*fit);
-		if(!cat) continue;
-		if(!gInventory.isCategoryComplete(*fit))
-		{
-			cat->fetchDescendents();
-			lldebugs << "fetching folder " << *fit <<llendl;
-			mIncompleteFolders.push_back(*fit);
-		}
-		else
-		{
-			mCompleteFolders.push_back(*fit);
-			lldebugs << "completing folder " << *fit <<llendl;
-		}
-	}
-
-	// Now for the items - we fetch everything which is not a direct
-	// descendent of an incomplete folder because the item will show
-	// up in an inventory descendents message soon enough so we do not
-	// have to fetch it individually.
-	LLSD items_llsd;
-	LLUUID owner_id;
-	for(item_ref_t::const_iterator iit = item_ids.begin(); iit != item_ids.end(); ++iit)
-	{
-		LLViewerInventoryItem* item = gInventory.getItem(*iit);
-		if(!item)
-		{
-			lldebugs << "uanble to find item " << *iit << llendl;
-			continue;
-		}
-		if(item->isComplete())
-		{
-			// It's complete, so put it on the complete container.
-			mCompleteItems.push_back(*iit);
-			lldebugs << "completing item " << *iit << llendl;
-			continue;
-		}
-		else
-		{
-			mIncompleteItems.push_back(*iit);
-			owner_id = item->getPermissions().getOwner();
-		}
-		if(std::find(mIncompleteFolders.begin(), mIncompleteFolders.end(), item->getParentUUID()) == mIncompleteFolders.end())
-		{
-			LLSD item_entry;
-			item_entry["owner_id"] = owner_id;
-			item_entry["item_id"] = (*iit);
-			items_llsd.append(item_entry);
-		}
-		else
-		{
-			lldebugs << "not worrying about " << *iit << llendl;
-		}
-	}
-	fetch_items_from_llsd(items_llsd);
-}
-
-void LLInventoryExistenceObserver::watchItem(const LLUUID& id)
-{
-	if(id.notNull())
-	{
-		mMIA.push_back(id);
-	}
-}
-
-void LLInventoryExistenceObserver::changed(U32 mask)
-{
-	// scan through the incomplete items and move or erase them as
-	// appropriate.
-	if(!mMIA.empty())
-	{
-		for(item_ref_t::iterator it = mMIA.begin(); it < mMIA.end(); )
-		{
-			LLViewerInventoryItem* item = gInventory.getItem(*it);
-			if(!item)
-			{
-				++it;
-				continue;
-			}
-			mExist.push_back(*it);
-			it = mMIA.erase(it);
-		}
-		if(mMIA.empty())
-		{
-			done();
-		}
-	}
-}
-
-void LLInventoryAddedObserver::changed(U32 mask)
-{
-	if(!(mask & LLInventoryObserver::ADD))
-	{
-		return;
-	}
-
-	// *HACK: If this was in response to a packet off
-	// the network, figure out which item was updated.
-	LLMessageSystem* msg = gMessageSystem;
-
-	std::string msg_name;
-	if (mMessageName.empty())
-	{
-		msg_name = msg->getMessageName();
-	}
-	else
-	{
-		msg_name = mMessageName;
-	}
-
-	if (msg_name.empty())
-	{
-		return;
-	}
-	
-	// We only want newly created inventory items. JC
-	if ( msg_name != "UpdateCreateInventoryItem")
-	{
-		return;
-	}
-
-	LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
-	S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
-	for(S32 i = 0; i < num_blocks; ++i)
-	{
-		titem->unpackMessage(msg, _PREHASH_InventoryData, i);
-		if (!(titem->getUUID().isNull()))
-		{
-			//we don't do anything with null keys
-			mAdded.push_back(titem->getUUID());
-		}
-	}
-	if (!mAdded.empty())
-	{
-		done();
-	}
-}
-
-LLInventoryTransactionObserver::LLInventoryTransactionObserver(
-	const LLTransactionID& transaction_id) :
-	mTransactionID(transaction_id)
-{
-}
-
-void LLInventoryTransactionObserver::changed(U32 mask)
-{
-	if(mask & LLInventoryObserver::ADD)
-	{
-		// This could be it - see if we are processing a bulk update
-		LLMessageSystem* msg = gMessageSystem;
-		if(msg->getMessageName()
-		   && (0 == strcmp(msg->getMessageName(), "BulkUpdateInventory")))
-		{
-			// we have a match for the message - now check the
-			// transaction id.
-			LLUUID id;
-			msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_TransactionID, id);
-			if(id == mTransactionID)
-			{
-				// woo hoo, we found it
-				folder_ref_t folders;
-				item_ref_t items;
-				S32 count;
-				count = msg->getNumberOfBlocksFast(_PREHASH_FolderData);
-				S32 i;
-				for(i = 0; i < count; ++i)
-				{
-					msg->getUUIDFast(_PREHASH_FolderData, _PREHASH_FolderID, id, i);
-					if(id.notNull())
-					{
-						folders.push_back(id);
-					}
-				}
-				count = msg->getNumberOfBlocksFast(_PREHASH_ItemData);
-				for(i = 0; i < count; ++i)
-				{
-					msg->getUUIDFast(_PREHASH_ItemData, _PREHASH_ItemID, id, i);
-					if(id.notNull())
-					{
-						items.push_back(id);
-					}
-				}
-
-				// call the derived class the implements this method.
-				done(folders, items);
-			}
-		}
-	}
-}
-
-
 ///----------------------------------------------------------------------------
 /// LLAssetIDMatches 
 ///----------------------------------------------------------------------------
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index faf026887a91f2a90da901f12ab0aa0849ebd143..bd64591194cce79d586c6bb5160b8bdb762d2035 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -41,40 +41,27 @@
 #include "lluuid.h"
 #include "llpermissionsflags.h"
 #include "llstring.h"
-
 #include <map>
 #include <set>
 #include <string>
 #include <vector>
 
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryObserver
-//
-// This class is designed to be a simple abstract base class which can
-// relay messages when the inventory changes.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// ! REFACTOR ! Remove llinventoryobservers.h and have other files that need it explicitly 
+// include llinventoryobservers.h instead of llinventorymodel.h .  This will reduce dependency on
+// llinventorymodel.h.
+#include "llinventoryobserver.h" 
+
+class LLInventoryObserver;
+class LLInventoryObject;
+class LLInventoryItem;
+class LLInventoryCategory;
+class LLViewerInventoryItem;
+class LLViewerInventoryCategory;
+class LLViewerInventoryItem;
+class LLViewerInventoryCategory;
+class LLMessageSystem;
+class LLInventoryCollectFunctor;
 
-class LLInventoryObserver
-{
-public:
-	// This enumeration is a way to refer to what changed in a more
-	// human readable format. You can mask the value provided by
-	// chaged() to see if the observer is interested in the change.
-	enum 
-	{
-		NONE = 0,
-		LABEL = 1,			// name changed
-		INTERNAL = 2,		// internal change, eg, asset uuid different
-		ADD = 4,			// something added
-		REMOVE = 8,			// something deleted
-		STRUCTURE = 16,		// structural change, eg, item or folder moved
-		CALLING_CARD = 32,	// online, grant status, cancel, etc change
-		ALL = 0xffffffff
-	};
-	virtual ~LLInventoryObserver() {};
-	virtual void changed(U32 mask) = 0;
-	std::string mMessageName; // used by Agent Inventory Service only. [DEV-20328]
-};
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLInventoryModel
@@ -87,16 +74,6 @@ class LLInventoryObserver
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-class LLInventoryObject;
-class LLInventoryItem;
-class LLInventoryCategory;
-class LLViewerInventoryItem;
-class LLViewerInventoryCategory;
-class LLViewerInventoryItem;
-class LLViewerInventoryCategory;
-class LLMessageSystem;
-class LLInventoryCollectFunctor;
-
 class LLInventoryModel
 {
 public:
@@ -473,23 +450,12 @@ class LLInventoryModel
 	cat_array_t* getUnlockedCatArray(const LLUUID& id);
 	item_array_t* getUnlockedItemArray(const LLUUID& id);
 	
-protected:
+private:
 	// Variables used to track what has changed since the last notify.
 	U32 mModifyMask;
 	typedef std::set<LLUUID> changed_items_t;
 	changed_items_t mChangedItemIDs;
 
-	// Information for tracking the actual inventory. We index this
-	// information in a lot of different ways so we can access
-	// the inventory using several different identifiers.
-	// mInventory member data is the 'master' list of inventory, and
-	// mCategoryMap and mItemMap store uuid->object mappings. 
-	typedef std::map<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
-	typedef std::map<LLUUID, LLPointer<LLViewerInventoryItem> > item_map_t;
-	//inv_map_t mInventory;
-	cat_map_t mCategoryMap;
-	item_map_t mItemMap;
-
 	std::map<LLUUID, bool> mCategoryLock;
 	std::map<LLUUID, bool> mItemLock;
 	
@@ -525,6 +491,21 @@ class LLInventoryModel
 	// This flag is used to handle an invalid inventory state.
 	bool mIsAgentInvUsable;
 
+private:
+	// Information for tracking the actual inventory. We index this
+	// information in a lot of different ways so we can access
+	// the inventory using several different identifiers.
+	// mInventory member data is the 'master' list of inventory, and
+	// mCategoryMap and mItemMap store uuid->object mappings. 
+	typedef std::map<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
+	typedef std::map<LLUUID, LLPointer<LLViewerInventoryItem> > item_map_t;
+	//inv_map_t mInventory;
+	cat_map_t mCategoryMap;
+	item_map_t mItemMap;
+
+	// Flag set when notifyObservers is being called, to look for bugs
+	// where it's called recursively.
+	BOOL mIsNotifyObservers;
 public:
 	// *NOTE: DEBUG functionality
 	void dumpInventory() const;
@@ -767,183 +748,5 @@ class LLFindWearables : public LLInventoryCollectFunctor
 							LLInventoryItem* item);
 };
 
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryCompletionObserver
-//
-// Class which can be used as a base class for doing something when
-// when all observed items are locally complete. This class implements
-// the changed() method of LLInventoryObserver and declares a new
-// method named done() which is called when all watched items have
-// complete information in the inventory model.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryCompletionObserver : public LLInventoryObserver
-{
-public:
-	LLInventoryCompletionObserver() {}
-	virtual void changed(U32 mask);
-
-	void watchItem(const LLUUID& id);
-
-protected:
-	virtual void done() = 0;
-
-	typedef std::vector<LLUUID> item_ref_t;
-	item_ref_t mComplete;
-	item_ref_t mIncomplete;
-};
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryFetchObserver
-//
-// This class is much like the LLInventoryCompletionObserver, except
-// that it handles all the the fetching necessary. Override the done()
-// method to do the thing you want.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryFetchObserver : public LLInventoryObserver
-{
-public:
-	LLInventoryFetchObserver() {}
-	virtual void changed(U32 mask);
-
-	typedef std::vector<LLUUID> item_ref_t;
-
-	bool isEverythingComplete() const;
-	void fetchItems(const item_ref_t& ids);
-	virtual void done() = 0;
-
-protected:
-	item_ref_t mComplete;
-	item_ref_t mIncomplete;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryFetchDescendentsObserver
-//
-// This class is much like the LLInventoryCompletionObserver, except
-// that it handles fetching based on category. Override the done()
-// method to do the thing you want.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInventoryFetchDescendentsObserver : public LLInventoryObserver
-{
-public:
-	LLInventoryFetchDescendentsObserver() {}
-	virtual void changed(U32 mask);
-
-	typedef std::vector<LLUUID> folder_ref_t;
-	void fetchDescendents(const folder_ref_t& ids);
-	bool isEverythingComplete() const;
-	virtual void done() = 0;
-
-protected:
-	bool isComplete(LLViewerInventoryCategory* cat);
-	folder_ref_t mIncompleteFolders;
-	folder_ref_t mCompleteFolders;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryFetchComboObserver
-//
-// This class does an appropriate combination of fetch descendents and
-// item fetches based on completion of categories and items. Much like
-// the fetch and fetch descendents, this will call done() when everything
-// has arrived.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInventoryFetchComboObserver : public LLInventoryObserver
-{
-public:
-	LLInventoryFetchComboObserver() : mDone(false) {}
-	virtual void changed(U32 mask);
-
-	typedef std::vector<LLUUID> folder_ref_t;
-	typedef std::vector<LLUUID> item_ref_t;
-	void fetch(const folder_ref_t& folder_ids, const item_ref_t& item_ids);
-
-	virtual void done() = 0;
-
-protected:
-	bool mDone;
-	folder_ref_t mCompleteFolders;
-	folder_ref_t mIncompleteFolders;
-	item_ref_t mCompleteItems;
-	item_ref_t mIncompleteItems;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryExistenceObserver
-//
-// This class is used as a base class for doing somethign when all the
-// observed item ids exist in the inventory somewhere. You can derive
-// a class from this class and implement the done() method to do
-// something useful.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryExistenceObserver : public LLInventoryObserver
-{
-public:
-	LLInventoryExistenceObserver() {}
-	virtual void changed(U32 mask);
-
-	void watchItem(const LLUUID& id);
-
-protected:
-	virtual void done() = 0;
-
-	typedef std::vector<LLUUID> item_ref_t;
-	item_ref_t mExist;
-	item_ref_t mMIA;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryAddedObserver
-//
-// This class is used as a base class for doing something when 
-// a new item arrives in inventory.
-// It does not watch for a certain UUID, rather it acts when anything is added
-// Derive a class from this class and implement the done() method to do
-// something useful.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryAddedObserver : public LLInventoryObserver
-{
-public:
-	LLInventoryAddedObserver() : mAdded() {}
-	virtual void changed(U32 mask);
-
-protected:
-	virtual void done() = 0;
-
-	typedef std::vector<LLUUID> item_ref_t;
-	item_ref_t mAdded;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryTransactionObserver
-//
-// Class which can be used as a base class for doing something when an
-// inventory transaction completes.
-//
-// *NOTE: This class is not quite complete. Avoid using unless you fix up it's
-// functionality gaps.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryTransactionObserver : public LLInventoryObserver
-{
-public:
-	LLInventoryTransactionObserver(const LLTransactionID& transaction_id);
-	virtual void changed(U32 mask);
-
-protected:
-	typedef std::vector<LLUUID> folder_ref_t;
-	typedef std::vector<LLUUID> item_ref_t;
-	virtual void done(const folder_ref_t& folders, const item_ref_t& items) = 0;
-
-	LLTransactionID mTransactionID;
-};
-
-
 #endif // LL_LLINVENTORYMODEL_H
 
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3ccf593d278a7fb10c7f5b8d62639aed9823e7e8
--- /dev/null
+++ b/indra/newview/llinventoryobserver.cpp
@@ -0,0 +1,564 @@
+/** 
+ * @file llinventoryobserver.cpp
+ * @brief Implementation of the inventory observers used to track agent inventory.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ * 
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llinventoryobserver.h"
+
+#include "llassetstorage.h"
+#include "llcrc.h"
+#include "lldir.h"
+#include "llsys.h"
+#include "llxfermanager.h"
+#include "message.h"
+
+#include "llagent.h"
+#include "llagentwearables.h"
+#include "llfloater.h"
+#include "llfocusmgr.h"
+#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodel.h"
+#include "llviewermessage.h"
+#include "llviewerwindow.h"
+#include "llviewerregion.h"
+#include "llappviewer.h"
+#include "lldbstrings.h"
+#include "llviewerstats.h"
+#include "llmutelist.h"
+#include "llnotifications.h"
+#include "llcallbacklist.h"
+#include "llpreview.h"
+#include "llviewercontrol.h"
+#include "llvoavatarself.h"
+#include "llsdutil.h"
+#include <deque>
+
+void LLInventoryCompletionObserver::changed(U32 mask)
+{
+	// scan through the incomplete items and move or erase them as
+	// appropriate.
+	if(!mIncomplete.empty())
+	{
+		for(item_ref_t::iterator it = mIncomplete.begin(); it < mIncomplete.end(); )
+		{
+			LLViewerInventoryItem* item = gInventory.getItem(*it);
+			if(!item)
+			{
+				it = mIncomplete.erase(it);
+				continue;
+			}
+			if(item->isComplete())
+			{
+				mComplete.push_back(*it);
+				it = mIncomplete.erase(it);
+				continue;
+			}
+			++it;
+		}
+		if(mIncomplete.empty())
+		{
+			done();
+		}
+	}
+}
+
+void LLInventoryCompletionObserver::watchItem(const LLUUID& id)
+{
+	if(id.notNull())
+	{
+		mIncomplete.push_back(id);
+	}
+}
+
+
+void LLInventoryFetchObserver::changed(U32 mask)
+{
+	// scan through the incomplete items and move or erase them as
+	// appropriate.
+	if(!mIncomplete.empty())
+	{
+		for(item_ref_t::iterator it = mIncomplete.begin(); it < mIncomplete.end(); )
+		{
+			LLViewerInventoryItem* item = gInventory.getItem(*it);
+			if(!item)
+			{
+				// BUG: This can cause done() to get called prematurely below.
+				// This happens with the LLGestureInventoryFetchObserver that
+				// loads gestures at startup. JC
+				it = mIncomplete.erase(it);
+				continue;
+			}
+			if(item->isComplete())
+			{
+				mComplete.push_back(*it);
+				it = mIncomplete.erase(it);
+				continue;
+			}
+			++it;
+		}
+		if(mIncomplete.empty())
+		{
+			done();
+		}
+	}
+	//llinfos << "LLInventoryFetchObserver::changed() mComplete size " << mComplete.size() << llendl;
+	//llinfos << "LLInventoryFetchObserver::changed() mIncomplete size " << mIncomplete.size() << llendl;
+}
+
+bool LLInventoryFetchObserver::isEverythingComplete() const
+{
+	return mIncomplete.empty();
+}
+
+void fetch_items_from_llsd(const LLSD& items_llsd)
+{
+	if (!items_llsd.size()) return;
+	LLSD body;
+	body[0]["cap_name"] = "FetchInventory";
+	body[1]["cap_name"] = "FetchLib";
+	for (S32 i=0; i<items_llsd.size();i++)
+	{
+		if (items_llsd[i]["owner_id"].asString() == gAgent.getID().asString())
+		{
+			body[0]["items"].append(items_llsd[i]);
+			continue;
+		}
+		if (items_llsd[i]["owner_id"].asString() == ALEXANDRIA_LINDEN_ID.asString())
+		{
+			body[1]["items"].append(items_llsd[i]);
+			continue;
+		}
+	}
+		
+	for (S32 i=0; i<body.size(); i++)
+	{
+		if (0 >= body[i].size()) continue;
+		std::string url = gAgent.getRegion()->getCapability(body[i]["cap_name"].asString());
+
+		if (!url.empty())
+		{
+			body[i]["agent_id"]	= gAgent.getID();
+			LLHTTPClient::post(url, body[i], new LLInventoryModel::fetchInventoryResponder(body[i]));
+			break;
+		}
+
+		LLMessageSystem* msg = gMessageSystem;
+		BOOL start_new_message = TRUE;
+		for (S32 j=0; j<body[i]["items"].size(); j++)
+		{
+			LLSD item_entry = body[i]["items"][j];
+			if(start_new_message)
+			{
+				start_new_message = FALSE;
+				msg->newMessageFast(_PREHASH_FetchInventory);
+				msg->nextBlockFast(_PREHASH_AgentData);
+				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			}
+			msg->nextBlockFast(_PREHASH_InventoryData);
+			msg->addUUIDFast(_PREHASH_OwnerID, item_entry["owner_id"].asUUID());
+			msg->addUUIDFast(_PREHASH_ItemID, item_entry["item_id"].asUUID());
+			if(msg->isSendFull(NULL))
+			{
+				start_new_message = TRUE;
+				gAgent.sendReliableMessage();
+			}
+		}
+		if(!start_new_message)
+		{
+			gAgent.sendReliableMessage();
+		}
+	}
+}
+
+void LLInventoryFetchObserver::fetchItems(
+	const LLInventoryFetchObserver::item_ref_t& ids)
+{
+	LLUUID owner_id;
+	LLSD items_llsd;
+	for(item_ref_t::const_iterator it = ids.begin(); it < ids.end(); ++it)
+	{
+		LLViewerInventoryItem* item = gInventory.getItem(*it);
+		if(item)
+		{
+			if(item->isComplete())
+			{
+				// It's complete, so put it on the complete container.
+				mComplete.push_back(*it);
+				continue;
+			}
+			else
+			{
+				owner_id = item->getPermissions().getOwner();
+			}
+		}
+		else
+		{
+			// assume it's agent inventory.
+			owner_id = gAgent.getID();
+		}
+		
+		// It's incomplete, so put it on the incomplete container, and
+		// pack this on the message.
+		mIncomplete.push_back(*it);
+		
+		// Prepare the data to fetch
+		LLSD item_entry;
+		item_entry["owner_id"] = owner_id;
+		item_entry["item_id"] = (*it);
+		items_llsd.append(item_entry);
+	}
+	fetch_items_from_llsd(items_llsd);
+}
+
+// virtual
+void LLInventoryFetchDescendentsObserver::changed(U32 mask)
+{
+	for(folder_ref_t::iterator it = mIncompleteFolders.begin(); it < mIncompleteFolders.end();)
+	{
+		LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
+		if(!cat)
+		{
+			it = mIncompleteFolders.erase(it);
+			continue;
+		}
+		if(isComplete(cat))
+		{
+			mCompleteFolders.push_back(*it);
+			it = mIncompleteFolders.erase(it);
+			continue;
+		}
+		++it;
+	}
+	if(mIncompleteFolders.empty())
+	{
+		done();
+	}
+}
+
+void LLInventoryFetchDescendentsObserver::fetchDescendents(
+	const folder_ref_t& ids)
+{
+	for(folder_ref_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
+	{
+		LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
+		if(!cat) continue;
+		if(!isComplete(cat))
+		{
+			cat->fetchDescendents();		//blindly fetch it without seeing if anything else is fetching it.
+			mIncompleteFolders.push_back(*it);	//Add to list of things being downloaded for this observer.
+		}
+		else
+		{
+			mCompleteFolders.push_back(*it);
+		}
+	}
+}
+
+bool LLInventoryFetchDescendentsObserver::isEverythingComplete() const
+{
+	return mIncompleteFolders.empty();
+}
+
+bool LLInventoryFetchDescendentsObserver::isComplete(LLViewerInventoryCategory* cat)
+{
+	S32 version = cat->getVersion();
+	S32 descendents = cat->getDescendentCount();
+	if((LLViewerInventoryCategory::VERSION_UNKNOWN == version)
+	   || (LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN == descendents))
+	{
+		return false;
+	}
+	// it might be complete - check known descendents against
+	// currently available.
+	LLInventoryModel::cat_array_t* cats;
+	LLInventoryModel::item_array_t* items;
+	gInventory.getDirectDescendentsOf(cat->getUUID(), cats, items);
+	if(!cats || !items)
+	{
+		// bit of a hack - pretend we're done if they are gone or
+		// incomplete. should never know, but it would suck if this
+		// kept tight looping because of a corrupt memory state.
+		return true;
+	}
+	S32 known = cats->count() + items->count();
+	if(descendents == known)
+	{
+		// hey - we're done.
+		return true;
+	}
+	return false;
+}
+
+void LLInventoryFetchComboObserver::changed(U32 mask)
+{
+	if(!mIncompleteItems.empty())
+	{
+		for(item_ref_t::iterator it = mIncompleteItems.begin(); it < mIncompleteItems.end(); )
+		{
+			LLViewerInventoryItem* item = gInventory.getItem(*it);
+			if(!item)
+			{
+				it = mIncompleteItems.erase(it);
+				continue;
+			}
+			if(item->isComplete())
+			{
+				mCompleteItems.push_back(*it);
+				it = mIncompleteItems.erase(it);
+				continue;
+			}
+			++it;
+		}
+	}
+	if(!mIncompleteFolders.empty())
+	{
+		for(folder_ref_t::iterator it = mIncompleteFolders.begin(); it < mIncompleteFolders.end();)
+		{
+			LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
+			if(!cat)
+			{
+				it = mIncompleteFolders.erase(it);
+				continue;
+			}
+			if(gInventory.isCategoryComplete(*it))
+			{
+				mCompleteFolders.push_back(*it);
+				it = mIncompleteFolders.erase(it);
+				continue;
+			}
+			++it;
+		}
+	}
+	if(!mDone && mIncompleteItems.empty() && mIncompleteFolders.empty())
+	{
+		mDone = true;
+		done();
+	}
+}
+
+void LLInventoryFetchComboObserver::fetch(
+	const folder_ref_t& folder_ids,
+	const item_ref_t& item_ids)
+{
+	lldebugs << "LLInventoryFetchComboObserver::fetch()" << llendl;
+	for(folder_ref_t::const_iterator fit = folder_ids.begin(); fit != folder_ids.end(); ++fit)
+	{
+		LLViewerInventoryCategory* cat = gInventory.getCategory(*fit);
+		if(!cat) continue;
+		if(!gInventory.isCategoryComplete(*fit))
+		{
+			cat->fetchDescendents();
+			lldebugs << "fetching folder " << *fit <<llendl;
+			mIncompleteFolders.push_back(*fit);
+		}
+		else
+		{
+			mCompleteFolders.push_back(*fit);
+			lldebugs << "completing folder " << *fit <<llendl;
+		}
+	}
+
+	// Now for the items - we fetch everything which is not a direct
+	// descendent of an incomplete folder because the item will show
+	// up in an inventory descendents message soon enough so we do not
+	// have to fetch it individually.
+	LLSD items_llsd;
+	LLUUID owner_id;
+	for(item_ref_t::const_iterator iit = item_ids.begin(); iit != item_ids.end(); ++iit)
+	{
+		LLViewerInventoryItem* item = gInventory.getItem(*iit);
+		if(!item)
+		{
+			lldebugs << "uanble to find item " << *iit << llendl;
+			continue;
+		}
+		if(item->isComplete())
+		{
+			// It's complete, so put it on the complete container.
+			mCompleteItems.push_back(*iit);
+			lldebugs << "completing item " << *iit << llendl;
+			continue;
+		}
+		else
+		{
+			mIncompleteItems.push_back(*iit);
+			owner_id = item->getPermissions().getOwner();
+		}
+		if(std::find(mIncompleteFolders.begin(), mIncompleteFolders.end(), item->getParentUUID()) == mIncompleteFolders.end())
+		{
+			LLSD item_entry;
+			item_entry["owner_id"] = owner_id;
+			item_entry["item_id"] = (*iit);
+			items_llsd.append(item_entry);
+		}
+		else
+		{
+			lldebugs << "not worrying about " << *iit << llendl;
+		}
+	}
+	fetch_items_from_llsd(items_llsd);
+}
+
+void LLInventoryExistenceObserver::watchItem(const LLUUID& id)
+{
+	if(id.notNull())
+	{
+		mMIA.push_back(id);
+	}
+}
+
+void LLInventoryExistenceObserver::changed(U32 mask)
+{
+	// scan through the incomplete items and move or erase them as
+	// appropriate.
+	if(!mMIA.empty())
+	{
+		for(item_ref_t::iterator it = mMIA.begin(); it < mMIA.end(); )
+		{
+			LLViewerInventoryItem* item = gInventory.getItem(*it);
+			if(!item)
+			{
+				++it;
+				continue;
+			}
+			mExist.push_back(*it);
+			it = mMIA.erase(it);
+		}
+		if(mMIA.empty())
+		{
+			done();
+		}
+	}
+}
+
+void LLInventoryAddedObserver::changed(U32 mask)
+{
+	if(!(mask & LLInventoryObserver::ADD))
+	{
+		return;
+	}
+
+	// *HACK: If this was in response to a packet off
+	// the network, figure out which item was updated.
+	LLMessageSystem* msg = gMessageSystem;
+
+	std::string msg_name;
+	if (mMessageName.empty())
+	{
+		msg_name = msg->getMessageName();
+	}
+	else
+	{
+		msg_name = mMessageName;
+	}
+
+	if (msg_name.empty())
+	{
+		return;
+	}
+	
+	// We only want newly created inventory items. JC
+	if ( msg_name != "UpdateCreateInventoryItem")
+	{
+		return;
+	}
+
+	LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
+	S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
+	for(S32 i = 0; i < num_blocks; ++i)
+	{
+		titem->unpackMessage(msg, _PREHASH_InventoryData, i);
+		if (!(titem->getUUID().isNull()))
+		{
+			//we don't do anything with null keys
+			mAdded.push_back(titem->getUUID());
+		}
+	}
+	if (!mAdded.empty())
+	{
+		done();
+	}
+}
+
+LLInventoryTransactionObserver::LLInventoryTransactionObserver(
+	const LLTransactionID& transaction_id) :
+	mTransactionID(transaction_id)
+{
+}
+
+void LLInventoryTransactionObserver::changed(U32 mask)
+{
+	if(mask & LLInventoryObserver::ADD)
+	{
+		// This could be it - see if we are processing a bulk update
+		LLMessageSystem* msg = gMessageSystem;
+		if(msg->getMessageName()
+		   && (0 == strcmp(msg->getMessageName(), "BulkUpdateInventory")))
+		{
+			// we have a match for the message - now check the
+			// transaction id.
+			LLUUID id;
+			msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_TransactionID, id);
+			if(id == mTransactionID)
+			{
+				// woo hoo, we found it
+				folder_ref_t folders;
+				item_ref_t items;
+				S32 count;
+				count = msg->getNumberOfBlocksFast(_PREHASH_FolderData);
+				S32 i;
+				for(i = 0; i < count; ++i)
+				{
+					msg->getUUIDFast(_PREHASH_FolderData, _PREHASH_FolderID, id, i);
+					if(id.notNull())
+					{
+						folders.push_back(id);
+					}
+				}
+				count = msg->getNumberOfBlocksFast(_PREHASH_ItemData);
+				for(i = 0; i < count; ++i)
+				{
+					msg->getUUIDFast(_PREHASH_ItemData, _PREHASH_ItemID, id, i);
+					if(id.notNull())
+					{
+						items.push_back(id);
+					}
+				}
+
+				// call the derived class the implements this method.
+				done(folders, items);
+			}
+		}
+	}
+}
diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h
new file mode 100644
index 0000000000000000000000000000000000000000..384e6292e8a6aad73f8e0c74d0faac1d9dc2fdc1
--- /dev/null
+++ b/indra/newview/llinventoryobserver.h
@@ -0,0 +1,249 @@
+/** 
+ * @file llinventoryobserver.h
+ * @brief LLInventoryObserver class header file
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ * 
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLINVENTORYOBSERVERS_H
+#define LL_LLINVENTORYOBSERVERS_H
+
+#include "lluuid.h"
+#include <string>
+#include <vector>
+
+class LLViewerInventoryCategory;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryObserver
+//
+// This class is designed to be a simple abstract base class which can
+// relay messages when the inventory changes.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryObserver
+{
+public:
+	// This enumeration is a way to refer to what changed in a more
+	// human readable format. You can mask the value provided by
+	// chaged() to see if the observer is interested in the change.
+	enum 
+	{
+		NONE = 0,
+		LABEL = 1,			// name changed
+		INTERNAL = 2,		// internal change, eg, asset uuid different
+		ADD = 4,			// something added
+		REMOVE = 8,			// something deleted
+		STRUCTURE = 16,		// structural change, eg, item or folder moved
+		CALLING_CARD = 32,	// online, grant status, cancel, etc change
+		ALL = 0xffffffff
+	};
+	virtual ~LLInventoryObserver() {};
+	virtual void changed(U32 mask) = 0;
+	std::string mMessageName; // used by Agent Inventory Service only. [DEV-20328]
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryCompletionObserver
+//
+// Class which can be used as a base class for doing something when
+// when all observed items are locally complete. This class implements
+// the changed() method of LLInventoryObserver and declares a new
+// method named done() which is called when all watched items have
+// complete information in the inventory model.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryCompletionObserver : public LLInventoryObserver
+{
+public:
+	LLInventoryCompletionObserver() {}
+	virtual void changed(U32 mask);
+
+	void watchItem(const LLUUID& id);
+
+protected:
+	virtual void done() = 0;
+
+	typedef std::vector<LLUUID> item_ref_t;
+	item_ref_t mComplete;
+	item_ref_t mIncomplete;
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryFetchObserver
+//
+// This class is much like the LLInventoryCompletionObserver, except
+// that it handles all the the fetching necessary. Override the done()
+// method to do the thing you want.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryFetchObserver : public LLInventoryObserver
+{
+public:
+	LLInventoryFetchObserver() {}
+	virtual void changed(U32 mask);
+
+	typedef std::vector<LLUUID> item_ref_t;
+
+	bool isEverythingComplete() const;
+	void fetchItems(const item_ref_t& ids);
+	virtual void done() = 0;
+
+protected:
+	item_ref_t mComplete;
+	item_ref_t mIncomplete;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryFetchDescendentsObserver
+//
+// This class is much like the LLInventoryCompletionObserver, except
+// that it handles fetching based on category. Override the done()
+// method to do the thing you want.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLInventoryFetchDescendentsObserver : public LLInventoryObserver
+{
+public:
+	LLInventoryFetchDescendentsObserver() {}
+	virtual void changed(U32 mask);
+
+	typedef std::vector<LLUUID> folder_ref_t;
+	void fetchDescendents(const folder_ref_t& ids);
+	bool isEverythingComplete() const;
+	virtual void done() = 0;
+
+protected:
+	bool isComplete(LLViewerInventoryCategory* cat);
+	folder_ref_t mIncompleteFolders;
+	folder_ref_t mCompleteFolders;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryFetchComboObserver
+//
+// This class does an appropriate combination of fetch descendents and
+// item fetches based on completion of categories and items. Much like
+// the fetch and fetch descendents, this will call done() when everything
+// has arrived.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLInventoryFetchComboObserver : public LLInventoryObserver
+{
+public:
+	LLInventoryFetchComboObserver() : mDone(false) {}
+	virtual void changed(U32 mask);
+
+	typedef std::vector<LLUUID> folder_ref_t;
+	typedef std::vector<LLUUID> item_ref_t;
+	void fetch(const folder_ref_t& folder_ids, const item_ref_t& item_ids);
+
+	virtual void done() = 0;
+
+protected:
+	bool mDone;
+	folder_ref_t mCompleteFolders;
+	folder_ref_t mIncompleteFolders;
+	item_ref_t mCompleteItems;
+	item_ref_t mIncompleteItems;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryExistenceObserver
+//
+// This class is used as a base class for doing somethign when all the
+// observed item ids exist in the inventory somewhere. You can derive
+// a class from this class and implement the done() method to do
+// something useful.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryExistenceObserver : public LLInventoryObserver
+{
+public:
+	LLInventoryExistenceObserver() {}
+	virtual void changed(U32 mask);
+
+	void watchItem(const LLUUID& id);
+
+protected:
+	virtual void done() = 0;
+
+	typedef std::vector<LLUUID> item_ref_t;
+	item_ref_t mExist;
+	item_ref_t mMIA;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryAddedObserver
+//
+// This class is used as a base class for doing something when 
+// a new item arrives in inventory.
+// It does not watch for a certain UUID, rather it acts when anything is added
+// Derive a class from this class and implement the done() method to do
+// something useful.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryAddedObserver : public LLInventoryObserver
+{
+public:
+	LLInventoryAddedObserver() : mAdded() {}
+	virtual void changed(U32 mask);
+
+protected:
+	virtual void done() = 0;
+
+	typedef std::vector<LLUUID> item_ref_t;
+	item_ref_t mAdded;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryTransactionObserver
+//
+// Class which can be used as a base class for doing something when an
+// inventory transaction completes.
+//
+// *NOTE: This class is not quite complete. Avoid using unless you fix up it's
+// functionality gaps.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryTransactionObserver : public LLInventoryObserver
+{
+public:
+	LLInventoryTransactionObserver(const LLTransactionID& transaction_id);
+	virtual void changed(U32 mask);
+
+protected:
+	typedef std::vector<LLUUID> folder_ref_t;
+	typedef std::vector<LLUUID> item_ref_t;
+	virtual void done(const folder_ref_t& folders, const item_ref_t& items) = 0;
+
+	LLTransactionID mTransactionID;
+};
+
+
+#endif // LL_LLINVENTORYOBSERVERS_H
+
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 9a71e53441e9f9f8ec32ce8c3633f258ddf03c7f..dfd4af5c287df000707cfb75dd8ffd569363a626 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -191,11 +191,9 @@ BOOL LLInventoryPanel::postBuild()
 	{
 		rebuildViewsFor(mStartFolderID);
 		mHasInventoryConnection = true;
+		defaultOpenInventory();
 	}
 
-	// bit of a hack to make sure the inventory is open.
-	mFolders->openFolder(preferred_type != LLFolderType::FT_NONE ? LLViewerFolderType::lookupNewCategoryName(preferred_type) : "My Inventory");
-
 	if (mSortOrderSetting != INHERIT_SORT_ORDER)
 	{
 		setSortOrder(gSavedSettings.getU32(mSortOrderSetting));
@@ -300,6 +298,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 	{
 		rebuildViewsFor(mStartFolderID);
 		mHasInventoryConnection = true;
+		defaultOpenInventory();
 		return;
 	}
 
@@ -561,6 +560,25 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
 	}
 }
 
+// bit of a hack to make sure the inventory is open.
+void LLInventoryPanel::defaultOpenInventory()
+{
+	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
+	if (preferred_type != LLFolderType::FT_NONE)
+	{
+		const std::string& top_level_folder_name = LLViewerFolderType::lookupNewCategoryName(preferred_type);
+		mFolders->openFolder(top_level_folder_name);
+	}
+	else
+	{
+		// Get the first child (it should be "My Inventory") and
+		// open it up by name (just to make sure the first child is actually a folder).
+		LLView* first_child = mFolders->getFirstChild();
+		const std::string& first_child_name = first_child->getName();
+		mFolders->openFolder(first_child_name);
+	}
+}
+
 struct LLConfirmPurgeData
 {
 	LLUUID mID;
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 9f74fad5c1c0acca15b4be0bff86b128602c7a58..e398c441059eb711569e4bb1ecb9fd7d95a717cd 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -165,7 +165,7 @@ class LLInventoryPanel : public LLPanel
 	// Given the id and the parent, build all of the folder views.
 	void rebuildViewsFor(const LLUUID& id);
 	virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719
-
+	void defaultOpenInventory(); // open the first level of inventory
 protected:
 	LLInventoryModel*			mInventory;
 	LLInventoryObserver*		mInventoryObserver;
diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp
index bd6702a0b2f6f9dabafca900cf460caf658fdb9d..d7eaad94f017a8524d935b4f49d9e2ea8d0aa8a1 100644
--- a/indra/newview/lljoystickbutton.cpp
+++ b/indra/newview/lljoystickbutton.cpp
@@ -134,16 +134,31 @@ void LLJoystick::updateSlop()
 	return;
 }
 
+BOOL LLJoystick::pointInCircle(S32 x, S32 y) const 
+{ 
+	//cnt is x and y coordinates of center of joystick circle, and also its radius,
+	//because area is not just rectangular, it's a square!
+	//Make sure to change method if this changes.
+	int cnt = this->getLocalRect().mTop/2;
+	if((x-cnt)*(x-cnt)+(y-cnt)*(y-cnt)<=cnt*cnt)
+		return TRUE;
+	return FALSE;
+}
 
 BOOL LLJoystick::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	//llinfos << "joystick mouse down " << x << ", " << y << llendl;
+	bool handles = false;
 
-	mLastMouse.set(x, y);
-	mFirstMouse.set(x, y);
+	if(handles = pointInCircle(x, y))
+	{
+		mLastMouse.set(x, y);
+		mFirstMouse.set(x, y);
+		mMouseDownTimer.reset();
+		handles = LLButton::handleMouseDown(x, y, mask);
+	}
 
-	mMouseDownTimer.reset();
-	return LLButton::handleMouseDown(x, y, mask);
+	return handles;
 }
 
 
diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h
index 4c657913b8c3a6fadc782182b3f43fcaec7f3643..0465f78031fdd8d6f5c081aef1ffd2788d3ce852 100644
--- a/indra/newview/lljoystickbutton.h
+++ b/indra/newview/lljoystickbutton.h
@@ -78,6 +78,8 @@ class LLJoystick
 
 	static void		onBtnHeldDown(void *userdata);		// called by llbutton callback handler
 	void            setInitialQuadrant(EJoystickQuadrant initial) { mInitialQuadrant = initial; };
+
+	BOOL			pointInCircle(S32 x, S32 y) const;
 	
 	static std::string nameFromQuadrant(const EJoystickQuadrant quadrant);
 	static EJoystickQuadrant quadrantFromName(const std::string& name);
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 945294f3f2734980302da7bf106e29b45927641c..a01426ea8794e46d5f6bccd1784a0a1f8718ed4a 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -182,6 +182,9 @@ void LLLoginInstance::constructAuthParams(const LLSD& credentials)
 	mRequestData["method"] = "login_to_simulator";
 	mRequestData["params"] = request_params;
 	mRequestData["options"] = requested_options;
+
+	mRequestData["cfg_srv_timeout"] = gSavedSettings.getF32("LoginSRVTimeout");
+	mRequestData["cfg_srv_pump"] = gSavedSettings.getString("LoginSRVPump");
 }
 
 bool LLLoginInstance::handleLoginEvent(const LLSD& event)
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 39934313118de30ce7e915a37b2f5941b0f4c361..333646d2c5e2b2cb45cb28ad179f057f28bdb9a6 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -36,7 +36,6 @@
 #include "lltrans.h"
 
 #include "llnearbychatbar.h"
-#include "llspeakbutton.h"
 #include "llbottomtray.h"
 #include "llagent.h"
 #include "llgesturemgr.h"
@@ -98,9 +97,10 @@ void LLGestureComboBox::refreshGestures()
 	clearRows();
 	mGestures.clear();
 
-	LLGestureManager::item_map_t::iterator it;
+	LLGestureManager::item_map_t::const_iterator it;
+	const LLGestureManager::item_map_t& active_gestures = LLGestureManager::instance().getActiveGestures();
 	LLSD::Integer idx(0);
-	for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it)
+	for (it = active_gestures.begin(); it != active_gestures.end(); ++it)
 	{
 		LLMultiGesture* gesture = (*it).second;
 		if (gesture)
@@ -234,14 +234,6 @@ BOOL LLNearbyChatBar::postBuild()
 
 	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
 	mOutputMonitor->setVisible(FALSE);
-	mSpeakBtn = getParent()->getChild<LLSpeakButton>("talk");
-
-	// Speak button should be initially disabled because
-	// it takes some time between logging in to world and connecting to voice channel.
-	mSpeakBtn->setEnabled(FALSE);
-
-	// Registering Chat Bar to receive Voice client status change notifications.
-	gVoiceClient->addObserver(this);
 
 	return TRUE;
 }
@@ -733,27 +725,6 @@ class LLChatHandler : public LLCommandHandler
 	}
 };
 
-void LLNearbyChatBar::onChange(EStatusType status, const std::string &channelURI, bool proximal)
-{
-	// Time it takes to connect to voice channel might be pretty long,
-	// so don't expect user login or STATUS_VOICE_ENABLED to be followed by STATUS_JOINED.
-	BOOL enable = FALSE;
-
-	switch (status)
-	{
-	// Do not add STATUS_VOICE_ENABLED because voice chat is 
-	// inactive until STATUS_JOINED
-	case STATUS_JOINED:
-		enable = TRUE;
-		break;
-	default:
-		enable = FALSE;
-		break;
-	}
-
-	mSpeakBtn->setEnabled(enable);
-}
-
 // Creating the object registers with the dispatcher.
 LLChatHandler gChatHandler;
 
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 56ee706a9746a865c7ea2c49d77bfc5203ef04b5..224118e088d6db9300babb35076c74593b4ad1a5 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -42,9 +42,6 @@
 #include "llspeakers.h"
 
 
-class LLSpeakButton;
-
-
 class LLGestureComboBox
 	: public LLComboBox
 	, public LLGestureManagerObserver
@@ -76,7 +73,6 @@ class LLGestureComboBox
 
 class LLNearbyChatBar
 :	public LLPanel
-,   public LLVoiceClientStatusObserver
 {
 public:
 	// constructor for inline chat-bars (e.g. hosted in chat history window)
@@ -105,11 +101,6 @@ class LLNearbyChatBar
 	S32 getMinWidth() const;
 	S32 getMaxWidth() const;
 
-	/**
-	 * Implements LLVoiceClientStatusObserver::onChange()
-	 */
-	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
-
 protected:
 	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
 	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
@@ -127,7 +118,6 @@ class LLNearbyChatBar
 	static S32 sLastSpecialChatChannel;
 
 	LLLineEditor*		mChatBox;
-	LLSpeakButton*		mSpeakBtn;
 	LLOutputMonitorCtrl* mOutputMonitor;
 	LLLocalSpeakerMgr*  mSpeakerMgr;
 };
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index b4e0ab198af32d9d89c2a4b14882609a7e933ecf..f3b63c8616c7390acc81acf5ad3792bd4664c0f1 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -332,7 +332,8 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
 	//only messages from AGENTS
 	if(CHAT_SOURCE_OBJECT == chat_msg.mSourceType)
 	{
-		return;//dn't show toast for messages from objects
+		if(chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
+			return;//ok for now we don't skip messeges from object, so skip only debug messages
 	}
 
 	LLUUID id;
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 471dd284265f48c2e0bdfd7a8d6e5ba46012da77..94e733913d4acaf41f2965ea5dfbdfa947243d5e 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -96,11 +96,11 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
 		if (!LLIMMgr::instance().hasSession(session_id))
 		{
 			session_id = LLIMMgr::instance().addSession(
-					notification->getSubstitutions()["NAME"], IM_NOTHING_SPECIAL,
+					notification->getSubstitutions()["OBJECTFROMNAME"], IM_NOTHING_SPECIAL,
 					notification->getPayload()["from_id"]);
 		}
 		LLIMMgr::instance().addMessage(session_id, LLUUID(),
-				notification->getSubstitutions()["NAME"],
+				notification->getSubstitutions()["OBJECTFROMNAME"],
 				notification->getMessage());
 
 		LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 3b54f1546e8ce996d7dc9c4b6fc1b03ebed53f2c..2254684f2150c9ae3bb7090739df9f13e961240e 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -41,6 +41,7 @@
 #include "llimview.h"
 #include "lltexteditor.h"
 #include "lltexturectrl.h"
+#include "lltoggleablemenu.h"
 #include "lltooldraganddrop.h"
 #include "llscrollcontainer.h"
 #include "llavatariconctrl.h"
@@ -333,8 +334,14 @@ BOOL LLPanelAvatarProfile::postBuild()
 	childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIMButtonClick,this)),NULL);
 	childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this)),NULL);
 	childSetCommitCallback("teleport",(boost::bind(&LLPanelAvatarProfile::onTeleportButtonClick,this)),NULL);
+	childSetCommitCallback("overflow_btn", boost::bind(&LLPanelAvatarProfile::onOverflowButtonClicked, this), NULL);
 	childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this)),NULL);
 
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	registrar.add("Profile.Pay",  boost::bind(&LLPanelAvatarProfile::pay, this));
+
+	mProfileMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_profile_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+
 	LLTextureCtrl* pic = getChild<LLTextureCtrl>("2nd_life_pic");
 	pic->setFallbackImageName("default_profile_picture.j2c");
 
@@ -513,6 +520,11 @@ void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data)
 	childSetValue("acc_status_text", caption_text);
 }
 
+void LLPanelAvatarProfile::pay()
+{
+	LLAvatarActions::pay(getAvatarId());
+}
+
 void LLPanelAvatarProfile::onUrlTextboxClicked(const std::string& url)
 {
 	LLWeb::loadURL(url);
@@ -552,6 +564,23 @@ void LLPanelAvatarProfile::onShareButtonClick()
 	//*TODO not implemented
 }
 
+void LLPanelAvatarProfile::onOverflowButtonClicked()
+{
+	if (!mProfileMenu->toggleVisibility())
+		return;
+
+	LLView* btn = getChild<LLView>("overflow_btn");
+
+	if (mProfileMenu->getButtonRect().isEmpty())
+	{
+		mProfileMenu->setButtonRect(btn);
+	}
+	mProfileMenu->updateParent(LLMenuGL::sMenuContainer);
+
+	LLRect rect = btn->getRect();
+	LLMenuGL::showPopup(this, mProfileMenu, rect.mRight, rect.mTop);
+}
+
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index ae0b8e98449f893b2fc2f4f419c20cf632fb480b..a0caf0c9156dd01102014c61edc1d131672e4788 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -38,6 +38,7 @@
 
 class LLComboBox;
 class LLLineEditor;
+class LLToggleableMenu;
 
 enum EOnlineStatus
 {
@@ -160,12 +161,17 @@ class LLPanelAvatarProfile
 	 * Fills Avatar's online status.
 	 */
 	virtual void fillOnlineStatus(const LLAvatarData* avatar_data);
-	
+
 	/**
 	 * Fills account status.
 	 */
 	virtual void fillAccountStatus(const LLAvatarData* avatar_data);
 
+	/**
+	 * Opens "Pay Resident" dialog.
+	 */
+	void pay();
+
 	void onUrlTextboxClicked(const std::string& url);
 	void onHomepageTextboxClicked();
 	void onAddFriendButtonClick();
@@ -173,10 +179,12 @@ class LLPanelAvatarProfile
 	void onCallButtonClick();
 	void onTeleportButtonClick();
 	void onShareButtonClick();
+	void onOverflowButtonClicked();
 
 private:
 
-	std::string mGroups;
+	std::string 			mGroups;
+	LLToggleableMenu*		mProfileMenu;
 };
 
 /**
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index 1770138b3ec648089a93f86b8a7d74c17122c7f5..9cd949c9cc58dbf45b25803f511f8468b36f09f2 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -174,10 +174,8 @@ void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)
 
 	getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(mAvatarID);
 
-	// Fetch the currect name
-	gCacheName->get(mAvatarID, FALSE, boost::bind(&LLPanelIMControlPanel::nameUpdatedCallback, this, _1, _2, _3, _4));
-
-	// Disable profile button if participant is not realy SL avatar
+	// Disable most profile buttons if the participant is
+	// not really an SL avatar (e.g., an Avaline caller).
 	LLIMModel::LLIMSession* im_session =
 		im_model.findIMSession(session_id);
 	if( im_session && !im_session->mOtherParticipantIsAvatar )
@@ -188,6 +186,13 @@ void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)
 		childSetEnabled("share_btn", FALSE);
 		childSetEnabled("teleport_btn", FALSE);
 		childSetEnabled("pay_btn", FALSE);
+
+        getChild<LLTextBox>("avatar_name")->setValue(im_session->mName);
+	}
+	else
+	{
+		// If the participant is an avatar, fetch the currect name
+		gCacheName->get(mAvatarID, FALSE, boost::bind(&LLPanelIMControlPanel::nameUpdatedCallback, this, _1, _2, _3, _4));
 	}
 }
 
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 15a75cb93063e3a06186a6b83430d3ecfe2e0757..e3b2ab77aaaa7d7567644f2a035d3f96f6bcbf9d 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -204,11 +204,6 @@ void LLPanelMainInventory::initListCommandsHandlers()
 	mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelMainInventory::onGearButtonClick, this));
 	mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this));
 	mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
-	/*
-	mListCommands->getChild<LLButton>("add_btn")->setHeldDownCallback(boost::bind(&LLPanelMainInventory::onAddButtonHeldDown, this));
-	static const LLSD add_landmark_command("add_landmark");
-	mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddAction, this, add_landmark_command));
-	*/
 
 	LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
 	trash_btn->setDragAndDropHandler(boost::bind(&LLPanelMainInventory::handleDragAndDropToTrash, this
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 9ba94c8ca98eec7c08a3b6e5a4facdb90f27e3f4..ca87ebf5a2b7287be34de9942c2792107a1c2c59 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -519,7 +519,6 @@ BOOL LLPanelPeople::postBuild()
 	LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME);
 	groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked,	this));
 	groups_panel->childSetAction("plus_btn",	boost::bind(&LLPanelPeople::onGroupPlusButtonClicked,	this));
-	groups_panel->childSetAction("minus_btn",	boost::bind(&LLPanelPeople::onGroupMinusButtonClicked,	this));
 
 	LLPanel* friends_panel = getChild<LLPanel>(FRIENDS_TAB_NAME);
 	friends_panel->childSetAction("add_btn",	boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked,	this));
@@ -568,6 +567,7 @@ BOOL LLPanelPeople::postBuild()
 	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
 	
 	registrar.add("People.Group.Plus.Action",  boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked,  this, _2));
+	registrar.add("People.Group.Minus.Action", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked,  this));
 	registrar.add("People.Friends.ViewSort.Action",  boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked,  this, _2));
 	registrar.add("People.Nearby.ViewSort.Action",  boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked,  this, _2));
 	registrar.add("People.Groups.ViewSort.Action",  boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked,  this, _2));
@@ -1193,7 +1193,7 @@ void LLPanelPeople::onCallButtonClicked()
 	if (selected_uuids.size() == 1)
 	{
 		// initiate a P2P voice chat with the selected user
-		LLAvatarActions::startCall(selected_uuids[0]);
+		LLAvatarActions::startCall(getCurrentItemID());
 	}
 	else if (selected_uuids.size() > 1)
 	{
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 6905c7e546fe61ec9ffac2c768dcf9c55598a23a..04b4226f82f8dd7bde746d338ae79fd06ff022ec 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -346,11 +346,18 @@ void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab)
 
 void LLPanelPicks::onOverflowButtonClicked()
 {
-	LLRect rect;
-	childGetRect(XML_BTN_OVERFLOW, rect);
+	if (!mOverflowMenu->toggleVisibility())
+		return;
+
+	LLView* btn = getChild<LLView>(XML_BTN_OVERFLOW);
 
+	if (mOverflowMenu->getButtonRect().isEmpty())
+	{
+		mOverflowMenu->setButtonRect(btn);
+	}
 	mOverflowMenu->updateParent(LLMenuGL::sMenuContainer);
-	mOverflowMenu->setButtonRect(rect, this);
+
+	LLRect rect = btn->getRect();
 	LLMenuGL::showPopup(this, mOverflowMenu, rect.mRight, rect.mTop);
 }
 
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 3d0fba9426a71b925148becf93ba32ae9751783b..eb10d97b371ef11eaf2d6e56d0cf12e15fccd576 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -601,9 +601,12 @@ void LLPanelPlaces::onOverflowButtonClicked()
 	if (!menu->toggleVisibility())
 		return;
 
+	if (menu->getButtonRect().isEmpty())
+	{
+		menu->setButtonRect(mOverflowBtn);
+	}
 	menu->updateParent(LLMenuGL::sMenuContainer);
 	LLRect rect = mOverflowBtn->getRect();
-	menu->setButtonRect(rect, this);
 	LLMenuGL::showPopup(this, menu, rect.mRight, rect.mTop);
 }
 
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index f5367c04772fe15dd79a81acc001bb07e0f4a82b..13bd059d45eeb4adc6db5f1321e1d872a2dd9973 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -130,6 +130,7 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
 				{
 					name.erase(found, moderator_indicator_len);
 					item->setName(name);
+					item->reshapeAvatarName();
 				}
 			}
 		}
@@ -151,6 +152,7 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
 					name += " ";
 					name += moderator_indicator;
 					item->setName(name);
+					item->reshapeAvatarName();
 				}
 			}
 		}
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index ed606d54570bf6119f04866145e6b6da18efb743..81eb133b07fcfc6875190c4d8fa8e8ad27ed9fdc 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -455,7 +455,7 @@ void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer)
 	if(!mOverflowToastPanel)
 		return;
 
-	mOverflowToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::closeOverflowToastPanel, this));
+	mOverflowToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this));
 
 	LLTextBox* text_box = mOverflowToastPanel->getChild<LLTextBox>("toast_text");
 	std::string	text = llformat(mOverflowFormatString.c_str(),mHiddenToastsNum);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 8c5439d47ea624916188f0304e545abbc7b44f98..6ca67345984c475b8b87bbc08f859718604b44f6 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -435,7 +435,7 @@ void LLSpatialGroup::clearDrawMap()
 
 BOOL LLSpatialGroup::isRecentlyVisible() const
 {
-	return (LLDrawable::getCurrentFrame() - (S32)mVisible) < LLDrawable::getMinVisFrameRange() ;
+	return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < LLDrawable::getMinVisFrameRange() ;
 }
 
 BOOL LLSpatialGroup::isVisible() const
diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp
index 57ea018f2540c833bb9a19dfe6fbdb30d2fc35f8..51d53b267406beefb09b4721b7b7fa18779b0ab5 100644
--- a/indra/newview/llspeakbutton.cpp
+++ b/indra/newview/llspeakbutton.cpp
@@ -133,6 +133,16 @@ LLSpeakButton::~LLSpeakButton()
 	LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn);
 }
 
+void LLSpeakButton::setSpeakToolTip(const std::string& msg)
+{
+	mSpeakBtn->setToolTip(msg);
+}
+
+void LLSpeakButton::setShowToolTip(const std::string& msg)
+{
+	mShowBtn->setToolTip(msg);
+}
+
 void LLSpeakButton::onMouseDown_SpeakBtn()
 {
 	bool down = true;
diff --git a/indra/newview/llspeakbutton.h b/indra/newview/llspeakbutton.h
index e213c562dd820c5781e234208b14c395a865fa3c..02c8ab38909031b48f48b721f6a38bc326e0bf45 100644
--- a/indra/newview/llspeakbutton.h
+++ b/indra/newview/llspeakbutton.h
@@ -62,6 +62,11 @@ class LLSpeakButton : public LLUICtrl
 	/*virtual*/ ~LLSpeakButton();
 	/*virtual*/ void draw();
 
+	// *HACK: Need to put tooltips in a translatable location,
+	// the panel that contains this button.
+	void setSpeakToolTip(const std::string& msg);
+	void setShowToolTip(const std::string& msg);
+
 protected:
 	friend class LLUICtrlFactory;
 	LLSpeakButton(const Params& p);
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 2ed82b7d621c1b8be82159dee900538fd2f0c226..261bdbcfc05833b57611c03bc3c829583b619562 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -359,6 +359,9 @@ void LLSpeakerMgr::updateSpeakerList()
 
 LLPointer<LLSpeaker> LLSpeakerMgr::findSpeaker(const LLUUID& speaker_id)
 {
+	//In some conditions map causes crash if it is empty(Windows only), adding check (EK)
+	if (mSpeakers.size() == 0)
+		return NULL;
 	speaker_map_t::iterator found_it = mSpeakers.find(speaker_id);
 	if (found_it == mSpeakers.end())
 	{
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 64dcd7b97fbe6e4f45eefe500b0cea70a7e452c9..696b0d9af174d5c3fedc87422118152a301a33e9 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -873,6 +873,9 @@ bool idle_startup()
 		gViewerWindow->getWindow()->show();
 		display_startup();
 
+		//DEV-10530.  do cleanup.  remove at some later date.  jan-2009
+		LLFloaterPreference::cleanupBadSetting();
+
 		// DEV-16927.  The following code removes errant keystrokes that happen while the window is being 
 		// first made visible.
 #ifdef _WIN32
@@ -1688,8 +1691,11 @@ bool idle_startup()
 		//all categories loaded. lets create "My Favorites" category
 		gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true);
 
-		// lets create "Friends" and "Friends/All" in the Inventory "Calling Cards" and fill it with buddies
-		LLFriendCardsManager::instance().syncFriendsFolder();
+		// Checks whether "Friends" and "Friends/All" folders exist in "Calling Cards" folder,
+		// fetches their contents if needed and synchronizes it with buddies list.
+		// If the folders are not found they are created.
+		LLFriendCardsManager::instance().syncFriendCardsFolders();
+
 
 		// set up callbacks
 		llinfos << "Registering Callbacks" << llendl;
@@ -1900,9 +1906,6 @@ bool idle_startup()
         //DEV-17797.  get null folder.  Any items found here moved to Lost and Found
         LLInventoryModel::findLostItems();
 
-		//DEV-10530.  do cleanup.  remove at some later date.  jan-2009
-		LLFloaterPreference::cleanupBadSetting();
-
 		LLStartUp::setStartupState( STATE_PRECACHE );
 		timeout.reset();
 		return FALSE;
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 2fb6550107a40c19ac772d83f4428dbe5b6e7793..eada3879456eddb085ae715e8e80867ef8b6fa72 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -90,9 +90,9 @@ BOOL LLSysWellWindow::postBuild()
 void LLSysWellWindow::setMinimized(BOOL minimize)
 {
 	// we don't show empty Message Well window
-	if (!minimize)
+	if (!minimize && isWindowEmpty())
 	{
-		setVisible(!isWindowEmpty());
+		return;
 	}
 
 	LLDockableFloater::setMinimized(minimize);
@@ -268,8 +268,11 @@ void LLSysWellWindow::toggleWindow()
 	{
 		setVisible(FALSE);
 	}
-	//set window in foreground
-	setFocus(getVisible());
+	else if(!isDocked())
+	{
+		// bring to front undocked floater
+		setVisible(TRUE);
+	}
 }
 
 //---------------------------------------------------------------------------------
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 903df21e785044ceb557eba7c05fd6332156737c..513439daeb9850c6126bf3aa392d4356665b2eac 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -225,6 +225,7 @@ void LLToast::setVisible(BOOL show)
 		{
 			mTimer.start();
 		}
+		LLModalDialog::setFrontmost(TRUE);
 	}
 	LLPanel::setVisible(show);
 	if(mPanel)
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index 9370e318cfbc5a87a692830c890a02600fc8076a..1ea5f515b76e277e647698c5dbab32ac9cb70d41 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -69,7 +69,7 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) :	LLToastPanel(p.notif
 	mNotification = p.notification;
 
 	// if message comes from the system - there shouldn't be a reply btn
-	if(p.from == "Second Life")
+	if(p.from == SYSTEM_FROM)
 	{
 		mAvatar->setVisible(FALSE);
 		sys_msg_icon->setVisible(TRUE);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 964d3bc2fa5728227eb596cd81c535528c57bd09..7772f613f0a05ea35937a2442566150ef46ee004 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -197,7 +197,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
 
 	LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
-	
+	LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>);
 	LLFloaterReg::add("parcel_info", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterParcelInfo>);
 	LLFloaterPayUtil::registerFloater();
 
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 493457704bbdcb96864790d355e1536bf9555a66..69d4da373e8e6407c764585592a62bd1d85fa1b6 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -135,9 +135,19 @@ LOG_CLASS(LLMimeDiscoveryResponder);
 	LLMimeDiscoveryResponder( viewer_media_t media_impl)
 		: mMediaImpl(media_impl),
 		  mInitialized(false)
-	{}
-
+	{
+		if(mMediaImpl->mMimeTypeProbe != NULL)
+		{
+			llerrs << "impl already has an outstanding responder" << llendl;
+		}
+		
+		mMediaImpl->mMimeTypeProbe = this;
+	}
 
+	~LLMimeDiscoveryResponder()
+	{
+		disconnectOwner();
+	}
 
 	virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content)
 	{
@@ -149,23 +159,54 @@ LOG_CLASS(LLMimeDiscoveryResponder);
 
 	virtual void error( U32 status, const std::string& reason )
 	{
+		llwarns << "responder failed with status " << status << ", reason " << reason << llendl;
+		if(mMediaImpl)
+		{
+			mMediaImpl->mMediaSourceFailed = true;
+		}
 		// completeAny(status, "none/none");
 	}
 
 	void completeAny(U32 status, const std::string& mime_type)
 	{
-		if(!mInitialized && ! mime_type.empty())
+		// the call to initializeMedia may disconnect the responder, which will clear mMediaImpl.
+		// Make a local copy so we can call loadURI() afterwards.
+		LLViewerMediaImpl *impl = mMediaImpl;
+		
+		if(impl && !mInitialized && ! mime_type.empty())
 		{
-			if(mMediaImpl->initializeMedia(mime_type))
+			if(impl->initializeMedia(mime_type))
 			{
 				mInitialized = true;
-				mMediaImpl->loadURI();
+				impl->loadURI();
+				disconnectOwner();
 			}
 		}
 	}
+	
+	void cancelRequest()
+	{
+		disconnectOwner();
+	}
+	
+private:
+	void disconnectOwner()
+	{
+		if(mMediaImpl)
+		{
+			if(mMediaImpl->mMimeTypeProbe != this)
+			{
+				llerrs << "internal error: mMediaImpl->mMimeTypeProbe != this" << llendl;
+			}
 
-	public:
-		viewer_media_t mMediaImpl;
+			mMediaImpl->mMimeTypeProbe = NULL;
+		}
+		mMediaImpl = NULL;
+	}
+	
+	
+public:
+		LLViewerMediaImpl *mMediaImpl;
 		bool mInitialized;
 };
 static LLViewerMedia::impl_list sViewerMediaImplList;
@@ -708,6 +749,7 @@ LLViewerMediaImpl::LLViewerMediaImpl(	  const LLUUID& texture_id,
 	mIsDisabled(false),
 	mIsParcelMedia(false),
 	mProximity(-1),
+	mMimeTypeProbe(NULL),
 	mIsUpdated(false)
 { 
 
@@ -811,7 +853,9 @@ void LLViewerMediaImpl::destroyMediaSource()
 	{
 		oldImage->setPlaying(FALSE) ;
 	}
-
+	
+	cancelMimeTypeProbe();
+	
 	if(mMediaSource)
 	{
 		delete mMediaSource;
@@ -1316,6 +1360,8 @@ void LLViewerMediaImpl::unload()
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type,  bool rediscover_type, bool server_request)
 {
+	cancelMimeTypeProbe();
+
 	if(mMediaURL != url)
 	{
 		// Don't carry media play state across distinct URLs.
@@ -1358,6 +1404,12 @@ void LLViewerMediaImpl::navigateInternal()
 	// Helpful to have media urls in log file. Shouldn't be spammy.
 	llinfos << "media id= " << mTextureId << " url=" << mMediaURL << " mime_type=" << mMimeType << llendl;
 
+	if(mMimeTypeProbe != NULL)
+	{
+		llwarns << "MIME type probe already in progress -- bailing out." << llendl;
+		return;
+	}
+	
 	if(mNavigateServerRequest)
 	{
 		setNavState(MEDIANAVSTATE_SERVER_SENT);
@@ -1390,7 +1442,7 @@ void LLViewerMediaImpl::navigateInternal()
 
 		if(scheme.empty() || "http" == scheme || "https" == scheme)
 		{
-			LLHTTPClient::getHeaderOnly( mMediaURL, new LLMimeDiscoveryResponder(this));
+			LLHTTPClient::getHeaderOnly( mMediaURL, new LLMimeDiscoveryResponder(this), 10.0f);
 		}
 		else if("data" == scheme || "file" == scheme || "about" == scheme)
 		{
@@ -1521,7 +1573,15 @@ void LLViewerMediaImpl::update()
 {
 	if(mMediaSource == NULL)
 	{
-		if(mPriority != LLPluginClassMedia::PRIORITY_UNLOADED)
+		if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
+		{
+			// This media source should not be loaded.
+		}
+		else if(mMimeTypeProbe != NULL)
+		{
+			// this media source is doing a MIME type probe -- don't try loading it again.
+		}
+		else
 		{
 			// This media may need to be loaded.
 			if(sMediaCreateTimer.hasExpired())
@@ -2120,6 +2180,21 @@ void LLViewerMediaImpl::setNavState(EMediaNavState state)
 	}
 }
 
+void LLViewerMediaImpl::cancelMimeTypeProbe()
+{
+	if(mMimeTypeProbe != NULL)
+	{
+		// There doesn't seem to be a way to actually cancel an outstanding request.
+		// Simulate it by telling the LLMimeDiscoveryResponder not to write back any results.
+		mMimeTypeProbe->cancelRequest();
+		
+		// The above should already have set mMimeTypeProbe to NULL.
+		if(mMimeTypeProbe != NULL)
+		{
+			llerrs << "internal error: mMimeTypeProbe is not NULL after cancelling request." << llendl;
+		}
+	}
+}
 
 void LLViewerMediaImpl::addObject(LLVOVolume* obj) 
 {
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 3f5f3ca746c1a0979f2a961f66c775237505ab97..719deb28bf678ffb82b5c5b35150c29bfeebf8cb 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -48,6 +48,7 @@ class LLUUID;
 class LLViewerMediaTexture;
 class LLMediaEntry;
 class LLVOVolume ;
+class LLMimeDiscoveryResponder;
 
 typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
 ///////////////////////////////////////////////////////////////////////////////
@@ -294,6 +295,7 @@ class LLViewerMediaImpl
 	EMediaNavState getNavState() { return mMediaNavState; }
 	void setNavState(EMediaNavState state);
 	
+	void cancelMimeTypeProbe();
 public:
 	// a single media url with some data and an impl.
 	LLPluginClassMedia* mMediaSource;
@@ -331,7 +333,8 @@ class LLViewerMediaImpl
 	bool mIsDisabled;
 	bool mIsParcelMedia;
 	S32 mProximity;
-
+	LLMimeDiscoveryResponder *mMimeTypeProbe;
+	
 private:
 	BOOL mIsUpdated ;
 	std::list< LLVOVolume* > mObjectList ;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 976d89a5b7f2f3f6d9fb5a4a8c75dc9c498764fd..728fb7c61645a45813aa274f58e9f478e7387d0a 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -1879,7 +1879,9 @@ class LLAdvancedDebugAvatarTextures : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
+#ifndef LL_RELEASE_FOR_DOWNLOAD
 		handle_debug_avatar_textures(NULL);
+#endif
 		return true;
 	}
 };
@@ -1893,7 +1895,9 @@ class LLAdvancedDumpAvatarLocalTextures : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
+#ifndef LL_RELEASE_FOR_DOWNLOAD
 		handle_dump_avatar_local_textures(NULL);
+#endif
 		return true;
 	}
 };
@@ -7860,10 +7864,8 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis");
 	view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments");
 	view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures");
-	#ifndef LL_RELEASE_FOR_DOWNLOAD
 	view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures");
 	view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures");
-	#endif
 	// Advanced > Network
 	view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog");
 	view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 4088eafe16cc2303ee00288712cc9ad7e1e44200..b1efec83e60d668501eec0e976b903c39fad29a9 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1365,7 +1365,9 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
 
 	payload["from_id"] = info->mFromID;
 	args["OBJECTFROMNAME"] = info->mFromName;
-	args["NAME"] = info->mFromName;
+	args["NAME"] = LLSLURL::buildCommand("agent", info->mFromID, "about");
+	std::string verb = "highlight?name=" + msg;
+	args["ITEM_SLURL"] = LLSLURL::buildCommand("inventory", info->mObjectID, verb.c_str());
 
 	LLNotification::Params p("ObjectGiveItem");
 	p.substitutions(args).payload(payload).functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2));
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 9923c9ac74fcc1e35182848bb0237346f7614ced..85bc26c9c0e69637859e30e5e254a70bdc48a3e9 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -206,33 +206,31 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid
 LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
 	                                               const LLUUID &image_id,											       
 												   BOOL usemipmaps,
-												   S32 boost_priority,
+												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
 												   LLGLint internal_format,
 												   LLGLenum primary_format,
 												   LLHost request_from_host)
 {
-	llassert_always(boost_priority >= LLViewerTexture::BOOST_NONE) ;
 	return gTextureList.getImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
 }
 	
 LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
 	                                               const std::string& filename,												   
 												   BOOL usemipmaps,
-												   S32 boost_priority,
+												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
 												   LLGLint internal_format,
 												   LLGLenum primary_format, 
 												   const LLUUID& force_id)
 {
-	llassert_always(boost_priority >= LLViewerTexture::BOOST_NONE) ;
 	return gTextureList.getImageFromFile(filename, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
 }
 
 //static 
 LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,									 
 									 BOOL usemipmaps,
-									 S32 boost_priority,
+									 LLViewerTexture::EBoostLevel boost_priority,
 									 S8 texture_type,
 									 LLGLint internal_format,
 									 LLGLenum primary_format,
@@ -1485,9 +1483,8 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 		if ( mBoostLevel > BOOST_HIGH)
 		{
 			priority += 10000000.f;
-		}
-		
-		if(mAdditionalDecodePriority > 0.0f)
+		}		
+		else if(mAdditionalDecodePriority > 0.0f)
 		{
 			// 1-9
 			S32 additional_priority = (S32)(1.0f + mAdditionalDecodePriority*8.0f + .5f); // round
@@ -3147,8 +3144,7 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
 
 	if(mNeedsResetMaxVirtualSize)
 	{
-		mMaxVirtualSize = 0.f ;//reset
-		mNeedsResetMaxVirtualSize = FALSE ;
+		addTextureStats(0.f, FALSE) ;//reset
 	}
 
 	if(mIsPlaying) //media is playing
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index bde87d1dd5726d7105a15669bc2ce634a8743723..141979052d7636ca1d48cb28f0a0df3fbb8f65b4 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -107,12 +107,11 @@ class LLViewerTexture : public LLTexture
 
 	enum EBoostLevel
 	{
-		//skip 0 and 1 to avoid mistakenly mixing boost level with boolean numbers.
-		BOOST_NONE 			= 2,
-		BOOST_AVATAR_BAKED	= 3,
-		BOOST_AVATAR		= 4,
-		BOOST_CLOUDS		= 5,
-		BOOST_SCULPTED      = 6,
+		BOOST_NONE 			= 0,
+		BOOST_AVATAR_BAKED	= 1,
+		BOOST_AVATAR		= 2,
+		BOOST_CLOUDS		= 3,
+		BOOST_SCULPTED      = 4,
 		
 		BOOST_HIGH 			= 10,
 		BOOST_TERRAIN		= 11, // has to be high priority for minimap / low detail
@@ -668,7 +667,7 @@ class LLViewerTextureManager
 
 	static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,									 
 									 BOOL usemipmap = TRUE,
-									 S32 boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -677,7 +676,7 @@ class LLViewerTextureManager
 	
 	static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename,									 
 									 BOOL usemipmap = TRUE,
-									 S32 boost_priority = LLViewerTexture::BOOST_NONE,
+									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -686,7 +685,7 @@ class LLViewerTextureManager
 
 	static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url,									 
 									 BOOL usemipmap = TRUE,
-									 S32 boost_priority = LLViewerTexture::BOOST_NONE,
+									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 081b7cc4831e0676803a8d2a0a04b80faf41dd5b..703a13976cfc7aa080e39a590532785a12603347 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -325,7 +325,7 @@ void LLViewerTextureList::restoreGL()
 
 LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,												   
 												   BOOL usemipmaps,
-												   S32 boost_priority,
+												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
 												   LLGLint internal_format,
 												   LLGLenum primary_format, 
@@ -345,7 +345,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
 
 LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& url,
 												   BOOL usemipmaps,
-												   S32 boost_priority,
+												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
 												   LLGLint internal_format,
 												   LLGLenum primary_format, 
@@ -411,7 +411,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
 
 LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,											       
 												   BOOL usemipmaps,
-												   S32 boost_priority,
+												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
 												   LLGLint internal_format,
 												   LLGLenum primary_format,
@@ -441,7 +441,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
 //when this function is called, there is no such texture in the gTextureList with image_id.
 LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,											       
 												   BOOL usemipmaps,
-												   S32 boost_priority,
+												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
 												   LLGLint internal_format,
 												   LLGLenum primary_format,
@@ -1346,7 +1346,7 @@ LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id, S32 priority)
 
 	const BOOL use_mips = FALSE;
 	const LLRect scale_rect = LLRect::null;
-	return loadUIImageByID(image_id, use_mips, scale_rect, priority);
+	return loadUIImageByID(image_id, use_mips, scale_rect, (LLViewerTexture::EBoostLevel)priority);
 }
 
 LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priority)
@@ -1360,21 +1360,27 @@ LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priori
 
 	const BOOL use_mips = FALSE;
 	const LLRect scale_rect = LLRect::null;
-	return loadUIImageByName(image_name, image_name, use_mips, scale_rect, priority);
+	return loadUIImageByName(image_name, image_name, use_mips, scale_rect, (LLViewerTexture::EBoostLevel)priority);
 }
 
 LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std::string& filename,
-											  BOOL use_mips, const LLRect& scale_rect, S32 boost_priority )
+											  BOOL use_mips, const LLRect& scale_rect, LLViewerTexture::EBoostLevel boost_priority )
 {
-	if (boost_priority == 0) boost_priority = LLViewerFetchedTexture::BOOST_UI;
+	if (boost_priority == LLViewerTexture::BOOST_NONE)
+	{
+		boost_priority = LLViewerTexture::BOOST_UI;
+	}
 	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, MIPMAP_NO, boost_priority);
 	return loadUIImage(imagep, name, use_mips, scale_rect);
 }
 
 LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id,
-											BOOL use_mips, const LLRect& scale_rect, S32 boost_priority)
+											BOOL use_mips, const LLRect& scale_rect, LLViewerTexture::EBoostLevel boost_priority)
 {
-	if (boost_priority == 0) boost_priority = LLViewerFetchedTexture::BOOST_UI;
+	if (boost_priority == LLViewerTexture::BOOST_NONE)
+	{
+		boost_priority = LLViewerTexture::BOOST_UI;
+	}
 	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, MIPMAP_NO, boost_priority);
 	return loadUIImage(imagep, id.asString(), use_mips, scale_rect);
 }
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 3c9c81a689a50f36191220c3024d9631027a982f..028f8441ab0a44f48dadbe2dd38f580ca8ad5018 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -130,7 +130,7 @@ class LLViewerTextureList
 
 	LLViewerFetchedTexture * getImage(const LLUUID &image_id,									 
 									 BOOL usemipmap = TRUE,
-									 S32 boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -139,7 +139,7 @@ class LLViewerTextureList
 	
 	LLViewerFetchedTexture * getImageFromFile(const std::string& filename,									 
 									 BOOL usemipmap = TRUE,
-									 S32 boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -148,7 +148,7 @@ class LLViewerTextureList
 	
 	LLViewerFetchedTexture* getImageFromUrl(const std::string& url,
 									 BOOL usemipmap = TRUE,
-									 BOOL level_immediate = FALSE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -157,7 +157,7 @@ class LLViewerTextureList
 
 	LLViewerFetchedTexture* createImage(const LLUUID &image_id,
 									 BOOL usemipmap = TRUE,
-									 S32 boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -228,9 +228,11 @@ class LLUIImageList : public LLImageProviderInterface, public LLSingleton<LLUIIm
 	static void onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
 private:
 	LLUIImagePtr loadUIImageByName(const std::string& name, const std::string& filename,
-								   BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, S32 boost_priority = 0);
+		                           BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, 
+		                           LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI);
 	LLUIImagePtr loadUIImageByID(const LLUUID& id,
-								 BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, S32 boost_priority = 0);
+								 BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, 
+								 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI);
 
 	LLUIImagePtr loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null);
 
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 89649407ff07249360726a445d988819a66ea690..d93913b9443849d73a2d47f86c33b6897f19958c 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -306,8 +306,10 @@ void LLVoiceChannel::activate()
 		// activating the proximal channel between IM calls
 		LLVoiceChannel* old_channel = sCurrentVoiceChannel;
 		sCurrentVoiceChannel = this;
+		mCallDialogPayload["old_channel_name"] = "";
 		if (old_channel)
 		{
+			mCallDialogPayload["old_channel_name"] = old_channel->getSessionName();
 			old_channel->deactivate();
 		}
 	}
@@ -870,6 +872,19 @@ void LLVoiceChannelP2P::setState(EState state)
 {
 	// HACK: Open/close the call window if needed.
 	toggleCallWindowIfNeeded(state);
+	
+	// *HACK: open outgoing call floater if needed, might be better done elsewhere.
+	mCallDialogPayload["session_id"] = mSessionID;
+	mCallDialogPayload["session_name"] = mSessionName;
+	mCallDialogPayload["other_user_id"] = mOtherUserID;
+	if (!mReceivedCall && state == STATE_RINGING)
+	{
+		llinfos << "RINGINGGGGGGGG " << mSessionName << llendl;
+		if (!mSessionName.empty())
+		{
+			LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE);
+		}
+	}
 
 	// you only "answer" voice invites in p2p mode
 	// so provide a special purpose message here
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index 20b6157b48b7c09f80929dad64532c1a4edde95d..639585de559bed89c1756831f216471540e31c85 100644
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -109,6 +109,7 @@ class LLVoiceChannel : public LLVoiceClientStatusObserver
 	EState		mState;
 	std::string	mSessionName;
 	LLSD mNotifyArgs;
+	LLSD mCallDialogPayload;
 	BOOL		mIgnoreNextSessionLeave;
 	LLHandle<LLPanel> mLoginNotificationHandle;
 
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 39d4bb0c029396af530e18908570179de4ba5a45..5fedfc943bfe9caf3a34e640d219ece4e65e97a7 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -1598,7 +1598,7 @@ void LLVoiceClient::stateMachine()
 				}
 				else
 				{
-					LL_WARNS("Voice") << "region doesn't have ParcelVoiceInfoRequest capability.  This is normal for a short time after teleporting, but bad if it persists for very long." << LL_ENDL;
+					LL_WARNS_ONCE("Voice") << "region doesn't have ParcelVoiceInfoRequest capability.  This is normal for a short time after teleporting, but bad if it persists for very long." << LL_ENDL;
 				}
 			}
 		}
@@ -4273,7 +4273,7 @@ void LLVoiceClient::mediaStreamUpdatedEvent(
 				if(incoming)
 				{
 					// Send the voice chat invite to the GUI layer
-					// TODO: Question: Should we correlate with the mute list here?
+					// *TODO: Question: Should we correlate with the mute list here?
 					session->mIMSessionID = LLIMMgr::computeSessionID(IM_SESSION_P2P_INVITE, session->mCallerID);
 					session->mVoiceInvitePending = true;
 					if(session->mName.empty())
diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp
index 8d3165b98c65eb47d8d91759aee9cef25571d7bc..9897f40c4e96afbaa2b382f2abeaefa2f51847e3 100644
--- a/indra/newview/llworldmipmap.cpp
+++ b/indra/newview/llworldmipmap.cpp
@@ -196,7 +196,7 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32
 	// END DEBUG
 	//LL_INFOS("World Map") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL;
 
-	LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
+	LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 	img->setBoostLevel(LLViewerTexture::BOOST_MAP);
 
 	// Return the smart pointer
diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml
index 5c09bc3a02b338eacc634d029fe4fc7c4ae4cb76..f553184c19a12fe6e374e0133467af32eb4791b2 100644
--- a/indra/newview/skins/default/xui/en/floater_camera.xml
+++ b/indra/newview/skins/default/xui/en/floater_camera.xml
@@ -49,22 +49,57 @@
          top="22"
          visible="false"
          width="78" />
-         <!--TODO: replace with slider, + - images -->
- <joystick_zoom
-         follows="top|left"
-         height="78"
-         image_unselected="ScrollThumb_Vert"
-         layout="topleft"
-         left="7"
-         minus_image="ScrollThumb_Vert"
-         name="zoom"
-         plus_image="ScrollThumb_Vert"
-         quadrant="left"
-         scale_image="false"
-         sound_flags="3"
-         tool_tip="Zoom camera toward focus"
-         top="22"
-         width="20" />
+         <!--TODO: replace + - images -->
+         <panel
+            border="false"
+            class="camera_zoom_panel"
+            height="94"
+            layout="topleft"
+            left="7"
+            mouse_opaque="false"
+            name="zoom"
+            top="22"
+            width="18">
+           <button
+              follows="top|left"
+              height="18"
+              image_disabled="AddItem_Disabled"
+              image_selected="AddItem_Press"
+              image_unselected="AddItem_Off"
+              layout="topleft"
+              name="zoom_plus_btn"
+              width="18">
+             <commit_callback
+                function="Zoom.plus" />
+             <mouse_held_callback
+                function="Zoom.plus" />
+           </button>
+           <slider_bar
+              height="48"
+              layout="topleft"
+              name="zoom_slider"
+              orientation="vertical"
+              tool_tip="Zoom camera toward focus"
+              top_pad="0"
+              width="18">
+             <commit_callback function="Slider.value_changed"/>
+           </slider_bar>
+           <button
+              follows="top|left"
+              height="18"
+              image_disabled="AddItem_Disabled"
+              image_selected="AddItem_Press"
+              image_unselected="AddItem_Off"
+              layout="topleft"
+              name="zoom_minus_btn"
+              top_pad="0"
+              width="18">
+             <commit_callback
+                function="Zoom.minus" />
+             <mouse_held_callback
+                function="Zoom.minus" />
+           </button>
+         </panel>
          <joystick_rotate
          follows="top|left"
          height="78"
@@ -72,6 +107,7 @@
          image_unselected="Cam_Rotate_Out"
          layout="topleft"
          left="45"
+         mouse_opaque="false" 
          name="cam_rotate_stick"
          quadrant="left"
          scale_image="false"
@@ -80,7 +116,7 @@
          tool_tip="Orbit camera around focus"
          top="22"
          width="78" />
-            <panel
+         <panel
          height="78"
          layout="topleft"
          left="36"
diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml
index b23482655cf524845464bf121cd5188e966d7b5b..a3ac87820280ff57f6d81090b227d5bfd62f7291 100644
--- a/indra/newview/skins/default/xui/en/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_gesture.xml
@@ -84,21 +84,21 @@
                  top_delta="0"
                  width="18" />
                 <button
-                 follows="bottom|left"
+                 follows="bottom|right"
                  font="SansSerifBigBold"
                  height="18"
                  image_selected="TrashItem_Press"
                  image_unselected="TrashItem_Off"
                  image_disabled="TrashItem_Disabled"
                  layout="topleft"
-                 left_pad="230"
                  name="del_btn"
+                 right="-5"
                  tool_tip="Delete this gesture"
                  top_delta="0"
                  width="18" />
             </panel>
     <button
-     follows="bottom|right"
+     follows="left|bottom"
      height="23"
      label="Edit"
      layout="topleft"
@@ -107,7 +107,7 @@
      top_pad="5"
      width="83" />
     <button
-     follows="bottom|right"
+     follows="left|bottom"
      height="23"
      label="Play"
      layout="topleft"
@@ -116,7 +116,7 @@
      top_delta="0"
      width="83" />
     <button
-     follows="bottom|right"
+     follows="left|bottom"
      height="23"
      label="Stop"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
index 16873df31014cde3a7c43512d89e3b94d45c3ce4..9c2898945ba7b150fd703a130899d45df4e850b5 100644
--- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
@@ -4,13 +4,17 @@
  can_close="false"
  can_minimize="false"
  can_tear_off="false"
- height="200"
+ height="125"
  layout="topleft"
  name="incoming call"
  help_topic="incoming_call"
  title="UNKNOWN PERSON IS CALLING"
- width="240">
-     <floater.string
+ width="410">
+    <floater.string
+     name="localchat">
+        Local Voice Chat
+    </floater.string>
+    <floater.string
      name="anonymous">
         anonymous
     </floater.string>
@@ -31,18 +35,26 @@
      left_delta="19"
      top="35"
      width="36" />
-    <text_editor
-     font="SansSerif"
-     height="64"
-     border_visible="false"
+    <text
+     font="SansSerifLarge"
+     height="20"
      layout="topleft"
      left="77"
-     max_length="2147483647"
      name="caller name"
-     read_only="true"
-     top="21"
-     width="163"
+     top="27"
+     width="315"
      word_wrap="true" />
+    <text
+     font="SansSerif"
+     height="50"
+     layout="topleft"
+     left="77"
+     name="question"
+     top="52"
+     width="315"
+     word_wrap="true">
+     Do you want to leave [CURRENT_CHAT] and join this voice chat?
+    </text>
     <button
      height="24"
      label="Accept"
@@ -57,16 +69,14 @@
      label="Reject"
      label_selected="Reject"
      layout="topleft"
-     left_delta="0"
      name="Reject"
-     top_pad="12"
+     left_pad="10"
      width="100" />
     <button
      height="24"
      label="Start IM"
      layout="topleft"
-     left_delta="0"
      name="Start IM"
-     top_pad="12"
+     left_pad="10"
      width="100" />
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml
index 30639f955f4335ebf95af27eb1ae14efed58858d..b48c962413f02d1440b73127e03ef0ba28ceb754 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory.xml
@@ -36,10 +36,10 @@
 	 filename="panel_main_inventory.xml"
 	 follows="all"
 	 layout="topleft"
+	 hide_top_panel="true"
 	 left="0"
 	 label="Inventory Panel"
 	 name="Inventory Panel"
 	 top="15"
-	 width="467">
-</panel>
+	 width="467" />
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml
new file mode 100644
index 0000000000000000000000000000000000000000..44956f7e52f1b32a621cfa4df21426596e5c3498
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_close="false"
+ can_minimize="false"
+ can_tear_off="false"
+ height="125"
+ layout="topleft"
+ name="outgoing call"
+ help_topic="outgoing_call"
+ title="CALLING"
+ width="410">
+    <floater.string
+     name="localchat">
+        Local Voice Chat
+    </floater.string>
+    <floater.string
+     name="anonymous">
+        anonymous
+    </floater.string>
+    <floater.string
+     name="VoiceInviteP2P">
+        is calling.
+    </floater.string>
+    <floater.string
+     name="VoiceInviteAdHoc">
+        has joined a Voice Chat call with a conference chat.
+    </floater.string>
+    <avatar_icon
+     enabled="false"
+     follows="left|top"
+     height="36"
+     image_name="icon_avatar_online.tga"
+     layout="topleft"
+     left_delta="19"
+     top="35"
+     width="36" />
+    <text
+     font="SansSerifLarge"
+     height="20"
+     layout="topleft"
+     left="77"
+     name="calling"
+     top="27"
+     width="315"
+     word_wrap="true">
+Calling [CALLEE_NAME]
+    </text>
+    <text
+     font="SansSerif"
+     height="50"
+     layout="topleft"
+     left="77"
+     name="leaving"
+     top="52"
+     width="315"
+     word_wrap="true">
+Leaving [CURRENT_CHAT].
+    </text>
+    <button
+     height="24"
+     label="Cancel"
+     label_selected="Cancel"
+     left="70"
+     layout="topleft"
+     name="Cancel"
+     left_pad="10"
+     width="100" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_slider.xml b/indra/newview/skins/default/xui/en/floater_test_slider.xml
index 57d8e686ce3d5235a2a9003a90d6d00b86c8071a..86ff82e01f2b244ef5b08cfbdcfc31ce7b2e3b47 100644
--- a/indra/newview/skins/default/xui/en/floater_test_slider.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_slider.xml
@@ -57,6 +57,13 @@
      width="200" />
     <slider_bar
      bottom="320"
+     height="100"
+     left="20"
+     name="slider_bar_vertical"
+     orientation="vertical"
+     width="20" />
+    <slider_bar
+     bottom="300"
      height="20"
      increment="1"
      initial_value="2.0"
@@ -64,6 +71,7 @@
      layout="topleft"
      max_val="5"
      min_val="1"
+     left_pad="20"
      name="slider_bar"
      width="300" />
     <slider
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index c33d7cf31d8e0c263af15d0687789ea5644c66f8..b2f46bc433959005105f0372a73c4995c9748d82 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -262,6 +262,18 @@
 		  <check_box.commit_callback
 			function="BuildTool.selectComponent"/>
 	</check_box>
+
+   <text
+   text_color="LtGray_50"
+   follows="top|left"
+   halign="left"
+   left="13"
+   name="RenderingCost"
+   top_pad="9"
+   type="string"
+   width="100">
+   þ: [COUNT]
+   </text>
 	<check_box
      control_name="ScaleUniform"
      height="19"
@@ -325,7 +337,7 @@
 	 <button.commit_callback
 	     function="BuildTool.gridOptions"/>
 	</button>
-    <button
+   <button
      follows="left|top"
      height="20"
      image_disabled="Object_Cube"
@@ -701,6 +713,7 @@
 	     function="BuildTool.applyToSelection"/>
     </button>
     <text
+    text_color="LtGray_50"
      type="string"
      length="1"
      height="12"
@@ -714,6 +727,7 @@
         Objects: [COUNT]
     </text>
     <text
+    text_color="LtGray_50"
      type="string"
      length="1"
      follows="left|top"
@@ -730,7 +744,7 @@
      halign="center"
      left="0"
      name="Object Info Tabs"
-     tab_max_width="55"
+     tab_max_width="54"
      tab_min_width="40"
      tab_position="top"
      tab_height="25"
diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml
index 4e2cce1428c392baeb908d6bcca5d8af31bdd722..1adb824e2a6ad6ff4956db4b9167488a13221699 100644
--- a/indra/newview/skins/default/xui/en/floater_tos.xml
+++ b/indra/newview/skins/default/xui/en/floater_tos.xml
@@ -53,22 +53,6 @@
         Please read the following Terms of Service carefully. To continue logging in to [SECOND_LIFE],
 you must accept the agreement.
     </text>
-    <text_editor
-     type="string"
-     length="1"
-     follows="left|top"
-     font="SansSerif"
-     height="283"
-     layout="topleft"
-     left_delta="0"
-     max_length="65536"
-     name="tos_text"
-     top_pad="43"
-     width="568"
-     handle_edit_keys_directly="true" 
-     word_wrap="true">
-        TOS_TEXT
-    </text_editor>
     <web_browser
      follows="left|top"
      height="340"
@@ -76,6 +60,6 @@ you must accept the agreement.
      left_delta="0"
      name="tos_html"
      start_url="data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E Loading %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E"
-     top_delta="-27"
+     top_delta="0"
      width="568" />
 </floater>
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
index 6dd44255bf30c2fcb9b8ad5851df2b39a1305174..304492bedb2c330abba093bc6d2d9a20b62ea7db 100644
--- a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
@@ -13,15 +13,11 @@
        function="CheckControl"
        parameter="GroupListShowIcons" />
   </menu_item_check>
-  <menu_item_check
+  <menu_item_call
    label="Leave Selected Group"
    layout="topleft"
    name="Leave Selected Group">
-      <menu_item_check.on_click
-       function="People.Groups.ViewSort.Action"
-       parameter="show_icons" />
-      <menu_item_check.on_check
-       function="CheckControl"
-       parameter="GroupListShowIcons" />
-  </menu_item_check>
+      <menu_item_call.on_click
+       function="People.Group.Minus.Action"/>
+  </menu_item_call>
 </menu>
diff --git a/indra/newview/skins/default/xui/en/menu_profile_overflow.xml b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7b52fecef713b9255d35a89f525318d76122b7a6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ height="50"
+ layout="topleft"
+ mouse_opaque="false"
+ name="profile_overflow_menu"
+ width="120">
+    <menu_item_call
+     label="Pay"
+     layout="topleft"
+     name="pay">
+        <menu_item_call.on_click
+         function="Profile.Pay" />
+    </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index ff0cd7ffebe57e63c054380c22739992763137f1..70b21d14bec5f204dff128667b60341e31f48aca 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4957,8 +4957,9 @@ No valid parcel could be found.
   <notification
    icon="notify.tga"
    name="ObjectGiveItem"
-   type="notify">
-An object named [OBJECTFROMNAME] owned by [FIRST] [LAST] has given you a [OBJECTTYPE] named [OBJECTNAME].
+   type="offer">
+An object named [OBJECTFROMNAME] owned by [NAME] has offered you [OBJECTTYPE]:
+[ITEM_SLURL]
     <form name="form">
       <button
        index="0"
@@ -5000,7 +5001,8 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you a
    icon="notify.tga"
    name="UserGiveItem"
    type="offer">
-[NAME] has given you a [OBJECTTYPE] named &apos;[OBJECTNAME]&apos;.
+[NAME] has offered you [OBJECTTYPE]:
+[ITEM_SLURL]
     <form name="form">
       <button
        index="0"
@@ -5739,6 +5741,15 @@ Are you sure you want to delete your teleport history?
      yestext="OK"/>
   </notification>
 
+  <notification
+   icon="alert.tga"
+   name="BottomTrayButtonCanNotBeShown"
+   type="alert">
+Selected button can not be shown right now.
+The button will be shown when there is enough space for it.
+  </notification>
+
+
   <global name="UnsupportedCPU">
 - Your CPU speed does not meet the minimum requirements.
   </global>
diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
index 5562ec84066302b124706c42e833f371217a9f50..38294c907a3fab60aad946015d2c9812ffcc8a50 100644
--- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml
+++ b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
@@ -7,7 +7,9 @@
 	left="0"
 	height="35"
 	width="318"
-	background_visible="false">
+  background_opaque="false"
+  background_visible="true"
+  bg_alpha_color="0.0 0.0 0.0 0.0" >
   <chiclet_im_p2p
 		name="p2p_chiclet"
 		layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 818801645527b5eb23a2021dadf06b6dcee65c7c..a902f50582431ce571deb58fa79fdc83fb3bcd3b 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -13,6 +13,8 @@
  chrome="true"
  border_visible="false"
  width="1000">
+  <string name="SpeakBtnToolTip">Turns microphone on/off</string>
+  <string name="VoiceControlBtnToolTip">Shows/hides voice control panel</string>
     <layout_stack
      mouse_opaque="false"
      border_size="0"
@@ -70,9 +72,7 @@
            left="0"
            name="talk"
            top="3"
-          width="100"
-          speak_button.tool_tip="Turns microphone on/off"
-          show_button.tool_tip="Shows/hides voice control panel" />
+          width="100" />
         </layout_panel>
         <icon
             auto_resize="false"
@@ -333,6 +333,6 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
          min_width="4" 
          right="-1"
          top="0"
-         width="26"/>
+         width="4"/>
     </layout_stack>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml
index ef3120174e8cb3337ff91ac1366f13df3c75b6b9..984a799b41a8ac8991fc18ef477dd355c820040d 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml
@@ -1,77 +1,117 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel background_visible="true" bevel_style="in" bg_alpha_color="0 0 0 0"
-	height="155" label="instant_message" layout="topleft" left="0"
-	name="panel_group_notify" top="0" width="350">
-    <string
-     name="message_max_lines_count">
-        4
-    </string>
-	<panel follows="top" background_visible="true" bevel_style="in" bg_alpha_color="black"
-		height="30" label="header" layout="topleft" left="0" name="header"
-		top="0" width="350">
-		<icon follows="left|top|right|bottom" height="20"  width="20" layout="topleft"
-			top="5"  left="5" mouse_opaque="true" name="group_icon"/>
-		<text type="string" length="1" follows="left|top|right|bottom"
-			font="SansSerifBigBold" height="20" layout="topleft" left_pad="10" name="title"
-			text_color="GroupNotifyTextColor" top="5" width="275" use_ellipses="true">
-			Sender Name / Group Name
-        </text>
-	</panel>
-	<text
-     follows="top"
-     height="20"
-     layout="topleft"
-     left="25"
-     name="subject"
-     text_color="GroupNotifyTextColor"
-     font="SansSerifBig"
-     top="40"
-     use_ellipses="true"
-     value="subject"
-     width="300"
-     word_wrap="true">
-     subject 
-    </text>
-    <text
-     follows="top"
-     height="20"
-     layout="topleft"
-     left="25"
-     name="datetime"
-     text_color="GroupNotifyTextColor"
-     font="SansSerif"
-     top="80"
-     use_ellipses="true"
-     value="datetime"
-     width="300"
-     word_wrap="true">
-     datetime
-    </text>
-    <text
-     follows="left|top|bottom|right"
-     height="0"
-     layout="topleft"
-     left="25"
-     name="message"
-     text_color="GroupNotifyTextColor"
-     top="100"
-     use_ellipses="true"
-     value="message"
-     width="300"
-     word_wrap="true"
-     visible="true" >
-    </text>
-    <icon
-	  follows="left|bottom|right" height="15" width="15"
-		layout="topleft" bottom="122" left="25" mouse_opaque="true" name="attachment_icon" visible="true"
-	/>
-	<text font="SansSerif" font.style="UNDERLINE" font_shadow="none"
-		type="string" length="1" follows="left|bottom|right" layout="topleft"
-		left="45" bottom="122" height="15" width="280" name="attachment"
-		text_color="GroupNotifyTextColor" visible="true">
-		Attachment
-     </text>
-
-	<button label="OK" layout="topleft" bottom="145" left="140" height="20"
-		width="70" name="btn_ok" follows="bottom" />
-</panel>
\ No newline at end of file
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ bevel_style="in"
+ bg_alpha_color="0 0 0 0"
+ height="135"
+ label="instant_message"
+ layout="topleft"
+ left="0"
+ name="panel_group_notify"
+ top="0"
+ width="305">
+    <string
+     name="message_max_lines_count"
+     value="4" />
+    <panel
+     background_visible="true"
+     bevel_style="in"
+     bg_alpha_color="black"
+     follows="top"
+     height="30"
+     label="header"
+     layout="topleft"
+     left="0"
+     name="header"
+     top="0"
+     width="305">
+        <icon
+         follows="left|top|right|bottom"
+         height="20"
+         layout="topleft"
+         left="5"
+         mouse_opaque="true"
+         name="group_icon"
+         top="5"
+         width="20" />
+        <text
+         follows="left|top|right|bottom"
+         font="SansSerifBigBold"
+         height="20"
+         layout="topleft"
+         left_pad="10"
+         name="title"
+         text_color="GroupNotifyTextColor"
+         top="5"
+         use_ellipses="true"
+         value="Sender Name / Group Name"
+         width="230" />
+    </panel>
+    <text
+     follows="top"
+     font="SansSerifBig"
+     height="20"
+     layout="topleft"
+     left="25"
+     name="subject"
+     text_color="GroupNotifyTextColor"
+     top="40"
+     use_ellipses="true"
+     value="subject"
+     width="270"
+     wrap="true" />
+    <text
+     follows="top"
+     font="SansSerif"
+     height="20"
+     layout="topleft"
+     left="25"
+     name="datetime"
+     text_color="GroupNotifyTextColor"
+     top="80"
+     use_ellipses="true"
+     value="datetime"
+     width="270"
+     wrap="true" />
+    <text
+     follows="left|top|bottom|right"
+     height="0"
+     layout="topleft"
+     left="25"
+     name="message"
+     text_color="GroupNotifyTextColor"
+     top="100"
+     use_ellipses="true"
+     value="message"
+     width="270"
+     wrap="true" />
+    <icon
+     bottom="122"
+     follows="left|bottom|right"
+     height="15"
+     layout="topleft"
+     left="25"
+     mouse_opaque="true"
+     name="attachment_icon"
+     width="15" />
+    <text
+     bottom="122"
+     follows="left|bottom|right"
+     font="SansSerif"
+     height="15"
+     layout="topleft"
+     left="45"
+     name="attachment"
+     text_color="GroupNotifyTextColor"
+     value="Attachment"
+     width="280" />
+    <button
+     bottom="130"
+     follows="bottom"
+     height="20"
+     label="OK"
+     layout="topleft"
+     left="25"
+     name="btn_ok"
+     width="70" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index a77094e9420613c82153a43d598c04e1264286dd..ecf35523cd863b862cabbd33cf79e0049d440287 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -23,7 +23,7 @@
      layout="topleft"
      left_delta="7"
      left="0"
-     max_length="254"
+     max_length="512"
      name="chat_box"
      tool_tip="Press Enter to say, Ctrl+Enter to shout"
      top="0"
diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml
index 34a185fb44a23bb1e672f8ce58a8c3a4330a6f8b..462188ee24a84c572fea52248f018032c81caf32 100644
--- a/indra/newview/skins/default/xui/en/panel_notification.xml
+++ b/indra/newview/skins/default/xui/en/panel_notification.xml
@@ -10,7 +10,7 @@
   left="0"
   name="notification_panel"
   top="0"
-  	height="10"
+  	height="140"
   width="305">
   <!-- THIS PANEL CONTROLS TOAST HEIGHT? -->
   <panel
@@ -20,18 +20,18 @@
   bg_alpha_color="0.3 0.3 0.3 0"
   bg_opaque_color="0.3 0.3 0.3 0"
     follows="left|right|top"
-    height="10"
+    height="100"
     label="info_panel"
     layout="topleft"
     left="0"
     name="info_panel"
     top="0"
     width="305">
-  <!--  <text
+    <text
       border_visible="false"
       follows="left|right|top|bottom"
       font="SansSerif"
-      height="90"
+      height="85"
       layout="topleft"
       left="10"
       name="text_box"
@@ -39,21 +39,21 @@
       text_color="white"
       top="10"
       visible="false" 
-      width="300"
+      width="285"
       wrap="true"/>
     <text
       border_visible="false"
       follows="left|right|top|bottom"
       font="SansSerifBold"
-      height="90"
+      height="85"
       layout="topleft"
-      left="45"
+      left="10"
       name="caution_text_box"
       text_color="1 0.82 0.46 1"
-      top="5"
+      top="10"
       visible="false"
-      width="300"
-      wrap="true"/>  -->
+      width="285"
+      wrap="true"/>
     <text_editor
     	h_pad="0"
 	v_pad="0"
@@ -63,6 +63,7 @@
       enabled="false"
       follows="left|right|top|bottom"
       font="SansSerif"
+      height="85" 
       layout="topleft"
       left="10"
       mouse_opaque="false"
@@ -74,17 +75,20 @@
       top="10"
       visible="false"
       width="285"
-      wrap="true"/>
+      wrap="true"
+      parse_highlights="true"
+      allow_html="true"/>
   </panel>
   <panel
     background_visible="false"
     follows="left|right|bottom"
+    height="40" 
     label="control_panel"
     layout="topleft"
     left="0"
     left_delta="-38"
     name="control_panel"
-    top="20">
+    top_pad="0">
   </panel>
   <!--
   <icon
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index 0f5e96416df6616f9cfa1cd98ecabcae1d417aca..5110b6b2ef5768b9e817d961f0ae85d5b45010a2 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -283,7 +283,7 @@
          mouse_opaque="false"
          name="add_friend"
          top="5"
-         width="75" />
+         width="76" />
         <button
          follows="bottom|left"
          height="19"
@@ -292,7 +292,7 @@
          name="im"
          top="5"
          left_pad="5"
-         width="45" />
+         width="31" />
         <button
          follows="bottom|left"
          height="19"
@@ -301,7 +301,7 @@
          name="call"
          left_pad="5"
          top="5"
-         width="45" />
+         width="40" />
         <button
          enabled="false"
          follows="bottom|left"
@@ -311,7 +311,7 @@
          name="show_on_map_btn"
          top="5"
          left_pad="5"
-         width="45" />
+         width="42" />
         <button
          follows="bottom|left"
          height="19"
@@ -320,7 +320,17 @@
          name="teleport"
          left_pad="5"
          top="5"
-         width="80" />
+         width="64" />
+        <button
+         follows="bottom|right"
+         font="SansSerifSmall"
+         height="19"
+         label="â–¼"
+         layout="topleft"
+         name="overflow_btn"
+         right="-1"
+         top="5"
+         width="21" />
  </panel>
  <panel
      follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
index 7722583ce21c59630836e11e5304f7dc928e3542..63e60aab784d7be42230dc9a429e8a0c5346567c 100644
--- a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
@@ -9,7 +9,10 @@
   width="300"
   height="35"
   layout="topleft"
-  follows="left|right">
+  follows="left|right"
+  background_opaque="false"
+  background_visible="true"
+  bg_alpha_color="0.0 0.0 0.0 0.0" >
   <text
     top="2"
     left="10"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index ea66bfa197fbfa14bb0a338fa5088fbef93ca991..761c17cfd2819c3a8eb57f83f8a2bc55d77a2c27 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2863,7 +2863,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
     Connecting...
   </string>
   <string name="conference-title">
-    Friends Conference
+    Ad-hoc Conference
   </string>
   <string name="inventory_item_offered-im">
     Inventory item offered
diff --git a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
index bc1ca339a2054ce9953be12ea1deb66715694178..706c89f5ed155bcf438253d73f011d02e928edce 100644
--- a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
@@ -4,6 +4,8 @@
             thumb_center_color="SliderThumbCenterColor"
             thumb_image="SliderThumb_Off"
             thumb_image_pressed="SliderThumb_Press"
-            thumb_image_disabled="SliderThumb_Disabled" 
-            track_image="SliderTrack_Horiz"
-            track_highlight_image="SliderTrack_Horiz" />
+            thumb_image_disabled="SliderThumb_Disabled"
+            track_image_horizontal="SliderTrack_Horiz"
+            track_image_vertical="SliderTrack_Vert"
+            track_highlight_horizontal_image="SliderTrack_Horiz"
+            track_highlight_vertical_image="SliderTrack_Vert" />
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index d31a81e1280ae0f5be8087fee28d218cf56db24a..7b28a3b72c3898b63ebe3d5ab02f2570eb4d1d92 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -76,6 +76,7 @@ LLControlGroup::LLControlGroup(const std::string& name) :
 LLControlGroup::~LLControlGroup() {}
 void LLControlGroup::setBOOL(const std::string& name, BOOL val) {}
 BOOL LLControlGroup::getBOOL(const std::string& name) { return FALSE; }
+F32 LLControlGroup::getF32(const std::string& name) { return 0.0f; }
 U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; }
 void LLControlGroup::setString(const std::string& name, const std::string& val) {}
 std::string LLControlGroup::getString(const std::string& name) { return "test_string"; }
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index 7a30315b9a8c7c30b110f4c3f78bf84c1fe942f8..b14c59ab9ac1d702501ae9a26b1a92fe4619f69e 100644
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -70,7 +70,7 @@ class LLLogin::Impl
 	LLEventPump& getEventPump() { return mPump; }
 
 private:
-	void sendProgressEvent(const std::string& state, const std::string& change,
+	LLSD getProgressEventLLSD(const std::string& state, const std::string& change,
 						   const LLSD& data = LLSD())
 	{
 		LLSD status_data;
@@ -87,7 +87,13 @@ class LLLogin::Impl
 		{
 			status_data["data"] = data;
 		}
+		return status_data;
+	}
 
+	void sendProgressEvent(const std::string& state, const std::string& change,
+						   const LLSD& data = LLSD())
+	{
+		LLSD status_data = getProgressEventLLSD(state, change, data);
 		mPump.post(status_data);
 	}
 
@@ -140,15 +146,28 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD credential
         // Request SRV record.
         LL_INFOS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL;
 
-        // *NOTE:Mani - Completely arbitrary timeout value for SRV request.
-        filter.errorAfter(5, "SRV Request timed out!");
+        // *NOTE:Mani - Completely arbitrary default timeout value for SRV request.
+		F32 seconds_to_timeout = 5.0f;
+		if(credentials.has("cfg_srv_timeout"))
+		{
+			seconds_to_timeout = credentials["cfg_srv_timeout"].asReal();
+		}
+
+		filter.eventAfter(seconds_to_timeout, 
+			getProgressEventLLSD("offline", "fail.login"));
+
+		std::string srv_pump_name = "LLAres";
+		if(credentials.has("cfg_srv_pump"))
+		{
+			srv_pump_name = credentials["cfg_srv_pump"].asString();
+		}
 
-        // Make request
+		// Make request
         LLSD request;
         request["op"] = "rewriteURI";
         request["uri"] = uri;
         request["reply"] = replyPump.getName();
-        rewrittenURIs = postAndWait(self, request, "LLAres", filter);
+        rewrittenURIs = postAndWait(self, request, srv_pump_name, filter);
     } // we no longer need the filter
 
     LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction"));
diff --git a/indra/viewer_components/login/tests/lllogin_test.cpp b/indra/viewer_components/login/tests/lllogin_test.cpp
index a8ae2883d54ddcd13899e2d4a7bdc6284c46f686..99ea796ad0103d74173fc40e11c120fbed5903e6 100644
--- a/indra/viewer_components/login/tests/lllogin_test.cpp
+++ b/indra/viewer_components/login/tests/lllogin_test.cpp
@@ -47,6 +47,7 @@ class LoginListener: public LLEventTrackable
 	bool call(const LLSD& event)
 	{
 		mDebug(STRINGIZE("LoginListener called!: " << event));
+		
 		mLastEvent = event;
 		return false;
 	}
@@ -414,4 +415,42 @@ namespace tut
 
 		ensure_equals("Failed to offline", listener.lastEvent()["state"].asString(), "offline");
 	}
+
+/*
+    template<> template<>
+    void llviewerlogin_object::test<5>()
+    {
+        DEBUG;
+		// Test SRV request timeout.
+		set_test_name("LLLogin SRV timeout testing");
+
+		// Testing normal login procedure.
+		LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.
+
+		// LLAresListener dummyLLAres("dummy_llares");
+		// dummyLLAres.listenTo(llaresPump);
+
+		LLLogin login;
+		LoginListener listener("test_ear");
+		listener.listenTo(login.getEventPump());
+
+		LLSD credentials;
+		credentials["first"] = "these";
+		credentials["last"] = "don't";
+		credentials["passwd"] = "matter";
+		credentials["cfg_srv_timeout"] = 0.0f;
+
+		login.connect("login.bar.com", credentials);
+
+		ensure_equals("SRV State", listener.lastEvent()["change"].asString(), "srvrequest"); 
+
+		// Get the mainloop eventpump, which needs a pinging in order to drive the 
+		// SRV timeout.
+		LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
+		LLSD frame_event;
+		mainloop.post(frame_event);
+
+		ensure_equals("SRV Failure", listener.lastEvent()["change"].asString(), "fail.login"); 
+	}
+*/
 }