diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index c45db3b1859d0a67d36ec9270d8ce69c7ed5ade7..1af90c871b48fad20adc7cae730d087e6a71488c 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -576,6 +576,43 @@ std::string utf8str_truncate(const std::string& utf8str, const S32 max_len)
 	}
 }
 
+// [RLVa:KB] - Checked: RLVa-2.1.0
+std::string utf8str_substr(const std::string& utf8str, const S32 index, const S32 max_len)
+{
+	if (0 == max_len)
+	{
+		return std::string();
+	}
+	if (utf8str.length() - index  <= max_len)
+	{
+		return utf8str.substr(index, max_len);
+	}
+	else
+	{
+		S32 cur_char = max_len;
+
+		// If we're ASCII, we don't need to do anything
+		if ((U8)utf8str[index + cur_char] > 0x7f)
+		{
+			// If first two bits are (10), it's the tail end of a multibyte char.  We need to shift back
+			// to the first character
+			while (0x80 == (0xc0 & utf8str[index + cur_char]))
+			{
+				cur_char--;
+				// Keep moving forward until we hit the first char;
+				if (cur_char == 0)
+				{
+					// Make sure we don't trash memory if we've got a bogus string.
+					break;
+				}
+			}
+		}
+		// The byte index we're on is one we want to get rid of, so we only want to copy up to (cur_char-1) chars
+		return utf8str.substr(index, cur_char);
+	}
+}
+// [/RLVa:KB]
+
 std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len)
 {
     if (0 == symbol_len)
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index a40db0f8cc786473daff03886aa1a19a78f8be27..f7d304b55ad73f070ea25f7b5906d190251e8ca9 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -557,6 +557,10 @@ LL_COMMON_API S32 wstring_wstring_length_from_utf16_length(const LLWString & wst
  */
 LL_COMMON_API std::string utf8str_truncate(const std::string& utf8str, const S32 max_len);
 
+// [RLVa:KB] - Checked: RLVa-2.1.0
+LL_COMMON_API std::string utf8str_substr(const std::string& utf8str, const S32 index, const S32 max_len);
+// [/RLVa:KB]
+
 LL_COMMON_API std::string utf8str_trim(const std::string& utf8str);
 
 LL_COMMON_API S32 utf8str_compare_insensitive(
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 8d1f3c1c2c27e8be052954bc295115ca56d3882d..28ea32d57c03823b92a81cc49bd8dcbc80be842a 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2573,10 +2573,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			// do nothing -- don't distract newbies in
 			// Prelude with global IMs
 		}
-// [RLVa:KB] - Checked: RLVa-2.0.3
-		else if ( (RlvActions::isRlvEnabled()) && (RlvSettings::getEnableIMQuery()) && (offline == IM_ONLINE) && ("@version" == message) && (!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) )
+// [RLVa:KB] - Checked: RLVa-2.1.0
+		else if ( (RlvActions::isRlvEnabled()) && (offline == IM_ONLINE) && (!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) &&
+		          (message.length() > 3) && (RLV_CMD_PREFIX == message[0]) && (RlvHandler::instance().processIMQuery(from_id, message)) )
 		{
-			RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(LLUUID::null), session_id);
+			// Eat the message and do nothing
 		}
 // [/RLVa:KB]
 //		else if (offline == IM_ONLINE 
diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp
index 92fb4bcc4d1356377633db748d04e66d3580de44..237b10c8697c50e72358e4bb97f451fbc8195412 100644
--- a/indra/newview/rlvcommon.cpp
+++ b/indra/newview/rlvcommon.cpp
@@ -18,6 +18,8 @@
 #include "llagent.h"
 #include "llagentui.h"
 #include "llavatarnamecache.h"
+#include "llcallingcard.h"
+#include "llimview.h"
 #include "llinstantmessage.h"
 #include "llnotificationsutil.h"
 #include "llregionhandle.h"
@@ -27,6 +29,7 @@
 #include "llversioninfo.h"
 #include "llviewerparcelmgr.h"
 #include "llviewermenu.h"
+#include "llviewermessage.h"
 #include "llviewerobjectlist.h"
 #include "llviewerregion.h"
 #include "llworld.h"
@@ -603,6 +606,55 @@ bool RlvUtil::sendChatReply(S32 nChannel, const std::string& strUTF8Text)
 	return true;
 }
 
