diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 96028e3f8f4646bc87633d18c02004b01cbad02d..1a9202ec909703112a75ef6258529b24644a6585 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -695,6 +695,14 @@ void LLAvatarActions::csr(const LLUUID& id, std::string name)
 //static 
 void LLAvatarActions::share(const LLUUID& id)
 {
+// [RLVa:KB] - @share
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(id)) )
+	{
+		RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", id));
+		return;
+	}
+// [/RLVa:KB]
+
 	LLSD key;
 	LLFloaterSidePanelContainer::showPanel("inventory", key);
 	LLFloaterReg::showInstance("im_container");
@@ -913,10 +921,34 @@ namespace action_give_inventory
 	 * @param avatar_names - avatar names request to be sent.
 	 * @param avatar_uuids - avatar names request to be sent.
 	 */
-	static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL)
+//	static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL)
+// [RLVa:KB] - @share
+	static void give_inventory(uuid_vec_t avatar_uuids, std::vector<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL)
+// [/RLVa:KB]
 	{
 		llassert(avatar_names.size() == avatar_uuids.size());
 
+// [RLVa:KB] - @share
+		if ( (RlvActions::isRlvEnabled()) && (RlvActions::hasBehaviour(RLV_BHVR_SHARE)) )
+		{
+			for (int idxAvatar = avatar_uuids.size() - 1; idxAvatar >= 0; idxAvatar--)
+			{
+				if (!RlvActions::canGiveInventory(avatar_uuids[idxAvatar]))
+				{
+					RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", avatar_uuids[idxAvatar], "completename").getSLURLString()));
+
+					avatar_uuids.erase(avatar_uuids.begin() + idxAvatar);
+					avatar_names.erase(avatar_names.begin() + idxAvatar);
+				}
+			}
+		}
+
+		if (avatar_uuids.empty())
+		{
+			return;
+		}
+// [/RLVa:KB]
+
 		const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel);
 		if (inventory_selected_uuids.empty())
 		{
@@ -1039,6 +1071,14 @@ std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs(LLInventoryPanel* ac
 //static
 void LLAvatarActions::shareWithAvatars(LLView * panel)
 {
+// [RLVa:KB] - @share
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory()) )
+	{
+		RlvUtil::notifyBlocked(RlvStringKeys::Blocked::ShareGeneric);
+		return;
+	}
+// [/RLVa:KB]
+
 	using namespace action_give_inventory;
 
 	LLFloater* root_floater = gFloaterView->getParentFloater(panel);
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index a59262180a05c18f758f82e8b63e451fc2834c81..c0306c2c145c353a0b3fe096ed0a7fad57f53744 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -49,6 +49,7 @@
 #include "llvoavatarself.h"
 // [RLVa:KB] - Checked: RLVa-1.2.2
 #include "llavatarnamecache.h"
+#include "llslurl.h"
 #include "rlvactions.h"
 #include "rlvcommon.h"
 #include "rlvui.h"
@@ -200,7 +201,10 @@ bool LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent,
 	if (item->getPermissions().allowCopyBy(gAgentID))
 	{
 		// just give it away.
-		LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id);
+// [RLVa:KB] - @share
+		res = LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id);
+// [/RLVa:KB]
+//		LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id);
 	}
 	else
 	{
@@ -361,6 +365,14 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL
 	switch(option)
 	{
 	case 0:  // "Yes"
+// [RLVa:KB] - @share
+		if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(notification["payload"]["agent_id"].asUUID())) )
+		{
+			RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", notification["payload"]["agent_id"], "completename").getSLURLString()));
+			return false;
+		}
+// [/RLVa:KB]
+
 		for (LLSD::array_iterator it = itmes.beginArray(); it != itmes.endArray(); it++)
 		{
 			item = gInventory.getItem((*it).asUUID());
@@ -394,11 +406,24 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL
 }
 
 // static
-void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
+//void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
+//												const LLInventoryItem* item,
+//												const LLUUID& im_session_id)
+// [RLVa:KB] - @share
+bool LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
 												const LLInventoryItem* item,
 												const LLUUID& im_session_id)
+// [/RLVa:KB]
 {
-	if (!item) return;
+//	if (!item) return;
+// [RLVa:KB] - @share
+	if (!item) return false;
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(to_agent)) )
+	{
+		return false;
+	}
+// [/RLVa:KB]
+
 	std::string name;
 	std::string item_name = item->getName();
 	LLAgentUI::buildFullname(name);
@@ -451,6 +476,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
 	{
 		LLRecentPeople::instance().add(to_agent);
 	}
+	return true;
 // [/RLVa:KB]
 }
 
@@ -466,6 +492,14 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons
 		cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID());
 		if (cat)
 		{
+// [RLVa:KB] - @share
+			if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(notification["payload"]["agent_id"].asUUID())) )
+			{
+				RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", notification["payload"]["agent_id"], "completename").getSLURLString()));
+				return false;
+			}
+// [/RLVa:KB]
+
 			give_successful = LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
 				cat);
 			LLViewerInventoryCategory::cat_array_t cats;
@@ -513,6 +547,13 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
 	{
 		return false;
 	}
