From 80be4c1d2d73982ea2df6dd7ef3fc3465416c882 Mon Sep 17 00:00:00 2001
From: Steven Bennetts <steve@lindenlab.com>
Date: Tue, 12 Aug 2008 17:29:50 +0000
Subject: [PATCH] QAR-767 Combined maint-render-7 and maint-viewer-9 merge
 merge release@93398 viewer-merge-1@94007 -> release dataserver-is-deprecated

---
 doc/contributions.txt                         |   5 +
 indra/cmake/00-Common.cmake                   |   5 +
 indra/cmake/ELFIO.cmake                       |   1 +
 indra/copy_win_scripts/CMakeLists.txt         |   4 +-
 indra/linux_crash_logger/CMakeLists.txt       |  17 +-
 indra/llaudio/llaudiodecodemgr.cpp            |  10 +-
 indra/llcharacter/llkeyframemotion.cpp        |  14 +-
 indra/llcharacter/llkeyframemotion.h          |   5 +-
 indra/llcommon/llmemory.cpp                   |   1 -
 indra/llcommon/llmemtype.h                    |   1 +
 indra/llcommon/llstring.h                     |  64 +++-
 indra/llcommon/lltimer.cpp                    |   2 +-
 indra/llcommon/llversionviewer.h              |   4 +-
 indra/llimage/llimagejpeg.cpp                 |  33 +-
 indra/llimage/llimagejpeg.h                   |   4 +-
 indra/llmath/llvolume.cpp                     |  31 --
 indra/llmessage/llcurl.cpp                    |   6 +
 indra/llmessage/llcurl.h                      |   5 +
 indra/llmessage/llmessageconfig.cpp           |  17 +-
 indra/llrender/llgl.cpp                       |  16 +
 indra/llrender/llgl.h                         |   1 +
 indra/llrender/llrender.cpp                   |   6 +
 indra/llrender/llrender.h                     |   1 +
 indra/llrender/llvertexbuffer.cpp             |   3 +
 indra/llui/llbutton.cpp                       |  28 +-
 indra/llui/llbutton.h                         |   1 +
 indra/llui/llcombobox.cpp                     |   6 +
 indra/llui/llfloater.cpp                      |  51 ++-
 indra/llui/llfloater.h                        |   7 +-
 indra/llui/llmenugl.cpp                       |   7 +
 indra/llui/lltabcontainer.cpp                 |  48 ++-
 indra/llui/lltexteditor.cpp                   |   4 +-
 indra/llui/llview.cpp                         |   2 +-
 indra/llui/llview.h                           |   4 +-
 indra/llvfs/lldir.cpp                         |  37 +-
 indra/llvfs/lldir.h                           |   5 +-
 indra/llvfs/lldir_mac.cpp                     |  11 +-
 indra/llwindow/llmousehandler.h               |   7 +-
 indra/llwindow/llwindow.cpp                   |   6 +
 indra/llwindow/llwindow.h                     |   5 +-
 indra/llwindow/llwindowmacosx.cpp             |  28 +-
 indra/llwindow/llwindowmacosx.h               |   3 +
 indra/llwindow/llwindowsdl.cpp                |   6 +-
 indra/mac_crash_logger/CMakeLists.txt         |  33 +-
 .../CrashReporter.nib/classes.nib             |   8 +
 .../CrashReporter.nib/info.nib                |  20 +
 .../CrashReporter.nib/objects.xib             |  69 ++++
 indra/mac_crash_logger/Info.plist             |  26 ++
 indra/mac_updater/CMakeLists.txt              |  35 +-
 indra/mac_updater/Info.plist                  |  26 ++
 indra/mac_updater/mac_updater.cpp             |  12 +
 indra/newview/CMakeLists.txt                  |  33 +-
 indra/newview/app_settings/settings.xml       |  48 ++-
 indra/newview/featuretable.txt                |  42 +--
 indra/newview/featuretable_linux.txt          | 145 +++++---
 indra/newview/llagent.cpp                     | 105 ++++--
 indra/newview/llagent.h                       |   4 +-
 indra/newview/llappviewer.cpp                 |  81 ++++-
 indra/newview/llappviewer.h                   |   4 +
 indra/newview/llappviewerlinux.cpp            |   6 +-
 indra/newview/llappviewermacosx.cpp           |   2 +-
 indra/newview/llappviewerwin32.cpp            |   5 +-
 indra/newview/llcolorswatch.cpp               |   4 +-
 indra/newview/lldrawable.cpp                  |  88 +++--
 indra/newview/lldrawable.h                    |   2 -
 indra/newview/lldrawpoolavatar.cpp            |  10 +-
 indra/newview/lldrawpoolbump.cpp              |   2 +-
 indra/newview/lldrawpoolwlsky.cpp             |   3 +-
 indra/newview/llfeaturemanager.cpp            |   4 +
 indra/newview/llfloaterabout.cpp              |  15 +-
 indra/newview/llfloateranimpreview.cpp        |   6 +-
 indra/newview/llfloatercolorpicker.cpp        |   6 +-
 indra/newview/llfloaterfriends.cpp            | 106 ++++--
 indra/newview/llfloaterfriends.h              |   6 +-
 indra/newview/llfloaterimagepreview.cpp       |   6 +-
 indra/newview/llfloatermemleak.cpp            | 265 ++++++++++++++
 indra/newview/llfloatermemleak.h              |  89 +++++
 indra/newview/llfloaternamedesc.cpp           |   1 +
 indra/newview/llfloatertools.cpp              |   2 +-
 indra/newview/llfloatertopobjects.cpp         |   9 +-
 indra/newview/llfolderview.cpp                |  47 +--
 indra/newview/llfolderview.h                  |   2 +-
 indra/newview/llhudtext.cpp                   |  15 +
 indra/newview/llhudtext.h                     |   3 +
 indra/newview/llimpanel.cpp                   |  10 +-
 indra/newview/llinventorymodel.cpp            |  40 ++
 indra/newview/llinventorymodel.h              |   2 +
 indra/newview/lllogchat.cpp                   |  13 +
 indra/newview/lllogchat.h                     |   2 +
 indra/newview/llmaniprotate.cpp               |  57 +--
 indra/newview/llmanipscale.cpp                |  12 +-
 indra/newview/llmaniptranslate.cpp            |  26 +-
 indra/newview/llmemoryview.cpp                |   1 +
 indra/newview/llnetmap.cpp                    |   2 +-
 indra/newview/llpanelgroupgeneral.cpp         |   3 +-
 indra/newview/llpanelobject.cpp               |  60 ++-
 indra/newview/llpanelobject.h                 |   8 +-
 indra/newview/llpolymesh.cpp                  |   4 +-
 indra/newview/llpreviewtexture.cpp            |   4 +-
 indra/newview/llselectmgr.cpp                 |  36 +-
 indra/newview/llsky.h                         |   3 -
 indra/newview/llstartup.cpp                   | 147 +++++---
 indra/newview/llstartup.h                     |  17 +-
 indra/newview/llstylemap.cpp                  |  10 +
 indra/newview/llstylemap.h                    |   3 +
 indra/newview/lltextureview.cpp               |   5 +-
 indra/newview/lltool.cpp                      |   4 +-
 indra/newview/lltool.h                        |   3 +
 indra/newview/lltooldraganddrop.cpp           | 344 ++++++------------
 indra/newview/lltooldraganddrop.h             |  17 +-
 indra/newview/lltoolselect.cpp                |   7 +-
 indra/newview/lluploaddialog.cpp              |   2 +-
 indra/newview/llviewercontrol.cpp             |   7 +
 indra/newview/llviewerdisplay.cpp             |   8 +-
 indra/newview/llviewerjointattachment.cpp     |  25 +-
 indra/newview/llviewerjoystick.cpp            |  31 +-
 indra/newview/llviewermedia.cpp               |   2 +-
 indra/newview/llviewermenu.cpp                | 100 ++++-
 indra/newview/llviewermessage.cpp             |   2 +-
 indra/newview/llviewerobject.cpp              | 246 ++++++++++---
 indra/newview/llviewerobject.h                |  24 +-
 indra/newview/llviewerobjectlist.cpp          |   6 +-
 indra/newview/llviewerpartsim.cpp             | 211 ++++++-----
 indra/newview/llviewerpartsim.h               |   6 +-
 indra/newview/llviewerpartsource.cpp          |   8 +-
 indra/newview/llviewerregion.cpp              |  11 +-
 indra/newview/llviewerregion.h                |   8 +-
 indra/newview/llviewershadermgr.cpp           |   4 +
 indra/newview/llviewerwindow.cpp              | 280 ++++----------
 indra/newview/llviewerwindow.h                |  27 +-
 indra/newview/llvoavatar.cpp                  | 254 ++++++++-----
 indra/newview/llvoavatar.h                    |   9 +-
 indra/newview/llvoiceclient.cpp               |  46 ++-
 indra/newview/llvoiceclient.h                 |   1 +
 indra/newview/llvoicevisualizer.cpp           |   8 -
 indra/newview/llvopartgroup.cpp               |  19 +-
 indra/newview/llvovolume.cpp                  |  11 +-
 indra/newview/llvovolume.h                    |   1 +
 indra/newview/llwearable.h                    |   7 +-
 indra/newview/llwearablelist.cpp              |   2 +-
 indra/newview/llworld.cpp                     |   4 +-
 indra/newview/pipeline.cpp                    |  77 ++--
 indra/newview/pipeline.h                      |   6 +-
 .../skins/default/xui/ja/floater_joystick.xml |  14 +-
 indra/newview/viewer_manifest.py              |   5 +
 indra/win_crash_logger/CMakeLists.txt         |  20 +-
 146 files changed, 2852 insertions(+), 1397 deletions(-)
 create mode 100644 indra/mac_crash_logger/CrashReporter.nib/classes.nib
 create mode 100644 indra/mac_crash_logger/CrashReporter.nib/info.nib
 create mode 100644 indra/mac_crash_logger/CrashReporter.nib/objects.xib
 create mode 100644 indra/mac_crash_logger/Info.plist
 create mode 100644 indra/mac_updater/Info.plist
 create mode 100644 indra/newview/llfloatermemleak.cpp
 create mode 100644 indra/newview/llfloatermemleak.h

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 511c552a33..b9bf6f5ff9 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -79,6 +79,7 @@ bushing Spatula
 	VWR-424
 Carjay McGinnis
 	VWR-3737
+	VWR-6154
 Catherine Pfeffer
 	VWR-1282
 Dale Glass
@@ -122,6 +123,8 @@ Feep Larsson
 	VWR-447
 	VWR-1314
 	VWR-4444
+Fluf Fredriksson
+	VWR-3450
 Fremont Cunningham
 	VWR-1147
 Gudmund Shepherd
@@ -207,6 +210,7 @@ Michelle2 Zenovka
 	VWR-3749
 	VWR-4506
 	VWR-7831
+	VWR-4022
 Mm Alder
 	VWR-3777
 	VWR-4794
@@ -377,6 +381,7 @@ Wilton Lundquist
 Whoops Babii
 	VWR-631
 	VWR-1640
+	VWR-3340
 Zarkonnen Decosta
 	VWR-253
 Zi Ree
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index d404150bfd..1d697deeae 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -146,6 +146,11 @@ if (LINUX)
 
   if (VIEWER)
     add_definitions(-DAPPID=secondlife)
+    add_definitions(-fvisibility=hidden)
+    if (NOT STANDALONE)
+      # this stops us requiring a really recent glibc at runtime
+      add_definitions(-fno-stack-protector)
+    endif (NOT STANDALONE)
   endif (VIEWER)
 
   set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
diff --git a/indra/cmake/ELFIO.cmake b/indra/cmake/ELFIO.cmake
index e420ce27bb..e51993b0f7 100644
--- a/indra/cmake/ELFIO.cmake
+++ b/indra/cmake/ELFIO.cmake
@@ -9,6 +9,7 @@ elseif (LINUX)
   use_prebuilt_binary(elfio)
   set(ELFIO_LIBRARIES ELFIO)
   set(ELFIO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
+  set(ELFIO_FOUND "YES")
 endif (STANDALONE)
 
 if (ELFIO_FOUND)
diff --git a/indra/copy_win_scripts/CMakeLists.txt b/indra/copy_win_scripts/CMakeLists.txt
index 35581e83fe..93a8c1d6d2 100644
--- a/indra/copy_win_scripts/CMakeLists.txt
+++ b/indra/copy_win_scripts/CMakeLists.txt
@@ -24,12 +24,12 @@ foreach(file ${file-list})
         set(win_scripts-files ${win_scripts-files} ${file})
     endif(EXISTS ${win_scripts-src}/${file})
 endforeach(file ${file-list})
-    
+
 copy_if_different(
     ${win_scripts-src} 
     ${win_scripts-dst} 
     win_scripts-targets 
     ${win_scripts-files} 
     )
-    
+
 add_custom_target(copy_win_scripts ALL DEPENDS ${win_scripts-targets})
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
index a3a4d6be0b..628d4acefc 100644
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ b/indra/linux_crash_logger/CMakeLists.txt
@@ -57,25 +57,12 @@ target_link_libraries(linux-crash-logger
     )
 
 add_custom_command(
-    OUTPUT linux-crash-logger-stripped-globalsyms
+    OUTPUT linux-crash-logger-stripped
     COMMAND strip
-    ARGS --strip-debug -o linux-crash-logger-stripped-globalsyms
+    ARGS --strip-debug -o linux-crash-logger-stripped
          linux-crash-logger
     DEPENDS linux-crash-logger
     )
 
-add_custom_command(
-    OUTPUT linux-crash-logger-stripped
-    COMMAND objcopy
-    ARGS
-      --keep-global-symbols
-      ${VIEWER_DIR}/newview/linux_tools/exposed-symbols.txt
-      linux-crash-logger-stripped-globalsyms
-      linux-crash-logger-stripped
-    DEPENDS
-      linux-crash-logger-stripped-globalsyms
-      ${VIEWER_DIR}/newview/linux_tools/exposed-symbols.txt
-    )
-
 add_custom_target(linux-crash-logger-stripped ALL
                   DEPENDS linux-crash-logger-stripped)
diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index d45026c2df..699f0e65de 100644
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -386,7 +386,7 @@ BOOL LLVorbisDecodeState::finishDecode()
 		mWAVBuffer[7] = (data_length >> 24) & 0x000000FF;
 
 		//
-		// FUCK!!! Vorbis encode/decode messes up loop point transitions (pop)
+		// FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop)
 		// do a cheap-and-cheesy crossfade 
 		//
 		{
@@ -413,12 +413,12 @@ BOOL LLVorbisDecodeState::finishDecode()
 			if((WAV_HEADER_SIZE+(2 * fade_length)) < (S32)mWAVBuffer.size())
 			{
 				memcpy(&mWAVBuffer[WAV_HEADER_SIZE], pcmout, (2 * fade_length));	/*Flawfinder: ignore*/
-		    }
+			}
 			S32 near_end = mWAVBuffer.size() - (2 * fade_length);
 			if ((S32)mWAVBuffer.size() >= ( near_end + 2* fade_length))
 			{
 				memcpy(pcmout, &mWAVBuffer[near_end], (2 * fade_length));	/*Flawfinder: ignore*/
-		    }
+			}
 			llendianswizzle(&pcmout, 2, fade_length);
 
 			samplep = (S16 *)pcmout;
@@ -443,8 +443,8 @@ BOOL LLVorbisDecodeState::finishDecode()
 		}
 #if !defined(USE_WAV_VFILE)
 		mBytesRead = -1;
-		mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, data_length,
-												 new WriteResponder(this));
+		mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, mWAVBuffer.size(),
+							 new WriteResponder(this));
 #endif
 	}
 
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index 710cd44a6f..090e1913cf 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -655,9 +655,9 @@ BOOL LLKeyframeMotion::setupPose()
 BOOL LLKeyframeMotion::onActivate()
 {
 	// If the keyframe anim has an associated emote, trigger it. 
-	if( mEmoteName.length() > 0 )
+	if( mJointMotionList->mEmoteName.length() > 0 )
 	{
-		mCharacter->startMotion( gAnimLibrary.stringToAnimState(mEmoteName) );
+		mCharacter->startMotion( gAnimLibrary.stringToAnimState(mJointMotionList->mEmoteName) );
 	}
 
 	mLastLoopedTime = 0.f;
@@ -1230,7 +1230,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
 	//-------------------------------------------------------------------------
 	// get emote (optional)
 	//-------------------------------------------------------------------------
-	if (!dp.unpackString(mEmoteName, "emote_name"))
+	if (!dp.unpackString(mJointMotionList->mEmoteName, "emote_name"))
 	{
 		llwarns << "can't read optional_emote_animation" << llendl;
 		return FALSE;
@@ -1672,7 +1672,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
 				if (!parent)
 				{
 					llwarns << "Joint with no parent: " << joint->getName()
-							<< " Emote: " << mEmoteName << llendl;
+							<< " Emote: " << mJointMotionList->mEmoteName << llendl;
 					return FALSE;
 				}
 				joint = parent;
@@ -1710,7 +1710,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
 	success &= dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version");
 	success &= dp.packS32(mJointMotionList->mBasePriority, "base_priority");
 	success &= dp.packF32(mJointMotionList->mDuration, "duration");
-	success &= dp.packString(mEmoteName, "emote_name");
+	success &= dp.packString(mJointMotionList->mEmoteName, "emote_name");
 	success &= dp.packF32(mJointMotionList->mLoopInPoint, "loop_in_point");
 	success &= dp.packF32(mJointMotionList->mLoopOutPoint, "loop_out_point");
 	success &= dp.packS32(mJointMotionList->mLoop, "loop");
@@ -1848,11 +1848,11 @@ void LLKeyframeMotion::setEmote(const LLUUID& emote_id)
 	const char* emote_name = gAnimLibrary.animStateToString(emote_id);
 	if (emote_name)
 	{
-		mEmoteName = emote_name;
+		mJointMotionList->mEmoteName = emote_name;
 	}
 	else
 	{
-		mEmoteName = "";
+		mJointMotionList->mEmoteName = "";
 	}
 }
 
diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h
index a50447c3bf..d11aec1ed8 100644
--- a/indra/llcharacter/llkeyframemotion.h
+++ b/indra/llcharacter/llkeyframemotion.h
@@ -420,6 +420,10 @@ public:
 		typedef std::list<JointConstraintSharedData*> constraint_list_t;
 		constraint_list_t		mConstraints;
 		LLBBoxLocal				mPelvisBBox;
+		// mEmoteName is a facial motion, but it's necessary to appear here so that it's cached.
+		// TODO: LLKeyframeDataCache::getKeyframeData should probably return a class containing 
+		// JointMotionList and mEmoteName, see LLKeyframeMotion::onInitialize.
+		std::string				mEmoteName; 
 	public:
 		JointMotionList();
 		~JointMotionList();
@@ -439,7 +443,6 @@ protected:
 	std::vector<LLPointer<LLJointState> > mJointStates;
 	LLJoint*						mPelvisp;
 	LLCharacter*					mCharacter;
-	std::string						mEmoteName;
 	typedef std::list<JointConstraint*>	constraint_list_t;
 	constraint_list_t				mConstraints;
 	U32								mLastSkeletonSerialNum;
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 56879f4e73..c6008052c3 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -335,7 +335,6 @@ U64 getCurrentRSS()
 U64 getCurrentRSS()
 {
 	U64 residentSize = 0;
-
 	task_basic_info_data_t basicInfo;
 	mach_msg_type_number_t  basicInfoCount = TASK_BASIC_INFO_COUNT;
 	if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
diff --git a/indra/llcommon/llmemtype.h b/indra/llcommon/llmemtype.h
index 2e275bd523..e16b7713a9 100644
--- a/indra/llcommon/llmemtype.h
+++ b/indra/llcommon/llmemtype.h
@@ -80,6 +80,7 @@ public:
 		MTYPE_SPACE_PARTITION,
 		MTYPE_PIPELINE,
 		MTYPE_AVATAR,
+		MTYPE_AVATAR_MESH,
 		MTYPE_PARTICLES,
 		MTYPE_REGIONS,
 		MTYPE_INVENTORY,
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 50681b7967..475531a2ad 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -155,6 +155,16 @@ public:
 	static BOOL isDigit(llwchar a) { return iswdigit(a) != 0; }
 };
 
+// Allowing assignments from non-strings into format_map_t is apparently
+// *really* error-prone, so subclass std::string with just basic c'tors.
+class FormatMapString : public std::string
+{
+public:
+	FormatMapString() : std::string() {};
+	FormatMapString(const char* s) : std::string(s) {};
+	FormatMapString(const std::string& s) : std::string(s) {};
+};
+
 template <class T>
 class LLStringUtilBase
 {
@@ -167,7 +177,7 @@ public:
 
 	static std::basic_string<T> null;
 	
-	typedef std::map<std::basic_string<T>, std::basic_string<T> > format_map_t;
+	typedef std::map<FormatMapString, FormatMapString> format_map_t;
 	static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map);
 	
 	static BOOL	isValidIndex(const std::basic_string<T>& string, size_type i)
@@ -516,27 +526,57 @@ namespace LLStringFn
 
 ////////////////////////////////////////////////////////////
 
+// LLStringBase::format()
+//
+// This function takes a string 's' and a map 'fmt_map' of strings-to-strings.
+// All occurances of strings in 's' from the left-hand side of 'fmt_map' are
+// then replaced with the corresponding right-hand side of 'fmt_map', non-
+// recursively.  The function returns the number of substitutions made.
+
 // static
 template<class T> 
 S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map)
 {
 	typedef typename std::basic_string<T>::size_type string_size_type_t;
-	typedef typename format_map_t::const_iterator format_map_const_iterator_t;
+	string_size_type_t scanstart = 0;
 	S32 res = 0;
-	for (format_map_const_iterator_t iter = fmt_map.begin(); iter != fmt_map.end(); ++iter)
+
+	// Look for the first match of any keyword, replace that keyword,
+	// repeat from the end of the replacement string.  This avoids
+	// accidentally performing substitution on a substituted string.
+	while (1)
 	{
-		U32 fmtlen = iter->first.size();
-		string_size_type_t n = 0;
-		while (1)
+		string_size_type_t first_match_pos = scanstart;
+		string_size_type_t first_match_str_length = 0;
+		std::basic_string<T> first_match_str_replacement;
+
+		for (format_map_t::const_iterator iter = fmt_map.begin();
+		     iter != fmt_map.end();
+		     ++iter)
 		{
-			n = s.find(iter->first, n);
-			if (n == std::basic_string<T>::npos)
+			string_size_type_t n = s.find(iter->first, scanstart);
+			if (n != std::basic_string<T>::npos &&
+			    (n < first_match_pos ||
+			     0 == first_match_str_length))
 			{
-				break;
+				first_match_pos = n;
+				first_match_str_length = iter->first.length();
+				first_match_str_replacement = iter->second;
 			}
-			s.erase(n, fmtlen);
-			s.insert(n, iter->second);
-			n += fmtlen;
+		}
+
+		if (0 == first_match_str_length)
+		{
+			// no more keys found to substitute from this point
+			// in the string forward.
+			break;
+		}
+		else
+		{
+			s.erase(first_match_pos, first_match_str_length);
+			s.insert(first_match_pos, first_match_str_replacement);
+			scanstart = first_match_pos +
+				first_match_str_replacement.length();
 			++res;
 		}
 	}
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 77d683adc0..7570420d2c 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -538,7 +538,7 @@ void LLEventTimer::updateClass()
 	{
 		LLEventTimer* timer = *iter++;
 		F32 et = timer->mEventTimer.getElapsedTimeF32();
-		if (et > timer->mPeriod) {
+		if (timer->mEventTimer.getStarted() && et > timer->mPeriod) {
 			timer->mEventTimer.reset();
 			if ( timer->tick() )
 			{
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index f58154602b..0555b9ea3c 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -33,8 +33,8 @@
 #define LL_LLVERSIONVIEWER_H
 
 const S32 LL_VERSION_MAJOR = 1;
-const S32 LL_VERSION_MINOR = 20;
-const S32 LL_VERSION_PATCH = 15;
+const S32 LL_VERSION_MINOR = 21;
+const S32 LL_VERSION_PATCH = 0;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Release";
diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp
index 1bddd7a051..aab19aa261 100644
--- a/indra/llimage/llimagejpeg.cpp
+++ b/indra/llimage/llimagejpeg.cpp
@@ -35,6 +35,7 @@
 
 #include "llerror.h"
 
+jmp_buf	LLImageJPEG::sSetjmpBuffer ;
 LLImageJPEG::LLImageJPEG(S32 quality) 
 	:
 	LLImageFormatted(IMG_CODEC_JPEG),
@@ -42,8 +43,6 @@ LLImageJPEG::LLImageJPEG(S32 quality)
 	mOutputBufferSize( 0 ),
 	mEncodeQuality( quality ) // on a scale from 1 to 100
 {
-	// Including in initializer list above generates warning on VC2005
-	memset(mSetjmpBuffer, 0, sizeof(mSetjmpBuffer));
 }
 
 LLImageJPEG::~LLImageJPEG()
@@ -78,7 +77,16 @@ BOOL LLImageJPEG::updateData()
 	jerr.error_exit =		&LLImageJPEG::errorExit;			// Error exit handler: does not return to caller
 	jerr.emit_message =		&LLImageJPEG::errorEmitMessage;		// Conditionally emit a trace or warning message
 	jerr.output_message =	&LLImageJPEG::errorOutputMessage;	// Routine that actually outputs a trace or error message
-
+	
+	//
+	//try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error
+	//so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao 
+	//
+	if(setjmp(sSetjmpBuffer))
+	{
+		jpeg_destroy_decompress(&cinfo);
+		return FALSE;
+	}
 	try
 	{
 		// Now we can initialize the JPEG decompression object.
@@ -210,7 +218,15 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
 	jerr.emit_message =		&LLImageJPEG::errorEmitMessage;		// Conditionally emit a trace or warning message
 	jerr.output_message =	&LLImageJPEG::errorOutputMessage;	// Routine that actually outputs a trace or error message
 	
-
+	//
+	//try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error
+	//so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao 
+	//
+	if(setjmp(sSetjmpBuffer))
+	{
+		jpeg_destroy_decompress(&cinfo);
+		return FALSE;
+	}
 	try
 	{
 		// Now we can initialize the JPEG decompression object.
@@ -404,7 +420,7 @@ void LLImageJPEG::errorExit( j_common_ptr cinfo )
 	jpeg_destroy(cinfo);
 
 	// Return control to the setjmp point
-	throw 1;
+	longjmp(sSetjmpBuffer, 1) ;
 }
 
 // Decide whether to emit a trace or warning message.
@@ -502,8 +518,11 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
 	jerr.emit_message =		&LLImageJPEG::errorEmitMessage;		// Conditionally emit a trace or warning message
 	jerr.output_message =	&LLImageJPEG::errorOutputMessage;	// Routine that actually outputs a trace or error message
 
-	// Establish the setjmp return context mSetjmpBuffer.  Used by library to abort.
-	if( setjmp(mSetjmpBuffer) ) 
+	//
+	//try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error
+	//so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao 
+	//
+	if( setjmp(sSetjmpBuffer) ) 
 	{
 		// If we get here, the JPEG code has signaled an error.
 		// We need to clean up the JPEG object, close the input file, and return.
diff --git a/indra/llimage/llimagejpeg.h b/indra/llimage/llimagejpeg.h
index 36d3454d4b..85e69d9b8f 100644
--- a/indra/llimage/llimagejpeg.h
+++ b/indra/llimage/llimagejpeg.h
@@ -84,8 +84,8 @@ protected:
 	S32				mOutputBufferSize;	// bytes in mOuputBuffer
 
 	S32				mEncodeQuality;		// on a scale from 1 to 100
-
-	jmp_buf			mSetjmpBuffer;		// To allow the library to abort.
+private:
+	static jmp_buf	sSetjmpBuffer;		// To allow the library to abort.
 };
 
 #endif  // LL_LLIMAGEJPEG_H
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 242b0809eb..7418be46cc 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -280,9 +280,6 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
 	F32 t, t_step, t_first, t_fraction, ang, ang_step;
 	LLVector3 pt1,pt2;
 
-	mMaxX = 0.f;
-	mMinX = 0.f;
-
 	F32 begin  = params.getBegin();
 	F32 end    = params.getEnd();
 
@@ -318,15 +315,6 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
 	if (t_fraction < 0.9999f)
 	{
 		LLVector3 new_pt = lerp(pt1, pt2, t_fraction);
-		F32 pt_x = new_pt.mV[VX];
-		if (pt_x < mMinX)
-		{
-			mMinX = pt_x;
-		}
-		else if (pt_x > mMaxX)
-		{
-			mMaxX = pt_x;
-		}
 		mProfile.push_back(new_pt);
 	}
 
@@ -336,16 +324,6 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
 		// Iterate through all the integer steps of t.
 		pt1.setVec(cos(ang)*scale,sin(ang)*scale,t);
 
-		F32 pt_x = pt1.mV[VX];
-		if (pt_x < mMinX)
-		{
-			mMinX = pt_x;
-		}
-		else if (pt_x > mMaxX)
-		{
-			mMaxX = pt_x;
-		}
-
 		if (mProfile.size() > 0) {
 			LLVector3 p = mProfile[mProfile.size()-1];
 			for (S32 i = 0; i < split && mProfile.size() > 0; i++) {
@@ -369,15 +347,6 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
 	if (t_fraction > 0.0001f)
 	{
 		LLVector3 new_pt = lerp(pt1, pt2, t_fraction);
-		F32 pt_x = new_pt.mV[VX];
-		if (pt_x < mMinX)
-		{
-			mMinX = pt_x;
-		}
-		else if (pt_x > mMaxX)
-		{
-			mMaxX = pt_x;
-		}
 		
 		if (mProfile.size() > 0) {
 			LLVector3 p = mProfile[mProfile.size()-1];
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 376b2ecc99..c3ffbcc8ed 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -101,6 +101,12 @@ void LLCurl::setCAFile(const std::string& file)
 	sCAFile = file;
 }
 
+//static
+std::string LLCurl::getVersionString()
+{
+	return std::string(curl_version());
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
 LLCurl::Responder::Responder()
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index b7634d420f..0700befab3 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -134,6 +134,11 @@ public:
 	 * @ brief Set certificate authority path used to verify HTTPS certs.
 	 */
 	static void setCAPath(const std::string& path);
+
+	/**
+	 * @ brief Return human-readable string describing libcurl version.
+	 */
+	static std::string getVersionString();
 	
 	/**
 	 * @ brief Get certificate authority file used to verify HTTPS certs.
diff --git a/indra/llmessage/llmessageconfig.cpp b/indra/llmessage/llmessageconfig.cpp
index 0159eb3562..8f957f4ebf 100644
--- a/indra/llmessage/llmessageconfig.cpp
+++ b/indra/llmessage/llmessageconfig.cpp
@@ -52,13 +52,14 @@ static LLSD sMessages;
 class LLMessageConfigFile : public LLLiveFile
 {
 public:
-	LLMessageConfigFile()
-        : LLLiveFile(filename(), messageConfigRefreshRate)
+	LLMessageConfigFile() :
+		LLLiveFile(filename(), messageConfigRefreshRate),
+		mMaxQueuedEvents(0)
             { }
 
-    static std::string filename();
+	static std::string filename();
 
-    LLSD mMessages;
+	LLSD mMessages;
 	std::string mServerDefault;
 	
 	static LLMessageConfigFile& instance();
@@ -66,7 +67,7 @@ public:
 
 	/* virtual */ void loadFile();
 	void loadServerDefaults(const LLSD& data);
-	 void loadMaxQueuedEvents(const LLSD& data);
+	void loadMaxQueuedEvents(const LLSD& data);
 	void loadMessages(const LLSD& data);
 	void loadCapBans(const LLSD& blacklist);
 	void loadMessageBans(const LLSD& blacklist);
@@ -74,7 +75,10 @@ public:
 
 public:
 	LLSD mCapBans;
-	 S32 mMaxQueuedEvents;
+	S32 mMaxQueuedEvents;
+
+private:
+	static const S32 DEFAULT_MAX_QUEUED_EVENTS = 100;
 };
 
 std::string LLMessageConfigFile::filename()
@@ -125,7 +129,6 @@ void LLMessageConfigFile::loadServerDefaults(const LLSD& data)
 	mServerDefault = data["serverDefaults"][sServerName].asString();
 }
 
-const S32 DEFAULT_MAX_QUEUED_EVENTS = 100;
 void LLMessageConfigFile::loadMaxQueuedEvents(const LLSD& data)
 {
 	 if (data.has("maxQueuedEvents"))
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 8c63122cb8..bd7cdf3d70 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -284,6 +284,7 @@ LLGLManager::LLGLManager() :
 	mIsGF3(FALSE),
 	mIsGFFX(FALSE),
 	mATIOffsetVerticalLines(FALSE),
+	mATIOldDriver(FALSE),
 
 	mHasRequirements(TRUE),
 
@@ -381,6 +382,17 @@ bool LLGLManager::initGL()
 			mATIOffsetVerticalLines = TRUE;
 		}
 #endif // LL_WINDOWS
+
+#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
+		// release 7277 is a point at which we verify that ATI OpenGL
+		// drivers get pretty stable with SL, ~Catalyst 8.2,
+		// for both Win32 and Linux.
+		if (mDriverVersionRelease < 7277 &&
+		    mDriverVersionRelease != 0) // 0 == Undetectable driver version - these get to pretend to be new ATI drivers, though that decision may be revisited.
+		{
+			mATIOldDriver = TRUE;
+		}
+#endif // (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
 	}
 	else if (mGLVendor.find("NVIDIA ") != std::string::npos)
 	{
@@ -988,6 +1000,10 @@ void LLGLState::initClass()
 {
 	sStateMap[GL_DITHER] = GL_TRUE;
 	sStateMap[GL_TEXTURE_2D] = GL_TRUE;
+
+	//make sure multisample defaults to disabled
+	sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
+	glDisable(GL_MULTISAMPLE_ARB);
 }
 
 //static
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index e9b4c7929e..f387b7b179 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -100,6 +100,7 @@ public:
 	BOOL mIsGF3;
 	BOOL mIsGFFX;
 	BOOL mATIOffsetVerticalLines;
+	BOOL mATIOldDriver;
 
 	// Whether this version of GL is good enough for SL to use
 	BOOL mHasRequirements;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index fc911de46b..4a87424bb8 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -451,6 +451,12 @@ void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
 	glTranslatef(x,y,z);
 }
 
+void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
+{
+	flush();
+	glScalef(x,y,z);
+}
+
 void LLRender::pushMatrix()
 {
 	flush();
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index a0a492bc73..2d512ab543 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -178,6 +178,7 @@ public:
 	~LLRender();
 
 	void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
+	void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
 	void pushMatrix();
 	void popMatrix();
 
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 2e827ed442..3f2eb61641 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -190,6 +190,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 	if (mode > NUM_MODES)
 	{
 		llerrs << "Invalid draw mode: " << mode << llendl;
+		return;
 	}
 
 	glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, 
@@ -217,6 +218,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 	if (mode > NUM_MODES)
 	{
 		llerrs << "Invalid draw mode: " << mode << llendl;
+		return;
 	}
 
 	glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
@@ -240,6 +242,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 	if (mode > NUM_MODES)
 	{
 		llerrs << "Invalid draw mode: " << mode << llendl;
+		return;
 	}
 
 	glDrawArrays(sGLMode[mode], first, count);
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 4f5f630fcd..3f6338006f 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -208,6 +208,7 @@ void LLButton::init(void (*click_callback)(void*), void *callback_data, const LL
 	mHighlightColor = (				LLUI::sColorsGroup->getColor( "ButtonUnselectedFgColor" ) );
 	mUnselectedBgColor = (				LLUI::sColorsGroup->getColor( "ButtonUnselectedBgColor" ) );
 	mSelectedBgColor = (				LLUI::sColorsGroup->getColor( "ButtonSelectedBgColor" ) );
+	mFlashBgColor = (				LLUI::sColorsGroup->getColor( "ButtonFlashBgColor" ) );
 
 	mImageOverlayAlignment = LLFontGL::HCENTER;
 	mImageOverlayColor = LLColor4::white;
@@ -433,7 +434,9 @@ void LLButton::draw()
 					|| mToggleState;
 	
 	BOOL use_glow_effect = FALSE;
-	if ( mNeedsHighlight || flash )
+	LLColor4 glow_color = LLColor4::white;
+	LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
+	if ( mNeedsHighlight )
 	{
 		if (pressed)
 		{
@@ -469,6 +472,16 @@ void LLButton::draw()
 		mImagep = mImageUnselected;
 	}
 
+	if (mFlashing)
+	{
+		use_glow_effect = TRUE;
+		glow_type = LLRender::BT_ALPHA; // blend the glow
+		if (mNeedsHighlight) // highlighted AND flashing
+			glow_color = (glow_color*0.5f + mFlashBgColor*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
+		else
+			glow_color = mFlashBgColor;
+	}
+
 	// Override if more data is available
 	// HACK: Use gray checked state to mean either:
 	//   enabled and tentative
@@ -555,7 +568,10 @@ void LLButton::draw()
 	
 	if (use_glow_effect)
 	{
-		mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f));
+		mCurGlowStrength = lerp(mCurGlowStrength,
+					mFlashing ? (flash? 1.0 : 0.0)
+					: mHoverGlowStrength,
+					LLCriticalDamp::getInterpolant(0.05f));
 	}
 	else
 	{
@@ -571,8 +587,8 @@ void LLButton::draw()
 			mImagep->draw(getLocalRect(), getEnabled() ? mImageColor : mDisabledImageColor  );
 			if (mCurGlowStrength > 0.01f)
 			{
-				gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
-				mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
+				gGL.setSceneBlendType(glow_type);
+				mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), glow_color % mCurGlowStrength);
 				gGL.setSceneBlendType(LLRender::BT_ALPHA);
 			}
 		}
@@ -581,8 +597,8 @@ void LLButton::draw()
 			mImagep->draw(0, 0, getEnabled() ? mImageColor : mDisabledImageColor );
 			if (mCurGlowStrength > 0.01f)
 			{
-				gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
-				mImagep->drawSolid(0, 0, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
+				gGL.setSceneBlendType(glow_type);
+				mImagep->drawSolid(0, 0, glow_color % mCurGlowStrength);
 				gGL.setSceneBlendType(LLRender::BT_ALPHA);
 			}
 		}
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 9e24376938..2c35614401 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -267,6 +267,7 @@ private:
 	LLColor4		mHighlightColor;
 	LLColor4		mUnselectedBgColor;
 	LLColor4		mSelectedBgColor;
+	LLColor4		mFlashBgColor;
 
 	LLColor4		mImageColor;
 	LLColor4		mDisabledImageColor;
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 8d8487f612..89ce68a32e 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -774,6 +774,12 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask)
 	BOOL result = FALSE;
 	if (hasFocus())
 	{
+		if (mList->getVisible() 
+			&& key == KEY_ESCAPE && mask == MASK_NONE)
+		{
+			hideList();
+			return TRUE;
+		}
 		//give list a chance to pop up and handle key
 		LLScrollListItem* last_selected_item = mList->getLastSelectedItem();
 		if (last_selected_item)
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 838f6fa193..7f8f54a44a 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -649,24 +649,55 @@ void LLFloater::applyRectControl()
 	}
 }
 
-void LLFloater::setTitle( const std::string& title )
+void LLFloater::applyTitle()
 {
 	if (gNoRender)
 	{
 		return;
 	}
-	if (mDragHandle)
-		mDragHandle->setTitle( title );
+
+	if (!mDragHandle)
+	{
+		return;
+	}
+
+	if (isMinimized() && !mShortTitle.empty())
+	{
+		mDragHandle->setTitle( mShortTitle );
+	}
+	else
+	{
+		mDragHandle->setTitle ( mTitle );
+	}
 }
 
-const std::string& LLFloater::getTitle() const
+const std::string& LLFloater::getCurrentTitle() const
 {
 	return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null;
 }
 
+void LLFloater::setTitle( const std::string& title )
+{
+	mTitle = title;
+	applyTitle();
+}
+
+std::string LLFloater::getTitle()
+{
+	if (mTitle.empty())
+	{
+		return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null;
+	}
+	else
+	{
+		return mTitle;
+	}
+}
+
 void LLFloater::setShortTitle( const std::string& short_title )
 {
 	mShortTitle = short_title;
+	applyTitle();
 }
 
 std::string LLFloater::getShortTitle()
@@ -895,6 +926,9 @@ void LLFloater::setMinimized(BOOL minimize)
 		// Reshape *after* setting mMinimized
 		reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
 	}
+	
+	applyTitle ();
+
 	make_ui_sound("UISndWindowClose");
 	updateButtons();
 }
@@ -1340,7 +1374,7 @@ void LLFloater::draw()
 			gl_rect_2d( left, top, right, bottom, getTransparentColor() );
 		}
 
-		if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getTitle().empty())
+		if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getCurrentTitle().empty())
 		{
 			// draw highlight on title bar to indicate focus.  RDW
 			const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
@@ -2846,7 +2880,7 @@ LLXMLNodePtr LLFloater::getXML(bool save_children) const
 {
 	LLXMLNodePtr node = LLPanel::getXML();
 
-	node->createChild("title", TRUE)->setStringValue(getTitle());
+	node->createChild("title", TRUE)->setStringValue(getCurrentTitle());
 
 	node->createChild("can_resize", TRUE)->setBoolValue(isResizable());
 
@@ -2893,7 +2927,7 @@ LLView* LLFloater::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f
 void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory, BOOL open)	/* Flawfinder: ignore */
 {
 	std::string name(getName());
-	std::string title(getTitle());
+	std::string title(getCurrentTitle());
 	std::string short_title(getShortTitle());
 	std::string rect_control("");
 	BOOL resizable = isResizable();
@@ -2933,6 +2967,9 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
 			minimizable,
 			close_btn);
 
+	setTitle(title);
+	applyTitle ();
+
 	setShortTitle(short_title);
 
 	BOOL can_tear_off;
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index e467d6f921..4ca15857b9 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -142,8 +142,10 @@ public:
 
 	LLMultiFloater* getHost() { return (LLMultiFloater*)mHostHandle.get(); }
 
-	void			setTitle( const std::string& title );
-	const std::string&	getTitle() const;
+	void			applyTitle();
+	const std::string&	getCurrentTitle() const;
+	void			setTitle( const std::string& title);
+	std::string		getTitle();
 	void			setShortTitle( const std::string& short_title );
 	std::string		getShortTitle();
 	void			setTitleVisible(bool visible);
@@ -247,6 +249,7 @@ private:
 	BOOL			mMinimized;
 	BOOL			mForeground;
 	LLHandle<LLFloater>	mDependeeHandle;
+	std::string		mTitle;
 	std::string		mShortTitle;
 
 	BOOL			mFirstLook;			// TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible.
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index fba0984dce..3237ef8e27 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3902,6 +3902,13 @@ BOOL LLMenuBarGL::handleKeyHere(KEY key, MASK mask)
 	{
 		mAltKeyTrigger = FALSE;
 	}
+	
+	if (key == KEY_ESCAPE && mask == MASK_NONE)
+	{
+		LLMenuGL::setKeyboardMode(FALSE);
+		// if any menus are visible, this will return TRUE, stopping further processing of ESCAPE key
+		return LLMenuGL::sMenuContainer->hideMenus();
+	}
 
 	// before processing any other key, check to see if ALT key has triggered menu access
 	checkMenuTrigger();
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 488e62c61e..0bf7162d56 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -152,24 +152,43 @@ LLView* LLTabContainer::getChildView(const std::string& name, BOOL recurse, BOOL
 void LLTabContainer::draw()
 {
 	S32 target_pixel_scroll = 0;
-	S32 cur_scroll_pos = mIsVertical ? 0 : getScrollPos();
+	S32 cur_scroll_pos = getScrollPos();
 	if (cur_scroll_pos > 0)
 	{
-		S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE  + TABCNTR_ARROW_BTN_SIZE + 1);
-		for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
+		if (!mIsVertical)
 		{
-			if (cur_scroll_pos == 0)
+			S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE  + TABCNTR_ARROW_BTN_SIZE + 1);
+			for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
 			{
-				break;
+				if (cur_scroll_pos == 0)
+				{
+					break;
+				}
+				target_pixel_scroll += (*iter)->mButton->getRect().getWidth();
+				cur_scroll_pos--;
 			}
-			target_pixel_scroll += (*iter)->mButton->getRect().getWidth();
-			cur_scroll_pos--;
-		}
 
-		// Show part of the tab to the left of what is fully visible
-		target_pixel_scroll -= TABCNTR_TAB_PARTIAL_WIDTH;
-		// clamp so that rightmost tab never leaves right side of screen
-		target_pixel_scroll = llmin(mTotalTabWidth - available_width_with_arrows, target_pixel_scroll);
+			// Show part of the tab to the left of what is fully visible
+			target_pixel_scroll -= TABCNTR_TAB_PARTIAL_WIDTH;
+			// clamp so that rightmost tab never leaves right side of screen
+			target_pixel_scroll = llmin(mTotalTabWidth - available_width_with_arrows, target_pixel_scroll);
+		}
+		else
+		{
+			S32 available_height_with_arrows = getRect().getHeight() - getTopBorderHeight() - (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1);
+			for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
+			{
+				if (cur_scroll_pos==0)
+				{
+					break;
+				}
+				target_pixel_scroll += (*iter)->mButton->getRect().getHeight();
+				cur_scroll_pos--;
+			}
+			S32 total_tab_height = (BTN_HEIGHT + TABCNTRV_PAD) * getTabCount() + TABCNTRV_PAD;
+			// clamp so that the bottom tab never leaves bottom of panel
+			target_pixel_scroll = llmin(total_tab_height - available_height_with_arrows, target_pixel_scroll);
+		}
 	}
 
 	setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f)));