+void RlvUtil::sendIMMessage(const LLUUID& idRecipient, const std::string& strMsg, char chSplit)
+{
+	const LLUUID idSession = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, idRecipient);
+	const LLRelationship* pBuddyInfo = LLAvatarTracker::instance().getBuddyInfo(idRecipient);
+	std::string strAgentName;
+	LLAgentUI::buildFullname(strAgentName);
+
+	std::string::size_type lenMsg = strMsg.length(), lenIt = 0;
+
+	const char* pstrIt = strMsg.c_str(); std::string strTemp;
+	while (lenIt < lenMsg)
+	{
+		if (lenIt + MAX_MSG_STR_LEN < lenMsg)
+		{
+			// Find the last split character
+			const char* pstrTemp = pstrIt + MAX_MSG_STR_LEN;
+			while ( (pstrTemp > pstrIt) && (*pstrTemp != chSplit) )
+				pstrTemp--;
+
+			if (pstrTemp > pstrIt)
+				strTemp = strMsg.substr(lenIt, pstrTemp - pstrIt);
+			else
+				strTemp = utf8str_substr(strMsg, lenIt, MAX_MSG_STR_LEN);
+		}
+		else
+		{
+			strTemp = strMsg.substr(lenIt, std::string::npos);
+		}
+
+		pack_instant_message(
+			gMessageSystem,
+			gAgent.getID(),
+			false,
+			gAgent.getSessionID(),
+			idRecipient,
+			strAgentName.c_str(),
+			strTemp.c_str(),
+			( (!pBuddyInfo) || (pBuddyInfo->isOnline()) ) ? IM_ONLINE : IM_OFFLINE,
+			IM_NOTHING_SPECIAL,
+			idSession);
+		gAgent.sendReliableMessage();
+
+		lenIt += strTemp.length();
+		pstrIt = strMsg.c_str() + lenIt;
+		if (*pstrIt == chSplit)
+			lenIt++;
+	}
+}
+
 void RlvUtil::teleportCallback(U64 hRegion, const LLVector3& posRegion, const LLVector3& vecLookAt)
 {
 	if (hRegion)
diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h
index 5f3811873455b94047d3f19e048f504b74182cef..4d5bf9c8d682857166fad049a3285a906b0b1ff6 100644
--- a/indra/newview/rlvcommon.h
+++ b/indra/newview/rlvcommon.h
@@ -184,7 +184,7 @@ class RlvUtil
 	static bool isValidReplyChannel(S32 nChannel, bool fLoopback = false);
 	static bool sendChatReply(S32 nChannel, const std::string& strUTF8Text);
 	static bool sendChatReply(const std::string& strChannel, const std::string& strUTF8Text);
-
+	static void sendIMMessage(const LLUUID& idTo, const std::string& strMsg, char chSplit);
 	static void teleportCallback(U64 hRegion, const LLVector3& posRegion, const LLVector3& vecLookAt);
 protected:
 	static bool m_fForceTp;															// @standtp
diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h
index 53d06d7bb63561deb9aa8b61d0d6dca42c2e59c3..a615ce98c83128d33d6879d086cc66f5da075b63 100644
--- a/indra/newview/rlvdefines.h
+++ b/indra/newview/rlvdefines.h
@@ -388,6 +388,9 @@ enum ERlvAttachGroupType
 #define RLV_STRING_BLOCKED_TPLUREREQ_REMOTE	"blocked_tplurerequest_remote"
 #define RLV_STRING_BLOCKED_VIEWXXX			"blocked_viewxxx"
 #define RLV_STRING_BLOCKED_WIREFRAME		"blocked_wireframe"
+#define RLV_STRING_STOPIM_NOSESSION         "stopim_nosession"
+#define RLV_STRING_STOPIM_ENDSESSION_REMOTE "stopim_endsession_remote"
+#define RLV_STRING_STOPIM_ENDSESSION_LOCAL  "stopim_endsession_local"
 
 // ============================================================================
 
diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp
index 90aa3bbbe45e7ae18f3a9a96881dba07ff6102e3..68da540ecc3f21c26186a6bafe520a753cc82f28 100644
--- a/indra/newview/rlvfloaters.cpp
+++ b/indra/newview/rlvfloaters.cpp
@@ -229,23 +229,20 @@ void RlvFloaterBehaviours::onAvatarNameLookup(const LLUUID& idAgent, const LLAva
 		refreshAll();
 }
 
-// Checked: 2011-05-26 (RLVa-1.3.1c) | Added: RLVa-1.3.1c
-void RlvFloaterBehaviours::onBtnCopyToClipboard()
+// static
+const std::string RlvFloaterBehaviours::getFormattedBehaviourString()
 {
 	std::ostringstream strRestrictions;
 
 	strRestrictions << RlvStrings::getVersion(LLUUID::null) << "\n";
 
-	const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap();
-	for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj)
+	for (const auto& rlvObjectEntry : RlvHandler::instance().getObjectMap())
 	{
-		strRestrictions << "\n" << rlvGetItemNameFromObjID(itObj->first) << ":\n";
-
-		const rlv_command_list_t* pCommands = itObj->second.getCommandList();
-		for (rlv_command_list_t::const_iterator itCmd = pCommands->begin(), endCmd = pCommands->end(); itCmd != endCmd; ++itCmd)
+		strRestrictions << "\n" << rlvGetItemNameFromObjID(rlvObjectEntry.first) << ":\n";
+		for (const RlvCommand& rlvCmd : rlvObjectEntry.second.getCommandList())
 		{
 			std::string strOption; LLUUID idOption;
-			if ( (itCmd->hasOption()) && (idOption.set(itCmd->getOption(), FALSE)) && (idOption.notNull()) )
+			if ( (rlvCmd.hasOption()) && (idOption.set(rlvCmd.getOption(), FALSE)) && (idOption.notNull()) )
 			{
 				LLAvatarName avName;
 				if (gObjectList.findObject(idOption))
@@ -253,17 +250,23 @@ void RlvFloaterBehaviours::onBtnCopyToClipboard()
 				else if (LLAvatarNameCache::get(idOption, &avName))
 					strOption = (!avName.getAccountName().empty()) ? avName.getAccountName() : avName.getDisplayName();
 				else if (!gCacheName->getGroupName(idOption, strOption))
-					strOption = itCmd->getOption();
+					strOption = rlvCmd.getOption();
 			}
 
-			strRestrictions << "  -> " << itCmd->asString();
-			if ( (!strOption.empty()) && (strOption != itCmd->getOption()) )
+			strRestrictions << "  -> " << rlvCmd.asString();
+			if ((!strOption.empty()) && (strOption != rlvCmd.getOption()))
 				strRestrictions << "  [" << strOption << "]";
 			strRestrictions << "\n";
 		}
 	}
 
-	LLWString wstrRestrictions = utf8str_to_wstring(strRestrictions.str());
+	return strRestrictions.str() + strRestrictions.str() + strRestrictions.str() + strRestrictions.str() + strRestrictions.str();
+}
+
+// Checked: 2011-05-26 (RLVa-1.3.1c) | Added: RLVa-1.3.1c
+void RlvFloaterBehaviours::onBtnCopyToClipboard()
+{
+	LLWString wstrRestrictions = utf8str_to_wstring(getFormattedBehaviourString());
 	LLClipboard::instance().copyToClipboard(wstrRestrictions, 0, wstrRestrictions.length());
 }
 
