diff --git a/.hgpatchinfo/Viewer-Build.dep b/.hgpatchinfo/Viewer-Build.dep
index 1bbd3c55f24693a3aee406c3a1027ce110a98d8c..40641d35a11723a3291ccf2950cd994c09b999f8 100644
--- a/.hgpatchinfo/Viewer-Build.dep
+++ b/.hgpatchinfo/Viewer-Build.dep
@@ -1 +1 @@
-c752f2cb29e1603448903308299658c6f7fb6466
\ No newline at end of file
+b8cd74d2bcc862fc9593bebf5140d5b6367c63c2
\ No newline at end of file
diff --git a/BuildParams b/BuildParams
index 6b7d15f6cca37f89d2a6d16b00409aca9130e20e..f70488d94250ebe58dbfc6e2972e59cad7f63649 100644
--- a/BuildParams
+++ b/BuildParams
@@ -56,6 +56,7 @@ viewer-release.build_viewer_update_version_manager = true
 
 viewer-development-import.build_debug_release_separately = true
 viewer-development-fixes.build_debug_release_separately = true
+viewer-development-tweaks.build_debug_release_separately = true
 
 # =======================================
 # brad
@@ -77,18 +78,6 @@ brad-parabuild.email = brad@lindenlab.com
 brad-parabuild.build_server = false
 brad-parabuild.build_server_tests = false
 
-# ========================================
-# moss
-# ========================================
-
-mossbuild1.email = moss@lindenlab.com
-mossbuild1.build_server = false
-mossbuild1.build_server_tests = false
-
-mossbuild2.email = moss@lindenlab.com
-mossbuild2.build_server = false
-mossbuild2.build_server_tests = false
-
 # ========================================
 # gooey
 # ========================================
@@ -172,6 +161,12 @@ oz_viewer-review2_coverity.build_CYGWIN_Debug = false
 oz_viewer-review2_coverity.build_CYGWIN_RelWithDebInfo = false
 oz_viewer-review2_coverity.build_CYGWIN_Release = false
 
+# ========================================
+# tofu
+# ========================================
+
+tofu_viewer-development-staging.email = tofu.linden@lindenlab.com
+
 # ========================================
 # enus
 # ========================================
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 6edb727682ad4880042ab760fe9bcd0136ee41c3..5892a8081d8f7ec5d0074540edc572cacc971bcb 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -68,6 +68,7 @@ Aleric Inglewood
 	SNOW-766
 Ales Beaumont
 	VWR-9352
+	SNOW-240
 Alissa Sabre
 	VWR-81
 	VWR-83
@@ -406,6 +407,7 @@ Michelle2 Zenovka
 	VWR-8310
 	VWR-9499
 Mm Alder
+	SNOW-376
 	VWR-197
 	VWR-3777
 	VWR-4232
@@ -523,6 +525,8 @@ princess niven
 	CT-352
 Renault Clio
 	VWR-1976
+resu Ampan
+	SNOW-93
 Ringo Tuxing
 	CT-225
 	CT-226
@@ -584,6 +588,8 @@ Sergen Davies
 	CT-230
 	CT-231
 	CT-321
+Shawn Kaufmat
+	SNOW-240
 SignpostMarv Martin
 	VWR-153
 	VWR-154
@@ -641,6 +647,7 @@ Techwolf Lupindo
 	SNOW-649
 	SNOW-680
 	SNOW-681
+	SNOW-690
 	VWR-12385
 tenebrous pau
 	VWR-247
@@ -648,6 +655,8 @@ Tharax Ferraris
 	VWR-605
 Thickbrick Sleaford
 	SNOW-207
+	SNOW-421
+	SNOW-462
 	SNOW-586
 	SNOW-743
 	VWR-7109
@@ -668,6 +677,8 @@ Tue Torok
 	CT-72
 	CT-73
 	CT-74
+Twisted Laws
+	SNOW-352
 Vadim Bigbear
 	VWR-2681
 Vector Hastings
@@ -679,6 +690,7 @@ Whoops Babii
 	VWR-631
 	VWR-1640
 	VWR-3340
+	SNOW-667
 	VWR-4800
 	VWR-4802
 	VWR-4804
diff --git a/indra/cmake/FindJsonCpp.cmake b/indra/cmake/FindJsonCpp.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..9d16f2aaabcfbdb88e7763f16d0ef38deb8580c4
--- /dev/null
+++ b/indra/cmake/FindJsonCpp.cmake
@@ -0,0 +1,55 @@
+# -*- cmake -*-
+
+# - Find JSONCpp
+# Find the JSONCpp includes and library
+# This module defines
+#  JSONCPP_INCLUDE_DIR, where to find json.h, etc.
+#  JSONCPP_LIBRARIES, the libraries needed to use jsoncpp.
+#  JSONCPP_FOUND, If false, do not try to use jsoncpp.
+#  also defined, but not for general use are
+#  JSONCPP_LIBRARY, where to find the jsoncpp library.
+
+FIND_PATH(JSONCPP_INCLUDE_DIR jsoncpp/json.h
+/usr/local/include
+/usr/include
+)
+
+# Get the GCC compiler version
+EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
+            ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
+            OUTPUT_VARIABLE _gcc_COMPILER_VERSION
+            OUTPUT_STRIP_TRAILING_WHITESPACE
+            )
+
+SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so)
+FIND_LIBRARY(JSONCPP_LIBRARY
+  NAMES ${JSONCPP_NAMES}
+  PATHS /usr/lib /usr/local/lib
+  )
+
+IF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
+    SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
+    SET(JSONCPP_FOUND "YES")
+ELSE (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
+  SET(JSONCPP_FOUND "NO")
+ENDIF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
+
+
+IF (JSONCPP_FOUND)
+   IF (NOT JSONCPP_FIND_QUIETLY)
+      MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}")
+   ENDIF (NOT JSONCPP_FIND_QUIETLY)
+ELSE (JSONCPP_FOUND)
+   IF (JSONCPP_FIND_REQUIRED)
+      MESSAGE(FATAL_ERROR "Could not find JSONCpp library")
+   ENDIF (JSONCPP_FIND_REQUIRED)
+ENDIF (JSONCPP_FOUND)
+
+# Deprecated declarations.
+SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIR} )
+GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARY} PATH)
+
+MARK_AS_ADVANCED(
+  JSONCPP_LIBRARY
+  JSONCPP_INCLUDE_DIR
+  )
diff --git a/indra/cmake/JsonCpp.cmake b/indra/cmake/JsonCpp.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..7dd565be7cef495d842f30caf8e9c2191c94b5e2
--- /dev/null
+++ b/indra/cmake/JsonCpp.cmake
@@ -0,0 +1,22 @@
+# -*- cmake -*-
+
+include(Prebuilt)
+
+set(JSONCPP_FIND_QUIETLY ON)
+set(JSONCPP_FIND_REQUIRED ON)
+
+if (STANDALONE)
+  include(FindJsonCpp)
+else (STANDALONE)
+  use_prebuilt_binary(jsoncpp)
+  if (WINDOWS)
+    set(JSONCPP_LIBRARIES 
+      debug json_vc80d
+      optimized json_vc80)
+  elseif (DARWIN)
+    set(JSONCPP_LIBRARIES json_mac-universal-gcc_libmt)
+  elseif (LINUX)
+    set(JSONCPP_LIBRARIES jsoncpp)
+  endif (WINDOWS)
+  set(JSONCPP_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/jsoncpp)
+endif (STANDALONE)
diff --git a/indra/fix-incredibuild.py b/indra/fix-incredibuild.py
new file mode 100644
index 0000000000000000000000000000000000000000..b96b00dc850cddca4329fb5c80bb5eecedaf9e3f
--- /dev/null
+++ b/indra/fix-incredibuild.py
@@ -0,0 +1,38 @@
+import sys
+import os
+import glob
+
+def delete_file_types(path, filetypes):
+    if os.path.exists(path):
+        print 'Cleaning: ' + path
+        orig_dir = os.getcwd();
+        os.chdir(path)
+        filelist = []
+        for type in filetypes:
+            filelist.extend(glob.glob(type))
+        for file in filelist:
+            os.remove(file)
+        os.chdir(orig_dir)
+
+def main():
+    build_types = ['*.exp','*.exe','*.pdb','*.idb',
+                 '*.ilk','*.lib','*.obj','*.ib_pdb_index']
+    pch_types = ['*.pch']
+    delete_file_types("build-vc80/newview/Release", build_types)
+    delete_file_types("build-vc80/newview/secondlife-bin.dir/Release/", 
+                      pch_types)
+    delete_file_types("build-vc80/newview/RelWithDebInfo", build_types)
+    delete_file_types("build-vc80/newview/secondlife-bin.dir/RelWithDebInfo/", 
+                      pch_types)
+    delete_file_types("build-vc80/newview/Debug", build_types)
+    delete_file_types("build-vc80/newview/secondlife-bin.dir/Debug/", 
+                      pch_types)
+
+
+    delete_file_types("build-vc80/test/RelWithDebInfo", build_types)
+    delete_file_types("build-vc80/test/test.dir/RelWithDebInfo/", 
+                      pch_types)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index c82f194ff4a2fa4b1e4f636840f3d71993feae8d..01dfd03c188a903fd6cfb58716faf9d7caa8e607 100644
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -218,7 +218,7 @@ BOOL LLVorbisDecodeState::initDecode()
 	S32 sample_count = ov_pcm_total(&mVF, -1);
 	size_t size_guess = (size_t)sample_count;
 	vorbis_info* vi = ov_info(&mVF, -1);
-	size_guess *= vi->channels;
+	size_guess *= (vi? vi->channels : 1);
 	size_guess *= 2;
 	size_guess += 2048;
 	
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 69e3ff266a8e62acfa2bf2218f1175b1a4e0fc11..10f460e8a6d0baf2ba038b517d093986659969be 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -71,7 +71,7 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize
 		break;
 
 	default:
-		llwarns << "serialize request for unkown ELLSD_Serialize" << llendl;
+		llwarns << "serialize request for unknown ELLSD_Serialize" << llendl;
 	}
 
 	if (f.notNull())
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 88fecb57bf7f9158abb115746bbc569f99e5cf32..7e41e787b52814a97d590cf171463627b6602250 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -435,7 +435,7 @@ LL_COMMON_API bool iswindividual(llwchar elem);
  */
 
 // Make the incoming string a utf8 string. Replaces any unknown glyph
-// with the UNKOWN_CHARACTER. Once any unknown glph is found, the rest
+// with the UNKNOWN_CHARACTER. Once any unknown glyph is found, the rest
 // of the data may not be recovered.
 LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw);
 
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index be0ab9fcb7e82941562ea176cd5ae2b9f3720d0c..5c33b675ca3a64221ee46f48cb5869f14615e5e7 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -147,7 +147,7 @@ U8* LLImageBase::allocateData(S32 size)
 		size = mWidth * mHeight * mComponents;
 		if (size <= 0)
 		{
-			llerrs << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl;
+			llerrs << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,(S32)mComponents) << llendl;
 		}
 	}
 	
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 90fcf6ab3f180917a57bf95950d1e70800813dc9..9d037f2565db8fba6ce2c29ed27afc7500960906 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1055,7 +1055,8 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
 		{
 			llinfos << "Calling glCopyTexSubImage2D(...)" << llendl ;
 			checkTexSize(true) ;
-			llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << llcallstacksendl ;
+			llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height <<
+				" : " << (S32)mComponents << llcallstacksendl ;
 		}
 
 		glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index f0f34ebd4fab910d3e2d23f29ac989d058dd3df8..d51276bf269f66da7d3539569dc13db709b84c03 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -1117,7 +1117,7 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
 	// Get the visibility control name for the floater
 	std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString());
 	// Set the button control value (toggle state) to the floater visibility control (Sets the value as well)
-	button->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name));
+	button->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name));
 	// Set the clicked callback to toggle the floater
 	button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname));
 }
@@ -1131,7 +1131,7 @@ void LLButton::setDockableFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
 	// Get the visibility control name for the floater
 	std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString());
 	// Set the button control value (toggle state) to the floater visibility control (Sets the value as well)
-	button->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name));
+	button->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name));
 	// Set the clicked callback to toggle the floater
 	button->setClickedCallback(boost::bind(&LLDockableFloater::toggleInstance, sdname));
 }
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index ff9080627130698105e093dd3af92fc42c3b1ba9..c0942cf3c75341552851b72e993080be56641a39 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -499,7 +499,7 @@ void LLFloater::storeRectControl()
 {
 	if( mRectControl.size() > 1 )
 	{
-		LLUI::sSettingGroups["floater"]->setRect( mRectControl, getRect() );
+		getControlGroup()->setRect( mRectControl, getRect() );
 	}
 }
 
@@ -507,7 +507,7 @@ void LLFloater::storeVisibilityControl()
 {
 	if( !sQuitting && mVisibilityControl.size() > 1 )
 	{
-		LLUI::sSettingGroups["floater"]->setBOOL( mVisibilityControl, getVisible() );
+		getControlGroup()->setBOOL( mVisibilityControl, getVisible() );
 	}
 }
 
@@ -515,7 +515,7 @@ void LLFloater::storeDockStateControl()
 {
 	if( !sQuitting && mDocStateControl.size() > 1 )
 	{
-		LLUI::sSettingGroups["floater"]->setBOOL( mDocStateControl, isDocked() );
+		getControlGroup()->setBOOL( mDocStateControl, isDocked() );
 	}
 }
 
@@ -525,7 +525,7 @@ LLRect LLFloater::getSavedRect() const
 
 	if (mRectControl.size() > 1)
 	{
-		rect = LLUI::sSettingGroups["floater"]->getRect(mRectControl);
+		rect = getControlGroup()->getRect(mRectControl);
 	}
 
 	return rect;
@@ -550,6 +550,13 @@ std::string LLFloater::getControlName(const std::string& name, const LLSD& key)
 	return ctrl_name;
 }
 
+// static
+LLControlGroup*	LLFloater::getControlGroup()
+{
+	// Floater size, position, visibility, etc are saved in per-account settings.
+	return LLUI::sSettingGroups["account"];
+}
+
 void LLFloater::setVisible( BOOL visible )
 {
 	LLPanel::setVisible(visible); // calls handleVisibilityChange()
@@ -805,7 +812,7 @@ void LLFloater::applyRectControl()
 	// override center if we have saved rect control
 	if (mRectControl.size() > 1)
 	{
-		const LLRect& rect = LLUI::sSettingGroups["floater"]->getRect(mRectControl);
+		const LLRect& rect = getControlGroup()->getRect(mRectControl);
 		if (rect.getWidth() > 0 && rect.getHeight() > 0)
 		{
 			translate( rect.mLeft - getRect().mLeft, rect.mBottom - getRect().mBottom);
@@ -821,7 +828,7 @@ void LLFloater::applyDockState()
 {
 	if (mDocStateControl.size() > 1)
 	{
-		bool dockState = LLUI::sSettingGroups["floater"]->getBOOL(mDocStateControl);
+		bool dockState = getControlGroup()->getBOOL(mDocStateControl);
 		setDocked(dockState);
 	}
 
@@ -1984,6 +1991,7 @@ LLFloaterView::LLFloaterView (const Params& p)
 :	LLUICtrl (p),
 
 	mFocusCycleMode(FALSE),
+	mMinimizePositionVOffset(0),
 	mSnapOffsetBottom(0),
 	mSnapOffsetRight(0)
 {
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index ed1f0715afbd06798583383f9b62cd7a26f69a38..5ecf515cf9268965c50349bea2c635faeee80ff2 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -206,7 +206,8 @@ public:
 	LLRect			getSavedRect() const;
 	bool			hasSavedRect() const;
 
-	static std::string	getControlName(const std::string& name, const LLSD& key);
+	static std::string		getControlName(const std::string& name, const LLSD& key);
+	static LLControlGroup*	getControlGroup();
 
 	bool			isMinimizeable() const{ return mCanMinimize; }
 	bool			isCloseable() const{ return mCanClose; }
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index ccffe98c9653c3bf3874f712b4a7ac7d3d4044e7..4720ebb82255b3411fe16229b7aecf83da4eff1b 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -284,9 +284,9 @@ void LLFloaterReg::showInitialVisibleInstances()
 	{
 		const std::string& name = iter->first;
 		std::string controlname = getVisibilityControlName(name);
-		if (LLUI::sSettingGroups["floater"]->controlExists(controlname))
+		if (LLFloater::getControlGroup()->controlExists(controlname))
 		{
-			BOOL isvis = LLUI::sSettingGroups["floater"]->getBOOL(controlname);
+			BOOL isvis = LLFloater::getControlGroup()->getBOOL(controlname);
 			if (isvis)
 			{
 				showInstance(name, LLSD()); // keyed floaters shouldn't set save_vis to true
@@ -340,7 +340,7 @@ std::string LLFloaterReg::getRectControlName(const std::string& name)
 std::string LLFloaterReg::declareRectControl(const std::string& name)
 {
 	std::string controlname = getRectControlName(name);
-	LLUI::sSettingGroups["floater"]->declareRect(controlname, LLRect(),
+	LLFloater::getControlGroup()->declareRect(controlname, LLRect(),
 												 llformat("Window Position and Size for %s", name.c_str()),
 												 TRUE);
 	return controlname;
@@ -358,7 +358,7 @@ std::string LLFloaterReg::getVisibilityControlName(const std::string& name)
 std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
 {
 	std::string controlname = getVisibilityControlName(name);
-	LLUI::sSettingGroups["floater"]->declareBOOL(controlname, FALSE,
+	LLFloater::getControlGroup()->declareBOOL(controlname, FALSE,
 												 llformat("Window Visibility for %s", name.c_str()),
 												 TRUE);
 	return controlname;
@@ -368,7 +368,7 @@ std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
 std::string LLFloaterReg::declareDockStateControl(const std::string& name)
 {
 	std::string controlname = getDockStateControlName(name);
-	LLUI::sSettingGroups["floater"]->declareBOOL(controlname, TRUE,
+	LLFloater::getControlGroup()->declareBOOL(controlname, TRUE,
 												 llformat("Window Docking state for %s", name.c_str()),
 												 TRUE);
 	return controlname;
@@ -391,11 +391,11 @@ void LLFloaterReg::registerControlVariables()
 	for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter)
 	{
 		const std::string& name = iter->first;
-		if (LLUI::sSettingGroups["floater"]->controlExists(getRectControlName(name)))
+		if (LLFloater::getControlGroup()->controlExists(getRectControlName(name)))
 		{
 			declareRectControl(name);
 		}
-		if (LLUI::sSettingGroups["floater"]->controlExists(getVisibilityControlName(name)))
+		if (LLFloater::getControlGroup()->controlExists(getVisibilityControlName(name)))
 		{
 			declareVisibilityControl(name);
 		}
@@ -419,7 +419,7 @@ void LLFloaterReg::initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LL
 	// Get the visibility control name for the floater
 	std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString());
 	// Set the control value to the floater visibility control (Sets the value as well)
-	ctrl->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name));
+	ctrl->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name));
 }
 
 // callback args may use "floatername.key" format
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 5cc9add1e2a0bf948d844e13e68037b28a09f629..0ff7557ead620c4cf002eeeace15ff68d02a5f23 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -368,6 +368,22 @@ S32 LLLayoutStack::getDefaultWidth(S32 cur_width)
 	return cur_width;
 }
 
+void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front)
+{
+	LayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move);
+	LayoutPanel* embedded_target_panel = move_to_front ? *mPanels.begin() : findEmbeddedPanel(target_panel);
+
+	if (!embedded_panel_to_move || !embedded_target_panel || embedded_panel_to_move == embedded_target_panel)
+	{
+		llwarns << "One of the panels was not found in stack or NULL was passed instead of valid panel" << llendl;
+		return;
+	}
+	e_panel_list_t::iterator it = std::find(mPanels.begin(), mPanels.end(), embedded_panel_to_move);
+	mPanels.erase(it);
+	it = move_to_front ? mPanels.begin() : std::find(mPanels.begin(), mPanels.end(), embedded_target_panel);
+	mPanels.insert(it, embedded_panel_to_move);
+}
+
 void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, S32 max_width, S32 max_height, BOOL auto_resize, BOOL user_resize, EAnimate animate, S32 index)
 {
 	// panel starts off invisible (collapsed)
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index cd59ee3966f58ad32863cc5deea02169af81d4d9..6fcc8e2ac34a6c092b6155f3ed47fc41f447f44a 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -72,6 +72,11 @@ public:
 	void removePanel(LLPanel* panel);
 	void collapsePanel(LLPanel* panel, BOOL collapsed = TRUE);
 	S32 getNumPanels() { return mPanels.size(); }
+	/**
+	 * Moves panel_to_move before target_panel inside layout stack (both panels should already be there).
+	 * If move_to_front is true target_panel is ignored and panel_to_move is moved to the beginning of mPanels
+	 */
+	void movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front = false);
 
 	void updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize);
 	void setPanelUserResize(const std::string& panel_name, BOOL user_resize);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ac710dea48c36e80accaaa18ccf8785f198b1930..1aadab5d05fcee4234c324e474766f425efa601f 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -13,6 +13,7 @@ include(ELFIO)
 include(FMOD)
 include(OPENAL)
 include(FindOpenGL)
+include(JsonCpp)
 include(LLAudio)
 include(LLCharacter)
 include(LLCommon)
@@ -44,6 +45,7 @@ include(CMakeCopyIfDifferent)
 include_directories(
     ${DBUSGLIB_INCLUDE_DIRS}
     ${ELFIO_INCLUDE_DIR}
+    ${JSONCPP_INCLUDE_DIRS}
     ${LLAUDIO_INCLUDE_DIRS}
     ${LLCHARACTER_INCLUDE_DIRS}
     ${LLCOMMON_INCLUDE_DIRS}
@@ -82,6 +84,7 @@ set(viewer_SOURCE_FILES
     llappviewerlistener.cpp
     llassetuploadqueue.cpp
     llassetuploadresponders.cpp
+    llattachmentsmgr.cpp
     llaudiosourcevo.cpp
     llavataractions.cpp
     llavatariconctrl.cpp
@@ -203,6 +206,7 @@ set(viewer_SOURCE_FILES
     llfloatersearch.cpp
     llfloatersellland.cpp
     llfloatersettingsdebug.cpp
+    llfloatersidetraytab.cpp
     llfloatersnapshot.cpp
     llfloatertelehub.cpp
     llfloatertestinspectors.cpp
@@ -308,6 +312,7 @@ set(viewer_SOURCE_FILES
     lloutfitslist.cpp
     lloutfitobserver.cpp
     lloutputmonitorctrl.cpp
+    llpanelappearancetab.cpp
     llpanelavatar.cpp
     llpanelavatartag.cpp
     llpanelblockedlist.cpp
@@ -456,6 +461,7 @@ set(viewer_SOURCE_FILES
     lltracker.cpp
     lltransientdockablefloater.cpp
     lltransientfloatermgr.cpp
+    lltranslate.cpp
     lluilistener.cpp
     lluploaddialog.cpp
     llurl.cpp
@@ -604,6 +610,7 @@ set(viewer_HEADER_FILES
     llappviewerlistener.h
     llassetuploadqueue.h
     llassetuploadresponders.h
+    llattachmentsmgr.h
     llaudiosourcevo.h
     llavataractions.h
     llavatariconctrl.h
@@ -727,6 +734,7 @@ set(viewer_HEADER_FILES
     llfloatersearch.h
     llfloatersellland.h
     llfloatersettingsdebug.h
+    llfloatersidetraytab.h
     llfloatersnapshot.h
     llfloatertelehub.h
     llfloatertestinspectors.h
@@ -979,6 +987,7 @@ set(viewer_HEADER_FILES
     lltracker.h
     lltransientdockablefloater.h
     lltransientfloatermgr.h
+    lltranslate.h
     lluiconstants.h
     lluilistener.h
     lluploaddialog.h
@@ -1648,6 +1657,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${OPENGL_LIBRARIES}
     ${FMODWRAPPER_LIBRARY} # must come after LLAudio
     ${OPENGL_LIBRARIES}
+    ${JSONCPP_LIBRARIES}
     ${SDL_LIBRARY}
     ${SMARTHEAP_LIBRARY}
     ${UI_LIBRARIES}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index c3f52768a5f83895d46b8957469bd2d86dcc93bd..ec8647f050c2adf17037f4ba441ad78081702111 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1147,6 +1147,17 @@
       <key>Value</key>
       <string />
     </map>	
+    <key>CacheNumberOfRegionsForObjects</key>
+    <map>
+      <key>Comment</key>
+      <string>Controls number of regions to be cached for objects, ranges from 16 to 128.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>128</integer>
+    </map>
     <key>CacheSize</key>
     <map>
       <key>Comment</key>
@@ -2677,6 +2688,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>DoubleClickTeleport</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable double-click to teleport where allowed</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>DragAndDropToolTipDelay</key>
     <map>
       <key>Comment</key>
@@ -8901,6 +8923,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>FriendsListShowPermissions</key>
+    <map>
+      <key>Comment</key>
+      <string>Show/hide permission icons in the friend list</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>NearbyListShowIcons</key>
     <map>
       <key>Comment</key>
@@ -9858,6 +9891,28 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>TranslateLanguage</key>
+    <map>
+      <key>Comment</key>
+      <string>Translate Language specifier</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>default</string>
+    </map>
+    <key>TranslateChat</key>
+    <map>
+      <key>Comment</key>
+      <string>Translate incoming chat messages</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>TutorialURL</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 9440e877dfac4435dcac52e6c2c12cb40a5fd9e2..e3fc9d4949a536c3016db05c3269fc4f8d708224 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 22
+version 23
 
 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences
 // Should be combined into one table
@@ -81,7 +81,7 @@ RenderTerrainDetail			1	0
 RenderTerrainLODFactor		1	1
 RenderTreeLODFactor			1	0
 RenderUseImpostors			1	1
-RenderVolumeLODFactor		1	0
+RenderVolumeLODFactor		1	0.5
 VertexShaderEnable			1	0
 WindLightUseAtmosShaders	1	0
 WLSkyDetail					1	48
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 85b8564138f58f3ccfc3f2afd3b0c1d1d74b27a9..1bad7e5260ba4f486f5038c891577de75515aa4a 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -1,4 +1,4 @@
-version 21
+version 22
 
 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences
 // Should be combined into one table
@@ -80,7 +80,7 @@ RenderTerrainDetail			1	0
 RenderTerrainLODFactor		1	1
 RenderTreeLODFactor			1	0
 RenderUseImpostors			1	1
-RenderVolumeLODFactor		1	0
+RenderVolumeLODFactor		1	0.5
 VertexShaderEnable			1	0
 WindLightUseAtmosShaders	1	0
 WLSkyDetail					1	48
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 2095f3a81d83739c6fd7499424a144ec20ad64e8..4fba47e3df7e527a494f110705048c067938d24a 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 21
+version 22
 
 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences
 // Should be combined into one table
@@ -81,7 +81,7 @@ RenderTerrainDetail			1	0
 RenderTerrainLODFactor		1	1
 RenderTreeLODFactor			1	0
 RenderUseImpostors			1	1
-RenderVolumeLODFactor		1	0
+RenderVolumeLODFactor		1	0.5
 RenderWaterReflections		1	0
 VertexShaderEnable			1	0
 WindLightUseAtmosShaders	1	0
diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9b901022c412142d744d461930fe54dc537977cb
--- /dev/null
+++ b/indra/newview/featuretable_xp.txt
@@ -0,0 +1,554 @@
+version 23
+
+// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
+// Should be combined into one table
+
+//
+// Generates lists of feature mask that can be applied on top of each other.
+//
+//		//		Begin comments
+//		list <name>
+//		Starts a feature list named <name>
+//		<name> <available> <recommended>
+//		<name> is the name of a feature
+//		<available> is 0 or 1, whether the feature is available
+//		<recommended> is an F32 which is the recommended value
+//
+// For now, the first list read sets up all of the default values
+//
+
+
+//
+// All contains everything at their default settings for high end machines
+// NOTE: All settings are set to the MIN of applied values, including 'all'!
+//
+list all
+RenderAnisotropic			1	1
+RenderAvatarCloth			1	1
+RenderAvatarLODFactor		1	1.0
+RenderAvatarMaxVisible      1   12
+RenderAvatarVP				1	1
+RenderCubeMap				1	1
+RenderDelayVBUpdate			1	0
+RenderFarClip				1	256
+RenderFlexTimeFactor		1	1.0
+RenderFogRatio				1	4.0
+RenderGamma					1	0
+RenderGlowResolutionPow		1	9
+RenderGround				1	1
+RenderMaxPartCount			1	8192
+RenderNightBrightness		1	1.0
+RenderObjectBump			1	1
+RenderReflectionDetail		1	4
+RenderTerrainDetail			1	1
+RenderTerrainLODFactor		1	2.0
+RenderTreeLODFactor			1	1.0
+RenderUseImpostors			1	1
+RenderVBOEnable				1	1
+RenderVolumeLODFactor		1	2.0
+UseStartScreen				1	1
+UseOcclusion				1	1
+VertexShaderEnable			1	1
+WindLightUseAtmosShaders	1	1
+WLSkyDetail					1	128
+Disregard128DefaultDrawDistance	1	1
+Disregard96DefaultDrawDistance	1	1
+RenderTextureMemoryMultiple		1	1.0
+RenderShaderLightingMaxLevel	1	3
+SkyUseClassicClouds			1	1
+RenderDeferred				1	0
+RenderDeferredSSAO			1	0
+RenderShadowDetail			1	0
+WatchdogDisabled				1	1
+RenderUseStreamVBO			1	1
+
+//
+// Low Graphics Settings
+//
+list Low
+RenderAnisotropic			1	0
+RenderAvatarCloth			1	0
+RenderAvatarLODFactor		1	0
+RenderAvatarMaxVisible      1   3
+RenderAvatarVP				1	0
+RenderFarClip				1	64
+RenderFlexTimeFactor		1	0
+RenderGlowResolutionPow		1	8
+RenderMaxPartCount			1	0
+RenderObjectBump			1	0
+RenderReflectionDetail		1	0
+RenderTerrainDetail			1	0
+RenderTerrainLODFactor		1	1
+RenderTreeLODFactor			1	0
+RenderUseImpostors			1	1
+RenderVolumeLODFactor		1	0.5
+VertexShaderEnable			1	0
+WindLightUseAtmosShaders	1	0
+WLSkyDetail					1	48
+SkyUseClassicClouds			1	0
+RenderDeferred				1	0
+RenderDeferredSSAO			1	0
+RenderShadowDetail			1	0
+
+
+//
+// Mid Graphics Settings
+//
+list Mid
+RenderAnisotropic			1	0
+RenderAvatarCloth			1	0
+RenderAvatarLODFactor		1	0.5
+RenderAvatarVP				1	1
+RenderFarClip				1	96
+RenderFlexTimeFactor		1	1.0
+RenderGlowResolutionPow		1	8
+RenderMaxPartCount			1	2048
+RenderObjectBump			1	1
+RenderReflectionDetail		1	0
+RenderTerrainDetail			1	1
+RenderTerrainLODFactor		1	1.0
+RenderTreeLODFactor			1	0.5
+RenderUseImpostors			1	1
+RenderVolumeLODFactor		1	1.125
+VertexShaderEnable			1	1
+WindLightUseAtmosShaders	1	0
+WLSkyDetail					1	48
+RenderDeferred				1	0
+RenderDeferredSSAO			1	0
+RenderShadowDetail			1	0
+
+
+//
+// High Graphics Settings (purty)
+//
+list High
+RenderAnisotropic			1	1
+RenderAvatarCloth			1	0
+RenderAvatarLODFactor		1	1.0
+RenderAvatarVP				1	1
+RenderFarClip				1	128
+RenderFlexTimeFactor		1	1.0
+RenderGlowResolutionPow		1	9
+RenderMaxPartCount			1	4096
+RenderObjectBump			1	1
+RenderReflectionDetail		1	2
+RenderTerrainDetail			1	1
+RenderTerrainLODFactor		1	2.0
+RenderTreeLODFactor			1	0.5
+RenderUseImpostors			1	1
+RenderVolumeLODFactor		1	1.125
+VertexShaderEnable			1	1
+WindLightUseAtmosShaders	1	1
+WLSkyDetail					1	48
+RenderDeferred				1	0
+RenderDeferredSSAO			1	0
+RenderShadowDetail			1	0
+
+
+//
+// Ultra graphics (REALLY PURTY!)
+//
+list Ultra
+RenderAnisotropic			1	1
+RenderAvatarCloth			1	1
+RenderAvatarLODFactor		1	1.0
+RenderAvatarVP				1	1
+RenderFarClip				1	256
+RenderFlexTimeFactor		1	1.0
+RenderGlowResolutionPow		1	9
+RenderMaxPartCount			1	8192
+RenderObjectBump			1	1
+RenderReflectionDetail		1	4
+RenderTerrainDetail			1	1
+RenderTerrainLODFactor		1	2.0
+RenderTreeLODFactor			1	1.0
+RenderUseImpostors			1	1
+RenderVolumeLODFactor		1	2.0
+VertexShaderEnable			1	1
+WindLightUseAtmosShaders	1	1
+WLSkyDetail					1	128
+RenderDeferred				1	0
+RenderDeferredSSAO			1	0
+RenderShadowDetail			1	0
+
+//
+// Class Unknown Hardware (unknown)
+//
+list Unknown
+RenderVBOEnable				1	0
+
+//
+// Class 0 Hardware (just old)
+//
+list Class0
+RenderVBOEnable				1	1
+
+//
+// Class 1 Hardware
+//
+list Class1
+RenderVBOEnable				1	1
+
+//
+// Class 2 Hardware (make it purty)
+//
+list Class2
+RenderVBOEnable				1	1
+
+//
+// Class 3 Hardware (make it purty)
+//
+list Class3
+RenderVBOEnable				1	1
+
+//
+// No Pixel Shaders available
+//
+list NoPixelShaders
+RenderAvatarVP				0	0
+RenderAvatarCloth			0	0
+RenderReflectionDetail		0	0
+VertexShaderEnable			0	0
+WindLightUseAtmosShaders	0	0
+RenderDeferred				0	0
+RenderDeferredSSAO			0	0
+RenderShadowDetail			0	0
+
+//
+// No Vertex Shaders available
+//
+list NoVertexShaders
+RenderAvatarVP				0	0
+RenderAvatarCloth			0	0
+RenderReflectionDetail		0	0
+VertexShaderEnable			0	0
+WindLightUseAtmosShaders	0	0
+RenderDeferred				0	0
+RenderDeferredSSAO			0	0
+RenderShadowDetail			0	0
+
+//
+// "Default" setups for safe, low, medium, high
+//
+list safe
+RenderAnisotropic			1	0
+RenderAvatarCloth			0	0
+RenderAvatarVP				0	0
+RenderObjectBump			0	0
+RenderMaxPartCount			1	1024
+RenderTerrainDetail 		1	0
+RenderUseImpostors			0	0
+RenderVBOEnable				1	0
+RenderReflectionDetail		0	0
+WindLightUseAtmosShaders	0	0
+RenderDeferred				0	0
+RenderDeferredSSAO			0	0
+RenderShadowDetail			0	0
+
+//
+// CPU based feature masks
+//
+
+// 1Ghz or less (equiv)
+list CPUSlow
+RenderMaxPartCount			1	1024
+
+//
+// RAM based feature masks
+//
+list RAM256MB
+RenderObjectBump			0	0
+
+//
+// Graphics card based feature masks
+//
+list OpenGLPre15
+RenderVBOEnable				1	0
+
+list Intel
+RenderAnisotropic			1	0
+
+list GeForce2
+RenderAnisotropic			1	0
+RenderMaxPartCount			1	2048
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	1
+
+list SiS
+UseOcclusion				0	0
+
+
+list Intel_830M
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+RenderUseImpostors			0	0
+
+list Intel_845G					
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+RenderUseImpostors			0	0
+
+list Intel_855GM				
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+RenderUseImpostors			0	0
+
+list Intel_865G			
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+RenderUseImpostors			0	0
+
+list Intel_900		
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+RenderUseImpostors			0	0
+
+list Intel_915GM	
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+RenderUseImpostors			0	0
+
+list Intel_915G					
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+RenderUseImpostors			0	0
+
+list Intel_945GM			
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_945G
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_950
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_965
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+RenderUseImpostors			1	0
+UseOcclusion				0	0
+
+list Intel_G33
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_G45
+WindLightUseAtmosShaders		0	0
+
+list Intel_Bear_Lake	
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_Broadwater 
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_Brookdale	
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_Eaglelake
+WindLightUseAtmosShaders	0	0
+
+list Intel_Montara
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_Springdale
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+
+list ATI_FireGL_5200
+RenderVBOEnable				1	0
+WindLightUseAtmosShaders	0	0
+
+
+list ATI_Mobility_Radeon_7xxx
+RenderVBOEnable				0	0
+
+list ATI_Radeon_7xxx
+RenderVBOEnable				0	0
+
+list ATI_All-in-Wonder_Radeon
+RenderVBOEnable				0	0
+
+list ATI_All-in-Wonder_7500
+RenderVBOEnable				0	0
+
+list ATI_Mobility_Radeon_9600
+Disregard96DefaultDrawDistance	1	0
+
+
+/// tweaked ATI to 96 Draw distance
+
+list ATI_Radeon_9000
+Disregard96DefaultDrawDistance	1	0
+list ATI_Radeon_9200
+Disregard96DefaultDrawDistance	1	0
+list ATI_Radeon_9500
+Disregard96DefaultDrawDistance	1	0
+list ATI_Radeon_9600
+Disregard96DefaultDrawDistance	1	0
+
+/// tweaked ATI to 128 draw distance
+
+list ATI_Radeon_X300 
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+list ATI_Radeon_X400 
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+list ATI_Radeon_X500 
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+list ATI_Radeon_X600 
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+list ATI_Radeon_X700 
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+list ATI_Radeon_X1300 
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+UseStartScreen					0	0
+list ATI_Radeon_X1400 
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+list ATI_Radeon_X1500 
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+UseStartScreen					0	0
+list ATI_Radeon_X1600 
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+list ATI_Radeon_X1700 
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+list ATI_Mobility_Radeon_X1xxx
+Disregard128DefaultDrawDistance	1	0
+RenderVBOEnable				1	0
+
+list ATI_Radeon_HD_2300
+Disregard128DefaultDrawDistance	1	0
+list ATI_Radeon_HD_2400
+Disregard128DefaultDrawDistance	1	0
+list ATI_ASUS_AH24xx
+Disregard128DefaultDrawDistance	1	0
+
+
+// Avatar hardware skinning causes invisible avatars
+// on various ATI chipsets on drivers before 8.2
+
+list ATIOldDriver
+RenderAvatarVP				0	0
+RenderAvatarCloth			0	0
+
+// ATI cards generally perform better when not using VBOs for streaming data
+
+list ATI
+RenderUseStreamVBO			1	0
+
+/// Tweaked NVIDIA
+
+list NVIDIA_GeForce_FX_5100
+Disregard96DefaultDrawDistance	1	0
+list NVIDIA_GeForce_FX_5200
+Disregard96DefaultDrawDistance	1	0
+list NVIDIA_GeForce_FX_5500
+Disregard96DefaultDrawDistance	1	0
+list NVIDIA_GeForce_FX_5600
+Disregard96DefaultDrawDistance	1	0
+
+list NVIDIA_GeForce_FX_Go5100
+Disregard96DefaultDrawDistance	1	0
+list NVIDIA_GeForce_FX_Go5200
+Disregard96DefaultDrawDistance	1	0
+list NVIDIA_GeForce_FX_Go5300
+Disregard96DefaultDrawDistance	1	0
+list NVIDIA_GeForce_FX_Go5500
+Disregard96DefaultDrawDistance	1	0
+list NVIDIA_GeForce_FX_Go5600
+Disregard96DefaultDrawDistance	1	0
+
+list NVIDIA_GeForce_6100
+Disregard128DefaultDrawDistance	1	0
+list NVIDIA_GeForce_6200
+Disregard128DefaultDrawDistance	1	0
+list NVIDIA_GeForce_6500
+Disregard128DefaultDrawDistance	1	0
+list NVIDIA_GeForce_6600
+Disregard128DefaultDrawDistance	1	0
+
+list NVIDIA_G73
+Disregard128DefaultDrawDistance	1	0
+
+list NVIDIA_GeForce_Go_6100
+RenderVBOEnable				1	0
+Disregard128DefaultDrawDistance	1	0
+list NVIDIA_GeForce_Go_6200
+RenderVBOEnable				1	0
+Disregard128DefaultDrawDistance	1	0
+list NVIDIA_GeForce_Go_6500
+RenderVBOEnable				1	0
+Disregard128DefaultDrawDistance	1	0
+list NVIDIA_GeForce_Go_6600
+RenderVBOEnable				1	0
+Disregard128DefaultDrawDistance	1	0
+list NVIDIA_GeForce_Go_6700
+RenderVBOEnable				1	0
+Disregard128DefaultDrawDistance	1	0
+list NVIDIA_GeForce_Go_6800
+RenderVBOEnable				1	0
+Disregard128DefaultDrawDistance	1	0
+list NVIDIA_GeForce_Go_6
+RenderVBOEnable				1	0
+Disregard128DefaultDrawDistance	1	0
+
+list NVIDIA_GeForce_7000
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_7100
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_7200
+Disregard128DefaultDrawDistance	1	0
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_7300
+Disregard128DefaultDrawDistance	1	0
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_7400
+Disregard128DefaultDrawDistance	1	0
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_7500
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_7600
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_7700
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_7800
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_7900
+RenderShaderLightingMaxLevel	1	2
+
+list NVIDIA_GeForce_Go_7200
+Disregard128DefaultDrawDistance	1	0
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_Go_7300
+Disregard128DefaultDrawDistance	1	0
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_Go_7300_LE
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_Go_7400
+Disregard128DefaultDrawDistance	1	0
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_Go_7600
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_Go_7700
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_Go_7800
+RenderShaderLightingMaxLevel	1	2
+list NVIDIA_GeForce_Go_7900
+RenderShaderLightingMaxLevel	1	2
+
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index fe7e883d8382a8e525e6ac31fd7bab9f6bcc41f6..b202cb5098829d3c77fcb4d701f21fbcdff94a69 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -167,6 +167,7 @@ LLAgent::LLAgent() :
 
 	mbAlwaysRun(false),
 	mbRunning(false),
+	mbTeleportKeepsLookAt(false),
 
 	mAgentAccess(gSavedSettings),
 	mTeleportState( TELEPORT_NONE ),
@@ -3249,7 +3250,11 @@ bool LLAgent::teleportCore(bool is_local)
 
 	// local logic
 	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT);
-	if (!is_local)
+	if (is_local)
+	{
+		gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL );
+	}
+	else
 	{
 		gTeleportDisplay = TRUE;
 		gAgent.setTeleportState( LLAgent::TELEPORT_START );
@@ -3268,13 +3273,15 @@ bool LLAgent::teleportCore(bool is_local)
 
 void LLAgent::teleportRequest(
 	const U64& region_handle,
-	const LLVector3& pos_local)
+	const LLVector3& pos_local,
+	bool look_at_from_camera)
 {
 	LLViewerRegion* regionp = getRegion();
-	if(regionp && teleportCore())
+	bool is_local = (region_handle == to_region_handle(getPositionGlobal()));
+	if(regionp && teleportCore(is_local))
 	{
-		llinfos << "TeleportRequest: '" << region_handle << "':" << pos_local
-				<< llendl;
+		LL_INFOS("") << "TeleportLocationRequest: '" << region_handle << "':"
+					 << pos_local << LL_ENDL;
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessage("TeleportLocationRequest");
 		msg->nextBlockFast(_PREHASH_AgentData);
@@ -3284,6 +3291,10 @@ void LLAgent::teleportRequest(
 		msg->addU64("RegionHandle", region_handle);
 		msg->addVector3("Position", pos_local);
 		LLVector3 look_at(0,1,0);
+		if (look_at_from_camera)
+		{
+			look_at = LLViewerCamera::getInstance()->getAtAxis();
+		}
 		msg->addVector3("LookAt", look_at);
 		sendReliableMessage();
 	}
@@ -3395,6 +3406,16 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
 	}
 }
 
+// Teleport to global position, but keep facing in the same direction 
+void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global)
+{
+	mbTeleportKeepsLookAt = true;
+	gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);	// detach camera form avatar, so it keeps direction
+	U64 region_handle = to_region_handle(pos_global);
+	LLVector3 pos_local = (LLVector3)(pos_global - from_region_handle(region_handle));
+	teleportRequest(region_handle, pos_local, getTeleportKeepsLookAt());
+}
+
 void LLAgent::setTeleportState(ETeleportState state)
 {
 	mTeleportState = state;
@@ -3402,18 +3423,28 @@ void LLAgent::setTeleportState(ETeleportState state)
 	{
 		LLFloaterReg::hideInstance("snapshot");
 	}
-	if (mTeleportState == TELEPORT_MOVING)
-	{
-		// We're outa here. Save "back" slurl.
-		LLAgentUI::buildSLURL(mTeleportSourceSLURL);
-	}
-	else if(mTeleportState == TELEPORT_ARRIVING)
+
+	switch (mTeleportState)
 	{
-		// First two position updates after a teleport tend to be weird
-		LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2;
+		case TELEPORT_NONE:
+			mbTeleportKeepsLookAt = false;
+			break;
+
+		case TELEPORT_MOVING:
+			// We're outa here. Save "back" slurl.
+			LLAgentUI::buildSLURL(mTeleportSourceSLURL);
+			break;
 
-		// Let the interested parties know we've teleported.
-		LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal());
+		case TELEPORT_ARRIVING:
+			// First two position updates after a teleport tend to be weird
+			LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2;
+			
+			// Let the interested parties know we've teleported.
+			LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal());
+			break;
+
+		default:
+			break;
 	}
 }
 
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index c643cef78fffcae33a5027bc09745986037b12b8..30685461b9f6b07df851fda6168a59c2417b6a54 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -339,6 +339,7 @@ public:
 private:
 	bool 			mbAlwaysRun; 			// Should the avatar run by default rather than walk?
 	bool 			mbRunning;				// Is the avatar trying to run right now?
+	bool			mbTeleportKeepsLookAt;	// Try to keep look-at after teleport is complete
 
 	//--------------------------------------------------------------------
 	// Sit and stand
@@ -506,7 +507,8 @@ public:
 		TELEPORT_REQUESTED = 2,		// Waiting for source simulator to respond
 		TELEPORT_MOVING = 3,		// Viewer has received destination location from source simulator
 		TELEPORT_START_ARRIVAL = 4,	// Transition to ARRIVING.  Viewer has received avatar update, etc., from destination simulator
-		TELEPORT_ARRIVING = 5		// Make the user wait while content "pre-caches"
+		TELEPORT_ARRIVING = 5,		// Make the user wait while content "pre-caches"
+		TELEPORT_LOCAL = 6			// Teleporting in-sim without showing the progress screen
 	};
 
 public:
@@ -524,12 +526,15 @@ private:
 	//--------------------------------------------------------------------
 public:
 	void 			teleportRequest(const U64& region_handle,
-									const LLVector3& pos_local);			// Go to a named location home
+									const LLVector3& pos_local,				// Go to a named location home
+									bool look_at_from_camera = false);
 	void 			teleportViaLandmark(const LLUUID& landmark_id);			// Teleport to a landmark
 	void 			teleportHome()	{ teleportViaLandmark(LLUUID::null); }	// Go home
 	void 			teleportViaLure(const LLUUID& lure_id, BOOL godlike);	// To an invited location
 	void 			teleportViaLocation(const LLVector3d& pos_global);		// To a global location - this will probably need to be deprecated
+	void			teleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation
 	void 			teleportCancel();										// May or may not be allowed by server
+	bool			getTeleportKeepsLookAt() { return mbTeleportKeepsLookAt; } // Whether look-at reset after teleport
 protected:
 	bool 			teleportCore(bool is_local = false); 					// Stuff for all teleports; returns true if the teleport can proceed
 
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index d5a27b7cb3f1c3a31bca6eba16e38318d622954d..7a7ec5dcc48ad6d68cbee27ea32d2c55814946df 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1885,7 +1885,7 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra
 		msg->nextBlockFast(_PREHASH_ObjectData );
 		msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
 		msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
-		msg->addU8Fast(_PREHASH_AttachmentPt, 0 );	// Wear at the previous or default attachment point
+		msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD);	// Wear at the previous or default attachment point
 		pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
 		msg->addStringFast(_PREHASH_Name, item->getName());
 		msg->addStringFast(_PREHASH_Description, item->getDescription());
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index e9e5563e34f171053f024b637046b9ba6fdba8d3..ad4eed1d670fb3d4ea462d01e80931703ea7e67a 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -31,6 +31,7 @@
 #include "llagentcamera.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
+#include "llattachmentsmgr.h"
 #include "llcommandhandler.h"
 #include "lleventtimer.h"
 #include "llgesturemgr.h"
@@ -2764,6 +2765,8 @@ LLAppearanceMgr::LLAppearanceMgr():
 
 	mUnlockOutfitTimer.reset(new LLOutfitUnLockTimer(gSavedSettings.getS32(
 			"OutfitOperationsTimeout")));
+
+	gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle,NULL);
 }
 
 LLAppearanceMgr::~LLAppearanceMgr()
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index bfe3e52657019fbb34f4f832005bf51a5706d821..fd6b8b739dc669c94af2ae70e18f1f6e7d5eaf5d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3025,14 +3025,6 @@ void LLAppViewer::migrateCacheDirectory()
 #endif // LL_WINDOWS || LL_DARWIN
 }
 
