diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index c5ba23f68cfbc25c924c5bec41217c50d772f7cd..4bab669046c289767360347d7c5e2f88bc186f18 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -35,6 +35,7 @@
 // external library headers
 #include <boost/bind.hpp>
 // other Linden headers
+#include "lltimer.h"
 #include "llevents.h"
 #include "llerror.h"
 #include "stringize.h"
@@ -280,6 +281,21 @@ void LLCoros::setStackSize(S32 stacksize)
     mStackSize = stacksize;
 }
 
+void LLCoros::printActiveCoroutines()
+{
+    LL_INFOS("LLCoros") << "-------------- List of active coroutines ------------";
+    CoroMap::iterator iter;
+    CoroMap::iterator end = mCoros.end();
+    F64 time = LLTimer::getTotalSeconds();
+    for (iter = mCoros.begin(); iter != end; iter++)
+    {
+        F64 life_time = time - iter->second->mCreationTime;
+        LL_CONT << LL_NEWLINE << "Name: " << iter->first << " life: " << life_time;
+    }
+    LL_CONT << LL_ENDL;
+    LL_INFOS("LLCoros") << "-----------------------------------------------------" << LL_ENDL;
+}
+
 #if LL_WINDOWS
 
 static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
@@ -375,7 +391,8 @@ LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name,
     mCoro(boost::bind(toplevel, _1, this, callable), stacksize),
     // don't consume events unless specifically directed
     mConsuming(false),
-    mSelf(0)
+    mSelf(0),
+    mCreationTime(LLTimer::getTotalSeconds())
 {
 }
 
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 884d6b159c5a3fc21b70ef6e80da618555225c76..8fb27af6a474d175b3d6d49505bbb2df54e261dd 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -151,6 +151,9 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
     /// for delayed initialization
     void setStackSize(S32 stacksize);
 
+    /// for delayed initialization
+    void printActiveCoroutines();
+
     /// get the current coro::self& for those who really really care
     static coro::self& get_self();
 
@@ -223,6 +226,7 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
         // function signature down to that point -- and of course through every
         // other caller of every such function.
         LLCoros::coro::self* mSelf;
+        F64 mCreationTime; // since epoch
     };
     typedef boost::ptr_map<std::string, CoroData> CoroMap;
     CoroMap mCoros;
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index f31a054139ee23cf9268dab395055b3b7cf981ef..29de79dc6423efc167280989a1d86fe966aa8030 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -249,23 +249,13 @@ namespace LLError
 	{
 #ifdef __GNUC__
 		// GCC: type_info::name() returns a mangled class name,st demangle
-
-		static size_t abi_name_len = 100;
-		static char* abi_name_buf = (char*)malloc(abi_name_len);
-			// warning: above is voodoo inferred from the GCC manual,
-			// do NOT change
-
-		int status;
-			// We don't use status, and shouldn't have to pass apointer to it
-			// but gcc 3.3 libstc++'s implementation of demangling is broken
-			// and fails without.
-			
-		char* name = abi::__cxa_demangle(mangled,
-										abi_name_buf, &abi_name_len, &status);
-			// this call can realloc the abi_name_buf pointer (!)
-
-		return name ? name : mangled;
-
+        // passing nullptr, 0 forces allocation of a unique buffer we can free
+        // fixing MAINT-8724 on OSX 10.14
+		int status = -1;
+		char* name = abi::__cxa_demangle(mangled, nullptr, 0, &status);
+        std::string result(name ? name : mangled);
+        free(name);
+        return result;
 #elif LL_WINDOWS
 		// DevStudio: type_info::name() includes the text "class " at the start
 
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index 49d865cbfaa79749c6fbe10384a5aa64f425ee88..0b72b5318601f92834dadb93df0cfd968838576e 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -95,10 +95,12 @@ HttpService::~HttpService()
 			if (! mThread->timedJoin(250))
 			{
 				// Failed to join, expect problems ahead so do a hard termination.
-				mThread->cancel();
+				LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread.  Expect problems." << LL_NEWLINE
+									<< "State: " << S32(sState)
+									<< " Last policy: " << U32(mLastPolicy)
+									<< LL_ENDL;
 
-				LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread.  Expect problems."
-								   << LL_ENDL;
+				mThread->cancel();
 			}
 		}
 	}
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index e3e605d040aae7aa7ed8bc808520e5bfe3ede00c..1312f6afda3f3e8bee997d70d10614d6215a6384 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -192,7 +192,13 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
 				ret = (U8*) ll_aligned_malloc<64>(size);
 				if (!ret)
 				{
-					LL_ERRS() << "Failed to allocate for LLVBOPool buffer" << LL_ENDL;
+					LL_ERRS() << "Failed to allocate "<< size << " bytes for LLVBOPool buffer " << name <<"." << LL_NEWLINE
+							  << "Free list size: " << mFreeList.size() // this happens if we are out of memory so a solution might be to clear some from freelist
+							  << " Allocated Bytes: " << LLVertexBuffer::sAllocatedBytes
+							  << " Allocated Index Bytes: " << LLVertexBuffer::sAllocatedIndexBytes
+							  << " Pooled Bytes: " << sBytesPooled
+							  << " Pooled Index Bytes: " << sIndexBytesPooled
+							  << LL_ENDL;
 				}
 			}
 		}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 212e27477ba70f94f9e1e91a07352e3336fe11ee..ed65b1e45f1b6cb55a3fcb9be4d50ae7322800fd 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -2784,7 +2784,6 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
 	}
 
 	// if this column is the primary sort key, reverse the direction