@@ -612,13 +631,13 @@ BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,	BOOL drop,	EDrag
 	{
 		if (has_scroll_arrows)
 		{
-			if (mJumpPrevArrowBtn->getRect().pointInRect(x,	y))
+			if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y))
 			{
 				S32	local_x	= x	- mJumpPrevArrowBtn->getRect().mLeft;
 				S32	local_y	= y	- mJumpPrevArrowBtn->getRect().mBottom;
 				mJumpPrevArrowBtn->handleHover(local_x,	local_y, mask);
 			}
-			if (mJumpNextArrowBtn->getRect().pointInRect(x,	y))
+			if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y))
 			{
 				S32	local_x	= x	- mJumpNextArrowBtn->getRect().mLeft;
 				S32	local_y	= y	- mJumpNextArrowBtn->getRect().mBottom;
@@ -1794,3 +1813,4 @@ void LLTabContainer::commitHoveredButton(S32 x, S32 y)
 }
 
 
+
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index b70ad4c53c..4f02715d2c 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -4180,8 +4180,8 @@ void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node)
 ///////////////////////////////////////////////////////////////////
 S32 LLTextEditor::findHTMLToken(const std::string &line, S32 pos, BOOL reverse) const
 {
-	std::string openers=" \t('\"[{<>";
-	std::string closers=" \t)'\"]}><;";
+	std::string openers=" \t\n('\"[{<>";
+	std::string closers=" \t\n)'\"]}><;";
 
 	S32 m2;
 	S32 retval;
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index c1da6c93fe..b05014d94e 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -698,7 +698,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_s
 {
 	BOOL handled = FALSE;
 
-    std::string tool_tip;
+	std::string tool_tip;
 
 	for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
 	{
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 2e1d0e3868..130c3b52f7 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -518,7 +518,7 @@ public:
 			{
 				// need non-const to update private dummy widget cache
 				llwarns << "Making dummy " << xml_tag << " named " << name << " in " << getName() << llendl;
-				const_cast<LLView*>(this)->mDummyWidgets.insert(std::make_pair(name, widget));
+				mDummyWidgets.insert(std::make_pair(name, widget));
 			}
 			else
 			{
@@ -646,7 +646,7 @@ private:
 	std::string		mControlName;
 
 	typedef std::map<std::string, LLView*> dummy_widget_map_t;
-	dummy_widget_map_t mDummyWidgets;
+	mutable dummy_widget_map_t mDummyWidgets;
 
 	boost::signals::connection mControlConnection;
 	
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index f4865202d5..325a2a39b6 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -59,8 +59,19 @@ LLDir_Linux gDirUtil;
 
 LLDir *gDirUtilp = (LLDir *)&gDirUtil;
 
-LLDir::LLDir() 
-: mDirDelimiter("/") // fallback to forward slash if not overridden
+LLDir::LLDir()
+:	mAppName(""),
+	mExecutablePathAndName(""),
+	mExecutableFilename(""),
+	mExecutableDir(""),
+	mAppRODataDir(""),
+	mOSUserDir(""),
+	mOSUserAppDir(""),
+	mLindenUserDir(""),
+	mOSCacheDir(""),
+	mCAFile(""),
+	mTempDir(""),
+	mDirDelimiter("/") // fallback to forward slash if not overridden
 {
 }
 
@@ -205,13 +216,20 @@ const std::string  LLDir::getCacheDir(bool get_default) const
 	if (mCacheDir.empty() || get_default)
 	{
 		std::string res;
-		if (getOSUserAppDir().empty())
+		if (getOSCacheDir().empty())
 		{
-			res = "data";
+			if (getOSUserAppDir().empty())
+			{
+				res = "data";
+			}
+			else
+			{
+				res = getOSUserAppDir() + mDirDelimiter + "cache";
+			}
 		}
 		else
 		{
-			res = getOSUserAppDir() + mDirDelimiter + "cache";
+			res = getOSCacheDir() + mDirDelimiter + "SecondLife";
 		}
 		return res;
 	}
@@ -221,6 +239,12 @@ const std::string  LLDir::getCacheDir(bool get_default) const
 	}
 }
 
+const std::string &LLDir::getOSCacheDir() const
+{
+	return mOSCacheDir;
+}
+
+
 const std::string &LLDir::getCAFile() const
 {
 	return mCAFile;
@@ -350,6 +374,9 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
 		prefix += mDirDelimiter;
 		prefix += "browser_profile";
 		break;
+
+	case LL_PATH_EXECUTABLE:
+		prefix = getExecutableDir();
 		
 	default:
 		llassert(0);
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 93b15276a3..b0255b4d00 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -51,7 +51,8 @@ typedef enum ELLPath
 	LL_PATH_PER_ACCOUNT_CHAT_LOGS = 13,
 	LL_PATH_MOZILLA_PROFILE = 14,
 //	LL_PATH_HTML = 15,
-	LL_PATH_LAST = 16
+	LL_PATH_EXECUTABLE = 16,
+	LL_PATH_LAST
 } ELLPath;
 
 
@@ -86,6 +87,7 @@ class LLDir
 	const std::string &getPerAccountChatLogsDir() const;	// Location of the per account chat logs dir.
 	const std::string &getTempDir() const;			// Common temporary directory
 	const std::string  getCacheDir(bool get_default = false) const;	// Location of the cache.
+	const std::string &getOSCacheDir() const;		// location of OS-specific cache folder (may be empty string)
 	const std::string &getCAFile() const;			// File containing TLS certificate authorities
 	const std::string &getDirDelimiter() const;	// directory separator for platform (ie. '\' or '/' or ':')
 	const std::string &getSkinDir() const;		// User-specified skin folder.
@@ -135,6 +137,7 @@ protected:
 	std::string mCAFile;				 // Location of the TLS certificate authority PEM file.
 	std::string mTempDir;
 	std::string mCacheDir;
+	std::string mOSCacheDir;
 	std::string mDirDelimiter;
 	std::string mSkinDir;			// Location for current skin info.
 	std::string mDefaultSkinDir;			// Location for default skin info.
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index 80134e2978..a6072c02fe 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -159,13 +159,22 @@ LLDir_Mac::LLDir_Mac()
 				
 				// Create our sub-dirs
 				(void) CFCreateDirectory(&newFileRef, CFSTR("data"), NULL);
-				(void) CFCreateDirectory(&newFileRef, CFSTR("cache"), NULL);
+				//(void) CFCreateDirectory(&newFileRef, CFSTR("cache"), NULL);
 				(void) CFCreateDirectory(&newFileRef, CFSTR("logs"), NULL);
 				(void) CFCreateDirectory(&newFileRef, CFSTR("user_settings"), NULL);
 				(void) CFCreateDirectory(&newFileRef, CFSTR("browser_profile"), NULL);
 			}
 		}
 		
+		//mOSCacheDir
+		FSRef cacheDirRef;
+		error = FSFindFolder(kUserDomain, kCachedDataFolderType, true, &cacheDirRef);
+		if (error == noErr)
+		{
+			FSRefToLLString(&cacheDirRef, mOSCacheDir);
+			(void)CFCreateDirectory(&cacheDirRef, CFSTR("SecondLife"),NULL);
+		}
+		
 		// mOSUserAppDir
 		mOSUserAppDir = mOSUserDir;
 		
diff --git a/indra/llwindow/llmousehandler.h b/indra/llwindow/llmousehandler.h
index 6fbdbe3c3e..3ede7e7830 100644
--- a/indra/llwindow/llmousehandler.h
+++ b/indra/llwindow/llmousehandler.h
@@ -43,7 +43,11 @@ class LLMouseHandler
 public:
 	LLMouseHandler() {}
 	virtual ~LLMouseHandler() {}
-	
+	typedef enum {
+		SHOW_NEVER,
+		SHOW_IF_NOT_BLOCKED,
+		SHOW_ALWAYS,
+	} EShowToolTip;
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask) = 0;
 	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask) = 0;
 	virtual BOOL	handleHover(S32 x, S32 y, MASK mask) = 0;
@@ -52,6 +56,7 @@ public:
 	virtual BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask) = 0;
 	virtual BOOL	handleRightMouseUp(S32 x, S32 y, MASK mask) = 0;
 	virtual BOOL	handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) = 0;
+	virtual EShowToolTip getShowToolTip() { return SHOW_IF_NOT_BLOCKED; };
 	virtual const std::string& getName() const = 0;
 
 	virtual void	onMouseCaptureLost() = 0;
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index 5f46b36c68..6b1cabc505 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -285,6 +285,12 @@ void LLWindow::setCallbacks(LLWindowCallbacks *callbacks)
 	}
 }
 
+void *LLWindow::getMediaWindow()
+{
+	// Default to returning the platform window.
+	return getPlatformWindow();
+}
+
 // static
 std::string LLWindow::getFontListSans()
 {
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 84ea9755fd..ec09234c83 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -219,8 +219,11 @@ public:
 // opens system default color picker
 	virtual BOOL dialog_color_picker (F32 *r, F32 *g, F32 *b) { return FALSE; };
 
-// return a platform-specific window reference (HWND on Windows, WindowRef on the Mac)
+// return a platform-specific window reference (HWND on Windows, WindowRef on the Mac, Gtk window on Linux)
 	virtual void *getPlatformWindow() = 0;
+
+// return the platform-specific window reference we use to initialize llmozlib (HWND on Windows, WindowRef on the Mac, Gtk window on Linux)
+	virtual void *getMediaWindow();
 	
 	// control platform's Language Text Input mechanisms.
 	virtual void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) {}
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index df3fb2e240..72623a17f2 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -61,6 +61,7 @@ const S32	MAX_NUM_RESOLUTIONS = 32;
 //
 
 BOOL LLWindowMacOSX::sUseMultGL = FALSE;
+WindowRef LLWindowMacOSX::sMediaWindow = NULL;
 
 // Cross-platform bits:
 
@@ -3201,22 +3202,31 @@ BOOL LLWindowMacOSX::dialog_color_picker ( F32 *r, F32 *g, F32 *b)
 	return (retval);
 }
 
-static WindowRef dummywindowref = NULL;
 
 void *LLWindowMacOSX::getPlatformWindow()
 {
-	if(mWindow != NULL)
-		return (void*)mWindow;
+	// NOTE: this will be NULL in fullscreen mode.  Plan accordingly.
+	return (void*)mWindow;
+}
+
+void *LLWindowMacOSX::getMediaWindow()
+{
+	/* 
+		Mozilla needs to be initialized with a WindowRef to function properly.  
+		(There's no good reason for this, since it shouldn't be interacting with our window in any way, but that's another issue.)
+		If we're in windowed mode, we _could_ hand it our actual window pointer, but a subsequent switch to fullscreen will destroy that window, 
+		which trips up Mozilla.
+		Instead of using our actual window, we create an invisible window which will persist for the lifetime of the application and pass that to Mozilla.
+		This satisfies its deep-seated need to latch onto a WindowRef and solves the issue with switching between fullscreen and windowed modes.
 
-	// If we're in fullscreen mode, there's no window pointer available.
-	// Since Mozilla needs one to function, create a dummy window here.
-	// Note that we will never destroy it, but since only one will be created per run of the application, that's okay.
+		Note that we will never destroy this window (by design!), but since only one will ever be created per run of the application, that's okay.
+	*/
 	
-	if(dummywindowref == NULL)
+	if(sMediaWindow == NULL)
 	{
 		Rect window_rect = {100, 100, 200, 200};
 
-		dummywindowref = NewCWindow(
+		sMediaWindow = NewCWindow(
 			NULL,
 			&window_rect,
 			(ConstStr255Param) "\p",
@@ -3227,7 +3237,7 @@ void *LLWindowMacOSX::getPlatformWindow()
 			0);
 	}
 	
-	return (void*)dummywindowref;
+	return (void*)sMediaWindow;
 }
 
 void LLWindowMacOSX::stopDockTileBounce()
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 10955b1288..24cdb54a9e 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -105,6 +105,7 @@ public:
 	/*virtual*/ BOOL dialog_color_picker(F32 *r, F32 *g, F32 *b);
 
 	/*virtual*/ void *getPlatformWindow();
+	/*virtual*/ void *getMediaWindow();
 	/*virtual*/ void bringToFront() {};
 	
 	/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
@@ -201,6 +202,8 @@ protected:
 	static BOOL	sUseMultGL;
 
 	friend class LLWindowManager;
+	static WindowRef sMediaWindow;
+
 };
 
 
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 42a9144d58..e2d114245d 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -2830,14 +2830,18 @@ std::string LLWindowSDL::getFontListSans()
 	{
 		if (success >= 2 && locale->lang) // confident!
 		{
+			LL_INFOS("AppInit") << "Language " << locale->lang << LL_ENDL;
+			LL_INFOS("AppInit") << "Location " << locale->country << LL_ENDL;
+			LL_INFOS("AppInit") << "Variant " << locale->variant << LL_ENDL;
+
 			llinfos << "Preferring fonts of language: "
 				<< locale->lang
 				<< llendl;
 			sort_order = "lang=" + std::string(locale->lang) + ":"
 				+ sort_order;
 		}
-		FL_FreeLocale(&locale);
 	}
+	FL_FreeLocale(&locale);
 
 	if (!FcInit())
 	{
diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt
index c8eb17e325..9cddb562f7 100644
--- a/indra/mac_crash_logger/CMakeLists.txt
+++ b/indra/mac_crash_logger/CMakeLists.txt
@@ -33,10 +33,28 @@ set(mac_crash_logger_HEADER_FILES
 
 set_source_files_properties(${mac_crash_logger_HEADER_FILES}
                             PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_HEADER_FILES})
 
-add_executable(mac-crash-logger ${mac_crash_logger_SOURCE_FILES})
+set(mac_crash_logger_RESOURCE_FILES
+  Info.plist
+  CrashReporter.nib/
+  )
+set_source_files_properties(
+  ${mac_crash_logger_RESOURCE_FILES}
+  PROPERTIES
+  HEADER_FILE_ONLY TRUE
+  )
+set_source_files_properties(
+  Info.plist
+  PROPERTIES
+  MACOSX_PACKAGE_LOCATION . # will it blend? + poppy
+  )
+SOURCE_GROUP("Resources" FILES ${mac_crash_logger_RESOURCE_FILES})
+list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_RESOURCE_FILES})
+
+add_executable(mac-crash-logger
+  MACOSX_BUNDLE
+  ${mac_crash_logger_SOURCE_FILES})
 
 target_link_libraries(mac-crash-logger
     ${LLCRASHLOGGER_LIBRARIES}
@@ -48,3 +66,14 @@ target_link_libraries(mac-crash-logger
     ${LLCOMMON_LIBRARIES}
     ${BOOST_SIGNALS_LIBRARY}
     )
+
+add_custom_command(
+  TARGET mac-crash-logger POST_BUILD
+  COMMAND ${CMAKE_COMMAND}
+  ARGS
+    -E
+    copy_directory
+    ${CMAKE_CURRENT_SOURCE_DIR}/CrashReporter.nib
+    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mac-crash-logger.app/Contents/Resources/CrashReporter.nib
+  )
+
diff --git a/indra/mac_crash_logger/CrashReporter.nib/classes.nib b/indra/mac_crash_logger/CrashReporter.nib/classes.nib
new file mode 100644
index 0000000000..c4b887e72b
--- /dev/null
+++ b/indra/mac_crash_logger/CrashReporter.nib/classes.nib
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IBVersion</key>
+	<string>1</string>
+</dict>
+</plist>
diff --git a/indra/mac_crash_logger/CrashReporter.nib/info.nib b/indra/mac_crash_logger/CrashReporter.nib/info.nib
new file mode 100644
index 0000000000..b5417442d0
--- /dev/null
+++ b/indra/mac_crash_logger/CrashReporter.nib/info.nib
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IBFramework Version</key>
+	<string>629</string>
+	<key>IBLastKnownRelativeProjectPath</key>
+	<string>../macview.xcodeproj</string>
+	<key>IBOldestOS</key>
+	<integer>5</integer>
+	<key>IBOpenObjects</key>
+	<array>
+		<integer>193</integer>
+	</array>
+	<key>IBSystem Version</key>
+	<string>9B18</string>
+	<key>targetFramework</key>
+	<string>IBCarbonFramework</string>
+</dict>
+</plist>
diff --git a/indra/mac_crash_logger/CrashReporter.nib/objects.xib b/indra/mac_crash_logger/CrashReporter.nib/objects.xib
new file mode 100644
index 0000000000..1099f561e7
--- /dev/null
+++ b/indra/mac_crash_logger/CrashReporter.nib/objects.xib
@@ -0,0 +1,69 @@
+<?xml version="1.0" standalone="yes"?>
+<object class="NSIBObjectData">
+  <object name="rootObject" class="NSCustomObject" id="1">
+  </object>
+  <array count="7" name="allObjects">
+    <object class="IBCarbonStaticText" id="181">
+      <string name="title">Second Life appears to have crashed or frozen the last time it ran.&#10;&#10;This crash reporter collects information about your computer&apos;s hardware configuration, operating system, and some Second Life logs, all of which are used for debugging purposes only.&#10;&#10;In the space below, please briefly describe what you were doing or trying to do just prior to the crash. Thank you for your help!&#10;&#10;This report is NOT read by Customer Support. If you have billing or other questions, please go to: http://www.secondlife.com/support/&#10;&#10;If you don&apos;t wish to send Linden Lab a crash report, press Cancel.&#10;</string>
+      <string name="bounds">20 20 231 487 </string>
+    </object>
+    <object class="IBCarbonButton" id="183">
+      <ostype name="command">not!</ostype>
+      <int name="buttonType">2</int>
+      <string name="title">Don&apos;t Send</string>
+      <string name="bounds">414 390 434 487 </string>
+    </object>
+    <object class="IBCarbonRootControl" id="167">
+      <array count="5" name="subviews">
+        <reference idRef="181"/>
+        <object class="IBCarbonButton" id="182">
+          <ostype name="command">ok  </ostype>
+          <string name="title">Send Report</string>
+          <string name="bounds">414 273 434 378 </string>
+        </object>
+        <reference idRef="183"/>
+        <object class="IBCarbonEditText" id="185">
+          <ostype name="controlSignature">text</ostype>
+          <boolean name="isUnicode">TRUE</boolean>
+          <string name="bounds">242 23 391 484 </string>
+        </object>
+        <object class="IBCarbonCheckBox" id="193">
+          <ostype name="controlSignature">remb</ostype>
+          <int name="initialState">1</int>
+          <string name="title">Remember This Choice</string>
+          <string name="bounds">415 20 433 186 </string>
+        </object>
+      </array>
+      <string name="bounds">0 0 454 507 </string>
+    </object>
+    <object class="IBCarbonWindow" id="166">
+      <int name="carbonWindowClass">2</int>
+      <int name="themeBrush">3</int>
+      <int name="windowPosition">7</int>
+      <string name="title">Second Life Crash Logger</string>
+      <reference name="rootControl" idRef="167"/>
+      <string name="windowRect">257 653 711 1160 </string>
+      <string name="ScreenRectAtEncodeTime">0 0 768 1024 </string>
+    </object>
+    <reference idRef="193"/>
+    <reference idRef="185"/>
+    <reference idRef="182"/>
+  </array>
+  <array count="7" name="allParents">
+    <reference idRef="167"/>
+    <reference idRef="167"/>
+    <reference idRef="166"/>
+    <reference idRef="1"/>
+    <reference idRef="167"/>
+    <reference idRef="167"/>
+    <reference idRef="167"/>
+  </array>
+  <dictionary count="2" name="nameTable">
+    <string>CrashReporter</string>
+    <reference idRef="166"/>
+    <string>File&apos;s Owner</string>
+    <reference idRef="1"/>
+  </dictionary>
+  <string name="targetFramework">IBCarbonFramework</string>
+  <unsigned_int name="nextObjectID">194</unsigned_int>
+</object>
diff --git a/indra/mac_crash_logger/Info.plist b/indra/mac_crash_logger/Info.plist
new file mode 100644
index 0000000000..f48293e825
--- /dev/null
+++ b/indra/mac_crash_logger/Info.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>mac-crash-logger</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.secondlife.indra.crashreporter</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0.0</string>
+</dict>
+</plist>
diff --git a/indra/mac_updater/CMakeLists.txt b/indra/mac_updater/CMakeLists.txt
index 39aa4d2b15..3ac5aeebd5 100644
--- a/indra/mac_updater/CMakeLists.txt
+++ b/indra/mac_updater/CMakeLists.txt
@@ -40,10 +40,43 @@ set_source_files_properties(${mac_updater_HEADER_FILES}
 
 list(APPEND mac_updater_SOURCE_FILES ${mac_updater_HEADER_FILES})
 
-add_executable(mac-updater ${mac_updater_SOURCE_FILES})
+
+set(mac_updater_RESOURCE_FILES
+  Info.plist
+  AutoUpdater.nib/
+  )
+set_source_files_properties(
+  ${mac_updater_RESOURCE_FILES}
+  PROPERTIES
+  HEADER_FILE_ONLY TRUE
+  )
+set_source_files_properties(
+  Info.plist
+  PROPERTIES
+  MACOSX_PACKAGE_LOCATION . # will it blend? + poppy
+  )
+SOURCE_GROUP("Resources" FILES ${mac_updater_RESOURCE_FILES})
+list(APPEND mac_updater_SOURCE_FILES ${mac_updater_RESOURCE_FILES})
+
+
+add_executable(mac-updater
+  MACOSX_BUNDLE
+  ${mac_updater_SOURCE_FILES})
 
 target_link_libraries(mac-updater
     ${LLVFS_LIBRARIES}
     ${CURL_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
     )
+
+add_custom_command(
+  TARGET mac-updater POST_BUILD
+  COMMAND ${CMAKE_COMMAND}
+  ARGS
+    -E
+    copy_directory
+    ${CMAKE_CURRENT_SOURCE_DIR}/AutoUpdater.nib
+    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mac-updater.app/Contents/Resources/AutoUpdater.nib
+  )
+
+
diff --git a/indra/mac_updater/Info.plist b/indra/mac_updater/Info.plist
new file mode 100644
index 0000000000..bb27fddb03
--- /dev/null
+++ b/indra/mac_updater/Info.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>mac-updater</string>
+	<key>CFBundleGetInfoString</key>
+	<string></string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.secondlife.indra.autoupdater</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string></string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0.0</string>
+</dict>
+</plist>
diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp
index 800521e572..4531e5ac18 100644
--- a/indra/mac_updater/mac_updater.cpp
+++ b/indra/mac_updater/mac_updater.cpp
@@ -50,6 +50,8 @@
 #include "MoreFilesX.h"
 #include "FSCopyObject.h"
 
+#include "llerrorcontrol.h"
+
 enum
 {
 	kEventClassCustom = 'Cust',
@@ -345,6 +347,16 @@ int main(int argc, char **argv)
 	// We assume that all the logs we're looking for reside on the current drive
 	gDirUtilp->initAppDirs("SecondLife");
 
+	LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+
+	// Rename current log file to ".old"
+	std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log.old");
+	std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log");
+	LLFile::rename(log_file.c_str(), old_log_file.c_str());
+
+	// Set the log file to updater.log
+	LLError::logToFile(log_file);
+
 	/////////////////////////////////////////
 	//
 	// Process command line arguments
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 0fea3076c3..699d13ea9b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -159,6 +159,7 @@ set(viewer_SOURCE_FILES
     llfloaterlandholdings.cpp
     llfloaterlandmark.cpp
     llfloatermap.cpp
+    llfloatermemleak.cpp
     llfloatermute.cpp
     llfloaternamedesc.cpp
     llfloaternewim.cpp
@@ -549,6 +550,7 @@ set(viewer_HEADER_FILES
     llfloaterlandholdings.h
     llfloaterlandmark.h
     llfloatermap.h
+    llfloatermemleak.h
     llfloatermute.h
     llfloaternamedesc.h
     llfloaternewim.h
@@ -1312,10 +1314,21 @@ if (WINDOWS)
           -E
           copy_if_different
           ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/messages/message_template.msg
-          ${CMAKE_CURRENT_SOURCE_DIR}/app_settings/message_template.msg
+          ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/app_settings/message_template.msg
         COMMENT "Copying message_template.msg to the runtime folder."
         )
 
+    add_custom_command(
+        TARGET secondlife-bin PRE_BUILD
+        COMMAND ${CMAKE_COMMAND}
+        ARGS
+          -E
+          copy_if_different
+          ${CMAKE_CURRENT_SOURCE_DIR}/../../etc/message.xml
+          ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/app_settings/message.xml
+        COMMENT "Copying message.xml to the runtime folder."
+        )
+       
     add_dependencies(secondlife-bin copy_win_libs)
 
     if (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
@@ -1389,25 +1402,12 @@ set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
 
 if (LINUX)
   add_custom_command(
-      OUTPUT secondlife-stripped-globalsyms
+      OUTPUT secondlife-stripped
       COMMAND strip
-      ARGS --strip-debug -o secondlife-stripped-globalsyms secondlife-bin
+      ARGS --strip-debug -o secondlife-stripped secondlife-bin
       DEPENDS secondlife-bin
       )
 
-  add_custom_command(
-      OUTPUT secondlife-stripped
-      COMMAND objcopy
-      ARGS
-        --keep-global-symbols
-        ${CMAKE_CURRENT_SOURCE_DIR}/linux_tools/exposed-symbols.txt
-        secondlife-stripped-globalsyms
-        secondlife-stripped
-      DEPENDS
-        secondlife-stripped-globalsyms
-        ${CMAKE_CURRENT_SOURCE_DIR}/linux_tools/exposed-symbols.txt
-      )
-
   set(product SecondLife-${ARCH}-${viewer_VERSION})
 
   add_custom_command(
@@ -1483,6 +1483,7 @@ if (DARWIN)
         secondlife-bin
         ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
       )
+      add_dependencies(package mac-updater mac-crash-logger)
   endif (PACKAGE)
 endif (DARWIN)
 
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4c47cb45b2..fd4f293d66 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -670,6 +670,17 @@
       <key>Value</key>
       <string>http://www.secondlife.com</string>
     </map>
+    <key>BlockAvatarAppearanceMessages</key>
+        <map>
+        <key>Comment</key>
+            <string>Ignore's appearance messages (for simulating Ruth)</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>0</integer>
+        </map>
     <key>BrowserProxyAddress</key>
     <map>
       <key>Comment</key>
@@ -888,7 +899,7 @@
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <integer>3</integer>
+      <integer>8</integer>
     </map>
     <key>ButtonFlashRate</key>
     <map>
@@ -899,7 +910,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>2.0</real>
+      <real>1.25</real>
     </map>
     <key>ButtonHPad</key>
     <map>
@@ -4944,17 +4955,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>NoQuickTime</key>
-    <map>
-      <key>Comment</key>
-      <string>Disable quicktime playback.</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>NoVerifySSLCert</key>
     <map>
       <key>Comment</key>
@@ -5701,6 +5701,28 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>RenderAttachedLights</key>
+        <map>
+        <key>Comment</key>
+            <string>Render lighted prims that are attached to avatars</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>1</integer>
+        </map>
+    <key>RenderAttachedParticles</key>
+        <map>
+        <key>Comment</key>
+            <string>Render particle systems that are attached to avatars</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>1</integer>
+        </map> 
     <key>RenderAvatarCloth</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 032d9bfdc3..0a1295874d 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 16
+version 17
 
 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences
 // Should be combined into one table
@@ -394,48 +394,20 @@ list ATI_Radeon_X1600
 Disregard128DefaultDrawDistance	1	0
 list ATI_Radeon_X1700 
 Disregard128DefaultDrawDistance	1	0
-
 list ATI_Mobility_Radeon_X1xxx
 Disregard128DefaultDrawDistance	1	0
-
-
-
-// Avatar hardware skinning causes
-// invisible avatars on x2600... so I masked
-// out other possible bad ones till it's fixed in 8.2
-
 list ATI_Radeon_HD_2300
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
 Disregard128DefaultDrawDistance	1	0
 list ATI_Radeon_HD_2400
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
 Disregard128DefaultDrawDistance	1	0
-list ATI_Radeon_HD_2600
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-list ATI_Radeon_HD_2900
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-list ATI_Radeon_HD_3800
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-
 list ATI_ASUS_AH24xx
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
 Disregard128DefaultDrawDistance	1	0
-list ATI_ASUS_AH26xx
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-list ATI_ASUS_EAH24xx
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-list ATI_ASUS_EAH26xx
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-list ATI_ASUS_EAH38xx
+
+
+// Avatar hardware skinning causes invisible avatars
+// on various ATI chipsets on drivers before 8.2
+
+list ATIOldDriver
 RenderAvatarVP				0	0
 RenderAvatarCloth			0	0
 
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 88570e3e09..3eaa781206 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -1,4 +1,4 @@
-version 16
+version 17
 
 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences
 // Should be combined into one table
@@ -45,6 +45,7 @@ RenderUseImpostors			1	1
 RenderVBOEnable				1	1
 RenderVolumeLODFactor		1	2.0
 RenderWaterReflections		1	1
+UseStartScreen				1	1
 UseOcclusion				1	1
 VertexShaderEnable			1	1
 WindLightUseAtmosShaders	1	1
@@ -241,25 +242,108 @@ RenderVBOEnable				1	0
 list Intel
 RenderAnisotropic			1	0
 RenderLightingDetail		1	0
-RenderTerrainDetail			1	0
-RenderVBOEnable				1	0
+// Avoid some Intel crashes on Linux
 RenderCubeMap				0	0
 
-
 list GeForce2
 RenderAnisotropic			1	0
 RenderLightingDetail		1	0
 RenderMaxPartCount			1	2048
 RenderTerrainDetail			1	0
+RenderVBOEnable				1	1
 
-list Intel_965
+list SiS
 UseOcclusion				0	0
 
-list ATI
+
+list Intel_830M
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_845G					
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_855GM				
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_865G			
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_900		
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_915GM	
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	0
+
+list Intel_915G					
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	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
 UseOcclusion				0	0
-WindLightUseAtmosShaders	0	0
+
+list Intel_G33
+RenderTerrainDetail			1	0
+RenderVBOEnable				1	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_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_9800
 RenderAvatarCloth			0	0
 VertexShaderEnable			0	0
@@ -302,58 +386,35 @@ list ATI_Radeon_X700
 Disregard128DefaultDrawDistance	1	0
 list ATI_Radeon_X1300 
 Disregard128DefaultDrawDistance	1	0
+UseStartScreen					0	0
 list ATI_Radeon_X1400 
 Disregard128DefaultDrawDistance	1	0
 list ATI_Radeon_X1500 
 Disregard128DefaultDrawDistance	1	0
+UseStartScreen					0	0
 list ATI_Radeon_X1600 
 Disregard128DefaultDrawDistance	1	0
 list ATI_Radeon_X1700 
 Disregard128DefaultDrawDistance	1	0
 list ATI_Mobility_Radeon_X1xxx
 Disregard128DefaultDrawDistance	1	0
-
-
-
-
-// Avatar hardware skinning causes
-// invisible avatars on HD 2400... so I masked
-// out other possible bad ones till it's fixed
-
 list ATI_Radeon_HD_2300
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
 Disregard128DefaultDrawDistance	1	0
 list ATI_Radeon_HD_2400
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
 Disregard128DefaultDrawDistance	1	0
-list ATI_Radeon_HD_2600
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-list ATI_Radeon_HD_2900
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-list ATI_Radeon_HD_3800
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-
 list ATI_ASUS_AH24xx
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
 Disregard128DefaultDrawDistance	1	0
-list ATI_ASUS_AH26xx
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-list ATI_ASUS_EAH24xx
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-list ATI_ASUS_EAH26xx
-RenderAvatarVP				0	0
-RenderAvatarCloth			0	0
-list ATI_ASUS_EAH38xx
+
+
+// Avatar hardware skinning causes invisible avatars
+// on various ATI chipsets on drivers before 8.2
+
+list ATIOldDriver
 RenderAvatarVP				0	0
 RenderAvatarCloth			0	0
+// Avoid driver crashes with some features on Linux with old ATI drivers
+UseOcclusion				0	0
+WindLightUseAtmosShaders	0	0
 
 
 /// Tweaked NVIDIA
@@ -387,6 +448,8 @@ Disregard128DefaultDrawDistance	1	0
 list NVIDIA_GeForce_6600
 Disregard128DefaultDrawDistance	1	0
 
+list NVIDIA_G73
+Disregard128DefaultDrawDistance	1	0
 
 list NVIDIA_GeForce_Go_6100
 RenderVBOEnable				1	0
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index cffd4410c3..edf8967f46 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -126,11 +126,8 @@
 #include "roles_constants.h"
 #include "llviewercontrol.h"
 #include "llappviewer.h"
-#include "llvoiceclient.h"
-
-// Ventrella
+#include "llviewerjoystick.h"
 #include "llfollowcam.h"
-// end Ventrella
 
 extern LLMenuBarGL* gMenuBarView;
 
@@ -176,7 +173,7 @@ const F32 AVATAR_ZOOM_MIN_Z_FACTOR = 1.15f;
 
 const F32 MAX_CAMERA_DISTANCE_FROM_AGENT = 50.f;
 
-const F32 MAX_CAMERA_SMOOTH_DISTANCE = 20.0f;
+const F32 MAX_CAMERA_SMOOTH_DISTANCE = 50.0f;
 
 const F32 HEAD_BUFFER_SIZE = 0.3f;
 const F32 CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP = 0.2f;
@@ -1952,6 +1949,11 @@ void LLAgent::cameraPanLeft(F32 meters)
 
 	mFocusTargetGlobal += meters * left_axis;
 	mFocusGlobal = mFocusTargetGlobal;
+
+	// effectively disable smoothing for camera pan, which causes some residents unhappiness
+	mCameraSmoothingLastPositionGlobal += meters * left_axis;
+	mCameraSmoothingLastPositionAgent += meters * left_axis;
+	
 	cameraZoomIn(1.f);
 	updateFocusOffset();
 }
@@ -1966,6 +1968,11 @@ void LLAgent::cameraPanUp(F32 meters)
 
 	mFocusTargetGlobal += meters * up_axis;
 	mFocusGlobal = mFocusTargetGlobal;
+
+	// effectively disable smoothing for camera pan, which causes some residents unhappiness
+	mCameraSmoothingLastPositionGlobal += meters * up_axis;
+	mCameraSmoothingLastPositionAgent += meters * up_axis;
+
 	cameraZoomIn(1.f);
 	updateFocusOffset();
 }
@@ -3226,9 +3233,9 @@ void LLAgent::updateCamera()
 		
 		if (cameraThirdPerson()) // only smooth in third person mode
 		{
-			F32 smoothing = llclampf(1.f - pow(2.f, -4.f * gSavedSettings.getF32("CameraPositionSmoothing") / gFPSClamped));
-			// we use average FPS instead of LLCriticalDamp b/c exact frame time is jittery
-
+			const F32 SMOOTHING_HALF_LIFE = 0.02f;
+			
+			F32 smoothing = LLCriticalDamp::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
 					
 			if (!mFocusObject)  // we differentiate on avatar mode 
 			{
@@ -3238,7 +3245,7 @@ void LLAgent::updateCamera()
 				LLVector3d delta = camera_pos_agent - mCameraSmoothingLastPositionAgent;
 				if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE)  // only smooth over short distances please
 				{
-					camera_pos_agent = lerp(camera_pos_agent, mCameraSmoothingLastPositionAgent, smoothing);
+					camera_pos_agent = lerp(mCameraSmoothingLastPositionAgent, camera_pos_agent, smoothing);
 					camera_pos_global = camera_pos_agent + agent_pos;
 				}
 			}
@@ -3247,7 +3254,7 @@ void LLAgent::updateCamera()
 				LLVector3d delta = camera_pos_global - mCameraSmoothingLastPositionGlobal;
 				if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please
 				{
-					camera_pos_global = lerp(camera_pos_global, mCameraSmoothingLastPositionGlobal, smoothing);
+					camera_pos_global = lerp(mCameraSmoothingLastPositionGlobal, camera_pos_global, smoothing);
 				}
 			}
 		}
@@ -3291,19 +3298,6 @@ void LLAgent::updateCamera()
 		setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent);
 	}
 