+// [RLVa:KB] - @share
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(to_agent)) )
+	{
+		return false;
+	}
+// [/RLVa:KB]
+
 	LL_INFOS() << "LLGiveInventory::commitGiveInventoryCategory() - "
 		<< cat->getUUID() << LL_ENDL;
 
diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h
index 20e6df76e5c7add2d46fade4f917b319e522e43a..86919f90104fe674e03143f01f914412c31edc03 100644
--- a/indra/newview/llgiveinventory.h
+++ b/indra/newview/llgiveinventory.h
@@ -82,9 +82,14 @@ class LLGiveInventory
 									const std::string& item_name = std::string(),
 									bool is_folder = false);
 
-	static void commitGiveInventoryItem(const LLUUID& to_agent,
+// [RLVa:KB] - @share
+	static bool commitGiveInventoryItem(const LLUUID& to_agent,
 									const LLInventoryItem* item,
 									const LLUUID &im_session_id = LLUUID::null);
+// [/RLVa:KB]
+//	static void commitGiveInventoryItem(const LLUUID& to_agent,
+//									const LLInventoryItem* item,
+//									const LLUUID &im_session_id = LLUUID::null);
 
 	// give inventory category functionality
 	static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response);
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index d4f3ba4773f47e3b7b80975408dd1c81f8172d2e..083b4a98ddb9b96088a2757a6f5b2894f30b9df0 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -78,13 +78,11 @@ const F32 PARCEL_POST_HEIGHT = 0.666f;
 // Returns true if you got at least one object
 void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 {
-// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c
+// [RLVa:KB] - @edit* and @interact
 	// Block rectangle selection if:
-	//   - prevented from editing and no exceptions are set (see below for the case where exceptions are set)
+	//   - prevented from editing anything at all
 	//   - prevented from interacting at all
-	if ( (rlv_handler_t::isEnabled()) && 
-		 ( ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasException(RLV_BHVR_EDIT))) || 
-		   (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) ) )
+	if (RlvActions::isRlvEnabled() && (RlvActions::canEdit(ERlvCheckType::None) || RlvActions::hasBehaviour(RLV_BHVR_INTERACT)) )
 	{
 		return;
 	}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 6a17c84be815d831eea0264258279abda21c74d2..2dee36662f15c22f0902f5d77573f8a25974bdd6 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -6043,6 +6043,19 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
 	BOOL rv = FALSE;
 	if(item)
 	{
+// [RLVa:KB] - @share
+		if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(item->getCreatorUUID())) )
+		{
+			if (drop)
+			{
+				RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", item->getCreatorUUID(), "completename").getSLURLString()));
+			}
+			// We should return false but our caller uses the return value as both 'will accept' *and* 'was handled' so
+			// returning false will result in the dropped item being moved when it is blocked.
+			return true;
+		}
+// [/RLVa:KB]
+
 		// check the type
 		switch(cargo_type)
 		{
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index f7216bab71cfbf524cbf12c231dfb5f35382e487..8f63c59f81cfc74a9365b86ae5129ba0449c258e 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -4367,8 +4367,9 @@ void LLSelectMgr::convertTransient()
 
 void LLSelectMgr::deselectAllIfTooFar()
 {
-// [RLVa:KB] - Checked: RLVa-1.3.0
-	if ( (!mSelectedObjects->isEmpty()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ))) )
+// [RLVa:KB] - @edit*
+	// Continuously verify the selection as soon as there is at least one prim we shouldn't be able to edit
+	if ( !mSelectedObjects->isEmpty() && RlvActions::isRlvEnabled() && !RlvActions::canEdit(ERlvCheckType::All) )
 	{
 		struct NotTransientOrFocusedMediaOrEditable : public LLSelectedNodeFunctor
 		{
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 806fd523c6d52db0fd9cb622170809ae9a5e3279..476480aa8bac0e11ff966a010d24ea067f1151e3 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -61,6 +61,7 @@
 #include "llworld.h"
 #include "llpanelface.h"
 // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
+#include "rlvactions.h"
 #include "rlvhandler.h"
 #include "rlvlocks.h"
 // [/RLVa:KB]
@@ -1652,6 +1653,14 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
 											  EAcceptance* accept,
 											  const LLSD& dest)
 {
+// [RLVa:KB] - @share
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(dest_agent)) )
+	{
+		*accept = ACCEPT_NO_LOCKED;
+		return true;
+	}
+// [/RLVa:KB]
+
 	// check the type
 	switch(cargo_type)
 	{
@@ -2476,6 +2485,12 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryObject(
 	}
 	if( obj && avatar )
 	{
+// [RLVa:KB] - @share
+		if ( (obj) && (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(obj->getID())) )
+		{
+			return ACCEPT_NO_LOCKED;
+		}
+// [/RLVa:KB]
 		if(drop)
 		{
 			LLGiveInventory::doGiveInventoryItem(obj->getID(), item );
@@ -2502,6 +2517,12 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventory(
 	{
 		return ACCEPT_NO;
 	}
+// [RLVa:KB] - @share
+	if ( (obj) && (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(obj->getID())) )
+	{
+		return ACCEPT_NO_LOCKED;
+	}
+// [/RLVa:KB]
 	if (drop && obj)
 	{
 		LLGiveInventory::doGiveInventoryItem(obj->getID(), item);
@@ -2515,6 +2536,12 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryCategory(
 	LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
 {
 	LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryCategory()" << LL_ENDL;
+// [RLVa:KB] - @share
+	if ( (obj) && (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(obj->getID())) )
+	{
+		return ACCEPT_NO_LOCKED;
+	}
+// [/RLVa:KB]
 	if(drop && obj)
 	{
 		LLViewerInventoryItem* item;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index afdd79811d65328c70fce33335b3eb0db758336d..b57d03292f4947b7012e0d77d8b394105b21e69f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3051,17 +3051,19 @@ bool enable_object_edit()
 	} 
 	else if (LLSelectMgr::getInstance()->selectGetAllValidAndObjectsFound())
 	{
-//		enable = true;
-// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c
-		bool fRlvCanEdit = (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ));
-		if (!fRlvCanEdit)
+// [RLVa:KB] - @edit*
+		if (RlvActions::isRlvEnabled() && !RlvActions::canEdit(ERlvCheckType::All))
 		{
 			LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection();
 			RlvSelectIsEditable f;
-			fRlvCanEdit = (hSel.notNull()) && ((hSel->getFirstRootNode(&f, TRUE)) == NULL);
+			enable = (hSel.notNull()) && (!hSel->getFirstRootNode(&f, true));
+		}
+		else
+		{
+			enable = true;
 		}
-		enable = fRlvCanEdit;
 // [/RLVa:KB]
+//		enable = true;
 	}
 
 	return enable;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 583fbf813c533bb58ec6ce7dfdccea980aac1fd1..bffe8301232a8b41d0f62d2bb47b40428c2173fe 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -975,7 +975,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
             mScratchBuffer.release();
 		}
 		
-		if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
+//		if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
+// [RLVa:KB] - @setsphere
+		if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0 || RlvActions::hasPostProcess())
+// [/RLVa:KB]
 		{ //only need mDeferredLight for shadows OR ssao OR dof OR fxaa
 			if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
 		}
diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp
index 099539d68a9d679ef4c844ebfa6f96bb9b9a2177..43ba16276cb0fa70662a6fe663eb167a40890346 100644
--- a/indra/newview/rlvactions.cpp
+++ b/indra/newview/rlvactions.cpp
@@ -18,6 +18,7 @@
 #include "llagent.h"
 #include "llimview.h"
 #include "llviewercamera.h"
+#include "llvisualeffect.h"
 #include "llvoavatarself.h"
 #include "llworld.h"
 
@@ -133,6 +134,20 @@ bool RlvActions::canChangeActiveGroup(const LLUUID& idRlvObject)
 	return (idRlvObject.isNull()) ? !gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP) : !gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, idRlvObject);
 }
 
+bool RlvActions::canGiveInventory()
+{
+	// User can give at least one (unspecified) avatar inventory if:
+	//   - not specifically restricted from giving inventory (or at least one exception exists)
+	return (!gRlvHandler.hasBehaviour(RLV_BHVR_SHARE)) || (gRlvHandler.hasException(RLV_BHVR_SHARE));
+}
+
+bool RlvActions::canGiveInventory(const LLUUID& idAgent)
+{
+	// User can give another avatar inventory if:
+	//   - not specifically restricted from giving inventory (or the target is an exception)
+	return (!gRlvHandler.hasBehaviour(RLV_BHVR_SHARE)) || (gRlvHandler.isException(RLV_BHVR_SHARE, idAgent));
+}
+
 // Little helper function to check the IM exclusion range for @recvim, @sendim and @startim (returns: min_dist <= (pos user - pos target) <= max_dist)
 static bool rlvCheckAvatarIMDistance(const LLUUID& idAvatar, ERlvBehaviourModifier eModDistMin, ERlvBehaviourModifier eModDistMax)
 {
@@ -386,6 +401,11 @@ bool RlvActions::canChangeEnvironment(const LLUUID& idRlvObject)
 	return (idRlvObject.isNull()) ? !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV) : !gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETENV, idRlvObject);
 }
 