-	sort_column_t cur_sort_column;
 	if (!parent->mSortColumns.empty() && parent->mSortColumns.back().first == column_index)
 	{
 		ascending = !parent->mSortColumns.back().second;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b7a860aae095d39215c0297f7c6e8f90adb4cd25..367d4577caee4a6b3a0d47bdf95368c0ff38dbc4 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2055,7 +2055,12 @@ if (DARWIN)
   # These all get set with PROPERTIES
   set(product "Second Life")
   # this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
-  set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
+  if (PACKAGE)
+      set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
+  else (PACKAGE)
+      # force the name of the actual executable to allow running it within Xcode for debugging
+      set(MACOSX_WRAPPER_EXECUTABLE_NAME "../Resources/Second Life Viewer.app/Contents/MacOS/Second Life")
+  endif (PACKAGE)
   set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
   set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
   set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f0782e0bf780c482ad9bfc2aa3a0e72db5a5cea2..a01435626f64608785166158545b9921bb2a88a6 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -3703,13 +3703,13 @@
 	<key>FeatureManagerHTTPTable</key>
       <map>
         <key>Comment</key>
-        <string>Base directory for HTTP feature/gpu table fetches</string>
+        <string>Deprecated</string>
         <key>Persist</key>
-        <integer>1</integer>
+        <integer>0</integer>
         <key>Type</key>
         <string>String</string>
         <key>Value</key>
-        <string>http://viewer-settings.secondlife.com</string>
+        <string></string>
     </map>
     <key>FPSLogFrequency</key>
         <map>
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 5b9f1b9d4fd31d45c0736e7a6832ade9d08e5add..92a30260964a2fe8aeb7a63b83672106c3dadf72 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -76,6 +76,8 @@ const F32 AVATAR_ZOOM_MIN_Y_FACTOR = 0.7f;
 const F32 AVATAR_ZOOM_MIN_Z_FACTOR = 1.15f;
 
 const F32 MAX_CAMERA_DISTANCE_FROM_AGENT = 50.f;
+const F32 MAX_CAMERA_DISTANCE_FROM_OBJECT = 496.f;
+const F32 CAMERA_FUDGE_FROM_OBJECT = 16.f;
 
 const F32 MAX_CAMERA_SMOOTH_DISTANCE = 50.0f;
 
@@ -738,10 +740,7 @@ F32 LLAgentCamera::getCameraZoomFraction()
 	else
 	{
 		F32 min_zoom;
-		const F32 DIST_FUDGE = 16.f; // meters
-		F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE, 
-								LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
-								MAX_CAMERA_DISTANCE_FROM_AGENT);
+		F32 max_zoom = getCameraMaxZoomDistance();
 
 		F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
 		if (mFocusObject.notNull())
@@ -787,23 +786,17 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
 	else
 	{
 		F32 min_zoom = LAND_MIN_ZOOM;
-		const F32 DIST_FUDGE = 16.f; // meters
-		F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE, 
-								LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
-								MAX_CAMERA_DISTANCE_FROM_AGENT);
+		F32 max_zoom = getCameraMaxZoomDistance();
 
 		if (mFocusObject.notNull())
 		{
-			if (mFocusObject.notNull())
+			if (mFocusObject->isAvatar())
 			{
-				if (mFocusObject->isAvatar())
-				{
-					min_zoom = AVATAR_MIN_ZOOM;
-				}
-				else
-				{
-					min_zoom = OBJECT_MIN_ZOOM;
-				}
+				min_zoom = AVATAR_MIN_ZOOM;
+			}
+			else
+			{
+				min_zoom = OBJECT_MIN_ZOOM;
 			}
 		}
 
@@ -909,10 +902,7 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
 
 	new_distance = llmax(new_distance, min_zoom); 
 
-	// Don't zoom too far back
-	const F32 DIST_FUDGE = 16.f; // meters
-	F32 max_distance = llmin(mDrawDistance - DIST_FUDGE, 
-							 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
+	F32 max_distance = getCameraMaxZoomDistance();
 
     max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance.  MAINT-3154
 
@@ -978,10 +968,7 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters)
 
 		new_distance = llmax(new_distance, min_zoom);
 
-		// Don't zoom too far back
-		const F32 DIST_FUDGE = 16.f; // meters
-		F32 max_distance = llmin(mDrawDistance - DIST_FUDGE, 
-								 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
+		F32 max_distance = getCameraMaxZoomDistance();
 
 		if (new_distance > max_distance)
 		{
@@ -1946,6 +1933,13 @@ LLVector3 LLAgentCamera::getCameraOffsetInitial()
 	return convert_from_llsd<LLVector3>(mCameraOffsetInitial[mCameraPreset]->get(), TYPE_VEC3, "");
 }
 
+F32 LLAgentCamera::getCameraMaxZoomDistance()
+{
+    // Ignore "DisableCameraConstraints", we don't want to be out of draw range when we focus onto objects or avatars
+    return llmin(MAX_CAMERA_DISTANCE_FROM_OBJECT,
+                 mDrawDistance - 1, // convenience, don't hit draw limit when focusing on something
+                 LLWorld::getInstance()->getRegionWidthInMeters() - CAMERA_FUDGE_FROM_OBJECT);
+}
 
 //-----------------------------------------------------------------------------
 // handleScrollWheel()
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
index ab793ff316b2ea54eef884323d6b81506b66a07b..d087de1e2ff5d55227ea3bb700faf579b818f139 100644
--- a/indra/newview/llagentcamera.h
+++ b/indra/newview/llagentcamera.h
@@ -112,6 +112,8 @@ class LLAgentCamera
 private:
 	/** Determines default camera offset depending on the current camera preset */
 	LLVector3 getCameraOffsetInitial();
+	/** Determines maximum camera distance from target for mouselook, opposite to LAND_MIN_ZOOM */
+	F32 getCameraMaxZoomDistance();
 
 	/** Camera preset in Third Person Mode */
 	ECameraPreset mCameraPreset; 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f705084bdbccb2fd709329e9fe5b1bf92a1d8f6e..b9e26573518a14de30f4e0c97eaf157a34b9b157 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1082,6 +1082,8 @@ bool LLAppViewer::init()
 		}
 	}
 