-	// Send the camera position to the spatialized voice system.
-	if(gVoiceClient && getRegion())
-	{
-		LLMatrix3 rot;
-		rot.setRows(LLViewerCamera::getInstance()->getAtAxis(), LLViewerCamera::getInstance()->getLeftAxis (),  LLViewerCamera::getInstance()->getUpAxis());		
-
-		// MBW -- XXX -- Setting velocity to 0 for now.  May figure it out later...
-		gVoiceClient->setCameraPosition(
-				getRegion()->getPosGlobalFromRegion(LLViewerCamera::getInstance()->getOrigin()),// position
-				LLVector3::zero, 			// velocity
-				rot);						// rotation matrix
-	}
-
 	// update the travel distance stat
 	// this isn't directly related to the camera
 	// but this seemed like the best place to do this
@@ -3506,20 +3500,24 @@ LLVector3d LLAgent::calcFocusPositionTargetGlobal()
 	}
 	else
 	{
-		// ...offset from avatar
-		LLVector3d focus_offset;
-		focus_offset.setVec(gSavedSettings.getVector3("FocusOffsetDefault"));
-
-		LLQuaternion agent_rot = mFrameAgent.getQuaternion();
-		if (!mAvatarObject.isNull() && mAvatarObject->getParent())
-		{
-			agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation();
-		}
+		return getPositionGlobal() + calcThirdPersonFocusOffset();
+	}
+}
 
-		focus_offset = focus_offset * agent_rot;
+LLVector3d LLAgent::calcThirdPersonFocusOffset()
+{
+	// ...offset from avatar
+	LLVector3d focus_offset;
+	focus_offset.setVec(gSavedSettings.getVector3("FocusOffsetDefault"));
 
-		return getPositionGlobal() + focus_offset;
+	LLQuaternion agent_rot = mFrameAgent.getQuaternion();
+	if (!mAvatarObject.isNull() && mAvatarObject->getParent())
+	{
+		agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation();
 	}
+
+	focus_offset = focus_offset * agent_rot;
+	return focus_offset;
 }
 
 void LLAgent::setupSitCamera()
@@ -3947,6 +3945,11 @@ void LLAgent::resetCamera()
 //-----------------------------------------------------------------------------
 void LLAgent::changeCameraToMouselook(BOOL animate)
 {
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return;
+	}
+
 	// visibility changes at end of animation
 	gViewerWindow->getWindow()->resetBusyCount();
 
@@ -3973,7 +3976,7 @@ void LLAgent::changeCameraToMouselook(BOOL animate)
 
 	if( mCameraMode != CAMERA_MODE_MOUSELOOK )
 	{
-		gViewerWindow->setKeyboardFocus( NULL );
+		gFocusMgr.setKeyboardFocus( NULL );
 		
 		mLastCameraMode = mCameraMode;
 		mCameraMode = CAMERA_MODE_MOUSELOOK;
@@ -4002,6 +4005,11 @@ void LLAgent::changeCameraToMouselook(BOOL animate)
 //-----------------------------------------------------------------------------
 void LLAgent::changeCameraToDefault()
 {
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return;
+	}
+
 	if (LLFollowCamMgr::getActiveFollowCamParams())
 	{
 		changeCameraToFollow();
@@ -4019,6 +4027,11 @@ void LLAgent::changeCameraToDefault()
 //-----------------------------------------------------------------------------
 void LLAgent::changeCameraToFollow(BOOL animate)
 {
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return;
+	}
+
 	if( mCameraMode != CAMERA_MODE_FOLLOW )
 	{
 		if (mCameraMode == CAMERA_MODE_MOUSELOOK)
@@ -4077,7 +4090,10 @@ void LLAgent::changeCameraToFollow(BOOL animate)
 //-----------------------------------------------------------------------------
 void LLAgent::changeCameraToThirdPerson(BOOL animate)
 {
-//printf( "changeCameraToThirdPerson\n" );
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return;
+	}
 
 	gViewerWindow->getWindow()->resetBusyCount();
 
@@ -4159,6 +4175,11 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate)
 //-----------------------------------------------------------------------------
 void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_animate)
 {
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return;
+	}
+
 	setControlFlags(AGENT_CONTROL_STAND_UP); // force stand up
 	gViewerWindow->getWindow()->resetBusyCount();
 
@@ -4194,8 +4215,8 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani
 			mbFlagsDirty = TRUE;
 		}
 
-		gViewerWindow->setKeyboardFocus( NULL );
-		gViewerWindow->setMouseCapture( NULL );
+		gFocusMgr.setKeyboardFocus( NULL );
+		gFocusMgr.setMouseCapture( NULL );
 
 		LLVOAvatar::onCustomizeStart();
 	}
@@ -4475,7 +4496,7 @@ void LLAgent::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
 	//RN: when focused on the avatar, we're not "looking" at it
 	// looking implies intent while focusing on avatar means
 	// you're just walking around with a camera on you...eesh.
-	if (focus_on_avatar && !mFocusOnAvatar)
+	if (!mFocusOnAvatar && focus_on_avatar)
 	{
 		setFocusGlobal(LLVector3d::zero);
 		mCameraFOVZoomFactor = 0.f;
@@ -4499,6 +4520,12 @@ void LLAgent::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
 			}
 		}
 	}
+	// unlocking camera from avatar
+	else if (mFocusOnAvatar && !focus_on_avatar)
+	{
+		// keep camera focus point consistent, even though it is now unlocked
+		setFocusGlobal(getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID());
+	}
 	
 	mFocusOnAvatar = focus_on_avatar;
 }
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index ea9138fdd1..db7fafbba8 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -151,7 +151,9 @@ public:
 	void			sendReliableMessage();
 
 	LLVector3d		calcCameraPositionTargetGlobal(BOOL *hit_limit = NULL); // Calculate the camera position target
-	LLVector3d		calcFocusPositionTargetGlobal();			// target for this mode
+	LLVector3d		calcFocusPositionTargetGlobal();
+	LLVector3d		calcThirdPersonFocusOffset();
+			// target for this mode
 	LLVector3d		getCameraPositionGlobal() const;
 	const LLVector3 &getCameraPositionAgent() const;
 	F32				calcCameraFOVZoomFactor();
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 76d5bcec34..211182f2b5 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -115,6 +115,7 @@
 #include "llcontainerview.h"
 #include "llfloaterstats.h"
 #include "llhoverview.h"
+#include "llfloatermemleak.h"
 
 #include "llsdserialize.h"
 
@@ -550,7 +551,8 @@ LLAppViewer::LLAppViewer() :
 	mQuitRequested(false),
 	mLogoutRequestSent(false),
 	mYieldTime(-1),
-	mMainloopTimeout(NULL)
+	mMainloopTimeout(NULL),
+	mAgentRegionLastAlive(false)
 {
 	if(NULL != sInstance)
 	{
@@ -616,9 +618,11 @@ bool LLAppViewer::init()
 	// *FIX: The following code isn't grouped into functions yet.
 
 	//
-	// Various introspection concerning the libs we're using.
+	// Various introspection concerning the libs we're using - particularly
+        // the libs involved in getting to a full login screen.
 	//
-	LL_DEBUGS("InitInfo") << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << LL_ENDL;
+	LL_INFOS("InitInfo") << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << LL_ENDL;
+	LL_INFOS("InitInfo") << "libcurl version is: " << LLCurl::getVersionString() << LL_ENDL;
 
 	// Get the single value from the crash settings file, if it exists
 	std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
@@ -899,7 +903,13 @@ bool LLAppViewer::mainLoop()
 			{
 				debugTime.reset();
 			}
+			
 #endif
+			//memory leaking simulation
+			if(LLFloaterMemLeak::getInstance())
+			{
+				LLFloaterMemLeak::getInstance()->idle() ;				
+			}			
 
 			if (!LLApp::isExiting())
 			{
@@ -1056,6 +1066,12 @@ bool LLAppViewer::mainLoop()
 		catch(std::bad_alloc)
 		{
 			llwarns << "Bad memory allocation in LLAppViewer::mainLoop()!" << llendl ;
+
+			//stop memory leaking simulation
+			if(LLFloaterMemLeak::getInstance())
+			{
+				LLFloaterMemLeak::getInstance()->stop() ;				
+			}	
 		}
 	}
 
@@ -1069,6 +1085,12 @@ bool LLAppViewer::mainLoop()
 		catch(std::bad_alloc)
 		{
 			llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
+
+			//stop memory leaking simulation
+			if(LLFloaterMemLeak::getInstance())
+			{
+				LLFloaterMemLeak::getInstance()->stop() ;				
+			}	
 		}
 	}
 	
@@ -1244,6 +1266,7 @@ bool LLAppViewer::cleanup()
 	// Shut down the VFS's AFTER the decode manager cleans up (since it cleans up vfiles).
 	// Also after viewerwindow is deleted, since it may have image pointers (which have vfiles)
 	// Also after shutting down the messaging system since it has VFS dependencies
+
 	//
 	LLVFile::cleanupClass();
 	llinfos << "VFS cleaned up" << llendflush;
@@ -1951,7 +1974,7 @@ bool LLAppViewer::initConfiguration()
 				_spawnl(_P_WAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL);
 #elif LL_DARWIN
 				std::string command_str;
-				command_str = "crashreporter.app/Contents/MacOS/crashreporter ";
+				command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger ";
 				command_str += "-previous";
 				// XXX -- We need to exit fullscreen mode for this to work.
 				// XXX -- system() also doesn't wait for completion.  Hmm...
@@ -2590,6 +2613,38 @@ bool LLAppViewer::initCache()
 		}
 	}
 	
+	// Delete old cache directory
+#ifdef LL_DARWIN
+	if (LL_VERSION_MAJOR >= 1 && LL_VERSION_MINOR >= 21)
+	{
+		if (gLastRunVersion != gCurrentVersion)
+		{
+			// NOTE: (Nyx) as of 1.21, cache for mac is moving to /library/caches/SecondLife from
+			// /library/application support/SecondLife/cache This should clear/delete the old dir.
+			std::string cache_dir = gDirUtilp->getOSUserAppDir();
+			std::string new_cache_dir = gDirUtilp->getOSCacheDir();
+			cache_dir = cache_dir + "/cache";
+			new_cache_dir = new_cache_dir + "/" + gSecondLife;
+			if (gDirUtilp->fileExists(cache_dir))
+			{
+				gDirUtilp->setCacheDir(cache_dir);
+				purgeCache();
+				gDirUtilp->setCacheDir(new_cache_dir);
+
+				std::string ds_store = cache_dir + "/.DS_Store";
+				if (gDirUtilp->fileExists(ds_store.c_str()))
+				{
+					LLFile::remove(ds_store.c_str());
+				}
+				if (LLFile::remove(cache_dir.c_str()) != 0)
+				{
+					llwarns << "could not delete old cache directory" << llendl;
+				}
+			}
+		}
+	}
+#endif
+
 	// Setup and verify the cache location
 	std::string cache_location = gSavedSettings.getString("CacheLocation");
 	std::string new_cache_location = gSavedSettings.getString("NewCacheLocation");
@@ -3528,6 +3583,23 @@ void LLAppViewer::idleNetwork()
 	gAssetStorage->checkForTimeouts();
 
 	gViewerThrottle.updateDynamicThrottle();
+
+
+	// Check that the circuit between the viewer and the agent's current
+	// region is still alive
+	LLViewerRegion *agent_region = gAgent.getRegion();
+	if (agent_region)
+	{
+		LLUUID this_region_id = agent_region->getRegionID();
+		bool this_region_alive = agent_region->isAlive();
+		if ((mAgentRegionLastAlive && !this_region_alive) // newly dead
+		    && (mAgentRegionLastID == this_region_id)) // same region
+		{
+			forceDisconnect(LLTrans::getString("AgentLostConnection"));
+		}
+		mAgentRegionLastID = this_region_id;
+		mAgentRegionLastAlive = this_region_alive;
+	}
 }
 
 void LLAppViewer::disconnectViewer()
@@ -3678,4 +3750,3 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
 	}
 }
 
-
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 66c4024c41..758b9cc3b4 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -206,6 +206,10 @@ private:
 	LLSD mSettingsFileList;
 
 	LLWatchdogTimeout* mMainloopTimeout;
+
+	// for tracking viewer<->region circuit death
+	bool mAgentRegionLastAlive;
+	LLUUID mAgentRegionLastID;
 };
 
 // consts from viewer.h
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 980ccd81fd..a40ee702c6 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -448,14 +448,18 @@ bool LLAppViewerLinux::initParseCommandLine(LLCommandLineParser& clp)
 	{
 		if (success >= 2 && locale->lang) // confident!
 		{
+			LL_INFOS("AppInit") << "Language " << ll_safe_string(locale->lang) << LL_ENDL;
+			LL_INFOS("AppInit") << "Location " << ll_safe_string(locale->country) << LL_ENDL;
+			LL_INFOS("AppInit") << "Variant " << ll_safe_string(locale->variant) << LL_ENDL;
+
 			LLControlVariable* c = gSavedSettings.getControl("SystemLanguage");
 			if(c)
 			{
 				c->setValue(std::string(locale->lang), false);
 			}
 		}
-		FL_FreeLocale(&locale);
 	}
+	FL_FreeLocale(&locale);
 
 	return true;
 }
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index a6d93e5652..4d0b96ba73 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -202,7 +202,7 @@ void LLAppViewerMacOSX::handleCrashReporting()
 {
 	// Macintosh
 	std::string command_str;
-	command_str += "open crashreporter.app";	
+	command_str += "open mac-crash-logger.app";	
 	
 	clear_signals();
 	llinfos << "Launching crash reporter using: '" << command_str << "'" << llendl;
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index b88bcb758b..1d8f6a218c 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -395,14 +395,17 @@ bool LLAppViewerWin32::initParseCommandLine(LLCommandLineParser& clp)
 	{
 		if (success >= 2 && locale->lang) // confident!
 		{
+			LL_INFOS("AppInit") << "Language: " << ll_safe_string(locale->lang) << LL_ENDL;
+			LL_INFOS("AppInit") << "Location: " << ll_safe_string(locale->country) << LL_ENDL;
+			LL_INFOS("AppInit") << "Variant: " << ll_safe_string(locale->variant) << LL_ENDL;
 			LLControlVariable* c = gSavedSettings.getControl("SystemLanguage");
 			if(c)
 			{
 				c->setValue(std::string(locale->lang), false);
 			}
 		}
-		FL_FreeLocale(&locale);
 	}
+	FL_FreeLocale(&locale);
 
 	return true;
 }
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index b8166a98f6..57f65fed38 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -172,7 +172,7 @@ BOOL LLColorSwatchCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	// Route future Mouse messages here preemptively.  (Release on mouse up.)
 	// No handler is needed for capture lost since this object has no state that depends on it.
-	gViewerWindow->setMouseCapture( this );
+	gFocusMgr.setMouseCapture( this );
 
 	return TRUE;
 }
@@ -184,7 +184,7 @@ BOOL LLColorSwatchCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
 	if( hasMouseCapture() )
 	{
 		// Release the mouse
-		gViewerWindow->setMouseCapture( NULL );
+		gFocusMgr.setMouseCapture( NULL );
 
 		// If mouseup in the widget, it's been clicked
 		if ( pointInView(x, y) )
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 6f5dc1d3e7..b207c44e95 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -384,9 +384,14 @@ void LLDrawable::makeActive()
 		gPipeline.setActive(this, TRUE);
 
 		//all child objects must also be active
-		for (U32 i = 0; i < getChildCount(); i++)
+		llassert_always(mVObjp);
+		
+		LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();
+		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+			 iter != child_list.end(); iter++)
 		{
-			LLDrawable* drawable = getChild(i);
+			LLViewerObject* child = *iter;
+			LLDrawable* drawable = child->mDrawable;
 			if (drawable)
 			{
 				drawable->makeActive();
@@ -430,11 +435,13 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
 		{
 			LL_WARNS_ONCE("Drawable") << "Drawable becomes static with active parent!" << LL_ENDL;
 		}
-		
-		S32 child_count = mVObjp->mChildList.size();
-		for (S32 child_num = 0; child_num < child_count; child_num++)
+
+		LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();
+		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+			 iter != child_list.end(); iter++)
 		{
-			LLDrawable* child_drawable = mVObjp->mChildList[child_num]->mDrawable;
+			LLViewerObject* child = *iter;
+			LLDrawable* child_drawable = child->mDrawable;
 			if (child_drawable)
 			{
 				if (child_drawable->getParent() != this)
@@ -1179,11 +1186,23 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
 			av = objparent->mDrawable;
 			LLSpatialGroup* group = av->getSpatialGroup();
 
-			BOOL impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor();
-			BOOL loaded   = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded();
-			
+			BOOL impostor = FALSE;
+			BOOL loaded = FALSE;
+			if (objparent->isAvatar())
+			{
+				LLVOAvatar* avatarp = (LLVOAvatar*) objparent;
+				if (avatarp->isVisible())
+				{
+					impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor();
+					loaded   = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded();
+				}
+				else
+				{
+					return;
+				}
+			}
+
 			if (!group ||
-				av->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance ||
 				LLDrawable::getCurrentFrame() - av->mVisible > 1 ||
 				impostor ||
 				!loaded)
@@ -1214,9 +1233,16 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
 		if (for_select)
 		{
 			results->push_back(mDrawable);
-			for (U32 i = 0; i < mDrawable->getChildCount(); i++)
+			if (mDrawable->getVObj())
 			{
-				results->push_back(mDrawable->getChild(i));
+				LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
+				for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+					 iter != child_list.end(); iter++)
+				{
+					LLViewerObject* child = *iter;
+					LLDrawable* drawable = child->mDrawable;					
+					results->push_back(drawable);
+				}
 			}
 		}
 		else 
@@ -1240,18 +1266,24 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in)
 	
 	mDrawable->updateDistance(camera);
 	
-	for (U32 i = 0; i < mDrawable->getChildCount(); ++i)
+	if (mDrawable->getVObj())
 	{
-		LLDrawable* child = mDrawable->getChild(i);
-		if (!child)
+		LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
+		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+			 iter != child_list.end(); iter++)
 		{
-			llwarns << "Corrupt drawable found while updating spatial bridge distance." << llendl;
-			continue;
-		}
+			LLViewerObject* child = *iter;
+			LLDrawable* drawable = child->mDrawable;					
+			if (!drawable)
+			{
+				llwarns << "Corrupt drawable found while updating spatial bridge distance." << llendl;
+				continue;
+			}
 
-		if (!child->isAvatar())
-		{
-			child->updateDistance(camera);
+			if (!drawable->isAvatar())
+			{
+				drawable->updateDistance(camera);
+			}
 		}
 	}
 }
@@ -1287,12 +1319,18 @@ void LLSpatialBridge::cleanupReferences()
 	if (mDrawable)
 	{
 		mDrawable->setSpatialGroup(NULL);
-		for (U32 i = 0; i < mDrawable->getChildCount(); i++)
+		if (mDrawable->getVObj())
 		{
-			LLDrawable* drawable = mDrawable->getChild(i);
-			if (drawable)
+			LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
+			for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+				 iter != child_list.end(); iter++)
 			{
-				drawable->setSpatialGroup(NULL);
+				LLViewerObject* child = *iter;
+				LLDrawable* drawable = child->mDrawable;					
+				if (drawable)
+				{
+					drawable->setSpatialGroup(NULL);
+				}
 			}
 		}
 
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index d6f77f2ab4..238c956cb7 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -116,8 +116,6 @@ public:
 	virtual BOOL		isSpatialBridge() const		{ return FALSE; }
 	virtual LLSpatialPartition* asPartition()		{ return NULL; }
 	LLDrawable*			getParent() const			{ return mParent; }
-	LLDrawable*			getChild(U32 index)			{ return mVObjp->mChildList[index]->mDrawable; }
-	U32					getChildCount()				{ return mVObjp ? mVObjp->mChildList.size() : 0; }
 	
 	// must set parent through LLViewerObject::		()
 	//BOOL                setParent(LLDrawable *parent);
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 6d81edd7ca..e068d90caf 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -104,8 +104,7 @@ BOOL gRenderAvatar = TRUE;
 
 S32 LLDrawPoolAvatar::getVertexShaderLevel() const
 {
-	return sShaderLevel;
-	//return (S32) LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
+	return (S32) LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
 }
 
 void LLDrawPoolAvatar::prerender()
@@ -586,6 +585,7 @@ void LLDrawPoolAvatar::renderForSelect()
 		return;
 	}
 
+	S32 curr_shader_level = getVertexShaderLevel();
 	S32 name = avatarp->mDrawable->getVObj()->mGLName;
 	LLColor4U color((U8)(name >> 16), (U8)(name >> 8), (U8)name);
 
@@ -602,7 +602,7 @@ void LLDrawPoolAvatar::renderForSelect()
 	}
 
 	sVertexProgram = &gAvatarPickProgram;
-	if (sShaderLevel > 0)
+	if (curr_shader_level > 0)
 	{
 		gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX];
 	}
@@ -611,7 +611,7 @@ void LLDrawPoolAvatar::renderForSelect()
 
 	glColor4ubv(color.mV);
 
-	if (sShaderLevel > 0)  // for hardware blending
+	if (curr_shader_level > 0)  // for hardware blending
 	{
 		sRenderingSkinned = TRUE;
 		sVertexProgram->bind();
@@ -621,7 +621,7 @@ void LLDrawPoolAvatar::renderForSelect()
 	avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
 
 	// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done
-	if (sShaderLevel > 0)
+	if (curr_shader_level > 0)
 	{
 		sRenderingSkinned = FALSE;
 		sVertexProgram->unbind();
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 11391ee6fb..2f25c757cb 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -851,7 +851,7 @@ LLImageGL* LLBumpImageList::getBrightnessDarknessImage(LLViewerImage* src_image,
 			bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);			
 
 			// Note: this may create an LLImageGL immediately
-			src_image->setLoadedCallback( callback_func, 0, TRUE, new LLUUID(src_image->getID()) );
+			src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()) );
 			bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image
 
 //			bump_total++;
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index ea3999f93f..9f22d2aa0f 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -78,7 +78,8 @@ LLDrawPoolWLSky::LLDrawPoolWLSky(void) :
 LLDrawPoolWLSky::~LLDrawPoolWLSky()
 {
 	//llinfos << "destructing wlsky draw pool." << llendl;
-	sCloudNoiseTexture = 0;
+	sCloudNoiseTexture = NULL;
+	sCloudNoiseRawImage = NULL;
 }
 
 LLViewerImage *LLDrawPoolWLSky::getDebugTexture()
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 73d8036122..ecc40aa094 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -587,6 +587,10 @@ void LLFeatureManager::applyBaseMasks()
 	{
 		maskFeatures("ATI");
 	}
+	if (gGLManager.mATIOldDriver)
+	{
+		maskFeatures("ATIOldDriver");
+	}
 	if (gGLManager.mIsGFFX)
 	{
 		maskFeatures("GeForceFX");
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 9746b06500..2fe1781a96 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -39,6 +39,9 @@
 #include "llui.h"	// for tr()
 #include "v3dmath.h"
 
+#include "llcurl.h"
+#include "llimagej2c.h"
+
 #include "llviewertexteditor.h"
 #include "llviewercontrol.h"
 #include "llagent.h"
@@ -113,7 +116,7 @@ LLFloaterAbout::LLFloaterAbout()
 		support.append("\n\n");
 	}
 
-	//*NOTE: Do not translate text like GPU, Graphics Card, etc -
+	// *NOTE: Do not translate text like GPU, Graphics Card, etc -
 	//  Most PC users that know what these mean will be used to the english versions,
 	//  and this info sometimes gets sent to support
 	
@@ -144,6 +147,16 @@ LLFloaterAbout::LLFloaterAbout()
 	support.append( (const char*) glGetString(GL_VERSION) );
 	support.append("\n");
 
+	support.append("\n");
+
+	support.append("libcurl Version: ");
+	support.append( LLCurl::getVersionString() );
+	support.append("\n");
+
+	support.append("J2C Decoder Version: ");
+	support.append( LLImageJ2C::getEngineInfo() );
+	support.append("\n");
+
 	LLMediaManager *mgr = LLMediaManager::getInstance();
 	if (mgr)
 	{
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 417ac0e868..2d595bc492 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -38,6 +38,7 @@
 #include "lldir.h"
 #include "llvfile.h"
 #include "llapr.h"
+#include "llstring.h"
 
 #include "llagent.h"
 #include "llbbox.h"
@@ -48,6 +49,7 @@
 #include "lldrawpoolavatar.h"
 #include "llrender.h"
 #include "llface.h"
+#include "llfocusmgr.h"
 #include "llkeyframemotion.h"
 #include "lllineeditor.h"
 #include "llsliderctrl.h"
@@ -451,7 +453,7 @@ BOOL LLFloaterAnimPreview::handleMouseDown(S32 x, S32 y, MASK mask)
 	if (mPreviewRect.pointInRect(x, y))
 	{
 		bringToFront( x, y );
-		gViewerWindow->setMouseCapture(this);
+		gFocusMgr.setMouseCapture(this);
 		gViewerWindow->hideCursor();
 		mLastMouseX = x;
 		mLastMouseY = y;
@@ -466,7 +468,7 @@ BOOL LLFloaterAnimPreview::handleMouseDown(S32 x, S32 y, MASK mask)
 //-----------------------------------------------------------------------------
 BOOL LLFloaterAnimPreview::handleMouseUp(S32 x, S32 y, MASK mask)
 {
-	gViewerWindow->setMouseCapture(FALSE);
+	gFocusMgr.setMouseCapture(FALSE);
 	gViewerWindow->showCursor();
 	return LLFloater::handleMouseUp(x, y, mask);
 }
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index d02fd072e2..4218c4c65a 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -913,7 +913,7 @@ handleMouseDown ( S32 x, S32 y, MASK mask )
 
 	if ( rgbAreaRect.pointInRect ( x, y ) )
 	{
-		gViewerWindow->setMouseCapture(this);
+		gFocusMgr.setMouseCapture(this);
 		// mouse button down
 		setMouseDownInHueRegion ( TRUE );
 
@@ -932,7 +932,7 @@ handleMouseDown ( S32 x, S32 y, MASK mask )
 
 	if ( lumAreaRect.pointInRect ( x, y ) )
 	{
-		gViewerWindow->setMouseCapture(this);
+		gFocusMgr.setMouseCapture(this);
 		// mouse button down
 		setMouseDownInLumRegion ( TRUE );
 
@@ -1148,7 +1148,7 @@ handleMouseUp ( S32 x, S32 y, MASK mask )
 
 	if (hasMouseCapture())
 	{
-		gViewerWindow->setMouseCapture(NULL);
+		gFocusMgr.setMouseCapture(NULL);
 	}
 
 	// dispatch to base class for the rest of things
diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp
index 55d9aeead9..46727c3698 100644
--- a/indra/newview/llfloaterfriends.cpp
+++ b/indra/newview/llfloaterfriends.cpp
@@ -44,7 +44,6 @@
 #include "llfloateravatarpicker.h"
 #include "llviewerwindow.h"
 #include "llbutton.h"
-#include "llcallingcard.h"
 #include "llfloateravatarinfo.h"
 #include "llinventorymodel.h"
 #include "llnamelistctrl.h"
@@ -143,7 +142,7 @@ void LLPanelFriends::updateFriends(U32 changed_mask)
 	LLDynamicArray<LLUUID> selected_friends = getSelectedIDs();
 	if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
 	{
-		refreshNames();
+		refreshNames(changed_mask);
 	}
 	else if(changed_mask & LLFriendObserver::POWERS)
 	{
@@ -185,7 +184,8 @@ BOOL LLPanelFriends::postBuild()
 	childSetCommitCallback("friend_list", onSelectName, this);
 	childSetDoubleClickCallback("friend_list", onClickIM);
 
-	refreshNames();
+	U32 changed_mask = LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE;
+	refreshNames(changed_mask);
 
 	childSetAction("im_btn", onClickIM, this);
 	childSetAction("profile_btn", onClickProfile, this);
@@ -206,7 +206,6 @@ BOOL LLPanelFriends::postBuild()
 	return TRUE;
 }
 
-
 BOOL LLPanelFriends::addFriend(const LLUUID& agent_id)
 {
 	LLAvatarTracker& at = LLAvatarTracker::instance();
@@ -264,7 +263,8 @@ BOOL LLPanelFriends::addFriend(const LLUUID& agent_id)
 	return have_name;
 }
 
-// propagate actual relationship to UI
+// propagate actual relationship to UI.
+// Does not resort the UI list because it can be called frequently. JC
 BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationship* info)
 {
 	if (!info) return FALSE;
@@ -287,9 +287,7 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh
 	// enable this item, in case it was disabled after user input
 	itemp->setEnabled(TRUE);
 
-	// changed item in place, need to request sort
-	mFriendsList->sortItems();
-
+	// Do not resort, this function can be called frequently.
 	return have_name;
 }
 
@@ -359,7 +357,7 @@ struct SortFriendsByID
 	}
 };
 
-void LLPanelFriends::refreshNames()
+void LLPanelFriends::refreshNames(U32 changed_mask)
 {
 	LLDynamicArray<LLUUID> selected_ids = getSelectedIDs();	
 	S32 pos = mFriendsList->getScrollPos();	
@@ -367,27 +365,67 @@ void LLPanelFriends::refreshNames()
 	// get all buddies we know about
 	LLAvatarTracker::buddy_map_t all_buddies;
 	LLAvatarTracker::instance().copyBuddyList(all_buddies);
-	
-	// get all friends in list and sort by UUID
+
+	BOOL have_names = TRUE;
+
+	if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE))
+	{
+		have_names &= refreshNamesSync(all_buddies);
+	}
+
+	if(changed_mask & LLFriendObserver::ONLINE)
+	{
+		have_names &= refreshNamesPresence(all_buddies);
+	}
+
+	if (!have_names)
+	{
+		mEventTimer.start();
+	}
+	// Changed item in place, need to request sort and update columns
+	// because we might have changed data in a column on which the user
+	// has already sorted. JC
+	mFriendsList->sortItems();
+
+	// re-select items
+	mFriendsList->selectMultiple(selected_ids);
+	mFriendsList->setScrollPos(pos);
+}
+
+BOOL LLPanelFriends::refreshNamesSync(const LLAvatarTracker::buddy_map_t & all_buddies)
+{
+	mFriendsList->deleteAllItems();
+
+	BOOL have_names = TRUE;
+	LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
+
+	for(; buddy_it != all_buddies.end(); ++buddy_it)
+	{
+		have_names &= addFriend(buddy_it->first);
+	}
+
+	return have_names;
+}
+
+BOOL LLPanelFriends::refreshNamesPresence(const LLAvatarTracker::buddy_map_t & all_buddies)
+{
 	std::vector<LLScrollListItem*> items = mFriendsList->getAllData();
 	std::sort(items.begin(), items.end(), SortFriendsByID());
 
-	std::vector<LLScrollListItem*>::iterator item_it = items.begin();
-	std::vector<LLScrollListItem*>::iterator item_end = items.end();
-
+	LLAvatarTracker::buddy_map_t::const_iterator buddy_it  = all_buddies.begin();
+	std::vector<LLScrollListItem*>::const_iterator item_it = items.begin();
 	BOOL have_names = TRUE;
-	LLAvatarTracker::buddy_map_t::iterator buddy_it;
-	for (buddy_it = all_buddies.begin() ; buddy_it != all_buddies.end(); ++buddy_it)
+
+	while(true)
 	{
-		// erase any items that reflect residents who are no longer buddies
-		while(item_it != item_end && buddy_it->first > (*item_it)->getValue().asUUID())
+		if(item_it == items.end() || buddy_it == all_buddies.end())
 		{
-			mFriendsList->deleteItems((*item_it)->getValue());
-			++item_it;
+			break;
 		}
 
-		// update existing friends with new info
-		if (item_it != item_end && buddy_it->first == (*item_it)->getValue().asUUID())
+		const LLUUID & buddy_uuid = buddy_it->first;
+		const LLUUID & item_uuid  = (*item_it)->getValue().asUUID();
+		if(item_uuid == buddy_uuid)
 		{
 			const LLRelationship* info = buddy_it->second;
 			if (!info) 
@@ -402,27 +440,23 @@ void LLPanelFriends::refreshNames()
 				// update existing item in UI
 				have_names &= updateFriendItem(buddy_it->first, info);
 			}
+
+			++buddy_it;
 			++item_it;
 		}
-		// add new friend to list
-		else 
+		else if(item_uuid < buddy_uuid)
 		{
-			have_names &= addFriend(buddy_it->first);
+			++item_it;
+		}
+		else //if(item_uuid > buddy_uuid)
+		{
+			++buddy_it;
 		}
 	}