@@ -315,16 +318,14 @@ void RlvFloaterBehaviours::refreshAll()
 	//
 	// List behaviours
 	//
-	const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap();
-	for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj)
+	for (const auto& rlvObjectEntry : RlvHandler::instance().getObjectMap())
 	{
-		const std::string strIssuer = rlvGetItemNameFromObjID(itObj->first);
+		const std::string strIssuer = rlvGetItemNameFromObjID(rlvObjectEntry.first);
 
-		const rlv_command_list_t* pCommands = itObj->second.getCommandList();
-		for (rlv_command_list_t::const_iterator itCmd = pCommands->begin(), endCmd = pCommands->end(); itCmd != endCmd; ++itCmd)
+		for (const RlvCommand& rlvCmd : rlvObjectEntry.second.getCommandList())
 		{
 			std::string strOption; LLUUID idOption;
-			if ( (itCmd->hasOption()) && (idOption.set(itCmd->getOption(), FALSE)) && (idOption.notNull()) )
+			if ( (rlvCmd.hasOption()) && (idOption.set(rlvCmd.getOption(), FALSE)) && (idOption.notNull()) )
 			{
 				LLAvatarName avName;
 				if (gObjectList.findObject(idOption))
@@ -342,15 +343,15 @@ void RlvFloaterBehaviours::refreshAll()
 						LLAvatarNameCache::get(idOption, boost::bind(&RlvFloaterBehaviours::onAvatarNameLookup, this, _1, _2));
 						m_PendingLookup.push_back(idOption);
 					}
-					strOption = itCmd->getOption();
+					strOption = rlvCmd.getOption();
 				}
 			}
 