+// don't nag developers who need to run the executable directly
+#if LL_RELEASE_FOR_DOWNLOAD
 	// MAINT-8305: If we're processing a SLURL, skip the launcher check.
 	if (gSavedSettings.getString("CmdLineLoginLocation").empty())
 	{
@@ -1098,6 +1100,7 @@ bool LLAppViewer::init()
 			LLNotificationsUtil::add("RunLauncher");
 		}
 	}
+#endif
 
 #if LL_WINDOWS
 	if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
@@ -1794,6 +1797,8 @@ bool LLAppViewer::cleanup()
 	// (Deleted observers should have already removed themselves)
 	gInventory.cleanupInventory();
 
+	LLCoros::getInstance()->printActiveCoroutines();
+
 	LL_INFOS() << "Cleaning up Selections" << LL_ENDL;
 
 	// Clean up selection managers after UI is destroyed, as UI may be observing them.
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index 7413dbed20049131d5a6728f0c5be8f778248675..7c7f55f68c6a5802999ef1a0095f47543b02b95f 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -286,6 +286,9 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
         && regionp->getRenderInfoReportTimer().hasExpired() // Time to make request)
         )
 	{
+        // make sure we won't re-report, coro will update timer with correct time later
+        regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS);
+
         std::string coroname =
             LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
             boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