+bool RlvActions::hasPostProcess()
+{
+	return LLVfxManager::instance().hasEffect(EVisualEffect::RlvSphere);
+}
+
 // ============================================================================
 // World interaction
 //
@@ -408,19 +428,53 @@ bool RlvActions::canBuyObject(const LLUUID& idObj)
 	return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_BUY));
 }
 
-// Handles: @edit and @editobj
+// Handles: @edit, @editobj, @editattach and @editworld
+bool RlvActions::canEdit(ERlvCheckType eCheckType)
+{
+	RlvHandler& rlvHandler = RlvHandler::instance();
+	switch (eCheckType)
+	{
+		case ERlvCheckType::All:
+			// No edit restrictions of any kind
+			return
+				!rlvHandler.hasBehaviour(RLV_BHVR_EDIT) && !rlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ) &&
+				!rlvHandler.hasBehaviour(RLV_BHVR_EDITATTACH) && !rlvHandler.hasBehaviour(RLV_BHVR_EDITWORLD);
+
+		case ERlvCheckType::Some:
+			// Not @edit restricted (or at least one exception) and either not @editattach or not @editworld restricted
+			return
+				(!rlvHandler.hasBehaviour(RLV_BHVR_EDIT) || rlvHandler.hasException(RLV_BHVR_EDIT)) &&
+				(!rlvHandler.hasBehaviour(RLV_BHVR_EDITATTACH) || rlvHandler.hasBehaviour(RLV_BHVR_EDITWORLD));
+
+		case ERlvCheckType::None:
+			// Either @edit restricted with no exceptions or @editattach and @editworld restricted at the same time
+			return
+				(rlvHandler.hasBehaviour(RLV_BHVR_EDIT) && !rlvHandler.hasException(RLV_BHVR_EDIT)) ||
+				(rlvHandler.hasBehaviour(RLV_BHVR_EDITATTACH) && rlvHandler.hasBehaviour(RLV_BHVR_EDITWORLD));
+
+		default:
+			RLV_ASSERT(false);
+			return false;
+	}
+}
+
+// Handles: @edit, @editobj, @editattach and @editworld
 bool RlvActions::canEdit(const LLViewerObject* pObj)
 {
 	// User can edit the specified object if:
 	//   - not generally restricted from editing (or the object's root is an exception)
 	//   - not specifically restricted from editing this object's root
+	//   - it's an attachment   and not restricted from editing attachments
+	//     it's a rezzed object and not restricted from editing any world objects
 
 	// NOTE-RLVa: edit checks should *never* be subject to @fartouch distance checks since we don't have the pick offset so
 	//            instead just implicitly rely on the presence of a (transient) selection
 	return
 		(pObj) &&
 		( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_EDIT)) || (RlvHandler::instance().isException(RLV_BHVR_EDIT, pObj->getRootEdit()->getID())) ) &&