-			if ( (itCmd->hasOption()) && (rlvGetShowException(itCmd->getBehaviourType())) )
+			if ( (rlvCmd.hasOption()) && (rlvGetShowException(rlvCmd.getBehaviourType())) )
 			{
 				// List under the "Exception" tab
-				sdExceptRow["enabled"] = gRlvHandler.isException(itCmd->getBehaviourType(), idOption);
-				sdExceptColumns[0]["value"] = itCmd->getBehaviour();
+				sdExceptRow["enabled"] = gRlvHandler.isException(rlvCmd.getBehaviourType(), idOption);
+				sdExceptColumns[0]["value"] = rlvCmd.getBehaviour();
 				sdExceptColumns[1]["value"] = strOption;
 				sdExceptColumns[2]["value"] = strIssuer;
 				pExceptList->addElement(sdExceptRow, ADD_BOTTOM);
@@ -358,7 +359,7 @@ void RlvFloaterBehaviours::refreshAll()
 			else
 			{
 				// List under the "Restrictions" tab
-				sdBhvrColumns[0]["value"] = (strOption.empty()) ? itCmd->asString() : itCmd->getBehaviour() + ":" + strOption;
+				sdBhvrColumns[0]["value"] = (strOption.empty()) ? rlvCmd.asString() : rlvCmd.getBehaviour() + ":" + strOption;
 				sdBhvrColumns[1]["value"] = strIssuer;
 				pBhvrList->addElement(sdBhvrRow, ADD_BOTTOM);
 			}
@@ -660,7 +661,7 @@ void RlvFloaterStrings::onClose(bool fQuitting)
 		RlvStrings::saveToFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, RLV_STRINGS_FILE));
 
 		// Remind the user their changes require a relog to take effect
-		LLNotificationsUtil::add("RLVChangeStrings");
+		LLNotificationsUtil::add("RLVaChangeStrings");
 	}
 }
 
diff --git a/indra/newview/rlvfloaters.h b/indra/newview/rlvfloaters.h
index 8238aa68885e6d1b5308c10564a8acfbd9cd44ef..17903dd903ed3da0626430d4d67cc88c09a8f36c 100644
--- a/indra/newview/rlvfloaters.h
+++ b/indra/newview/rlvfloaters.h
@@ -49,6 +49,7 @@ class RlvFloaterBehaviours : public LLFloater
 	/*
 	 * Member functions
 	 */
+	static const std::string getFormattedBehaviourString();
 protected:
 	void onAvatarNameLookup(const LLUUID& idAgent, const LLAvatarName& avName);
 	void onBtnCopyToClipboard();
diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp
index 4395cdb7d9c6173367b5c30cbc5f45095330871f..4a0a5a88cc41d5f2da8b49166590307c14f6b4ba 100644
--- a/indra/newview/rlvhandler.cpp
+++ b/indra/newview/rlvhandler.cpp
@@ -22,6 +22,7 @@
 #include "llgroupactions.h"
 #include "llhudtext.h"
 #include "llmoveview.h"
+#include "llslurl.h"
 #include "llstartup.h"
 #include "llviewermessage.h"
 #include "llviewermenu.h"
@@ -31,10 +32,13 @@
 
 // Command specific includes
 #include "llagentcamera.h"				// @setcam and related
+#include "llavataractions.h"            // @stopim IM query
 #include "llavatarnamecache.h"			// @shownames
 #include "llavatarlist.h"				// @shownames
 #include "llenvmanager.h"				// @setenv
 #include "llfloatersidepanelcontainer.h"// @shownames
+#include "llnotifications.h"			// @list IM query
+#include "llnotificationsutil.h"
 #include "lloutfitslist.h"				// @showinv - "Appearance / My Outfits" panel
 #include "llpaneloutfitsinventory.h"	// @showinv - "Appearance" floater
 #include "llpanelpeople.h"				// @shownames
@@ -468,6 +472,70 @@ ERlvCmdRet RlvHandler::processClearCommand(const RlvCommand& rlvCmd)
 	return RLV_RET_SUCCESS; // Don't fail clear commands even if the object didn't exist since it confuses people
 }
 