-	if (!have_names)
-	{
-		mEventTimer.start();
-	}
-	// changed item in place, need to request sort and update columns
-	mFriendsList->sortItems();
 
-	// re-select items
-	mFriendsList->selectMultiple(selected_ids);
-	mFriendsList->setScrollPos(pos);
+	return have_names;
 }
 
-
 void LLPanelFriends::refreshUI()
 {	
 	BOOL single_selected = FALSE;
@@ -732,6 +766,8 @@ void LLPanelFriends::modifyRightsConfirmation(S32 option, void* user_data)
 			{
 				const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(rights_it->first);
 				panelp->updateFriendItem(rights_it->first, info);
+				// Might have changed the column the user is sorted on.
+				panelp->mFriendsList->sortItems();
 			}
 		}
 		panelp->refreshUI();
diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h
index 211c6cf487..d934faa616 100644
--- a/indra/newview/llfloaterfriends.h
+++ b/indra/newview/llfloaterfriends.h
@@ -38,6 +38,7 @@
 #include "llstring.h"
 #include "lluuid.h"
 #include "lltimer.h"
+#include "llcallingcard.h"
 
 class LLFriendObserver;
 class LLRelationship;
@@ -96,8 +97,9 @@ private:
 
 	// protected members
 	typedef std::map<LLUUID, S32> rights_map_t;
-	void reloadNames();
-	void refreshNames();
+	void refreshNames(U32 changed_mask);
+	BOOL refreshNamesSync(const LLAvatarTracker::buddy_map_t & all_buddies);
+	BOOL refreshNamesPresence(const LLAvatarTracker::buddy_map_t & all_buddies);
 	void refreshUI();
 	void refreshRightsChangeList();
 	void applyRightsToFriends();
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 50b8b39bd0..32dcf3ae0a 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -45,6 +45,7 @@
 #include "lldrawpoolavatar.h"
 #include "llrender.h"
 #include "llface.h"
+#include "llfocusmgr.h"
 #include "lltextbox.h"
 #include "lltoolmgr.h"
 #include "llui.h"
@@ -54,6 +55,7 @@
 #include "pipeline.h"
 #include "lluictrlfactory.h"
 #include "llviewerimagelist.h"
+#include "llstring.h"
 
 //static
 S32 LLFloaterImagePreview::sUploadAmount = 10;
@@ -426,7 +428,7 @@ BOOL LLFloaterImagePreview::handleMouseDown(S32 x, S32 y, MASK mask)
 	if (mPreviewRect.pointInRect(x, y))
 	{
 		bringToFront( x, y );
-		gViewerWindow->setMouseCapture(this);
+		gFocusMgr.setMouseCapture(this);
 		gViewerWindow->hideCursor();
 		mLastMouseX = x;
 		mLastMouseY = y;
@@ -441,7 +443,7 @@ BOOL LLFloaterImagePreview::handleMouseDown(S32 x, S32 y, MASK mask)
 //-----------------------------------------------------------------------------
 BOOL LLFloaterImagePreview::handleMouseUp(S32 x, S32 y, MASK mask)
 {
-	gViewerWindow->setMouseCapture(FALSE);
+	gFocusMgr.setMouseCapture(FALSE);
 	gViewerWindow->showCursor();
 	return LLFloater::handleMouseUp(x, y, mask);
 }
diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp
new file mode 100644
index 0000000000..62401dbc96
--- /dev/null
+++ b/indra/newview/llfloatermemleak.cpp
@@ -0,0 +1,265 @@
+/** 
+ * @file llfloatermemleak.cpp
+ * @brief LLFloatermemleak class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 "llfloatermemleak.h"
+
+#include "lluictrlfactory.h"
+#include "llbutton.h"
+#include "llspinctrl.h"
+#include "llresmgr.h"
+
+#include "llmath.h"
+#include "llviewerwindow.h"
+
+LLFloaterMemLeak* LLFloaterMemLeak::sInstance = NULL;
+U32 LLFloaterMemLeak::sMemLeakingSpeed = 0 ; //bytes leaked per frame
+U32 LLFloaterMemLeak::sMaxLeakedMem = 0 ; //maximum allowed leaked memory
+U32 LLFloaterMemLeak::sTotalLeaked = 0 ;
+S32 LLFloaterMemLeak::sStatus = LLFloaterMemLeak::STOP ;
+BOOL LLFloaterMemLeak::sbAllocationFailed = FALSE ;
+
+LLFloaterMemLeak::LLFloaterMemLeak() : LLFloater("Memory Leaking Simulation Floater")
+{
+}
+
+LLFloaterMemLeak::~LLFloaterMemLeak()
+{
+	release() ;
+		
+	sMemLeakingSpeed = 0 ; //bytes leaked per frame
+	sMaxLeakedMem = 0 ; //maximum allowed leaked memory	
+	sInstance = NULL ;
+}
+
+void LLFloaterMemLeak::release()
+{
+	for(S32 i = 0 ; i < (S32)mLeakedMem.size() ; i++)
+	{
+		delete[] mLeakedMem[i] ;
+	}
+	mLeakedMem.clear() ;
+
+	sStatus = STOP ;
+	sTotalLeaked = 0 ;
+	sbAllocationFailed = FALSE ;
+}
+
+void LLFloaterMemLeak::stop()
+{
+	sStatus = STOP ;
+	sbAllocationFailed = TRUE ;
+}
+
+void LLFloaterMemLeak::idle()
+{
+	if(STOP == sStatus)
+	{
+		return ;
+	}
+
+	sbAllocationFailed = FALSE ;
+	
+	if(RELEASE == sStatus)
+	{
+		release() ;
+		return ;
+	}
+
+	char* p = NULL ;
+	if(sMemLeakingSpeed > 0 && sTotalLeaked < sMaxLeakedMem)
+	{
+		p = new char[sMemLeakingSpeed] ;
+
+		if(p)
+		{
+			mLeakedMem.push_back(p) ;
+			sTotalLeaked += sMemLeakingSpeed ;
+		}
+	}
+	if(!p)
+	{
+		sStatus = STOP ;
+		sbAllocationFailed = TRUE ;
+	}
+}
+
+//----------------------
+void LLFloaterMemLeak::onChangeLeakingSpeed(LLUICtrl* ctrl, void* userData)
+{
+	LLFloaterMemLeak *mem_leak = (LLFloaterMemLeak *)userData;		
+	if (mem_leak)
+	{
+		F32 tmp ;
+		tmp = mem_leak->childGetValue("leak_speed").asReal();
+
+		if(tmp > (F32)0xFFFFFFFF)
+		{
+			sMemLeakingSpeed = 0xFFFFFFFF ;
+		}
+		else
+		{
+			sMemLeakingSpeed = (U32)tmp ;
+		}
+	}
+}
+
+void LLFloaterMemLeak::onChangeMaxMemLeaking(LLUICtrl* ctrl, void* userData)
+{
+	LLFloaterMemLeak *mem_leak = (LLFloaterMemLeak *)userData;		
+	if (mem_leak)
+	{
+		F32 tmp ;
+		tmp = mem_leak->childGetValue("max_leak").asReal();
+		if(tmp > (F32)0xFFF)
+		{
+			sMaxLeakedMem = 0xFFFFFFFF ;
+		}
+		else
+		{
+			sMaxLeakedMem = ((U32)tmp) << 20 ;
+		}
+	}
+}
+
+void LLFloaterMemLeak::onClickStart(void* userData)
+{
+	sStatus = START ;
+}
+
+void LLFloaterMemLeak::onClickStop(void* userData)
+{
+	sStatus = STOP ;
+}
+
+void LLFloaterMemLeak::onClickRelease(void* userData)
+{
+	sStatus = RELEASE ;
+}
+
+void LLFloaterMemLeak::onClickClose(void* userData)
+{
+	if (sInstance)
+	{
+		sInstance->setVisible(FALSE);
+	}
+}
+
+//----------------------------------------------
+
+BOOL LLFloaterMemLeak::postBuild(void) 
+{
+	childSetCommitCallback("leak_speed", onChangeLeakingSpeed, this);
+	childSetCommitCallback("max_leak", onChangeMaxMemLeaking, this);
+
+	childSetAction("start_btn", onClickStart, this);
+	childSetAction("stop_btn", onClickStop, this);
+	childSetAction("release_btn", onClickRelease, this);
+	childSetAction("close_btn", onClickClose, this);
+
+	return TRUE ;
+}
+
+void LLFloaterMemLeak::draw()
+{
+	//show total memory leaked
+	if(sTotalLeaked > 0)
+	{
+		std::string bytes_string;
+		LLResMgr::getInstance()->getIntegerString(bytes_string, sTotalLeaked >> 10 );
+		childSetTextArg("total_leaked_label", "[SIZE]", bytes_string);
+	}
+	else
+	{
+		childSetTextArg("total_leaked_label", "[SIZE]", LLStringExplicit("0"));
+	}
+
+	if(sbAllocationFailed)
+	{
+		childSetTextArg("note_label_1", "[NOTE1]", LLStringExplicit("Memory leaking simulation stops. Reduce leaking speed or"));
+		childSetTextArg("note_label_2", "[NOTE2]", LLStringExplicit("increase max leaked memory, then press Start to continue."));
+	}
+	else
+	{
+		childSetTextArg("note_label_1", "[NOTE1]", LLStringExplicit(""));
+		childSetTextArg("note_label_2", "[NOTE2]", LLStringExplicit(""));
+	}
+
+	LLFloater::draw();
+}
+
+// static instance of it
+LLFloaterMemLeak* LLFloaterMemLeak::instance()
+{
+	if (!sInstance)
+	{
+		sInstance = new LLFloaterMemLeak();
+		LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_mem_leaking.xml", NULL, FALSE);
+
+		if(sInstance)
+		{
+			F32 a, b ;
+			a = sInstance->childGetValue("leak_speed").asReal();
+			if(a > (F32)(0xFFFFFFFF))
+			{
+				sMemLeakingSpeed = 0xFFFFFFFF ;
+			}
+			else
+			{
+				sMemLeakingSpeed = (U32)a ;
+			}
+			b = sInstance->childGetValue("max_leak").asReal();
+			if(b > (F32)0xFFF)
+			{
+				sMaxLeakedMem = 0xFFFFFFFF ;
+			}
+			else
+			{
+				sMaxLeakedMem = ((U32)b) << 20 ;
+			}
+
+			sbAllocationFailed = FALSE ;
+		}
+	}
+	return sInstance ;
+}
+
+void LLFloaterMemLeak::show(void*)
+{
+	instance()->open();
+}
+
+LLFloaterMemLeak* LLFloaterMemLeak::getInstance()
+{
+	return sInstance ;
+}
+
diff --git a/indra/newview/llfloatermemleak.h b/indra/newview/llfloatermemleak.h
new file mode 100644
index 0000000000..d97cdc771b
--- /dev/null
+++ b/indra/newview/llfloatermemleak.h
@@ -0,0 +1,89 @@
+/** 
+ * @file llfloatermemleak.h
+ * @brief memory leaking simulation window, debug use only
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ * 
+ * Copyright (c) 2004-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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_LLFLOATERMEMLEAK_H
+#define LL_LLFLOATERMEMLEAK_H
+
+#include "llfloater.h"
+
+class LLFloaterMemLeak : public LLFloater
+{
+public:
+    LLFloaterMemLeak();
+	virtual ~LLFloaterMemLeak();
+
+	/// initialize all the callbacks for the menu
+	//void initCallbacks(void);
+	virtual BOOL postBuild() ;
+	virtual void draw() ;
+
+	/// one and one instance only
+	static LLFloaterMemLeak* instance();
+	
+	static void onChangeLeakingSpeed(LLUICtrl* ctrl, void* userData);
+	static void onChangeMaxMemLeaking(LLUICtrl* ctrl, void* userData);
+	static void onClickStart(void* userData);
+	static void onClickStop(void* userData);
+	static void onClickRelease(void* userData);
+	static void onClickClose(void* userData);
+		
+	/// show off our menu
+	static void show(void*);
+
+public:
+	static LLFloaterMemLeak* getInstance() ;
+	void idle() ;
+	void stop() ;
+
+private:
+	void release() ;
+
+private:
+	enum 
+	{
+		RELEASE = -1 ,
+		STOP,
+		START
+	} ;
+
+	// one instance on the inside
+	static LLFloaterMemLeak* sInstance;
+
+	static U32 sMemLeakingSpeed ; //bytes leaked per frame
+	static U32 sMaxLeakedMem ; //maximum allowed leaked memory
+	static U32 sTotalLeaked ;
+	static S32 sStatus ; //0: stop ; >0: start ; <0: release
+	static BOOL sbAllocationFailed ;
+
+	std::vector<char*> mLeakedMem ;	
+};
+
+#endif // LL_LLFLOATERMEMLEAK_H
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index a95cafa7e4..f53482a476 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -46,6 +46,7 @@
 #include "llviewercontrol.h"
 #include "llviewermenufile.h"	// upload_new_resource()
 #include "lluictrlfactory.h"
+#include "llstring.h"
 
 // linden includes
 #include "llassetstorage.h"
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index d193685432..65e5dc2bf9 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -1011,7 +1011,7 @@ void LLFloaterTools::setObjectType( void* data )
 	LLPCode pcode = *(LLPCode*) data;
 	LLToolPlacer::setObjectType( pcode );
 	gSavedSettings.setBOOL("CreateToolCopySelection", FALSE);
-	gViewerWindow->setMouseCapture(NULL);
+	gFocusMgr.setMouseCapture(NULL);
 }
 
 // static
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index 2d0723f1eb..5ed50c0c2a 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -170,7 +170,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 		F32 score;
 		std::string name_buf;
 		std::string owner_buf;
-		F32 mono_score;
+		F32 mono_score = 0.f;
 
 		msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block);
 		msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block);
@@ -206,15 +206,16 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 		element["columns"][3]["column"] = "time";
 		element["columns"][3]["value"] = formatted_time((time_t)time_stamp);
 		element["columns"][3]["font"] = "SANSSERIF";
-		
+
 		if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS)
 		{
-			msg->getF32Fast(_PREHASH_ReportData, "MonoScore", mono_score, block);
+			// Not in the message template, needs to be checked against number of blocks
+			//msg->getF32Fast(_PREHASH_ReportData, "MonoScore", mono_score, block);
 			element["columns"][4]["column"] = "Mono Time";
 			element["columns"][4]["value"] = llformat("%0.3f", mono_score);
 			element["columns"][4]["font"] = "SANSSERIF";
 		}
-
+		
 		list->addElement(element);
 		
 		mObjectListData.append(element);
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 2739a30031..016909cf7f 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -609,7 +609,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
 {
 	// No handler needed for focus lost since this class has no
 	// state that depends on it.
-	gViewerWindow->setMouseCapture( this );
+	gFocusMgr.setMouseCapture( this );
 
 	if (!mIsSelected)
 	{
@@ -680,7 +680,7 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 					// Release keyboard focus, so that if stuff is dropped into the
 					// world, pressing the delete key won't blow away the inventory
 					// item.
-					gViewerWindow->setKeyboardFocus(NULL);
+					gFocusMgr.setKeyboardFocus(NULL);
 
 					return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
 				}
@@ -747,7 +747,7 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
 	if( hasMouseCapture() )
 	{
 		getRoot()->setShowSelectionContext(FALSE);
-		gViewerWindow->setMouseCapture( NULL );
+		gFocusMgr.setMouseCapture( NULL );
 	}
 	return TRUE;
 }
@@ -2585,9 +2585,9 @@ LLFolderView::~LLFolderView( void )
 
 	LLView::deleteViewByHandle(mPopupMenuHandle);
 
-	if(gViewerWindow->hasTopCtrl(mRenamer))
+	if(mRenamer == gFocusMgr.getTopCtrl())
 	{
-		gViewerWindow->setTopCtrl(NULL);
+		gFocusMgr.setTopCtrl(NULL);
 	}
 
 	mAutoOpenItems.removeAllNodes();
@@ -3132,9 +3132,9 @@ void LLFolderView::draw()
 	{
 		closeAutoOpenedFolders();
 	}
-	if(gViewerWindow->hasKeyboardFocus(this) && !getVisible())
+	if(this == gFocusMgr.getKeyboardFocus() && !getVisible())
 	{
-		gViewerWindow->setKeyboardFocus( NULL );
+		gFocusMgr.setKeyboardFocus( NULL );
 	}
 
 	// while dragging, update selection rendering to reflect single/multi drag status
@@ -3199,7 +3199,7 @@ void LLFolderView::finishRenamingItem( void )
 	mRenamer->setFocus( FALSE );
 	mRenamer->setVisible( FALSE );
 	mRenamer->setCommitOnFocusLost( TRUE );
-	gViewerWindow->setTopCtrl( NULL );
+	gFocusMgr.setTopCtrl( NULL );
 
 	if( mRenameItem )
 	{
@@ -3211,13 +3211,12 @@ void LLFolderView::finishRenamingItem( void )
 	scrollToShowSelection();
 }
 
-void LLFolderView::revertRenamingItem( void )
+void LLFolderView::closeRenamer( void )
 {
-	mRenamer->setCommitOnFocusLost( FALSE );
+	// will commit current name (which could be same as original name)
 	mRenamer->setFocus( FALSE );
 	mRenamer->setVisible( FALSE );
-	mRenamer->setCommitOnFocusLost( TRUE );
-	gViewerWindow->setTopCtrl( NULL );
+	gFocusMgr.setTopCtrl( NULL );
 
 	if( mRenameItem )
 	{
@@ -3274,11 +3273,11 @@ void LLFolderView::removeSelectedItems( void )
 					// change selection on successful delete
 					if (new_selection)
 					{
-						setSelectionFromRoot(new_selection, new_selection->isOpen(), gViewerWindow->childHasKeyboardFocus(this));
+						setSelectionFromRoot(new_selection, new_selection->isOpen(), gFocusMgr.childHasKeyboardFocus(this));
 					}
 					else
 					{
-						setSelectionFromRoot(NULL, gViewerWindow->childHasKeyboardFocus(this));
+						setSelectionFromRoot(NULL, gFocusMgr.childHasKeyboardFocus(this));
 					}
 				}
 			}
@@ -3304,11 +3303,11 @@ void LLFolderView::removeSelectedItems( void )
 			}
 			if (new_selection)
 			{
-				setSelectionFromRoot(new_selection, new_selection->isOpen(), gViewerWindow->childHasKeyboardFocus(this));
+				setSelectionFromRoot(new_selection, new_selection->isOpen(), gFocusMgr.childHasKeyboardFocus(this));
 			}
 			else
 			{
-				setSelectionFromRoot(NULL, gViewerWindow->childHasKeyboardFocus(this));
+				setSelectionFromRoot(NULL, gFocusMgr.childHasKeyboardFocus(this));
 			}
 
 			for(S32 i = 0; i < count; ++i)
@@ -3626,7 +3625,7 @@ void LLFolderView::startRenamingSelectedItem( void )
 		// set focus will fail unless item is visible
 		mRenamer->setFocus( TRUE );
 		mRenamer->setLostTopCallback(onRenamerLost);
-		gViewerWindow->setTopCtrl( mRenamer );
+		gFocusMgr.setTopCtrl( mRenamer );
 	}
 }
 
@@ -3687,19 +3686,11 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 		break;
 
 	case KEY_ESCAPE:
-		// mark flag don't commit
 		if( mRenameItem && mRenamer->getVisible() )
 		{
-			revertRenamingItem();
+			closeRenamer();
 			handled = TRUE;
 		}
-		else
-		{
-			if( gViewerWindow->childHasKeyboardFocus( this ) )
-			{
-				gViewerWindow->setKeyboardFocus( NULL );
-			}
-		}
 		mSearchString.clear();
 		break;
 
@@ -4107,9 +4098,9 @@ BOOL LLFolderView::handleScrollWheel(S32 x, S32 y, S32 clicks)
 
 void LLFolderView::deleteAllChildren()
 {
-	if(gViewerWindow->hasTopCtrl(mRenamer))
+	if(mRenamer == gFocusMgr.getTopCtrl())
 	{
-		gViewerWindow->setTopCtrl(NULL);
+		gFocusMgr.setTopCtrl(NULL);
 	}
 	LLView::deleteViewByHandle(mPopupMenuHandle);
 	mPopupMenuHandle = LLHandle<LLView>();
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 32b0580a5c..841146db5a 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -880,7 +880,7 @@ protected:
 	static void onRenamerLost( LLUICtrl* renamer, void* user_data);
 
 	void finishRenamingItem( void );
-	void revertRenamingItem( void );
+	void closeRenamer( void );
 
 protected:
 	LLHandle<LLView>					mPopupMenuHandle;
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index da9441e108..80e62aff8f 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -961,6 +961,21 @@ void LLHUDText::renderAllHUD()
 	}
 }
 
+void LLHUDText::shiftAll(const LLVector3& offset)
+{
+	TextObjectIterator text_it;
+	for (text_it = sTextObjects.begin(); text_it != sTextObjects.end(); ++text_it)
+	{
+		LLHUDText *textp = text_it->get();
+		textp->shift(offset);
+	}
+}
+
+void LLHUDText::shift(const LLVector3& offset)
+{
+	mPositionAgent += offset;
+}
+
 //static 
 void LLHUDText::addPickable(std::set<LLViewerObject*> &pick_list)
 {
diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h
index bb96c356bb..b46a1635dd 100644
--- a/indra/newview/llhudtext.h
+++ b/indra/newview/llhudtext.h
@@ -121,6 +121,9 @@ public:
 	BOOL getHidden() const { return mHidden; }
 	void setHidden( BOOL hide ) { mHidden = hide; }
 	void setOnHUDAttachment(BOOL on_hud) { mOnHUDAttachment = on_hud; }
+	void shift(const LLVector3& offset);
+
+	static void shiftAll(const LLVector3& offset);
 	static void renderAllHUD();
 	static void addPickable(std::set<LLViewerObject*> &pick_list);
 	static void reshape();
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 40da1a4f3c..328cb85c1f 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -2173,11 +2173,17 @@ void LLFloaterIMPanel::chatFromLogFile(LLLogChat::ELogLineType type, std::string
 	{
 	case LLLogChat::LOG_EMPTY:
 		// add warning log enabled message
-		message = LLFloaterChat::getInstance()->getUIString("IM_logging_string");
+		if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+		{
+			message = LLFloaterChat::getInstance()->getUIString("IM_logging_string");
+		}
 		break;
 	case LLLogChat::LOG_END:
 		// add log end message
-		message = LLFloaterChat::getInstance()->getUIString("IM_logging_string");
+		if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+		{
+			message = LLFloaterChat::getInstance()->getUIString("IM_logging_string");
+		}
 		break;
 	case LLLogChat::LOG_LINE:
 		// just add normal lines from file
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index c05eea7bd8..9aa7f54fa9 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -56,6 +56,7 @@
 #include "llcallbacklist.h"
 #include "llpreview.h"
 #include "llviewercontrol.h"
+#include "llvoavatar.h"
 #include "llsdutil.h"
 #include <deque>
 
@@ -3064,6 +3065,45 @@ void LLInventoryModel::dumpInventory()
 /// LLInventoryCollectFunctor implementations
 ///----------------------------------------------------------------------------
 
+// static
+bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(LLInventoryItem* item)
+{
+	if (!item)
+		return false;
+
+	bool allowed = false;
+	LLVOAvatar* my_avatar = NULL;
+
+	switch(item->getType())
+	{
+	case LLAssetType::AT_CALLINGCARD:
+		// not allowed
+		break;
+		
+	case LLAssetType::AT_OBJECT:
+		my_avatar = gAgent.getAvatarObject();
+		if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
+		{
+			allowed = true;
+		}
+		break;
+		
+	case LLAssetType::AT_BODYPART:
+	case LLAssetType::AT_CLOTHING:
+		if(!gAgent.isWearingItem(item->getUUID()))
+		{
+			allowed = true;
+		}
+		break;
+		
+	default:
+		allowed = true;
+		break;
+	}
+
+	return allowed;
+}
+
 bool LLIsType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
 {
 	if(mType == LLAssetType::AT_CATEGORY)
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 8d554e2673..85eb46404b 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -484,6 +484,8 @@ class LLInventoryCollectFunctor
 public:
 	virtual ~LLInventoryCollectFunctor(){};
 	virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) = 0;
+
+	static bool itemTransferCommonlyAllowed(LLInventoryItem* item);
 };
 
 
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index cb7af207d2..d129687a11 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -40,11 +40,24 @@ const S32 LOG_RECALL_SIZE = 2048;
 //static
 std::string LLLogChat::makeLogFileName(std::string filename)
 {
+	filename = cleanFileName(filename);
 	filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS,filename);
 	filename += ".txt";
 	return filename;
 }
 
+std::string LLLogChat::cleanFileName(std::string filename)
+{
+	std::string invalidChars = "\"\'\\/?*:<>|";
+	S32 position = filename.find_first_of(invalidChars);
+	while (position != filename.npos)
+	{
+		filename[position] = '_';
+		position = filename.find_first_of(invalidChars, position);
+	}
+	return filename;
+}
+
 std::string LLLogChat::timestamp(bool withdate)
 {
 	time_t utc_time;
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 45279fd6ae..28e073de4c 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -48,6 +48,8 @@ public:
 	static void loadHistory(std::string filename, 
 		                    void (*callback)(ELogLineType,std::string,void*), 
 							void* userdata);
+private:
+	static std::string cleanFileName(std::string filename);
 };
 
 #endif
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index ca0812c8a0..f1a0fd4c67 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -448,6 +448,19 @@ BOOL LLManipRotate::handleMouseUp(S32 x, S32 y, MASK mask)
 
 	if( hasMouseCapture() )
 	{
+		for (LLObjectSelection::iterator iter = mObjectSelection->begin();
+		 iter != mObjectSelection->end(); iter++)
+		{
+			LLSelectNode* selectNode = *iter;
+			LLViewerObject* object = selectNode->getObject();
+
+			// have permission to move and object is root of selection or individually selected
+			if (object->permMove() && (object->isRootEdit() || selectNode->mIndividualSelection))
+			{
+				object->mUnselectedChildrenPositions.clear() ;
+			}
+		}
+
 		mManipPart = LL_NO_PART;
 
 		// Might have missed last update due to timing.
@@ -544,16 +557,12 @@ void LLManipRotate::drag( S32 x, S32 y )
 			}
 
 			LLQuaternion new_rot = selectNode->mSavedRotation * mRotation;
-			std::vector<LLVector3> child_positions;
+			std::vector<LLVector3>& child_positions = object->mUnselectedChildrenPositions ;
 			std::vector<LLQuaternion> child_rotations;
 			if (object->isRootEdit() && selectNode->mIndividualSelection)
 			{
-				for (U32 i = 0; i < object->mChildList.size(); i++)
-				{
-					LLViewerObject* childp = object->mChildList[i];
-					child_positions.push_back(childp->getPositionEdit());
-					child_rotations.push_back(childp->getRotationEdit());
-				}
+				object->saveUnselectedChildrenRotation(child_rotations) ;
+				object->saveUnselectedChildrenPosition(child_positions) ;			
 			}
 
 			if (object->getParent() && object->mDrawable.notNull())
@@ -575,17 +584,7 @@ void LLManipRotate::drag( S32 x, S32 y )
 			{
 				//RN: must do non-damped updates on these objects so relative rotation appears constant
 				// instead of having two competing slerps making the child objects appear to "wobble"
-				for (U32 i = 0; i < object->mChildList.size(); i++)
-				{
-					LLViewerObject* childp = object->mChildList[i];
-					LLVector3 child_offset = ((child_positions[i] - object->getPositionEdit()) * ~object->getRotationEdit()) - childp->getPosition();
-					if (!childp->isSelected() && childp->mDrawable.notNull())
-					{
-						childp->setRotation(child_rotations[i] * ~object->getRotationEdit());
-						childp->setPosition((child_positions[i] - object->getPositionEdit()) * ~object->getRotationEdit());
-						rebuild(childp);
-					}
-				}
+				object->resetChildrenRotationAndPosition(child_rotations, child_positions) ;
 			}
 		}
 	}
@@ -667,28 +666,8 @@ void LLManipRotate::drag( S32 x, S32 y )
 			if (object->isRootEdit() && selectNode->mIndividualSelection)
 			{
 				// only offset by parent's translation as we've already countered parent's rotation
-				LLVector3 child_offset;
-				if (object->isAttachment() && object->mDrawable.notNull())
-				{
-					LLXform* attachment_point_xform = object->mDrawable->getXform()->getParent();
-					LLQuaternion parent_rotation = object->getRotation() * attachment_point_xform->getWorldRotation();
-					child_offset = LLVector3(old_position - new_position) * ~parent_rotation;
-				}
-				else
-				{
-					child_offset = LLVector3(old_position - new_position) * ~object->getRenderRotation();
-				}
-
 				rebuild(object);
-				for (U32 i = 0; i < object->mChildList.size(); i++)
-				{
-					LLViewerObject* childp = object->mChildList[i];
-					if (!childp->isSelected() && childp->mDrawable.notNull())
-					{
-						childp->setPosition(childp->getPosition() + child_offset);
-						rebuild(childp);
-					}
-				}
+				object->resetChildrenPosition(old_position - new_position) ;				
 			}
 		}
 	}
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 5859d4c75f..68e59ce9e0 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -1003,9 +1003,11 @@ void LLManipScale::dragCorner( S32 x, S32 y )
 			if (selectNode->mIndividualSelection)
 			{
 				// counter-translate child objects if we are moving the root as an individual
-				for (U32 child_num = 0; child_num < cur->mChildList.size(); child_num++)
+				LLViewerObject::const_child_list_t& child_list = cur->getChildren();
+				for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+					 iter != child_list.end(); iter++)
 				{
-					LLViewerObject* childp = cur->mChildList[child_num];
+					LLViewerObject* childp = *iter;
 
 					if (cur->isAttachment())
 					{
@@ -1301,9 +1303,11 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto
 			if (cur->isRootEdit() && selectNode->mIndividualSelection)
 			{
 				// counter-translate child objects if we are moving the root as an individual
-				for (U32 child_num = 0; child_num < cur->mChildList.size(); child_num++)
+				LLViewerObject::const_child_list_t& child_list = cur->getChildren();
+				for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+					 iter != child_list.end(); iter++)
 				{
-					LLViewerObject* childp = cur->mChildList[child_num];
+					LLViewerObject* childp = *iter;
 					if (!getUniform())
 					{
 						LLVector3 child_pos = childp->getPosition() - (delta_pos * ~cur->getRotationEdit());
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 7785b5a078..ac82295008 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -677,19 +677,9 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 				if (selectNode->mIndividualSelection)
 				{
 					send_update = FALSE;
-					LLVector3 child_offset = (old_position_local - new_position_local) * ~object->getRotation();
-
+		
 					// counter-translate child objects if we are moving the root as an individual
-					for (U32 child_num = 0; child_num < object->mChildList.size(); child_num++)
-					{
-						LLViewerObject* childp = object->mChildList[child_num];
-
-						if (!childp->isSelected())
-						{
-							childp->setPosition(childp->getPosition() + child_offset);
-							rebuild(childp);
-						}
-					}
+					object->resetChildrenPosition(old_position_local - new_position_local, TRUE) ;					
 				}
 			}
 			else
@@ -743,18 +733,8 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 
 				if (selectNode->mIndividualSelection)
 				{
-					LLVector3 parent_offset = (new_position_agent - old_position_agent) * ~object->getRotation();
-
 					// counter-translate child objects if we are moving the root as an individual
-					for (U32 child_num = 0; child_num < object->mChildList.size(); child_num++)
-					{
-						LLViewerObject* childp = object->mChildList[child_num];
-						if (!childp->isSelected())
-						{
-							childp->setPosition(childp->getPosition() - parent_offset);
-							rebuild(childp);
-						}
-					}
+					object->resetChildrenPosition(old_position_agent - new_position_agent, TRUE) ;					
 					send_update = FALSE;
 				}
 				else if (old_position_global != new_position_global)
diff --git a/indra/newview/llmemoryview.cpp b/indra/newview/llmemoryview.cpp
index 75f05f6d0c..a5a4db8dc4 100644
--- a/indra/newview/llmemoryview.cpp
+++ b/indra/newview/llmemoryview.cpp
@@ -121,6 +121,7 @@ static const struct mtv_display_info mtv_display_table[] =
 	{ LLMemType::MTYPE_SPACE_PARTITION,	"Space Partition",	&LLColor4::blue2 },
 	{ LLMemType::MTYPE_VERTEX_DATA,		"Vertex Buffer",	&LLColor4::blue3 },
 	{ LLMemType::MTYPE_AVATAR,			"Avatar",			&LLColor4::purple1 },
+	{ LLMemType::MTYPE_AVATAR_MESH,		"Avatar Mesh",		&LLColor4::purple2 },
 	{ LLMemType::MTYPE_ANIMATION,		"Animation",		&LLColor4::purple3 },
 	{ LLMemType::MTYPE_REGIONS,			"Regions",			&LLColor4::blue1 },
 	{ LLMemType::MTYPE_VOLUME,			"Volume",			&LLColor4::pink1 },
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 3a33f62c38..47948281ab 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -279,7 +279,7 @@ void LLNetMap::draw()
 				gGL.color4f(0.8f, 0.8f, 0.8f, 1.f);
 			}
 
-			if (!regionp->mAlive)
+			if (!regionp->isAlive())
 			{
 				gGL.color4f(1.f, 0.5f, 0.5f, 1.f);
 			}
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index a70ca9444f..c4c7749b8a 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -441,7 +441,8 @@ bool LLPanelGroupGeneral::apply(std::string& mesg)
 		llinfos << "LLPanelGroupGeneral::apply" << llendl;
 
 		// Check to make sure mature has been set
-		if(mComboMature->getCurrentIndex() == DECLINE_TO_STATE)
+		if(mComboMature &&
+		   mComboMature->getCurrentIndex() == DECLINE_TO_STATE)
 		{
 			LLStringUtil::format_map_t args;
 			gViewerWindow->alertXml("SetGroupMature", &callbackConfirmMatureApply,
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index b181aff62d..d3fb041bad 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -1546,7 +1546,7 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
 }
 
 // BUG: Make work with multiple objects
-void LLPanelObject::sendRotation()
+void LLPanelObject::sendRotation(BOOL btn_down)
 {
 	if (mObject.isNull()) return;
 
@@ -1570,16 +1570,34 @@ void LLPanelObject::sendRotation()
 		{
 			rotation = rotation * ~mRootObject->getRotationRegion();
 		}
+		std::vector<LLVector3>& child_positions = mObject->mUnselectedChildrenPositions ;
+		std::vector<LLQuaternion> child_rotations;
+		if (mObject->isRootEdit())
+		{
+			mObject->saveUnselectedChildrenRotation(child_rotations) ;
+			mObject->saveUnselectedChildrenPosition(child_positions) ;			
+		}
 
-		mObject->setRotation(rotation, TRUE );
+		mObject->setRotation(rotation);
+		LLManip::rebuild(mObject) ;
+
+		// for individually selected roots, we need to counterrotate all the children
+		if (mObject->isRootEdit())
+		{			
+			mObject->resetChildrenRotationAndPosition(child_rotations, child_positions) ;			
+		}
 
-		LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_ROTATION);
+		if(!btn_down)
+		{
+			child_positions.clear() ;
+			LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_ROTATION | UPD_POSITION);
+		}
 	}
 }
 
 
 // BUG: Make work with multiple objects
-void LLPanelObject::sendScale()
+void LLPanelObject::sendScale(BOOL btn_down)
 {
 	if (mObject.isNull()) return;
 
@@ -1599,7 +1617,11 @@ void LLPanelObject::sendScale()
 		}
 
 		mObject->setScale(newscale, TRUE);
-		LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE | UPD_POSITION);
+
+		if(!btn_down)
+		{
+			LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE | UPD_POSITION);
+		}
 
 		LLSelectMgr::getInstance()->adjustTexturesByScale(TRUE, !dont_stretch_textures);
 //		llinfos << "scale sent" << llendl;
@@ -1611,7 +1633,7 @@ void LLPanelObject::sendScale()
 }
 
 
-void LLPanelObject::sendPosition()
+void LLPanelObject::sendPosition(BOOL btn_down)
 {	
 	if (mObject.isNull()) return;
 
@@ -1654,7 +1676,7 @@ void LLPanelObject::sendPosition()
 		LLVector3d delta = new_pos_global - old_pos_global;
 		// moved more than 1/2 millimeter
 		if (delta.magVec() >= 0.0005f)
-		{
+		{			
 			if (mRootObject != mObject)
 			{
 				newpos = newpos - mRootObject->getPositionRegion();
@@ -1664,8 +1686,21 @@ void LLPanelObject::sendPosition()
 			else
 			{
 				mObject->setPositionEdit(newpos);
+			}			
+			
+			LLManip::rebuild(mObject) ;
+
+			// for individually selected roots, we need to counter-translate all unselected children
+			if (mObject->isRootEdit())
+			{								
+				// only offset by parent's translation
+				mObject->resetChildrenPosition(LLVector3(-delta), TRUE) ;				
+			}
+
+			if(!btn_down)
+			{
+				LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);
 			}
-			LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);
 
 			LLSelectMgr::getInstance()->updateSelectionCenter();
 		}
@@ -1846,21 +1881,24 @@ void LLPanelObject::onCommitLock(LLUICtrl *ctrl, void *data)
 void LLPanelObject::onCommitPosition( LLUICtrl* ctrl, void* userdata )
 {
 	LLPanelObject* self = (LLPanelObject*) userdata;
-	self->sendPosition();
+	BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
+	self->sendPosition(btn_down);
 }
 
 // static
 void LLPanelObject::onCommitScale( LLUICtrl* ctrl, void* userdata )
 {
 	LLPanelObject* self = (LLPanelObject*) userdata;
-	self->sendScale();
+	BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
+	self->sendScale(btn_down);
 }
 
 // static
 void LLPanelObject::onCommitRotation( LLUICtrl* ctrl, void* userdata )
 {
 	LLPanelObject* self = (LLPanelObject*) userdata;
-	self->sendRotation();
+	BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
+	self->sendRotation(btn_down);
 }
 
 // static
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 87c9ce04a0..dd94922e10 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -87,9 +87,9 @@ public:
 protected:
 	void			getState();
 
-	void			sendRotation();
-	void			sendScale();
-	void			sendPosition();
+	void			sendRotation(BOOL btn_down);
+	void			sendScale(BOOL btn_down);
+	void			sendPosition(BOOL btn_down);
 	void			sendIsPhysical();
 	void			sendIsTemporary();
 	void			sendIsPhantom();
@@ -180,7 +180,7 @@ protected:
 
 	LLUUID          mSculptTextureRevert;   // so we can revert the sculpt texture on cancel
 	U8              mSculptTypeRevert;      // so we can revert the sculpt type on cancel
-	
+
 	LLPointer<LLViewerObject> mObject;
 	LLPointer<LLViewerObject> mRootObject;
 };
diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp
index fef4726b12..5ee54156b7 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/newview/llpolymesh.cpp
@@ -679,7 +679,9 @@ const LLVector2 &LLPolyMeshSharedData::getUVs(U32 index)
 // LLPolyMesh()
 //-----------------------------------------------------------------------------
 LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh)
-{
+{	
+	LLMemType mt(LLMemType::MTYPE_AVATAR_MESH);
+
 	llassert(shared_data);
 
 	mSharedData = shared_data;
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 6f2c57c055..55bad7fc7d 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -311,9 +311,7 @@ void LLPreviewTexture::saveAs()
 		mLoadingFullImage = TRUE;
 		getWindow()->incBusyCount();
 		mImage->setLoadedCallback( LLPreviewTexture::onFileLoadedForSave, 
-									0, 
-									TRUE, 
-									new LLUUID( mItemUUID ) );
+								   0, TRUE, FALSE, new LLUUID( mItemUUID ) );
 	}
 }
 
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 2f11dad010..cf11336377 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -845,9 +845,12 @@ void LLSelectMgr::highlightObjectAndFamily(LLViewerObject* objectp)
 
 	highlightObjectOnly(root_obj);
 
-	for(U32 i = 0; i < root_obj->mChildList.size(); i++)
+	LLViewerObject::const_child_list_t& child_list = root_obj->getChildren();
+	for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+		 iter != child_list.end(); iter++)
 	{
-		highlightObjectOnly(root_obj->mChildList[i]);
+		LLViewerObject* child = *iter;
+		highlightObjectOnly(child);
 	}
 }
 
@@ -872,8 +875,9 @@ void LLSelectMgr::highlightObjectAndFamily(const std::vector<LLViewerObject*>& o
 		LLViewerObject* root = (LLViewerObject*)object->getRoot();
 		mRectSelectedObjects.insert(root);
 
-		for (LLViewerObject::child_list_t::const_iterator iter2 = root->mChildList.begin();
-			 iter2 != root->mChildList.end(); ++iter2)
+		LLViewerObject::const_child_list_t& child_list = root->getChildren();
+		for (LLViewerObject::child_list_t::const_iterator iter2 = child_list.begin();
+			 iter2 != child_list.end(); iter2++)
 		{
 			LLViewerObject* child = *iter2;
 			mRectSelectedObjects.insert(child);
@@ -902,10 +906,11 @@ void LLSelectMgr::unhighlightObjectAndFamily(LLViewerObject* objectp)
 
 	unhighlightObjectOnly(root_obj);
 
-	for (LLViewerObject::child_list_t::iterator iter2 = root_obj->mChildList.begin();
-		 iter2 != root_obj->mChildList.end(); ++iter2)
+	LLViewerObject::const_child_list_t& child_list = root_obj->getChildren();
+	for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+		 iter != child_list.end(); iter++)
 	{
-		LLViewerObject* child = *iter2;
+		LLViewerObject* child = *iter;
 		unhighlightObjectOnly(child);
 	}
 }
@@ -1005,10 +1010,11 @@ void LLSelectMgr::addGridObject(LLViewerObject* objectp)
 	LLSelectNode* nodep = new LLSelectNode(objectp, FALSE);
 	mGridObjects.addNodeAtEnd(nodep);
 
-	for (LLViewerObject::child_list_t::iterator iter2 = objectp->mChildList.begin();
-		 iter2 != objectp->mChildList.end(); ++iter2)
+	LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+	for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+		 iter != child_list.end(); iter++)
 	{
-		LLViewerObject* child = *iter2;
+		LLViewerObject* child = *iter;
 		nodep = new LLSelectNode(child, FALSE);
 		mGridObjects.addNodeAtEnd(nodep);
 	}
@@ -4719,8 +4725,9 @@ void LLSelectMgr::updateSilhouettes()
 			}
 			else
 			{
-				for (LLViewerObject::child_list_t::iterator iter = objectp->mChildList.begin();
-					 iter != objectp->mChildList.end(); ++iter)
+				LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+				for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+					 iter != child_list.end(); iter++)
 				{
 					LLViewerObject* child_objectp = *iter;
 				
@@ -5412,8 +5419,9 @@ S32 get_family_count(LLViewerObject *parent)
 		llwarns << "Trying to get_family_count on null parent!" << llendl;
 	}
 	S32 count = 1;	// for this object
-	for (LLViewerObject::child_list_t::iterator iter = parent->mChildList.begin();
-		 iter != parent->mChildList.end(); ++iter)
+	LLViewerObject::const_child_list_t& child_list = parent->getChildren();
+	for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+		 iter != child_list.end(); iter++)
 	{
 		LLViewerObject* child = *iter;
 
diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h
index e9e9999ff9..35d669152e 100644
--- a/indra/newview/llsky.h
+++ b/indra/newview/llsky.h
@@ -117,9 +117,6 @@ protected:
 	F32				mSunPhase;
 	LLColor4		mFogColor;				// Color to use for fog and haze
 
-	F32				mHaze;					// a multiplier to scale the lighting
-	F32				mDomeRadius;			// sky dome size
-
 	LLVector3		mLastSunDirection;
 };
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index d24c738f2c..59b25acca4 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -188,7 +188,7 @@
 //
 // exported globals
 //
-BOOL gAgentMovementCompleted = FALSE;
+bool gAgentMovementCompleted = false;
 
 std::string SCREEN_HOME_FILENAME = "screen_home.bmp";
 std::string SCREEN_LAST_FILENAME = "screen_last.bmp";
@@ -214,7 +214,7 @@ static std::string sInitialOutfitGender;	// "male" or "female"
 
 static bool gUseCircuitCallbackCalled = false;
 
-S32 LLStartUp::gStartupState = STATE_FIRST;
+EStartupState LLStartUp::gStartupState = STATE_FIRST;
 
 
 //
@@ -225,7 +225,7 @@ void login_show();
 void login_callback(S32 option, void* userdata);
 std::string load_password_from_disk();
 void save_password_to_disk(const char* hashed_password);
-BOOL is_hex_string(U8* str, S32 len);
+bool is_hex_string(U8* str, S32 len);
 void show_first_run_dialog();
 void first_run_dialog_callback(S32 option, void* userdata);
 void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);
@@ -301,9 +301,9 @@ void update_texture_fetch()
 static std::vector<std::string> sAuthUris;
 static S32 sAuthUriNum = -1;
 
-// Returns FALSE to skip other idle processing. Should only return
-// TRUE when all initialization done.
-BOOL idle_startup()
+// Returns false to skip other idle processing. Should only return
+// true when all initialization done.
+bool idle_startup()
 {
 	LLMemType mt1(LLMemType::MTYPE_STARTUP);
 	
@@ -341,12 +341,12 @@ BOOL idle_startup()
 	static S32  agent_location_id = START_LOCATION_ID_LAST;
 	static S32  location_which = START_LOCATION_ID_LAST;
 
-	static BOOL show_connect_box = TRUE;
+	static bool show_connect_box = true;
 	static BOOL remember_password = TRUE;
 
-	static BOOL stipend_since_login = FALSE;
+	static bool stipend_since_login = false;
 
-	static BOOL samename = FALSE;
+	static bool samename = false;
 
 	// HACK: These are things from the main loop that usually aren't done
 	// until initialization is complete, but need to be done here for things
@@ -443,6 +443,18 @@ BOOL idle_startup()
 
 		LLFILE* found_template = NULL;
 		found_template = LLFile::fopen(message_template_path, "r");		/* Flawfinder: ignore */
+		
+		#if LL_WINDOWS
+			// On the windows dev builds, unpackaged, the message_template.msg 
+			// file will be located in 
+			// indra/build-vc**/newview/<config>/app_settings.
+			if (!found_template)
+			{
+				message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", "message_template.msg");
+				found_template = LLFile::fopen(message_template_path.c_str(), "r");		/* Flawfinder: ignore */
+			}	
+		#endif
+
 		if (found_template)
 		{
 			fclose(found_template);
@@ -468,7 +480,24 @@ BOOL idle_startup()
 				std::string msg = llformat("Unable to start networking, error %d", gMessageSystem->getErrorCode());
 				LLAppViewer::instance()->earlyExit(msg);
 			}
-			LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+
+			#if LL_WINDOWS
+				// On the windows dev builds, unpackaged, the message.xml file will 
+				// be located in indra/build-vc**/newview/<config>/app_settings.
+				std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml");
+							
+				if (!LLFile::isfile(message_path.c_str())) 
+				{
+					LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", ""));
+				}
+				else
+				{
+					LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+				}
+			#else			
+				LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+			#endif
+
 		}
 		else
 		{
@@ -558,7 +587,7 @@ BOOL idle_startup()
 #else
 				void* window_handle = NULL;
 #endif
-				BOOL init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle);
+				bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle);
 				if(!init)
 				{
 					LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL;
@@ -584,7 +613,7 @@ BOOL idle_startup()
 			lastname = gLoginHandler.mLastName;
 			web_login_key = gLoginHandler.mWebLoginKey;
 
-			show_connect_box = FALSE;
+			show_connect_box = false;
 		}
         else if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
         {
@@ -599,9 +628,9 @@ BOOL idle_startup()
 			remember_password = gSavedSettings.getBOOL("RememberPassword");
 			
 #ifdef USE_VIEWER_AUTH
-			show_connect_box = TRUE;
+			show_connect_box = true;
 #else
-			show_connect_box = FALSE;
+			show_connect_box = false;
 #endif
 			gSavedSettings.setBOOL("AutoLogin", TRUE);
         }