-//static
-S32 LLAppViewer::getCacheVersion() 
-{
-	static const S32 cache_version = 7;
-
-	return cache_version ;
-}
-
 void dumpVFSCaches()
 {
 	llinfos << "======= Static VFS ========" << llendl;
@@ -3071,23 +3063,40 @@ void dumpVFSCaches()
 	SetCurrentDirectory(w_str);
 #endif
 }
+
+//static
+U32 LLAppViewer::getTextureCacheVersion() 
+{
+	//viewer texture cache version, change if the texture cache format changes.
+	const U32 TEXTURE_CACHE_VERSION = 7;
+
+	return TEXTURE_CACHE_VERSION ;
+}
+
+//static
+U32 LLAppViewer::getObjectCacheVersion() 
+{
+	// Viewer object cache version, change if object update
+	// format changes. JC
+	const U32 INDRA_OBJECT_CACHE_VERSION = 14;
+
+	return INDRA_OBJECT_CACHE_VERSION;
+}
+
 bool LLAppViewer::initCache()
 {
 	mPurgeCache = false;
-	BOOL disable_texture_cache = FALSE ;
 	BOOL read_only = mSecondInstance ? TRUE : FALSE;
 	LLAppViewer::getTextureCache()->setReadOnly(read_only) ;
+	LLVOCache::getInstance()->setReadOnly(read_only);
 
-	if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getCacheVersion()) 
+	BOOL texture_cache_mismatch = FALSE ;
+	if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion()) 
 	{
-		if(read_only) 
+		texture_cache_mismatch = TRUE ;
+		if(!read_only) 
 		{
-			disable_texture_cache = TRUE ; //if the cache version of this viewer is different from the running one, this viewer can not use the texture cache.
-		}
-		else
-		{
-			mPurgeCache = true; // Purge cache if the version number is different.
-			gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getCacheVersion());
+			gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
 		}
 	}
 
@@ -3138,9 +3147,11 @@ bool LLAppViewer::initCache()
 	const S64 MAX_CACHE_SIZE = 1024*MB;
 	cache_size = llmin(cache_size, MAX_CACHE_SIZE);
 	S64 texture_cache_size = ((cache_size * 8)/10);
-	S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, disable_texture_cache);
+	S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
 	texture_cache_size -= extra;
 
+	LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()) ;
+
 	LLSplashScreen::update(LLTrans::getString("StartupInitializingVFS"));
 	
 	// Init the VFS
@@ -3303,6 +3314,7 @@ void LLAppViewer::purgeCache()
 {
 	LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << llendl;
 	LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
+	LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
 	std::string mask = gDirUtilp->getDirDelimiter() + "*.*";
 	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
 }
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 1fcf38d18ad8ffd41a43a4e378ff113ffc73acaf..c5cac6827c8a1f1a6d6400f615446bc8fb1463c9 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -94,7 +94,8 @@ public:
 	static LLImageDecodeThread* getImageDecodeThread() { return sImageDecodeThread; }
 	static LLTextureFetch* getTextureFetch() { return sTextureFetch; }
 
-	static S32 getCacheVersion() ;
+	static U32 getTextureCacheVersion() ;
+	static U32 getObjectCacheVersion() ;
 
 	const std::string& getSerialNumber() { return mSerialNumber; }
 	
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c9543988a68b212751730df554946ac92bf3074b
--- /dev/null
+++ b/indra/newview/llattachmentsmgr.cpp
@@ -0,0 +1,131 @@
+/** 
+ * @file llattachmentsmgr.cpp
+ * @brief Manager for initiating attachments changes on the viewer
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llattachmentsmgr.h"
+
+#include "llagent.h"
+#include "llinventorymodel.h"
+#include "lltooldraganddrop.h" // pack_permissions_slam
+#include "llviewerinventory.h"
+#include "llviewerregion.h"
+#include "message.h"
+
+
+LLAttachmentsMgr::LLAttachmentsMgr()
+{
+}
+
+LLAttachmentsMgr::~LLAttachmentsMgr()
+{
+}
+
+void LLAttachmentsMgr::addAttachment(const LLUUID& item_id,
+									 const U8 attachment_pt,
+									 const BOOL add)
+{
+	AttachmentsInfo attachment;
+	attachment.mItemID = item_id;
+	attachment.mAttachmentPt = attachment_pt;
+	attachment.mAdd = add;
+	mPendingAttachments.push_back(attachment);
+}
+
+// static
+void LLAttachmentsMgr::onIdle(void *)
+{
+	LLAttachmentsMgr::instance().onIdle();
+}
+
+void LLAttachmentsMgr::onIdle()
+{
+	S32 obj_count = mPendingAttachments.size();
+	if (obj_count == 0)
+	{
+		return;
+	}
+	
+	// Limit number of packets to send
+	const S32 MAX_PACKETS_TO_SEND = 10;
+	const S32 OBJECTS_PER_PACKET = 4;
+	const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET;
+	if( obj_count > MAX_OBJECTS_TO_SEND )
+	{
+		obj_count = MAX_OBJECTS_TO_SEND;
+	}
+
+	LLUUID compound_msg_id;
+	compound_msg_id.generate();
+	LLMessageSystem* msg = gMessageSystem;
+
+	
+	S32 i = 0;
+	for (attachments_vec_t::const_iterator iter = mPendingAttachments.begin();
+		 iter != mPendingAttachments.end();
+		 ++iter)
+	{
+		if( 0 == (i % OBJECTS_PER_PACKET) )
+		{
+			// Start a new message chunk
+			msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv);
+			msg->nextBlockFast(_PREHASH_AgentData);
+			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			msg->nextBlockFast(_PREHASH_HeaderData);
+			msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id );
+			msg->addU8Fast(_PREHASH_TotalObjects, obj_count );
+			msg->addBOOLFast(_PREHASH_FirstDetachAll, false );
+		}
+
+		const AttachmentsInfo &attachment = (*iter);
+		LLViewerInventoryItem* item = gInventory.getItem(attachment.mItemID);
+		if (!item)
+		{
+			llinfos << "Attempted to add non-existant item ID:" << attachment.mItemID << llendl;
+			continue;
+		}
+		S32 attachment_pt = attachment.mAttachmentPt;
+		if (attachment.mAdd) 
+			attachment_pt |= ATTACHMENT_ADD;
+
+		msg->nextBlockFast(_PREHASH_ObjectData );
+		msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
+		msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
+		msg->addU8Fast(_PREHASH_AttachmentPt, attachment_pt);
+		pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
+		msg->addStringFast(_PREHASH_Name, item->getName());
+		msg->addStringFast(_PREHASH_Description, item->getDescription());
+
+		if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) )
+		{
+			// End of message chunk
+			msg->sendReliable( gAgent.getRegion()->getHost() );
+		}
+		i++;
+	}
+
+	mPendingAttachments.clear();
+}
diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d8ab74dfd9b6caa739f60b9bcb7d2ece67947d8
--- /dev/null
+++ b/indra/newview/llattachmentsmgr.h
@@ -0,0 +1,73 @@
+/** 
+ * @file llattachmentsmgr.h
+ * @brief Batches up attachment requests and sends them all
+ * in one message.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLATTACHMENTSMGR_H
+#define LL_LLATTACHMENTSMGR_H
+
+#include "llsingleton.h"
+
+class LLViewerInventoryItem;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLAttachmentsMgr
+// 
+// The sole purpose of this class is to take attachment
+// requests, queue them up, and send them all at once.
+// This handles situations where the viewer may request
+// a bunch of attachments at once in a short period of
+// time, where each of the requests would normally be
+// sent as a separate message versus being batched into
+// one single message.
+// 
+// The intent of this batching is to reduce viewer->server
+// traffic.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLAttachmentsMgr: public LLSingleton<LLAttachmentsMgr>
+{
+public:
+	LLAttachmentsMgr();
+	virtual ~LLAttachmentsMgr();
+
+	void addAttachment(const LLUUID& item_id,
+					   const U8 attachment_pt,
+					   const BOOL add);
+	static void onIdle(void *);
+protected:
+	void onIdle();
+private:
+	struct AttachmentsInfo
+	{
+		LLUUID mItemID;
+		U8 mAttachmentPt;
+		BOOL mAdd;
+	};
+
+	typedef std::vector<AttachmentsInfo> attachments_vec_t;
+	attachments_vec_t mPendingAttachments;
+};
+
+#endif
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 1cd705c2f9d8b555f56a83cbb388e029083a00a2..5241f20c0e1d764ef54aeef4d8c695779b150931 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -90,6 +90,20 @@ void LLAvatarList::setSpeakingIndicatorsVisible(bool visible)
 	}
 }
 
+void LLAvatarList::showPermissions(bool visible)
+{
+	// Save the value for new items to use.
+	mShowPermissions = visible;
+
+	// Enable or disable showing permissions icons for all existing items.
+	std::vector<LLPanel*> items;
+	getItems(items);
+	for(std::vector<LLPanel*>::const_iterator it = items.begin(), end_it = items.end(); it != end_it; ++it)
+	{
+		static_cast<LLAvatarListItem*>(*it)->setShowPermissions(mShowPermissions);
+	}
+}
+
 static bool findInsensitive(std::string haystack, const std::string& needle_upper)
 {
     LLStringUtil::toUpper(haystack);
@@ -107,6 +121,7 @@ LLAvatarList::Params::Params()
 , show_info_btn("show_info_btn", true)
 , show_profile_btn("show_profile_btn", true)
 , show_speaking_indicator("show_speaking_indicator", true)
+, show_permissions_granted("show_permissions_granted", false)
 {
 }
 
@@ -121,6 +136,7 @@ LLAvatarList::LLAvatarList(const Params& p)
 , mShowInfoBtn(p.show_info_btn)
 , mShowProfileBtn(p.show_profile_btn)
 , mShowSpeakingIndicator(p.show_speaking_indicator)
+, mShowPermissions(p.show_permissions_granted)
 {
 	setCommitOnSelectionChange(true);
 
@@ -377,6 +393,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
 	item->setShowInfoBtn(mShowInfoBtn);
 	item->setShowProfileBtn(mShowProfileBtn);
 	item->showSpeakingIndicator(mShowSpeakingIndicator);
+	item->setShowPermissions(mShowPermissions);
 
 	item->setDoubleClickCallback(boost::bind(&LLAvatarList::onItemDoubleClicked, this, _1, _2, _3, _4));
 
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 83faa53c281a6f309899ca8902cfb3130160f1ce..9d3dcb75f367167db967928f581db7de273f24bd 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -54,7 +54,8 @@ public:
 						show_last_interaction_time, // show most recent interaction time. *HACK: move this to a derived class
 						show_info_btn,
 						show_profile_btn,
-						show_speaking_indicator;
+						show_speaking_indicator,
+						show_permissions_granted;
 		Params();
 	};
 
@@ -78,6 +79,7 @@ public:
 
 	void toggleIcons();
 	void setSpeakingIndicatorsVisible(bool visible);
+	void showPermissions(bool visible);
 	void sortByName();
 	void setShowIcons(std::string param_name);
 	bool getIconsVisible() const { return mShowIcons; }
@@ -115,6 +117,7 @@ private:
 	bool mShowInfoBtn;
 	bool mShowProfileBtn;
 	bool mShowSpeakingIndicator;
+	bool mShowPermissions;
 
 	LLTimer*				mLITUpdateTimer; // last interaction time update timer
 	std::string				mIconParamName;
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 341913edf7b80723677976545d18e01a94c7d011..8fc4ad6763c8c33992572b3e399c142571146e56 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -60,12 +60,17 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
 	mAvatarIcon(NULL),
 	mAvatarName(NULL),
 	mLastInteractionTime(NULL),
+	mIconPermissionOnline(NULL),
+	mIconPermissionMap(NULL),
+	mIconPermissionEditMine(NULL),
+	mIconPermissionEditTheirs(NULL),
 	mSpeakingIndicator(NULL),
 	mInfoBtn(NULL),
 	mProfileBtn(NULL),
 	mOnlineStatus(E_UNKNOWN),
 	mShowInfoBtn(true),
-	mShowProfileBtn(true)
+	mShowProfileBtn(true),
+	mShowPermissions(false)
 {
 	if (not_from_ui_factory)
 	{
@@ -86,7 +91,16 @@ BOOL  LLAvatarListItem::postBuild()
 	mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon");
 	mAvatarName = getChild<LLTextBox>("avatar_name");
 	mLastInteractionTime = getChild<LLTextBox>("last_interaction");
-	
+
+	mIconPermissionOnline = getChild<LLIconCtrl>("permission_online_icon");
+	mIconPermissionMap = getChild<LLIconCtrl>("permission_map_icon");
+	mIconPermissionEditMine = getChild<LLIconCtrl>("permission_edit_mine_icon");
+	mIconPermissionEditTheirs = getChild<LLIconCtrl>("permission_edit_theirs_icon");
+	mIconPermissionOnline->setVisible(false);
+	mIconPermissionMap->setVisible(false);
+	mIconPermissionEditMine->setVisible(false);
+	mIconPermissionEditTheirs->setVisible(false);
+
 	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
 	mInfoBtn = getChild<LLButton>("info_btn");
 	mProfileBtn = getChild<LLButton>("profile_btn");
@@ -125,8 +139,10 @@ void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask)
 	mInfoBtn->setVisible(mShowInfoBtn);
 	mProfileBtn->setVisible(mShowProfileBtn);
 
+	mHovered = true;
 	LLPanel::onMouseEnter(x, y, mask);
 
+	showPermissions(mShowPermissions);
 	updateChildren();
 }
 
@@ -136,8 +152,10 @@ void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask)
 	mInfoBtn->setVisible(false);
 	mProfileBtn->setVisible(false);
 
+	mHovered = false;
 	LLPanel::onMouseLeave(x, y, mask);
 
+	showPermissions(false);
 	updateChildren();
 }
 
@@ -146,6 +164,12 @@ void LLAvatarListItem::changed(U32 mask)
 {
 	// no need to check mAvatarId for null in this case
 	setOnline(LLAvatarTracker::instance().isBuddyOnline(mAvatarId));
+
+	if (mask & LLFriendObserver::POWERS)
+	{
+		showPermissions(mShowPermissions && mHovered);
+		updateChildren();
+	}
 }
 
 void LLAvatarListItem::setOnline(bool online)
@@ -230,10 +254,7 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, const LLUUID& session_id, b
 
 void LLAvatarListItem::showLastInteractionTime(bool show)
 {
-	if (show)
-		return;
-
-	mLastInteractionTime->setVisible(false);
+	mLastInteractionTime->setVisible(show);
 	updateChildren();
 }
 
@@ -244,17 +265,11 @@ void LLAvatarListItem::setLastInteractionTime(U32 secs_since)
 
 void LLAvatarListItem::setShowInfoBtn(bool show)
 {
-	// Already done? Then do nothing.
-	if(mShowInfoBtn == show)
-		return;
 	mShowInfoBtn = show;
 }
 
 void LLAvatarListItem::setShowProfileBtn(bool show)
 {
-	// Already done? Then do nothing.
-	if(mShowProfileBtn == show)
-			return;
 	mShowProfileBtn = show;
 }
 
@@ -273,7 +288,9 @@ void LLAvatarListItem::setAvatarIconVisible(bool visible)
 {
 	// Already done? Then do nothing.
 	if (mAvatarIcon->getVisible() == (BOOL)visible)
+	{
 		return;
+	}
 
 	// Show/hide avatar icon.
 	mAvatarIcon->setVisible(visible);
@@ -322,7 +339,7 @@ const std::string LLAvatarListItem::getAvatarName() const
 	return mAvatarName->getValue();
 }
 
-//== PRIVATE SECITON ==========================================================
+//== PRIVATE SECTION ==========================================================
 
 void LLAvatarListItem::setNameInternal(const std::string& name, const std::string& highlight)
 {
@@ -432,10 +449,22 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
 	//info btn width + padding
 	S32 info_btn_width = avatar_item->mProfileBtn->getRect().mLeft - avatar_item->mInfoBtn->getRect().mLeft;
 
+	// edit their objects permission icon width + padding
+	S32 permission_edit_theirs_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mIconPermissionEditTheirs->getRect().mLeft;
+
+	// edit my objects permission icon width + padding
+	S32 permission_edit_mine_width = avatar_item->mIconPermissionEditTheirs->getRect().mLeft - avatar_item->mIconPermissionEditMine->getRect().mLeft;
+
+	// map permission icon width + padding
+	S32 permission_map_width = avatar_item->mIconPermissionEditMine->getRect().mLeft - avatar_item->mIconPermissionMap->getRect().mLeft;
+
+	// online permission icon width + padding
+	S32 permission_online_width = avatar_item->mIconPermissionMap->getRect().mLeft - avatar_item->mIconPermissionOnline->getRect().mLeft;
+
 	// last interaction time textbox width + padding
-	S32 last_interaction_time_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
+	S32 last_interaction_time_width = avatar_item->mIconPermissionOnline->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
 
-	// icon width + padding
+	// avatar icon width + padding
 	S32 icon_width = avatar_item->mAvatarName->getRect().mLeft - avatar_item->mAvatarIcon->getRect().mLeft;
 
 	sLeftPadding = avatar_item->mAvatarIcon->getRect().mLeft;
@@ -445,9 +474,14 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
 	sChildrenWidths[--index] = icon_width;
 	sChildrenWidths[--index] = 0; // for avatar name we don't need its width, it will be calculated as "left available space"
 	sChildrenWidths[--index] = last_interaction_time_width;
+	sChildrenWidths[--index] = permission_online_width;
+	sChildrenWidths[--index] = permission_map_width;
+	sChildrenWidths[--index] = permission_edit_mine_width;
+	sChildrenWidths[--index] = permission_edit_theirs_width;
 	sChildrenWidths[--index] = info_btn_width;
 	sChildrenWidths[--index] = profile_btn_width;
 	sChildrenWidths[--index] = speaking_indicator_width;
+	llassert(index == 0);
 }
 
 void LLAvatarListItem::updateChildren()
@@ -526,6 +560,27 @@ void LLAvatarListItem::updateChildren()
 	LL_DEBUGS("AvatarItemReshape") << "name rect after: " << name_view_rect << LL_ENDL;
 }
 
+bool LLAvatarListItem::showPermissions(bool visible)
+{
+	const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+	if(relation && visible)
+	{
+		mIconPermissionOnline->setVisible(relation->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS));
+		mIconPermissionMap->setVisible(relation->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION));
+		mIconPermissionEditMine->setVisible(relation->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS));
+		mIconPermissionEditTheirs->setVisible(relation->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS));
+	}
+	else
+	{
+		mIconPermissionOnline->setVisible(false);
+		mIconPermissionMap->setVisible(false);
+		mIconPermissionEditMine->setVisible(false);
+		mIconPermissionEditTheirs->setVisible(false);
+	}
+
+	return NULL != relation;
+}
+
 LLView* LLAvatarListItem::getItemChildView(EAvatarListItemChildIndex child_view_index)
 {
 	LLView* child_view = mAvatarName;
@@ -542,7 +597,19 @@ LLView* LLAvatarListItem::getItemChildView(EAvatarListItemChildIndex child_view_
 		child_view = mLastInteractionTime;
 		break;
 	case ALIC_SPEAKER_INDICATOR:
-		child_view = mSpeakingIndicator; 
+		child_view = mSpeakingIndicator;
+		break;
+	case ALIC_PERMISSION_ONLINE:
+		child_view = mIconPermissionOnline;
+		break;
+	case ALIC_PERMISSION_MAP:
+		child_view = mIconPermissionMap;
+		break;
+	case ALIC_PERMISSION_EDIT_MINE:
+		child_view = mIconPermissionEditMine;
+		break;
+	case ALIC_PERMISSION_EDIT_THEIRS:
+		child_view = mIconPermissionEditTheirs;
 		break;
 	case ALIC_INFO_BUTTON:
 		child_view = mInfoBtn;
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index e252e69ea9b614852d87c55aed039281808e6d2d..ffb988b2abd131c0155608f73e295f1c7d5eb465 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -36,6 +36,7 @@
 #include "llcallingcard.h" // for LLFriendObserver
 
 class LLAvatarIconCtrl;
+class LLIconCtrl;
 
 class LLAvatarListItem : public LLPanel, public LLFriendObserver
 {
@@ -94,6 +95,7 @@ public:
 	void setShowProfileBtn(bool show);
 	void setShowInfoBtn(bool show);
 	void showSpeakingIndicator(bool show);
+	void setShowPermissions(bool show) { mShowPermissions = show; };
 	void showLastInteractionTime(bool show);
 	void setAvatarIconVisible(bool visible);
 	
@@ -113,6 +115,15 @@ protected:
 
 	LLAvatarIconCtrl* mAvatarIcon;
 
+	/// Indicator for permission to see me online.
+	LLIconCtrl* mIconPermissionOnline;
+	/// Indicator for permission to see my position on the map.
+	LLIconCtrl* mIconPermissionMap;
+	/// Indicator for permission to edit my objects.
+	LLIconCtrl* mIconPermissionEditMine;
+	/// Indicator for permission to edit their objects.
+	LLIconCtrl* mIconPermissionEditTheirs;
+
 private:
 
 	typedef enum e_online_status {
@@ -132,6 +143,10 @@ private:
 		ALIC_SPEAKER_INDICATOR,
 		ALIC_PROFILE_BUTTON,
 		ALIC_INFO_BUTTON,
+		ALIC_PERMISSION_EDIT_THEIRS,
+		ALIC_PERMISSION_EDIT_MINE,
+		ALIC_PERMISSION_MAP,
+		ALIC_PERMISSION_ONLINE,
 		ALIC_INTERACTION_TIME,
 		ALIC_NAME,
 		ALIC_ICON,
@@ -158,6 +173,13 @@ private:
 	 */
 	void updateChildren();
 
