diff --git a/.hgtags b/.hgtags
index 643eda1a2bd556d3aeed685537671f188dd3aa1c..d9c1bbbb81638a7334c77e3d8f9342a96f305393 100644
--- a/.hgtags
+++ b/.hgtags
@@ -194,3 +194,4 @@ b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
 61aa7974df089e8621fe9a4c69bcdefdb3cc208a 3.0.3-beta2
 0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release
 0496d2f74043cf4e6058e76ac3db03d44cff42ce 3.0.3-release
+92a3aa04775438226399b19deee12ac3b5a62838 3.0.5-start
diff --git a/BuildParams b/BuildParams
old mode 100755
new mode 100644
diff --git a/autobuild.xml b/autobuild.xml
index e5c6b83037782ddffd1ac14a2c1ec297b188d304..347ef419edd01e53e18d6af551e6705c66b7e5c2 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1206,9 +1206,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>a7c80fd8516df3b879b669b2b220067f</string>
+              <string>9cd66e879908f047d9af665b92946ecc</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/232420/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20110608.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/239803/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20110830.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin</string>
@@ -1230,9 +1230,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b9cc0333cc274c9cc40256ab7146b4fc</string>
+              <string>ab9393795515cbbe9526bde33b41bf2a</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/232420/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20110608.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/239670/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20110829.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 016aa0064a03977605b6de9494576803768972d1..bcdc5a63d215706d86f8cb88822212ded5377ec4 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -65,11 +65,15 @@ Aimee Trescothick
 Alejandro Rosenthal
 	VWR-1184
 Aleric Inglewood
+	SNOW-84
 	SNOW-240
+	SNOW-477
 	SNOW-522
 	SNOW-626
+	SNOW-744
 	SNOW-756
 	SNOW-764
+	SNOW-766
 	SNOW-800
 	VWR-10001
 	VWR-10579
@@ -95,11 +99,8 @@ Aleric Inglewood
 	VWR-24366
 	VWR-24519
 	VWR-24520
-	SNOW-84
-	SNOW-477
-	SNOW-744
-	SNOW-766
 	STORM-163
+	STORM-864
 	STORM-955
 	STORM-960
 Ales Beaumont
@@ -176,6 +177,8 @@ Ardy Lay
 	VWR-24917
 Argent Stonecutter
 	VWR-68
+ArminWeatherHax
+	STORM-1532
 Armin Weatherwax
 	VWR-8436
 ArminasX Saiman
@@ -567,6 +570,7 @@ Jonathan Yap
 	STORM-1276
 	STORM-1462
 	STORM-1459
+	STORM-1297
 	STORM-1522
 	STORM-1567
 	STORM-1572
diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp
index a40de9fa68b21afe656d862642d2b7992a33829f..88dfdb9c2449c5e3d2a88c38e731c3d1a0ffc88b 100644
--- a/indra/llaudio/llaudioengine_fmod.cpp
+++ b/indra/llaudio/llaudioengine_fmod.cpp
@@ -673,7 +673,7 @@ bool LLAudioBufferFMOD::loadWAV(const std::string& filename)
 		return false;
 	}
 
-	if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
+	if (!LLAPRFile::isExist(filename, LL_APR_RPB))
 	{
 		// File not found, abort.
 		return false;
diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp
index 0e0c80a45675b6aad361fb49fd563645cf3409d8..44eeea0ca4115730f614c873faefaa503c68dc9a 100644
--- a/indra/llaudio/llvorbisencode.cpp
+++ b/indra/llaudio/llvorbisencode.cpp
@@ -82,8 +82,7 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro
 	error_msg.clear();
 
 	//********************************
-	LLAPRFile infile ;
-    infile.open(in_fname,LL_APR_RB);
+	LLAPRFile infile(in_fname, LL_APR_RB);
 	//********************************
 	if (!infile.getFileHandle())
 	{
@@ -233,8 +232,7 @@ S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname
 
 	S32 data_left = 0;
 
-	LLAPRFile infile ;
-	infile.open(in_fname,LL_APR_RB);
+	LLAPRFile infile(in_fname,LL_APR_RB);
 	if (!infile.getFileHandle())
 	{
 		llwarns << "Couldn't open temporary ogg file for writing: " << in_fname
@@ -242,8 +240,7 @@ S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname
 		return(LLVORBISENC_SOURCE_OPEN_ERR);
 	}
 
-	LLAPRFile outfile ;
-	outfile.open(out_fname,LL_APR_WPB);
+	LLAPRFile outfile(out_fname, LL_APR_WPB);
 	if (!outfile.getFileHandle())
 	{
 		llwarns << "Couldn't open upload sound file for reading: " << in_fname
diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp
index f3cf950afae70deffcafc7a07adabcb4878f415e..c3c7f03247f4b412c9a6f3a8514bb917c2142aeb 100644
--- a/indra/llcharacter/llbvhloader.cpp
+++ b/indra/llcharacter/llbvhloader.cpp
@@ -219,8 +219,7 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
 	//--------------------------------------------------------------------
 	std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName);
 
-	LLAPRFile infile ;
-	infile.open(path, LL_APR_R);
+	LLAPRFile infile(path, LL_APR_R);
 	apr_file_t *fp = infile.getFileHandle();
 	if (!fp)
 		return E_ST_NO_XLT_FILE;
diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp
index 82fe8971f5a4183d6e7c2dfc917d74e9c91ffaf0..c3d5dec875414b3a27e2e91b665db28de8456500 100644
--- a/indra/llcharacter/llkeyframemotionparam.cpp
+++ b/indra/llcharacter/llkeyframemotionparam.cpp
@@ -351,8 +351,7 @@ BOOL LLKeyframeMotionParam::loadMotions()
 	// open the file
 	//-------------------------------------------------------------------------
 	S32 fileSize = 0;
-	LLAPRFile infile ;
-	infile.open(path, LL_APR_R, NULL, &fileSize);
+	LLAPRFile infile(path, LL_APR_R, &fileSize);
 	apr_file_t* fp = infile.getFileHandle() ;
 	if (!fp || fileSize == 0)
 	{
diff --git a/indra/llcharacter/llstatemachine.cpp b/indra/llcharacter/llstatemachine.cpp
index e0454131a52e393d6c006a5897815336a0fa20df..dcc4ff5f0e7c2b095984f170b036662cff37a5b8 100644
--- a/indra/llcharacter/llstatemachine.cpp
+++ b/indra/llcharacter/llstatemachine.cpp
@@ -204,8 +204,7 @@ LLFSMState* LLStateDiagram::getState(U32 state_id)
 
 BOOL LLStateDiagram::saveDotFile(const std::string& filename)
 {
-	LLAPRFile outfile ;
-	outfile.open(filename, LL_APR_W);
+	LLAPRFile outfile(filename, LL_APR_W);
 	apr_file_t* dot_file = outfile.getFileHandle() ;
 
 	if (!dot_file)
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index c755020a64e28f13c1f85b560b8a4ef2e3e69e27..60d4cfe6d30e1d0919df89d3b0900f6de4559128 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -31,6 +31,7 @@ set(llcommon_SOURCE_FILES
     llallocator_heap_profile.cpp
     llapp.cpp
     llapr.cpp
+    llaprpool.cpp
     llassettype.cpp
     llavatarname.cpp
     llbase32.cpp
@@ -80,6 +81,7 @@ set(llcommon_SOURCE_FILES
     llrand.cpp
     llrefcount.cpp
     llrun.cpp
+    llscopedvolatileaprpool.h
     llsd.cpp
     llsdserialize.cpp
     llsdserialize_xml.cpp
@@ -122,6 +124,7 @@ set(llcommon_HEADER_FILES
     llavatarname.h
     llapp.h
     llapr.h
+    llaprpool.h
     llassettype.h
     llassoclist.h
     llavatarconstants.h
@@ -319,6 +322,7 @@ if (LL_TESTS)
   LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}"
                           "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/setpython.py")
+  LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}")                          
   LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index ed192a9975125106a8ffafb4d1f72b84d59f0917..a8b7106078fb3fa32d9c839735464481ef890789 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -137,10 +137,6 @@ void LLApp::commonCtor()
 		mOptions.append(sd);
 	}
 
-	// Make sure we clean up APR when we exit
-	// Don't need to do this if we're cleaning up APR in the destructor
-	//atexit(ll_cleanup_apr);
-
 	// Set the application to this instance.
 	sApplication = this;
 	
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index d1c44c94032851a19a4ab42f20006ce04a1eb1f4..1e4a51102e782d282e49e63cdd51dc8fab697951 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -29,212 +29,8 @@
 #include "linden_common.h"
 #include "llapr.h"
 #include "apr_dso.h"
+#include "llscopedvolatileaprpool.h"
 
-apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
-LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
-apr_thread_mutex_t *gLogMutexp = NULL;
-apr_thread_mutex_t *gCallStacksLogMutexp = NULL;
-
-const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
-
-void ll_init_apr()
-{
-	if (!gAPRPoolp)
-	{
-		// Initialize APR and create the global pool
-		apr_initialize();
-		apr_pool_create(&gAPRPoolp, NULL);
-		
-		// Initialize the logging mutex
-		apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
-		apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
-	}
-
-	if(!LLAPRFile::sAPRFilePoolp)
-	{
-		LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;
-	}
-}
-
-
-void ll_cleanup_apr()
-{
-	LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
-
-	if (gLogMutexp)
-	{
-		// Clean up the logging mutex
-
-		// All other threads NEED to be done before we clean up APR, so this is okay.
-		apr_thread_mutex_destroy(gLogMutexp);
-		gLogMutexp = NULL;
-	}
-	if (gCallStacksLogMutexp)
-	{
-		// Clean up the logging mutex
-
-		// All other threads NEED to be done before we clean up APR, so this is okay.
-		apr_thread_mutex_destroy(gCallStacksLogMutexp);
-		gCallStacksLogMutexp = NULL;
-	}
-	if (gAPRPoolp)
-	{
-		apr_pool_destroy(gAPRPoolp);
-		gAPRPoolp = NULL;
-	}
-	if (LLAPRFile::sAPRFilePoolp)
-	{
-		delete LLAPRFile::sAPRFilePoolp ;
-		LLAPRFile::sAPRFilePoolp = NULL ;
-	}
-	apr_terminate();
-}
-
-//
-//
-//LLAPRPool
-//
-LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) 	
-	: mParent(parent),
-	mReleasePoolFlag(releasePoolFlag),
-	mMaxSize(size),
-	mPool(NULL)
-{	
-	createAPRPool() ;
-}
-
-LLAPRPool::~LLAPRPool() 
-{
-	releaseAPRPool() ;
-}
-
-void LLAPRPool::createAPRPool()
-{
-	if(mPool)
-	{
-		return ;
-	}
-
-	mStatus = apr_pool_create(&mPool, mParent);
-	ll_apr_warn_status(mStatus) ;
-
-	if(mMaxSize > 0) //size is the number of blocks (which is usually 4K), NOT bytes.
-	{
-		apr_allocator_t *allocator = apr_pool_allocator_get(mPool); 
-		if (allocator) 
-		{ 
-			apr_allocator_max_free_set(allocator, mMaxSize) ;
-		}
-	}
-}
-
-void LLAPRPool::releaseAPRPool()
-{
-	if(!mPool)
-	{
-		return ;
-	}
-
-	if(!mParent || mReleasePoolFlag)
-	{
-		apr_pool_destroy(mPool) ;
-		mPool = NULL ;
-	}
-}
-
-//virtual
-apr_pool_t* LLAPRPool::getAPRPool() 
-{	
-	return mPool ; 
-}
-
-LLVolatileAPRPool::LLVolatileAPRPool(BOOL is_local, apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) 
-				  : LLAPRPool(parent, size, releasePoolFlag),
-				  mNumActiveRef(0),
-				  mNumTotalRef(0),
-				  mMutexPool(NULL),
-				  mMutexp(NULL)
-{
-	//create mutex
-	if(!is_local) //not a local apr_pool, that is: shared by multiple threads.
-	{
-		apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex
-		apr_thread_mutex_create(&mMutexp, APR_THREAD_MUTEX_UNNESTED, mMutexPool);
-	}
-}
-
-LLVolatileAPRPool::~LLVolatileAPRPool()
-{
-	//delete mutex
-	if(mMutexp)
-	{
-		apr_thread_mutex_destroy(mMutexp);
-		apr_pool_destroy(mMutexPool);
-	}
-}
-
-//
-//define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool().
-//
-//virtual 
-apr_pool_t* LLVolatileAPRPool::getAPRPool() 
-{
-	return LLVolatileAPRPool::getVolatileAPRPool() ;
-}
-
-apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool() 
-{	
-	LLScopedLock lock(mMutexp) ;
-
-	mNumTotalRef++ ;
-	mNumActiveRef++ ;
-
-	if(!mPool)
-	{
-		createAPRPool() ;
-	}
-	
-	return mPool ;
-}
-
-void LLVolatileAPRPool::clearVolatileAPRPool() 
-{
-	LLScopedLock lock(mMutexp) ;
-
-	if(mNumActiveRef > 0)
-	{
-		mNumActiveRef--;
-		if(mNumActiveRef < 1)
-		{
-			if(isFull()) 
-			{
-				mNumTotalRef = 0 ;
-
-				//destroy the apr_pool.
-				releaseAPRPool() ;
-			}
-			else 
-			{
-				//This does not actually free the memory, 
-				//it just allows the pool to re-use this memory for the next allocation. 
-				apr_pool_clear(mPool) ;
-			}
-		}
-	}
-	else
-	{
-		llassert_always(mNumActiveRef > 0) ;
-	}
-
-	//paranoia check if the pool is jammed.
-	//will remove the check before going to release.
-	llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
-}
-
-BOOL LLVolatileAPRPool::isFull()
-{
-	return mNumTotalRef > FULL_VOLATILE_APR_POOL ;
-}
 //---------------------------------------------------------------------
 //
 // LLScopedLock
@@ -313,15 +109,17 @@ void ll_apr_assert_status(apr_status_t status, apr_dso_handle_t *handle)
 //
 LLAPRFile::LLAPRFile()
 	: mFile(NULL),
-	  mCurrentFilePoolp(NULL)
+	  mVolatileFilePoolp(NULL),
+	  mRegularFilePoolp(NULL)
 {
 }
 
-LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool)
+LLAPRFile::LLAPRFile(std::string const& filename, apr_int32_t flags, S32* sizep, access_t access_type)
 	: mFile(NULL),
-	  mCurrentFilePoolp(NULL)
+	  mVolatileFilePoolp(NULL),
+	  mRegularFilePoolp(NULL)
 {
-	open(filename, flags, pool);
+	open(filename, flags, access_type, sizep);
 }
 
 LLAPRFile::~LLAPRFile()
@@ -338,36 +136,58 @@ apr_status_t LLAPRFile::close()
 		mFile = NULL ;
 	}
 
-	if(mCurrentFilePoolp)
+	if (mVolatileFilePoolp)
 	{
-		mCurrentFilePoolp->clearVolatileAPRPool() ;
-		mCurrentFilePoolp = NULL ;
+		mVolatileFilePoolp->clearVolatileAPRPool() ;
+		mVolatileFilePoolp = NULL ;
+	}
+
+	if (mRegularFilePoolp)
+	{
+		delete mRegularFilePoolp;
+		mRegularFilePoolp = NULL;
 	}
 
 	return ret ;
 }
 
-apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool, S32* sizep)
+apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep)
 {
-	apr_status_t s ;
-
-	//check if already open some file
-	llassert_always(!mFile) ;
-	llassert_always(!mCurrentFilePoolp) ;
-	
-	apr_pool_t* apr_pool = pool ? pool->getVolatileAPRPool() : NULL ;
-	s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, getAPRFilePool(apr_pool));
+	llassert_always(!mFile);
+	llassert_always(!mVolatileFilePoolp && !mRegularFilePoolp);
 
-	if (s != APR_SUCCESS || !mFile)
+	apr_status_t status;
+	{
+		apr_pool_t* apr_file_open_pool;	// The use of apr_pool_t is OK here.
+										// This is a temporary variable for a pool that is passed directly to apr_file_open below.
+		if (access_type == short_lived)
+		{
+			// Use a "volatile" thread-local pool.
+			mVolatileFilePoolp = &LLThreadLocalData::tldata().mVolatileAPRPool;
+			// Access the pool and increment its reference count.
+			// The reference count of LLVolatileAPRPool objects will be decremented
+			// again in LLAPRFile::close by calling mVolatileFilePoolp->clearVolatileAPRPool().
+			apr_file_open_pool = mVolatileFilePoolp->getVolatileAPRPool();
+		}
+		else
+		{
+			mRegularFilePoolp = new LLAPRPool(LLThreadLocalData::tldata().mRootPool);
+			apr_file_open_pool = (*mRegularFilePoolp)();
+		}
+		status = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, apr_file_open_pool);
+	}
+	if (status != APR_SUCCESS || !mFile)
 	{
 		mFile = NULL ;
-		
+		close() ;
 		if (sizep)
 		{
 			*sizep = 0;
 		}
+		return status;
 	}
-	else if (sizep)
+
+	if (sizep)
 	{
 		S32 file_size = 0;
 		apr_off_t offset = 0;
@@ -381,49 +201,7 @@ apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, LLV
 		*sizep = file_size;
 	}
 
-	if(!mCurrentFilePoolp)
-	{
-		mCurrentFilePoolp = pool ;
-
-		if(!mFile)
-		{
-			close() ;
-		}
-	}
-
-	return s ;
-}
-
-//use gAPRPoolp.
-apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, BOOL use_global_pool)
-{
-	apr_status_t s;
-
-	//check if already open some file
-	llassert_always(!mFile) ;
-	llassert_always(!mCurrentFilePoolp) ;
-	llassert_always(use_global_pool) ; //be aware of using gAPRPoolp.
-	
-	s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, gAPRPoolp);
-	if (s != APR_SUCCESS || !mFile)
-	{
-		mFile = NULL ;
-		close() ;
-		return s;
-	}
-
-	return s;
-}
-
-apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool)
-{	
-	if(!pool)
-	{
-		mCurrentFilePoolp = sAPRFilePoolp ;
-		return mCurrentFilePoolp->getVolatileAPRPool() ;
-	}
-
-	return pool ;
+	return status;
 }
 
 // File I/O
@@ -481,45 +259,6 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset)
 //static components of LLAPRFile
 //
 
-//static
-apr_status_t LLAPRFile::close(apr_file_t* file_handle, LLVolatileAPRPool* pool) 
-{
-	apr_status_t ret = APR_SUCCESS ;
-	if(file_handle)
-	{
-		ret = apr_file_close(file_handle);
-		file_handle = NULL ;
-	}
-
-	if(pool)
-	{
-		pool->clearVolatileAPRPool() ;
-	}
-
-	return ret ;
-}
-
-//static
-apr_file_t* LLAPRFile::open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
-{
-	apr_status_t s;
-	apr_file_t* file_handle ;
-
-	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
-
-	s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool());
-	if (s != APR_SUCCESS || !file_handle)
-	{
-		ll_apr_warn_status(s);
-		LL_WARNS("APR") << " Attempting to open filename: " << filename << LL_ENDL;
-		file_handle = NULL ;
-		close(file_handle, pool) ;
-		return NULL;
-	}
-
-	return file_handle ;
-}
-
 //static
 S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
 {
@@ -553,13 +292,15 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
 }
 
 //static
-S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
+S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes)
 {
-	//*****************************************
-	apr_file_t* file_handle = open(filename, pool, APR_READ|APR_BINARY); 
-	//*****************************************	
-	if (!file_handle)
+	apr_file_t* file_handle;
+	LLScopedVolatileAPRPool pool;
+	apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool);
+	if (s != APR_SUCCESS || !file_handle)
 	{
+		ll_apr_warn_status(s);
+		LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL;
 		return 0;
 	}
 
@@ -589,14 +330,13 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb
 		}
 	}
 	
-	//*****************************************
-	close(file_handle, pool) ; 
-	//*****************************************
+	apr_file_close(file_handle);
+
 	return (S32)bytes_read;
 }
 
 //static
-S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
+S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes)
 {
 	apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
 	if (offset < 0)
@@ -605,11 +345,13 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n
 		offset = 0;
 	}
 	
-	//*****************************************
-	apr_file_t* file_handle = open(filename, pool, flags);
-	//*****************************************
-	if (!file_handle)
+	apr_file_t* file_handle;
+	LLScopedVolatileAPRPool pool;
+	apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool);
+	if (s != APR_SUCCESS || !file_handle)
 	{
+		ll_apr_warn_status(s);
+		LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL;
 		return 0;
 	}
 
@@ -639,21 +381,18 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n
 		}
 	}
 
-	//*****************************************
-	LLAPRFile::close(file_handle, pool);
-	//*****************************************
+	apr_file_close(file_handle);
 
 	return (S32)bytes_written;
 }
 
 //static
-bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)
+bool LLAPRFile::remove(const std::string& filename)
 {
 	apr_status_t s;
 
-	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
-	s = apr_file_remove(filename.c_str(), pool->getVolatileAPRPool());
-	pool->clearVolatileAPRPool() ;
+	LLScopedVolatileAPRPool pool;
+	s = apr_file_remove(filename.c_str(), pool);
 
 	if (s != APR_SUCCESS)
 	{
@@ -665,13 +404,12 @@ bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)
 }
 
 //static
-bool LLAPRFile::rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool)
+bool LLAPRFile::rename(const std::string& filename, const std::string& newname)
 {
 	apr_status_t s;
 
-	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
-	s = apr_file_rename(filename.c_str(), newname.c_str(), pool->getVolatileAPRPool());
-	pool->clearVolatileAPRPool() ;
+	LLScopedVolatileAPRPool pool;
+	s = apr_file_rename(filename.c_str(), newname.c_str(), pool);
 	
 	if (s != APR_SUCCESS)
 	{
@@ -683,49 +421,44 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname,
 }
 
 //static
-bool LLAPRFile::isExist(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
+bool LLAPRFile::isExist(const std::string& filename, apr_int32_t flags)
 {
-	apr_file_t* apr_file;
+	apr_file_t* file_handle;
 	apr_status_t s;
 
-	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
-	s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool());	
+	LLScopedVolatileAPRPool pool;
+	s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool);
 
-	if (s != APR_SUCCESS || !apr_file)
+	if (s != APR_SUCCESS || !file_handle)
 	{
-		pool->clearVolatileAPRPool() ;
 		return false;
 	}
 	else
 	{
-		apr_file_close(apr_file) ;
-		pool->clearVolatileAPRPool() ;
+		apr_file_close(file_handle);
 		return true;
 	}
 }
 
 //static
-S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool)
+S32 LLAPRFile::size(const std::string& filename)
 {
-	apr_file_t* apr_file;
+	apr_file_t* file_handle;
 	apr_finfo_t info;
 	apr_status_t s;
 	
-	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
-	s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool->getVolatileAPRPool());
+	LLScopedVolatileAPRPool pool;
+	s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool);
 	
-	if (s != APR_SUCCESS || !apr_file)
+	if (s != APR_SUCCESS || !file_handle)
 	{		
-		pool->clearVolatileAPRPool() ;
-		
 		return 0;
 	}
 	else
 	{
-		apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);		
+		apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, file_handle);
 
-		apr_file_close(apr_file) ;
-		pool->clearVolatileAPRPool() ;
+		apr_file_close(file_handle) ;
 		
 		if (s == APR_SUCCESS)
 		{
@@ -739,31 +472,29 @@ S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool)
 }
 
 //static
-bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool)
+bool LLAPRFile::makeDir(const std::string& dirname)
 {
 	apr_status_t s;
 
-	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
-	s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool->getVolatileAPRPool());
-	pool->clearVolatileAPRPool() ;
+	LLScopedVolatileAPRPool pool;
+	s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool);
 		
 	if (s != APR_SUCCESS)
 	{
 		ll_apr_warn_status(s);
-		LL_WARNS("APR") << " Attempting to make directory: " << dirname << LL_ENDL;
+		LL_WARNS("APR") << " while attempting to make directory: " << dirname << LL_ENDL;
 		return false;
 	}
 	return true;
 }
 
 //static
-bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool)
+bool LLAPRFile::removeDir(const std::string& dirname)
 {
 	apr_status_t s;
 
-	pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
-	s = apr_file_remove(dirname.c_str(), pool->getVolatileAPRPool());
-	pool->clearVolatileAPRPool() ;
+	LLScopedVolatileAPRPool pool;
+	s = apr_file_remove(dirname.c_str(), pool);
 	
 	if (s != APR_SUCCESS)
 	{
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index af33ce666f1558193d3d2818cf0c3a5e98d6ee7a..3f846f13145034e0d26c33b5f50a09064ddff737 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -50,71 +50,9 @@
 #include "apr_atomic.h"
 #include "llstring.h"
 
-extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
-extern apr_thread_mutex_t* gCallStacksLogMutexp;
-
 struct apr_dso_handle_t;
-
-/** 
- * @brief initialize the common apr constructs -- apr itself, the
- * global pool, and a mutex.
- */
-void LL_COMMON_API ll_init_apr();
-
-/** 
- * @brief Cleanup those common apr constructs.
- */
-void LL_COMMON_API ll_cleanup_apr();
-
-//
-//LL apr_pool
-//manage apr_pool_t, destroy allocated apr_pool in the destruction function.
-//
-class LL_COMMON_API LLAPRPool
-{
-public:
-	LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ;
-	virtual ~LLAPRPool() ;
-
-	virtual apr_pool_t* getAPRPool() ;
-	apr_status_t getStatus() {return mStatus ; }
-
-protected:
-	void releaseAPRPool() ;
-	void createAPRPool() ;
-
-protected:
-	apr_pool_t*  mPool ;              //pointing to an apr_pool
-	apr_pool_t*  mParent ;			  //parent pool
-	apr_size_t   mMaxSize ;           //max size of mPool, mPool should return memory to system if allocated memory beyond this limit. However it seems not to work.
-	apr_status_t mStatus ;            //status when creating the pool
-	BOOL         mReleasePoolFlag ;   //if set, mPool is destroyed when LLAPRPool is deleted. default value is true.
-};
-
-//
-//volatile LL apr_pool
-//which clears memory automatically.
-//so it can not hold static data or data after memory is cleared
-//
-class LL_COMMON_API LLVolatileAPRPool : public LLAPRPool
-{
-public:
-	LLVolatileAPRPool(BOOL is_local = TRUE, apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE);
-	virtual ~LLVolatileAPRPool();
-
-	/*virtual*/ apr_pool_t* getAPRPool() ; //define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool().
-	apr_pool_t* getVolatileAPRPool() ;	
-	void        clearVolatileAPRPool() ;
-
-	BOOL        isFull() ;
-	
-private:
-	S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool.
-	S32 mNumTotalRef ;  //number of total pointers pointing to the apr_pool since last creating.  
-
-	apr_thread_mutex_t *mMutexp;
-	apr_pool_t         *mMutexPool;
-} ;
+class LLAPRPool;
+class LLVolatileAPRPool;
 
 /** 
  * @class LLScopedLock
@@ -205,15 +143,20 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable
 	// make this non copyable since a copy closes the file
 private:
 	apr_file_t* mFile ;
-	LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool. 
+	LLVolatileAPRPool* mVolatileFilePoolp;	// (Thread local) APR pool currently in use.
+	LLAPRPool* mRegularFilePoolp;		// ...or a regular pool.
 
 public:
+	enum access_t {
+		long_lived,		// Use a global pool for long-lived file accesses.
+		short_lived		// Use a volatile pool for short-lived file accesses.
+	};
+
 	LLAPRFile() ;
-	LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL);
+	LLAPRFile(std::string const& filename, apr_int32_t flags, S32* sizep = NULL, access_t access_type = short_lived);
 	~LLAPRFile() ;
-	
-	apr_status_t open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL, S32* sizep = NULL);
-	apr_status_t open(const std::string& filename, apr_int32_t flags, BOOL use_global_pool); //use gAPRPoolp.
+
+	apr_status_t open(const std::string& filename, apr_int32_t flags, access_t access_type, S32* sizep = NULL);
 	apr_status_t close() ;
 
 	// Returns actual offset, -1 if seek fails
@@ -226,32 +169,24 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable
 	
 	apr_file_t* getFileHandle() {return mFile;}	
 
-private:
-	apr_pool_t* getAPRFilePool(apr_pool_t* pool) ;	
-	
 //
 //*******************************************************************************************************************************
 //static components
 //
-public:
-	static LLVolatileAPRPool *sAPRFilePoolp ; //a global apr_pool for APRFile, which is used only when local pool does not exist.
-
 private:
-	static apr_file_t* open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags);
-	static apr_status_t close(apr_file_t* file, LLVolatileAPRPool* pool) ;
 	static S32 seek(apr_file_t* file, apr_seek_where_t where, S32 offset);
 public:
 	// returns false if failure:
-	static bool remove(const std::string& filename, LLVolatileAPRPool* pool = NULL);
-	static bool rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool = NULL);
-	static bool isExist(const std::string& filename, LLVolatileAPRPool* pool = NULL, apr_int32_t flags = APR_READ);
-	static S32 size(const std::string& filename, LLVolatileAPRPool* pool = NULL);
-	static bool makeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
-	static bool removeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
+	static bool remove(const std::string& filename);
+	static bool rename(const std::string& filename, const std::string& newname);
+	static bool isExist(const std::string& filename, apr_int32_t flags = APR_READ);
+	static S32 size(const std::string& filename);
+	static bool makeDir(const std::string& dirname);
+	static bool removeDir(const std::string& dirname);
 
 	// Returns bytes read/written, 0 if read/write fails:
-	static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);	
-	static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL); // offset<0 means append
+	static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes);	
+	static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes); // offset<0 means append
 //*******************************************************************************************************************************
 };
 
@@ -267,6 +202,4 @@ bool LL_COMMON_API ll_apr_warn_status(apr_status_t status, apr_dso_handle_t* han
 void LL_COMMON_API ll_apr_assert_status(apr_status_t status);
 void LL_COMMON_API ll_apr_assert_status(apr_status_t status, apr_dso_handle_t* handle);
 
-extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool
-
 #endif // LL_LLAPR_H
diff --git a/indra/llcommon/llaprpool.cpp b/indra/llcommon/llaprpool.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6f21b61b65e23df52654d4e3dd70a43828c4cc0d
--- /dev/null
+++ b/indra/llcommon/llaprpool.cpp
@@ -0,0 +1,202 @@
+/**
+ * @file llaprpool.cpp
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ *
+ * CHANGELOG
+ *   and additional copyright holders.
+ *
+ *   04/04/2010
+ *   - Initial version, written by Aleric Inglewood @ SL
+ *
+ *   10/11/2010
+ *   - Added APR_HAS_THREADS #if's to allow creation and destruction
+ *     of subpools by threads other than the parent pool owner.
+ */
+
+#include "linden_common.h"
+
+#include "llerror.h"
+#include "llaprpool.h"
+#include "llthread.h"
+
+// Create a subpool from parent.
+void LLAPRPool::create(LLAPRPool& parent)
+{
+	llassert(!mPool);			// Must be non-initialized.
+	mParent = &parent;
+	if (!mParent)				// Using the default parameter?
+	{
+		// By default use the root pool of the current thread.
+		mParent = &LLThreadLocalData::tldata().mRootPool;
+	}
+	llassert(mParent->mPool);	// Parent must be initialized.
+#if APR_HAS_THREADS
+	// As per the documentation of APR (ie http://apr.apache.org/docs/apr/1.4/apr__pools_8h.html):
+	//
+	// Note that most operations on pools are not thread-safe: a single pool should only be
+	// accessed by a single thread at any given time. The one exception to this rule is creating
+	// a subpool of a given pool: one or more threads can safely create subpools at the same
+	// time that another thread accesses the parent pool.
+	//
+	// In other words, it's safe for any thread to create a (sub)pool, independent of who
+	// owns the parent pool.
+	mOwner = apr_os_thread_current();
+#else
+	mOwner = mParent->mOwner;
+	llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+#endif
+	apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool);
+	llassert_always(apr_pool_create_status == APR_SUCCESS);
+	llassert(mPool);			// Initialized.
+	apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null);
+}
+
+// Destroy the (sub)pool, if any.
+void LLAPRPool::destroy(void)
+{
+	// Only do anything if we are not already (being) destroyed.
+	if (mPool)
+	{
+#if !APR_HAS_THREADS
+		// If we are a root pool, then every thread may destruct us: in that case
+		// we have to assume that no other thread will use this pool concurrently,
+		// of course. Otherwise, if we are a subpool, only the thread that owns
+		// the parent may destruct us, since that is the pool that is still alive,
+		// possibly being used by others and being altered here.
+		llassert(!mParent || apr_os_thread_equal(mParent->mOwner, apr_os_thread_current()));
+#endif
+		apr_pool_t* pool = mPool;	// The use of apr_pool_t is OK here.
+									// Temporary store before destroying the pool.
+		mPool = NULL;				// Mark that we are BEING destructed.
+		apr_pool_cleanup_kill(pool, this, &s_plain_cleanup);
+		apr_pool_destroy(pool);
+	}
+}
+
+bool LLAPRPool::parent_is_being_destructed(void)
+{
+	return mParent && (!mParent->mPool || mParent->parent_is_being_destructed());
+}
+
+LLAPRInitialization::LLAPRInitialization(void)
+{
+	static bool apr_initialized = false;
+
+	if (!apr_initialized)
+	{
+		apr_initialize();
+	}
+
+	apr_initialized = true;
+}
+
+bool LLAPRRootPool::sCountInitialized = false;
+apr_uint32_t volatile LLAPRRootPool::sCount;
+
+apr_thread_mutex_t* gLogMutexp;
+apr_thread_mutex_t* gCallStacksLogMutexp;
+
+LLAPRRootPool::LLAPRRootPool(void) : LLAPRInitialization(), LLAPRPool(0)
+{
+	// sCountInitialized don't need locking because when we get here there is still only a single thread.
+	if (!sCountInitialized)
+	{
+		// Initialize the logging mutex
+		apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool);
+		apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool);
+
+		apr_status_t status = apr_atomic_init(mPool);
+		llassert_always(status == APR_SUCCESS);
+		apr_atomic_set32(&sCount, 1);	// Set to 1 to account for the global root pool.
+		sCountInitialized = true;
+
+		// Initialize thread-local APR pool support.
+		// Because this recursively calls LLAPRRootPool::LLAPRRootPool(void)
+		// it must be done last, so that sCount is already initialized.
+		LLThreadLocalData::init();
+	}
+	apr_atomic_inc32(&sCount);
+}
+
+LLAPRRootPool::~LLAPRRootPool()
+{
+	if (!apr_atomic_dec32(&sCount))
+	{
+		// The last pool was destructed. Cleanup remainder of APR.
+		LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
+
+		if (gLogMutexp)
+		{
+			// Clean up the logging mutex
+
+			// All other threads NEED to be done before we clean up APR, so this is okay.
+			apr_thread_mutex_destroy(gLogMutexp);
+			gLogMutexp = NULL;
+		}
+		if (gCallStacksLogMutexp)
+		{
+			// Clean up the logging mutex
+
+			// All other threads NEED to be done before we clean up APR, so this is okay.
+			apr_thread_mutex_destroy(gCallStacksLogMutexp);
+			gCallStacksLogMutexp = NULL;
+		}
+
+		// Must destroy ALL, and therefore this last LLAPRRootPool, before terminating APR.
+		static_cast<LLAPRRootPool*>(this)->destroy();
+
+		apr_terminate();
+	}
+}
+
+//static
+// Return a global root pool that is independent of LLThreadLocalData.
+// Normally you should NOT use this. Only use for early initialization
+// (before main) and deinitialization (after main).
+LLAPRRootPool& LLAPRRootPool::get(void)
+{
+  static LLAPRRootPool global_APRpool(0);
+  return global_APRpool;
+}
+
+void LLVolatileAPRPool::clearVolatileAPRPool()
+{
+	llassert_always(mNumActiveRef > 0);
+	if (--mNumActiveRef == 0)
+	{
+		if (isOld())
+		{
+			destroy();
+			mNumTotalRef = 0 ;
+		}
+		else
+		{
+			// This does not actually free the memory,
+			// it just allows the pool to re-use this memory for the next allocation.
+			clear();
+		}
+	}
+
+	// Paranoia check if the pool is jammed.
+	llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
+}
diff --git a/indra/llcommon/llaprpool.h b/indra/llcommon/llaprpool.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf4102c5849e98f1e78095ee22131b8263d5b744
--- /dev/null
+++ b/indra/llcommon/llaprpool.h
@@ -0,0 +1,256 @@
+/**
+ * @file llaprpool.h
+ * @brief Implementation of LLAPRPool
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ *
+ * CHANGELOG
+ *   and additional copyright holders.
+ *
+ *   04/04/2010
+ *   - Initial version, written by Aleric Inglewood @ SL
+ *
+ *   10/11/2010
+ *   - Added APR_HAS_THREADS #if's to allow creation and destruction
+ *     of subpools by threads other than the parent pool owner.
+ *
+ *   05/02/2011
+ *   - Fixed compilation on windows: Suppress compile warning 4996
+ *     and include <winsock2.h> before including <ws2tcpip.h>,
+ *     by Merov Linden @ SL.
+ */
+
+#ifndef LL_LLAPRPOOL_H
+#define LL_LLAPRPOOL_H
+
+#ifdef LL_WINDOWS
+#pragma warning(push)
+#pragma warning(disable:4996)
+#include <winsock2.h>
+#include <ws2tcpip.h>		// Needed before including apr_portable.h
+#pragma warning(pop)
+#endif
+
+#include "apr_portable.h"
+#include "apr_pools.h"
+#include "llerror.h"
+
+extern void ll_init_apr();
+
+/**
+ * @brief A wrapper around the APR memory pool API.
+ *
+ * Usage of this class should be restricted to passing it to libapr-1 function calls that need it.
+ *
+ */
+class LL_COMMON_API LLAPRPool
+{
+protected:
+	//! Pointer to the underlaying pool. NULL if not initialized.
+	apr_pool_t* mPool;		// The use of apr_pool_t is OK here.
+							// This is the wrapped pointer that it is all about!
+	//! Pointer to the parent pool, if any. Only valid when mPool is non-zero.
+	LLAPRPool* mParent;
+	//! The thread that owns this memory pool. Only valid when mPool is non-zero.
+	apr_os_thread_t mOwner;
+
+public:
+	/// Construct an uninitialized (destructed) pool.
+	LLAPRPool(void) : mPool(NULL) { }
+
+	/// Construct a subpool from an existing pool.
+	/// This is not a copy-constructor, this class doesn't have one!
+	LLAPRPool(LLAPRPool& parent) : mPool(NULL) { create(parent); }
+
+	/// Destruct the memory pool (free all of its subpools and allocated memory).
+	~LLAPRPool() { destroy(); }
+
+protected:
+	/// Create a pool that is allocated from the Operating System. Only used by LLAPRRootPool.
+	LLAPRPool(int) : mPool(NULL), mParent(NULL), mOwner(apr_os_thread_current())
+	{
+		apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, NULL);
+		llassert_always(apr_pool_create_status == APR_SUCCESS);
+		llassert(mPool);
+		apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null);
+	}
+
+public:
+	/// Create a subpool from parent. May only be called for an uninitialized/destroyed pool.
+	/// The default parameter causes the root pool of the current thread to be used.
+	void create(LLAPRPool& parent = *static_cast<LLAPRPool*>(NULL));
+
+	/// Destroy the (sub)pool, if any.
+	void destroy(void);
+
+	// Use some safebool idiom (http://www.artima.com/cppsource/safebool.html) rather than operator bool.
+	typedef LLAPRPool* const LLAPRPool::* const bool_type;
+	/// Return true if the pool is initialized.
+	operator bool_type() const { return mPool ? &LLAPRPool::mParent : 0; }
+
+	/// Painful, but we have to either provide access to this, or wrap
+	/// every APR function call that needs an apr pool as argument.
+	/// NEVER destroy a pool that is returned by this function!
+	apr_pool_t* operator()(void) const		// The use of apr_pool_t is OK here.
+	  										// This is the accessor for passing the pool to libapr-1 functions.
+	{
+		llassert(mPool);
+		llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+		return mPool;
+	}
+
+	/// Free all memory without destructing the pool.
+	void clear(void)
+	{
+		llassert(mPool);
+		llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+		apr_pool_clear(mPool);
+	}
+
+// These methods would make this class 'complete' (as wrapper around the libapr
+// pool functions), but we don't use memory pools in the viewer (only when
+// we are forced to pass one to a libapr call), so don't define them in order
+// not to encourage people to use them.
+#if 0
+	void* palloc(size_t size)
+	{
+		llassert(mPool);
+		llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+		return apr_palloc(mPool, size);
+	}
+	void* pcalloc(size_t size)
+	{
+		llassert(mPool);
+		llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+		return apr_pcalloc(mPool, size);
+	}
+#endif
+
+private:
+	bool parent_is_being_destructed(void);
+	static apr_status_t s_plain_cleanup(void* userdata) { return static_cast<LLAPRPool*>(userdata)->plain_cleanup(); }
+
+	apr_status_t plain_cleanup(void)
+	{
+		if (mPool && 						// We are not being destructed,
+			parent_is_being_destructed())	// but our parent is.
+		  // This means the pool is being destructed recursively by libapr
+		  // because one of its parents is being destructed.
+		{
+			mPool = NULL;	// Stop destroy() from destructing the pool again.
+		}
+		return APR_SUCCESS;
+	}
+};
+
+class LLAPRInitialization
+{
+public:
+	LLAPRInitialization(void);
+};
+
+/**
+ * @brief Root memory pool (allocates memory from the operating system).
+ *
+ * This class should only be used by LLThreadLocalData
+ * (and LLMutexRootPool when APR_HAS_THREADS isn't defined).
+ */
+class LL_COMMON_API LLAPRRootPool : public LLAPRInitialization, public LLAPRPool
+{
+private:
+	/// Construct a root memory pool. Should only be used by LLThreadLocalData and LLMutexRootPool.
+	friend class LLThreadLocalData;
+#if !APR_HAS_THREADS
+	friend class LLMutexRootPool;
+#endif
+	/// Construct a root memory pool.
+	/// Should only be used by LLThreadLocalData.
+	LLAPRRootPool(void);
+	~LLAPRRootPool();
+
+private:
+	// Keep track of how many root pools exist and when the last one is destructed.
+	static bool sCountInitialized;
+	static apr_uint32_t volatile sCount;
+
+public:
+	// Return a global root pool that is independent of LLThreadLocalData.
+	// Normally you should not use this. Only use for early initialization
+	// (before main) and deinitialization (after main).
+	static LLAPRRootPool& get(void);
+
+#if APR_POOL_DEBUG
+	void grab_ownership(void)
+	{
+		// You need a patched libapr to use this.
+		// See http://web.archiveorange.com/archive/v/5XO9y2zoxUOMt6Gmi1OI
+		apr_pool_owner_set(mPool);
+	}
+#endif
+
+private:
+	// Used for constructing the Special Global Root Pool (returned by LLAPRRootPool::get).
+	// It is the same as the default constructor but omits to increment sCount. As a result,
+	// we must be sure that at least one other LLAPRRootPool is created before termination
+	// of the application (which is the case: we create one LLAPRRootPool per thread).
+	LLAPRRootPool(int) : LLAPRInitialization(), LLAPRPool(0) { }
+};
+
+/** Volatile memory pool
+ *
+ * 'Volatile' APR memory pool which normally only clears memory,
+ * and does not destroy the pool (the same pool is reused) for
+ * greater efficiency. However, as a safe guard the apr pool
+ * is destructed every FULL_VOLATILE_APR_POOL uses to allow
+ * the system memory to be allocated more efficiently and not
+ * get scattered through RAM.
+ */
+class LL_COMMON_API LLVolatileAPRPool : protected LLAPRPool
+{
+public:
+	LLVolatileAPRPool(void) : mNumActiveRef(0), mNumTotalRef(0) { }
+
+	void clearVolatileAPRPool(void);
+
+	bool isOld(void) const { return mNumTotalRef > FULL_VOLATILE_APR_POOL; }
+	bool isUnused() const { return mNumActiveRef == 0; }
+
+private:
+	friend class LLScopedVolatileAPRPool;
+	friend class LLAPRFile;
+	apr_pool_t* getVolatileAPRPool(void)	// The use of apr_pool_t is OK here.
+	{
+		if (!mPool) create();
+		++mNumActiveRef;
+		++mNumTotalRef;
+		return LLAPRPool::operator()();
+	}
+
+private:
+	S32 mNumActiveRef;	// Number of active uses of the pool.
+	S32 mNumTotalRef;	// Number of total uses of the pool since last creation.
+
+	// Maximum number of references to LLVolatileAPRPool until the pool is recreated.
+	static S32 const FULL_VOLATILE_APR_POOL = 1024;
+};
+
+#endif // LL_LLAPRPOOL_H
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 8be9e4f4de28ef135295efef826e5eb4608e1373..b8a739485250f74f4f70285bc12a7f779cc0d1df 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -30,18 +30,10 @@
 #include "llmemory.h"
 #include "llthread.h"
 
-//static
-BOOL LLCommon::sAprInitialized = FALSE;
-
 //static
 void LLCommon::initClass()
 {
 	LLMemory::initClass();
-	if (!sAprInitialized)
-	{
-		ll_init_apr();
-		sAprInitialized = TRUE;
-	}
 	LLTimer::initClass();
 	LLThreadSafeRefCount::initThreadSafeRefCount();
 // 	LLWorkerThread::initClass();
@@ -55,10 +47,5 @@ void LLCommon::cleanupClass()
 // 	LLWorkerThread::cleanupClass();
 	LLThreadSafeRefCount::cleanupThreadSafeRefCount();
 	LLTimer::cleanupClass();
-	if (sAprInitialized)
-	{
-		ll_cleanup_apr();
-		sAprInitialized = FALSE;
-	}
 	LLMemory::cleanupClass();
 }
diff --git a/indra/llcommon/llcommon.h b/indra/llcommon/llcommon.h
index ca9cad5d05ed9d8a744cd68a9c59c9d000bc2e6b..171590f3d807ba667457c4533e6c8e6037780f70 100644
--- a/indra/llcommon/llcommon.h
+++ b/indra/llcommon/llcommon.h
@@ -35,8 +35,6 @@ class LL_COMMON_API LLCommon
 public:
 	static void initClass();
 	static void cleanupClass();
-private:
-	static BOOL sAprInitialized;
 };
 
 #endif
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index c35799bbb91761845f1ca616a1c3e87ffefdc7a6..bda9d7c177467ca8d4e5fd0a9676d0929740c7b6 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -866,6 +866,9 @@ You get:
 	
 */
 
+extern apr_thread_mutex_t* gLogMutexp;
+extern apr_thread_mutex_t* gCallStacksLogMutexp;
+
 namespace {
 	bool checkLevelMap(const LevelMap& map, const std::string& key,
 						LLError::ELevel& level)
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index b3e604f8e83f177c6a2285c524fea201b7e30bbb..369f2a7a97a7d8e2b976f9d9583a02e072519b43 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -296,5 +296,4 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
 		Such computation is done iff the message will be logged.
 	*/
 
-
 #endif // LL_LLERROR_H
diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp
index ebb5961c91f266ef81ec011e7a4e53e5a48722ad..463f558c2c3c42fe025b8503ca3ae0ea07af4acd 100644
--- a/indra/llcommon/llfasttimer_class.cpp
+++ b/indra/llcommon/llfasttimer_class.cpp
@@ -303,14 +303,15 @@ LLFastTimer::NamedTimer::~NamedTimer()
 
 std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx)
 {
+	F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond();
 	if (history_idx < 0)
 	{
-		// by default, show average number of calls
-		return llformat("%s (%d calls)", getName().c_str(), (S32)getCallAverage());
+		// by default, show average number of call
+		return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getCountAverage() * ms_multiplier), (S32)getCallAverage());
 	}
 	else
 	{
-		return llformat("%s (%d calls)", getName().c_str(), (S32)getHistoricalCalls(history_idx));
+		return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getHistoricalCount(history_idx) * ms_multiplier), (S32)getHistoricalCalls(history_idx));
 	}
 }
 
@@ -693,17 +694,7 @@ void LLFastTimer::nextFrame()
 		llinfos << "Slow frame, fast timers inaccurate" << llendl;
 	}
 
-	if (sPauseHistory)
-	{
-		sResetHistory = true;
-	}
-	else if (sResetHistory)
-	{
-		sLastFrameIndex = 0;
-		sCurFrameIndex = 0;
-		sResetHistory = false;
-	}
-	else // not paused
+	if (!sPauseHistory)
 	{
 		NamedTimer::processTimes();
 		sLastFrameIndex = sCurFrameIndex++;
diff --git a/indra/llcommon/llfasttimer_class.h b/indra/llcommon/llfasttimer_class.h
index 827747f0c686fc87f6cc56776a7cd741f156608e..f481e968a6badaea8dba11a83eed24fc1dc6bfc1 100644
--- a/indra/llcommon/llfasttimer_class.h
+++ b/indra/llcommon/llfasttimer_class.h
@@ -66,7 +66,7 @@ class LL_COMMON_API LLFastTimer
 	public:
 		~NamedTimer();
 
-		enum { HISTORY_NUM = 60 };
+		enum { HISTORY_NUM = 300 };
 
 		const std::string& getName() const { return mName; }
 		NamedTimer* getParent() const { return mParent; }
diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp
index d394f179fb52fd674854f724c9fd2721f00ec567..4b5cdbe28859dccd6c84d30e90f96133138b5696 100644
--- a/indra/llcommon/llfixedbuffer.cpp
+++ b/indra/llcommon/llfixedbuffer.cpp
@@ -30,8 +30,7 @@
 
 LLFixedBuffer::LLFixedBuffer(const U32 max_lines)
 	: LLLineBuffer(),
-	  mMaxLines(max_lines),
-	  mMutex(NULL)
+	  mMaxLines(max_lines)
 {
 	mTimer.reset();
 }
diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index f57620451117ab40509dae0ef013d8eaf41c6f68..5dc3ea5d7bc751bfe0cefbfa25419eb50470e937 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -35,14 +35,15 @@
 //static 
 void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
 {
-	static std::map<std::string, void *> instances;
+	typedef std::map<std::string, void *> InstancesMap;
+	static InstancesMap instances;
 
-	std::string k = info.name();
-	if(instances.find(k) == instances.end())
-	{
-		instances[k] = NULL;
-	}
-
-	return instances[k];
+	// std::map::insert() is just what we want here. You attempt to insert a
+	// (key, value) pair. If the specified key doesn't yet exist, it inserts
+	// the pair and returns a std::pair of (iterator, true). If the specified
+	// key DOES exist, insert() simply returns (iterator, false). One lookup
+	// handles both cases.
+	return instances.insert(InstancesMap::value_type(info.name(),
+													 InstancesMap::mapped_type()))
+		.first->second;
 }
-
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index afb714c71c5882ed742c5b6aa7b8aca1da3da80c..5a3990a8df58d8dcf4f40069af59f31cefc80452 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -29,6 +29,7 @@
 #define LL_LLINSTANCETRACKER_H
 
 #include <map>
+#include <typeinfo>
 
 #include "string_table.h"
 #include <boost/utility.hpp>
@@ -37,10 +38,40 @@
 #include <boost/iterator/transform_iterator.hpp>
 #include <boost/iterator/indirect_iterator.hpp>
 
+/**
+ * Base class manages "class-static" data that must actually have singleton
+ * semantics: one instance per process, rather than one instance per module as
+ * sometimes happens with data simply declared static.
+ */
 class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
 {
-	protected:
-		static void * & getInstances(std::type_info const & info);
+protected:
+	/// Get a process-unique void* pointer slot for the specified type_info
+	static void * & getInstances(std::type_info const & info);
+
+	/// Find or create a STATICDATA instance for the specified TRACKED class.
+	/// STATICDATA must be default-constructible.
+	template<typename STATICDATA, class TRACKED>
+	static STATICDATA& getStatic()
+	{
+		void *& instances = getInstances(typeid(TRACKED));
+		if (! instances)
+		{
+			instances = new STATICDATA;
+		}
+		return *static_cast<STATICDATA*>(instances);
+	}
+
+    /// It's not essential to derive your STATICDATA (for use with
+    /// getStatic()) from StaticBase; it's just that both known
+    /// implementations do.
+    struct StaticBase
+    {
+        StaticBase():
+            sIterationNestDepth(0)
+        {}
+        S32 sIterationNestDepth;
+    };
 };
 
 /// This mix-in class adds support for tracking all instances of the specified class parameter T
@@ -50,8 +81,15 @@ class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
 template<typename T, typename KEY = T*>
 class LLInstanceTracker : public LLInstanceTrackerBase
 {
-	typedef typename std::map<KEY, T*> InstanceMap;
 	typedef LLInstanceTracker<T, KEY> MyT;
+	typedef typename std::map<KEY, T*> InstanceMap;
+	struct StaticData: public StaticBase
+	{
+		InstanceMap sMap;
+	};
+	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+	static InstanceMap& getMap_() { return getStatic().sMap; }
+
 public:
 	class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
 	{
@@ -61,12 +99,12 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 		instance_iter(const typename InstanceMap::iterator& it)
 		:	mIterator(it)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		~instance_iter()
 		{
-			--sIterationNestDepth;
+			--getStatic().sIterationNestDepth;
 		}
 
 
@@ -95,18 +133,18 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 		key_iter(typename InstanceMap::iterator it)
 			:	mIterator(it)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		key_iter(const key_iter& other)
 			:	mIterator(other.mIterator)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		~key_iter()
 		{
-			--sIterationNestDepth;
+			--getStatic().sIterationNestDepth;
 		}
 
 
@@ -159,8 +197,8 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 	virtual ~LLInstanceTracker() 
 	{ 
 		// it's unsafe to delete instances of this type while all instances are being iterated over.
-		llassert(sIterationNestDepth == 0);
-		remove_(); 		
+		llassert_always(getStatic().sIterationNestDepth == 0);
+		remove_();		
 	}
 	virtual void setKey(KEY key) { remove_(); add_(key); }
 	virtual const KEY& getKey() const { return mInstanceKey; }
@@ -176,31 +214,24 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 		getMap_().erase(mInstanceKey);
 	}
 
-    static InstanceMap& getMap_()
-    {
-		void * & instances = getInstances(typeid(MyT));
-        if (! instances)
-        {
-            instances = new InstanceMap;
-        }
-        return * static_cast<InstanceMap*>(instances);
-    }
-
 private:
-
 	KEY mInstanceKey;
-	static S32 sIterationNestDepth;
 };
 
-template <typename T, typename KEY> S32 LLInstanceTracker<T, KEY>::sIterationNestDepth = 0;
-
 /// explicit specialization for default case where KEY is T*
 /// use a simple std::set<T*>
 template<typename T>
 class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
 {
-	typedef typename std::set<T*> InstanceSet;
 	typedef LLInstanceTracker<T, T*> MyT;
+	typedef typename std::set<T*> InstanceSet;
+	struct StaticData: public StaticBase
+	{
+		InstanceSet sSet;
+	};
+	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+	static InstanceSet& getSet_() { return getStatic().sSet; }
+
 public:
 
 	/// for completeness of analogy with the generic implementation
@@ -213,18 +244,18 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
 		instance_iter(const typename InstanceSet::iterator& it)
 		:	mIterator(it)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		instance_iter(const instance_iter& other)
 		:	mIterator(other.mIterator)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		~instance_iter()
 		{
-			--sIterationNestDepth;
+			--getStatic().sIterationNestDepth;
 		}
 
 	private:
@@ -250,13 +281,13 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
 protected:
 	LLInstanceTracker()
 	{
-		// it's safe but unpredictable to create instances of this type while all instances are being iterated over.  I hate unpredictable.  This assert will probably be turned on early in the next development cycle.
+		// it's safe but unpredictable to create instances of this type while all instances are being iterated over.  I hate unpredictable.	 This assert will probably be turned on early in the next development cycle.
 		getSet_().insert(static_cast<T*>(this));
 	}
 	virtual ~LLInstanceTracker()
 	{
 		// it's unsafe to delete instances of this type while all instances are being iterated over.
-		llassert(sIterationNestDepth == 0);
+		llassert_always(getStatic().sIterationNestDepth == 0);
 		getSet_().erase(static_cast<T*>(this));
 	}
 
@@ -264,20 +295,6 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
 	{
 		getSet_().insert(static_cast<T*>(this));
 	}
-
-	static InstanceSet& getSet_()
-	{
-		void * & instances = getInstances(typeid(MyT));
-		if (! instances)
-		{
-			instances = new InstanceSet;
-		}
-		return * static_cast<InstanceSet *>(instances);
-	}
-
-	static S32 sIterationNestDepth;
 };
 
-template <typename T> S32 LLInstanceTracker<T, T*>::sIterationNestDepth = 0;
-
 #endif
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 21d1c84d695d4a5868e21fc1825f05db63db58d9..8c02ad82908c17618a6905f94a0c1dfedc6e1f01 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -26,14 +26,13 @@
 
 #include "linden_common.h"
 
-#include "llmemory.h"
 
-#if MEM_TRACK_MEM
+//#if MEM_TRACK_MEM
 #include "llthread.h"
-#endif
+//#endif
 
 #if defined(LL_WINDOWS)
-# include <windows.h>
+//# include <windows.h>
 # include <psapi.h>
 #elif defined(LL_DARWIN)
 # include <sys/types.h>
@@ -43,10 +42,24 @@
 # include <unistd.h>
 #endif
 
+#include "llmemory.h"
+
+#include "llsys.h"
+#include "llframetimer.h"
 //----------------------------------------------------------------------------
 
 //static
 char* LLMemory::reserveMem = 0;
+U32 LLMemory::sAvailPhysicalMemInKB = U32_MAX ;
+U32 LLMemory::sMaxPhysicalMemInKB = 0;
+U32 LLMemory::sAllocatedMemInKB = 0;
+U32 LLMemory::sAllocatedPageSizeInKB = 0 ;
+U32 LLMemory::sMaxHeapSizeInKB = U32_MAX ;
+BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE;
+
+#if __DEBUG_PRIVATE_MEM__
+LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker;
+#endif
 
 //static
 void LLMemory::initClass()
@@ -71,6 +84,148 @@ void LLMemory::freeReserve()
 	reserveMem = NULL;
 }
 
+//static 
+void LLMemory::initMaxHeapSizeGB(F32 max_heap_size_gb, BOOL prevent_heap_failure)
+{
+	sMaxHeapSizeInKB = (U32)(max_heap_size_gb * 1024 * 1024) ;
+	sEnableMemoryFailurePrevention = prevent_heap_failure ;
+}
+
+//static 
+void LLMemory::updateMemoryInfo() 
+{
+#if LL_WINDOWS	
+	HANDLE self = GetCurrentProcess();
+	PROCESS_MEMORY_COUNTERS counters;
+	
+	if (!GetProcessMemoryInfo(self, &counters, sizeof(counters)))
+	{
+		llwarns << "GetProcessMemoryInfo failed" << llendl;
+		return ;
+	}
+
+	sAllocatedMemInKB = (U32)(counters.WorkingSetSize / 1024) ;
+	sAllocatedPageSizeInKB = (U32)(counters.PagefileUsage / 1024) ;
+
+	U32 avail_phys, avail_virtual;
+	LLMemoryInfo::getAvailableMemoryKB(avail_phys, avail_virtual) ;
+	sMaxPhysicalMemInKB = llmin(avail_phys + sAllocatedMemInKB, sMaxHeapSizeInKB);
+
+	if(sMaxPhysicalMemInKB > sAllocatedMemInKB)
+	{
+		sAvailPhysicalMemInKB = sMaxPhysicalMemInKB - sAllocatedMemInKB ;
+	}
+	else
+	{
+		sAvailPhysicalMemInKB = 0 ;
+	}
+#else
+	//not valid for other systems for now.
+	sAllocatedMemInKB = (U32)(LLMemory::getCurrentRSS() / 1024) ;
+	sMaxPhysicalMemInKB = U32_MAX ;
+	sAvailPhysicalMemInKB = U32_MAX ;
+#endif
+
+	return ;
+}
+
+//
+//this function is to test if there is enough space with the size in the virtual address space.
+//it does not do any real allocation
+//if success, it returns the address where the memory chunk can fit in;
+//otherwise it returns NULL.
+//
+//static 
+void* LLMemory::tryToAlloc(void* address, U32 size)
+{
+#if LL_WINDOWS
+	address = VirtualAlloc(address, size, MEM_RESERVE | MEM_TOP_DOWN, PAGE_NOACCESS) ;
+	if(address)
+	{
+		if(!VirtualFree(address, 0, MEM_RELEASE))
+		{
+			llerrs << "error happens when free some memory reservation." << llendl ;
+		}
+	}
+	return address ;
+#else
+	return (void*)0x01 ; //skip checking
+#endif	
+}
+
+//static 
+void LLMemory::logMemoryInfo(BOOL update)
+{
+	if(update)
+	{
+		updateMemoryInfo() ;
+	}
+
+	llinfos << "Current allocated physical memory(KB): " << sAllocatedMemInKB << llendl ;
+	llinfos << "Current allocated page size (KB): " << sAllocatedPageSizeInKB << llendl ;
+	llinfos << "Current availabe physical memory(KB): " << sAvailPhysicalMemInKB << llendl ;
+	llinfos << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << llendl ;
+}
+
+//return 0: everything is normal;
+//return 1: the memory pool is low, but not in danger;
+//return -1: the memory pool is in danger, is about to crash.
+//static 
+S32 LLMemory::isMemoryPoolLow()
+{
+	static const U32 LOW_MEMEOY_POOL_THRESHOLD_KB = 64 * 1024 ; //64 MB for emergency use
+
+	if(!sEnableMemoryFailurePrevention)
+	{
+		return 0 ; //no memory failure prevention.
+	}
+
+	if(sAvailPhysicalMemInKB < (LOW_MEMEOY_POOL_THRESHOLD_KB >> 2)) //out of physical memory
+	{
+		return -1 ;
+	}
+
+	if(sAllocatedPageSizeInKB + (LOW_MEMEOY_POOL_THRESHOLD_KB >> 2) > sMaxHeapSizeInKB) //out of virtual address space.
+	{
+		return -1 ;
+	}
+
+	return (S32)(sAvailPhysicalMemInKB < LOW_MEMEOY_POOL_THRESHOLD_KB || 
+		sAllocatedPageSizeInKB + LOW_MEMEOY_POOL_THRESHOLD_KB > sMaxHeapSizeInKB) ;
+}
+
+//static 
+U32 LLMemory::getAvailableMemKB() 
+{
+	return sAvailPhysicalMemInKB ;
+}
+
+//static 
+U32 LLMemory::getMaxMemKB() 
+{
+	return sMaxPhysicalMemInKB ;
+}
+
+//static 
+U32 LLMemory::getAllocatedMemKB() 
+{
+	return sAllocatedMemInKB ;
+}
+
+void* ll_allocate (size_t size)
+{
+	if (size == 0)
+	{
+		llwarns << "Null allocation" << llendl;
+	}
+	void *p = malloc(size);
+	if (p == NULL)
+	{
+		LLMemory::freeReserve();
+		llerrs << "Out of memory Error" << llendl;
+	}
+	return p;
+}
 
 //----------------------------------------------------------------------------
 
@@ -237,7 +392,7 @@ U64 LLMemory::getCurrentRSS()
 
 U32 LLMemory::getWorkingSetSize()
 {
-	return 0 ;
+	return 0;
 }
 
 #endif
@@ -258,7 +413,7 @@ LLMemTracker::LLMemTracker()
 	mDrawnIndex = 0 ;
 	mPaused = FALSE ;
 
-	mMutexp = new LLMutex(NULL) ;
+	mMutexp = new LLMutex() ;
 	mStringBuffer = new char*[128] ;
 	mStringBuffer[0] = new char[mCapacity * 128] ;
 	for(S32 i = 1 ; i < mCapacity ; i++)
@@ -376,3 +531,1661 @@ const char* LLMemTracker::getNextLine()
 #endif //MEM_TRACK_MEM
 //--------------------------------------------------------------------------------------------------
 
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+//minimum slot size and minimal slot size interval
+const U32 ATOMIC_MEM_SLOT = 16 ; //bytes
+
+//minimum block sizes (page size) for small allocation, medium allocation, large allocation 
+const U32 MIN_BLOCK_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {2 << 10, 4 << 10, 16 << 10} ; //
+
+//maximum block sizes for small allocation, medium allocation, large allocation 
+const U32 MAX_BLOCK_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {64 << 10, 1 << 20, 4 << 20} ;
+
+//minimum slot sizes for small allocation, medium allocation, large allocation 
+const U32 MIN_SLOT_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION]  = {ATOMIC_MEM_SLOT, 2 << 10, 512 << 10};
+
+//maximum slot sizes for small allocation, medium allocation, large allocation 
+const U32 MAX_SLOT_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION]  = {(2 << 10) - ATOMIC_MEM_SLOT, (512 - 2) << 10, 4 << 20};
+
+//size of a block with multiple slots can not exceed CUT_OFF_SIZE
+const U32 CUT_OFF_SIZE = (64 << 10) ; //64 KB
+
+//max number of slots in a block
+const U32 MAX_NUM_SLOTS_IN_A_BLOCK = llmin(MIN_BLOCK_SIZES[0] / ATOMIC_MEM_SLOT, ATOMIC_MEM_SLOT * 8) ;
+
+//-------------------------------------------------------------
+//align val to be integer times of ATOMIC_MEM_SLOT
+U32 align(U32 val)
+{
+	U32 aligned = (val / ATOMIC_MEM_SLOT) * ATOMIC_MEM_SLOT ;
+	if(aligned < val)
+	{
+		aligned += ATOMIC_MEM_SLOT ;
+	}
+
+	return aligned ;
+}
+
+//-------------------------------------------------------------
+//class LLPrivateMemoryPool::LLMemoryBlock
+//-------------------------------------------------------------
+//
+//each memory block could fit for two page sizes: 0.75 * mSlotSize, which starts from the beginning of the memory chunk and grow towards the end of the
+//the block; another is mSlotSize, which starts from the end of the block and grows towards the beginning of the block.
+//
+LLPrivateMemoryPool::LLMemoryBlock::LLMemoryBlock()
+{
+	//empty
+}
+		
+LLPrivateMemoryPool::LLMemoryBlock::~LLMemoryBlock() 
+{
+	//empty
+}
+
+//create and initialize a memory block
+void LLPrivateMemoryPool::LLMemoryBlock::init(char* buffer, U32 buffer_size, U32 slot_size)
+{
+	mBuffer = buffer ;
+	mBufferSize = buffer_size ;
+	mSlotSize = slot_size ;
+	mTotalSlots = buffer_size / mSlotSize ;	
+	
+	llassert_always(buffer_size / mSlotSize <= MAX_NUM_SLOTS_IN_A_BLOCK) ; //max number is 128
+	
+	mAllocatedSlots = 0 ;
+	mDummySize = 0 ;
+
+	//init the bit map.
+	//mark free bits	
+	if(mTotalSlots > 32) //reserve extra space from mBuffer to store bitmap if needed.
+	{
+		mDummySize = ATOMIC_MEM_SLOT ;		
+		mTotalSlots -= (mDummySize + mSlotSize - 1) / mSlotSize ;
+		mUsageBits = 0 ;
+
+		S32 usage_bit_len = (mTotalSlots + 31) / 32 ;
+		
+		for(S32 i = 0 ; i < usage_bit_len - 1 ; i++)
+		{
+			*((U32*)mBuffer + i) = 0 ;
+		}
+		for(S32 i = usage_bit_len - 1 ; i < mDummySize / sizeof(U32) ; i++)
+		{
+			*((U32*)mBuffer + i) = 0xffffffff ;
+		}
+
+		if(mTotalSlots & 31)
+		{
+			*((U32*)mBuffer + usage_bit_len - 2) = (0xffffffff << (mTotalSlots & 31)) ;
+		}		
+	}	
+	else//no extra bitmap space reserved
+	{
+		mUsageBits = 0 ;
+		if(mTotalSlots & 31)
+		{
+			mUsageBits = (0xffffffff << (mTotalSlots & 31)) ;
+		}
+	}
+
+	mSelf = this ;
+	mNext = NULL ;
+	mPrev = NULL ;
+
+	llassert_always(mTotalSlots > 0) ;
+}
+
+//mark this block to be free with the memory [mBuffer, mBuffer + mBufferSize).
+void LLPrivateMemoryPool::LLMemoryBlock::setBuffer(char* buffer, U32 buffer_size)
+{
+	mBuffer = buffer ;
+	mBufferSize = buffer_size ;
+	mSelf = NULL ;
+	mTotalSlots = 0 ; //set the block is free.
+}
+
+//reserve a slot
+char* LLPrivateMemoryPool::LLMemoryBlock::allocate() 
+{
+	llassert_always(mAllocatedSlots < mTotalSlots) ;
+	
+	//find a free slot
+	U32* bits = NULL ;
+	U32  k = 0 ;
+	if(mUsageBits != 0xffffffff)
+	{
+		bits = &mUsageBits ;
+	}
+	else if(mDummySize > 0)//go to extra space
+	{		
+		for(S32 i = 0 ; i < mDummySize / sizeof(U32); i++)
+		{
+			if(*((U32*)mBuffer + i) != 0xffffffff)
+			{
+				bits = (U32*)mBuffer + i ;
+				k = i + 1 ;
+				break ;
+			}
+		}
+	}	
+	S32 idx = 0 ;
+	U32 tmp = *bits ;
+	for(; tmp & 1 ; tmp >>= 1, idx++) ;
+
+	//set the slot reserved
+	if(!idx)
+	{
+		*bits |= 1 ;
+	}
+	else
+	{
+		*bits |= (1 << idx) ;
+	}
+
+	mAllocatedSlots++ ;
+	
+	return mBuffer + mDummySize + (k * 32 + idx) * mSlotSize ;
+}
+
+//free a slot
+void  LLPrivateMemoryPool::LLMemoryBlock::freeMem(void* addr) 
+{
+	//bit index
+	U32 idx = ((U32)addr - (U32)mBuffer - mDummySize) / mSlotSize ;
+
+	U32* bits = &mUsageBits ;
+	if(idx >= 32)
+	{
+		bits = (U32*)mBuffer + (idx - 32) / 32 ;
+	}
+
+	//reset the bit
+	if(idx & 31)
+	{
+		*bits &= ~(1 << (idx & 31)) ;
+	}
+	else
+	{
+		*bits &= ~1 ;
+	}
+
+	mAllocatedSlots-- ;
+}
+
+//for debug use: reset the entire bitmap.
+void  LLPrivateMemoryPool::LLMemoryBlock::resetBitMap()
+{
+	for(S32 i = 0 ; i < mDummySize / sizeof(U32) ; i++)
+	{
+		*((U32*)mBuffer + i) = 0 ;
+	}
+	mUsageBits = 0 ;
+}
+//-------------------------------------------------------------------
+//class LLMemoryChunk
+//--------------------------------------------------------------------
+LLPrivateMemoryPool::LLMemoryChunk::LLMemoryChunk()
+{
+	//empty
+}
+
+LLPrivateMemoryPool::LLMemoryChunk::~LLMemoryChunk()
+{
+	//empty
+}
+
+//create and init a memory chunk
+void LLPrivateMemoryPool::LLMemoryChunk::init(char* buffer, U32 buffer_size, U32 min_slot_size, U32 max_slot_size, U32 min_block_size, U32 max_block_size) 
+{
+	mBuffer = buffer ;
+	mBufferSize = buffer_size ;
+	mAlloatedSize = 0 ;
+
+	mMetaBuffer = mBuffer + sizeof(LLMemoryChunk) ;
+
+	mMinBlockSize = min_block_size; //page size
+	mMinSlotSize = min_slot_size;
+	mMaxSlotSize = max_slot_size ;
+	mBlockLevels = mMaxSlotSize / mMinSlotSize ;
+	mPartitionLevels = max_block_size / mMinBlockSize + 1 ;
+
+	S32 max_num_blocks = (buffer_size - sizeof(LLMemoryChunk) - mBlockLevels * sizeof(LLMemoryBlock*) - mPartitionLevels * sizeof(LLMemoryBlock*)) / 
+		                 (mMinBlockSize + sizeof(LLMemoryBlock)) ;
+	//meta data space
+	mBlocks = (LLMemoryBlock*)mMetaBuffer ; //space reserved for all memory blocks.
+	mAvailBlockList = (LLMemoryBlock**)((char*)mBlocks + sizeof(LLMemoryBlock) * max_num_blocks) ; 
+	mFreeSpaceList = (LLMemoryBlock**)((char*)mAvailBlockList + sizeof(LLMemoryBlock*) * mBlockLevels) ; 
+	
+	//data buffer, which can be used for allocation
+	mDataBuffer = (char*)mFreeSpaceList + sizeof(LLMemoryBlock*) * mPartitionLevels ;
+	
+	//alignmnet
+	mDataBuffer = mBuffer + align(mDataBuffer - mBuffer) ;
+	
+	//init
+	for(U32 i = 0 ; i < mBlockLevels; i++)
+	{
+		mAvailBlockList[i] = NULL ;
+	}
+	for(U32 i = 0 ; i < mPartitionLevels ; i++)
+	{
+		mFreeSpaceList[i] = NULL ;
+	}
+
+	//assign the entire chunk to the first block
+	mBlocks[0].mPrev = NULL ;
+	mBlocks[0].mNext = NULL ;
+	mBlocks[0].setBuffer(mDataBuffer, buffer_size - (mDataBuffer - mBuffer)) ;
+	addToFreeSpace(&mBlocks[0]) ;
+
+	mNext = NULL ;
+	mPrev = NULL ;
+}
+
+//static 
+U32 LLPrivateMemoryPool::LLMemoryChunk::getMaxOverhead(U32 data_buffer_size, U32 min_slot_size, 
+													   U32 max_slot_size, U32 min_block_size, U32 max_block_size)
+{
+	//for large allocations, reserve some extra memory for meta data to avoid wasting much 
+	if(data_buffer_size / min_slot_size < 64) //large allocations
+	{
+		U32 overhead = sizeof(LLMemoryChunk) + (data_buffer_size / min_block_size) * sizeof(LLMemoryBlock) +
+			sizeof(LLMemoryBlock*) * (max_slot_size / min_slot_size) + sizeof(LLMemoryBlock*) * (max_block_size / min_block_size + 1) ;
+
+		//round to integer times of min_block_size
+		overhead = ((overhead + min_block_size - 1) / min_block_size) * min_block_size ;
+		return overhead ;
+	}
+	else
+	{
+		return 0 ; //do not reserve extra overhead if for small allocations
+	}
+}
+
+char* LLPrivateMemoryPool::LLMemoryChunk::allocate(U32 size)
+{
+	if(mMinSlotSize > size)
+	{
+		size = mMinSlotSize ;
+	}
+	if(mAlloatedSize + size  > mBufferSize - (mDataBuffer - mBuffer))
+	{
+		return NULL ; //no enough space in this chunk.
+	}
+
+	char* p = NULL ;
+	U32 blk_idx = getBlockLevel(size);
+
+	LLMemoryBlock* blk = NULL ;
+
+	//check if there is free block available
+	if(mAvailBlockList[blk_idx])
+	{
+		blk = mAvailBlockList[blk_idx] ;
+		p = blk->allocate() ;
+		
+		if(blk->isFull())
+		{
+			popAvailBlockList(blk_idx) ;
+		}
+	}
+
+	//ask for a new block
+	if(!p)
+	{
+		blk = addBlock(blk_idx) ;
+		if(blk)
+		{
+			p = blk->allocate() ;
+
+			if(blk->isFull())
+			{
+				popAvailBlockList(blk_idx) ;
+			}
+		}
+	}
+
+	//ask for space from larger blocks
+	if(!p)
+	{
+		for(S32 i = blk_idx + 1 ; i < mBlockLevels; i++)
+		{
+			if(mAvailBlockList[i])
+			{
+				blk = mAvailBlockList[i] ;
+				p = blk->allocate() ;
+
+				if(blk->isFull())
+				{
+					popAvailBlockList(i) ;
+				}
+				break ;
+			}
+		}
+	}
+
+	if(p && blk)
+	{		
+		mAlloatedSize += blk->getSlotSize() ;
+	}
+	return p ;
+}
+
+void LLPrivateMemoryPool::LLMemoryChunk::freeMem(void* addr)
+{	
+	U32 blk_idx = getPageIndex((U32)addr) ;
+	LLMemoryBlock* blk = (LLMemoryBlock*)(mMetaBuffer + blk_idx * sizeof(LLMemoryBlock)) ;
+	blk = blk->mSelf ;
+
+	bool was_full = blk->isFull() ;
+	blk->freeMem(addr) ;
+	mAlloatedSize -= blk->getSlotSize() ;
+
+	if(blk->empty())
+	{
+		removeBlock(blk) ;
+	}
+	else if(was_full)
+	{
+		addToAvailBlockList(blk) ;
+	}	
+}
+
+bool LLPrivateMemoryPool::LLMemoryChunk::empty()
+{
+	return !mAlloatedSize ;
+}
+
+bool LLPrivateMemoryPool::LLMemoryChunk::containsAddress(const char* addr) const
+{
+	return (U32)mBuffer <= (U32)addr && (U32)mBuffer + mBufferSize > (U32)addr ;
+}
+
+//debug use
+void LLPrivateMemoryPool::LLMemoryChunk::dump()
+{
+#if 0
+	//sanity check
+	//for(S32 i = 0 ; i < mBlockLevels ; i++)
+	//{
+	//	LLMemoryBlock* blk = mAvailBlockList[i] ;
+	//	while(blk)
+	//	{
+	//		blk_list.push_back(blk) ;
+	//		blk = blk->mNext ;
+	//	}
+	//}
+	for(S32 i = 0 ; i < mPartitionLevels ; i++)
+	{
+		LLMemoryBlock* blk = mFreeSpaceList[i] ;
+		while(blk)
+		{
+			blk_list.push_back(blk) ;
+			blk = blk->mNext ;
+		}
+	}
+
+	std::sort(blk_list.begin(), blk_list.end(), LLMemoryBlock::CompareAddress());
+
+	U32 total_size = blk_list[0]->getBufferSize() ;
+	for(U32 i = 1 ; i < blk_list.size(); i++)
+	{
+		total_size += blk_list[i]->getBufferSize() ;
+		if((U32)blk_list[i]->getBuffer() < (U32)blk_list[i-1]->getBuffer() + blk_list[i-1]->getBufferSize())
+		{
+			llerrs << "buffer corrupted." << llendl ;
+		}
+	}
+
+	llassert_always(total_size + mMinBlockSize >= mBufferSize - ((U32)mDataBuffer - (U32)mBuffer)) ;
+
+	U32 blk_num = (mBufferSize - (mDataBuffer - mBuffer)) / mMinBlockSize ;
+	for(U32 i = 0 ; i < blk_num ; )
+	{
+		LLMemoryBlock* blk = &mBlocks[i] ;
+		if(blk->mSelf)
+		{
+			U32 end = blk->getBufferSize() / mMinBlockSize ;
+			for(U32 j = 0 ; j < end ; j++)
+			{
+				llassert_always(blk->mSelf == blk || !blk->mSelf) ;
+			}
+			i += end ;
+		}
+		else
+		{
+			llerrs << "gap happens" << llendl ;
+		}
+	}
+#endif
+#if 0
+	llinfos << "---------------------------" << llendl ;
+	llinfos << "Chunk buffer: " << (U32)getBuffer() << " size: " << getBufferSize() << llendl ;
+
+	llinfos << "available blocks ... " << llendl ;
+	for(S32 i = 0 ; i < mBlockLevels ; i++)
+	{
+		LLMemoryBlock* blk = mAvailBlockList[i] ;
+		while(blk)
+		{
+			llinfos << "blk buffer " << (U32)blk->getBuffer() << " size: " << blk->getBufferSize() << llendl ;
+			blk = blk->mNext ;
+		}
+	}
+
+	llinfos << "free blocks ... " << llendl ;
+	for(S32 i = 0 ; i < mPartitionLevels ; i++)
+	{
+		LLMemoryBlock* blk = mFreeSpaceList[i] ;
+		while(blk)
+		{
+			llinfos << "blk buffer " << (U32)blk->getBuffer() << " size: " << blk->getBufferSize() << llendl ;
+			blk = blk->mNext ;
+		}
+	}
+#endif
+}
+
+//compute the size for a block, the size is round to integer times of mMinBlockSize.
+U32 LLPrivateMemoryPool::LLMemoryChunk::calcBlockSize(U32 slot_size)
+{
+	//
+	//Note: we try to make a block to have 32 slots if the size is not over 32 pages
+	//32 is the number of bits of an integer in a 32-bit system
+	//
+
+	U32 block_size;
+	U32 cut_off_size = llmin(CUT_OFF_SIZE, (U32)(mMinBlockSize << 5)) ;
+
+	if((slot_size << 5) <= mMinBlockSize)//for small allocations, return one page 
+	{
+		block_size = mMinBlockSize ;
+	}
+	else if(slot_size >= cut_off_size)//for large allocations, return one-slot block
+	{
+		block_size = (slot_size / mMinBlockSize) * mMinBlockSize ;
+		if(block_size < slot_size)
+		{
+			block_size += mMinBlockSize ;
+		}
+	}
+	else //medium allocations
+	{
+		if((slot_size << 5) >= cut_off_size)
+		{
+			block_size = cut_off_size ;
+		}
+		else
+		{
+			block_size = ((slot_size << 5) / mMinBlockSize) * mMinBlockSize ;
+		}
+	}
+
+	llassert_always(block_size >= slot_size) ;
+
+	return block_size ;
+}
+
+//create a new block in the chunk
+LLPrivateMemoryPool::LLMemoryBlock* LLPrivateMemoryPool::LLMemoryChunk::addBlock(U32 blk_idx)
+{	
+	U32 slot_size = mMinSlotSize * (blk_idx + 1) ;
+	U32 preferred_block_size = calcBlockSize(slot_size) ;	
+	U16 idx = getPageLevel(preferred_block_size); 
+	LLMemoryBlock* blk = NULL ;
+	
+	if(mFreeSpaceList[idx])//if there is free slot for blk_idx
+	{
+		blk = createNewBlock(mFreeSpaceList[idx], preferred_block_size, slot_size, blk_idx) ;
+	}
+	else if(mFreeSpaceList[mPartitionLevels - 1]) //search free pool
+	{		
+		blk = createNewBlock(mFreeSpaceList[mPartitionLevels - 1], preferred_block_size, slot_size, blk_idx) ;
+	}
+	else //search for other non-preferred but enough space slot.
+	{
+		S32 min_idx = 0 ;
+		if(slot_size > mMinBlockSize)
+		{
+			min_idx = getPageLevel(slot_size) ;
+		}
+		for(S32 i = (S32)idx - 1 ; i >= min_idx ; i--) //search the small slots first
+		{
+			if(mFreeSpaceList[i])
+			{
+				U32 new_preferred_block_size = mFreeSpaceList[i]->getBufferSize();
+				new_preferred_block_size = (new_preferred_block_size / mMinBlockSize) * mMinBlockSize ; //round to integer times of mMinBlockSize.
+
+				//create a NEW BLOCK THERE.
+				if(new_preferred_block_size >= slot_size) //at least there is space for one slot.
+				{
+					
+					blk = createNewBlock(mFreeSpaceList[i], new_preferred_block_size, slot_size, blk_idx) ;
+				}
+				break ;
+			} 
+		}
+
+		if(!blk)
+		{
+			for(U16 i = idx + 1 ; i < mPartitionLevels - 1; i++) //search the large slots 
+			{
+				if(mFreeSpaceList[i])
+				{
+					//create a NEW BLOCK THERE.
+					blk = createNewBlock(mFreeSpaceList[i], preferred_block_size, slot_size, blk_idx) ;
+					break ;
+				} 
+			}
+		}
+	}
+
+	return blk ;
+}
+
+//create a new block at the designed location
+LLPrivateMemoryPool::LLMemoryBlock* LLPrivateMemoryPool::LLMemoryChunk::createNewBlock(LLMemoryBlock* blk, U32 buffer_size, U32 slot_size, U32 blk_idx)
+{
+	//unlink from the free space
+	removeFromFreeSpace(blk) ;
+
+	//check the rest space
+	U32 new_free_blk_size = blk->getBufferSize() - buffer_size ;	
+	if(new_free_blk_size < mMinBlockSize) //can not partition the memory into size smaller than mMinBlockSize
+	{
+		new_free_blk_size = 0 ; //discard the last small extra space.
+	}			
+
+	//add the rest space back to the free list
+	if(new_free_blk_size > 0) //blk still has free space
+	{
+		LLMemoryBlock* next_blk = blk + (buffer_size / mMinBlockSize) ;
+		next_blk->mPrev = NULL ;
+		next_blk->mNext = NULL ;
+		next_blk->setBuffer(blk->getBuffer() + buffer_size, new_free_blk_size) ;
+		addToFreeSpace(next_blk) ;
+	}
+
+	blk->init(blk->getBuffer(), buffer_size, slot_size) ;
+	//insert to the available block list...
+	mAvailBlockList[blk_idx] = blk ;
+
+	//mark the address map: all blocks covered by this block space pointing back to this block.
+	U32 end = (buffer_size / mMinBlockSize) ;
+	for(U32 i = 1 ; i < end ; i++)
+	{
+		(blk + i)->mSelf = blk ;
+	}
+
+	return blk ;
+}
+
+//delete a block, release the block to the free pool.
+void LLPrivateMemoryPool::LLMemoryChunk::removeBlock(LLMemoryBlock* blk)
+{
+	//remove from the available block list
+	if(blk->mPrev)
+	{
+		blk->mPrev->mNext = blk->mNext ;
+	}
+	if(blk->mNext)
+	{
+		blk->mNext->mPrev = blk->mPrev ;
+	}
+	U32 blk_idx = getBlockLevel(blk->getSlotSize());
+	if(mAvailBlockList[blk_idx] == blk)
+	{
+		mAvailBlockList[blk_idx] = blk->mNext ;
+	}
+
+	blk->mNext = NULL ;
+	blk->mPrev = NULL ;
+	
+	//mark it free
+	blk->setBuffer(blk->getBuffer(), blk->getBufferSize()) ;
+
+#if 1
+	//merge blk with neighbors if possible
+	if(blk->getBuffer() > mDataBuffer) //has the left neighbor
+	{
+		if((blk - 1)->mSelf->isFree())
+		{
+			LLMemoryBlock* left_blk = (blk - 1)->mSelf ;
+			removeFromFreeSpace((blk - 1)->mSelf);
+			left_blk->setBuffer(left_blk->getBuffer(), left_blk->getBufferSize() + blk->getBufferSize()) ;
+			blk = left_blk ;
+		}
+	}
+	if(blk->getBuffer() + blk->getBufferSize() <= mBuffer + mBufferSize - mMinBlockSize) //has the right neighbor
+	{
+		U32 d = blk->getBufferSize() / mMinBlockSize ;
+		if((blk + d)->isFree())
+		{
+			LLMemoryBlock* right_blk = blk + d ;
+			removeFromFreeSpace(blk + d) ;
+			blk->setBuffer(blk->getBuffer(), blk->getBufferSize() + right_blk->getBufferSize()) ;
+		}
+	}
+#endif
+	
+	addToFreeSpace(blk) ;
+
+	return ;
+}
+
+//the top block in the list is full, pop it out of the list
+void LLPrivateMemoryPool::LLMemoryChunk::popAvailBlockList(U32 blk_idx) 
+{
+	if(mAvailBlockList[blk_idx])
+	{
+		LLMemoryBlock* next = mAvailBlockList[blk_idx]->mNext ;
+		if(next)
+		{
+			next->mPrev = NULL ;
+		}
+		mAvailBlockList[blk_idx]->mPrev = NULL ;
+		mAvailBlockList[blk_idx]->mNext = NULL ;
+		mAvailBlockList[blk_idx] = next ;
+	}
+}
+
+//add the block back to the free pool
+void LLPrivateMemoryPool::LLMemoryChunk::addToFreeSpace(LLMemoryBlock* blk) 
+{
+	llassert_always(!blk->mPrev) ;
+	llassert_always(!blk->mNext) ;
+
+	U16 free_idx = blk->getBufferSize() / mMinBlockSize - 1;
+
+	(blk + free_idx)->mSelf = blk ; //mark the end pointing back to the head.
+	free_idx = llmin(free_idx, (U16)(mPartitionLevels - 1)) ;
+
+	blk->mNext = mFreeSpaceList[free_idx] ;
+	if(mFreeSpaceList[free_idx])
+	{
+		mFreeSpaceList[free_idx]->mPrev = blk ;
+	}
+	mFreeSpaceList[free_idx] = blk ;
+	blk->mPrev = NULL ;
+	blk->mSelf = blk ;
+	
+	return ;
+}
+
+//remove the space from the free pool
+void LLPrivateMemoryPool::LLMemoryChunk::removeFromFreeSpace(LLMemoryBlock* blk) 
+{
+	U16 free_idx = blk->getBufferSize() / mMinBlockSize - 1;
+	free_idx = llmin(free_idx, (U16)(mPartitionLevels - 1)) ;
+
+	if(mFreeSpaceList[free_idx] == blk)
+	{
+		mFreeSpaceList[free_idx] = blk->mNext ;
+	}
+	if(blk->mPrev)
+	{
+		blk->mPrev->mNext = blk->mNext ;
+	}
+	if(blk->mNext)
+	{
+		blk->mNext->mPrev = blk->mPrev ;
+	}
+	blk->mNext = NULL ;
+	blk->mPrev = NULL ;
+	blk->mSelf = NULL ;
+
+	return ;
+}
+
+void LLPrivateMemoryPool::LLMemoryChunk::addToAvailBlockList(LLMemoryBlock* blk) 
+{
+	llassert_always(!blk->mPrev) ;
+	llassert_always(!blk->mNext) ;
+
+	U32 blk_idx = getBlockLevel(blk->getSlotSize());
+
+	blk->mNext = mAvailBlockList[blk_idx] ;
+	if(blk->mNext)
+	{
+		blk->mNext->mPrev = blk ;
+	}
+	blk->mPrev = NULL ;
+	mAvailBlockList[blk_idx] = blk ;
+
+	return ;
+}
+
+U32 LLPrivateMemoryPool::LLMemoryChunk::getPageIndex(U32 addr)
+{
+	return (addr - (U32)mDataBuffer) / mMinBlockSize ;
+}
+
+//for mAvailBlockList
+U32 LLPrivateMemoryPool::LLMemoryChunk::getBlockLevel(U32 size)
+{
+	llassert(size >= mMinSlotSize && size <= mMaxSlotSize) ;
+
+	//start from 0
+	return (size + mMinSlotSize - 1) / mMinSlotSize - 1 ;
+}
+
+//for mFreeSpaceList
+U16 LLPrivateMemoryPool::LLMemoryChunk::getPageLevel(U32 size)
+{
+	//start from 0
+	U16 level = size / mMinBlockSize - 1 ;
+	if(level >= mPartitionLevels)
+	{
+		level = mPartitionLevels - 1 ;
+	}
+	return level ;
+}
+
+//-------------------------------------------------------------------
+//class LLPrivateMemoryPool
+//--------------------------------------------------------------------
+const U32 CHUNK_SIZE = 4 << 20 ; //4 MB
+const U32 LARGE_CHUNK_SIZE = 4 * CHUNK_SIZE ; //16 MB
+LLPrivateMemoryPool::LLPrivateMemoryPool(S32 type) :
+	mMutexp(NULL),	
+	mReservedPoolSize(0),
+	mHashFactor(1),
+	mType(type)
+{
+	const U32 MAX_POOL_SIZE = 256 * 1024 * 1024 ; //256 MB
+
+	mMaxPoolSize = MAX_POOL_SIZE ;
+	if(type == STATIC_THREADED || type == VOLATILE_THREADED)
+	{
+		mMutexp = new LLMutex ;
+	}
+
+	for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++)
+	{
+		mChunkList[i] = NULL ;
+	}	
+	
+	mNumOfChunks = 0 ;
+}
+
+LLPrivateMemoryPool::~LLPrivateMemoryPool()
+{
+	destroyPool();
+	delete mMutexp ;
+}
+
+char* LLPrivateMemoryPool::allocate(U32 size)
+{	
+	if(!size)
+	{
+		return NULL ;
+	}
+
+	//if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it
+	if(size >= CHUNK_SIZE)
+	{
+		return (char*)malloc(size) ;
+	}
+
+	char* p = NULL ;
+
+	//find the appropriate chunk
+	S32 chunk_idx = getChunkIndex(size) ;
+	
+	lock() ;
+
+	LLMemoryChunk* chunk = mChunkList[chunk_idx];
+	while(chunk)
+	{
+		if((p = chunk->allocate(size)))
+		{
+			break ;
+		}
+		chunk = chunk->mNext ;
+	}
+	
+	//fetch new memory chunk
+	if(!p)
+	{
+		if(mReservedPoolSize + CHUNK_SIZE > mMaxPoolSize)
+		{
+			chunk = mChunkList[chunk_idx];
+			while(chunk)
+			{
+				if((p = chunk->allocate(size)))
+				{
+					break ;
+				}
+				chunk = chunk->mNext ;
+			}
+		}
+
+		chunk = addChunk(chunk_idx) ;
+		if(chunk)
+		{
+			p = chunk->allocate(size) ;
+		}
+	}
+
+	unlock() ;
+
+	return p ;
+}
+
+void LLPrivateMemoryPool::freeMem(void* addr)
+{
+	if(!addr)
+	{
+		return ;
+	}
+	
+	lock() ;
+	
+	LLMemoryChunk* chunk = findChunk((char*)addr) ;
+	
+	if(!chunk)
+	{
+		free(addr) ; //release from heap
+	}
+	else
+	{
+		chunk->freeMem(addr) ;
+
+		if(chunk->empty())
+		{
+			removeChunk(chunk) ;
+		}
+	}
+	
+	unlock() ;
+}
+
+void LLPrivateMemoryPool::dump()
+{
+}
+
+U32 LLPrivateMemoryPool::getTotalAllocatedSize()
+{
+	U32 total_allocated = 0 ;
+
+	LLMemoryChunk* chunk ;
+	for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++)
+	{
+		chunk = mChunkList[i];
+		while(chunk)
+		{
+			total_allocated += chunk->getAllocatedSize() ;
+			chunk = chunk->mNext ;
+		}
+	}
+
+	return total_allocated ;
+}
+
+void LLPrivateMemoryPool::lock()
+{
+	if(mMutexp)
+	{
+		mMutexp->lock() ;
+	}
+}
+
+void LLPrivateMemoryPool::unlock()
+{
+	if(mMutexp)
+	{
+		mMutexp->unlock() ;
+	}
+}
+
+S32  LLPrivateMemoryPool::getChunkIndex(U32 size) 
+{
+	S32 i ;
+	for(i = 0 ; size > MAX_SLOT_SIZES[i]; i++);
+	
+	llassert_always(i < SUPER_ALLOCATION);
+
+	return i ;
+}
+
+//destroy the entire pool
+void  LLPrivateMemoryPool::destroyPool()
+{
+	lock() ;
+
+	if(mNumOfChunks > 0)
+	{
+		llwarns << "There is some memory not freed when destroy the memory pool!" << llendl ;
+	}
+
+	mNumOfChunks = 0 ;
+	mChunkHashList.clear() ;
+	mHashFactor = 1 ;
+	for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++)
+	{
+		mChunkList[i] = NULL ;
+	}
+
+	unlock() ;
+}
+
+void  LLPrivateMemoryPool::checkSize(U32 asked_size)
+{
+	if(mReservedPoolSize + asked_size > mMaxPoolSize)
+	{
+		llinfos << "Max pool size: " << mMaxPoolSize << llendl ;
+		llinfos << "Total reserved size: " << mReservedPoolSize + asked_size << llendl ;
+		llinfos << "Total_allocated Size: " << getTotalAllocatedSize() << llendl ;
+
+		llerrs << "The pool is overflowing..." << llendl ;
+	}
+}
+
+LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_index)
+{
+	U32 preferred_size ;
+	U32 overhead ;
+	if(chunk_index < LARGE_ALLOCATION)
+	{
+		preferred_size = CHUNK_SIZE ; //4MB
+		overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index],
+			MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ;
+	}
+	else
+	{
+		preferred_size = LARGE_CHUNK_SIZE ; //16MB
+		overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index], 
+			MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ;
+	}
+
+	checkSize(preferred_size + overhead) ;
+	mReservedPoolSize += preferred_size + overhead ;
+
+	char* buffer = (char*)malloc(preferred_size + overhead) ;
+	if(!buffer)
+	{
+		return NULL ;
+	}
+	
+	LLMemoryChunk* chunk = new (buffer) LLMemoryChunk() ;
+	chunk->init(buffer, preferred_size + overhead, MIN_SLOT_SIZES[chunk_index],
+		MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ;
+
+	//add to the tail of the linked list
+	{
+		if(!mChunkList[chunk_index])
+		{
+			mChunkList[chunk_index] = chunk ;
+		}
+		else
+		{
+			LLMemoryChunk* cur = mChunkList[chunk_index] ;
+			while(cur->mNext)
+			{
+				cur = cur->mNext ;
+			}
+			cur->mNext = chunk ;
+			chunk->mPrev = cur ;
+		}
+	}
+
+	//insert into the hash table
+	addToHashTable(chunk) ;
+	
+	mNumOfChunks++;
+
+	return chunk ;
+}
+
+void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk) 
+{
+	if(!chunk)
+	{
+		return ;
+	}
+
+	//remove from the linked list
+	for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++)
+	{
+		if(mChunkList[i] == chunk)
+		{
+			mChunkList[i] = chunk->mNext ;
+		}
+	}
+
+	if(chunk->mPrev)
+	{
+		chunk->mPrev->mNext = chunk->mNext ;
+	}
+	if(chunk->mNext)
+	{
+		chunk->mNext->mPrev = chunk->mPrev ;
+	}
+
+	//remove from the hash table
+	removeFromHashTable(chunk) ;
+	
+	mNumOfChunks--;
+	mReservedPoolSize -= chunk->getBufferSize() ;
+	
+	//release memory
+	free(chunk->getBuffer()) ;
+}
+
+U16 LLPrivateMemoryPool::findHashKey(const char* addr)
+{
+	return (((U32)addr) / CHUNK_SIZE) % mHashFactor ;
+}
+
+LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::findChunk(const char* addr)
+{
+	U16 key = findHashKey(addr) ;	
+	if(mChunkHashList.size() <= key)
+	{
+		return NULL ;
+	}
+
+	return mChunkHashList[key].findChunk(addr) ;	
+}
+
+void LLPrivateMemoryPool::addToHashTable(LLMemoryChunk* chunk) 
+{
+	static const U16 HASH_FACTORS[] = {41, 83, 193, 317, 419, 523, 0xFFFF}; 
+	
+	U16 i ;
+	if(mChunkHashList.empty())
+	{
+		mHashFactor = HASH_FACTORS[0] ;
+		rehash() ;		
+	}
+
+	U16 start_key = findHashKey(chunk->getBuffer()) ;
+	U16 end_key = findHashKey(chunk->getBuffer() + chunk->getBufferSize() - 1) ;
+	bool need_rehash = false ;
+	
+	if(mChunkHashList[start_key].hasElement(chunk))
+	{
+		return; //already inserted.
+	}
+	need_rehash = mChunkHashList[start_key].add(chunk) ;
+	
+	if(start_key == end_key && !need_rehash)
+	{
+		return ; //done
+	}
+
+	if(!need_rehash)
+	{
+		need_rehash = mChunkHashList[end_key].add(chunk) ;
+	}
+
+	if(!need_rehash)
+	{
+		if(end_key < start_key)
+		{
+			need_rehash = fillHashTable(start_key + 1, mHashFactor, chunk) ;
+			if(!need_rehash)
+			{
+				need_rehash = fillHashTable(0, end_key, chunk) ;
+			}
+		}
+		else
+		{
+			need_rehash = fillHashTable(start_key + 1, end_key, chunk) ;
+		}
+	}
+	
+	if(need_rehash)
+	{
+		i = 0 ;
+		while(HASH_FACTORS[i] <= mHashFactor) i++;
+
+		mHashFactor = HASH_FACTORS[i] ;
+		llassert_always(mHashFactor != 0xFFFF) ;//stop point to prevent endlessly recursive calls
+
+		rehash() ;
+	}
+}
+
+void LLPrivateMemoryPool::removeFromHashTable(LLMemoryChunk* chunk) 
+{
+	U16 start_key = findHashKey(chunk->getBuffer()) ;
+	U16 end_key = findHashKey(chunk->getBuffer() + chunk->getBufferSize() - 1) ;
+	
+	mChunkHashList[start_key].remove(chunk) ;
+	if(start_key == end_key)
+	{
+		return ; //done
+	}
+
+	mChunkHashList[end_key].remove(chunk) ;
+	
+	if(end_key < start_key)
+	{
+		for(U16 i = start_key + 1 ; i < mHashFactor; i++)
+		{
+			mChunkHashList[i].remove(chunk) ;
+		}
+		for(U16 i = 0 ; i < end_key; i++)
+		{
+			mChunkHashList[i].remove(chunk) ;
+		}
+	}
+	else
+	{
+		for(U16 i = start_key + 1 ; i < end_key; i++)
+		{
+			mChunkHashList[i].remove(chunk) ;
+		}
+	}
+}
+
+void LLPrivateMemoryPool::rehash()
+{
+	llinfos << "new hash factor: " << mHashFactor << llendl ;
+
+	mChunkHashList.clear() ;
+	mChunkHashList.resize(mHashFactor) ;
+
+	LLMemoryChunk* chunk ;
+	for(U16 i = 0 ; i < SUPER_ALLOCATION ; i++)
+	{
+		chunk = mChunkList[i] ; 
+		while(chunk)
+		{
+			addToHashTable(chunk) ;
+			chunk = chunk->mNext ;
+		}
+	}
+}
+
+bool LLPrivateMemoryPool::fillHashTable(U16 start, U16 end, LLMemoryChunk* chunk)
+{
+	for(U16 i = start; i < end; i++)
+	{
+		if(mChunkHashList[i].add(chunk))
+		{			
+			return true ;
+		}		
+	}
+
+	return false ;
+}
+
+//--------------------------------------------------------------------
+// class LLChunkHashElement
+//--------------------------------------------------------------------
+LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::LLChunkHashElement::findChunk(const char* addr)
+{
+	if(mFirst && mFirst->containsAddress(addr))
+	{
+		return mFirst ;
+	}
+	else if(mSecond && mSecond->containsAddress(addr))
+	{
+		return mSecond ;
+	}
+
+	return NULL ;
+}
+
+//return false if successfully inserted to the hash slot.
+bool LLPrivateMemoryPool::LLChunkHashElement::add(LLPrivateMemoryPool::LLMemoryChunk* chunk)
+{
+	llassert_always(!hasElement(chunk)) ;
+
+	if(!mFirst)
+	{
+		mFirst = chunk ;
+	}
+	else if(!mSecond)
+	{
+		mSecond = chunk ;
+	}
+	else
+	{
+		return true ; //failed
+	}
+
+	return false ;
+}
+
+void LLPrivateMemoryPool::LLChunkHashElement::remove(LLPrivateMemoryPool::LLMemoryChunk* chunk)
+{
+	if(mFirst == chunk)
+	{
+		mFirst = NULL ;
+	}
+	else if(mSecond ==chunk)
+	{
+		mSecond = NULL ;
+	}
+	else
+	{
+		llerrs << "This slot does not contain this chunk!" << llendl ;
+	}
+}
+
+//--------------------------------------------------------------------
+//class LLPrivateMemoryPoolManager
+//--------------------------------------------------------------------
+LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::sInstance = NULL ;
+
+LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager(BOOL enabled) 
+{
+	mPoolList.resize(LLPrivateMemoryPool::MAX_TYPES) ;
+
+	for(S32 i = 0 ; i < LLPrivateMemoryPool::MAX_TYPES; i++)
+	{
+		mPoolList[i] = NULL ;
+	}
+
+	mPrivatePoolEnabled = enabled ;
+}
+
+LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager() 
+{
+
+#if __DEBUG_PRIVATE_MEM__
+	if(!sMemAllocationTracker.empty())
+	{
+		llwarns << "there is potential memory leaking here. The list of not freed memory blocks are from: " <<llendl ;
+
+		S32 k = 0 ;
+		for(mem_allocation_info_t::iterator iter = sMemAllocationTracker.begin() ; iter != sMemAllocationTracker.end() ; ++iter)
+		{
+			llinfos << k++ << ", " << iter->second << llendl ;
+		}
+		sMemAllocationTracker.clear() ;
+	}
+#endif
+
+#if 0
+	//all private pools should be released by their owners before reaching here.
+	for(S32 i = 0 ; i < LLPrivateMemoryPool::MAX_TYPES; i++)
+	{
+		llassert_always(!mPoolList[i]) ;
+	}
+	mPoolList.clear() ;
+
+#else
+	//forcefully release all memory
+	for(S32 i = 0 ; i < LLPrivateMemoryPool::MAX_TYPES; i++)
+	{
+		if(mPoolList[i])
+		{
+			delete mPoolList[i] ;
+			mPoolList[i] = NULL ;
+		}
+	}
+	mPoolList.clear() ;
+#endif
+}
+
+//static 
+void LLPrivateMemoryPoolManager::initClass(BOOL enabled) 
+{
+	llassert_always(!sInstance) ;
+
+	sInstance = new LLPrivateMemoryPoolManager(enabled) ;
+}
+
+//static 
+LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::getInstance() 
+{
+	//if(!sInstance)
+	//{
+	//	sInstance = new LLPrivateMemoryPoolManager(FALSE) ;
+	//}
+	return sInstance ;
+}
+	
+//static 
+void LLPrivateMemoryPoolManager::destroyClass() 
+{
+	if(sInstance)
+	{
+		delete sInstance ;
+		sInstance = NULL ;
+	}
+}
+
+LLPrivateMemoryPool* LLPrivateMemoryPoolManager::newPool(S32 type) 
+{
+	if(!mPrivatePoolEnabled)
+	{
+		return NULL ;
+	}
+
+	if(!mPoolList[type])
+	{
+		mPoolList[type] = new LLPrivateMemoryPool(type) ;
+	}
+
+	return mPoolList[type] ;
+}
+
+void LLPrivateMemoryPoolManager::deletePool(LLPrivateMemoryPool* pool) 
+{
+	if(pool && pool->isEmpty())
+	{
+		mPoolList[pool->getType()] = NULL ;
+		delete pool;
+	}
+}
+
+//debug
+void LLPrivateMemoryPoolManager::updateStatistics()
+{
+	mTotalReservedSize = 0 ;
+	mTotalAllocatedSize = 0 ;
+
+	for(U32 i = 0; i < mPoolList.size(); i++)
+	{
+		if(mPoolList[i])
+		{
+			mTotalReservedSize += mPoolList[i]->getTotalReservedSize() ;
+			mTotalAllocatedSize += mPoolList[i]->getTotalAllocatedSize() ;
+		}
+	}
+}
+
+#if __DEBUG_PRIVATE_MEM__
+//static 
+char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size, const char* function, const int line) 
+{
+	char* p ;
+
+	if(!poolp)
+	{
+		p = (char*)malloc(size) ;
+	}
+	else
+	{
+		p = poolp->allocate(size) ;
+	}
+	
+	if(p)
+	{
+		char num[16] ;
+		sprintf(num, " line: %d ", line) ;
+		std::string str(function) ;
+		str += num; 
+
+		sMemAllocationTracker[p] = str ;
+	}
+
+	return p ;
+}	
+#else
+//static 
+char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size) 
+{
+	if(poolp)
+	{
+		return poolp->allocate(size) ;		
+	}
+	else
+	{
+		return (char*)malloc(size) ;
+	}
+}
+#endif
+
+//static 
+void  LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr) 
+{
+	if(!addr)
+	{
+		return ;
+	}
+
+#if __DEBUG_PRIVATE_MEM__
+	sMemAllocationTracker.erase((char*)addr) ;
+#endif
+
+	if(poolp)
+	{
+		poolp->freeMem(addr) ;
+	}
+	else
+	{
+		free(addr) ;
+	}	
+}
+
+//--------------------------------------------------------------------
+//class LLPrivateMemoryPoolTester
+//--------------------------------------------------------------------
+#if 0
+LLPrivateMemoryPoolTester* LLPrivateMemoryPoolTester::sInstance = NULL ;
+LLPrivateMemoryPool* LLPrivateMemoryPoolTester::sPool = NULL ;
+LLPrivateMemoryPoolTester::LLPrivateMemoryPoolTester()
+{	
+}
+	
+LLPrivateMemoryPoolTester::~LLPrivateMemoryPoolTester() 
+{	
+}
+
+//static 
+LLPrivateMemoryPoolTester* LLPrivateMemoryPoolTester::getInstance() 
+{
+	if(!sInstance)
+	{
+		sInstance = ::new LLPrivateMemoryPoolTester() ;
+	}
+	return sInstance ;
+}
+
+//static 
+void LLPrivateMemoryPoolTester::destroy()
+{
+	if(sInstance)
+	{
+		::delete sInstance ;
+		sInstance = NULL ;
+	}
+
+	if(sPool)
+	{
+		LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ;
+		sPool = NULL ;
+	}
+}
+
+void LLPrivateMemoryPoolTester::run(S32 type) 
+{
+	if(sPool)
+	{
+		LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ;
+	}
+	sPool = LLPrivateMemoryPoolManager::getInstance()->newPool(type) ;
+
+	//run the test
+	correctnessTest() ;
+	performanceTest() ;
+	//fragmentationtest() ;
+
+	//release pool.
+	LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ;
+	sPool = NULL ;
+}
+
+void LLPrivateMemoryPoolTester::test(U32 min_size, U32 max_size, U32 stride, U32 times, 
+									 bool random_deletion, bool output_statistics)
+{
+	U32 levels = (max_size - min_size) / stride + 1 ;
+	char*** p ;
+	U32 i, j ;
+	U32 total_allocated_size = 0 ;
+
+	//allocate space for p ;
+	if(!(p = ::new char**[times]) || !(*p = ::new char*[times * levels]))
+	{
+		llerrs << "memory initialization for p failed" << llendl ;
+	}
+
+	//init
+	for(i = 0 ; i < times; i++)
+	{
+		p[i] = *p + i * levels ;
+		for(j = 0 ; j < levels; j++)
+		{
+			p[i][j] = NULL ;
+		}
+	}
+
+	//allocation
+	U32 size ;
+	for(i = 0 ; i < times ; i++)
+	{
+		for(j = 0 ; j < levels; j++) 
+		{
+			size = min_size + j * stride ;
+			p[i][j] = ALLOCATE_MEM(sPool, size) ;
+
+			total_allocated_size+= size ;
+
+			*(U32*)p[i][j] = i ;
+			*((U32*)p[i][j] + 1) = j ;
+			//p[i][j][size - 1] = '\0' ; //access the last element to verify the success of the allocation.
+
+			//randomly release memory
+			if(random_deletion)
+			{
+				S32 k = rand() % levels ;
+
+				if(p[i][k])
+				{
+					llassert_always(*(U32*)p[i][k] == i && *((U32*)p[i][k] + 1) == k) ;
+					FREE_MEM(sPool, p[i][k]) ;
+					total_allocated_size -= min_size + k * stride ;
+					p[i][k] = NULL ;
+				}
+			}
+		}
+	}
+
+	//output pool allocation statistics
+	if(output_statistics)
+	{
+	}
+
+	//release all memory allocations
+	for(i = 0 ; i < times; i++)
+	{
+		for(j = 0 ; j < levels; j++)
+		{
+			if(p[i][j])
+			{
+				llassert_always(*(U32*)p[i][j] == i && *((U32*)p[i][j] + 1) == j) ;
+				FREE_MEM(sPool, p[i][j]) ;
+				total_allocated_size -= min_size + j * stride ;
+				p[i][j] = NULL ;
+			}
+		}
+	}
+
+	::delete[] *p ;
+	::delete[] p ;
+}
+
+void LLPrivateMemoryPoolTester::testAndTime(U32 size, U32 times)
+{
+	LLTimer timer ;
+
+	llinfos << " -**********************- " << llendl ;
+	llinfos << "test size: " << size << " test times: " << times << llendl ;
+
+	timer.reset() ;
+	char** p = new char*[times] ;
+		
+	//using the customized memory pool
+	//allocation
+	for(U32 i = 0 ; i < times; i++)
+	{
+		p[i] = ALLOCATE_MEM(sPool, size) ;
+		if(!p[i])
+		{
+			llerrs << "allocation failed" << llendl ;
+		}
+	}
+	//de-allocation
+	for(U32 i = 0 ; i < times; i++)
+	{
+		FREE_MEM(sPool, p[i]) ;
+		p[i] = NULL ;
+	}
+	llinfos << "time spent using customized memory pool: " << timer.getElapsedTimeF32() << llendl ;
+
+	timer.reset() ;
+
+	//using the standard allocator/de-allocator:
+	//allocation
+	for(U32 i = 0 ; i < times; i++)
+	{
+		p[i] = ::new char[size] ;
+		if(!p[i])
+		{
+			llerrs << "allocation failed" << llendl ;
+		}
+	}
+	//de-allocation
+	for(U32 i = 0 ; i < times; i++)
+	{
+		::delete[] p[i] ;
+		p[i] = NULL ;
+	}
+	llinfos << "time spent using standard allocator/de-allocator: " << timer.getElapsedTimeF32() << llendl ;
+
+	delete[] p;
+}
+
+void LLPrivateMemoryPoolTester::correctnessTest() 
+{
+	//try many different sized allocation, and all kinds of edge cases, access the allocated memory 
+	//to see if allocation is right.
+	
+	//edge case
+	char* p = ALLOCATE_MEM(sPool, 0) ;
+	FREE_MEM(sPool, p) ;
+
+	//small sized
+	// [8 bytes, 2KB), each asks for 256 allocations and deallocations
+	test(8, 2040, 8, 256, true, true) ;
+	
+	//medium sized
+	//[2KB, 512KB), each asks for 16 allocations and deallocations
+	test(2048, 512 * 1024 - 2048, 2048, 16, true, true) ;
+
+	//large sized
+	//[512KB, 4MB], each asks for 8 allocations and deallocations
+	test(512 * 1024, 4 * 1024 * 1024, 64 * 1024, 6, true, true) ;
+}
+
+void LLPrivateMemoryPoolTester::performanceTest() 
+{
+	U32 test_size[3] = {768, 3* 1024, 3* 1024 * 1024};
+	
+	//small sized
+	testAndTime(test_size[0], 8) ;
+	
+	//medium sized
+	testAndTime(test_size[1], 8) ;
+
+	//large sized
+	testAndTime(test_size[2], 8) ;
+}
+
+void LLPrivateMemoryPoolTester::fragmentationtest() 
+{
+	//for internal fragmentation statistics:
+	//every time when asking for a new chunk during correctness test, and performance test,
+	//print out the chunk usage statistices.
+}
+#endif
+//--------------------------------------------------------------------
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 3bd14035768e31b1859e33645f4924d8319cffed..db753f0d8ba19c239decb6024f983f60d491b6d5 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -27,7 +27,6 @@
 #define LLMEMORY_H
 
 #include "llmemtype.h"
-
 #if LL_DEBUG
 inline void* ll_aligned_malloc( size_t size, int align )
 {
@@ -105,6 +104,10 @@ inline void ll_aligned_free_32(void *p)
 #define ll_aligned_free_32 free
 #endif // LL_DEBUG
 
+#ifndef __DEBUG_PRIVATE_MEM__
+#define __DEBUG_PRIVATE_MEM__  0
+#endif
+
 class LL_COMMON_API LLMemory
 {
 public:
@@ -115,8 +118,24 @@ class LL_COMMON_API LLMemory
 	// Return value is zero if not known.
 	static U64 getCurrentRSS();
 	static U32 getWorkingSetSize();
+	static void* tryToAlloc(void* address, U32 size);
+	static void initMaxHeapSizeGB(F32 max_heap_size_gb, BOOL prevent_heap_failure);
+	static void updateMemoryInfo() ;
+	static void logMemoryInfo(BOOL update = FALSE);
+	static S32  isMemoryPoolLow();
+
+	static U32 getAvailableMemKB() ;
+	static U32 getMaxMemKB() ;
+	static U32 getAllocatedMemKB() ;
 private:
 	static char* reserveMem;
+	static U32 sAvailPhysicalMemInKB ;
+	static U32 sMaxPhysicalMemInKB ;
+	static U32 sAllocatedMemInKB;
+	static U32 sAllocatedPageSizeInKB ;
+
+	static U32 sMaxHeapSizeInKB;
+	static BOOL sEnableMemoryFailurePrevention;
 };
 
 //----------------------------------------------------------------------------
@@ -163,6 +182,326 @@ class LL_COMMON_API LLMemTracker
 
 //----------------------------------------------------------------------------
 
+
+//
+//class LLPrivateMemoryPool defines a private memory pool for an application to use, so the application does not
+//need to access the heap directly fro each memory allocation. Throught this, the allocation speed is faster, 
+//and reduces virtaul address space gragmentation problem.
+//Note: this class is thread-safe by passing true to the constructor function. However, you do not need to do this unless
+//you are sure the memory allocation and de-allocation will happen in different threads. To make the pool thread safe
+//increases allocation and deallocation cost.
+//
+class LL_COMMON_API LLPrivateMemoryPool
+{
+	friend class LLPrivateMemoryPoolManager ;
+
+public:
+	class LL_COMMON_API LLMemoryBlock //each block is devided into slots uniformly
+	{
+	public: 
+		LLMemoryBlock() ;
+		~LLMemoryBlock() ;
+
+		void init(char* buffer, U32 buffer_size, U32 slot_size) ;
+		void setBuffer(char* buffer, U32 buffer_size) ;
+
+		char* allocate() ;
+		void  freeMem(void* addr) ;
+
+		bool empty() {return !mAllocatedSlots;}
+		bool isFull() {return mAllocatedSlots == mTotalSlots;}
+		bool isFree() {return !mTotalSlots;}
+
+		U32  getSlotSize()const {return mSlotSize;}
+		U32  getTotalSlots()const {return mTotalSlots;}
+		U32  getBufferSize()const {return mBufferSize;}
+		char* getBuffer() const {return mBuffer;}
+
+		//debug use
+		void resetBitMap() ;
+	private:
+		char* mBuffer;
+		U32   mSlotSize ; //when the block is not initialized, it is the buffer size.
+		U32   mBufferSize ;
+		U32   mUsageBits ;
+		U8    mTotalSlots ;
+		U8    mAllocatedSlots ;
+		U8    mDummySize ; //size of extra bytes reserved for mUsageBits.
+
+	public:
+		LLMemoryBlock* mPrev ;
+		LLMemoryBlock* mNext ;
+		LLMemoryBlock* mSelf ;
+
+		struct CompareAddress
+		{
+			bool operator()(const LLMemoryBlock* const& lhs, const LLMemoryBlock* const& rhs)
+			{
+				return (U32)lhs->getBuffer() < (U32)rhs->getBuffer();
+			}
+		};
+	};
+
+	class LL_COMMON_API LLMemoryChunk //is divided into memory blocks.
+	{
+	public:
+		LLMemoryChunk() ;
+		~LLMemoryChunk() ;
+
+		void init(char* buffer, U32 buffer_size, U32 min_slot_size, U32 max_slot_size, U32 min_block_size, U32 max_block_size) ;
+		void setBuffer(char* buffer, U32 buffer_size) ;
+
+		bool empty() ;
+		
+		char* allocate(U32 size) ;
+		void  freeMem(void* addr) ;
+
+		char* getBuffer() const {return mBuffer;}
+		U32 getBufferSize() const {return mBufferSize;}
+		U32 getAllocatedSize() const {return mAlloatedSize;}
+
+		bool containsAddress(const char* addr) const;
+
+		static U32 getMaxOverhead(U32 data_buffer_size, U32 min_slot_size, 
+													   U32 max_slot_size, U32 min_block_size, U32 max_block_size) ;
+	
+		void dump() ;
+
+	private:
+		U32 getPageIndex(U32 addr) ;
+		U32 getBlockLevel(U32 size) ;
+		U16 getPageLevel(U32 size) ;
+		LLMemoryBlock* addBlock(U32 blk_idx) ;
+		void popAvailBlockList(U32 blk_idx) ;
+		void addToFreeSpace(LLMemoryBlock* blk) ;
+		void removeFromFreeSpace(LLMemoryBlock* blk) ;
+		void removeBlock(LLMemoryBlock* blk) ;
+		void addToAvailBlockList(LLMemoryBlock* blk) ;
+		U32  calcBlockSize(U32 slot_size);
+		LLMemoryBlock* createNewBlock(LLMemoryBlock* blk, U32 buffer_size, U32 slot_size, U32 blk_idx) ;
+
+	private:
+		LLMemoryBlock** mAvailBlockList ;//256 by mMinSlotSize
+		LLMemoryBlock** mFreeSpaceList;
+		LLMemoryBlock*  mBlocks ; //index of blocks by address.
+		
+		char* mBuffer ;
+		U32   mBufferSize ;
+		char* mDataBuffer ;
+		char* mMetaBuffer ;
+		U32   mMinBlockSize ;
+		U32   mMinSlotSize ;
+		U32   mMaxSlotSize ;
+		U32   mAlloatedSize ;
+		U16   mBlockLevels;
+		U16   mPartitionLevels;
+
+	public:
+		//form a linked list
+		LLMemoryChunk* mNext ;
+		LLMemoryChunk* mPrev ;
+	} ;
+
+private:
+	LLPrivateMemoryPool(S32 type) ;
+	~LLPrivateMemoryPool() ;
+
+	char *allocate(U32 size) ;
+	void  freeMem(void* addr) ;
+	
+	void  dump() ;
+	U32   getTotalAllocatedSize() ;
+	U32   getTotalReservedSize() {return mReservedPoolSize;}
+	S32   getType() const {return mType; }
+	bool  isEmpty() const {return !mNumOfChunks; }
+
+private:
+	void lock() ;
+	void unlock() ;	
+	S32 getChunkIndex(U32 size) ;
+	LLMemoryChunk*  addChunk(S32 chunk_index) ;
+	void checkSize(U32 asked_size) ;
+	void removeChunk(LLMemoryChunk* chunk) ;
+	U16  findHashKey(const char* addr);
+	void addToHashTable(LLMemoryChunk* chunk) ;
+	void removeFromHashTable(LLMemoryChunk* chunk) ;
+	void rehash() ;
+	bool fillHashTable(U16 start, U16 end, LLMemoryChunk* chunk) ;
+	LLMemoryChunk* findChunk(const char* addr) ;
+
+	void destroyPool() ;
+
+public:
+	enum
+	{
+		SMALL_ALLOCATION = 0, //from 8 bytes to 2KB(exclusive), page size 2KB, max chunk size is 4MB.
+		MEDIUM_ALLOCATION,    //from 2KB to 512KB(exclusive), page size 32KB, max chunk size 4MB
+		LARGE_ALLOCATION,     //from 512KB to 4MB(inclusive), page size 64KB, max chunk size 16MB
+		SUPER_ALLOCATION      //allocation larger than 4MB.
+	};
+
+	enum
+	{
+		STATIC = 0 ,       //static pool(each alllocation stays for a long time) without threading support
+		VOLATILE,          //Volatile pool(each allocation stays for a very short time) without threading support
+		STATIC_THREADED,   //static pool with threading support
+		VOLATILE_THREADED, //volatile pool with threading support
+		MAX_TYPES
+	}; //pool types
+
+private:
+	LLMutex* mMutexp ;
+	U32  mMaxPoolSize;
+	U32  mReservedPoolSize ;	
+
+	LLMemoryChunk* mChunkList[SUPER_ALLOCATION] ; //all memory chunks reserved by this pool, sorted by address	
+	U16 mNumOfChunks ;
+	U16 mHashFactor ;
+
+	S32 mType ;
+
+	class LLChunkHashElement
+	{
+	public:
+		LLChunkHashElement() {mFirst = NULL ; mSecond = NULL ;}
+
+		bool add(LLMemoryChunk* chunk) ;
+		void remove(LLMemoryChunk* chunk) ;
+		LLMemoryChunk* findChunk(const char* addr) ;
+
+		bool empty() {return !mFirst && !mSecond; }
+		bool full()  {return mFirst && mSecond; }
+		bool hasElement(LLMemoryChunk* chunk) {return mFirst == chunk || mSecond == chunk;}
+
+	private:
+		LLMemoryChunk* mFirst ;
+		LLMemoryChunk* mSecond ;
+	};
+	std::vector<LLChunkHashElement> mChunkHashList ;
+};
+
+class LL_COMMON_API LLPrivateMemoryPoolManager
+{
+private:
+	LLPrivateMemoryPoolManager(BOOL enabled) ;
+	~LLPrivateMemoryPoolManager() ;
+
+public:	
+	static LLPrivateMemoryPoolManager* getInstance() ;
+	static void initClass(BOOL enabled) ;
+	static void destroyClass() ;
+
+	LLPrivateMemoryPool* newPool(S32 type) ;
+	void deletePool(LLPrivateMemoryPool* pool) ;
+
+private:
+	static LLPrivateMemoryPoolManager* sInstance ;
+	std::vector<LLPrivateMemoryPool*> mPoolList ;
+	BOOL mPrivatePoolEnabled;
+
+public:
+	//debug and statistics info.
+	void updateStatistics() ;
+
+	U32 mTotalReservedSize ;
+	U32 mTotalAllocatedSize ;
+
+public:
+#if __DEBUG_PRIVATE_MEM__
+	static char* allocate(LLPrivateMemoryPool* poolp, U32 size, const char* function, const int line) ;	
+	
+	typedef std::map<char*, std::string> mem_allocation_info_t ;
+	static mem_allocation_info_t sMemAllocationTracker;
+#else
+	static char* allocate(LLPrivateMemoryPool* poolp, U32 size) ;	
+#endif
+	static void  freeMem(LLPrivateMemoryPool* poolp, void* addr) ;
+};
+
+//-------------------------------------------------------------------------------------
+#if __DEBUG_PRIVATE_MEM__
+#define ALLOCATE_MEM(poolp, size) LLPrivateMemoryPoolManager::allocate((poolp), (size), __FUNCTION__, __LINE__)
+#else
+#define ALLOCATE_MEM(poolp, size) LLPrivateMemoryPoolManager::allocate((poolp), (size))
+#endif
+#define FREE_MEM(poolp, addr) LLPrivateMemoryPoolManager::freeMem((poolp), (addr))
+//-------------------------------------------------------------------------------------
+
+//
+//the below singleton is used to test the private memory pool.
+//
+#if 0
+class LL_COMMON_API LLPrivateMemoryPoolTester
+{
+private:
+	LLPrivateMemoryPoolTester() ;
+	~LLPrivateMemoryPoolTester() ;
+
+public:
+	static LLPrivateMemoryPoolTester* getInstance() ;
+	static void destroy() ;
+
+	void run(S32 type) ;	
+
+private:
+	void correctnessTest() ;
+	void performanceTest() ;
+	void fragmentationtest() ;
+
+	void test(U32 min_size, U32 max_size, U32 stride, U32 times, bool random_deletion, bool output_statistics) ;
+	void testAndTime(U32 size, U32 times) ;
+
+#if 0
+public:
+	void* operator new(size_t size)
+	{
+		return (void*)sPool->allocate(size) ;
+	}
+    void  operator delete(void* addr)
+	{
+		sPool->freeMem(addr) ;
+	}
+	void* operator new[](size_t size)
+	{
+		return (void*)sPool->allocate(size) ;
+	}
+    void  operator delete[](void* addr)
+	{
+		sPool->freeMem(addr) ;
+	}
+#endif
+
+private:
+	static LLPrivateMemoryPoolTester* sInstance;
+	static LLPrivateMemoryPool* sPool ;
+	static LLPrivateMemoryPool* sThreadedPool ;
+};
+#if 0
+//static
+void* LLPrivateMemoryPoolTester::operator new(size_t size)
+{
+	return (void*)sPool->allocate(size) ;
+}
+
+//static
+void  LLPrivateMemoryPoolTester::operator delete(void* addr)
+{
+	sPool->free(addr) ;
+}
+
+//static
+void* LLPrivateMemoryPoolTester::operator new[](size_t size)
+{
+	return (void*)sPool->allocate(size) ;
+}
+
+//static
+void  LLPrivateMemoryPoolTester::operator delete[](void* addr)
+{
+	sPool->free(addr) ;
+}
+#endif
+#endif
 // LLRefCount moved to llrefcount.h
 
 // LLPointer moved to llpointer.h
diff --git a/indra/llcommon/llscopedvolatileaprpool.h b/indra/llcommon/llscopedvolatileaprpool.h
new file mode 100644
index 0000000000000000000000000000000000000000..dbaf4edcad96d1591b2ca3cd8eee13bb360a9628
--- /dev/null
+++ b/indra/llcommon/llscopedvolatileaprpool.h
@@ -0,0 +1,52 @@
+/**
+ * @file llscopedvolatileaprpool.h
+ * @brief Implementation of LLScopedVolatileAPRPool
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSCOPEDVOLATILEAPRPOOL_H
+#define LL_LLSCOPEDVOLATILEAPRPOOL_H
+
+#include "llthread.h"
+
+/** Scoped volatile memory pool.
+ *
+ * As the LLVolatileAPRPool should never keep allocations very
+ * long, its most common use is for allocations with a lifetime
+ * equal to it's scope.
+ *
+ * This is a convenience class that makes just a little easier to type.
+ */
+class LL_COMMON_API LLScopedVolatileAPRPool
+{
+private:
+	LLVolatileAPRPool& mPool;
+	apr_pool_t* mScopedAPRpool;		// The use of apr_pool_t is OK here.
+public:
+	LLScopedVolatileAPRPool() : mPool(LLThreadLocalData::tldata().mVolatileAPRPool), mScopedAPRpool(mPool.getVolatileAPRPool()) { }
+	~LLScopedVolatileAPRPool() { mPool.clearVolatileAPRPool(); }
+	//! @attention Only use this to pass the underlaying pointer to a libapr-1 function that requires it.
+	operator apr_pool_t*() const { return mScopedAPRpool; }		// The use of apr_pool_t is OK here.
+};
+
+#endif
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 00757be27744c29f78b80aa72897500d0cff7553..49d99f2cd0fe7f0cf1665115dc83d0d883b98c24 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -114,8 +114,7 @@ class LLSingleton : private boost::noncopyable
 
 		~SingletonInstanceData()
 		{
-			SingletonInstanceData& data = getData();
-			if (data.mInitState != DELETED)
+			if (mInitState != DELETED)
 			{
 				deleteSingleton();
 			}
@@ -130,7 +129,26 @@ class LLSingleton : private boost::noncopyable
 		data.mInitState = DELETED;
 	}
 
-	// Can be used to control when the singleton is deleted.  Not normally needed.
+	/**
+	 * @brief Immediately delete the singleton.
+	 *
+	 * A subsequent call to LLProxy::getInstance() will construct a new
+	 * instance of the class.
+	 *
+	 * LLSingletons are normally destroyed after main() has exited and the C++
+	 * runtime is cleaning up statically-constructed objects. Some classes
+	 * derived from LLSingleton have objects that are part of a runtime system
+	 * that is terminated before main() exits. Calling the destructor of those
+	 * objects after the termination of their respective systems can cause
+	 * crashes and other problems during termination of the project. Using this
+	 * method to destroy the singleton early can prevent these crashes.
+	 *
+	 * An example where this is needed is for a LLSingleton that has an APR
+	 * object as a member that makes APR calls on destruction. The APR system is
+	 * shut down explicitly before main() exits. This causes a crash on exit.
+	 * Using this method before the call to apr_terminate() and NOT calling
+	 * getInstance() again will prevent the crash.
+	 */
 	static void deleteSingleton()
 	{
 		delete getData().mSingletonInstance;
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index f3b48b0156060fa66709849fd253dcf4de54edf6..e7fe6568085e8b0691f160bf312359f6f7822c42 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -936,13 +936,18 @@ LLStringUtil::size_type LLStringUtil::getSubstitution(const std::string& instr,
 {
 	const std::string delims (",");
 	
-	// Find the first ]
-	size_type pos2 = instr.find(']', start);
+	// Find the first [
+	size_type pos1 = instr.find('[', start);
+	if (pos1 == std::string::npos)
+		return std::string::npos;
+
+	//Find the first ] after the initial [
+	size_type pos2 = instr.find(']', pos1);
 	if (pos2 == std::string::npos)
 		return std::string::npos;
 
-	// Find the last [ before ]
-	size_type pos1 = instr.find_last_of('[', pos2-1);
+	// Find the last [ before ] in case of nested [[]]
+	pos1 = instr.find_last_of('[', pos2-1);
 	if (pos1 == std::string::npos || pos1 < start)
 		return std::string::npos;
 	
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 4063cc730b49e5b470c6f534f19dc49b4e015218..bdde1b5c48fdb4ed345029920c80a5834b71dd50 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -36,6 +36,12 @@
 #include <sched.h>
 #endif
 
+#if !LL_DARWIN
+U32 ll_thread_local local_thread_ID = 0;
+#endif 
+
+U32 LLThread::sIDIter = 0;
+
 //----------------------------------------------------------------------------
 // Usage:
 // void run_func(LLThread* thread)
@@ -56,12 +62,6 @@
 // 
 //----------------------------------------------------------------------------
 
-#if !LL_DARWIN
-U32 ll_thread_local sThreadID = 0;
-#endif 
-
-U32 LLThread::sIDIter = 0;
-
 LL_COMMON_API void assert_main_thread()
 {
 	static U32 s_thread_id = LLThread::currentID();
@@ -79,9 +79,12 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
 	LLThread *threadp = (LLThread *)datap;
 
 #if !LL_DARWIN
-	sThreadID = threadp->mID;
+	local_thread_ID = threadp->mID;
 #endif
 
+	// Create a thread local data.
+	LLThreadLocalData::create(threadp);
+
 	// Run the user supplied function
 	threadp->run();
 
@@ -94,40 +97,22 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
 }
 
 
-LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
-	mPaused(FALSE),
+LLThread::LLThread(std::string const& name) :
+	mPaused(false),
 	mName(name),
 	mAPRThreadp(NULL),
-	mStatus(STOPPED)
+	mStatus(STOPPED),
+	mThreadLocalData(NULL)
 {
-	mID = ++sIDIter;
+	mID = ++sIDIter; //flaw: assume this is called only in the main thread!
 
-	// Thread creation probably CAN be paranoid about APR being initialized, if necessary
-	if (poolp)
-	{
-		mIsLocalPool = FALSE;
-		mAPRPoolp = poolp;
-	}
-	else
-	{
-		mIsLocalPool = TRUE;
-		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
-	}
-	mRunCondition = new LLCondition(mAPRPoolp);
-
-	mLocalAPRFilePoolp = NULL ;
+	mRunCondition = new LLCondition;
 }
 
 
 LLThread::~LLThread()
 {
 	shutdown();
-
-	if(mLocalAPRFilePoolp)
-	{
-		delete mLocalAPRFilePoolp ;
-		mLocalAPRFilePoolp = NULL ;
-	}
 }
 
 void LLThread::shutdown()
@@ -164,7 +149,7 @@ void LLThread::shutdown()
 		if (!isStopped())
 		{
 			// This thread just wouldn't stop, even though we gave it time
-			//llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl;
+			//llwarns << "LLThread::shutdown() exiting thread before clean exit!" << llendl;
 			// Put a stake in its heart.
 			apr_thread_exit(mAPRThreadp, -1);
 			return;
@@ -174,15 +159,8 @@ void LLThread::shutdown()
 
 	delete mRunCondition;
 	mRunCondition = 0;
-	
-	if (mIsLocalPool && mAPRPoolp)
-	{
-		apr_pool_destroy(mAPRPoolp);
-		mAPRPoolp = 0;
-	}
 }
 
-
 void LLThread::start()
 {
 	llassert(isStopped());
@@ -191,7 +169,7 @@ void LLThread::start()
 	mStatus = RUNNING;
 
 	apr_status_t status =
-		apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
+		apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool());
 	
 	if(status == APR_SUCCESS)
 	{	
@@ -216,7 +194,7 @@ void LLThread::pause()
 	if (!mPaused)
 	{
 		// this will cause the thread to stop execution as soon as checkPause() is called
-		mPaused = 1;		// Does not need to be atomic since this is only set/unset from the main thread
+		mPaused = true;		// Does not need to be atomic since this is only set/unset from the main thread
 	}	
 }
 
@@ -224,7 +202,7 @@ void LLThread::unpause()
 {
 	if (mPaused)
 	{
-		mPaused = 0;
+		mPaused = false;
 	}
 
 	wake(); // wake up the thread if necessary
@@ -301,116 +279,76 @@ void LLThread::wakeLocked()
 	}
 }
 
-//============================================================================
-
-LLMutex::LLMutex(apr_pool_t *poolp) :
-	mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD)
-{
-	//if (poolp)
-	//{
-	//	mIsLocalPool = FALSE;
-	//	mAPRPoolp = poolp;
-	//}
-	//else
-	{
-		mIsLocalPool = TRUE;
-		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
-	}
-	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
-}
+#ifdef SHOW_ASSERT
+// This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread.
+static apr_os_thread_t main_thread_id;
+LL_COMMON_API bool is_main_thread(void) { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); }
+#endif
 
+// The thread private handle to access the LLThreadLocalData instance.
+apr_threadkey_t* LLThreadLocalData::sThreadLocalDataKey;
 
-LLMutex::~LLMutex()
+//static
+void LLThreadLocalData::init(void)
 {
-#if MUTEX_DEBUG
-	//bad assertion, the subclass LLSignal might be "locked", and that's OK
-	//llassert_always(!isLocked()); // better not be locked!
-#endif
-	apr_thread_mutex_destroy(mAPRMutexp);
-	mAPRMutexp = NULL;
-	if (mIsLocalPool)
+	// Only do this once.
+	if (sThreadLocalDataKey)
 	{
-		apr_pool_destroy(mAPRPoolp);
+		return;
 	}
-}
 
+	apr_status_t status = apr_threadkey_private_create(&sThreadLocalDataKey, &LLThreadLocalData::destroy, LLAPRRootPool::get()());
+	ll_apr_assert_status(status);   // Or out of memory, or system-imposed limit on the
+									// total number of keys per process {PTHREAD_KEYS_MAX}
+									// has been exceeded.
 
-void LLMutex::lock()
-{
-#if LL_DARWIN
-	if (mLockingThread == LLThread::currentID())
-#else
-	if (mLockingThread == sThreadID)
-#endif
-	{ //redundant lock
-		mCount++;
-		return;
-	}
-	
-	apr_thread_mutex_lock(mAPRMutexp);
-	
-#if MUTEX_DEBUG
-	// Have to have the lock before we can access the debug info
-	U32 id = LLThread::currentID();
-	if (mIsLocked[id] != FALSE)
-		llerrs << "Already locked in Thread: " << id << llendl;
-	mIsLocked[id] = TRUE;
-#endif
+	// Create the thread-local data for the main thread (this function is called by the main thread).
+	LLThreadLocalData::create(NULL);
 
-#if LL_DARWIN
-	mLockingThread = LLThread::currentID();
-#else
-	mLockingThread = sThreadID;
+#ifdef SHOW_ASSERT
+	// This function is called by the main thread.
+	main_thread_id = apr_os_thread_current();
 #endif
 }
 
-void LLMutex::unlock()
+// This is called once for every thread when the thread is destructed.
+//static
+void LLThreadLocalData::destroy(void* thread_local_data)
 {
-	if (mCount > 0)
-	{ //not the root unlock
-		mCount--;
-		return;
-	}
-	
-#if MUTEX_DEBUG
-	// Access the debug info while we have the lock
-	U32 id = LLThread::currentID();
-	if (mIsLocked[id] != TRUE)
-		llerrs << "Not locked in Thread: " << id << llendl;	
-	mIsLocked[id] = FALSE;
-#endif
-
-	mLockingThread = NO_THREAD;
-	apr_thread_mutex_unlock(mAPRMutexp);
+	delete static_cast<LLThreadLocalData*>(thread_local_data);
 }
 
-bool LLMutex::isLocked()
+//static
+void LLThreadLocalData::create(LLThread* threadp)
 {
-	apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp);
-	if (APR_STATUS_IS_EBUSY(status))
+	LLThreadLocalData* new_tld = new LLThreadLocalData;
+	if (threadp)
 	{
-		return true;
-	}
-	else
-	{
-		apr_thread_mutex_unlock(mAPRMutexp);
-		return false;
+		threadp->mThreadLocalData = new_tld;
 	}
+	apr_status_t status = apr_threadkey_private_set(new_tld, sThreadLocalDataKey);
+	llassert_always(status == APR_SUCCESS);
 }
 
-U32 LLMutex::lockingThread() const
+//static
+LLThreadLocalData& LLThreadLocalData::tldata(void)
 {
-	return mLockingThread;
+	if (!sThreadLocalDataKey)
+	{
+		LLThreadLocalData::init();
+	}
+
+	void* data;
+	apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey);
+	llassert_always(status == APR_SUCCESS);
+	return *static_cast<LLThreadLocalData*>(data);
 }
 
 //============================================================================
 
-LLCondition::LLCondition(apr_pool_t *poolp) :
-	LLMutex(poolp)
+LLCondition::LLCondition(LLAPRPool& parent) : LLMutex(parent)
 {
-	// base class (LLMutex) has already ensured that mAPRPoolp is set up.
-
-	apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
+	apr_thread_cond_create(&mAPRCondp, mPool());
 }
 
 
@@ -423,15 +361,6 @@ LLCondition::~LLCondition()
 
 void LLCondition::wait()
 {
-	if (!isLocked())
-	{ //mAPRMutexp MUST be locked before calling apr_thread_cond_wait
-		apr_thread_mutex_lock(mAPRMutexp);
-#if MUTEX_DEBUG
-		// avoid asserts on destruction in non-release builds
-		U32 id = LLThread::currentID();
-		mIsLocked[id] = TRUE;
-#endif
-	}
 	apr_thread_cond_wait(mAPRCondp, mAPRMutexp);
 }
 
@@ -446,6 +375,44 @@ void LLCondition::broadcast()
 }
 
 //============================================================================
+LLMutexBase::LLMutexBase() :
+	mLockingThread(NO_THREAD),
+	mCount(0)
+{
+}
+
+void LLMutexBase::lock() 
+{ 
+#if LL_DARWIN
+	if (mLockingThread == LLThread::currentID())
+#else
+	if (mLockingThread == local_thread_ID)
+#endif
+	{ //redundant lock
+		mCount++;
+		return;
+	}
+
+	apr_thread_mutex_lock(mAPRMutexp); 
+
+#if LL_DARWIN
+	mLockingThread = LLThread::currentID();
+#else
+	mLockingThread = local_thread_ID;
+#endif
+}
+
+void LLMutexBase::unlock() 
+{ 
+	if (mCount > 0)
+	{ //not the root unlock
+		mCount--;
+		return;
+	}
+	mLockingThread = NO_THREAD;
+
+	apr_thread_mutex_unlock(mAPRMutexp); 
+}
 
 //----------------------------------------------------------------------------
 
@@ -457,7 +424,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount()
 {
 	if (!sMutex)
 	{
-		sMutex = new LLMutex(0);
+		sMutex = new LLMutex;
 	}
 }
 
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 40291a25693717f212f835c9909ceb48ad79cd0d..b631b96252f0b6a1dea8db677c67a753f4c5ceed 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -29,7 +29,13 @@
 
 #include "llapp.h"
 #include "llapr.h"
+#include "llmemory.h"
 #include "apr_thread_cond.h"
+#include "llaprpool.h"
+
+#ifdef SHOW_ASSERT
+extern LL_COMMON_API bool is_main_thread(void);
+#endif
 
 class LLThread;
 class LLMutex;
@@ -41,6 +47,22 @@ class LLCondition;
 #define ll_thread_local __thread
 #endif
 
+class LL_COMMON_API LLThreadLocalData
+{
+private:
+	static apr_threadkey_t* sThreadLocalDataKey;
+
+public:
+	// Thread-local memory pools.
+	LLAPRRootPool mRootPool;
+	LLVolatileAPRPool mVolatileAPRPool;
+
+	static void init(void);
+	static void destroy(void* thread_local_data);
+	static void create(LLThread* pthread);
+	static LLThreadLocalData& tldata(void);
+};
+
 class LL_COMMON_API LLThread
 {
 private:
@@ -54,7 +76,7 @@ class LL_COMMON_API LLThread
 		QUITTING= 2 	// Someone wants this thread to quit
 	} EThreadStatus;
 
-	LLThread(const std::string& name, apr_pool_t *poolp = NULL);
+	LLThread(std::string const& name);
 	virtual ~LLThread(); // Warning!  You almost NEVER want to destroy a thread unless it's in the STOPPED state.
 	virtual void shutdown(); // stops the thread
 	
@@ -69,7 +91,7 @@ class LL_COMMON_API LLThread
 	// Called from MAIN THREAD.
 	void pause();
 	void unpause();
-	bool isPaused() { return isStopped() || mPaused == TRUE; }
+	bool isPaused() { return isStopped() || mPaused; }
 	
 	// Cause the thread to wake up and check its condition
 	void wake();
@@ -83,13 +105,11 @@ class LL_COMMON_API LLThread
 	// this kicks off the apr thread
 	void start(void);
 
-	apr_pool_t *getAPRPool() { return mAPRPoolp; }
-	LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
-
-	U32 getID() const { return mID; }
+	// Return thread-local data for the current thread.
+	static LLThreadLocalData& tldata(void) { return LLThreadLocalData::tldata(); }
 
 private:
-	BOOL				mPaused;
+	bool				mPaused;
 	
 	// static function passed to APR thread creation routine
 	static void *APR_THREAD_FUNC staticRun(apr_thread_t *apr_threadp, void *datap);
@@ -99,15 +119,11 @@ class LL_COMMON_API LLThread
 	LLCondition*		mRunCondition;
 
 	apr_thread_t		*mAPRThreadp;
-	apr_pool_t			*mAPRPoolp;
-	BOOL				mIsLocalPool;
 	EThreadStatus		mStatus;
 	U32					mID;
-
-	//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
-	//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
-	//      otherwise it will cause severe memory leaking!!! --bao
-	LLVolatileAPRPool  *mLocalAPRFilePoolp ; 
+	
+	friend void LLThreadLocalData::create(LLThread* threadp);
+	LLThreadLocalData*	mThreadLocalData;
 
 	void setQuitting();
 	
@@ -137,7 +153,15 @@ class LL_COMMON_API LLThread
 
 #define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
 
-class LL_COMMON_API LLMutex
+#ifdef MUTEX_DEBUG
+// We really shouldn't be using recursive locks. Make sure of that in debug mode.
+#define MUTEX_FLAG APR_THREAD_MUTEX_UNNESTED
+#else
+// Use the fastest platform-optimal lock behavior (can be recursive or non-recursive).
+#define MUTEX_FLAG APR_THREAD_MUTEX_DEFAULT
+#endif
+
+class LL_COMMON_API LLMutexBase
 {
 public:
 	typedef enum
@@ -145,32 +169,74 @@ class LL_COMMON_API LLMutex
 		NO_THREAD = 0xFFFFFFFF
 	} e_locking_thread;
 
-	LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex
-	virtual ~LLMutex();
-	
-	void lock();		// blocks
-	void unlock();
-	bool isLocked(); 	// non-blocking, but does do a lock/unlock so not free
-	U32 lockingThread() const; //get ID of locking thread
-	
+	LLMutexBase() ;
+
+	void lock() ;
+	void unlock() ;
+	// Returns true if lock was obtained successfully.
+	bool trylock() { return !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)); }
+
+	// non-blocking, but does do a lock/unlock so not free
+	bool isLocked() { bool is_not_locked = trylock(); if (is_not_locked) unlock(); return !is_not_locked; }
+
 protected:
-	apr_thread_mutex_t *mAPRMutexp;
+	// mAPRMutexp is initialized and uninitialized in the derived class.
+	apr_thread_mutex_t* mAPRMutexp;
 	mutable U32			mCount;
 	mutable U32			mLockingThread;
-	
-	apr_pool_t			*mAPRPoolp;
-	BOOL				mIsLocalPool;
-	
-#if MUTEX_DEBUG
-	std::map<U32, BOOL> mIsLocked;
+};
+
+class LL_COMMON_API LLMutex : public LLMutexBase
+{
+public:
+	LLMutex(LLAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent)
+	{
+		apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mPool());
+	}
+	~LLMutex()
+	{
+		//this assertion erroneously triggers whenever an LLCondition is destroyed
+		//llassert(!isLocked()); // better not be locked!
+		apr_thread_mutex_destroy(mAPRMutexp);
+		mAPRMutexp = NULL;
+	}
+
+protected:
+	LLAPRPool mPool;
+};
+
+#if APR_HAS_THREADS
+// No need to use a root pool in this case.
+typedef LLMutex LLMutexRootPool;
+#else // APR_HAS_THREADS
+class LL_COMMON_API LLMutexRootPool : public LLMutexBase
+{
+public:
+	LLMutexRootPool(void)
+	{
+		apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mRootPool());
+	}
+	~LLMutexRootPool()
+	{
+#if APR_POOL_DEBUG
+		// It is allowed to destruct root pools from a different thread.
+		mRootPool.grab_ownership();
 #endif
+		llassert(!isLocked());
+		apr_thread_mutex_destroy(mAPRMutexp);
+		mAPRMutexp = NULL;
+	}
+
+protected:
+	LLAPRRootPool mRootPool;
 };
+#endif // APR_HAS_THREADS
 
 // Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
 class LL_COMMON_API LLCondition : public LLMutex
 {
 public:
-	LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well.
+	LLCondition(LLAPRPool& parent = LLThread::tldata().mRootPool);
 	~LLCondition();
 	
 	void wait();		// blocks
@@ -181,10 +247,10 @@ class LL_COMMON_API LLCondition : public LLMutex
 	apr_thread_cond_t *mAPRCondp;
 };
 
-class LLMutexLock
+class LL_COMMON_API LLMutexLock
 {
 public:
-	LLMutexLock(LLMutex* mutex)
+	LLMutexLock(LLMutexBase* mutex)
 	{
 		mMutex = mutex;
 		mMutex->lock();
@@ -194,7 +260,7 @@ class LLMutexLock
 		mMutex->unlock();
 	}
 private:
-	LLMutex* mMutex;
+	LLMutexBase* mMutex;
 };
 
 //============================================================================
diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp
index 8a73e632a9ada2249b4353f88828d5d66fcfe00d..05d24944f3e3ae4223eb35ca998fb284c5614967 100644
--- a/indra/llcommon/llthreadsafequeue.cpp
+++ b/indra/llcommon/llthreadsafequeue.cpp
@@ -34,19 +34,11 @@
 //-----------------------------------------------------------------------------
 
 
-LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity):
-	mOwnsPool(pool == 0),
-	mPool(pool),
+LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(unsigned int capacity):
 	mQueue(0)
 {
-	if(mOwnsPool) {
-		apr_status_t status = apr_pool_create(&mPool, 0);
-		if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate pool");
-	} else {
-		; // No op.
-	}
-	
-	apr_status_t status = apr_queue_create(&mQueue, capacity, mPool);
+	mPool.create();
+	apr_status_t status = apr_queue_create(&mQueue, capacity, mPool());
 	if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue");
 }
 
@@ -59,7 +51,6 @@ LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation()
 			" elements;" << "memory will be leaked" << LL_ENDL;
 		apr_queue_term(mQueue);
 	}
-	if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool);
 }
 
 
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 58cac38769cd2d3801fc9f01b1d1cc2a010ae0c6..43d0b396f2494059192e0ae61533f64a69ae4b17 100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -30,9 +30,9 @@
 
 #include <string>
 #include <stdexcept>
+#include "llaprpool.h"
 
 
-struct apr_pool_t; // From apr_pools.h
 class LLThreadSafeQueueImplementation; // See below.
 
 
@@ -75,7 +75,7 @@ struct apr_queue_t; // From apr_queue.h
 class LL_COMMON_API LLThreadSafeQueueImplementation
 {
 public:
-	LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity);
+	LLThreadSafeQueueImplementation(unsigned int capacity);
 	~LLThreadSafeQueueImplementation();
 	void pushFront(void * element);
 	bool tryPushFront(void * element);
@@ -84,8 +84,7 @@ class LL_COMMON_API LLThreadSafeQueueImplementation
 	size_t size();
 	
 private:
-	bool mOwnsPool;
-	apr_pool_t * mPool;
+	LLAPRPool mPool;			// The pool used for mQueue.
 	apr_queue_t * mQueue;
 };
 
@@ -99,9 +98,8 @@ class LLThreadSafeQueue
 public:
 	typedef ElementT value_type;
 	
-	// If the pool is set to NULL one will be allocated and managed by this
-	// queue.
-	LLThreadSafeQueue(apr_pool_t * pool = 0, unsigned int capacity = 1024);
+	// Constructor.
+	LLThreadSafeQueue(unsigned int capacity = 1024);
 	
 	// Add an element to the front of queue (will block if the queue has
 	// reached capacity).
@@ -139,8 +137,8 @@ class LLThreadSafeQueue
 
 
 template<typename ElementT>
-LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity):
-	mImplementation(pool, capacity)
+LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(unsigned int capacity) :
+	mImplementation(capacity)
 {
 	; // No op.
 }
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
old mode 100755
new mode 100644
index 324507fe7a5aff6357ea0a11e548330e865a77b7..ef55cfec893e83cd731263a0db46dfe234294bb7
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -29,7 +29,7 @@
 
 const S32 LL_VERSION_MAJOR = 3;
 const S32 LL_VERSION_MINOR = 0;
-const S32 LL_VERSION_PATCH = 4;
+const S32 LL_VERSION_PATCH = 5;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 3ac50832fda64969a0bedcb6707216999e7c69cd..6b308bb9179eeff39de601357c054ebcc51c0771 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -37,12 +37,7 @@
 LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) :
 	LLQueuedThread(name, threaded)
 {
-	mDeleteMutex = new LLMutex(NULL);
-
-	if(!mLocalAPRFilePoolp)
-	{
-		mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
-	}
+	mDeleteMutex = new LLMutex;
 }
 
 LLWorkerThread::~LLWorkerThread()
@@ -204,7 +199,6 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na
 	  mWorkerClassName(name),
 	  mRequestHandle(LLWorkerThread::nullHandle()),
 	  mRequestPriority(LLWorkerThread::PRIORITY_NORMAL),
-	  mMutex(NULL),
 	  mWorkFlags(0)
 {
 	if (!mWorkerThread)
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index 9bff18303eb944312d83cb9eaa5e249d325de5bc..bef5ef53fe4fd4f97753429e09bd4c5fd1ba8708 100644
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
@@ -94,7 +94,6 @@ class LL_COMMON_API LLWorkerThread : public LLQueuedThread
 
 private:
 	void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion
-	
 };
 
 //============================================================================
@@ -194,7 +193,7 @@ class LL_COMMON_API LLWorkerClass
 	U32 mRequestPriority; // last priority set
 
 private:
-	LLMutex mMutex;
+	LLMutexRootPool mMutex;		// Use LLMutexRootPool since this object is created and destructed by multiple threads.
 	LLAtomicU32 mWorkFlags;
 };
 
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index 80b35bbdc38981ba3f4eb4670c35157d95031aed..b34d1c5fd34c266e14b8abc1595f8795408dc63f 100644
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -40,6 +40,7 @@
 #include <boost/scoped_ptr.hpp>
 // other Linden headers
 #include "../test/lltut.h"
+#include "wrapllerrs.h"
 
 struct Keyed: public LLInstanceTracker<Keyed, std::string>
 {
@@ -165,4 +166,67 @@ namespace tut
 
         ensure_equals("unreported instance", instances.size(), 0);
     }
+
+    template<> template<>
+    void object::test<5>()
+    {
+        set_test_name("delete Keyed with outstanding instance_iter");
+        std::string what;
+        Keyed* keyed = new Keyed("one");
+        {
+            WrapLL_ERRS wrapper;
+            Keyed::instance_iter i(Keyed::beginInstances());
+            try
+            {
+                delete keyed;
+            }
+            catch (const WrapLL_ERRS::FatalException& e)
+            {
+                what = e.what();
+            }
+        }
+        ensure(! what.empty());
+    }
+
+    template<> template<>
+    void object::test<6>()
+    {
+        set_test_name("delete Keyed with outstanding key_iter");
+        std::string what;
+        Keyed* keyed = new Keyed("one");
+        {
+            WrapLL_ERRS wrapper;
+            Keyed::key_iter i(Keyed::beginKeys());
+            try
+            {
+                delete keyed;
+            }
+            catch (const WrapLL_ERRS::FatalException& e)
+            {
+                what = e.what();
+            }
+        }
+        ensure(! what.empty());
+    }
+
+    template<> template<>
+    void object::test<7>()
+    {
+        set_test_name("delete Unkeyed with outstanding instance_iter");
+        std::string what;
+        Unkeyed* unkeyed = new Unkeyed;
+        {
+            WrapLL_ERRS wrapper;
+            Unkeyed::instance_iter i(Unkeyed::beginInstances());
+            try
+            {
+                delete unkeyed;
+            }
+            catch (const WrapLL_ERRS::FatalException& e)
+            {
+                what = e.what();
+            }
+        }
+        ensure(! what.empty());
+    }
 } // namespace tut
diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..385289aefef69b16997148840929fe7b94963c3f
--- /dev/null
+++ b/indra/llcommon/tests/llsingleton_test.cpp
@@ -0,0 +1,76 @@
+/** 
+ * @file llsingleton_test.cpp
+ * @date 2011-08-11
+ * @brief Unit test for the LLSingleton class
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llsingleton.h"
+#include "../test/lltut.h"
+
+namespace tut
+{
+	struct singleton
+	{
+		// We need a class created with the LLSingleton template to test with.
+		class LLSingletonTest: public LLSingleton<LLSingletonTest>
+		{
+
+		};
+	};
+
+	typedef test_group<singleton> singleton_t;
+	typedef singleton_t::object singleton_object_t;
+	tut::singleton_t tut_singleton("LLSingleton");
+
+	template<> template<>
+	void singleton_object_t::test<1>()
+	{
+
+	}
+	template<> template<>
+	void singleton_object_t::test<2>()
+	{
+		LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+		ensure(singleton_test);
+	}
+	template<> template<>
+	void singleton_object_t::test<3>()
+	{
+		//Construct the instance
+		LLSingletonTest::getInstance();
+		ensure(LLSingletonTest::instanceExists());
+
+		//Delete the instance
+		LLSingletonTest::deleteSingleton();
+		ensure(LLSingletonTest::destroyed());
+		ensure(!LLSingletonTest::instanceExists());
+
+		//Construct it again.
+		LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+		ensure(singleton_test);
+		ensure(LLSingletonTest::instanceExists());
+	}
+}
diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp
index 304e91ed927ed434c90764869ae3556850c82cfa..6a1cbf652a2ff9442db30eea5d317338a56e796d 100644
--- a/indra/llcommon/tests/llstring_test.cpp
+++ b/indra/llcommon/tests/llstring_test.cpp
@@ -624,6 +624,14 @@ namespace tut
 		subcount = LLStringUtil::format(s, fmt_map);
 		ensure_equals("LLStringUtil::format: Assorted Test2 result", s, "?Am I not a long string?short[A]bbbaaaba[A]");
 		ensure_equals("LLStringUtil::format: Assorted Test2 result count", 9, subcount);
+		
+		// Test on nested brackets
+		std::string srcs6 = "[[TRICK1]][[A]][[B]][[AAA]][[BBB]][[TRICK2]][[KEYLONGER]][[KEYSHORTER]]?[[DELETE]]";
+		s = srcs6;
+		subcount = LLStringUtil::format(s, fmt_map);
+		ensure_equals("LLStringUtil::format: Assorted Test2 result", s, "[[A]][a][b][aaa][bbb][[A]][short][Am I not a long string?]?[]");
+		ensure_equals("LLStringUtil::format: Assorted Test2 result count", 9, subcount);
+
 
 		// Test an assorted substitution
 		std::string srcs8 = "foo[DELETE]bar?";
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 331a1692ee8abff68e12d4d02173634011f1741d..514ef6011f82363b6f264eded30a6b8719c1ec80 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -414,8 +414,7 @@ bool LLCrashLogger::init()
 		return false;
 	}
 
-	gServicePump = new LLPumpIO(gAPRPoolp);
-	gServicePump->prime(gAPRPoolp);
+	gServicePump = new LLPumpIO;
 	LLHTTPClient::setPump(*gServicePump);
 
 	//If we've opened the crash logger, assume we can delete the marker file if it exists
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index f0d15d9607f6d49597337da5cfcba535c0b2bcf6..23adbf68c88ea913fce5fb859343e9d730dfa5fe 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -39,6 +39,7 @@
 #include "llimagepng.h"
 #include "llimagedxt.h"
 #include "llimageworker.h"
+#include "llmemory.h"
 
 //---------------------------------------------------------------------------
 // LLImage
@@ -47,11 +48,14 @@
 //static
 std::string LLImage::sLastErrorMessage;
 LLMutex* LLImage::sMutex = NULL;
+LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;
 
 //static
 void LLImage::initClass()
 {
-	sMutex = new LLMutex(NULL);
+	sMutex = new LLMutex;
+
+	LLImageBase::createPrivatePool() ;
 }
 
 //static
@@ -59,6 +63,8 @@ void LLImage::cleanupClass()
 {
 	delete sMutex;
 	sMutex = NULL;
+
+	LLImageBase::destroyPrivatePool() ;
 }
 
 //static
@@ -97,6 +103,25 @@ LLImageBase::~LLImageBase()
 	deleteData(); // virtual
 }
 
+//static 
+void LLImageBase::createPrivatePool() 
+{
+	if(!sPrivatePoolp)
+	{
+		sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC_THREADED) ;
+	}
+}
+	
+//static 
+void LLImageBase::destroyPrivatePool() 
+{
+	if(sPrivatePoolp)
+	{
+		LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp) ;
+		sPrivatePoolp = NULL ;
+	}
+}
+
 // virtual
 void LLImageBase::dump()
 {
@@ -130,7 +155,7 @@ void LLImageBase::sanityCheck()
 // virtual
 void LLImageBase::deleteData()
 {
-	delete[] mData;
+	FREE_MEM(sPrivatePoolp, mData) ;
 	mData = NULL;
 	mDataSize = 0;
 }
@@ -167,7 +192,7 @@ U8* LLImageBase::allocateData(S32 size)
 	{
 		deleteData(); // virtual
 		mBadBufferAllocation = false ;
-		mData = new U8[size];
+		mData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
 		if (!mData)
 		{
 			llwarns << "allocate image data: " << size << llendl;
@@ -185,7 +210,7 @@ U8* LLImageBase::allocateData(S32 size)
 U8* LLImageBase::reallocateData(S32 size)
 {
 	LLMemType mt1(mMemType);
-	U8 *new_datap = new U8[size];
+	U8 *new_datap = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
 	if (!new_datap)
 	{
 		llwarns << "Out of memory in LLImageBase::reallocateData" << llendl;
@@ -195,7 +220,7 @@ U8* LLImageBase::reallocateData(S32 size)
 	{
 		S32 bytes = llmin(mDataSize, size);
 		memcpy(new_datap, mData, bytes);	/* Flawfinder: ignore */
-		delete[] mData;
+		FREE_MEM(sPrivatePoolp, mData) ;
 	}
 	mData = new_datap;
 	mDataSize = size;
@@ -341,6 +366,7 @@ BOOL LLImageRaw::resize(U16 width, U16 height, S8 components)
 	return TRUE;
 }
 
+#if 0
 U8 * LLImageRaw::getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const
 {
 	LLMemType mt1(mMemType);
@@ -361,6 +387,7 @@ U8 * LLImageRaw::getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const
 	}
 	return data;
 }
+#endif
 
 BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
 							 const U8 *data, U32 stride, BOOL reverse_y)
@@ -830,6 +857,7 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
 	}
 }
 
+#if 0
 //scale down image by not blending a pixel with its neighbors.
 BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height)
 {
@@ -853,7 +881,7 @@ BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height)
 	ratio_x -= 1.0f ;
 	ratio_y -= 1.0f ;
 
-	U8* new_data = new U8[new_data_size] ;
+	U8* new_data = allocateMemory(new_data_size) ;
 	llassert_always(new_data != NULL) ;
 
 	U8* old_data = getData() ;
@@ -875,6 +903,7 @@ BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height)
 	
 	return TRUE ;
 }
+#endif
 
 BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
 {
@@ -1506,6 +1535,7 @@ void LLImageFormatted::setData(U8 *data, S32 size)
 	{
 		deleteData();
 		setDataAndSize(data, size); // Access private LLImageBase members
+
 		sGlobalFormattedMemory += getDataSize();
 	}
 }
@@ -1524,7 +1554,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size)
 			S32 newsize = cursize + size;
 			reallocateData(newsize);
 			memcpy(getData() + cursize, data, size);
-			delete[] data;
+			FREE_MEM(LLImageBase::getPrivatePool(), data);
 		}
 	}
 }
@@ -1536,8 +1566,7 @@ BOOL LLImageFormatted::load(const std::string &filename)
 	resetLastError();
 
 	S32 file_size = 0;
-	LLAPRFile infile ;
-	infile.open(filename, LL_APR_RB, NULL, &file_size);
+	LLAPRFile infile(filename, LL_APR_RB, &file_size);
 	apr_file_t* apr_file = infile.getFileHandle();
 	if (!apr_file)
 	{
@@ -1572,8 +1601,7 @@ BOOL LLImageFormatted::save(const std::string &filename)
 {
 	resetLastError();
 
-	LLAPRFile outfile ;
-	outfile.open(filename, LL_APR_WB);
+	LLAPRFile outfile(filename, LL_APR_WB);
 	if (!outfile.getFileHandle())
 	{
 		setLastError("Unable to open file for writing", filename);
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index c464c3b2b67e01fe2a692331978bd9771d282852..4469c9e86025e628d2b1100c6d8c85baaa604c93 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -29,7 +29,6 @@
 
 #include "lluuid.h"
 #include "llstring.h"
-//#include "llmemory.h"
 #include "llthread.h"
 #include "llmemtype.h"
 
@@ -69,6 +68,7 @@ const S32 MAX_IMG_PACKET_SIZE = 1000;
 class LLImageFormatted;
 class LLImageRaw;
 class LLColor4U;
+class LLPrivateMemoryPool;
 
 typedef enum e_image_codec
 {
@@ -140,7 +140,7 @@ class LLImageBase : public LLThreadSafeRefCount
 
 protected:
 	// special accessor to allow direct setting of mData and mDataSize by LLImageFormatted
-	void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; }
+	void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; }	
 	
 public:
 	static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels);
@@ -151,6 +151,10 @@ class LLImageBase : public LLThreadSafeRefCount
 
 	static EImageCodec getCodecFromExtension(const std::string& exten);
 	
+	static void createPrivatePool() ;
+	static void destroyPrivatePool() ;
+	static LLPrivateMemoryPool* getPrivatePool() {return sPrivatePoolp;}
+
 private:
 	U8 *mData;
 	S32 mDataSize;
@@ -162,6 +166,8 @@ class LLImageBase : public LLThreadSafeRefCount
 
 	bool mBadBufferAllocation ;
 	bool mAllowOverSize ;
+
+	static LLPrivateMemoryPool* sPrivatePoolp ;
 public:
 	LLMemType::DeclareMemType& mMemType; // debug
 };
@@ -185,7 +191,7 @@ class LLImageRaw : public LLImageBase
 	
 	BOOL resize(U16 width, U16 height, S8 components);
 
-	U8 * getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const;
+	//U8 * getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const;
 	BOOL setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
 					 const U8 *data, U32 stride = 0, BOOL reverse_y = FALSE);
 
@@ -197,7 +203,7 @@ class LLImageRaw : public LLImageBase
 	void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE);
 	void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE);
 	BOOL scale( S32 new_width, S32 new_height, BOOL scale_image = TRUE );
-	BOOL scaleDownWithoutBlending( S32 new_width, S32 new_height) ;
+	//BOOL scaleDownWithoutBlending( S32 new_width, S32 new_height) ;
 
 	// Fill the buffer with a constant color
 	void fill( const LLColor4U& color );
diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp
index c6bfa50b403a3babfb42c30096e8a3f188456632..926c74914520986403b59ed476f021466c28baec 100644
--- a/indra/llimage/llimagedimensionsinfo.cpp
+++ b/indra/llimage/llimagedimensionsinfo.cpp
@@ -40,7 +40,7 @@ bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec)
 	mSrcFilename = src_filename;
 
 	S32 file_size = 0;
-	apr_status_t s = mInfile.open(src_filename, LL_APR_RB, NULL, &file_size);
+	apr_status_t s = mInfile.open(src_filename, LL_APR_RB, LLAPRFile::long_lived, &file_size);
 
 	if (s != APR_SUCCESS)
 	{
diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp
index 4bd3efddaae3eaead08d0a45400c987d86ca2401..2867f5e6f0aa7c5807396c655f6e0ff781695aec 100644
--- a/indra/llimage/llimagedxt.cpp
+++ b/indra/llimage/llimagedxt.cpp
@@ -429,7 +429,7 @@ bool LLImageDXT::convertToDXR()
 	S32 nmips = calcNumMips(width,height);
 	S32 total_bytes = getDataSize();
 	U8* olddata = getData();
-	U8* newdata = new U8[total_bytes];
+	U8* newdata = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), total_bytes);
 	if (!newdata)
 	{
 		llerrs << "Out of memory in LLImageDXT::convertToDXR()" << llendl;
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 44e6b89dd34ac5072c74c87c26b0e26a58b8976c..8c5dc63e9ddac751de93c0f2aebd6b199a8013ae 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -370,8 +370,7 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
 	resetLastError();
 
 	S32 file_size = 0;
-	LLAPRFile infile ;
-	infile.open(filename, LL_APR_RB, NULL, &file_size);
+	LLAPRFile infile(filename, LL_APR_RB, &file_size);
 	apr_file_t* apr_file = infile.getFileHandle() ;
 	if (!apr_file)
 	{
@@ -385,14 +384,14 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
 	}
 	else
 	{
-		U8 *data = new U8[file_size];
+		U8 *data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), file_size);
 		apr_size_t bytes_read = file_size;
 		apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read	
 		infile.close() ;
 
 		if (s != APR_SUCCESS || (S32)bytes_read != file_size)
 		{
-			delete[] data;
+			FREE_MEM(LLImageBase::getPrivatePool(), data);
 			setLastError("Unable to read entire file");
 			res = FALSE;
 		}
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 28dc3bd313365a58409042d40c9ad4601b0332c5..2c6d6f31eadd2e0ed425a0c9c1a53c5941b8e823 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -35,20 +35,18 @@
 LLImageDecodeThread::LLImageDecodeThread(bool threaded)
 	: LLQueuedThread("imagedecode", threaded)
 {
-	mCreationMutex = new LLMutex(getAPRPool());
 }
 
 //virtual 
 LLImageDecodeThread::~LLImageDecodeThread()
 {
-	delete mCreationMutex ;
 }
 
 // MAIN THREAD
 // virtual
 S32 LLImageDecodeThread::update(U32 max_time_ms)
 {
-	LLMutexLock lock(mCreationMutex);
+	LLMutexLock lock(&mCreationMutex);
 	for (creation_list_t::iterator iter = mCreationList.begin();
 		 iter != mCreationList.end(); ++iter)
 	{
@@ -71,7 +69,7 @@ S32 LLImageDecodeThread::update(U32 max_time_ms)
 LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, 
 	U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
 {
-	LLMutexLock lock(mCreationMutex);
+	LLMutexLock lock(&mCreationMutex);
 	handle_t handle = generateHandle();
 	mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
 	return handle;
@@ -81,7 +79,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted*
 // Returns the size of the mutex guarded list as an indication of sanity
 S32 LLImageDecodeThread::tut_size()
 {
-	LLMutexLock lock(mCreationMutex);
+	LLMutexLock lock(&mCreationMutex);
 	S32 res = mCreationList.size();
 	return res;
 }
diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h
index c684222fa5f85f10794ed51217b59c35cebf1570..6a24b7522ab29d026959ba559379a67c3c948f4c 100644
--- a/indra/llimage/llimageworker.h
+++ b/indra/llimage/llimageworker.h
@@ -98,7 +98,7 @@ class LLImageDecodeThread : public LLQueuedThread
 	};
 	typedef std::list<creation_info> creation_list_t;
 	creation_list_t mCreationList;
-	LLMutex* mCreationMutex;
+	LLMutex mCreationMutex;
 };
 
 #endif
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
old mode 100755
new mode 100644
diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp
index c60b75008837f770c63c324e57f917f5f6e97153..42180197feb14e04ea0a4aeb2376518eeaf4feb0 100644
--- a/indra/llmath/llvolumemgr.cpp
+++ b/indra/llmath/llvolumemgr.cpp
@@ -49,7 +49,7 @@ LLVolumeMgr::LLVolumeMgr()
 {
 	// the LLMutex magic interferes with easy unit testing,
 	// so you now must manually call useMutex() to use it
-	//mDataMutex = new LLMutex(gAPRPoolp);
+	//mDataMutex = new LLMutex;
 }
 
 LLVolumeMgr::~LLVolumeMgr()
@@ -216,7 +216,7 @@ void LLVolumeMgr::useMutex()
 { 
 	if (!mDataMutex)
 	{
-		mDataMutex = new LLMutex(gAPRPoolp);
+		mDataMutex = new LLMutex;
 	}
 }
 
diff --git a/indra/llmath/tests/v3math_test.cpp b/indra/llmath/tests/v3math_test.cpp
index df7a77002fc2d9950f55ece6c14a2abe0535d672..e4ae1c10efafc62e59c022a823b0ebd3e8637e24 100644
--- a/indra/llmath/tests/v3math_test.cpp
+++ b/indra/llmath/tests/v3math_test.cpp
@@ -564,4 +564,22 @@ namespace tut
 		z1 = U8_to_F32(F32_to_U8(z, lowerz, upperz), lowerz, upperz);
 		ensure("2:quantize8: Fail ", is_approx_equal(x1, vec3a.mV[VX]) && is_approx_equal(y1, vec3a.mV[VY]) && is_approx_equal(z1, vec3a.mV[VZ]));
 	}
+
+	template<> template<>
+	void v3math_object::test<35>()
+	{
+		LLSD sd = LLSD::emptyArray();
+		sd[0] = 1.f;
+
+		LLVector3 parsed_1(sd);
+		ensure("1:LLSD parse: Fail ", is_approx_equal(parsed_1.mV[VX], 1.f) && is_approx_equal(parsed_1.mV[VY], 0.f) && is_approx_equal(parsed_1.mV[VZ], 0.f));
+
+		sd[1] = 2.f;
+		LLVector3 parsed_2(sd);
+		ensure("2:LLSD parse: Fail ", is_approx_equal(parsed_2.mV[VX], 1.f) && is_approx_equal(parsed_2.mV[VY], 2.f) && is_approx_equal(parsed_2.mV[VZ], 0.f));
+
+		sd[2] = 3.f;
+		LLVector3 parsed_3(sd);
+		ensure("3:LLSD parse: Fail ", is_approx_equal(parsed_3.mV[VX], 1.f) && is_approx_equal(parsed_3.mV[VY], 2.f) && is_approx_equal(parsed_3.mV[VZ], 3.f));
+	}
 }
diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp
index 5a67035ed15fff56a9d42742c26c74dee8b36f4f..fab9858b697f76e49847afa58ec1cb43ab902b46 100644
--- a/indra/llmessage/llares.cpp
+++ b/indra/llmessage/llares.cpp
@@ -28,6 +28,7 @@
 
 #include "linden_common.h"
 #include "llares.h"
+#include "llscopedvolatileaprpool.h"
 
 #include <ares_dns.h>
 #include <ares_version.h>
@@ -464,11 +465,6 @@ void LLAres::search(const std::string &query, LLResType type,
 
 bool LLAres::process(U64 timeout)
 {
-	if (!gAPRPoolp)
-	{
-		ll_init_apr();
-	}
-
 	ares_socket_t socks[ARES_GETSOCK_MAXNUM];
 	apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM];
 	apr_int32_t nsds = 0;	
@@ -482,10 +478,7 @@ bool LLAres::process(U64 timeout)
 		return nsds > 0;
 	}
 
-	apr_status_t status;
-	LLAPRPool pool;
-	status = pool.getStatus() ;
-	ll_apr_assert_status(status);
+	LLScopedVolatileAPRPool scoped_pool;
 
 	for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)
 	{
@@ -502,7 +495,7 @@ bool LLAres::process(U64 timeout)
 
 		apr_socket_t *aprSock = NULL;
 
-		status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool());
+		apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool);
 		if (status != APR_SUCCESS)
 		{
 			ll_apr_warn_status(status);
@@ -511,7 +504,7 @@ bool LLAres::process(U64 timeout)
 
 		aprFds[nactive].desc.s = aprSock;
 		aprFds[nactive].desc_type = APR_POLL_SOCKET;
-		aprFds[nactive].p = pool.getAPRPool();
+		aprFds[nactive].p = scoped_pool;
 		aprFds[nactive].rtnevents = 0;
 		aprFds[nactive].client_data = &socks[i];
 
@@ -520,7 +513,7 @@ bool LLAres::process(U64 timeout)
 
 	if (nactive > 0)
 	{
-		status = apr_poll(aprFds, nactive, &nsds, timeout);
+		apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout);
 
 		if (status != APR_SUCCESS && status != APR_TIMEUP)
 		{
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index bfdf49c74b520774e42090148bc181a5f3c80964..6d9213f51b7f53c17b9f18e9b1783ce7ce306a4f 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -222,7 +222,7 @@ namespace boost
 std::set<CURL*> LLCurl::Easy::sFreeHandles;
 std::set<CURL*> LLCurl::Easy::sActiveHandles;
 LLMutex* LLCurl::Easy::sHandleMutex = NULL;
-
+LLMutex* LLCurl::Easy::sMultiMutex = NULL;
 
 //static
 CURL* LLCurl::Easy::allocEasyHandle()
@@ -499,7 +499,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
 	
 	//don't verify host name so urls with scrubbed host names will work (improves DNS performance)
 	setopt(CURLOPT_SSL_VERIFYHOST, 0);
-	setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
+	setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT));
 
 	setoptString(CURLOPT_URL, url);
 
@@ -531,7 +531,7 @@ LLCurl::Multi::Multi()
 	mThreaded = LLCurl::sMultiThreaded && LLThread::currentID() == sMainThreadID;
 	if (mThreaded)
 	{
-		mSignal = new LLCondition(NULL);
+		mSignal = new LLCondition();
 	}
 	else
 	{
@@ -553,6 +553,11 @@ LLCurl::Multi::~Multi()
 {
 	llassert(isStopped());
 
+	if (LLCurl::sMultiThreaded)
+	{
+		LLCurl::Easy::sMultiMutex->lock();
+	}
+
 	delete mSignal;
 	mSignal = NULL;
 
@@ -573,6 +578,11 @@ LLCurl::Multi::~Multi()
 
 	check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle));
 	--gCurlMultiCount;
+
+	if (LLCurl::sMultiThreaded)
+	{
+		LLCurl::Easy::sMultiMutex->unlock();
+	}
 }
 
 CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue)
@@ -606,6 +616,7 @@ void LLCurl::Multi::run()
 		mPerformState = PERFORM_STATE_PERFORMING;
 		if (!mQuitting)
 		{
+			LLMutexLock lock(LLCurl::Easy::sMultiMutex);
 			doPerform();
 		}
 	}
@@ -1178,13 +1189,14 @@ void LLCurl::initClass(bool multi_threaded)
 
 	check_curl_code(code);
 	
-	Easy::sHandleMutex = new LLMutex(NULL);
+	Easy::sHandleMutex = new LLMutex();
+	Easy::sMultiMutex = new LLMutex();
 
 #if SAFE_SSL
 	S32 mutex_count = CRYPTO_num_locks();
 	for (S32 i=0; i<mutex_count; i++)
 	{
-		sSSLMutex.push_back(new LLMutex(NULL));
+		sSSLMutex.push_back(new LLMutex);
 	}
 	CRYPTO_set_id_callback(&LLCurl::ssl_thread_id);
 	CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback);
@@ -1200,6 +1212,8 @@ void LLCurl::cleanupClass()
 
 	delete Easy::sHandleMutex;
 	Easy::sHandleMutex = NULL;
+	delete Easy::sMultiMutex;
+	Easy::sMultiMutex = NULL;
 
 	for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter)
 	{
@@ -1213,3 +1227,13 @@ void LLCurl::cleanupClass()
 }
 
 const unsigned int LLCurl::MAX_REDIRECTS = 5;
+
+// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
+void LLCurlFF::check_easy_code(CURLcode code)
+{
+	check_curl_code(code);
+}
+void LLCurlFF::check_multi_code(CURLMcode code)
+{
+	check_curl_multi_code(code);
+}
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
old mode 100644
new mode 100755
index 5ab4dc35b91e3ea65bf27166a95e22756ba199f8..87de202717ca5c03e75b53fcd350f8ecd68485f4
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -232,6 +232,7 @@ class LLCurl::Easy
 
 private:
 	friend class LLCurl;
+	friend class LLCurl::Multi;
 
 	CURL*				mCurlEasyHandle;
 	struct curl_slist*	mHeaders;
@@ -251,6 +252,7 @@ class LLCurl::Easy
 	static std::set<CURL*> sFreeHandles;
 	static std::set<CURL*> sActiveHandles;
 	static LLMutex* sHandleMutex;
+	static LLMutex* sMultiMutex;
 };
 
 class LLCurl::Multi : public LLThread
@@ -371,7 +373,11 @@ class LLCurlEasyRequest
 	bool mResultReturned;
 };
 
-void check_curl_code(CURLcode code);
-void check_curl_multi_code(CURLMcode code);
+// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
+namespace LLCurlFF
+{
+	void check_easy_code(CURLcode code);
+	void check_multi_code(CURLMcode code);
+}
 
 #endif // LL_LLCURL_H
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index 73e8a690851800ca5bf7a69314e15ee446bc316e..920a57ab55420a40bf6509460232aa0e687d0591 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -963,13 +963,9 @@ class LLHTTPResponseFactory : public LLChainIOFactory
 
 
 // static
-LLHTTPNode& LLIOHTTPServer::create(
-	apr_pool_t* pool, LLPumpIO& pump, U16 port)
+LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port)
 {
-	LLSocket::ptr_t socket = LLSocket::create(
-        pool,
-        LLSocket::STREAM_TCP,
-        port);
+	LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP, port);
     if(!socket)
     {
         llerrs << "Unable to initialize socket" << llendl;
@@ -978,7 +974,7 @@ LLHTTPNode& LLIOHTTPServer::create(
     LLHTTPResponseFactory* factory = new LLHTTPResponseFactory;
 	boost::shared_ptr<LLChainIOFactory> factory_ptr(factory);
 
-    LLIOServerSocket* server = new LLIOServerSocket(pool, socket, factory_ptr);
+    LLIOServerSocket* server = new LLIOServerSocket(socket, factory_ptr);
 
 	LLPumpIO::chain_t chain;
     chain.push_back(LLIOPipe::ptr_t(server));
diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h
index 5c1b0531ff2693de45fd6b15147523e27f7e725f..2294e4b8ae2c07eadaf66f6b0827de938d4f0ed2 100644
--- a/indra/llmessage/lliohttpserver.h
+++ b/indra/llmessage/lliohttpserver.h
@@ -50,7 +50,7 @@ class LLIOHTTPServer
 public:
 	typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data);
 
-	static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port);
+	static LLHTTPNode& create(LLPumpIO& pump, U16 port);
 	/**< Creates an HTTP wire server on the pump for the given TCP port.
 	 *
 	 *   Returns the root node of the new server.  Add LLHTTPNode instances
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index ee9379f20585f0d1407984a4620a770f8a92ae80..a885ba8ee15ce7a4b69e7c5325875c57e8258d0f 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -35,6 +35,7 @@
 #include "llhost.h"
 #include "llmemtype.h"
 #include "llpumpio.h"
+#include "llthread.h"
 
 //
 // constants
@@ -98,51 +99,31 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock)
 ///
 
 // static
-LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
+LLSocket::ptr_t LLSocket::create(EType type, U16 port)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_TCP);
-	LLSocket::ptr_t rv;
-	apr_socket_t* socket = NULL;
-	apr_pool_t* new_pool = NULL;
 	apr_status_t status = APR_EGENERAL;
-
-	// create a pool for the socket
-	status = apr_pool_create(&new_pool, pool);
-	if(ll_apr_warn_status(status))
-	{
-		if(new_pool) apr_pool_destroy(new_pool);
-		return rv;
-	}
+	LLSocket::ptr_t rv(new LLSocket);
 
 	if(STREAM_TCP == type)
 	{
-		status = apr_socket_create(
-			&socket,
-			APR_INET,
-			SOCK_STREAM,
-			APR_PROTO_TCP,
-			new_pool);
+		status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, rv->mPool());
 	}
 	else if(DATAGRAM_UDP == type)
 	{
-		status = apr_socket_create(
-			&socket,
-			APR_INET,
-			SOCK_DGRAM,
-			APR_PROTO_UDP,
-			new_pool);
+		status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, rv->mPool());
 	}
 	else
 	{
-		if(new_pool) apr_pool_destroy(new_pool);
+		rv.reset();
 		return rv;
 	}
 	if(ll_apr_warn_status(status))
 	{
-		if(new_pool) apr_pool_destroy(new_pool);
+		rv->mSocket = NULL;
+		rv.reset();
 		return rv;
 	}
-	rv = ptr_t(new LLSocket(socket, new_pool));
 	if(port > 0)
 	{
 		apr_sockaddr_t* sa = NULL;
@@ -152,7 +133,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
 			APR_UNSPEC,
 			port,
 			0,
-			new_pool);
+			rv->mPool());
 		if(ll_apr_warn_status(status))
 		{
 			rv.reset();
@@ -160,8 +141,8 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
 		}
 		// This allows us to reuse the address on quick down/up. This
 		// is unlikely to create problems.
-		ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1));
-		status = apr_socket_bind(socket, sa);
+		ll_apr_warn_status(apr_socket_opt_set(rv->mSocket, APR_SO_REUSEADDR, 1));
+		status = apr_socket_bind(rv->mSocket, sa);
 		if(ll_apr_warn_status(status))
 		{
 			rv.reset();
@@ -175,7 +156,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
 			// to keep a queue of incoming connections for ACCEPT.
 			lldebugs << "Setting listen state for socket." << llendl;
 			status = apr_socket_listen(
-				socket,
+				rv->mSocket,
 				LL_DEFAULT_LISTEN_BACKLOG);
 			if(ll_apr_warn_status(status))
 			{
@@ -196,21 +177,28 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
 }
 
 // static
-LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool)
+LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_TCP);
-	LLSocket::ptr_t rv;
-	if(!socket)
+	if (!listen_socket->getSocket())
+	{
+		status = APR_ENOSOCKET;
+		return LLSocket::ptr_t();
+	}
+	LLSocket::ptr_t rv(new LLSocket);
+	lldebugs << "accepting socket" << llendl;
+	status = apr_socket_accept(&rv->mSocket, listen_socket->getSocket(), rv->mPool());
+	if (status != APR_SUCCESS)
 	{
+		rv->mSocket = NULL;
+		rv.reset();
 		return rv;
 	}
-	rv = ptr_t(new LLSocket(socket, pool));
 	rv->mPort = PORT_EPHEMERAL;
 	rv->setNonBlocking();
 	return rv;
 }
 
-
 bool LLSocket::blockingConnect(const LLHost& host)
 {
 	if(!mSocket) return false;
@@ -223,7 +211,7 @@ bool LLSocket::blockingConnect(const LLHost& host)
 		APR_UNSPEC,
 		host.getPort(),
 		0,
-		mPool)))
+		mPool())))
 	{
 		return false;
 	}
@@ -234,13 +222,11 @@ bool LLSocket::blockingConnect(const LLHost& host)
 	return true;
 }
 
-LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) :
-	mSocket(socket),
-	mPool(pool),
+LLSocket::LLSocket() :
+	mSocket(NULL),
+	mPool(LLThread::tldata().mRootPool),
 	mPort(PORT_INVALID)
 {
-	ll_debug_socket("Constructing wholely formed socket", mSocket);
-	LLMemType m1(LLMemType::MTYPE_IO_TCP);
 }
 
 LLSocket::~LLSocket()
@@ -253,11 +239,6 @@ LLSocket::~LLSocket()
 		apr_socket_close(mSocket);
 		mSocket = NULL;
 	}
-	if(mPool)
-	{
-		apr_pool_destroy(mPool);
-		mPool = NULL;
-	}
 }
 
 // See http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-13.html#ss13.4
@@ -539,10 +520,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
 ///
 
 LLIOServerSocket::LLIOServerSocket(
-	apr_pool_t* pool,
 	LLIOServerSocket::socket_t listener,
 	factory_t factory) :
-	mPool(pool),
 	mListenSocket(listener),
 	mReactor(factory),
 	mInitialized(false),
@@ -604,21 +583,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
 	lldebugs << "accepting socket" << llendl;
 
 	PUMP_DEBUG;
-	apr_pool_t* new_pool = NULL;
-	apr_status_t status = apr_pool_create(&new_pool, mPool);
-	apr_socket_t* socket = NULL;
-	status = apr_socket_accept(
-		&socket,
-		mListenSocket->getSocket(),
-		new_pool);
-	LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool));
+	apr_status_t status;
+	LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket));
 	//EStatus rv = STATUS_ERROR;
-	if(llsocket)
+	if(llsocket && status == APR_SUCCESS)
 	{
 		PUMP_DEBUG;
 
 		apr_sockaddr_t* remote_addr;
-		apr_socket_addr_get(&remote_addr, APR_REMOTE, socket);
+		apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket());
 		
 		char* remote_host_string;
 		apr_sockaddr_ip_get(&remote_host_string, remote_addr);
@@ -633,7 +606,6 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
 		{
 			chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket)));
 			pump->addChain(chain, mResponseTimeout);
-			status = STATUS_OK;
 		}
 		else
 		{
@@ -642,7 +614,8 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
 	}
 	else
 	{
-		llwarns << "Unable to create linden socket." << llendl;
+		char buf[256];
+		llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl;
 	}
 
 	PUMP_DEBUG;
@@ -655,11 +628,10 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
 #if 0
 LLIODataSocket::LLIODataSocket(
 	U16 suggested_port,
-	U16 start_discovery_port,
-	apr_pool_t* pool) : 
+	U16 start_discovery_port) :
 	mSocket(NULL)
 {
-	if(!pool || (PORT_INVALID == suggested_port)) return;
+	if(PORT_INVALID == suggested_port) return;
 	if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return;
 	apr_sockaddr_t* sa = NULL;
 	if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return;
diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h
index be0f7dfcc655e1e47ac2ccdf8f967037ac4458a8..f0a6f256573afb557122a25ab6a219fd401e2588 100644
--- a/indra/llmessage/lliosocket.h
+++ b/indra/llmessage/lliosocket.h
@@ -38,7 +38,6 @@
  */
 
 #include "lliopipe.h"
-#include "apr_pools.h"
 #include "apr_network_io.h"
 #include "llchainio.h"
 
@@ -88,34 +87,22 @@ class LLSocket
 	 * socket. If you intend the socket to be known to external
 	 * clients without prior port notification, do not use
 	 * PORT_EPHEMERAL.
-	 * @param pool The apr pool to use. A child pool will be created
-	 * and associated with the socket.
 	 * @param type The type of socket to create
 	 * @param port The port for the socket
 	 * @return A valid socket shared pointer if the call worked.
 	 */
 	static ptr_t create(
-		apr_pool_t* pool,
 		EType type,
 		U16 port = PORT_EPHEMERAL);
 
 	/** 
-	 * @brief Create a LLSocket when you already have an apr socket.
+	 * @brief Create a LLSocket by accepting a connection from a listen socket.
 	 *
-	 * This method assumes an ephemeral port. This is typically used
-	 * by calls which spawn a socket such as a call to
-	 * <code>accept()</code> as in the server socket. This call should
-	 * not fail if you have a valid apr socket.
-	 * Because of the nature of how accept() works, you are expected
-	 * to create a new pool for the socket, use that pool for the
-	 * accept, and pass it in here where it will be bound with the
-	 * socket and destroyed at the same time.
-	 * @param socket The apr socket to use 
-	 * @param pool The pool used to create the socket. *NOTE: The pool
-	 * passed in will be DESTROYED.
+	 * @param status Output. Status of the accept if a valid listen socket was passed.
+	 * @param listen_socket The listen socket to use.
 	 * @return A valid socket shared pointer if the call worked.
 	 */
-	static ptr_t create(apr_socket_t* socket, apr_pool_t* pool);
+	static ptr_t create(apr_status_t& status, ptr_t& listen_socket);
 
 	/** 
 	 * @brief Perform a blocking connect to a host. Do not use in production.
@@ -145,6 +132,12 @@ class LLSocket
 	 */
 	apr_socket_t* getSocket() const { return mSocket; }
 
+	/** 
+	 * @brief Protected constructor since should only make sockets
+	 * with one of the two <code>create()</code> calls.
+	 */
+	LLSocket(void);
+
 	/** 
 	 * @brief Set default socket options, with SO_NONBLOCK = 0 and a timeout in us.
 	 * @param timeout Number of microseconds to wait on this socket. Any
@@ -174,8 +167,8 @@ class LLSocket
 	// The apr socket.
 	apr_socket_t* mSocket;
 
-	// our memory pool
-	apr_pool_t* mPool;
+	// Our memory pool.
+	LLAPRPool mPool;
 
 	// The port if we know it.
 	U16 mPort;
@@ -300,7 +293,7 @@ class LLIOServerSocket : public LLIOPipe
 public:
 	typedef LLSocket::ptr_t socket_t;
 	typedef boost::shared_ptr<LLChainIOFactory> factory_t;
-	LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor);
+	LLIOServerSocket(socket_t listener, factory_t reactor);
 	virtual ~LLIOServerSocket();
 
 	/** 
@@ -332,7 +325,6 @@ class LLIOServerSocket : public LLIOPipe
 	//@}
 
 protected:
-	apr_pool_t* mPool;
 	socket_t mListenSocket;
 	factory_t mReactor;
 	bool mInitialized;
@@ -366,8 +358,7 @@ class LLIODataSocket : public LLIOSocket
 	 */
 	LLIODataSocket(
 		U16 suggested_port,
-		U16 start_discovery_port,
-		apr_pool_t* pool);
+		U16 start_discovery_port);
 	virtual ~LLIODataSocket();
 
 protected:
diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp
index 08b31e9c7a29b45cdc61fde26fd5a79a25fba74d..8a898ab1b0b41c301952ac7d493479e600eb098b 100644
--- a/indra/llmessage/llmail.cpp
+++ b/indra/llmessage/llmail.cpp
@@ -50,6 +50,7 @@
 #include "llstring.h"
 #include "lluuid.h"
 #include "net.h"
+#include "llaprpool.h"
 
 //
 // constants
@@ -57,7 +58,7 @@
 const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096;
 
 static bool gMailEnabled = true;
-static apr_pool_t* gMailPool;
+static LLAPRPool gMailPool;
 static apr_sockaddr_t* gSockAddr;
 static apr_socket_t* gMailSocket;
 
@@ -82,7 +83,7 @@ bool connect_smtp()
 		gSockAddr->sa.sin.sin_family,
 		SOCK_STREAM,
 		APR_PROTO_TCP,
-		gMailPool);
+		gMailPool());
 	if(ll_apr_warn_status(status)) return false;
 	status = apr_socket_connect(gMailSocket, gSockAddr);
 	if(ll_apr_warn_status(status))
@@ -139,19 +140,19 @@ BOOL LLMail::send(
 }
 
 // static
-void LLMail::init(const std::string& hostname, apr_pool_t* pool)
+void LLMail::init(const std::string& hostname)
 {
 	gMailSocket = NULL;
-	if(hostname.empty() || !pool)
+	if (hostname.empty())
 	{
-		gMailPool = NULL;
 		gSockAddr = NULL;
+		gMailPool.destroy();
 	}
 	else
 	{
-		gMailPool = pool;
+		gMailPool.create();
 
-		// collect all the information into a socaddr sturcture. the
+		// Collect all the information into a sockaddr structure. the
 		// documentation is a bit unclear, but I either have to
 		// specify APR_UNSPEC or not specify any flags. I am not sure
 		// which option is better.
@@ -161,7 +162,7 @@ void LLMail::init(const std::string& hostname, apr_pool_t* pool)
 			APR_UNSPEC,
 			25,
 			APR_IPV4_ADDR_OK,
-			gMailPool);
+			gMailPool());
 		ll_apr_warn_status(status);
 	}
 }
diff --git a/indra/llmessage/llmail.h b/indra/llmessage/llmail.h
index 37917143639aae2b224d7543a234f6545e58ae6f..0a5c532088334812a37dfe0db3ae6a096bc33090 100644
--- a/indra/llmessage/llmail.h
+++ b/indra/llmessage/llmail.h
@@ -27,15 +27,13 @@
 #ifndef LL_LLMAIL_H
 #define LL_LLMAIL_H
 
-typedef struct apr_pool_t apr_pool_t;
-
 #include "llsd.h"
 
 class LLMail
 {
 public:
 	// if hostname is NULL, then the host is resolved as 'mail'
-	static void init(const std::string& hostname, apr_pool_t* pool);
+	static void init(const std::string& hostname);
 
 	// Allow all email transmission to be disabled/enabled.
 	static void enable(bool mail_enabled);
diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp
index 7628984de4cc0c53b90c808b1c01b1935b6de5ea..fc6e9c519302d9da1790c21d77daf6cf8f99f2e6 100644
--- a/indra/llmessage/llpacketring.cpp
+++ b/indra/llmessage/llpacketring.cpp
@@ -228,13 +228,13 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
 		if (LLProxy::isSOCKSProxyEnabled())
 		{
 			U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
-			packet_size = receive_packet(socket, reinterpret_cast<char *>(buffer));
+			packet_size = receive_packet(socket, static_cast<char*>(static_cast<void*>(buffer)));
 			
 			if (packet_size > SOCKS_HEADER_SIZE)
 			{
 				// *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
 				memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE);
-				proxywrap_t * header = reinterpret_cast<proxywrap_t *>(buffer);
+				proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer));
 				mLastSender.setAddress(header->addr);
 				mLastSender.setPort(ntohs(header->port));
 
@@ -353,14 +353,20 @@ BOOL LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 bu
 		return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort());
 	}
 
-	proxywrap_t *socks_header = reinterpret_cast<proxywrap_t *>(&mProxyWrappedSendBuffer);
+	char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
+
+	proxywrap_t *socks_header = static_cast<proxywrap_t*>(static_cast<void*>(&headered_send_buffer));
 	socks_header->rsv   = 0;
 	socks_header->addr  = host.getAddress();
 	socks_header->port  = htons(host.getPort());
 	socks_header->atype = ADDRESS_IPV4;
 	socks_header->frag  = 0;
 
-	memcpy(mProxyWrappedSendBuffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
+	memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
 
-	return send_packet(h_socket, (const char*) mProxyWrappedSendBuffer, buf_size + 10, LLProxy::getInstance()->getUDPProxy().getAddress(), LLProxy::getInstance()->getUDPProxy().getPort());
+	return send_packet(	h_socket,
+						headered_send_buffer,
+						buf_size + SOCKS_HEADER_SIZE,
+						LLProxy::getInstance()->getUDPProxy().getAddress(),
+						LLProxy::getInstance()->getUDPProxy().getPort());
 }
diff --git a/indra/llmessage/llpacketring.h b/indra/llmessage/llpacketring.h
index 7edcc834db83338ec72be7523a3607cb0e582a51..b214271e782adde01e3c51590ecf0e29ef639be3 100644
--- a/indra/llmessage/llpacketring.h
+++ b/indra/llmessage/llpacketring.h
@@ -83,9 +83,6 @@ class LLPacketRing
 	LLHost mLastSender;
 	LLHost mLastReceivingIF;
 
-
-	U8 mProxyWrappedSendBuffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
-
 private:
 	BOOL sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
 };
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 3f4a6accbf625a0ab7b1c684afeeb916db8a6f4a..4a7d326c0e6eae90dfe6e7cb3b6fe0358c075f20 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -43,16 +43,15 @@
 bool LLProxy::sUDPProxyEnabled = false;
 
 // Some helpful TCP static functions.
-static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
-static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host); // Open a TCP channel to a given host
+static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
+static LLSocket::ptr_t tcp_open_channel(LLHost host); // Open a TCP channel to a given host
 static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel
 
 LLProxy::LLProxy():
 		mHTTPProxyEnabled(false),
-		mProxyMutex(0),
+		mProxyMutex(),
 		mUDPProxy(),
 		mTCPProxy(),
-		mPool(gAPRPoolp),
 		mHTTPProxy(),
 		mProxyType(LLPROXY_SOCKS),
 		mAuthMethodSelected(METHOD_NOAUTH),
@@ -64,14 +63,13 @@ LLProxy::LLProxy():
 LLProxy::~LLProxy()
 {
 	stopSOCKSProxy();
-	sUDPProxyEnabled  = false;
-	mHTTPProxyEnabled = false;
+	disableHTTPProxy();
 }
 
 /**
  * @brief Open the SOCKS 5 TCP control channel.
  *
- * Perform a SOCKS 5 authentication and UDP association to the proxy server.
+ * Perform a SOCKS 5 authentication and UDP association with the proxy server.
  *
  * @param proxy The SOCKS 5 server to connect to.
  * @return SOCKS_OK if successful, otherwise a socks error code from llproxy.h.
@@ -84,11 +82,15 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
 	socks_auth_request_t  socks_auth_request;
 	socks_auth_response_t socks_auth_response;
 
-	socks_auth_request.version     = SOCKS_VERSION;       // SOCKS version 5
-	socks_auth_request.num_methods = 1;                   // Sending 1 method.
-	socks_auth_request.methods     = getSelectedAuthMethod(); // Send only the selected method.
+	socks_auth_request.version		= SOCKS_VERSION;				// SOCKS version 5
+	socks_auth_request.num_methods	= 1;							// Sending 1 method.
+	socks_auth_request.methods		= getSelectedAuthMethod();		// Send only the selected method.
 
-	result = tcp_handshake(mProxyControlChannel, (char*)&socks_auth_request, sizeof(socks_auth_request), (char*)&socks_auth_response, sizeof(socks_auth_response));
+	result = tcp_blocking_handshake(mProxyControlChannel,
+									static_cast<char*>(static_cast<void*>(&socks_auth_request)),
+									sizeof(socks_auth_request),
+									static_cast<char*>(static_cast<void*>(&socks_auth_response)),
+									sizeof(socks_auth_response));
 	if (result != APR_SUCCESS)
 	{
 		LL_WARNS("Proxy") << "SOCKS authentication request failed, error on TCP control channel : " << result << LL_ENDL;
@@ -98,12 +100,12 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
 
 	if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE)
 	{
-		LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods" << LL_ENDL;
+		LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods." << LL_ENDL;
 		stopSOCKSProxy();
 		return SOCKS_NOT_ACCEPTABLE;
 	}
 
-	// SOCKS 5 USERNAME/PASSWORD authentication
+	/* SOCKS 5 USERNAME/PASSWORD authentication */
 	if (socks_auth_response.method == METHOD_PASSWORD)
 	{
 		// The server has requested a username/password combination
@@ -115,11 +117,15 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
 		password_auth[1] = socks_username.size();
 		memcpy(&password_auth[2], socks_username.c_str(), socks_username.size());
 		password_auth[socks_username.size() + 2] = socks_password.size();
-		memcpy(&password_auth[socks_username.size()+3], socks_password.c_str(), socks_password.size());
+		memcpy(&password_auth[socks_username.size() + 3], socks_password.c_str(), socks_password.size());
 
 		authmethod_password_reply_t password_reply;
 
-		result = tcp_handshake(mProxyControlChannel, password_auth, request_size, (char*)&password_reply, sizeof(password_reply));
+		result = tcp_blocking_handshake(mProxyControlChannel,
+										password_auth,
+										request_size,
+										static_cast<char*>(static_cast<void*>(&password_reply)),
+										sizeof(password_reply));
 		delete[] password_auth;
 
 		if (result != APR_SUCCESS)
@@ -151,7 +157,11 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
 	// "If the client is not in possession of the information at the time of the UDP ASSOCIATE,
 	//  the client MUST use a port number and address of all zeros. RFC 1928"
 
-	result = tcp_handshake(mProxyControlChannel, (char*)&connect_request, sizeof(connect_request), (char*)&connect_reply, sizeof(connect_reply));
+	result = tcp_blocking_handshake(mProxyControlChannel,
+									static_cast<char*>(static_cast<void*>(&connect_request)),
+									sizeof(connect_request),
+									static_cast<char*>(static_cast<void*>(&connect_reply)),
+									sizeof(connect_reply));
 	if (result != APR_SUCCESS)
 	{
 		LL_WARNS("Proxy") << "SOCKS connect request failed, error on TCP control channel : " << result << LL_ENDL;
@@ -170,6 +180,7 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
 	mUDPProxy.setAddress(proxy.getAddress());
 	// The connection was successful. We now have the UDP port to send requests that need forwarding to.
 	LL_INFOS("Proxy") << "SOCKS 5 UDP proxy connected on " << mUDPProxy << LL_ENDL;
+
 	return SOCKS_OK;
 }
 
@@ -177,7 +188,8 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
  * @brief Initiates a SOCKS 5 proxy session.
  *
  * Performs basic checks on host to verify that it is a valid address. Opens the control channel
- * and then negotiates the proxy connection with the server.
+ * and then negotiates the proxy connection with the server. Closes any existing SOCKS
+ * connection before proceeding. Also disables an HTTP proxy if it is using SOCKS as the proxy.
  *
  *
  * @param host Socks server to connect to.
@@ -185,43 +197,37 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
  */
 S32 LLProxy::startSOCKSProxy(LLHost host)
 {
-	S32 status = SOCKS_OK;
-
 	if (host.isOk())
 	{
 		mTCPProxy = host;
 	}
 	else
 	{
-		status = SOCKS_INVALID_HOST;
+		return SOCKS_INVALID_HOST;
 	}
 
-	if (mProxyControlChannel && status == SOCKS_OK)
-	{
-		tcp_close_channel(&mProxyControlChannel);
-	}
+	// Close any running SOCKS connection.
+	stopSOCKSProxy();
 
-	if (status == SOCKS_OK)
+	mProxyControlChannel = tcp_open_channel(mTCPProxy);
+	if (!mProxyControlChannel)
 	{
-		mProxyControlChannel = tcp_open_channel(mPool, mTCPProxy);
-		if (!mProxyControlChannel)
-		{
-			status = SOCKS_HOST_CONNECT_FAILED;
-		}
+		return SOCKS_HOST_CONNECT_FAILED;
 	}
 
-	if (status == SOCKS_OK)
-	{
-		status = proxyHandshake(mTCPProxy);
-	}
-	if (status == SOCKS_OK)
+	S32 status = proxyHandshake(mTCPProxy);
+
+	if (status != SOCKS_OK)
 	{
-		sUDPProxyEnabled = true;
+		// Shut down the proxy if any of the above steps failed.
+		stopSOCKSProxy();
 	}
 	else
 	{
-		stopSOCKSProxy();
+		// Connection was successful.
+		sUDPProxyEnabled = true;
 	}
+
 	return status;
 }
 
@@ -242,7 +248,7 @@ void LLProxy::stopSOCKSProxy()
 
 	if (LLPROXY_SOCKS == getHTTPProxyType())
 	{
-		void disableHTTPProxy();
+		disableHTTPProxy();
 	}
 
 	if (mProxyControlChannel)
@@ -350,16 +356,6 @@ void LLProxy::disableHTTPProxy()
 	mHTTPProxyEnabled = false;
 }
 
-/**
- * @brief Get the HTTP proxy address and port
- */
-//
-LLHost LLProxy::getHTTPProxy() const
-{
-	LLMutexLock lock(&mProxyMutex);
-	return mHTTPProxy;
-}
-
 /**
  * @brief Get the currently selected HTTP proxy type
  */
@@ -441,21 +437,21 @@ void LLProxy::applyProxySettings(CURL* handle)
 		// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
 		if (mHTTPProxyEnabled)
 		{
-			check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
-			check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
+			LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
+			LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
 
 			if (mProxyType == LLPROXY_SOCKS)
 			{
-				check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
+				LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
 				if (mAuthMethodSelected == METHOD_PASSWORD)
 				{
 					std::string auth_string = mSocksUsername + ":" + mSocksPassword;
-					check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
+					LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
 				}
 			}
 			else
 			{
-				check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
+				LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
 			}
 		}
 	}
@@ -474,7 +470,7 @@ void LLProxy::applyProxySettings(CURL* handle)
  * @param maxinlen		Maximum possible length of received data.  Short reads are allowed.
  * @return 				Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received.
  */
-static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
+static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
 {
 	apr_socket_t* apr_socket = handle->getSocket();
 	apr_status_t rv = APR_SUCCESS;
@@ -523,13 +519,12 @@ static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outl
  *
  * Checks for a successful connection, and makes sure the connection is closed if it fails.
  *
- * @param pool		APR pool to pass into the LLSocket.
  * @param host		The host to open the connection to.
  * @return			The created socket.  Will evaluate as NULL if the connection is unsuccessful.
  */
-static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host)
+static LLSocket::ptr_t tcp_open_channel(LLHost host)
 {
-	LLSocket::ptr_t socket = LLSocket::create(pool, LLSocket::STREAM_TCP);
+	LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP);
 	bool connected = socket->blockingConnect(host);
 	if (!connected)
 	{
@@ -542,7 +537,7 @@ static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host)
 /**
  * @brief Close the socket.
  *
- * @param handle_ptr A pointer-to-pointer to avoid increasing the use count.
+ * @param handle_ptr The handle of the socket being closed. A pointer-to-pointer to avoid increasing the use count.
  */
 static void tcp_close_channel(LLSocket::ptr_t* handle_ptr)
 {
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index 29e7e285679bc9f035e39cafb8b1588c65387b27..a9193705404ace5c51168c261d5c9a35bb951f5a 100644
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
@@ -36,7 +36,6 @@
 #include <string>
 
 // SOCKS error codes returned from the StartProxy method
-
 #define SOCKS_OK 0
 #define SOCKS_CONNECT_ERROR (-1)
 #define SOCKS_NOT_PERMITTED (-2)
@@ -46,7 +45,6 @@
 #define SOCKS_HOST_CONNECT_FAILED (-6)
 #define SOCKS_INVALID_HOST (-7)
 
-
 #ifndef MAXHOSTNAMELEN
 #define	MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */
 #endif
@@ -225,62 +223,71 @@ class LLProxy: public LLSingleton<LLProxy>
 {
 	LOG_CLASS(LLProxy);
 public:
-	// METHODS THAT DO NOT LOCK mProxyMutex!
-
+	/*###########################################################################################
+	METHODS THAT DO NOT LOCK mProxyMutex!
+	###########################################################################################*/
+	// Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only.
 	LLProxy();
 
-	// static check for enabled status for UDP packets
+	// Static check for enabled status for UDP packets. Call from main thread only.
 	static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; }
 
-	// check for enabled status for HTTP packets
-	// mHTTPProxyEnabled is atomic, so no locking is required for thread safety.
-	bool isHTTPProxyEnabled() const { return mHTTPProxyEnabled; }
-
-	// Get the UDP proxy address and port
+	// Get the UDP proxy address and port. Call from main thread only.
 	LLHost getUDPProxy() const { return mUDPProxy; }
 
-	// Get the SOCKS 5 TCP control channel address and port
-	LLHost getTCPProxy() const { return mTCPProxy; }
+	/*###########################################################################################
+	END OF NON-LOCKING METHODS
+	###########################################################################################*/
 
-	// END OF NON-LOCKING METHODS
+	/*###########################################################################################
+	METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+	###########################################################################################*/
+	// Destructor, closes open connections. Do not call directly, use cleanupClass().
+	~LLProxy();
 
-	// METHODS THAT DO LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+	// Delete LLProxy singleton. Allows the apr_socket used in the SOCKS 5 control channel to be
+	// destroyed before the call to apr_terminate. Call from main thread only.
+	static void cleanupClass();
 
-	~LLProxy();
+	// Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
+	// Safe to call from any thread.
+	void applyProxySettings(CURL* handle);
+	void applyProxySettings(LLCurl::Easy* handle);
+	void applyProxySettings(LLCurlEasyRequest* handle);
 
-	// Start a connection to the SOCKS 5 proxy
+	// Start a connection to the SOCKS 5 proxy. Call from main thread only.
 	S32 startSOCKSProxy(LLHost host);
 
-	// Disconnect and clean up any connection to the SOCKS 5 proxy
+	// Disconnect and clean up any connection to the SOCKS 5 proxy. Call from main thread only.
 	void stopSOCKSProxy();
 
-	// Delete LLProxy singleton, destroying the APR pool used by the control channel.
-	static void cleanupClass();
-
-	// Set up to use Password auth when connecting to the SOCKS proxy
+	// Use Password auth when connecting to the SOCKS proxy. Call from main thread only.
 	bool setAuthPassword(const std::string &username, const std::string &password);
 
-	// Set up to use No Auth when connecting to the SOCKS proxy
+	// Disable authentication when connecting to the SOCKS proxy. Call from main thread only.
 	void setAuthNone();
 
-	// Get the currently selected auth method.
-	LLSocks5AuthType getSelectedAuthMethod() const;
-
-	// Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy
-	// as specified in type
+	// Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy.
+	// as specified in type. Call from main thread only.
 	bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type);
 	bool enableHTTPProxy();
 
-	// Stop proxying HTTP packets
+	// Stop proxying HTTP packets. Call from main thread only.
 	void disableHTTPProxy();
 
-	// Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
-	void applyProxySettings(CURL* handle);
-	void applyProxySettings(LLCurl::Easy* handle);
-	void applyProxySettings(LLCurlEasyRequest* handle);
+	/*###########################################################################################
+	END OF LOCKING METHODS
+	###########################################################################################*/
+private:
+	/*###########################################################################################
+	METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+	###########################################################################################*/
 
-	// Get the HTTP proxy address and port
-	LLHost getHTTPProxy() const;
+	// Perform a SOCKS 5 authentication and UDP association with the proxy server.
+	S32 proxyHandshake(LLHost proxy);
+
+	// Get the currently selected auth method.
+	LLSocks5AuthType getSelectedAuthMethod() const;
 
 	// Get the currently selected HTTP proxy type
 	LLHttpProxyType getHTTPProxyType() const;
@@ -288,21 +295,21 @@ class LLProxy: public LLSingleton<LLProxy>
 	std::string getSocksPwd() const;
 	std::string getSocksUser() const;
 
-	// END OF LOCKING METHODS
-private:
-	// Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort
-	S32 proxyHandshake(LLHost proxy);
+	/*###########################################################################################
+	END OF LOCKING METHODS
+	###########################################################################################*/
 
 private:
-	// Is the HTTP proxy enabled?
-	// Safe to read in any thread, do not write directly,
-	// use enableHTTPProxy() and disableHTTPProxy() instead.
+	// Is the HTTP proxy enabled? Safe to read in any thread, but do not write directly.
+	// Instead use enableHTTPProxy() and disableHTTPProxy() instead.
 	mutable LLAtomic32<bool> mHTTPProxyEnabled;
 
-	// Mutex to protect shared members in non-main thread calls to applyProxySettings()
+	// Mutex to protect shared members in non-main thread calls to applyProxySettings().
 	mutable LLMutex mProxyMutex;
 
-	// MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE!
+	/*###########################################################################################
+	MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE!
+	###########################################################################################*/
 
 	// Is the UDP proxy enabled?
 	static bool sUDPProxyEnabled;
@@ -315,12 +322,13 @@ class LLProxy: public LLSingleton<LLProxy>
 	// socket handle to proxy TCP control channel
 	LLSocket::ptr_t mProxyControlChannel;
 
-	// APR pool for the socket
-	apr_pool_t* mPool;
-
-	// END OF UNSHARED MEMBERS
+	/*###########################################################################################
+	END OF UNSHARED MEMBERS
+	###########################################################################################*/
 
-	// MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex!
+	/*###########################################################################################
+	MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex!
+	###########################################################################################*/
 
 	// HTTP proxy address and port
 	LLHost mHTTPProxy;
@@ -328,7 +336,7 @@ class LLProxy: public LLSingleton<LLProxy>
 	// Currently selected HTTP proxy type. Can be web or socks.
 	LLHttpProxyType mProxyType;
 
-	// SOCKS 5 auth method selected
+	// SOCKS 5 selected authentication method.
 	LLSocks5AuthType mAuthMethodSelected;
 
 	// SOCKS 5 username
@@ -336,7 +344,9 @@ class LLProxy: public LLSingleton<LLProxy>
 	// SOCKS 5 password
 	std::string mSocksPassword;
 
-	// END OF SHARED MEMBERS
+	/*###########################################################################################
+	END OF SHARED MEMBERS
+	###########################################################################################*/
 };
 
 #endif
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index a8d2a0a22409e03b021626f57e34d8f4223d2dc6..89cfd66e1b25d931db2aa237bc4e58b2c0b46880 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -37,6 +37,7 @@
 #include "llmemtype.h"
 #include "llstl.h"
 #include "llstat.h"
+#include "llthread.h"
 
 // These should not be enabled in production, but they can be
 // intensely useful during development for finding certain kinds of
@@ -162,14 +163,12 @@ struct ll_delete_apr_pollset_fd_client_data
 /**
  * LLPumpIO
  */
-LLPumpIO::LLPumpIO(apr_pool_t* pool) :
+LLPumpIO::LLPumpIO(void) :
 	mState(LLPumpIO::NORMAL),
 	mRebuildPollset(false),
 	mPollset(NULL),
 	mPollsetClientID(0),
 	mNextLock(0),
-	mPool(NULL),
-	mCurrentPool(NULL),
 	mCurrentPoolReallocCount(0),
 	mChainsMutex(NULL),
 	mCallbackMutex(NULL),
@@ -178,21 +177,24 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) :
 	mCurrentChain = mRunningChains.end();
 
 	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
-	initialize(pool);
+	initialize();
 }
 
 LLPumpIO::~LLPumpIO()
 {
 	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
-	cleanup();
-}
-
-bool LLPumpIO::prime(apr_pool_t* pool)
-{
-	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
-	cleanup();
-	initialize(pool);
-	return ((pool == NULL) ? false : true);
+#if LL_THREADS_APR
+	if (mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
+	if (mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
+#endif
+	mChainsMutex = NULL;
+	mCallbackMutex = NULL;
+	if(mPollset)
+	{
+//		lldebugs << "cleaning up pollset" << llendl;
+		apr_pollset_destroy(mPollset);
+		mPollset = NULL;
+	}
 }
 
 bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
@@ -352,8 +354,7 @@ bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll)
 	{
 		// each fd needs a pool to work with, so if one was
 		// not specified, use this pool.
-		// *FIX: Should it always be this pool?
-		value.second.p = mPool;
+		value.second.p = (*mCurrentChain).mDescriptorsPool->operator()();
 	}
 	value.second.client_data = new S32(++mPollsetClientID);
 	(*mCurrentChain).mDescriptors.push_back(value);
@@ -825,39 +826,15 @@ void LLPumpIO::control(LLPumpIO::EControl op)
 	}
 }
 
-void LLPumpIO::initialize(apr_pool_t* pool)
+void LLPumpIO::initialize(void)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
-	if(!pool) return;
+	mPool.create();
 #if LL_THREADS_APR
 	// SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
-	apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool);
-	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool);
-#endif
-	mPool = pool;
-}
-
-void LLPumpIO::cleanup()
-{
-	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
-#if LL_THREADS_APR
-	if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
-	if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
+	apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
+	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
 #endif
-	mChainsMutex = NULL;
-	mCallbackMutex = NULL;
-	if(mPollset)
-	{
-//		lldebugs << "cleaning up pollset" << llendl;
-		apr_pollset_destroy(mPollset);
-		mPollset = NULL;
-	}
-	if(mCurrentPool)
-	{
-		apr_pool_destroy(mCurrentPool);
-		mCurrentPool = NULL;
-	}
-	mPool = NULL;
 }
 
 void LLPumpIO::rebuildPollset()
@@ -885,21 +862,19 @@ void LLPumpIO::rebuildPollset()
 		if(mCurrentPool
 		   && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT)))
 		{
-			apr_pool_destroy(mCurrentPool);
-			mCurrentPool = NULL;
+			mCurrentPool.destroy();
 			mCurrentPoolReallocCount = 0;
 		}
 		if(!mCurrentPool)
 		{
-			apr_status_t status = apr_pool_create(&mCurrentPool, mPool);
-			(void)ll_apr_warn_status(status);
+			mCurrentPool.create(mPool);
 		}
 
 		// add all of the file descriptors
 		run_it = mRunningChains.begin();
 		LLChainInfo::conditionals_t::iterator fd_it;
 		LLChainInfo::conditionals_t::iterator fd_end;
-		apr_pollset_create(&mPollset, size, mCurrentPool, 0);
+		apr_pollset_create(&mPollset, size, mCurrentPool(), 0);
 		for(; run_it != run_end; ++run_it)
 		{
 			fd_it = (*run_it).mDescriptors.begin();
@@ -1157,7 +1132,8 @@ bool LLPumpIO::handleChainError(
 LLPumpIO::LLChainInfo::LLChainInfo() :
 	mInit(false),
 	mLock(0),
-	mEOS(false)
+	mEOS(false),
+	mDescriptorsPool(new LLAPRPool(LLThread::tldata().mRootPool))
 {
 	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
 	mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);
diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h
index 9303c9d7fcf994e728f49507e292a49e797b8128..75c35ae7ab95291ed4e6a28abd10aeb70490fd36 100644
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
@@ -30,11 +30,12 @@
 #define LL_LLPUMPIO_H
 
 #include <set>
+#include <boost/shared_ptr.hpp>
 #if LL_LINUX  // needed for PATH_MAX in APR.
 #include <sys/param.h>
 #endif
 
-#include "apr_pools.h"
+#include "llaprpool.h"
 #include "llbuffer.h"
 #include "llframetimer.h"
 #include "lliopipe.h"
@@ -58,9 +59,8 @@ extern const F32 NEVER_CHAIN_EXPIRY_SECS;
  * <code>pump()</code> on a thread used for IO and call
  * <code>respond()</code> on a thread that is expected to do higher
  * level processing. You can call almost any other method from any
- * thread - see notes for each method for details. In order for the
- * threading abstraction to work, you need to call <code>prime()</code>
- * with a valid apr pool.
+ * thread - see notes for each method for details.
+ *
  * A pump instance manages much of the state for the pipe, including
  * the list of pipes in the chain, the channel for each element in the
  * chain, the buffer, and if any pipe has marked the stream or process
@@ -79,24 +79,13 @@ class LLPumpIO
 	/**
 	 * @brief Constructor.
 	 */
-	LLPumpIO(apr_pool_t* pool);
+	LLPumpIO(void);
 
 	/**
 	 * @brief Destructor.
 	 */
 	~LLPumpIO();
 
-	/**
-	 * @brief Prepare this pump for usage.
-	 *
-	 * If you fail to call this method prior to use, the pump will
-	 * try to work, but will not come with any thread locking
-	 * mechanisms.
-	 * @param pool The apr pool to use.
-	 * @return Returns true if the pump is primed.
-	 */
-	bool prime(apr_pool_t* pool);
-
 	/**
 	 * @brief Typedef for having a chain of pipes.
 	 */
@@ -368,6 +357,7 @@ class LLPumpIO
 		typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t;
 		typedef std::vector<pipe_conditional_t> conditionals_t;
 		conditionals_t mDescriptors;
+		boost::shared_ptr<LLAPRPool> mDescriptorsPool;
 	};
 
 	// All the running chains & info
@@ -386,9 +376,9 @@ class LLPumpIO
 	callbacks_t mPendingCallbacks;
 	callbacks_t mCallbacks;
 
-	// memory allocator for pollsets & mutexes.
-	apr_pool_t* mPool;
-	apr_pool_t* mCurrentPool;
+	// Memory pool for pollsets & mutexes.
+	LLAPRPool mPool;
+	LLAPRPool mCurrentPool;
 	S32 mCurrentPoolReallocCount;
 
 #if LL_THREADS_APR
@@ -400,8 +390,7 @@ class LLPumpIO
 #endif
 
 protected:
-	void initialize(apr_pool_t* pool);
-	void cleanup();
+	void initialize();
 
 	/** 
 	 * @brief Given the internal state of the chains, rebuild the pollset
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index d5400e41696c3e46002031564846e269edf5228e..91a5a8ce2cf6d8a0e813fcf208ca5cf99c9e65b4 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -41,6 +41,7 @@
 #include "llstring.h"
 #include "apr_env.h"
 #include "llapr.h"
+#include "llscopedvolatileaprpool.h"
 static const U32 HTTP_STATUS_PIPE_ERROR = 499;
 
 /**
@@ -211,26 +212,31 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback)
 // is called with use_proxy = FALSE
 void LLURLRequest::useProxy(bool use_proxy)
 {
-    static char *env_proxy;
+    static std::string env_proxy;
 
-    if (use_proxy && (env_proxy == NULL))
+    if (use_proxy && env_proxy.empty())
     {
-        apr_status_t status;
-        LLAPRPool pool;
-		status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool());
+		char* env_proxy_str;
+        LLScopedVolatileAPRPool scoped_pool;
+        apr_status_t status = apr_env_get(&env_proxy_str, "ALL_PROXY", scoped_pool);
         if (status != APR_SUCCESS)
         {
-			status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool());
+			status = apr_env_get(&env_proxy_str, "http_proxy", scoped_pool);
         }
         if (status != APR_SUCCESS)
         {
-           use_proxy = FALSE;
+            use_proxy = false;
         }
+		else
+		{
+			// env_proxy_str is stored in the scoped_pool, so we have to make a copy.
+			env_proxy = env_proxy_str;
+		}
     }
 
-    LL_DEBUGS("Proxy") << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << LL_ENDL;
+    LL_DEBUGS("Proxy") << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (!env_proxy.empty() ? env_proxy : "(null)") << LL_ENDL;
 
-    if (env_proxy && use_proxy)
+    if (use_proxy && !env_proxy.empty())
     {
 		mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
     }
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index d0b0e178b83625400f790737d0f45eb1d5aba00a..7d21e35f96a386c65bd5efed4b6e3436df580b1b 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -97,8 +97,10 @@ std::string get_shared_secret();
 class LLMessagePollInfo
 {
 public:
+	LLMessagePollInfo(void) : mPool(LLThread::tldata().mRootPool) { }
 	apr_socket_t *mAPRSocketp;
 	apr_pollfd_t mPollFD;
+	LLAPRPool mPool;
 };
 
 namespace
@@ -287,20 +289,13 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port,
 	}
 //	LL_DEBUGS("Messaging") <<  << "*** port: " << mPort << llendl;
 
-	//
-	// Create the data structure that we can poll on
-	//
-	if (!gAPRPoolp)
-	{
-		LL_ERRS("Messaging") << "No APR pool before message system initialization!" << llendl;
-		ll_init_apr();
-	}
+	mPollInfop = new LLMessagePollInfo;
+
 	apr_socket_t *aprSocketp = NULL;
-	apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp);
+	apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool());
 
-	mPollInfop = new LLMessagePollInfo;
 	mPollInfop->mAPRSocketp = aprSocketp;
-	mPollInfop->mPollFD.p = gAPRPoolp;
+	mPollInfop->mPollFD.p = mPollInfop->mPool();
 	mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET;
 	mPollInfop->mPollFD.reqevents = APR_POLLIN;
 	mPollInfop->mPollFD.rtnevents = 0;
diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h
index 2aff90ca1ef8657f0c56cced2cc9a33c02f98041..23e1c791f470db900d2ea13fd5687edc3dfa8bd7 100644
--- a/indra/llmessage/tests/networkio.h
+++ b/indra/llmessage/tests/networkio.h
@@ -30,7 +30,6 @@
 #define LL_NETWORKIO_H
 
 #include "llmemory.h"               // LLSingleton
-#include "llapr.h"
 #include "llares.h"
 #include "llpumpio.h"
 #include "llhttpclient.h"
@@ -48,14 +47,8 @@ class NetworkIO: public LLSingleton<NetworkIO>
         mServicePump(NULL),
         mDone(false)
     {
-        ll_init_apr();
-        if (! gAPRPoolp)
-        {
-            throw std::runtime_error("Can't initialize APR");
-        }
-
         // Create IO Pump to use for HTTP Requests.
-        mServicePump = new LLPumpIO(gAPRPoolp);
+        mServicePump = new LLPumpIO;
         LLHTTPClient::setPump(*mServicePump);
         if (ll_init_ares() == NULL || !gAres->isInitialized())
         {
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index d081109acc57e3298b1a2940e1f58962e7f56064..c53857fceef2c28b01df11ad1d93661991bd2fb2 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -842,6 +842,14 @@ void LLPluginClassMedia::setJavascriptEnabled(const bool enabled)
 	sendMessage(message);
 }
 
+
+void LLPluginClassMedia::enableMediaPluginDebugging( bool enable )
+{
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "enable_media_plugin_debugging");
+	message.setValueBoolean( "enable", enable );
+	sendMessage( message );
+}
+
 void LLPluginClassMedia::setTarget(const std::string &target)
 {
 	mTarget = target;
@@ -1066,6 +1074,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 			mAuthURL = message.getValue("url");
 			mAuthRealm = message.getValue("realm");
 			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_AUTH_REQUEST);
+		}		
+		else if(message_name == "debug_message")
+		{
+			mDebugMessageText = message.getValue("message_text");
+			mDebugMessageLevel = message.getValue("message_level");
+			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_DEBUG_MESSAGE);
 		}
 		else
 		{
@@ -1298,6 +1312,13 @@ void LLPluginClassMedia::setBrowserUserAgent(const std::string& user_agent)
 	sendMessage(message);
 }
 
+void LLPluginClassMedia::showWebInspector( bool show )
+{
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "show_web_inspector");
+	message.setValueBoolean("show", true);	// only open for now - closed manually by user
+	sendMessage(message);
+}
+
 void LLPluginClassMedia::proxyWindowOpened(const std::string &target, const std::string &uuid)
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_opened");
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index d32cb0afe9d77b79d07c2ad0d298edb3ebd020d9..1f548f8cc02e6657716f3e15fd404b23abe2fdfe 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -118,6 +118,9 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 
 	void scrollEvent(int x, int y, MASK modifiers);
 
+	// enable/disable media plugin debugging messages and info spam
+	void enableMediaPluginDebugging( bool enable );
+
 	// Javascript <-> viewer events
 	void jsEnableObject( bool enable );
 	void jsAgentLocationEvent( double x, double y, double z );
@@ -209,6 +212,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	void browse_forward();
 	void browse_back();
 	void setBrowserUserAgent(const std::string& user_agent);
+	void showWebInspector( bool show );
 	void proxyWindowOpened(const std::string &target, const std::string &uuid);
 	void proxyWindowClosed(const std::string &uuid);
 	void ignore_ssl_cert_errors(bool ignore);
@@ -244,6 +248,10 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE
 	std::string getClickUUID() const { return mClickUUID; };
 
+	// These are valid during MEDIA_EVENT_DEBUG_MESSAGE
+	std::string getDebugMessageText() const { return mDebugMessageText; };
+	std::string getDebugMessageLevel() const { return mDebugMessageLevel; };
+
 	// This is valid after MEDIA_EVENT_NAVIGATE_ERROR_PAGE
 	S32 getStatusCode() const { return mStatusCode; };
 	
@@ -395,6 +403,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	std::string		mClickNavType;
 	std::string		mClickTarget;
 	std::string		mClickUUID;
+	std::string		mDebugMessageText;
+	std::string		mDebugMessageLevel;
 	S32				mGeometryX;
 	S32				mGeometryY;
 	S32				mGeometryWidth;
diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h
index 5a4fb1ce906f8872a19604d62d307e0671ec0dee..2f3edba7f368d5488ce02d892e7b45730a6ce345 100644
--- a/indra/llplugin/llpluginclassmediaowner.h
+++ b/indra/llplugin/llpluginclassmediaowner.h
@@ -64,6 +64,8 @@ class LLPluginClassMediaOwner
 
 		MEDIA_EVENT_AUTH_REQUEST,			// The plugin wants to display an auth dialog
 
+		MEDIA_EVENT_DEBUG_MESSAGE,			// plugin sending back debug information for host to process
+
 		MEDIA_EVENT_LINK_HOVERED			// Got a "link hovered" event from the plugin
 		
 	} EMediaEvent;
diff --git a/indra/llplugin/llplugininstance.cpp b/indra/llplugin/llplugininstance.cpp
index 7cde82a20e6d58aedafe33fe776a165fc8129b97..e8efb233ffbe44daa25751c87d4fd8b4b1cdbfdf 100644
--- a/indra/llplugin/llplugininstance.cpp
+++ b/indra/llplugin/llplugininstance.cpp
@@ -29,8 +29,7 @@
 #include "linden_common.h"
 
 #include "llplugininstance.h"
-
-#include "llapr.h"
+#include "llthread.h"			// Needed for LLThread::tldata().mRootPool
 
 #if LL_WINDOWS
 #include "direct.h"	// needed for _chdir()
@@ -52,6 +51,7 @@ const char *LLPluginInstance::PLUGIN_INIT_FUNCTION_NAME = "LLPluginInitEntryPoin
  * @param[in] owner Plugin instance. TODO:DOC is this a good description of what "owner" is?
  */
 LLPluginInstance::LLPluginInstance(LLPluginInstanceMessageListener *owner) :
+	mDSOHandlePool(LLThread::tldata().mRootPool),
 	mDSOHandle(NULL),
 	mPluginUserData(NULL),
 	mPluginSendMessageFunction(NULL)
@@ -97,7 +97,7 @@ int LLPluginInstance::load(const std::string& plugin_dir, std::string &plugin_fi
 
 	int result = apr_dso_load(&mDSOHandle,
 					  plugin_file.c_str(),
-					  gAPRPoolp);
+					  mDSOHandlePool());
 	if(result != APR_SUCCESS)
 	{
 		char buf[1024];
diff --git a/indra/llplugin/llplugininstance.h b/indra/llplugin/llplugininstance.h
index 3643a15d8c27cb1da54ea87cde7f538efa731487..ee28f68e8369f87463d34a9ecfa83d0f744f8b97 100644
--- a/indra/llplugin/llplugininstance.h
+++ b/indra/llplugin/llplugininstance.h
@@ -30,6 +30,7 @@
 
 #include "llstring.h"
 #include "llapr.h"
+#include "llaprpool.h"
 
 #include "apr_dso.h"
 
@@ -88,6 +89,7 @@ class LLPluginInstance
 	static void staticReceiveMessage(const char *message_string, void **user_data);
 	void receiveMessage(const char *message_string);
 
+	LLAPRPool mDSOHandlePool;
 	apr_dso_handle_t *mDSOHandle;
 	
 	void *mPluginUserData;
diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp
index 8d13e38ad5c501c69749f5158219534485185a07..dd47300b9c676706a43d71d6317d4366929a3ee5 100644
--- a/indra/llplugin/llpluginmessagepipe.cpp
+++ b/indra/llplugin/llpluginmessagepipe.cpp
@@ -92,8 +92,6 @@ void LLPluginMessagePipeOwner::killMessagePipe(void)
 }
 
 LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket):
-	mInputMutex(gAPRPoolp),
-	mOutputMutex(gAPRPoolp),
 	mOwner(owner),
 	mSocket(socket)
 {
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index f8a282184ed6d99a5d3144071fbd1f0a7b7ccec9..fd63fdde81629c0c51670ce67af25e67180b5237 100644
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -40,7 +40,7 @@ LLPluginProcessChild::LLPluginProcessChild()
 {
 	mState = STATE_UNINITIALIZED;
 	mInstance = NULL;
-	mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
+	mSocket = LLSocket::create(LLSocket::STREAM_TCP);
 	mSleepTime = PLUGIN_IDLE_SECONDS;	// default: send idle messages at 100Hz
 	mCPUElapsed = 0.0f;
 	mBlockingRequest = false;
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 110fac0f2388abe4a39bb009cd660fe899e89e52..7aec72731eef0bf55379f4a7783c0f7ec9d8182d 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -33,6 +33,7 @@
 #include "llpluginmessageclasses.h"
 
 #include "llapr.h"
+#include "llscopedvolatileaprpool.h"
 
 //virtual 
 LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
@@ -42,6 +43,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
 
 bool LLPluginProcessParent::sUseReadThread = false;
 apr_pollset_t *LLPluginProcessParent::sPollSet = NULL;
+LLAPRPool LLPluginProcessParent::sPollSetPool;
 bool LLPluginProcessParent::sPollsetNeedsRebuild = false;
 LLMutex *LLPluginProcessParent::sInstancesMutex;
 std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances;
@@ -52,7 +54,7 @@ class LLPluginProcessParentPollThread: public LLThread
 {
 public:
 	LLPluginProcessParentPollThread() :
-		LLThread("LLPluginProcessParentPollThread", gAPRPoolp)
+		LLThread("LLPluginProcessParentPollThread")
 	{
 	}
 protected:
@@ -77,12 +79,11 @@ class LLPluginProcessParentPollThread: public LLThread
 
 };
 
-LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
-	mIncomingQueueMutex(gAPRPoolp)
+LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner* owner)
 {
 	if(!sInstancesMutex)
 	{
-		sInstancesMutex = new LLMutex(gAPRPoolp);
+		sInstancesMutex = new LLMutex;
 	}
 	
 	mOwner = owner;
@@ -95,6 +96,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
 	mBlocked = false;
 	mPolledInput = false;
 	mPollFD.client_data = NULL;
+	mPollFDPool.create();
 
 	mPluginLaunchTimeout = 60.0f;
 	mPluginLockupTimeout = 15.0f;
@@ -171,44 +173,28 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
 bool LLPluginProcessParent::accept()
 {
 	bool result = false;
-	
 	apr_status_t status = APR_EGENERAL;
-	apr_socket_t *new_socket = NULL;
-	
-	status = apr_socket_accept(
-		&new_socket,
-		mListenSocket->getSocket(),
-		gAPRPoolp);
 
+	mSocket = LLSocket::create(status, mListenSocket);
 	
 	if(status == APR_SUCCESS)
 	{
 //		llinfos << "SUCCESS" << llendl;
 		// Success.  Create a message pipe on the new socket
-
-		// we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor!
-		apr_pool_t* new_pool = NULL;
-		status = apr_pool_create(&new_pool, gAPRPoolp);
-
-		mSocket = LLSocket::create(new_socket, new_pool);
 		new LLPluginMessagePipe(this, mSocket);
 
 		result = true;
 	}
-	else if(APR_STATUS_IS_EAGAIN(status))
-	{
-//		llinfos << "EAGAIN" << llendl;
-
-		// No incoming connections.  This is not an error.
-		status = APR_SUCCESS;
-	}
 	else
 	{
-//		llinfos << "Error:" << llendl;
-		ll_apr_warn_status(status);
-		
-		// Some other error.
-		errorState();
+		mSocket.reset();
+		// EAGAIN means "No incoming connections". This is not an error.
+		if (!APR_STATUS_IS_EAGAIN(status))
+		{
+			// Some other error.
+			ll_apr_warn_status(status);
+			errorState();
+		}
 	}
 	
 	return result;	
@@ -274,10 +260,10 @@ void LLPluginProcessParent::idle(void)
 
 			case STATE_INITIALIZED:
 			{
-	
 				apr_status_t status = APR_SUCCESS;
+				LLScopedVolatileAPRPool addr_pool;
 				apr_sockaddr_t* addr = NULL;
-				mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
+				mListenSocket = LLSocket::create(LLSocket::STREAM_TCP);
 				mBoundPort = 0;
 				
 				// This code is based on parts of LLSocket::create() in lliosocket.cpp.
@@ -288,7 +274,7 @@ void LLPluginProcessParent::idle(void)
 					APR_INET,
 					0,	// port 0 = ephemeral ("find me a port")
 					0,
-					gAPRPoolp);
+					addr_pool);
 					
 				if(ll_apr_warn_status(status))
 				{
@@ -601,7 +587,7 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe)
 	if(message_pipe != NULL)
 	{
 		// Set up the apr_pollfd_t
-		mPollFD.p = gAPRPoolp;
+		mPollFD.p = mPollFDPool();
 		mPollFD.desc_type = APR_POLL_SOCKET;
 		mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP;
 		mPollFD.rtnevents = 0;
@@ -648,6 +634,7 @@ void LLPluginProcessParent::updatePollset()
 		// delete the existing pollset.
 		apr_pollset_destroy(sPollSet);
 		sPollSet = NULL;
+		sPollSetPool.destroy();
 	}
 	
 	std::list<LLPluginProcessParent*>::iterator iter;
@@ -670,12 +657,14 @@ void LLPluginProcessParent::updatePollset()
 		{
 #ifdef APR_POLLSET_NOCOPY
 			// The pollset doesn't exist yet.  Create it now.
-			apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY);
+			sPollSetPool.create();
+			apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY);
 			if(status != APR_SUCCESS)
 			{
 #endif // APR_POLLSET_NOCOPY
 				LL_WARNS("PluginPoll") << "Couldn't create pollset.  Falling back to non-pollset mode." << LL_ENDL;
 				sPollSet = NULL;
+				sPollSetPool.destroy();
 #ifdef APR_POLLSET_NOCOPY
 			}
 			else
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index 26c6b0c4027e5438464749561b562a5a91c341af..74b7e9f50cd1b5ec2a365851dc60b89074e35bcd 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -178,7 +178,9 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner
 
 	static bool sUseReadThread;
 	apr_pollfd_t mPollFD;
+	LLAPRPool mPollFDPool;
 	static apr_pollset_t *sPollSet;
+	static LLAPRPool sPollSetPool;
 	static bool sPollsetNeedsRebuild;
 	static LLMutex *sInstancesMutex;
 	static std::list<LLPluginProcessParent*> sInstances;
diff --git a/indra/llplugin/llpluginsharedmemory.cpp b/indra/llplugin/llpluginsharedmemory.cpp
index 63ff5085c6e1705f180d0c361a45bf305a1fe196..e2ff645a9c5ae7ddb88ad6683a5d85f9544b93bc 100644
--- a/indra/llplugin/llpluginsharedmemory.cpp
+++ b/indra/llplugin/llpluginsharedmemory.cpp
@@ -187,7 +187,8 @@ bool LLPluginSharedMemory::create(size_t size)
 	mName += createName();
 	mSize = size;
 	
-	apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp );
+	mPool.create();
+	apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), mPool());
 	
 	if(ll_apr_warn_status(status))
 	{
@@ -210,7 +211,7 @@ bool LLPluginSharedMemory::destroy(void)
 		}
 		mImpl->mAprSharedMemory = NULL;
 	}
-	
+	mPool.destroy();
 	return true;
 }
 
@@ -219,7 +220,8 @@ bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
 	mName = name;
 	mSize = size;
 	
-	apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp );
+	mPool.create();
+	apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), mPool() );
 	
 	if(ll_apr_warn_status(status))
 	{
@@ -241,6 +243,7 @@ bool LLPluginSharedMemory::detach(void)
 		}
 		mImpl->mAprSharedMemory = NULL;
 	}
+	mPool.destroy();
 	
 	return true;
 }
diff --git a/indra/llplugin/llpluginsharedmemory.h b/indra/llplugin/llpluginsharedmemory.h
index c6cd49cabb7e119b0f9c326cc3ea358ed9f408d7..84b7a58c328c27f90e99186e1c71420607bb70d8 100644
--- a/indra/llplugin/llpluginsharedmemory.h
+++ b/indra/llplugin/llpluginsharedmemory.h
@@ -28,6 +28,8 @@
 #ifndef LL_LLPLUGINSHAREDMEMORY_H
 #define LL_LLPLUGINSHAREDMEMORY_H
 
+#include "llaprpool.h"
+
 class LLPluginSharedMemoryPlatformImpl;
 
 /**
@@ -108,6 +110,7 @@ class LLPluginSharedMemory
 	bool close(void);
 	bool unlink(void);
 	
+	LLAPRPool mPool;
 	std::string mName;
 	size_t mSize;
 	void *mMappedAddress;
diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp
index 516a58db8836115afd18cf276a95c0b30e445b5c..ff86e4e1351ce10f1d2de229f43f2e391edbe6a0 100644
--- a/indra/llplugin/slplugin/slplugin.cpp
+++ b/indra/llplugin/slplugin/slplugin.cpp
@@ -176,8 +176,6 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
 int main(int argc, char **argv)
 #endif
 {
-	ll_init_apr();
-
 	// Set up llerror logging
 	{
 		LLError::initForApplication(".");
@@ -393,8 +391,6 @@ int main(int argc, char **argv)
 
 	delete plugin;
 
-	ll_cleanup_apr();
-
 	return 0;
 }
 
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
old mode 100755
new mode 100644
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index d72918b15d0b61b682e6d7f4284004f6b9060449..edcc47aa1471ab65ddd90506c0c562e3c2c0d1c2 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -927,13 +927,7 @@ LLRender::LLRender()
     mMode(LLRender::TRIANGLES),
     mCurrTextureUnitIndex(0),
     mMaxAnisotropy(0.f) 
-{
-	mBuffer = new LLVertexBuffer(immediate_mask, 0);
-	mBuffer->allocateBuffer(4096, 0, TRUE);
-	mBuffer->getVertexStrider(mVerticesp);
-	mBuffer->getTexCoord0Strider(mTexcoordsp);
-	mBuffer->getColorStrider(mColorsp);
-	
+{	
 	mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS);
 	for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++)
 	{
@@ -964,6 +958,17 @@ LLRender::~LLRender()
 	shutdown();
 }
 
+void LLRender::init()
+{
+	llassert_always(mBuffer.isNull()) ;
+
+	mBuffer = new LLVertexBuffer(immediate_mask, 0);
+	mBuffer->allocateBuffer(4096, 0, TRUE);
+	mBuffer->getVertexStrider(mVerticesp);
+	mBuffer->getTexCoord0Strider(mTexcoordsp);
+	mBuffer->getColorStrider(mColorsp);
+}
+
 void LLRender::shutdown()
 {
 	for (U32 i = 0; i < mTexUnits.size(); i++)
@@ -979,6 +984,7 @@ void LLRender::shutdown()
 		delete mLightState[i];
 	}
 	mLightState.clear();
+	mBuffer = NULL ;
 }
 
 void LLRender::refreshState(void)
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 9eedebe2ce08efb9d74d45871c70466b5883da86..8f7ee30d87e53f704387e232be8dd9ca731a556d 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -310,6 +310,7 @@ class LLRender
 
 	LLRender();
 	~LLRender();
+	void init() ;
 	void shutdown();
 	
 	// Refreshes renderer state to the cached values
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index b6a252e8fa82bf5b2f7735e8c278f1d9ef7373eb..8fd11937801b8eba7f68933bd5692a82e19ef3cf 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -25,7 +25,6 @@
  */
 
 #include "linden_common.h"
-#include "llmemory.h"
 
 #include <boost/static_assert.hpp>
 #include "llsys.h"
@@ -36,6 +35,7 @@
 #include "llrender.h"
 #include "llvector4a.h"
 #include "llglslshader.h"
+#include "llmemory.h"
 
 
 //============================================================================
@@ -46,6 +46,7 @@ LLVBOPool LLVertexBuffer::sDynamicVBOPool;
 LLVBOPool LLVertexBuffer::sStreamIBOPool;
 LLVBOPool LLVertexBuffer::sDynamicIBOPool;
 
+LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL ;
 U32 LLVertexBuffer::sBindCount = 0;
 U32 LLVertexBuffer::sSetCount = 0;
 S32 LLVertexBuffer::sCount = 0;
@@ -443,6 +444,11 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
 	}
 
 	sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
+
+	if(!sPrivatePoolp)
+	{
+		sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ;
+	}
 }
 
 //static 
@@ -472,7 +478,11 @@ void LLVertexBuffer::cleanupClass()
 	unbind();
 	clientCopy(); // deletes GL buffers
 
-	//llassert_always(!sCount) ;
+	if(sPrivatePoolp)
+	{
+		LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp) ;
+		sPrivatePoolp = NULL ;
+	}
 }
 
 void LLVertexBuffer::clientCopy(F64 max_time)
@@ -722,7 +732,7 @@ void LLVertexBuffer::createGLBuffer()
 	{
 		static int gl_buffer_idx = 0;
 		mGLBuffer = ++gl_buffer_idx;
-		mMappedData = (U8*) ll_aligned_malloc_16(size);
+		mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
 	}
 }
 
@@ -756,7 +766,7 @@ void LLVertexBuffer::createGLIndices()
 	}
 	else
 	{
-		mMappedIndexData = (U8*) ll_aligned_malloc_16(size);
+		mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
 		static int gl_buffer_idx = 0;
 		mGLIndices = ++gl_buffer_idx;
 	}
@@ -779,7 +789,7 @@ void LLVertexBuffer::destroyGLBuffer()
 		}
 		else
 		{
-			ll_aligned_free_16(mMappedData);
+			FREE_MEM(sPrivatePoolp, mMappedData) ;
 			mMappedData = NULL;
 			mEmpty = TRUE;
 		}
@@ -808,7 +818,7 @@ void LLVertexBuffer::destroyGLIndices()
 		}
 		else
 		{
-			ll_aligned_free_16(mMappedIndexData);
+			FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
 			mMappedIndexData = NULL;
 			mEmpty = TRUE;
 		}
@@ -941,8 +951,8 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
 			{
 				if (!useVBOs())
 				{
-					ll_aligned_free_16(mMappedData);
-					mMappedData = (U8*) ll_aligned_malloc_16(newsize);
+					FREE_MEM(sPrivatePoolp, mMappedData);
+					mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, newsize);
 				}
 				mResized = TRUE;
 			}
@@ -962,8 +972,8 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
 			{
 				if (!useVBOs())
 				{
-					ll_aligned_free_16(mMappedIndexData);
-					mMappedIndexData = (U8*) ll_aligned_malloc_16(new_index_size);
+					FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
+					mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, new_index_size);
 				}
 				mResized = TRUE;
 			}
@@ -998,8 +1008,8 @@ void LLVertexBuffer::freeClientBuffer()
 {
 	if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData))
 	{
-		ll_aligned_free_16(mMappedData) ;
-		ll_aligned_free_16(mMappedIndexData) ;
+		FREE_MEM(sPrivatePoolp, mMappedData) ;
+		FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
 		mMappedData = NULL ;
 		mMappedIndexData = NULL ;
 	}
@@ -1009,7 +1019,7 @@ void LLVertexBuffer::allocateClientVertexBuffer()
 {
 	if(!mMappedData)
 	{
-		mMappedData = (U8*)ll_aligned_malloc_16(getSize());
+		mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, getSize());
 	}
 }
 
@@ -1017,7 +1027,7 @@ void LLVertexBuffer::allocateClientIndexBuffer()
 {
 	if(!mMappedIndexData)
 	{
-		mMappedIndexData = (U8*)ll_aligned_malloc_16(getIndicesSize());
+		mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, getIndicesSize());		
 	}
 }
 
@@ -1159,12 +1169,9 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
 			{
 				log_glerror();
 
-				//check the availability of memory
-				U32 avail_phy_mem, avail_vir_mem;
-				LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ;
-				llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ; 
-				llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
-
+			//check the availability of memory
+			LLMemory::logMemoryInfo(TRUE) ; 
+			
 				if(!sDisableVBOMapping)
 				{			
 					//--------------------
@@ -1324,6 +1331,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
 		if (!mMappedIndexData)
 		{
 			log_glerror();
+			LLMemory::logMemoryInfo(TRUE) ;
 
 			if(!sDisableVBOMapping)
 			{
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index cc5d11e1c29018ff1ec085da20c4e7045d33600d..578cec38859c6d88d4eda6964fad47efa7cf9f0e 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -79,7 +79,7 @@ class LLGLFence
 
 //============================================================================
 // base class 
-
+class LLPrivateMemoryPool ;
 class LLVertexBuffer : public LLRefCount
 {
 public:
@@ -282,6 +282,9 @@ class LLVertexBuffer : public LLRefCount
 	void waitFence() const;
 
 
+private:
+	static LLPrivateMemoryPool* sPrivatePoolp ;
+
 public:
 	static S32 sCount;
 	static S32 sGLCount;
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 6afe27637902ce458662ddf71c0551fbc960b9f9..4b0b7c561da6858175798772dfcc4257c9ffce0f 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -339,7 +339,7 @@ LLAccordionCtrlTab::Params::Params()
 	,fit_panel("fit_panel",true)
 	,selection_enabled("selection_enabled", false)
 {
-	mouse_opaque(false);
+	changeDefault(mouse_opaque, false);
 }
 
 LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p)
diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp
index fde3c53a6512ae79da093eea1bb2cef77822131a..8ede4e3468ba9ece7517e7148f089ab3c8e0abbc 100644
--- a/indra/llui/llbadge.cpp
+++ b/indra/llui/llbadge.cpp
@@ -27,11 +27,14 @@
 #define LLBADGE_CPP
 #include "llbadge.h"
 
+#include "llscrollcontainer.h"
 #include "lluictrlfactory.h"
 
 
 static LLDefaultChildRegistry::Register<LLBadge> r("badge");
 
+static const S32 BADGE_OFFSET_NOT_SPECIFIED = 0x7FFFFFFF;
+
 // Compiler optimization, generate extern template
 template class LLBadge* LLView::getChild<class LLBadge>(const std::string& name, BOOL recurse) const;
 
@@ -46,14 +49,13 @@ LLBadge::Params::Params()
 	, label_offset_horiz("label_offset_horiz")
 	, label_offset_vert("label_offset_vert")
 	, location("location", LLRelPos::TOP_LEFT)
+	, location_offset_hcenter("location_offset_hcenter")
+	, location_offset_vcenter("location_offset_vcenter")
 	, location_percent_hcenter("location_percent_hcenter")
 	, location_percent_vcenter("location_percent_vcenter")
 	, padding_horiz("padding_horiz")
 	, padding_vert("padding_vert")
-{
-	// We set a name here so the name isn't necessary in any xml files that use badges
-	name = "badge";
-}
+{}
 
 bool LLBadge::Params::equals(const Params& a) const
 {
@@ -70,6 +72,8 @@ bool LLBadge::Params::equals(const Params& a) const
 	comp &= (label_offset_horiz() == a.label_offset_horiz());
 	comp &= (label_offset_vert() == a.label_offset_vert());
 	comp &= (location() == a.location());
+	comp &= (location_offset_hcenter() == a.location_offset_hcenter());
+	comp &= (location_offset_vcenter() == a.location_offset_vcenter());
 	comp &= (location_percent_hcenter() == a.location_percent_hcenter());
 	comp &= (location_percent_vcenter() == a.location_percent_vcenter());
 	comp &= (padding_horiz() == a.padding_horiz());
@@ -91,16 +95,29 @@ LLBadge::LLBadge(const LLBadge::Params& p)
 	, mLabelOffsetHoriz(p.label_offset_horiz)
 	, mLabelOffsetVert(p.label_offset_vert)
 	, mLocation(p.location)
+	, mLocationOffsetHCenter(BADGE_OFFSET_NOT_SPECIFIED)
+	, mLocationOffsetVCenter(BADGE_OFFSET_NOT_SPECIFIED)
 	, mLocationPercentHCenter(0.5f)
 	, mLocationPercentVCenter(0.5f)
 	, mPaddingHoriz(p.padding_horiz)
 	, mPaddingVert(p.padding_vert)
+	, mParentScroller(NULL)
 {
 	if (mImage.isNull())
 	{
 		llwarns << "Badge: " << getName() << " with no image!" << llendl;
 	}
 
+	if (p.location_offset_hcenter.isProvided())
+	{
+		mLocationOffsetHCenter = p.location_offset_hcenter();
+	}
+
+	if (p.location_offset_vcenter.isProvided())
+	{
+		mLocationOffsetVCenter = p.location_offset_vcenter();
+	}
+
 	//
 	// The following logic is to set the mLocationPercentHCenter and mLocationPercentVCenter
 	// based on the Location enum and our horizontal and vertical location percentages.  The
@@ -144,6 +161,15 @@ bool LLBadge::addToView(LLView * view)
 	if (child_added)
 	{
 		setShape(view->getLocalRect());
+
+		// Find a parent scroll container, if there is one in case we need it for positioning
+
+		LLView * parent = mOwner.get();
+
+		while ((parent != NULL) && ((mParentScroller = dynamic_cast<LLScrollContainer *>(parent)) == NULL))
+		{
+			parent = parent->getParent();
+		}
 	}
 
 	return child_added;
@@ -200,22 +226,12 @@ void LLBadge::draw()
 
 		if (owner_view)
 		{
-			//
-			// Calculate badge position based on owner
-			//
-			
-			LLRect owner_rect;
-			owner_view->localRectToOtherView(owner_view->getLocalRect(), & owner_rect, this);
-			
-			F32 badge_center_x = owner_rect.mLeft + owner_rect.getWidth() * mLocationPercentHCenter;
-			F32 badge_center_y = owner_rect.mBottom + owner_rect.getHeight() * mLocationPercentVCenter;
-
 			//
 			// Calculate badge size based on label text
 			//
 
 			LLWString badge_label_wstring = mLabel;
-			
+
 			S32 badge_label_begin_offset = 0;
 			S32 badge_char_length = S32_MAX;
 			S32 badge_pixel_length = S32_MAX;
@@ -227,6 +243,77 @@ void LLBadge::draw()
 
 			F32 badge_height = (2.0f * mPaddingVert) + mGLFont->getLineHeight();
 
+			//
+			// Calculate badge position based on owner
+			//
+			
+			LLRect owner_rect;
+			owner_view->localRectToOtherView(owner_view->getLocalRect(), & owner_rect, this);
+
+			S32 location_offset_horiz = mLocationOffsetHCenter;
+			S32 location_offset_vert = mLocationOffsetVCenter;
+
+			// If we're in a scroll container, do some math to keep us in the same place on screen if applicable
+			if (mParentScroller != NULL)
+			{
+				LLRect visibleRect = mParentScroller->getVisibleContentRect();
+
+				if (mLocationOffsetHCenter != BADGE_OFFSET_NOT_SPECIFIED)
+				{
+					if (LLRelPos::IsRight(mLocation))
+					{
+						location_offset_horiz += visibleRect.mRight;
+					}
+					else if (LLRelPos::IsLeft(mLocation))
+					{
+						location_offset_horiz += visibleRect.mLeft;
+					}
+					else // center
+					{
+						location_offset_horiz += (visibleRect.mLeft + visibleRect.mRight) / 2;
+					}
+				}
+
+				if (mLocationOffsetVCenter != BADGE_OFFSET_NOT_SPECIFIED)
+				{
+					if (LLRelPos::IsTop(mLocation))
+					{
+						location_offset_vert += visibleRect.mTop;
+					}
+					else if (LLRelPos::IsBottom(mLocation))
+					{
+						location_offset_vert += visibleRect.mBottom;
+					}
+					else // center
+					{
+						location_offset_vert += (visibleRect.mBottom + visibleRect.mTop) / 2;
+					}
+				}
+			}
+			
+			F32 badge_center_x;
+			F32 badge_center_y;
+
+			// Compute x position
+			if (mLocationOffsetHCenter == BADGE_OFFSET_NOT_SPECIFIED)
+			{
+				badge_center_x = owner_rect.mLeft + owner_rect.getWidth() * mLocationPercentHCenter;
+			}
+			else
+			{
+				badge_center_x = location_offset_horiz;
+			}
+
+			// Compute y position
+			if (mLocationOffsetVCenter == BADGE_OFFSET_NOT_SPECIFIED)
+			{
+				badge_center_y = owner_rect.mBottom + owner_rect.getHeight() * mLocationPercentVCenter;
+			}
+			else
+			{
+				badge_center_y = location_offset_vert;
+			}
+
 			//
 			// Draw button image, if available.
 			// Otherwise draw basic rectangular button.
diff --git a/indra/llui/llbadge.h b/indra/llui/llbadge.h
index f81ccdf0cd1640cacb592bcd5916e861074ff066..4b21a71aaa3c4ef5a37d1d56d5cb4562c5504bb9 100644
--- a/indra/llui/llbadge.h
+++ b/indra/llui/llbadge.h
@@ -39,8 +39,9 @@
 // Declarations
 //
 
-class LLUICtrlFactory;
 class LLFontGL;
+class LLScrollContainer;
+class LLUICtrlFactory;
 
 //
 // Relative Position Alignment
@@ -108,6 +109,8 @@ class LLBadge
 		Optional< S32 >					label_offset_vert;
 
 		Optional< LLRelPos::Location >	location;
+		Optional< S32 >					location_offset_hcenter;
+		Optional< S32 >					location_offset_vcenter;
 		Optional< U32 >					location_percent_hcenter;
 		Optional< U32 >					location_percent_vcenter;
 
@@ -150,6 +153,8 @@ class LLBadge
 	S32						mLabelOffsetVert;
 
 	LLRelPos::Location		mLocation;
+	S32						mLocationOffsetHCenter;
+	S32						mLocationOffsetVCenter;
 	F32						mLocationPercentHCenter;
 	F32						mLocationPercentVCenter;
 	
@@ -157,6 +162,8 @@ class LLBadge
 
 	F32						mPaddingHoriz;
 	F32						mPaddingVert;
+
+	LLScrollContainer*		mParentScroller;
 };
 
 // Build time optimization, generate once in .cpp file
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 7b015bd57694a4d12ffb280b84f6dabbca7c5d3c..2459429f6e52f28f6c259841fd208f22a7881f01 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -101,11 +101,11 @@ LLButton::Params::Params()
 	commit_on_return("commit_on_return", true),
 	use_draw_context_alpha("use_draw_context_alpha", true),
 	badge("badge"),
-	handle_right_mouse("handle_right_mouse")
+	handle_right_mouse("handle_right_mouse"),
+	held_down_delay("held_down_delay")
 {
 	addSynonym(is_toggle, "toggle");
-	held_down_delay.seconds = 0.5f;
-	initial_value.set(LLSD(false), false);
+	changeDefault(initial_value, LLSD(false));
 }
 
 
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index cddda03faf9ce538bf02692421918ab43c6ca325..89d8842393be9247c54273ad7ea40589fd0635eb 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -525,15 +525,12 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p)
 	else
 	{
 		mButton->setRect(rect);
-		mButton->setTabStop(TRUE);
-		mButton->setHAlign(LLFontGL::LEFT);
 		mButton->setLabel(mLabel.getString());
 		
 		if (mTextEntry)
 		{
 			mTextEntry->setVisible(FALSE);
 		}
-		mButton->setFollowsAll();
 	}
 }
 
diff --git a/indra/llui/llconsole.h b/indra/llui/llconsole.h
index bb8ea50bedfd7e537c9c7855782142b09fa913cb..f32f1dd74c37296bd9ae627a8b01735e2c7d3277 100644
--- a/indra/llui/llconsole.h
+++ b/indra/llui/llconsole.h
@@ -54,7 +54,7 @@ class LLConsole : public LLFixedBuffer, public LLUICtrl, public LLInstanceTracke
 			persist_time("persist_time", 0.f), // forever
 			font_size_index("font_size_index")
 		{
-			mouse_opaque(false);
+			changeDefault(mouse_opaque, false);
 		}
 	};
 protected:
diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h
index 7d3d5cf78769e89f46843a8157ad3f14543cd6e8..e81600fd6c1a564387b7ac2526d99126dbbbd4b9 100644
--- a/indra/llui/llcontainerview.h
+++ b/indra/llui/llcontainerview.h
@@ -50,7 +50,7 @@ class LLContainerView : public LLView
 			  show_label("show_label", FALSE),
 			  display_children("display_children", TRUE)
 		{
-			mouse_opaque(false);
+			changeDefault(mouse_opaque, false);
 		}
 	};
 
diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h
index 7c56475e751f081cd254ecb39d2f7835142c37e6..e095e577b1e555d711bf56c87567ec1f396ba4fa 100644
--- a/indra/llui/lldraghandle.h
+++ b/indra/llui/lldraghandle.h
@@ -51,8 +51,8 @@ class LLDragHandle : public LLView
 			drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")),
 			drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark"))
 		{
-			mouse_opaque(true);
-			follows.flags(FOLLOWS_ALL);
+			changeDefault(mouse_opaque, true);
+			changeDefault(follows.flags, FOLLOWS_ALL);
 		}
 	};
 	void initFromParams(const Params&);
diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h
index 710699fdc1b9c51939397bcfd58b8458717ca1a6..3a05bc05a165efa6466d27639f9be4692b955d01 100644
--- a/indra/llui/llfiltereditor.h
+++ b/indra/llui/llfiltereditor.h
@@ -42,12 +42,7 @@ class LLFilterEditor : public LLSearchEditor
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLSearchEditor::Params>
-	{
-		Params()
-		{
-			name = "filter_editor";
-		}
-	};
+	{};
 
 protected:
 	LLFilterEditor(const Params&);
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 8917d5490c98930423262a7a2534b09958a4c301..bc494e97f555d0be2f68221cbbb62925d495191f 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -182,7 +182,7 @@ LLFloater::Params::Params()
 	open_callback("open_callback"),
 	close_callback("close_callback")
 {
-	visible = false;
+	changeDefault(visible, false);
 }
 
 
diff --git a/indra/llui/llflyoutbutton.h b/indra/llui/llflyoutbutton.h
index 8d59380a007ec15ca5c73e6770e4a5f8e3cfc62a..36998eba2e42a7a62ed64100cbd62ff3e79f93a1 100644
--- a/indra/llui/llflyoutbutton.h
+++ b/indra/llui/llflyoutbutton.h
@@ -46,7 +46,7 @@ class LLFlyoutButton : public LLComboBox
 		:	action_button("action_button"),
 		    allow_text_entry("allow_text_entry")
 		{
-			LLComboBox::Params::allow_text_entry = false;
+			changeDefault(LLComboBox::Params::allow_text_entry, false);
 		}
 
 	};
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index 47f2cfaf89b0c885c2db74df1381d9488bfaf2b5..30b79b4d20d068867355d4a6a5421aa005d45d51 100644
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -43,10 +43,7 @@ LLIconCtrl::Params::Params()
 	color("color"),
 	use_draw_context_alpha("use_draw_context_alpha", true),
 	scale_image("scale_image")
-{
-	tab_stop = false;
-	mouse_opaque = false;
-}
+{}
 
 LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
 :	LLUICtrl(p),
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index a59247ba096b8cf30e1544153f310185c2dc0994..a250404292aab6b9e91cf67893fdf54a43da2bf9 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -115,9 +115,7 @@ LLLayoutStack::Params::Params()
 	open_time_constant("open_time_constant", 0.02f),
 	close_time_constant("close_time_constant", 0.03f),
 	border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0))
-{
-	name="stack";
-}
+{}
 
 LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p) 
 :	LLView(p),
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 06fbc0f234850f5c1eb063407bd3d3c94cf4f7fa..ebdd47ae80508a493897f471091e0fc07f7f76ce 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -103,10 +103,11 @@ LLLineEditor::Params::Params()
 	text_pad_right("text_pad_right"),
 	default_text("default_text")
 {
-	mouse_opaque = true;
+	changeDefault(mouse_opaque, true);
 	addSynonym(select_on_focus, "select_all_on_focus_received");
 	addSynonym(border, "border");
 	addSynonym(label, "watermark_text");
+	addSynonym(max_length.chars, "max_length");
 }
 
 LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 8de9c769e299dfe749007a8bed1c2f1e5f1d4ff7..6cac841cdeacb3fceb58351b210fa7d2b2840e41 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -90,7 +90,6 @@ const S32 TEAROFF_SEPARATOR_HEIGHT_PIXELS = 10;
 const S32 MENU_ITEM_PADDING = 4;
 
 const std::string SEPARATOR_NAME("separator");
-const std::string SEPARATOR_LABEL( "-----------" );
 const std::string VERTICAL_SEPARATOR_LABEL( "|" );
 
 const std::string LLMenuGL::BOOLEAN_TRUE_PREFIX( "\xE2\x9C\x94" ); // U+2714 HEAVY CHECK MARK
@@ -149,7 +148,7 @@ LLMenuItemGL::Params::Params()
 	highlight_bg_color("highlight_bg_color"),
 	highlight_fg_color("highlight_fg_color")
 {	
-	mouse_opaque = true;
+	changeDefault(mouse_opaque, true);
 }
 
 // Default constructor
@@ -566,8 +565,6 @@ void LLMenuItemGL::handleVisibilityChange(BOOL new_visibility)
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 LLMenuItemSeparatorGL::Params::Params()
 {
-	name = "separator";
-	label = SEPARATOR_LABEL;
 }
 
 LLMenuItemSeparatorGL::LLMenuItemSeparatorGL(const LLMenuItemSeparatorGL::Params& p) :
@@ -755,30 +752,6 @@ U32 LLMenuItemTearOffGL::getNominalHeight( void ) const
 	return TEAROFF_SEPARATOR_HEIGHT_PIXELS; 
 }
 
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLMenuItemBlankGL
-//
-// This class represents a blank, non-functioning item.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLMenuItemBlankGL : public LLMenuItemGL
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
-	{
-		Params()
-		{
-			name="";
-			enabled = false;
-		}
-	};
-	LLMenuItemBlankGL( const Params& p ) :	LLMenuItemGL( p )
-	{}
-	virtual void draw( void ) {}
-};
-
-
 ///============================================================================
 /// Class LLMenuItemCallGL
 ///============================================================================
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 7bde8e83ec7f7f5af017da49cda4e02d6bafed33..77db588390fe7fb4c869e03653e6c5ed5ef1881e 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -372,17 +372,16 @@ class LLMenuGL
 			drop_shadow("drop_shadow", true),
 			bg_visible("bg_visible", true),
 			create_jump_keys("create_jump_keys", false),
+			keep_fixed_size("keep_fixed_size", false),
 			bg_color("bg_color",  LLUIColorTable::instance().getColor( "MenuDefaultBgColor" )),
 			scrollable("scrollable", false), 
 			max_scrollable_items("max_scrollable_items", U32_MAX),
 			preferred_width("preferred_width", U32_MAX),
 			shortcut_pad("shortcut_pad")
-			
 		{
 			addSynonym(bg_visible, "opaque");
 			addSynonym(bg_color, "color");
-
-			name = "menu";
+			addSynonym(can_tear_off, "can_tear_off");
 		}
 	};
 
@@ -650,7 +649,7 @@ class LLContextMenu
 	{
 		Params()
 		{
-			visible = false;
+			changeDefault(visible, false);
 		}
 	};
 
@@ -698,16 +697,7 @@ class LLMenuBarGL : public LLMenuGL
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLMenuGL::Params>
-	{
-		Params()
-		{
-			can_tear_off = false;
-			keep_fixed_size = true;
-			horizontal_layout = true;
-			visible = true;
-			drop_shadow = false;
-		}
-	};
+	{};
 	LLMenuBarGL( const Params& p );
 	virtual ~LLMenuBarGL();
 
@@ -825,13 +815,7 @@ class LLMenuItemTearOffGL : public LLMenuItemGL
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
-	{
-		Params()
-		{
-			name = "tear off";
-			label = "~~~~~~~~~~~";
-		}
-	};
+	{};
 
 	LLMenuItemTearOffGL( const Params& );
 	
diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp
index 9052bc7d1da914e93ffdb40beba8f6665ea29764..70bcfb5b4f92053621f45dbdb48902a0444c954f 100644
--- a/indra/llui/llmultislider.cpp
+++ b/indra/llui/llmultislider.cpp
@@ -66,11 +66,7 @@ LLMultiSlider::Params::Params()
 	mouse_up_callback("mouse_up_callback"),
 	thumb_width("thumb_width"),
 	sliders("slider")
-{
-	name = "multi_slider_bar";
-	mouse_opaque(true);
-	follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
-}
+{}
 
 LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
 :	LLF32UICtrl(p),
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 6085c61f9a2470155942bebce0cbc14cc87a43e9..ffe5908a9d7ed490ad1fbe3b7b2b95347d72e156 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -245,7 +245,6 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
 	LLParamSDParser parser;
 	parser.writeSD(mFormData, p.form_elements);
 
-	mFormData = mFormData[""];
 	if (!mFormData.isArray())
 	{
 		// change existing contents to a one element array
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index e3193bc352f3c30789f4580a01b88b9fce0328ee..a45b617c2ecb8f5d2af50c13c203c653b391fdaa 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -90,7 +90,6 @@ LLPanel::Params::Params()
 	visible_callback("visible_callback"),
 	accepts_badge("accepts_badge")
 {
-	name = "panel";
 	addSynonym(background_visible, "bg_visible");
 	addSynonym(has_border, "border_visible");
 	addSynonym(label, "title");
diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp
index 3a12debf7e058b79335b1340a89eebf202bd9695..95a7d0938244cd6e43c640543c8acbe16b8c6369 100644
--- a/indra/llui/llradiogroup.cpp
+++ b/indra/llui/llradiogroup.cpp
@@ -74,9 +74,6 @@ LLRadioGroup::Params::Params()
 {
 	addSynonym(items, "radio_item");
 
-	name = "radio_group";
-	mouse_opaque = true;
-	follows.flags = FOLLOWS_LEFT | FOLLOWS_TOP;
 	// radio items are not tabbable until they are selected
 	tab_stop = false;
 }
@@ -96,7 +93,10 @@ void LLRadioGroup::initFromParams(const Params& p)
 	{
 		LLRadioGroup::ItemParams item_params(*it);
 
-		item_params.font.setIfNotProvided(mFont); // apply radio group font by default
+		if (!item_params.font.isProvided())
+		{
+			item_params.font = mFont; // apply radio group font by default
+		}
 		item_params.commit_callback.function = boost::bind(&LLRadioGroup::onClickButton, this, _1);
 		item_params.from_xui = p.from_xui;
 		if (p.from_xui)
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 3a867a10a74db22ee93ae245df49cd7275155665..5d3bf7a670084727bbfa6951d84be13615ad16da 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -63,9 +63,7 @@ LLScrollbar::Params::Params()
 	right_button("right_button"),
 	bg_visible("bg_visible", false),
 	bg_color("bg_color", LLColor4::black)
-{
-	tab_stop = false;
-}
+{}
 
 LLScrollbar::LLScrollbar(const Params & p)
 :		LLUICtrl(p),
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 380c477eb219f26843f374d94805f1f6d57e8dd9..b44b4c36b676d06dafaee90c648eb2edeb1f25df 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -74,11 +74,7 @@ LLScrollContainer::Params::Params()
 	min_auto_scroll_rate("min_auto_scroll_rate", 100),
 	max_auto_scroll_rate("max_auto_scroll_rate", 1000),
 	reserve_scroll_corner("reserve_scroll_corner", false)
-{
-	name = "scroll_container";
-	mouse_opaque(true);
-	tab_stop(false);
-}
+{}
 
 
 // Default constructor
diff --git a/indra/llui/llscrollingpanellist.h b/indra/llui/llscrollingpanellist.h
index 8f569c2a582106f7e812f0a9f0610d95d3e031f0..e8df176ec380595668057e6981ce0ceca832945d 100644
--- a/indra/llui/llscrollingpanellist.h
+++ b/indra/llui/llscrollingpanellist.h
@@ -51,12 +51,7 @@ class LLScrollingPanelList : public LLUICtrl
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
-	{
-		Params()
-		{
-			name = "scrolling_panel_list";
-		}
-	};
+	{};
 	LLScrollingPanelList(const Params& p)
 	:	LLUICtrl(p) 
 	{}
diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp
index 696e4a2bb1e60a61391a12ed6dd6408fdb0d8409..07a6dfaa102c92a6cd9ad6f0ab73209bb498587d 100644
--- a/indra/llui/llscrolllistcolumn.cpp
+++ b/indra/llui/llscrolllistcolumn.cpp
@@ -46,10 +46,7 @@ static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(&typeid
 //---------------------------------------------------------------------------
 LLScrollColumnHeader::Params::Params()
 :	column("column")
-{
-	name  = "column_header";
-	tab_stop(false);
-}
+{}
 
 
 LLScrollColumnHeader::LLScrollColumnHeader(const LLScrollColumnHeader::Params& p) 
diff --git a/indra/llui/llscrolllistcolumn.h b/indra/llui/llscrolllistcolumn.h
index e2711ac75ac7f197382ea89b8bae0f03a48ff6c5..12baea8e0c4c7fc9d5787507fd87931023a10dea 100644
--- a/indra/llui/llscrolllistcolumn.h
+++ b/indra/llui/llscrolllistcolumn.h
@@ -135,7 +135,7 @@ class LLScrollListColumn
 			halign("halign", LLFontGL::LEFT)
 		{
 			// default choice to "dynamic_width"
-			width.dynamic_width = true;
+			changeDefault(width.dynamic_width, true);
 
 			addSynonym(sort_column, "sort");
 		}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index b7848ec37c31ccd795d5f73d42dfefa0bcbf61fe..622f3e215c923f62d6deea4e7e2f19cbb4333c92 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -147,12 +147,9 @@ LLScrollListCtrl::Params::Params()
 	highlighted_color("highlighted_color"),
 	contents(""),
 	scroll_bar_bg_visible("scroll_bar_bg_visible"),
-	scroll_bar_bg_color("scroll_bar_bg_color")
-	, border("border")
-{
-	name = "scroll_list";
-	mouse_opaque = true;
-}
+	scroll_bar_bg_color("scroll_bar_bg_color"), 
+	border("border")
+{}
 
 LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 :	LLUICtrl(p),
@@ -2813,7 +2810,10 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS
 		}
 
 		S32 index = columnp->mIndex;
-		cell_p.width.setIfNotProvided(columnp->getWidth());
+		if (!cell_p.width.isProvided())
+		{
+			cell_p.width = columnp->getWidth();
+		}
 
 		LLScrollListCell* cell = LLScrollListCell::create(cell_p);
 
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 9ad13054cb525d61e1351a1ceefc48c58fbc86a2..04919e69916046457a4a68cc1ee2233a2f12ff83 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -183,7 +183,7 @@ LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack)
 			}
 		}
 
-		LLSD* child_sd = &(*sd_to_write)[it->first];
+		LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first];
 
 		if (child_sd->isArray())
 		{
diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h
index f5c3b532c4ff48e342bbc5ccec65f01172690744..c2d79169385eda2f43fdcd94ddfc4535c1769a5c 100644
--- a/indra/llui/llsearcheditor.h
+++ b/indra/llui/llsearcheditor.h
@@ -55,9 +55,7 @@ class LLSearchEditor : public LLUICtrl
 			search_button_visible("search_button_visible"),
 			clear_button("clear_button"), 
 			clear_button_visible("clear_button_visible")
-		{
-			name = "search_editor";
-		}
+		{}
 	};
 
 	void setCommitOnFocusLost(BOOL b)	{ if (mSearchEditor) mSearchEditor->setCommitOnFocusLost(b); }
diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp
index 013950a5adc5083903e74c046141af6521b0e0b1..db72234f94d95ff7f4f5d491168acfa8c228362a 100644
--- a/indra/llui/llslider.cpp
+++ b/indra/llui/llslider.cpp
@@ -54,9 +54,7 @@ LLSlider::Params::Params()
 	track_highlight_vertical_image("track_highlight_vertical_image"),
 	mouse_down_callback("mouse_down_callback"),
 	mouse_up_callback("mouse_up_callback")
-{
-	follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
-}
+{}
 
 LLSlider::LLSlider(const LLSlider::Params& p)
 :	LLF32UICtrl(p),
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index d760178e358e8d703d11cff6e4d8636925301e71..583ed1ed2e91143f0813084189beb16eccdd9735 100644
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -76,8 +76,14 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
 		}
 		LLRect label_rect( left, top, label_width, bottom );
 		LLTextBox::Params params(p.slider_label);
-		params.rect.setIfNotProvided(label_rect);
-		params.font.setIfNotProvided(p.font);
+		if (!params.rect.isProvided())
+		{
+			params.rect = label_rect;
+		}
+		if (!params.font.isProvided())
+		{
+			params.font = p.font;
+		}
 		params.initial_value(p.label());
 		mLabelBox = LLUICtrlFactory::create<LLTextBox> (params);
 		addChild(mLabelBox);
@@ -113,15 +119,33 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
 	S32 slider_left = label_width ? label_width + sliderctrl_spacing : 0;
 	LLSlider::Params slider_p(p.slider_bar);
 	slider_p.name("slider_bar");
-	slider_p.rect.setIfNotProvided(LLRect(slider_left,top,slider_right,bottom));
-	slider_p.initial_value.setIfNotProvided(p.initial_value().asReal());
-	slider_p.min_value.setIfNotProvided(p.min_value);
-	slider_p.max_value.setIfNotProvided(p.max_value);
-	slider_p.increment.setIfNotProvided(p.increment);
-	slider_p.orientation.setIfNotProvided(p.orientation);
+	if (!slider_p.rect.isProvided())
+	{
+		slider_p.rect = LLRect(slider_left,top,slider_right,bottom);
+	}
+	if (!slider_p.initial_value.isProvided())
+	{
+		slider_p.initial_value = p.initial_value().asReal();
+	}
+	if (!slider_p.min_value.isProvided())
+	{
+		slider_p.min_value = p.min_value;
+	}
+	if (!slider_p.max_value.isProvided())
+	{
+		slider_p.max_value = p.max_value;
+	}
+	if (!slider_p.increment.isProvided())
+	{
+		slider_p.increment = p.increment;
+	}
+	if (!slider_p.orientation.isProvided())
+	{
+		slider_p.orientation = p.orientation;
+	}
 	
-	slider_p.commit_callback.function(&LLSliderCtrl::onSliderCommit);
-	slider_p.control_name(p.control_name);
+	slider_p.commit_callback.function = &LLSliderCtrl::onSliderCommit;
+	slider_p.control_name = p.control_name;
 	slider_p.mouse_down_callback( p.mouse_down_callback );
 	slider_p.mouse_up_callback( p.mouse_up_callback );
 	mSlider = LLUICtrlFactory::create<LLSlider> (slider_p);
@@ -134,8 +158,15 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
 		if( p.can_edit_text() )
 		{
 			LLLineEditor::Params line_p(p.value_editor);
-			line_p.rect.setIfNotProvided(text_rect);
-			line_p.font.setIfNotProvided(p.font);
+			if (!line_p.rect.isProvided())
+			{
+				line_p.rect = text_rect;
+			}
+			if (!line_p.font.isProvided())
+			{
+				line_p.font = p.font;
+			}
+			
 			line_p.commit_callback.function(&LLSliderCtrl::onEditorCommit);
 			line_p.prevalidate_callback(&LLTextValidate::validateFloat);
 			mEditor = LLUICtrlFactory::create<LLLineEditor>(line_p);
@@ -149,8 +180,14 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
 		else
 		{
 			LLTextBox::Params text_p(p.value_text);
-			text_p.rect.setIfNotProvided(text_rect);
-			text_p.font.setIfNotProvided(p.font);
+			if (!text_p.rect.isProvided())
+			{
+				text_p.rect = text_rect;
+			}
+			if (!text_p.font.isProvided())
+			{
+				text_p.font = p.font;
+			}
 			mTextBox = LLUICtrlFactory::create<LLTextBox>(text_p);
 			addChild(mTextBox);
 		}
diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h
index 62a9db82fe9586ccd8e1adddd13ea5ecd5ae85fb..513fff323454128fc46e50c16c2545d94bc3ff03 100644
--- a/indra/llui/llstatbar.h
+++ b/indra/llui/llstatbar.h
@@ -65,7 +65,7 @@ class LLStatBar : public LLView
 			  show_mean("show_mean", TRUE),
 			  stat("stat")
 		{
-			follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
+			changeDefault(follows.flags, FOLLOWS_TOP | FOLLOWS_LEFT);
 		}
 	};
 	LLStatBar(const Params&);
diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h
index 22a9fcd672210362f50a02384ec2aa21a9756977..5abdc42448c3b21f55f655411b80131b0af2bdd5 100644
--- a/indra/llui/llstatview.h
+++ b/indra/llui/llstatview.h
@@ -46,7 +46,7 @@ class LLStatView : public LLContainerView
 		Params() 
 		:	setting("setting")
 		{
-			follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
+			changeDefault(follows.flags, FOLLOWS_TOP | FOLLOWS_LEFT);
 		}
 	};
 
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 7f0d6504031419288fbd129503f2e55baf42cb39..9c6a76822c2e12e1379e3b0bd54acdbafd888798 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -217,10 +217,7 @@ LLTabContainer::Params::Params()
 	tab_icon_ctrl_pad("tab_icon_ctrl_pad", 0),
 	use_ellipses("use_ellipses"),
 	font_halign("halign")
-{
-	name(std::string("tab_container"));
-	mouse_opaque = false;
-}
+{}
 
 LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
 :	LLPanel(p),
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index 639003979479a4b90d9db9ee429ed43a0dbd880b..bc6461a0c21a25df950036225f9acb34b8981e37 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -55,7 +55,7 @@ static LLDefaultChildRegistry::Register<LLToolTipView> register_tooltip_view("to
 
 LLToolTipView::Params::Params()
 {
-	mouse_opaque = false;
+	changeDefault(mouse_opaque, false);
 }
 
 LLToolTipView::LLToolTipView(const LLToolTipView::Params& p)
@@ -156,7 +156,7 @@ LLToolTip::Params::Params()
 	web_based_media("web_based_media", false),
 	media_playing("media_playing", false)
 {
-	chrome = true;
+	changeDefault(chrome, true);
 }
 
 LLToolTip::LLToolTip(const LLToolTip::Params& p)
@@ -402,12 +402,12 @@ void LLToolTipMgr::createToolTip(const LLToolTip::Params& params)
 
 	LLToolTip::Params tooltip_params(params);
 	// block mouse events if there is a click handler registered (specifically, hover)
-	if (params.click_callback.isProvided())
+	if (params.click_callback.isProvided() && !params.mouse_opaque.isProvided())
 	{
 		// set mouse_opaque to true if it wasn't already set to something else
 		// this prevents mouse down from going "through" the tooltip and ultimately
 		// causing the tooltip to disappear
-		tooltip_params.mouse_opaque.setIfNotProvided(true);
+		tooltip_params.mouse_opaque = true;
 	}
 	tooltip_params.rect = LLRect (0, 1, 1, 0);
 
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 499b97f52d4db7f7dfa9bd75c13e70fea9671fff..f0ba7fc7d7e4ab5bb7b6d0ad3598609d482dadc4 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -104,14 +104,17 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 	public:
 		ParamDefaults()
 		{
-			// recursively initialize from base class param block
-			((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get());
-			// after initializing base classes, look up template file for this param block
+			// look up template file for this param block...
 			const std::string* param_block_tag = getWidgetTag(&typeid(PARAM_BLOCK));
 			if (param_block_tag)
-			{
-				LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, mPrototype);
+			{	// ...and if it exists, back fill values using the most specific template first
+				PARAM_BLOCK params;
+				LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params);
+				mPrototype.fillFrom(params);
 			}
+			// recursively fill from base class param block
+			((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get());
+
 		}
 
 		const PARAM_BLOCK& get() { return mPrototype; }
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 659a54cc6e00d62cbba4b5c376351c662d985541..60452b9ae4d578817759761bdde98f7313c6a2de 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -2485,7 +2485,7 @@ void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
 	{
 		LLRect parent_rect = parent->getLocalRect();
 		// overwrite uninitialized rect params, using context
-		LLRect last_rect = parent->getLocalRect();
+		LLRect default_rect = parent->getLocalRect();
 
 		bool layout_topleft = (p.layout() == "topleft");
 
@@ -2509,15 +2509,13 @@ void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
 			p.rect.height = MIN_WIDGET_HEIGHT;
 		}
 
-		last_rect.translate(0, last_rect.getHeight());
+		default_rect.translate(0, default_rect.getHeight());
 
 		// If there was a recently constructed child, use its rectangle
-		get_last_child_rect(parent, &last_rect);
+		get_last_child_rect(parent, &default_rect);
 
 		if (layout_topleft)
 		{
-			p.bottom_delta.setIfNotProvided(0, false);
-
 			// Invert the sense of bottom_delta for topleft layout
 			if (p.bottom_delta.isProvided())
 			{
@@ -2530,33 +2528,44 @@ void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
 			else if (p.top_delta.isProvided())
 			{
 				p.bottom_delta =
-					-(p.top_delta + p.rect.height - last_rect.getHeight());
+					-(p.top_delta + p.rect.height - default_rect.getHeight());
 			}
-			else if (!p.bottom_delta.isProvided()
-					 && !p.left_delta.isProvided()
-					 && !p.top_pad.isProvided()
+			else if (!p.left_delta.isProvided()
 					 && !p.left_pad.isProvided())
 			{
 				// set default position is just below last rect
 				p.bottom_delta.set(-(p.rect.height + VPAD), false);
 			}
+			else
+			{
+				p.bottom_delta.set(0, false);
+			}
 	
 			// default to same left edge
-			p.left_delta.setIfNotProvided(0, false);
+			if (!p.left_delta.isProvided())
+			{
+				p.left_delta.set(0, false);
+			}
 			if (p.left_pad.isProvided())
 			{
 				// left_pad is based on prior widget's right edge
-				p.left_delta.set(p.left_pad + last_rect.getWidth(), false);
+				p.left_delta.set(p.left_pad + default_rect.getWidth(), false);
 			}
 			
-			last_rect.translate(p.left_delta, p.bottom_delta);				
+			default_rect.translate(p.left_delta, p.bottom_delta);				
 		}
 		else
 		{	
 			// set default position is just below last rect
-			p.bottom_delta.setIfNotProvided(-(p.rect.height + VPAD), false);
-			p.left_delta.setIfNotProvided(0, false);
-			last_rect.translate(p.left_delta, p.bottom_delta);
+			if (!p.bottom_delta.isProvided())
+			{
+				p.bottom_delta.set(-(p.rect.height + VPAD), false);
+			}
+			if (!p.left_delta.isProvided())
+			{
+				p.left_delta.set(0, false);
+			}
+			default_rect.translate(p.left_delta, p.bottom_delta);
 		}
 
 		// this handles case where *both* x and x_delta are provided
@@ -2567,12 +2576,38 @@ void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
 		// selectively apply rectangle defaults, making sure that
 		// params are not flagged as having been "provided"
 		// as rect params are overconstrained and rely on provided flags
-		p.rect.left.setIfNotProvided(last_rect.mLeft, false);
-		p.rect.bottom.setIfNotProvided(last_rect.mBottom, false);
-		p.rect.top.setIfNotProvided(last_rect.mTop, false);
-		p.rect.right.setIfNotProvided(last_rect.mRight, false);
-		p.rect.width.setIfNotProvided(last_rect.getWidth(), false);
-		p.rect.height.setIfNotProvided(last_rect.getHeight(), false);
+		if (!p.rect.left.isProvided())
+		{
+			p.rect.left.set(default_rect.mLeft, false);
+			//HACK: get around the fact that setting a rect param component value won't invalidate the existing rect object value
+			p.rect.paramChanged(p.rect.left, true);
+		}
+		if (!p.rect.bottom.isProvided())
+		{
+			p.rect.bottom.set(default_rect.mBottom, false);
+			p.rect.paramChanged(p.rect.bottom, true);
+		}
+		if (!p.rect.top.isProvided())
+		{
+			p.rect.top.set(default_rect.mTop, false);
+			p.rect.paramChanged(p.rect.top, true);
+		}
+		if (!p.rect.right.isProvided())
+		{
+			p.rect.right.set(default_rect.mRight, false);
+			p.rect.paramChanged(p.rect.right, true);
+
+		}
+		if (!p.rect.width.isProvided())
+		{
+			p.rect.width.set(default_rect.getWidth(), false);
+			p.rect.paramChanged(p.rect.width, true);
+		}
+		if (!p.rect.height.isProvided())
+		{
+			p.rect.height.set(default_rect.getHeight(), false);
+			p.rect.paramChanged(p.rect.height, true);
+		}
 	}
 }
 
diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp
index 32d7ea7c25ae46fbb47c356f6858be8d8424d4ee..919267dcc677fccdeefa1fa3178818619192e866 100644
--- a/indra/llui/llviewborder.cpp
+++ b/indra/llui/llviewborder.cpp
@@ -57,9 +57,6 @@ LLViewBorder::Params::Params()
 {
 	addSynonym(border_thickness, "thickness");
 	addSynonym(render_style, "style");
-	name = "view_border";
-	mouse_opaque = false;
-	follows.flags = FOLLOWS_ALL;
 }
 
 
diff --git a/indra/llui/llwindowshade.cpp b/indra/llui/llwindowshade.cpp
index 77e94385d424eedb561bf3837e1a10096bfa86eb..cf76202215526725897aefd2b2ac86eb98e34286 100644
--- a/indra/llui/llwindowshade.cpp
+++ b/indra/llui/llwindowshade.cpp
@@ -43,7 +43,7 @@ LLWindowShade::Params::Params()
 	text_color("text_color"),
 	can_close("can_close", true)
 {
-	mouse_opaque = false;
+	changeDefault(mouse_opaque, false);
 }
 
 LLWindowShade::LLWindowShade(const LLWindowShade::Params& params)
diff --git a/indra/llvfs/lllfsthread.cpp b/indra/llvfs/lllfsthread.cpp
index 3d3ed9f6d4d32f34999a3b36bc659b19461e6a8b..bf49b9668e6cfd212ddefbf4b7d05f5d299d597a 100644
--- a/indra/llvfs/lllfsthread.cpp
+++ b/indra/llvfs/lllfsthread.cpp
@@ -67,10 +67,6 @@ LLLFSThread::LLLFSThread(bool threaded) :
 	LLQueuedThread("LFS", threaded),
 	mPriorityCounter(PRIORITY_LOWBITS)
 {
-	if(!mLocalAPRFilePoolp)
-	{
-		mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
-	}
 }
 
 LLLFSThread::~LLLFSThread()
@@ -182,8 +178,7 @@ bool LLLFSThread::Request::processRequest()
 	if (mOperation ==  FILE_READ)
 	{
 		llassert(mOffset >= 0);
-		LLAPRFile infile ; // auto-closes
-		infile.open(mFileName, LL_APR_RB, mThread->getLocalAPRFilePool());
+		LLAPRFile infile(mFileName, LL_APR_RB);
 		if (!infile.getFileHandle())
 		{
 			llwarns << "LLLFS: Unable to read file: " << mFileName << llendl;
@@ -205,8 +200,7 @@ bool LLLFSThread::Request::processRequest()
 		apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
 		if (mOffset < 0)
 			flags |= APR_APPEND;
-		LLAPRFile outfile ; // auto-closes
-		outfile.open(mFileName, flags, mThread->getLocalAPRFilePool());
+		LLAPRFile outfile(mFileName, flags);
 		if (!outfile.getFileHandle())
 		{
 			llwarns << "LLLFS: Unable to write file: " << mFileName << llendl;
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index 82c926620a07960695337df7148752bdb9aa5f0a..ade19f8103e06d4be7399b57d1a82e402bdb21ce 100644
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -234,7 +234,7 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename
 	mDataFP(NULL),
 	mIndexFP(NULL)
 {
-	mDataMutex = new LLMutex(0);
+	mDataMutex = new LLMutex;
 
 	S32 i;
 	for (i = 0; i < VFSLOCK_COUNT; i++)
@@ -2098,8 +2098,7 @@ void LLVFS::dumpFiles()
 			std::string filename = id.asString() + extension;
 			llinfos << " Writing " << filename << llendl;
 			
-			LLAPRFile outfile;
-			outfile.open(filename, LL_APR_WB);
+			LLAPRFile outfile(filename, LL_APR_WB);
 			outfile.write(&buffer[0], size);
 			outfile.close();
 
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index e402061e1f55902c0798bca0121f141778e0dc3d..050d4b729f5a4aa3b3a3755e2181efbd9e8ee8d3 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -385,7 +385,8 @@ class LLCachedControl
 {
 public:
 	LLCachedControl(LLControlGroup& group,
-					const std::string& name, 
+					const std::string& name,
+
 					const T& default_value, 
 					const std::string& comment = "Declared In Code")
 	{
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 194ef8af6a27c7fe98b559f4a2fd9149ae74e9ba..9d0fe781ce6ebb5f4a5f38edc866d0ef22d089cc 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -717,14 +717,6 @@ namespace LLInitParam
 			Param::enclosingBlock().paramChanged(*this, flag_as_provided);
 		}
 
-		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
-		{
-			if (!isProvided())
-			{
-				set(val, flag_as_provided);
-			}
-		}
-
 		// implicit conversion
 		operator value_assignment_t() const { return param_value_t::getValue(); } 
 		// explicit conversion
@@ -869,18 +861,10 @@ namespace LLInitParam
 			Param::enclosingBlock().paramChanged(*this, flag_as_provided);
 		}
 
-		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
-		{
-			if (!isProvided())
-			{
-				set(val, flag_as_provided);
-			}
-		}
-
 		// propagate changed status up to enclosing block
 		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
 		{ 
-			ParamValue<T, NAME_VALUE_LOOKUP>::paramChanged(changed_param, user_provided);
+			param_value_t::paramChanged(changed_param, user_provided);
 			Param::enclosingBlock().paramChanged(*this, user_provided);
 			if (user_provided)
 			{
@@ -1033,15 +1017,6 @@ namespace LLInitParam
 			Param::enclosingBlock().paramChanged(*this, flag_as_provided);
 		}
 
-
-		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
-		{
-			if (!isProvided())
-			{
-				set(val, flag_as_provided);
-			}
-		}
-
 		value_t& add()
 		{
 			mValues.push_back(param_value_t(value_t()));
@@ -1232,14 +1207,6 @@ namespace LLInitParam
 			Param::enclosingBlock().paramChanged(*this, flag_as_provided);
 		}
 
-		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
-		{
-			if (!isProvided())
-			{
-				set(val, flag_as_provided);
-			}
-		}
-
 		value_t& add()
 		{
 			mValues.push_back(value_t());
@@ -1719,6 +1686,17 @@ namespace LLInitParam
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
 		}
+
+		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block>
+		void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param, 
+			typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
+		{
+			if (!param.isProvided())
+			{
+				param.set(value, false);
+			}
+		}
+
 	};
 	
 	template<typename T>
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
index 6bc272c009aa5e6c87721c6057c2eae9bc917253..77d6d196633efd775f2279c2a03ccc12d8a2333c 100644
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
@@ -37,7 +37,6 @@ extern "C" {
 #include <stdio.h>
 #include <gst/gst.h>
 
-#include "apr_pools.h"
 #include "apr_dso.h"
 }
 
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
index 2e4baaa9eb23744e7b185f873565ac36abb5be09..93a10424dde4d521b48aeee049de9bc342c78290 100644
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
@@ -28,16 +28,18 @@
 
 #if LL_GSTREAMER010_ENABLED
 
+#include "linden_common.h"
+
 #include <string>
 
 extern "C" {
 #include <gst/gst.h>
 
-#include "apr_pools.h"
 #include "apr_dso.h"
 }
 
 #include "llmediaimplgstreamertriviallogging.h"
+#include "llaprpool.h"
 
 #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL
 #include "llmediaimplgstreamer_syms_raw.inc"
@@ -56,7 +58,7 @@ void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname)
 }
 
 static bool sSymsGrabbed = false;
-static apr_pool_t *sSymGSTDSOMemoryPool = NULL;
+static LLAPRPool sSymGSTDSOMemoryPool;
 static apr_dso_handle_t *sSymGSTDSOHandleG = NULL;
 static apr_dso_handle_t *sSymGSTDSOHandleV = NULL;
 
@@ -78,11 +80,11 @@ bool grab_gst_syms(std::string gst_dso_name,
 #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0)
 
 	//attempt to load the shared libraries
-	apr_pool_create(&sSymGSTDSOMemoryPool, NULL);
+	sSymGSTDSOMemoryPool.create();
   
 	if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle,
 					       gst_dso_name.c_str(),
-					       sSymGSTDSOMemoryPool) ))
+					       sSymGSTDSOMemoryPool()) ))
 	{
 		INFOMSG("Found DSO: %s", gst_dso_name.c_str());
 #include "llmediaimplgstreamer_syms_raw.inc"
@@ -96,7 +98,7 @@ bool grab_gst_syms(std::string gst_dso_name,
 		if ( APR_SUCCESS ==
 		     (rv = apr_dso_load(&sSymGSTDSOHandle,
 					gst_dso_name_vid.c_str(),
-					sSymGSTDSOMemoryPool) ))
+					sSymGSTDSOMemoryPool()) ))
 		{
 			INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str());
 #include "llmediaimplgstreamer_syms_rawv.inc"
@@ -150,8 +152,7 @@ void ungrab_gst_syms()
 	
 	if ( sSymGSTDSOMemoryPool )
 	{
-		apr_pool_destroy(sSymGSTDSOMemoryPool);
-		sSymGSTDSOMemoryPool = NULL;
+		sSymGSTDSOMemoryPool.destroy();
 	}
 	
 	// NULL-out all of the symbols we'd grabbed
diff --git a/indra/media_plugins/webkit/linux_volume_catcher.cpp b/indra/media_plugins/webkit/linux_volume_catcher.cpp
index 91be3a89e9a6e58cee506e4312cc250647440351..94dfd80700306ff32170cee44dff5b031c25879f 100644
--- a/indra/media_plugins/webkit/linux_volume_catcher.cpp
+++ b/indra/media_plugins/webkit/linux_volume_catcher.cpp
@@ -65,7 +65,7 @@ extern "C" {
 #undef LL_PA_SYM
 
 static bool sSymsGrabbed = false;
-static apr_pool_t *sSymPADSOMemoryPool = NULL;
+static LLAPRPool sSymPADSOMemoryPool;
 static apr_dso_handle_t *sSymPADSOHandleG = NULL;
 
 bool grab_pa_syms(std::string pulse_dso_name)
@@ -84,11 +84,11 @@ bool grab_pa_syms(std::string pulse_dso_name)
 #define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0)
 
 	//attempt to load the shared library
-	apr_pool_create(&sSymPADSOMemoryPool, NULL);
+	sSymPADSOMemoryPool.create();
   
 	if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle,
 					       pulse_dso_name.c_str(),
-					       sSymPADSOMemoryPool) ))
+					       sSymPADSOMemoryPool()) ))
 	{
 		INFOMSG("Found DSO: %s", pulse_dso_name.c_str());
 
@@ -130,12 +130,8 @@ void ungrab_pa_syms()
 		apr_dso_unload(sSymPADSOHandleG);
 		sSymPADSOHandleG = NULL;
 	}
-	
-	if ( sSymPADSOMemoryPool )
-	{
-		apr_pool_destroy(sSymPADSOMemoryPool);
-		sSymPADSOMemoryPool = NULL;
-	}
+
+	sSymPADSOMemoryPool.destroy();
 	
 	// NULL-out all of the symbols we'd grabbed
 #define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0)
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
index 96f642f2a04f2341b02ee7d210533c57e9abb042..0f74772e428acaed85ad9eca6f8401264f7636d5 100644
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
@@ -90,6 +90,7 @@ class MediaPluginWebKit :
 	bool mCookiesEnabled;
 	bool mJavascriptEnabled;
 	bool mPluginsEnabled;
+	bool mEnableMediaPluginDebugging;
 
 	enum
 	{
@@ -119,6 +120,17 @@ class MediaPluginWebKit :
 	
 	VolumeCatcher mVolumeCatcher;
 
+	void postDebugMessage( const std::string& msg )
+	{
+		if ( mEnableMediaPluginDebugging )
+		{
+			LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message");
+			debug_message.setValue("message_text", "Media> " + msg);
+			debug_message.setValue("message_level", "info");
+			sendMessage(debug_message);
+		}
+	}
+	
 	void setInitState(int state)
 	{
 //		std::cerr << "changing init state to " << state << std::endl;
@@ -252,6 +264,9 @@ class MediaPluginWebKit :
 		std::string component_dir = application_dir;
 #endif
 
+		// debug spam sent to viewer and displayed in the log as usual
+		postDebugMessage( "Component dir set to: " + component_dir );
+
 		// window handle - needed on Windows and must be app window.
 #if LL_WINDOWS
 		char window_title[ MAX_PATH ];
@@ -266,10 +281,16 @@ class MediaPluginWebKit :
 		if ( result )
 		{
 			mInitState = INIT_STATE_INITIALIZED;
-			
+
+			// debug spam sent to viewer and displayed in the log as usual
+			postDebugMessage( "browser initialized okay" );
+
 			return true;
 		};
 
+		// debug spam sent to viewer and displayed in the log as usual
+		postDebugMessage( "browser nOT initialized." );
+
 		return false;
 	};
 
@@ -292,20 +313,30 @@ class MediaPluginWebKit :
 		if(!mHostLanguage.empty())
 		{
 			LLQtWebKit::getInstance()->setHostLanguage(mHostLanguage);
+			postDebugMessage( "Setting language to " + mHostLanguage );
 		}
 
 		// turn on/off cookies based on what host app tells us
 		LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled );
-
+		
 		// turn on/off plugins based on what host app tells us
 		LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled );
 
 		// turn on/off Javascript based on what host app tells us
 		LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled );
-		
+
+		std::stringstream str;
+		str << "Cookies enabled = " << mCookiesEnabled << ", plugins enabled = " << mPluginsEnabled << ", Javascript enabled = " << mJavascriptEnabled;
+		postDebugMessage( str.str() );
+
 		// create single browser window
 		mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight, mTarget);
 
+		str.str("");
+		str.clear();
+		str << "Setting browser window size to " << mWidth << " x " << mHeight;
+		postDebugMessage( str.str() );
+
 		// tell LLQtWebKit about the size of the browser window
 		LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );
 
@@ -314,6 +345,7 @@ class MediaPluginWebKit :
 
 		// append details to agent string
 		LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
+		postDebugMessage( "Updating user agent with " + mUserAgent );
 		
 #if !LL_QTWEBKIT_USES_PIXMAPS
 		// don't flip bitmap
@@ -410,7 +442,10 @@ class MediaPluginWebKit :
 			message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK));
 			message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD));
 			sendMessage(message);
-		
+
+			// debug spam sent to viewer and displayed in the log as usual
+			postDebugMessage( "Navigate begin event at: " + event.getEventUri() );
+
 			setStatus(STATUS_LOADING);
 		}
 
@@ -452,6 +487,8 @@ class MediaPluginWebKit :
 			setInitState(INIT_STATE_NAVIGATE_COMPLETE);
 		}
 
+		// debug spam sent to viewer and displayed in the log as usual
+		postDebugMessage( "Navigate complete event at: " + event.getEventUri() );
 	}
 
 	////////////////////////////////////////////////////////////////////////////////
@@ -824,6 +861,7 @@ MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_
 	mHostLanguage = "en";		// default to english
 	mJavascriptEnabled = true;	// default to on
 	mPluginsEnabled = true;		// default to on
+	mEnableMediaPluginDebugging = false;
 	mUserAgent = "LLPluginMedia Web Browser";
 }
 
@@ -1167,6 +1205,12 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
 			{
 				authResponse(message_in);
 			}
+			else
+			if(message_name == "enable_media_plugin_debugging")
+			{
+				mEnableMediaPluginDebugging = message_in.getValueBoolean( "enable" );
+			}
+
 			else
 			if(message_name == "js_enable_object")
 			{
@@ -1321,6 +1365,15 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
 				mUserAgent = message_in.getValue("user_agent");
 				LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
 			}
+			else if(message_name == "show_web_inspector")
+			{
+#if LLQTWEBKIT_API_VERSION >= 10
+				bool val = message_in.getValueBoolean("show");
+				LLQtWebKit::getInstance()->showWebInspector( val );
+#else
+				llwarns << "Ignoring showWebInspector message (llqtwebkit version is too old)." << llendl;
+#endif
+			}
 			else if(message_name == "ignore_ssl_cert_errors")
 			{
 #if LLQTWEBKIT_API_VERSION >= 3
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index a117d9a593dcab2959e46b8343d64e294f5265f2..11b19ca4fec0cce1ba1a9276d2440a7bbd0d6201 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -368,6 +368,7 @@ set(viewer_SOURCE_FILES
     llpanelmarketplaceinbox.cpp
     llpanelmarketplaceinboxinventory.cpp
     llpanelmarketplaceoutbox.cpp
+    llpanelmarketplaceoutboxinventory.cpp
     llpanelmediasettingsgeneral.cpp
     llpanelmediasettingspermissions.cpp
     llpanelmediasettingssecurity.cpp
@@ -924,6 +925,7 @@ set(viewer_HEADER_FILES
     llpanelmarketplaceinbox.h
     llpanelmarketplaceinboxinventory.h
     llpanelmarketplaceoutbox.h
+    llpanelmarketplaceoutboxinventory.h
     llpanelmediasettingsgeneral.h
     llpanelmediasettingspermissions.h
     llpanelmediasettingssecurity.h
diff --git a/indra/newview/app_settings/CA.pem b/indra/newview/app_settings/CA.pem
index 6140842a7f743a92b985c4ae645123b725c56807..8c1b9a1f3770e834df496bf15536f190d4721eaa 100644
--- a/indra/newview/app_settings/CA.pem
+++ b/indra/newview/app_settings/CA.pem
@@ -2792,188 +2792,6 @@ KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv
 2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3
 mfnGV/TJVTl4uix5yaaIK/QI
 -----END CERTIFICATE-----
-cp . `md5 -q .`.pem
-cp ./.pem `md5 -q ./.pem`.pem
-cp ./cert000.pem `md5 -q ./cert000.pem`.pem
-cp ./cert001.pem `md5 -q ./cert001.pem`.pem
-cp ./cert002.pem `md5 -q ./cert002.pem`.pem
-cp ./cert003.pem `md5 -q ./cert003.pem`.pem
-cp ./cert004.pem `md5 -q ./cert004.pem`.pem
-cp ./cert005.pem `md5 -q ./cert005.pem`.pem
-cp ./cert006.pem `md5 -q ./cert006.pem`.pem
-cp ./cert007.pem `md5 -q ./cert007.pem`.pem
-cp ./cert008.pem `md5 -q ./cert008.pem`.pem
-cp ./cert009.pem `md5 -q ./cert009.pem`.pem
-cp ./cert010.pem `md5 -q ./cert010.pem`.pem
-cp ./cert011.pem `md5 -q ./cert011.pem`.pem
-cp ./cert012.pem `md5 -q ./cert012.pem`.pem
-cp ./cert013.pem `md5 -q ./cert013.pem`.pem
-cp ./cert014.pem `md5 -q ./cert014.pem`.pem
-cp ./cert015.pem `md5 -q ./cert015.pem`.pem
-cp ./cert016.pem `md5 -q ./cert016.pem`.pem
-cp ./cert017.pem `md5 -q ./cert017.pem`.pem
-cp ./cert018.pem `md5 -q ./cert018.pem`.pem
-cp ./cert019.pem `md5 -q ./cert019.pem`.pem
-cp ./cert020.pem `md5 -q ./cert020.pem`.pem
-cp ./cert021.pem `md5 -q ./cert021.pem`.pem
-cp ./cert022.pem `md5 -q ./cert022.pem`.pem
-cp ./cert023.pem `md5 -q ./cert023.pem`.pem
-cp ./cert024.pem `md5 -q ./cert024.pem`.pem
-cp ./cert025.pem `md5 -q ./cert025.pem`.pem
-cp ./cert026.pem `md5 -q ./cert026.pem`.pem
-cp ./cert027.pem `md5 -q ./cert027.pem`.pem
-cp ./cert028.pem `md5 -q ./cert028.pem`.pem
-cp ./cert029.pem `md5 -q ./cert029.pem`.pem
-cp ./cert030.pem `md5 -q ./cert030.pem`.pem
-cp ./cert031.pem `md5 -q ./cert031.pem`.pem
-cp ./cert032.pem `md5 -q ./cert032.pem`.pem
-cp ./cert033.pem `md5 -q ./cert033.pem`.pem
-cp ./cert034.pem `md5 -q ./cert034.pem`.pem
-cp ./cert035.pem `md5 -q ./cert035.pem`.pem
-cp ./cert036.pem `md5 -q ./cert036.pem`.pem
-cp ./cert037.pem `md5 -q ./cert037.pem`.pem
-cp ./cert038.pem `md5 -q ./cert038.pem`.pem
-cp ./cert039.pem `md5 -q ./cert039.pem`.pem
-cp ./cert040.pem `md5 -q ./cert040.pem`.pem
-cp ./cert041.pem `md5 -q ./cert041.pem`.pem
-cp ./cert042.pem `md5 -q ./cert042.pem`.pem
-cp ./cert043.pem `md5 -q ./cert043.pem`.pem
-cp ./cert044.pem `md5 -q ./cert044.pem`.pem
-cp ./cert045.pem `md5 -q ./cert045.pem`.pem
-cp ./cert046.pem `md5 -q ./cert046.pem`.pem
-cp ./cert047.pem `md5 -q ./cert047.pem`.pem
-cp ./cert048.pem `md5 -q ./cert048.pem`.pem
-cp ./cert049.pem `md5 -q ./cert049.pem`.pem
-cp ./cert050.pem `md5 -q ./cert050.pem`.pem
-cp ./cert051.pem `md5 -q ./cert051.pem`.pem
-cp ./cert052.pem `md5 -q ./cert052.pem`.pem
-cp ./cert053.pem `md5 -q ./cert053.pem`.pem
-cp ./cert054.pem `md5 -q ./cert054.pem`.pem
-cp ./cert055.pem `md5 -q ./cert055.pem`.pem
-cp ./cert056.pem `md5 -q ./cert056.pem`.pem
-cp ./cert057.pem `md5 -q ./cert057.pem`.pem
-cp ./cert058.pem `md5 -q ./cert058.pem`.pem
-cp ./cert059.pem `md5 -q ./cert059.pem`.pem
-cp ./cert060.pem `md5 -q ./cert060.pem`.pem
-cp ./cert061.pem `md5 -q ./cert061.pem`.pem
-cp ./cert062.pem `md5 -q ./cert062.pem`.pem
-cp ./cert063.pem `md5 -q ./cert063.pem`.pem
-cp ./cert064.pem `md5 -q ./cert064.pem`.pem
-cp ./cert065.pem `md5 -q ./cert065.pem`.pem
-cp ./cert066.pem `md5 -q ./cert066.pem`.pem
-cp ./cert067.pem `md5 -q ./cert067.pem`.pem
-cp ./cert068.pem `md5 -q ./cert068.pem`.pem
-cp ./cert069.pem `md5 -q ./cert069.pem`.pem
-cp ./cert070.pem `md5 -q ./cert070.pem`.pem
-cp ./cert071.pem `md5 -q ./cert071.pem`.pem
-cp ./cert072.pem `md5 -q ./cert072.pem`.pem
-cp ./cert073.pem `md5 -q ./cert073.pem`.pem
-cp ./cert074.pem `md5 -q ./cert074.pem`.pem
-cp ./cert075.pem `md5 -q ./cert075.pem`.pem
-cp ./cert076.pem `md5 -q ./cert076.pem`.pem
-cp ./cert077.pem `md5 -q ./cert077.pem`.pem
-cp ./cert078.pem `md5 -q ./cert078.pem`.pem
-cp ./cert079.pem `md5 -q ./cert079.pem`.pem
-cp ./cert080.pem `md5 -q ./cert080.pem`.pem
-cp ./cert081.pem `md5 -q ./cert081.pem`.pem
-cp ./cert082.pem `md5 -q ./cert082.pem`.pem
-cp ./cert083.pem `md5 -q ./cert083.pem`.pem
-cp ./cert084.pem `md5 -q ./cert084.pem`.pem
-cp ./cert085.pem `md5 -q ./cert085.pem`.pem
-cp ./cert086.pem `md5 -q ./cert086.pem`.pem
-cp ./cert087.pem `md5 -q ./cert087.pem`.pem
-cp ./cert088.pem `md5 -q ./cert088.pem`.pem
-cp ./cert089.pem `md5 -q ./cert089.pem`.pem
-cp ./cert090.pem `md5 -q ./cert090.pem`.pem
-cp ./cert091.pem `md5 -q ./cert091.pem`.pem
-cp ./cert092.pem `md5 -q ./cert092.pem`.pem
-cp ./cert093.pem `md5 -q ./cert093.pem`.pem
-cp ./cert094.pem `md5 -q ./cert094.pem`.pem
-cp ./cert095.pem `md5 -q ./cert095.pem`.pem
-cp ./cert096.pem `md5 -q ./cert096.pem`.pem
-cp ./cert097.pem `md5 -q ./cert097.pem`.pem
-cp ./cert098.pem `md5 -q ./cert098.pem`.pem
-cp ./cert099.pem `md5 -q ./cert099.pem`.pem
-cp ./cert100.pem `md5 -q ./cert100.pem`.pem
-cp ./cert101.pem `md5 -q ./cert101.pem`.pem
-cp ./cert102.pem `md5 -q ./cert102.pem`.pem
-cp ./cert103.pem `md5 -q ./cert103.pem`.pem
-cp ./cert104.pem `md5 -q ./cert104.pem`.pem
-cp ./cert105.pem `md5 -q ./cert105.pem`.pem
-cp ./cert106.pem `md5 -q ./cert106.pem`.pem
-cp ./cert107.pem `md5 -q ./cert107.pem`.pem
-cp ./cert108.pem `md5 -q ./cert108.pem`.pem
-cp ./cert109.pem `md5 -q ./cert109.pem`.pem
-cp ./cert110.pem `md5 -q ./cert110.pem`.pem
-cp ./cert111.pem `md5 -q ./cert111.pem`.pem
-cp ./cert112.pem `md5 -q ./cert112.pem`.pem
-cp ./cert113.pem `md5 -q ./cert113.pem`.pem
-cp ./cert114.pem `md5 -q ./cert114.pem`.pem
-cp ./cert115.pem `md5 -q ./cert115.pem`.pem
-cp ./cert116.pem `md5 -q ./cert116.pem`.pem
-cp ./cert117.pem `md5 -q ./cert117.pem`.pem
-cp ./cert118.pem `md5 -q ./cert118.pem`.pem
-cp ./cert119.pem `md5 -q ./cert119.pem`.pem
-cp ./cert120.pem `md5 -q ./cert120.pem`.pem
-cp ./cert121.pem `md5 -q ./cert121.pem`.pem
-cp ./cert122.pem `md5 -q ./cert122.pem`.pem
-cp ./cert123.pem `md5 -q ./cert123.pem`.pem
-cp ./cert124.pem `md5 -q ./cert124.pem`.pem
-cp ./cert125.pem `md5 -q ./cert125.pem`.pem
-cp ./cert126.pem `md5 -q ./cert126.pem`.pem
-cp ./cert127.pem `md5 -q ./cert127.pem`.pem
-cp ./cert128.pem `md5 -q ./cert128.pem`.pem
-cp ./cert129.pem `md5 -q ./cert129.pem`.pem
-cp ./cert130.pem `md5 -q ./cert130.pem`.pem
-cp ./cert131.pem `md5 -q ./cert131.pem`.pem
-cp ./cert132.pem `md5 -q ./cert132.pem`.pem
-cp ./cert133.pem `md5 -q ./cert133.pem`.pem
-cp ./cert134.pem `md5 -q ./cert134.pem`.pem
-cp ./cert135.pem `md5 -q ./cert135.pem`.pem
-cp ./cert136.pem `md5 -q ./cert136.pem`.pem
-cp ./cert137.pem `md5 -q ./cert137.pem`.pem
-cp ./cert138.pem `md5 -q ./cert138.pem`.pem
-cp ./cert139.pem `md5 -q ./cert139.pem`.pem
-cp ./cert140.pem `md5 -q ./cert140.pem`.pem
-cp ./cert141.pem `md5 -q ./cert141.pem`.pem
-cp ./cert142.pem `md5 -q ./cert142.pem`.pem
-cp ./cert143.pem `md5 -q ./cert143.pem`.pem
-cp ./cert144.pem `md5 -q ./cert144.pem`.pem
-cp ./cert145.pem `md5 -q ./cert145.pem`.pem
-cp ./cert146.pem `md5 -q ./cert146.pem`.pem
-cp ./cert147.pem `md5 -q ./cert147.pem`.pem
-cp ./cert148.pem `md5 -q ./cert148.pem`.pem
-cp ./cert149.pem `md5 -q ./cert149.pem`.pem
-cp ./cert150.pem `md5 -q ./cert150.pem`.pem
-cp ./cert151.pem `md5 -q ./cert151.pem`.pem
-cp ./cert152.pem `md5 -q ./cert152.pem`.pem
-cp ./cert153.pem `md5 -q ./cert153.pem`.pem
-cp ./cert154.pem `md5 -q ./cert154.pem`.pem
-cp ./cert155.pem `md5 -q ./cert155.pem`.pem
-cp ./cert156.pem `md5 -q ./cert156.pem`.pem
-cp ./cert157.pem `md5 -q ./cert157.pem`.pem
-cp ./cert158.pem `md5 -q ./cert158.pem`.pem
-cp ./cert159.pem `md5 -q ./cert159.pem`.pem
-cp ./cert160.pem `md5 -q ./cert160.pem`.pem
-cp ./cert161.pem `md5 -q ./cert161.pem`.pem
-cp ./cert162.pem `md5 -q ./cert162.pem`.pem
-cp ./cert163.pem `md5 -q ./cert163.pem`.pem
-cp ./cert164.pem `md5 -q ./cert164.pem`.pem
-cp ./cert165.pem `md5 -q ./cert165.pem`.pem
-cp ./cert166.pem `md5 -q ./cert166.pem`.pem
-cp ./cert167.pem `md5 -q ./cert167.pem`.pem
-cp ./cert168.pem `md5 -q ./cert168.pem`.pem
-cp ./cert169.pem `md5 -q ./cert169.pem`.pem
-cp ./cert170.pem `md5 -q ./cert170.pem`.pem
-cp ./cert171.pem `md5 -q ./cert171.pem`.pem
-cp ./cert172.pem `md5 -q ./cert172.pem`.pem
-cp ./cert173.pem `md5 -q ./cert173.pem`.pem
-cp ./cert174.pem `md5 -q ./cert174.pem`.pem
-cp ./cert175.pem `md5 -q ./cert175.pem`.pem
-cp ./cert176.pem `md5 -q ./cert176.pem`.pem
-cp ./cert177.pem `md5 -q ./cert177.pem`.pem
-cp ./cert178.pem `md5 -q ./cert178.pem`.pem
-cp ./foo.sh `md5 -q ./foo.sh`.pem
 -----BEGIN CERTIFICATE-----
 MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
 GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
@@ -3012,136 +2830,6 @@ Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
 mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
 4SVhM7JZG+Ju1zdXtg2pEto=
 -----END CERTIFICATE-----
-cp . `md5 -q .`.pem
-cp ./cert000 `md5 -q ./cert000`.pem
-cp ./cert001 `md5 -q ./cert001`.pem
-cp ./cert002 `md5 -q ./cert002`.pem
-cp ./cert003 `md5 -q ./cert003`.pem
-cp ./cert004 `md5 -q ./cert004`.pem
-cp ./cert005 `md5 -q ./cert005`.pem
-cp ./cert006 `md5 -q ./cert006`.pem
-cp ./cert007 `md5 -q ./cert007`.pem
-cp ./cert008 `md5 -q ./cert008`.pem
-cp ./cert009 `md5 -q ./cert009`.pem
-cp ./cert010 `md5 -q ./cert010`.pem
-cp ./cert011 `md5 -q ./cert011`.pem
-cp ./cert012 `md5 -q ./cert012`.pem
-cp ./cert013 `md5 -q ./cert013`.pem
-cp ./cert014 `md5 -q ./cert014`.pem
-cp ./cert015 `md5 -q ./cert015`.pem
-cp ./cert016 `md5 -q ./cert016`.pem
-cp ./cert017 `md5 -q ./cert017`.pem
-cp ./cert018 `md5 -q ./cert018`.pem
-cp ./cert019 `md5 -q ./cert019`.pem
-cp ./cert020 `md5 -q ./cert020`.pem
-cp ./cert021 `md5 -q ./cert021`.pem
-cp ./cert022 `md5 -q ./cert022`.pem
-cp ./cert023 `md5 -q ./cert023`.pem
-cp ./cert024 `md5 -q ./cert024`.pem
-cp ./cert025 `md5 -q ./cert025`.pem
-cp ./cert026 `md5 -q ./cert026`.pem
-cp ./cert027 `md5 -q ./cert027`.pem
-cp ./cert028 `md5 -q ./cert028`.pem
-cp ./cert029 `md5 -q ./cert029`.pem
-cp ./cert030 `md5 -q ./cert030`.pem
-cp ./cert031 `md5 -q ./cert031`.pem
-cp ./cert032 `md5 -q ./cert032`.pem
-cp ./cert033 `md5 -q ./cert033`.pem
-cp ./cert034 `md5 -q ./cert034`.pem
-cp ./cert035 `md5 -q ./cert035`.pem
-cp ./cert036 `md5 -q ./cert036`.pem
-cp ./cert037 `md5 -q ./cert037`.pem
-cp ./cert038 `md5 -q ./cert038`.pem
-cp ./cert039 `md5 -q ./cert039`.pem
-cp ./cert040 `md5 -q ./cert040`.pem
-cp ./cert041 `md5 -q ./cert041`.pem
-cp ./cert042 `md5 -q ./cert042`.pem
-cp ./cert043 `md5 -q ./cert043`.pem
-cp ./cert044 `md5 -q ./cert044`.pem
-cp ./cert045 `md5 -q ./cert045`.pem
-cp ./cert046 `md5 -q ./cert046`.pem
-cp ./cert047 `md5 -q ./cert047`.pem
-cp ./cert048 `md5 -q ./cert048`.pem
-cp ./cert049 `md5 -q ./cert049`.pem
-cp ./cert050 `md5 -q ./cert050`.pem
-cp ./cert051 `md5 -q ./cert051`.pem
-cp ./cert052 `md5 -q ./cert052`.pem
-cp ./cert053 `md5 -q ./cert053`.pem
-cp ./cert054 `md5 -q ./cert054`.pem
-cp ./cert055 `md5 -q ./cert055`.pem
-cp ./cert056 `md5 -q ./cert056`.pem
-cp ./cert057 `md5 -q ./cert057`.pem
-cp ./cert058 `md5 -q ./cert058`.pem
-cp ./cert059 `md5 -q ./cert059`.pem
-cp ./cert060 `md5 -q ./cert060`.pem
-cp ./cert061 `md5 -q ./cert061`.pem
-cp ./cert062 `md5 -q ./cert062`.pem
-cp ./cert063 `md5 -q ./cert063`.pem
-cp ./cert064 `md5 -q ./cert064`.pem
-cp ./cert065 `md5 -q ./cert065`.pem
-cp ./cert066 `md5 -q ./cert066`.pem
-cp ./cert067 `md5 -q ./cert067`.pem
-cp ./cert068 `md5 -q ./cert068`.pem
-cp ./cert069 `md5 -q ./cert069`.pem
-cp ./cert070 `md5 -q ./cert070`.pem
-cp ./cert071 `md5 -q ./cert071`.pem
-cp ./cert072 `md5 -q ./cert072`.pem
-cp ./cert073 `md5 -q ./cert073`.pem
-cp ./cert074 `md5 -q ./cert074`.pem
-cp ./cert075 `md5 -q ./cert075`.pem
-cp ./cert076 `md5 -q ./cert076`.pem
-cp ./cert077 `md5 -q ./cert077`.pem
-cp ./cert078 `md5 -q ./cert078`.pem
-cp ./cert079 `md5 -q ./cert079`.pem
-cp ./cert080 `md5 -q ./cert080`.pem
-cp ./cert081 `md5 -q ./cert081`.pem
-cp ./cert082 `md5 -q ./cert082`.pem
-cp ./cert083 `md5 -q ./cert083`.pem
-cp ./cert084 `md5 -q ./cert084`.pem
-cp ./cert085 `md5 -q ./cert085`.pem
-cp ./cert086 `md5 -q ./cert086`.pem
-cp ./cert087 `md5 -q ./cert087`.pem
-cp ./cert088 `md5 -q ./cert088`.pem
-cp ./cert089 `md5 -q ./cert089`.pem
-cp ./cert090 `md5 -q ./cert090`.pem
-cp ./cert091 `md5 -q ./cert091`.pem
-cp ./cert092 `md5 -q ./cert092`.pem
-cp ./cert093 `md5 -q ./cert093`.pem
-cp ./cert094 `md5 -q ./cert094`.pem
-cp ./cert095 `md5 -q ./cert095`.pem
-cp ./cert096 `md5 -q ./cert096`.pem
-cp ./cert097 `md5 -q ./cert097`.pem
-cp ./cert098 `md5 -q ./cert098`.pem
-cp ./cert099 `md5 -q ./cert099`.pem
-cp ./cert100 `md5 -q ./cert100`.pem
-cp ./cert101 `md5 -q ./cert101`.pem
-cp ./cert102 `md5 -q ./cert102`.pem
-cp ./cert103 `md5 -q ./cert103`.pem
-cp ./cert104 `md5 -q ./cert104`.pem
-cp ./cert105 `md5 -q ./cert105`.pem
-cp ./cert106 `md5 -q ./cert106`.pem
-cp ./cert107 `md5 -q ./cert107`.pem
-cp ./cert108 `md5 -q ./cert108`.pem
-cp ./cert109 `md5 -q ./cert109`.pem
-cp ./cert110 `md5 -q ./cert110`.pem
-cp ./cert111 `md5 -q ./cert111`.pem
-cp ./cert112 `md5 -q ./cert112`.pem
-cp ./cert113 `md5 -q ./cert113`.pem
-cp ./cert114 `md5 -q ./cert114`.pem
-cp ./cert115 `md5 -q ./cert115`.pem
-cp ./cert116 `md5 -q ./cert116`.pem
-cp ./cert117 `md5 -q ./cert117`.pem
-cp ./cert118 `md5 -q ./cert118`.pem
-cp ./cert119 `md5 -q ./cert119`.pem
-cp ./cert120 `md5 -q ./cert120`.pem
-cp ./cert121 `md5 -q ./cert121`.pem
-cp ./cert122 `md5 -q ./cert122`.pem
-cp ./cert123 `md5 -q ./cert123`.pem
-cp ./cert124 `md5 -q ./cert124`.pem
-cp ./cert125 `md5 -q ./cert125`.pem
-cp ./cert126 `md5 -q ./cert126`.pem
-cp ./cert127 `md5 -q ./cert127`.pem
-cp ./foo.sh `md5 -q ./foo.sh`.pem
 -----BEGIN CERTIFICATE-----
 MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET
 MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE
@@ -4587,60 +4275,6 @@ zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy
 wy39FCqQmbkHzJ8=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIFijCCA3KgAwIBAgIQDHbanJEMTiye/hXQWJM8TDANBgkqhkiG9w0BAQUFADBf
-MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp
-Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww
-HhcNMDcwNTE2MTcxOTM2WhcNMjUwMzMxMTgxOTIxWjBfMQswCQYDVQQGEwJOTDES
-MBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdpTm90YXIgUm9vdCBDQTEg
-MB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmwwggIiMA0GCSqGSIb3DQEB
-AQUAA4ICDwAwggIKAoICAQCssFjBAL3YIQgLK5r+blYwBZ8bd5AQQVzDDYcRd46B
-8cp86Yxq7Th0Nbva3/m7wAk3tJZzgX0zGpg595NvlX89ubF1h7pRSOiLcD6VBMXY
-tsMW2YiwsYcdcNqGtA8Ui3rPENF0NqISe3eGSnnme98CEWilToauNFibJBN4ViIl
-HgGLS1Fx+4LMWZZpiFpoU8W5DQI3y0u8ZkqQfioLBQftFl9VkHXYRskbg+IIvvEj
-zJkd1ioPgyAVWCeCLvriIsJJsbkBgWqdbZ1Ad2h2TiEqbYRAhU52mXyC8/O3AlnU
-JgEbjt+tUwbRrhjd4rI6y9eIOI6sWym5GdOY+RgDz0iChmYLG2kPyes4iHomGgVM
-ktck1JbyrFIto0fVUvY//s6EBnCmqj6i8rZWNBhXouSBbefK8GrTx5FrAoNBfBXv
-a5pkXuPQPOWx63tdhvvL5ndJzaNl3Pe5nLjkC1+Tz8wwGjIczhxjlaX56uF0i57p
-K6kwe6AYHw4YC+VbqdPRbB4HZ4+RS6mKvNJmqpMBiLKR+jFc1abBUggJzQpjotMi
-puih2TkGl/VujQKQjBR7P4DNG5y6xFhyI6+2Vp/GekIzKQc/gsnmHwUNzUwoNovT
-yD4cxojvXu6JZOkd69qJfjKmadHdzIif0dDJZiHcBmfFlHqabWJMfczgZICynkeO
-owIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
-HQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wDQYJKoZIhvcNAQEFBQADggIBADsC
-jcs8MOhuoK3yc7NfniUTBAXT9uOLuwt5zlPe5JbF0a9zvNXD0EBVfEB/zRtfCdXy
-fJ9oHbtdzno5wozWmHvFg1Wo1X1AyuAe94leY12hE8JdiraKfADzI8PthV9xdvBo
-Y6pFITlIYXg23PFDk9Qlx/KAZeFTAnVR/Ho67zerhChXDNjU1JlWbOOi/lmEtDHo
-M/hklJRRl6s5xUvt2t2AC298KQ3EjopyDedTFLJgQT2EkTFoPSdE2+Xe9PpjRchM
-Ppj1P0G6Tss3DbpmmPHdy59c91Q2gmssvBNhl0L4eLvMyKKfyvBovWsdst+Nbwed
-2o5nx0ceyrm/KkKRt2NTZvFCo+H0Wk1Ya7XkpDOtXHAd3ODy63MUkZoDweoAZbwH
-/M8SESIsrqC9OuCiKthZ6SnTGDWkrBFfGbW1G/8iSlzGeuQX7yCpp/Q/rYqnmgQl
-nQ7KN+ZQ/YxCKQSa7LnPS3K94gg2ryMvYuXKAdNw23yCIywWMQzGNgeQerEfZ1jE
-O1hZibCMjFCz2IbLaKPECudpSyDOwR5WS5WpI2jYMNjD67BVUc3l/Su49bsRn1NU
-9jQZjHkJNsphFyUXC4KYcwx3dMPVDceoEkzHp1RxRy4sGn3J4ys7SN4nhKdjNrN9
-j6BkOSQNPXuHr2ZcdBtLc7LljPCGmbjlxd+Ewbfr
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO
-TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh
-dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy
-MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk
-ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn
-ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71
-9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO
-hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U
-tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o
-BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh
-SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww
-OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv
-cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA
-7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k
-/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm
-eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6
-u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy
-7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
-iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
 MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
 MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
 bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2
@@ -5915,3 +5549,25 @@ na9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkhMp6q
 qIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0Z
 TbvGRNs2yyqcjg==
 -----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO
+TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy
+MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk
+ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn
+ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71
+9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO
+hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U
+tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o
+BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh
+SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww
+OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv
+cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA
+7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k
+/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm
+eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6
+u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy
+7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
+iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
+-----END CERTIFICATE-----
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 31a2a1dc00ce261b707af6cbd71fe2462b66c6dc..f4535f12f862afae4c2e41b91fb93588dae170d1 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -25,7 +25,7 @@
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <real>0</real>
+      <real>300</real>
     </map>
     <key>AdminMenu</key>
     <map>
@@ -1981,6 +1981,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>DebugShowPrivateMem</key>
+    <map>
+      <key>Comment</key>
+      <string>Show Private Mem Info</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>DebugShowRenderInfo</key>
     <map>
       <key>Comment</key>
@@ -4270,6 +4281,17 @@
 		<key>Value</key>
 		<integer>0</integer>
 	</map>
+    <key>InventoryMarketplaceUserStatus</key>
+    <map>
+      <key>Comment</key>
+      <string>Marketplace user status.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string />
+    </map>
     <key>InventorySortOrder</key>
     <map>
       <key>Comment</key>
@@ -5459,6 +5481,17 @@
       <key>Value</key>
       <real>48.0</real>
     </map>
+    <key>MaxHeapSize</key>
+    <map>
+      <key>Comment</key>
+      <string>Maximum heap size (GB)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>1.6</real>
+    </map>
     <key>MaxSelectDistance</key>
     <map>
       <key>Comment</key>
@@ -5481,6 +5514,17 @@
       <key>Value</key>
       <real>60.0</real>
     </map>
+  <key>MediaPluginDebugging</key>
+  <map>
+    <key>Comment</key>
+    <string>Turn on debugging messages that may help diagnosing media issues (WARNING: May reduce performance).</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
   <key>MediaControlFadeTime</key>
   <map>
     <key>Comment</key>
@@ -5580,6 +5624,17 @@
     <key>Value</key>
     <integer>1</integer>
   </map>
+  <key>MemoryFailurePreventionEnabled</key>
+  <map>
+    <key>Comment</key>
+    <string>If set, the viewer will quit to avoid crash when memory failure happens</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
   <key>MemoryLogFrequency</key>
         <map>
         <key>Comment</key>
@@ -5591,6 +5646,17 @@
         <key>Value</key>
             <real>600.0</real>
         </map>
+    <key>MemoryPrivatePoolEnabled</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable the private memory pool management</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>MemProfiling</key>
     <map>
       <key>Comment</key>
@@ -7050,17 +7116,6 @@
       <key>Value</key>
       <real>0.0</real>
     </map>
-    <key>QuitAfterSecondsOfAFK</key>
-    <map>
-      <key>Comment</key>
-      <string>The duration allowed after being AFK before quitting.</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>F32</string>
-      <key>Value</key>
-      <real>0.0</real>
-    </map>
     <key>QuitOnLoginActivated</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 1142f01232c9c1df3693725e55b6e2596c6e57c1..d8295ddb876a3d60eb6771f16f4a70fa1da17e29 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -33,16 +33,16 @@
         <key>Value</key>
             <string />
         </map>
-    <key>LastInventoryInboxExpand</key>
-       <map>
-            <key>Comment</key>
-            <string>The last time the received items inbox was expanded.</string>
-            <key>Persist</key>
+    <key>LastInventoryInboxActivity</key>
+        <map>
+        <key>Comment</key>
+            <string>The last time the received items inbox was poked by the user.</string>
+        <key>Persist</key>
             <integer>1</integer>
-            <key>Type</key>
-            <string>String</string>
-            <key>Value</key>
-            <string />
+        <key>Type</key>
+            <string>U32</string>
+        <key>Value</key>
+            <integer>0</integer>
         </map>
     <key>LastLogoff</key>
         <map>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 642a1907f0078f10a7ae7f3eb317a90e1b792150..296ae8f10b973e364e102ad94238928c24c1c89e 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -107,7 +107,6 @@ const F64 CHAT_AGE_FAST_RATE = 3.0;
 const F32 MIN_FIDGET_TIME = 8.f; // seconds
 const F32 MAX_FIDGET_TIME = 20.f; // seconds
 
-
 // The agent instance.
 LLAgent gAgent;
 
@@ -115,6 +114,9 @@ LLAgent gAgent;
 // Statics
 //
 
+/// minimum time after setting away state before coming back based on movement
+const F32 LLAgent::MIN_AFK_TIME = 10.0f;
+
 const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f;
 
 std::map<std::string, std::string> LLAgent::sTeleportErrorMessages;
@@ -1165,6 +1167,7 @@ void LLAgent::setAFK()
 	{
 		sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_START);
 		setControlFlags(AGENT_CONTROL_AWAY | AGENT_CONTROL_STOP);
+		LL_INFOS("AFK") << "Setting Away" << LL_ENDL;
 		gAwayTimer.start();
 		if (gAFKMenu)
 		{
@@ -1188,6 +1191,7 @@ void LLAgent::clearAFK()
 	{
 		sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_STOP);
 		clearControlFlags(AGENT_CONTROL_AWAY);
+		LL_INFOS("AFK") << "Clearing Away" << LL_ENDL;
 		if (gAFKMenu)
 		{
 			gAFKMenu->setLabel(LLTrans::getString("AvatarSetAway"));
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 67ed1923c0cbb7adf25f02d7803713a34e21c5db..5e23ced4243c1b065617869dfa9509715583707a 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -318,7 +318,8 @@ class LLAgent : public LLOldEvents::LLObservable
 	void			setAFK();
 	void			clearAFK();
 	BOOL			getAFK() const;
-
+	static const F32 MIN_AFK_TIME;
+	
 	//--------------------------------------------------------------------
 	// Run
 	//--------------------------------------------------------------------
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 1388d9aee010e87806b0efdccf6488be97cd2e1d..3cb9b77010eed60ce98d493cae49f1acd950426e 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -2285,7 +2285,9 @@ void LLAppearanceMgr::autopopulateOutfits()
 void LLAppearanceMgr::onFirstFullyVisible()
 {
 	gAgentAvatarp->debugAvatarVisible();
-	autopopulateOutfits();
+	// The auto-populate is failing at the point of generating outfits
+	// folders, so don't do the library copy until that is resolved.
+	// autopopulateOutfits();
 }
 
 bool LLAppearanceMgr::updateBaseOutfit()
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6a808b5daf0aa7e94bb08040116acd95b03d2fa2..2e1108d42c1a5f0944f29ddd1ef808b04a87411a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -247,7 +247,6 @@ extern BOOL gDebugGL;
 
 ////////////////////////////////////////////////////////////
 // All from the last globals push...
-const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard
 
 F32 gSimLastTime; // Used in LLAppViewer::init and send_stats()
 F32 gSimFrames;
@@ -430,8 +429,11 @@ static bool app_metrics_qa_mode = false;
 void idle_afk_check()
 {
 	// check idle timers
-	if (gSavedSettings.getS32("AFKTimeout") && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getS32("AFKTimeout")))
+	F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32();
+	F32 afk_timeout  = gSavedSettings.getS32("AFKTimeout");
+	if (afk_timeout && (current_idle > afk_timeout) && ! gAgent.getAFK())
 	{
+		LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL;
 		gAgent.setAFK();
 	}
 }
@@ -686,7 +688,7 @@ LLAppViewer::~LLAppViewer()
 }
 
 bool LLAppViewer::init()
-{
+{	
 	//
 	// Start of the application
 	//
@@ -719,6 +721,11 @@ bool LLAppViewer::init()
 
 	LL_INFOS("InitInfo") << "Configuration initialized." << LL_ENDL ;
 
+	//set the max heap size.
+	initMaxHeapSize() ;
+
+	LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled")) ;
+
 	// write Google Breakpad minidump files to our log directory
 	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
 	logdir += gDirUtilp->getDirDelimiter();
@@ -781,6 +788,12 @@ bool LLAppViewer::init()
 		&LLUI::sGLScaleFactor);
 	LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
 
+	// Setup paths and LLTrans after LLUI::initClass has been called.
+	LLUI::setupPaths();
+	LLTransUtil::parseStrings("strings.xml", default_trans_args);
+	LLTransUtil::parseLanguageStrings("language_settings.xml");
+
+	// Setup notifications after LLUI::setupPaths() has been called.
 	LLNotifications::instance();
 	LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
 
@@ -826,12 +839,6 @@ bool LLAppViewer::init()
 		LLError::setPrintLocation(true);
 	}
 
-
-	// Setup paths and LLTrans after LLUI::initClass has been called
-	LLUI::setupPaths();
-	LLTransUtil::parseStrings("strings.xml", default_trans_args);		
-	LLTransUtil::parseLanguageStrings("language_settings.xml");
-	
 	// LLKeyboard relies on LLUI to know what some accelerator keys are called.
 	LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString );
 
@@ -1088,9 +1095,97 @@ bool LLAppViewer::init()
 
 	LLAgentLanguage::init();
 
+	return true;
+}
+
+void LLAppViewer::initMaxHeapSize()
+{
+	//set the max heap size.
+	//here is some info regarding to the max heap size:
+	//------------------------------------------------------------------------------------------
+	// OS       | setting | SL address bits | max manageable memory space | max heap size
+	// Win 32   | default | 32-bit          | 2GB                         | < 1.7GB
+	// Win 32   | /3G     | 32-bit          | 3GB                         | < 1.7GB or 2.7GB
+	//Linux 32  | default | 32-bit          | 3GB                         | < 2.7GB
+	//Linux 32  |HUGEMEM  | 32-bit          | 4GB                         | < 3.7GB
+	//64-bit OS |default  | 32-bit          | 4GB                         | < 3.7GB
+	//64-bit OS |default  | 64-bit          | N/A (> 4GB)                 | N/A (> 4GB)
+	//------------------------------------------------------------------------------------------
+	//currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB.
+
+	//F32 max_heap_size_gb = llmin(1.6f, (F32)gSavedSettings.getF32("MaxHeapSize")) ;
+	F32 max_heap_size_gb = gSavedSettings.getF32("MaxHeapSize") ;
+	BOOL enable_mem_failure_prevention = (BOOL)gSavedSettings.getBOOL("MemoryFailurePreventionEnabled") ;
+
+	LLMemory::initMaxHeapSizeGB(max_heap_size_gb, enable_mem_failure_prevention) ;
+}
+
+void LLAppViewer::checkMemory()
+{
+	const static F32 MEMORY_CHECK_INTERVAL = 1.0f ; //second
+	//const static F32 MAX_QUIT_WAIT_TIME = 30.0f ; //seconds
+	const static U32 MAX_SIZE_CHECKED_MEMORY_BLOCK = 64 * 1024 * 1024 ; //64 MB
+	//static F32 force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ;
+	static void* last_reserved_address = NULL ;
 
+	if(MEMORY_CHECK_INTERVAL > mMemCheckTimer.getElapsedTimeF32())
+	{
+		return ;
+	}
+	mMemCheckTimer.reset() ;
 
-	return true;
+	if(gGLManager.mDebugGPU)
+	{
+		//update the availability of memory
+		LLMemory::updateMemoryInfo() ;
+	}
+
+	//check the virtual address space fragmentation
+	if(!last_reserved_address)
+	{
+		last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ;
+	}
+	else
+	{
+		last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ;
+		if(!last_reserved_address) //failed, try once more
+		{
+			last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ;
+		}
+	}
+
+	S32 is_low = !last_reserved_address || LLMemory::isMemoryPoolLow() ;
+
+	//if(is_low < 0) //to force quit
+	//{
+	//	if(force_quit_timer > MAX_QUIT_WAIT_TIME) //just hit the limit for the first time
+	//	{
+	//		//send out the notification to tell the viewer is about to quit in 30 seconds.
+	//		LLNotification::Params params("ForceQuitDueToLowMemory");
+	//		LLNotifications::instance().add(params);
+
+	//		force_quit_timer = MAX_QUIT_WAIT_TIME - MEMORY_CHECK_INTERVAL ;
+	//	}
+	//	else
+	//	{
+	//		force_quit_timer -= MEMORY_CHECK_INTERVAL ;
+	//		if(force_quit_timer < 0.f)
+	//		{
+	//			forceQuit() ; //quit
+	//		}
+	//	}
+	//}
+	//else
+	//{
+	//	force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ;
+	//}
+
+	LLPipeline::throttleNewMemoryAllocation(!is_low ? FALSE : TRUE) ;		
+	
+	if(is_low)
+	{
+		LLMemory::logMemoryInfo() ;
+	}
 }
 
 static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages");
@@ -1118,7 +1213,7 @@ bool LLAppViewer::mainLoop()
 	//-------------------------------------------
 
 	// Create IO Pump to use for HTTP Requests.
-	gServicePump = new LLPumpIO(gAPRPoolp);
+	gServicePump = new LLPumpIO;
 	LLHTTPClient::setPump(*gServicePump);
 	LLCurl::setCAFile(gDirUtilp->getCAFile());
 
@@ -1128,7 +1223,6 @@ bool LLAppViewer::mainLoop()
 	LLVoiceClient::getInstance()->init(gServicePump);
 	LLTimer frameTimer,idleTimer;
 	LLTimer debugTime;
-	LLFrameTimer memCheckTimer;
 	LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
 	joystick->setNeedsReset(true);
 
@@ -1139,7 +1233,9 @@ bool LLAppViewer::mainLoop()
     // point of posting.
     LLSD newFrame;
 
-	const F32 memory_check_interval = 1.0f ; //second
+	//LLPrivateMemoryPoolTester::getInstance()->run(false) ;
+	//LLPrivateMemoryPoolTester::getInstance()->run(true) ;
+	//LLPrivateMemoryPoolTester::destroy() ;
 
 	// Handle messages
 	while (!LLApp::isExiting())
@@ -1150,18 +1246,8 @@ bool LLAppViewer::mainLoop()
 		llclearcallstacks;
 
 		//check memory availability information
-		{
-			if(memory_check_interval < memCheckTimer.getElapsedTimeF32())
-			{
-				memCheckTimer.reset() ;
-
-				//update the availability of memory
-				LLMemoryInfo::getAvailableMemoryKB(mAvailPhysicalMemInKB, mAvailVirtualMemInKB) ;
-			}
-			llcallstacks << "Available physical mem(KB): " << mAvailPhysicalMemInKB << llcallstacksendl ;
-			llcallstacks << "Available virtual mem(KB): " << mAvailVirtualMemInKB << llcallstacksendl ;
-		}
-
+		checkMemory() ;
+		
 		try
 		{
 			pingMainloopTimeout("Main:MiscNativeWindowEvents");
@@ -1325,7 +1411,7 @@ bool LLAppViewer::mainLoop()
 				idleTimer.reset();
 				bool is_slow = (frameTimer.getElapsedTimeF64() > FRAME_SLOW_THRESHOLD) ;
 				S32 total_work_pending = 0;
-				S32 total_io_pending = 0;				
+				S32 total_io_pending = 0;	
 				while(!is_slow)//do not unpause threads if the frame rates are very low.
 				{
 					S32 work_pending = 0;
@@ -1393,15 +1479,7 @@ bool LLAppViewer::mainLoop()
 		}
 		catch(std::bad_alloc)
 		{			
-			{
-				llinfos << "Availabe physical memory(KB) at the beginning of the frame: " << mAvailPhysicalMemInKB << llendl ;
-				llinfos << "Availabe virtual memory(KB) at the beginning of the frame: " << mAvailVirtualMemInKB << llendl ;
-
-				LLMemoryInfo::getAvailableMemoryKB(mAvailPhysicalMemInKB, mAvailVirtualMemInKB) ;
-
-				llinfos << "Current availabe physical memory(KB): " << mAvailPhysicalMemInKB << llendl ;
-				llinfos << "Current availabe virtual memory(KB): " << mAvailVirtualMemInKB << llendl ;
-			}
+			LLMemory::logMemoryInfo(TRUE) ;
 
 			//stop memory leaking simulation
 			LLFloaterMemLeak* mem_leak_instance =
@@ -1494,16 +1572,16 @@ bool LLAppViewer::cleanup()
 	}
 
 	// *TODO - generalize this and move DSO wrangling to a helper class -brad
-	std::set<struct apr_dso_handle_t *>::const_iterator i;
-	for(i = mPlugins.begin(); i != mPlugins.end(); ++i)
+	for(std::map<apr_dso_handle_t*, boost::shared_ptr<LLAPRPool> >::iterator plugin = mPlugins.begin();
+		plugin != mPlugins.end(); ++plugin)
 	{
 		int (*ll_plugin_stop_func)(void) = NULL;
-		apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop");
+		apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, plugin->first, "ll_plugin_stop");
 		ll_plugin_stop_func();
 
-		rv = apr_dso_unload(*i);
+		rv = apr_dso_unload(plugin->first);
 	}
-	mPlugins.clear();
+	mPlugins.clear();	// Forget handles and destroy all memory pools.
 
 	//flag all elements as needing to be destroyed immediately
 	// to ensure shutdown order
@@ -1887,6 +1965,9 @@ bool LLAppViewer::cleanup()
 
 	LLMainLoopRepeater::instance().stop();
 
+	//release all private memory pools.
+	LLPrivateMemoryPoolManager::destroyClass() ;
+
 	ll_close_fail_log();
 
 	MEM_TRACK_RELEASE
@@ -1938,7 +2019,7 @@ bool LLAppViewer::initThreads()
 
 	if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
 	{
-		LLFastTimer::sLogLock = new LLMutex(NULL);
+		LLFastTimer::sLogLock = new LLMutex;
 		mFastTimerLogThread = new LLFastTimerLogThread(LLFastTimer::sLogName);
 		mFastTimerLogThread->start();
 	}
@@ -3186,8 +3267,7 @@ void LLAppViewer::handleViewerCrash()
 		else crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME);
 		llinfos << "Creating crash marker file " << crash_file_name << llendl;
 		
-		LLAPRFile crash_file ;
-		crash_file.open(crash_file_name, LL_APR_W);
+		LLAPRFile crash_file(crash_file_name, LL_APR_W);
 		if (crash_file.getFileHandle())
 		{
 			LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL;
@@ -3251,11 +3331,10 @@ bool LLAppViewer::anotherInstanceRunning()
 	LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
 
 	//Freeze case checks
-	if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB))
+	if (LLAPRFile::isExist(marker_file, LL_APR_RB))
 	{
 		// File exists, try opening with write permissions
-		LLAPRFile outfile ;
-		outfile.open(marker_file, LL_APR_WB);
+		LLAPRFile outfile(marker_file, LL_APR_WB);
 		apr_file_t* fMarker = outfile.getFileHandle() ; 
 		if (!fMarker)
 		{
@@ -3294,25 +3373,25 @@ void LLAppViewer::initMarkerFile()
 	std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
 	std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
 
-	if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())
+	if (LLAPRFile::isExist(mMarkerFileName, LL_APR_RB) && !anotherInstanceRunning())
 	{
 		gLastExecEvent = LAST_EXEC_FROZE;
 		LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL;
 	}    
-	if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))
+	if(LLAPRFile::isExist(logout_marker_file, LL_APR_RB))
 	{
 		gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
 		LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
 		LLAPRFile::remove(logout_marker_file);
 	}
-	if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
+	if(LLAPRFile::isExist(llerror_marker_file, LL_APR_RB))
 	{
 		if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
 		else gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
 		LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
 		LLAPRFile::remove(llerror_marker_file);
 	}
-	if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
+	if(LLAPRFile::isExist(error_marker_file, LL_APR_RB))
 	{
 		if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
 		else gLastExecEvent = LAST_EXEC_OTHER_CRASH;
@@ -3328,7 +3407,7 @@ void LLAppViewer::initMarkerFile()
 	
 	// Create the marker file for this execution & lock it
 	apr_status_t s;
-	s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);	
+	s = mMarkerFile.open(mMarkerFileName, LL_APR_W, LLAPRFile::long_lived);
 
 	if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
 	{
@@ -4109,18 +4188,6 @@ void LLAppViewer::idle()
 		}
 	}
 
-	// debug setting to quit after N seconds of being AFK - 0 to never do this
-	F32 qas_afk = gSavedSettings.getF32("QuitAfterSecondsOfAFK");
-	if (qas_afk > 0.f)
-	{
-		// idle time is more than setting
-		if ( gAwayTriggerTimer.getElapsedTimeF32() > qas_afk )
-		{
-			// go ahead and just quit gracefully
-			LLAppViewer::instance()->requestQuit();
-		}
-	}
-
 	// Must wait until both have avatar object and mute list, so poll
 	// here.
 	request_initial_instant_messages();
@@ -4586,8 +4653,7 @@ void LLAppViewer::sendLogoutRequest()
 		gLogoutInProgress = TRUE;
 		mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
 		
-		LLAPRFile outfile ;
-		outfile.open(mLogoutMarkerFileName, LL_APR_W);
+		LLAPRFile outfile(mLogoutMarkerFileName, LL_APR_W);
 		mLogoutMarkerFile =  outfile.getFileHandle() ;
 		if (mLogoutMarkerFile)
 		{
@@ -5039,14 +5105,15 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
 	}
 #endif // LL_WINDOWS
 
-	apr_dso_handle_t * eventhost_dso_handle = NULL;
-	apr_pool_t * eventhost_dso_memory_pool = NULL;
+	boost::shared_ptr<LLAPRPool> eventhost_dso_memory_pool_ptr(new LLAPRPool);
+	LLAPRPool& eventhost_dso_memory_pool(*eventhost_dso_memory_pool_ptr);
+	apr_dso_handle_t* eventhost_dso_handle = NULL;
 
 	//attempt to load the shared library
-	apr_pool_create(&eventhost_dso_memory_pool, NULL);
+	eventhost_dso_memory_pool.create();
 	apr_status_t rv = apr_dso_load(&eventhost_dso_handle,
 		dso_path.c_str(),
-		eventhost_dso_memory_pool);
+		eventhost_dso_memory_pool());
 	llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle));
 	llassert_always(eventhost_dso_handle != NULL);
 
@@ -5066,7 +5133,8 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
 		llerrs << "problem loading eventhost plugin, status: " << status << llendl;
 	}
 
-	mPlugins.insert(eventhost_dso_handle);
+	// Store the handle and link it to the pool that was used to allocate it.
+	mPlugins[eventhost_dso_handle] = eventhost_dso_memory_pool_ptr;
 }
 
 void LLAppViewer::launchUpdater()
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 32115e0e7b9418386f32e26e32c9453d6c2e6376..168aaf5d947ece222eac412d4a7706f647481e39 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -170,7 +170,7 @@ class LLAppViewer : public LLApp
 	
 	// mute/unmute the system's master audio
 	virtual void setMasterSystemAudioMute(bool mute);
-	virtual bool getMasterSystemAudioMute();
+	virtual bool getMasterSystemAudioMute();	
 
 	// Metrics policy helper statics.
 	static void metricsUpdateRegion(U64 region_handle);
@@ -193,11 +193,12 @@ class LLAppViewer : public LLApp
 
 private:
 
+	void initMaxHeapSize();
 	bool initThreads(); // Initialize viewer threads, return false on failure.
 	bool initConfiguration(); // Initialize settings from the command line/config file.
 	void initUpdater(); // Initialize the updater service.
 	bool initCache(); // Initialize local client cache.
-
+	void checkMemory() ;
 
 	// We have switched locations of both Mac and Windows cache, make sure
 	// files migrate and old cache is cleared out.
@@ -269,10 +270,9 @@ class LLAppViewer : public LLApp
 
     LLAllocator mAlloc;
 
-	std::set<struct apr_dso_handle_t*> mPlugins;
+	std::map<apr_dso_handle_t*, boost::shared_ptr<LLAPRPool> > mPlugins;
 
-	U32 mAvailPhysicalMemInKB ;
-	U32 mAvailVirtualMemInKB ;
+	LLFrameTimer mMemCheckTimer;
 	
 	boost::scoped_ptr<LLUpdaterService> mUpdater;
 
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 48d02dfeaade77a3b13729edbb1ab2925af61897..db11462fcbd292c4c1f82258938a48b53f2b2b77 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -111,6 +111,7 @@ int main( int argc, char **argv )
 	}
 	delete viewer_app_ptr;
 	viewer_app_ptr = NULL;
+
 	return 0;
 }
 
diff --git a/indra/newview/llappviewerlinux_api_dbus.cpp b/indra/newview/llappviewerlinux_api_dbus.cpp
index 32e7e0a83d5b10d350bcfceefa47d5478a5bd9c5..1ae469dfcfde79ffcf9ad423038e454ea387c60e 100644
--- a/indra/newview/llappviewerlinux_api_dbus.cpp
+++ b/indra/newview/llappviewerlinux_api_dbus.cpp
@@ -27,11 +27,11 @@
 #if LL_DBUS_ENABLED
 
 #include "linden_common.h"
+#include "llaprpool.h"
 
 extern "C" {
 #include <dbus/dbus-glib.h>
 
-#include "apr_pools.h"
 #include "apr_dso.h"
 }
 
@@ -44,7 +44,7 @@ extern "C" {
 #undef LL_DBUS_SYM
 
 static bool sSymsGrabbed = false;
-static apr_pool_t *sSymDBUSDSOMemoryPool = NULL;
+static LLAPRPool sSymDBUSDSOMemoryPool;
 static apr_dso_handle_t *sSymDBUSDSOHandleG = NULL;
 
 bool grab_dbus_syms(std::string dbus_dso_name)
@@ -63,11 +63,11 @@ bool grab_dbus_syms(std::string dbus_dso_name)
 #define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##DBUSSYM, sSymDBUSDSOHandle, #DBUSSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #DBUSSYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #DBUSSYM, (void*)ll##DBUSSYM);}while(0)
 
 	//attempt to load the shared library
-	apr_pool_create(&sSymDBUSDSOMemoryPool, NULL);
+	sSymDBUSDSOMemoryPool.create();
   
 	if ( APR_SUCCESS == (rv = apr_dso_load(&sSymDBUSDSOHandle,
 					       dbus_dso_name.c_str(),
-					       sSymDBUSDSOMemoryPool) ))
+					       sSymDBUSDSOMemoryPool()) ))
 	{
 		INFOMSG("Found DSO: %s", dbus_dso_name.c_str());
 
@@ -109,11 +109,7 @@ void ungrab_dbus_syms()
 		sSymDBUSDSOHandleG = NULL;
 	}
 	
-	if ( sSymDBUSDSOMemoryPool )
-	{
-		apr_pool_destroy(sSymDBUSDSOMemoryPool);
-		sSymDBUSDSOMemoryPool = NULL;
-	}
+	sSymDBUSDSOMemoryPool.destroy();
 	
 	// NULL-out all of the symbols we'd grabbed
 #define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{ll##DBUSSYM = NULL;}while(0)
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index c2916717bd415f80fa6243c4780ec117229f145e..8929c0c1a4ceb023c0c91a37cf27939e2f1aba2f 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -113,6 +113,7 @@ int main( int argc, char **argv )
 	}
 	delete viewer_app_ptr;
 	viewer_app_ptr = NULL;
+
 	return 0;
 }
 
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
old mode 100755
new mode 100644
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index d0f4d19f561df37d2d66d974904ccfe76be399b7..42e7decec188e4cbf76e94d4ef6771ebd11fc045 100644
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -141,7 +141,6 @@ LLAvatarIconCtrl::Params::Params()
 	draw_tooltip("draw_tooltip", true),
 	default_icon_name("default_icon_name")
 {
-	name = "avatar_icon";
 }
 
 
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 79e6c7b66bd8c3599a3b0b73ecfeddad958bf8d6..c8cfe5b51ecbf249ee12cd7524c925fd85075557 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -201,7 +201,8 @@ class LLBottomTrayLite
 };
 
 LLBottomTray::LLBottomTray(const LLSD&)
-:	mChicletPanel(NULL),
+:	mDesiredNearbyChatWidth(0),
+	mChicletPanel(NULL),
 	mSpeakPanel(NULL),
 	mSpeakBtn(NULL),
 	mNearbyChatBar(NULL),
@@ -1095,33 +1096,35 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
 	if (still_should_be_processed)
 	{
 		processShrinkButtons(delta_width, buttons_freed_width);
+		still_should_be_processed = delta_width < 0;
 	}
+
 	// 3. Decreasing width of nearby chat.
 	const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mChatBarContainer);
 	const S32 chatbar_panel_width = mChatBarContainer->getRect().getWidth();
 	if (still_should_be_processed && chatbar_panel_width > chatbar_panel_min_width)
 	{
 		// we have some space to decrease chatbar panel
-		S32 panel_delta_min = chatbar_panel_width - chatbar_panel_min_width;
+		S32 chatbar_shrink_headroom = chatbar_panel_width - chatbar_panel_min_width;
 
-		S32 delta_panel = llmin(-delta_width, panel_delta_min);
+		S32 shrink_by = llmin(-delta_width, chatbar_shrink_headroom);
 
 		// is chatbar panel wide enough to process resizing?
-		delta_width += panel_delta_min;
+		delta_width += chatbar_shrink_headroom;
 
 		still_should_be_processed = delta_width < 0;
 
 		// chatbar should only be shrunk here, not stretched
-		if(delta_panel > 0)
+		if (shrink_by > 0)
 		{
-			lldebugs << "Shrinking nearby chat bar by " << delta_panel << " px " << llendl;
-			mChatBarContainer->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mChatBarContainer->getRect().getHeight());
+			lldebugs << "Shrinking nearby chat bar by " << shrink_by << " px " << llendl;
+			mChatBarContainer->reshape(mNearbyChatBar->getRect().getWidth() - shrink_by, mChatBarContainer->getRect().getHeight());
 		}
 
 		log(mNearbyChatBar, "after processing panel decreasing via nearby chatbar panel");
 
 		lldebugs << "RS_CHATBAR_INPUT"
-			<< ", delta_panel: " << delta_panel
+			<< ", shrink_by: " << shrink_by
 			<< ", delta_width: " << delta_width
 			<< llendl;
 	}
@@ -1200,16 +1203,16 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
 		<< ", mDesiredNearbyChatWidth = " << mDesiredNearbyChatWidth << llendl;
 	if (delta_width > 0 && chatbar_panel_width < mDesiredNearbyChatWidth)
 	{
-		S32 delta_panel_max = mDesiredNearbyChatWidth - chatbar_panel_width;
-		S32 delta_panel = llmin(delta_width, delta_panel_max);
-		lldebugs << "Unprocesed delta width: " << delta_width
-			<< ", can be applied to chatbar: " << delta_panel_max
-			<< ", will be applied: " << delta_panel
+		S32 extend_by_max = mDesiredNearbyChatWidth - chatbar_panel_width;
+		S32 extend_by = llmin(delta_width, extend_by_max);
+		lldebugs << "Unprocessed delta width: " << delta_width
+			<< " px, chatbar can be extended by " << extend_by_max
+			<< " px, extending it by " << extend_by << " px"
 			<< llendl;
 
-		delta_width -= delta_panel_max;
-		lldebugs << "Extending nearby chat bar by " << delta_panel << " px " << llendl;
-		mChatBarContainer->reshape(chatbar_panel_width + delta_panel, mChatBarContainer->getRect().getHeight());
+		delta_width -= extend_by_max;
+		lldebugs << "Extending nearby chat bar by " << extend_by << " px " << llendl;
+		mChatBarContainer->reshape(chatbar_panel_width + extend_by, mChatBarContainer->getRect().getHeight());
 		log(mNearbyChatBar, "applied unprocessed delta width");
 	}
 
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 62718531ef0155f0e0f0da3a12a28828a8e0c8ad..e26b0792e93370eda7d2dbf3f0e284d442aacc4d 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -323,7 +323,7 @@ class LLBottomTray
 	void processExtendButtons(S32& available_width);
 
 	/**
-	 * Extends the Speak button if there is anough headroom.
+	 * Extends the Speak button if there is enough headroom.
 	 *
 	 * Unlike other buttons, the Speak buttons has only two possible widths:
 	 * the minimal one (without label) and the maximal (default) one.
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index db936b28d91f9b0ce572e82a8f0876e9b969b65b..1a0b98f6cf485f17e11999d4a8c912a7cc79c2d1 100644
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
@@ -43,7 +43,7 @@ namespace LLNotificationsUI
  */
 class LLChannelManager : public LLSingleton<LLChannelManager>
 {
-public:	
+public:
 	struct Params
 	{
 		LLUUID				id;
@@ -51,7 +51,8 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
 		EToastAlignment		toast_align;
 		EChannelAlignment	channel_align;
 
-		Params():	id(LLUUID("")), display_toasts_always(false), toast_align(NA_BOTTOM), channel_align(CA_LEFT)
+		Params()
+		:	id(LLUUID("")), display_toasts_always(false), toast_align(NA_BOTTOM), channel_align(CA_LEFT)
 		{}
 	};
 
diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp
index 024ccbcd0b0913f5c695fa53eac259d42bde3933..aa6c9c094c628b7358982cb340f1d026e9229f36 100644
--- a/indra/newview/llchatmsgbox.cpp
+++ b/indra/newview/llchatmsgbox.cpp
@@ -70,7 +70,7 @@ class ChatSeparator : public LLTextSegment
 LLChatMsgBox::Params::Params() :
 	block_spacing("block_spacing", 10)
 {
-	line_spacing.pixels = 4;
+	changeDefault(line_spacing.pixels, 4);
 }
 
 LLChatMsgBox::LLChatMsgBox(const Params& p) :
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 3000209aadd228895e5d237e1935bb8c1601e8ac..245157923ddfee6d3fc991bf937d778b49192d30 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -126,9 +126,9 @@ LLSysWellChiclet::Params::Params()
 , unread_notifications("unread_notifications")
 , max_displayed_count("max_displayed_count", 99)
 {
-	button.name("button");
-	button.tab_stop(FALSE);
-	button.label(LLStringUtil::null);
+	button.name = "button";
+	button.tab_stop = FALSE;
+	button.label = LLStringUtil::null;
 }
 
 LLSysWellChiclet::LLSysWellChiclet(const Params& p)
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index a6e12006a136e35b8eaa62d18c1066f9eb4e8134..1f1069dcb492a7d81dcfcf56b6fc875aca37229f 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -107,9 +107,9 @@ class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
 	{
 		Params()
 		{
-			draw_tooltip(FALSE);
-			mouse_opaque(FALSE);
-			default_icon_name("Generic_Person");
+			changeDefault(draw_tooltip, FALSE);
+			changeDefault(mouse_opaque, FALSE);
+			changeDefault(default_icon_name, "Generic_Person");
 		};
 	};
 
@@ -131,9 +131,8 @@ class LLChicletGroupIconCtrl : public LLIconCtrl
 		Optional<std::string> default_icon;
 
 		Params()
-		 : default_icon("default_icon", "Generic_Group")
-		{
-		};
+		:	default_icon("default_icon", "Generic_Group")
+		{}
 	};
 
 	/**
@@ -162,9 +161,9 @@ class LLChicletInvOfferIconCtrl : public LLChicletAvatarIconCtrl
 		Optional<std::string> default_icon;
 
 		Params()
-		 : default_icon("default_icon", "Generic_Object_Small")
+		:	default_icon("default_icon", "Generic_Object_Small")
 		{
-			avatar_id = LLUUID::null;
+			changeDefault(avatar_id, LLUUID::null);
 		};
 	};
 
@@ -314,9 +313,7 @@ class LLIMChiclet : public LLChiclet
 		TYPE_AD_HOC
 	};
 	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
-	{
-		Params(){}
-	};
+	{};
 
 	
 	virtual ~LLIMChiclet() {};
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index d77ebc5367ea3a33e770231d91ac4b8202204fab..5b942f283afc49c8619845e97a6bcc8c5e884771 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -57,7 +57,6 @@ LLColorSwatchCtrl::Params::Params()
 	caption_text("caption_text"),
 	border("border")
 {
-	name = "colorswatch";
 }
 
 LLColorSwatchCtrl::LLColorSwatchCtrl(const Params& p)
diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp
index 216cc66ef8637c624294fa7b9a85960d53e367d5..cc6ba05e7e197f5e2da6e723c48d243c64cd2f7e 100644
--- a/indra/newview/lldebugview.cpp
+++ b/indra/newview/lldebugview.cpp
@@ -41,6 +41,7 @@
 #include "llmemoryview.h"
 #include "llsceneview.h"
 #include "llviewertexture.h"
+#include "llfloaterreg.h"
 
 //
 // Globals
@@ -79,12 +80,7 @@ void LLDebugView::init()
 	r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), 
   									 (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f));
 	
-	mFastTimerView = new LLFastTimerView(r);
-	mFastTimerView->setFollowsTop();
-	mFastTimerView->setFollowsLeft();
-	mFastTimerView->setVisible(FALSE);			// start invisible
-	addChild(mFastTimerView);
-	mFastTimerView->setRect(rect);
+	mFastTimerView = dynamic_cast<LLFastTimerView*>(LLFloaterReg::getInstance("fast_timers"));
 
 	gSceneView = new LLSceneView(r);
 	gSceneView->setFollowsTop();
diff --git a/indra/newview/lldebugview.h b/indra/newview/lldebugview.h
index 5245f163c08ea04f064dceefe5bd7d0034688961..20262fc89e5a9042c839331893c057a5cdd2982d 100644
--- a/indra/newview/lldebugview.h
+++ b/indra/newview/lldebugview.h
@@ -48,7 +48,7 @@ class LLDebugView : public LLView
 	{
 		Params()
 		{
-			mouse_opaque = false;
+			changeDefault(mouse_opaque, false);
 		}
 	};
 	LLDebugView(const Params&);
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index f781d5f3ff96274388f40bc2a12bfcebc53ba944..fb9958ee9dd52affbea8ee0538be67a76037105e 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -40,6 +40,7 @@
 #include "llvertexbuffer.h"
 #include "llviewerdisplay.h"
 #include "llrender.h"
+#include "pipeline.h"
 
 // static
 LLViewerDynamicTexture::instance_list_t LLViewerDynamicTexture::sInstances[ LLViewerDynamicTexture::ORDER_COUNT ];
@@ -201,7 +202,7 @@ void LLViewerDynamicTexture::postRender(BOOL success)
 BOOL LLViewerDynamicTexture::updateAllInstances()
 {
 	sNumRenders = 0;
-	if (gGLManager.mIsDisabled)
+	if (gGLManager.mIsDisabled || LLPipeline::sMemAllocationThrottled)
 	{
 		return TRUE;
 	}
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 366154302cda4270eb5cbe529da3090079fece87..a161428c2b99b2366a0775b3447ecbf08f8bb182 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -80,12 +80,10 @@ static timer_tree_iterator_t end_timer_tree()
 	return timer_tree_iterator_t(); 
 }
 
-LLFastTimerView::LLFastTimerView(const LLRect& rect)
-:	LLFloater(LLSD()),
+LLFastTimerView::LLFastTimerView(const LLSD& key)
+:	LLFloater(key),
 	mHoverTimer(NULL)
 {
-	setRect(rect);
-	setVisible(FALSE);
 	mDisplayMode = 0;
 	mAvgCountTotal = 0;
 	mMaxCountTotal = 0;
@@ -98,10 +96,30 @@ LLFastTimerView::LLFastTimerView(const LLRect& rect)
 	FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount();
 	mPrintStats = -1;	
 	mAverageCyclesPerTimer = 0;
-	setCanMinimize(false);
-	setCanClose(true);
 }
 
+void LLFastTimerView::onPause()
+{
+	LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
+	// reset scroll to bottom when unpausing
+	if (!LLFastTimer::sPauseHistory)
+	{
+		mScrollIndex = 0;
+		getChild<LLButton>("pause_btn")->setLabel(getString("pause"));
+	}
+	else
+	{
+		getChild<LLButton>("pause_btn")->setLabel(getString("run"));
+	}
+}
+
+BOOL LLFastTimerView::postBuild()
+{
+	LLButton& pause_btn = getChildRef<LLButton>("pause_btn");
+	
+	pause_btn.setCommitCallback(boost::bind(&LLFastTimerView::onPause, this));
+	return TRUE;
+}
 
 BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
@@ -116,14 +134,16 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
 		{
 			mHoverTimer->getParent()->setCollapsed(true);
 		}
+		return TRUE;
 	}
 	else if (mBarRect.pointInRect(x, y))
 	{
 		S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
 		bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY);
 		mPrintStats = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - bar_idx;
+		return TRUE;
 	}
-	return FALSE;
+	return LLFloater::handleRightMouseDown(x, y, mask);
 }
 
 LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y)
@@ -151,18 +171,6 @@ BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask)
 
 BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
 {
-
-	{
-		S32 local_x = x - mButtons[BUTTON_CLOSE]->getRect().mLeft;
-		S32 local_y = y - mButtons[BUTTON_CLOSE]->getRect().mBottom;
-		if(mButtons[BUTTON_CLOSE]->getVisible()
-			&&  mButtons[BUTTON_CLOSE]->pointInView(local_x, local_y)  )
-		{
-			return LLFloater::handleMouseDown(x, y, mask);;
-		}
-	}
-	
-
 	if (x < mBarRect.mLeft) 
 	{
 		LLFastTimer::NamedTimer* idp = getLegendID(y);
@@ -196,36 +204,42 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
 	{
 		mDisplayCenter = (ChildAlignment)((mDisplayCenter + 1) % ALIGN_COUNT);
 	}
-	else
+	else if (mGraphRect.pointInRect(x, y))
 	{
-		// pause/unpause
-		LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
-		// reset scroll to bottom when unpausing
-		if (!LLFastTimer::sPauseHistory)
-		{
-			mScrollIndex = 0;
-		}
+		gFocusMgr.setMouseCapture(this);
+		return TRUE;
 	}
-	// SJB: Don't pass mouse clicks through the display
-	return TRUE;
+	//else
+	//{
+	//	// pause/unpause
+	//	LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
+	//	// reset scroll to bottom when unpausing
+	//	if (!LLFastTimer::sPauseHistory)
+	//	{
+	//		mScrollIndex = 0;
+	//	}
+	//}
+	return LLFloater::handleMouseDown(x, y, mask);
 }
 
 BOOL LLFastTimerView::handleMouseUp(S32 x, S32 y, MASK mask)
 {
+	if (hasMouseCapture())
 	{
-		S32 local_x = x - mButtons[BUTTON_CLOSE]->getRect().mLeft;
-		S32 local_y = y - mButtons[BUTTON_CLOSE]->getRect().mBottom;
-		if(mButtons[BUTTON_CLOSE]->getVisible()
-			&&  mButtons[BUTTON_CLOSE]->pointInView(local_x, local_y)  )
-		{
-			return LLFloater::handleMouseUp(x, y, mask);;
-		}
+		gFocusMgr.setMouseCapture(NULL);
 	}
-	return FALSE;
+	return LLFloater::handleMouseUp(x, y, mask);;
 }
 
 BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
 {
+	if (hasMouseCapture())
+	{
+		F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f);
+		mScrollIndex = llround( lerp * (F32)(LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
+		mScrollIndex = llclamp(	mScrollIndex, 0, LLFastTimer::getLastFrameIndex());
+		return TRUE;
+	}
 	mHoverTimer = NULL;
 	mHoverID = NULL;
 
@@ -282,7 +296,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
 		}
 	}
 	
-	return FALSE;
+	return LLFloater::handleHover(x, y, mask);
 }
 
 
@@ -318,15 +332,15 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
 			}
 		}
 	}
-	
-	return FALSE;
+
+	return LLFloater::handleToolTip(x, y, mask);
 }
 
 BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
 {
 	LLFastTimer::sPauseHistory = TRUE;
-	mScrollIndex = llclamp(mScrollIndex - clicks, 
-							0, 
+	mScrollIndex = llclamp(	mScrollIndex + clicks,
+							0,
 							llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
 	return TRUE;
 }
@@ -345,8 +359,8 @@ void LLFastTimerView::draw()
 	F64 iclock_freq = 1000.0 / clock_freq;
 	
 	S32 margin = 10;
-	S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.75f);
-	S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f);
+	S32 height = getRect().getHeight();
+	S32 width = getRect().getWidth();
 	
 	LLRect new_rect;
 	new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height);
@@ -630,7 +644,6 @@ void LLFastTimerView::draw()
 										 LLFontGL::LEFT, LLFontGL::TOP);
 		}
 
-		LLRect graph_rect;
 		// Draw borders
 		{
 			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -663,9 +676,9 @@ void LLFastTimerView::draw()
 			by = LINE_GRAPH_HEIGHT-barh-dy-7;
 			
 			//line graph
-			graph_rect = LLRect(xleft-5, by, getRect().getWidth()-5, 5);
+			mGraphRect = LLRect(xleft-5, by, getRect().getWidth()-5, 5);
 			
-			gl_rect_2d(graph_rect, FALSE);
+			gl_rect_2d(mGraphRect, FALSE);
 		}
 		
 		mBarStart.clear();
@@ -813,7 +826,7 @@ void LLFastTimerView::draw()
 		//draw line graph history
 		{
 			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-			LLLocalClipRect clip(graph_rect);
+			LLLocalClipRect clip(mGraphRect);
 			
 			//normalize based on last frame's maximum
 			static U64 last_max = 0;
@@ -830,8 +843,8 @@ void LLFastTimerView::draw()
 			else
 				tdesc = llformat("%4.2f ms", ms);
 							
-			x = graph_rect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5;
-			y = graph_rect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight());
+			x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5;
+			y = mGraphRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight());
  
 			LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
 										 LLFontGL::LEFT, LLFontGL::TOP);
@@ -841,24 +854,24 @@ void LLFastTimerView::draw()
 				S32 first_frame = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex;
 				S32 last_frame = first_frame - MAX_VISIBLE_HISTORY;
 				
-				F32 frame_delta = ((F32) (graph_rect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1);
+				F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1);
 				
-				F32 right = (F32) graph_rect.mLeft + frame_delta*first_frame;
-				F32 left = (F32) graph_rect.mLeft + frame_delta*last_frame;
+				F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame;
+				F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame;
 				
 				gGL.color4f(0.5f,0.5f,0.5f,0.3f);
-				gl_rect_2d((S32) left, graph_rect.mTop, (S32) right, graph_rect.mBottom);
+				gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom);
 				
 				if (mHoverBarIndex >= 0)
 				{
 					S32 bar_frame = first_frame - mHoverBarIndex;
-					F32 bar = (F32) graph_rect.mLeft + frame_delta*bar_frame;
+					F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame;
 
 					gGL.color4f(0.5f,0.5f,0.5f,1);
 				
 					gGL.begin(LLRender::LINES);
-					gGL.vertex2i((S32)bar, graph_rect.mBottom);
-					gGL.vertex2i((S32)bar, graph_rect.mTop);
+					gGL.vertex2i((S32)bar, mGraphRect.mBottom);
+					gGL.vertex2i((S32)bar, mGraphRect.mTop);
 					gGL.end();
 				}
 			}
@@ -883,7 +896,7 @@ void LLFastTimerView::draw()
 				
 				if (mHoverID != NULL &&
 					idp != mHoverID)
-				{	//fade out non-hihglighted timers
+				{	//fade out non-highlighted timers
 					if (idp->getParent() != mHoverID)
 					{
 						alpha = alpha_interp;
@@ -891,8 +904,10 @@ void LLFastTimerView::draw()
 				}
 
 				gGL.color4f(col[0], col[1], col[2], alpha);				
-				gGL.begin(LLRender::LINE_STRIP);
-				for (U32 j = 0; j < LLFastTimer::NamedTimer::HISTORY_NUM; j++)
+				gGL.begin(LLRender::TRIANGLE_STRIP);
+				for (U32 j = llmax(0, LLFastTimer::NamedTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex());
+					j < LLFastTimer::NamedTimer::HISTORY_NUM;
+					j++)
 				{
 					U64 ticks = idp->getHistoricalCount(j);
 
@@ -912,9 +927,10 @@ void LLFastTimerView::draw()
 						//normalize to highlighted timer
 						cur_max = llmax(cur_max, ticks);
 					}
-					F32 x = graph_rect.mLeft + ((F32) (graph_rect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j;
-					F32 y = graph_rect.mBottom + (F32) graph_rect.getHeight()/max_ticks*ticks;
+					F32 x = mGraphRect.mLeft + ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j;
+					F32 y = mGraphRect.mBottom + (F32) mGraphRect.getHeight()/max_ticks*ticks;
 					gGL.vertex2f(x,y);
+					gGL.vertex2f(x,mGraphRect.mBottom);
 				}
 				gGL.end();
 				
@@ -932,18 +948,20 @@ void LLFastTimerView::draw()
 			}
 			
 			//interpolate towards new maximum
-			F32 dt = gFrameIntervalSeconds*3.f;
-			last_max = (U64) ((F32) last_max + ((F32) cur_max- (F32) last_max) * dt);
+			last_max = (U64) lerp((F32)last_max, (F32) cur_max, LLCriticalDamp::getInterpolant(0.1f));
+			if (last_max - cur_max <= 1 ||  cur_max - last_max  <= 1)
+			{
+				last_max = cur_max;
+			}
 			F32 alpha_target = last_max > cur_max ?
 								llmin((F32) last_max/ (F32) cur_max - 1.f,1.f) :
 								llmin((F32) cur_max/ (F32) last_max - 1.f,1.f);
-			
-			alpha_interp = alpha_interp + (alpha_target-alpha_interp) * dt;
+			alpha_interp = lerp(alpha_interp, alpha_target, LLCriticalDamp::getInterpolant(0.1f));
 
 			if (mHoverID != NULL)
 			{
-				x = (graph_rect.mRight + graph_rect.mLeft)/2;
-				y = graph_rect.mBottom + 8;
+				x = (mGraphRect.mRight + mGraphRect.mLeft)/2;
+				y = mGraphRect.mBottom + 8;
 
 				LLFontGL::getFontMonospace()->renderUTF8(
 					mHoverID->getName(), 
diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h
index ea8251191b29e6a4fd50ca3d16d505aa1364a8e9..a349e7ad4c9324c3e3e8a7f3e5273c872f263c83 100644
--- a/indra/newview/llfasttimerview.h
+++ b/indra/newview/llfasttimerview.h
@@ -33,8 +33,9 @@
 class LLFastTimerView : public LLFloater
 {
 public:
-	LLFastTimerView(const LLRect& rect);
-	
+	LLFastTimerView(const LLSD&);
+	BOOL postBuild();
+
 	static BOOL sAnalyzePerformance;
 
 	static void outputAllMetrics();
@@ -44,6 +45,7 @@ class LLFastTimerView : public LLFloater
 	static void doAnalysisDefault(std::string baseline, std::string target, std::string output) ;
 	static LLSD analyzePerformanceLogDefault(std::istream& is) ;
 	static void exportCharts(const std::string& base, const std::string& target);
+	void onPause();
 
 public:
 
@@ -89,6 +91,7 @@ class LLFastTimerView : public LLFloater
 	LLFrameTimer mHighlightTimer;
 	S32 mPrintStats;
 	S32 mAverageCyclesPerTimer;
+	LLRect mGraphRect;
 };
 
 #endif
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 1f334815d6a1e42c56232e051d6f6169cf4758a2..9f0218a95e34b463af7712ba2495ac57e1b92d8f 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -223,8 +223,7 @@ BOOL LLFloaterAnimPreview::postBuild()
 		// now load bvh file
 		S32 file_size;
 		
-		LLAPRFile infile ;
-		infile.open(mFilenameAndPath, LL_APR_RB, NULL, &file_size);
+		LLAPRFile infile(mFilenameAndPath, LL_APR_RB, &file_size);
 		
 		if (!infile.getFileHandle())
 		{
diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp
index 58931d112e954ddbb86255c25b8ee09f2890c442..9edfe1e3546d8b31ec3c559fe07286b572a972a4 100644
--- a/indra/newview/llfloatermemleak.cpp
+++ b/indra/newview/llfloatermemleak.cpp
@@ -90,6 +90,11 @@ LLFloaterMemLeak::~LLFloaterMemLeak()
 
 void LLFloaterMemLeak::release()
 {
+	if(mLeakedMem.empty())
+	{
+		return ;
+	}
+
 	for(S32 i = 0 ; i < (S32)mLeakedMem.size() ; i++)
 	{
 		delete[] mLeakedMem[i] ;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
old mode 100755
new mode 100644
index ef846ec42e0a46c2467bd49a8283daedd91cb591..2510f43aa71799855e394b3d405082489bf53e6b
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -367,7 +367,7 @@ mCalculateBtn(NULL)
 	mLastMouseX = 0;
 	mLastMouseY = 0;
 	mGLName = 0;
-	mStatusLock = new LLMutex(NULL);
+	mStatusLock = new LLMutex();
 	mModelPreview = NULL;
 
 	mLODMode[LLModel::LOD_HIGH] = 0;
@@ -2878,7 +2878,7 @@ LLColor4 LLModelLoader::getDaeColor(daeElement* element)
 //-----------------------------------------------------------------------------
 
 LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
-: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex(NULL)
+: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex()
 , mPelvisZOffset( 0.0f )
 , mLegacyRigValid( false )
 , mRigValidJointUpload( false )
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index ec162e00ebf731e4af0f032635aae77149ba8495..8b72d838300b80db62295f3e27572c2fdd123285 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -181,6 +181,7 @@ LLFolderView::Params::Params()
 // Default constructor
 LLFolderView::LLFolderView(const Params& p)
 :	LLFolderViewFolder(p),
+	mRunningHeight(0),
 	mScrollContainer( NULL ),
 	mPopupMenuHandle(),
 	mAllowMultiSelect(p.allow_multiselect),
@@ -479,6 +480,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
 		target_height = running_height;
 	}
 
+	mRunningHeight = running_height;
 	LLRect scroll_rect = mScrollContainer->getContentWindowRect();
 	reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
 
@@ -524,10 +526,11 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
 	LLRect scroll_rect;
 	if (mScrollContainer)
 	{
+		LLView::reshape(width, height, called_from_parent);
 		scroll_rect = mScrollContainer->getContentWindowRect();
 	}
 	width = llmax(mMinWidth, scroll_rect.getWidth());
-	height = llmax(height, scroll_rect.getHeight());
+	height = llmax(mRunningHeight, scroll_rect.getHeight());
 
 	// restrict width with scroll container's width
 	if (mUseEllipses)
@@ -1007,6 +1010,33 @@ void LLFolderView::removeSelectedItems( void )
 	LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLFolderView::onItemsRemovalConfirmation, this, _1, _2));
 }
 
+bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFolderViewItem*>& selectedItems)
+{
+	LLFolderViewItem* item_parent = dynamic_cast<LLFolderViewItem*>(item->getParent());
+
+	if (item_parent)
+	{
+		for(std::vector<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
+		{
+			const LLFolderViewItem* const selected_item = (*it);
+
+			LLFolderViewItem* parent = item_parent;
+
+			while (parent)
+			{
+				if (selected_item == parent)
+				{
+					return true;
+				}
+
+				parent = dynamic_cast<LLFolderViewItem*>(parent->getParent());
+			}
+		}
+	}
+
+	return false;
+}
+
 void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -1081,7 +1111,7 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 			if (!new_selection)
 			{
 				new_selection = last_item->getPreviousOpenNode(FALSE);
-				while (new_selection && new_selection->isSelected())
+				while (new_selection && (new_selection->isSelected() || isDescendantOfASelectedItem(new_selection, items)))
 				{
 					new_selection = new_selection->getPreviousOpenNode(FALSE);
 				}
@@ -1915,9 +1945,9 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	if (!handled)
 	{
 		if (getListener()->getUUID().notNull())
-		{
-			LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-		}
+	{
+		handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+	}
 		else
 		{
 			if (!mFolders.empty())
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 705a76a7b4e361e162fb2dd173c808157a0159af..8af01e9102b8667e386527a1e59ef207b9a59e7d 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -314,6 +314,7 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	signal_t						mReshapeSignal;
 	S32								mSignalSelectCallback;
 	S32								mMinWidth;
+	S32								mRunningHeight;
 	std::map<LLUUID, LLFolderViewItem*> mItemMap;
 	BOOL							mDragAndDropThisFrame;
 	
diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h
index 3bfbf3611033942a69331389ca6673b9c431042e..aee31ca0339e2caa1f39ed1b4dc57bf10e44da23 100644
--- a/indra/newview/llfoldervieweventlistener.h
+++ b/indra/newview/llfoldervieweventlistener.h
@@ -96,7 +96,8 @@ class LLFolderViewEventListener
 	// otherwise FALSE.
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
-							void* cargo_data) = 0;
+							void* cargo_data,
+							std::string& tooltip_msg) = 0;
 };
 
 #endif
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index e2b7c45eabb5f0979ab7353af047ab860d633fdc..622dcfe8ddbeab9cd6bba470b6cf9758844dddf0 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -101,10 +101,7 @@ LLFolderViewItem::Params::Params()
 	item_height("item_height"),
 	item_top_pad("item_top_pad"),
 	creation_date()
-{
-	mouse_opaque(true);
-	follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_RIGHT);
-}
+{}
 
 // Default constructor
 LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
@@ -132,7 +129,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mIconOpen(p.icon_open),
 	mIconOverlay(p.icon_overlay),
 	mListener(p.listener),
-	mShowLoadStatus(false)
+	mShowLoadStatus(false),
+	mIsMouseOverTitle(false)
 {
 }
 
@@ -284,9 +282,9 @@ void LLFolderViewItem::refreshFromListener()
 		setToolTip(mLabel);
 		setIcon(mListener->getIcon());
 		time_t creation_date = mListener->getCreationDate();
-		if (mCreationDate != creation_date)
+		if ((creation_date > 0) && (mCreationDate != creation_date))
 		{
-			setCreationDate(mListener->getCreationDate());
+			setCreationDate(creation_date);
 			dirtyFilter();
 		}
 		if (mRoot->useLabelSuffix())
@@ -724,6 +722,8 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
 
 BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 {
+	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
+
 	if( hasMouseCapture() && isMovable() )
 	{
 		S32 screen_x;
@@ -830,6 +830,11 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
 	return TRUE;
 }
 
+void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	mIsMouseOverTitle = false;
+}
+
 BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 										 EDragAndDropType cargo_type,
 										 void* cargo_data,
@@ -840,7 +845,7 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	BOOL handled = FALSE;
 	if(mListener)
 	{
-		accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data);
+		accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
 		handled = accepted;
 		if (accepted)
 		{
@@ -879,6 +884,7 @@ void LLFolderViewItem::draw()
 	static LLUIColor sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
 	static LLUIColor sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
 	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
+	static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
 
 	const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
 	const S32 TOP_PAD = default_params.item_top_pad;
@@ -960,6 +966,14 @@ void LLFolderViewItem::draw()
 			}
 		}
 	}
+	else if (mIsMouseOverTitle)
+	{
+		gl_rect_2d(FOCUS_LEFT,
+			focus_top, 
+			getRect().getWidth() - 2,
+			focus_bottom,
+			sMouseOverColor, FALSE);
+	}
 
 	//--------------------------------------------------------------------------------//
 	// Draw DragNDrop highlight
@@ -2040,23 +2054,42 @@ BOOL LLFolderViewFolder::isRemovable()
 BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 {
 	mItems.push_back(item);
+	
 	if (item->isSelected())
 	{
 		recursiveIncrementNumDescendantsSelected(1);
 	}
+	
 	item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
 	item->setVisible(FALSE);
-	addChild( item );
+	
+	addChild(item);
+	
 	item->dirtyFilter();
+
+	// Update the folder creation date if the child is newer than our current date
+	setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate()));
+
+	// Handle sorting
 	requestArrange();
 	requestSort();
+
+	// Traverse parent folders and update creation date and resort, if necessary
 	LLFolderViewFolder* parentp = getParentFolder();
-	while (parentp && parentp->mSortFunction.isByDate())
+	while (parentp)
 	{
-		// parent folder doesn't have a time stamp yet, so get it from us
-		parentp->requestSort();
+		// Update the folder creation date if the child is newer than our current date
+		parentp->setCreationDate(llmax<time_t>(parentp->mCreationDate, item->getCreationDate()));
+
+		if (parentp->mSortFunction.isByDate())
+		{
+			// parent folder doesn't have a time stamp yet, so get it from us
+			parentp->requestSort();
+		}
+
 		parentp = parentp->getParentFolder();
 	}
+
 	return TRUE;
 }
 
@@ -2162,7 +2195,7 @@ BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
 													EAcceptance* accept,
 													std::string& tooltip_msg)
 {
-	BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data);
+	BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
 	if (accepted) 
 	{
 		mDragAndDropTarget = TRUE;
@@ -2254,7 +2287,7 @@ BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
 
 	if (!handled)
 	{
-		BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data);
+		BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data, tooltip_msg);
 
 		if (accepted) 
 		{
@@ -2299,6 +2332,8 @@ BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
 
 BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
 {
+	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
+
 	BOOL handled = LLView::handleHover(x, y, mask);
 
 	if (!handled)
@@ -2418,41 +2453,6 @@ void LLFolderViewFolder::draw()
 
 time_t LLFolderViewFolder::getCreationDate() const
 {
-	// folders have no creation date try to create one from an item somewhere in our folder hierarchy
-	if (!mCreationDate)
-	{
-		for (items_t::const_iterator iit = mItems.begin();
-			 iit != mItems.end(); ++iit)
-		{
-			LLFolderViewItem* itemp = (*iit);
-
-			const time_t item_creation_date = itemp->getCreationDate();
-			
-			if (item_creation_date)
-			{
-				setCreationDate(item_creation_date);
-				break;
-			}
-		}
-		
-		if (!mCreationDate)
-		{
-			for (folders_t::const_iterator fit = mFolders.begin();
-				 fit != mFolders.end(); ++fit)
-			{
-				LLFolderViewFolder* folderp = (*fit);
-				
-				const time_t folder_creation_date = folderp->getCreationDate();
-				
-				if (folder_creation_date)
-				{
-					setCreationDate(folder_creation_date);
-					break;
-				}
-			}
-		}
-	}
-
 	return llmax<time_t>(mCreationDate, mSubtreeCreationDate);
 }
 
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index dac0c3032c4c31a20e01be3e6b28b8abf72043a3..676eaf825dcb3260f45537bc8d5202fe407469c7 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -136,7 +136,7 @@ class LLFolderViewItem : public LLView
 	std::string					mSearchableLabel;
 	S32							mLabelWidth;
 	bool						mLabelWidthDirty;
-	mutable time_t				mCreationDate;
+	time_t						mCreationDate;
 	LLFolderViewFolder*			mParentFolder;
 	LLFolderViewEventListener*	mListener;
 	BOOL						mIsCurSelection;
@@ -159,6 +159,7 @@ class LLFolderViewItem : public LLView
 	BOOL                        mIsLoading;
 	LLTimer                     mTimeSinceRequestStart;
 	bool						mShowLoadStatus;
+	bool						mIsMouseOverTitle;
 
 	// helper function to change the selection from the root.
 	void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
@@ -173,7 +174,7 @@ class LLFolderViewItem : public LLView
 
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
-	virtual void setCreationDate(time_t creation_date_utc) const { mCreationDate = creation_date_utc; }
+	virtual void setCreationDate(time_t creation_date_utc)	{ mCreationDate = creation_date_utc; }
 
 public:
 	BOOL postBuild();
@@ -328,6 +329,8 @@ class LLFolderViewItem : public LLView
 	virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
 	virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
 
+	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
+
 	virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return NULL; }
 
 	//	virtual void handleDropped();
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index f0fc710f3d09ce22a720eed8e0669171abc4259d..a36aa3dedf9ba5186d9961082d100cc773ad82ff 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -70,6 +70,9 @@
 #include "llvoavatarself.h"
 #include "llwearablelist.h"
 
+// Marketplace outbox current disabled
+#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU	0	// keep in sync with ENABLE_INVENTORY_DISPLAY_OUTBOX, ENABLE_MERCHANT_OUTBOX_PANEL
+
 typedef std::pair<LLUUID, LLUUID> two_uuids_t;
 typedef std::list<two_uuids_t> two_uuids_list_t;
 
@@ -107,6 +110,23 @@ bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);
 void teleport_via_landmark(const LLUUID& asset_id);
 static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
 
+// Helper functions
+
+bool isAddAction(const std::string& action)
+{
+	return ("wear" == action || "attach" == action || "activate" == action);
+}
+
+bool isRemoveAction(const std::string& action)
+{
+	return ("take_off" == action || "detach" == action || "deactivate" == action);
+}
+
+bool isMarketplaceCopyAction(const std::string& action)
+{
+	return (("copy_to_outbox" == action) || ("move_to_outbox" == action));
+}
+
 // +=================================================+
 // |        LLInvFVBridge                            |
 // +=================================================+
@@ -538,10 +558,14 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
 			{
 				items.push_back(std::string("Find Links"));
 			}
-			items.push_back(std::string("Rename"));
-			if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
+
+			if (!isInboxFolder())
 			{
-				disabled_items.push_back(std::string("Rename"));
+				items.push_back(std::string("Rename"));
+				if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
+				{
+					disabled_items.push_back(std::string("Rename"));
+				}
 			}
 			
 			if (show_asset_id)
@@ -569,11 +593,31 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
 			{
 				disabled_items.push_back(std::string("Copy"));
 			}
+
+			if (canListOnMarketplace())
+			{
+				items.push_back(std::string("Marketplace Separator"));
+
+				bool copyable = true;
+				LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID);
+				if (inv_item)
+				{
+					copyable = inv_item->getPermissions().allowCopyBy(gAgent.getID());
+				}
+
+				const std::string merchant_action = ((copyable == true) ? "Merchant Copy" : "Merchant Move");
+				items.push_back(merchant_action);
+
+				if (!canListOnMarketplaceNow())
+				{
+					disabled_items.push_back(merchant_action);
+				}
+			}
 		}
 	}
 
 	// Don't allow items to be pasted directly into the COF or the inbox
-	if (!isCOFFolder() && !isInboxFolder())
+	if (!isCOFFolder() && !isInboxFolder() && !isOutboxFolder())
 	{
 		items.push_back(std::string("Paste"));
 	}
@@ -610,6 +654,10 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	if(isItemInTrash())
 	{
 		addTrashContextMenuOptions(items, disabled_items);
+	}	
+	else if(isOutboxFolder())
+	{
+		items.push_back(std::string("Delete"));
 	}
 	else
 	{
@@ -794,6 +842,25 @@ BOOL LLInvFVBridge::isInboxFolder() const
 	return gInventory.isObjectDescendentOf(mUUID, inbox_id);
 }
 
+BOOL LLInvFVBridge::isOutboxFolder() const
+{
+	const LLUUID outbox_id = getOutboxFolder();
+
+	if (outbox_id.isNull())
+	{
+		return FALSE;
+	}
+
+	return gInventory.isObjectDescendentOf(mUUID, outbox_id);
+}
+
+const LLUUID LLInvFVBridge::getOutboxFolder() const
+{
+	const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+
+	return outbox_id;
+}
+
 BOOL LLInvFVBridge::isItemPermissive() const
 {
 	return FALSE;
@@ -938,9 +1005,14 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
 			new_listener = new LLMeshBridge(inventory, root, uuid);
 			break;
 
+		case LLAssetType::AT_IMAGE_TGA:
+		case LLAssetType::AT_IMAGE_JPEG:
+			//llwarns << LLAssetType::lookup(asset_type) << " asset type is unhandled for uuid " << uuid << llendl;
+			break;
+
 		default:
 			llinfos << "Unhandled asset type (llassetstorage.h): "
-					<< (S32)asset_type << llendl;
+					<< (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << llendl;
 			break;
 	}
 
@@ -989,6 +1061,65 @@ BOOL LLInvFVBridge::canShare() const
 	return FALSE;
 }
 
+BOOL LLInvFVBridge::canListOnMarketplace() const
+{
+#if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
+	LLInventoryModel * model = getInventoryModel();
+	const LLViewerInventoryCategory * cat = model->getCategory(mUUID);
+	if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
+	{
+		return FALSE;
+	}
+
+	if (!isAgentInventory())
+	{
+		return FALSE;
+	}
+	
+	if (getOutboxFolder().isNull())
+	{
+		return FALSE;
+	}
+
+	if (isInboxFolder() || isOutboxFolder())
+	{
+		return FALSE;
+	}
+
+	LLViewerInventoryItem * item = model->getItem(mUUID);
+	if (item && !item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+#else
+	return FALSE;
+#endif
+}
+
+BOOL LLInvFVBridge::canListOnMarketplaceNow() const
+{
+#if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
+	if (get_is_item_worn(mUUID))
+	{
+		return FALSE;
+	}
+
+	// Loop through all items worn by avatar and check to see if they are descendants
+	// of the item we are trying to list on the marketplace
+	if (get_is_parent_to_worn_item(mUUID))
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+#else
+	return FALSE;
+#endif
+}
+
+
 // +=================================================+
 // |        InventoryFVBridgeBuilder                 |
 // +=================================================+
@@ -1086,6 +1217,16 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 		folder_view_itemp->getListener()->pasteLinkFromClipboard();
 		return;
 	}
+	else if (isMarketplaceCopyAction(action))
+	{
+		llinfos << "Copy item to marketplace action!" << llendl;
+
+		LLInventoryItem* itemp = model->getItem(mUUID);
+		if (!itemp) return;
+
+		const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+		copy_item_to_outbox(itemp, outbox_id, LLUUID::null);
+	}
 }
 
 void LLItemBridge::selectItem()
@@ -1226,7 +1367,7 @@ std::string LLItemBridge::getLabelSuffix() const
 {
 	// String table is loaded before login screen and inventory items are
 	// loaded after login, so LLTrans should be ready.
-	static std::string NO_COPY =LLTrans::getString("no_copy");
+	static std::string NO_COPY = LLTrans::getString("no_copy");
 	static std::string NO_MOD = LLTrans::getString("no_modify");
 	static std::string NO_XFER = LLTrans::getString("no_transfer");
 	static std::string LINK = LLTrans::getString("link");
@@ -1294,6 +1435,11 @@ BOOL LLItemBridge::isItemRenameable() const
 			return FALSE;
 		}
 
+		if (isInboxFolder())
+		{
+			return FALSE;
+		}
+
 		return (item->getPermissions().allowModifyBy(gAgent.getID()));
 	}
 	return FALSE;
@@ -1457,16 +1603,6 @@ BOOL LLItemBridge::isItemPermissive() const
 	return FALSE;
 }
 
-bool LLItemBridge::isAddAction(std::string action) const
-{
-	return ("wear" == action || "attach" == action || "activate" == action);
-}
-
-bool LLItemBridge::isRemoveAction(std::string action) const
-{
-	return ("take_off" == action || "detach" == action || "deactivate" == action);
-}
-
 // +=================================================+
 // |        LLFolderBridge                           |
 // +=================================================+
@@ -1648,8 +1784,77 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const
 
 }
 
+static BOOL can_move_to_outbox(LLInventoryItem* inv_item, std::string& tooltip_msg)
+{
+	bool worn = get_is_item_worn(inv_item->getUUID());
+	bool allow_transfer = inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
+
+	if (!allow_transfer)
+	{
+		tooltip_msg = LLTrans::getString("TooltipOutboxNoTransfer");
+	}
+	else if(worn)
+	{
+		tooltip_msg = LLTrans::getString("TooltipOutboxWorn");
+	}
+	
+	return !worn && allow_transfer;
+}
+
+
+
+void LLFolderBridge::dropFolderToOutbox(LLInventoryCategory* inv_cat)
+{
+	copy_folder_to_outbox(inv_cat, getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false), inv_cat->getUUID());	
+}
+
+
+
+int get_folder_levels(LLInventoryCategory* inv_cat)
+{
+	LLInventoryModel::cat_array_t* cats;
+	LLInventoryModel::item_array_t* items;
+	gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cats, items);
+
+	int max_child_levels = 0;
+
+	for (S32 i=0; i < cats->count(); ++i)
+	{
+		LLInventoryCategory* category = cats->get(i);
+		max_child_levels = llmax(max_child_levels, get_folder_levels(category));
+	}
+
+	return 1 + max_child_levels;
+}
+
+int get_folder_path_length(const LLUUID& ancestor_id, const LLUUID& descendant_id)
+{
+	int depth = 0;
+
+	if (ancestor_id == descendant_id) return depth;
+
+	const LLInventoryCategory* category = gInventory.getCategory(descendant_id);
+
+	while(category)
+	{
+		LLUUID parent_id = category->getParentUUID();
+
+		if (parent_id.isNull()) break;
+
+		depth++;
+
+		if (parent_id == ancestor_id) return depth;
+
+		category = gInventory.getCategory(parent_id);
+	}
+
+	llwarns << "get_folder_path_length() couldn't trace a path from the descendant to the ancestor" << llendl;
+	return -1;
+}
+
 BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
-											BOOL drop)
+											BOOL drop,
+											std::string& tooltip_msg)
 {
 
 	LLInventoryModel* model = getInventoryModel();
@@ -1674,10 +1879,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 		const LLUUID &cat_id = inv_cat->getUUID();
 		const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false);
 		const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
-		
+		const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
+
 		const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
 		const BOOL move_is_into_outfit = getCategory() && (getCategory()->getPreferredType() == LLFolderType::FT_OUTFIT);
 		const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id);
+		const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); 
+		const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_cat->getUUID(), outbox_id);
 
 		//--------------------------------------------------------------------------------
 		// Determine if folder can be moved.
@@ -1730,6 +1938,27 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 				}
 			}
 		}
+		if (move_is_into_outbox)
+		{
+			for (S32 i=0; i < descendent_items.count(); ++i)
+			{
+				LLInventoryItem* item = descendent_items[i];
+				if (!can_move_to_outbox(item, tooltip_msg))
+				{
+					is_movable = FALSE;
+					break; 
+				}
+			}
+
+			int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat);
+
+			if (nested_folder_levels > 4)
+			{
+				tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels");
+				is_movable = FALSE;
+			}
+			
+		}
 
 		// 
 		//--------------------------------------------------------------------------------
@@ -1797,6 +2026,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 #endif
 				}
 			}
+			if (move_is_into_outbox && !move_is_from_outbox)
+			{
+				dropFolderToOutbox(inv_cat);
+			}
 			else
 			{
 				if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
@@ -2209,6 +2442,16 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 		removeSystemFolder();
 	}
 #endif
+	else if (isMarketplaceCopyAction(action))
+	{
+		llinfos << "Copy folder to marketplace action!" << llendl;
+
+		LLInventoryCategory * cat = gInventory.getCategory(mUUID);
+		if (!cat) return;
+
+		const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+		copy_folder_to_outbox(cat, outbox_id, cat->getUUID());
+	}
 }
 
 void LLFolderBridge::openItem()
@@ -2493,6 +2736,7 @@ void LLFolderBridge::folderOptionsMenu()
 	if (trash_id == mUUID) return;
 	if (isItemInTrash()) return;
 	if (!isAgentInventory()) return;
+	if (isOutboxFolder()) return;
 
 	LLFolderType::EType type = category->getPreferredType();
 	const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
@@ -2628,6 +2872,10 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 		mItems.clear(); // clear any items that used to exist
 		addTrashContextMenuOptions(mItems, mDisabledItems);
 	}
+	else if(isOutboxFolder())
+	{
+		mItems.push_back(std::string("Delete"));
+	}
 	else if(isAgentInventory()) // do not allow creating in library
 	{
 		LLViewerInventoryCategory *cat =  getCategory();
@@ -2635,7 +2883,7 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 		// Not sure what the right thing is to do here.
 		if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT))
 		{
-			if (!isInboxFolder()) // don't allow creation in inbox
+			if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox
 			{
 				// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
 				if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
@@ -2702,10 +2950,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 		mDisabledItems.push_back(std::string("Delete System Folder"));
 	}
 
-	mItems.push_back(std::string("Share"));
-	if (!canShare())
+	if (!isOutboxFolder())
 	{
-		mDisabledItems.push_back(std::string("Share"));
+		mItems.push_back(std::string("Share"));
+		if (!canShare())
+		{
+			mDisabledItems.push_back(std::string("Share"));
+		}
 	}
 
 	hide_context_entries(menu, mItems, mDisabledItems);
@@ -2746,7 +2997,8 @@ BOOL LLFolderBridge::hasChildren() const
 
 BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 								EDragAndDropType cargo_type,
-								void* cargo_data)
+								void* cargo_data,
+								std::string& tooltip_msg)
 {
 	LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
 
@@ -2766,7 +3018,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 		case DAD_ANIMATION:
 		case DAD_GESTURE:
 		case DAD_MESH:
-			accept = dragItemIntoFolder(inv_item, drop);
+			accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);
 			break;
 		case DAD_LINK:
 			// DAD_LINK type might mean one of two asset types: AT_LINK or AT_LINK_FOLDER.
@@ -2777,12 +3029,12 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 				LLInventoryCategory* linked_category = gInventory.getCategory(inv_item->getLinkedUUID());
 				if (linked_category)
 				{
-					accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop);
+					accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop, tooltip_msg);
 				}
 			}
 			else
 			{
-				accept = dragItemIntoFolder(inv_item, drop);
+				accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);
 			}
 			break;
 		case DAD_CATEGORY:
@@ -2792,7 +3044,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 			}
 			else
 			{
-				accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop);
+				accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop, tooltip_msg);
 			}
 			break;
 		case DAD_ROOT_CATEGORY:
@@ -3049,7 +3301,8 @@ void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_c
 // into the folder, as well as performing the actual drop, depending
 // if drop == TRUE.
 BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
-										BOOL drop)
+										BOOL drop,
+										std::string& tooltip_msg)
 {
 	LLInventoryModel* model = getInventoryModel();
 
@@ -3060,11 +3313,14 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 	const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
 	const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false);
 	const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
+	const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
 
 	const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
 	const BOOL move_is_into_favorites = (mUUID == favorites_id);
 	const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
 	const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id);
+	const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); //(mUUID == outbox_id);
+	const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_item->getUUID(), outbox_id);
 
 	LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
 	BOOL accept = FALSE;
@@ -3130,6 +3386,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 		{
 			accept = can_move_to_landmarks(inv_item);
 		}
+		else if (move_is_into_outbox)
+		{
+			accept = can_move_to_outbox(inv_item, tooltip_msg);
+		}
 
 		if(accept && drop)
 		{
@@ -3180,6 +3440,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			{
 				dropToOutfit(inv_item, move_is_into_current_outfit);
 			}
+			else if (move_is_into_outbox && !move_is_from_outbox)
+			{
+				copy_item_to_outbox(inv_item, outbox_id, LLUUID::null);
+			}
 			// NORMAL or TRASH folder
 			// (move the item, restamp if into trash)
 			else
@@ -3380,6 +3644,10 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	if(isItemInTrash())
 	{
 		addTrashContextMenuOptions(items, disabled_items);
+	}	
+	else if(isOutboxFolder())
+	{
+		items.push_back(std::string("Delete"));
 	}
 	else
 	{
@@ -3456,6 +3724,10 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	if(isItemInTrash())
 	{
 		addTrashContextMenuOptions(items, disabled_items);
+	}	
+	else if(isOutboxFolder())
+	{
+		items.push_back(std::string("Delete"));
 	}
 	else
 	{
@@ -3470,8 +3742,11 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 		getClipboardEntries(true, items, disabled_items, flags);
 	}
 
-	items.push_back(std::string("Sound Separator"));
-	items.push_back(std::string("Sound Play"));
+	if (!isOutboxFolder())
+	{
+		items.push_back(std::string("Sound Separator"));
+		items.push_back(std::string("Sound Play"));
+	}
 
 	hide_context_entries(menu, items, disabled_items);
 }
@@ -3507,6 +3782,10 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	if(isItemInTrash())
 	{
 		addTrashContextMenuOptions(items, disabled_items);
+	}	
+	else if(isOutboxFolder())
+	{
+		items.push_back(std::string("Delete"));
 	}
 	else
 	{
@@ -3521,8 +3800,11 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 		getClipboardEntries(true, items, disabled_items, flags);
 	}
 
-	items.push_back(std::string("Landmark Separator"));
-	items.push_back(std::string("About Landmark"));
+	if (!isOutboxFolder())
+	{
+		items.push_back(std::string("Landmark Separator"));
+		items.push_back(std::string("About Landmark"));
+	}
 
 	// Disable "About Landmark" menu item for
 	// multiple landmarks selected. Only one landmark
@@ -3736,6 +4018,10 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	if(isItemInTrash())
 	{
 		addTrashContextMenuOptions(items, disabled_items);
+	}	
+	else if(isOutboxFolder())
+	{
+		items.push_back(std::string("Delete"));
 	}
 	else
 	{
@@ -3778,7 +4064,8 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 
 BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
 									 EDragAndDropType cargo_type,
-									 void* cargo_data)
+									 void* cargo_data,
+									 std::string& tooltip_msg)
 {
 	LLViewerInventoryItem* item = getItem();
 	BOOL rv = FALSE;
@@ -3993,6 +4280,10 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	{
 		addTrashContextMenuOptions(items, disabled_items);
 	}
+	else if(isOutboxFolder())
+	{
+		items.push_back(std::string("Delete"));
+	}
 	else
 	{
 		items.push_back(std::string("Share"));
@@ -4046,6 +4337,10 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	if(isItemInTrash())
 	{
 		addTrashContextMenuOptions(items, disabled_items);
+	}	
+	else if(isOutboxFolder())
+	{
+		items.push_back(std::string("Delete"));
 	}
 	else
 	{
@@ -4060,9 +4355,12 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 		getClipboardEntries(true, items, disabled_items, flags);
 	}
 
-	items.push_back(std::string("Animation Separator"));
-	items.push_back(std::string("Animation Play"));
-	items.push_back(std::string("Animation Audition"));
+	if (!isOutboxFolder())
+	{
+		items.push_back(std::string("Animation Separator"));
+		items.push_back(std::string("Animation Play"));
+		items.push_back(std::string("Animation Audition"));
+	}
 
 	hide_context_entries(menu, items, disabled_items);
 
@@ -4319,6 +4617,10 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	if(isItemInTrash())
 	{
 		addTrashContextMenuOptions(items, disabled_items);
+	}	
+	else if(isOutboxFolder())
+	{
+		items.push_back(std::string("Delete"));
 	}
 	else
 	{
@@ -4652,6 +4954,10 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	{
 		addTrashContextMenuOptions(items, disabled_items);
 	}
+	else if(isOutboxFolder())
+	{
+		items.push_back(std::string("Delete"));
+	}
 	else
 	{	// FWIW, it looks like SUPPRESS_OPEN_ITEM is not set anywhere
 		BOOL can_open = ((flags & SUPPRESS_OPEN_ITEM) != SUPPRESS_OPEN_ITEM);
@@ -5040,6 +5346,10 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 
 		items.push_back(std::string("Restore Item"));
 	}
+	else if(isOutboxFolder())
+	{
+		items.push_back(std::string("Delete"));
+	}
 	else
 	{
 		items.push_back(std::string("Properties"));
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 15629c0c75465c025e5a53b1563165c8db9e0de1..2d625befb4cff555fb26f94ad01e3de584016aba 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -52,7 +52,7 @@ typedef std::vector<std::string> menuentry_vec_t;
 //
 // You'll want to call LLInvItemFVELister::createBridge() to actually create
 // an instance of this class. This helps encapsulate the
-// funcationality a bit. (except for folders, you can create those
+// functionality a bit. (except for folders, you can create those
 // manually...)
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLInvFVBridge : public LLFolderViewEventListener
@@ -70,6 +70,8 @@ class LLInvFVBridge : public LLFolderViewEventListener
 	virtual ~LLInvFVBridge() {}
 
 	BOOL canShare() const;
+	BOOL canListOnMarketplace() const;
+	BOOL canListOnMarketplaceNow() const;
 
 	//--------------------------------------------------------------------
 	// LLInvFVBridge functionality
@@ -115,7 +117,8 @@ class LLInvFVBridge : public LLFolderViewEventListener
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
-							void* cargo_data) { return FALSE; }
+							void* cargo_data,
+							std::string& tooltip_msg) { return FALSE; }
 	virtual LLInventoryType::EType getInventoryType() const { return mInvType; }
 	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
 
@@ -140,6 +143,9 @@ class LLInvFVBridge : public LLFolderViewEventListener
 	BOOL isAgentInventory() const; // false if lost or in the inventory library
 	BOOL isCOFFolder() const; // true if COF or descendent of
 	BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox
+	BOOL isOutboxFolder() const; // true if COF or descendent of marketplace outbox
+	const LLUUID getOutboxFolder() const;
+
 	virtual BOOL isItemPermissive() const;
 	static void changeItemParent(LLInventoryModel* model,
 								 LLViewerInventoryItem* item,
@@ -208,8 +214,7 @@ class LLItemBridge : public LLInvFVBridge
 	/*virtual*/ void clearDisplayName() { mDisplayName.clear(); }
 
 	LLViewerInventoryItem* getItem() const;
-	bool isAddAction(std::string action) const;
-	bool isRemoveAction(std::string action) const;
+
 protected:
 	BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response);
 	virtual BOOL isItemPermissive() const;
@@ -228,8 +233,9 @@ class LLFolderBridge : public LLInvFVBridge
 		mCallingCards(FALSE),
 		mWearables(FALSE)
 	{}
-	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop);
-	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop);
+		
+	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg);
+	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg);
 
 	virtual void performAction(LLInventoryModel* model, std::string action);
 	virtual void openItem();
@@ -255,7 +261,8 @@ class LLFolderBridge : public LLInvFVBridge
 	virtual BOOL hasChildren() const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
-							void* cargo_data);
+							void* cargo_data,
+							std::string& tooltip_msg);
 
 	virtual BOOL isItemRemovable() const;
 	virtual BOOL isItemMovable() const ;
@@ -299,6 +306,8 @@ class LLFolderBridge : public LLInvFVBridge
 
 	void dropToFavorites(LLInventoryItem* inv_item);
 	void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
+	void dropToOutbox(LLInventoryItem* inv_item);
+	void dropFolderToOutbox(LLInventoryCategory* inv_cat);
 
 	//--------------------------------------------------------------------
 	// Messy hacks for handling folder options
@@ -378,7 +387,8 @@ class LLCallingCardBridge : public LLItemBridge
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
-							void* cargo_data);
+							void* cargo_data,
+							std::string& tooltip_msg);
 	void refreshFolderViewItem();
 protected:
 	LLCallingCardObserver* mObserver;
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index d6278a5fda98470eb80e5b807e19ca92c78fd7b0..516b47e616dfe7a7239d12ce75d2ff12d3daf542 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -256,16 +256,20 @@ std::string::size_type LLInventoryFilter::getStringMatchOffset() const
 // has user modified default filter params?
 BOOL LLInventoryFilter::isNotDefault() const
 {
-	return mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes 
-		|| mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes 
-		|| mFilterOps.mFilterWearableTypes != mDefaultFilterOps.mFilterWearableTypes 
-		|| mFilterOps.mFilterTypes != FILTERTYPE_OBJECT
-		|| mFilterOps.mFilterLinks != FILTERLINK_INCLUDE_LINKS
-		|| mFilterSubString.size() 
-		|| mFilterOps.mPermissions != mDefaultFilterOps.mPermissions
-		|| mFilterOps.mMinDate != mDefaultFilterOps.mMinDate 
-		|| mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate
-		|| mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo;
+	BOOL not_default = FALSE;
+
+	not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
+	not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
+	not_default |= (mFilterOps.mFilterWearableTypes != mDefaultFilterOps.mFilterWearableTypes);
+	not_default |= (mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes);
+	not_default |= (mFilterOps.mFilterLinks != mDefaultFilterOps.mFilterLinks);
+	not_default |= (mFilterSubString.size());
+	not_default |= (mFilterOps.mPermissions != mDefaultFilterOps.mPermissions);
+	not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);
+	not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);
+	not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo);
+
+	return not_default;
 }
 
 BOOL LLInventoryFilter::isActive() const
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index db3b96873043243e5036f8ac91a407cc9313a73b..0af013fde5ec25d9c738d988a3cede632bdf9239 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -58,6 +58,7 @@
 #include "llinventorypanel.h"
 #include "lllineeditor.h"
 #include "llmenugl.h"
+#include "llnotificationsutil.h"
 #include "llpanelmaininventory.h"
 #include "llpreviewanim.h"
 #include "llpreviewgesture.h"
@@ -210,6 +211,58 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s
 	model->notifyObservers();
 }
 
+class LLInventoryCollectAllItems : public LLInventoryCollectFunctor
+{
+public:
+	virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+	{
+		return true;
+	}
+};
+
+BOOL get_is_parent_to_worn_item(const LLUUID& id)
+{
+	const LLViewerInventoryCategory* cat = gInventory.getCategory(id);
+	if (!cat)
+	{
+		return FALSE;
+	}
+
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLInventoryCollectAllItems collect_all;
+	gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH, collect_all);
+
+	for (LLInventoryModel::item_array_t::const_iterator it = items.begin(); it != items.end(); ++it)
+	{
+		const LLViewerInventoryItem * const item = *it;
+
+		llassert(item->getIsLinkType());
+
+		LLUUID linked_id = item->getLinkedUUID();
+		const LLViewerInventoryItem * const linked_item = gInventory.getItem(linked_id);
+
+		if (linked_item)
+		{
+			LLUUID parent_id = linked_item->getParentUUID();
+
+			while (!parent_id.isNull())
+			{
+				LLInventoryCategory * parent_cat = gInventory.getCategory(parent_id);
+
+				if (cat == parent_cat)
+				{
+					return TRUE;
+				}
+
+				parent_id = parent_cat->getParentUUID();
+			}
+		}
+	}
+
+	return FALSE;
+}
+
 BOOL get_is_item_worn(const LLUUID& id)
 {
 	const LLViewerInventoryItem* item = gInventory.getItem(id);
@@ -471,6 +524,133 @@ void show_item_original(const LLUUID& item_uuid)
 	}
 }
 
+void move_to_outbox_cb(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (option != 0) return; // canceled
+
+	LLViewerInventoryItem * viitem = gInventory.getItem(notification["payload"]["item_id"].asUUID());
+	LLUUID dest_folder_id = notification["payload"]["dest_folder_id"].asUUID();
+
+	if (viitem)
+	{	
+		// when moving item directly into outbox create folder with that name
+		if (dest_folder_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
+		{
+			dest_folder_id = gInventory.createNewCategory(dest_folder_id,  LLFolderType::FT_NONE, viitem->getName());
+			gInventory.notifyObservers();
+		}
+
+		LLUUID parent = viitem->getParentUUID();
+
+		change_item_parent(
+			&gInventory,
+			viitem,
+			dest_folder_id,
+			false);
+
+		LLUUID top_level_folder = notification["payload"]["top_level_folder"].asUUID();
+
+		if (top_level_folder != LLUUID::null)
+		{
+			LLViewerInventoryCategory* category;
+			
+			while (parent.notNull())
+			{
+				LLInventoryModel::cat_array_t* cat_array;
+				LLInventoryModel::item_array_t* item_array;
+				gInventory.getDirectDescendentsOf(parent,cat_array,item_array);
+
+				LLUUID next_parent;
+
+				category = gInventory.getCategory(parent);
+
+				if (!category) break;
+
+				next_parent = category->getParentUUID();
+
+				if (cat_array->empty() && item_array->empty())
+				{
+					remove_category(&gInventory, parent);
+				}
+
+				if (parent == top_level_folder)
+				{
+					break;
+				}
+
+				parent = next_parent;
+			}
+		}
+
+	}
+}
+
+
+void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder)
+{
+	if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
+	{
+		// when moving item directly into outbox create folder with that name
+		if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
+		{
+			dest_folder = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, inv_item->getName());
+			gInventory.notifyObservers();
+		}
+
+		copy_inventory_item(
+			gAgent.getID(),
+			inv_item->getPermissions().getOwner(),
+			inv_item->getUUID(),
+			dest_folder,
+			inv_item->getName(),
+			LLPointer<LLInventoryCallback>(NULL));
+	}
+	else
+	{	
+		LLSD args;
+		args["ITEM_NAME"] = inv_item->getName();
+		LLSD payload;
+		payload["item_id"] = inv_item->getUUID();
+		payload["dest_folder_id"] = dest_folder;
+		payload["top_level_folder"] = top_level_folder;
+		LLNotificationsUtil::add("ConfirmNoCopyToOutbox", args, payload, boost::bind(&move_to_outbox_cb, _1, _2));
+	}
+}
+
+void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder)
+{
+	LLUUID new_folder_id = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, inv_cat->getName());
+	gInventory.notifyObservers();
+
+	LLInventoryModel::cat_array_t* cat_array;
+	LLInventoryModel::item_array_t* item_array;
+	gInventory.getDirectDescendentsOf(inv_cat->getUUID(),cat_array,item_array);
+
+	// copy the vector because otherwise the iterator won't be happy if we delete from it
+	LLInventoryModel::item_array_t item_array_copy = *item_array;
+
+	for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
+	{
+		LLInventoryItem* item = *iter;
+		copy_item_to_outbox(item, new_folder_id, top_level_folder);
+	}
+
+	LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
+
+	for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
+	{
+		LLViewerInventoryCategory* category = *iter;
+		copy_folder_to_outbox(category, new_folder_id, top_level_folder);
+	}
+
+	// delete the folder if we have emptied it
+	//if (cat_array->empty() && item_array->empty())
+	//{
+	//	remove_category(inventory_model, inv_cat->getUUID());
+	//}
+}
+
 ///----------------------------------------------------------------------------
 /// LLInventoryCollectFunctor implementations
 ///----------------------------------------------------------------------------
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 2016b92666d9ea168425196e462be886dc7bc2f6..7b452537f83b039ed4d898de95c9ddadd3c42e2d 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -37,6 +37,9 @@
  **                    MISCELLANEOUS GLOBAL FUNCTIONS
  **/
 
+// Is this a parent folder to a worn item
+BOOL get_is_parent_to_worn_item(const LLUUID& id);
+
 // Is this item or its baseitem is worn, attached, etc...
 BOOL get_is_item_worn(const LLUUID& id);
 
@@ -71,6 +74,10 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s
 // Generates a string containing the path to the item specified by item_id.
 void append_path(const LLUUID& id, std::string& path);
 
+void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder);
+
+void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder);
+
 /**                    Miscellaneous global functions
  **                                                                            **
  *******************************************************************************/
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 1aa402802e6b364f10ed3a8132b9434199698063..615d3aefde7bb8d5ad90085393a202c140437819 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -129,6 +129,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 	mScroller(NULL),
 	mSortOrderSetting(p.sort_order_setting),
 	mInventory(p.inventory),
+	mAcceptsDragAndDrop(p.accepts_drag_and_drop),
 	mAllowMultiSelect(p.allow_multi_select),
 	mShowItemLinkOverlays(p.show_item_link_overlays),
 	mShowLoadStatus(p.show_load_status),
@@ -163,49 +164,6 @@ void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
 	{
 		root_id = gInventory.getLibraryRootFolderID();
 	}
-	// leslie -- temporary HACK to work around sim not creating inbox and outbox with proper system folder type
-	else if (preferred_type == LLFolderType::FT_INBOX)
-	{
-		LLInventoryModel::cat_array_t* cats;
-		LLInventoryModel::item_array_t* items;
-		
-		gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
-		
-		if (cats)
-		{
-			for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
-			{
-				LLInventoryCategory* cat = *cat_it;
-				
-				if (cat->getName() == "Received Items")
-				{
-					root_id = cat->getUUID();
-				}
-			}
-		}
-	}
-	// leslie -- temporary HACK to work around sim not creating inbox and outbox with proper system folder type
-	else if (preferred_type == LLFolderType::FT_OUTBOX)
-	{
-		LLInventoryModel::cat_array_t* cats;
-		LLInventoryModel::item_array_t* items;
-		
-		gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
-		
-		if (cats)
-		{
-			for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
-			{
-				LLInventoryCategory* cat = *cat_it;
-				
-				if (cat->getName() == "Merchant Outbox")
-				{
-					root_id = cat->getUUID();
-				}
-			}
-		}
-	}
-	// leslie -- end temporary HACK
 	else
 	{
 		root_id = (preferred_type != LLFolderType::FT_NONE)
@@ -277,10 +235,10 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	{
 		setSortOrder(gSavedSettings.getU32(DEFAULT_SORT_ORDER));
 	}
-	mFolderRoot->setSortOrder(getFilter()->getSortOrder());
 
 	// hide inbox
 	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
+	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
 
 	// Initialize base class params.
 	LLPanel::initFromParams(params);
@@ -389,6 +347,10 @@ U32 LLInventoryPanel::getSortOrder() const
 	return mFolderRoot->getSortOrder(); 
 }
 
+void LLInventoryPanel::requestSort()
+{
+	mFolderRoot->requestSort();
+}
 
 void LLInventoryPanel::setSinceLogoff(BOOL sl)
 {
@@ -863,19 +825,24 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 								   EAcceptance* accept,
 								   std::string& tooltip_msg)
 {
-	BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+	BOOL handled = FALSE;
 
-	// If folder view is empty the (x, y) point won't be in its rect
-	// so the handler must be called explicitly.
-	// but only if was not handled before. See EXT-6746.
-	if (!handled && !mFolderRoot->hasVisibleChildren())
+	if (mAcceptsDragAndDrop)
 	{
-		handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-	}
+		handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
 
-	if (handled)
-	{
-		mFolderRoot->setDragAndDropThisFrame();
+		// If folder view is empty the (x, y) point won't be in its rect
+		// so the handler must be called explicitly.
+		// but only if was not handled before. See EXT-6746.
+		if (!handled && !mFolderRoot->hasVisibleChildren())
+		{
+			handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+		}
+
+		if (handled)
+		{
+			mFolderRoot->setDragAndDropThisFrame();
+		}
 	}
 
 	return handled;
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 7676bbb6d7ed752a5b95b8de48975a559fad60f2..8635ebc5c8df831186148b7bfd5b9b9ba6b222cf 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -86,6 +86,7 @@ class LLInventoryPanel : public LLPanel
 		Optional<bool>						use_label_suffix;
 		Optional<bool>						show_load_status;
 		Optional<LLScrollContainer::Params>	scroll;
+		Optional<bool>						accepts_drag_and_drop;
 
 		Params()
 		:	sort_order_setting("sort_order_setting"),
@@ -96,7 +97,8 @@ class LLInventoryPanel : public LLPanel
 			start_folder("start_folder"),
 			use_label_suffix("use_label_suffix", true),
 			show_load_status("show_load_status"),
-			scroll("scroll")
+			scroll("scroll"),
+			accepts_drag_and_drop("accepts_drag_and_drop")
 		{}
 	};
 
@@ -181,6 +183,7 @@ class LLInventoryPanel : public LLPanel
 	LLInventoryModel*			mInventory;
 	LLInventoryObserver*		mInventoryObserver;
 	LLInvPanelComplObserver*	mCompletionObserver;
+	BOOL						mAcceptsDragAndDrop;
 	BOOL 						mAllowMultiSelect;
 	BOOL 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons
 	BOOL						mShowLoadStatus;
@@ -208,6 +211,8 @@ class LLInventoryPanel : public LLPanel
 	
 	void setSortOrder(U32 order);
 	U32 getSortOrder() const;
+	void requestSort();
+
 private:
 	std::string					mSortOrderSetting;
 
diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h
index 93e2e7128b7c9b940ec1faaf113d94b4eaca3340..8d76aa9531cf9704c44af08a62d22099f0113c0c 100644
--- a/indra/newview/lljoystickbutton.h
+++ b/indra/newview/lljoystickbutton.h
@@ -57,7 +57,7 @@ class LLJoystick
 		Params()
 		:	quadrant("quadrant", JQ_ORIGIN)
 		{
-			label = "";
+			changeDefault(label, "");
 		}
 	};
 	LLJoystick(const Params&);
@@ -137,7 +137,7 @@ class LLJoystickCameraRotate
 	{
 		Params()
 		{
-			held_down_delay.seconds(0.0);
+			changeDefault(held_down_delay.seconds, 0.0);
 		}
 	};
 
diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp
index 5c020e6d982eb7060b857a800f36b4d050f87f25..d73048a28b101b9fdf6a0044f27c6f173ce400c7 100644
--- a/indra/newview/llmainlooprepeater.cpp
+++ b/indra/newview/llmainlooprepeater.cpp
@@ -46,7 +46,7 @@ void LLMainLoopRepeater::start(void)
 {
 	if(mQueue != 0) return;
 
-	mQueue = new LLThreadSafeQueue<LLSD>(gAPRPoolp, 1024);
+	mQueue = new LLThreadSafeQueue<LLSD>(1024);
 	mMainLoopConnection = LLEventPumps::instance().
 		obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1));
 	mRepeaterConnection = LLEventPumps::instance().
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 1eb786f433d873008c1f34e628c7bec12fb0c0e7..0bdeb114f54407d21bb36e7ec982fe2a4a7269b1 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -79,7 +79,6 @@ LLMediaCtrl::Params::Params()
 	trusted_content("trusted_content", false),
 	focus_on_click("focus_on_click", true)
 {
-	tab_stop(false);
 }
 
 LLMediaCtrl::LLMediaCtrl( const Params& p) :
@@ -319,6 +318,11 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )
 
 	if (mContextMenu)
 	{
+		// hide/show debugging options
+		bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");
+		mContextMenu->setItemVisible("open_webinspector", media_plugin_debugging_enabled );
+		mContextMenu->setItemVisible("debug_separator", media_plugin_debugging_enabled );
+
 		mContextMenu->show(x, y);
 		LLMenuGL::showPopup(this, mContextMenu, x, y);
 	}
@@ -385,12 +389,22 @@ void LLMediaCtrl::onFocusLost()
 //
 BOOL LLMediaCtrl::postBuild ()
 {
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
+	registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this));
+
 	mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
 		"menu_media_ctrl.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
 	setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2));
+
 	return TRUE;
 }
 
+void LLMediaCtrl::onOpenWebInspector()
+{
+	if (mMediaSource && mMediaSource->hasMedia())
+		mMediaSource->getMediaPlugin()->showWebInspector( true );
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )
@@ -1065,6 +1079,12 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 			mHoverTextChanged = true;
 		};
 		break;
+
+		case MEDIA_EVENT_DEBUG_MESSAGE:
+		{
+			LL_INFOS("media") << self->getDebugMessageText() << LL_ENDL; 
+		};
+		break;
 	};
 
 	// chain all events to any potential observers of this object.
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index 0e4a5b1d65cb80d5bc6eda9f090855ee2962ae10..3c0436e27a45e336bef5590229c3650a41839777 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -166,6 +166,9 @@ class LLMediaCtrl :
 		// Incoming media event dispatcher
 		virtual void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
 
+		// right click debugging item
+		void onOpenWebInspector();
+
 		LLUUID getTextureID() {return mMediaTextureID;}
 
 	protected:
diff --git a/indra/newview/llmemoryview.h b/indra/newview/llmemoryview.h
index 9bdc59ab100049d4f21c79acd7e231be4dce55e8..dc4849a9c4aaf9e0d39fe1a238d0f2789da2620f 100644
--- a/indra/newview/llmemoryview.h
+++ b/indra/newview/llmemoryview.h
@@ -38,8 +38,8 @@ class LLMemoryView : public LLView
 	{
 		Params()
 		{
-			mouse_opaque = true;
-			visible = false;
+			changeDefault(mouse_opaque, true);
+			changeDefault(visible, false);
 		}
 	};
 	LLMemoryView(const LLMemoryView::Params&);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
old mode 100755
new mode 100644
index afed306a28fa343b593453d0b8dc3c1c883b11f4..fc594841e314c807c0ff14701eaf5ee1588ccc43
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -445,12 +445,12 @@ class LLWholeModelUploadResponder: public LLCurl::Responder
 };
 
 LLMeshRepoThread::LLMeshRepoThread()
-: LLThread("mesh repo", NULL) 
+: LLThread("mesh repo") 
 { 
 	mWaiting = false;
-	mMutex = new LLMutex(NULL);
-	mHeaderMutex = new LLMutex(NULL);
-	mSignal = new LLCondition(NULL);
+	mMutex = new LLMutex();
+	mHeaderMutex = new LLMutex();
+	mSignal = new LLCondition();
 }
 
 LLMeshRepoThread::~LLMeshRepoThread()
@@ -1199,7 +1199,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
 	mUploadTextures = upload_textures;
 	mUploadSkin = upload_skin;
 	mUploadJoints = upload_joints;
-	mMutex = new LLMutex(NULL);
+	mMutex = new LLMutex();
 	mCurlRequest = NULL;
 	mPendingUploads = 0;
 	mFinished = false;
@@ -2029,7 +2029,7 @@ LLMeshRepository::LLMeshRepository()
 
 void LLMeshRepository::init()
 {
-	mMeshMutex = new LLMutex(NULL);
+	mMeshMutex = new LLMutex();
 	
 	LLConvexDecomposition::getInstance()->initSystem();
 
@@ -2852,8 +2852,8 @@ LLPhysicsDecomp::LLPhysicsDecomp()
 	mQuitting = false;
 	mDone = false;
 
-	mSignal = new LLCondition(NULL);
-	mMutex = new LLMutex(NULL);
+	mSignal = new LLCondition();
+	mMutex = new LLMutex();
 }
 
 LLPhysicsDecomp::~LLPhysicsDecomp()
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
old mode 100755
new mode 100644
diff --git a/indra/newview/llmorphview.h b/indra/newview/llmorphview.h
index 1d8ee8e9441c65f8ac11ea2a8e6206642bf3be63..318d49bba5d0e32ba1a0a462cf6a5cedf8bbdfac 100644
--- a/indra/newview/llmorphview.h
+++ b/indra/newview/llmorphview.h
@@ -40,8 +40,8 @@ class LLMorphView : public LLView
 	{
 		Params()
 		{
-			mouse_opaque(false);
-			follows.flags(FOLLOWS_ALL);
+			changeDefault(mouse_opaque, false);
+			changeDefault(follows.flags, FOLLOWS_ALL);
 		}
 	};
 	LLMorphView(const LLMorphView::Params&);
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index afceb58ccf2a98bfdf1d061f3273df8f0247851e..4e28d1f526266e49d2fdbb0a6194c421b8d051f2 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -57,7 +57,6 @@ LLNameListCtrl::Params::Params()
 	allow_calling_card_drop("allow_calling_card_drop", false),
 	short_names("short_names", false)
 {
-	name = "name_list";
 }
 
 LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index d58a1cb66399f1e8b7c896082b139877784451f4..988e801b61a12ca5f775bf27b3d669e72467ef1e 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -66,8 +66,8 @@ class LLDropTarget : public LLView
 		Params()
 		:	agent_id("agent_id")
 		{
-			mouse_opaque(false);
-			follows.flags(FOLLOWS_ALL);
+			changeDefault(mouse_opaque, false);
+			changeDefault(follows.flags, FOLLOWS_ALL);
 		}
 	};
 
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 1576ccccdf3e5249bed0b605e2988e17066dc220..bc594b55170d959745f5b5e605339b5c7495b0bb 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -579,6 +579,11 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
 
 	}
 
+	// After role member data was changed in Roles->Members
+	// need to update role titles. See STORM-918.
+	if (gc == GC_ROLE_MEMBER_DATA)
+		LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID);
+
 	// If this was just a titles update, we are done.
 	if (gc == GC_TITLES) return;
 
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index e64192c2ae907604fd18115ea3588c46935baa24..31c0e3d01a740015b8d343b86181321aca8d6336 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -82,8 +82,8 @@ class LLGroupDropTarget : public LLView
 		:	panel("panel"),
 			group_id("group_id")
 		{
-			mouse_opaque(false);
-			follows.flags(FOLLOWS_ALL);
+			changeDefault(mouse_opaque, false);
+			changeDefault(follows.flags, FOLLOWS_ALL);
 		}
 	};
 	LLGroupDropTarget(const Params&);
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index bef809f3a71749423ad6e8f6c0c28cc16401f13c..db7d836799c4d61d040437c2cfb217c185f82f4d 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -154,6 +154,10 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 	}
 	updateLocationCombo(false);
 
+	LLUICtrl& mode_combo = getChildRef<LLUICtrl>("mode_combo");
+	mode_combo.setValue(gSavedSettings.getString("SessionSettingsFile"));
+	mode_combo.setCommitCallback(boost::bind(&LLPanelLogin::onModeChange, this, getChild<LLUICtrl>("mode_combo")->getValue(), _2));
+
 	LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
 	server_choice_combo->setCommitCallback(onSelectServer, NULL);
 	server_choice_combo->setFocusLostCallback(boost::bind(onServerComboLostFocus, _1));
@@ -1021,6 +1025,32 @@ void LLPanelLogin::updateLoginPanelLinks()
 	sInstance->getChildView("forgot_password_text")->setVisible( system_grid);
 }
 
+void LLPanelLogin::onModeChange(const LLSD& original_value, const LLSD& new_value)
+{
+	if (original_value.asString() != new_value.asString())
+	{
+		LLNotificationsUtil::add("ModeChange", LLSD(), LLSD(), boost::bind(&LLPanelLogin::onModeChangeConfirm, this, original_value, new_value, _1, _2));
+	}
+}
+
+void LLPanelLogin::onModeChangeConfirm(const LLSD& original_value, const LLSD& new_value, const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	switch (option)
+	{
+	case 0:
+		gSavedSettings.getControl("SessionSettingsFile")->set(new_value);
+		LLAppViewer::instance()->requestQuit();
+		break;
+	case 1:
+		// revert to original value
+		getChild<LLUICtrl>("mode_combo")->setValue(original_value);
+		break;
+	default:
+		break;
+	}
+}
+
 std::string canonicalize_username(const std::string& name)
 {
 	std::string cname = name;
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 4078eedc774030fb78ce8ba2d69ceeb49bbc40e4..be9de884d14b1cd0168c8051997a687470d465d8 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -87,6 +87,8 @@ class LLPanelLogin:
 	void reshapeBrowser();
 	void addFavoritesToStartLocation();
 	void addUsersWithFavoritesToUsername();
+	void onModeChange(const LLSD& original_value, const LLSD& new_value);
+	void onModeChangeConfirm(const LLSD& original_value, const LLSD& new_value, const LLSD& notification, const LLSD& response);
 	static void onClickConnect(void*);
 	static void onClickNewAccount(void*);
 	static void onClickVersion(void*);
@@ -97,7 +99,6 @@ class LLPanelLogin:
 	static void onServerComboLostFocus(LLFocusableElement*);
 	static void updateServerCombo();
 	static void updateStartSLURL();
-	
 	static void updateLoginPanelLinks();
 
 private:
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index f17f36a9776e9377532da38691c5e9ba01896fa4..0579ecbb90efd2ca1ed0c5122225cb0ead98aadf 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -53,10 +53,6 @@ LLPanelMarketplaceInbox::LLPanelMarketplaceInbox(const Params& p)
 
 LLPanelMarketplaceInbox::~LLPanelMarketplaceInbox()
 {
-	if (getChild<LLButton>("inbox_btn")->getToggleState())
-	{
-		gSavedPerAccountSettings.setString("LastInventoryInboxExpand", LLDate::now().asString());
-	}
 }
 
 // virtual
@@ -93,12 +89,17 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()
 														  inbox_inventory_parent,
 														  LLInventoryPanel::child_registry_t::instance());
 	
+	llassert(mInventoryPanel);
+	
 	// Reshape the inventory to the proper size
 	LLRect inventory_placeholder_rect = inbox_inventory_placeholder->getRect();
 	mInventoryPanel->setShape(inventory_placeholder_rect);
 	
-	// Set the sort order newest to oldest, and a selection change callback
+	// Set the sort order newest to oldest
 	mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);	
+	mInventoryPanel->getFilter()->markDefault();
+
+	// Set selection callback for proper update of inventory status buttons
 	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this));
 
 	// Set up the note to display when the inbox is empty
@@ -115,6 +116,8 @@ void LLPanelMarketplaceInbox::onFocusReceived()
 	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
 
 	sidepanel_inventory->clearSelections(true, false, true);
+
+	gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
 }
 
 BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
diff --git a/indra/newview/llpanelmarketplaceinbox.h b/indra/newview/llpanelmarketplaceinbox.h
index 7b4ed137db767007d96f55beb9f1f1df37518d51..705a095cf0109b2bb99532c05b8cbbeac56001df 100644
--- a/indra/newview/llpanelmarketplaceinbox.h
+++ b/indra/newview/llpanelmarketplaceinbox.h
@@ -37,9 +37,7 @@ class LLPanelMarketplaceInbox : public LLPanel, public LLSideTrayTabBadgeDriver
 public:
 
 	struct Params :	public LLInitParam::Block<Params, LLPanel::Params>
-	{
-		Params() {}
-	};
+	{};
 
 	LOG_CLASS(LLPanelMarketplaceInbox);
 
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 2c97d539a1ecff99b4e7c08eb2d051af54ae587e..faba6dc0cf19490970f5c87bbf07ea8abe090c81 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -37,6 +37,8 @@
 #include "llviewerfoldertype.h"
 
 
+#define DEBUGGING_FRESHNESS	0
+
 //
 // statics
 //
@@ -66,7 +68,7 @@ void LLInboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& para
 	
 	LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false);
 	
-	// leslie -- temporary HACK to work around sim not creating inbox and outbox with proper system folder type
+	// leslie -- temporary HACK to work around sim not creating inbox with proper system folder type
 	if (root_id.isNull())
 	{
 		std::string start_folder_name(params.start_folder());
@@ -133,6 +135,27 @@ LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge
 	return LLUICtrlFactory::create<LLInboxFolderViewFolder>(params);
 }
 
+LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
+{
+	LLFolderViewItem::Params params;
+
+	params.name = bridge->getDisplayName();
+	params.icon = bridge->getIcon();
+	params.icon_open = bridge->getOpenIcon();
+
+	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
+	{
+		params.icon_overlay = LLUI::getUIImage("Inv_Link");
+	}
+
+	params.creation_date = bridge->getCreationDate();
+	params.root = mFolderRoot;
+	params.listener = bridge;
+	params.rect = LLRect (0, 0, 0, 0);
+	params.tool_tip = params.name;
+
+	return LLUICtrlFactory::create<LLInboxFolderViewItem>(params);
+}
 
 //
 // LLInboxFolderViewFolder Implementation
@@ -141,7 +164,7 @@ LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge
 LLInboxFolderViewFolder::LLInboxFolderViewFolder(const Params& p)
 	: LLFolderViewFolder(p)
 	, LLBadgeOwner(getHandle())
-	, mFresh(true)
+	, mFresh(false)
 {
 #if SUPPORTING_FRESH_ITEM_COUNT
 	initBadgeParams(p.new_badge());
@@ -152,19 +175,6 @@ LLInboxFolderViewFolder::~LLInboxFolderViewFolder()
 {
 }
 
-// virtual
-time_t LLInboxFolderViewFolder::getCreationDate() const
-{
-	time_t ret_val = LLFolderViewFolder::getCreationDate();
-
-	if (!mCreationDate)
-	{
-		updateFlag();
-	}
-
-	return ret_val;
-}
-
 // virtual
 void LLInboxFolderViewFolder::draw()
 {
@@ -180,29 +190,68 @@ void LLInboxFolderViewFolder::draw()
 	LLFolderViewFolder::draw();
 }
 
-void LLInboxFolderViewFolder::updateFlag() const
+void LLInboxFolderViewFolder::computeFreshness()
+{
+	const U32 last_expansion_utc = gSavedPerAccountSettings.getU32("LastInventoryInboxActivity");
+
+	if (last_expansion_utc > 0)
+	{
+		const U32 time_offset_for_pdt = 7 * 60 * 60;
+		const U32 last_expansion = last_expansion_utc - time_offset_for_pdt;
+
+		mFresh = (mCreationDate > last_expansion);
+
+#if DEBUGGING_FRESHNESS
+		if (mFresh)
+		{
+			llinfos << "Item is fresh! -- creation " << mCreationDate << ", saved_freshness_date " << last_expansion << llendl;
+		}
+#endif
+	}
+	else
+	{
+		mFresh = true;
+	}
+}
+
+void LLInboxFolderViewFolder::deFreshify()
 {
-	LLDate saved_freshness_date = LLDate(gSavedPerAccountSettings.getString("LastInventoryInboxExpand"));
-	mFresh = (mCreationDate > saved_freshness_date.secondsSinceEpoch());
+	mFresh = false;
+
+	gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
 }
 
 void LLInboxFolderViewFolder::selectItem()
 {
-	mFresh = false;
 	LLFolderViewFolder::selectItem();
+
+	deFreshify();
 }
 
 void LLInboxFolderViewFolder::toggleOpen()
 {
-	mFresh = false;
 	LLFolderViewFolder::toggleOpen();
+
+	deFreshify();
 }
 
-void LLInboxFolderViewFolder::setCreationDate(time_t creation_date_utc) const
+void LLInboxFolderViewFolder::setCreationDate(time_t creation_date_utc)
 { 
 	mCreationDate = creation_date_utc; 
-	updateFlag();
+
+	if (mParentFolder == mRoot)
+	{
+		computeFreshness();
+	}
 }
 
+//
+// LLInboxFolderViewItem Implementation
+//
+
+BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+	return TRUE;
+}
 
 // eof
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index 8946b9dc98dbb4120b5d0f5bd3a1aa2a3068646e..46eeb9ea7fa35e9955009ea493faf9fa6382034a 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -33,7 +33,7 @@
 #include "llfolderviewitem.h"
 
 
-#define SUPPORTING_FRESH_ITEM_COUNT	0
+#define SUPPORTING_FRESH_ITEM_COUNT	1
 
 
 
@@ -41,9 +41,7 @@ class LLInboxInventoryPanel : public LLInventoryPanel
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
-	{
-		Params() {}
-	};
+	{};
 	
 	LLInboxInventoryPanel(const Params& p);
 	~LLInboxInventoryPanel();
@@ -52,7 +50,8 @@ class LLInboxInventoryPanel : public LLInventoryPanel
 	void buildFolderView(const LLInventoryPanel::Params& params);
 
 	// virtual
-	class LLFolderViewFolder*	createFolderViewFolder(LLInvFVBridge * bridge);
+	LLFolderViewFolder * createFolderViewFolder(LLInvFVBridge * bridge);
+	LLFolderViewItem * createFolderViewItem(LLInvFVBridge * bridge);
 };
 
 
@@ -72,21 +71,32 @@ class LLInboxFolderViewFolder : public LLFolderViewFolder, public LLBadgeOwner
 	LLInboxFolderViewFolder(const Params& p);
 	~LLInboxFolderViewFolder();
 
-	time_t getCreationDate() const;
-	
 	void draw();
 	
-	void updateFlag() const;
+	void computeFreshness();
+	void deFreshify();
+
 	void selectItem();
 	void toggleOpen();
 
 	bool isFresh() const { return mFresh; }
 	
 protected:
-	void setCreationDate(time_t creation_date_utc) const;
+	void setCreationDate(time_t creation_date_utc);
 
-	mutable bool	mFresh;
+	bool mFresh;
 };
 
 
+class LLInboxFolderViewItem : public LLFolderViewItem
+{
+public:
+	LLInboxFolderViewItem(const Params& p)
+		: LLFolderViewItem(p)
+	{
+	}
+
+	BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+};
+
 #endif //LL_INBOXINVENTORYPANEL_H
diff --git a/indra/newview/llpanelmarketplaceoutbox.cpp b/indra/newview/llpanelmarketplaceoutbox.cpp
index d51a0d78fe25362513d46bd33a35ffd405287a24..73fb92ff727c37d3208b29b6eb29eee2725c43fb 100644
--- a/indra/newview/llpanelmarketplaceoutbox.cpp
+++ b/indra/newview/llpanelmarketplaceoutbox.cpp
@@ -27,6 +27,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llpanelmarketplaceoutbox.h"
+#include "llpanelmarketplaceoutboxinventory.h"
 
 #include "llappviewer.h"
 #include "llbutton.h"
@@ -34,11 +35,17 @@
 #include "lleventcoro.h"
 #include "llinventorypanel.h"
 #include "llloadingindicator.h"
+#include "llnotificationsutil.h"
 #include "llpanelmarketplaceinbox.h"
+#include "llsdutil.h"
 #include "llsidepanelinventory.h"
 #include "llsidetray.h"
 #include "lltimer.h"
-
+#include "llviewernetwork.h"
+#include "llagent.h"
+#include "llviewermedia.h"
+#include "llfolderview.h"
+#include "llinventoryfunctions.h"
 
 static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox");
 
@@ -83,7 +90,7 @@ void LLPanelMarketplaceOutbox::handleLoginComplete()
 void LLPanelMarketplaceOutbox::onFocusReceived()
 {
 	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
-	
+
 	sidepanel_inventory->clearSelections(true, true, false);
 }
 
@@ -96,7 +103,7 @@ void LLPanelMarketplaceOutbox::onSelectionChange()
 
 LLInventoryPanel * LLPanelMarketplaceOutbox::setupInventoryPanel()
 {
-	LLView * outbox_inventory_placeholder = getChild<LLView>("outbox_inventory_placeholder");
+	LLView * outbox_inventory_placeholder = getChild<LLView>("outbox_inventory_placeholder_panel");
 	LLView * outbox_inventory_parent = outbox_inventory_placeholder->getParent();
 	
 	mInventoryPanel = 
@@ -104,12 +111,17 @@ LLInventoryPanel * LLPanelMarketplaceOutbox::setupInventoryPanel()
 														  outbox_inventory_parent,
 														  LLInventoryPanel::child_registry_t::instance());
 	
+	llassert(mInventoryPanel);
+	
 	// Reshape the inventory to the proper size
 	LLRect inventory_placeholder_rect = outbox_inventory_placeholder->getRect();
 	mInventoryPanel->setShape(inventory_placeholder_rect);
 	
-	// Set the sort order newest to oldest, and a selection change callback
+	// Set the sort order newest to oldest
 	mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);	
+	mInventoryPanel->getFilter()->markDefault();
+
+	// Set selection callback for proper update of inventory status buttons
 	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceOutbox::onSelectionChange, this));
 	
 	// Set up the note to display when the outbox is empty
@@ -121,11 +133,30 @@ LLInventoryPanel * LLPanelMarketplaceOutbox::setupInventoryPanel()
 	return mInventoryPanel;
 }
 
-bool LLPanelMarketplaceOutbox::isOutboxEmpty() const
+BOOL LLPanelMarketplaceOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+								   EDragAndDropType cargo_type,
+								   void* cargo_data,
+								   EAcceptance* accept,
+								   std::string& tooltip_msg)
 {
-	// TODO: Check for contents of outbox
+	BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+
+	if (!handled && mInventoryPanel && mInventoryPanel->getRootFolder())
+	{
+		handled = mInventoryPanel->getRootFolder()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
+
+		if (handled)
+		{
+			mInventoryPanel->getRootFolder()->setDragAndDropThisFrame();
+		}
+	}
 
-	return false;
+	return handled;
+}
+
+bool LLPanelMarketplaceOutbox::isOutboxEmpty() const
+{
+	return (getTotalItemCount() == 0);
 }
 
 bool LLPanelMarketplaceOutbox::isSyncInProgress() const
@@ -149,28 +180,119 @@ void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel)
 		waitForEventOn(self, "mainloop");
 	}
 
-	outboxPanel->onSyncComplete();
+	outboxPanel->onSyncComplete(true, LLSD::emptyMap());
 
 	gTimeDelayDebugFunc = "";
 }
 
-void LLPanelMarketplaceOutbox::onSyncButtonClicked()
+
+class LLInventorySyncResponder : public LLHTTPClient::Responder
 {
-	// TODO: Actually trigger sync to marketplace
+public:
+	LLInventorySyncResponder(LLPanelMarketplaceOutbox * outboxPanel)
+		: LLCurl::Responder()
+		, mOutboxPanel(outboxPanel)
+	{
+	}
 
+	void completed(U32 status, const std::string& reason, const LLSD& content)
+	{
+		llinfos << "inventory_import complete status: " << status << ", reason: " << reason << llendl;
+
+		if (isGoodStatus(status))
+		{
+			// Complete success
+			llinfos << "success" << llendl;
+		}	
+		else
+		{
+			llwarns << "failed" << llendl;
+		}
+
+		mOutboxPanel->onSyncComplete(isGoodStatus(status), content);
+	}
+
+private:
+	LLPanelMarketplaceOutbox *	mOutboxPanel;
+};
+
+void LLPanelMarketplaceOutbox::onSyncButtonClicked()
+{
+	// Get the sync animation going
 	mSyncInProgress = true;
 	updateSyncButtonStatus();
 
-	// Set a timer (for testing only)
+	// Make the url for the inventory import request
+	std::string url = "https://marketplace.secondlife.com/";
+
+	if (!LLGridManager::getInstance()->isInProductionGrid())
+	{
+		std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
+		url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str());
+
+		// TEMP for Jim's pdp
+		//url = "http://pdp24.lindenlab.com:3000/";
+	}
+	
+	url += "api/1/users/";
+	url += gAgent.getID().getString();
+	url += "/inventory_import";
+
+	llinfos << "http get:  " << url << llendl;
+	LLHTTPClient::get(url, new LLInventorySyncResponder(this), LLViewerMedia::getHeaders());
 
-    gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this));
+	// Set a timer (for testing only)
+    //gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this));
 }
 
-void LLPanelMarketplaceOutbox::onSyncComplete()
+void LLPanelMarketplaceOutbox::onSyncComplete(bool goodStatus, const LLSD& content)
 {
 	mSyncInProgress = false;
-
 	updateSyncButtonStatus();
+	
+	const LLSD& errors_list = content["errors"];
+
+	if (goodStatus && (errors_list.size() == 0))
+	{
+		LLNotificationsUtil::add("OutboxUploadComplete", LLSD::emptyMap(), LLSD::emptyMap());
+	}
+	else
+	{
+		LLNotificationsUtil::add("OutboxUploadHadErrors", LLSD::emptyMap(), LLSD::emptyMap());
+	}
+
+	llinfos << "Marketplace upload llsd:" << llendl;
+	llinfos << ll_pretty_print_sd(content) << llendl;
+	llinfos << llendl;
+
+	const LLSD& imported_list = content["imported"];
+	LLSD::array_const_iterator it = imported_list.beginArray();
+	for ( ; it != imported_list.endArray(); ++it)
+	{
+		LLUUID imported_folder = (*it).asUUID();
+		llinfos << "Successfully uploaded folder " << imported_folder.asString() << " to marketplace." << llendl;
+	}
+
+	for (it = errors_list.beginArray(); it != errors_list.endArray(); ++it)
+	{
+		const LLSD& item_error_map = (*it);
+
+		LLUUID error_folder = item_error_map["folder_id"].asUUID();
+		const std::string& error_string = item_error_map["identifier"].asString();
+		LLUUID error_item = item_error_map["item_id"].asUUID();
+		const std::string& error_item_name = item_error_map["item_name"].asString();
+		const std::string& error_message = item_error_map["message"].asString();
+
+		llinfos << "Error item " << error_folder.asString() << ", " << error_string << ", "
+				<< error_item.asString() << ", " << error_item_name << ", " << error_message << llendl;
+		
+		LLFolderViewFolder * item_folder = mInventoryPanel->getRootFolder()->getFolderByID(error_folder);
+		LLOutboxFolderViewFolder * outbox_item_folder = dynamic_cast<LLOutboxFolderViewFolder *>(item_folder);
+
+		llassert(outbox_item_folder);
+
+		outbox_item_folder->setErrorString(error_string);
+	}
 }
 
 void LLPanelMarketplaceOutbox::updateSyncButtonStatus()
@@ -192,3 +314,46 @@ void LLPanelMarketplaceOutbox::updateSyncButtonStatus()
 		mSyncButton->setEnabled(!isOutboxEmpty());
 	}
 }
+
+U32 LLPanelMarketplaceOutbox::getTotalItemCount() const
+{
+	U32 item_count = 0;
+
+	if (mInventoryPanel)
+	{
+		const LLFolderViewFolder * outbox_folder = mInventoryPanel->getRootFolder();
+
+		if (outbox_folder)
+		{
+			item_count += outbox_folder->getFoldersCount();
+		}
+	}
+
+	return item_count;
+}
+
+void LLPanelMarketplaceOutbox::draw()
+{
+	const U32 item_count = getTotalItemCount();
+	const bool not_empty = (item_count > 0);
+
+	if (not_empty)
+	{
+		std::string item_count_str = llformat("%d", item_count);
+
+		LLStringUtil::format_map_t args;
+		args["[NUM]"] = item_count_str;
+		getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelWithArg", args));
+	}
+	else
+	{
+		getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelNoArg"));
+	}
+	
+	if (!isSyncInProgress())
+	{
+		mSyncButton->setEnabled(not_empty);
+	}
+	
+	LLPanel::draw();
+}
diff --git a/indra/newview/llpanelmarketplaceoutbox.h b/indra/newview/llpanelmarketplaceoutbox.h
index 8e2c35914d551afa87035c8299040fee850f60e2..c6b4a5abe2f04dbad64cbfa47f02522247beed14 100644
--- a/indra/newview/llpanelmarketplaceoutbox.h
+++ b/indra/newview/llpanelmarketplaceoutbox.h
@@ -40,9 +40,7 @@ class LLPanelMarketplaceOutbox : public LLPanel
 public:
 	
 	struct Params :	public LLInitParam::Block<Params, LLPanel::Params>
-	{
-		Params() {}
-	};
+	{};
 	
 	LOG_CLASS(LLPanelMarketplaceOutbox);
 
@@ -54,12 +52,22 @@ class LLPanelMarketplaceOutbox : public LLPanel
 
 	/*virtual*/ BOOL postBuild();
 
+	/*virtual*/ void draw();
+
 	LLInventoryPanel * setupInventoryPanel();
 
+	U32 getTotalItemCount() const;
+
 	bool isOutboxEmpty() const;
 	bool isSyncInProgress() const;
 
-	void onSyncComplete();
+	void onSyncComplete(bool goodStatus, const LLSD& content);
+
+	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+								   EDragAndDropType cargo_type,
+								   void* cargo_data,
+								   EAcceptance* accept,
+								   std::string& tooltip_msg);
 
 protected:
 	void onSyncButtonClicked();
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed1206aec82eade5702da9a98e781e6470d67ba8
--- /dev/null
+++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
@@ -0,0 +1,271 @@
+/** 
+ * @file llpanelmarketplaceoutboxinventory.cpp
+ * @brief LLOutboxInventoryPanel  class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelmarketplaceoutboxinventory.h"
+
+#include "llfolderview.h"
+#include "llfoldervieweventlistener.h"
+#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
+#include "llpanellandmarks.h"
+#include "llplacesinventorybridge.h"
+#include "lltrans.h"
+#include "llviewerfoldertype.h"
+
+
+//
+// statics
+//
+
+static LLDefaultChildRegistry::Register<LLOutboxInventoryPanel> r1("outbox_inventory_panel");
+static LLDefaultChildRegistry::Register<LLOutboxFolderViewFolder> r2("outbox_folder_view_folder");
+
+
+//
+// Marketplace errors
+//
+
+enum
+{
+	MKTERR_NONE = 0,
+
+	MKTERR_NOT_MERCHANT,
+	MKTERR_FOLDER_EMPTY,
+	MKTERR_UNASSOCIATED_PRODUCTS,
+	MKTERR_OBJECT_LIMIT,
+	MKTERR_FOLDER_DEPTH,
+	MKTERR_UNSELLABLE_ITEM,
+	MKTERR_INTERNAL_IMPORT,
+
+	MKTERR_COUNT
+};
+
+static const std::string MARKETPLACE_ERROR_STRINGS[MKTERR_COUNT] =
+{
+	"NO_ERROR",
+	"NOT_MERCHANT_ERROR",
+	"FOLDER_EMPTY_ERROR",
+	"UNASSOCIATED_PRODUCTS_ERROR",
+	"OBJECT_LIMIT_ERROR",
+	"FOLDER_DEPTH_ERROR",
+	"UNSELLABLE_ITEM_FOUND",
+	"INTERNAL_IMPORT_ERROR",
+};
+
+static const std::string MARKETPLACE_ERROR_NAMES[MKTERR_COUNT] =
+{
+	"Marketplace Error None",
+	"Marketplace Error Not Merchant",
+	"Marketplace Error Empty Folder",
+	"Marketplace Error Unassociated Products",
+	"Marketplace Error Object Limit",
+	"Marketplace Error Folder Depth",
+	"Marketplace Error Unsellable Item",
+	"Marketplace Error Internal Import",
+};
+
+
+//
+// LLOutboxInventoryPanel Implementation
+//
+
+LLOutboxInventoryPanel::LLOutboxInventoryPanel(const LLOutboxInventoryPanel::Params& p)
+	: LLInventoryPanel(p)
+{
+}
+
+LLOutboxInventoryPanel::~LLOutboxInventoryPanel()
+{
+}
+
+// virtual
+void LLOutboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
+{
+	// Determine the root folder in case specified, and
+	// build the views starting with that folder.
+	
+	LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+	
+	// leslie -- temporary HACK to work around sim not creating outbox with proper system folder type
+	if (root_id.isNull())
+	{
+		std::string start_folder_name(params.start_folder());
+		
+		LLInventoryModel::cat_array_t* cats;
+		LLInventoryModel::item_array_t* items;
+		
+		gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
+		
+		if (cats)
+		{
+			for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
+			{
+				LLInventoryCategory* cat = *cat_it;
+				
+				if (cat->getName() == start_folder_name)
+				{
+					root_id = cat->getUUID();
+					break;
+				}
+			}
+		}
+		
+		if (root_id == LLUUID::null)
+		{
+			llwarns << "No category found that matches outbox inventory panel start_folder: " << start_folder_name << llendl;
+		}
+	}
+	// leslie -- end temporary HACK
+	
+	if (root_id == LLUUID::null)
+	{
+		llwarns << "Outbox inventory panel has no root folder!" << llendl;
+		root_id = LLUUID::generateNewID();
+	}
+	
+	LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
+																	LLAssetType::AT_CATEGORY,
+																	LLInventoryType::IT_CATEGORY,
+																	this,
+																	NULL,
+																	root_id);
+	
+	mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
+}
+
+LLFolderViewFolder * LLOutboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
+{
+	LLOutboxFolderViewFolder::Params params;
+	
+	params.name = bridge->getDisplayName();
+	params.icon = bridge->getIcon();
+	params.icon_open = bridge->getOpenIcon();
+	
+	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
+	{
+		params.icon_overlay = LLUI::getUIImage("Inv_Link");
+	}
+	
+	params.root = mFolderRoot;
+	params.listener = bridge;
+	params.tool_tip = params.name;
+	
+	return LLUICtrlFactory::create<LLOutboxFolderViewFolder>(params);
+}
+
+LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
+{
+	LLFolderViewItem::Params params;
+
+	params.name = bridge->getDisplayName();
+	params.icon = bridge->getIcon();
+	params.icon_open = bridge->getOpenIcon();
+
+	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
+	{
+		params.icon_overlay = LLUI::getUIImage("Inv_Link");
+	}
+
+	params.creation_date = bridge->getCreationDate();
+	params.root = mFolderRoot;
+	params.listener = bridge;
+	params.rect = LLRect (0, 0, 0, 0);
+	params.tool_tip = params.name;
+
+	return LLUICtrlFactory::create<LLOutboxFolderViewItem>(params);
+}
+
+//
+// LLOutboxFolderViewFolder Implementation
+//
+
+LLOutboxFolderViewFolder::LLOutboxFolderViewFolder(const Params& p)
+	: LLFolderViewFolder(p)
+	, LLBadgeOwner(getHandle())
+	, mError(0)
+{
+	initBadgeParams(p.error_badge());
+}
+
+LLOutboxFolderViewFolder::~LLOutboxFolderViewFolder()
+{
+}
+
+// virtual
+void LLOutboxFolderViewFolder::draw()
+{
+	if (!badgeHasParent())
+	{
+		addBadgeToParentPanel();
+	}
+	
+	setBadgeVisibility(hasError());
+
+	LLFolderViewFolder::draw();
+}
+
+void LLOutboxFolderViewFolder::setErrorString(const std::string& errorString)
+{
+	S32 error_code = MKTERR_NONE;
+
+	for (S32 i = 1; i < MKTERR_COUNT; ++i)
+	{
+		if (MARKETPLACE_ERROR_STRINGS[i] == errorString)
+		{
+			error_code = i;
+			break;
+		}
+	}
+
+	setError(error_code);
+}
+
+void LLOutboxFolderViewFolder::setError(S32 errorCode)
+{
+	mError = errorCode;
+
+	if (hasError())
+	{
+		setToolTip(LLTrans::getString(MARKETPLACE_ERROR_NAMES[mError]));
+	}
+	else
+	{
+		setToolTip(LLStringExplicit(""));
+	}
+}
+
+//
+// LLOutboxFolderViewItem Implementation
+//
+
+BOOL LLOutboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+	return TRUE;
+}
+
+// eof
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.h b/indra/newview/llpanelmarketplaceoutboxinventory.h
new file mode 100644
index 0000000000000000000000000000000000000000..346680a79d9ab56d8c2966570bf1bfd6415d6829
--- /dev/null
+++ b/indra/newview/llpanelmarketplaceoutboxinventory.h
@@ -0,0 +1,97 @@
+/** 
+ * @file llpanelmarketplaceoutboxinventory.h
+ * @brief LLOutboxInventoryPanel class declaration
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_OUTBOXINVENTORYPANEL_H
+#define LL_OUTBOXINVENTORYPANEL_H
+
+
+#include "llbadgeowner.h"
+#include "llinventorypanel.h"
+#include "llfolderviewitem.h"
+
+
+class LLOutboxInventoryPanel : public LLInventoryPanel
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
+	{
+		Params() {}
+	};
+	
+	LLOutboxInventoryPanel(const Params& p);
+	~LLOutboxInventoryPanel();
+
+	// virtual
+	void buildFolderView(const LLInventoryPanel::Params& params);
+
+	// virtual
+	LLFolderViewFolder *	createFolderViewFolder(LLInvFVBridge * bridge);
+	LLFolderViewItem *		createFolderViewItem(LLInvFVBridge * bridge);
+};
+
+
+class LLOutboxFolderViewFolder : public LLFolderViewFolder, public LLBadgeOwner
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
+	{
+		Optional<LLBadge::Params>	error_badge;
+		
+		Params()
+			: error_badge("error_badge")
+		{
+		}
+	};
+	
+	LLOutboxFolderViewFolder(const Params& p);
+	~LLOutboxFolderViewFolder();
+
+	void draw();
+
+	void setErrorString(const std::string& errorString);
+	void setError(S32 errorCode);
+	
+	bool hasError() const { return (mError != 0); }
+
+protected:
+	S32 mError;
+};
+
+
+class LLOutboxFolderViewItem : public LLFolderViewItem
+{
+public:
+	LLOutboxFolderViewItem(const Params& p)
+		: LLFolderViewItem(p)
+	{
+	}
+
+	// virtual
+	BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+};
+
+
+#endif //LL_OUTBOXINVENTORYPANEL_H
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 83ba8afbfca6acfe7b041d2aa293bbed755ce540..44364b5831d55a8d37c427076f230e9db546d4b6 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -140,7 +140,8 @@ class LLTaskInvFVBridge : public LLFolderViewEventListener
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
-							void* cargo_data);
+							void* cargo_data,
+							std::string& tooltip_msg);
 };
 
 LLTaskInvFVBridge::LLTaskInvFVBridge(
@@ -581,7 +582,8 @@ BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
 
 BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop,
 								   EDragAndDropType cargo_type,
-								   void* cargo_data)
+								   void* cargo_data,
+								   std::string& tooltip_msg)
 {
 	//llinfos << "LLTaskInvFVBridge::dragOrDrop()" << llendl;
 	return FALSE;
@@ -711,7 +713,8 @@ class LLTaskCategoryBridge : public LLTaskInvFVBridge
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
-							void* cargo_data);
+							void* cargo_data,
+							std::string& tooltip_msg);
 	virtual BOOL canOpenItem() const { return TRUE; }
 	virtual void openItem();
 };
@@ -805,7 +808,8 @@ BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
 
 BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
 									  EDragAndDropType cargo_type,
-									  void* cargo_data)
+									  void* cargo_data,
+									  std::string& tooltip_msg)
 {
 	//llinfos << "LLTaskCategoryBridge::dragOrDrop()" << llendl;
 	BOOL accept = FALSE;
diff --git a/indra/newview/llsearchcombobox.cpp b/indra/newview/llsearchcombobox.cpp
index 6558c9a7fac6955672f3cc86f85232e4e79ca54c..2824c70582abeb11fa6fda0f95faf9b6fb7b6d05 100644
--- a/indra/newview/llsearchcombobox.cpp
+++ b/indra/newview/llsearchcombobox.cpp
@@ -52,10 +52,9 @@ class LLSearchHistoryBuilder
 };
 
 LLSearchComboBox::Params::Params()
-: search_button("search_button")
-, dropdown_button_visible("dropdown_button_visible", false)
-{
-}
+:	search_button("search_button"),
+	dropdown_button_visible("dropdown_button_visible", false)
+{}
 
 LLSearchComboBox::LLSearchComboBox(const Params&p)
 : LLComboBox(p)
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index 0935a0005b4ed5907be5f7dd261377044580d2b2..db578483209b23ae6d202e9fd889c71c9eaea1f3 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -132,7 +132,7 @@ class LLProtectedDataException
 // LLCertificates are considered unmodifiable
 // Certificates are pulled out of stores, or created via
 // factory calls
-class LLCertificate : public LLRefCount
+class LLCertificate : public LLThreadSafeRefCount
 {
 	LOG_CLASS(LLCertificate);
 public:
@@ -170,7 +170,7 @@ class LLCertificateVector : public LLThreadSafeRefCount
 	
 	// base iterator implementation class, providing
 	// the functionality needed for the iterator class.
-	class iterator_impl : public LLRefCount
+	class iterator_impl : public LLThreadSafeRefCount
 	{
 	public:
 		iterator_impl() {};
@@ -289,7 +289,7 @@ bool operator!=(const LLCertificateVector::iterator& _lhs, const LLCertificateVe
 // * Persistence of credential information based on grid (for saving username/password)
 // * Serialization to an OGP identifier/authenticator pair
 // 
-class LLCredential  : public LLRefCount
+class LLCredential  : public LLThreadSafeRefCount
 {
 public:
 	
@@ -424,7 +424,7 @@ class LLCertValidationInvalidSignatureException : public LLCertException
 
 // LLSecAPIHandler Class
 // Interface handler class for the various security storage handlers.
-class LLSecAPIHandler : public LLRefCount
+class LLSecAPIHandler : public LLThreadSafeRefCount
 {
 public:
 	
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index a800611aac721ccccca32c6ec1ec7c3d5e0d49da..bd62b5c101af064e6dcebc001462e7e09ff149f7 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -52,7 +52,10 @@
 #include "llsidepaneltaskinfo.h"
 #include "llstring.h"
 #include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltrans.h"
 #include "llviewermedia.h"
+#include "llviewernetwork.h"
 #include "llweb.h"
 
 static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory");
@@ -61,16 +64,25 @@ static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_
 // Constants
 //
 
+// No longer want the inbox panel to auto-expand since it creates issues with the "new" tag time stamp
+#define AUTO_EXPAND_INBOX	0
+
+// Temporarily disabling the outbox until we straighten out the API
+#define ENABLE_MERCHANT_OUTBOX_PANEL		0	// keep in sync with ENABLE_INVENTORY_DISPLAY_OUTBOX, ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
+
 static const char * const INBOX_BUTTON_NAME = "inbox_btn";
 static const char * const OUTBOX_BUTTON_NAME = "outbox_btn";
 
 static const char * const INBOX_LAYOUT_PANEL_NAME = "inbox_layout_panel";
 static const char * const OUTBOX_LAYOUT_PANEL_NAME = "outbox_layout_panel";
+
+static const char * const INBOX_OUTBOX_LAYOUT_PANEL_NAME = "inbox_outbox_layout_panel";
 static const char * const MAIN_INVENTORY_LAYOUT_PANEL_NAME = "main_inventory_layout_panel";
 
 static const char * const INBOX_INVENTORY_PANEL = "inventory_inbox";
 static const char * const OUTBOX_INVENTORY_PANEL = "inventory_outbox";
 
+static const char * const INBOX_OUTBOX_LAYOUT_STACK_NAME = "inbox_outbox_layout_stack";
 static const char * const INVENTORY_LAYOUT_STACK_NAME = "inventory_layout_stack";
 
 static const char * const MARKETPLACE_INBOX_PANEL = "marketplace_inbox";
@@ -235,16 +247,20 @@ BOOL LLSidepanelInventory::postBuild()
 	
 	// Marketplace inbox/outbox setup
 	{
-		LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
+		LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
 
 		// Disable user_resize on main inventory panel by default
-		stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, false);
-		stack->setPanelUserResize(INBOX_LAYOUT_PANEL_NAME, false);
-		stack->setPanelUserResize(OUTBOX_LAYOUT_PANEL_NAME, false);
+		inv_stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, false);
+		inv_stack->setPanelUserResize(INBOX_OUTBOX_LAYOUT_PANEL_NAME, false);
+
+		// Collapse marketplace panel by default
+		inv_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME), true);
+		
+		LLLayoutStack* inout_stack = getChild<LLLayoutStack>(INBOX_OUTBOX_LAYOUT_STACK_NAME);
 
 		// Collapse both inbox and outbox panels
-		stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), true);
-		stack->collapsePanel(getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME), true);
+		inout_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), true);
+		inout_stack->collapsePanel(getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME), true);
 		
 		// Set up button states and callbacks
 		LLButton * inbox_button = getChild<LLButton>(INBOX_BUTTON_NAME);
@@ -297,15 +313,16 @@ void LLSidepanelInventory::handleLoginComplete()
 		enableInbox(true);
 	}
 	
+#if ENABLE_MERCHANT_OUTBOX_PANEL
 	// Set up observer for outbox changes, if we have an outbox already
 	if (!outbox_id.isNull())
 	{
 		observeOutboxModifications(outbox_id);
 
 		// Enable the display of the outbox if it exists
-		//enableOutbox(true);
-		// leslie NOTE: Disabling outbox until we support it officially.
+		enableOutbox(true);
 	}
+#endif
 }
 
 void LLSidepanelInventory::observeInboxOutboxCreation()
@@ -388,96 +405,159 @@ void LLSidepanelInventory::observeOutboxModifications(const LLUUID& outboxID)
 void LLSidepanelInventory::enableInbox(bool enabled)
 {
 	mInboxEnabled = enabled;
-	getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME)->setVisible(enabled);
+	
+	LLLayoutPanel * inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
+	inbox_layout_panel->setVisible(enabled);
+
+	if (mInboxEnabled)
+	{
+		LLLayoutPanel * inout_layout_panel = getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME);
+
+		inout_layout_panel->setVisible(TRUE);
+		
+		if (mOutboxEnabled)
+		{
+			S32 inbox_min_dim = inbox_layout_panel->getMinDim();
+			S32 outbox_min_dim = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME)->getMinDim();
+			
+			inout_layout_panel->setMinDim(inbox_min_dim + outbox_min_dim);
+		}
+	}
 }
 
 void LLSidepanelInventory::enableOutbox(bool enabled)
 {
 	mOutboxEnabled = enabled;
-	getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME)->setVisible(enabled);
+	
+	LLLayoutPanel * outbox_layout_panel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
+	outbox_layout_panel->setVisible(enabled);
+
+	if (mOutboxEnabled)
+	{
+		LLLayoutPanel * inout_layout_panel = getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME);
+		
+		inout_layout_panel->setVisible(TRUE);
+		
+		if (mInboxEnabled)
+		{
+			S32 inbox_min_dim = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME)->getMinDim();
+			S32 outbox_min_dim = outbox_layout_panel->getMinDim();
+			
+			inout_layout_panel->setMinDim(inbox_min_dim + outbox_min_dim);
+		}
+		
+		updateOutboxUserStatus();
+	}
 }
 
 void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id)
 {
 	// Trigger a load of the entire inbox so we always know the contents and their creation dates for sorting
 	LLInventoryModelBackgroundFetch::instance().start(inbox_id);
-	
-	// Expand the inbox since we have fresh items
-	LLPanelMarketplaceInbox * inbox = findChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
-	if (inbox)
+
+#if AUTO_EXPAND_INBOX
+	// If the outbox is expanded, don't auto-expand the inbox
+	if (mOutboxEnabled)
+	{
+		if (getChild<LLButton>(OUTBOX_BUTTON_NAME)->getToggleState())
+		{
+			return;
+		}
+	}
+
+	// Expand the inbox since we have fresh items and the outbox is not expanded
+	if (mInboxEnabled)
 	{
 		getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
 		onToggleInboxBtn();
-	}	
+	}
+#endif
 }
 
 void LLSidepanelInventory::onOutboxChanged(const LLUUID& outbox_id)
 {
-	// Perhaps use this to track outbox changes?
+	// Expand the outbox since we have new items in it
+	if (mOutboxEnabled)
+	{
+		getChild<LLButton>(OUTBOX_BUTTON_NAME)->setToggleState(true);
+		onToggleOutboxBtn();
+	}	
 }
 
-bool manageInboxOutboxPanels(LLLayoutStack * stack,
-							 LLButton * pressedButton, LLLayoutPanel * pressedPanel,
+bool LLSidepanelInventory::manageInboxOutboxPanels(LLButton * pressedButton, LLLayoutPanel * pressedPanel,
 							 LLButton * otherButton, LLLayoutPanel * otherPanel)
 {
 	bool expand = pressedButton->getToggleState();
 	bool otherExpanded = otherButton->getToggleState();
 
-	//
-	// NOTE: Ideally we could have two panel sizes stored for a collapsed and expanded minimum size.
-	//       For now, leave this code disabled because it creates some bad artifacts when expanding
-	//       and collapsing the inbox/outbox.
-	//
-	//S32 smallMinSize = (expand ? pressedPanel->getMinDim() : otherPanel->getMinDim());
-	//S32 pressedMinSize = (expand ? 2 * smallMinSize : smallMinSize);
-	//otherPanel->setMinDim(smallMinSize);
-	//pressedPanel->setMinDim(pressedMinSize);
+	LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
+	LLLayoutStack* inout_stack = getChild<LLLayoutStack>(INBOX_OUTBOX_LAYOUT_STACK_NAME);
+	LLLayoutPanel* inout_panel = getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME);
 
+	// Enable user_resize on main inventory panel only when a marketplace box is expanded
+	inv_stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, expand);
+	inv_stack->collapsePanel(inout_panel, !expand);
+
+	// Collapse other marketplace panel if it is expanded
 	if (expand && otherExpanded)
 	{
 		// Reshape pressedPanel to the otherPanel's height so we preserve the marketplace panel size
 		pressedPanel->reshape(pressedPanel->getRect().getWidth(), otherPanel->getRect().getHeight());
 
-		stack->collapsePanel(otherPanel, true);
+		inout_stack->collapsePanel(otherPanel, true);
 		otherButton->setToggleState(false);
 	}
+	else
+	{
+		// NOTE: This is an attempt to reshape the inventory panel to the proper size but it doesn't seem to propagate
+		// properly to the child panels.
 
-	stack->collapsePanel(pressedPanel, !expand);
+		S32 new_height = inout_panel->getRect().getHeight();
 
-	// Enable user_resize on main inventory panel only when a marketplace box is expanded
-	stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, expand);
+		if (otherPanel->getVisible())
+		{
+			new_height -= otherPanel->getMinDim();
+		}
+
+		pressedPanel->reshape(pressedPanel->getRect().getWidth(), new_height);
+	}
+
+	// Expand/collapse the indicated panel
+	inout_stack->collapsePanel(pressedPanel, !expand);
 
 	return expand;
 }
 
 void LLSidepanelInventory::onToggleInboxBtn()
 {
-	LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
-	LLButton* pressedButton = getChild<LLButton>(INBOX_BUTTON_NAME);
-	LLLayoutPanel* pressedPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
-	LLButton* otherButton = getChild<LLButton>(OUTBOX_BUTTON_NAME);
-	LLLayoutPanel* otherPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
+	LLButton* inboxButton = getChild<LLButton>(INBOX_BUTTON_NAME);
+	LLLayoutPanel* inboxPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
+	LLButton* outboxButton = getChild<LLButton>(OUTBOX_BUTTON_NAME);
+	LLLayoutPanel* outboxPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
 
-	manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel);
+	const bool inbox_expanded = manageInboxOutboxPanels(inboxButton, inboxPanel, outboxButton, outboxPanel);
 
-	gSavedPerAccountSettings.setString("LastInventoryInboxExpand", LLDate::now().asString());
+	if (inbox_expanded && inboxPanel->isInVisibleChain())
+	{
+		gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
+	}
 }
 
 void LLSidepanelInventory::onToggleOutboxBtn()
 {
-	LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
-	LLButton* pressedButton = getChild<LLButton>(OUTBOX_BUTTON_NAME);
-	LLLayoutPanel* pressedPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
-	LLButton* otherButton = getChild<LLButton>(INBOX_BUTTON_NAME);
-	LLLayoutPanel* otherPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
+	LLButton* inboxButton = getChild<LLButton>(INBOX_BUTTON_NAME);
+	LLLayoutPanel* inboxPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
+	LLButton* outboxButton = getChild<LLButton>(OUTBOX_BUTTON_NAME);
+	LLLayoutPanel* outboxPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME);
 
-	manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel);
+	manageInboxOutboxPanels(outboxButton, outboxPanel, inboxButton, inboxPanel);
 }
 
 void LLSidepanelInventory::onOpen(const LLSD& key)
 {
 	LLFirstUse::newInventory(false);
 
+#if AUTO_EXPAND_INBOX
 	// Expand the inbox if we have fresh items
 	LLPanelMarketplaceInbox * inbox = findChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
 	if (inbox && (inbox->getFreshItemCount() > 0))
@@ -485,6 +565,12 @@ void LLSidepanelInventory::onOpen(const LLSD& key)
 		getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
 		onToggleInboxBtn();
 	}
+#else
+	if (mInboxEnabled && getChild<LLButton>(INBOX_BUTTON_NAME)->getToggleState())
+	{
+		gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
+	}
+#endif
 
 	if(key.size() == 0)
 		return;
@@ -636,6 +722,77 @@ void LLSidepanelInventory::showInventoryPanel()
 	updateVerbs();
 }
 
+void LLSidepanelInventory::updateOutboxUserStatus()
+{
+	const bool isMerchant = (gSavedSettings.getString("InventoryMarketplaceUserStatus") == "merchant");
+	const bool hasOutbox = !gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false).isNull();
+	
+	LLView * outbox_placeholder = getChild<LLView>("outbox_inventory_placeholder_panel");
+	LLView * outbox_placeholder_parent = outbox_placeholder->getParent();
+	
+	LLTextBox * outbox_title_box = outbox_placeholder->getChild<LLTextBox>("outbox_inventory_placeholder_title");
+	LLTextBox * outbox_text_box = outbox_placeholder->getChild<LLTextBox>("outbox_inventory_placeholder_text");
+
+	std::string outbox_text;
+	std::string outbox_title;
+	std::string outbox_tooltip;
+
+	if (isMerchant)
+	{
+		if (hasOutbox)
+		{
+			outbox_text = LLTrans::getString("InventoryOutboxNoItems");
+			outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle");
+			outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip");
+		}
+		else
+		{
+			outbox_text = LLTrans::getString("InventoryOutboxCreationError");
+			outbox_title = LLTrans::getString("InventoryOutboxCreationErrorTitle");
+			outbox_tooltip = LLTrans::getString("InventoryOutboxCreationErrorTooltip");
+		}
+	}
+	else
+	{
+		//
+		// The string to become a merchant contains 3 URL's which need the domain name patched in.
+		//
+		
+		std::string domain = "secondlife.com";
+		
+		if (!LLGridManager::getInstance()->isInProductionGrid())
+		{
+			std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
+			domain = llformat("%s.lindenlab.com", utf8str_tolower(gridLabel).c_str());
+		}
+		
+		LLStringUtil::format_map_t domain_arg;
+		domain_arg["[DOMAIN_NAME]"] = domain;
+
+		std::string marketplace_url = LLTrans::getString("MarketplaceURL", domain_arg);
+		std::string marketplace_url_create = LLTrans::getString("MarketplaceURL_CreateStore", domain_arg);
+		std::string marketplace_url_info = LLTrans::getString("MarketplaceURL_LearnMore", domain_arg);
+		
+		LLStringUtil::format_map_t args1, args2, args3;
+		args1["[MARKETPLACE_URL]"] = marketplace_url;
+		args2["[LEARN_MORE_URL]"] = marketplace_url_info;
+		args3["[CREATE_STORE_URL]"] = marketplace_url_create;
+		
+		// NOTE: This is dumb, ridiculous and very finicky.  The order of these is very important
+		//       to have these three string substitutions work properly.
+		outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", args1);
+		LLStringUtil::format(outbox_text, args2);
+		LLStringUtil::format(outbox_text, args3);
+
+		outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle");
+		outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip");
+	}
+	
+	outbox_text_box->setValue(outbox_text);
+	outbox_title_box->setValue(outbox_title);
+	outbox_placeholder_parent->setToolTip(outbox_tooltip);
+}
+
 void LLSidepanelInventory::updateVerbs()
 {
 	mInfoBtn->setEnabled(FALSE);
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index f80a3a9dd39c5f8922e3b98f1f540c762dd9e7bf..b7d11f7f9b98705fcc4894f4ed8b3ee63503174c 100644
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -29,11 +29,13 @@
 
 #include "llpanel.h"
 
+class LLButton;
 class LLFolderViewItem;
 class LLInboxOutboxAddedObserver;
 class LLInventoryCategoriesObserver;
 class LLInventoryItem;
 class LLInventoryPanel;
+class LLLayoutPanel;
 class LLPanelMainInventory;
 class LLSidepanelItemInfo;
 class LLSidepanelTaskInfo;
@@ -58,7 +60,7 @@ class LLSidepanelInventory : public LLPanel
 	LLInventoryPanel* getActivePanel(); // Returns an active inventory panel, if any.
 	LLPanelMainInventory* getMainInventoryPanel() const { return mPanelMainInventory; }
 	BOOL isMainInventoryPanelActive() const;
-	
+
 	void clearSelections(bool clearMain, bool clearInbox, bool clearOutbox);
 	std::set<LLUUID> getInboxOrOutboxSelectionList();
 
@@ -74,10 +76,11 @@ class LLSidepanelInventory : public LLPanel
 
 	void enableInbox(bool enabled);
 	void enableOutbox(bool enabled);
-
+	
 	bool isInboxEnabled() const { return mInboxEnabled; }
 	bool isOutboxEnabled() const { return mOutboxEnabled; }
 
+	void updateOutboxUserStatus();
 	void updateVerbs();
 
 protected:
@@ -93,6 +96,8 @@ class LLSidepanelInventory : public LLPanel
 	void onInboxChanged(const LLUUID& inbox_id);
 	void onOutboxChanged(const LLUUID& outbox_id);
 
+	bool manageInboxOutboxPanels(LLButton * pressedButton, LLLayoutPanel * pressedPanel, LLButton * otherButton, LLLayoutPanel * otherPanel);
+
 	//
 	// UI Elements
 	//
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index a7c40578460cfb3900810b73ca879558f59abbd8..50ecad92dd8be43201a994766e96441641af6544 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -62,6 +62,8 @@
 using namespace std;
 using namespace LLNotificationsUI;
 
+class LLSideTrayButton;
+
 static LLRootViewRegistry::Register<LLSideTray>	t1("side_tray");
 static LLDefaultChildRegistry::Register<LLSideTrayTab>	t2("sidetray_tab");
 
@@ -168,8 +170,131 @@ class LLSideTrayTab: public LLPanel
 
 	bool			mHasBadge;
 	LLBadge::Params	mBadgeParams;
+	LLSideTrayButton*	mSideTrayButton;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// LLSideTrayButton
+// Side Tray tab button with "tear off" handling.
+//////////////////////////////////////////////////////////////////////////////
+
+class LLSideTrayButton : public LLButton
+{
+public:
+	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask)
+	{
+		// Route future Mouse messages here preemptively.  (Release on mouse up.)
+		// No handler needed for focus lost since this class has no state that depends on it.
+		gFocusMgr.setMouseCapture(this);
+
+		localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
+
+		// Note: don't pass on to children
+		return TRUE;
+	}
+
+	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask)
+	{
+		// We only handle the click if the click both started and ended within us
+		if( !hasMouseCapture() ) return FALSE;
+
+		S32 screen_x;
+		S32 screen_y;
+		localPointToScreen(x, y, &screen_x, &screen_y);
+
+		S32 delta_x = screen_x - mDragLastScreenX;
+		S32 delta_y = screen_y - mDragLastScreenY;
+
+		LLSideTray* side_tray = LLSideTray::getInstance();
+
+		// Check if the tab we are dragging is docked.
+		if (!side_tray->isTabAttached(mTabName)) return FALSE;
+
+		// Same value is hardcoded in LLDragHandle::handleHover().
+		const S32 undock_threshold = 12;
+
+		// Detach a tab if it has been pulled further than undock_threshold.
+		if (delta_x <= -undock_threshold ||	delta_x >= undock_threshold	||
+			delta_y <= -undock_threshold ||	delta_y >= undock_threshold)
+		{
+			LLSideTrayTab* tab = side_tray->getTab(mTabName);
+			if (!tab) return FALSE;
+
+			tab->setDocked(false);
+
+			LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", tab->getName());
+			if (!floater_tab) return FALSE;
+
+			LLRect original_rect = floater_tab->getRect();
+			S32 header_snap_y = floater_tab->getHeaderHeight() / 2;
+			S32 snap_x = screen_x - original_rect.mLeft - original_rect.getWidth() / 2;
+			S32 snap_y = screen_y - original_rect.mTop + header_snap_y;
+
+			// Move the floater to appear "under" the mouse pointer.
+			floater_tab->setRect(original_rect.translate(snap_x, snap_y));
+
+			// Snap the mouse pointer to the center of the floater header
+			// and call 'mouse down' event handler to begin dragging.
+			floater_tab->handleMouseDown(original_rect.getWidth() / 2,
+				original_rect.getHeight() - header_snap_y,
+				mask);
+
+			return TRUE;
+		}
+
+		return FALSE;
+	}
+
+	void setBadgeDriver(LLSideTrayTabBadgeDriver* driver)
+	{
+		mBadgeDriver = driver;
+	}
+
+	void setVisible(BOOL visible)
+	{
+		setBadgeVisibility(visible);
+
+		LLButton::setVisible(visible);
+	}
+
+protected:
+	LLSideTrayButton(const LLButton::Params& p)
+		: LLButton(p)
+		, mDragLastScreenX(0)
+		, mDragLastScreenY(0)
+		, mBadgeDriver(NULL)
+	{
+		// Find out the tab name to use in handleHover().
+		size_t pos = getName().find("_button");
+		llassert(pos != std::string::npos);
+		mTabName = getName().substr(0, pos);
+	}
+
+	friend class LLUICtrlFactory;
+
+	void draw()
+	{
+		if (mBadgeDriver)
+		{
+			setBadgeLabel(mBadgeDriver->getBadgeString());
+		}
+
+		LLButton::draw();
+	}
+
+private:
+	S32		mDragLastScreenX;
+	S32		mDragLastScreenY;
+
+	std::string					mTabName;
+	LLSideTrayTabBadgeDriver*	mBadgeDriver;
 };
 
+
+////////////////////////////////////////////////////
+// LLSideTrayTab implementation
+////////////////////////////////////////////////////
+
 LLSideTrayTab::LLSideTrayTab(const Params& p)
 :	LLPanel(),
 	mTabTitle(p.tab_title),
@@ -177,7 +302,8 @@ LLSideTrayTab::LLSideTrayTab(const Params& p)
 	mImageSelected(p.image_selected),
 	mDescription(p.description),
 	mMainPanel(NULL),
-	mBadgeParams(p.badge)
+	mBadgeParams(p.badge),
+	mSideTrayButton(NULL)
 {
 	mHasBadge = p.badge.isProvided();
 }
@@ -271,6 +397,11 @@ void LLSideTrayTab::toggleTabDocked(bool toggle_floater /* = true */)
 
 	bool docking = !isDocked();
 
+	if (mSideTrayButton)
+	{
+		mSideTrayButton->setVisible(docking);
+	}
+
 	// Hide the "Tear Off" button when a tab gets undocked
 	// and show "Dock" button instead.
 	getChild<LLButton>("undock")->setVisible(docking);
@@ -461,116 +592,6 @@ LLSideTrayTab*  LLSideTrayTab::createInstance	()
 template <>
 LLPanel* tab_cast<LLPanel*>(LLSideTrayTab* tab) { return tab; }
 
-//////////////////////////////////////////////////////////////////////////////
-// LLSideTrayButton
-// Side Tray tab button with "tear off" handling.
-//////////////////////////////////////////////////////////////////////////////
-
-class LLSideTrayButton : public LLButton
-{
-public:
-	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask)
-	{
-		// Route future Mouse messages here preemptively.  (Release on mouse up.)
-		// No handler needed for focus lost since this class has no state that depends on it.
-		gFocusMgr.setMouseCapture(this);
-
-		localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
-
-		// Note: don't pass on to children
-		return TRUE;
-	}
-
-	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask)
-	{
-		// We only handle the click if the click both started and ended within us
-		if( !hasMouseCapture() ) return FALSE;
-
-		S32 screen_x;
-		S32 screen_y;
-		localPointToScreen(x, y, &screen_x, &screen_y);
-
-		S32 delta_x = screen_x - mDragLastScreenX;
-		S32 delta_y = screen_y - mDragLastScreenY;
-
-		LLSideTray* side_tray = LLSideTray::getInstance();
-
-		// Check if the tab we are dragging is docked.
-		if (!side_tray->isTabAttached(mTabName)) return FALSE;
-
-		// Same value is hardcoded in LLDragHandle::handleHover().
-		const S32 undock_threshold = 12;
-
-		// Detach a tab if it has been pulled further than undock_threshold.
-		if (delta_x <= -undock_threshold ||	delta_x >= undock_threshold	||
-			delta_y <= -undock_threshold ||	delta_y >= undock_threshold)
-		{
-			LLSideTrayTab* tab = side_tray->getTab(mTabName);
-			if (!tab) return FALSE;
-
-			tab->setDocked(false);
-
-			LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", tab->getName());
-			if (!floater_tab) return FALSE;
-
-			LLRect original_rect = floater_tab->getRect();
-			S32 header_snap_y = floater_tab->getHeaderHeight() / 2;
-			S32 snap_x = screen_x - original_rect.mLeft - original_rect.getWidth() / 2;
-			S32 snap_y = screen_y - original_rect.mTop + header_snap_y;
-
-			// Move the floater to appear "under" the mouse pointer.
-			floater_tab->setRect(original_rect.translate(snap_x, snap_y));
-
-			// Snap the mouse pointer to the center of the floater header
-			// and call 'mouse down' event handler to begin dragging.
-			floater_tab->handleMouseDown(original_rect.getWidth() / 2,
-										 original_rect.getHeight() - header_snap_y,
-										 mask);
-
-			return TRUE;
-		}
-
-		return FALSE;
-	}
-
-	void setBadgeDriver(LLSideTrayTabBadgeDriver* driver)
-	{
-		mBadgeDriver = driver;
-	}
-
-protected:
-	LLSideTrayButton(const LLButton::Params& p)
-		: LLButton(p)
-		, mDragLastScreenX(0)
-		, mDragLastScreenY(0)
-		, mBadgeDriver(NULL)
-	{
-		// Find out the tab name to use in handleHover().
-		size_t pos = getName().find("_button");
-		llassert(pos != std::string::npos);
-		mTabName = getName().substr(0, pos);
-	}
-
-	friend class LLUICtrlFactory;
-
-	void draw()
-	{
-		if (mBadgeDriver)
-		{
-			setBadgeLabel(mBadgeDriver->getBadgeString());
-		}
-
-		LLButton::draw();
-	}
-
-private:
-	S32		mDragLastScreenX;
-	S32		mDragLastScreenY;
-
-	std::string					mTabName;
-	LLSideTrayTabBadgeDriver*	mBadgeDriver;
-};
-
 //////////////////////////////////////////////////////////////////////////////
 // LLSideTray
 //////////////////////////////////////////////////////////////////////////////
@@ -685,7 +706,6 @@ LLSideTrayTab* LLSideTray::getTab(const std::string& name)
 bool LLSideTray::isTabAttached(const std::string& name)
 {
 	LLSideTrayTab* tab = getTab(name);
-	llassert(tab);
 	if (!tab) return false;
 
 	return std::find(mTabs.begin(), mTabs.end(), tab) != mTabs.end();
@@ -786,7 +806,7 @@ bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible
 	{
 		// Keep previously active tab visible if requested.
 		if (keep_prev_visible) tab_to_keep_visible = mActiveTab;
-	toggleTabButton(mActiveTab);
+		toggleTabButton(mActiveTab);
 	}
 
 	//select new tab
@@ -794,9 +814,9 @@ bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible
 
 	if (mActiveTab)
 	{
-	toggleTabButton(mActiveTab);
-	LLSD key;//empty
-	mActiveTab->onOpen(key);
+		toggleTabButton(mActiveTab);
+		LLSD key;//empty
+		mActiveTab->onOpen(key);
 	}
 
 	//arrange();
@@ -976,7 +996,9 @@ LLButton* LLSideTrayTab::createButton(bool allowTearOff, LLUICtrl::commit_callba
 	LLButton* button;
 	if (allowTearOff)
 	{
-		button = LLUICtrlFactory::create<LLSideTrayButton>(bparams);
+		mSideTrayButton = LLUICtrlFactory::create<LLSideTrayButton>(bparams);
+
+		button = mSideTrayButton;
 	}
 	else
 	{
@@ -1449,7 +1471,7 @@ void	LLSideTray::updateSidetrayVisibility()
 			parent->setVisible(new_visibility);
 
 			// Signal change of visible width.
-			llinfos << "Visible: " << new_visibility << llendl;
+			//llinfos << "Visible: " << new_visibility << llendl;
 			mVisibleWidthChangeSignal(this, new_visibility);
 		}
 	}
diff --git a/indra/newview/llsidetraypanelcontainer.cpp b/indra/newview/llsidetraypanelcontainer.cpp
index 214f59577203c2008698132f7e3e48f132883426..95a12c7c233e738c4e9167a731eeb8b35495679d 100644
--- a/indra/newview/llsidetraypanelcontainer.cpp
+++ b/indra/newview/llsidetraypanelcontainer.cpp
@@ -32,10 +32,10 @@ static LLDefaultChildRegistry::Register<LLSideTrayPanelContainer> r2("panel_cont
 std::string LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME = "sub_panel_name";
 
 LLSideTrayPanelContainer::Params::Params()
- : default_panel_name("default_panel_name")
+:	default_panel_name("default_panel_name")
 {
 	// Always hide tabs.
-	hide_tabs(true);
+	changeDefault(hide_tabs, true);
 }
 
 LLSideTrayPanelContainer::LLSideTrayPanelContainer(const Params& p)
diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp
index 4cf1df165555ce3098f91a3c64902d5e3ce3e479..a853726deaae2a9c8453c23f0ea98dc7f0fcf43b 100644
--- a/indra/newview/llslurl.cpp
+++ b/indra/newview/llslurl.cpp
@@ -273,11 +273,11 @@ LLSLURL::LLSLURL(const std::string& slurl)
 			mRegion = LLURI::unescape(path_array[0].asString());
 			path_array.erase(0);
 			
-			// parse the x, y, z
-			if(path_array.size() >= 3)
+			// parse the x, y, and optionally z
+			if(path_array.size() >= 2)
 			{	
 			  
-			  mPosition = LLVector3(path_array);
+			  mPosition = LLVector3(path_array); // this construction handles LLSD without all components (values default to 0.f)
 			  if((F32(mPosition[VX]) < 0.f) || 
                              (mPosition[VX] > REGION_WIDTH_METERS) ||
 			     (F32(mPosition[VY]) < 0.f) || 
diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp
index d3e96f8dfb308ed9684768c5c599b22d3f931456..bbe573c546e9764579184c2d511943271b7989af 100644
--- a/indra/newview/llspeakbutton.cpp
+++ b/indra/newview/llspeakbutton.cpp
@@ -47,12 +47,10 @@ static LLDefaultChildRegistry::Register<LLSpeakButton> t1("talk_button");
 //////////////////////////////////////////////////////////////////////////
 
 LLSpeakButton::Params::Params()
- : speak_button("speak_button")
- , show_button("show_button")
- , monitor("monitor")
-{
-	// See widgets/talk_button.xml
-}
+:	speak_button("speak_button"),
+	show_button("show_button"),
+	monitor("monitor")
+{}
 
 LLSpeakButton::LLSpeakButton(const Params& p)
 : LLUICtrl(p)
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 1b8be7a5b23805be39b9b9e530ecbadf52055fe1..0a008858437b210df76862dc477e863ac48db98f 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -162,6 +162,8 @@ BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
 
 BOOL LLStatusBar::postBuild()
 {
+	LLControlVariablePtr mode_control = gSavedSettings.getControl("SessionSettingsFile");
+
 	gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3));
 
 	mTextTime = getChild<LLTextBox>("TimeText" );
@@ -233,9 +235,40 @@ BOOL LLStatusBar::postBuild()
 
 	mScriptOut = getChildView("scriptout");
 
+	LLUICtrl& mode_combo = getChildRef<LLUICtrl>("mode_combo");
+	mode_combo.setValue(gSavedSettings.getString("SessionSettingsFile"));
+	mode_combo.setCommitCallback(boost::bind(&LLStatusBar::onModeChange, this, getChild<LLUICtrl>("mode_combo")->getValue(), _2));
+
+
 	return TRUE;
 }
 
+void LLStatusBar::onModeChange(const LLSD& original_value, const LLSD& new_value)
+{
+	if (original_value.asString() != new_value.asString())
+	{
+		LLNotificationsUtil::add("ModeChange", LLSD(), LLSD(), boost::bind(&LLStatusBar::onModeChangeConfirm, this, original_value, new_value, _1, _2));
+	}
+}
+
+void LLStatusBar::onModeChangeConfirm(const LLSD& original_value, const LLSD& new_value, const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	switch (option)
+	{
+	case 0:
+		gSavedSettings.getControl("SessionSettingsFile")->set(new_value);
+		LLAppViewer::instance()->requestQuit();
+		break;
+	case 1:
+		// revert to original value
+		getChild<LLUICtrl>("mode_combo")->setValue(original_value);
+		break;
+	default:
+		break;
+	}
+}
+
 // Per-frame updates of visibility
 void LLStatusBar::refresh()
 {
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 4ea3183d1820a4c606bbadb45e78ff64923bdd66..6feeab393b2972717de79c7e10797fa8acfdc6a7 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -92,6 +92,8 @@ class LLStatusBar
 	void onMouseEnterVolume();
 	void onMouseEnterNearbyMedia();
 	void onClickScreen(S32 x, S32 y);
+	void onModeChange(const LLSD& original_value, const LLSD& new_value);
+	void onModeChangeConfirm(const LLSD& original_value, const LLSD& new_value, const LLSD& notification, const LLSD& response);
 
 	static void onClickMediaToggle(void* data);
 	static void onClickBalance(void* data);
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 9b417307fd574ee6eede09278f3c7301a4b19490..87b6304f9ddf250efdd5ac7a1a7b82f6290279f0 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -113,7 +113,7 @@ class LLTextureCacheWorker : public LLWorkerClass
 	~LLTextureCacheWorker()
 	{
 		llassert_always(!haveWork());
-		delete[] mReadData;
+		FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
 	}
 
 	// override this interface
@@ -176,7 +176,7 @@ class LLTextureCacheLocalFileWorker : public LLTextureCacheWorker
 
 bool LLTextureCacheLocalFileWorker::doRead()
 {
-	S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool());
+	S32 local_size = LLAPRFile::size(mFileName);
 
 	if (local_size > 0 && mFileName.size() > 4)
 	{
@@ -215,7 +215,7 @@ bool LLTextureCacheLocalFileWorker::doRead()
 			mDataSize = 0;
 			return true;
 		}
-		mReadData = new U8[mDataSize];
+		mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
 		mBytesRead = -1;
 		mBytesToRead = mDataSize;
 		setPriority(LLWorkerThread::PRIORITY_LOW | mPriority);
@@ -233,7 +233,7 @@ bool LLTextureCacheLocalFileWorker::doRead()
 // 						<< " Bytes: " << mDataSize << " Offset: " << mOffset
 // 						<< " / " << mDataSize << llendl;
 				mDataSize = 0; // failed
-				delete[] mReadData;
+				FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
 				mReadData = NULL;
 			}
 			return true;
@@ -248,9 +248,9 @@ bool LLTextureCacheLocalFileWorker::doRead()
 	{
 		mDataSize = local_size;
 	}
-	mReadData = new U8[mDataSize];
+	mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
 	
-	S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());	
+	S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize);
 
 	if (bytes_read != mDataSize)
 	{
@@ -258,7 +258,7 @@ bool LLTextureCacheLocalFileWorker::doRead()
 // 				<< " Bytes: " << mDataSize << " Offset: " << mOffset
 // 				<< " / " << mDataSize << llendl;
 		mDataSize = 0;
-		delete[] mReadData;
+		FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
 		mReadData = NULL;
 	}
 	else
@@ -331,7 +331,7 @@ bool LLTextureCacheRemoteWorker::doRead()
 		// Is it a JPEG2000 file? 
 		{
 			local_filename = filename + ".j2c";
-			local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
+			local_size = LLAPRFile::size(local_filename);
 			if (local_size > 0)
 			{
 				mImageFormat = IMG_CODEC_J2C;
@@ -341,7 +341,7 @@ bool LLTextureCacheRemoteWorker::doRead()
 		if (local_size == 0)
 		{
 			local_filename = filename + ".jpg";
-			local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
+			local_size = LLAPRFile::size(local_filename);
 			if (local_size > 0)
 			{
 				mImageFormat = IMG_CODEC_JPEG;
@@ -352,7 +352,7 @@ bool LLTextureCacheRemoteWorker::doRead()
 		if (local_size == 0)
 		{
 			local_filename = filename + ".tga";
-			local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
+			local_size = LLAPRFile::size(local_filename);
 			if (local_size > 0)
 			{
 				mImageFormat = IMG_CODEC_TGA;
@@ -377,16 +377,15 @@ bool LLTextureCacheRemoteWorker::doRead()
 			mDataSize = local_size;
 		}
 		// Allocate read buffer
-		mReadData = new U8[mDataSize];
-		S32 bytes_read = LLAPRFile::readEx(local_filename, 
-											 mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());
+		mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
+		S32 bytes_read = LLAPRFile::readEx(local_filename, mReadData, mOffset, mDataSize);
 		if (bytes_read != mDataSize)
 		{
  			llwarns << "Error reading file from local cache: " << local_filename
  					<< " Bytes: " << mDataSize << " Offset: " << mOffset
  					<< " / " << mDataSize << llendl;
 			mDataSize = 0;
-			delete[] mReadData;
+			FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
 			mReadData = NULL;
 		}
 		else
@@ -429,15 +428,14 @@ bool LLTextureCacheRemoteWorker::doRead()
 		S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset;
 		size = llmin(size, mDataSize);
 		// Allocate the read buffer
-		mReadData = new U8[size];
-		S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName, 
-											 mReadData, offset, size, mCache->getLocalAPRFilePool());
+		mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), size);
+		S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName, mReadData, offset, size);
 		if (bytes_read != size)
 		{
 			llwarns << "LLTextureCacheWorker: "  << mID
 					<< " incorrect number of bytes read from header: " << bytes_read
 					<< " / " << size << llendl;
-			delete[] mReadData;
+			FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
 			mReadData = NULL;
 			mDataSize = -1; // failed
 			done = true;
@@ -457,7 +455,7 @@ bool LLTextureCacheRemoteWorker::doRead()
 	if (!done && (mState == BODY))
 	{
 		std::string filename = mCache->getTextureFileName(mID);
-		S32 filesize = LLAPRFile::size(filename, mCache->getLocalAPRFilePool());
+		S32 filesize = LLAPRFile::size(filename);
 
 		if (filesize && (filesize + TEXTURE_CACHE_ENTRY_SIZE) > mOffset)
 		{
@@ -467,7 +465,7 @@ bool LLTextureCacheRemoteWorker::doRead()
 			S32 data_offset, file_size, file_offset;
 			
 			// Reserve the whole data buffer first
-			U8* data = new U8[mDataSize];
+			U8* data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
 
 			// Set the data file pointers taking the read offset into account. 2 cases:
 			if (mOffset < TEXTURE_CACHE_ENTRY_SIZE)
@@ -480,7 +478,7 @@ bool LLTextureCacheRemoteWorker::doRead()
 				// Copy the raw data we've been holding from the header cache into the new sized buffer
 				llassert_always(mReadData);
 				memcpy(data, mReadData, data_offset);
-				delete[] mReadData;
+				FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
 				mReadData = NULL;
 			}
 			else
@@ -499,14 +497,13 @@ bool LLTextureCacheRemoteWorker::doRead()
 			// Read the data at last
 			S32 bytes_read = LLAPRFile::readEx(filename, 
 											 mReadData + data_offset,
-											 file_offset, file_size,
-											 mCache->getLocalAPRFilePool());
+											 file_offset, file_size);
 			if (bytes_read != file_size)
 			{
 				llwarns << "LLTextureCacheWorker: "  << mID
 						<< " incorrect number of bytes read from body: " << bytes_read
 						<< " / " << file_size << llendl;
-				delete[] mReadData;
+				FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
 				mReadData = NULL;
 				mDataSize = -1; // failed
 				done = true;
@@ -598,16 +595,16 @@ bool LLTextureCacheRemoteWorker::doWrite()
 		{
 			// We need to write a full record in the header cache so, if the amount of data is smaller
 			// than a record, we need to transfer the data to a buffer padded with 0 and write that
-			U8* padBuffer = new U8[TEXTURE_CACHE_ENTRY_SIZE];
+			U8* padBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_CACHE_ENTRY_SIZE);
 			memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE);		// Init with zeros
 			memcpy(padBuffer, mWriteData, mDataSize);			// Copy the write buffer
-			bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool());
-			delete [] padBuffer;
+			bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size);
+			FREE_MEM(LLImageBase::getPrivatePool(), padBuffer);
 		}
 		else
 		{
 			// Write the header record (== first TEXTURE_CACHE_ENTRY_SIZE bytes of the raw file) in the header file
-			bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size, mCache->getLocalAPRFilePool());
+			bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size);
 		}
 
 		if (bytes_written <= 0)
@@ -642,8 +639,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
 // 			llinfos << "Writing Body: " << filename << " Bytes: " << file_offset+file_size << llendl;
 			S32 bytes_written = LLAPRFile::writeEx(	filename, 
 													mWriteData + TEXTURE_CACHE_ENTRY_SIZE,
-													0, file_size,
-													mCache->getLocalAPRFilePool());
+													0, file_size);
 			if (bytes_written <= 0)
 			{
 				llwarns << "LLTextureCacheWorker: "  << mID
@@ -698,7 +694,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)
 			}
 			else
 			{
-				delete[] mReadData;
+				FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
 				mReadData = NULL;
 			}
 		}
@@ -740,9 +736,6 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted)
 
 LLTextureCache::LLTextureCache(bool threaded)
 	: LLWorkerThread("TextureCache", threaded),
-	  mWorkersMutex(NULL),
-	  mHeaderMutex(NULL),
-	  mListMutex(NULL),
 	  mHeaderAPRFile(NULL),
 	  mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called.
 	  mTexturesSizeTotal(0),
@@ -846,7 +839,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
 	// Is it a JPEG2000 file? 
 	{
 		local_filename = filename + ".j2c";
-		local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
+		local_size = LLAPRFile::size(local_filename);
 		if (local_size > 0)
 		{
 			return TRUE ;
@@ -856,7 +849,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
 	// If not, is it a jpeg file?		
 	{
 		local_filename = filename + ".jpg";
-		local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
+		local_size = LLAPRFile::size(local_filename);
 		if (local_size > 0)
 		{
 			return TRUE ;
@@ -866,7 +859,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
 	// Hmm... What about a targa file? (used for UI texture mostly)		
 	{
 		local_filename = filename + ".tga";
-		local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
+		local_size = LLAPRFile::size(local_filename);
 		if (local_size > 0)
 		{
 			return TRUE ;
@@ -912,10 +905,10 @@ void LLTextureCache::purgeCache(ELLPath location)
 		if(LLFile::isdir(mTexturesDirName))
 		{
 			std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename);
-			LLAPRFile::remove(file_name, getLocalAPRFilePool());
+			LLAPRFile::remove(file_name);
 
 			file_name = gDirUtilp->getExpandedFilename(location, cache_filename);
-			LLAPRFile::remove(file_name, getLocalAPRFilePool());
+			LLAPRFile::remove(file_name);
 
 			purgeAllTextures(true);
 		}
@@ -991,7 +984,9 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset)
 {
 	llassert_always(mHeaderAPRFile == NULL);
 	apr_int32_t flags = readonly ? APR_READ|APR_BINARY : APR_READ|APR_WRITE|APR_BINARY;
-	mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, getLocalAPRFilePool());
+	// All code calling openHeaderEntriesFile, immediately calls closeHeaderEntriesFile,
+	// so this file is very short-lived.
+	mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags);
 	if(offset > 0)
 	{
 		mHeaderAPRFile->seek(APR_SET, offset);
@@ -1014,10 +1009,9 @@ void LLTextureCache::readEntriesHeader()
 {
 	// mHeaderEntriesInfo initializes to default values so safe not to read it
 	llassert_always(mHeaderAPRFile == NULL);
-	if (LLAPRFile::isExist(mHeaderEntriesFileName, getLocalAPRFilePool()))
+	if (LLAPRFile::isExist(mHeaderEntriesFileName))
 	{
-		LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
-						  getLocalAPRFilePool());
+		LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
 	}
 	else //create an empty entries header.
 	{
@@ -1032,8 +1026,7 @@ void LLTextureCache::writeEntriesHeader()
 	llassert_always(mHeaderAPRFile == NULL);
 	if (!mReadOnly)
 	{
-		LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
-						   getLocalAPRFilePool());
+		LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
 	}
 }
 
@@ -1622,7 +1615,7 @@ void LLTextureCache::purgeTextures(bool validate)
 			if (uuididx == validate_idx)
 			{
  				LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL;
-				S32 bodysize = LLAPRFile::size(filename, getLocalAPRFilePool());
+				S32 bodysize = LLAPRFile::size(filename);
 				if (bodysize != entries[idx].mBodySize)
 				{
 					LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize
@@ -1857,7 +1850,7 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)
 		mTexturesSizeMap.erase(id);
 	}
 	mHeaderIDMap.erase(id);
-	LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool());		
+	LLAPRFile::remove(getTextureFileName(id));		
 }
 
 //called after mHeaderMutex is locked.
@@ -1869,7 +1862,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
 	{
 		if (entry.mBodySize == 0)	// Always attempt to remove when mBodySize > 0.
 		{
-		  if (LLAPRFile::isExist(filename, getLocalAPRFilePool()))		// Sanity check. Shouldn't exist when body size is 0.
+		  if (LLAPRFile::isExist(filename))		// Sanity check. Shouldn't exist when body size is 0.
 		  {
 			  LL_WARNS("TextureCache") << "Entry has body size of zero but file " << filename << " exists. Deleting this file, too." << LL_ENDL;
 		  }
@@ -1890,7 +1883,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
 
 	if (file_maybe_exists)
 	{
-		LLAPRFile::remove(filename, getLocalAPRFilePool());		
+		LLAPRFile::remove(filename);
 	}
 }
 
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 64e3a2658c38565f1b8f32253fdb50621ed90773..79f5ba58358329f1231efdfd732751c4a5e4bf59 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -142,9 +142,6 @@ class LLTextureCache : public LLWorkerThread
 	std::string getTextureFileName(const LLUUID& id);
 	void addCompleted(Responder* responder, bool success);
 	
-protected:
-	//void setFileAPRPool(apr_pool_t* pool) { mFileAPRPool = pool ; }
-
 private:
 	void setDirNames(ELLPath location);
 	void readHeaderCache();
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index fdfbee400e84c65f4e76d471995308d355865d6f..b1312d641f64fe848d7e136be829db43576f43b0 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -92,11 +92,7 @@ class LLTextureCtrl
 			multiselect_text("multiselect_text"),
 			caption_text("caption_text"),
 			border("border")
-		{
-			name = "texture picker";
-			mouse_opaque(true);
-			follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
-		}
+		{}
 	};
 protected:
 	LLTextureCtrl(const Params&);
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 18c3a3b87ddf6ef917c86fc2107d112e46bbf026..e9be45ffd0cfef841ddf5d2c5232a6cae60226a3 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -674,7 +674,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mRetryAttempt(0),
 	  mActiveCount(0),
 	  mGetStatus(0),
-	  mWorkMutex(NULL),
 	  mFirstPacket(0),
 	  mLastPacket(-1),
 	  mTotalPackets(0),
@@ -817,7 +816,7 @@ void LLTextureFetchWorker::setImagePriority(F32 priority)
 
 void LLTextureFetchWorker::resetFormattedData()
 {
-	delete[] mBuffer;
+	FREE_MEM(LLImageBase::getPrivatePool(), mBuffer);
 	mBuffer = NULL;
 	mBufferSize = 0;
 	if (mFormattedImage.notNull())
@@ -888,7 +887,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		mSentRequest = UNSENT;
 		mDecoded  = FALSE;
 		mWritten  = FALSE;
-		delete[] mBuffer;
+		FREE_MEM(LLImageBase::getPrivatePool(), mBuffer);
 		mBuffer = NULL;
 		mBufferSize = 0;
 		mHaveAllData = FALSE;
@@ -1284,7 +1283,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			llassert_always(mBufferSize == cur_size + mRequestedSize);
 			if(!mBufferSize)//no data received.
 			{
-				delete[] mBuffer; 
+				FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); 
 				mBuffer = NULL;
 
 				//abort.
@@ -1312,7 +1311,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded.
 			}
 			
-			U8* buffer = new U8[mBufferSize];
+			U8* buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mBufferSize);
 			if (cur_size > 0)
 			{
 				memcpy(buffer, mFormattedImage->getData(), cur_size);
@@ -1321,7 +1320,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			// NOTE: setData releases current data and owns new data (buffer)
 			mFormattedImage->setData(buffer, mBufferSize);
 			// delete temp data
-			delete[] mBuffer; // Note: not 'buffer' (assigned in setData())
+			FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); // Note: not 'buffer' (assigned in setData())
 			mBuffer = NULL;
 			mBufferSize = 0;
 			mLoadedDiscard = mRequestedDiscard;
@@ -1618,7 +1617,7 @@ bool LLTextureFetchWorker::processSimulatorPackets()
 			if (buffer_size > cur_size)
 			{
 				/// We have new data
-				U8* buffer = new U8[buffer_size];
+				U8* buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), buffer_size);
 				S32 offset = 0;
 				if (cur_size > 0 && mFirstPacket > 0)
 				{
@@ -1670,7 +1669,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
 		if (data_size > 0)
 		{
 			// *TODO: set the formatted image data here directly to avoid the copy
-			mBuffer = new U8[data_size];
+			mBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size);
 			buffer->readAfter(channels.in(), NULL, mBuffer, data_size);
 			mBufferSize += data_size;
 			if (data_size < mRequestedSize && mRequestedDiscard == 0)
@@ -1816,8 +1815,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
 	  mDebugPause(FALSE),
 	  mPacketCount(0),
 	  mBadPacketCount(0),
-	  mQueueMutex(getAPRPool()),
-	  mNetworkQueueMutex(getAPRPool()),
 	  mTextureCache(cache),
 	  mImageDecodeThread(imagedecodethread),
 	  mTextureBandwidth(0),
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 0115115a230fde1d5a2c5030a8649dd37af0fa02..6547154bc481e879817ab4b02adfa2b45161a6e2 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -94,7 +94,7 @@ class LLTextureBar : public LLView
 		Params()
 		:	texture_view("texture_view")
 		{
-			mouse_opaque(false);
+			changeDefault(mouse_opaque, false);
 		}
 	};
 	LLTextureBar(const Params& p)
@@ -387,7 +387,7 @@ class LLAvatarTexBar : public LLView
 		:	texture_view("texture_view")
 		{
 			S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
-			rect(LLRect(0,0,100,line_height * 4));
+			changeDefault(rect, LLRect(0,0,100,line_height * 4));
 		}
 	};
 
@@ -486,7 +486,7 @@ class LLGLTexMemBar : public LLView
 		:	texture_view("texture_view")
 		{
 			S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
-			rect(LLRect(0,0,100,line_height * 4));
+			changeDefault(rect, LLRect(0,0,100,line_height * 4));
 		}
 	};
 
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 14f17e8917621aebab511ee5e7883cbe555cbb90..3e5ce427a80dfbe2551c8a51593ace4ad7fe85a8 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1652,6 +1652,13 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
 		return ACCEPT_NO;
 	}
 
+	const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
+	if(gInventory.isObjectDescendentOf(item->getUUID(), outbox_id))
+	{
+		return ACCEPT_NO;
+	}
+
+
 	if( drop )
 	{
 		if(mSource == SOURCE_LIBRARY)
@@ -2055,6 +2062,12 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory(
 			return ACCEPT_NO;
 		}
 
+		const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
+		if(gInventory.isObjectDescendentOf(category->getUUID(), outbox_id))
+		{
+			return ACCEPT_NO;
+		}
+
 		if(drop)
 		{
 			BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE );
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 39053fe9e4b2889545f93311b363666c6add65b2..6142ee0dd661edc04998e9769d670c03d8d1c402 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -202,6 +202,7 @@ void display_stats()
 		gMemoryAllocated = LLMemory::getCurrentRSS();
 		U32 memory = (U32)(gMemoryAllocated / (1024*1024));
 		llinfos << llformat("MEMORY: %d MB", memory) << llendl;
+		LLMemory::logMemoryInfo() ;
 		gRecentMemoryTime.reset();
 	}
 }
@@ -692,7 +693,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 				glh::matrix4f mod = glh_get_current_modelview();
 				glViewport(0,0,512,512);
 				LLVOAvatar::updateFreezeCounter() ;
-				LLVOAvatar::updateImpostors();
+
+				if(!LLPipeline::sMemAllocationThrottled)
+				{		
+					LLVOAvatar::updateImpostors();
+				}
 
 				glh_set_current_projection(proj);
 				glh_set_current_modelview(mod);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index fecc6d91bd81855e89f1f10361067ce19689ed0a..4af5fdd9f36a51eefaca02b8a7dca814808afb74 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -33,6 +33,7 @@
 
 #include "llcompilequeue.h"
 #include "llcallfloater.h"
+#include "llfasttimerview.h"
 #include "llfloaterabout.h"
 #include "llfloateranimpreview.h"
 #include "llfloaterauction.h"
@@ -159,6 +160,7 @@ void LLViewerFloaterReg::registerFloaters()
 	// *NOTE: Please keep these alphabetized for easier merges
 
 	LLFloaterAboutUtil::registerFloater();
+	LLFloaterReg::add("fast_timers", "floater_fast_timers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFastTimerView>);
 	LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>);
 	LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
 	LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>);
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index fbf11f20dbb956213c5f8d72a0766106b70df2e7..f6e840adcd803988264a97bd9c9c8f2b29b1ef81 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -51,9 +51,6 @@
 #define RY_I	5
 #define RZ_I	3
 
-// minimum time after setting away state before coming back
-const F32 MIN_AFK_TIME = 2.f;
-
 F32  LLViewerJoystick::sLastDelta[] = {0,0,0,0,0,0,0};
 F32  LLViewerJoystick::sDelta[] = {0,0,0,0,0,0,0};
 
@@ -551,7 +548,7 @@ void LLViewerJoystick::moveObjects(bool reset)
 	if (!is_zero)
 	{
 		// Clear AFK state if moved beyond the deadzone
-		if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
+		if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
 		{
 			gAgent.clearAFK();
 		}
@@ -725,7 +722,7 @@ void LLViewerJoystick::moveAvatar(bool reset)
 	if (!is_zero)
 	{
 		// Clear AFK state if moved beyond the deadzone
-		if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
+		if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
 		{
 			gAgent.clearAFK();
 		}
@@ -941,7 +938,7 @@ void LLViewerJoystick::moveFlycam(bool reset)
 	}
 	
 	// Clear AFK state if moved beyond the deadzone
-	if (!is_zero && gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
+	if (!is_zero && gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
 	{
 		gAgent.clearAFK();
 	}
@@ -1001,7 +998,7 @@ bool LLViewerJoystick::toggleFlycam()
 		gAgentCamera.changeCameraToDefault();
 	}
 
-	if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
+	if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
 	{
 		gAgent.clearAFK();
 	}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 384f7cd61d32423c005156e7f87b54db3fc6a332..13dbc5e38637bd3962224a0c03470c02909b651e 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1366,6 +1366,10 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom
 }
 
 
+// This is defined in two files but I don't want to create a dependence between this and llsidepanelinventory
+// just to be able to temporarily disable the outbox.
+#define ENABLE_INVENTORY_DISPLAY_OUTBOX		0	// keep in sync with ENABLE_MERCHANT_OUTBOX_PANEL, ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
+
 class LLInventoryUserStatusResponder : public LLHTTPClient::Responder
 {
 public:
@@ -1378,8 +1382,18 @@ class LLInventoryUserStatusResponder : public LLHTTPClient::Responder
 	{
 		if (isGoodStatus(status))
 		{
+			std::string merchantStatus = content[gAgent.getID().getString()].asString();
+			llinfos << "Marketplace merchant status: " << merchantStatus << llendl;
+
+			// Save the merchant status before turning on the display
+			gSavedSettings.setString("InventoryMarketplaceUserStatus", merchantStatus);
+
 			// Complete success
 			gSavedSettings.setBOOL("InventoryDisplayInbox", true);
+
+#if ENABLE_INVENTORY_DISPLAY_OUTBOX
+			gSavedSettings.setBOOL("InventoryDisplayOutbox", true);
+#endif
 		}
 		else if (status == 401)
 		{
@@ -1394,6 +1408,39 @@ class LLInventoryUserStatusResponder : public LLHTTPClient::Responder
 	}
 };
 
+
+void doOnetimeEarlyHTTPRequests()
+{
+	std::string url = "https://marketplace.secondlife.com/";
+
+	if (!LLGridManager::getInstance()->isInProductionGrid())
+	{
+		std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
+		url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str());
+
+		// TEMP for Jim's pdp
+		//url = "http://pdp24.lindenlab.com:3000/";
+	}
+	
+	url += "api/1/users/";
+	url += gAgent.getID().getString();
+	url += "/user_status";
+
+	llinfos << "http get: " << url << llendl;
+	LLHTTPClient::get(url, new LLInventoryUserStatusResponder(), LLViewerMedia::getHeaders());
+}
+
+
+LLSD LLViewerMedia::getHeaders()
+{
+	LLSD headers = LLSD::emptyMap();
+	headers["Accept"] = "*/*";
+	headers["Cookie"] = sOpenIDCookie;
+	headers["User-Agent"] = getCurrentUserAgent();
+
+	return headers;
+}
+
 /////////////////////////////////////////////////////////////////////////////////////////
 // static
 void LLViewerMedia::setOpenIDCookie()
@@ -1441,24 +1488,7 @@ void LLViewerMedia::setOpenIDCookie()
 			new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
 			headers);
 
-		std::string url = "https://marketplace.secondlife.com/";
-
-		if (!LLGridManager::getInstance()->isInProductionGrid())
-		{
-			std::string gridLabel = LLGridManager::getInstance()->getGridLabel();
-			url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str());
-		}
-	
-		url += "api/1/users/";
-		url += gAgent.getID().getString();
-		url += "/user_status";
-
-		headers = LLSD::emptyMap();
-		headers["Accept"] = "*/*";
-		headers["Cookie"] = sOpenIDCookie;
-		headers["User-Agent"] = getCurrentUserAgent();
-
-		LLHTTPClient::get(url, new LLInventoryUserStatusResponder(), headers);
+		doOnetimeEarlyHTTPRequests();
 	}
 }
 
@@ -1776,6 +1806,7 @@ void LLViewerMediaImpl::createMediaSource()
 			LL_WARNS("Media") << "Failed to initialize media for mime type " << mMimeType << LL_ENDL;
 		}
 	}
+
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -1880,7 +1911,10 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 			// collect 'javascript enabled' setting from prefs and send to embedded browser
 			bool javascript_enabled = gSavedSettings.getBOOL( "BrowserJavascriptEnabled" );
 			media_source->setJavascriptEnabled( javascript_enabled );
-			
+		
+			bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");
+			media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled );
+
 			media_source->setTarget(target);
 			
 			const std::string plugin_dir = gDirUtilp->getLLPluginDir();
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index aeac6ba29aee7f8aa7c202d703357fd6936a502a..0b69b8f0c1c0664fa5af23a1c7c9af07b0f4a13b 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -162,6 +162,8 @@ class LLViewerMedia
 	static LLPluginClassMedia* getSpareBrowserMediaSource();
 
 	static void setOnlyAudibleMediaTextureID(const LLUUID& texture_id);
+
+	static LLSD getHeaders();
 	
 private:
 	static void setOpenIDCookie();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 26599f557e760023213f2941b059cffd2eb38036..754731b290dfd409cc3182b4600c3d0307fcdc17 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -523,7 +523,7 @@ class LLAdvancedToggleConsole : public view_listener_t
 		}
 		else if ("fast timers" == console_type)
 		{
-			toggle_visibility( (void*)gDebugView->mFastTimerView );
+			LLFloaterReg::toggleInstance("fast_timers");
 		}
 		else if ("scene view" == console_type)
 		{
@@ -563,7 +563,7 @@ class LLAdvancedCheckConsole : public view_listener_t
 		}
 		else if ("fast timers" == console_type)
 		{
-			new_value = get_visibility( (void*)gDebugView->mFastTimerView );
+			new_value = LLFloaterReg::instanceVisible("fast_timers");
 		}
 		else if ("scene view" == console_type)
 		{
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index b9293b3b3105f8c9a1ebaef7e2752b97df21728a..8139f7deda420d6d63ee616d306b634a5164409c 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -149,7 +149,7 @@ void LLFilePickerThread::run()
 //static
 void LLFilePickerThread::initClass()
 {
-	sMutex = new LLMutex(NULL);
+	sMutex = new LLMutex();
 }
 
 //static
@@ -816,8 +816,7 @@ LLUUID upload_new_resource(
 		uuid = tid.makeAssetID(gAgent.getSecureSessionID());
 		// copy this file into the vfs for upload
 		S32 file_size;
-		LLAPRFile infile ;
-		infile.open(filename, LL_APR_RB, NULL, &file_size);
+		LLAPRFile infile(filename, LL_APR_RB, &file_size);
 		if (infile.getFileHandle())
 		{
 			LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 68745d5aeb95cc521360b7e6b8f85a5891cf44c5..6435904feed196fcf3b30f98e38bb95f9f7d878c 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1299,29 +1299,12 @@ bool highlight_offered_object(const LLUUID& obj_id)
 
 void inventory_offer_mute_callback(const LLUUID& blocked_id,
 								   const std::string& full_name,
-								   bool is_group,
-								   boost::shared_ptr<LLNotificationResponderInterface> offer_ptr)
+								   bool is_group)
 {
-	LLOfferInfo* offer =  dynamic_cast<LLOfferInfo*>(offer_ptr.get());
-	
-	std::string from_name = full_name;
-	LLMute::EType type;
-	if (is_group)
-	{
-		type = LLMute::GROUP;
-	}
-	else if(offer && offer->mFromObject)
-	{
-		//we have to block object by name because blocked_id is an id of owner
-		type = LLMute::BY_NAME;
-	}
-	else
-	{
-		type = LLMute::AGENT;
-	}
+	// *NOTE: blocks owner if the offer came from an object
+	LLMute::EType mute_type = is_group ? LLMute::GROUP : LLMute::AGENT;
 
-	// id should be null for BY_NAME mute, see  LLMuteList::add for details  
-	LLMute mute(type == LLMute::BY_NAME ? LLUUID::null : blocked_id, from_name, type);
+	LLMute mute(blocked_id, full_name, mute_type);
 	if (LLMuteList::getInstance()->add(mute))
 	{
 		LLPanelBlockedList::showPanelAndSelect(blocked_id);
@@ -1335,6 +1318,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
 		bool matches(const LLNotificationPtr notification) const
 		{
 			if(notification->getName() == "ObjectGiveItem" 
+				|| notification->getName() == "OwnObjectGiveItem"
 				|| notification->getName() == "UserGiveItem")
 			{
 				return (notification->getPayload()["from_id"].asUUID() == blocked_id);
@@ -1495,7 +1479,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 		llassert(notification_ptr != NULL);
 		if (notification_ptr != NULL)
 		{
-			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
+			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
 		}
 	}
 
@@ -1640,7 +1624,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 		llassert(notification_ptr != NULL);
 		if (notification_ptr != NULL)
 		{
-			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
+			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
 		}
 	}
 	
@@ -1818,6 +1802,7 @@ void LLOfferInfo::initRespondFunctionMap()
 	if(mRespondFunctions.empty())
 	{
 		mRespondFunctions["ObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
+		mRespondFunctions["OwnObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
 		mRespondFunctions["UserGiveItem"] = boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2);
 	}
 }
@@ -1905,7 +1890,7 @@ void inventory_offer_handler(LLOfferInfo* info)
 	std::string verb = "select?name=" + LLURI::escape(msg);
 	args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
 
-	LLNotification::Params p("ObjectGiveItem");
+	LLNotification::Params p;
 
 	// Object -> Agent Inventory Offer
 	if (info->mFromObject)
@@ -1915,7 +1900,10 @@ void inventory_offer_handler(LLOfferInfo* info)
 		// Note: sets inventory_task_offer_callback as the callback
 		p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
 		info->mPersist = true;
-		p.name = "ObjectGiveItem";
+
+		// Offers from your own objects need a special notification template.
+		p.name = info->mFromID == gAgentID ? "OwnObjectGiveItem" : "ObjectGiveItem";
+
 		// Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
 	    LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE);
 	}
@@ -2594,8 +2582,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
 				info->mType = (LLAssetType::EType) bucketp->asset_type;
 				info->mObjectID = bucketp->object_id;
+				info->mFromObject = FALSE;
 			}
-			else
+			else // IM_TASK_INVENTORY_OFFERED
 			{
 				if (sizeof(S8) != binary_bucket_size)
 				{
@@ -2605,6 +2594,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				}
 				info->mType = (LLAssetType::EType) binary_bucket[0];
 				info->mObjectID = LLUUID::null;
+				info->mFromObject = TRUE;
 			}
 
 			info->mIM = dialog;
@@ -2613,14 +2603,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			info->mTransactionID = session_id;
 			info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
 
-			if (dialog == IM_TASK_INVENTORY_OFFERED)
-			{
-				info->mFromObject = TRUE;
-			}
-			else
-			{
-				info->mFromObject = FALSE;
-			}
 			info->mFromName = name;
 			info->mDesc = message;
 			info->mHost = msg->getSender();
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
old mode 100644
new mode 100755
index cd71b6d42a704a01b8ebb3cd077f5bd4dc8caa47..db7bb002c10e78109495bda635b1bff62afd2408
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -140,6 +140,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
 			if (!gAgentAvatarp)
 			{
 				gAgentAvatarp = new LLVOAvatarSelf(id, pcode, regionp);
+				gAgentAvatarp->initInstance();
 			}
 			else 
 			{
@@ -149,9 +150,10 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
 		}
 		else
 		{
-			res = new LLVOAvatar(id, pcode, regionp); 
+			LLVOAvatar *avatar = new LLVOAvatar(id, pcode, regionp); 
+			avatar->initInstance();
+			res = avatar;
 		}
-		static_cast<LLVOAvatar*>(res)->initInstance();
 		break;
 	}
 	case LL_PCODE_LEGACY_GRASS:
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index db5684665b55b353e7e66ce707ffefbe05cdb11c..153a91e7d872e97f9b3faabf5578b6bb01b94d6a 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1254,7 +1254,8 @@ void LLViewerObjectList::removeDrawable(LLDrawable* drawablep)
 BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
 {
 	// Don't ever kill gAgentAvatarp, just force it to the agent's region
-	if (objectp == gAgentAvatarp)
+	// unless region is NULL which is assumed to mean you are logging out.
+	if ((objectp == gAgentAvatarp) && gAgent.getRegion())
 	{
 		objectp->setRegion(gAgent.getRegion());
 		return FALSE;
@@ -1277,6 +1278,7 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
 
 		return TRUE;
 	}
+
 	return FALSE;
 }
 
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index dfa35edef46b505135f8f792cb79a23f6722b992..90fbc41daa8f38477b50ff77981ac8277045eb60 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -485,6 +485,12 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
 {
 	switch(event)
 	{
+		case MEDIA_EVENT_DEBUG_MESSAGE:
+		{
+			// LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_DEBUG_MESSAGE " << LL_ENDL;
+		};
+		break;
+
 		case MEDIA_EVENT_CONTENT_UPDATED:
 		{
 			// LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL;
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index 0861dfcb20bda7d767ec9d7c5c4a5dfeb0bf9861..fb428d0dc14ec1624e91d53998cbead3292432fa 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -36,12 +36,7 @@ class LLViewerTextEditor : public LLTextEditor
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLTextEditor::Params>
-	{
-		Params()
-		{
-			name = "text_editor";
-		}
-	};
+	{};
 
 protected:
 	LLViewerTextEditor(const Params&);
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 70509f9a9f409dbb59a0b848d6ef18e3b7f4ef89..280337be0f73086905810f72437f5abd62039613 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -3109,9 +3109,16 @@ void LLViewerLODTexture::processTextureStats()
 	{
 		mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel) ;
 	}
+	else if(LLPipeline::sMemAllocationThrottled)//release memory of large textures by decrease their resolutions.
+	{
+		if(scaleDown())
+		{
+			mDesiredDiscardLevel = mCachedRawDiscardLevel ;
+		}
+	}
 }
 
-void LLViewerLODTexture::scaleDown()
+bool LLViewerLODTexture::scaleDown()
 {
 	if(hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel())
 	{		
@@ -3122,7 +3129,10 @@ void LLViewerLODTexture::scaleDown()
 		{
 			tester->setStablizingTime() ;
 		}
+
+		return true ;
 	}
+	return false ;
 }
 //----------------------------------------------------------------------------------------------
 //end of LLViewerLODTexture
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index de528927b46fbe56a243fd07aafb4db7c1756907..a4a5ae0a5b7364a3ecfda4cd299812a5ba597a75 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -597,7 +597,7 @@ class LLViewerLODTexture : public LLViewerFetchedTexture
 
 private:
 	void init(bool firstinit) ;
-	void scaleDown() ;		
+	bool scaleDown() ;		
 
 private:
 	F32 mDiscardVirtualSize;		// Virtual size used to calculate desired discard	
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 8d4f9b346f1a019da2795f89d4850844ad7db742..a7f4209e696ac5e84886979a11fc886befa27712 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -240,8 +240,6 @@ BOOL				gDisplayBadge = FALSE;
 static const U8 NO_FACE = 255;
 BOOL gQuietSnapshot = FALSE;
 
-const F32 MIN_AFK_TIME = 2.f; // minimum time after setting away state before coming back
-
 static const F32 MIN_DISPLAY_SCALE = 0.75f;
 
 std::string	LLViewerWindow::sSnapshotBaseName;
@@ -662,6 +660,17 @@ class LLDebugText
 			addText(xpos, ypos, llformat("%d %d %d %d", color[0], color[1], color[2], color[3]));
 			ypos += y_inc;
 		}
+
+		if (gSavedSettings.getBOOL("DebugShowPrivateMem"))
+		{
+			LLPrivateMemoryPoolManager::getInstance()->updateStatistics() ;
+			addText(xpos, ypos, llformat("Total Reserved(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalReservedSize / 1024));
+			ypos += y_inc;
+
+			addText(xpos, ypos, llformat("Total Allocated(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalAllocatedSize / 1024));
+			ypos += y_inc;
+		}
+
 		// only display these messages if we are actually rendering beacons at this moment
 		if (LLPipeline::getRenderBeacons(NULL) && LLFloaterReg::instanceVisible("beacons"))
 		{
@@ -1203,7 +1212,7 @@ void LLViewerWindow::handleMouseMove(LLWindow *window,  LLCoordGL pos, MASK mask
 
 	mWindow->showCursorFromMouseMove();
 
-	if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
+	if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
 	{
 		gAgent.clearAFK();
 	}
@@ -1291,7 +1300,7 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key,  MASK mask, BOOL repeated)
 	// Let the voice chat code check for its PTT key.  Note that this never affects event processing.
 	LLVoiceClient::getInstance()->keyDown(key, mask);
 	
-	if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
+	if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
 	{
 		gAgent.clearAFK();
 	}
@@ -1341,6 +1350,7 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
 	{
 		mActive = FALSE;
 				
+		// if the user has chosen to go Away automatically after some time, then go Away when minimizing
 		if (gSavedSettings.getS32("AFKTimeout"))
 		{
 			gAgent.setAFK();
@@ -1630,6 +1640,7 @@ LLViewerWindow::LLViewerWindow(
 	}
 	LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
 	LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
+	gGL.init() ;
 
 	if (LLFeatureManager::getInstance()->isSafe()
 		|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
@@ -2026,15 +2037,17 @@ void LLViewerWindow::shutdownGL()
 	llinfos << "All textures and llimagegl images are destroyed!" << llendl ;
 
 	llinfos << "Cleaning up select manager" << llendl;
-	LLSelectMgr::getInstance()->cleanup();
-
-	LLVertexBuffer::cleanupClass();
+	LLSelectMgr::getInstance()->cleanup();	
 
 	llinfos << "Stopping GL during shutdown" << llendl;
 	stopGL(FALSE);
 	stop_glerror();
 
 	gGL.shutdown();
+
+	LLVertexBuffer::cleanupClass();
+
+	llinfos << "LLVertexBuffer cleaned." << llendl ;
 }
 
 // shutdownViews() and shutdownGL() need to be called first
@@ -4148,6 +4161,19 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 	{
 		return FALSE;
 	}
+	//check if there is enough memory for the snapshot image
+	if(LLPipeline::sMemAllocationThrottled)
+	{
+		return FALSE ; //snapshot taking is disabled due to memory restriction.
+	}
+	if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K
+	{
+		if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3))
+		{
+			llwarns << "No enough memory to take the snapshot with size (w : h): " << image_width << " : " << image_height << llendl ;
+			return FALSE ; //there is no enough memory for taking this snapshot.
+		}
+	}
 
 	// PRE SNAPSHOT
 	gDisplaySwapBuffers = FALSE;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 79468462221f8ba3ef4507ba44393d9bb1e6d559..7c6a815defc53facb45602cf4473b5a1a366556c 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -7506,8 +7506,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
 // static
 void LLVOAvatar::dumpArchetypeXML( void* )
 {
-	LLAPRFile outfile;
-	outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"new archetype.xml"), LL_APR_WB );
+	LLAPRFile outfile(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER, "new archetype.xml"), LL_APR_WB);
 	apr_file_t* file = outfile.getFileHandle() ;
 	if (!file)
 	{
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 6d457434b5f1cabedc4aa973e9e7d6ac198c2374..baf01ec06617478425e448ac2ed3acf92c4c5475 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -268,7 +268,6 @@ LLVOCache::LLVOCache():
 	mCacheSize(1)
 {
 	mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled");
-	mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
 }
 
 LLVOCache::~LLVOCache()
@@ -278,7 +277,6 @@ LLVOCache::~LLVOCache()
 		writeCacheHeader();
 		clearCacheInMemory();
 	}
-	delete mLocalAPRFilePoolp;
 }
 
 void LLVOCache::setDirNames(ELLPath location)
@@ -435,7 +433,7 @@ void LLVOCache::removeFromCache(HeaderEntryInfo* entry)
 
 	std::string filename;
 	getObjectCacheFilename(entry->mHandle, filename);
-	LLAPRFile::remove(filename, mLocalAPRFilePoolp);
+	LLAPRFile::remove(filename);
 	entry->mTime = INVALID_TIME ;
 	updateEntry(entry) ; //update the head file.
 }
@@ -452,9 +450,9 @@ void LLVOCache::readCacheHeader()
 	clearCacheInMemory();	
 
 	bool success = true ;
-	if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
+	if (LLAPRFile::isExist(mHeaderFileName))
 	{
-		LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);		
+		LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY);		
 		
 		//read the meta element
 		success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
@@ -539,7 +537,7 @@ void LLVOCache::writeCacheHeader()
 
 	bool success = true ;
 	{
-		LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+		LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY);
 
 		//write the meta element
 		success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
@@ -577,7 +575,7 @@ void LLVOCache::writeCacheHeader()
 
 BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)
 {
-	LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+	LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY);
 	apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
 
 	return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
@@ -603,7 +601,7 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
 	{
 		std::string filename;
 		getObjectCacheFilename(handle, filename);
-		LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
+		LLAPRFile apr_file(filename, APR_READ|APR_BINARY);
 	
 		LLUUID cache_id ;
 		success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ;
@@ -726,7 +724,7 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
 	{
 		std::string filename;
 		getObjectCacheFilename(handle, filename);
-		LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+		LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY);
 	
 		success = check_write(&apr_file, (void*)id.mData, UUID_BYTES) ;
 
@@ -751,4 +749,3 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
 
 	return ;
 }
-
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 14e3b4c79355a94b23827c9b29be224c13a085e7..13651c67799c1591ef01c9f36cc61932ba76bad5 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -142,7 +142,6 @@ class LLVOCache
 	U32                  mNumEntries;
 	std::string          mHeaderFileName ;
 	std::string          mObjectCacheDirName;
-	LLVolatileAPRPool*   mLocalAPRFilePoolp ; 	
 	header_entry_queue_t mHeaderEntryQueue;
 	handle_entry_map_t   mHandleEntryMap;	
 
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 0db0010688369ee1f21417d407b42888b99148c1..90a05cd9e5bc9a4ab459424821a34a4b9ad025c4 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -942,7 +942,7 @@ void LLVivoxVoiceClient::stateMachine()
 
 				if(!mSocket)
 				{
-					mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);	
+					mSocket = LLSocket::create(LLSocket::STREAM_TCP);	
 				}
 				
 				mConnected = mSocket->blockingConnect(mDaemonHost);
@@ -4498,17 +4498,25 @@ bool LLVivoxVoiceClient::parcelVoiceInfoReceived(state requesting_state)
 
 bool LLVivoxVoiceClient::requestParcelVoiceInfo()
 {
-	LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL;
-
-	// grab the cap for parcel voice info from the region.  
 	LLViewerRegion * region = gAgent.getRegion();
-	if (region == NULL)
+	if (region == NULL || !region->capabilitiesReceived())
 	{
+		// we don't have the cap yet, so return false so the caller can try again later.
+
+		LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest capability not yet available, deferring" << LL_ENDL;
 		return false;
 	}
+
 	// grab the cap.
 	std::string url = gAgent.getRegion()->getCapability("ParcelVoiceInfoRequest");
-	if (!url.empty())
+	if (url.empty())
+	{
+		// Region dosn't have the cap. Stop probing.
+		LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest capability not available in this region" << LL_ENDL;
+		setState(stateDisableCleanup);
+		return false;
+	}
+	else 
 	{
 		// if we've already retrieved the cap from the region, go ahead and make the request,
 		// and return true so we can go into the state that waits for the response.
@@ -4517,18 +4525,11 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
 		LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL;
 		
 		LLHTTPClient::post(
-						   url,
-						   data,
-						   new LLVivoxVoiceClientCapResponder(getState()));
+						url,
+						data,
+						new LLVivoxVoiceClientCapResponder(getState()));
 		return true;
 	}
-	else 
-	{
-		
-		// we don't have the cap yet, so return false so the caller can try again later.
-		LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest cap not yet available, deferring" << LL_ENDL;
-		return false;
-	}
 }
 
 void LLVivoxVoiceClient::switchChannel(
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
old mode 100755
new mode 100644
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index 4f582fc2dbd7d6f534cba1d3256ba42a4640730c..64ca94b5678779c7ff37d6272e635fe1e19cba08 100644
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -178,8 +178,8 @@ void LLWatchdog::init(killer_event_callback func)
 	mKillerCallback = func;
 	if(!mSuspectsAccessMutex && !mTimer)
 	{
-		mSuspectsAccessMutex = new LLMutex(NULL);
-		mTimer = new LLWatchdogTimerThread();
+		mSuspectsAccessMutex = new LLMutex;
+		mTimer = new LLWatchdogTimerThread;
 		mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000);
 		mLastClockCount = LLTimer::getTotalTime();
 
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 4a6ec7fdbbed5f8e88cc7c073e532497e40013fc..a7ae456f3ce76923d8da794595e505afd7b462f3 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -127,6 +127,12 @@ void LLWorld::destroyClass()
 		LLVOCache::getInstance()->destroyClass() ;
 	}
 	LLViewerPartSim::getInstance()->destroyClass();
+
+	mDefaultWaterTexturep = NULL ;
+	for (S32 i = 0; i < 8; i++)
+	{
+		mEdgeWaterObjects[i] = NULL;
+	}
 }
 
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 7a264041383d22d55f95797727443f1aed7ba7c1..a50f66f2829d46690f2475c5a562f0d8a3ec224c 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -103,6 +103,7 @@
 #include "llmutelist.h"
 #include "lltoolpie.h"
 #include "llcurl.h"
+#include "llnotifications.h"
 
 
 void check_stack_depth(S32 stack_depth)
@@ -317,6 +318,7 @@ BOOL	LLPipeline::sRenderFrameTest = FALSE;
 BOOL	LLPipeline::sRenderAttachedLights = TRUE;
 BOOL	LLPipeline::sRenderAttachedParticles = TRUE;
 BOOL	LLPipeline::sRenderDeferred = FALSE;
+BOOL    LLPipeline::sMemAllocationThrottled = FALSE;
 S32		LLPipeline::sVisibleLightCount = 0;
 F32		LLPipeline::sMinRenderSize = 0.f;
 
@@ -561,6 +563,24 @@ void LLPipeline::destroyGL()
 
 static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
 
+//static
+void LLPipeline::throttleNewMemoryAllocation(BOOL disable)
+{
+	if(sMemAllocationThrottled != disable)
+	{
+		sMemAllocationThrottled = disable ;
+
+		if(sMemAllocationThrottled)
+		{
+			//send out notification
+			LLNotification::Params params("LowMemory");
+			LLNotifications::instance().add(params);
+
+			//release some memory.
+		}
+	}
+}
+
 void LLPipeline::resizeScreenTexture()
 {
 	LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 28e6526acd960dc761e6cc3644798f736e6945d0..3f0640221e0367f818c9a321f7b0ad8ff192e873 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -362,6 +362,8 @@ class LLPipeline
 	static void updateRenderDeferred();
 	static void refreshRenderDeferred();
 
+	static void throttleNewMemoryAllocation(BOOL disable);
+
 	void addDebugBlip(const LLVector3& position, const LLColor4& color);
 
 private:
@@ -517,8 +519,9 @@ class LLPipeline
 	static BOOL				sRenderAttachedLights;
 	static BOOL				sRenderAttachedParticles;
 	static BOOL				sRenderDeferred;
+	static BOOL             sMemAllocationThrottled;
 	static S32				sVisibleLightCount;
-	static F32				sMinRenderSize;
+	static F32				sMinRenderSize;	
 
 	//screen texture
 	U32 					mScreenWidth;
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 31b6fc77f58d55a9642f86efb186e9edaf96bf24..d19e56e9a03e457694695cb59814b090d861f223 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -29,9 +29,15 @@
 	<color
 	 name="LtGray"
 	 value="0.75 0.75 0.75 1" />
+	<color
+	 name="LtGray_35"
+	 value="0.75 0.75 0.75 0.35" />
 	<color
 	 name="LtGray_50"
 	 value="0.75 0.75 0.75 0.50" />
+	<color
+	 name="Gray"
+	 value="0.5 0.5 0.5 1" />
 	<color
 	 name="DkGray"
 	 value="0.125 0.125 0.125 1" />
@@ -197,7 +203,7 @@
      reference="Black" />
     <color
      name="ColorPaletteEntry02"
-     value="0.5 0.5 0.5 1" />
+     reference="Gray" />
     <color
      name="ColorPaletteEntry03"
      value="0.5 0 0 1" />
@@ -423,12 +429,15 @@
     <color
      name="InventoryItemLinkColor"
      reference="LtGray_50" />
+    <color
+     name="InventoryMouseOverColor"
+     reference="LtGray_35" />
     <color
      name="InventorySearchStatusColor"
      reference="EmphasisColor" />
     <color
      name="LabelDisabledColor"
-	 reference="White_25" />
+     reference="White_25" />
     <color
      name="LabelSelectedColor"
      reference="White" />
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 799cd907dcfad95a2d9f6e6740a9b14d2aa2c96f..4d83ec290216886bd19212fd40ffaeb9ffdc7eb8 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -72,6 +72,10 @@ with the same filename but different name
   <texture name="BackButton_Over" file_name="icons/back_arrow_over.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" />
   <texture name="BackButton_Press" file_name="icons/back_arrow_press.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" />
 
+  <texture name="Error_Tag_Background" file_name="widgets/Error_Tag_Background.png" preload="true" scale.left="12" scale.top="2" scale.right="36" scale.bottom="2" />
+  <texture name="New_Tag_Background" file_name="widgets/New_Tag_Background.png" preload="true" scale.left="12" scale.top="2" scale.right="36" scale.bottom="2" />
+  <texture name="New_Tag_Border" file_name="widgets/New_Tag_Border.png" preload="true" scale.left="12" scale.top="2" scale.right="36" scale.bottom="2" />
+
   <texture name="Badge_Background" file_name="widgets/Badge_Background.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
   <texture name="Badge_Border" file_name="widgets/Badge_Border.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
 
diff --git a/indra/newview/skins/default/textures/widgets/Badge_Background_New.png b/indra/newview/skins/default/textures/widgets/Badge_Background_New.png
deleted file mode 100644
index 9f114f2e4aa0d0529e67af3d779dd9748488e6dd..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/widgets/Badge_Background_New.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/widgets/Error_Tag_Background.png b/indra/newview/skins/default/textures/widgets/Error_Tag_Background.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8dbc8e87a3b5e48caeb1aa511eff8e15babee9f
Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Error_Tag_Background.png differ
diff --git a/indra/newview/skins/default/textures/widgets/New_Tag_Background.png b/indra/newview/skins/default/textures/widgets/New_Tag_Background.png
new file mode 100644
index 0000000000000000000000000000000000000000..cd639dd80f3cf4575096363b892baa54a610bbfd
Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/New_Tag_Background.png differ
diff --git a/indra/newview/skins/default/textures/widgets/New_Tag_Border.png b/indra/newview/skins/default/textures/widgets/New_Tag_Border.png
new file mode 100644
index 0000000000000000000000000000000000000000..56df0d012789f7ef3021c656d561c090dab3c335
Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/New_Tag_Border.png differ
diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
new file mode 100644
index 0000000000000000000000000000000000000000..49aa8f384008638e734b0a7bab7ab2f6adeed287
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_minimize="false"
+ can_tear_off="false"
+ can_resize="true"
+ can_drag_on_left="false"
+ can_close="true"
+ height="500"
+ layout="topleft"
+ name="fast_timers"
+ save_rect="true"
+ save_visibility="false"
+ single_instance="true" 
+ min_width="400"
+ width="700">
+  <string name="pause" >Pause</string>
+  <string name="run">Run</string>
+  <button follows="top|right" 
+          name="pause_btn"
+          left="-200"
+          top="5"
+          width="180"
+          height="40"
+          pad_bottom="-5"
+          label="Pause"
+          font="SansSerifHuge"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
old mode 100755
new mode 100644
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
index 449731ab8906ad9c5811e3bb2e4e478163aa78f2..93bfe53aae9193531c539f04310cbfd2b74018db 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
@@ -29,7 +29,7 @@
 	 height="10"
 	 left_delta="23"
 	 layout="topleft"
-	 name="Proxy location"
+	 name="http_proxy_label"
 	 top_pad="10"
 	 width="300">
 	    HTTP Proxy:
@@ -81,7 +81,7 @@
 	 height="10"
 	 layout="topleft"
 	 left_delta="23"
-	 name="Proxy location"
+	 name="socks5_proxy_label"
 	 top_pad="10"
 	 width="300">
 	    SOCKS 5 Proxy:
@@ -125,7 +125,7 @@
 	 height="10"
 	 layout="topleft"
 	 left="40"
-	 name="Proxy location"
+	 name="socks_auth_label"
 	 top_pad="15"
 	 width="300">
 	    SOCKS Authentication:
@@ -163,6 +163,7 @@
 	 height="10"
 	 layout="topleft"
 	 left_delta="20"
+	 name="socks5_username_label"
 	 top_delta="50"
 	 width="200">
 	    Username:
@@ -174,6 +175,7 @@
 	 height="10"
 	 left_pad="15"
 	 layout="topleft"
+	 name="socks5_password_label"
 	 width="200">
 	    Password:
 	</text>
@@ -207,7 +209,7 @@
 	 height="10"
 	 layout="topleft"
 	 left="25"
-	 name="Proxy location"
+	 name="other_proxy_label"
 	 top_pad="18"
 	 width="300">
 	   Other HTTP traffic proxy:
diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
index 14320995908068ff3df7eabd02c6109ee81c458c..f017a7ace6b418c2ecf27b91c80a4b0ecd22847e 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
@@ -89,7 +89,6 @@
         <layout_panel name="leave_call_panel" height="26" auto_resize="false">
         <layout_stack
          clip="true"
-         auto_resize="false"
          follows="left|top|right"
          height="26"
          layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index e91f4458aee8d9c2954530f720fd577abba7fcb0..fb85e5278a00c72e6a3e78a95777ea7e1a22d543 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -674,7 +674,26 @@
          function="Inventory.DoToSelected"
          parameter="take_off" />
     </menu_item_call>
-    <menu_item_call
+	<menu_item_separator
+	 layout="topleft"
+	 name="Marketplace Separator" />
+	<menu_item_call
+	 label="Copy to Merchant Outbox"
+	 layout="topleft"
+	 name="Merchant Copy">
+		<menu_item_call.on_click
+		 function="Inventory.DoToSelected"
+		 parameter="copy_to_outbox" />
+	</menu_item_call>
+	<menu_item_call
+	 label="Move to Merchant Outbox"
+	 layout="topleft"
+	 name="Merchant Move">
+		<menu_item_call.on_click
+		 function="Inventory.DoToSelected"
+		 parameter="move_to_outbox" />
+	</menu_item_call>
+	<menu_item_call
      label="--no options--"
      layout="topleft"
      name="--no options--" />
diff --git a/indra/newview/skins/default/xui/en/menu_media_ctrl.xml b/indra/newview/skins/default/xui/en/menu_media_ctrl.xml
index c39c26f25f5278cc53619923df540bd565eedace..960da4bd7a22894f79da0e9c4aa704298db2447e 100644
--- a/indra/newview/skins/default/xui/en/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/menu_media_ctrl.xml
@@ -28,4 +28,16 @@
     <menu_item_call.on_enable
      function="Edit.EnablePaste" />
   </menu_item_call>
+  <menu_item_separator
+   layout="topleft"
+   name="debug_separator"
+   visible="false" />
+  <menu_item_call
+   label="Open Web Inspector"
+   layout="topleft"
+   name="open_webinspector"
+   visible="false">
+    <menu_item_call.on_click
+     function="Open.WebInspector" />
+  </menu_item_call>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index b08e3abb71fee7651437283dc5b493fe4f0400bb..36ebe737532a017b0868ab7701db08ddc357a774 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2133,6 +2133,16 @@
                function="ToggleControl"
                parameter="DebugShowMemory" />
             </menu_item_check>
+	     <menu_item_check
+               label="Show Private Mem Info"
+               name="Show Private Mem Info">
+              <menu_item_check.on_check
+               function="CheckControl"
+               parameter="DebugShowPrivateMem" />
+              <menu_item_check.on_click
+               function="ToggleControl"
+               parameter="DebugShowPrivateMem" />
+            </menu_item_check>
 
             <menu_item_separator/>
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 03bdd9f07110f47725077f3aa63543a2f612a35d..64438fe61410f53b1fbdbda96e30922bbf73b982 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -200,6 +200,40 @@ Save changes to current clothing/body part?
   </notification>
 
   <notification
+   icon="alertmodal.tga"
+     name="ConfirmNoCopyToOutbox"
+     type="alertmodal">
+        You don't have permission to copy this item to the Marketplace Outbox. Are you sure you want to move the following item?
+        [ITEM_NAME]
+        <usetemplate
+         name="okcancelbuttons"
+         notext="No"
+         yestext="Yes"/>
+    </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="OutboxUploadComplete"
+   type="alertmodal">
+Marketplace upload complete.
+        <usetemplate
+         name="okbutton"
+         yestext="Hooray!"/>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="OutboxUploadHadErrors"
+   type="alertmodal">
+Marketplace upload completed with errors!  Please correct the problems in your outbox and retry.  Thanks.
+        <usetemplate
+         name="okbutton"
+         yestext="Boo!"/>
+  </notification>
+
+    
+
+    <notification
    icon="alertmodal.tga"
    name="CompileQueueSaveText"
    type="alertmodal">
@@ -5089,7 +5123,7 @@ Topic: [SUBJECT], Message: [MESSAGE]
    name="FriendOnline"
    type="notifytip">
     <tag>friendship</tag>
-&lt;nolink&gt;[NAME]&lt;/nolink&gt; is Online
+[NAME] is Online
   </notification>
 
   <notification
@@ -5097,7 +5131,7 @@ Topic: [SUBJECT], Message: [MESSAGE]
    name="FriendOffline"
    type="notifytip">
     <tag>friendship</tag>
-&lt;nolink&gt;[NAME]&lt;/nolink&gt; is Offline
+[NAME] is Offline
   </notification>
 
   <notification
@@ -5916,7 +5950,25 @@ An object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; owned by [NAME_SLU
       <button
        index="2"
        name="Mute"
-       text="Block"/>
+       text="Block Owner"/>
+    </form>
+  </notification>
+
+  <notification
+   icon="notify.tga"
+   name="OwnObjectGiveItem"
+   type="offer">
+Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you this [OBJECTTYPE]:
+&lt;nolink&gt;[ITEM_SLURL]&lt;/nolink&gt;
+    <form name="form">
+      <button
+       index="0"
+       name="Keep"
+       text="Keep"/>
+      <button
+       index="1"
+       name="Discard"
+       text="Discard"/>
     </form>
   </notification>
 
@@ -6818,7 +6870,7 @@ Select residents to share with.
 See the log file for details.
   </notification>
    
-   <notification
+  <notification
     name="MeshUploadPermError"
     icon="alert.tga"
     type="alert">
@@ -6842,7 +6894,7 @@ Are you sure you want to share the following items:
 
 With the following Residents:
 
-&lt;nolink&gt;[RESIDENTS]&lt;/nolink&gt;
+[RESIDENTS]
   <tag>confirm</tag>
 	<usetemplate
      name="okcancelbuttons"
@@ -7147,6 +7199,20 @@ Click and drag anywhere on the world to rotate your view
     <tag>funds</tag>
   </notification>
 
+   <notification
+   icon="alertmodal.tga"
+   name="LowMemory"
+   type="alertmodal">
+    Your memory pool is low. Some functions of SL are disabled to avoid crash. Please close other applications. Restart SL if this persists.
+  </notification>
+
+  <notification
+     icon="alertmodal.tga"
+     name="ForceQuitDueToLowMemory"
+     type="alertmodal">
+    SL will quit in 30 seconds due to out of memory.
+  </notification>
+
   <notification
   name="PopupAttempt"
   icon="Popup_Caution"
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index c8f8d077013a3d1f10dba9a52b2516397d615775..ec5853649eb3e6090f5e248fa687f129c44c5dfc 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -47,13 +47,13 @@
          mouse_opaque="false"
 		 name="chat_bar_layout_panel"
          user_resize="true"
-     width="310" >
+     width="250" >
           <panel
             name="chat_bar"
             filename="panel_nearby_chat_bar.xml"
             left="0"
             height="28"
-        width="308"
+        width="248"
             top="0"
             mouse_opaque="false"
             follows="left|right"
@@ -341,7 +341,7 @@ Disabled for now.
          height="28"
          layout="topleft"
          min_height="28"
-     min_width="52"
+     min_width="62"
          mouse_opaque="false"
          name="mini_map_btn_panel"
          user_resize="false"
diff --git a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
index d06190ec54853d0747b53746dd67c91b70bac2c9..383e637ace13947f996cb4a8132b6e498a35ef2d 100644
--- a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
@@ -4,7 +4,7 @@
     start_folder="Received Items"
     follows="all" layout="topleft"
     top="0" left="0" height="165" width="308"
-	top_pad="0"
+    top_pad="0"
     bg_opaque_color="DkGray2"
     bg_alpha_color="DkGray2"
     background_visible="true"
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index 83f1bff91f5c5d6d33cbf6b95e3cec43d3afc2e9..1c3e08d59b27f94ec486a1e4b17ff8cd45f47518 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -27,7 +27,6 @@ bg_opaque_color="Black"
 border_visible="false"
 bottom="600"
 follows="all"
-hide_loading="true"
 left="0"
 name="login_html"
 start_url=""
@@ -117,17 +116,33 @@ label="Remember password"
   name="connect_btn"
   top="35"
   width="90" />
-  <!-- Utf code in label is a filled up-pointing triangle -->
-  <menu_button
-  left_pad="5"
-  top="35"
-  width="80"
+  <text
+  follows="left|bottom"
+  font="SansSerifSmall"
+  height="15"
+  left_pad="10"
+  name="mode_selection_text"
+  top="20"
+  width="130">
+    Mode:
+  </text>
+  <combo_box
+    follows="left|bottom"
   height="23"
-  label="Mode &#9650;"
-  name="mode_menu"  
+    max_chars="128"
   tool_tip="Select your mode. Choose Basic for fast, easy exploration and chat. Choose Advanced to access more features."
-  menu_filename="menu_mode_change.xml"
-    />
+    top_pad="0"
+    name="mode_combo"
+    width="110">
+    <combo_box.item
+      label="Basic"
+      name="Basic"
+      value="settings_minimal.xml" />
+    <combo_box.item
+      label="Advanced"
+      name="Advanced"
+      value="" />
+  </combo_box>
   <text
   follows="left|bottom"
   font="SansSerifSmall"
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index 0df9aa2868a8aa6eb46e1b16c582d68fea086f11..e6c5110999d4bc5067490c58e88637e3cf9cae8a 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -6,7 +6,7 @@
  height="423"
  label="Things"
  layout="topleft"
- min_height="350"
+ min_height="300"
  min_width="240"
  name="main inventory panel"
  width="330">
@@ -82,10 +82,11 @@
      left="0"
      name="All Items"
      sort_order_setting="InventorySortOrder"
-	 show_item_link_overlays="true"
+     show_item_link_overlays="true"
      top="16"
      width="288" />
     <recent_inventory_panel
+     accepts_drag_and_drop="false"
      bg_opaque_color="DkGray2"
      bg_alpha_color="DkGray2"
      background_visible="true"
@@ -99,7 +100,7 @@
      layout="topleft"
      left_delta="0"
      name="Recent Items"
-	 show_item_link_overlays="true"
+     show_item_link_overlays="true"
      width="290" />
   </tab_container>
   <layout_stack
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 8a7bd53054b60293cb4ae0a5c094d27ea651e56b..51ffec4727141fdbaeecf7a4f6b5eeadbf4823a7 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -97,7 +97,7 @@
 	     mouse_opaque="false"
 	     name="location_combo"
 	     top_delta="0"
-	     width="266">
+	     width="226">
          <combo_list
          mouse_wheel_opaque="true"/>
 	     <!-- *TODO: Delete.  Let the location_input use the correct art sizes.
@@ -137,7 +137,7 @@
 	     name="search_combo_box"
 	     tool_tip="Search"
 	     top_delta="0"
-	     width="200" >
+	     width="244" >
          <combo_editor
           label="Search [SECOND_LIFE]"
           name="search_combo_editor"/>
@@ -146,7 +146,8 @@
           border.highlight_light_color="FocusColor"
           border.highlight_dark_color="FocusColor"
           border.shadow_light_color="FocusColor"
-          border.shadow_dark_color="FocusColor"/>
+          border.shadow_dark_color="FocusColor"
+          mouse_wheel_opaque="true" />
         </search_combo_box>
 	</panel>
     <favorites_bar
diff --git a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
index af32056428a3db41605ed8565e53b95c52da7ea6..66117615e42e16cbc81cdbf65f34e41791e4ec0c 100644
--- a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<inventory_panel
+<outbox_inventory_panel
     name="inventory_outbox"
     start_folder="Outbox"
     follows="all" layout="topleft"
     top="0" left="0" height="165" width="308"
-	top_pad="0"
+    top_pad="0"
     bg_opaque_color="DkGray2"
     bg_alpha_color="DkGray2"
     background_visible="true"
@@ -12,6 +12,7 @@
     border="false"
     bevel_style="none"
     show_item_link_overlays="true"
+    tool_tip="Drag and drop items here to prepare them for sale on your storefront"
     >
     <scroll reserve_scroll_corner="false" />
-</inventory_panel>
+</outbox_inventory_panel>
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index cc4522f9443711f50669c9b708e650b1f7e924bb..0ebfd9c037a949af794e497f74f8afca315b0614 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -66,7 +66,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
      layout="topleft"
      left="10"
      label="Filter"
-     max_length="300"
+     max_length_chars="300"
      name="filter_input"
      text_color="Black"
      text_pad_left="10"
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index 978b204df9cbcdf8ef166f4f9e16c9b62454bccd..87e263726d2b7643725afc007af6905b70e86a4e 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -72,20 +72,19 @@ bg_opaque_color="DkGray2"
     </accordion_tab>
  </accordion>
    <panel
-bg_opaque_color="DkGray2"
+       bg_opaque_color="DkGray2"
        background_visible="true"
        background_opaque="true"
-         bevel_style="none"
-         enabled="false"
-         auto_resize="false"
-         follows="bottom|left|right"
-         left="1"
-         height="27"
-         label="bottom_panel"
-         layout="bottom"
-         name="edit_panel"
-         top_pad="-2"
-         width="313">
+       bevel_style="none"
+       enabled="false"
+       follows="bottom|left|right"
+       left="1"
+       height="27"
+       label="bottom_panel"
+       layout="bottom"
+       name="edit_panel"
+       top_pad="-2"
+       width="313">
          
          <layout_stack
 		  follows="bottom|left|right"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index b6b8a337a121d3df9267b6184012f630a4379c63..5d7334f780f7a05b5df15f4d4136907b55052477 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -25,7 +25,7 @@ background_visible="true"
      layout="topleft"
      left="10"
      label="Filter My Places"
-     max_length="300"
+     max_length_chars="300"
      name="Filter"
      top="3"
      width="303" />
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index cb701e03da35c826a958b4138a748708c8ea84e9..f5a9daa994c3705bb7cc1a16f29f4bc1a30e85a0 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -277,7 +277,7 @@
                initial_value="(retrieving)"
                layout="topleft"
                left="0"
-               link="true"
+               parse_urls="true"
                name="partner_text"
                top="0"
                use_ellipses="true"
diff --git a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
index 72b2f5e84fa505230ac281dddedffcedb6f86a3e..912f81f915f9901a31158548071f7eca65acb4fc 100644
--- a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
+++ b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
@@ -24,7 +24,6 @@
      layout="topleft"
      left_delta="0"
      name="browser_layout"
-     orientation="vertical" 
      top_delta="0"
      width="313">
       <web_browser
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index f25a73da38a6e699f21781ed8a615c90baf59751..5894abd03b20a10fb1fd1a99895a75a0a7169a91 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -35,7 +35,7 @@
     </panel.string>
   <panel
     height="18"
-    left="-315"
+    left="-355"
     width="95"
     top="1"
     follows="right|top" 
@@ -44,7 +44,6 @@
     background_opaque="true" 
     bg_opaque_image="bevel_background">
     <text
-     auto_resize="true"
      halign="center"
      font="SansSerifSmall"
      follows="all"
@@ -58,7 +57,6 @@
      value="L$20" 
      width="40" />
     <button
-     auto_resize="true"
      halign="center"
      font="SansSerifSmall"
      follows="right|top|bottom"
@@ -77,20 +75,27 @@
      top="0"
      width="55" />
   </panel>
-  <!-- UTF 9660 code in label below is a down-pointing filled-in triangle -->
-  <menu_button
-     follows="right|top"    
-    image_color="0 0 0 0"
-    hover_glow_amount="0"
+  <combo_box
+    follows="right|top"   
+    drop_down_button.pad_left="10" 
     left_pad="5"
-    top="2"
-    width="55"
-    height="18"
-    label="Mode &#9660;"
+    top="0"
+    width="120"
+    height="20"
+    name="mode_combo"
     tool_tip="Select your mode. Choose Basic for fast, easy exploration and chat. Choose Advanced to access more features."
-    menu_filename="menu_mode_change.xml"
-    />
+    >
+    <combo_box.item
+      label="Basic Mode"
+      name="Basic"
+      value="settings_minimal.xml" />
+    <combo_box.item
+      label="Advanced Mode"
+      name="Advanced"
+      value="" />
+  </combo_box>
     <text
+      left_pad="5"
      type="string"
      font="SansSerifSmall"
      text_readonly_color="TimeTextColor"
@@ -99,10 +104,9 @@
      height="16"
      top="5"
      layout="topleft"
-     left_pad="5"
      name="TimeText"
      tool_tip="Current time (Pacific)"
-     width="90">
+     width="75">
         24:00 AM PST
     </text>
     <button
diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
index b5839878d59ae8c05ebaf4ef5bf6b8f3a6469646..1d98a84e25f410138697bc0efc12ae00bbf9d2fd 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
@@ -114,7 +114,7 @@ width="333">
    layout="topleft"
    left="10"
    label="Filter Outfits"
-   max_length="300"
+   max_length_chars="300"
    name="Filter"
    search_button_visible="true"
    top_pad="10"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
index 79a0ec7c72ff108ed12c500fc7a26b481e293b77..7a176ff3671e2cf9aad5b926a2073227e8135890 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
@@ -30,11 +30,12 @@
               width="330">
              <layout_panel
                  name="main_inventory_layout_panel"
+								 layout="topleft"
                  min_dim="150"
                  width="330"
                  follows="bottom|left|right"
                  user_resize="false"
-                 height="480">
+                 height="300">
                  <panel
                       class="panel_main_inventory"
                       filename="panel_main_inventory.xml"
@@ -44,14 +45,36 @@
                       name="panel_main_inventory"
                       top="0"
                       label=""
-                      height="480"
+                      height="300"
                       width="330" />
              </layout_panel>
-             <layout_panel
+					   <layout_panel
                  width="330"
+								 layout="topleft"
                  auto_resize="true"
                  user_resize="false"
                  follows="bottom|left|right"
+                 name="inbox_outbox_layout_panel"
+                 visible="false"
+                 min_dim="35"
+                 max_dim="235"
+                 expanded_min_dim="125"
+                 height="235">
+							 <layout_stack
+										follows="left|right|top|bottom"
+										layout="topleft"
+										left="0"
+										top="0"
+										orientation="vertical"
+										name="inbox_outbox_layout_stack"
+										height="235"
+										width="330">
+								 <layout_panel
+                 width="330"
+								 layout="topleft"
+                 auto_resize="true"
+                 user_resize="false"
+                 follows="left|right|top"
                  name="inbox_layout_panel"
                  visible="false"
                  min_dim="35"
@@ -72,6 +95,7 @@
                      <string name="InboxLabelNoArg">Received Items</string>
                      <button
                         label="Received Items"
+												font="SansSerifMedium"
                         name="inbox_btn"
                         height="35"
                         width="308"
@@ -96,7 +120,6 @@
                         name="inbox_fresh_new_count"
                         font="SansSerifMedium"
                         halign="right"
-                        text_color="EmphasisColor"
                         top_pad="0"
                         width="300">
                         [NUM] New
@@ -129,41 +152,45 @@
                  </panel>
              </layout_panel>
              <layout_panel
-                width="330"
-                auto_resize="true"
-                user_resize="false"
-                follows="bottom|left|right"
-                name="outbox_layout_panel"
-                visible="false"
-                min_dim="35"
-                max_dim="200"
-                expanded_min_dim="90"
-                height="200">
+                 width="330"
+                 layout="topleft"
+                 auto_resize="true"
+                 user_resize="false"
+                 follows="all"
+                 name="outbox_layout_panel"
+                 visible="false"
+                 min_dim="35"
+                 max_dim="200"
+                 expanded_min_dim="90"
+                 height="200">
                  <panel
                       follows="all"
                       layout="topleft"
-                      left="10"
+                      left="0"
                       name="marketplace_outbox"
                       class="panel_marketplace_outbox"
                       top="0"
                       label=""
                       height="200"
-                      width="310">
+                      width="330">
+                     <string name="OutboxLabelWithArg">Merchant Outbox ([NUM])</string>
+                     <string name="OutboxLabelNoArg">Merchant Outbox</string>
                      <button
                         label="Merchant Outbox"
-                        is_toggle="true"
-                        handle_right_mouse="false"
+                        font="SansSerifMedium"
                         name="outbox_btn"
-                        follows="top|left|right"
-                        image_unselected="MarketplaceBtn_Off"
-                        image_selected="MarketplaceBtn_Selected"
                         height="35"
-                        tab_stop="false"
                         width="308"
+                        image_unselected="MarketplaceBtn_Off"
+                        image_selected="MarketplaceBtn_Selected"
                         halign="left"
+                        handle_right_mouse="false"
+                        follows="top|left|right"
+                        is_toggle="true"
+                        tab_stop="false"
                         pad_left="35"
                         top="0"
-                        left="0" />
+                        left="10" />
                      <button
                          image_unselected="OutboxPush_Off"
                          image_selected="OutboxPush_Selected"
@@ -213,24 +240,50 @@
                         bg_opaque_color="InventoryBackgroundColor"
                         background_visible="true"
                         background_opaque="true"
-                        tool_tip="Drag and drop items here to prepare them for sale on your storefront"
                         >
-                        <text
-							name="outbox_inventory_placeholder"
-							type="string"
+						<panel
+							name="outbox_inventory_placeholder_panel"
 							follows="all"
 							layout="topleft"
 							top="0"
 							left="0"
 							width="308"
 							height="165"
-							wrap="true"
-							halign="center">
-							Set up your merchant account to use this feature.
-						</text>
+							bg_opaque_color="InventoryBackgroundColor"
+							background_visible="true"
+							background_opaque="true"
+							>
+							<text
+								name="outbox_inventory_placeholder_title"
+								type="string"
+								follows="all"
+								layout="topleft"
+								top="10"
+								left="0"
+								width="308"
+								height="25"
+								wrap="true"
+								halign="center"
+								font="SansSerifBold">
+								Loading...
+							</text>
+							<text
+								name="outbox_inventory_placeholder_text"
+								type="string"
+								follows="all"
+								layout="topleft"
+								top="35"
+								left="0"
+								width="308"
+								height="130"
+								wrap="true"
+								halign="left" />
+						</panel>
                     </panel>
                  </panel>
              </layout_panel>
+						 </layout_stack>
+						 </layout_panel>
          </layout_stack>
 		<panel
 		     follows="bottom|left|right"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 2094275bed543d56d11953e740895d71e2a4fec0..c0154ae9b3ce0674f75ee40ed4940fb0c0d58c35 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -164,12 +164,16 @@ Please try logging in again in a minute.</string>
 	<string name="TooltipLand">Land:</string>
 	<string name="TooltipMustSingleDrop">Only a single item can be dragged here</string>
 	<string name="TooltipPrice" value="L$[AMOUNT]: "/>
-
+	<string name="TooltipOutboxNoTransfer">One or more of these objects cannot be sold or transferred to another user.</string>
+	<string name="TooltipOutboxWorn">You are wearing one or more of these objects. Remove them from your avatar and try moving them again.</string>
+	<string name="TooltipOutboxFolderLevels">This folder has too many levels of subfolders. Rearrange the interior folders to a maximum of 4 levels deep (Root Folder contains A contains B contains C).</string>
+	<string name="TooltipOutboxTooManyObjects">This folder contains more than 200 objects. Box some of the items to reduce the object count.</string>
+	
 	<!-- tooltips for Urls -->
 	<string name="TooltipHttpUrl">Click to view this web page</string>
 	<string name="TooltipSLURL">Click to view this location's information</string>
 	<string name="TooltipAgentUrl">Click to view this Resident's profile</string>
-  <string name="TooltipAgentInspect">Learn more about this Resident</string>
+	<string name="TooltipAgentInspect">Learn more about this Resident</string>
 	<string name="TooltipAgentMute">Click to mute this Resident</string>
 	<string name="TooltipAgentUnmute">Click to unmute this Resident</string>
 	<string name="TooltipAgentIM">Click to IM this Resident</string>
@@ -2025,8 +2029,29 @@ Returns a string with the requested data about the region
 	<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>
 	<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
 	<string name="InventoryInboxNoItems">Items purchased through the marketplace will be delivered here.</string>
-	<string name="InventoryOutboxNoItems">Drag items here in preparation for listing on your marketplace storefront.</string>
-    <!-- use value="" because they have preceding spaces -->
+	<string name="MarketplaceURL">http://marketplace.[DOMAIN_NAME]</string>
+	<string name="MarketplaceURL_CreateStore">http://marketplace.[DOMAIN_NAME]/create_store</string>
+	<string name="MarketplaceURL_LearnMore">http://marketplace.[DOMAIN_NAME]/learn_more</string>
+	<string name="InventoryOutboxCreationErrorTitle">Your Merchant Outbox is not properly configured</string>
+	<string name="InventoryOutboxCreationErrorTooltip">Merchant Outbox configuration error</string>
+	<string name="InventoryOutboxCreationError">Please contact Customer Service to correct the problem.</string>
+	<string name="InventoryOutboxNotMerchantTitle">Anyone can sell items on the Marketplace</string>
+	<string name="InventoryOutboxNotMerchantTooltip">Become a merchant!</string>
+	<string name="InventoryOutboxNotMerchant">[[MARKETPLACE_URL] The Second Life Marketplace] offers more than one million virtual products for sale, all of them created by Residents. You, too, can sell items you create, as well as some of the items you have purchased. It’s easy and setup is free.  [[LEARN_MORE_URL] Learn more] or [[CREATE_STORE_URL] create a store] on the Marketplace to get started.</string>
+	<string name="InventoryOutboxNoItemsTitle">A new way to send items to the Marketplace</string>
+	<string name="InventoryOutboxNoItemsTooltip">Drag and drop items here to prepare them for sale on the Marketplace</string>
+	<string name="InventoryOutboxNoItems">Drag items or folders that you wish to sell into this area.  A copy of the item will appear, leaving your inventory unchanged, unless you have dragged a no-copy item.  When you are ready to send the items to the Marketplace, click the Upload button. Once your items have been moved to your Marketplace Inventory, they will disappear from this folder.</string>
+
+	<string name="Marketplace Error None">No errors</string>
+	<string name="Marketplace Error Not Merchant">Error: Before sending items to the Marketplace you will need to set yourself up as a merchant (free of charge).</string>
+	<string name="Marketplace Error Empty Folder">Error: This folder has no contents.</string>
+	<string name="Marketplace Error Unassociated Products">Error: This item failed to upload because your merchant account has too many items unassociated with products.  To fix this error, login to the marketplace website and reduce your unassociated item count.</string>
+	<string name="Marketplace Error Object Limit">Error: This item contains too many objects.  Fix this error by placing objects together in boxes to reduce the total count to less than 200.</string>
+	<string name="Marketplace Error Folder Depth">Error: This item contains too many levels of nested folders.  Reorganize it to a maximum of 3 levels of nested folders.</string>
+	<string name="Marketplace Error Unsellable Item">Error: This item can not be sold on the marketplace.</string>
+	<string name="Marketplace Error Internal Import">Error: There was a problem with this item.  Try again later.</string>
+
+	<!-- use value="" because they have preceding spaces -->
 	<string name="no_transfer" value=" (no transfer)" />
 	<string name="no_modify"   value=" (no modify)" />
 	<string name="no_copy"     value=" (no copy)" />
diff --git a/indra/newview/skins/default/xui/en/widgets/accordion.xml b/indra/newview/skins/default/xui/en/widgets/accordion.xml
index 1a66f0f5c575aee10375d2d306ca2ed65b31adb1..55dde492ca770cc627fab072b04c6b4e0b44140c 100644
--- a/indra/newview/skins/default/xui/en/widgets/accordion.xml
+++ b/indra/newview/skins/default/xui/en/widgets/accordion.xml
@@ -16,7 +16,7 @@
      name="no_matched_tabs_msg"
      v_pad="15"
      width="200"
-     wrap="true "/>
+     wrap="true"/>
     <!-- This widget will not be created in viewer. Only its value will be used for empty accordion without filter. -->
     <no_visible_tabs_text
      name="no_visible_tabs_msg"
diff --git a/indra/newview/skins/default/xui/en/widgets/badge.xml b/indra/newview/skins/default/xui/en/widgets/badge.xml
index 2d4c02b092904cf34c6ddf30f32cc3a4059324b3..738d150f642b2ae46a3c2293047e63d4ae4d1c91 100644
--- a/indra/newview/skins/default/xui/en/widgets/badge.xml
+++ b/indra/newview/skins/default/xui/en/widgets/badge.xml
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <!-- Additional attributes:
    -->
-<badge border_image="Badge_Border"
+<badge name="badge"
+       border_image="Badge_Border"
        border_color="BadgeBorderColor"
        font="SansSerifSmall"
        image="Badge_Background"
diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml
index 302014eb24b8db5f20ec2afb9bb8ba19d44d1077..61d36468d741e1113c274af93a8909737595366a 100644
--- a/indra/newview/skins/default/xui/en/widgets/button.xml
+++ b/indra/newview/skins/default/xui/en/widgets/button.xml
@@ -26,5 +26,6 @@
         height="23"
         scale_image="true"
         handle_right_mouse="true"
-        use_draw_context_alpha="true">
+        use_draw_context_alpha="true"
+        held_down_delay.seconds="0.5">
 </button>
diff --git a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
index 48b987d7e8639d399e4226629b04c407a5d5e96a..ab3de1eaab0441e16912499be6f56f89e4ce160b 100644
--- a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
+++ b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <color_swatch alpha_background_image="color_swatch_alpha.tga"
               border_color="ColorSwatchBorderColor"
-              name="color_swatch">
+              name="colorswatch">
   <color_swatch.caption_text name="caption"
                              halign="center"
                              follows="left|right|bottom"
diff --git a/indra/newview/skins/default/xui/en/widgets/combo_box.xml b/indra/newview/skins/default/xui/en/widgets/combo_box.xml
index d1f68a9ef9aaac3578ee47240573787d3f1c9f4a..82d620d1e6b57f6f9a6430b7c660e1d7cdee82ba 100644
--- a/indra/newview/skins/default/xui/en/widgets/combo_box.xml
+++ b/indra/newview/skins/default/xui/en/widgets/combo_box.xml
@@ -16,6 +16,9 @@
                               font="SansSerifSmall"
                               scale_image="true"
                               pad_right="24"
+                              halign="left"
+                              tab_stop="true"
+                              follows="all"
                               image_unselected="DropDown_Off"
                               image_selected="DropDown_On"
                               image_pressed="DropDown_Press" 
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
index 0720621f0b3ae701e950eebb8f5bfb8d6b2396a7..2cc4abdd3038c32019e47d4aa5f9c0df60d2bb7c 100644
--- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <filter_editor
+  name="filter_editor"
   clear_button_visible="true"
   search_button_visible="false"
   text_pad_left="7"
diff --git a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
index e6bdcccfdfcb5fbd7dc958a31b542c0b0258f422..6fa74f403d8f8d4add86d3e9d11589eb722c29a9 100644
--- a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
@@ -5,4 +5,6 @@
   item_height="20" 
   item_top_pad="4"
   selection_image="Rounded_Square"
+  mouse_opaque="true"
+  follows="left|top|right"
   />
diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
index 95f5cf2ecd03676a59f248f8c66384a4293e7f59..77d8024cb257b35a15f351c6553b8b347bb208e8 100644
--- a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
@@ -10,10 +10,12 @@
         label="New" 
         label_offset_horiz="-1"
         location="right" 
-        padding_horiz="4" 
-        padding_vert="1" 
-        location_percent_hcenter="70"
-        border_image=""
-        image="Badge_Background_New"
+        padding_horiz="12.5" 
+        padding_vert="2"
+        location_offset_hcenter="-23"
+        border_image="New_Tag_Border"
+        border_color="DkGray2"
+        image="New_Tag_Background"
+        image_color="Black"
         />
 </inbox_folder_view_folder>
diff --git a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml
index 00f4c43915517e15ab65089f422c1e9783acec40..eaf148c5e49c846aba227756fd7e3ecf86602559 100644
--- a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml
@@ -4,11 +4,12 @@
   background_visible="true"
   background_opaque="true"
   show_load_status="true"
+  accepts_drag_and_drop="true"
   >
     <scroll
-		name="Inventory Scroller"
-        follows="all"
-		reserve_scroll_corner="true"
-        tab_stop="true"
-        />
+      name="Inventory Scroller"
+      follows="all"
+      reserve_scroll_corner="true"
+      tab_stop="true"
+    />
 </panel>
diff --git a/indra/newview/skins/default/xui/en/widgets/layout_stack.xml b/indra/newview/skins/default/xui/en/widgets/layout_stack.xml
new file mode 100644
index 0000000000000000000000000000000000000000..48bcb465331d4896031389c61279411737029ed8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/layout_stack.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- Global settings for all widgets ("UI Controls") -->
+<!-- The params in this file aren't currently getting loaded in OSX -->
+<layout_stack name="stack"/> 
diff --git a/indra/newview/skins/default/xui/en/widgets/menu.xml b/indra/newview/skins/default/xui/en/widgets/menu.xml
index 58543338f6ffc0ebafe3e40510ca78800fbffb32..13ac84beb2787d81f16c95016ad0407edd3c7f44 100644
--- a/indra/newview/skins/default/xui/en/widgets/menu.xml
+++ b/indra/newview/skins/default/xui/en/widgets/menu.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu bg_color="MenuDefaultBgColor"
+<menu name="menu" 
+      bg_color="MenuDefaultBgColor"
       bg_visible="true"
       drop_shadow="true"
       tear_off="false"
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_bar.xml b/indra/newview/skins/default/xui/en/widgets/menu_bar.xml
new file mode 100644
index 0000000000000000000000000000000000000000..27efa72563568485adac534a39081df088274368
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/menu_bar.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu_bar
+			tear_off = "false"
+			keep_fixed_size = "true"
+			horizontal_layout = "true"
+			visible = "true"
+			drop_shadow = "false"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml b/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml
index e5cea476dae8c063aa07679c7e2af00109e65490..7452d685eba5d7bcd20e20214ae0fb0a6a54fa1c 100644
--- a/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml
+++ b/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <menu_item_separator enabled_color="MenuItemEnabledColor"
-	disabled_color="MenuItemDisabledColor"
-	highlight_bg_color="MenuItemHighlightBgColor"
-  highlight_fg_color="MenuItemHighlightFgColor">
+                     name="separator"
+                     disabled_color="MenuItemDisabledColor"
+                     highlight_bg_color="MenuItemHighlightBgColor"
+                     highlight_fg_color="MenuItemHighlightFgColor"
+                     label="-----------">
 </menu_item_separator>
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_item_tear_off.xml b/indra/newview/skins/default/xui/en/widgets/menu_item_tear_off.xml
index 185ed6ee3efa8f9c634e171948b719ab41a341c5..72af3924c184a397df0ea02e1211ad93d280de12 100644
--- a/indra/newview/skins/default/xui/en/widgets/menu_item_tear_off.xml
+++ b/indra/newview/skins/default/xui/en/widgets/menu_item_tear_off.xml
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <!-- Use "disabled color" to make it look like menu separators -->
 <menu_item_tear_off enabled_color="MenuItemDisabledColor"
-	disabled_color="MenuItemDisabledColor"
-	highlight_bg_color="MenuItemHighlightBgColor"
-  highlight_fg_color="MenuItemHighlightFgColor">
-</menu_item_tear_off>
+                    name="tear_off"
+              			label = "~~~~~~~~~~~"
+                    disabled_color="MenuItemDisabledColor"
+                    highlight_bg_color="MenuItemHighlightBgColor"
+                    highlight_fg_color="MenuItemHighlightFgColor"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/multi_slider.xml b/indra/newview/skins/default/xui/en/widgets/multi_slider.xml
index e0900b48f3b8a4b5d531559b50525fe6c71d4eb5..90b06259828c126a9af7bb4f28abf24a5a81b6d4 100644
--- a/indra/newview/skins/default/xui/en/widgets/multi_slider.xml
+++ b/indra/newview/skins/default/xui/en/widgets/multi_slider.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <multi_slider text_color="LabelTextColor"
-                  text_disabled_color="LabelDisabledColor"
-                  draw_track="true"
-                  use_triangle="false"
-                  font="SansSerifSmall"/>
+              mouse_opaque="true"
+              text_disabled_color="LabelDisabledColor"
+              draw_track="true"
+              use_triangle="false"
+              font="SansSerifSmall"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml b/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml
index 04a2cd635c80d61ce929b51fe4af880bd04c3bf3..bbcb008df4d86506f721acb2ed4943206670c18e 100644
--- a/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<multi_slider_bar track_color="MultiSliderTrackColor"
+<multi_slider_bar name="multi_slider_bar"
+                  track_color="MultiSliderTrackColor"
                   thumb_disabled_color="MultiSliderDisabledThumbColor"
                   thumb_outline_color="MultiSliderThumbOutlineColor"
                   thumb_center_color="MultiSliderThumbCenterColor"
@@ -7,4 +8,6 @@
                   triangle_color="MultiSliderTriangleColor"
                   draw_track="true"
                   use_triangle="false"
-                  thumb_width="8"/>
+                  thumb_width="8"
+                  mouse_opaque="true"
+                  follows="left|top"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/name_list.xml b/indra/newview/skins/default/xui/en/widgets/name_list.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3ae0f6822792a7c2719d1501031bf433f38666fe
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/name_list.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<name_list name="name_list"
+           />
diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
new file mode 100644
index 0000000000000000000000000000000000000000..07929961075f9c24174a607c85fa9c876604e93f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<outbox_folder_view_folder
+  folder_arrow_image="Folder_Arrow"
+  folder_indentation="8"
+  item_height="20" 
+  item_top_pad="4"
+  selection_image="Rounded_Square"
+  >
+  <error_badge 
+    label=" " 
+    label_offset_horiz="-1"
+    location="right" 
+    padding_horiz="12.5" 
+    padding_vert="2"
+    location_offset_hcenter="-23"
+    image="Error_Tag_Background"
+    image_color="Black"
+    />
+</outbox_folder_view_folder>
diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e3f20728196e2b51f9cd489e3e3477160396866f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<outbox_inventory_panel show_load_status="false" />
diff --git a/indra/newview/skins/default/xui/en/widgets/panel.xml b/indra/newview/skins/default/xui/en/widgets/panel.xml
index 47a210d9b70d989b6d086798196c06372728ea88..b36f723831d9eeae9f1ee13e04f8e26e8f360697 100644
--- a/indra/newview/skins/default/xui/en/widgets/panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/panel.xml
@@ -4,7 +4,8 @@
   bg_opaque_image - image name for "in-front" panel look
   bg_alpha_image - image name for "in-back" or transparent panel look
 -->
-<panel bg_opaque_color="PanelFocusBackgroundColor"
+<panel name="panel"
+       bg_opaque_color="PanelFocusBackgroundColor"
        bg_alpha_color="PanelDefaultBackgroundColor"
        bg_opaque_image_overlay="White"
        bg_alpha_image_overlay="White"
diff --git a/indra/newview/skins/default/xui/en/widgets/radio_group.xml b/indra/newview/skins/default/xui/en/widgets/radio_group.xml
index ad7ef5bffcb0df21a74671a43085379832f958a4..ab3184d34b3f636ebab75ef9c7e692dd9c59b13e 100644
--- a/indra/newview/skins/default/xui/en/widgets/radio_group.xml
+++ b/indra/newview/skins/default/xui/en/widgets/radio_group.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<radio_group draw_border="false"
-             name="radio_group"
+<radio_group name="radio_group"
              mouse_opaque="false"
              follows="left|top"
              font="SansSerifSmall"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml b/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml
index e6d4bff8b57521b3bd0b4ebf65753607cb369b8b..682dcf40d8b62c29f9832a2bd9568ac2f0fe9065 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml
@@ -5,7 +5,8 @@
 			track_image_horizontal ="ScrollTrack_Horiz"
 			track_color="ScrollbarTrackColor"
             thumb_color="ScrollbarThumbColor"
-            thickness="15">
+            thickness="15"
+            tab_stop="false">
   <up_button name="up_button"
              image_unselected="ScrollArrow_Up"
              image_selected="ScrollArrow_Up"
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml b/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml
index f936a1e208af0e08a843b39472889cbc95bc66f8..8a48fcb32d4e73157795957479c1b5588a597314 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml
@@ -1,11 +1,12 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<scroll_column_header
-		    image_unselected="SegmentedBtn_Middle_Selected"
+<scroll_column_header name="column_header"
+                      image_unselected="SegmentedBtn_Middle_Selected"
                       image_selected="SegmentedBtn_Middle_Selected"
-		      image_pressed="SegmentedBtn_Middle_Selected_Press"
+                      image_pressed="SegmentedBtn_Middle_Selected_Press"
                       image_disabled="SegmentedBtn_Middle_Disabled"
                       image_disabled_selected="SegmentedBtn_Middle_Selected_Disabled"
                       image_overlay="DisclosureArrow_Opened_Off"
                       image_overlay_alignment="right"
                       halign="left"
+                      tab_stop="false"
                       scale_image="true" />
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_container.xml b/indra/newview/skins/default/xui/en/widgets/scroll_container.xml
index 86356ff563eb82444972881f9368bd53ab21cbea..a6d096a964b2f1b5bad6d38de895c17023131442 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_container.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_container.xml
@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<scroll_container color="black"
+<scroll_container name="scroll_container"
+                  color="black"
                   opaque="false"
                   min_auto_scroll_rate="120"
-                  max_auto_scroll_rate="500"/>
+                  max_auto_scroll_rate="500"
+                  tab_stop="false"
+                  mouse_opaque="true" />
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
index dd9367580792eeb4af5a65b2f8db675a58648133..e43989c6c7d2b1c8d72aba97350e60a6f5df4da1 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<scroll_list fg_unselected_color="ScrollUnselectedColor"
+<scroll_list name="scroll_list" 
+             fg_unselected_color="ScrollUnselectedColor"
              fg_selected_color="ScrollSelectedFGColor"
              bg_selected_color="ScrollSelectedBGColor"
              fg_disable_color="ScrollDisabledColor"
@@ -13,6 +14,7 @@
              scroll_bar_bg_visible="false"
              scroll_bar_bg_color="black"
              mouse_wheel_opaque="false"
+             mouse_opaque="true"
              background_visible="true"
              heading_height="23"
              draw_border="false"
diff --git a/indra/newview/skins/default/xui/en/widgets/scrolling_panel_list.xml b/indra/newview/skins/default/xui/en/widgets/scrolling_panel_list.xml
new file mode 100644
index 0000000000000000000000000000000000000000..40cbf5977a863ac84dc488920a62f46885dcbf9f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/scrolling_panel_list.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<scrolling_panel_list name="scrolling_panel_list"/>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
index 32e443a0586c68488f83d65cc490c05de4eaa56d..faa0404b3547251814d9900bae85c8c33af1e3f7 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <search_editor
+  name="search_editor"
   clear_button_visible="false"
   search_button_visible="true"
   text_pad_left="6" 
diff --git a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
index ea63cac790f1211f7b13e5f75630357eb625fe35..0335213ed66f5995f5324fddfcaf5579a335367b 100644
--- a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <!--All horizontal sliders are configured to have no highlighted track. See EXT-5939. -->
-<slider_bar track_color="SliderTrackColor"
+<slider_bar follows="left|top"
+            track_color="SliderTrackColor"
             thumb_outline_color="SliderThumbOutlineColor"
             thumb_center_color="SliderThumbCenterColor"
             thumb_image="SliderThumb_Off"
diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml
index c37ead0be20ccdd6100a74f28b132bc2eb978202..3e2202b20fc5486448786fe78601bcfb2c1ec14d 100644
--- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml
+++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml
@@ -3,7 +3,9 @@
 label_pad_bottom - vertical padding under tab button labels
 label_pad_left - padding to the left of tab button labels
 -->
-<tab_container tab_min_width="60"
+<tab_container name="tab_container" 
+               mouse_opaque="false"
+               tab_min_width="60"
                tab_max_width="150"
                use_custom_icon_ctrl="false"
                halign="center"
diff --git a/indra/newview/skins/default/xui/en/widgets/text_editor.xml b/indra/newview/skins/default/xui/en/widgets/text_editor.xml
index 0f7f50b3129a7a1b14638208f65b6c706e08c6b3..100571cc01d8cf1bf6de2bd6ef1c61d39209885b 100644
--- a/indra/newview/skins/default/xui/en/widgets/text_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/text_editor.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <!-- Core parameters are in simple_text_editor.xml -->
 <text_editor
+  name="text_editor"
   parse_urls="false"
   show_context_menu="true"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml
index 757f0f49d1b028295cf43d90da9ae2ce0a0e14f2..ba2fdf4f1fe39d66d2e8214cc9b77e0ead036766 100644
--- a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml
+++ b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml
@@ -1,5 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<texture_picker border_color="DefaultHighlightLight">
+<texture_picker border_color="DefaultHighlightLight"
+                name="texture picker"
+                mouse_opaque="true"
+                follows="left|top"
+                >
   <multiselect_text font="SansSerifSmall"/>
   <caption_text text="Multiple" 
                 halign="center" 
diff --git a/indra/newview/skins/default/xui/en/widgets/view_border.xml b/indra/newview/skins/default/xui/en/widgets/view_border.xml
index 0b0a9beb95973724feb9a023d14ce02a11807027..bf40e3086bbaec00380ec9d54d5d693b491cf830 100644
--- a/indra/newview/skins/default/xui/en/widgets/view_border.xml
+++ b/indra/newview/skins/default/xui/en/widgets/view_border.xml
@@ -1,8 +1,11 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<view_border highlight_light_color="DefaultHighlightLight"
+<view_border name="view_border" 
+             highlight_light_color="DefaultHighlightLight"
              highlight_dark_color="DefaultHighlightDark"
              shadow_light_color="DefaultShadowLight"
              shadow_dark_color="DefaultShadowDark"
              border_thickness="1"
              border_style="line"
-             bevel_style="out"/>
\ No newline at end of file
+             bevel_style="out"
+             mouse_opaque="false"
+             follows="all"/>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/web_browser.xml b/indra/newview/skins/default/xui/en/widgets/web_browser.xml
index 118d63bbf0720d22fd8fb16295023345dc750578..676fafd828f88926bd2217f481322de19ffdb069 100644
--- a/indra/newview/skins/default/xui/en/widgets/web_browser.xml
+++ b/indra/newview/skins/default/xui/en/widgets/web_browser.xml
@@ -1,2 +1,4 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<web_browser border_visible="true"/>
+<web_browser border_visible="true"
+             tab_stop="false"
+             />
diff --git a/indra/newview/skins/default/xui/fr/floater_model_preview.xml b/indra/newview/skins/default/xui/fr/floater_model_preview.xml
index 2639339be5dd538a61b4cbd8821e08cc0cf13231..2b8e441ef08a34e2adc6936ba77652779f1c1c7b 100644
--- a/indra/newview/skins/default/xui/fr/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_model_preview.xml
@@ -131,7 +131,7 @@ Serveur :
 			<button label="Parcourir..." name="lod_browse"/>
 			<combo_box name="lod_mode">
 				<combo_item name="triangle_limit">
-					Limite du triangle
+					Triangles max.
 				</combo_item>
 				<combo_item name="error_threshold">
 					Seuil d&apos;erreur
@@ -141,7 +141,7 @@ Serveur :
 				Opér. construction :
 			</text>
 			<text name="queue_mode_text">
-				Mode fil d&apos;attente :
+				Mode file d&apos;attente :
 			</text>
 			<combo_box name="build_operator">
 				<combo_item name="edge_collapse">
@@ -244,7 +244,7 @@ Serveur :
 		Frais de chargement : [FEE] L$
 	</text>
 	<button label="Réinitialiser" name="reset_btn" tool_tip="Rétablir les paramètres par défaut."/>
-	<button label="Calculer les poids et les frais" name="calculate_btn" tool_tip="Calculer les poids et les frais."/>
+	<button label="Calculer poids et frais" name="calculate_btn" tool_tip="Calculer les poids et les frais."/>
 	<button label="Charger" name="ok_btn" tool_tip="Charger dans le simulateur."/>
 	<button label="Annuler" name="cancel_btn"/>
 </floater>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index e6d407f727058be6fb79c2429f67858bcae0992f..4b4eedab8e3962cee0c0db13f8752c7e0e52d63c 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -4228,7 +4228,7 @@ de l&apos;infraction signalée
 		/fumer
 	</string>
 	<string name="/stretch">
-		/s&apos;étirer
+		/bailler
 	</string>
 	<string name="/whistle">
 		/siffler
diff --git a/indra/newview/skins/minimal/xui/en/main_view.xml b/indra/newview/skins/minimal/xui/en/main_view.xml
index ec2683880a30fafc8f40d5b6d5fcf9ecd4151bb7..0ce6cbc98456ff6b1d93d83d6c88a2a6b524abe2 100644
--- a/indra/newview/skins/minimal/xui/en/main_view.xml
+++ b/indra/newview/skins/minimal/xui/en/main_view.xml
@@ -187,9 +187,9 @@
        name="status_bar_container"
        tab_stop="false"
        height="30"
-       left="-120"
+       left="-160"
        top="0"
-       width="120"
+       width="160"
        visible="false"/>
   <panel follows="top|bottom"
          height="500"
diff --git a/indra/newview/skins/minimal/xui/en/panel_login.xml b/indra/newview/skins/minimal/xui/en/panel_login.xml
index d89a0c6be16f0dde4d728281dfd62d743103d01e..40d2df78e13a91ff2ee27515fe2038ec32b87b89 100644
--- a/indra/newview/skins/minimal/xui/en/panel_login.xml
+++ b/indra/newview/skins/minimal/xui/en/panel_login.xml
@@ -118,16 +118,33 @@ label="Remember password"
   name="connect_btn"
   top="35"
   width="90" />
-  <menu_button
-left_pad="10"
-top="35"
-width="80"
-height="23"
-label="Mode â–²"
-name="mode_menu"
-tool_tip="Select your mode. Choose Basic for fast, easy exploration and chat. Choose Advanced to access more features."
-menu_filename="menu_mode_change.xml"
-    />
+  <text
+  follows="left|bottom"
+  font="SansSerifSmall"
+  height="15"
+  left_pad="10"
+  name="mode_selection_text"
+  top="20"
+  width="130">
+    Mode:
+  </text>
+  <combo_box
+  follows="left|bottom"
+  height="23"
+  max_chars="128"
+  tool_tip="Select your mode. Choose Basic for fast, easy exploration and chat. Choose Advanced to access more features."
+  top_pad="0"
+  name="mode_combo"
+  width="110">
+    <combo_box.item
+      label="Basic"
+      name="Basic"
+      value="settings_minimal.xml" />
+    <combo_box.item
+      label="Advanced"
+      name="Advanced"
+      value="" />
+  </combo_box>
 </layout_panel>
 <layout_panel
 tab_stop="false"
diff --git a/indra/newview/skins/minimal/xui/en/panel_navigation_bar.xml b/indra/newview/skins/minimal/xui/en/panel_navigation_bar.xml
index e50911b8d2187558df98b76e58b7627cd2eaba89..73a85642741f4fb28e580c3bb867bb0cb9161753 100644
--- a/indra/newview/skins/minimal/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/minimal/xui/en/panel_navigation_bar.xml
@@ -63,7 +63,7 @@ width="31" />
      mouse_opaque="false"
      name="location_combo"
      top_delta="0"
-     width="390">
+     width="325">
     </location_input>
     <icon follows="right"
           height="20"
diff --git a/indra/newview/skins/minimal/xui/en/panel_status_bar.xml b/indra/newview/skins/minimal/xui/en/panel_status_bar.xml
index 42e6f30d4827bf28a2b92dc1ba26ac2f7f0c1e79..fdd6b5d6ec5cdd25c957ae2f9e7195b6efe03c2d 100644
--- a/indra/newview/skins/minimal/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/minimal/xui/en/panel_status_bar.xml
@@ -12,7 +12,7 @@
  name="status"
  top="19"
  tab_stop="false"
- width="120">
+ width="185">
     <panel.string
      name="packet_loss_tooltip">
         Packet Loss
@@ -33,18 +33,27 @@
      name="buycurrencylabel">
         L$ [AMT]
     </panel.string>
-  <menu_button
-     follows="right|top"    
-    image_color="0 0 0 0"
-    hover_glow_amount="0"
-    left="5"
-    top="7"
-    width="55"  
-    height="18"
-    label="Mode â–¼"
-    tool_tip="Select your mode. Choose Basic for fast, easy exploration and chat. Choose Advanced to access more features."
-    menu_filename="menu_mode_change.xml"
-    />
+  <combo_box
+   follows="right|top"
+   left_pad="5"
+   drop_down_button.pad_left="10"
+   left="0"
+   top="5"
+   pad_left="5"
+   width="120"
+   height="23"
+   name="mode_combo"
+   tool_tip="Select your mode. Choose Basic for fast, easy exploration and chat. Choose Advanced to access more features."
+    >
+    <combo_box.item
+      label="Basic Mode"
+      name="Basic"
+      value="settings_minimal.xml" />
+    <combo_box.item
+      label="Advanced Mode"
+      name="Advanced"
+      value="" />
+  </combo_box>
      <button
      follows="right|top"
      height="16"
@@ -53,7 +62,7 @@
      image_pressed="Pause_Press"
      image_pressed_selected="Play_Press"
      is_toggle="true"
-     left="65"
+     left_pad="5"
      top="7"
      name="media_toggle_btn"
      tool_tip="Start/Stop All Media (Music, Video, Web pages)"
diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp
index acc6e814bc7a196d1f071cc6c79d4a15b9f68123..102294959a35ee15c9bcc75174144d6cd8b1fa03 100644
--- a/indra/newview/tests/llworldmap_test.cpp
+++ b/indra/newview/tests/llworldmap_test.cpp
@@ -27,7 +27,6 @@
 
 // Dependencies
 #include "linden_common.h"
-#include "llapr.h"
 #include "llsingleton.h"
 #include "lltrans.h"
 #include "lluistring.h"
diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp
index 09beb53869d4afcefa164840ebdfb6cc3b210b5a..532f26ee6086a3d56bbed28b2099dcd0f08b5f0c 100644
--- a/indra/test/lltemplatemessagebuilder_tut.cpp
+++ b/indra/test/lltemplatemessagebuilder_tut.cpp
@@ -29,7 +29,6 @@
 #include "linden_common.h"
 #include "lltut.h"
 
-#include "llapr.h"
 #include "llmessagetemplate.h"
 #include "llquaternion.h"
 #include "lltemplatemessagebuilder.h"
@@ -53,7 +52,6 @@ namespace tut
 			static bool init = false;
 			if(! init)
 			{
-				ll_init_apr();
 				const F32 circuit_heartbeat_interval=5;
 				const F32 circuit_timeout=100;
 
diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp
index d971b334752dc1c99e5c7bc80d62f84430a62a10..9a6ccd4d6819cb8935af4e52cc987bb4ac40998d 100644
--- a/indra/test/message_tut.cpp
+++ b/indra/test/message_tut.cpp
@@ -29,7 +29,6 @@
 #include "linden_common.h"
 #include "lltut.h"
 
-#include "llapr.h"
 #include "llmessageconfig.h"
 #include "llsdserialize.h"
 #include "llversionserver.h"
@@ -62,7 +61,6 @@ namespace tut
 			static bool init = false;
 			if(!init)
 			{
-				ll_init_apr();
 				//init_prehash_data();
 				init = true;
 			}
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index ffdb0cb976a311f79a8233ddc4fa7409f139473e..45e8aef99a972b8be9e726c6f4d66ac521d17fcb 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -37,8 +37,8 @@
 #include "linden_common.h"
 #include "llerrorcontrol.h"
 #include "lltut.h"
+#include "llaprpool.h"
 
-#include "apr_pools.h"
 #include "apr_getopt.h"
 
 // the CTYPE_WORKAROUND is needed for linux dev stations that don't
@@ -349,17 +349,12 @@ int main(int argc, char **argv)
 	ctype_workaround();
 #endif
 
-	apr_initialize();
-	apr_pool_t* pool = NULL;
-	if(APR_SUCCESS != apr_pool_create(&pool, NULL))
-	{
-		std::cerr << "Unable to initialize pool" << std::endl;
-		return 1;
-	}
+	LLAPRPool pool;
+	pool.create();
 	apr_getopt_t* os = NULL;
-	if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv))
+	if(APR_SUCCESS != apr_getopt_init(&os, pool(), argc, argv))
 	{
-		std::cerr << "Unable to  pool" << std::endl;
+		std::cerr << "Unable to initialize the arguments for parsing by apr_getopt()." << std::endl;
 		return 1;
 	}
 
@@ -477,8 +472,6 @@ int main(int argc, char **argv)
 		s.close();
 	}
 
-	apr_terminate();
-
 	int retval = (success ? 0 : 1);
 	return retval;
 
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index 884b00f0ccba6f96325047e51614638ffa24eb9d..d5ee09c5bc3a35f41c7593b01bacdff72b08c181 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -27,7 +27,6 @@
 #include "linden_common.h"
 #include "indra_constants.h"
 
-#include "llapr.h"
 #include "llerrorcontrol.h"
 
 #include <math.h>
@@ -186,9 +185,6 @@ LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int wind
 		std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl;
 	};
 
-	// initialize linden lab APR module
-	ll_init_apr();
-
 	// Set up llerror logging
 	{
 		LLError::initForApplication(".");
diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
index c7b70c2de8e91fcd8deec2075c3a66f9df8f8675..24ba00ad8e6db18c3a29ede865cbff8d68e480a1 100644
--- a/indra/viewer_components/updater/llupdateinstaller.cpp
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -26,6 +26,7 @@
 #include "linden_common.h"
 #include <apr_file_io.h>
 #include "llapr.h"
+#include "llscopedvolatileaprpool.h"
 #include "llprocesslauncher.h"
 #include "llupdateinstaller.h"
 #include "lldir.h" 
@@ -45,7 +46,8 @@ namespace {
 	{
 		std::string scriptFile = gDirUtilp->getBaseFileName(path);
 		std::string newPath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, scriptFile);
-		apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, gAPRPoolp);
+		LLScopedVolatileAPRPool pool;
+		apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, pool);
 		if(status != APR_SUCCESS) throw RelocateError();
 		
 		return newPath;
diff --git a/scripts/gpu_table_tester b/scripts/gpu_table_tester
old mode 100644
new mode 100755
diff --git a/scripts/templates/template-cpp.cpp b/scripts/templates/template-cpp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..35d8441c87e4d6bb9d4870a12552844ba2c3ec58
--- /dev/null
+++ b/scripts/templates/template-cpp.cpp
@@ -0,0 +1,30 @@
+/** 
+* @file #filename#.cpp
+* @brief Implementation of #filename#
+* @author #getpass.getuser()#@lindenlab.com
+*
+* $LicenseInfo:firstyear=#datetime.datetime.now().year#&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) #datetime.datetime.now().year#, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+
+#'' if ( skip_h ) else '%cinclude "%s.h"' % (35,filename)#
+
diff --git a/scripts/templates/template-h.h b/scripts/templates/template-h.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce7b4ddc8774c2d9c881a4d58e18dc4ce2c61833
--- /dev/null
+++ b/scripts/templates/template-h.h
@@ -0,0 +1,31 @@
+/** 
+* @file   #filename#.h
+* @brief  Header file for #filename#
+* @author #getpass.getuser()#@lindenlab.com
+*
+* $LicenseInfo:firstyear=#datetime.datetime.now().year#&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) #datetime.datetime.now().year#, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#'%c'%35#ifndef LL_#filename.upper().replace('-','_')#_H
+#'%c'%35#define LL_#filename.upper().replace('-','_')#_H
+
+
+#'%c'%35#endif // LL_#filename.upper().replace('-','_')#_H