@@ -306,6 +309,9 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
             << " from " << url
             << LL_ENDL;
 
+        // make sure we won't re-request, coro will update timer with correct time later
+        regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST);
+
 		// First send a request to get the latest data
         std::string coroname =
             LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 8f1641e908bc98d2e07cb8b92374440130988171..487496df9a3691a16d809525d721ccc2a2a555c4 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -62,13 +62,10 @@
 
 #if LL_DARWIN
 const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_mac.%s.txt";
 #elif LL_LINUX
 const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_linux.%s.txt";
 #else
 const char FEATURE_TABLE_FILENAME[] = "featuretable.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable.%s.txt";
 #endif
 
 #if 0                               // consuming code in #if 0 below
@@ -273,33 +270,11 @@ bool LLFeatureManager::loadFeatureTables()
 	app_path += gDirUtilp->getDirDelimiter();
 
 	std::string filename;
-	std::string http_filename; 
 	filename = FEATURE_TABLE_FILENAME;
-	http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
 
 	app_path += filename;
 
-	// second table is downloaded with HTTP - note that this will only be used on the run _after_ it is downloaded
-	std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
-
-	// use HTTP table if it exists
-	std::string path;
-	bool parse_ok = false;
-	if (gDirUtilp->fileExists(http_path))
-	{
-		parse_ok = parseFeatureTable(http_path);
-		if (!parse_ok)
-		{
-			// the HTTP table failed to parse, so delete it
-			LLFile::remove(http_path);
-			LL_WARNS("RenderInit") << "Removed invalid feature table '" << http_path << "'" << LL_ENDL;
-		}
-	}
-
-	if (!parse_ok)
-	{
-		parse_ok = parseFeatureTable(app_path);
-	}
+	bool parse_ok = parseFeatureTable(app_path);
 
 	return parse_ok;
 }
@@ -495,70 +470,6 @@ bool LLFeatureManager::loadGPUClass()
 	return true; // indicates that a gpu value was established
 }
 