+	/**
+	 * Update visibility of active permissions icons.
+	 *
+	 * Need to call updateChildren() afterwards to sort out their layout.
+	 */
+	bool showPermissions(bool visible);
+
 	/**
 	 * Gets child view specified by index.
 	 *
@@ -181,6 +203,12 @@ private:
 	bool mShowInfoBtn;
 	bool mShowProfileBtn;
 
+	/// indicates whether to show icons representing permissions granted
+	bool mShowPermissions;
+
+	/// true when the mouse pointer is hovering over this item
+	bool mHovered;
+
 	static bool	sStaticInitialized; // this variable is introduced to improve code readability
 	static S32  sLeftPadding; // padding to first left visible child (icon or name)
 	static S32  sRightNamePadding; // right padding from name to next visible child
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 6ee438723656d303f24fa8ec8b50cb22ac399e03..29f4311ea48f7c9d0cb3e6b5f0f70eaa6caa6182 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -49,6 +49,48 @@
 #include "lltoolmgr.h"
 #include "llviewerparcelmgr.h"
 
+#include "llviewerwindow.h"
+#include "llsdserialize.h"
+
+// Distance from mouse down on which drag'n'drop should be started.
+#define DRAG_START_DISTANCE 3
+
+static const std::string SORTING_DATA_FILE_NAME = "bottomtray_buttons_order.xml";
+
+LLDefaultChildRegistry::Register<LLBottomtrayButton> bottomtray_button("bottomtray_button");
+
+// LLBottomtrayButton methods
+
+// virtual
+BOOL LLBottomtrayButton::handleHover(S32 x, S32 y, MASK mask)
+{
+	S32 screenX, screenY;
+	localPointToScreen(x, y, &screenX, &screenY);
+	// pass hover to bottomtray
+	LLBottomTray::getInstance()->onDraggableButtonHover(screenX, screenY);
+	return FALSE;
+}
+//virtual
+BOOL LLBottomtrayButton::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+	S32 screenX, screenY;
+	localPointToScreen(x, y, &screenX, &screenY);
+	// pass mouse up to bottomtray
+	LLBottomTray::getInstance()->onDraggableButtonMouseUp(this, screenX, screenY);
+	LLButton::handleMouseUp(x, y, mask);
+	return FALSE;
+}
+//virtual
+BOOL LLBottomtrayButton::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	S32 screenX, screenY;
+	localPointToScreen(x, y, &screenX, &screenY);
+	// pass mouse up to bottomtray
+	LLBottomTray::getInstance()->onDraggableButtonMouseDown(this, screenX, screenY);
+	LLButton::handleMouseDown(x, y, mask);
+	return FALSE;
+}
+
 static void update_build_button_enable_state()
 {
 	bool can_edit = LLToolMgr::getInstance()->canEdit();
@@ -153,6 +195,10 @@ LLBottomTray::LLBottomTray(const LLSD&)
 ,	mCamButton(NULL)
 ,	mBottomTrayLite(NULL)
 ,	mIsInLiteMode(false)
+,	mDragStarted(false)
+,	mDraggedItem(NULL)
+,	mLandingTab(NULL)
+,	mCheckForDrag(false)
 {
 	// Firstly add ourself to IMSession observers, so we catch session events
 	// before chiclets do that.
@@ -177,6 +223,8 @@ LLBottomTray::LLBottomTray(const LLSD&)
 		mBottomTrayLite->setFollowsAll();
 		mBottomTrayLite->setVisible(FALSE);
 	}
+
+	mImageDragIndication = LLUI::getUIImage(getString("DragIndicationImageName"));
 }
 
 LLBottomTray::~LLBottomTray()
@@ -504,11 +552,251 @@ BOOL LLBottomTray::postBuild()
 	showWellButton(RS_IM_WELL, !LLIMWellWindow::getInstance()->isWindowEmpty());
 	showWellButton(RS_NOTIFICATION_WELL, !LLNotificationWellWindow::getInstance()->isWindowEmpty());
 
+	loadButtonsOrder();
+
 	LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&update_build_button_enable_state));
 
 	return TRUE;
 }
 
+//Drag-n-drop
+
+void LLBottomTray::onDraggableButtonMouseDown(LLUICtrl* ctrl, S32 x, S32 y)
+{
+	if (ctrl == NULL) return;
+	LLView* parent_view = ctrl->getParent();
+	if(parent_view != NULL)
+	{
+		// we actually drag'n'drop panel (not button) in code, so have to find a parent
+		// of button which called this method on mouse down.
+		LLPanel* parent = dynamic_cast<LLPanel*>(parent_view);
+		// It may happen that we clicked not usual button, but button inside widget(speak, gesture)
+		// so we'll need to get a level higher to reach layout panel as a parent.
+		if(parent == NULL) parent = dynamic_cast<LLPanel*>(parent_view->getParent());
+		if (parent && parent->getVisible())
+		{
+			mDraggedItem = parent;
+			mCheckForDrag = true;
+			mStartX = x;
+			mStartY = y;
+		}
+	}
+}
+
+LLPanel* LLBottomTray::findChildPanelByLocalCoords(S32 x, S32 y)
+{
+	LLPanel* ctrl = 0;
+	S32 screenX, screenY;
+	const child_list_t* list = mToolbarStack->getChildList();
+
+	localPointToScreen(x, y, &screenX, &screenY);
+
+	// look for a child panel which contains the point (screenX, screenY) in it's rectangle
+	for (child_list_const_iter_t i = list->begin(); i != list->end(); ++i)
+	{
+		LLRect rect;
+		localRectToScreen((*i)->getRect(), &rect);
+
+		if (rect.pointInRect(screenX, screenY))
+		{
+			ctrl = dynamic_cast<LLPanel*>(*i);
+			break;
+		}
+	}
+
+	return ctrl;
+}
+
+void LLBottomTray::onDraggableButtonHover(S32 x, S32 y)
+{
+	// if mouse down on draggable item was done, check whether we should start DnD
+	if (mCheckForDrag)
+	{
+		// Start drag'n'drop if mouse cursor was dragged away frome mouse down location enough
+		if(sqrt((float)((mStartX-x)*(mStartX-x)+(mStartY-y)*(mStartY-y))) > DRAG_START_DISTANCE)
+		{
+			mDragStarted = true;
+			mCheckForDrag = false;
+		}
+	}
+	if (mDragStarted)
+	{
+		// Check whether the cursor is over draggable area, find which panel it is and set is as
+		// landing tab for drag'n'drop
+		if(isCursorOverDraggableArea(x, y))
+		{
+			LLPanel* panel = findChildPanelByLocalCoords(x,y);
+			if (panel && panel != mDraggedItem) mLandingTab = panel;
+			gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROWDRAG);
+		}
+		else
+		{
+			gViewerWindow->getWindow()->setCursor(UI_CURSOR_NO);
+		}
+	}
+}
+
+bool LLBottomTray::isCursorOverDraggableArea(S32 x, S32 y)
+{
+	bool result = getRect().pointInRect(x, y);
+	result = result && mNearbyChatBar->calcScreenRect().mRight < x;
+	result = result && mChicletPanel->calcScreenRect().mRight > x;
+	return result;
+}
+
+void LLBottomTray::updateButtonsOrdersAfterDnD()
+{
+	// *TODO: change implementation of this method to support simplify it
+	// (and according to future possible changes in the way button order is saved between sessions).
+	state_object_map_t::const_iterator it = mStateProcessedObjectMap.begin();
+	state_object_map_t::const_iterator it_end = mStateProcessedObjectMap.end();
+	// Speak button is currently the only draggable button not in mStateProcessedObjectMap,
+	// so if dragged_state is not found in that map, it should be RS_BUTTON_SPEAK. Change this code if any other
+	// exclusions from mStateProcessedObjectMap will become draggable.
+	EResizeState dragged_state = RS_BUTTON_SPEAK;
+	EResizeState landing_state = RS_NORESIZE;
+	bool landing_state_found = false;
+	// Find states for dragged item and landing tab
+	for (; it != it_end; ++it)
+	{
+		if (it->second == mDraggedItem)
+		{
+			dragged_state = it->first;
+		}
+		else if (it->second == mLandingTab)
+		{
+			landing_state = it->first;
+			landing_state_found = true;
+		}
+	}
+	
+	// Update order of buttons according to drag'n'drop
+	mButtonsOrder.erase(std::find(mButtonsOrder.begin(), mButtonsOrder.end(), dragged_state));
+	if (!landing_state_found && mLandingTab == getChild<LLPanel>(PANEL_CHICLET_NAME))
+	{
+		mButtonsOrder.push_back(dragged_state);
+	}
+	else
+	{
+		if (!landing_state_found) landing_state = RS_BUTTON_SPEAK;
+		mButtonsOrder.insert(std::find(mButtonsOrder.begin(), mButtonsOrder.end(), landing_state), dragged_state);
+	}
+	// Synchronize button process order with their order
+	resize_state_vec_t::const_iterator it1 = mButtonsOrder.begin();
+	const resize_state_vec_t::const_iterator it_end1 = mButtonsOrder.end();
+	resize_state_vec_t::iterator it2 = mButtonsProcessOrder.begin();
+	for (; it1 != it_end1; ++it1)
+	{
+		// Skip Speak because it is not in mButtonsProcessOrder(it's the reason why mButtonsOrder was introduced).
+		// If any other draggable items will be added to bottomtray later, they should also be skipped here.
+		if (*it1 != RS_BUTTON_SPEAK)
+		{
+			*it2 = *it1;
+			++it2;
+		}
+	}
+
+	saveButtonsOrder();
+}
+
+void LLBottomTray::saveButtonsOrder()
+{
+	std::string user_dir = gDirUtilp->getLindenUserDir();
+	if (user_dir.empty()) return;
+	
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
+	LLSD settings_llsd;
+	int i = 0;
+	const resize_state_vec_t::const_iterator it_end = mButtonsOrder.end();
+	// we use numbers as keys for map which is saved in file and contains resize states as its values
+	for (resize_state_vec_t::const_iterator it = mButtonsOrder.begin(); it != it_end; ++it, i++)
+	{
+		std::string str = llformat("%d", i);
+		settings_llsd[str] = *it;		
+	}
+	llofstream file;
+	file.open(filename);
+	LLSDSerialize::toPrettyXML(settings_llsd, file);
+}
+
+void LLBottomTray::loadButtonsOrder()
+{
+	// load per-resident sorting information
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
+
+	LLSD settings_llsd;
+	llifstream file;
+	file.open(filename);
+	if (!file.is_open()) return;
+	
+	LLSDSerialize::fromXML(settings_llsd, file);
+	
+
+	mButtonsOrder.clear();
+	mButtonsProcessOrder.clear();
+	int i = 0;
+	// getting button order from file
+	for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
+		iter != settings_llsd.endMap(); ++iter, ++i)
+	{
+		std::string str = llformat("%d", i);
+		EResizeState state = (EResizeState)settings_llsd[str].asInteger();
+		mButtonsOrder.push_back(state);
+		// RS_BUTTON_SPEAK is skipped, because it shouldn't be in mButtonsProcessOrder (it does not hide or shrink).
+		if (state != RS_BUTTON_SPEAK)
+		{
+			mButtonsProcessOrder.push_back(state);
+		}		
+	}
+
+	// There are other panels in layout stack order of which is not saved. Also, panels order of which is saved,
+	// are already in layout stack but in wrong order. The most convenient way to place them is moving them 
+	// to front one by one (because in this case we don't have to pass the panel before which we want to insert our
+	// panel to movePanel()). So panels are moved in order from the end of mButtonsOrder vector(reverse iterator is used).
+	const resize_state_vec_t::const_reverse_iterator it_end = mButtonsOrder.rend();
+	// placing panels in layout stack according to button order which we loaded in previous for
+	for (resize_state_vec_t::const_reverse_iterator it = mButtonsOrder.rbegin(); it != it_end; ++it, ++i)
+	{
+		LLPanel* panel_to_move = *it == RS_BUTTON_SPEAK ? mSpeakPanel : mStateProcessedObjectMap[*it];
+		mToolbarStack->movePanel(panel_to_move, NULL, true); // prepend 		
+	}
+	// Nearbychat is not stored in order settings file, but it must be the first of the panels, so moving it
+	// manually here
+	mToolbarStack->movePanel(mNearbyChatBar, NULL, true);
+}
+
+void LLBottomTray::onDraggableButtonMouseUp(LLUICtrl* ctrl, S32 x, S32 y)
+{
+	//if mouse up happened over area where drop is possible, change order of buttons
+	if (mLandingTab != NULL && mDraggedItem != NULL && mDragStarted)
+	{
+		if(isCursorOverDraggableArea(x, y))
+		{
+			// change order of panels in layout stack
+			mToolbarStack->movePanel(mDraggedItem, (LLPanel*)mLandingTab);
+			// change order of buttons in order vectors
+			updateButtonsOrdersAfterDnD();
+		}
+	}
+	gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
+	mDragStarted = false;
+	mDraggedItem = NULL;
+	mLandingTab = NULL;
+	mCheckForDrag = false;
+}
+
+void LLBottomTray::draw()
+{
+	LLPanel::draw();
+	if (mLandingTab)
+	{
+		static S32 w = mImageDragIndication->getWidth();
+		static S32 h = mImageDragIndication->getHeight();
+		LLRect rect = mLandingTab->calcScreenRect();
+		mImageDragIndication->draw(rect.mLeft - w/2, rect.getHeight(), w, h);
+	}
+}
+
 bool LLBottomTray::onContextMenuItemEnabled(const LLSD& userdata)
 {
 	std::string item = userdata.asString();
@@ -1181,6 +1469,9 @@ void LLBottomTray::initResizeStateContainers()
 	mButtonsProcessOrder.push_back(RS_BUTTON_WORLD_MAP);
 	mButtonsProcessOrder.push_back(RS_BUTTON_MINI_MAP);
 
+	mButtonsOrder.push_back(RS_BUTTON_SPEAK);
+	mButtonsOrder.insert(mButtonsOrder.end(), mButtonsProcessOrder.begin(), mButtonsProcessOrder.end());
+
 	// init default widths
 
 	// process buttons that can be hidden on resize...
@@ -1233,7 +1524,7 @@ void LLBottomTray::setButtonsControlsAndListeners()
 	// set control name for Build button. It is not enough to link it with Button.SetFloaterToggle in xml
 	std::string vis_control_name = LLFloaterReg::declareVisibilityControl("build");
 	// Set the button control value (toggle state) to the floater visibility control (Sets the value as well)
-	build_btn->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name));
+	build_btn->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name));
 }
 
 bool LLBottomTray::toggleShowButton(LLBottomTray::EResizeState button_type, const LLSD& new_visibility)
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index bd9d35f209a880ca1cb44449e4140232da438c24..1197c5a10a8db9446f3caf56d861cfa4fc3307d7 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -47,6 +47,30 @@ class LLBottomTrayLite;
 extern template class LLBottomTray* LLSingleton<class LLBottomTray>::getInstance();
 #endif
 
+/**
+ * Class for buttons that should have drag'n'drop ability in bottomtray.
+ * These buttons pass mouse events handling to bottomtray.
+ */
+class LLBottomtrayButton : public LLButton
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLButton::Params>
+	{
+		Params(){}
+	};
+	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+protected:
+	LLBottomtrayButton(const Params& p)
+		:	LLButton(p)
+	{
+
+	}
+	friend class LLUICtrlFactory;
+};
+
 class LLBottomTray 
 	: public LLSingleton<LLBottomTray>
 	, public LLPanel
@@ -101,6 +125,20 @@ public:
 	 */
 	LLIMChiclet* createIMChiclet(const LLUUID& session_id);
 
+	// Below are methods that were introduced or overriden in bottomtray to handle drag'n'drop
+
+	virtual void draw();
+
+	/**
+	 * These three methods handle drag'n'drop, they may be called directly from child buttons.
+	 * handleHover and other virtual handle* couldn't be used here, because we should call LLPanel::handle*,
+	 * but x and y here are often outside of bottomtray.
+	 */
+	void onDraggableButtonHover(S32 x, S32 y);
+	void onDraggableButtonMouseDown(LLUICtrl* button, S32 x, S32 y);
+	void onDraggableButtonMouseUp(LLUICtrl* button, S32 x, S32 y);
+
+
 private:
 	typedef enum e_resize_status_type
 	{
@@ -134,6 +172,29 @@ private:
 									| RS_BUTTON_BUILD | RS_BUTTON_SEARCH | RS_BUTTON_WORLD_MAP | RS_BUTTON_MINI_MAP
 	}EResizeState;
 
+	// Below are three methods that were introduced to handle drag'n'drop
+
+	/**
+	 * finds a panel under the specified LOCAL point
+	 */
+	LLPanel* findChildPanelByLocalCoords(S32 x, S32 y);
+
+	/**
+	 * checks whether the cursor is over an area where the dragged button may be dropped
+	 */
+	bool isCursorOverDraggableArea(S32 x, S32 y);
+
+	/**
+	 * Updates process(shrink/show/hide) order of buttons and order in which they'll be stored for further save/load.
+	 * It is called when dragged button is dropped
+	 */
+	void updateButtonsOrdersAfterDnD();
+
+	// saves order of buttons to file on disk
+	void saveButtonsOrder();
+	// reads order of buttons from file on disk
+	void loadButtonsOrder();
+
 	/**
 	 * Updates child controls size and visibility when it is necessary to reduce total width.
 	 *
@@ -360,6 +421,13 @@ private:
 	 * Contains order in which child buttons should be processed in show/hide, extend/shrink methods.
 	 */
 	resize_state_vec_t mButtonsProcessOrder;
+	/**
+	 * Contains order in which child buttons are shown.
+	 * It traces order of all bottomtray buttons that may change place via drag'n'drop and should
+	 * save and load it between sessions. mButtonsProcessOrder is not enough for it because it contains only
+	 * buttons that may be hidden.
+	 */
+	resize_state_vec_t mButtonsOrder;
 
 protected:
 
@@ -381,6 +449,38 @@ protected:
 	LLButton*			mMovementButton;
 	LLBottomTrayLite*   mBottomTrayLite;
 	bool                mIsInLiteMode;
+
+	// Drag'n'Drop
+
+	/**
+	 * Is true if mouse down happened on draggable button.
+	 * Set false whether on drag start or on mouse up.
+	 */
+	bool mCheckForDrag;
+	/**
+	 * These two variables hold corrdinates of mouse down on draggable button.
+	 * They are used to compare with current coordinates of cursor and determine whether drag'n'drop should start.
+	 */
+	S32 mStartX;
+	S32 mStartY;
+	/**
+	 * True if drag'n'drop is happening.
+	 */
+	bool mDragStarted;
+
+	/**
+	 * Pointer to panel which is currently dragged (though it seems to user that button is dragged,
+	 * we are changing place of layout panel).
+	 */
+	LLPanel* mDraggedItem;
+	/**
+	 * Panel before which the dragged button will be inserted.
+	 */
+	LLPanel* mLandingTab;
+	/**
+	 * Image used to show position where dragged button will be dropped.
+	 */
+	LLUIImage* mImageDragIndication;
 };
 
 #endif // LL_LLBOTTOMPANEL_H
diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h
index 617f8fe27b74381185915d68762c789ee687fa36..15ca51743a345b950be7b18fce931612365414ac 100644
--- a/indra/newview/llcallingcard.h
+++ b/indra/newview/llcallingcard.h
@@ -45,7 +45,7 @@ class LLFriendObserver
 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.
+	// changed() to see if the observer is interested in the change.
 	enum 
 	{
 		NONE = 0,
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 7d82ec3a71e612efaa1e0e6a1975863a9a95f33f..d251931ecabd1e482a1ba5ad39159be339fff949 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -126,7 +126,7 @@ BOOL LLChatBar::postBuild()
 	mInputEditor->setPassDelete(TRUE);
 	mInputEditor->setReplaceNewlinesWithSpaces(FALSE);
 
-	mInputEditor->setMaxTextLength(1023);
+	mInputEditor->setMaxTextLength(DB_CHAT_MSG_STR_LEN);
 	mInputEditor->setEnableLineHistory(TRUE);
 
 	mIsBuilt = TRUE;
@@ -569,8 +569,12 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
 	S32 channel = 0;
 	LLWString out_text = stripChannelNumber(wtext, &channel);
 	std::string utf8_out_text = wstring_to_utf8str(out_text);
-	std::string utf8_text = wstring_to_utf8str(wtext);
+	if (!utf8_out_text.empty())
+	{
+		utf8_out_text = utf8str_truncate(utf8_out_text, MAX_MSG_STR_LEN);
+	}
 
+	std::string utf8_text = wstring_to_utf8str(wtext);
 	utf8_text = utf8str_trim(utf8_text);
 	if (!utf8_text.empty())
 	{
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 1f67a659bd2a101bceef36f5c60729e31a86ab0e..dfb1db523dbe21b33674a65f10ed4d42fe7cc583 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -760,7 +760,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		if (notification != NULL)
 		{
 			LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel(
-					notification, chat.mSessionID);
+					notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history);
 			//we can't set follows in xml since it broke toasts behavior
 			notify_box->setFollowsLeft();
 			notify_box->setFollowsRight();
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index ed35546ca31e911165b685818dda4a5114a699fb..a3d2941114f39d4124e0cc9b550202676debb977 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -54,6 +54,13 @@ LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 compon
 {
 	llassert((1 <= components) && (components <= 4));
 
+	if(gGLManager.mDebugGPU)
+	{
+		if(components == 3)
+		{
+			mComponents = 4 ; //convert to 32bits.
+		}
+	}
 	generateGLTexture();
 
 	llassert( 0 <= order && order < ORDER_COUNT );
diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index f0c2469977d35e1f1160ea62c82721ece9fb9031..5e10f60aba0b972a938bd5f46cc32054476cd8bc 100644
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -121,7 +121,6 @@ LLExpandableTextBox::LLTextBoxEx::LLTextBoxEx(const Params& p)
 
 void LLExpandableTextBox::LLTextBoxEx::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	hideExpandText();
 	LLTextEditor::reshape(width, height, called_from_parent);
 
 	if (getTextPixelHeight() > getRect().getHeight())
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 03cfc6764a8479f2bd20a16f3609a5fc4bcfd90f..ca2ef5f5b8e1bdafcf462cccf502359253947c76 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -67,8 +67,8 @@ const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_linux.%s.txt";
 const char FEATURE_TABLE_FILENAME[] = "featuretable_solaris.txt";
 const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_solaris.%s.txt";
 #else
-const char FEATURE_TABLE_FILENAME[] = "featuretable.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable.%s.txt";
+const char FEATURE_TABLE_FILENAME[] = "featuretable%s.txt";
+const char FEATURE_TABLE_VER_FILENAME[] = "featuretable%s.%s.txt";
 #endif
 
 const char GPU_TABLE_FILENAME[] = "gpu_table.txt";
@@ -220,10 +220,30 @@ BOOL LLFeatureManager::loadFeatureTables()
 	// first table is install with app
 	std::string app_path = gDirUtilp->getAppRODataDir();
 	app_path += gDirUtilp->getDirDelimiter();
-	app_path += FEATURE_TABLE_FILENAME;
 
+	std::string filename;
+	std::string http_filename; 
+#if LL_WINDOWS
+	std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+	if (os_string.find("Microsoft Windows XP") == 0)
+	{
+		filename = llformat(FEATURE_TABLE_FILENAME, "_xp");
+		http_filename = llformat(FEATURE_TABLE_VER_FILENAME, "_xp", LLVersionInfo::getVersion().c_str());
+	}
+	else
+	{
+		filename = llformat(FEATURE_TABLE_FILENAME, "");
+		http_filename = llformat(FEATURE_TABLE_VER_FILENAME, "", LLVersionInfo::getVersion().c_str());
+	}
+#else
+	filename = FEATURE_TABLE_FILENAME;
+	http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
+#endif
+
+	app_path += filename;
+
+	
 	// second table is downloaded with HTTP
-	std::string http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
 	std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
 
 	// use HTTP table if it exists
@@ -488,7 +508,35 @@ private:
 	std::string mFilename;
 };
 
-void fetch_table(std::string table)
+void fetch_feature_table(std::string table)
+{
+	const std::string base       = gSavedSettings.getString("FeatureManagerHTTPTable");
+
+#if LL_WINDOWS
+	std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+	std::string filename;
+	if (os_string.find("Microsoft Windows XP") == 0)
+	{
+		filename = llformat(table.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
+	}
+	else
+	{
+		filename = llformat(table.c_str(), "", LLVersionInfo::getVersion().c_str());
+	}
+#else
+	const std::string filename   = llformat(table.c_str(), LLVersionInfo::getVersion().c_str());
+#endif
+
+	const std::string url        = base + "/" + filename;
+
+	const std::string path       = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
+
+	llinfos << "LLFeatureManager fetching " << url << " into " << path << llendl;
+	
+	LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
+}
+
+void fetch_gpu_table(std::string table)
 {
 	const std::string base       = gSavedSettings.getString("FeatureManagerHTTPTable");
 
@@ -506,8 +554,8 @@ void fetch_table(std::string table)
 // fetch table(s) from a website (S3)
 void LLFeatureManager::fetchHTTPTables()
 {
-	fetch_table(FEATURE_TABLE_VER_FILENAME);
-	fetch_table(GPU_TABLE_VER_FILENAME);
+	fetch_feature_table(FEATURE_TABLE_VER_FILENAME);
+	fetch_gpu_table(GPU_TABLE_VER_FILENAME);
 }
 
 
diff --git a/indra/newview/llfloatersidetraytab.cpp b/indra/newview/llfloatersidetraytab.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f13b4db3a062e45679a17be31ff39f1d1ff1bd4f
--- /dev/null
+++ b/indra/newview/llfloatersidetraytab.cpp
@@ -0,0 +1,45 @@
+/** 
+ * @file llfloatersidetraytab.cpp
+ * @brief LLFloaterSideTrayTab class definition
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatersidetraytab.h"
+
+// newview includes
+#include "lltransientfloatermgr.h"
+
+LLFloaterSideTrayTab::LLFloaterSideTrayTab(const LLSD& key, const Params& params)
+:	LLFloater(key, params)
+{
+	// Prevent transient floaters (e.g. IM windows) from hiding
+	// when this floater is clicked.
+	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
+}
+
+LLFloaterSideTrayTab::~LLFloaterSideTrayTab()
+{
+	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::GLOBAL, this);
+}
diff --git a/indra/newview/llfloatersidetraytab.h b/indra/newview/llfloatersidetraytab.h
new file mode 100644
index 0000000000000000000000000000000000000000..e47f82e8ba250c47f0ad890ae2f4c69cc2f116bd
--- /dev/null
+++ b/indra/newview/llfloatersidetraytab.h
@@ -0,0 +1,47 @@
+/** 
+ * @file llfloatersidetraytab.h
+ * @brief LLFloaterSideTrayTab class definition
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERSIDETRAYTAB_H
+#define LL_LLFLOATERSIDETRAYTAB_H
+
+#include "llfloater.h"
+
+/**
+ * When a side tray tab gets detached, it's wrapped in an instance of this class.
+ *
+ * This class helps to make sure that clicking a detached side tray tab doesn't
+ * make transient floaters (e.g. IM windows) hide, so that it's possible to
+ * drag an inventory item from detached My Inventory window to a docked IM window,
+ * i.e. share the item (see VWR-22891).
+ */
+class LLFloaterSideTrayTab : public LLFloater
+{
+public:
+	LLFloaterSideTrayTab(const LLSD& key, const Params& params = getDefaultParams());
+	~LLFloaterSideTrayTab();
+};
+
+#endif // LL_LLFLOATERSIDETRAYTAB_H
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 85e45d012b5bcf9dfb7eef6b2fe165b835ff30b8..7546c070ea6070559d2a96611d897bc01b419a9b 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1175,8 +1175,8 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
 				}
 				else
 				{
-					if (!rd) llwarns << "Received role data for unkown role " << role_id << " in group " << group_id << llendl;
-					if (!md) llwarns << "Received role data for unkown member " << member_id << " in group " << group_id << llendl;
+					if (!rd) llwarns << "Received role data for unknown role " << role_id << " in group " << group_id << llendl;
+					if (!md) llwarns << "Received role data for unknown member " << member_id << " in group " << group_id << llendl;
 				}
 			}
 		}
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 5f7d1a2ffa933704fa52fa6ff80df7f8acbbd457..b3b0c93b9954c8389034eaf483c0d2fefa7cb528 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -168,7 +168,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 	LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, NULL);
 
 	setTitle(mSessionLabel);
