diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 736de651da3a5720ba81ea6bc3f259c5ce6ba5ff..3375c13c94aae54d68ea2fdd99d52f1ba8bc763b 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -765,3 +765,35 @@ std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelC
 {
 	return getUrl(url);
 }
+
+//
+// LLUrlEntryIcon describes an icon with <icon>...</icon> tags
+//
+LLUrlEntryIcon::LLUrlEntryIcon()
+{
+	mPattern = boost::regex("<icon\\s*>\\s*([^<]*)?\\s*</icon\\s*>",
+							boost::regex::perl|boost::regex::icase);
+	mDisabledLink = true;
+}
+
+std::string LLUrlEntryIcon::getUrl(const std::string &url) const
+{
+	return LLStringUtil::null;
+}
+
+std::string LLUrlEntryIcon::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	return LLStringUtil::null;
+}
+
+std::string LLUrlEntryIcon::getIcon(const std::string &url)
+{
+	// Grep icon info between <icon>...</icon> tags
+	// matches[1] contains the icon name/path
+	boost::match_results<std::string::const_iterator> matches;
+	mIcon = (boost::regex_match(url, matches, mPattern) && matches[1].matched)
+		? matches[1]
+		: LLStringUtil::null;
+	LLStringUtil::trim(mIcon);
+	return mIcon;
+}
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 29575d752ced36fca7fa35713084028004b41d1d..71f030677ad47aa907d385b0eafb528f36712a39 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -77,7 +77,7 @@ class LLUrlEntryBase
 	virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; }
 
 	/// Return an icon that can be displayed next to Urls of this type
-	std::string getIcon() const { return mIcon; }
+	virtual std::string getIcon(const std::string &url) { return mIcon; }
 
 	/// Return the color to render the displayed text
 	LLUIColor getColor() const { return mColor; }
@@ -296,4 +296,17 @@ class LLUrlEntryNoLink : public LLUrlEntryBase
 	/*virtual*/ std::string getUrl(const std::string &string) const;
 };
 
+///
+/// LLUrlEntryIcon describes an icon with <icon>...</icon> tags
+///
+class LLUrlEntryIcon : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryIcon();
+	/*virtual*/ std::string getUrl(const std::string &string) const;
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+	/*virtual*/ std::string getIcon(const std::string &url);
+};
+
+
 #endif
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 0a70aa586a2cc40135232a4d9e992f27c3829ffe..4341286eb4cf46e2c654268c5f6a4b6813ab9d87 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -45,6 +45,7 @@ LLUrlRegistry::LLUrlRegistry()
 {
 	// Urls are matched in the order that they were registered
 	registerUrl(new LLUrlEntryNoLink());
+	registerUrl(new LLUrlEntryIcon());
 	registerUrl(new LLUrlEntrySLURL());
 	registerUrl(new LLUrlEntryHTTP());
 	registerUrl(new LLUrlEntryHTTPLabel());
@@ -135,7 +136,8 @@ static bool stringHasUrl(const std::string &text)
 			text.find(".net") != std::string::npos ||
 			text.find(".edu") != std::string::npos ||
 			text.find(".org") != std::string::npos ||
-			text.find("<nolink>") != std::string::npos);
+			text.find("<nolink>") != std::string::npos ||
+			text.find("<icon") != std::string::npos);
 }
 
 bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb)
@@ -177,7 +179,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
 						match_entry->getUrl(url),
 						match_entry->getLabel(url, cb),
 						match_entry->getTooltip(url),
-						match_entry->getIcon(),
+						match_entry->getIcon(url),
 						match_entry->getColor(),
 						match_entry->getMenuName(),
 						match_entry->getLocation(url),
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index ba0c8d464db147811e1654da634a7bff751ccc18..e12457550a4fc3f434221d3b237c87ca008e7f3b 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1933,7 +1933,7 @@ class LLPostponedServerObjectNotification: public LLPostponedNotification
 	}
 };
 