+bool RlvHandler::processIMQuery(const LLUUID& idSender, const std::string& strMessage)
+{
+	if ("@stopim" == strMessage)
+	{
+		// If the user can't start an IM session and one is open terminate it - always notify the sender in this case
+		if ( (!RlvActions::canStartIM(idSender)) && (RlvActions::hasOpenP2PSession(idSender)) )
+		{
+			RlvUtil::sendBusyMessage(idSender, RlvStrings::getString(RLV_STRING_STOPIM_ENDSESSION_REMOTE));
+			LLAvatarActions::endIM(idSender);
+			RlvUtil::notifyBlocked(RLV_STRING_STOPIM_ENDSESSION_LOCAL, LLSD().with("NAME", LLSLURL("agent", idSender, "about").getSLURLString()));
+			return true;
+		}
+
+		// User can start an IM session (or one isn't open) so we do nothing - notify and hide it from the user only if IM queries are enabled
+		if (!RlvSettings::getEnableIMQuery())
+			return false;
+		RlvUtil::sendBusyMessage(idSender, RlvStrings::getString(RLV_STRING_STOPIM_NOSESSION));
+		return true;
+	}
+	else if (RlvSettings::getEnableIMQuery())
+	{
+		if ("@version" == strMessage)
+		{
+			RlvUtil::sendBusyMessage(idSender, RlvStrings::getVersion(LLUUID::null));
+			return true;
+		}
+		else if ("@list" == strMessage)
+		{
+			LLNotification::Params params;
+			params.name = "RLVaListRequested";
+			params.functor.function(boost::bind(&RlvHandler::onIMQueryListResponse, this, _1, _2));
+			params.substitutions = LLSD().with("NAME_LABEL", LLSLURL("agent", idSender, "completename").getSLURLString()).with("NAME_SLURL", LLSLURL("agent", idSender, "about").getSLURLString());
+			params.payload = LLSD().with("from_id", idSender);
+
+			class RlvPostponedOfferNotification : public LLPostponedNotification
+			{
+			protected:
+				void modifyNotificationParams() override
+				{
+					LLSD substitutions = mParams.substitutions;
+					substitutions["NAME"] = mName;
+					mParams.substitutions = substitutions;
+				}
+			};
+			LLPostponedNotification::add<RlvPostponedOfferNotification>(params, idSender, false);
+			return true;
+		}
+	}
+	return false;
+}
+
+void RlvHandler::onIMQueryListResponse(const LLSD& sdNotification, const LLSD sdResponse)
+{
+	const LLUUID idRequester = sdNotification["payload"]["from_id"].asUUID();
+	if (LLNotificationsUtil::getSelectedOption(sdNotification, sdResponse) == 0)
+	{
+		RlvUtil::sendIMMessage(idRequester, RlvFloaterBehaviours::getFormattedBehaviourString(), '\n');
+	}
+	else
+	{
+		RlvUtil::sendBusyMessage(idRequester, RlvStrings::getString("imquery_list_deny"));
+	}
+}
+
 // ============================================================================
 // Externally invoked event handlers
 //
diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h
index 4960c92d933c0786e431972c05c3765d09b28577..ef2ca55786063c1e55d708bbaf5f462e35959ae2 100644
--- a/indra/newview/rlvhandler.h
+++ b/indra/newview/rlvhandler.h
@@ -107,6 +107,7 @@ class RlvHandler : public LLOldEvents::LLSimpleListener
 	// Command processing helper functions
 	ERlvCmdRet processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj);
 	void       processRetainedCommands(ERlvBehaviour eBhvrFilter = RLV_BHVR_UNKNOWN, ERlvParamType eTypeFilter = RLV_TYPE_UNKNOWN);
+	bool       processIMQuery(const LLUUID& idSender, const std::string& strCommand);
 
 	// Returns a pointer to the currently executing command (do *not* save this pointer)
 	const RlvCommand* getCurrentCommand() const { return (!m_CurCommandStack.empty()) ? m_CurCommandStack.top() : NULL; }
@@ -118,6 +119,7 @@ class RlvHandler : public LLOldEvents::LLSimpleListener
 	static bool isEnabled()	{ return m_fEnabled; }
 	static bool setEnabled(bool fEnable);
 protected:
+	void onIMQueryListResponse(const LLSD& sdNotification, const LLSD sdResponse);
 
 	// --------------------------------
 
@@ -216,11 +218,10 @@ class RlvHandler : public LLOldEvents::LLSimpleListener
 	// --------------------------------
 
 	/*
-	 * Internal access functions used by unit tests
+	 * Internal access functions
 	 */
 public:
-	const rlv_object_map_t*    getObjectMap() const		{ return &m_Objects; }
-	//const rlv_exception_map_t* getExceptionMap() const	{ return &m_Exceptions; }
+	const rlv_object_map_t& getObjectMap() const { return m_Objects; }
 };
 
 typedef RlvHandler rlv_handler_t;
diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h
index 6f9dc3c722f2f8dce59fbc178d580b17df6dee60..964d8a5c5722b1ba604831bba53c2187b283c15d 100644
--- a/indra/newview/rlvhelper.h
+++ b/indra/newview/rlvhelper.h
@@ -548,7 +548,7 @@ class RlvObject
 	const LLUUID& getObjectID() const	{ return m_idObj; }
 	const LLUUID& getRootID() const		{ return m_idRoot; }
 	bool          hasLookup() const     { return m_fLookup; }
-	const rlv_command_list_t* getCommandList() const { return &m_Commands; }
+	const rlv_command_list_t& getCommandList() const { return m_Commands; }
 
 	/*
 	 * Member variables
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index fe898ec9e44988e77dd46b016b49d3450746f340..1a1dca5280149da11e9c662af5a4841ebaa09e5a 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -11016,11 +11016,32 @@ Cannot create large prims that intersect other players.  Please re-try when othe
 
   <notification
    icon="alertmodal.tga"
-   name="RLVChangeStrings"
+   name="RLVaChangeStrings"
    type="alertmodal">
 Changes won't take effect until after you restart [APP_NAME].
   </notification>
-  
+
+  <notification
+   icon="notify.tga"
+   name="RLVaListRequested"
+   label="Restriction request from [NAME_LABEL]"
+   log_to_im="true"
+   log_to_chat="false"
+   type="offer">
+[NAME_SLURL] has requested to be sent a list of your currently active RLV restrictions.
+    <tag>confirm</tag>
+    <form name="form">
+      <button
+       index="0"
+       name="Allow"
+       text="Allow"/>
+      <button
+       index="1"
+       name="Deny"
+       text="Deny"/>
+    </form>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="PreferenceChatClearLog"
diff --git a/indra/newview/skins/default/xui/en/rlva_strings.xml b/indra/newview/skins/default/xui/en/rlva_strings.xml
index 996f884a9c8bc993cfe3dc477da736f9486d01a7..f25c7d908cda7e43d332b70267b27ee13d0e1e0e 100644
--- a/indra/newview/skins/default/xui/en/rlva_strings.xml
+++ b/indra/newview/skins/default/xui/en/rlva_strings.xml
@@ -45,6 +45,48 @@
 			<boolean>1</boolean>
 		</map>
 
+		<!-- Sent to the remote party when they issue @list as an IM query (if enabled) -->
+		<key>imquery_list_deny</key>
+		<map>
+			<key>value</key>
+			<string>*** The other party respectfully requests you mind your own business (bunnies made me do it!)</string>
+			<key>description</key>
+			<string>Sent to the remote party when you deny their request to list your active RLV restrictions)</string>
+			<key>label</key>
+			<string>@list command (remote)</string>
+			<key>customizable</key>
+			<boolean>1</boolean>
+		</map>
+
+		<!-- Sent to the remote party when they issue @stopim as an IM query (if enabled) -->
+		<key>stopim_nosession</key>
+		<map>
+			<key>value</key>
+			<string>*** The other party is not under a @startim restriction</string>
+			<key>description</key>
+			<string>Sent to the remote party when they attempt to forcefully close your IM conversation with them (and no such session exists)</string>
+			<key>label</key>
+			<string>@stopim command with no session (remote)</string>
+			<key>customizable</key>
+			<boolean>1</boolean>
+		</map>
+		<key>stopim_endsession_remote</key>
+		<map>
+			<key>value</key>
+			<string>*** Session has been ended for the other party</string>
+			<key>description</key>
+			<string>Sent to the remote party when they attempt to forcefully close the IM conversation (and it exists)</string>
+			<key>label</key>
+			<string>@stopim command with an active session (remote)</string>
+			<key>customizable</key>
+			<boolean>1</boolean>
+		</map>
+		<key>stopim_endsession_local</key>
+		<map>
+			<key>value</key>
+			<string>[NAME] has remotely closed the IM conversation with @stopim</string>
+		</map>
+
 		<!-- Shown as notifications -->
 		<key>blocked_autopilot</key>
 		<map>