-	mInputEditor->setMaxTextLength(1023);
+	mInputEditor->setMaxTextLength(DB_IM_MSG_STR_LEN);
 	// enable line history support for instant message bar
 	mInputEditor->setEnableLineHistory(TRUE);
 
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 78327a25fbb7341ff4b69d669b41229efb893b7d..07d13cf72950ba51302d3b640c1d0379a53ce5f0 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -28,19 +28,20 @@
 #include "llinventorybridge.h"
 
 // external projects
-#include "lltransfersourceasset.h"
+#include "lltransfersourceasset.h" 
 
 #include "llagent.h"
 #include "llagentcamera.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
-#include "llavataractions.h"
+#include "llattachmentsmgr.h"
+#include "llavataractions.h" 
 #include "llfloateropenobject.h"
 #include "llfloaterreg.h"
 #include "llfloaterworldmap.h"
 #include "llfriendcard.h"
 #include "llgesturemgr.h"
-#include "llgiveinventory.h"
+#include "llgiveinventory.h" 
 #include "llimfloater.h"
 #include "llimview.h"
 #include "llinventoryclipboard.h"
@@ -100,7 +101,7 @@ void dec_busy_count()
 void remove_inventory_category_from_avatar(LLInventoryCategory* category);
 void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);
 bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
-bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response);
+bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);
 void teleport_via_landmark(const LLUUID& asset_id);
 
 // +=================================================+
@@ -3978,22 +3979,22 @@ std::string LLObjectBridge::getLabelSuffix() const
 {
 	if (get_is_item_worn(mUUID))
 	{
-		if (!isAgentAvatarValid())
+		if (!isAgentAvatarValid()) // Error condition, can't figure out attach point
 		{
 			return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn");
 		}
-
 		std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID);
-
+		if (attachment_point_name == LLStringUtil::null) // Error condition, invalid attach point
+		{
+			attachment_point_name = "Invalid Attachment";
+		}
 		// e.g. "(worn on ...)" / "(attached to ...)"
 		LLStringUtil::format_map_t args;
 		args["[ATTACHMENT_POINT]"] =  LLTrans::getString(attachment_point_name);
+
 		return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args);
 	}
-	else
-	{
-		return LLItemBridge::getLabelSuffix();
-	}
+	return LLItemBridge::getLabelSuffix();
 }
 
 void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment, bool replace)
@@ -4024,19 +4025,15 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
 		}
 	}
 
-	if (!replace)
-	{
-		attach_pt |= ATTACHMENT_ADD;
-	}
-
 	LLSD payload;
 	payload["item_id"] = item_id; // Wear the base object in case this is a link.
 	payload["attachment_point"] = attach_pt;
+	payload["is_add"] = !replace;
 
 	if (replace &&
 		(attachment && attachment->getNumObjects() > 0))
 	{
-		LLNotificationsUtil::add("ReplaceAttachment", LLSD(), payload, confirm_replace_attachment_rez);
+		LLNotificationsUtil::add("ReplaceAttachment", LLSD(), payload, confirm_attachment_rez);
 	}
 	else
 	{
@@ -4044,7 +4041,7 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
 	}
 }
 
-bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response)
+bool confirm_attachment_rez(const LLSD& notification, const LLSD& response)
 {
 	if (!gAgentAvatarp->canAttachMoreObjects())
 	{
@@ -4062,27 +4059,41 @@ bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& respon
 
 		if (itemp)
 		{
+			/*
+			{
+				U8 attachment_pt = notification["payload"]["attachment_point"].asInteger();
+				
+				LLMessageSystem* msg = gMessageSystem;
+				msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
+				msg->nextBlockFast(_PREHASH_AgentData);
+				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+				msg->nextBlockFast(_PREHASH_ObjectData);
+				msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
+				msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
+				msg->addU8Fast(_PREHASH_AttachmentPt, attachment_pt);
+				pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
+				msg->addStringFast(_PREHASH_Name, itemp->getName());
+				msg->addStringFast(_PREHASH_Description, itemp->getDescription());
+				msg->sendReliable(gAgent.getRegion()->getHost());
+				return false;
+			}
+			*/
+
+			// Queue up attachments to be sent in next idle tick, this way the
+			// attachments are batched up all into one message versus each attachment
+			// being sent in its own separate attachments message.
 			U8 attachment_pt = notification["payload"]["attachment_point"].asInteger();
-			
+			BOOL is_add = notification["payload"]["is_add"].asBoolean();
 
-			LLMessageSystem* msg = gMessageSystem;
-			msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			msg->nextBlockFast(_PREHASH_ObjectData);
-			msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
-			msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
-			msg->addU8Fast(_PREHASH_AttachmentPt, attachment_pt);
-			pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
-			msg->addStringFast(_PREHASH_Name, itemp->getName());
-			msg->addStringFast(_PREHASH_Description, itemp->getDescription());
-			msg->sendReliable(gAgent.getRegion()->getHost());
+			LLAttachmentsMgr::instance().addAttachment(item_id,
+													   attachment_pt,
+													   is_add);
 		}
 	}
 	return false;
 }
-static LLNotificationFunctorRegistration confirm_replace_attachment_rez_reg("ReplaceAttachment", confirm_replace_attachment_rez);
+static LLNotificationFunctorRegistration confirm_replace_attachment_rez_reg("ReplaceAttachment", confirm_attachment_rez);
 
 void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 021790648d634abbe318c9f8a8c6ec01b07e2bcb..7216d61e7fc3197255b5be8d849aa5c53cfc68da 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -85,6 +85,8 @@ LLIconDictionary::LLIconDictionary()
 	addEntry(LLInventoryIcon::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem"));
 	addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkItem"));
 
+	addEntry(LLInventoryIcon::ICONNAME_INVALID, 				new IconEntry("Inv_Invalid"));
+
 	addEntry(LLInventoryIcon::ICONNAME_NONE, 					new IconEntry("NONE"));
 }
 
diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h
index 3c7ac7f6093652b1b73d9a187424bcade2969e0e..9a2cc080955577616c3c7f8b30f191a894a43e8c 100644
--- a/indra/newview/llinventoryicon.h
+++ b/indra/newview/llinventoryicon.h
@@ -73,8 +73,8 @@ public:
 		ICONNAME_LINKITEM,
 		ICONNAME_LINKFOLDER,
 
+		ICONNAME_INVALID,
 		ICONNAME_COUNT,
-
 		ICONNAME_NONE = -1
 	};
 
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 820520df9e2cbf40c2294d30903c6bfade102cf7..50adae09c0e81531dc3fb0463a5fedc9f0af29d9 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -916,6 +916,8 @@ BOOL is_inventorysp_active()
 // static
 LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
 {
+	S32 z_min = S32_MAX;
+	LLInventoryPanel* res = NULL;
 	// A. If the inventory side panel is open, use that preferably.
 	if (is_inventorysp_active())
 	{
@@ -925,11 +927,26 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
 			return inventorySP->getActivePanel();
 		}
 	}
+	// or if it is in floater undocked from sidetray get it and remember z order of floater to later compare it
+	// with other inventory floaters order.
+	else if (!LLSideTray::getInstance()->isTabAttached("sidebar_inventory"))
+	{
+		LLSidepanelInventory *inventorySP =
+			dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
+		LLFloater* inv_floater = LLFloaterReg::findInstance("side_bar_tab", LLSD("sidebar_inventory"));
+		if (inventorySP && inv_floater)
+		{
+			res = inventorySP->getActivePanel();
+			z_min = gFloaterView->getZOrder(inv_floater);
+		}
+		else
+		{
+			llwarns << "Inventory tab is detached from sidetray, but  either panel or floater were not found!" << llendl;
+		}
+	}
 	
 	// B. Iterate through the inventory floaters and return whichever is on top.
 	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
-	S32 z_min = S32_MAX;
-	LLInventoryPanel* res = NULL;
 	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
 	{
 		LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter);
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 5f71d7100b8f21d2e756730f73c15b8b1fff02b7..28aea7ae3d0ec2fac6f95d3dca9a02a570ce1aa4 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -115,7 +115,7 @@ void    LLNearbyChat::applySavedVariables()
 {
 	if (mRectControl.size() > 1)
 	{
-		const LLRect& rect = LLUI::sSettingGroups["floater"]->getRect(mRectControl);
+		const LLRect& rect = LLFloater::getControlGroup()->getRect(mRectControl);
 		if(!rect.isEmpty() && rect.isValid())
 		{
 			reshape(rect.getWidth(), rect.getHeight());
@@ -124,7 +124,7 @@ void    LLNearbyChat::applySavedVariables()
 	}
 
 
-	if(!LLUI::sSettingGroups["floater"]->controlExists(mDocStateControl))
+	if(!LLFloater::getControlGroup()->controlExists(mDocStateControl))
 	{
 		setDocked(true);
 	}
@@ -132,7 +132,7 @@ void    LLNearbyChat::applySavedVariables()
 	{
 		if (mDocStateControl.size() > 1)
 		{
-			bool dockState = LLUI::sSettingGroups["floater"]->getBOOL(mDocStateControl);
+			bool dockState = LLFloater::getControlGroup()->getBOOL(mDocStateControl);
 			setDocked(dockState);
 		}
 	}
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 43630c13fd7f9cf5fd2597166a95f0a8e64c26b7..a8e4a759b7a3f1ac1a2e5ee4544c789c038e12bc 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -103,10 +103,10 @@ LLGestureComboList::LLGestureComboList(const LLGestureComboList::Params& p)
 	, mViewAllItemIndex(0)
 	, mGetMoreItemIndex(0)
 {
-	LLButton::Params button_params = p.combo_button;
+	LLBottomtrayButton::Params button_params = p.combo_button;
 	button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT);
 
-	mButton = LLUICtrlFactory::create<LLButton>(button_params);
+	mButton = LLUICtrlFactory::create<LLBottomtrayButton>(button_params);
 	mButton->reshape(getRect().getWidth(),getRect().getHeight());
 	mButton->setCommitCallback(boost::bind(&LLGestureComboList::onButtonCommit, this));
 
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 955a665624b40f1a8aaaec330072a85c06d4bfe7..cc905736fd315ebe9f6ad479752137845618228e 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -34,6 +34,7 @@
 #include "llvoiceclient.h"
 #include "lloutputmonitorctrl.h"
 #include "llspeakers.h"
+#include "llbottomtray.h"
 
 
 class LLGestureComboList
@@ -43,7 +44,7 @@ class LLGestureComboList
 public:
 	struct Params :	public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
-		Optional<LLButton::Params>			combo_button;
+		Optional<LLBottomtrayButton::Params>			combo_button;
 		Optional<LLScrollListCtrl::Params>	combo_list;
 		
 		Params();
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index b5683296ebf6c73e047357a20dcc60229ee6c38c..4231a73af1b977479e26c80e796c150bd2247160 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -353,7 +353,7 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
 	if (!gAgent.getGroupData(payload["group_id"].asUUID(), groupData))
 	{
 		llwarns
-						<< "Group notice for unkown group: "
+						<< "Group notice for unknown group: "
 								<< payload["group_id"].asUUID() << llendl;
 		return;
 	}
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 51f9a03a9cff99e08126948b70ebb18a0da5a1b4..cf0b3d94bda01291026dea34d034e7a10c5cca19 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -439,6 +439,7 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
 
 		static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode();
 		LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL);
+		if (!tab) continue;
 
 		tab->setName(name);
 		tab->setTitle(name);
@@ -455,10 +456,7 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
 			mAccordion->removeCollapsibleCtrl(tab);
 
 			// kill removed tab
-			if (tab != NULL)
-			{
-				tab->die();
-			}
+			tab->die();
 			continue;
 		}
 
@@ -974,23 +972,6 @@ void LLOutfitsList::applyFilterToTab(
 	}
 }
 
-bool LLOutfitsList::canTakeOffSelected()
-{
-	uuid_vec_t selected_uuids;
-	getSelectedItemsUUIDs(selected_uuids);
-
-	LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false);
-
-	for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it)
-	{
-		LLViewerInventoryItem* item = gInventory.getItem(*it);
-		if (!item) continue;
-
-		if (is_worn(NULL, item)) return true;
-	}
-	return false;
-}
-
 bool LLOutfitsList::canWearSelected()
 {
 	uuid_vec_t selected_items;
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index 37b909c93e191fbebd7bb093b3e6552c0c20d936..faf6f7ce1e34c9b6d457758ce7665feec9a6d6c2 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -98,7 +98,7 @@ public:
 
 	const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; }
 
-	void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const;
+	/*virtual*/ void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const;
 
 	boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb);
 
@@ -173,11 +173,6 @@ private:
 	 */
 	void applyFilterToTab(const LLUUID& category_id, LLAccordionCtrlTab* tab, const std::string& filter_substring);
 
-	/**
-	 * Returns true if there are any items that can be taken off among currently selected, otherwise false.
-	 */
-	bool canTakeOffSelected();
-
 	/**
 	 * Returns true if all selected items can be worn.
 	 */
diff --git a/indra/newview/llpanelappearancetab.cpp b/indra/newview/llpanelappearancetab.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9910a3a2ac476458b34bed02c51806fed38a398f
--- /dev/null
+++ b/indra/newview/llpanelappearancetab.cpp
@@ -0,0 +1,51 @@
+/**
+ * @file llpanelappearancetab.h
+ * @brief Tabs interface for Side Bar "My Appearance" panel
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelappearancetab.h"
+
+
+#include "llinventoryfunctions.h"
+#include "llinventorymodel.h"
+
+//virtual
+bool LLPanelAppearanceTab::canTakeOffSelected()
+{
+	uuid_vec_t selected_uuids;
+	getSelectedItemsUUIDs(selected_uuids);
+
+	LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false);
+
+	for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it)
+	{
+		LLViewerInventoryItem* item = gInventory.getItem(*it);
+		if (!item) continue;
+
+		if (is_worn(NULL, item)) return true;
+	}
+	return false;
+}
diff --git a/indra/newview/llpanelappearancetab.h b/indra/newview/llpanelappearancetab.h
index fa929aac0a5fd7f4d2273c50e413813c631886fc..81366c5db4a26cc6b97595672fd9c4ca8393110d 100644
--- a/indra/newview/llpanelappearancetab.h
+++ b/indra/newview/llpanelappearancetab.h
@@ -41,9 +41,17 @@ public:
 
 	virtual void showGearMenu(LLView* spawning_view) = 0;
 
+	virtual void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const {}
+
 	static const std::string& getFilterSubString() { return sFilterSubString; }
 
 protected:
+
+	/**
+	 * Returns true if there are any items that can be taken off among currently selected, otherwise false.
+	 */
+	bool canTakeOffSelected();
+
 	static std::string		sFilterSubString;
 };
 
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index e42057e93ac7ffe8833444b091a36a8d4ada34cf..62ed7acb1519416407a8753d1bc9a956276943cf 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -112,6 +112,7 @@ void LLPanelGroup::onOpen(const LLSD& key)
 	if(!key.has("action"))
 	{
 		setGroupID(group_id);
+		getChild<LLAccordionCtrl>("groups_accordion")->expandDefaultTab();
 		return;
 	}
 
@@ -176,11 +177,6 @@ BOOL LLPanelGroup::postBuild()
 	LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");
 	LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel");
 
-	if (LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("groups_accordion"))
-	{
-		setVisibleCallback(boost::bind(&LLPanelGroup::onVisibilityChange, this, _2, accordion_ctrl));
-	}
-
 	if(panel_general)	mTabs.push_back(panel_general);
 	if(panel_roles)		mTabs.push_back(panel_roles);
 	if(panel_notices)	mTabs.push_back(panel_notices);
@@ -304,14 +300,6 @@ void LLPanelGroup::onBtnCancel()
 	onBackBtnClick();
 }
 
-void LLPanelGroup::onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl)
-{
-	if (in_visible_chain.asBoolean() && accordion_ctrl != NULL)
-	{
-		accordion_ctrl->expandDefaultTab();
-	}
-}
-
 void LLPanelGroup::changed(LLGroupChange gc)
 {
 	for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 86875d2da3743b521487f119a17f298f6b9ad82d..b494c7d403deb7e633aa347abc485e255bb75439 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -36,7 +36,6 @@ class LLOfferInfo;
 const S32 UPDATE_MEMBERS_PER_FRAME = 500;
 
 // Forward declares
-class LLAccordionCtrl;
 class LLPanelGroupTab;
 class LLTabContainer;
 class LLAgent;
@@ -97,7 +96,6 @@ protected:
 	void onBackBtnClick();
 	void onBtnJoin();
 	void onBtnCancel();
-	void onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl);
 
 	static void onBtnApply(void*);
 	static void onBtnRefresh(void*);
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 06ba08b51c9ca4b90a8cca81a50aa767552e2ba7..d096b17145a64a6f7a1d8bdc6187e6adb7a81eb2 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -522,8 +522,10 @@ BOOL LLPanelPeople::postBuild()
 	mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all");
 	mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));
 	mOnlineFriendList->setShowIcons("FriendsListShowIcons");
+	mOnlineFriendList->showPermissions("FriendsListShowPermissions");
 	mAllFriendList->setNoItemsCommentText(getString("no_friends"));
 	mAllFriendList->setShowIcons("FriendsListShowIcons");
+	mAllFriendList->showPermissions("FriendsListShowPermissions");
 
 	LLPanel* nearby_tab = getChild<LLPanel>(NEARBY_TAB_NAME);
 	nearby_tab->setVisibleCallback(boost::bind(&Updater::setActive, mNearbyListUpdater, _2));
@@ -1205,6 +1207,14 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata)
 		mAllFriendList->toggleIcons();
 		mOnlineFriendList->toggleIcons();
 	}
+	else if (chosen_item == "view_permissions")
+	{
+		bool show_permissions = !gSavedSettings.getBOOL("FriendsListShowPermissions");
+		gSavedSettings.setBOOL("FriendsListShowPermissions", show_permissions);
+
+		mAllFriendList->showPermissions(show_permissions);
+		mOnlineFriendList->showPermissions(show_permissions);
+	}
 }
 
 void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata)
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index a6bc34c62e69e7df3d999663fc74fc369f1c8001..860470cd73ee55829c3bd19b96b1a98531191677 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -29,6 +29,7 @@
 #include "llpanelwearing.h"
 
 #include "llappearancemgr.h"
+#include "llinventoryfunctions.h"
 #include "llinventorymodel.h"
 #include "llinventoryobserver.h"
 #include "llsidetray.h"
@@ -46,12 +47,16 @@ static void edit_outfit()
 class LLWearingGearMenu
 {
 public:
-	LLWearingGearMenu()
-	:	mMenu(NULL)
+	LLWearingGearMenu(LLPanelWearing* panel_wearing)
+	:	mMenu(NULL), mPanelWearing(panel_wearing)
 	{
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
 
 		registrar.add("Gear.Edit", boost::bind(&edit_outfit));
+		registrar.add("Gear.TakeOff", boost::bind(&LLWearingGearMenu::onTakeOff, this));
+
+		enable_registrar.add("Gear.OnEnable", boost::bind(&LLPanelWearing::isActionEnabled, mPanelWearing, _2));
 
 		mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
 			"menu_wearing_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
@@ -70,7 +75,20 @@ public:
 	}
 
 private:
+
+	void onTakeOff()
+	{
+		uuid_vec_t selected_uuids;
+		mPanelWearing->getSelectedItemsUUIDs(selected_uuids);
+
+		for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it)
+		{
+				LLAppearanceMgr::instance().removeItemFromAvatar(*it);
+		}
+	}
+
 	LLMenuGL*		mMenu;
+	LLPanelWearing* mPanelWearing;
 };
 
 //////////////////////////////////////////////////////////////////////////
@@ -150,7 +168,7 @@ LLPanelWearing::LLPanelWearing()
 {
 	mCategoriesObserver = new LLInventoryCategoriesObserver();
 
-	mGearMenu = new LLWearingGearMenu();
+	mGearMenu = new LLWearingGearMenu(this);
 	mContextMenu = new LLWearingContextMenu();
 }
 
@@ -226,6 +244,12 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata)
 		// allow save only if outfit isn't locked and is dirty
 		return !outfit_locked && outfit_dirty;
 	}
+
+	if (command_name == "take_off")
+	{
+		return hasItemSelected() && canTakeOffSelected();
+	}
+
 	return false;
 }
 
@@ -255,4 +279,14 @@ void LLPanelWearing::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
 	mContextMenu->show(ctrl, selected_uuids, x, y);
 }
 
+bool LLPanelWearing::hasItemSelected()
+{
+	return mCOFItemsList->getSelectedItem() != NULL;
+}
+
+void LLPanelWearing::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const
+{
+	mCOFItemsList->getSelectedUUIDs(selected_uuids);
+}
+
 // EOF
diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h
index 6ae8efef99d471cd7719ff852e62a63a7f085fc1..1fa97735b1b6d35e491db0fba7df2d0ad354fd95 100644
--- a/indra/newview/llpanelwearing.h
+++ b/indra/newview/llpanelwearing.h
@@ -60,8 +60,12 @@ public:
 
 	/*virtual*/ void showGearMenu(LLView* spawning_view);
 
+	/*virtual*/ void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const;
+
 	boost::signals2::connection setSelectionChangeCallback(commit_callback_t cb);
 
+	bool hasItemSelected();
+
 private:
 	void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
 
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 7af3ad9896df80a923313645db64e975507336f3..88e37b815f67556bc14e01c9ebf7cd02c9562843 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -244,9 +244,7 @@ void LLSideTrayTab::toggleTabDocked()
 	LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", tab_name);
 	if (!floater_tab) return;
 
-	LLFloaterReg::toggleInstance("side_bar_tab", tab_name);
-
-	bool docking = !LLFloater::isShown(floater_tab);
+	bool docking = LLFloater::isShown(floater_tab);
 
 	// Hide the "Tear Off" button when a tab gets undocked
 	// and show "Dock" button instead.
@@ -261,6 +259,10 @@ void LLSideTrayTab::toggleTabDocked()
 	{
 		undock(floater_tab);
 	}
+
+	// Open/close the floater *after* we reparent the tab panel,
+	// so that it doesn't receive redundant visibility change notifications.
+	LLFloaterReg::toggleInstance("side_bar_tab", tab_name);
 }
 
 void LLSideTrayTab::dock()
@@ -282,7 +284,7 @@ void LLSideTrayTab::dock()
 
 	if (side_tray->getCollapsed())
 	{
-		side_tray->expandSideBar();
+		side_tray->expandSideBar(false);
 	}
 }
 
@@ -291,6 +293,10 @@ void LLSideTrayTab::undock(LLFloater* floater_tab)
 	LLSideTray* side_tray = getSideTray();
 	if (!side_tray) return;
 
+	// Remember whether the tab have been active before detaching
+	// because removeTab() will change active tab.
+	bool was_active = side_tray->getActiveTab() == this;
+
 	// Remove the tab from Side Tray's tabs list.
 	// We have to do it despite removing the tab from Side Tray's child view tree
 	// by addChild(). Otherwise the tab could be accessed by the pointer in LLSideTray::mTabs.
@@ -300,9 +306,15 @@ void LLSideTrayTab::undock(LLFloater* floater_tab)
 		return;
 	}
 
-	setVisible(true); // *HACK: restore visibility after being hidden by LLSideTray::selectTabByName().
+	// If we're undocking while side tray is collapsed we need to explicitly show the panel.
+	if (!getVisible())
+	{
+		setVisible(true);
+	}
+
 	floater_tab->addChild(this);
 	floater_tab->setTitle(mTabTitle);
+	floater_tab->setName(getName());
 
 	// Reshape the floater if needed.
 	LLRect floater_rect;
@@ -334,7 +346,7 @@ void LLSideTrayTab::undock(LLFloater* floater_tab)
 		side_tray->collapseSideBar();
 	}
 
-	if (side_tray->getActiveTab() != this)
+	if (!was_active)
 	{
 		// When a tab other then current active tab is detached from Side Tray
 		// onOpen() should be called as tab visibility is changed.
@@ -618,8 +630,9 @@ bool LLSideTray::selectTabByIndex(size_t index)
 	return selectTabByName(sidebar_tab->getName());
 }
 
-bool LLSideTray::selectTabByName	(const std::string& name)
+bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible)
 {
+	LLSideTrayTab* tab_to_keep_visible = NULL;
 	LLSideTrayTab* new_tab = getTab(name);
 	if (!new_tab) return false;
 
@@ -630,6 +643,8 @@ bool LLSideTray::selectTabByName	(const std::string& name)
 	//deselect old tab
 	if (mActiveTab)
 	{
+		// Keep previously active tab visible if requested.
+		if (keep_prev_visible) tab_to_keep_visible = mActiveTab;
 		toggleTabButton(mActiveTab);
 	}
 
@@ -650,9 +665,17 @@ bool LLSideTray::selectTabByName	(const std::string& name)
 	for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
 	{
 		LLSideTrayTab* sidebar_tab = *child_it;
+
+		bool vis = sidebar_tab == mActiveTab;
+
+		// Force keeping the tab visible if requested.
+		vis |= sidebar_tab == tab_to_keep_visible;
+
 		// When the last tab gets detached, for a short moment the "Toggle Sidebar" pseudo-tab
 		// is shown. So, to avoid the flicker we make sure it never gets visible.
-		sidebar_tab->setVisible(sidebar_tab == mActiveTab && (*child_it)->getName() != "sidebar_openclose");
+		vis &= (*child_it)->getName() != "sidebar_openclose";
+
+		sidebar_tab->setVisible(vis);
 	}
 	return true;
 }
@@ -741,7 +764,7 @@ bool LLSideTray::removeTab(LLSideTrayTab* tab)
 	{
 		child_vector_iter_t next_tab_it =
 				(tab_it < (mTabs.end() - 1)) ? tab_it + 1 : mTabs.begin();
-		selectTabByName((*next_tab_it)->getName());
+		selectTabByName((*next_tab_it)->getName(), true); // Don't hide the tab being removed.
 	}
 
 	// Remove the tab.
@@ -976,9 +999,9 @@ void LLSideTray::detachTabs()
 
 		std::string floater_ctrl_name = LLFloater::getControlName("side_bar_tab", LLSD(tab->getName()));
 		std::string vis_ctrl_name = LLFloaterReg::getVisibilityControlName(floater_ctrl_name);
-		if (!LLUI::sSettingGroups["floater"]->controlExists(vis_ctrl_name)) continue;
+		if (!LLFloater::getControlGroup()->controlExists(vis_ctrl_name)) continue;
 
-		bool is_visible = LLUI::sSettingGroups["floater"]->getBOOL(vis_ctrl_name);
+		bool is_visible = LLFloater::getControlGroup()->getBOOL(vis_ctrl_name);
 		if (!is_visible) continue;
 
 		llassert(isTabAttached(tab->getName()));
@@ -1016,7 +1039,7 @@ void LLSideTray::collapseSideBar()
 	setFocus( FALSE );
 }
 
-void LLSideTray::expandSideBar()
+void LLSideTray::expandSideBar(bool open_active)
 {
 	mCollapsed = false;
 	LLSideTrayTab* openclose_tab = getTab("sidebar_openclose");
@@ -1024,8 +1047,11 @@ void LLSideTray::expandSideBar()
 	{
 		mCollapseButton->setImageOverlay( openclose_tab->mImageSelected );
 	}
-	LLSD key;//empty
-	mActiveTab->onOpen(key);
+
+	if (open_active)
+	{
+		mActiveTab->onOpen(LLSD());
+	}
 
 	reflectCollapseChange();
 
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index 248def8e3d506a7eb395734d66d413b4002329e8..4e79007c13d624454348e43d3f8394664a5154ba 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -76,9 +76,12 @@ public:
 	// interface functions
 	    
 	/**
-     * Select tab with specific name and set it active    
-     */
-	bool 		selectTabByName	(const std::string& name);
+	 * Select tab with specific name and set it active
+	 *
+	 * @param name				Tab to switch to.
+	 * @param keep_prev_visible	Whether to keep the previously selected tab visible.
+	 */
+	bool 		selectTabByName	(const std::string& name, bool keep_prev_visible = false);
 	
 	/**
      * Select tab with specific index and set it active    
@@ -119,8 +122,10 @@ public:
     
 	/*
      * expand SideBar
+     *
+     * @param open_active Whether to call onOpen() for the active tab.
      */
-	void		expandSideBar	();
+	void		expandSideBar(bool open_active = true);
 
 
 	/**
diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp
index b8838346d06a7e265bb80b333dbf80a8c436c60d..3dce66f394d49fef75b17a0e77188d710c656052 100644
--- a/indra/newview/llspeakbutton.cpp
+++ b/indra/newview/llspeakbutton.cpp
@@ -37,6 +37,8 @@
 
 #include "llspeakbutton.h"
 
+#include "llbottomtray.h"
+
 static LLDefaultChildRegistry::Register<LLSpeakButton> t1("talk_button");
 
 //////////////////////////////////////////////////////////////////////////
@@ -67,7 +69,7 @@ void LLSpeakButton::setSpeakBtnEnabled(bool enabled)
 }
 void LLSpeakButton::setFlyoutBtnEnabled(bool enabled)
 {
-	LLButton* show_btn = getChild<LLButton>("speak_flyout_btn");
+	LLButton* show_btn = getChild<LLBottomtrayButton>("speak_flyout_btn");
 	show_btn->setEnabled(enabled);
 }
 
@@ -96,9 +98,9 @@ LLSpeakButton::LLSpeakButton(const Params& p)
 	mSpeakBtn->setMouseUpCallback(boost::bind(&LLSpeakButton::onMouseUp_SpeakBtn, this));
 	mSpeakBtn->setToggleState(FALSE);
 
-	LLButton::Params show_params = p.show_button;
+	LLBottomtrayButton::Params show_params = p.show_button;
 	show_params.rect(show_rect);
-	mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
+	mShowBtn = LLUICtrlFactory::create<LLBottomtrayButton>(show_params);
 	addChild(mShowBtn);
 	LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn);
 
diff --git a/indra/newview/llspeakbutton.h b/indra/newview/llspeakbutton.h
index ec1d07b6338470b82d609a4dc61a120dbeadd731..2fdf80c1f2fe91257172b1bc8b11d10e237c4dc5 100644
--- a/indra/newview/llspeakbutton.h
+++ b/indra/newview/llspeakbutton.h
@@ -33,6 +33,7 @@
 class LLCallFloater;
 class LLButton;
 class LLOutputMonitorCtrl;
+class LLBottomtrayButton;
 
 /*
  * Button displaying voice chat status. Displays voice chat options when
@@ -44,10 +45,8 @@ public:
 
 	struct Params :	public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
-		Optional<LLButton::Params>
-			speak_button,
-			show_button;
-
+		Optional<LLButton::Params> speak_button;
+		Optional<LLBottomtrayButton::Params> show_button;
 		Optional<LLOutputMonitorCtrl::Params> monitor;
 
 		Params();
@@ -86,7 +85,7 @@ protected:
 
 private:
 	LLButton*	mSpeakBtn;
-	LLButton*	mShowBtn;
+	LLBottomtrayButton*	mShowBtn;
 	LLHandle<LLFloater> mPrivateCallPanel;
 	LLOutputMonitorCtrl* mOutputMonitor;
 };
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 2fd0a22f809d056d3a261bc3e1af031b2f688255..6a213309a0bff583ceb3b205df5fd4189ee01b40 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -927,7 +927,7 @@ void LLTextureCache::setReadOnly(BOOL read_only)
 }
 
 //called in the main thread.
-S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL disable_texture_cache)
+S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache_mismatch)
 {
 	llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
 
@@ -942,20 +942,23 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL disable_textu
 		sCacheMaxTexturesSize = max_size;
 	max_size -= sCacheMaxTexturesSize;
 	
-	if(disable_texture_cache) //the texture cache is disabled
-	{
-		llinfos << "The texture cache is disabled!" << llendl ;
-		setReadOnly(TRUE) ;
-		purgeAllTextures(true); 
-
-		return max_size ;
-	}
-
 	LL_INFOS("TextureCache") << "Headers: " << sCacheMaxEntries
 			<< " Textures size: " << sCacheMaxTexturesSize/(1024*1024) << " MB" << LL_ENDL;
 
 	setDirNames(location);
 	
+	if(texture_cache_mismatch) 
+	{
+		//if readonly, disable the texture cache,
+		//otherwise wipe out the texture cache.
+		purgeAllTextures(true); 
+
+		if(mReadOnly)
+		{
+			return max_size ;
+		}
+	}
+	
 	if (!mReadOnly)
 	{
 		LLFile::mkdir(mTexturesDirName);
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 7f1bba56fb9335ffaf140441443f9acacffc5b44..64e3a2658c38565f1b8f32253fdb50621ed90773 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -105,7 +105,7 @@ public:
 	
 	void purgeCache(ELLPath location);
 	void setReadOnly(BOOL read_only) ;
-	S64 initCache(ELLPath location, S64 maxsize, BOOL disable_texture_cache);
+	S64 initCache(ELLPath location, S64 maxsize, BOOL texture_cache_mismatch);
 
 	handle_t readFromCache(const std::string& local_filename, const LLUUID& id, U32 priority, S32 offset, S32 size,
 						   ReadResponder* responder);
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 6a75e4b00998fd696f17dc0eb29c241158b6aad4..c87aff022fcee4d572818b5aa9d8b7b92009033d 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -48,6 +48,7 @@
 #include "llviewertexture.h"
 #include "llviewertexturelist.h"
 #include "llvovolume.h"
+#include "llviewerstats.h"
 
 // For avatar texture view
 #include "llvoavatarself.h"
@@ -513,6 +514,7 @@ void LLGLTexMemBar::draw()
 	F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
 	S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
 	S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
+	S32 total_downloaded = BYTES_TO_MEGA_BYTES(gTotalTextureBytes);
 	//----------------------------------------------------------------------------
 	LLGLSUIDefault gls_ui;
 	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
@@ -523,13 +525,13 @@ void LLGLTexMemBar::draw()
 	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
 											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
 
-	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
+	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot: %d MB",
 					total_mem,
 					max_total_mem,
 					bound_mem,
 					max_bound_mem,
-					LLImageRaw::sGlobalRawMemory >> 20,					discard_bias,
-					cache_usage, cache_max_usage);
+					LLImageRaw::sGlobalRawMemory >> 20,	discard_bias,
+					cache_usage, cache_max_usage, total_downloaded);
 	//, cache_entries, cache_max_entries
 
 	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index ca6efa9d2fe484bb8815868d79cc3354466e221c..1a1c94674b60937c5ceaa4c3104e96a1dc640304 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -51,7 +51,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
 
 LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
 
-LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect) : 
+LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect, bool show_images) : 
 LLToastPanel(notification),
 mTextBox(NULL),
 mInfoPanel(NULL),
@@ -120,6 +120,7 @@ mCloseNotificationOnDestroy(true)
 
 	mTextBox->setMaxTextLength(MAX_LENGTH);
 	mTextBox->setVisible(TRUE);
+	mTextBox->setPlainText(!show_images);
 	mTextBox->setValue(notification->getMessage());
 
 	// add buttons for a script notification
@@ -523,8 +524,9 @@ void LLToastNotifyPanel::disableRespondedOptions(LLNotificationPtr& notification
 
 //////////////////////////////////////////////////////////////////////////
 
-LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */)
- : mSessionID(session_id), LLToastNotifyPanel(pNotification, rect)
+LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */,
+										   bool show_images /* = true */)
+ : mSessionID(session_id), LLToastNotifyPanel(pNotification, rect, show_images)
 {
 	mTextBox->setFollowsAll();
 }
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
index 9e1eac90b36ba86b096e7aebcb13d4747e9566d7..57711b3d80f1a8f9850465481cbca5a42b9be4cb 100644
--- a/indra/newview/lltoastnotifypanel.h
+++ b/indra/newview/lltoastnotifypanel.h
@@ -60,7 +60,7 @@ public:
 	 * @deprecated if you intend to instantiate LLToastNotifyPanel - it's point to
 	 * implement right class for desired toast panel. @see LLGenericTipPanel as example.
 	 */