-		( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_EDITOBJ)) || (!RlvHandler::instance().isException(RLV_BHVR_EDITOBJ, pObj->getRootEdit()->getID())) );
+		( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_EDITOBJ)) || (!RlvHandler::instance().isException(RLV_BHVR_EDITOBJ, pObj->getRootEdit()->getID())) ) &&
+		( (pObj->isAttachment()) ? !RlvHandler::instance().hasBehaviour(RLV_BHVR_EDITATTACH)
+			                     : !RlvHandler::instance().hasBehaviour(RLV_BHVR_EDITWORLD) );
 }
 
 // Handles: @fartouch and @interact
@@ -467,6 +521,12 @@ bool RlvActions::canGroundSit()
 	return (!hasBehaviour(RLV_BHVR_SIT)) && (canStand());
 }
 
+bool RlvActions::canGroundSit(const LLUUID& idRlvObjExcept)
+{
+	// See canGroundSit() but disregard any restrictions held by the issuing object
+	return (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SIT, idRlvObjExcept)) && (canStand(idRlvObjExcept));
+}
+
 bool RlvActions::canSit(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/)
 {
 	// User can sit on the specified object if:
@@ -520,8 +580,8 @@ bool RlvActions::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset
 	//  (2) Attachment (on another avatar)
 	//        - a) not prevented from touching any object
 	//        - b) not specifically prevented from touching that object
-	//        - d) not prevented from touching attachments (or the attachment is an exception)
-	//        - e) not prevented from touching other avatar's attachments (or the attachment is an exception)
+	//        - d) not prevented from touching attachments (or the attachment and/or its wearer is/are an exception)
+	//        - e) not prevented from touching other avatar's attachments (or the attachment is worn by a specific avatar on the exception list)
 	//        - h) not prevented from touching faraway objects (or the attachment's center + pick offset is within range)
 	//        - i) specifically allowed to touch that object (overrides all restrictions)
 	//  (3) Attachment (on own avatar)
@@ -539,7 +599,7 @@ bool RlvActions::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset
 	// NOTE-RLVa: * touch restrictions apply linkset-wide (as opposed to, for instance, hover text which is object-specific) but only the root object's restrictions are tested
 	//            * @touchall affects world objects and world attachments (self and others') but >not< HUD attachments
 	//            * @fartouch distance matches against the specified object + pick offset (so >not< the linkset root)
-	//            * @touchattachother exceptions are only checked under the general @touchattach exceptions
+	//            * @touchattachother exceptions change when they specify an avatar id (=block all) or an object id (=allow indiviual - see general @touchattach exceptions)
 	//            * @touchattachself exceptions are only checked under the general @touchattach exceptions
 	//            * @touchme in any object of a linkset affects that entire linkset (= if you can specifically touch one prim in a linkset you can touch that entire linkset)
 	const LLUUID& idRoot = (pObj) ? pObj->getRootEdit()->getID() : LLUUID::null;
@@ -552,12 +612,23 @@ bool RlvActions::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset
 		( (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHTHIS)) || (!rlvHandler.isException(RLV_BHVR_TOUCHTHIS, idRoot, ERlvExceptionCheck::Permissive)) );
 	if (fCanTouch)
 	{
-		if ( (!pObj->isAttachment()) || (!pObj->permYouOwner()) )
+		if (!pObj->isAttachment())
+		{
+			// Rezzed object - test for (1.c) and (1.h)
+			fCanTouch =
+				( (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHWORLD)) || (rlvHandler.isException(RLV_BHVR_TOUCHWORLD, idRoot, ERlvExceptionCheck::Permissive)) ) &&
+				( (!rlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= s_nFartouchDist * s_nFartouchDist) );
+		}
+		else if (!pObj->permYouOwner())
 		{
-			// Rezzed or attachment worn by other - test for (1.c), (2.d), (2.e) and (1/2.h)
+			// Attachment worn by other - test for (2.d), (2.e) and (2.h)
+			const LLUUID& idAttachAgent = static_cast<LLViewerObject*>(pObj->getRoot())->getID();
 			fCanTouch =
-				( (!pObj->isAttachment()) ? (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHWORLD)) || (rlvHandler.isException(RLV_BHVR_TOUCHWORLD, idRoot, ERlvExceptionCheck::Permissive))
-				                          : ((!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACH)) && (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACHOTHER))) || (rlvHandler.isException(RLV_BHVR_TOUCHATTACH, idRoot, ERlvExceptionCheck::Permissive)) ) &&
+				(
+				    ( (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACH) && !rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACHOTHER)) ||
+					  (rlvHandler.isException(RLV_BHVR_TOUCHATTACH, idRoot, ERlvExceptionCheck::Permissive) || rlvHandler.isException(RLV_BHVR_TOUCHATTACH, idAttachAgent, ERlvExceptionCheck::Permissive)) ) &&
+					(!rlvHandler.isException(RLV_BHVR_TOUCHATTACHOTHER, idAttachAgent))
+				) &&
 				( (!rlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= s_nFartouchDist * s_nFartouchDist) );
 		}
 		else if (!pObj->isHUDAttachment())
diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h
index 99f94df7cd3a14df164062de7bb3e694ea71a887..ea341f784e83782af9ccff5f3f3791e5a47f694d 100644
--- a/indra/newview/rlvactions.h
+++ b/indra/newview/rlvactions.h
@@ -35,6 +35,8 @@ class LLVOAvatar;
 // RlvActions class declaration - developer-friendly non-RLVa code facing class, use in lieu of RlvHandler whenever possible
 //
 
+enum class ERlvCheckType { All, Some, None };
+
 class RlvActions
 {
 	// ======
@@ -91,6 +93,16 @@ class RlvActions
 	 */
 	static bool canChangeActiveGroup(const LLUUID& idRlvObject = LLUUID::null);
 
+	/*
+	 * Returns true if the user is allowed to give inventory to at least one (unspecified) avatar (used to blanket ban use of 'Share' if the user cannot give items to *anyone*)
+	 */
+	static bool canGiveInventory();
+
+	/*
+	 * Returns true if the user is allowed to give the specified avatar inventory
+	 */
+	static bool canGiveInventory(const LLUUID& idAgent);
+
 	/*
 	 * Returns true if the user is allowed to receive IMs from the specified sender (can be an avatar or a group)
 	 */
@@ -226,6 +238,10 @@ class RlvActions
 	 */
 	static bool canChangeEnvironment(const LLUUID& idRlvObject = LLUUID::null);
 
+	/*
+	 * Returns true if a postprocessing shader is currently active
+	 */
+	static bool hasPostProcess();
 
 	// =================
 	// World interaction
@@ -247,6 +263,11 @@ class RlvActions
 	 */
 	static bool canBuyObject(const LLUUID& idObj);
 
+	/*
+	 * Returns true if the user can edit all, some, or nothing (used to bail early, or to skip expensive selection checks)
+	 */
+	static bool canEdit(ERlvCheckType eCheckType);
+
 	/*
 	 * Returns true if the user can edit the specified object (with an optional relative offset)
 	 */
@@ -256,6 +277,7 @@ class RlvActions
 	 * Returns true if the user can sit on the ground
 	 */
 	static bool canGroundSit();
+	static bool canGroundSit(const LLUUID& idRlvObjExcept);
 
 	/*
 	 * Returns true if the user can interact with the specified object (with an optional relative offset)
diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h
index df7ebb5c1acf7324d8d4468f6a597ba1de297074..a0985de0b17afb97feb536ea4d54df30a4073c98 100644
--- a/indra/newview/rlvdefines.h
+++ b/indra/newview/rlvdefines.h
@@ -127,6 +127,7 @@ enum ERlvBehaviour {
 	RLV_BHVR_SENDGESTURE,
 	RLV_BHVR_PERMISSIVE,			// "permissive"
 	RLV_BHVR_NOTIFY,				// "notify"
+	RLV_BHVR_SHARE,
 	RLV_BHVR_SHOWINV,				// "showinv"
 	RLV_BHVR_SHOWMINIMAP,			// "showminimap"
 	RLV_BHVR_SHOWWORLDMAP,			// "showworldmap"
@@ -154,7 +155,9 @@ enum ERlvBehaviour {
 	RLV_BHVR_ALLOWIDLE,				// "allowidle"
 	RLV_BHVR_BUY,					// "buy"
 	RLV_BHVR_EDIT,					// "edit"
+	RLV_BHVR_EDITATTACH,
 	RLV_BHVR_EDITOBJ,				// "editobj"
+	RLV_BHVR_EDITWORLD,
 	RLV_BHVR_VIEWTRANSPARENT,
 	RLV_BHVR_VIEWWIREFRAME,
 	RLV_BHVR_PAY,					// "pay"
@@ -174,6 +177,7 @@ enum ERlvBehaviour {
 	RLV_BHVR_SETGROUP,				// "setgroup"
 	RLV_BHVR_UNSIT,					// "unsit"
 	RLV_BHVR_SIT,					// "sit"
+	RLV_BHVR_SITGROUND,
 	RLV_BHVR_SITTP,					// "sittp"
 	RLV_BHVR_STANDTP,				// "standtp"
 	RLV_BHVR_SETDEBUG,				// "setdebug"
@@ -431,6 +435,8 @@ namespace RlvStringKeys
 		inline constexpr std::string_view RecvIm = "blocked_recvim"sv;
 		inline constexpr std::string_view RecvImRemote = "blocked_recvim_remote"sv;
 		inline constexpr std::string_view SendIm = "blocked_sendim"sv;
+		inline constexpr std::string_view Share = make_string_view("blocked_share");
+		inline constexpr std::string_view ShareGeneric = make_string_view("blocked_share_generic");
 		inline constexpr std::string_view StartConference = "blocked_startconf"sv;
 		inline constexpr std::string_view StartIm = "blocked_startim"sv;
 		inline constexpr std::string_view Teleport = "blocked_teleport"sv;
diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp
index a03d72b41f421a8d94b9c92aa3e2506cd8b53754..6dc05f8f1ce7813e5230423712dce75d692128b0 100644
--- a/indra/newview/rlvhandler.cpp
+++ b/indra/newview/rlvhandler.cpp
@@ -888,10 +888,7 @@ void RlvHandler::setCameraOverride(bool fOverride)
 // Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c
 void RlvHandler::onSitOrStand(bool fSitting)
 {
-	if (rlv_handler_t::isEnabled())
-	{
-		RlvSettings::updateLoginLastLocation();
-	}
+	RlvSettings::updateLoginLastLocation();
 
 	if ( (hasBehaviour(RLV_BHVR_STANDTP)) && (!fSitting) && (!m_posSitSource.isExactlyZero()) )
 	{
@@ -903,6 +900,30 @@ void RlvHandler::onSitOrStand(bool fSitting)
 		doOnIdleOneTime(boost::bind(RlvUtil::forceTp, m_posSitSource));
 		m_posSitSource.setZero();
 	}
+	else if ( (!fSitting) && (m_fPendingGroundSit) )
+	{
+		gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
+		send_agent_update(TRUE, TRUE);
+
+		m_fPendingGroundSit = false;
+		m_idPendingSitActor = m_idPendingUnsitActor;
+	}
+
+	if (isAgentAvatarValid())
+	{
+		const LLViewerObject* pSitObj = static_cast<const LLViewerObject*>(gAgentAvatarp->getParent());
+		const LLUUID& idSitObj = (pSitObj) ? pSitObj->getID() : LLUUID::null;
+		if (fSitting)
+		{
+			RlvBehaviourNotifyHandler::instance().onSit(idSitObj, !gRlvHandler.hasBehaviourExcept(RLV_BHVR_SIT, m_idPendingSitActor));
+			m_idPendingSitActor.setNull();
+		}
+		else
+		{
+			RlvBehaviourNotifyHandler::instance().onStand(idSitObj, !gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, m_idPendingUnsitActor));
+			m_idPendingUnsitActor.setNull();
+		}
+	}
 }
 
 // Checked: 2010-03-11 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
@@ -2104,6 +2125,8 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETSPHERE>::onCommand(const RlvCommand&
 	{
 		if (gRlvHandler.hasBehaviour(rlvCmd.getObjectID(), rlvCmd.getBehaviourType()))
 		{
+			LLVfxManager::instance().addEffect(new RlvSphereEffect(rlvCmd.getObjectID()));
+
 			Rlv::forceAtmosphericShadersIfAvailable();
 
 			// If we're not using deferred but are using Windlight shaders we need to force use of FBO and depthmap texture
@@ -2117,8 +2140,13 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETSPHERE>::onCommand(const RlvCommand&
 				gPipeline.resetVertexBuffers();
 				LLViewerShaderMgr::instance()->setShaders();
 			}
-
-			LLVfxManager::instance().addEffect(new RlvSphereEffect(rlvCmd.getObjectID()));
+			else if (!gPipeline.mDeferredLight.isComplete())
+			{
+				// In case of deferred with no shadows, no ambient occlusion, no depth of field, and no antialiasing
+				gPipeline.releaseGLBuffers();
+				gPipeline.createGLBuffers();
+				RLV_ASSERT(gPipeline.mDeferredLight.isComplete());
+			}
 		}
 		else
 		{
@@ -2736,6 +2764,9 @@ ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const
 				{
 					gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
 					send_agent_update(TRUE, TRUE);	// See behaviour notes on why we have to force an agent update here
+
+					gRlvHandler.m_idPendingSitActor.setNull();
+					gRlvHandler.m_idPendingUnsitActor = gRlvHandler.getCurrentObject();
 				}
 			}
 			break;
@@ -3178,6 +3209,34 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SETGROUP>::onCommand(const RlvCommand& rlvCm
 	return (fValid) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION;
 }
 
+// Handles: @sitground=force
+template<> template<>
+ERlvCmdRet RlvForceHandler<RLV_BHVR_SITGROUND>::onCommand(const RlvCommand& rlvCmd)
+{
+	if ( (!RlvActions::canGroundSit(rlvCmd.getObjectID())) || (!isAgentAvatarValid()) )
+		return RLV_RET_FAILED_LOCK;
+
+	if (!gAgentAvatarp->isSitting())
+	{
+		gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
+
+		gRlvHandler.m_fPendingGroundSit = false;
+		gRlvHandler.m_idPendingSitActor = gRlvHandler.getCurrentObject();
+		gRlvHandler.m_idPendingUnsitActor.setNull();
+	}
+	else if (gAgentAvatarp->getParent())
+	{
+		gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
+
+		gRlvHandler.m_fPendingGroundSit = true;
+		gRlvHandler.m_idPendingSitActor.setNull();
+		gRlvHandler.m_idPendingUnsitActor = gRlvHandler.getCurrentObject();
+	}
+	send_agent_update(TRUE, TRUE);
+
+	return RLV_RET_SUCCESS;
+}
+
 // Handles: @sit:<uuid>=force
 template<> template<>
 ERlvCmdRet RlvForceHandler<RLV_BHVR_SIT>::onCommand(const RlvCommand& rlvCmd)
@@ -3189,10 +3248,7 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SIT>::onCommand(const RlvCommand& rlvCmd)
 	LLViewerObject* pObj = NULL;
 	if (idTarget.isNull())
 	{
-		if ( (!RlvActions::canGroundSit()) || ((isAgentAvatarValid()) && (gAgentAvatarp->isSitting())) )
-			return RLV_RET_FAILED_LOCK;
-		gAgent.sitDown();
-		send_agent_update(TRUE, TRUE);
+		return RlvForceHandler<RLV_BHVR_SITGROUND>::onCommand(rlvCmd);
 	}
 	else if ( ((pObj = gObjectList.findObject(idTarget)) != NULL) && (LL_PCODE_VOLUME == pObj->getPCode()))
 	{
@@ -3215,6 +3271,9 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SIT>::onCommand(const RlvCommand& rlvCmd)
 		gMessageSystem->addUUIDFast(_PREHASH_TargetID, pObj->mID);
 		gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3::zero);
 		pObj->getRegion()->sendReliableMessage();
+
+		gRlvHandler.m_idPendingSitActor = gRlvHandler.getCurrentObject();
+		gRlvHandler.m_idPendingUnsitActor.setNull();
 	}
 	else
 	{
diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h
index edd495faed5225fb2e327cd26c96240cc3921662..09adc36d07166efa0b7ba28a83574fdf2190be95 100644
--- a/indra/newview/rlvhandler.h
+++ b/indra/newview/rlvhandler.h
@@ -267,6 +267,9 @@ class RlvHandler : public LLOldEvents::LLSimpleListener, public LLParticularGrou
 
 	bool                                    m_fCanCancelTp;					// @accepttp=n and @tpto=force
 	mutable LLVector3d                      m_posSitSource;					// @standtp=n (mutable because onForceXXX handles are all declared as const)
+	bool                                    m_fPendingGroundSit = false;	// @sitground=force
+	LLUUID                                  m_idPendingSitActor;			// @sit=force and @sitground=force
+	LLUUID                                  m_idPendingUnsitActor;			// @unsit=force
 	mutable LLUUID                          m_idAgentGroup;					// @setgroup=n
 	std::pair<LLUUID, std::string>          m_PendingGroupChange;			// @setgroup=force
 	std::pair<LLTimer, LLUUID>              m_GroupChangeExpiration;        // @setgroup=force
diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp
index 12cf12d5e953e74f9694a6cf0d5b51b52e13bfbd..6f1e5819505aade063538c71847d56e4fb045845 100644
--- a/indra/newview/rlvhelper.cpp
+++ b/indra/newview/rlvhelper.cpp
@@ -102,7 +102,9 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
 	addEntry(new RlvBehaviourInfo("detachthis_except",		RLV_BHVR_DETACHTHISEXCEPT,		RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_NODE));
 	addEntry(new RlvBehaviourInfo("detachallthis_except",	RLV_BHVR_DETACHTHISEXCEPT,		RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE));
 	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_EDIT, RLV_OPTION_NONE_OR_EXCEPTION>("edit"));
+	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("editattach", RLV_BHVR_EDITATTACH));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_EXCEPTION>("editobj", RLV_BHVR_EDITOBJ));
+	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("editworld", RLV_BHVR_EDITWORLD));
 	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_VIEWTRANSPARENT, RLV_OPTION_NONE>("viewtransparent", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
 	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_VIEWWIREFRAME, RLV_OPTION_NONE>("viewwireframe", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("emote", RLV_BHVR_EMOTE));
@@ -138,6 +140,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
 	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETDEBUG, RLV_OPTION_NONE>("setdebug"));
 	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETENV, RLV_OPTION_NONE>("setenv"));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("setgroup", RLV_BHVR_SETGROUP));
+	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("share", RLV_BHVR_SHARE, RlvBehaviourInfo::BHVR_STRICT));
 	addEntry(new RlvBehaviourInfo("sharedunwear",			RLV_BHVR_SHAREDUNWEAR,			RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED));
 	addEntry(new RlvBehaviourInfo("sharedwear",				RLV_BHVR_SHAREDWEAR,			RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED));
 	addEntry(new RlvBehaviourProcessor<RLV_BHVR_SHOWHOVERTEXT>("showhovertext"));
@@ -165,7 +168,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("temprun", RLV_BHVR_TEMPRUN));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("touchall", RLV_BHVR_TOUCHALL));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("touchattach", RLV_BHVR_TOUCHATTACH));
-	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("touchattachother", RLV_BHVR_TOUCHATTACHOTHER));
+	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("touchattachother", RLV_BHVR_TOUCHATTACHOTHER));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("touchattachself", RLV_BHVR_TOUCHATTACHSELF));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_MODIFIER>("touchfar", RLV_BHVR_FARTOUCH, RlvBehaviourInfo::BHVR_SYNONYM));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("touchhud", RLV_BHVR_TOUCHHUD, RlvBehaviourInfo::BHVR_EXTENDED));
@@ -289,6 +292,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
 	addEntry(new RlvForceProcessor<RLV_BHVR_SETCAM_MODE>("setcam_mode", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
 	addEntry(new RlvForceProcessor<RLV_BHVR_SETGROUP>("setgroup"));
 	addEntry(new RlvForceProcessor<RLV_BHVR_SIT>("sit"));
+	addEntry(new RlvForceProcessor<RLV_BHVR_SITGROUND>("sitground"));
 	addEntry(new RlvForceProcessor<RLV_BHVR_TPTO>("tpto"));
 	addEntry(new RlvBehaviourInfo("unsit",					RLV_BHVR_UNSIT,					RLV_TYPE_FORCE));
 
@@ -1919,6 +1923,22 @@ void RlvBehaviourNotifyHandler::onReattach(const LLViewerJointAttachment* pAttac
 	sendNotification(llformat("reattached %s %s", (fAllowed) ? "legally" : "illegally", pAttachPt->getName().c_str()));
 }
 
+void RlvBehaviourNotifyHandler::onSit(const LLUUID& idObj, bool fAllowed)
+{
+	if (idObj.isNull())
+		sendNotification(llformat("sat ground %s", (fAllowed) ? "legally" : "illegally"));
+	else
+		sendNotification(llformat("sat object %s %s", (fAllowed) ? "legally" : "illegally", idObj.asString().c_str()));
+}
+
+void RlvBehaviourNotifyHandler::onStand(const LLUUID& idObj, bool fAllowed)
+{
+	if (idObj.isNull())
+		sendNotification(llformat("unsat ground %s", (fAllowed) ? "legally" : "illegally"));
+	else
+		sendNotification(llformat("unsat object %s %s", (fAllowed) ? "legally" : "illegally", idObj.asString().c_str()));
+}
+
 // =========================================================================
 // Various helper classes/timers/functors
 //
diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h
index 398af45d4d7e5e936342c605f5b65a24f3568519..a8696bc01abadb4bf5a7cab910df6bba1da5da1b 100644
--- a/indra/newview/rlvhelper.h
+++ b/indra/newview/rlvhelper.h
@@ -630,11 +630,13 @@ class RlvBehaviourNotifyHandler final : public LLSingleton<RlvBehaviourNotifyHan
 	 * Event handlers
 	 */
 public:
-	static void	onWear(LLWearableType::EType eType, bool fAllowed);
-	static void	onTakeOff(LLWearableType::EType eType, bool fAllowed);
-	static void	onAttach(const LLViewerJointAttachment* pAttachPt, bool fAllowed);
-	static void	onDetach(const LLViewerJointAttachment* pAttachPt, bool fAllowed);
-	static void	onReattach(const LLViewerJointAttachment* pAttachPt, bool fAllowed);
+	static void onWear(LLWearableType::EType eType, bool fAllowed);
+	static void onTakeOff(LLWearableType::EType eType, bool fAllowed);
+	static void onAttach(const LLViewerJointAttachment* pAttachPt, bool fAllowed);
+	static void onDetach(const LLViewerJointAttachment* pAttachPt, bool fAllowed);
+	static void onReattach(const LLViewerJointAttachment* pAttachPt, bool fAllowed);
+	       void onSit(const LLUUID& idObj, bool fAllowed);
+	       void onStand(const LLUUID& idObj, bool fAllowed);
 protected:
 	void		onCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet, bool fInternal);
 
diff --git a/indra/newview/skins/default/xui/en/rlva_strings.xml b/indra/newview/skins/default/xui/en/rlva_strings.xml
index de0e99d6d0949a6a1dec9013a380b5477fca062d..3ffb3d90094faa6b79b16e959a6ecb84b45d39a9 100644
--- a/indra/newview/skins/default/xui/en/rlva_strings.xml
+++ b/indra/newview/skins/default/xui/en/rlva_strings.xml
@@ -141,6 +141,16 @@
 			<key>value</key>
 			<string>Unable to show script dialog or textbox due to RLV restrictions</string>
 		</map>
+		<key>blocked_share</key>
+		<map>
+			<key>value</key>
+			<string>Unable to share inventory with [RECIPIENT] due to RLV restrictions.</string>
+		</map>
+		<key>blocked_share_generic</key>
+		<map>
+			<key>value</key>
+			<string>Unable to share inventory due to RLV restrictions.</string>
+		</map>
 		<key>blocked_startim</key>
 		<map>
 			<key>value</key>