@@ -614,9 +643,9 @@ BOOL idle_startup()
 			remember_password = TRUE;
 			
 #ifdef USE_VIEWER_AUTH
-			show_connect_box = TRUE;
+			show_connect_box = true;
 #else
-			show_connect_box = FALSE;
+			show_connect_box = false;
 #endif
 		}
 		else
@@ -627,7 +656,7 @@ BOOL idle_startup()
 			lastname = gSavedSettings.getString("LastName");
 			password = load_password_from_disk();
 			remember_password = gSavedSettings.getBOOL("RememberPassword");
-			show_connect_box = TRUE;
+			show_connect_box = true;
 		}
 
 
@@ -1058,11 +1087,11 @@ BOOL idle_startup()
 	{
 		LL_DEBUGS("AppInit") << "STATE_LOGIN_PROCESS_RESPONSE" << LL_ENDL;
 		std::ostringstream emsg;
-		BOOL quit = FALSE;
+		bool quit = false;
 		std::string login_response;
 		std::string reason_response;
 		std::string message_response;
-		BOOL successful_login = FALSE;
+		bool successful_login = false;
 		LLUserAuth::UserAuthcode error = LLUserAuth::getInstance()->authResponse();
 		// reset globals
 		gAcceptTOS = FALSE;
@@ -1074,7 +1103,7 @@ BOOL idle_startup()
 			if(login_response == "true")
 			{
 				// Yay, login!
-				successful_login = TRUE;
+				successful_login = true;
 			}
 			else if(login_response == "indeterminate")
 			{
@@ -1131,11 +1160,11 @@ BOOL idle_startup()
 																	message_response);
 						tos_dialog->startModal();
 						// LLFloaterTOS deletes itself.
-						return FALSE;
+						return false;
 					}
 					else
 					{
-						quit = TRUE;
+						quit = true;
 					}
 				}
 				if(reason_response == "critical")
@@ -1148,11 +1177,11 @@ BOOL idle_startup()
 																	message_response);
 						tos_dialog->startModal();
 						// LLFloaterTOS deletes itself.
-						return FALSE;
+						return false;
 					}
 					else
 					{
-						quit = TRUE;
+						quit = true;
 					}
 				}
 				if(reason_response == "key")
@@ -1168,11 +1197,11 @@ BOOL idle_startup()
 					{
 						update_app(TRUE, auth_message);
 						LLStartUp::setStartupState( STATE_UPDATE_CHECK );
-						return FALSE;
+						return false;
 					}
 					else
 					{
-						quit = TRUE;
+						quit = true;
 					}
 				}
 				if(reason_response == "optional")
@@ -1184,7 +1213,7 @@ BOOL idle_startup()
 						update_app(FALSE, auth_message);
 						LLStartUp::setStartupState( STATE_UPDATE_CHECK );
 						gSkipOptionalUpdate = TRUE;
-						return FALSE;
+						return false;
 					}
 				}
 			}
@@ -1216,7 +1245,7 @@ BOOL idle_startup()
 		{
 			LLUserAuth::getInstance()->reset();
 			LLAppViewer::instance()->forceQuit();
-			return FALSE;
+			return false;
 		}
 
 		if(successful_login)
@@ -1358,7 +1387,7 @@ BOOL idle_startup()
 				it = options[0].find("stipend_since_login");
 				if(it != no_flag)
 				{
-					if((*it).second == "Y") stipend_since_login = TRUE;
+					if((*it).second == "Y") stipend_since_login = true;
 				}
 				it = options[0].find("gendered");
 				if(it != no_flag)
@@ -1443,7 +1472,7 @@ BOOL idle_startup()
 				gViewerWindow->alertXml("ErrorMessage", args, login_alert_done);
 				reset_login();
 				gSavedSettings.setBOOL("AutoLogin", FALSE);
-				show_connect_box = TRUE;
+				show_connect_box = true;
 			}
 			
 			// Pass the user information to the voice chat server interface.
@@ -1463,7 +1492,7 @@ BOOL idle_startup()
 			gViewerWindow->alertXml("ErrorMessage", args, login_alert_done);
 			reset_login();
 			gSavedSettings.setBOOL("AutoLogin", FALSE);
-			show_connect_box = TRUE;
+			show_connect_box = true;
 			// Don't save an incorrect password to disk.
 			save_password_to_disk(NULL);
 		}
@@ -2002,7 +2031,7 @@ BOOL idle_startup()
 		llinfos << "Requesting Agent Data" << llendl;
 		gAgent.sendAgentDataUpdateRequest();
 
-		BOOL shown_at_exit = gSavedSettings.getBOOL("ShowInventory");
+		bool shown_at_exit = gSavedSettings.getBOOL("ShowInventory");
 
 		// Create the inventory views
 		llinfos << "Creating Inventory Views" << llendl;
@@ -2113,8 +2142,8 @@ BOOL idle_startup()
 						const BOOL no_inform_server = FALSE;
 						const BOOL no_deactivate_similar = FALSE;
 						gGestureManager.activateGestureWithAsset(item_id, asset_id,
-																 no_inform_server,
-																 no_deactivate_similar);
+											 no_inform_server,
+											 no_deactivate_similar);
 						// We need to fetch the inventory items for these gestures
 						// so we have the names to populate the UI.
 						item_ids.push_back(item_id);
@@ -2536,9 +2565,9 @@ void save_password_to_disk(const char* hashed_password)
 	}
 }
 
-BOOL is_hex_string(U8* str, S32 len)
+bool is_hex_string(U8* str, S32 len)
 {
-	BOOL rv = TRUE;
+	bool rv = true;
 	U8* c = str;
 	while(rv && len--)
 	{
@@ -2563,7 +2592,7 @@ BOOL is_hex_string(U8* str, S32 len)
 			++c;
 			break;
 		default:
-			rv = FALSE;
+			rv = false;
 			break;
 		}
 	}
@@ -2683,7 +2712,7 @@ void update_app(BOOL mandatory, const std::string& auth_msg)
 void update_dialog_callback(S32 option, void *userdata)
 {
 	std::string update_exe_path;
-	BOOL mandatory = userdata != NULL;
+	bool mandatory = userdata != NULL;
 
 #if !LL_RELEASE_FOR_DOWNLOAD
 	if (option == 2)
@@ -2805,7 +2834,7 @@ void update_dialog_callback(S32 option, void *userdata)
 	
 	update_exe_path = "'";
 	update_exe_path += gDirUtilp->getAppRODataDir();
-	update_exe_path += "/AutoUpdater.app/Contents/MacOS/AutoUpdater' -url \"";
+	update_exe_path += "/mac-updater.app/Contents/MacOS/mac-updater' -url \"";
 	update_exe_path += update_url.asString();
 	update_exe_path += "\" -name \"";
 	update_exe_path += LLAppViewer::instance()->getSecondLifeTitle();
@@ -3709,9 +3738,45 @@ void release_start_screen()
 
 
 // static
-void LLStartUp::setStartupState( S32 state )
+std::string LLStartUp::startupStateToString(EStartupState state)
+{
+#define RTNENUM(E) case E: return #E
+	switch(state){
+		RTNENUM( STATE_FIRST );
+		RTNENUM( STATE_LOGIN_SHOW );
+		RTNENUM( STATE_LOGIN_WAIT );
+		RTNENUM( STATE_LOGIN_CLEANUP );
+		RTNENUM( STATE_UPDATE_CHECK );
+		RTNENUM( STATE_LOGIN_AUTH_INIT );
+		RTNENUM( STATE_LOGIN_AUTHENTICATE );
+		RTNENUM( STATE_LOGIN_NO_DATA_YET );
+		RTNENUM( STATE_LOGIN_DOWNLOADING );
+		RTNENUM( STATE_LOGIN_PROCESS_RESPONSE );
+		RTNENUM( STATE_WORLD_INIT );
+		RTNENUM( STATE_SEED_GRANTED_WAIT );
+		RTNENUM( STATE_SEED_CAP_GRANTED );
+		RTNENUM( STATE_WORLD_WAIT );
+		RTNENUM( STATE_AGENT_SEND );
+		RTNENUM( STATE_AGENT_WAIT );
+		RTNENUM( STATE_INVENTORY_SEND );
+		RTNENUM( STATE_MISC );
+		RTNENUM( STATE_PRECACHE );
+		RTNENUM( STATE_WEARABLES_WAIT );
+		RTNENUM( STATE_CLEANUP );
+		RTNENUM( STATE_STARTED );
+	default:
+		return llformat("(state #%d)", state);
+	}
+#undef RTNENUM
+}
+
+
+// static
+void LLStartUp::setStartupState( EStartupState state )
 {
-	LL_INFOS("AppInit") << "Startup state changing from " << gStartupState << " to " << state << LL_ENDL;
+	LL_INFOS("AppInit") << "Startup state changing from " <<  
+		startupStateToString(gStartupState) << " to " <<  
+		startupStateToString(state) << LL_ENDL;
 	gStartupState = state;
 }
 
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index ea568395d4..3cfe1ca97f 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -35,7 +35,7 @@
 #include "llimagegl.h"
 
 // functions
-BOOL idle_startup();
+bool idle_startup();
 std::string load_password_from_disk();
 void release_start_screen();
 void login_alert_done(S32 option, void* user_data);
@@ -44,7 +44,7 @@ void login_alert_done(S32 option, void* user_data);
 extern std::string SCREEN_HOME_FILENAME;
 extern std::string SCREEN_LAST_FILENAME;
 
-enum EStartupState{
+typedef enum {
 	STATE_FIRST,					// Initial startup
 	STATE_BROWSER_INIT,             // Initialize web browser for login screen
 	STATE_LOGIN_SHOW,				// Show login screen
@@ -69,10 +69,10 @@ enum EStartupState{
 	STATE_WEARABLES_WAIT,			// Wait for clothing to download
 	STATE_CLEANUP,					// Final cleanup
 	STATE_STARTED					// Up and running in-world
-};
+} EStartupState;
 
 // exported symbols
-extern BOOL gAgentMovementCompleted;
+extern bool gAgentMovementCompleted;
 extern LLPointer<LLImageGL> gStartImageGL;
 extern std::string gInitialOutfit;
 extern std::string gInitialOutfitGender;	// "male" or "female"
@@ -85,8 +85,8 @@ public:
 		// going full screen
 
 	// Always use this to set gStartupState so changes are logged
-	static void	setStartupState( S32 state );
-	static S32	getStartupState()				{ return gStartupState;		};
+	static void setStartupState( EStartupState state );
+	static EStartupState getStartupState() { return gStartupState; };
 
 	static void multimediaInit();
 		// Initialize LLViewerMedia multimedia engine.
@@ -105,8 +105,9 @@ public:
 		// *HACK: On startup, if we were passed a secondlife://app/do/foo
 		// command URL, store it for later processing.
 
-protected:
-	static S32 gStartupState;			// Do not set directly, use LLStartup::setStartupState
+private:
+	static std::string startupStateToString(EStartupState state);
+	static EStartupState gStartupState; // Do not set directly, use LLStartup::setStartupState
 };
 
 
diff --git a/indra/newview/llstylemap.cpp b/indra/newview/llstylemap.cpp
index 0f092b31c4..bff23590d3 100644
--- a/indra/newview/llstylemap.cpp
+++ b/indra/newview/llstylemap.cpp
@@ -73,3 +73,13 @@ const LLStyleSP &LLStyleMap::lookup(const LLUUID &source)
 	}
 	return (*this)[source];
 }
+
+void LLStyleMap::update()
+{
+	for (style_map_t::iterator iter = begin(); iter != end(); ++iter)
+	{
+		LLStyleSP &style = iter->second;
+		// Update the link color in case it has been changed.
+		style->setColor(gSavedSettings.getColor4("HTMLLinkColor"));
+	}
+}
diff --git a/indra/newview/llstylemap.h b/indra/newview/llstylemap.h
index 4cff69fc73..fbf12a04a3 100644
--- a/indra/newview/llstylemap.h
+++ b/indra/newview/llstylemap.h
@@ -49,6 +49,9 @@ public:
 	// Just like the [] accessor but it will add the entry in if it doesn't exist.
 	const LLStyleSP &lookup(const LLUUID &source); 
 	static LLStyleMap &instance();
+
+	// Forces refresh of the entries, call when something changes (e.g. link color).
+	void update();
 };
 
 #endif  // LL_LLSTYLE_MAP_H
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 43f8391b55..d83a2ec944 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -459,14 +459,15 @@ void LLGLTexMemBar::draw()
 
 	//----------------------------------------------------------------------------
 
-	text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d",
+	text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d mRaw:%d mAux:%d CB:%d",
 					gImageList.getNumImages(),
 					LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(),
 					LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, 
 					LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),
 					LLLFSThread::sLocal->getPending(),
 					LLImageWorker::sCount, LLImageWorker::getWorkerThread()->getNumDeletes(),
-					LLImageRaw::sRawImageCount);
+					LLImageRaw::sRawImageCount, LLViewerImage::sRawCount, LLViewerImage::sAuxCount,
+					gImageList.mCallbackList.size());
 
 	LLFontGL::sMonospace->renderUTF8(text, 0, 0, line_height*2,
 									 text_color, LLFontGL::LEFT, LLFontGL::TOP);
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index 22690b550a..11e90e9c84 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -135,12 +135,12 @@ void LLTool::setMouseCapture( BOOL b )
 {
 	if( b )
 	{
-		gViewerWindow->setMouseCapture(mComposite ? mComposite : this );
+		gFocusMgr.setMouseCapture(mComposite ? mComposite : this );
 	}
 	else
 	if( hasMouseCapture() )
 	{
-		gViewerWindow->setMouseCapture( NULL );
+		gFocusMgr.setMouseCapture( NULL );
 	}
 }
 
diff --git a/indra/newview/lltool.h b/indra/newview/lltool.h
index 3cc7f24712..0113fe808c 100644
--- a/indra/newview/lltool.h
+++ b/indra/newview/lltool.h
@@ -62,6 +62,9 @@ public:
 	virtual BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleRightMouseUp(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen);
+
+	virtual EShowToolTip getShowToolTip() { return SHOW_ALWAYS; }; // tools should permit tips even when the mouse is down, as that's pretty normal for tools
+
 		// Return FALSE to allow context menu to be shown.
 	virtual void	screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const
 							{ *local_x = screen_x; *local_y = screen_y;	}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 109a11755b..fd6d3e77a4 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -42,6 +42,7 @@
 #include "llfirstuse.h"
 #include "llfloater.h"
 #include "llfloatertools.h"
+#include "llfocusmgr.h"
 #include "llgesturemgr.h"
 #include "llhudeffecttrail.h"
 #include "llhudmanager.h"
@@ -52,6 +53,7 @@
 #include "llpreviewnotecard.h"
 #include "llselectmgr.h"
 #include "lltoolmgr.h"
+#include "lltrans.h"
 #include "llui.h"
 #include "llviewerimagelist.h"
 #include "llviewerinventory.h"
@@ -70,10 +72,6 @@
 // or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a
 // bit from there to give some pad.
 const S32 MAX_ITEMS = 42;
-const char* FOLDER_INCLUDES_ATTACHMENTS_BEING_WORN = 
-				"Cannot give folders that contain objects that are attached to you.\n"
-				"Detach the object(s) and then try again.";
-
 
 // syntactic sugar
 #define callMemberFunction(object,ptrToMember)  ((object).*(ptrToMember))
@@ -127,41 +125,17 @@ protected:
 };
 
 bool LLDroppableItem::operator()(LLInventoryCategory* cat,
-								 LLInventoryItem* item)
+				 LLInventoryItem* item)
 {
 	bool allowed = false;
 	if(item)
 	{
-		LLVOAvatar* my_avatar = NULL;
-		switch(item->getType())
-		{
-		case LLAssetType::AT_CALLINGCARD:
-			// not allowed
-			break;
-
-		case LLAssetType::AT_OBJECT:
-			my_avatar = gAgent.getAvatarObject();
-			if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
-			{
-				allowed = true;
-			}
-			break;
-
-		case LLAssetType::AT_BODYPART:
-		case LLAssetType::AT_CLOTHING:
-			if(!gAgent.isWearingItem(item->getUUID()))
-			{
-				allowed = true;
-			}
-			break;
+		allowed = itemTransferCommonlyAllowed(item);
 
-		default:
-			allowed = true;
-			break;
-		}
-		if(mIsTransfer
+		if(allowed
+		   && mIsTransfer
 		   && !item->getPermissions().allowOperationBy(PERM_TRANSFER,
-													   gAgent.getID()))
+							       gAgent.getID()))
 		{
 			allowed = false;
 		}
@@ -182,45 +156,18 @@ public:
 };
 
 bool LLUncopyableItems::operator()(LLInventoryCategory* cat,
-								   LLInventoryItem* item)
+				   LLInventoryItem* item)
 {
-	BOOL uncopyable = FALSE;
+	bool uncopyable = false;
 	if(item)
 	{
-		BOOL allowed = FALSE;
-		LLVOAvatar* my_avatar = NULL;
-		switch(item->getType())
-		{
-		case LLAssetType::AT_CALLINGCARD:
-			// not allowed
-			break;
-
-		case LLAssetType::AT_OBJECT:
-			my_avatar = gAgent.getAvatarObject();
-			if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
-			{
-				allowed = TRUE;
-			}
-			break;
-
-		case LLAssetType::AT_BODYPART:
-		case LLAssetType::AT_CLOTHING:
-			if(!gAgent.isWearingItem(item->getUUID()))
-			{
-				allowed = TRUE;
-			}
-			break;
-
-		default:
-			allowed = TRUE;
-			break;
-		}
-		if(allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
+		if (itemTransferCommonlyAllowed(item) &&
+		   !item->getPermissions().allowCopyBy(gAgent.getID()))
 		{
-			uncopyable = TRUE;
+			uncopyable = true;
 		}
 	}
-	return (uncopyable ? true : false);
+	return uncopyable;
 }
 
 class LLDropCopyableItems : public LLInventoryCollectFunctor
@@ -233,45 +180,21 @@ public:
 
 
 bool LLDropCopyableItems::operator()(
-	LLInventoryCategory* cat, LLInventoryItem* item)
+	LLInventoryCategory* cat,
+	LLInventoryItem* item)
 {
-	BOOL allowed = FALSE;
+	bool allowed = false;
 	if(item)
 	{
-		LLVOAvatar* my_avatar = NULL;
-		switch(item->getType())
-		{
-		case LLAssetType::AT_CALLINGCARD:
-			// not allowed
-			break;
-
-		case LLAssetType::AT_OBJECT:
-			my_avatar = gAgent.getAvatarObject();
-			if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
-			{
-				allowed = TRUE;
-			}
-			break;
-
-		case LLAssetType::AT_BODYPART:
-		case LLAssetType::AT_CLOTHING:
-			if(!gAgent.isWearingItem(item->getUUID()))
-			{
-				allowed = TRUE;
-			}
-			break;
-
-		default:
-			allowed = TRUE;
-			break;
-		}
-		if(allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
+		allowed = itemTransferCommonlyAllowed(item);
+		if(allowed &&
+		   !item->getPermissions().allowCopyBy(gAgent.getID()))
 		{
 			// whoops, can't copy it - don't allow it.
-			allowed = FALSE;
+			allowed = false;
 		}
 	}
-	return (allowed ? true : false);
+	return allowed;
 }
 
 class LLGiveable : public LLInventoryCollectFunctor
@@ -289,48 +212,26 @@ protected:
 bool LLGiveable::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
 {
 	// All categories can be given.
-	if(cat) return TRUE;
-	BOOL allowed = FALSE;
+	if (cat)
+		return true;
+
+	bool allowed = false;
 	if(item)
 	{
-		LLVOAvatar* my_avatar = NULL;
-		switch(item->getType())
-		{
-		case LLAssetType::AT_CALLINGCARD:
-			// not allowed
-			break;
-
-		case LLAssetType::AT_OBJECT:
-			my_avatar = gAgent.getAvatarObject();
-			if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID()))
-			{
-				allowed = TRUE;
-			}
-			break;
-
-		case LLAssetType::AT_BODYPART:
-		case LLAssetType::AT_CLOTHING:
-			if(!gAgent.isWearingItem(item->getUUID()))
-			{
-				allowed = TRUE;
-			}
-			break;
-
-		default:
-			allowed = TRUE;
-			break;
-		}
-		if(!item->getPermissions().allowOperationBy(PERM_TRANSFER,
-													gAgent.getID()))
+		allowed = itemTransferCommonlyAllowed(item);
+		if(allowed &&
+		   !item->getPermissions().allowOperationBy(PERM_TRANSFER,
+							    gAgent.getID()))
 		{
 			allowed = FALSE;
 		}
-		if(allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
+		if(allowed &&
+		   !item->getPermissions().allowCopyBy(gAgent.getID()))
 		{
 			++mCountLosing;
 		}
 	}
-	return (allowed ? true : false);
+	return allowed;
 }
 
 class LLCategoryFireAndForget : public LLInventoryFetchComboObserver
@@ -687,7 +588,7 @@ void LLToolDragAndDrop::beginMultiDrag(
 	mCursor = UI_CURSOR_NO;
 	if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
 	{
-		// find cats in the cargo.
+		// find categories (i.e. inventory folders) in the cargo.
 		LLInventoryCategory* cat = NULL;
 		S32 count = llmin(cargo_ids.size(), types.size());
 		std::set<LLUUID> cat_ids;
@@ -736,7 +637,7 @@ void LLToolDragAndDrop::endDrag()
 
 void LLToolDragAndDrop::onMouseCaptureLost()
 {
-	// Called whenever the drag ends or if mouse captue is simply lost
+	// Called whenever the drag ends or if mouse capture is simply lost
 	LLToolMgr::getInstance()->clearTransientTool();
 	mCargoTypes.clear();
 	mCargoIDs.clear();
@@ -756,11 +657,8 @@ BOOL LLToolDragAndDrop::handleMouseUp( S32 x, S32 y, MASK mask )
 	return TRUE;
 }
 
-BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
+ECursorType LLToolDragAndDrop::acceptanceToCursor( EAcceptance acceptance )
 {
-	EAcceptance acceptance = ACCEPT_NO;
-	dragOrDrop( x, y, mask, FALSE, &acceptance );
-
 	switch( acceptance )
 	{
 	case ACCEPT_YES_MULTI:
@@ -773,8 +671,16 @@ BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
 			mCursor = UI_CURSOR_ARROWDRAG;
 		}
 		break;
-	case ACCEPT_YES_SINGLE: 
-		mCursor = UI_CURSOR_ARROWDRAG;
+	case ACCEPT_YES_SINGLE:
+		if (mCargoIDs.size() > 1)
+		{
+			mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop");
+			mCursor = UI_CURSOR_NO;
+		}
+		else
+		{
+			mCursor = UI_CURSOR_ARROWDRAG;
+		}
 		break;
 
 	case ACCEPT_NO_LOCKED:
@@ -796,7 +702,15 @@ BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
 		}
 		break;
 	case ACCEPT_YES_COPY_SINGLE:
-		mCursor = UI_CURSOR_ARROWCOPY;
+		if (mCargoIDs.size() > 1)
+		{
+			mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop");
+			mCursor = UI_CURSOR_NO;
+		}
+		else
+		{
+			mCursor = UI_CURSOR_ARROWCOPY;
+		}
 		break;
 	case ACCEPT_POSTPONED:
 		break;
@@ -804,7 +718,17 @@ BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
 		llassert( FALSE );
 	}
 
-	gViewerWindow->getWindow()->setCursor( mCursor );
+	return mCursor;
+}
+
+BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
+{
+	EAcceptance acceptance = ACCEPT_NO;
+	dragOrDrop( x, y, mask, FALSE, &acceptance );
+
+	ECursorType cursor = acceptanceToCursor(acceptance);
+	gViewerWindow->getWindow()->setCursor( cursor );
+
 	lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolDragAndDrop" << llendl;
 	return TRUE;
 }
@@ -826,7 +750,7 @@ BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, std::string& msg, LLRect *st
 	if (!mToolTipMsg.empty())
 	{
 		msg = mToolTipMsg;
-		//*stick_rect_screen = gViewerWindow->getWindowRect();
+		//*sticky_rect_screen = gViewerWindow->getWindowRect();
 		return TRUE;
 	}
 	return FALSE;
@@ -845,11 +769,11 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 
 	BOOL handled = FALSE;
 
-	LLView* top_view = gViewerWindow->getTopCtrl();
+	LLView* top_view = gFocusMgr.getTopCtrl();
 	LLViewerInventoryItem* item;
 	LLViewerInventoryCategory* cat;
 
-	mToolTipMsg.assign("");
+	mToolTipMsg.clear();
 
 	if(top_view)
 	{
@@ -884,17 +808,15 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 		// all objects passed, go ahead and perform drop if necessary
 		if (handled && drop && (U32)*acceptance >= ACCEPT_YES_COPY_SINGLE)
 		{
-			// drop all items
-			if ((U32)*acceptance >= ACCEPT_YES_COPY_MULTI)
-			{
-				mCurItemIndex = 0;
-			}
-			// drop just last item
-			else
+			if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI &&
+			    mCargoIDs.size() > 1)
 			{
-				mCurItemIndex = mCargoIDs.size() - 1;
+				// tried to give multi-cargo to a single-acceptor - refuse and return.
+				*acceptance = ACCEPT_NO;
+				return;
 			}
-			for (; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
+
+			for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
 			{
 				LLInventoryObject* cargo = locateInventory(item, cat);
 
@@ -943,30 +865,26 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 		// all objects passed, go ahead and perform drop if necessary
 		if (handled && drop && (U32)*acceptance > ACCEPT_NO_LOCKED)
 		{	
-			// drop all items
-			if ((U32)*acceptance >= ACCEPT_YES_COPY_MULTI)
+			if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI &&
+			    mCargoIDs.size() > 1)
 			{
-				mCurItemIndex = 0;
-			}
-			// drop just last item
-			else
-			{
-				mCurItemIndex = mCargoIDs.size() - 1;
+				// tried to give multi-cargo to a single-acceptor - refuse and return.
+				*acceptance = ACCEPT_NO;
+				return;
 			}
-			for (; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
+
+			for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
 			{
 				LLInventoryObject* cargo = locateInventory(item, cat);
 
 				if (cargo)
 				{
-					//S32 local_x, local_y;
-
 					EAcceptance item_acceptance;
 					handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
-														mCargoTypes[mCurItemIndex],
-														(void*)cargo,
-														&item_acceptance,
-														mToolTipMsg);
+											  mCargoTypes[mCurItemIndex],
+											  (void*)cargo,
+											  &item_acceptance,
+											  mToolTipMsg);
 				}
 			}
 		}
@@ -1081,76 +999,36 @@ void LLToolDragAndDrop::pickCallback(const LLPickInfo& pick_info)
 				(hit_obj, hit_face, pick_info.mKeyMask, FALSE));
 	}
 
-	if (LLToolDragAndDrop::getInstance()->mDrop && (U32)LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_SINGLE)
+	if (LLToolDragAndDrop::getInstance()->mDrop &&
+	    (U32)LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_SINGLE)
 	{
-		// if target allows multi-drop, go ahead and start iteration at beginning of cargo list
-		if (LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_MULTI)
+		// if target allows multi-drop or there is only one item being dropped, go ahead
+		if (LLToolDragAndDrop::getInstance()->mLastAccept >= ACCEPT_YES_COPY_MULTI ||
+		    LLToolDragAndDrop::getInstance()->mCargoIDs.size() == 1)
 		{
-			LLToolDragAndDrop::getInstance()->mCurItemIndex = 0;
+			// Target accepts multi, or cargo is a single-drop
+			for (LLToolDragAndDrop::getInstance()->mCurItemIndex = 0;
+			     LLToolDragAndDrop::getInstance()->mCurItemIndex < (S32)LLToolDragAndDrop::getInstance()->mCargoIDs.size(); 
+			     LLToolDragAndDrop::getInstance()->mCurItemIndex++)
+			{
+				// Call the right implementation function
+				(U32)callMemberFunction((*LLToolDragAndDrop::getInstance()), 
+							LLToolDragAndDrop::getInstance()->sDragAndDrop3d[LLToolDragAndDrop::getInstance()->mCargoTypes[LLToolDragAndDrop::getInstance()->mCurItemIndex]][target])
+					(hit_obj, hit_face, pick_info.mKeyMask, TRUE);
+			}
 		}
-		// otherwise start at end, to follow selection rules (last selected item is most current)
 		else
 		{
-			LLToolDragAndDrop::getInstance()->mCurItemIndex = LLToolDragAndDrop::getInstance()->mCargoIDs.size() - 1;
-		}
-
-		for (; LLToolDragAndDrop::getInstance()->mCurItemIndex < (S32)LLToolDragAndDrop::getInstance()->mCargoIDs.size(); 
-			LLToolDragAndDrop::getInstance()->mCurItemIndex++)
-		{
-			// Call the right implementation function
-			(U32)callMemberFunction((*LLToolDragAndDrop::getInstance()), 
-				LLToolDragAndDrop::getInstance()->sDragAndDrop3d[LLToolDragAndDrop::getInstance()->mCargoTypes[LLToolDragAndDrop::getInstance()->mCurItemIndex]][target])
-				(hit_obj, hit_face, pick_info.mKeyMask, TRUE);
+			// Target does not accept multi, but cargo is multi
+			LLToolDragAndDrop::getInstance()->mLastAccept = ACCEPT_NO;
 		}
 	}
 