-	LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null);
+	LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true);
 	virtual ~LLToastNotifyPanel();
 	LLPanel * getControlPanel() { return mControlPanel; }
 
@@ -137,7 +137,7 @@ class LLIMToastNotifyPanel : public LLToastNotifyPanel
 {
 public:
 
-	LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect = LLRect::null);
+	LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect = LLRect::null, bool show_images = true);
 
 	~LLIMToastNotifyPanel();
 
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index d8be70e54698b36ca8b3e7a438609811742aa33d..864de018e0234211bd1f1047e11215525ce97f34 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -619,6 +619,25 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
 			return TRUE;
 		}
 	}
+	else if (gSavedSettings.getBOOL("DoubleClickTeleport"))
+	{
+		LLViewerObject* objp = mPick.getObject();
+		LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL;
+
+		bool is_in_world = mPick.mObjectID.notNull() && objp && !objp->isHUDAttachment();
+		bool is_land = mPick.mPickType == LLPickInfo::PICK_LAND;
+		bool pos_non_zero = !mPick.mPosGlobal.isExactlyZero();
+		bool has_touch_handler = (objp && objp->flagHandleTouch()) || (parentp && parentp->flagHandleTouch());
+		bool has_click_action = final_click_action(objp);
+
+		if (pos_non_zero && (is_land || (is_in_world && !has_touch_handler && !has_click_action)))
+		{
+			LLVector3d pos = mPick.mPosGlobal;
+			pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot();
+			gAgent.teleportViaLocationLookAt(pos);
+			return TRUE;
+		}
+	}
 
 	return FALSE;
 }
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..050e34ade9ab137afb56fc864a8e437591998e7c
--- /dev/null
+++ b/indra/newview/lltranslate.cpp
@@ -0,0 +1,123 @@
+/**
+* @file lltranslate.cpp
+* @brief Functions for translating text via Google Translate.
+*
+* $LicenseInfo:firstyear=2009&license=viewergpl$
+*
+* Copyright (c) 2009-2010, 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 "lltranslate.h"
+
+#include "llbufferstream.h"
+#include "llui.h"
+#include "llversionviewer.h"
+#include "llviewercontrol.h"
+
+#include "jsoncpp/reader.h"
+
+// These two are concatenated with the language specifiers to form a complete Google Translate URL
+const char* LLTranslate::m_GoogleURL = "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=";
+const char* LLTranslate::m_GoogleLangSpec = "&langpair=";
+float LLTranslate::m_GoogleTimeout = 5;
+
+LLSD LLTranslate::m_Header;
+// These constants are for the GET header.
+const char* LLTranslate::m_AcceptHeader = "Accept";
+const char* LLTranslate::m_AcceptType = "text/plain";
+const char* LLTranslate::m_AgentHeader = "User-Agent";
+
+// These constants are in the JSON returned from Google
+const char* LLTranslate::m_GoogleData = "responseData";
+const char* LLTranslate::m_GoogleTranslation = "translatedText";
+const char* LLTranslate::m_GoogleLanguage = "detectedSourceLanguage";
+
+//static
+void LLTranslate::translateMessage(LLHTTPClient::ResponderPtr &result, const std::string &from_lang, const std::string &to_lang, const std::string &mesg)
+{
+	std::string url;
+	getTranslateUrl(url, from_lang, to_lang, mesg);
+
+    std::string user_agent = llformat("%s %d.%d.%d (%d)",
+		LL_CHANNEL,
+		LL_VERSION_MAJOR,
+		LL_VERSION_MINOR,
+		LL_VERSION_PATCH,
+		LL_VERSION_BUILD );
+
+	if (!m_Header.size())
+	{
+		m_Header.insert(m_AcceptHeader, LLSD(m_AcceptType));
+		m_Header.insert(m_AgentHeader, LLSD(user_agent));
+	}
+
+	LLHTTPClient::get(url, result, m_Header, m_GoogleTimeout);
+}
+
+//static
+void LLTranslate::getTranslateUrl(std::string &translate_url, const std::string &from_lang, const std::string &to_lang, const std::string &mesg)
+{
+	std::string escaped_mesg = curl_escape(mesg.c_str(), mesg.size());
+
+	translate_url = m_GoogleURL
+		+ escaped_mesg + m_GoogleLangSpec
+		+ from_lang // 'from' language; empty string for auto
+		+ "%7C" // |
+		+ to_lang; // 'to' language
+}
+
+//static
+bool LLTranslate::parseGoogleTranslate(const std::string& body, std::string &translation, std::string &detected_language)
+{
+	Json::Value root;
+	Json::Reader reader;
+	
+	bool success = reader.parse(body, root);
+	if (!success)
+	{
+		LL_WARNS("Translate") << "Non valid response from Google Translate API: '" << reader.getFormatedErrorMessages() << "'" << LL_ENDL;
+		return false;
+	}
+	
+	translation = 			root[m_GoogleData].get(m_GoogleTranslation, "").asString();
+	detected_language = 	root[m_GoogleData].get(m_GoogleLanguage, "").asString();
+	return true;
+}
+
+//static
+std::string LLTranslate::getTranslateLanguage()
+{
+	std::string language = gSavedSettings.getString("TranslateLanguage");
+	if (language.empty() || language == "default")
+	{
+		language = LLUI::getLanguage();
+	}
+	language = language.substr(0,2);
+	return language;
+}
+
diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h
new file mode 100644
index 0000000000000000000000000000000000000000..0786dc0ca3d74a5ac49dff7a376814c8d4f7e19f
--- /dev/null
+++ b/indra/newview/lltranslate.h
@@ -0,0 +1,124 @@
+/**
+* @file lltranslate.h
+* @brief Human language translation class and JSON response receiver.
+*
+* $LicenseInfo:firstyear=2009&license=viewergpl$
+*
+* Copyright (c) 2009-2010, 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_LLTRANSLATE_H
+#define LL_LLTRANSLATE_H
+
+#include "llhttpclient.h"
+#include "llbufferstream.h"
+
+class LLTranslate
+{
+	LOG_CLASS(LLTranslate);
+public :
+	class TranslationReceiver: public LLHTTPClient::Responder
+	{
+	protected:
+		TranslationReceiver(const std::string &from_lang, const std::string &to_lang)
+			: m_fromLang(from_lang),
+			m_toLang(to_lang)
+		{
+		}
+
+		virtual void handleResponse(const std::string &translation, const std::string &recognized_lang) {};
+		virtual void handleFailure() {};
+
+	public:
+		~TranslationReceiver()
+		{
+		}
+
+		virtual void completedRaw(	U32 status,
+									const std::string& reason,
+									const LLChannelDescriptors& channels,
+									const LLIOPipe::buffer_ptr_t& buffer)
+		{
+			if (200 <= status && status < 300)
+			{
+				LLBufferStream istr(channels, buffer.get());
+				std::stringstream strstrm;
+				strstrm << istr.rdbuf();
+
+				const std::string result = strstrm.str();
+				std::string translation;
+				std::string detected_language;
+
+				if (!parseGoogleTranslate(result, translation, detected_language))
+				{
+					handleFailure();
+					return;
+				}
+				
+				// Fix up the response
+				LLStringUtil::replaceString(translation, "&lt;", "<");
+				LLStringUtil::replaceString(translation, "&gt;",">");
+				LLStringUtil::replaceString(translation, "&quot;","\"");
+				LLStringUtil::replaceString(translation, "&#39;","'");
+				LLStringUtil::replaceString(translation, "&amp;","&");
+				LLStringUtil::replaceString(translation, "&apos;","'");
+
+				handleResponse(translation, detected_language);
+			}
+			else
+			{
+				LL_WARNS("Translate") << "HTTP request for Google Translate failed with status " << status << ", reason: " << reason << LL_ENDL;
+				handleFailure();
+			}
+		}
+
+	protected:
+		const std::string m_toLang;
+		const std::string m_fromLang;
+	};
+
+	static void translateMessage(LLHTTPClient::ResponderPtr &result, const std::string &from_lang, const std::string &to_lang, const std::string &mesg);
+	static float m_GoogleTimeout;
+	static std::string getTranslateLanguage();
+
+private:
+	static void getTranslateUrl(std::string &translate_url, const std::string &from_lang, const std::string &to_lang, const std::string &text);
+	static bool parseGoogleTranslate(const std::string& body, std::string &translation, std::string &detected_language);
+
+	static LLSD m_Header;
+	static const char* m_GoogleURL;
+	static const char* m_GoogleLangSpec;
+	static const char* m_AcceptHeader;
+	static const char* m_AcceptType;
+	static const char* m_AgentHeader;
+	static const char* m_UserAgent;
+
+	static const char* m_GoogleData;
+	static const char* m_GoogleTranslation;
+	static const char* m_GoogleLanguage;
+};
+
+#endif
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index d0ad918c58b05dd954e791a5c21b54e36c0f74a1..916cbe226774b842ebbd803aa33b431263df062f 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -85,6 +85,7 @@ LLPointer<LLViewerTexture> gDisconnectedImagep = NULL;
 // used to toggle renderer back on after teleport
 const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain
 const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
+const F32 TELEPORT_LOCAL_DELAY = 1.0f;  // Delay to prevent teleports after starting an in-sim teleport.
 BOOL		 gTeleportDisplay = FALSE;
 LLFrameTimer gTeleportDisplayTimer;
 LLFrameTimer gTeleportArrivalTimer;
@@ -406,6 +407,18 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			}
 			break;
 
+		case LLAgent::TELEPORT_LOCAL:
+			// Short delay when teleporting in the same sim (progress screen active but not shown - did not
+			// fall-through from TELEPORT_START)
+			{
+				if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY )
+				{
+					//LLFirstUse::useTeleport();
+					gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
+				}
+			}
+			break;
+
 		case LLAgent::TELEPORT_NONE:
 			// No teleport in progress
 			gViewerWindow->setShowProgress(FALSE);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 87282985751572617025722faa36479c19d26ac2..b6f2d34663ba1ab5b600c45750718b8e502750b6 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -86,6 +86,7 @@
 #include "llfloaterscriptlimits.h"
 #include "llfloatersellland.h"
 #include "llfloatersettingsdebug.h"
+#include "llfloatersidetraytab.h"
 #include "llfloatersnapshot.h"
 #include "llfloatertelehub.h"
 #include "llfloatertestinspectors.h"
@@ -234,7 +235,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("script_limits", "floater_script_limits.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptLimits>);
 	LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater);
 	LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>);
-	LLFloaterReg::add("side_bar_tab", "floater_side_bar_tab.xml",&LLFloaterReg::build<LLFloater>);
+	LLFloaterReg::add("side_bar_tab", "floater_side_bar_tab.xml", &LLFloaterReg::build<LLFloaterSideTrayTab>);
 	LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
 	LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>);
 	LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index daeace0ec5c9f2bf1e856dc13615bcac4e6d891e..f62223a38dfa060c700dd5afad7aaa6c2ac5daea 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -6573,6 +6573,16 @@ class LLToggleControl : public view_listener_t
 		std::string control_name = userdata.asString();
 		BOOL checked = gSavedSettings.getBOOL( control_name );
 		gSavedSettings.setBOOL( control_name, !checked );
+
+        // Doubleclick actions - there can be only one
+        if ((control_name == "DoubleClickAutoPilot") && !checked)
+        {
+			gSavedSettings.setBOOL( "DoubleClickTeleport", FALSE );
+        }
+        else if ((control_name == "DoubleClickTeleport") && !checked)
+        {
+			gSavedSettings.setBOOL( "DoubleClickAutoPilot", FALSE );
+        }
 		return true;
 	}
 };
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 781e324e25dc27c616538fe600d7376800545c73..c35173a7d41c197be55c27c54f3e11180cd342bf 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -77,10 +77,12 @@
 #include "llimview.h"
 #include "llspeakers.h"
 #include "lltrans.h"
+#include "lltranslate.h"
 #include "llviewerfoldertype.h"
 #include "lluri.h"
 #include "llviewergenericmessage.h"
 #include "llviewermenu.h"
+#include "llviewerjoystick.h"
 #include "llviewerobjectlist.h"
 #include "llviewerparcelmgr.h"
 #include "llviewerstats.h"
@@ -2909,6 +2911,50 @@ void process_decline_callingcard(LLMessageSystem* msg, void**)
 	LLNotificationsUtil::add("CallingCardDeclined");
 }
 
+class ChatTranslationReceiver : public LLTranslate::TranslationReceiver
+{
+public :
+	ChatTranslationReceiver(const std::string &from_lang, const std::string &to_lang, const std::string &mesg,
+							const LLChat &chat, const LLSD &toast_args)
+		: LLTranslate::TranslationReceiver(from_lang, to_lang),
+		m_chat(chat),
+		m_toastArgs(toast_args),
+		m_origMesg(mesg)
+	{
+	}
+
+	static boost::intrusive_ptr<ChatTranslationReceiver> build(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, const LLChat &chat, const LLSD &toast_args)
+	{
+		return boost::intrusive_ptr<ChatTranslationReceiver>(new ChatTranslationReceiver(from_lang, to_lang, mesg, chat, toast_args));
+	}
+
+protected:
+	void handleResponse(const std::string &translation, const std::string &detected_language)
+	{
+		// filter out non-interesting responeses
+		if ( !translation.empty()
+			&& (m_toLang != detected_language)
+			&& (LLStringUtil::compareInsensitive(translation, m_origMesg) != 0) )
+		{
+			m_chat.mText += " (" + translation + ")";
+		}
+
+		LLNotificationsUI::LLNotificationManager::instance().onChat(m_chat, m_toastArgs);
+	}
+
+	void handleFailure()
+	{
+		LLTranslate::TranslationReceiver::handleFailure();
+		m_chat.mText += " (?)";
+
+		LLNotificationsUI::LLNotificationManager::instance().onChat(m_chat, m_toastArgs);
+	}
+
+private:
+	LLChat m_chat;
+	std::string m_origMesg;
+	LLSD m_toastArgs;		
+};
 
 void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 {
@@ -3113,7 +3159,22 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
 		chat.mOwnerID = owner_id;
 
-		LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
+		if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM)
+		{
+			if (chat.mChatStyle == CHAT_STYLE_IRC)
+			{
+				mesg = mesg.substr(4, std::string::npos);
+			}
+			const std::string from_lang = ""; // leave empty to trigger autodetect
+			const std::string to_lang = LLTranslate::getTranslateLanguage();
+
+			LLHTTPClient::ResponderPtr result = ChatTranslationReceiver::build(from_lang, to_lang, mesg, chat, args);
+			LLTranslate::translateMessage(result, from_lang, to_lang, mesg);
+		}
+		else
+		{
+			LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
+		}
 	}
 }
 
@@ -3129,6 +3190,8 @@ void process_teleport_start(LLMessageSystem *msg, void**)
 	U32 teleport_flags = 0x0;
 	msg->getU32("Info", "TeleportFlags", teleport_flags);
 
+	LL_DEBUGS("Messaging") << "Got TeleportStart with TeleportFlags=" << teleport_flags << ". gTeleportDisplay: " << gTeleportDisplay << ", gAgent.mTeleportState: " << gAgent.getTeleportState() << LL_ENDL;
+
 	if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL)
 	{
 		gViewerWindow->setProgressCancelButtonVisible(FALSE);
@@ -3147,6 +3210,7 @@ void process_teleport_start(LLMessageSystem *msg, void**)
 		gAgent.setTeleportState( LLAgent::TELEPORT_START );
 		make_ui_sound("UISndTeleportOut");
 		
+		LL_INFOS("Messaging") << "Teleport initiated by remote TeleportStart message with TeleportFlags: " <<  teleport_flags << LL_ENDL;
 		// Don't call LLFirstUse::useTeleport here because this could be
 		// due to being killed, which would send you home, not to a Telehub
 	}
@@ -3488,6 +3552,12 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 
 	if( is_teleport )
 	{
+		if (gAgent.getTeleportKeepsLookAt())
+		{
+			// *NOTE: the LookAt data we get from the sim here doesn't
+			// seem to be useful, so get it from the camera instead
+			look_at = LLViewerCamera::getInstance()->getAtAxis();
+		}
 		// Force the camera back onto the agent, don't animate.
 		gAgentCamera.setFocusOnAvatar(TRUE, FALSE);
 		gAgentCamera.slamLookAt(look_at);
@@ -3534,7 +3604,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 		{
 			LLTracker::stopTracking(NULL);
 		}
-		else if ( is_teleport )
+		else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() )
 		{
 			//look at the beacon
 			LLVector3 global_agent_pos = agent_pos;
@@ -5806,7 +5876,18 @@ void process_teleport_local(LLMessageSystem *msg,void**)
 
 	if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
 	{
-		gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
+		if( gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL )
+		{
+			// To prevent TeleportStart messages re-activating the progress screen right
+			// after tp, keep the teleport state and let progress screen clear it after a short delay
+			// (progress screen is active but not visible)  *TODO: remove when SVC-5290 is fixed
+			gTeleportDisplayTimer.reset();
+			gTeleportDisplay = TRUE;
+		}
+		else
+		{
+			gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
+		}
 	}
 
 	// Sim tells us whether the new position is off the ground
@@ -5822,8 +5903,10 @@ void process_teleport_local(LLMessageSystem *msg,void**)
 	gAgent.setPositionAgent(pos);
 	gAgentCamera.slamLookAt(look_at);
 
-	// likewise make sure the camera is behind the avatar
-	gAgentCamera.resetView(TRUE, TRUE);
+	if ( !(gAgent.getTeleportKeepsLookAt() && LLViewerJoystick::getInstance()->getOverrideCamera()) )
+	{
+		gAgentCamera.resetView(TRUE, TRUE);
+	}
 
 	// send camera update to new region
 	gAgentCamera.updateCamera();
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index a86efa215b1c9a6ae29c4840d253190af2f6d344..98f16757b2b49a4c6d2819398b634ce62a9340cb 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -69,13 +69,6 @@
 	#pragma warning(disable:4355)
 #endif
 
-// Viewer object cache version, change if object update
-// format changes. JC
-const U32 INDRA_OBJECT_CACHE_VERSION = 14;
-
-// Format string used to construct filename for the object cache
-static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";
-
 extern BOOL gNoRender;
 
 const F32 WATER_TEXTURE_SCALE = 8.f;			//  Number of times to repeat the water texture across a region
@@ -214,7 +207,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	mProductName("unknown"),
 	mHttpUrl(""),
 	mCacheLoaded(FALSE),
-	mCacheEntriesCount(0),
+	mCacheDirty(FALSE),
 	mCacheID(),
 	mEventPoll(NULL),
 	mReleaseNotesRequested(FALSE),
@@ -264,8 +257,6 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	// Create the object lists
 	initStats();
 
-	mCacheStart.append(mCacheEnd);
-	
 	//create object partitions
 	//MUST MATCH declaration of eObjectPartitions
 	mObjectPartition.push_back(new LLHUDPartition());		//PARTITION_HUD
@@ -324,19 +315,6 @@ LLViewerRegion::~LLViewerRegion()
 	std::for_each(mObjectPartition.begin(), mObjectPartition.end(), DeletePointer());
 }
 
-
-const std::string LLViewerRegion::getObjectCacheFilename(U64 mHandle) const
-{
-	std::string filename;
-	U32 region_x, region_y;
-
-	grid_from_region_handle(mHandle, &region_x, &region_y);
-	filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
-			   llformat(OBJECT_CACHE_FILENAME, region_x, region_y));
-
-	return filename;
-}
-
 void LLViewerRegion::loadObjectCache()
 {
 	if (mCacheLoaded)
@@ -347,77 +325,10 @@ void LLViewerRegion::loadObjectCache()
 	// Presume success.  If it fails, we don't want to try again.
 	mCacheLoaded = TRUE;
 
-	LLVOCacheEntry *entry;
-
-	std::string filename = getObjectCacheFilename(mHandle);
-	LL_DEBUGS("ObjectCache") << filename << LL_ENDL;
-
-	LLFILE* fp = LLFile::fopen(filename, "rb");		/* Flawfinder: ignore */
-	if (!fp)
-	{
-		// might not have a file, which is normal
-		return;
-	}
-
-	U32 zero;
-	size_t nread;
-	nread = fread(&zero, sizeof(U32), 1, fp);
-	if (nread != 1 || zero)
-	{
-		// a non-zero value here means bad things!
-		// skip reading the cached values
-		llinfos << "Cache file invalid" << llendl;
-		fclose(fp);
-		return;
-	}
-
-	U32 version;
-	nread = fread(&version, sizeof(U32), 1, fp);
-	if (nread != 1 || version != INDRA_OBJECT_CACHE_VERSION)
+	if(LLVOCache::hasInstance())
 	{
-		// a version mismatch here means we've changed the binary format!
-		// skip reading the cached values
-		llinfos << "Cache version changed, discarding" << llendl;
-		fclose(fp);
-		return;
-	}
-
-	LLUUID cache_id;
-	nread = fread(&cache_id.mData, 1, UUID_BYTES, fp);
-	if (nread != (size_t)UUID_BYTES || mCacheID != cache_id)
-	{
-		llinfos << "Cache ID doesn't match for this region, discarding"
-			<< llendl;
-		fclose(fp);
-		return;
-	}
-
-	S32 num_entries;
-	nread = fread(&num_entries, sizeof(S32), 1, fp);
-	if (nread != 1)
-	{
-		llinfos << "Short read, discarding" << llendl;
-		fclose(fp);
-		return;
+		LLVOCache::getInstance()->readFromCache(mHandle, mCacheID, mCacheMap) ;
 	}
-	
-	S32 i;
-	for (i = 0; i < num_entries; i++)
-	{
-		entry = new LLVOCacheEntry(fp);
-		if (!entry->getLocalID())
-		{
-			llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
-			delete entry;
-			entry = NULL;
-			break;
-		}
-		mCacheEnd.insert(*entry);
-		mCacheMap[entry->getLocalID()] = entry;
-		mCacheEntriesCount++;
-	}
-
-	fclose(fp);
 }
 
 
@@ -428,61 +339,22 @@ void LLViewerRegion::saveObjectCache()
 		return;
 	}
 
-	S32 num_entries = mCacheEntriesCount;
-	if (0 == num_entries)
+	if (mCacheMap.empty())
 	{
 		return;
 	}
 
-	std::string filename = getObjectCacheFilename(mHandle);
-	LL_DEBUGS("ObjectCache") << filename << LL_ENDL;
-
-	LLFILE* fp = LLFile::fopen(filename, "wb");		/* Flawfinder: ignore */
-	if (!fp)
+	if(LLVOCache::hasInstance())
 	{
-		llwarns << "Unable to write cache file " << filename << llendl;
-		return;
+		LLVOCache::getInstance()->writeToCache(mHandle, mCacheID, mCacheMap, mCacheDirty) ;
+		mCacheDirty = FALSE;
 	}
 
-	// write out zero to indicate a version cache file
-	U32 zero = 0;
-	if (fwrite(&zero, sizeof(U32), 1, fp) != 1)
+	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mCacheMap.begin(); iter != mCacheMap.end(); ++iter)
 	{
-		llwarns << "Short write" << llendl;
+		delete iter->second;
 	}
-
-	// write out version number
-	U32 version = INDRA_OBJECT_CACHE_VERSION;
-	if (fwrite(&version, sizeof(U32), 1, fp) != 1)
-	{
-		llwarns << "Short write" << llendl;
-	}
-
-	// write the cache id for this sim
-	if (fwrite(&mCacheID.mData, 1, UUID_BYTES, fp) != (size_t)UUID_BYTES)
-	{
-		llwarns << "Short write" << llendl;
-	}
-
-	if (fwrite(&num_entries, sizeof(S32), 1, fp) != 1)
-	{
-		llwarns << "Short write" << llendl;
-	}
-
-	LLVOCacheEntry *entry;
-
-	for (entry = mCacheStart.getNext(); entry && (entry != &mCacheEnd); entry = entry->getNext())
-	{
-		entry->writeToFile(fp);
-	}
-
 	mCacheMap.clear();
-	mCacheEnd.unlink();
-	mCacheEnd.init();
-	mCacheStart.deleteAll();
-	mCacheStart.init();
-
-	fclose(fp);
 }
 
 void LLViewerRegion::sendMessage()
@@ -1175,7 +1047,6 @@ void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinary
 			mCacheMap.erase(local_id);
 			delete entry;
 			entry = new LLVOCacheEntry(local_id, crc, dp);
-			mCacheEnd.insert(*entry);
 			mCacheMap[local_id] = entry;
 		}
 	}
@@ -1184,18 +1055,13 @@ void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinary
 		// we haven't seen this object before
 
 		// Create new entry and add to map
-		if (mCacheEntriesCount > MAX_OBJECT_CACHE_ENTRIES)
+		if (mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES)
 		{
-			entry = mCacheStart.getNext();
-			mCacheMap.erase(entry->getLocalID());
-			delete entry;
-			mCacheEntriesCount--;
+			mCacheMap.erase(mCacheMap.begin());
 		}
 		entry = new LLVOCacheEntry(local_id, crc, dp);
 
-		mCacheEnd.insert(*entry);
 		mCacheMap[local_id] = entry;
-		mCacheEntriesCount++;
 	}
 	return ;
 }
@@ -1310,6 +1176,7 @@ void LLViewerRegion::requestCacheMisses()
 	mCacheMissFull.reset();
 	mCacheMissCRC.reset();
 
+	mCacheDirty = TRUE ;
 	// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
 }
 
@@ -1327,9 +1194,10 @@ void LLViewerRegion::dumpCache()
 	}
 
 	LLVOCacheEntry *entry;
-
-	for (entry = mCacheStart.getNext(); entry && (entry != &mCacheEnd); entry = entry->getNext())
+	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mCacheMap.begin(); iter != mCacheMap.end(); ++iter)
 	{
+		entry = iter->second ;
+
 		S32 hits = entry->getHitCount();
 		S32 changes = entry->getCRCChangeCount();
 
@@ -1340,7 +1208,7 @@ void LLViewerRegion::dumpCache()
 		change_bin[changes]++;
 	}
 
-	llinfos << "Count " << mCacheEntriesCount << llendl;
+	llinfos << "Count " << mCacheMap.size() << llendl;
 	for (i = 0; i < BINS; i++)
 	{
 		llinfos << "Hits " << i << " " << hit_bin[i] << llendl;
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 361ae87e1b9b087d96ba2f9ddcd4764fe53470d1..038c831e59dd1b9b6cfa9091573f4d02f5d8591f 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -323,9 +323,6 @@ public:
 	LLDynamicArray<LLUUID> mMapAvatarIDs;
 
 private:
-	// determine the cache filename for the region from the region handle
-	const std::string getObjectCacheFilename(U64 mHandle) const;
-
 	// The surfaces and other layers
 	LLSurface*	mLandp;
 
@@ -387,11 +384,8 @@ private:
 	// Regions can have order 10,000 objects, so assume
 	// a structure of size 2^14 = 16,000
 	BOOL									mCacheLoaded;
-	typedef std::map<U32, LLVOCacheEntry *>	cache_map_t;
-	cache_map_t			  				 	mCacheMap;
-	LLVOCacheEntry							mCacheStart;
-	LLVOCacheEntry							mCacheEnd;
-	U32										mCacheEntriesCount;
+	BOOL                                    mCacheDirty;
+	LLVOCacheEntry::vocache_entry_map_t		mCacheMap;
 	LLDynamicArray<U32>						mCacheMissFull;
 	LLDynamicArray<U32>						mCacheMissCRC;
 	// time?
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 5d8f58d5e9a42054ab74689325b6c69b23a02748..ca977d45999ea73dc391ce20c9dd4771a397edeb 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -263,5 +263,5 @@ void send_stats();
 
 extern std::map<S32,LLFrameTimer> gDebugTimers;
 extern std::map<S32,std::string> gDebugTimerLabel;
-
+extern U32	gTotalTextureBytes;
 #endif // LL_LLVIEWERSTATS_H
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 556451e3906a036decf70aad23559dd818bb59b5..43d18c6d838e91faa3e4c638fe40898ecd39c5d8 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3911,7 +3911,14 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 		image_buffer_x = llfloor(snapshot_width*scale_factor) ;
 		image_buffer_y = llfloor(snapshot_height *scale_factor) ;
 	}
-	raw->resize(image_buffer_x, image_buffer_y, 3);
+	if(image_buffer_x > 0 && image_buffer_y > 0)
+	{
+		raw->resize(image_buffer_x, image_buffer_y, 3);
+	}
+	else
+	{
+		return FALSE ;
+	}
 	if(raw->isBufferInvalid())
 	{
 		return FALSE ;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f9065d9e33c4d7f083b09b3e6a4820018f142c80..35dc8d4caf0bb49d0c477b35634c7e208d899802 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -176,7 +176,7 @@ const F32 TIME_BEFORE_MESH_CLEANUP = 5.f; // seconds
 const S32 AVATAR_RELEASE_THRESHOLD = 10; // number of avatar instances before releasing memory
 const F32 FOOT_GROUND_COLLISION_TOLERANCE = 0.25f;
 const F32 AVATAR_LOD_TWEAK_RANGE = 0.7f;
-const S32 MAX_BUBBLE_CHAT_LENGTH = 1023;
+const S32 MAX_BUBBLE_CHAT_LENGTH = DB_CHAT_MSG_STR_LEN;
 const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12;
 const F32 CHAT_FADE_TIME = 8.0;
 const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f;
@@ -6841,12 +6841,14 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 			llinfos << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
 		}
 