-void LLFeatureManager::fetchFeatureTableCoro(std::string tableName)
-{
-    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
-    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FeatureManagerHTTPTable", httpPolicy));
-    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-
-    const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable");
-
-
-#if LL_WINDOWS
-    std::string os_string = LLOSInfo::instance().getOSStringSimple();
-    std::string filename;
-
-    if (os_string.find("Microsoft Windows XP") == 0)
-    {
-        filename = llformat(tableName.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
-    }
-    else
-    {
-        filename = llformat(tableName.c_str(), "", LLVersionInfo::getVersion().c_str());
-    }
-#else
-    const std::string filename   = llformat(tableName.c_str(), LLVersionInfo::getVersion().c_str());
-#endif
-
-    std::string url        = base + "/" + filename;
-    // testing url below
-    //url = "http://viewer-settings.secondlife.com/featuretable.2.1.1.208406.txt";
-    const std::string path       = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
-
-
-    LL_INFOS() << "LLFeatureManager fetching " << url << " into " << path << LL_ENDL;
-
-    LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url);
-
-    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
-    if (status)
-    {   // There was a newer feature table on the server. We've grabbed it and now should write it.
-        // write to file
-        const LLSD::Binary &raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
-
-        LL_INFOS() << "writing feature table to " << path << LL_ENDL;
-
-        S32 size = raw.size();
-        if (size > 0)
-        {
-            // write to file
-            LLAPRFile out(path, LL_APR_WB);
-            out.write(raw.data(), size);
-            out.close();
-        }
-    }
-}
-
-// fetch table(s) from a website (S3)
-void LLFeatureManager::fetchHTTPTables()
-{
-    LLCoros::instance().launch("LLFeatureManager::fetchFeatureTableCoro",
-        boost::bind(&LLFeatureManager::fetchFeatureTableCoro, this, FEATURE_TABLE_VER_FILENAME));
-}
-
 void LLFeatureManager::cleanupFeatureTables()
 {
 	std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 54bd07329a9541fd8ea5176610724c99fb31ea44..f77861a1a754f4efa001027f946ac55897000d46 100644
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -145,9 +145,6 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag
 	// in the skip list if true
 	void applyFeatures(bool skipFeatures);
 
-	// load the dynamic GPU/feature table from a website
-	void fetchHTTPTables();
-
 	LLSD getRecommendedSettingsMap();
 
 protected:
@@ -158,8 +155,6 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag
 
 	void initBaseMask();
 
-    void fetchFeatureTableCoro(std::string name);
-
 	std::map<std::string, LLFeatureList *> mMaskList;
 	std::set<std::string> mSkippedFeatures;
 	BOOL		mInited;
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 9fb53dc9ab72576f7a63719e854fce2d087b8762..0f38cca56f20a5a3117da393491e4e59fc6ee78e 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -263,7 +263,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
 	addEntry(DAD_CLOTHING, 		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, 				&LLToolDragAndDrop::dad3dGiveInventory, 		&LLToolDragAndDrop::dad3dUpdateInventory, 			&LLToolDragAndDrop::dad3dNULL));
 	addEntry(DAD_OBJECT, 		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dRezAttachmentFromInv,	&LLToolDragAndDrop::dad3dGiveInventoryObject,	&LLToolDragAndDrop::dad3dRezObjectOnObject, 		&LLToolDragAndDrop::dad3dRezObjectOnLand));
 	addEntry(DAD_NOTECARD, 		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, 					&LLToolDragAndDrop::dad3dGiveInventory, 		&LLToolDragAndDrop::dad3dUpdateInventory, 			&LLToolDragAndDrop::dad3dNULL));
-	addEntry(DAD_CATEGORY, 		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory,			&LLToolDragAndDrop::dad3dGiveInventoryCategory,	&LLToolDragAndDrop::dad3dUpdateInventoryCategory,	&LLToolDragAndDrop::dad3dNULL));
+	addEntry(DAD_CATEGORY,		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory,			&LLToolDragAndDrop::dad3dGiveInventoryCategory,	&LLToolDragAndDrop::dad3dRezCategoryOnObject,		&LLToolDragAndDrop::dad3dNULL));
 	addEntry(DAD_ROOT_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL,	&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dNULL,						&LLToolDragAndDrop::dad3dNULL));
 	addEntry(DAD_BODYPART, 		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL,	&LLToolDragAndDrop::dad3dWearItem,				&LLToolDragAndDrop::dad3dGiveInventory,			&LLToolDragAndDrop::dad3dUpdateInventory,			&LLToolDragAndDrop::dad3dNULL));
 	addEntry(DAD_ANIMATION, 	new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL,	&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dGiveInventory,			&LLToolDragAndDrop::dad3dUpdateInventory,			&LLToolDragAndDrop::dad3dNULL));
@@ -2335,6 +2335,21 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory(
 	return rv;
 }
 
+
+EAcceptance LLToolDragAndDrop::dad3dRezCategoryOnObject(
+	LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+	if ((mask & MASK_CONTROL))
+	{
+		return dad3dUpdateInventoryCategory(obj, face, mask, drop);
+	}
+	else
+	{
+		return ACCEPT_NO;
+	}
+}
+
+
 BOOL LLToolDragAndDrop::dadUpdateInventoryCategory(LLViewerObject* obj,
 												   BOOL drop)
 {
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 2d99de224429c06ebc5ffdc33c5ba5fffa973eba..24a712029c9e30ed735f8e75335be0382a3a434e 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -162,6 +162,8 @@ class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop>
 									 MASK mask, BOOL drop);
 	EAcceptance dad3dRezObjectOnObject(LLViewerObject* obj, S32 face,
 									   MASK mask, BOOL drop);
+	EAcceptance dad3dRezCategoryOnObject(LLViewerObject* obj, S32 face,
+										 MASK mask, BOOL drop);
 	EAcceptance dad3dRezScript(LLViewerObject* obj, S32 face,
 							   MASK mask, BOOL drop);
 	EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face,