-	switch( LLToolDragAndDrop::getInstance()->mLastAccept )
-	{
-	case ACCEPT_YES_MULTI: 
-		if (LLToolDragAndDrop::getInstance()->mCargoIDs.size() > 1)
-		{
-			LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWDRAGMULTI;
-		}
-		else
-		{
-			LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWDRAG;
-		}
-		break;
-	case ACCEPT_YES_SINGLE: 
-		LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWDRAG;
-		break;
-
-	case ACCEPT_NO_LOCKED:
-		LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_NOLOCKED;
-		break;
-
-	case ACCEPT_NO:
-		LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_NO;
-		break;
-
-	case ACCEPT_YES_COPY_MULTI:
-	if (LLToolDragAndDrop::getInstance()->mCargoIDs.size() > 1)
-		{
-			LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWCOPYMULTI;
-		}
-		else
-		{
-			LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWCOPY;
-		}
-		break;
-	case ACCEPT_YES_COPY_SINGLE:
-		LLToolDragAndDrop::getInstance()->mCursor = UI_CURSOR_ARROWCOPY;
-		break;
-	case ACCEPT_POSTPONED:
-		break;
-	default:
-		llassert( FALSE );
-	}
+	ECursorType cursor = LLToolDragAndDrop::getInstance()->acceptanceToCursor( LLToolDragAndDrop::getInstance()->mLastAccept );
+	gViewerWindow->getWindow()->setCursor( cursor );
 
 	LLToolDragAndDrop::getInstance()->mLastHitPos = pick_info.mPosGlobal;
 	LLToolDragAndDrop::getInstance()->mLastCameraPos = gAgent.getCameraPositionGlobal();
-
-	gViewerWindow->getWindow()->setCursor( LLToolDragAndDrop::getInstance()->mCursor );
 }
 
 // static
@@ -1229,7 +1107,7 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
 	else if(!item->getPermissions().allowOperationBy(PERM_TRANSFER,
 													 gAgent.getID()))
 	{
-		// Check that we can add the testure as inventory to the object
+		// Check that we can add the texture as inventory to the object
 		if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
 		{
 			return FALSE;
@@ -1605,7 +1483,7 @@ struct LLGiveInventoryInfo
 };
 
 void LLToolDragAndDrop::giveInventory(const LLUUID& to_agent,
-									  LLInventoryItem* item)
+				      LLInventoryItem* item)
 {
 	llinfos << "LLToolDragAndDrop::giveInventory()" << llendl;
 	if(!isInventoryGiveAcceptable(item))
@@ -1621,11 +1499,11 @@ void LLToolDragAndDrop::giveInventory(const LLUUID& to_agent,
 	{
 		// ask if the agent is sure.
 		LLGiveInventoryInfo* info = new LLGiveInventoryInfo(to_agent,
-															item->getUUID());
+								    item->getUUID());
 
 		gViewerWindow->alertXml("CannotCopyWarning",
-								  &LLToolDragAndDrop::handleCopyProtectedItem,
-								  (void*)info);
+					&LLToolDragAndDrop::handleCopyProtectedItem,
+					(void*)info);
 	}
 }
 
@@ -1920,11 +1798,13 @@ BOOL LLToolDragAndDrop::isInventoryGiveAcceptable(LLInventoryItem* item)
 	}
 	BOOL copyable = FALSE;
 	if(item->getPermissions().allowCopyBy(gAgent.getID())) copyable = TRUE;
+
 	LLVOAvatar* my_avatar = gAgent.getAvatarObject();
 	if(!my_avatar)
 	{
 		return FALSE;
 	}
+
 	BOOL acceptable = TRUE;
 	switch(item->getType())
 	{
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 8e2788a173..f9e1d75754 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -178,6 +178,9 @@ protected:
 	EAcceptance dad3dActivateGesture(LLViewerObject *obj, S32 face,
 								 MASK mask, BOOL drop);
 
+	// set the LLToolDragAndDrop's cursor based on the given acceptance
+	ECursorType acceptanceToCursor( EAcceptance acceptance );
+
 	// This method converts mCargoID to an inventory item or
 	// folder. If no item or category is found, both pointers will be
 	// returned NULL.
@@ -189,9 +192,9 @@ protected:
 	//	LLViewerInventoryItem::item_array_t& items);
 
 	void dropObject(LLViewerObject* raycast_target,
-					BOOL bypass_sim_raycast,
-					BOOL from_task_inventory,
-					BOOL remove_from_inventory);
+			BOOL bypass_sim_raycast,
+			BOOL from_task_inventory,
+			BOOL remove_from_inventory);
 	
 	// accessor that looks at permissions, copyability, and names of
 	// inventory items to determine if a drop would be ok.
@@ -200,9 +203,9 @@ protected:
 	// deal with permissions of object, etc. returns TRUE if drop can
 	// proceed, otherwise FALSE.
 	static BOOL handleDropTextureProtections(LLViewerObject* hit_obj,
-											 LLInventoryItem* item,
-											 LLToolDragAndDrop::ESource source,
-											 const LLUUID& src_id);
+						 LLInventoryItem* item,
+						 LLToolDragAndDrop::ESource source,
+						 const LLUUID& src_id);
 
 
 	// give inventory item functionality
@@ -213,7 +216,7 @@ protected:
 	// give inventory category functionality
 	static void handleCopyProtectedCategory(S32 option, void* data);
 	static void commitGiveInventoryCategory(const LLUUID& to_agent,
-											LLInventoryCategory* cat);
+						LLInventoryCategory* cat);
 public:
 	// helper functions
 	static BOOL isInventoryDropAcceptable(LLViewerObject* obj, LLInventoryItem* item) { return (ACCEPT_YES_COPY_SINGLE <= willObjectAcceptInventory(obj, item)); }
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index e74cd58924..50c6de704a 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -199,9 +199,12 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
 					select_node->setTransient(TRUE);
 				}
 
-				for (S32 i = 0; i < (S32)root_object->mChildList.size(); i++)
+				LLViewerObject::const_child_list_t& child_list = root_object->getChildren();
+				for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+					 iter != child_list.end(); iter++)
 				{
-					select_node = selection->findNode(root_object->mChildList[i]);
+					LLViewerObject* child = *iter;
+					select_node = selection->findNode(child);
 					if (select_node)
 					{
 						select_node->setTransient(TRUE);
diff --git a/indra/newview/lluploaddialog.cpp b/indra/newview/lluploaddialog.cpp
index e347affa52..79225f82b0 100644
--- a/indra/newview/lluploaddialog.cpp
+++ b/indra/newview/lluploaddialog.cpp
@@ -85,7 +85,7 @@ LLUploadDialog::LLUploadDialog( const std::string& msg)
 	setMessage(msg);
 
 	// The dialog view is a root view
-	gViewerWindow->setTopCtrl( this );
+	gFocusMgr.setTopCtrl( this );
 }
 
 void LLUploadDialog::setMessage( const std::string& msg)
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 6b324cae9d..a62bf9b9cf 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -141,6 +141,12 @@ static bool handleAvatarLODChanged(const LLSD& newvalue)
 	return true;
 }
 
+static bool handleAvatarMaxVisibleChanged(const LLSD& newvalue)
+{
+	LLVOAvatar::sMaxVisible = (U32) newvalue.asInteger();
+	return true;
+}
+
 static bool handleTerrainLODChanged(const LLSD& newvalue)
 {
 		LLVOSurfacePatch::sLODFactor = (F32)newvalue.asReal();
@@ -454,6 +460,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
 	gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
 	gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
+	gSavedSettings.getControl("RenderAvatarMaxVisible")->getSignal()->connect(boost::bind(&handleAvatarMaxVisibleChanged, _1));
 	gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _1));
 	gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _1));
 	gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _1));
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 0e83ba1123..99abfb02ee 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -106,7 +106,7 @@ LLFrameTimer gRecentMemoryTime;
 // Rendering stuff
 void pre_show_depth_buffer();
 void post_show_depth_buffer();
-void render_ui_and_swap();
+void render_ui();
 void render_hud_attachments();
 void render_ui_3d();
 void render_ui_2d();
@@ -456,7 +456,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 	if (gDisconnected)
 	{
 		LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
-		render_ui_and_swap();
+		render_ui();
 		render_disconnected_background();
 	}
 	
@@ -760,7 +760,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 
 		if (!for_snapshot)
 		{
-			render_ui_and_swap();
+			render_ui();
 		}
 
 		LLSpatialGroup::sNoDelete = FALSE;
@@ -931,7 +931,7 @@ BOOL setup_hud_matrices(const LLRect& screen_region)
 }
 
 
-void render_ui_and_swap()
+void render_ui()
 {
 	LLGLState::checkStates();
 	
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 0a2e328015..d66d0da5b1 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -129,8 +129,9 @@ void LLViewerJointAttachment::setupDrawable(LLDrawable* drawablep)
 		}
 	}
 
-	for (LLViewerObject::child_list_t::iterator iter = mAttachedObject->mChildList.begin();
-		 iter != mAttachedObject->mChildList.end(); ++iter)
+	LLViewerObject::const_child_list_t& child_list = mAttachedObject->getChildren();
+	for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+		 iter != child_list.end(); iter++)
 	{
 		LLViewerObject* childp = *iter;
 		if (childp && childp->mDrawable.notNull())
@@ -208,8 +209,9 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
 		{
 			object->mText->setOnHUDAttachment(TRUE);
 		}
-		for (LLViewerObject::child_list_t::iterator iter = object->mChildList.begin();
-			iter != object->mChildList.end(); ++iter)
+		LLViewerObject::const_child_list_t& child_list = object->getChildren();
+		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+			 iter != child_list.end(); iter++)
 		{
 			LLViewerObject* childp = *iter;
 			if (childp && childp->mText.notNull())
@@ -258,8 +260,9 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
 		}
 	}
 
-	for (LLViewerObject::child_list_t::iterator iter = object->mChildList.begin();
-		 iter != object->mChildList.end(); ++iter)
+	LLViewerObject::const_child_list_t& child_list = object->getChildren();
+	for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+		 iter != child_list.end(); iter++)
 	{
 		LLViewerObject* childp = *iter;
 		if (childp && childp->mDrawable.notNull())
@@ -282,8 +285,9 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
 		{
 			object->mText->setOnHUDAttachment(FALSE);
 		}
-		for (LLViewerObject::child_list_t::iterator iter = object->mChildList.begin();
-			iter != object->mChildList.end(); ++iter)
+		LLViewerObject::const_child_list_t& child_list = object->getChildren();
+		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+			 iter != child_list.end(); iter++)
 		{
 			LLViewerObject* childp = *iter;
 			if (childp->mText.notNull())
@@ -351,8 +355,9 @@ void LLViewerJointAttachment::clampObjectPosition()
 void LLViewerJointAttachment::calcLOD()
 {
 	F32 maxarea = mAttachedObject->getMaxScale() * mAttachedObject->getMidScale();
-	for (LLViewerObject::child_list_t::iterator iter = mAttachedObject->mChildList.begin();
-		 iter != mAttachedObject->mChildList.end(); ++iter)
+	LLViewerObject::const_child_list_t& child_list = mAttachedObject->getChildren();
+	for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+		 iter != child_list.end(); iter++)
 	{
 		LLViewerObject* childp = *iter;
 		F32 area = childp->getMaxScale() * childp->getMidScale();
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index 1717153810..96e6da76b6 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -99,6 +99,11 @@ void LLViewerJoystick::setOverrideCamera(bool val)
 	{
 		mOverrideCamera = val;
 	}
+
+	if (mOverrideCamera)
+	{
+		gAgent.changeCameraToDefault();
+	}
 }
 
 // -----------------------------------------------------------------------------
@@ -793,14 +798,6 @@ void LLViewerJoystick::moveFlycam(bool reset)
 	{
 		cur_delta[i] = -getJoystickAxis(axis[i]);
 
-		// we need smaller camera movements in build mode
-		if (in_build_mode)
-		{
-			if (i == X_I || i == Y_I || i == Z_I)
-			{
-				cur_delta[i] /= BUILDMODE_FLYCAM_T_SCALE;
-			}
-		}
 
 		F32 tmp = cur_delta[i];
 		if (absolute)
@@ -817,6 +814,18 @@ void LLViewerJoystick::moveFlycam(bool reset)
 		{
 			cur_delta[i] = llmin(cur_delta[i]+dead_zone[i], 0.f);
 		}
+
+		// we need smaller camera movements in build mode
+		// NOTE: this needs to remain after the deadzone calculation, otherwise
+		// we have issues with flycam "jumping" when the build dialog is opened/closed  -Nyx
+		if (in_build_mode)
+		{
+			if (i == X_I || i == Y_I || i == Z_I)
+			{
+				cur_delta[i] /= BUILDMODE_FLYCAM_T_SCALE;
+			}
+		}
+
 		cur_delta[i] *= axis_scale[i];
 		
 		if (!absolute)
@@ -875,10 +884,16 @@ bool LLViewerJoystick::toggleFlycam()
 	{
 		return false;
 	}
+	if (!mOverrideCamera)
+	{
+		gAgent.changeCameraToDefault();
+	}
+
 	mOverrideCamera = !mOverrideCamera;
 	if (mOverrideCamera)
 	{
 		moveFlycam(true);
+		
 	}
 	else if (!LLToolMgr::getInstance()->inBuildMode())
 	{
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 3f57b26fec..f5d822f2e3 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -536,7 +536,7 @@ void LLViewerMedia::buildMediaManagerData( LLMediaManagerData* init_data )
 	init_data->setBrowserComponentDir( component_dir );
 	std::string profile_name("Second Life");
 	init_data->setBrowserProfileName( profile_name );
-	init_data->setBrowserParentWindow( gViewerWindow->getPlatformWindow() );
+	init_data->setBrowserParentWindow( gViewerWindow->getMediaWindow() );
 
 	// We use a custom user agent with viewer version and skin name.
 	LLViewerMediaImpl::updateBrowserUserAgent();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 771a71c5c5..5d2b8e43ba 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -128,6 +128,7 @@
 #include "llfloaterwater.h"
 #include "llfloaterwindlight.h"
 #include "llfloaterworldmap.h"
+#include "llfloatermemleak.h"
 #include "llframestats.h"
 #include "llframestatview.h"
 #include "llfasttimerview.h"
@@ -493,6 +494,8 @@ BOOL enable_not_thirdperson(void*);
 BOOL enable_have_card(void*);
 BOOL enable_detach(void*);
 BOOL enable_region_owner(void*);
+void menu_toggle_attached_lights(void* user_data);
+void menu_toggle_attached_particles(void* user_data);
 
 class LLLandmarkObserver : public LLInventoryObserver
 {
@@ -1434,6 +1437,23 @@ void init_debug_rendering_menu(LLMenuGL* menu)
 
 	item = new LLMenuItemCheckGL("Cheesy Beacon", menu_toggle_control, NULL, menu_check_control, (void*)"CheesyBeacon");
 	menu->append(item);
+
+	item = new LLMenuItemCheckGL("Attached Lights", menu_toggle_attached_lights, NULL, menu_check_control, (void*)"RenderAttachedLights");
+	menu->append(item);
+
+	item = new LLMenuItemCheckGL("Attached Particles", menu_toggle_attached_particles, NULL, menu_check_control, (void*)"RenderAttachedParticles");
+	menu->append(item);
+
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+	menu->appendSeparator();
+	menu->append(new LLMenuItemCallGL("Memory Leaking Simulation", LLFloaterMemLeak::show, NULL, NULL));
+#else
+	if(gSavedSettings.getBOOL("QAMode"))
+	{
+		menu->appendSeparator();
+		menu->append(new LLMenuItemCallGL("Memory Leaking Simulation", LLFloaterMemLeak::show, NULL, NULL));
+	}
+#endif
 	
 	menu->createJumpKeys();
 }
@@ -1771,35 +1791,62 @@ class LLViewCheckBuildMode : public view_listener_t
 
 bool toggle_build_mode()
 {
-	if (LLToolMgr::getInstance()->inEdit())
+	if (LLToolMgr::getInstance()->inBuildMode())
 	{
-		// just reset the view, will pull us out of edit mode
-		handle_reset_view();
-
+		if (gSavedSettings.getBOOL("EditCameraMovement"))
+		{
+			// just reset the view, will pull us out of edit mode
+			handle_reset_view();
+		}
+		else
+		{
+			// manually disable edit mode, but do not affect the camera
+			gAgent.resetView(false);
+			gFloaterTools->close();
+			gViewerWindow->showCursor();			
+		}
 		// avoid spurious avatar movements pulling out of edit mode
 		LLViewerJoystick::getInstance()->moveAvatar(true);
 	}
 	else
 	{
-		if (LLViewerJoystick::getInstance()->getOverrideCamera())
+		ECameraMode camMode = gAgent.getCameraMode();
+		if (CAMERA_MODE_MOUSELOOK == camMode ||	CAMERA_MODE_CUSTOMIZE_AVATAR == camMode)
 		{
-			handle_toggle_flycam();
+			// pull the user out of mouselook or appearance mode when entering build mode
+			handle_reset_view();
 		}
-			
-		if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
+
+		if (gSavedSettings.getBOOL("EditCameraMovement"))
 		{
-			// zoom in if we're looking at the avatar
-			gAgent.setFocusOnAvatar(FALSE, ANIMATE);
-			gAgent.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
-			gAgent.cameraZoomIn(0.666f);
-			gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
+			// camera should be set
+			if (LLViewerJoystick::getInstance()->getOverrideCamera())
+			{
+				handle_toggle_flycam();
+			}
+				
+			if (gAgent.getFocusOnAvatar())
+			{
+				// zoom in if we're looking at the avatar
+				gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+				gAgent.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
+				gAgent.cameraZoomIn(0.666f);
+				gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
+			}
 		}
 
+		
 		LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
 		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
 
 		// Could be first use
 		LLFirstUse::useBuild();
+
+		gAgent.resetView(false);
+
+		// avoid spurious avatar movements
+		LLViewerJoystick::getInstance()->moveAvatar(true);
+
 	}
 	return true;
 }
@@ -2880,8 +2927,12 @@ class LLEditEnableCustomizeAvatar : public view_listener_t
 {
 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
 	{
-		bool new_value = gAgent.getWearablesLoaded();
-		gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
+		LLVOAvatar* avatar = gAgent.getAvatarObject();
+
+		bool enabled = ((avatar && avatar->isFullyLoaded()) &&
+				   (gAgent.getWearablesLoaded()));
+
+		gMenuHolder->findControl(userdata["control"].asString())->setValue(enabled);
 		return true;
 	}
 };
@@ -6000,9 +6051,12 @@ BOOL object_selected_and_point_valid(void *user_data)
 	{
 		LLSelectNode* node = *iter;
 		LLViewerObject* object = node->getObject();
-		for (U32 child_num = 0; child_num < object->mChildList.size(); child_num++ )
+		LLViewerObject::const_child_list_t& child_list = object->getChildren();
+		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+			 iter != child_list.end(); iter++)
 		{
-			if (object->mChildList[child_num]->isAvatar())
+			LLViewerObject* child = *iter;
+			if (child->isAvatar())
 			{
 				return FALSE;
 			}
@@ -6383,6 +6437,18 @@ BOOL enable_land_selected( void* )
 	return !(LLViewerParcelMgr::getInstance()->selectionEmpty());
 }
 
+void menu_toggle_attached_lights(void* user_data)
+{
+	menu_toggle_control(user_data);
+	LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
+}
+
+void menu_toggle_attached_particles(void* user_data)
+{
+	menu_toggle_control(user_data);
+	LLPipeline::sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
+}
+
 class LLSomethingSelected : public view_listener_t
 {
 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index d440491661..9146acb750 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2666,7 +2666,7 @@ static void display_release_message(S32, void* data)
 
 void process_agent_movement_complete(LLMessageSystem* msg, void**)
 {
-	gAgentMovementCompleted = TRUE;
+	gAgentMovementCompleted = true;
 
 	LLUUID agent_id;
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 8745a73e79..461a21d51a 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -96,6 +96,7 @@
 #include "pipeline.h"
 #include "llviewernetwork.h"
 #include "llvowlsky.h"
+#include "llmanip.h"
 
 //#define DEBUG_UPDATE_TYPE
 
@@ -402,13 +403,10 @@ void LLViewerObject::dump() const
 		mNameValuePairs[key]->printNameValue(buffer);
 		llinfos << buffer << llendl;
 	}
-
-	S32 i;
-
-	LLViewerObject *child;
-	for (i = 0; i < mChildList.size(); i++)
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
 	{
-		child = mChildList[i];
+		LLViewerObject* child = *iter;
 		llinfos << "  child " << child->getID() << llendl;
 	}
 	*/
@@ -555,20 +553,16 @@ void LLViewerObject::removeChild(LLViewerObject *childp)
 	}
 }
 
-LLViewerObject::child_list_t& LLViewerObject::getChildren()
-{
-	return mChildList;
-}
-
 void LLViewerObject::addThisAndAllChildren(LLDynamicArray<LLViewerObject*>& objects)
 {
 	objects.put(this);
-	S32 count = mChildList.size();
-	for(S32 i = 0; i < count; i++)
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
 	{
-		if (!mChildList[i]->isAvatar())
+		LLViewerObject* child = *iter;
+		if (!child->isAvatar())
 		{
-			(mChildList[i])->addThisAndAllChildren(objects);
+			child->addThisAndAllChildren(objects);
 		}
 	}
 }
@@ -581,24 +575,25 @@ void LLViewerObject::addThisAndNonJointChildren(LLDynamicArray<LLViewerObject*>&
 	{
 		return;
 	}
-	S32 count = mChildList.size();
-	for(S32 i = 0; i < count; i++)
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
 	{
-		if ( (!mChildList[i]->isAvatar())
-			&& (!mChildList[i]->isJointChild()))
+		LLViewerObject* child = *iter;
+		if ( (!child->isAvatar()) && (!child->isJointChild()))
 		{
-			(mChildList[i])->addThisAndNonJointChildren(objects);
+			child->addThisAndNonJointChildren(objects);
 		}
 	}
 }
 
 BOOL LLViewerObject::isChild(LLViewerObject *childp) const
 {
-	S32 count = mChildList.size();
-	for(S32 i = 0; i < count; i++)
+	for (child_list_t::const_iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
 	{
-		const LLViewerObject *testChildp = &(*mChildList[i]);
-		if (testChildp == childp) return TRUE;
+		LLViewerObject* testchild = *iter;
+		if (testchild == childp)
+			return TRUE;
 	}
 	return FALSE;
 }
@@ -607,11 +602,11 @@ BOOL LLViewerObject::isChild(LLViewerObject *childp) const
 // returns TRUE if at least one avatar is sitting on this object
 BOOL LLViewerObject::isSeat() const
 {
-	S32 count = mChildList.size();
-	for(S32 i = 0; i < count; i++)
+	for (child_list_t::const_iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
 	{
-		const LLViewerObject *childp = &(*mChildList[i]);
-		if (childp->isAvatar())
+		LLViewerObject* child = *iter;
+		if (child->isAvatar())
 		{
 			return TRUE;
 		}
@@ -1844,7 +1839,19 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 			  ||(this_update_precision > mBestUpdatePrecision))))
 	{
 		mBestUpdatePrecision = this_update_precision;
-		setPositionParent(new_pos_parent);
+		
+		LLVector3 diff = new_pos_parent - test_pos_parent ;
+		F32 mag_sqr = diff.magVecSquared() ;
+		if(llfinite(mag_sqr)) 
+		{
+			setPositionParent(new_pos_parent);
+		}
+		else
+		{
+			llwarns << "Can not move the object/avatar to an infinite location!" << llendl ;	
+
+			retval |= INVALID_UPDATE ;
+		}
 
 		if (mParent && ((LLViewerObject*)mParent)->isAvatar())
 		{
@@ -1915,11 +1922,11 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 	// Additionally, if any child is selected, need to update the dialogs and selection
 	// center.
 	BOOL needs_refresh = mUserSelected;
-	LLViewerObject *childp;
-	for (U32 i = 0; i < mChildList.size(); i++)
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
 	{
-		childp = mChildList[i];
-		needs_refresh = needs_refresh || childp->mUserSelected;
+		LLViewerObject* child = *iter;
+		needs_refresh = needs_refresh || child->mUserSelected;
 	}
 
 	if (needs_refresh)
@@ -2892,13 +2899,20 @@ void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */)
  		getTEImage(i)->setBoostLevel(LLViewerImage::BOOST_SELECTED);
 	}
 
+	if (isSculpted())
+	{
+		LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+		LLUUID sculpt_id = sculpt_params->getSculptTexture();
+		gImageList.getImage(sculpt_id)->setBoostLevel(LLViewerImage::BOOST_SELECTED);
+	}
+	
 	if (boost_children)
 	{
-		S32 num_children = mChildList.size();
-		for (i = 0; i < num_children; i++)
+		for (child_list_t::iterator iter = mChildList.begin();
+			 iter != mChildList.end(); iter++)
 		{
-			LLViewerObject *childp = mChildList[i];
-			childp->boostTexturePriority();
+			LLViewerObject* child = *iter;
+			child->boostTexturePriority();
 		}
 	}
 }
@@ -3996,9 +4010,11 @@ S32 LLViewerObject::countInventoryContents(LLAssetType::EType type)
 void LLViewerObject::setCanSelect(BOOL canSelect)
 {
 	mbCanSelect = canSelect;
-	for (U32 i = 0; i < mChildList.size(); i++)
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
 	{
-		mChildList[i]->mbCanSelect = canSelect;
+		LLViewerObject* child = *iter;
+		child->mbCanSelect = canSelect;
 	}
 }
 
@@ -4551,9 +4567,11 @@ void LLViewerObject::setDrawableState(U32 state, BOOL recursive)
 	}
 	if (recursive)
 	{
-		for (U32 i = 0; i < mChildList.size(); i++)
+		for (child_list_t::iterator iter = mChildList.begin();
+			 iter != mChildList.end(); iter++)
 		{
-			mChildList[i]->setDrawableState(state, recursive);
+			LLViewerObject* child = *iter;
+			child->setDrawableState(state, recursive);
 		}
 	}
 }
@@ -4566,9 +4584,11 @@ void LLViewerObject::clearDrawableState(U32 state, BOOL recursive)
 	}
 	if (recursive)
 	{
-		for (U32 i = 0; i < mChildList.size(); i++)
+		for (child_list_t::iterator iter = mChildList.begin();
+			 iter != mChildList.end(); iter++)
 		{
-			mChildList[i]->clearDrawableState(state, recursive);
+			LLViewerObject* child = *iter;
+			child->clearDrawableState(state, recursive);
 		}
 	}
 }
@@ -4803,7 +4823,7 @@ void LLViewerObject::setRegion(LLViewerRegion *regionp)
 	mLatestRecvPacketID = 0;
 	mRegionp = regionp;
 
-	for (child_list_t::iterator i = getChildren().begin(); i != getChildren().end(); ++i)
+	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
 	{
 		LLViewerObject* child = *i;
 		child->setRegion(regionp);
@@ -4937,3 +4957,141 @@ void LLStaticViewerObject::updateDrawable(BOOL force_damped)
 	}
 	clearChanged(SHIFTED);
 }
