diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 13c381edaec7d4a5fc0a81ac99e145bc37ac55f8..3b18b7d70077e46b7cd30d254290d6485e99f169 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -246,6 +246,7 @@ set(viewer_SOURCE_FILES
     llinspectavatar.cpp
     llinspectgroup.cpp
     llinspectobject.cpp
+    llinspectremoteobject.cpp
     llinventorybridge.cpp
     llinventoryclipboard.cpp
     llinventoryfilter.cpp
@@ -741,6 +742,7 @@ set(viewer_HEADER_FILES
     llinspectavatar.h
     llinspectgroup.h
     llinspectobject.h
+    llinspectremoteobject.h
     llinventorybridge.h
     llinventoryclipboard.h
     llinventoryfilter.h
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e4d2eec242bf8bd846498aee5379b449b66a7335
--- /dev/null
+++ b/indra/newview/llinspectremoteobject.cpp
@@ -0,0 +1,200 @@
+/** 
+ * @file llinspectremoteobject.cpp
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llinspectremoteobject.h"
+#include "llinspect.h"
+#include "llslurl.h"
+#include "llmutelist.h"
+#include "llurlaction.h"
+#include "llpanelblockedlist.h"
+#include "llfloaterreg.h"
+#include "llui.h"
+#include "lluictrl.h"
+
+class LLViewerObject;
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectRemoteObject
+//////////////////////////////////////////////////////////////////////////////
+
+// Remote Object Inspector, a small information window used to
+// display information about potentially-remote objects. Used
+// to display details about objects sending messages to the user.
+class LLInspectRemoteObject : public LLInspect
+{
+	friend class LLFloaterReg;
+	
+public:
+	LLInspectRemoteObject(const LLSD& object_id);
+	virtual ~LLInspectRemoteObject() {};
+
+	/*virtual*/ BOOL postBuild(void);
+	/*virtual*/ void onOpen(const LLSD& avatar_id);
+
+	void onClickMap();
+	void onClickBlock();
+	void onClickClose();
+	
+private:
+	void update();
+	static void nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data);
+	
+private:
+	LLUUID		 mObjectID;
+	LLUUID		 mOwnerID;
+	std::string  mOwner;
+	std::string  mSLurl;
+	std::string  mName;
+	bool         mGroupOwned;
+};
+
+LLInspectRemoteObject::LLInspectRemoteObject(const LLSD& sd) :
+	LLInspect(LLSD()),
+	mObjectID(NULL),
+	mOwnerID(NULL),
+	mOwner(""),
+	mSLurl(""),
+	mName(""),
+	mGroupOwned(false)
+{
+}
+
+/*virtual*/
+BOOL LLInspectRemoteObject::postBuild(void)
+{
+	// hook up the inspector's buttons
+	getChild<LLUICtrl>("map_btn")->setCommitCallback(
+		boost::bind(&LLInspectRemoteObject::onClickMap, this));
+	getChild<LLUICtrl>("block_btn")->setCommitCallback(
+		boost::bind(&LLInspectRemoteObject::onClickBlock, this));
+	getChild<LLUICtrl>("close_btn")->setCommitCallback(
+		boost::bind(&LLInspectRemoteObject::onClickClose, this));
+
+	return TRUE;
+}
+
+/*virtual*/
+void LLInspectRemoteObject::onOpen(const LLSD& data)
+{
+	// Start animation
+	LLInspect::onOpen(data);
+
+	// Extract appropriate object information from input LLSD
+	// (Eventually, it might be nice to query server for details
+	// rather than require caller to pass in the information.)
+	mObjectID   = data["object_id"].asUUID();
+	mName       = data["name"].asString();
+	mOwnerID    = data["owner_id"].asUUID();
+	mGroupOwned = data["group_owned"].asBoolean();
+	mSLurl      = data["slurl"].asString();
+
+	// work out the owner's name
+	mOwner = "";
+	if (gCacheName)
+	{
+		gCacheName->get(mOwnerID, mGroupOwned, nameCallback, this);
+	}
+
+	// update the inspector with the current object state
+	update();
+
+	// Position the inspector relative to the mouse cursor
+	LLUI::positionViewNearMouse(this);
+}
+
+void LLInspectRemoteObject::onClickMap()
+{
+	std::string url = "secondlife://" + mSLurl;
+	LLUrlAction::showLocationOnMap(url);
+	closeFloater();
+}
+
+void LLInspectRemoteObject::onClickBlock()
+{
+	LLMute::EType mute_type = mGroupOwned ? LLMute::GROUP : LLMute::AGENT;
+	LLMute mute(mOwnerID, mOwner, mute_type);
+	LLMuteList::getInstance()->add(mute);
+	LLPanelBlockedList::showPanelAndSelect(mute.mID);
+	closeFloater();
+}
+
+void LLInspectRemoteObject::onClickClose()
+{
+	closeFloater();
+}
+
+//static 
+void LLInspectRemoteObject::nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
+{
+	LLInspectRemoteObject *self = (LLInspectRemoteObject*)data;
+	self->mOwner = first;
+	if (!last.empty())
+	{
+		self->mOwner += " " + last;
+	}
+	self->update();
+}
+
+void LLInspectRemoteObject::update()
+{
+	// show the object name as the inspector's title
+	getChild<LLUICtrl>("object_name")->setValue(mName);
+
+	// show the object's owner - click it to show profile
+	std::string owner = mOwner;
+	if (! mOwnerID.isNull())
+	{
+		if (mGroupOwned)
+		{
+			owner = LLSLURL::buildCommand("group", mOwnerID, "about");
+		}
+		else
+		{
+			owner = LLSLURL::buildCommand("agent", mOwnerID, "about");
+		}
+	}
+	getChild<LLUICtrl>("object_owner")->setValue(owner);
+
+	// display the object's SLurl - click it to teleport
+	std::string url = "secondlife:///app/teleport/" + mSLurl;
+	getChild<LLUICtrl>("object_slurl")->setValue(url);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectRemoteObjectUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLInspectRemoteObjectUtil::registerFloater()
+{
+	LLFloaterReg::add("inspect_remote_object", "inspect_remote_object.xml",
+					  &LLFloaterReg::build<LLInspectRemoteObject>);
+}
diff --git a/indra/newview/llinspectremoteobject.h b/indra/newview/llinspectremoteobject.h
new file mode 100644
index 0000000000000000000000000000000000000000..e756f1caf4effb63b725c186417ad22e074345fe
--- /dev/null
+++ b/indra/newview/llinspectremoteobject.h
@@ -0,0 +1,40 @@
+/** 
+ * @file llinspectremoteobject.h
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLINSPECTREMOTEOBJECT_H
+#define LLINSPECTREMOTEOBJECT_H
+
+namespace LLInspectRemoteObjectUtil
+{
+	void registerFloater();
+}
+
+#endif
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index edbac69e1b888a74bdc7875fafe077a107506eb9..964d3bc2fa5728227eb596cd81c535528c57bd09 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -112,6 +112,7 @@
 #include "llinspectavatar.h"
 #include "llinspectgroup.h"
 #include "llinspectobject.h"
+#include "llinspectremoteobject.h"
 #include "llmediaremotectrl.h"
 #include "llmoveview.h"
 #include "llnearbychat.h"
@@ -176,6 +177,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLInspectAvatarUtil::registerFloater();
 	LLInspectGroupUtil::registerFloater();
 	LLInspectObjectUtil::registerFloater();
+	LLInspectRemoteObjectUtil::registerFloater();
 	
 	LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
 	LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a90790c59a85f4ef976906c342cdf4156b91c13c..6d6fc5f49f27541d061691982d972cd1658fcbc9 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1431,6 +1431,17 @@ bool goto_url_callback(const LLSD& notification, const LLSD& response)
 }
 static LLNotificationFunctorRegistration goto_url_callback_reg("GotoURL", goto_url_callback);
 
+bool inspect_remote_object_callback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if (0 == option)
+	{
+		LLFloaterReg::showInstance("inspect_remote_object", notification["payload"]);
+	}
+	return false;
+}
+static LLNotificationFunctorRegistration inspect_remote_object_callback_reg("ServerObjectMessage", inspect_remote_object_callback);
+
 void process_improved_im(LLMessageSystem *msg, void **user_data)
 {
 	if (gNoRender)
@@ -1952,9 +1963,24 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				return;
 			}
 
+			// Build a link to open the object IM info window.
+			std::string location = ll_safe_string((char*)binary_bucket,binary_bucket_size);
+			LLStringUtil::trim(location);
+
 			LLSD substitutions;
+			substitutions["NAME"] = name;
 			substitutions["MSG"] = message.substr(message_offset);
-			LLNotifications::instance().add("ServerObjectMessage", substitutions);
+
+			LLSD payload;
+			payload["object_id"] = session_id;
+			payload["owner_id"] = from_id;
+			payload["slurl"] = location;
+			payload["name"] = name;
+			if (from_group)
+			{
+				payload["groupowned"] = "true";
+			}
+			LLNotifications::instance().add("ServerObjectMessage", substitutions, payload);
 		}
 		break;
 	case IM_FROM_TASK_AS_ALERT:
diff --git a/indra/newview/skins/default/xui/en/inspect_remote_object.xml b/indra/newview/skins/default/xui/en/inspect_remote_object.xml
new file mode 100644
index 0000000000000000000000000000000000000000..07c684d9047fe0910286c1770f1dd08c7fc4ae79
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/inspect_remote_object.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!--
+  Not can_close / no title to avoid window chrome
+  Single instance - only have one at a time, recycle it each spawn
+-->
+<floater
+ legacy_header_height="18"
+ bevel_style="in"
+ bg_opaque_image="Inspector_Background" 
+ can_close="false"
+ can_minimize="false"
+ height="145"
+ layout="topleft"
+ name="inspect_remote_object"
+ single_instance="true"
+ sound_flags="0"
+ visible="true"
+ width="300">
+  <text
+   follows="all"
+   font="SansSerifLargeBold"
+   height="16"
+   left="8"
+   name="object_name"
+   text_color="White"
+   top="5"
+   use_ellipses="true"
+   width="290">
+     Test Object Name That Is Really Long
+  </text>
+  <text
+   follows="all"
+   font="SansSerif"
+   height="20"
+   left="8"
+   name="object_owner_label"
+   width="55"
+   top_pad="20">
+     Owner:
+  </text>
+  <text
+   follows="top|left"
+   font="SansSerif"
+   height="20"
+   left_pad="10"
+   name="object_owner"
+   use_ellipses="true"
+   width="200"
+   word_wrap="false">
+     Longavatarname Johnsonlongstonnammer
+  </text>
+  <text
+   follows="top|left"
+   font="SansSerif"
+   height="20"
+   left="8"
+   name="object_slurl_label"
+   top_pad="10"
+   width="55">
+     Location:
+  </text>
+  <text
+   follows="top|left"
+   height="20"
+   left_pad="10"
+   name="object_slurl"
+   width="240"
+   use_ellipses="true"
+   word_wrap="false">
+     http://slurl.com/Ahern/50/50/50
+  </text>
+  <button
+   follows="top|left"
+   font="SansSerif"
+   height="20"
+   label="Map"
+   left="10"
+   name="map_btn"
+   top="114"
+   width="75" />
+  <button
+   follows="top|left"
+   font="SansSerif"
+   height="20"
+   label="Block"
+   left_pad="5"
+   name="block_btn"
+   top_delta="0"
+   width="75" />
+  <button
+   follows="top|left"
+   font="SansSerif"
+   height="20"
+   label="Close"
+   right="-10"
+   name="close_btn"
+   top_delta="0"
+   width="75" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index ccd8bc569e7e236a626be775f6974f98f922a1db..a44de51cb05f0e6c500e1cc2ea0f892e50e95338 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4696,7 +4696,12 @@ The objects on the selected parcel that are NOT owned by you have been returned
    icon="notify.tga"
    name="ServerObjectMessage"
    type="notify">
+Message from [NAME]:
 [MSG]
+    <usetemplate
+     name="okcancelbuttons"
+     notext="OK"
+     yestext="Inspect"/>
   </notification>
 
   <notification