+		const F32 LOADING_TIMEOUT_SECONDS = 60.f;
 		// this isn't really a problem if we already have a non-default shape
-		if (visualParamWeightsAreDefault())
+		if (visualParamWeightsAreDefault() && mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT_SECONDS)
 		{
 			// re-request appearance, hoping that it comes back with a shape next time
 			llinfos << "Re-requesting AvatarAppearance for object: "  << getID() << llendl;
 			LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());
+			mRuthTimer.reset();
 		}
 		else
 		{
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index a231afad3fdae41d0dd35479907d97ff7d431ff8..ec5c95469e76f0266a7f51ad0ff0c24231a528a9 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1163,12 +1163,24 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
 		gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id);
 		gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
 		
-		// this object might have been selected, so let the selection manager know it's gone now
+		// This object might have been selected, so let the selection manager know it's gone now
 		LLViewerObject *found_obj = gObjectList.findObject(item_id);
 		if (found_obj)
 		{
 			LLSelectMgr::getInstance()->remove(found_obj);
 		}
+
+		// Error checking in case this object was attached to an invalid point
+		// In that case, just remove the item from COF preemptively since detach 
+		// will fail.
+		if (isAgentAvatarValid())
+		{
+			const LLViewerObject *attached_obj = gAgentAvatarp->getWornAttachment(item_id);
+			if (!attached_obj)
+			{
+				LLAppearanceMgr::instance().removeCOFItemLinks(item_id, false);
+			}
+		}
 		return TRUE;
 	}
 	return FALSE;
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index eb2475f666022181efc42456a912c95e15b03a54..23a799ea3ac8b60633710fd292c265374a0a5848 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -33,6 +33,7 @@
 
 struct LocalTextureData;
 
+
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLVOAvatarSelf
 //
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 4e6d630ed88b29088baf52dcfcbaeb4a18396d67..0b903e62b1381484bea8eff1e71dc8b4d3da4ad3 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -25,10 +25,19 @@
  */
 
 #include "llviewerprecompiledheaders.h"
-
 #include "llvocache.h"
-
 #include "llerror.h"
+#include "llregionhandle.h"
+
+BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) 
+{
+	return apr_file->read(src, n_bytes) == n_bytes ;
+}
+
+BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes) 
+{
+	return apr_file->write(src, n_bytes) == n_bytes ;
+}
 
 //---------------------------------------------------------------------------
 // LLVOCacheEntry
@@ -57,26 +66,31 @@ LLVOCacheEntry::LLVOCacheEntry()
 	mDP.assignBuffer(mBuffer, 0);
 }
 
+LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
+{
+	S32 size = -1;
+	BOOL success;
 
-static inline void checkedRead(LLFILE *fp, void *data, size_t nbytes)
+	success = check_read(apr_file, &mLocalID, sizeof(U32));
+	if(success)
 {
-	if (fread(data, 1, nbytes, fp) != nbytes)
+		success = check_read(apr_file, &mCRC, sizeof(U32));
+	}
+	if(success)
 	{
-		llwarns << "Short read" << llendl;
-		memset(data, 0, nbytes);
+		success = check_read(apr_file, &mHitCount, sizeof(S32));
 	}
+	if(success)
+	{
+		success = check_read(apr_file, &mDupeCount, sizeof(S32));
 }
-
-LLVOCacheEntry::LLVOCacheEntry(LLFILE *fp)
+	if(success)
 {
-	S32 size;
-	checkedRead(fp, &mLocalID, sizeof(U32));
-	checkedRead(fp, &mCRC, sizeof(U32));
-	checkedRead(fp, &mHitCount, sizeof(S32));
-	checkedRead(fp, &mDupeCount, sizeof(S32));
-	checkedRead(fp, &mCRCChangeCount, sizeof(S32));
-
-	checkedRead(fp, &size, sizeof(S32));
+		success = check_read(apr_file, &mCRCChangeCount, sizeof(S32));
+	}
+	if(success)
+	{
+		success = check_read(apr_file, &size, sizeof(S32));
 
 	// Corruption in the cache entries
 	if ((size > 10000) || (size < 1))
@@ -90,11 +104,30 @@ LLVOCacheEntry::LLVOCacheEntry(LLFILE *fp)
 		mBuffer = NULL;
 		return;
 	}
+	}
+	if(success && size > 0)
+	{
+		mBuffer = new U8[size];
+		success = check_read(apr_file, mBuffer, size);
 
-	mBuffer = new U8[size];
-	checkedRead(fp, mBuffer, size);
+		if(success)
+		{
 	mDP.assignBuffer(mBuffer, size);
 }
+		else
+		{
+			delete[] mBuffer ;
+			mBuffer = NULL ;
+		}
+	}
+
+	if(!success)
+	{
+		mLocalID = 0;
+		mCRC = 0;
+		mBuffer = NULL;
+	}
+}
 
 LLVOCacheEntry::~LLVOCacheEntry()
 {
@@ -148,22 +181,467 @@ void LLVOCacheEntry::dump() const
 		<< llendl;
 }
 
-static inline void checkedWrite(LLFILE *fp, const void *data, size_t nbytes)
+BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
+{
+	BOOL success;
+	success = check_write(apr_file, (void*)&mLocalID, sizeof(U32));
+	if(success)
+	{
+		success = check_write(apr_file, (void*)&mCRC, sizeof(U32));
+	}
+	if(success)
+	{
+		success = check_write(apr_file, (void*)&mHitCount, sizeof(S32));
+	}
+	if(success)
+	{
+		success = check_write(apr_file, (void*)&mDupeCount, sizeof(S32));
+	}
+	if(success)
+	{
+		success = check_write(apr_file, (void*)&mCRCChangeCount, sizeof(S32));
+	}
+	if(success)
+	{
+		S32 size = mDP.getBufferSize();
+		success = check_write(apr_file, (void*)&size, sizeof(S32));
+	
+		if(success)
+		{
+			success = check_write(apr_file, (void*)mBuffer, size);
+	}
+}
+
+	return success ;
+}
+
+//-------------------------------------------------------------------
+//LLVOCache
+//-------------------------------------------------------------------
+// Format string used to construct filename for the object cache
+static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";
+
+const U32 MAX_NUM_OBJECT_ENTRIES = 128 ;
+const U32 NUM_ENTRIES_TO_PURGE = 16 ;
+const char* object_cache_dirname = "objectcache";
+const char* header_filename = "object.cache";
+
+LLVOCache* LLVOCache::sInstance = NULL;
+
+//static 
+LLVOCache* LLVOCache::getInstance() 
+{
+	if(!sInstance)
+	{
+		sInstance = new LLVOCache() ;
+}
+	return sInstance ;
+}
+
+//static 
+BOOL LLVOCache::hasInstance() 
+{
+	return sInstance != NULL ;
+}
+
+//static 
+void LLVOCache::destroyClass() 
+{
+	if(sInstance)
+	{
+		delete sInstance ;
+		sInstance = NULL ;
+	}
+}
+
+LLVOCache::LLVOCache():
+	mInitialized(FALSE),
+	mReadOnly(TRUE),
+	mNumEntries(0)
+{
+	mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
+}
+
+LLVOCache::~LLVOCache()
+{
+	writeCacheHeader();
+	clearCacheInMemory();
+	delete mLocalAPRFilePoolp;
+}
+
+void LLVOCache::setDirNames(ELLPath location)
+{
+	std::string delem = gDirUtilp->getDirDelimiter();
+
+	mHeaderFileName = gDirUtilp->getExpandedFilename(location, object_cache_dirname, header_filename);
+	mObjectCacheDirName = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
+}
+
+void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)
+{
+	if(mInitialized)
+	{
+		return ;
+	}
+
+	setDirNames(location);
+	if (!mReadOnly)
+	{
+		LLFile::mkdir(mObjectCacheDirName);
+	}	
+	mCacheSize = llmin(size, MAX_NUM_OBJECT_ENTRIES) ;
+	mCacheSize = llmax(mCacheSize, NUM_ENTRIES_TO_PURGE);
+
+	mMetaInfo.mVersion = cache_version;
+	readCacheHeader();
+	mInitialized = TRUE ;
+
+	if(mMetaInfo.mVersion != cache_version) 
+	{
+		mMetaInfo.mVersion = cache_version ;
+		if(mReadOnly) //disable cache
+		{
+			clearCacheInMemory();
+		}
+		else //delete the current cache if the format does not match.
+		{			
+			removeCache();
+		}
+	}	
+}
+	
+void LLVOCache::removeCache(ELLPath location) 
+{
+	if(mReadOnly)
+	{
+		return ;
+	}
+
+	std::string delem = gDirUtilp->getDirDelimiter();
+	std::string mask = delem + "*";
+	std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
+	gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files
+	LLFile::rmdir(cache_dir);
+
+	clearCacheInMemory();
+	mInitialized = FALSE ;
+}
+
+void LLVOCache::removeCache() 
+{
+	llassert_always(mInitialized) ;
+	if(mReadOnly)
+	{
+		return ;
+	}
+
+	std::string delem = gDirUtilp->getDirDelimiter();
+	std::string mask = delem + "*";
+	gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask); 
+
+	clearCacheInMemory() ;
+	writeCacheHeader();
+}
+
+void LLVOCache::clearCacheInMemory()
+{
+	if(!mHeaderEntryQueue.empty()) 
+	{
+		for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin(); iter != mHeaderEntryQueue.end(); ++iter)
+		{
+			delete *iter ;
+		}
+		mHeaderEntryQueue.clear();
+		mHandleEntryMap.clear();
+		mNumEntries = 0 ;
+	}
+}
+
+void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename) 
+{
+	U32 region_x, region_y;
+
+	grid_from_region_handle(handle, &region_x, &region_y);
+	filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, object_cache_dirname,
+			   llformat(OBJECT_CACHE_FILENAME, region_x, region_y));
+
+	return ;
+}
+
+void LLVOCache::removeFromCache(U64 handle)
+{
+	if(mReadOnly)
+	{
+		return ;
+	}
+
+	std::string filename;
+	getObjectCacheFilename(handle, filename);
+	LLAPRFile::remove(filename, mLocalAPRFilePoolp);	
+}
+
+BOOL LLVOCache::checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes) 
+{
+	if(!check_read(apr_file, src, n_bytes))
+	{
+		delete apr_file ;
+		removeCache() ;
+		return FALSE ;
+	}
+
+	return TRUE ;
+}
+
+BOOL LLVOCache::checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes) 
+{
+	if(!check_write(apr_file, src, n_bytes))
+	{
+		delete apr_file ;
+		removeCache() ;
+		return FALSE ;
+	}
+
+	return TRUE ;
+}
+
+void LLVOCache::readCacheHeader()
+{
+	//clear stale info.
+	clearCacheInMemory();	
+
+	if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
+	{
+		LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);		
+		
+		//read the meta element
+		if(!checkRead(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)))
+		{
+			return ;
+		}
+
+		HeaderEntryInfo* entry ;
+		mNumEntries = 0 ;
+		while(mNumEntries < MAX_NUM_OBJECT_ENTRIES)
+		{
+			entry = new HeaderEntryInfo() ;
+			if(!checkRead(apr_file, entry, sizeof(HeaderEntryInfo)))
+			{
+				delete entry ;			
+				return ;
+			}
+			else if(!entry->mTime) //end of the cache.
+			{
+				delete entry ;
+				return ;
+			}
+
+			entry->mIndex = mNumEntries++ ;
+			mHeaderEntryQueue.insert(entry) ;
+			mHandleEntryMap[entry->mHandle] = entry ;
+		}
+
+		delete apr_file ;
+	}
+	else
+	{
+		writeCacheHeader() ;
+	}
+}
+
+void LLVOCache::writeCacheHeader()
 {
-	if (fwrite(data, 1, nbytes, fp) != nbytes)
+	if(mReadOnly)
+	{
+		return ;
+	}	
+
+	LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+
+	//write the meta element
+	if(!checkWrite(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)))
 	{
-		llwarns << "Short write" << llendl;
+		return ;
 	}
+
+	mNumEntries = 0 ;
+	for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; iter != mHeaderEntryQueue.end(); ++iter)
+	{
+		(*iter)->mIndex = mNumEntries++ ;
+		if(!checkWrite(apr_file, (void*)*iter, sizeof(HeaderEntryInfo)))
+		{
+			return ;
+		}
+	}
+
+	mNumEntries = mHeaderEntryQueue.size() ;
+	if(mNumEntries < MAX_NUM_OBJECT_ENTRIES)
+	{
+		HeaderEntryInfo* entry = new HeaderEntryInfo() ;
+		for(S32 i = mNumEntries ; i < MAX_NUM_OBJECT_ENTRIES ; i++)
+		{
+			//fill the cache with the default entry.
+			if(!checkWrite(apr_file, entry, sizeof(HeaderEntryInfo)))
+			{
+				mReadOnly = TRUE ; //disable the cache.
+				return ;
+			}
+		}
+		delete entry ;
+	}
+	delete apr_file ;
 }
 
-void LLVOCacheEntry::writeToFile(LLFILE *fp) const
+BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)
 {
-	checkedWrite(fp, &mLocalID, sizeof(U32));
-	checkedWrite(fp, &mCRC, sizeof(U32));
-	checkedWrite(fp, &mHitCount, sizeof(S32));
-	checkedWrite(fp, &mDupeCount, sizeof(S32));
-	checkedWrite(fp, &mCRCChangeCount, sizeof(S32));
-	S32 size = mDP.getBufferSize();
-	checkedWrite(fp, &size, sizeof(S32));
-	checkedWrite(fp, mBuffer, size);
+	LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+	apr_file->seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
+
+	return checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
 }
+
+void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) 
+{
+	llassert_always(mInitialized);
+
+	handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
+	if(iter == mHandleEntryMap.end()) //no cache
+	{
+		return ;
+	}
+
+	std::string filename;
+	getObjectCacheFilename(handle, filename);
+	LLAPRFile* apr_file = new LLAPRFile(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
+
+	LLUUID cache_id ;
+	if(!checkRead(apr_file, cache_id.mData, UUID_BYTES))
+	{
+		return ;
+	}
+	if(cache_id != id)
+	{
+		llinfos << "Cache ID doesn't match for this region, discarding"<< llendl;
+
+		delete apr_file ;
+		return ;
+	}
+
+	S32 num_entries;
+	if(!checkRead(apr_file, &num_entries, sizeof(S32)))
+	{
+		return ;
+	}
+	
+	for (S32 i = 0; i < num_entries; i++)
+	{
+		LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file);
+		if (!entry->getLocalID())
+		{
+			llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
+			delete entry ;
+			break;
+		}
+		cache_entry_map[entry->getLocalID()] = entry;
+	}
+	num_entries = cache_entry_map.size() ;
+
+	delete apr_file ;
+	return ;
+}
+	
+void LLVOCache::purgeEntries()
+{
+	U32 limit = mCacheSize - NUM_ENTRIES_TO_PURGE ;
+	while(mHeaderEntryQueue.size() > limit)
+	{
+		header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ;
+		HeaderEntryInfo* entry = *iter ;
+		
+		removeFromCache(entry->mHandle) ;
+		mHandleEntryMap.erase(entry->mHandle) ;		
+		mHeaderEntryQueue.erase(iter) ;
+		delete entry ;
+	}
+
+	writeCacheHeader() ;
+	readCacheHeader() ;
+	mNumEntries = mHandleEntryMap.size() ;
+}
+
+void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) 
+{
+	llassert_always(mInitialized);
+
+	if(mReadOnly)
+	{
+		return ;
+	}
+
+	HeaderEntryInfo* entry;
+	handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
+	if(iter == mHandleEntryMap.end()) //new entry
+	{		
+		if(mNumEntries >= mCacheSize)
+		{
+			purgeEntries() ;
+		}
+		
+		entry = new HeaderEntryInfo();
+		entry->mHandle = handle ;
+		entry->mTime = time(NULL) ;
+		entry->mIndex = mNumEntries++ ;
+		mHeaderEntryQueue.insert(entry) ;
+		mHandleEntryMap[handle] = entry ;
+	}
+	else
+	{
+		entry = iter->second ;
+		entry->mTime = time(NULL) ;
+
+		//resort
+		mHeaderEntryQueue.erase(entry) ;
+		mHeaderEntryQueue.insert(entry) ;
+	}
+
+	//update cache header
+	if(!updateEntry(entry))
+	{
+		return ; //update failed.
+	}
+
+	if(!dirty_cache)
+	{
+		return ; //nothing changed, no need to update.
+	}
+
+	//write to cache file
+	std::string filename;
+	getObjectCacheFilename(handle, filename);
+	LLAPRFile* apr_file = new LLAPRFile(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+	
+	if(!checkWrite(apr_file, (void*)id.mData, UUID_BYTES))
+	{
+		return ;
+	}
+
+	S32 num_entries = cache_entry_map.size() ;
+	if(!checkWrite(apr_file, &num_entries, sizeof(S32)))
+	{
+		return ;
+	}
+
+	for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); iter != cache_entry_map.end(); ++iter)
+	{
+		if(!iter->second->writeToFile(apr_file))
+		{
+			//failed
+			delete apr_file ;
+			removeCache() ;
+			return ;
+		}
+	}
+
+	delete apr_file ;
+	return ;
+}
+
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 7a4572b399c1c4735933c609592fa21728ebecaf..56b48ef705d44263cd09c64ee0d47a91afd01613 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -36,11 +36,11 @@
 // Cache entries
 class LLVOCacheEntry;
 
-class LLVOCacheEntry : public LLDLinked<LLVOCacheEntry>
+class LLVOCacheEntry
 {
 public:
 	LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp);
-	LLVOCacheEntry(LLFILE *fp);
+	LLVOCacheEntry(LLAPRFile* apr_file);
 	LLVOCacheEntry();
 	~LLVOCacheEntry();
 
@@ -50,12 +50,15 @@ public:
 	S32 getCRCChangeCount() const	{ return mCRCChangeCount; }
 
 	void dump() const;
-	void writeToFile(LLFILE *fp) const;
+	BOOL writeToFile(LLAPRFile* apr_file) const;
 	void assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp);
 	LLDataPackerBinaryBuffer *getDP(U32 crc);
 	void recordHit();
 	void recordDupe() { mDupeCount++; }
 
+public:
+	typedef std::map<U32, LLVOCacheEntry*>	vocache_entry_map_t;
+
 protected:
 	U32							mLocalID;
 	U32							mCRC;
@@ -66,4 +69,81 @@ protected:
 	U8							*mBuffer;
 };
 
+//
+//Note: LLVOCache is not thread-safe
+//
+class LLVOCache
+{
+private:
+	struct HeaderEntryInfo
+	{
+		HeaderEntryInfo() : mIndex(0), mHandle(0), mTime(0) {}
+		S32 mIndex;
+		U64 mHandle ;
+		U32 mTime ;
+	};
+
+	struct HeaderMetaInfo
+	{
+		HeaderMetaInfo() : mVersion(0){}
+
+		U32 mVersion;
+	};
+
+	struct header_entry_less
+	{
+		bool operator()(const HeaderEntryInfo* lhs, const HeaderEntryInfo* rhs) const
+		{
+			return lhs->mTime < rhs->mTime; // older entry in front of queue (set)
+		}
+	};
+	typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t;
+	typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t;
+private:
+	LLVOCache() ;
+
+public:
+	~LLVOCache() ;
+
+	void initCache(ELLPath location, U32 size, U32 cache_version) ;
+	void removeCache(ELLPath location) ;
+
+	void readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ;
+	void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) ;
+
+	void setReadOnly(BOOL read_only) {mReadOnly = read_only;} 
+
+private:
+	void setDirNames(ELLPath location);	
+	// determine the cache filename for the region from the region handle	
+	void getObjectCacheFilename(U64 handle, std::string& filename);
+	void removeFromCache(U64 handle);
+	void readCacheHeader();
+	void writeCacheHeader();
+	void clearCacheInMemory();
+	void removeCache() ;
+	void purgeEntries();
+	BOOL updateEntry(const HeaderEntryInfo* entry);
+	BOOL checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes) ;
+	BOOL checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes) ;
+	
+private:
+	BOOL                 mInitialized ;
+	BOOL                 mReadOnly ;
+	HeaderMetaInfo       mMetaInfo;
+	U32                  mCacheSize;
+	U32                  mNumEntries;
+	std::string          mHeaderFileName ;
+	std::string          mObjectCacheDirName;
+	LLVolatileAPRPool*   mLocalAPRFilePoolp ; 	
+	header_entry_queue_t mHeaderEntryQueue;
+	handle_entry_map_t   mHandleEntryMap;	
+
+	static LLVOCache* sInstance ;
+public:
+	static LLVOCache* getInstance() ;
+	static BOOL       hasInstance() ;
+	static void       destroyClass() ;
+};
+
 #endif
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 2e003dd2b82992d26b60c851d02a107275b5cd39..e674fec0539c9ef45b275a28c6d0d3ebfa4286aa 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -386,7 +386,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient()
 {
 }
 
-//----------------------------------------------
+//---------------------------------------------------
 
 void LLVivoxVoiceClient::init(LLPumpIO *pump)
 {
@@ -400,7 +400,8 @@ void LLVivoxVoiceClient::terminate()
 	{
 		logout();
 		connectorShutdown();
-		closeSocket();		// Need to do this now -- bad things happen if the destructor does it later.	
+		closeSocket();		// Need to do this now -- bad things happen if the destructor does it later.
+		cleanUp();
 	}
 	else
 	{
@@ -408,6 +409,18 @@ void LLVivoxVoiceClient::terminate()
 	}
 }
 