-static void parse_lure_bucket(const std::string& bucket,
+static bool parse_lure_bucket(const std::string& bucket,
 							  U64& region_handle,
 							  LLVector3& pos,
 							  LLVector3& look_at,
@@ -1945,15 +1945,25 @@ static void parse_lure_bucket(const std::string& bucket,
 	tokenizer tokens(bucket, sep);
 	tokenizer::iterator iter = tokens.begin();
 
-	S32 gx = boost::lexical_cast<S32>((*(iter)).c_str());
-	S32 gy = boost::lexical_cast<S32>((*(++iter)).c_str());
-	S32 rx = boost::lexical_cast<S32>((*(++iter)).c_str());
-	S32 ry = boost::lexical_cast<S32>((*(++iter)).c_str());
-	S32 rz = boost::lexical_cast<S32>((*(++iter)).c_str());
-	S32 lx = boost::lexical_cast<S32>((*(++iter)).c_str());
-	S32 ly = boost::lexical_cast<S32>((*(++iter)).c_str());
-	S32 lz = boost::lexical_cast<S32>((*(++iter)).c_str());
-
+	S32 gx,gy,rx,ry,rz,lx,ly,lz;
+	try
+	{
+		gx = boost::lexical_cast<S32>((*(iter)).c_str());
+		gy = boost::lexical_cast<S32>((*(++iter)).c_str());
+		rx = boost::lexical_cast<S32>((*(++iter)).c_str());
+		ry = boost::lexical_cast<S32>((*(++iter)).c_str());
+		rz = boost::lexical_cast<S32>((*(++iter)).c_str());
+		lx = boost::lexical_cast<S32>((*(++iter)).c_str());
+		ly = boost::lexical_cast<S32>((*(++iter)).c_str());
+		lz = boost::lexical_cast<S32>((*(++iter)).c_str());
+	}
+	catch( boost::bad_lexical_cast& )
+	{
+		LL_WARNS("parse_lure_bucket")
+			<< "Couldn't parse lure bucket."
+			<< LL_ENDL;
+		return false;
+	}
 	// Grab region access
 	region_access = SIM_ACCESS_MIN;
 	if (++iter != tokens.end())
@@ -1978,6 +1988,7 @@ static void parse_lure_bucket(const std::string& bucket,
 	look_at.setVec((F32)lx, (F32)ly, (F32)lz);
 
 	region_handle = to_region_handle(gx, gy);
+	return true;
 }
 
 void process_improved_im(LLMessageSystem *msg, void **user_data)
@@ -2615,15 +2626,21 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				U64 region_handle;
 				U8 region_access;
 				std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
-				parse_lure_bucket(region_info, region_handle, pos, look_at, region_access);
+				std::string region_access_str = LLStringUtil::null;
+				std::string region_access_icn = LLStringUtil::null;
 
-				std::string region_access_str = LLViewerRegion::accessToString(region_access);
+				if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
+				{
+					region_access_str = LLViewerRegion::accessToString(region_access);
+					region_access_icn = LLViewerRegion::getAccessIcon(region_access);
+				}
 
 				LLSD args;
 				// *TODO: Translate -> [FIRST] [LAST] (maybe)
 				args["NAME_SLURL"] = LLSLURL::buildCommand("agent", from_id, "about");
 				args["MESSAGE"] = message;
-				args["MATURITY"] = region_access_str;
+				args["MATURITY_STR"] = region_access_str;
+				args["MATURITY_ICON"] = region_access_icn;
 				LLSD payload;
 				payload["from_id"] = from_id;
 				payload["lure_id"] = session_id;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 07d4ac664f4e7e3a79f325dc215fcb0cb8854468..c48668df9a760e93e073cd85493634ab3470b21a 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -626,6 +626,26 @@ std::string LLViewerRegion::accessToString(U8 sim_access)
 	}
 }
 
+// static
+std::string LLViewerRegion::getAccessIcon(U8 sim_access)
+{
+	switch(sim_access)
+	{
+	case SIM_ACCESS_MATURE:
+		return "Parcel_M_Dark";
+
+	case SIM_ACCESS_ADULT:
+		return "Parcel_R_Light";
+
+	case SIM_ACCESS_PG:
+		return "Parcel_PG_Light";
+
+	case SIM_ACCESS_MIN:
+	default:
+		return "";
+	}
+}
+
 // static
 std::string LLViewerRegion::accessToShortString(U8 sim_access)
 {
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 49d0900f2ace9f36b6f4d30bb204ed29faff3f9e..5c4d5a61fd78be35bcba2de3e553465c5635db85 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -203,6 +203,9 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 
 	// Returns "M", "PG", "A" etc.
 	static std::string accessToShortString(U8 sim_access);
+
+	// Return access icon name
+	static std::string getAccessIcon(U8 sim_access);
 	
 	// helper function which just makes sure all interested parties
 	// can process the message.
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 5d184fea3a7e339c39518a8d7b7708f336bcd423..4479a3dd4d92ffd763a5019cdacafc1858aeaac4 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5168,7 +5168,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you th
    type="offer">
 [NAME_SLURL] has offered to teleport you to their location:
 
-[MESSAGE], ([MATURITY])
+[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
     <form name="form">
       <button
        index="0"