+
+void LLViewerObject::saveUnselectedChildrenPosition(std::vector<LLVector3>& positions)
+{
+	if(mChildList.empty() || !positions.empty())
+	{
+		return ;
+	}
+
+	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+			iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* childp = *iter;
+		if (!childp->isSelected() && childp->mDrawable.notNull())
+		{
+			positions.push_back(childp->getPositionEdit());		
+		}
+	}
+
+	return ;
+}
+
+void LLViewerObject::saveUnselectedChildrenRotation(std::vector<LLQuaternion>& rotations)
+{
+	if(mChildList.empty())
+	{
+		return ;
+	}
+
+	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+			iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* childp = *iter;
+		if (!childp->isSelected() && childp->mDrawable.notNull())
+		{
+			rotations.push_back(childp->getRotationEdit());				
+		}		
+	}
+
+	return ;
+}
+
+//counter-rotation
+void LLViewerObject::resetChildrenRotationAndPosition(const std::vector<LLQuaternion>& rotations, 
+											const std::vector<LLVector3>& positions)
+{
+	if(mChildList.empty())
+	{
+		return ;
+	}
+
+	S32 index = 0 ;
+	LLQuaternion inv_rotation = ~getRotationEdit() ;
+	LLVector3 offset = getPositionEdit() ;
+	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+			iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* childp = *iter;
+		if (!childp->isSelected() && childp->mDrawable.notNull())
+		{
+			if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
+			{
+				childp->setRotation(rotations[index] * inv_rotation);
+				childp->setPosition((positions[index] - offset) * inv_rotation);
+				LLManip::rebuild(childp);					
+			}
+			else //avatar
+			{
+				LLVector3 reset_pos = (positions[index] - offset) * inv_rotation ;
+				LLQuaternion reset_rot = rotations[index] * inv_rotation ;
+
+				((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos);				
+				((LLVOAvatar*)childp)->mDrawable->mXform.setRotation(reset_rot) ;
+				
+				((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos, TRUE);				
+				((LLVOAvatar*)childp)->mDrawable->getVObj()->setRotation(reset_rot, TRUE) ;
+
+				LLManip::rebuild(childp);				
+			}	
+			index++;
+		}				
+	}
+
+	return ;
+}
+
+//counter-translation
+void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplified)
+{
+	if(mChildList.empty())
+	{
+		return ;
+	}
+
+	LLVector3 child_offset;
+	if(simplified) //translation only, rotation matrix does not change
+	{
+		child_offset = offset * ~getRotation();
+	}
+	else //rotation matrix might change too.
+	{
+		if (isAttachment() && mDrawable.notNull())
+		{
+			LLXform* attachment_point_xform = mDrawable->getXform()->getParent();
+			LLQuaternion parent_rotation = getRotation() * attachment_point_xform->getWorldRotation();
+			child_offset = offset * ~parent_rotation;
+		}
+		else
+		{
+			child_offset = offset * ~getRenderRotation();
+		}
+	}
+
+	for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+			iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* childp = *iter;
+		if (!childp->isSelected() && childp->mDrawable.notNull())
+		{
+			if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
+			{
+				childp->setPosition(childp->getPosition() + child_offset);
+				LLManip::rebuild(childp);
+			}
+			else //avatar
+			{
+				LLVector3 reset_pos = ((LLVOAvatar*)childp)->mDrawable->mXform.getPosition() + child_offset ;
+
+				((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos);
+				((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos);				
+				
+				LLManip::rebuild(childp);
+			}			
+		}		
+	}
+
+	return ;
+}
+
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 1fd4a29238..b6ff60ef9d 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -129,7 +129,8 @@ protected:
 	std::map<U16, ExtraParameter*> mExtraParameterList;
 
 public:
-	typedef std::vector<LLPointer<LLViewerObject> > child_list_t;
+	typedef std::list<LLPointer<LLViewerObject> > child_list_t;
+	typedef const child_list_t const_child_list_t;
 
 	LLViewerObject(const LLUUID &id, const LLPCode type, LLViewerRegion *regionp);
 	MEM_TYPE_NEW(LLMemType::MTYPE_OBJECT);
@@ -153,7 +154,7 @@ public:
 	enum { MEDIA_TYPE_NONE = 0, MEDIA_TYPE_WEB_PAGE = 1 };
 
 	// Return codes for processUpdateMessage
-	enum { MEDIA_URL_REMOVED = 0x1, MEDIA_URL_ADDED = 0x2, MEDIA_URL_UPDATED = 0x4 };
+	enum { MEDIA_URL_REMOVED = 0x1, MEDIA_URL_ADDED = 0x2, MEDIA_URL_UPDATED = 0x4, INVALID_UPDATE = 0x80000000 };
 
 	virtual U32		processUpdateMessage(LLMessageSystem *mesgsys,
 										void **user_data,
@@ -212,7 +213,8 @@ public:
 	U32 getLocalID() const							{ return mLocalID; }
 	U32 getCRC() const								{ return mTotalCRC; }
 
-	virtual BOOL isFlexible() const					{ return false; }
+	virtual BOOL isFlexible() const					{ return FALSE; }
+	virtual BOOL isSculpted() const 				{ return FALSE; }
 
 	// This method returns true if the object is over land owned by
 	// the agent.
@@ -234,7 +236,8 @@ public:
 	virtual void setParent(LLViewerObject* parent);
 	virtual void addChild(LLViewerObject *childp);
 	virtual void removeChild(LLViewerObject *childp);
-	child_list_t& getChildren();
+	const_child_list_t& getChildren() const { 	return mChildList; }
+	S32 numChildren() const { return mChildList.size(); }
 	void addThisAndAllChildren(LLDynamicArray<LLViewerObject*>& objects);
 	void addThisAndNonJointChildren(LLDynamicArray<LLViewerObject*>& objects);
 	BOOL isChild(LLViewerObject *childp) const;
@@ -472,6 +475,16 @@ public:
 	friend class LLViewerObjectList;
 	friend class LLViewerMediaList;
 
+public:
+	//counter-translation
+	void resetChildrenPosition(const LLVector3& offset, BOOL simplified = FALSE) ;
+	//counter-rotation
+	void resetChildrenRotationAndPosition(const std::vector<LLQuaternion>& rotations, 
+											const std::vector<LLVector3>& positions) ;
+	void saveUnselectedChildrenRotation(std::vector<LLQuaternion>& rotations) ;
+	void saveUnselectedChildrenPosition(std::vector<LLVector3>& positions) ;
+	std::vector<LLVector3> mUnselectedChildrenPositions ;
+
 private:
 	ExtraParameter* createNewParameterEntry(U16 param_type);
 	ExtraParameter* getExtraParameterEntry(U16 param_type) const;
@@ -496,7 +509,6 @@ public:
 		LL_VO_WL_SKY =				LL_PCODE_APP | 0xb0, // should this be moved to 0x40?
 	} EVOType;
 
-	child_list_t	mChildList;
 	LLUUID			mID;
 
 	// unique within region, not unique across regions
@@ -575,6 +587,8 @@ protected:
 	typedef std::map<char *, LLNameValue *> name_value_map_t;
 	name_value_map_t mNameValuePairs;	// Any name-value pairs stored by script
 
+	child_list_t	mChildList;
+	
 	F64				mLastInterpUpdateSecs;			// Last update for purposes of interpolation
 	F64				mLastMessageUpdateSecs;			// Last update from a message from the simulator
 	TPACKETID		mLatestRecvPacketID;			// Latest time stamp on message from simulator
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index a37120451e..6d0137663c 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1163,9 +1163,11 @@ void LLViewerObjectList::generatePickList(LLCamera &camera)
 					if (objectp)
 					{
 						mSelectPickList.insert(objectp);		
-						for (U32 i = 0; i < objectp->mChildList.size(); i++)
+						LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+						for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+							 iter != child_list.end(); iter++)
 						{
-							LLViewerObject* childp = objectp->mChildList[i];
+							LLViewerObject* childp = *iter;
 							if (childp)
 							{
 								mSelectPickList.insert(childp);
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index ccf7a5d1d7..779ef0a3c6 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -44,6 +44,7 @@
 #include "llworld.h"
 #include "pipeline.h"
 #include "llspatialpartition.h"
+#include "llvovolume.h"
 
 const F32 PART_SIM_BOX_SIDE = 16.f;
 const F32 PART_SIM_BOX_OFFSET = 0.5f*PART_SIM_BOX_SIDE;
@@ -169,6 +170,10 @@ LLViewerPartGroup::~LLViewerPartGroup()
 	cleanup();
 	
 	S32 count = (S32) mParticles.size();
+	for(S32 i = 0 ; i < count ; i++)
+	{
+		delete mParticles[i] ;
+	}
 	mParticles.clear();
 	
 	LLViewerPartSim::decPartCount(count);
@@ -240,151 +245,150 @@ BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size)
 void LLViewerPartGroup::updateParticles(const F32 lastdt)
 {
 	LLMemType mt(LLMemType::MTYPE_PARTICLES);
-	S32 i;
 	F32 dt;
 	
 	LLVector3 gravity(0.f, 0.f, GRAVITY);
 
 	LLViewerRegion *regionp = getRegion();
 	S32 end = (S32) mParticles.size();
-	for (i = 0; i < end; i++)
+	for (S32 i = 0 ; i < (S32)mParticles.size();)
 	{
 		LLVector3 a(0.f, 0.f, 0.f);
-		LLViewerPart& part = *((LLViewerPart*) mParticles[i]);
+		LLViewerPart* part = mParticles[i] ;
 
-		dt=lastdt+mSkippedTime-part.mSkipOffset;
-		part.mSkipOffset=0.f;
+		dt = lastdt + mSkippedTime - part->mSkipOffset;
+		part->mSkipOffset = 0.f;
 
 		// Update current time
-		const F32 cur_time = part.mLastUpdateTime + dt;
-		const F32 frac = cur_time/part.mMaxAge;
+		const F32 cur_time = part->mLastUpdateTime + dt;
+		const F32 frac = cur_time / part->mMaxAge;
 
 		// "Drift" the object based on the source object
-		if (part.mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK)
+		if (part->mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK)
 		{
-			part.mPosAgent = part.mPartSourcep->mPosAgent;
-			part.mPosAgent += part.mPosOffset;
+			part->mPosAgent = part->mPartSourcep->mPosAgent;
+			part->mPosAgent += part->mPosOffset;
 		}
 
 		// Do a custom callback if we have one...
-		if (part.mVPCallback)
+		if (part->mVPCallback)
 		{
-			(*part.mVPCallback)(part, dt);
+			(*part->mVPCallback)(*part, dt);
 		}
 
-		if (part.mFlags & LLPartData::LL_PART_WIND_MASK)
+		if (part->mFlags & LLPartData::LL_PART_WIND_MASK)
 		{
-			LLVector3 tempVel(part.mVelocity);
-			part.mVelocity *= 1.f - 0.1f*dt;
-			part.mVelocity += 0.1f*dt*regionp->mWind.getVelocity(regionp->getPosRegionFromAgent(part.mPosAgent));
+			LLVector3 tempVel(part->mVelocity);
+			part->mVelocity *= 1.f - 0.1f*dt;
+			part->mVelocity += 0.1f*dt*regionp->mWind.getVelocity(regionp->getPosRegionFromAgent(part->mPosAgent));
 		}
 
 		// Now do interpolation towards a target
-		if (part.mFlags & LLPartData::LL_PART_TARGET_POS_MASK)
+		if (part->mFlags & LLPartData::LL_PART_TARGET_POS_MASK)
 		{
-			F32 remaining = part.mMaxAge - part.mLastUpdateTime;
+			F32 remaining = part->mMaxAge - part->mLastUpdateTime;
 			F32 step = dt / remaining;
 
 			step = llclamp(step, 0.f, 0.1f);
 			step *= 5.f;
 			// we want a velocity that will result in reaching the target in the 
 			// Interpolate towards the target.
-			LLVector3 delta_pos = part.mPartSourcep->mTargetPosAgent - part.mPosAgent;
+			LLVector3 delta_pos = part->mPartSourcep->mTargetPosAgent - part->mPosAgent;
 
 			delta_pos /= remaining;
 
-			part.mVelocity *= (1.f - step);
-			part.mVelocity += step*delta_pos;
+			part->mVelocity *= (1.f - step);
+			part->mVelocity += step*delta_pos;
 		}
 
 
-		if (part.mFlags & LLPartData::LL_PART_TARGET_LINEAR_MASK)
+		if (part->mFlags & LLPartData::LL_PART_TARGET_LINEAR_MASK)
 		{
-			LLVector3 delta_pos = part.mPartSourcep->mTargetPosAgent - part.mPartSourcep->mPosAgent;			
-			part.mPosAgent = part.mPartSourcep->mPosAgent;
-			part.mPosAgent += frac*delta_pos;
-			part.mVelocity = delta_pos;
+			LLVector3 delta_pos = part->mPartSourcep->mTargetPosAgent - part->mPartSourcep->mPosAgent;			
+			part->mPosAgent = part->mPartSourcep->mPosAgent;
+			part->mPosAgent += frac*delta_pos;
+			part->mVelocity = delta_pos;
 		}
 		else
 		{
 			// Do velocity interpolation
-			part.mPosAgent += dt*part.mVelocity;
-			part.mPosAgent += 0.5f*dt*dt*part.mAccel;
-			part.mVelocity += part.mAccel*dt;
+			part->mPosAgent += dt*part->mVelocity;
+			part->mPosAgent += 0.5f*dt*dt*part->mAccel;
+			part->mVelocity += part->mAccel*dt;
 		}
 
 		// Do a bounce test
-		if (part.mFlags & LLPartData::LL_PART_BOUNCE_MASK)
+		if (part->mFlags & LLPartData::LL_PART_BOUNCE_MASK)
 		{
 			// Need to do point vs. plane check...
 			// For now, just check relative to object height...
-			F32 dz = part.mPosAgent.mV[VZ] - part.mPartSourcep->mPosAgent.mV[VZ];
+			F32 dz = part->mPosAgent.mV[VZ] - part->mPartSourcep->mPosAgent.mV[VZ];
 			if (dz < 0)
 			{
-				part.mPosAgent.mV[VZ] += -2.f*dz;
-				part.mVelocity.mV[VZ] *= -0.75f;
+				part->mPosAgent.mV[VZ] += -2.f*dz;
+				part->mVelocity.mV[VZ] *= -0.75f;
 			}
 		}
 
 
 		// Reset the offset from the source position
-		if (part.mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK)
+		if (part->mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK)
 		{
-			part.mPosOffset = part.mPosAgent;
-			part.mPosOffset -= part.mPartSourcep->mPosAgent;
+			part->mPosOffset = part->mPosAgent;
+			part->mPosOffset -= part->mPartSourcep->mPosAgent;
 		}
 
 		// Do color interpolation
-		if (part.mFlags & LLPartData::LL_PART_INTERP_COLOR_MASK)
+		if (part->mFlags & LLPartData::LL_PART_INTERP_COLOR_MASK)
 		{
-			part.mColor.setVec(part.mStartColor);
+			part->mColor.setVec(part->mStartColor);
 			// note: LLColor4's v%k means multiply-alpha-only,
 			//       LLColor4's v*k means multiply-rgb-only
-			part.mColor *= 1.f - frac; // rgb*k
-			part.mColor %= 1.f - frac; // alpha*k
-			part.mColor += frac%(frac*part.mEndColor); // rgb,alpha
+			part->mColor *= 1.f - frac; // rgb*k
+			part->mColor %= 1.f - frac; // alpha*k
+			part->mColor += frac%(frac*part->mEndColor); // rgb,alpha
 		}
 
 		// Do scale interpolation
-		if (part.mFlags & LLPartData::LL_PART_INTERP_SCALE_MASK)
+		if (part->mFlags & LLPartData::LL_PART_INTERP_SCALE_MASK)
 		{
-			part.mScale.setVec(part.mStartScale);
-			part.mScale *= 1.f - frac;
-			part.mScale += frac*part.mEndScale;
+			part->mScale.setVec(part->mStartScale);
+			part->mScale *= 1.f - frac;
+			part->mScale += frac*part->mEndScale;
 		}
 
 		// Set the last update time to now.
-		part.mLastUpdateTime = cur_time;
+		part->mLastUpdateTime = cur_time;
 
 
 		// Kill dead particles (either flagged dead, or too old)
-		if ((part.mLastUpdateTime > part.mMaxAge) || (LLViewerPart::LL_PART_DEAD_MASK == part.mFlags))
+		if ((part->mLastUpdateTime > part->mMaxAge) || (LLViewerPart::LL_PART_DEAD_MASK == part->mFlags))
 		{
-			end--;
-			LLPointer<LLViewerPart>::swap(mParticles[i], mParticles[end]);
-			// be sure to process the particle we just swapped-in
-			i--;
+			mParticles[i] = mParticles.back() ;
+			mParticles.pop_back() ;
+			delete part ;
 		}
 		else 
 		{
-			F32 desired_size = calc_desired_size(part.mPosAgent, part.mScale);
-			if (!posInGroup(part.mPosAgent, desired_size))
+			F32 desired_size = calc_desired_size(part->mPosAgent, part->mScale);
+			if (!posInGroup(part->mPosAgent, desired_size))
 			{
 				// Transfer particles between groups
-				LLViewerPartSim::getInstance()->put(&part);
-				end--;
-				LLPointer<LLViewerPart>::swap(mParticles[i], mParticles[end]);
-				// be sure to process the particle we just swapped-in
-				i--;
+				LLViewerPartSim::getInstance()->put(part) ;
+				mParticles[i] = mParticles.back() ;
+				mParticles.pop_back() ;
+			}
+			else
+			{
+				i++ ;
 			}
 		}
 	}
 
-	S32 removed = (S32)mParticles.size() - end;
+	S32 removed = end - (S32)mParticles.size();
 	if (removed > 0)
 	{
 		// we removed one or more particles, so flag this group for update
-		mParticles.erase(mParticles.begin() + end, mParticles.end());
 		if (mVOPartGroupp.notNull())
 		{
 			gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
@@ -408,9 +412,7 @@ void LLViewerPartGroup::shift(const LLVector3 &offset)
 	mMinObjPos += offset;
 	mMaxObjPos += offset;
 
-	S32 count = (S32) mParticles.size();
-	S32 i;
-	for (i = 0; i < count; i++)
+	for (S32 i = 0 ; i < (S32)mParticles.size(); i++)
 	{
 		mParticles[i]->mPosAgent += offset;
 	}
@@ -419,8 +421,8 @@ void LLViewerPartGroup::shift(const LLVector3 &offset)
 void LLViewerPartGroup::removeParticlesByID(const U32 source_id)
 {
 	LLMemType mt(LLMemType::MTYPE_PARTICLES);
-	S32 end = (S32) mParticles.size();
-	for (int i = 0; i < end; i++)
+
+	for (S32 i = 0; i < (S32)mParticles.size(); i++)
 	{
 		if(mParticles[i]->mPartSourcep->getID() == source_id)
 		{
@@ -500,42 +502,57 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part)
 {
 	LLMemType mt(LLMemType::MTYPE_PARTICLES);
 	const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million
+	LLViewerPartGroup *return_group = NULL ;
 	if (part->mPosAgent.magVecSquared() > MAX_MAG || !part->mPosAgent.isFinite())
 	{
 #if 0 && !LL_RELEASE_FOR_DOWNLOAD
 		llwarns << "LLViewerPartSim::put Part out of range!" << llendl;
 		llwarns << part->mPosAgent << llendl;
 #endif
-		return NULL;
 	}
-	
-	F32 desired_size = calc_desired_size(part->mPosAgent, part->mScale);
+	else
+	{	
+		F32 desired_size = calc_desired_size(part->mPosAgent, part->mScale);
 
-	S32 count = (S32) mViewerPartGroups.size();
-	for (S32 i = 0; i < count; i++)
-	{
-		if (mViewerPartGroups[i]->addPart(part, desired_size))
+		S32 count = (S32) mViewerPartGroups.size();
+		for (S32 i = 0; i < count; i++)
 		{
-			// We found a spatial group that we fit into, add us and exit
-			return mViewerPartGroups[i];
+			if (mViewerPartGroups[i]->addPart(part, desired_size))
+			{
+				// We found a spatial group that we fit into, add us and exit
+				return_group = mViewerPartGroups[i];
+				break ;
+			}
+		}
+
+		// Hmm, we didn't fit in any of the existing spatial groups
+		// Create a new one...
+		if(!return_group)
+		{
+			llassert_always(part->mPosAgent.isFinite());
+			LLViewerPartGroup *groupp = createViewerPartGroup(part->mPosAgent, desired_size);
+			groupp->mUniformParticles = (part->mScale.mV[0] == part->mScale.mV[1] && 
+									!(part->mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK));
+			if (!groupp->addPart(part))
+			{
+				llwarns << "LLViewerPartSim::put - Particle didn't go into its box!" << llendl;
+				llinfos << groupp->getCenterAgent() << llendl;
+				llinfos << part->mPosAgent << llendl;
+				mViewerPartGroups.pop_back() ;
+				delete groupp;
+				groupp = NULL ;
+			}
+			return_group = groupp;
 		}
 	}
 
-	// Hmm, we didn't fit in any of the existing spatial groups
-	// Create a new one...
-	llassert_always(part->mPosAgent.isFinite());
-	LLViewerPartGroup *groupp = createViewerPartGroup(part->mPosAgent, desired_size);
-	groupp->mUniformParticles = (part->mScale.mV[0] == part->mScale.mV[1] && 
-							!(part->mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK));
-	if (!groupp->addPart(part))
+	if(!return_group) //failed to insert the particle
 	{
-		llwarns << "LLViewerPartSim::put - Particle didn't go into its box!" << llendl;
-		llinfos << groupp->getCenterAgent() << llendl;
-		llinfos << part->mPosAgent << llendl;
-		delete groupp;
-		return NULL;
+		delete part ;
+		part = NULL ;
 	}
-	return groupp;
+
+	return return_group ;
 }
 
 LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size)
@@ -614,7 +631,24 @@ void LLViewerPartSim::updateSimulation()
 
 		if (!mViewerPartSources[i]->isDead())
 		{
-			mViewerPartSources[i]->update(dt);
+			BOOL upd = TRUE;
+			if (!LLPipeline::sRenderAttachedParticles)
+			{
+				LLViewerObject* vobj = mViewerPartSources[i]->mSourceObjectp;
+				if (vobj && (vobj->getPCode() == LL_PCODE_VOLUME))
+				{
+					LLVOVolume* vvo = (LLVOVolume *)vobj;
+					if (vvo && vvo->isAttachment())
+					{
+						upd = FALSE;
+					}
+				}
+			}
+
+			if (upd) 
+			{
+				mViewerPartSources[i]->update(dt);
+			}
 		}
 
 		if (mViewerPartSources[i]->isDead())
@@ -630,7 +664,6 @@ void LLViewerPartSim::updateSimulation()
 		num_updates++;
 	}
 
-
 	count = (S32) mViewerPartGroups.size();
 	for (i = 0; i < count; i++)
 	{
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index daccac4e8f..de763d3e53 100644
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -52,9 +52,9 @@ typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt);
 //
 
 
-class LLViewerPart : public LLPartData, public LLRefCount
+class LLViewerPart : public LLPartData
 {
-protected:
+public:
 	~LLViewerPart();
 public:
 	LLViewerPart();
@@ -100,7 +100,7 @@ public:
 
 	void shift(const LLVector3 &offset);
 
-	typedef std::vector<LLPointer<LLViewerPart> > part_list_t;
+	typedef std::vector<LLViewerPart*>  part_list_t;
 	part_list_t mParticles;
 
 	const LLVector3 &getCenterAgent() const		{ return mCenterAgent; }
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index b6f16d1002..9bdebbbd38 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -278,7 +278,7 @@ void LLViewerPartSourceScript::update(const F32 dt)
 				continue;
 			}
 
-			LLPointer<LLViewerPart> part = new LLViewerPart();
+			LLViewerPart* part = new LLViewerPart();
 
 			part->init(this, mImagep, NULL);
 			part->mFlags = mPartSysData.mPartData.mFlags;
@@ -569,7 +569,7 @@ void LLViewerPartSourceSpiral::update(const F32 dt)
 		{
 			mPosAgent = mSourceObjectp->getRenderPosition();
 		}
-		LLPointer<LLViewerPart> part = new LLViewerPart();
+		LLViewerPart* part = new LLViewerPart();
 		part->init(this, mImagep, updatePart);
 		part->mStartColor = mColor;
 		part->mEndColor = mColor;
@@ -717,7 +717,7 @@ void LLViewerPartSourceBeam::update(const F32 dt)
 			mImagep = gImageList.getImageFromFile("pixiesmall.j2c");
 		}
 
-		LLPointer<LLViewerPart> part = new LLViewerPart();
+		LLViewerPart* part = new LLViewerPart();
 		part->init(this, mImagep, NULL);
 
 		part->mFlags = LLPartData::LL_PART_INTERP_COLOR_MASK |
@@ -834,7 +834,7 @@ void LLViewerPartSourceChat::update(const F32 dt)
 		{
 			mPosAgent = mSourceObjectp->getRenderPosition();
 		}
-		LLPointer<LLViewerPart> part = new LLViewerPart();
+		LLViewerPart* part = new LLViewerPart();
 		part->init(this, mImagep, updatePart);
 		part->mStartColor = mColor;
 		part->mEndColor = mColor;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index d060d2593c..42ea36baec 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -233,7 +233,7 @@ void LLViewerRegion::initStats()
 	mPacketsLost = 0;
 	mLastPacketsLost = 0;
 	mPingDelay = 0;
-	mAlive = FALSE;					// can become false if circuit disconnects
+	mAlive = false;					// can become false if circuit disconnects
 }
 
 LLViewerRegion::~LLViewerRegion() 
@@ -808,11 +808,11 @@ void LLViewerRegion::updateNetStats()
 	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mHost);
 	if (!cdp)
 	{
-		mAlive = FALSE;
+		mAlive = false;
 		return;
 	}
 
-	mAlive = TRUE;
+	mAlive = true;
 	mDeltaTime = dt;
 
 	mLastPacketsIn =	mPacketsIn;
@@ -900,6 +900,11 @@ F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos)
 	return mLandp->resolveHeightRegion( region_pos );
 }
 
+bool LLViewerRegion::isAlive()
+{
+	return mAlive;
+}
+
 BOOL LLViewerRegion::isOwnedSelf(const LLVector3& pos)
 {
 	if (mParcelOverlay)
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 8c3115f78d..e2ba5b1636 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -123,6 +123,8 @@ public:
 	inline BOOL getAllowTerraform() 		const;
 	inline BOOL getRestrictPushObject()		const;
 
+	bool isAlive(); // can become false if circuit disconnects
+
 	void setWaterHeight(F32 water_level);
 	F32 getWaterHeight() const;
 
@@ -286,8 +288,6 @@ public:
 	LLCloudLayer mCloudLayer;
 	LLViewerParcelOverlay	*mParcelOverlay;
 
-	BOOL	mAlive;					// can become false if circuit disconnects
-
 	LLStat	mBitStat;
 	LLStat	mPacketsStat;
 	LLStat	mPacketsLostStat;
@@ -302,7 +302,7 @@ public:
 	LLDynamicArray<U32> mMapAvatars;
 	LLDynamicArray<LLUUID> mMapAvatarIDs;
 
-protected:
+private:
 	// The surfaces and other layers
 	LLSurface*	mLandp;
 
@@ -375,6 +375,8 @@ protected:
 	LLEventPoll* mEventPoll;
 
 private:
+	bool	mAlive;					// can become false if circuit disconnects
+
 	//spatial partitions for objects in this region
 	std::vector<LLSpatialPartition*> mObjectPartition;
 
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index fe0f3f12a6..f69f4fbb62 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -418,6 +418,7 @@ void LLViewerShaderMgr::setShaders()
 			mVertexShaderLevel[SHADER_OBJECT] = 0;
 			mVertexShaderLevel[SHADER_EFFECT] = 0;
 			mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
+			mVertexShaderLevel[SHADER_AVATAR] = 0;
 		}
 	}
 	else
@@ -431,6 +432,7 @@ void LLViewerShaderMgr::setShaders()
 		mVertexShaderLevel[SHADER_OBJECT] = 0;
 		mVertexShaderLevel[SHADER_EFFECT] = 0;
 		mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
+		mVertexShaderLevel[SHADER_AVATAR] = 0;
 	}
 	
 	if (gViewerWindow)
@@ -476,6 +478,8 @@ void LLViewerShaderMgr::unloadShaders()
 	mVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
 	mVertexShaderLevel[SHADER_WATER] = 0;
 	mVertexShaderLevel[SHADER_INTERFACE] = 0;
+	mVertexShaderLevel[SHADER_EFFECT] = 0;
+	mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
 
 	gPipeline.mVertexShadersLoaded = 0;
 }
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 4c575ff139..299785d590 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -29,17 +29,17 @@
  * $/LicenseInfo$
  */
 
+// system library includes
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+
 #include "llviewerprecompiledheaders.h"
 
 #include "llpanellogin.h"
 #include "llviewerkeyboard.h"
 #include "llviewerwindow.h"
 
-// system library includes
-#include <stdio.h>
-#include <iostream>
-#include <fstream>
-
 #include "llviewquery.h"
 #include "llxmltree.h"
 //#include "llviewercamera.h"
@@ -47,9 +47,6 @@
 
 #include "llvoiceclient.h"	// for push-to-talk button handling
 
-#ifdef SABINRIG
-#include "cbw.h"
-#endif //SABINRIG
 
 //
 // TODO: Many of these includes are unnecessary.  Remove them.
@@ -60,6 +57,7 @@
 #include "indra_constants.h"
 #include "llassetstorage.h"
 #include "llfontgl.h"
+#include "llmousehandler.h"
 #include "llrect.h"
 #include "llsky.h"
 #include "llstring.h"
@@ -191,7 +189,7 @@
 //
 // Globals
 //
-void render_ui_and_swap();
+void render_ui();
 LLBottomPanel* gBottomPanel = NULL;
 
 extern BOOL gDebugClicks;
@@ -237,34 +235,9 @@ const F32 MIN_AFK_TIME = 2.f; // minimum time after setting away state before co
 const F32 MAX_FAST_FRAME_TIME = 0.5f;
 const F32 FAST_FRAME_INCREMENT = 0.1f;
 
-const F32 MIN_DISPLAY_SCALE = 0.85f;
+const F32 MIN_DISPLAY_SCALE = 0.75f;
 
 const S32 CONSOLE_BOTTOM_PAD = 40;
-#ifdef SABINRIG
-/// ALL RIG STUFF
-bool rigControl = false;
-bool voltDisplay = true;
-bool nominalX = false;
-bool nominalY = false;
-static F32 nomerX = 0.0f;
-static F32 nomerY = 0.0f;
-const BOARD_NUM = 0; // rig stuff!
-const ADRANGE = BIP10VOLTS; // rig stuff!
-static unsigned short DataVal; // rig stuff!
-static F32 oldValueX = 0;
-static F32 newValueX = 50;
-static F32 oldValueY = 0;
-static F32 newValueY = 50;
-static S32 mouseX = 50;
-static S32 mouseY = 50;
-static float VoltageX = 50; // rig stuff!
-static float VoltageY = 50; // rig stuff!
-static float nVoltX = 0;
-static float nVoltY = 0;
-static F32 temp1 = 50.f;
-static F32 temp2 = 20.f;
-LLCoordGL new_gl;
-#endif //SABINRIG
 
 std::string	LLViewerWindow::sSnapshotBaseName;
 std::string	LLViewerWindow::sSnapshotDir;
@@ -273,81 +246,6 @@ std::string	LLViewerWindow::sMovieBaseName;
 
 extern void toggle_debug_menus(void*);
 
-#ifdef SABINRIG
-// static
-void LLViewerWindow::printFeedback()
-{
-	if(rigControl == true)
-	{
-		cbAIn (BOARD_NUM, 0, ADRANGE, &DataVal);
-		cbToEngUnits (BOARD_NUM,ADRANGE,DataVal,&VoltageX); //Convert raw to voltage for X-axis
-		cbAIn (BOARD_NUM, 1, ADRANGE, &DataVal);
-		cbToEngUnits (BOARD_NUM,ADRANGE,DataVal,&VoltageY); //Convert raw to voltage for Y-axis
-		if(voltDisplay == true)
-		{
-			llinfos <<  "Current Voltages - X:" << VoltageX << " Y:" << VoltageY << llendl; //Display voltage
-		}
-
-		if(nVoltX == 0)
-		{
-			nVoltX = VoltageX;
-			nVoltY = VoltageY; //First time setup of nominal values.
-		}
-
-		newValueX = VoltageX;
-		newValueY = VoltageY; //Take in current voltage and set to a separate value for adjustment.
-
-		mouseX = mCurrentMousePoint.mX;
-		mouseY = mCurrentMousePoint.mY; //Take in current cursor position and set to separate value for adjustment.
-
-		if( abs(newValueX - nVoltX) > nomerX )
-		{
-			if( (newValueX - oldValueX) < 0)
-			{
-				mouseX += (S32)( ((newValueX - oldValueX)*.5)) * -temp;
-			}
-			else
-			{
-				mouseX += (S32)( ((newValueX - oldValueX)*.5) * temp1);
-			}
-		}
-		else
-		{
-			mouseX = getWindowWidth() / 2;
-		}
-		if( abs(newValueY - nVoltY) > nomerY )
-		{
-			if( (newValueY - oldValueY) < 0)
-			{
-				mouseY += (S32)( ((newValueY - oldValueY)*(newValueY - oldValueY)) * -temp2);
-			}
-			else
-			{
-				mouseY += (S32)( ((newValueY - oldValueY)*(newValueY - oldValueY)) * temp2);
-			}
-		}
-		else
-		{
-			mouseY = getWindowHeight() / 2;
-		}
-		//mouseX += (S32)( (newValueX - nVoltX) * temp1 + 0.5 );
-		// (newValueX - oldValueX) = difference between current position and nominal position
-		// * temp1 = the amplification of the number that sets sensitivity
-		// + 0.5 = fixes rounding errors
-		
-
-		//mouseY += (S32)( (newValueY - nVoltY) * temp2 + 0.5 ); //Algorithm to adjust voltage for mouse adjustment.
-
-		oldValueX = newValueX;
-		oldValueY = newValueY;
-
-		new_gl.mX = mouseX;
-		new_gl.mY = mouseY; //Setup final coordinate to move mouse to.
-
-		setCursorPosition(new_gl); //Set final cursor position
-	}
-}
-#endif //SABINRIG
 
 ////////////////////////////////////////////////////////////////////////////
 //
@@ -635,6 +533,21 @@ void LLViewerWindow::updateDebugText()
 // LLViewerWindow
 //
 
+bool LLViewerWindow::shouldShowToolTipFor(LLMouseHandler *mh)
+{
+	if (mToolTip && mh)
+	{
+		LLMouseHandler::EShowToolTip showlevel = mh->getShowToolTip();
+
+		return (
+			showlevel == LLMouseHandler::SHOW_ALWAYS ||
+			(showlevel == LLMouseHandler::SHOW_IF_NOT_BLOCKED &&
+			 !mToolTipBlocked)
+			);
+	}
+	return false;
+}
+
 BOOL LLViewerWindow::handleMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask)
 {
 	S32 x = pos.mX;
@@ -664,11 +577,7 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask
 	gMouseIdleTimer.reset();
 
 	// Hide tooltips on mousedown
-	if( mToolTip )
-	{
-		mToolTipBlocked = TRUE;
-		mToolTip->setVisible( FALSE );
-	}
+	mToolTipBlocked = TRUE;
 
 	// Also hide hover info on mousedown
 	if (gHoverView)
@@ -708,7 +617,7 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask
 		}
 		else
 		{
-			setTopCtrl(NULL);
+			gFocusMgr.setTopCtrl(NULL);
 		}
 	}
 
@@ -791,7 +700,7 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window,  LLCoordGL pos, MASK ma
 		}
 		else
 		{
-			setTopCtrl(NULL);
+			gFocusMgr.setTopCtrl(NULL);
 		}
 	}
 
@@ -981,7 +890,7 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window,  LLCoordGL pos, MASK
 		}
 		else
 		{
-			setTopCtrl(NULL);
+			gFocusMgr.setTopCtrl(NULL);
 		}
 	}
 
@@ -1154,13 +1063,9 @@ void LLViewerWindow::handleMouseMove(LLWindow *window,  LLCoordGL pos, MASK mask
 		gAgent.clearAFK();
 	}
 
-	if(mToolTip && mouse_actually_moved)
+	if(mouse_actually_moved)
 	{
-		mToolTipBlocked = FALSE;  // Blocking starts on keyboard events and (only) ends here.
-		if( mToolTip->getVisible() && !mToolTipStickyRect.pointInRect( x, y ) )
-		{
-			mToolTip->setVisible( FALSE );
-		}
+		mToolTipBlocked = FALSE;
 	}
 
 	// Activate the hover picker on mouse move.
@@ -2395,11 +2300,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	}
 
 	// Hide tooltips on keypress
-	if(mToolTip )
-	{
-		mToolTipBlocked = TRUE; // block until next time mouse is moved
-		mToolTip->setVisible( FALSE );
-	}
+	mToolTipBlocked = TRUE; // block until next time mouse is moved
 
 	// Also hide hover info on keypress
 	if (gHoverView)
@@ -2432,22 +2333,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	}
 
 	// handle escape key
-	if (key == KEY_ESCAPE && mask == MASK_NONE)
-	{
-		if (gMenuHolder && gMenuHolder->hideMenus())
-		{
-			return TRUE;
-		}
-
-		//if quit from menu, turn off the Keyboardmode for the menu.
-		if(LLMenuGL::getKeyboardMode())
-			LLMenuGL::setKeyboardMode(FALSE);
-
-		if (gFocusMgr.getTopCtrl())
-		{
-			gFocusMgr.setTopCtrl(NULL);
-			return TRUE;
-		}
+	//if (key == KEY_ESCAPE && mask == MASK_NONE)
+	//{
 
 		// *TODO: get this to play well with mouselook and hidden
 		// cursor modes, etc, and re-enable.
@@ -2456,7 +2343,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 		//	gFocusMgr.setMouseCapture(NULL);
 		//	return TRUE;
 		//}
-	}
+	//}
 
 	// let menus handle navigation keys
 	if (gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE))
@@ -2890,7 +2777,6 @@ BOOL LLViewerWindow::handlePerFrameHover()
 
 	}
 
-	//llinfos << (mToolTipBlocked ? "BLOCKED" : "NOT BLOCKED") << llendl;
 	// Show a new tool tip (or update one that is alrady shown)
 	BOOL tool_tip_handled = FALSE;
 	std::string tool_tip_msg;
@@ -2902,38 +2788,48 @@ BOOL LLViewerWindow::handlePerFrameHover()
 		tooltip_delay = gSavedSettings.getF32( "DragAndDropToolTipDelay" );
 	}
 	if( handled && 
-		!mToolTipBlocked &&
-		(gMouseIdleTimer.getElapsedTimeF32() > tooltip_delay) &&
-		!mWindow->isCursorHidden() )
+	    gMouseIdleTimer.getElapsedTimeF32() > tooltip_delay &&
+	    !mWindow->isCursorHidden() )
 	{
 		LLRect screen_sticky_rect;
-
+		LLMouseHandler *mh;
+		S32 local_x, local_y;
 		if (mouse_captor)
 		{
-			S32 local_x, local_y;
-			mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
-			tool_tip_handled = mouse_captor->handleToolTip( local_x, local_y, tool_tip_msg, &screen_sticky_rect );
+			mouse_captor->screenPointToLocal(x, y, &local_x, &local_y);
+			mh = mouse_captor;
 		}
 		else if (handled_by_top_ctrl)
 		{
-			S32 local_x, local_y;
-			top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
-			tool_tip_handled = top_ctrl->handleToolTip( local_x, local_y, tool_tip_msg, &screen_sticky_rect );
+			top_ctrl->screenPointToLocal(x, y, &local_x, &local_y);
+			mh = top_ctrl;
 		}
 		else
 		{
-			tool_tip_handled = mRootView->handleToolTip(x, y, tool_tip_msg, &screen_sticky_rect );
+			local_x = x; local_y = y;
+			mh = mRootView;
 		}
 
-		if( tool_tip_handled && !tool_tip_msg.empty() )
+		BOOL tooltip_vis = FALSE;
+		if (shouldShowToolTipFor(mh))
 		{
-			mToolTipStickyRect = screen_sticky_rect;
-			mToolTip->setWrappedText( tool_tip_msg, 200 );
-			mToolTip->reshapeToFitText();
-			mToolTip->setOrigin( x, y );
-			LLRect virtual_window_rect(0, getWindowHeight(), getWindowWidth(), 0);
-			mToolTip->translateIntoRect( virtual_window_rect, FALSE );
-			mToolTip->setVisible( TRUE );
+			tool_tip_handled = mh->handleToolTip(local_x, local_y, tool_tip_msg, &screen_sticky_rect );
+		
+			if( tool_tip_handled && !tool_tip_msg.empty() )
+			{
+				mToolTipStickyRect = screen_sticky_rect;
+				mToolTip->setWrappedText( tool_tip_msg, 200 );
+				mToolTip->reshapeToFitText();
+				mToolTip->setOrigin( x, y );
+				LLRect virtual_window_rect(0, getWindowHeight(), getWindowWidth(), 0);
+				mToolTip->translateIntoRect( virtual_window_rect, FALSE );
+				tooltip_vis = TRUE;
+			}
+		}
+
+		if (mToolTip)
+		{
+			mToolTip->setVisible( tooltip_vis );
 		}
 	}		
 	
@@ -4014,7 +3910,7 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p
 	else
 	{
 		display(do_rebuild, 1.0f, 0, TRUE);
-		render_ui_and_swap();
+		render_ui();
 	}
 
 	S32 glformat, gltype, glpixel_length ;
@@ -4239,7 +4135,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 			{
 				display(do_rebuild, scale_factor, subimage_x+(subimage_y*llceil(scale_factor)), TRUE);
 				// Required for showing the GUI in snapshots?  See DEV-16350 for details. JC
-				render_ui_and_swap();
+				render_ui();
 			}
 
 			S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width);
@@ -4395,39 +4291,6 @@ void LLViewerWindow::drawMouselookInstructions()
 }
 
 
-// These functions are here only because LLViewerWindow used to do the work that gFocusMgr does now.
-// They let other objects continue to work without change.
-
-void LLViewerWindow::setKeyboardFocus(LLUICtrl* new_focus)
-{
-	gFocusMgr.setKeyboardFocus( new_focus );
-}
-
-LLUICtrl* LLViewerWindow::getKeyboardFocus()
-{
-	return gFocusMgr.getKeyboardFocus();
-}
-
-BOOL LLViewerWindow::hasKeyboardFocus(const LLUICtrl* possible_focus) const
-{
-	return possible_focus == gFocusMgr.getKeyboardFocus();
-}
-
-BOOL LLViewerWindow::childHasKeyboardFocus(const LLView* parent) const
-{
-	return gFocusMgr.childHasKeyboardFocus( parent );
-}
-
-void LLViewerWindow::setMouseCapture(LLMouseHandler* new_captor)
-{
-	gFocusMgr.setMouseCapture( new_captor );
-}
-
-LLMouseHandler* LLViewerWindow::getMouseCaptor() const
-{
-	return gFocusMgr.getMouseCapture();
-}
-
 S32	LLViewerWindow::getWindowHeight()	const 	
 { 
 	return mVirtualWindowRect.getHeight(); 
@@ -4448,21 +4311,6 @@ S32	LLViewerWindow::getWindowDisplayWidth() const
 	return mWindowRect.getWidth(); 
 }
 
-LLUICtrl* LLViewerWindow::getTopCtrl() const
-{
-	return gFocusMgr.getTopCtrl();
-}
-
-BOOL LLViewerWindow::hasTopCtrl(LLView* view) const
-{
-	return view == gFocusMgr.getTopCtrl();
-}
-
-void LLViewerWindow::setTopCtrl(LLUICtrl* new_top)
-{
-	gFocusMgr.setTopCtrl( new_top );
-}
-
 void LLViewerWindow::setupViewport(S32 x_offset, S32 y_offset)
 {
 	gGLViewport[0] = x_offset;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index c7d02cb720..30a9d91de9 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -51,14 +51,13 @@
 class LLView;
 class LLViewerObject;
 class LLUUID;
-class LLMouseHandler;
 class LLProgressView;
 class LLTool;
 class LLVelocityBar;
-class LLViewerWindow;
 class LLTextBox;
 class LLImageRaw;
 class LLHUDIcon;
+class LLMouseHandler;
 
 #define PICK_HALF_WIDTH 5
 #define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1)
@@ -192,6 +191,7 @@ public:
 
 	LLWindow*		getWindow()			const	{ return mWindow; }
 	void*			getPlatformWindow() const	{ return mWindow->getPlatformWindow(); }
+	void*			getMediaWindow() 	const	{ return mWindow->getMediaWindow(); }
 	void			focusClient()		const	{ return mWindow->focusClient(); };
 
 	LLCoordGL		getLastMouse()		const	{ return mLastMousePoint; }
@@ -210,9 +210,6 @@ public:
 	const LLPickInfo&	getLastPick() const { return mLastPick; }
 	const LLPickInfo&	getHoverPick() const { return mHoverPick; }
 
-	LLUICtrl*		getTopCtrl() const;
-	BOOL			hasTopCtrl(LLView* view) const;
-
 	void			setupViewport(S32 x_offset = 0, S32 y_offset = 0);
 	void			setup3DRender();
 	void			setup2DRender();
@@ -261,24 +258,10 @@ public:
 	void			setNormalControlsVisible( BOOL visible );
 	void			setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false);
 
-	// Handle the application becoming active (frontmost) or inactive
-	//BOOL			handleActivate(BOOL activate);
-
-	void			setKeyboardFocus(LLUICtrl* new_focus);		// new_focus = NULL to release the focus.
-	LLUICtrl*		getKeyboardFocus();	
-	BOOL			hasKeyboardFocus( const LLUICtrl* possible_focus ) const;
-	BOOL			childHasKeyboardFocus( const LLView* parent ) const;
-	
-	void			setMouseCapture(LLMouseHandler* new_captor);	// new_captor = NULL to release the mouse.
-	LLMouseHandler*	getMouseCaptor() const;
-
-	void			setTopCtrl(LLUICtrl* new_top); // set new_top = NULL to release top_view.
-
 	void			reshape(S32 width, S32 height);
 	void			sendShapeToSim();
 
 	void			draw();
-//	void			drawSelectedObjects();
 	void			updateDebugText();
 	void			drawDebugText();
 
@@ -368,12 +351,8 @@ public:
 
 	static bool alertCallback(S32 modal);
 	
-#ifdef SABINRIG
-	//Silly rig stuff
-	void		printFeedback(); //RIG STUFF!
-#endif //SABINRIG
-
 private:
+	bool                    shouldShowToolTipFor(LLMouseHandler *mh);
 	void			switchToolByMask(MASK mask);
 	void			destroyWindow();
 	void			drawMouselookInstructions();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 47090d5c65..9bdf842ad6 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -138,7 +138,7 @@ S32 LLVOAvatar::sFreezeCounter = 0 ;
 //-----------------------------------------------------------------------------
 // Constants
 //-----------------------------------------------------------------------------
-const F32 MIN_PIXEL_AREA_FOR_COMPOSITE = 200.f;
+const F32 MIN_PIXEL_AREA_FOR_COMPOSITE = 1024;
 
 F32 SHADOW_OFFSET_AMT = 0.03f;
 
@@ -673,6 +673,10 @@ LLVOAvatar::LLVOAvatar(
 	mUpperMaskTexName(0),
 	mLowerMaskTexName(0),
 	mCulled( FALSE ),
+	mVisibilityRank(0),
+	mFadeTime(0.f),
+	mLastFadeTime(0.f),
+	mLastFadeDistance(1.f),
 	mTexSkinColor( NULL ),
 	mTexHairColor( NULL ),
 	mTexEyeColor( NULL ),
@@ -731,6 +735,7 @@ LLVOAvatar::LLVOAvatar(
 	mNeedsAnimUpdate = TRUE;
 
 	mImpostorDistance = 0;
+	mImpostorPixelArea = 0;
 
 	setNumTEs(TEX_NUM_ENTRIES);
 
@@ -1528,6 +1533,8 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
 		}
 	}
 