+//---------------------------------------------------
+
+void LLVivoxVoiceClient::cleanUp()
+{
+	deleteAllSessions();
+	deleteAllBuddies();
+	deleteAllVoiceFonts();
+	deleteVoiceFontTemplates();
+}
+
+//---------------------------------------------------
+
 const LLVoiceVersionInfo& LLVivoxVoiceClient::getVersion()
 {
 	return mVoiceVersion;
@@ -776,14 +789,10 @@ void LLVivoxVoiceClient::stateMachine()
 	{
 		//MARK: stateDisableCleanup
 		case stateDisableCleanup:
-			// Clean up and reset everything. 
+			// Clean up and reset everything.
 			closeSocket();
-			deleteAllSessions();
-			deleteAllBuddies();
-			deleteAllVoiceFonts();
-			deleteVoiceFontTemplates();
+			cleanUp();
 
-			mConnectorHandle.clear();
 			mAccountHandle.clear();
 			mAccountPassword.clear();
 			mVoiceAccountServerURI.clear();
@@ -1675,12 +1684,9 @@ void LLVivoxVoiceClient::stateMachine()
 		//MARK: stateLoggedOut
 		case stateLoggedOut:			// logout response received
 			
-			// Once we're logged out, all these things are invalid.
+			// Once we're logged out, these things are invalid.
 			mAccountHandle.clear();
-			deleteAllSessions();
-			deleteAllBuddies();
-			deleteAllVoiceFonts();
-			deleteVoiceFontTemplates();
+			cleanUp();
 
 			if(mVoiceEnabled && !mRelogRequested)
 			{
@@ -1778,6 +1784,8 @@ void LLVivoxVoiceClient::closeSocket(void)
 {
 	mSocket.reset();
 	mConnected = false;	
+	mConnectorHandle.clear();
+	mAccountHandle.clear();
 }
 
 void LLVivoxVoiceClient::loginSendMessage()
@@ -2370,8 +2378,7 @@ void LLVivoxVoiceClient::giveUp()
 {
 	// All has failed.  Clean up and stop trying.
 	closeSocket();
-	deleteAllSessions();
-	deleteAllBuddies();
+	cleanUp();
 	
 	setState(stateJail);
 }
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index d10a56261611c99c2b83934a000f6965e0f888a2..08f2f75a39db57737eb07c676cb35b174a8a5b05 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -668,7 +668,10 @@ protected:
 
 private:
 	LLVoiceVersionInfo mVoiceVersion;
-		
+
+	/// Clean up objects created during a voice session.
+	void cleanUp();
+
 	state mState;
 	bool mSessionTerminateRequested;
 	bool mRelogRequested;
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 0ac6b9117bfaf8b87f6b7cf60c425c8db0fc15ed..6b3e7873a193b3076963ef779704ae6c1602b1c6 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -139,10 +139,10 @@ protected:
 	~LLSkyTex();
 
 
-	static S32 getResolution()						{ return sResolution; }
+	static S32 getResolution()					{ return sResolution; }
 	static S32 getCurrent()						{ return sCurrent; }
-	static S32 stepCurrent()					{ return (sCurrent = (sCurrent + 1) % 2); }
-	static S32 getNext()						{ return ((sCurrent+1) % 2); }
+	static S32 stepCurrent()					{ sCurrent++; sCurrent &= 1; return sCurrent; }
+	static S32 getNext()						{ return ((sCurrent+1) & 1); }
 	static S32 getWhich(const BOOL curr)		{ return curr ? sCurrent : getNext(); }
 
 	void initEmpty(const S32 tex);
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index 2b05273dc7d0dee6388c2513fd89a773e4d87a0e..b060c9f076cf8f67c55434975505f4477461b302 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -361,7 +361,7 @@ private:
 		bool mSortWearableTypeByName;
 
 		LLWearableTypeOrder(ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name);
-		LLWearableTypeOrder(){};
+	LLWearableTypeOrder() : mOrderPriority(ORDER_RANK_UNKNOWN), mSortAssetTypeByName(false), mSortWearableTypeByName(false) {};
 	};
 
 	ETypeListOrder getTypeListOrder(LLAssetType::EType item_type) const;
diff --git a/indra/newview/llwearabletype.cpp b/indra/newview/llwearabletype.cpp
index d2e62c86ab788aee5b6b9a9adf0dc584959db6a7..0d707d65bf8d52f3762ef33ba81a1aa599f6fe97 100644
--- a/indra/newview/llwearabletype.cpp
+++ b/indra/newview/llwearabletype.cpp
@@ -77,8 +77,8 @@ LLWearableDictionary::LLWearableDictionary()
 	addEntry(LLWearableType::WT_SKIRT,        new WearableEntry("skirt",       "New Skirt",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SKIRT));
 	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry("alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_ALPHA));
 	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry("tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_TATTOO));
-	addEntry(LLWearableType::WT_INVALID,      new WearableEntry("invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_NONE));
-	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry("none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_NONE));
+	addEntry(LLWearableType::WT_INVALID,      new WearableEntry("invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_INVALID));
+	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry("none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_INVALID));
 }
 
 // static
@@ -94,6 +94,7 @@ const std::string& LLWearableType::getTypeName(LLWearableType::EType type)
 { 
 	const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
 	const WearableEntry *entry = dict->lookup(type);
+	if (!entry) return getTypeName(WT_INVALID);
 	return entry->mName;
 }
 
@@ -102,6 +103,7 @@ const std::string& LLWearableType::getTypeDefaultNewName(LLWearableType::EType t
 { 
 	const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
 	const WearableEntry *entry = dict->lookup(type);
+	if (!entry) return getTypeDefaultNewName(WT_INVALID);
 	return entry->mDefaultNewName;
 }
 
@@ -110,6 +112,7 @@ const std::string& LLWearableType::getTypeLabel(LLWearableType::EType type)
 { 
 	const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
 	const WearableEntry *entry = dict->lookup(type);
+	if (!entry) return getTypeLabel(WT_INVALID);
 	return entry->mLabel;
 }
 
@@ -118,6 +121,7 @@ LLAssetType::EType LLWearableType::getAssetType(LLWearableType::EType type)
 {
 	const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
 	const WearableEntry *entry = dict->lookup(type);
+	if (!entry) return getAssetType(WT_INVALID);
 	return entry->mAssetType;
 }
 
@@ -126,6 +130,7 @@ LLInventoryIcon::EIconName LLWearableType::getIconName(LLWearableType::EType typ
 {
 	const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
 	const WearableEntry *entry = dict->lookup(type);
+	if (!entry) return getIconName(WT_INVALID);
 	return entry->mIconName;
-}
+} 
 
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 2ad43ff3942d5e8bc9bb3b43738e788fafe3fbd3..5760d04a084aff147368f0b11782df586570ced0 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -121,6 +121,7 @@ void LLWorld::destroyClass()
 		LLViewerRegion* region_to_delete = *region_it++;
 		removeRegion(region_to_delete->getHost());
 	}
+	LLVOCache::getInstance()->destroyClass() ;
 	LLViewerPartSim::getInstance()->destroyClass();
 }
 
@@ -256,6 +257,8 @@ void LLWorld::removeRegion(const LLHost &host)
 
 		llwarns << "Disabling region " << regionp->getName() << " that agent is in!" << llendl;
 		LLAppViewer::instance()->forceDisconnect(LLTrans::getString("YouHaveBeenDisconnected"));
+
+		regionp->saveObjectCache() ; //force to save objects here in case that the object cache is about to be destroyed.
 		return;
 	}
 
diff --git a/indra/newview/noise.cpp b/indra/newview/noise.cpp
index 00d04f7be459bf730ab78177890fdee63a272aaf..5f2c718b49be57cbba159822e3c1f25ed624e4aa 100644
--- a/indra/newview/noise.cpp
+++ b/indra/newview/noise.cpp
@@ -30,6 +30,7 @@
 
 #include "llrand.h"
 
+
 // static
 #define B 0x100
 S32 p[B + B + 2];
diff --git a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png
index de8a39fc8a43fb5b77ddd17f535a8d68ff95ce39..75833eccf3eb694728e4ca3b56b88025220235dd 100644
Binary files a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png and b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png differ
diff --git a/indra/newview/skins/default/textures/icons/Generic_Person_Large.png b/indra/newview/skins/default/textures/icons/Generic_Person_Large.png
index 65b0ce8b67706824f50b45c20a532b0be1169b39..532288b43066792d88a2c8b7682370372bb9d42a 100644
Binary files a/indra/newview/skins/default/textures/icons/Generic_Person_Large.png and b/indra/newview/skins/default/textures/icons/Generic_Person_Large.png differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Invalid.png b/indra/newview/skins/default/textures/icons/Inv_Invalid.png
new file mode 100644
index 0000000000000000000000000000000000000000..328be104eedbb2a8e0a1ed4968fba980927df415
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Inv_Invalid.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index ce67cf008324ae7082dababce2fdeb5aeaa73fdd..273531f9b291e422a9ae4b7a025dcfa08b5abbb5 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -229,7 +229,8 @@ with the same filename but different name
   <texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" />
   <texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" />
   <texture name="Inv_Link" file_name="icons/Inv_Link.png" preload="false" />
-
+  <texture name="Inv_Invalid" file_name="icons/Inv_Invalid.png" preload="false" />
+  
   <texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/>
   <texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/>
 
@@ -358,11 +359,16 @@ with the same filename but different name
   <texture name="Pause_Off" file_name="icons/Pause_Off.png" preload="false" />
   <texture name="Pause_Over" file_name="icons/Pause_Over.png" preload="false" />
   <texture name="Pause_Press" file_name="icons/Pause_Press.png" preload="false" />
+
+  <texture name="Permission_Visible_Online" file_name="ff_visible_online_button.tga" preload="false" />
+  <texture name="Permission_Visible_Map" file_name="ff_visible_map_button.tga" preload="false" />
+  <texture name="Permission_Edit_Objects_Mine" file_name="ff_edit_mine_button.tga" preload="false" />
+  <texture name="Permission_Edit_Objects_Theirs" file_name="ff_edit_theirs_button.tga" preload="false" />
+
   <texture name="Play_Off" file_name="icons/Play_Off.png" preload="false" />
   <texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />
   <texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
 
-
   <texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="10" scale.right="48" scale.bottom="2" />
   <texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" />
 
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_chat.xml b/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
index 20a376f1524bdc0a3eceb61bcba52000810f8b31..bea106bf28c64d37be89f35142c2450de7496885 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
@@ -56,4 +56,27 @@
 		<radio_item label="Separate vinduer" name="radio" value="0"/>
 		<radio_item label="Faner" name="radio2" value="1"/>
 	</radio_group>
+	<check_box label="Oversæt Chat" name="translate_chat_checkbox" />
+	<text name="translate_language_text" width="110">
+		Chat Sprog:
+	</text>
+	<combo_box name="translate_language_combobox" width="146">
+		<combo_box.item label="System standard" name="System Default Language"/>
+		<combo_box.item label="English (Engelsk)" name="English"/>
+		<combo_box.item label="Dansk" name="Danish"/>
+		<combo_box.item label="Deutsch (Tysk)" name="German"/>
+		<combo_box.item label="Español (Spansk)" name="Spanish"/>
+		<combo_box.item label="Français (Fransk)" name="French"/>
+		<combo_box.item label="Italiano (Italiensk)" name="Italian" />
+		<combo_box.item label="Magyar (Ungarsk)" name="Hungarian" />
+		<combo_box.item label="Nederlands (Hollandsk)" name="Dutch" />
+		<combo_box.item label="Polski (Polsk)" name="Polish" />
+		<combo_box.item label="Português (Portugisisk)" name="Portugese" />
+		<combo_box.item label="Русский (Russisk)" name="Russian" />
+		<combo_box.item label="Türkçe (Tyrkisk)" name="Turkish" />
+		<combo_box.item label="Українська (Ukrainsk)" name="Ukrainian" />
+		<combo_box.item label="中文 (简体) (Kinesisk)" name="Chinese" />
+		<combo_box.item label="日本語 (Japansk)" name="Japanese" />
+		<combo_box.item label="한국어 (Koreansk)" name="Korean" />
+	</combo_box>
 </panel>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_general.xml b/indra/newview/skins/default/xui/da/panel_preferences_general.xml
index e70cb4826264dc892765c727f2bd013660ced4e7..6a85cf4aae41c6f85f3e01e24bf3f3a32c0aebf7 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_general.xml
@@ -11,7 +11,7 @@
 		<combo_box.item label="Español (Spansk) - Beta" name="Spanish"/>
 		<combo_box.item label="Français (Fransk) - Beta" name="French"/>
 		<combo_box.item label="Polski (Polsk) - Beta" name="Polish"/>
-		<combo_box.item label="Portugués (Portugisisk) - Beta" name="Portugese"/>
+		<combo_box.item label="Português (Portugisisk) - Beta" name="Portugese"/>
 		<combo_box.item label="日本語 (Japansk) - Beta" name="(Japanese)"/>
 	</combo_box>
 	<text name="language_textbox2">
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index 3152661fd48542d82277f38139d27926e9aa9778..712f6f8b504aab2867ae799b4d5dceb292ca1224 100644
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
@@ -1117,6 +1117,9 @@
 	<string name="InvFolder Favorite">
 		Favoritter
 	</string>
+	<string name="InvFolder favorite">
+		Favoritter
+	</string>
 	<string name="InvFolder Current Outfit">
 		Nuværende sæt
 	</string>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
index 5c91b34a21f43245e201e8a7d6097734b407fda7..064eb3895bef8c2e1906a6ff310f610154d646bc 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
@@ -56,4 +56,27 @@
 		<radio_item label="Getrennte Fenster" name="radio" value="0"/>
 		<radio_item label="Registerkarten" name="radio2" value="1"/>
 	</radio_group>
+	<check_box label="Übersetzen Chat" name="translate_chat_checkbox" />
+	<text name="translate_language_text">
+		Chat-Sprache:
+	</text>
+	<combo_box name="translate_language_combobox" width="200">
+		<combo_box.item name="System Default Language" label="Betriebssystem-Einstellung" />
+		<combo_box.item name="English" label="English (Englisch)" />
+		<combo_box.item name="Danish" label="Danks (Dänisch)" />
+		<combo_box.item name="German" label="Deutsch" />
+		<combo_box.item name="Spanish" label="Español (Spanisch)" />
+		<combo_box.item name="French" label="Français (Französisch)" />
+		<combo_box.item name="Italian" label="Italiano (Italienisch)" />
+		<combo_box.item name="Hungarian" label="Magyar (Ungarisch)" />
+		<combo_box.item name="Dutch" label="Nederlands (Niederländisch)" />
+		<combo_box.item name="Polish" label="Polski (Polnisch)" />
+		<combo_box.item name="Portugese" label="Português (Portugiesisch)" />
+		<combo_box.item name="Russian" label="Русский (Russian)" />
+		<combo_box.item name="Turkish" label="Türkçe (Türkisch)" />
+		<combo_box.item name="Ukrainian" label="Українська (Ukrainisch)" />
+		<combo_box.item name="Chinese" label="中文 (简体) (Chinesisch)" />
+		<combo_box.item name="Japanese" label="日本語 (Japanisch)" />
+		<combo_box.item name="Korean" label="한국어 (Koreanisch)" />
+	</combo_box>
 </panel>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index bf7d2ef3b3fcdc3f53bc5c2544adf69a95d16ab4..1adc4e3db13b263b044e98a913c99971a34591c1 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -1147,6 +1147,9 @@
 	<string name="InvFolder Favorite">
 		Favoriten
 	</string>
+	<string name="InvFolder favorite">
+		Favoriten
+	</string>
 	<string name="InvFolder Current Outfit">
 		Aktuelles Outfit
 	</string>
diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
index 3b26c2ab5903e313e88e0290faca3a8b6e415389..4c5113aa5515147144e34a6dbf6b7e7347259b13 100644
--- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
@@ -14,7 +14,7 @@
  can_dock="true"
  bevel_style="in"
  height="300"
- min_width="150"
+ min_width="235"
  layout="topleft"
  name="nearby_chat"
  help_topic="nearby_chat"
@@ -24,15 +24,25 @@
  save_visibility="true"
  single_instance="true"
  width="320">
+            <check_box
+             bottom_delta="36"
+             control_name="TranslateChat"
+             enabled="true"
+             height="16"
+             label="Translate chat (powered by Google)"
+             layout="topleft"
+             left="5"
+             name="translate_chat_checkbox"
+             width="230" />
   <chat_history
     parse_urls="true"
     bg_readonly_color="ChatHistoryBgColor"
     bg_writeable_color="ChatHistoryBgColor"
     follows="all"
     left="5"
-    top="20"
+    top_delta="17"
     layout="topleft"
-    height="275"
+    height="260"
     name="chat_history"
     parse_highlights="true"
     text_color="ChatHistoryTextColor"
diff --git a/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml b/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
index bf0913fde771b5f80c34a7dea7bb887b8db58993..9f14e9ae0ac2b4eef088a13f1e93d99b233d31a8 100644
--- a/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
+++ b/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
@@ -2,7 +2,8 @@
 <floater
  can_close="false"
  can_resize="true"
- min_width="150"
+ min_width="333"
+ min_height="440"
  save_rect="true"
  save_visibility="true"
  >
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
index 92752a0feed87f14e5f342ddfcddc0f9d6db89b3..22796f7b68992c5e9102ca5d4ae6c2bbcd8e4d07 100644
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
@@ -31,6 +31,14 @@
      function="CheckControl"
      parameter="FriendsListShowIcons" />
   </menu_item_check>
+  <menu_item_check name="view_permissions" label="View Permissions Granted">
+    <menu_item_check.on_click
+     function="People.Friends.ViewSort.Action"
+     parameter="view_permissions" />
+    <menu_item_check.on_check
+     function="CheckControl"
+     parameter="FriendsListShowPermissions" />
+  </menu_item_check>
   <menu_item_separator layout="topleft" />
   <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
     <menu_item_call.on_click function="SideTray.ShowPanel" parameter="panel_block_list_sidetray" />
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index c79a484ef63d5b46f00b71bfe17a8dd3433f152d..19707c1bc9010cb0d90a0b310768cbc0f906096f 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1669,8 +1669,8 @@
             </menu_item_call>
             <menu_item_separator
              visible="false"/>
-            <!-- Made invisible to avoid a dissonance: menu item toggle menu where it is located. EXT-8069.
-              Can't be removed to keep sortcut workable.
+            <!-- Made invisible to avoid a dissonance: menu item toggles the menu where it is located. EXT-8069.
+              Can't be removed, to keep shortcut workable.
             -->
             <menu_item_check
              label="Show Advanced Menu"
@@ -2629,8 +2629,8 @@
                  function="Advanced.PrintTextureMemoryStats" />
             </menu_item_call>
             <menu_item_check
-             label="Double-ClickAuto-Pilot"
-             name="Double-ClickAuto-Pilot">
+             label="Double-Click Auto-Pilot"
+             name="Double-Click Auto-Pilot">
                 <menu_item_check.on_check
                  function="CheckControl"
                  parameter="DoubleClickAutoPilot" />
@@ -2638,6 +2638,16 @@
                  function="ToggleControl"
                  parameter="DoubleClickAutoPilot" />
             </menu_item_check>
+            <menu_item_check
+             label="Double-Click Teleport"
+             name="DoubleClick Teleport">
+                <menu_item_check.on_check
+                 function="CheckControl"
+                 parameter="DoubleClickTeleport" />
+                <menu_item_check.on_click
+                 function="ToggleControl"
+                 parameter="DoubleClickTeleport" />
+            </menu_item_check>
 
             <menu_item_separator />
 
diff --git a/indra/newview/skins/default/xui/en/menu_wearing_gear.xml b/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
index 747352cb291182138a0cb6f886a11d05dcc7a77d..84ab16c70954eb1bfed6ac6bde375129bcad60a8 100644
--- a/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
@@ -10,4 +10,14 @@
         <on_click
          function="Gear.Edit" />
     </menu_item_call>
+    <menu_item_call
+     label="Take Off"
+     layout="topleft"
+     name="takeoff">
+        <on_click
+         function="Gear.TakeOff" />
+        <on_enable
+         function="Gear.OnEnable"
+         parameter="take_off" />
+    </menu_item_call>
 </menu>
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index f58715be5695922d1969ca6fba28e7643c520301..b385654010e2d7be9107ac5276964d151f52d2c6 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -65,11 +65,55 @@
      height="15"
      layout="topleft"
      left_pad="5"
-     right="-72"
+     right="-164"
      name="last_interaction"
      text_color="LtGray_50"
      value="0s"
      width="35" />
+    <icon
+     height="20"
+     follows="right"
+     image_name="Permission_Visible_Online"
+     layout="topleft"
+     left_pad="3"
+     right="-141"
+     name="permission_online_icon"
+     tool_tip="This friend can see when you&apos;re online"
+     top="2"
+     width="20" />
+    <icon
+     height="20"
+     follows="right"
+     image_name="Permission_Visible_Map"
+     layout="topleft"
+     left_pad="3"
+     tool_tip="This friend can locate you on the map"
+     right="-118"
+     name="permission_map_icon"
+     top_delta="0"
+     width="20" />
+    <icon
+     height="20"
+     follows="right"
+     image_name="Permission_Edit_Objects_Mine"
+     layout="topleft"
+     left_pad="3"
+     right="-95"
+     name="permission_edit_mine_icon"
+     tool_tip="This friend can edit, delete or take your objects"
+     top_delta="0"
+     width="20" />
+    <icon
+     height="20"
+     follows="right"
+     image_name="Permission_Edit_Objects_Theirs"
+     layout="topleft"
+     left_pad="3"
+     right="-72"
+     name="permission_edit_theirs_icon"
+     tool_tip="You can edit this friend&apos;s objects"
+     top_delta="0"
+     width="20" />
     <button
      follows="right"
      height="16"
@@ -80,7 +124,7 @@
      right="-53"
      name="info_btn"
      tab_stop="false"
-     top_delta="-2"
+     top_delta="2"
      width="16" />
     <button
      follows="right"
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 4b622691b383fc34a9dc565c0b6366de2c4200f8..cdd596222d988eae7f2ed032006b9bb37aebe59a 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -11,6 +11,9 @@
  name="bottom_tray"
  top="28"
  width="1310">
+    <string
+     name="DragIndicationImageName"
+     value="Accordion_ArrowOpened_Off" />
     <string
      name="SpeakBtnToolTip"
      value="Turns microphone on/off" />
@@ -135,7 +138,7 @@
          name="movement_panel"
          user_resize="false"
          width="83">
-            <button
+            <bottomtray_button
              follows="left|right"
              height="23"
              image_pressed="PushButton_Press"
@@ -152,7 +155,8 @@
                 <init_callback
                  function="Button.SetDockableFloaterToggle"
                  parameter="moveview" />
-            </button>
+            </bottomtray_button>
+
         </layout_panel>
         <layout_panel
          auto_resize="false"
@@ -165,7 +169,7 @@
          name="cam_panel"
          user_resize="false"
          width="83">
-            <button
+            <bottomtray_button
              follows="left|right"
              height="23"
              image_pressed="PushButton_Press"
@@ -183,7 +187,7 @@
                 <init_callback
                  function="Button.SetDockableFloaterToggle"
                  parameter="camera" />
-            </button>
+            </bottomtray_button>
         </layout_panel>
         <layout_panel
          auto_resize="false"
@@ -195,7 +199,7 @@
          name="snapshot_panel"
          user_resize="false"
          width="39">
-            <button
+            <bottomtray_button
              follows="left|right"
              height="23"
              image_overlay="Snapshot_Off"
@@ -212,7 +216,7 @@
                 <init_callback
                  function="Button.SetFloaterToggle"
                  parameter="snapshot" />
-            </button>
+            </bottomtray_button>
         </layout_panel>
         <layout_panel
          auto_resize="false"
@@ -228,7 +232,7 @@
 <!--*FIX: Build Floater is not opened with default registration. Will be fixed soon.
 Disabled for now.
 -->
-            <button
+            <bottomtray_button
              follows="left|right"
              height="23"
              image_pressed="PushButton_Press"
@@ -246,7 +250,7 @@ Disabled for now.
                 <commit_callback
                  function="Build.Toggle"
                  parameter="build" />
-            </button>
+            </bottomtray_button>
         </layout_panel>
         <layout_panel
          auto_resize="false"
@@ -259,7 +263,7 @@ Disabled for now.
          name="search_btn_panel"
          user_resize="false"
          width="83">
-            <button
+            <bottomtray_button
              follows="left|right"
              height="23"
              image_pressed="PushButton_Press"
@@ -277,7 +281,7 @@ Disabled for now.
                 <init_callback
                  function="Button.SetFloaterToggle"
                  parameter="search" />
-            </button>
+            </bottomtray_button>
         </layout_panel>
         <layout_panel
          auto_resize="false"
@@ -290,7 +294,7 @@ Disabled for now.
          name="world_map_btn_panel"
          user_resize="false"
          width="83">
-            <button
+            <bottomtray_button
              follows="left|right"
              height="23"
              image_pressed="PushButton_Press"
@@ -308,7 +312,7 @@ Disabled for now.
                 <init_callback
                  function="Button.SetFloaterToggle"
                  parameter="world_map" />
-            </button>
+            </bottomtray_button>
         </layout_panel>
         <layout_panel
          auto_resize="false"
@@ -321,7 +325,7 @@ Disabled for now.
          name="mini_map_btn_panel"
          user_resize="false"
          width="83">
-            <button
+            <bottomtray_button
              follows="left|right"
              height="23"
              image_pressed="PushButton_Press"
@@ -339,7 +343,7 @@ Disabled for now.
                 <init_callback
                  function="Button.SetFloaterToggle"
                  parameter="mini_map" />
-            </button>
+            </bottomtray_button>
         </layout_panel>
         <layout_panel
          follows="left|right"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
index 8715a3a7a8515ba93008ac1a6f3ec0739b8a3106..903dcd4c2463f012ad551047f3587920483f5e3d 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
@@ -320,7 +320,7 @@
          left="10"
          name="partner_edit_link"
          value="[[URL] Edit]"
-         width="50" />
+         width="70" />
     </panel>
     </panel>
     </scroll_container>
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index eb02d4104bd4e4d4a41bee1654787c1c9ba07560..2a3add161a603c50b87a6dc9393143251e4c9851 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -84,7 +84,7 @@ background_visible="true"
       follows="all"
      left="8"
      top_pad="0"
-     height="536"
+     height="506"
      width="292"
      border_size="0">
    <layout_panel
@@ -176,15 +176,27 @@ background_visible="true"
          </accordion_tab>
          </accordion>
    </layout_panel>
-   <layout_panel
+  </layout_stack>
+  
+  <layout_stack
+     name="layout"
+     orientation="horizontal"
+     follows="bottom|left|right"
+     left="8"
+     top_pad="0"
+     height="30"
+     width="292"
+     border_size="0">
+     
+     	<layout_panel
          height="30"
          layout="topleft"
          auto_resize="false"
          left="0"
          top_pad="0"
-   name="button_row"
-   follows="bottom|left|right"
-   width="313">
+	     name="button_row"
+	     follows="bottom|left|right"
+	     width="313">
    
    		   <layout_stack
 	     	follows="bottom|left|right"
@@ -307,5 +319,7 @@ background_visible="true"
      visible="false"
      width="65" />-->
      </layout_panel>
-  </layout_stack>
+     
+     </layout_stack>
+  
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index c5d6aced7aff08471ccdf8297b6ec31ae9d5de89..f8ae238148c0634409cf23b82d88ee24d03381c7 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -57,7 +57,7 @@
      translate="false"
      value="Parcel_R_Dark" />
     <button
-     follows="top|right"
+     follows="top|left"
      height="24"
      image_hover_unselected="BackButton_Over"
      image_pressed="BackButton_Press"
diff --git a/indra/newview/skins/default/xui/en/panel_me.xml b/indra/newview/skins/default/xui/en/panel_me.xml
index 63c522ac69c104a00b49ef27c742e14fcd2f10e3..84b5d11ba71481c837615d58e0ab9a9127e652f5 100644
--- a/indra/newview/skins/default/xui/en/panel_me.xml
+++ b/indra/newview/skins/default/xui/en/panel_me.xml
@@ -26,7 +26,7 @@
    </text> -->
     <tab_container
      follows="all"
-     height="575"
+     height="555"
      halign="center"
      layout="topleft"
      left="5"
diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml
index 684d38146a280e380d2c5cfbcc3beaee6f205d00..37a1ed30480eb1cd45e9657ee0952bed6b34801f 100644
--- a/indra/newview/skins/default/xui/en/panel_my_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml
@@ -41,7 +41,7 @@
      layout="topleft"
      left="0"
      top="0"
-     height="522"
+     height="510"
      width="315"
      border_size="0">
       <layout_panel
@@ -324,82 +324,25 @@
           </panel>
         </scroll_container>
       </layout_panel>
-      <!-- <layout_panel
-     follows="bottom|left"
+      </layout_stack>
+ 	<panel
+     follows="bottom|left|right"
+     height="23"
      layout="topleft"
      left="0"
-     name="profile_buttons_panel"
-     height="28"
-     width="313">
-         <button
-         follows="bottom|left"
-         height="23"
-         label="Add Friend"
-         layout="topleft"
-         left="0"
-         mouse_opaque="false"
-         name="add_friend"
-         tool_tip="Offer friendship to the Resident"
-         top="5"
-         width="80" />
-        <button
-         follows="bottom|left"
-         height="23"
-         label="IM"
-         layout="topleft"
-         name="im"
-         top="5"
-         left_pad="3"
-         width="45" />
-        <button
-         follows="bottom|left"
-         height="23"
-         label="Call"
-         layout="topleft"
-         name="call"
-         left_pad="3"
-         top="5"
-         width="45" />
-        <button
-         enabled="false"
-         follows="bottom|left"
-         height="23"
-         label="Map"
-         layout="topleft"
-         name="show_on_map_btn"
-         top="5"
-         left_pad="3"
-         width="45" />
-        <button
-         follows="bottom|left"
-         height="23"
-         label="Teleport"
-         layout="topleft"
-         name="teleport"
-         left_pad="3"
-         top="5"
-         width="85" />
- </panel>-->
- <layout_panel
-     follows="bottom|left"
-     layout="topleft"
-     left="0"
-     top_pad="0"
+     top_pad="1"
      name="profile_me_buttons_panel"
      visible="false"
-     user_resize="false" 
-     auto_resize="false" 
-     height="28"
      width="315">
         <button
          follows="bottom"
          height="23"
          left="6"
-	 top="1"
+	 	 top="1"
          label="Edit Profile"
          name="edit_profile_btn"
          tool_tip="Edit your personal information"
          width="152" />
- </layout_panel>
-</layout_stack>
+ 	</panel>
+
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml
index 530e19195215f235ab05d9823b5fe8c14fe998c0..124b1cfc6beef726422a1ec906ac6e9f2a783a46 100644
--- a/indra/newview/skins/default/xui/en/panel_notes.xml
+++ b/indra/newview/skins/default/xui/en/panel_notes.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
  follows="all"
- height="533"
+ height="515"
  label="Notes &amp; Privacy"
  layout="topleft"
  left="0"
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index 1cbdecab9d4c98344d95fc5b09e17338e8f7b4f0..883cbb30c60f5632751009d4ef4063e19ae3d776 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -295,7 +295,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
          auto_resize="true"
          default_tab_group="3"
          height="450"
-         min_height="73"
+         min_height="80"
          name="add_wearables_panel"
          width="313"
          tab_group="2"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 059283ce095a7630bce4f8c6bf43db29402e0f99..ab8930c967c3a8a5bcdee4849e90764a04c8aefa 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -192,6 +192,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                          left="0"
                          multi_select="true"
                          name="avatars_online"
+                         show_permissions_granted="true"
                          top="0"
                          width="307" />
                 </accordion_tab>
@@ -208,6 +209,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                          left="0"
                          multi_select="true"
                          name="avatars_all"
+                         show_permissions_granted="true"
                          top="0"
                          width="307" />
                 </accordion_tab>
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index 647be28a6215c412ba1478defbd9e111ece09d36..4f7c4fa9b278172f2e6602618a6b6ebb067ed92c 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -30,7 +30,7 @@ bg_opaque_color="DkGray2"
  <accordion
   fit_parent="true" 
   follows="all"
-  height="470"
+  height="485"
   layout="topleft"
   left="0"
   name="accordion"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index ba967d3e2c0961f2bb21b9c8c2c688a99dfbad16..31e160ec3347e469b34a4f2e2a1498eb5c69c090 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -104,7 +104,7 @@
      layout="topleft"
      left="190"
      name="agent"
-     top_pad="-17"
+     top_pad="-15"
      width="44" >
 		<color_swatch.init_callback
 		 function="Pref.getUIColor"
@@ -135,7 +135,7 @@
      layout="topleft"
      left="360"
      name="im"
-     top_pad="-17"
+     top_pad="-15"
      width="44">
 		<color_swatch.init_callback
 		 function="Pref.getUIColor"
@@ -166,7 +166,7 @@
      layout="topleft"
      left="40"
      name="system"
-     top_pad="40"
+     top_pad="22"
      width="44" >
 		<color_swatch.init_callback
 		 function="Pref.getUIColor"
@@ -196,7 +196,7 @@
      layout="topleft"
      left="190"
      name="script_error"
-     top_pad="-17"
+     top_pad="-15"
      width="44">
 		<color_swatch.init_callback
 		 function="Pref.getUIColor"
@@ -226,7 +226,7 @@
      layout="topleft"
      left="360"
      name="objects"
-     top_pad="-17"
+     top_pad="-15"
      width="44" >
 		<color_swatch.init_callback
 		 function="Pref.getUIColor"
@@ -256,7 +256,7 @@
      layout="topleft"
      left="40"
      name="owner"
-     top_pad="40"
+     top_pad="22"
      width="44" >
 		<color_swatch.init_callback
 		 function="Pref.getUIColor"
@@ -286,7 +286,7 @@
      layout="topleft"
      left="190"
      name="links"
-     top_pad="-17"
+     top_pad="-15"
      width="44" >
 		<color_swatch.init_callback
 		 function="Pref.getUIColor"
@@ -316,7 +316,7 @@
      layout="topleft"
      left="30"
      name="play_typing_animation"
-     top_pad="40"
+     top_pad="32"
      width="400" />
     <check_box
      enabled="false"
@@ -343,7 +343,7 @@
      left="30"
      height="20"
      width="170"
-     top_pad="20">
+     top_pad="14">
      Show IMs in:
     </text>
     <text
@@ -386,4 +386,106 @@
       top_pad="5"
       width="150" />
     </radio_group>
+    <check_box
+     control_name="TranslateChat"
+     enabled="true"
+     height="16"
+     label="Use machine translation while chatting (powered by Google)"
+     layout="topleft"
+     left="30"
+     name="translate_chat_checkbox"
+     bottom_delta="40"
+     width="400" />
+    <text
+     bottom_delta="30"
+     name="translate_language_text"
+     follows="left|top"
+     layout="topleft"
+     left_delta="20"
+     height="20"
+     width="110">
+     Translate chat into: 
+    </text>
+    <combo_box
+     allow_text_entry="true"
+     bottom_delta="3"
+     control_name="TranslateLanguage"
+     enabled="true"
+     follows="left|top"
+     height="23"
+     left_delta="110"
+     max_chars="135"
+     mouse_opaque="true"
+     name="translate_language_combobox"
+     width="146">
+        <combo_box.item
+         label="System Default"
+         name="System Default Language"
+         value="default" />
+        <combo_box.item
+         label="English"
+         name="English"
+         value="en" />
+        <!-- After "System Default" and "English", please keep the rest of these combo_box.items in alphabetical order by the first character in the string. -->
+        <combo_box.item
+         label="Dansk (Danish)"
+         name="Danish"
+         value="da" />
+        <combo_box.item
+         label="Deutsch (German)"
+         name="German"
+         value="de" />
+        <combo_box.item
+         label="Español (Spanish)"
+         name="Spanish"
+         value="es" />
+        <combo_box.item
+         label="Français (French)"
+         name="French"
+         value="fr" />
+        <combo_box.item
+         label="Italiano (Italian)"
+         name="Italian"
+         value="it" />
+        <combo_box.item
+         label="Magyar (Hungarian)"
+         name="Hungarian"
+         value="hu" />
+        <combo_box.item
+         label="Nederlands (Dutch)"
+         name="Dutch"
+         value="nl" />
+        <combo_box.item
+         label="Polski (Polish)"
+         name="Polish"
+         value="pl" />
+        <combo_box.item
+         label="Português (Portuguese)"
+         name="Portugese"
+         value="pt" />
+        <combo_box.item
+         label="Русский (Russian)"
+         name="Russian"
+         value="ru" />
+        <combo_box.item
+         label="Türkçe (Turkish)"
+         name="Turkish"
+         value="tr" />
+        <combo_box.item
+         label="Українська (Ukrainian)"
+         name="Ukrainian"
+         value="uk" />
+        <combo_box.item
+         label="中文 (简体) (Chinese)"
+         name="Chinese"
+         value="zh" />
+        <combo_box.item
+         label="日本語 (Japanese)"
+         name="Japanese"
+         value="ja" />
+        <combo_box.item
+         label="한국어 (Korean)"
+         name="Korean"
+         value="ko" />
+    </combo_box>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index a69e8d29b0a8807a7c19190d9827558c70cfa861..17eebffa020775e846bb398ec86e89210431b4ec 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -77,7 +77,7 @@
          value="pl" />
         <combo_box.item
          enabled="true"
-         label="Portugués (Portuguese) - Beta"
+         label="Português (Portuguese) - Beta"
          name="Portugese"
          value="pt" />
         <combo_box.item
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index 88d7e68894d051ac3d466812c1259887398b4a26..e2cd27c419722eb87de35e1dd14d40cc333d50e1 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
  follows="all"
- height="540"
+ height="430"
  label="Profile"
  layout="topleft"
  left="0"
@@ -41,7 +41,7 @@
      layout="topleft"
      left="0"
      top="0"
-     height="524"
+     height="400"
      width="317"
      border_size="0">
       <layout_panel
@@ -50,7 +50,7 @@
          layout="topleft"
          top="0"
          left="0"
-         height="524"
+         height="400"
          width="317">
         <scroll_container
          color="DkGray2"
@@ -304,11 +304,25 @@
           </panel>
         </scroll_container>
       </layout_panel>
-      <layout_panel
+           
+</layout_stack>
+
+	<layout_stack
+     name="layout_verb_buttons"
+     orientation="horizontal"
+     follows="bottom|left|right"
+     layout="topleft"
+     left="2"
+     top_pad="1"
+     height="30"
+     width="315"
+     border_size="0">
+     	<layout_panel
          follows="bottom|left"
          height="30"
          layout="topleft"
          name="profile_buttons_panel"
+         top="0"
          auto_resize="false"
          width="317">
          	
@@ -448,6 +462,6 @@
          tool_tip="Edit your personal information"
          width="130" />
         </layout_panel>
+     </layout_stack>
 
-</layout_stack>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml
index 41c7b95c9f09c942ecc28ccadc403eb186c2cf5f..3b4d6ae58d97c4082c7bb27a53d139e7e7e3a442 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml
@@ -56,7 +56,7 @@
      width="150" />
     <tab_container
      follows="all"
-     height="538"
+     height="515"
      halign="center"
      layout="topleft"
      left="5"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index 4f923f411c817ec2bb2342d6e97b80b466f7ef64..182bc29e276c1deeaf9129770ef6a2304e11337a 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -79,333 +79,342 @@
      use_ellipses="true"
      value="(Inventory)"
      width="275" />
-	<panel
-         follows="all"
-         height="493"
-         help_topic=""
-         label=""
-         layout="topleft"
-         left="9"
-         name="item_profile"
-         top="45"
-         width="313"
-   background_visible="true"
-   bg_alpha_color="DkGray2">
-	    <text
-		     type="string"
-		     length="1"
-		     follows="left|top"
-		     height="10"
-		     layout="topleft"
-		     left="5"
-		     name="LabelItemNameTitle"
-		     top="10"
-		     width="78">
-	        Name:
-	    </text>
-    	<line_editor
-		     border_style="line"
-		     border_thickness="1"
-	    	 follows="left|top|right"
-		     height="20"
-		     layout="topleft"
-	    	 left_delta="78"
-		     max_length="63"
-		     name="LabelItemName"
-	    	 top_delta="0"
-		     width="225" />
-	    <text
-		     type="string"
-		     length="1"
-	    	 follows="left|top"
-	    	 height="10"
-		     layout="topleft"
-    		 left="5"
-		     name="LabelItemDescTitle"
-    		 top_pad="10"
-	    	 width="78">
-	        Description:
-	    </text>
-	    <line_editor
-		     border_style="line"
-    		 border_thickness="1"
-	    	 follows="left|top|right"
-	    	 height="23"
-		     layout="topleft"
-    		 left_delta="78"
-		     max_length="127"
-    		 name="LabelItemDesc"
-	    	 top_delta="-5"
-	    	 width="225" />
-	    <text
-		     type="string"
-		     length="1"
-		     follows="left|top"
-		     height="23"
-		     layout="topleft"
-    		 left="5"
-		     name="LabelCreatorTitle"
-		  top_pad="10"
-		     width="78">
-	        Creator:
-    	</text>
-	        <avatar_icon
-     follows="top|left"
-     height="20"
-     default_icon_name="Generic_Person"
-     layout="topleft"
-     left_pad="0"
-     top_delta="-6"
-     mouse_opaque="true"
-     width="20" />
-	    <text
-		     type="string"
-     follows="left|right|top"
-     font="SansSerifSmall"
-     height="15"
+    <scroll_container
+     color="DkGray2"
+     follows="all"
      layout="topleft"
-     left_pad="5"
-		     name="LabelCreatorName"
-		     top_delta="6"
-		     width="140">
-      </text>
-      <button
-      follows="top|right"
-      height="16"
-    image_selected="Inspector_I"
-    image_unselected="Inspector_I"
-      layout="topleft"
-      right="-5"
-      name="BtnCreator"
-      top_delta="-6"
-      width="16" />
-      <text
-      type="string"
-      length="1"
-      follows="left|top"
-      height="23"
-      layout="topleft"
-        left="5"
-      name="LabelOwnerTitle"
-        top_pad="10"
-      width="78">
-        Owner:
-      </text>
-      <avatar_icon
-        follows="top|left"
-        height="20"
-        default_icon_name="Generic_Person"
-        layout="topleft"
-        left_pad="0"
-        top_delta="-6"
-        mouse_opaque="true"
-        width="20" />
-      <text
-      type="string"
-        follows="left|right|top"
-        font="SansSerifSmall"
-        height="15"
-        layout="topleft"
-        left_pad="5"
-      name="LabelOwnerName"
-      top_delta="6"
-      width="140">
-      </text>
-	     <button
-			 follows="top|right"
-			 height="16"
-     image_selected="Inspector_I"
-     image_unselected="Inspector_I"
-			 layout="topleft"
-			 right="-5"
-			 name="BtnOwner"
-			 top_delta="-3"
-			 width="16" />
-	     <text
-			 type="string"
-			 length="1"
-			 follows="left|top"
-			 height="23"
-			 layout="topleft"
-    		 left="5"
-			 name="LabelAcquiredTitle"
-top_pad="10"
-			 width="78">
-			Acquired:
-	     </text>
-	     <text
-			 type="string"
-			 length="1"
-			 follows="left|top|right"
-			 height="23"
-			 layout="topleft"
-			 left_delta="78"
-			 name="LabelAcquiredDate"
-			 top_delta="0"
-			 width="222">
-      </text>
-	 <panel
-         border="false"
-         follows="left|top|right"
+     left="9"
+     name="item_profile_scroll"
+     opaque="true"
+     height="493"
+     width="313"
+     top="45">
+        <panel
+             follows="left|top|right"
+             height="390"
+             help_topic=""
+             label=""
+             layout="topleft"
+             left="0"
+             name="item_profile"
+             top="0"
+             width="295">
+            <text
+                 type="string"
+                 length="1"
+                 follows="left|top"
+                 height="10"
+                 layout="topleft"
+                 left="5"
+                 name="LabelItemNameTitle"
+                 top="10"
+                 width="78">
+                Name:
+            </text>
+            <line_editor
+                 border_style="line"
+                 border_thickness="1"
+                 follows="left|top|right"
+                 height="20"
+                 layout="topleft"
+                 left_delta="78"
+                 max_length="63"
+                 name="LabelItemName"
+                 top_delta="0"
+                 width="210" />
+            <text
+                 type="string"
+                 length="1"
+                 follows="left|top"
+                 height="10"
+                 layout="topleft"
+                 left="5"
+                 name="LabelItemDescTitle"
+                 top_pad="10"
+                 width="78">
+                Description:
+            </text>
+            <line_editor
+                 border_style="line"
+                 border_thickness="1"
+                 follows="left|top|right"
+                 height="23"
+                 layout="topleft"
+                 left_delta="78"
+                 max_length="127"
+                 name="LabelItemDesc"
+                 top_delta="-5"
+                 width="210" />
+            <text
+                 type="string"
+                 length="1"
+                 follows="left|top"
+                 height="23"
+                 layout="topleft"
+                 left="5"
+                 name="LabelCreatorTitle"
+              top_pad="10"
+                 width="78">
+                Creator:
+            </text>
+                <avatar_icon
+         follows="top|left"
+         height="20"
+         default_icon_name="Generic_Person"
          layout="topleft"
-         mouse_opaque="false"
-         name="perms_inv"
-         left="0"
-         top_pad="25"
-         height="155"
-         width="313">
-	  <text
-             type="string"
-             length="1"
-             left="10"
-             top_pad="13"
-             text_color="EmphasisColor"
-	     height="15"
+         left_pad="0"
+         top_delta="-6"
+         mouse_opaque="true"
+         width="20" />
+            <text
+                 type="string"
+         follows="left|right|top"
+         font="SansSerifSmall"
+         height="15"
+         layout="topleft"
+         left_pad="5"
+                 name="LabelCreatorName"
+                 top_delta="6"
+                 width="140">
+          </text>
+          <button
+          follows="top|right"
+          height="16"
+        image_selected="Inspector_I"
+        image_unselected="Inspector_I"
+          layout="topleft"
+          right="-5"
+          name="BtnCreator"
+          top_delta="-6"
+          width="16" />
+          <text
+          type="string"
+          length="1"
+          follows="left|top"
+          height="23"
+          layout="topleft"
+            left="5"
+          name="LabelOwnerTitle"
+            top_pad="10"
+          width="78">
+            Owner:
+          </text>
+          <avatar_icon
+            follows="top|left"
+            height="20"
+            default_icon_name="Generic_Person"
+            layout="topleft"
+            left_pad="0"
+            top_delta="-6"
+            mouse_opaque="true"
+            width="20" />
+          <text
+          type="string"
+            follows="left|right|top"
+            font="SansSerifSmall"
+            height="15"
+            layout="topleft"
+            left_pad="5"
+          name="LabelOwnerName"
+          top_delta="6"
+          width="140">
+          </text>
+             <button
+                 follows="top|right"
+                 height="16"
+         image_selected="Inspector_I"
+         image_unselected="Inspector_I"
+                 layout="topleft"
+                 right="-5"
+                 name="BtnOwner"
+                 top_delta="-3"
+                 width="16" />
+             <text
+                 type="string"
+                 length="1"
+                 follows="left|top"
+                 height="23"
+                 layout="topleft"
+                 left="5"
+                 name="LabelAcquiredTitle"
+    top_pad="10"
+                 width="78">
+                Acquired:
+             </text>
+             <text
+                 type="string"
+                 length="1"
+                 follows="left|top|right"
+                 height="23"
+                 layout="topleft"
+                 left_delta="78"
+                 name="LabelAcquiredDate"
+                 top_delta="0"
+                 width="210">
+          </text>
+         <panel
+             border="false"
              follows="left|top|right"
              layout="topleft"
-             name="perm_modify"
-             width="200">
-                You can:
+             mouse_opaque="false"
+             name="perms_inv"
+             left="0"
+             top_pad="25"
+             height="155"
+             width="313">
+          <text
+                 type="string"
+                 length="1"
+                 left="10"
+                 top_pad="13"
+                 text_color="EmphasisColor"
+             height="15"
+                 follows="left|top|right"
+                 layout="topleft"
+                 name="perm_modify"
+                 width="200">
+                    You can:
+                </text>
+            <check_box
+                 height="18"
+                 label="Modify"
+                 layout="topleft"
+                 left="20"
+                 name="CheckOwnerModify"
+                 top_pad="0"
+                 width="90" />
+            <check_box
+                 height="18"
+                 label="Copy"
+                 layout="topleft"
+                 left_pad="0"
+                 name="CheckOwnerCopy"
+                 width="90" />
+            <check_box
+                 height="18"
+                 label="Transfer"
+                 layout="topleft"
+                 left_pad="0"
+                 name="CheckOwnerTransfer"
+                 width="106" />
+            <text
+                 type="string"
+                 length="1"
+                 follows="left|top"
+                 height="16"
+                 layout="topleft"
+                 left="10"
+                 name="AnyoneLabel"
+                 top_pad="8"
+                 width="100">
+                Anyone:
             </text>
-	    <check_box
-			 height="18"
-			 label="Modify"
-			 layout="topleft"
-			 left="20"
-			 name="CheckOwnerModify"
-			 top_pad="0"
-			 width="90" />
-	    <check_box
-			 height="18"
-			 label="Copy"
-			 layout="topleft"
-			 left_pad="0"
-			 name="CheckOwnerCopy"
-			 width="90" />
-	    <check_box
-			 height="18"
-			 label="Transfer"
-			 layout="topleft"
-			 left_pad="0"
-			 name="CheckOwnerTransfer"
-			 width="106" />
-	    <text
-			 type="string"
-			 length="1"
-			 follows="left|top"
-			 height="16"
-			 layout="topleft"
-			 left="10"
-			 name="AnyoneLabel"
-			 top_pad="8"
-			 width="100">
-			Anyone:
-	    </text>
-	    <check_box
-			 height="18"
-			 label="Copy"
-			 layout="topleft"
-			 left_pad="0"
-			 name="CheckEveryoneCopy"
-			 top_delta="-2"
-			 width="150" />
-    	<text
-			 type="string"
-			 length="1"
-			 follows="left|top"
-			 height="16"
-			 layout="topleft"
-			 left="10"
-			 name="GroupLabel"
-			 top_pad="8"
-			 width="100">
-			Group:
-    	</text>
-	    <check_box
-			 height="18"
-			 label="Share"
-			 layout="topleft"
-			 left_pad="0"
-			 top_delta="-2"
-			 name="CheckShareWithGroup"
-			 tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."
-			 width="150" />
-	    <text
-			 type="string"
-			 length="1"
-			 follows="left|top"
-			 height="16"
-			 layout="topleft"
-			 left="10"
-			 name="NextOwnerLabel"
-			 top_pad="8"
-			 width="200"
-			 word_wrap="true">
-			Next owner:
-	    </text>
-	    <check_box
-			 height="18"
-			 label="Modify"
-			 layout="topleft"
-			 left="20"
-			 top_pad="0"
-			 name="CheckNextOwnerModify"
-			 width="90" />
-	    <check_box
-			 height="18"
-			 label="Copy"
-			 layout="topleft"
-			 left_pad="0"
-			 name="CheckNextOwnerCopy"
-			 width="90" />
-	    <check_box
-			 height="18"
-			 label="Transfer"
-			 layout="topleft"
-			 left_pad="0"
-			 name="CheckNextOwnerTransfer"
-			 tool_tip="Next owner can give away or resell this object"
-			 width="106" />
-	    </panel>
-	<check_box
-			 height="18"
-			 label="For Sale"
-			 layout="topleft"
-			 left="20"
-			 name="CheckPurchase"
-			 top_pad="20"
-			 width="100" />
-		<combo_box
-			 height="23"
-			 left_pad="0"
-			 layout="topleft"
-			 follows="left|top"
-			 name="combobox sale copy"
-			 width="170">
-			<combo_box.item
-			     label="Copy"
-			     name="Copy"
-			     value="Copy" />
-			<combo_box.item
-			     label="Original"
-			     name="Original"
-			     value="Original" />
-	    </combo_box>
-	    <spinner
-			    follows="left|top"
-			    decimal_digits="0"
-			    increment="1"
-			    control_name="Edit Cost"
-			    name="Edit Cost"
-			    label="Price: L$"
-			    label_width="75"
-			    left="120"
-			    width="170"
-			    min_val="0"
-			    height="23"
-			    max_val="999999999"
-			    top_pad="10"/>
-   </panel>
+            <check_box
+                 height="18"
+                 label="Copy"
+                 layout="topleft"
+                 left_pad="0"
+                 name="CheckEveryoneCopy"
+                 top_delta="-2"
+                 width="150" />
+            <text
+                 type="string"
+                 length="1"
+                 follows="left|top"
+                 height="16"
+                 layout="topleft"
+                 left="10"
+                 name="GroupLabel"
+                 top_pad="8"
+                 width="100">
+                Group:
+            </text>
+            <check_box
+                 height="18"
+                 label="Share"
+                 layout="topleft"
+                 left_pad="0"
+                 top_delta="-2"
+                 name="CheckShareWithGroup"
+                 tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."
+                 width="150" />
+            <text
+                 type="string"
+                 length="1"
+                 follows="left|top"
+                 height="16"
+                 layout="topleft"
+                 left="10"
+                 name="NextOwnerLabel"
+                 top_pad="8"
+                 width="200"
+                 word_wrap="true">
+                Next owner:
+            </text>
+            <check_box
+                 height="18"
+                 label="Modify"
+                 layout="topleft"
+                 left="20"
+                 top_pad="0"
+                 name="CheckNextOwnerModify"
+                 width="90" />
+            <check_box
+                 height="18"
+                 label="Copy"
+                 layout="topleft"
+                 left_pad="0"
+                 name="CheckNextOwnerCopy"
+                 width="90" />
+            <check_box
+                 height="18"
+                 label="Transfer"
+                 layout="topleft"
+                 left_pad="0"
+                 name="CheckNextOwnerTransfer"
+                 tool_tip="Next owner can give away or resell this object"
+                 width="106" />
+            </panel>
+        <check_box
+                 height="18"
+                 label="For Sale"
+                 layout="topleft"
+                 left="20"
+                 name="CheckPurchase"
+                 top_pad="20"
+                 width="100" />
+            <combo_box
+                 height="23"
+                 left_pad="0"
+                 layout="topleft"
+                 follows="left|top"
+                 name="combobox sale copy"
+                 width="170">
+                <combo_box.item
+                     label="Copy"
+                     name="Copy"
+                     value="Copy" />
+                <combo_box.item
+                     label="Original"
+                     name="Original"
+                     value="Original" />
+            </combo_box>
+            <spinner
+                    follows="left|top"
+                    decimal_digits="0"
+                    increment="1"
+                    control_name="Edit Cost"
+                    name="Edit Cost"
+                    label="Price: L$"
+                    label_width="75"
+                    left="120"
+                    width="170"
+                    min_val="0"
+                    height="23"
+                    max_val="999999999"
+                    top_pad="10"/>
+        </panel>
+    </scroll_container>
     <panel
 		 height="30"
 		 layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index cf040b10c7a5add2a8bfc9759c51e6a53d5a6da1..3fa5c7afec943027cdc66468a5a133bf95850627 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2019,6 +2019,7 @@ Clears (deletes) the media and all params from the given face.
 	<string name="Stomach">Stomach</string>
 	<string name="Left Pec">Left Pec</string>
 	<string name="Right Pec">Right Pec</string>
+	<string name="Invalid Attachment">Invalid Attachment Point</string>
 
   <!-- Avatar age computation, see LLDateUtil::ageFromDate -->
   <string name="YearsMonthsOld">[AGEYEARS] [AGEMONTHS] old</string>
@@ -2182,7 +2183,6 @@ Clears (deletes) the media and all params from the given face.
 	<string name="ATTACH_HUD_BOTTOM_LEFT">HUD Bottom Left</string>
 	<string name="ATTACH_HUD_BOTTOM">HUD Bottom</string>
 	<string name="ATTACH_HUD_BOTTOM_RIGHT">HUD Bottom Right</string>
-	<string name="Bad attachment point">Invalid Attachment Point</string>
 			
 	<!-- script editor -->
 	<string name="CursorPos">Line [LINE], Column [COLUMN]</string>
@@ -2225,7 +2225,7 @@ Clears (deletes) the media and all params from the given face.
   
   <!-- panel picks -->
   <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string>
-  <string name="NoAvatarPicksClassifiedsText">User has no picks or classfields</string>
+  <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string>
   <string name="PicksClassifiedsLoadingText">Loading...</string>
 
 	<!-- Multi Preview Floater -->
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
index fc8c9087889b9eccb63dae97221d8cc1b0406c07..22f967afe62ba623914b4057f32c58ea072540b3 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
@@ -56,4 +56,27 @@
 		<radio_item label="Varias ventanas" name="radio" value="0"/>
 		<radio_item label="Pestañas" name="radio2" value="1"/>
 	</radio_group>
+	<check_box label="Traducir Chat" name="translate_chat_checkbox" />
+	<text name="translate_language_text">
+		Idioma de chat:
+	</text>
+	<combo_box name="translate_language_combobox">
+		<combo_box.item name="System Default Language" label="Predeterminado del sistema" />
+		<combo_box.item name="English" label="English (Inglés)" />
+		<combo_box.item name="Danish" label="Dansk (Danés)" />
+		<combo_box.item name="German" label="Deutsch (Alemán)" />
+		<combo_box.item name="Spanish" label="Español" />
+		<combo_box.item name="French" label="Français (Francés)" />
+		<combo_box.item name="Italian" label="Italiano" />
+		<combo_box.item name="Hungarian" label="Magyar (Húngaro)" />
+		<combo_box.item name="Dutch" label="Nederlands (Neerlandés)" />
+		<combo_box.item name="Polish" label="Polski (Polaco)" />
+		<combo_box.item name="Portugese" label="Português (Portugués)" />
+		<combo_box.item name="Russian" label="Русский (Ruso)" />
+		<combo_box.item name="Turkish" label="Türkçe (Turco)" />
+		<combo_box.item name="Ukrainian" label="Українська (Ucraniano)" />
+		<combo_box.item name="Chinese" label="中文 (简体) (Chino)" />
+		<combo_box.item name="Japanese" label="日本語 (Japonés)" />
+		<combo_box.item name="Korean" label="한국어 (Coreano)" />
+	</combo_box>
 </panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_general.xml b/indra/newview/skins/default/xui/es/panel_preferences_general.xml
index ca157314aa560533faae96108b7a8bd4513ff414..20109cf2c514ba88b5ab0699439b2fc89bddee1b 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_general.xml
@@ -13,7 +13,7 @@
 		<combo_box.item label="Italiano - Beta" name="Italian"/>
 		<combo_box.item label="Nederlands (Neerlandés) - Beta" name="Dutch"/>
 		<combo_box.item label="Polski (Polaco) - Beta" name="Polish"/>
-		<combo_box.item label="Portugués (Portugués) - Beta" name="Portugese"/>
+		<combo_box.item label="Português (Portugués) - Beta" name="Portugese"/>
 		<combo_box.item label="日本語 (Japonés) - Beta" name="(Japanese)"/>
 	</combo_box>
 	<text name="language_textbox2">
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 9f5f1f99e76b6d03e4a2ea6f1fa4243cba25d7db..971b725d39f9936d00c3811f1895fb7dd0fa6c3a 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -1120,6 +1120,9 @@
 	<string name="InvFolder Favorite">
 		Favoritos
 	</string>
+	<string name="InvFolder favorite">
+		Favoritos
+	</string>
 	<string name="InvFolder Current Outfit">
 		Vestuario actual
 	</string>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index 76f3319525521c12e7c31f43375886fff31f2e30..ed1107f5e683f4341f4880834913f04d5417e653 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -56,4 +56,27 @@
 		<radio_item label="Plusieurs fenêtres" name="radio" value="0"/>
 		<radio_item label="Onglets" name="radio2" value="1"/>
 	</radio_group>
+		<check_box label="Traduire Chat" name="translate_chat_checkbox" />
+	<text name="translate_language_text">
+		Langue de chat :
+	</text>
+	<combo_box name="translate_language_combobox">
+		<combo_box.item name="System Default Language" label="Choix par défaut" />
+		<combo_box.item name="English" label="English (Anglais)" />
+		<combo_box.item name="Danish" label="Dansk (Danois)" />
+		<combo_box.item name="German" label="Deutsch (Allemand)" />
+		<combo_box.item name="Spanish" label="Español (Espagnol)" />
+		<combo_box.item name="French" label="Français" />
+		<combo_box.item name="Italian" label="Italiano (Italien)" />
+		<combo_box.item name="Hungarian" label="Magyar (Hongrois)" />
+		<combo_box.item name="Dutch" label="Nederlands (Néerlandais)" />
+		<combo_box.item name="Polish" label="Polski (Polonais)" />
+		<combo_box.item name="Portugese" label="Português (Portugais)" />
+		<combo_box.item name="Russian" label="Русский (Russe)" />
+		<combo_box.item name="Turkish" label="Türkçe (Turc)" />
+		<combo_box.item name="Ukrainian" label="Українська (Ukrainien)" />
+		<combo_box.item name="Chinese" label="中文 (简体) (Chinois)" />
+		<combo_box.item name="Japanese" label="日本語 (Japonais)" />
+		<combo_box.item name="Korean" label="한국어 (Coréen)" />
+	</combo_box>
 </panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
index 32451329725bad803760d57ba18676e5f9a4a3e5..20d5f754cedf4c1328d00380161248868961b5b4 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
@@ -13,7 +13,7 @@
 		<combo_box.item label="Italiano (Italien) - Bêta" name="Italian"/>
 		<combo_box.item label="Nederlands (Néerlandais) - Bêta" name="Dutch"/>
 		<combo_box.item label="Polski (Polonais) - Bêta" name="Polish"/>
-		<combo_box.item label="Portugués (Portugais) - Bêta" name="Portugese"/>
+		<combo_box.item label="Português (Portugais) - Bêta" name="Portugese"/>
 		<combo_box.item label="日本語 (Japonais) - Bêta" name="(Japanese)"/>
 	</combo_box>
 	<text name="language_textbox2">
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index f221e42e9a757e776ac9dc77343aac34b97b695d..159281f97fbc4860ca4fb45dc4b0b6209bd39bf9 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -1147,6 +1147,9 @@
 	<string name="InvFolder Favorite">
 		Favoris
 	</string>
+	<string name="InvFolder favorite">
+		Favoris
+	</string>
 	<string name="InvFolder Current Outfit">
 		Tenue actuelle
 	</string>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
index fb8ddf607de7a5cf46992ff0e40108620be6196b..d28ed41698e8ec72d788538ea77dc91d66a77323 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
@@ -56,4 +56,27 @@
 		<radio_item label="Finestre separate" name="radio" value="0"/>
 		<radio_item label="Schede" name="radio2" value="1"/>
 	</radio_group>
+	<check_box label="Traduci Chat" name="translate_chat_checkbox" />
+	<text name="translate_language_text" width="110">
+		Chat Lingua:
+	</text>
+	<combo_box name="translate_language_combobox" width="146">
+		<combo_box.item name="System Default Language" label="Default di sistema" />
+		<combo_box.item name="English" label="English" />
+		<combo_box.item name="Danish" label="Dansk (Danese)" />
+		<combo_box.item name="German" label="Deutsch (Tedesco)" />
+		<combo_box.item name="Spanish" label="Español (Spagnolo)" />
+		<combo_box.item name="French" label="Français (Francese)" />
+		<combo_box.item name="Italian" label="Italiano" />
+		<combo_box.item name="Hungarian" label="Magyar (Ungherese)" />
+		<combo_box.item name="Dutch" label="Nederlands (Olandese)" />
+		<combo_box.item name="Polish" label="Polski (Polacco)" />
+		<combo_box.item name="Portugese" label="Português (Portoghese)" />
+		<combo_box.item name="Russian" label="Русский (Russo)" />
+		<combo_box.item name="Turkish" label="Türkçe (Turco)" />
+		<combo_box.item name="Ukrainian" label="Українська (Ukraino)" />
+		<combo_box.item name="Chinese" label="中文 (简体) (Cinese)" />
+		<combo_box.item name="Japanese" label="日本語 (Giapponese)" />
+		<combo_box.item name="Korean" label="한국어 (Coreano)" />
+	</combo_box>
 </panel>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_general.xml b/indra/newview/skins/default/xui/it/panel_preferences_general.xml
index e8c826609ceafc13dbbf476b500759c2af7fedcb..60c4ed5211d4775ebba9699d53acb9c37cca83f0 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_general.xml
@@ -13,7 +13,7 @@
 		<combo_box.item label="Italiano - Beta" name="Italian"/>
 		<combo_box.item label="Nederlands (Olandese) - Beta" name="Dutch"/>
 		<combo_box.item label="Polski (Polacco) - Beta" name="Polish"/>
-		<combo_box.item label="Portugués (Portoghese) - Beta" name="Portugese"/>
+		<combo_box.item label="Português (Portoghese) - Beta" name="Portugese"/>
 		<combo_box.item label="日本語 (Giapponese) - Beta" name="(Japanese)"/>
 	</combo_box>
 	<text name="language_textbox2">
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index fb479b4653a4e847bb6324126518a503ca86ce61..fa465ee9c27e3c6bf2f6acbd2db801443b8478b5 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -1126,6 +1126,9 @@
 	<string name="InvFolder Favorite">
 		Preferiti
 	</string>
+	<string name="InvFolder favorite">
+		Preferiti
+	</string>
 	<string name="InvFolder Current Outfit">
 		Abbigliamento attuale
 	</string>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
index 86f880de0916e5ff0aecb2059d15b825d8b4bc84..4082f71a76974cc55d177f351832fe89cc27671e 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
@@ -56,4 +56,27 @@
 		<radio_item label="別々のウィンドウ" name="radio" value="0"/>
 		<radio_item label="タブ" name="radio2" value="1"/>
 	</radio_group>
+		<check_box label="翻訳チャット" name="translate_chat_checkbox" />
+	<text name="translate_language_text">
+		チャット言語:
+	</text>
+	<combo_box name="translate_language_combobox">
+		<combo_box.item name="System Default Language" label="システム・デフォルト" />
+		<combo_box.item name="English" label="English (英語)" />
+		<combo_box.item name="Danish" label="Dansk (デンマーク語)" />
+		<combo_box.item name="German" label="Deutsch (ドイツ語)" />
+		<combo_box.item name="Spanish" label="Español (スペイン語)" />
+		<combo_box.item name="French" label="Français (フランス語)" />
+		<combo_box.item name="Italian" label="Italiano (イタリア語)" />
+		<combo_box.item name="Hungarian" label="Magyar (ハンガリー語)" />
+		<combo_box.item name="Dutch" label="Nederlands (オランダ語)" />
+		<combo_box.item name="Polish" label="Polski (ポーランド語)" />
+		<combo_box.item name="Portugese" label="Português (ポルトガル語)" />
+		<combo_box.item name="Russian" label="Русский (ロシア語)" />
+		<combo_box.item name="Turkish" label="Türkçe (トルコ語)" />
+		<combo_box.item name="Ukrainian" label="Українська (ウクライナ語)" />
+		<combo_box.item name="Chinese" label="中文 (简体) (中国語)" />
+		<combo_box.item name="Japanese" label="日本語" />
+		<combo_box.item name="Korean" label="한국어 (韓国語)" />
+	</combo_box>
 </panel>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index b68b68a4f85b33232de4d9b4be7393a95495a5ca..dd59065a9ddef7b7a0662fa2d397be9ef6900824 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -1147,6 +1147,9 @@
 	<string name="InvFolder Favorite">
 		お気に入り
 	</string>
+	<string name="InvFolder favorite">
+		お気に入り
+	</string>
 	<string name="InvFolder Current Outfit">
 		着用中のアウトフィット
 	</string>
diff --git a/indra/newview/skins/default/xui/nl/panel_preferences_general.xml b/indra/newview/skins/default/xui/nl/panel_preferences_general.xml
index 9d9010a34919ac8bea24b5f221a172128d6131fd..7be570b27f35bb957a8e61225ac8bc0176e61a36 100644
--- a/indra/newview/skins/default/xui/nl/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/nl/panel_preferences_general.xml
@@ -78,7 +78,7 @@
 		<combo_box.item name="Hungarian" label="Magyar (Hongaars) - Bèta"/>
 		<combo_box.item name="Dutch" label="Nederlands - Bèta"/>
 		<combo_box.item name="Polish" label="Polski (Pools) - Bèta"/>
-		<combo_box.item name="Portugese" label="Portugués (Portugees) - Bèta"/>
+		<combo_box.item name="Portugese" label="Português (Portugees) - Bèta"/>
 		<combo_box.item name="Russian" label="Русский (Russisch) - Bèta"/>
 		<combo_box.item name="Turkish" label="Türkçe (Turks) - Bèta"/>
 		<combo_box.item name="Ukrainian" label="Українська (Oekraïens) - Bèta"/>
diff --git a/indra/newview/skins/default/xui/nl/strings.xml b/indra/newview/skins/default/xui/nl/strings.xml
index 25071b5460f11f6845f52a8b69af8d92988c7084..1ee26c3f24f1eeb18a3e9cbc02c49e6bba2685e6 100644
--- a/indra/newview/skins/default/xui/nl/strings.xml
+++ b/indra/newview/skins/default/xui/nl/strings.xml
@@ -912,6 +912,9 @@
 	<string name="InvFolder Favorite">
 		Favoriten
 	</string>
+	<string name="InvFolder favorite">
+		Favoriten
+	</string>
 	<string name="InvFolder Current Outfit">
 		Huidige Uitrusting
 	</string>
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml
index 5805df402cf30c8592a23bfb9c46b49ccdb7f404..e980d71ce44423cc18a7fef49822285f5e24b385 100644
--- a/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml
@@ -56,4 +56,27 @@
 		<radio_item label="Osobne okna" name="radio" value="0"/>
 		<radio_item label="Etykiety" name="radio2" value="1"/>
 	</radio_group>
+	<check_box label="Przetłumacz Czat" name="translate_chat_checkbox" />
+	<text name="translate_language_text">
+		Czat Język:
+	</text>
+	<combo_box name="translate_language_combobox">
+		<combo_box.item name="System Default Language" label="Domyślny" />
+		<combo_box.item name="English" label="English (Angielski)" />
+		<combo_box.item name="Danish" label="Dansk (Duński)" />
+		<combo_box.item name="German" label="Deutsch (Niemiecki)" />
+		<combo_box.item name="Spanish" label="Español (Hiszpański)" />
+		<combo_box.item name="French" label="Français (Francuski)" />
+		<combo_box.item name="Italian" label="Italiano (WÅ‚oski)" />
+		<combo_box.item name="Hungarian" label="Magyar (Węgierski)" />
+		<combo_box.item name="Dutch" label="Nederlands (Niderlandzki)" />
+		<combo_box.item name="Polish" label="Polski" />
+		<combo_box.item name="Portugese" label="Português (Portugalski)" />
+		<combo_box.item name="Russian" label="Русский (Rosyjski)" />
+		<combo_box.item name="Turkish" label="Türkçe (Turecki)" />
+		<combo_box.item name="Ukrainian" label="Українська (Ukraiński)" />
+		<combo_box.item name="Chinese" label="中文 (简体) (Chiński)" />
+		<combo_box.item name="Japanese" label="日本語 (Japoński)" />
+		<combo_box.item name="Korean" label="한국어 (Koreański)" />
+	</combo_box>
 </panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml
index 69686bcdbc280e5cf33bfeb027680a0b5f6396dc..65ea349aec8d4fed29bd2dc86556382211d147bf 100644
--- a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml
@@ -13,7 +13,7 @@
 		<combo_box.item label="Italiano (WÅ‚oski) - Beta" name="Italian"/>
 		<combo_box.item label="Nederlands (Niderlandzki) - Beta" name="Dutch"/>
 		<combo_box.item label="Polski - Beta" name="Polish"/>
-		<combo_box.item label="Portugués (Portugalski) - Beta" name="Portugese"/>
+		<combo_box.item label="Português (Portugalski) - Beta" name="Portugese"/>
 		<combo_box.item label="日本語 (Japoński) - Beta" name="(Japanese)"/>
 	</combo_box>
 	<text name="language_textbox2">
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index e2689720bfb31b86974850c02e459ad55cf768ea..f90e357373bb3a9c38f890b3f0e302266ee17845 100644
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -1114,6 +1114,12 @@
 	<string name="InvFolder Gestures">
 		Gesturki
 	</string>
+	<string name="InvFolder Favorite">
+		Ulubione
+	</string>
+	<string name="InvFolder favorite">
+		Ulubione
+	</string>
 	<string name="InvFolder Current Outfit">
 		Obecny strój
 	</string>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
index 02b0ef35fe2e1f9e381b0dfce71f168ebe80bf4f..1ec674e2e297b90b3825936618a61f311b43a0c1 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
@@ -56,4 +56,27 @@
 		<radio_item label="Janelas separadas" name="radio" value="0"/>
 		<radio_item label="Guias" name="radio2" value="1"/>
 	</radio_group>
+	<check_box label="Traduzir Chat" name="translate_chat_checkbox" />
+	<text name="translate_language_text">
+		Chat Língua:
+	</text>
+	<combo_box name="translate_language_combobox">
+		<combo_box.item name="System Default Language" label="Padrão do Sistema" />
+		<combo_box.item name="English" label="English (Inglês)" />
+		<combo_box.item name="Danish" label="Dansk (Dinamarquês)" />
+		<combo_box.item name="German" label="Deutsch (Alemão)" />
+		<combo_box.item name="Spanish" label="Español (Espanhol)" />
+		<combo_box.item name="French" label="Français (Francês)" />
+		<combo_box.item name="Italian" label="Italiano" />
+		<combo_box.item name="Hungarian" label="Magyar (Húngaro)" />
+		<combo_box.item name="Dutch" label="Nederlands (Holandês)" />
+		<combo_box.item name="Polish" label="Polski (Polonês)" />
+		<combo_box.item name="Portugese" label="Português" />
+		<combo_box.item name="Russian" label="Русский (Russo)" />
+		<combo_box.item name="Turkish" label="Türkçe (Turco)" />
+		<combo_box.item name="Ukrainian" label="Українська (Ucraniano)" />
+		<combo_box.item name="Chinese" label="中文 (简体) (Chinês)" />
+		<combo_box.item name="Japanese" label="日本語 (Japonês)" />
+		<combo_box.item name="Korean" label="한국어 (Coreano)" />
+	</combo_box>
 </panel>
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index 4bf2bda248f2c39bbcc2b99630a18f31bfac22b8..b6ecc9347bf0a9113334f61055f9544f8732763b 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -1120,6 +1120,9 @@
 	<string name="InvFolder Favorite">
 		Favoritos
 	</string>
+	<string name="InvFolder favorite">
+		Favoritos
+	</string>
 	<string name="InvFolder Current Outfit">
 		Look atual
 	</string>
diff --git a/install.xml b/install.xml
index a47a732d56a7a52572ffe110b3c10c7be8733e79..9c37b4bc1e8e2df134a2b73f9662338e765823b1 100644
--- a/install.xml
+++ b/install.xml
@@ -777,6 +777,46 @@
           </map>
         </map>
       </map>
+      <key>jsoncpp</key>
+      <map>
+        <key>copyright</key>
+        <string>json-cpp library released to Public Domain by Baptiste Lepilleur &lt;blep@users.sourceforge.net&gt;</string>
+        <key>description</key>
+        <string>jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++.</string>
+        <key>license</key>
+        <string>jsoncpp</string>
+        <key>packages</key>
+        <map>
+          <key>darwin</key>
+          <map>
+            <key>md5sum</key>
+            <string>4c6b949778099a63550898f00f3e6a5e</string>
+            <key>url</key>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jsoncpp-svn-r69-darwin-20090923.tar.bz2</uri>
+          </map>
+          <key>linux</key>
+          <map>
+            <key>md5sum</key>
+            <string>a2a94b8ca1d32f23e3e668d64023514e</string>
+            <key>url</key>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jsoncpp-svn-r69-linux-20090922.tar.bz2</uri>
+          </map>
+          <key>linux64</key>
+          <map>
+            <key>md5sum</key>
+            <string>a06ab38628ab7b53b8f3326cd942a6a8</string>
+            <key>url</key>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jsoncpp-svn-r69-linux64-20090922.tar.bz2</uri>
+          </map>
+          <key>windows</key>
+          <map>
+            <key>md5sum</key>
+            <string>caf152cfc730737c124f7612cf68fbd3</string>
+            <key>url</key>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jsoncpp-svn-r69-windows-20090922.tar.bz2</uri>
+          </map>
+        </map>
+      </map>
       <key>kdu</key>
       <map>
         <key>copyright</key>
@@ -1740,6 +1780,13 @@ Cass Everitt - cass@r3.nu
         <key>text</key>
         <string>http://nyctergatis.com/jpeglib/</string>
       </map>
+      <key>jsoncpp</key>
+      <map>
+        <key>text</key>
+        <string>The json-cpp library and this documentation are in Public Domain.  Retrieved from http://jsoncpp.sourceforge.net/ on 2009-09-04.</string>
+        <key>url</key>
+        <string>http://jsoncpp.sourceforge.net</string>
+      </map>
       <key>kdu</key>
       <map>
         <key>text</key>