+	mPixelArea = LLPipeline::calcPixelArea((newMin+newMax)*0.5f, (newMax-newMin)*0.5f, *LLViewerCamera::getInstance());
+
 	//stretch bounding box by attachments
 	for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); 
 		iter != mAttachmentPoints.end();
@@ -2338,6 +2345,15 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
 	// Do base class updates...
 	U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
 
+	if(retval & LLViewerObject::INVALID_UPDATE)
+	{
+		if(this == gAgent.getAvatarObject())
+		{
+			//tell sim to cancel this update
+			gAgent.teleportViaLocation(gAgent.getPositionGlobal());
+		}
+	}
+
 	//llinfos << getRotation() << llendl;
 	//llinfos << getPosition() << llendl;
 	if (update_type == OUT_FULL )
@@ -2642,7 +2658,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
 			F32 old_angle = mImpostorAngle.mV[i];
 			F32 angle_diff = fabsf(cur_angle-old_angle);
 		
-			if (angle_diff > 3.14159f/512.f*distance)
+			if (angle_diff > 3.14159f/512.f*distance*mUpdatePeriod)
 			{
 				mNeedsImpostorUpdate = TRUE;
 			}
@@ -3362,30 +3378,41 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 	// the rest should only be done occasionally for far away avatars
 	//--------------------------------------------------------------------
 
-	if (!mIsSelf && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter)
+	if (visible && !mIsSelf && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter)
 	{
 		F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f);
 		if (LLMuteList::getInstance()->isMuted(getID()))
-		{
+		{ // muted avatars update at 16 hz
 			mUpdatePeriod = 16;
-			visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE;
 		}
-		else if (visible && mPixelArea <= impostor_area)
-		{
-			mUpdatePeriod = llclamp((S32) sqrtf(impostor_area*4.f/mPixelArea), 2, 8);
-
-			visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE;
+		else if (visible && mVisibilityRank <= LLVOAvatar::sMaxVisible * 0.25f)
+		{ //first 25% of max visible avatars are not impostored
+			mUpdatePeriod = 1;
+		}
+		else if (visible && mVisibilityRank > LLVOAvatar::sMaxVisible * 0.75f)
+		{ //back 25% of max visible avatars are slow updating impostors
+			mUpdatePeriod = 8;
+		}
+		else if (visible && mImpostorPixelArea <= impostor_area)
+		{  // stuff in between gets an update period based on pixel area
+			mUpdatePeriod = llclamp((S32) sqrtf(impostor_area*4.f/mImpostorPixelArea), 2, 8);
+		}
+		else if (visible && mVisibilityRank > LLVOAvatar::sMaxVisible * 0.25f)
+		{ // force nearby impostors in ultra crowded areas
+			mUpdatePeriod = 2;
 		}
 		else
-		{
+		{ // not impostored
 			mUpdatePeriod = 1;
 		}
 
-		if (!visible)
-		{
-			updateMotions(LLCharacter::HIDDEN_UPDATE);
-			return FALSE;
-		}
+		visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE;
+	}
+
+	if (!visible)
+	{
+		updateMotions(LLCharacter::HIDDEN_UPDATE);
+		return FALSE;
 	}
 
 	// change animation time quanta based on avatar render load
@@ -3758,32 +3785,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 
 	mRoot.updateWorldMatrixChildren();
 
-	// Send the speaker position to the spatialized voice system.
-	if(mIsSelf)
-	{
-		LLMatrix3 rot;
-		LLVector3d pos;
-#if 1
-		// character rotation (stable, shouldn't move with animations)
-		rot = mRoot.getWorldRotation().getMatrix3();
-#else	
-		// actual head rotation (moves with animations, probably a bit too much)
-		rot.setRows(
-				LLVector3::x_axis * mSkullp->getWorldRotation(), 
-				LLVector3::y_axis * mSkullp->getWorldRotation(),  
-				LLVector3::z_axis * mSkullp->getWorldRotation());		
-#endif
-	
-		pos = getPositionGlobal();
-		pos += LLVector3d(mHeadOffset);
-		
-		// MBW -- XXX -- Setting velocity to 0 for now.  May figure it out later...
-		gVoiceClient->setAvatarPosition(
-				pos,				// position
-				LLVector3::zero, 	// velocity
-				rot);				// rotation matrix
-	}
-
 	if (!mDebugText.size() && mText.notNull())
 	{
 		mText->markDead();
@@ -4254,7 +4255,23 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color)
 	LLGLEnable test(GL_ALPHA_TEST);
 	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
 
-	gGL.color4f(1,1,1,1);
+	F32 blend = gFrameTimeSeconds - mFadeTime;
+
+	LLGLState gl_blend(GL_BLEND, blend < 1.f ? TRUE : FALSE);
+	gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+	F32 alpha;
+	if (mVisibilityRank >= (U32) LLVOAvatar::sMaxVisible)
+	{ //fade out
+		alpha = 1.f - llmin(blend, 1.f);
+	}
+	else 
+	{ //fade in
+		alpha = llmin(blend, 1.f);
+	}
+
+	color.mV[3] = (U8) (alpha*255);
+	
 	gGL.color4ubv(color.mV);
 	mImpostor.bindTexture();
 	gGL.begin(LLVertexBuffer::QUADS);
@@ -4380,7 +4397,6 @@ void LLVOAvatar::updateTextures(LLAgent &agent)
 			
 			const LLTextureEntry *te = getTE(i);
 			F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
-// 			BOOL boost_aux = (imagep->needsAux() && (!imagep->mFullWidth || !imagep->mFullHeight));
 			S32 boost_level = mIsSelf ? LLViewerImage::BOOST_AVATAR_BAKED_SELF : LLViewerImage::BOOST_AVATAR_BAKED;
 			
 			// Spam if this is a baked texture, not set to default image, without valid host info
@@ -5750,7 +5766,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
 	LLVector3 center = (ext[1] + ext[0]) * 0.5f;
 	LLVector3 size = (ext[1]-ext[0])*0.5f;
 
-	mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
+	mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
 
 	F32 range = mDrawable->mDistanceWRTCamera;
 
@@ -6199,9 +6215,11 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
 				stopMotionFromSource(viewer_object->getID());
 				LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE);
 
-				for (S32 i = 0; i < (S32)viewer_object->mChildList.size(); i++)
+				LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren();
+				for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+					 iter != child_list.end(); iter++)
 				{
-					LLViewerObject* child_objectp = viewer_object->mChildList[i];
+					LLViewerObject* child_objectp = *iter;
 					// the simulator should automatically handle
 					// permissions revocation
 
@@ -6243,6 +6261,10 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
 	mDrawable->mXform.setPosition(rel_pos);
 	mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot);
 
+	//in case the viewerobject is not updated in time
+	mDrawable->getVObj()->setPosition(sit_object->getWorldPosition()) ;
+	mDrawable->getVObj()->setRotation(sit_object->getWorldRotation()) ;
+
 	gPipeline.markMoved(mDrawable, TRUE);
 	mIsSitting = TRUE;
 	mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
@@ -6284,9 +6306,11 @@ void LLVOAvatar::getOffObject()
 		stopMotionFromSource(sit_object->getID());
 		LLFollowCamMgr::setCameraActive(sit_object->getID(), FALSE);
 
-		for (S32 i = 0; i < (S32)sit_object->mChildList.size(); i++)
+		LLViewerObject::const_child_list_t& child_list = sit_object->getChildren();
+		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+			 iter != child_list.end(); iter++)
 		{
-			LLViewerObject* child_objectp = sit_object->mChildList[i];
+			LLViewerObject* child_objectp = *iter;
 
 			stopMotionFromSource(child_objectp->getID());
 			LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE);
@@ -6299,7 +6323,11 @@ void LLVOAvatar::getOffObject()
 
 	// set *local* position based on last *world* position, since we're unparenting the avatar
 	mDrawable->mXform.setPosition(cur_position_world);
-	mDrawable->mXform.setRotation(cur_rotation_world);
+	mDrawable->mXform.setRotation(cur_rotation_world);	
+	
+	//in case the viewerobject is not updated from sim in time
+	mDrawable->getVObj()->setPosition(cur_position_world);
+	mDrawable->getVObj()->setRotation(cur_rotation_world);
 
 	gPipeline.markMoved(mDrawable, TRUE);
 
@@ -6750,7 +6778,9 @@ void LLVOAvatar::dumpTotalLocalTextureByteCount()
 
 BOOL LLVOAvatar::isVisible()
 {
-	return mDrawable.notNull() && (mDrawable->isVisible() || mIsDummy); 
+	return mDrawable.notNull()
+		&& (mDrawable->isVisible() || mIsDummy)
+		&& (mVisibilityRank < (U32) sMaxVisible || gFrameTimeSeconds - mFadeTime < 1.f); 
 }
 
 
@@ -7184,9 +7214,8 @@ void LLVOAvatar::updateMeshTextures()
 		{
 			mHeadBakedLoaded = FALSE;
 			mHeadMaskDiscard = -1;
-			baked->setNeedsAux(TRUE);
-			baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID ));	
-			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) );
+			baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));	
+			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) );
 		}
 	}
 	else
@@ -7235,9 +7264,8 @@ void LLVOAvatar::updateMeshTextures()
 		{
 			mUpperBakedLoaded = FALSE;
 			mUpperMaskDiscard = -1;
-			baked->setNeedsAux(TRUE);
-			baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID ));
-			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) );
+			baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));
+			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) );
 		}
 	}
 	else
@@ -7283,9 +7311,8 @@ void LLVOAvatar::updateMeshTextures()
 		{
 			mLowerBakedLoaded = FALSE;
 			mLowerMaskDiscard = -1;
-			baked->setNeedsAux(TRUE);
-			baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID ));
-			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) );
+			baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));
+			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) );
 		}
 	}
 	else
@@ -7329,7 +7356,7 @@ void LLVOAvatar::updateMeshTextures()
 		else
 		{
 			mEyesBakedLoaded = FALSE;
-			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) );
+			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) );
 		}
 	}
 	else
@@ -7372,7 +7399,7 @@ void LLVOAvatar::updateMeshTextures()
 		else
 		{
 			mSkirtBakedLoaded = FALSE;
-			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) );
+			baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) );
 		}
 	}
 	else
@@ -7473,7 +7500,7 @@ void LLVOAvatar::setLocalTexture( ELocTexIndex idx, LLViewerImage* tex, BOOL bak
 				}
 				else
 				{
-					tex->setLoadedCallback( onLocalTextureLoaded, desired_discard, TRUE, new LLAvatarTexData(getID(), idx) );
+					tex->setLoadedCallback( onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), idx) );
 				}
 			}
 			tex->setMinDiscardLevel(desired_discard);
@@ -8274,9 +8301,12 @@ LLBBox LLVOAvatar::getHUDBBox()
 			bbox.addPointLocal(hud_object->getPosition());
 			// add rotated bounding box for attached object
 			bbox.addBBoxAgent(hud_object->getBoundingBoxAgent());
-			for (U32 i = 0; i < hud_object->mChildList.size(); i++)
+			LLViewerObject::const_child_list_t& child_list = hud_object->getChildren();
+			for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+				 iter != child_list.end(); iter++)
 			{
-				bbox.addBBoxAgent(hud_object->mChildList[i]->getBoundingBoxAgent());
+				LLViewerObject* child_objectp = *iter;
+				bbox.addBBoxAgent(child_objectp->getBoundingBoxAgent());
 			}
 		}
 	}
@@ -8309,41 +8339,38 @@ void LLVOAvatar::onFirstTEMessageReceived()
 		{
 			mLastHeadBakedID = getTEImage( TEX_HEAD_BAKED )->getID();
 			LLViewerImage* image = getTEImage( TEX_HEAD_BAKED );
-			image->setNeedsAux(TRUE);
-			image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID ));	
-			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) );
+			image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));	
+			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) );
 		}
 
 		if( upper_baked )
 		{
 			mLastUpperBodyBakedID = getTEImage( TEX_UPPER_BAKED )->getID();
 			LLViewerImage* image = getTEImage( TEX_UPPER_BAKED );
-			image->setNeedsAux(TRUE);
-			image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID ));	
-			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) );
+			image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));	
+			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) );
 		}
 		
 		if( lower_baked )
 		{
 			mLastLowerBodyBakedID = getTEImage( TEX_LOWER_BAKED )->getID();
 			LLViewerImage* image = getTEImage( TEX_LOWER_BAKED );
-			image->setNeedsAux(TRUE);
-			image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID ));	
-			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) );
+			image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));	
+			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) );
 		}
 
 		if( eyes_baked )
 		{
 			mLastEyesBakedID = getTEImage( TEX_EYES_BAKED )->getID();
 			LLViewerImage* image = getTEImage( TEX_EYES_BAKED );
-			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) );
+			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) );
 		}
 
 		if( skirt_baked )
 		{
 			mLastSkirtBakedID = getTEImage( TEX_SKIRT_BAKED )->getID();
 			LLViewerImage* image = getTEImage( TEX_SKIRT_BAKED );
-			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) );
+			image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) );
 		}
 
 		updateMeshTextures();
@@ -8355,6 +8382,12 @@ void LLVOAvatar::onFirstTEMessageReceived()
 //-----------------------------------------------------------------------------
 void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 {
+	if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages"))
+	{
+		llwarns << "Blocking AvatarAppearance message" << llendl;
+		return;
+	}
+	
 	LLMemType mt(LLMemType::MTYPE_AVATAR);
 	
 //	llinfos << "processAvatarAppearance start " << mID << llendl;
@@ -8846,6 +8879,42 @@ void LLVOAvatar::dumpArchetypeXML( void* )
 }
 
 
+U32 LLVOAvatar::getVisibilityRank()
+{
+	return mVisibilityRank;
+}
+
+void LLVOAvatar::setVisibilityRank(U32 rank)
+{
+	BOOL stale = gFrameTimeSeconds - mLastFadeTime > 10.f;
+	
+	//only raise visibility rank or trigger a fade out every 10 seconds
+	if (mVisibilityRank >= (U32) LLVOAvatar::sMaxVisible && rank < (U32) LLVOAvatar::sMaxVisible ||
+		(stale && mVisibilityRank < (U32) LLVOAvatar::sMaxVisible && rank >= (U32) LLVOAvatar::sMaxVisible))
+	{ //remember the time we became visible/invisible based on visibility rank
+		mVisibilityRank = rank;
+		mLastFadeTime = gFrameTimeSeconds;
+		mLastFadeDistance = mDrawable->mDistanceWRTCamera;
+
+		F32 blend = gFrameTimeSeconds - mFadeTime;
+		mFadeTime = gFrameTimeSeconds;
+		if (blend < 1.f)
+		{ //move the blend time back if a blend is already in progress (prevent flashes)
+			mFadeTime -= 1.f-blend;
+		}
+	}
+	else if (stale)
+	{
+		mLastFadeTime = gFrameTimeSeconds;
+		mLastFadeDistance = mDrawable->mDistanceWRTCamera;
+		mVisibilityRank = rank;
+	}
+	else
+	{
+		mVisibilityRank = llmin(mVisibilityRank, rank);
+	}
+}
+
 // Assumes LLVOAvatar::sInstances has already been sorted.
 S32 LLVOAvatar::getUnbakedPixelAreaRank()
 {
@@ -8875,8 +8944,8 @@ void LLVOAvatar::cullAvatarsByPixelArea()
 	std::sort(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), CompareScreenAreaGreater());
 	
 	// Update the avatars that have changed status
-	S32 rank = 1;
-
+	S32 comp_rank = 1;
+	U32 rank = 0;
 	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
 		iter != LLCharacter::sInstances.end(); ++iter)
 	{
@@ -8892,8 +8961,8 @@ void LLVOAvatar::cullAvatarsByPixelArea()
 		}
 		else
 		{
-			culled = (rank > LLVOAvatar::sMaxOtherAvatarsToComposite) || (inst->mPixelArea < MIN_PIXEL_AREA_FOR_COMPOSITE);
-			rank++;
+			culled = (comp_rank > LLVOAvatar::sMaxOtherAvatarsToComposite) || (inst->mPixelArea < MIN_PIXEL_AREA_FOR_COMPOSITE);
+			comp_rank++;
 		}
 
 		if( inst->mCulled != culled )
@@ -8904,6 +8973,15 @@ void LLVOAvatar::cullAvatarsByPixelArea()
 
 			inst->updateMeshTextures();
 		}
+
+		if (inst->isSelf())
+		{
+			inst->setVisibilityRank(0);
+		}
+		else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible())
+		{
+			inst->setVisibilityRank(rank++);
+		}
 	}
 
 	if( LLVOAvatar::areAllNearbyInstancesBaked() )
@@ -9867,9 +9945,20 @@ U32 calc_shame(LLVOVolume* volume, std::set<LLUUID> &textures)
 
 	shame += invisi + shiny + glow + alpha*4 + flexi*8 + animtex*4 + particles*16+bump*4+scale+planar;
 
-	for (U32 i = 0; i < drawablep->getChildCount(); ++i)
+	LLViewerObject::const_child_list_t& child_list = volume->getChildren();
+	for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+		 iter != child_list.end(); iter++)
 	{
-		shame += calc_shame(drawablep->getChild(i)->getVOVolume(), textures);
+		LLViewerObject* child_objectp = *iter;
+		LLDrawable* child_drawablep = child_objectp->mDrawable;
+		if (child_drawablep)
+		{
+			LLVOVolume* child_volumep = child_drawablep->getVOVolume();
+			if (child_volumep)
+			{
+				shame += calc_shame(child_volumep, textures);
+			}
+		}
 	}
 
 	return shame;
@@ -9916,3 +10005,4 @@ void LLVOAvatar::idleUpdateRenderCost()
 	mText->setColor(LLColor4(red,green,0,1));
 }
 
+
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index ff846c8d83..2ed0f1ec9b 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -439,6 +439,8 @@ public:
 	BOOL			isCulled() { return mCulled; }
 	
 	S32				getUnbakedPixelAreaRank();
+	void			setVisibilityRank(U32 rank);
+	U32				getVisibilityRank();
 	static void		cullAvatarsByPixelArea();
 
 	void			dumpLocalTextures();
@@ -717,8 +719,9 @@ public:
 	LLVector3		mImpostorExtents[2];
 	LLVector3		mImpostorAngle;
 	F32				mImpostorDistance;
+	F32				mImpostorPixelArea;
 	LLVector3		mLastAnimExtents[2];  
-
+	
 	//--------------------------------------------------------------------
 	// Misc Render State
 	//--------------------------------------------------------------------
@@ -956,6 +959,10 @@ protected:
 	U32					mLowerMaskTexName;
 
 	BOOL				mCulled;
+	U32					mVisibilityRank;
+	F32					mFadeTime;
+	F32					mLastFadeTime;
+	F32					mLastFadeDistance;
 	F32					mMinPixelArea; // debug
 	F32					mMaxPixelArea; // debug
 	
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 445e553c23..3cf0eb839d 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -60,6 +60,7 @@
 #include "llviewerparcelmgr.h"
 #include "llfirstuse.h"
 #include "llviewerwindow.h"
+#include "llviewercamera.h"
 
 // for base64 decoding
 #include "apr_base64.h"
@@ -1191,7 +1192,11 @@ void LLVoiceClient::stateMachine()
 		setVoiceEnabled(false);
 	}
 	
-	if(!mVoiceEnabled)
+	if(mVoiceEnabled)
+	{
+		updatePosition();
+	}
+	else
 	{
 		if(getState() != stateDisabled)
 		{
@@ -3516,6 +3521,45 @@ void LLVoiceClient::enforceTether(void)
 	}
 }
 
+void LLVoiceClient::updatePosition(void)
+{
+	
+	if(gVoiceClient)
+	{
+		LLVOAvatar *agent = gAgent.getAvatarObject();
+		LLViewerRegion *region = gAgent.getRegion();
+		if(region && agent)
+		{
+			LLMatrix3 rot;
+			LLVector3d pos;
+
+			// MBW -- XXX -- Setting both camera and avatar velocity to 0 for now.  May figure it out later...
+
+			// Send the current camera position to the voice code
+			rot.setRows(LLViewerCamera::getInstance()->getAtAxis(), LLViewerCamera::getInstance()->getLeftAxis (),  LLViewerCamera::getInstance()->getUpAxis());		
+			pos = gAgent.getRegion()->getPosGlobalFromRegion(LLViewerCamera::getInstance()->getOrigin());
+			
+			gVoiceClient->setCameraPosition(
+					pos,				// position
+					LLVector3::zero, 	// velocity
+					rot);				// rotation matrix
+					
+			// Send the current avatar position to the voice code
+			rot = agent->getRootJoint()->getWorldRotation().getMatrix3();
+	
+			pos = agent->getPositionGlobal();
+			// MBW -- XXX -- Can we get the head offset from outside the LLVOAvatar?
+//			pos += LLVector3d(mHeadOffset);
+			pos += LLVector3d(0.f, 0.f, 1.f);
+		
+			gVoiceClient->setAvatarPosition(
+					pos,				// position
+					LLVector3::zero, 	// velocity
+					rot);				// rotation matrix
+		}
+	}
+}
+
 void LLVoiceClient::setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot)
 {
 	mCameraRequestedPosition = position;
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index f864b75bec..2e1efce6fb 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -188,6 +188,7 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
 		
 		/////////////////////////////
 		// Sending updates of current state
+static	void updatePosition(void);
 		void setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
 		void setAvatarPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
 		bool channelFromRegion(LLViewerRegion *region, std::string &name);
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 40e405a313..6eb3851d16 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -293,10 +293,6 @@ void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
 	if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking )
 	{
 		U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude);
-		if (transfer_index < 0)
-		{
-		   transfer_index = 0;
-		}
 		if (transfer_index >= sOohPowerTransfers)
 		{
 		   transfer_index = sOohPowerTransfers - 1;
@@ -304,10 +300,6 @@ void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
 		F32 transfer_ooh = sOohPowerTransfer[transfer_index];
 
 		transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude);
-		if (transfer_index < 0)
-		{
-		   transfer_index = 0;
-		}
 		if (transfer_index >= sAahPowerTransfers)
 		{
 		   transfer_index = sAahPowerTransfers - 1;
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 412e4660c8..6cc61e36e0 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -180,14 +180,13 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
 	pixel_meter_ratio *= pixel_meter_ratio;
 
 	S32 count=0;
-	S32 i;
 	mDepth = 0.f;
-
-	for (i = 0; i < num_parts; i++)
+	S32 i = 0 ;
+	for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++)
 	{
-		const LLViewerPart &part = *((LLViewerPart*) mViewerPartGroupp->mParticles[i]);
+		const LLViewerPart *part = mViewerPartGroupp->mParticles[i];
 
-		LLVector3 part_pos_agent(part.mPosAgent);
+		LLVector3 part_pos_agent(part->mPosAgent);
 		at = part_pos_agent - camera_agent;
 
 		F32 camera_dist_squared = at.magVecSquared();
@@ -196,7 +195,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
 			inv_camera_dist_squared = 1.f / camera_dist_squared;
 		else
 			inv_camera_dist_squared = 1.f;
-		F32 area = part.mScale.mV[0] * part.mScale.mV[1] * inv_camera_dist_squared;
+		F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared;
 		tot_area = llmax(tot_area, area);
  		
 		if (tot_area > max_area)
@@ -227,7 +226,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
 		
 		facep->setViewerObject(this);
 
-		if (part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK)
+		if (part->mFlags & LLPartData::LL_PART_EMISSIVE_MASK)
 		{
 			facep->setState(LLFace::FULLBRIGHT);
 		}
@@ -236,9 +235,9 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
 			facep->clearState(LLFace::FULLBRIGHT);
 		}
 
-		facep->mCenterLocal = part.mPosAgent;
-		facep->setFaceColor(part.mColor);
-		facep->setTexture(part.mImagep);
+		facep->mCenterLocal = part->mPosAgent;
+		facep->setFaceColor(part->mColor);
+		facep->setTexture(part->mImagep);
 
 		mPixelArea = tot_area * pixel_meter_ratio;
 		const F32 area_scale = 10.f; // scale area to increase priority a bit
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 1e1f8be859..225d9a18b2 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -68,7 +68,7 @@
 const S32 MIN_QUIET_FRAMES_COALESCE = 30;
 const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
 const F32 FORCE_CULL_AREA = 8.f;
-const S32 SCULPT_REZ = 128;
+const S32 SCULPT_REZ = 64;
 
 BOOL gAnimateTextures = TRUE;
 extern BOOL gHideSelectedObjects;
@@ -87,6 +87,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
 	mRelativeXformInvTrans.setIdentity();
 
 	mLOD = MIN_LOD;
+	mSculptLevel = -2;
 	mTextureAnimp = NULL;
 	mVObjRadius = LLVector3(1,1,0.5f).magVec();
 	mNumFaces = 0;
@@ -515,12 +516,13 @@ void LLVOVolume::updateTextures()
 		if (mSculptTexture.notNull())
 		{
 			mSculptTexture->addTextureStats(SCULPT_REZ * SCULPT_REZ);
-			mSculptTexture->setBoostLevel(LLViewerImage::BOOST_SCULPTED);
+			mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
+												(S32)LLViewerImage::BOOST_SCULPTED));
 		}
 
 		S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture
-		S32 current_discard = getVolume()->getSculptLevel();
-		
+		S32 current_discard = mSculptLevel;
+
 		if (texture_discard >= 0 && //texture has some data available
 			(texture_discard < current_discard || //texture has more data than last rebuild
 			current_discard < 0)) //no previous rebuild
@@ -701,6 +703,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail
 			if (mSculptTexture.notNull())
 			{
 				sculpt();
+				mSculptLevel = getVolume()->getSculptLevel();
 			}
 		}
 		else
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 262d4ecc8d..58a1b308a4 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -224,6 +224,7 @@ private:
 	LLFrameTimer mTextureUpdateTimer;
 	S32			mLOD;
 	BOOL		mLODChanged;
+	S32         mSculptLevel;
 	BOOL		mSculptChanged;
 	LLMatrix4	mRelativeXform;
 	LLMatrix3	mRelativeXformInvTrans;
diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h
index ab9a00c785..ffb360934a 100644
--- a/indra/newview/llwearable.h
+++ b/indra/newview/llwearable.h
@@ -61,9 +61,8 @@ enum	EWearableType  // If you change this, update LLWearable::getTypeName(), get
 
 class LLWearable
 {
+	friend class LLWearableList;
 public:
-	LLWearable(const LLTransactionID& transactionID);
-	LLWearable(const LLAssetID& assetID);
 	~LLWearable();
 
 	const LLAssetID&		getID() { return mAssetID; }
@@ -120,6 +119,10 @@ public:
 	friend std::ostream& operator<<(std::ostream &s, const LLWearable &w);
 
 private:
+	// Private constructor used by LLWearableList
+	LLWearable(const LLTransactionID& transactionID);
+	LLWearable(const LLAssetID& assetID);
+
 	static S32			sCurrentDefinitionVersion;	// Depends on the current state of the avatar_lad.xml.
 	S32					mDefinitionVersion;			// Depends on the state of the avatar_lad.xml when this asset was created.
 	std::string			mName;
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index 7678727e58..a32c43302d 100644
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -43,7 +43,7 @@
 #include "llnotify.h"
 
 // Globals
-LLWearableList gWearableList;
+LLWearableList gWearableList; // Globally constructed; be careful that there's no dependency with gAgent.
 
 
 struct LLWearableArrivedData
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 08c593755b..8cebf1c12a 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -135,7 +135,7 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
 	{
 		LLHost old_host = regionp->getHost();
 		// region already exists!
-		if (host == old_host && regionp->mAlive)
+		if (host == old_host && regionp->isAlive())
 		{
 			// This is a duplicate for the same host and it's alive, don't bother.
 			return regionp;
@@ -146,7 +146,7 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
 			llwarns << "LLWorld::addRegion exists, but old host " << old_host
 					<< " does not match new host " << host << llendl;
 		}
-		if (!regionp->mAlive)
+		if (!regionp->isAlive())
 		{
 			llwarns << "LLWorld::addRegion exists, but isn't alive" << llendl;
 		}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c24d1b882a..7269e32d71 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -197,6 +197,7 @@ glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top,
 	return ret;
 }
 
+void display_update_camera();
 //----------------------------------------
 
 S32		LLPipeline::sCompiles = 0;
@@ -224,6 +225,8 @@ BOOL	LLPipeline::sImpostorRender = FALSE;
 BOOL	LLPipeline::sUnderWaterRender = FALSE;
 BOOL	LLPipeline::sTextureBindTest = FALSE;
 BOOL	LLPipeline::sRenderFrameTest = FALSE;
+BOOL	LLPipeline::sRenderAttachedLights = TRUE;
+BOOL	LLPipeline::sRenderAttachedParticles = TRUE;
 
 static LLCullResult* sCull = NULL;
 
@@ -240,10 +243,30 @@ static const U32 gl_cube_face[] =
 void validate_framebuffer_object();
 
 LLPipeline::LLPipeline() :
+	mBackfaceCull(FALSE),
+	mBatchCount(0),
+	mMatrixOpCount(0),
+	mTextureMatrixOps(0),
+	mMaxBatchSize(0),
+	mMinBatchSize(0),
+	mMeanBatchSize(0),
+	mTrianglesDrawn(0),
+	mNumVisibleNodes(0),
+	mVerticesRelit(0),
+	mLightingChanges(0),
+	mGeometryChanges(0),
+	mNumVisibleFaces(0),
+
 	mCubeBuffer(NULL),
+	mCubeFrameBuffer(0),
+	mCubeDepth(0),
 	mInitialized(FALSE),
 	mVertexShadersEnabled(FALSE),
 	mVertexShadersLoaded(0),
+	mRenderTypeMask(0),
+	mRenderDebugFeatureMask(0),
+	mRenderDebugMask(0),
+	mOldRenderDebugMask(0),
 	mLastRebuildPool(NULL),
 	mAlphaPool(NULL),
 	mSkyPool(NULL),
@@ -256,15 +279,11 @@ LLPipeline::LLPipeline() :
 	mBumpPool(NULL),
 	mWLSkyPool(NULL),
 	mLightMask(0),
-	mLightMovingMask(0)
+	mLightMovingMask(0),
+	mLightingDetail(0)
 {
-	//mFramebuffer[0] = mFramebuffer[1] = mFramebuffer[2] = mFramebuffer[3] = 0;
 	mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0;
 	mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0;
-
-	//mDepthbuffer[0] = mDepthbuffer[1] = 0;
-	mCubeFrameBuffer = 0;
-	mCubeDepth = 0;
 }
 
 void LLPipeline::init()
@@ -273,6 +292,8 @@ void LLPipeline::init()
 
 	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+	sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
+	sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
 
 	mInitialized = TRUE;
 	
@@ -439,12 +460,6 @@ void LLPipeline::releaseGLBuffers()
 		mCubeDepth = mCubeFrameBuffer = 0;
 	}
 
-	/*if (mFramebuffer[0])
-	{
-		glDeleteFramebuffersEXT(4, mFramebuffer);
-		mFramebuffer[0] = mFramebuffer[1] = mFramebuffer[2] = mFramebuffer[3] = 0;
-	}*/
-
 	if (mBlurCubeBuffer[0])
 	{
 		glDeleteFramebuffersEXT(3, mBlurCubeBuffer);
@@ -1582,6 +1597,9 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
 			}
 		}
 	}
+
+	LLHUDText::shiftAll(offset);
+	display_update_camera();
 }
 
 void LLPipeline::markTextured(LLDrawable *drawablep)
@@ -1766,6 +1784,12 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
 		{
 			return;
 		}
+
+		LLVOAvatar* avatarp = (LLVOAvatar*) drawablep->getVObj().get();
+		if (!avatarp->isVisible())
+		{
+			return;
+		}
 	}
 
 	assertInitialized();
@@ -2153,6 +2177,7 @@ void render_hud_elements()
 	gGL.color4f(1,1,1,1);
 	if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
 	{
+		LLGLEnable multisample(GL_MULTISAMPLE_ARB);
 		gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d()
 	
 		// Draw the tracking overlays
@@ -2717,12 +2742,15 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render
 					}
 
 					//render child faces
-					for (U32 k = 0; k < drawable->getChildCount(); ++k)
+					LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+					for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+						 iter != child_list.end(); iter++)
 					{
-						LLDrawable* child = drawable->getChild(k);
-						for (S32 l = 0; l < child->getNumFaces(); ++l)
+						LLViewerObject* child = *iter;
+						LLDrawable* child_drawable = child->mDrawable;
+						for (S32 l = 0; l < child_drawable->getNumFaces(); ++l)
 						{
-							LLFace* facep = child->getFace(l);
+							LLFace* facep = child_drawable->getFace(l);
 							if (!facep->getPool())
 							{
 								facep->renderForSelect(prim_mask);
@@ -3174,12 +3202,16 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 				if (light->fade <= -LIGHT_FADE_TIME)
 				{
 					drawable->clearState(LLDrawable::NEARBY_LIGHT);
+					continue;
 				}
-				else
+				if (!sRenderAttachedLights && volight && volight->isAttachment())
 				{
-					F32 dist = calc_light_dist(volight, cam_pos, max_dist);
-					cur_nearby_lights.insert(Light(drawable, dist, light->fade));
+					drawable->clearState(LLDrawable::NEARBY_LIGHT);
+					continue;
 				}
+
+				F32 dist = calc_light_dist(volight, cam_pos, max_dist);
+				cur_nearby_lights.insert(Light(drawable, dist, light->fade));
 			}
 			mNearbyLights = cur_nearby_lights;
 		}
@@ -4026,11 +4058,6 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
 		return;
 	}
 
-	if (!drawable)
-	{
-		return;
-	}
-
 	for (S32 i = 0; i < drawable->getNumFaces(); i++)
 	{
 		LLFace* facep = drawable->getFace(i);
@@ -5224,7 +5251,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 		LLGLDepthTest depth(GL_FALSE, GL_FALSE);
 
 		gGL.color4f(1,1,1,1);
-		gGL.color4ub(64,64,64,1);
+		gGL.color4ub(64,64,64,255);
 		gGL.begin(LLVertexBuffer::QUADS);
 		gGL.vertex3fv((pos+left-up).mV);
 		gGL.vertex3fv((pos-left-up).mV);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index ac2c32fedd..389b80813d 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -389,6 +389,8 @@ public:
 	static BOOL				sRenderGlow;
 	static BOOL				sTextureBindTest;
 	static BOOL				sRenderFrameTest;
+	static BOOL				sRenderAttachedLights;
+	static BOOL				sRenderAttachedParticles;
 	
 	//screen texture
 	LLRenderTarget			mScreen;
@@ -403,10 +405,6 @@ public:
 
 	//texture for making the glow
 	LLRenderTarget				mGlow[3];
-	
-	//framebuffer objects for off-screen scratch space
-	//GLuint					mFramebuffer[4];
-	//GLuint					mDepthbuffer[2];
 
 	//dynamic cube map scratch space
 	LLPointer<LLCubeMap>	mCubeBuffer;
diff --git a/indra/newview/skins/default/xui/ja/floater_joystick.xml b/indra/newview/skins/default/xui/ja/floater_joystick.xml
index b71cffac63..0f1541a385 100644
--- a/indra/newview/skins/default/xui/ja/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/ja/floater_joystick.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater name="Joystick" title="ジョイスティックの設定">
 	<check_box name="enable_joystick" width="120" >
 		ジョイスティックを使う:
@@ -112,9 +112,15 @@
 	<text left="0" name="ZoomDeadZone" width="140">
 		ズーム・デッド・ゾーン
 	</text>
-	<spinner left="275" name="FlycamAxisDeadZone6" width="50" />
-	<button label="SpaceNavigatorのデフォルト設定" left="330"
-	     name="SpaceNavigatorDefaults" width="210" />
+	<spinner left="275" width="50" name="FlycamAxisDeadZone6" />
+	<button label="SpaceNavigatorのデフォルト設定" name="SpaceNavigatorDefaults" width="210" left="330"/>
+
+	<string name="JoystickMonitor">
+		ジョイスティック・モニター
+	</string>
+	<string name="Axis">
+		軸 [NUM]
+	</string>
 	<string name="NoDevice">
 		デバイスは検出されませんでした
 	</string>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 58acbaf3d1..caa691a0b4 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -388,6 +388,7 @@ class DarwinManifest(ViewerManifest):
                 self.path("licenses-mac.txt", dst="licenses.txt")
                 self.path("featuretable_mac.txt")
                 self.path("secondlife.icns")
+                self.path("SecondLife.nib")
                 
                 # Translations
                 self.path("English.lproj")
@@ -408,6 +409,10 @@ class DarwinManifest(ViewerManifest):
                 
                 #libfmodwrapper.dylib
                 self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib")
+                
+                # our apps
+                self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
+                self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
 
                 # command line arguments for connecting to the proper grid
                 self.put_in_file(self.flags_list(), 'arguments.txt')
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index 9be6c5c5bf..d15377a26b 100644
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -38,7 +38,25 @@ set(win_crash_logger_HEADER_FILES
 set_source_files_properties(${win_crash_logger_HEADER_FILES}
                             PROPERTIES HEADER_FILE_ONLY TRUE)
 
-list(APPEND win_crash_logger_SOURCE_FILES ${win_crash_logger_HEADER_FILES})
+set(win_crash_logger_RESOURCE_FILES
+    ll_icon.ico
+    )
+
+set_source_files_properties(${win_crash_logger_RESOURCE_FILES}
+                            PROPERTIES HEADER_FILE_ONLY TRUE)
+
+set(win_crash_logger_RESOURCE_FILES 
+    win_crash_logger.rc
+    ${win_crash_logger_RESOURCE_FILES}
+    )
+
+SOURCE_GROUP("Resource Files" FILES ${win_crash_logger_RESOURCE_FILES})
+
+list(APPEND 
+    win_crash_logger_SOURCE_FILES 
+    ${win_crash_logger_HEADER_FILES} 
+    ${win_crash_logger_RESOURCE_FILES}
+    )
 
 find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR})
 
-- 
GitLab