diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 5ff22f89ab0d2dac22bd055fa2f42362698a0d43..d4ec377e03ddb3e606966734d30c489859ffecb3 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -138,10 +138,7 @@ class LLChatHistoryHeader: public LLPanel
 
 		if (level == "profile")
 		{
-			LLSD params;
-			params["object_id"] = getAvatarId();
-
-			LLFloaterReg::showInstance("inspect_object", params);
+			LLFloaterReg::showInstance("inspect_remote_object", mObjectData);
 		}
 		else if (level == "block")
 		{
@@ -229,7 +226,7 @@ class LLChatHistoryHeader: public LLPanel
 		
 		if (mSourceType == CHAT_SOURCE_OBJECT)
 		{
-			LLFloaterReg::showInstance("inspect_object", LLSD().with("object_id", mAvatarID));
+			LLFloaterReg::showInstance("inspect_remote_object", mObjectData);
 		}
 		else if (mSourceType == CHAT_SOURCE_AGENT)
 		{
@@ -251,7 +248,7 @@ class LLChatHistoryHeader: public LLPanel
 
 	const LLUUID&		getAvatarId () const { return mAvatarID;}
 
-	void setup(const LLChat& chat,const LLStyle::Params& style_params) 
+	void setup(const LLChat& chat, const LLStyle::Params& style_params, const LLSD& args)
 	{
 		mAvatarID = chat.mFromID;
 		mSessionID = chat.mSessionID;
@@ -332,7 +329,8 @@ class LLChatHistoryHeader: public LLPanel
 
 
 		setTimeField(chat);
-		
+
+		// Set up the icon.
 		LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
 
 		if(mSourceType != CHAT_SOURCE_AGENT ||	mAvatarID.isNull())
@@ -352,6 +350,30 @@ class LLChatHistoryHeader: public LLPanel
 			case CHAT_SOURCE_UNKNOWN: 
 				icon->setValue(LLSD("Unknown_Icon"));
 		}
+
+		// In case the message came from an object, save the object info
+		// to be able properly show its profile.
+		if ( chat.mSourceType == CHAT_SOURCE_OBJECT)
+		{
+			std::string slurl = args["slurl"].asString();
+			if (slurl.empty())
+			{
+				LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent);
+				if(region)
+				{
+					LLSLURL region_slurl(region->getName(), chat.mPosAgent);
+					slurl = region_slurl.getLocationString();
+				}
+			}
+
+			LLSD payload;
+			payload["object_id"]	= chat.mFromID;
+			payload["name"]			= chat.mFromName;
+			payload["owner_id"]		= chat.mOwnerID;
+			payload["slurl"]		= LLWeb::escapeURL(slurl);
+
+			mObjectData = payload;
+		}
 	}
 
 	/*virtual*/ void draw()
@@ -540,6 +562,7 @@ class LLChatHistoryHeader: public LLPanel
 	static LLUICtrl*	sInfoCtrl;
 
 	LLUUID			    mAvatarID;
+	LLSD				mObjectData;
 	EChatSourceType		mSourceType;
 	std::string			mFrom;
 	LLUUID				mSessionID;
@@ -649,10 +672,10 @@ LLView* LLChatHistory::getSeparator()
 	return separator;
 }
 
-LLView* LLChatHistory::getHeader(const LLChat& chat,const LLStyle::Params& style_params)
+LLView* LLChatHistory::getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args)
 {
 	LLChatHistoryHeader* header = LLChatHistoryHeader::createInstance(mMessageHeaderFilename);
-	header->setup(chat,style_params);
+	header->setup(chat, style_params, args);
 	return header;
 }
 
@@ -834,7 +857,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		}
 		else
 		{
-			view = getHeader(chat, style_params);
+			view = getHeader(chat, style_params, args);
 			if (mEditor->getText().size() == 0)
 				p.top_pad = 0;
 			else
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index ac48d7bf29b82640ba1865dd9860525a7127b304..28344e6a1028f1c1bfaa4c5ba5632a263902a345 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -94,7 +94,7 @@ class LLChatHistory : public LLUICtrl
 		 * Builds a message header.
 		 * @return pointer to LLView header object.
 		 */
-		LLView* getHeader(const LLChat& chat,const LLStyle::Params& style_params);
+		LLView* getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args);
 
 		void onClickMoreText();
 
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 3584074ec168575d53f2c71f48108c77d37b7e55..8b52d478e63f4f56c1e797f0b0da7dff658a9d14 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1,6909 +1,6908 @@
-/** 
- * @file llviewermessage.cpp
- * @brief Dumping ground for viewer-side message system callbacks.
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-#include "llviewermessage.h"
-#include "boost/lexical_cast.hpp"
-
-// Linden libraries
-#include "llanimationstates.h"
-#include "llaudioengine.h" 
-#include "llavataractions.h"
-#include "llavatarnamecache.h"		// IDEVO HACK
-#include "lscript_byteformat.h"
-#include "lleconomy.h"
-#include "lleventtimer.h"
-#include "llfloaterreg.h"
-#include "llfollowcamparams.h"
-#include "llinventorydefines.h"
-#include "lllslconstants.h"
-#include "llregionhandle.h"
-#include "llsdserialize.h"
-#include "llteleportflags.h"
-#include "lltransactionflags.h"
-#include "llvfile.h"
-#include "llvfs.h"
-#include "llxfermanager.h"
-#include "mean_collision_data.h"
-
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llcallingcard.h"
-#include "llbuycurrencyhtml.h"
-#include "llfirstuse.h"
-#include "llfloaterbuyland.h"
-#include "llfloaterland.h"
-#include "llfloaterregioninfo.h"
-#include "llfloaterlandholdings.h"
-#include "llfloaterpostcard.h"
-#include "llfloaterpreference.h"
-#include "llhudeffecttrail.h"
-#include "llhudmanager.h"
-#include "llinventoryfunctions.h"
-#include "llinventoryobserver.h"
-#include "llinventorypanel.h"
-#include "llnearbychat.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
-#include "llpanelgrouplandmoney.h"
-#include "llrecentpeople.h"
-#include "llscriptfloater.h"
-#include "llselectmgr.h"
-#include "llsidetray.h"
-#include "llstartup.h"
-#include "llsky.h"
-#include "llslurl.h"
-#include "llstatenums.h"
-#include "llstatusbar.h"
-#include "llimview.h"
-#include "llspeakers.h"
-#include "lltrans.h"
-#include "lltranslate.h"
-#include "llviewerfoldertype.h"
-#include "llvoavatar.h"				// IDEVO HACK
-#include "lluri.h"
-#include "llviewergenericmessage.h"
-#include "llviewermenu.h"
-#include "llviewerjoystick.h"
-#include "llviewerobjectlist.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerstats.h"
-#include "llviewertexteditor.h"
-#include "llviewerthrottle.h"
-#include "llviewerwindow.h"
-#include "llvlmanager.h"
-#include "llvoavatarself.h"
-#include "llvotextbubble.h"
-#include "llworld.h"
-#include "pipeline.h"
-#include "llfloaterworldmap.h"
-#include "llviewerdisplay.h"
-#include "llkeythrottle.h"
-#include "llgroupactions.h"
-#include "llagentui.h"
-#include "llpanelblockedlist.h"
-#include "llpanelplaceprofile.h"
-
-#include <boost/algorithm/string/split.hpp> //
-#include <boost/regex.hpp>
-
-#include "llnotificationmanager.h" //
-
-#if LL_MSVC
-// disable boost::lexical_cast warning
-#pragma warning (disable:4702)
-#endif
-
-//
-// Constants
-//
-const F32 BIRD_AUDIBLE_RADIUS = 32.0f;
-const F32 SIT_DISTANCE_FROM_TARGET = 0.25f;
-static const F32 LOGOUT_REPLY_TIME = 3.f;	// Wait this long after LogoutReply before quitting.
-
-// Determine how quickly residents' scripts can issue question dialogs
-// Allow bursts of up to 5 dialogs in 10 seconds. 10*2=20 seconds recovery if throttle kicks in
-static const U32 LLREQUEST_PERMISSION_THROTTLE_LIMIT	= 5;     // requests
-static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL	= 10.0f; // seconds
-
-extern BOOL gDebugClicks;
-
-// function prototypes
-bool check_offer_throttle(const std::string& from_name, bool check_only);
-static void process_money_balance_reply_extended(LLMessageSystem* msg);
-
-//inventory offer throttle globals
-LLFrameTimer gThrottleTimer;
-const U32 OFFER_THROTTLE_MAX_COUNT=5; //number of items per time period
-const F32 OFFER_THROTTLE_TIME=10.f; //time period in seconds
-
-//script permissions
-const std::string SCRIPT_QUESTIONS[SCRIPT_PERMISSION_EOF] = 
-	{ 
-		"ScriptTakeMoney",
-		"ActOnControlInputs",
-		"RemapControlInputs",
-		"AnimateYourAvatar",
-		"AttachToYourAvatar",
-		"ReleaseOwnership",
-		"LinkAndDelink",
-		"AddAndRemoveJoints",
-		"ChangePermissions",
-		"TrackYourCamera",
-		"ControlYourCamera"
-	};
-
-const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] = 
-{
-	TRUE,	// ScriptTakeMoney,
-	FALSE,	// ActOnControlInputs
-	FALSE,	// RemapControlInputs
-	FALSE,	// AnimateYourAvatar
-	FALSE,	// AttachToYourAvatar
-	FALSE,	// ReleaseOwnership,
-	FALSE,	// LinkAndDelink,
-	FALSE,	// AddAndRemoveJoints
-	FALSE,	// ChangePermissions
-	FALSE,	// TrackYourCamera,
-	FALSE	// ControlYourCamera
-};
-
-bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	LLMessageSystem* msg = gMessageSystem;
-	const LLSD& payload = notification["payload"];
-
-	// add friend to recent people list
-	LLRecentPeople::instance().add(payload["from_id"]);
-
-	switch(option)
-	{
-	case 0:
-	{
-		// accept
-		LLAvatarTracker::formFriendship(payload["from_id"]);
-
-		const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
-
-		// This will also trigger an onlinenotification if the user is online
-		msg->newMessageFast(_PREHASH_AcceptFriendship);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->nextBlockFast(_PREHASH_TransactionBlock);
-		msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
-		msg->nextBlockFast(_PREHASH_FolderData);
-		msg->addUUIDFast(_PREHASH_FolderID, fid);
-		msg->sendReliable(LLHost(payload["sender"].asString()));
-
-		LLSD payload = notification["payload"];
-		payload["SUPPRESS_TOAST"] = true;
-		LLNotificationsUtil::add("FriendshipAcceptedByMe",
-				notification["substitutions"], payload);
-		break;
-	}
-	case 1: // Decline
-	{
-		LLSD payload = notification["payload"];
-		payload["SUPPRESS_TOAST"] = true;
-		LLNotificationsUtil::add("FriendshipDeclinedByMe",
-				notification["substitutions"], payload);
-	}
-	// fall-through
-	case 2: // Send IM - decline and start IM session
-		{
-			// decline
-			// We no longer notify other viewers, but we DO still send
-			// the rejection to the simulator to delete the pending userop.
-			msg->newMessageFast(_PREHASH_DeclineFriendship);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			msg->nextBlockFast(_PREHASH_TransactionBlock);
-			msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
-			msg->sendReliable(LLHost(payload["sender"].asString()));
-
-			// start IM session
-			if(2 == option)
-			{
-				LLAvatarActions::startIM(payload["from_id"].asUUID());
-			}
-	}
-	default:
-		// close button probably, possibly timed out
-		break;
-	}
-
-	return false;
-}
-static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback);
-static LLNotificationFunctorRegistration friendship_offer_callback_reg_nm("OfferFriendshipNoMessage", friendship_offer_callback);
-
-//const char BUSY_AUTO_RESPONSE[] =	"The Resident you messaged is in 'busy mode' which means they have "
-//									"requested not to be disturbed. Your message will still be shown in their IM "
-//									"panel for later viewing.";
-
-//
-// Functions
-//
-
-void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group,
-				S32 trx_type, const std::string& desc)
-{
-	if(0 == amount || !region) return;
-	amount = abs(amount);
-	LL_INFOS("Messaging") << "give_money(" << uuid << "," << amount << ")"<< LL_ENDL;
-	if(can_afford_transaction(amount))
-	{
-//		gStatusBar->debitBalance(amount);
-		LLMessageSystem* msg = gMessageSystem;
-		msg->newMessageFast(_PREHASH_MoneyTransferRequest);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-        msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->nextBlockFast(_PREHASH_MoneyData);
-		msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID() );
-		msg->addUUIDFast(_PREHASH_DestID, uuid);
-		msg->addU8Fast(_PREHASH_Flags, pack_transaction_flags(FALSE, is_group));
-		msg->addS32Fast(_PREHASH_Amount, amount);
-		msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY);
-		msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY);
-		msg->addS32Fast(_PREHASH_TransactionType, trx_type );
-		msg->addStringFast(_PREHASH_Description, desc);
-		msg->sendReliable(region->getHost());
-	}
-	else
-	{
-		LLStringUtil::format_map_t args;
-		args["AMOUNT"] = llformat("%d", amount);
-		LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("giving", args), amount );
-	}
-}
-
-void send_complete_agent_movement(const LLHost& sim_host)
-{
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_CompleteAgentMovement);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->addU32Fast(_PREHASH_CircuitCode, msg->mOurCircuitCode);
-	msg->sendReliable(sim_host);
-}
-
-void process_logout_reply(LLMessageSystem* msg, void**)
-{
-	// The server has told us it's ok to quit.
-	LL_DEBUGS("Messaging") << "process_logout_reply" << LL_ENDL;
-
-	LLUUID agent_id;
-	msg->getUUID("AgentData", "AgentID", agent_id);
-	LLUUID session_id;
-	msg->getUUID("AgentData", "SessionID", session_id);
-	if((agent_id != gAgent.getID()) || (session_id != gAgent.getSessionID()))
-	{
-		LL_WARNS("Messaging") << "Bogus Logout Reply" << LL_ENDL;
-	}
-
-	LLInventoryModel::update_map_t parents;
-	S32 count = msg->getNumberOfBlocksFast( _PREHASH_InventoryData );
-	for(S32 i = 0; i < count; ++i)
-	{
-		LLUUID item_id;
-		msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_ItemID, item_id, i);
-
-		if( (1 == count) && item_id.isNull() )
-		{
-			// Detect dummy item.  Indicates an empty list.
-			break;
-		}
-
-		// We do not need to track the asset ids, just account for an
-		// updated inventory version.
-		LL_INFOS("Messaging") << "process_logout_reply itemID=" << item_id << LL_ENDL;
-		LLInventoryItem* item = gInventory.getItem( item_id );
-		if( item )
-		{
-			parents[item->getParentUUID()] = 0;
-			gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
-		}
-		else
-		{
-			LL_INFOS("Messaging") << "process_logout_reply item not found: " << item_id << LL_ENDL;
-		}
-	}
-    LLAppViewer::instance()->forceQuit();
-}
-
-void process_layer_data(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLViewerRegion *regionp = LLWorld::getInstance()->getRegion(mesgsys->getSender());
-
-	if (!regionp || gNoRender)
-	{
-		return;
-	}
-
-
-	S32 size;
-	S8 type;
-
-	mesgsys->getS8Fast(_PREHASH_LayerID, _PREHASH_Type, type);
-	size = mesgsys->getSizeFast(_PREHASH_LayerData, _PREHASH_Data);
-	if (0 == size)
-	{
-		LL_WARNS("Messaging") << "Layer data has zero size." << LL_ENDL;
-		return;
-	}
-	if (size < 0)
-	{
-		// getSizeFast() is probably trying to tell us about an error
-		LL_WARNS("Messaging") << "getSizeFast() returned negative result: "
-			<< size
-			<< LL_ENDL;
-		return;
-	}
-	U8 *datap = new U8[size];
-	mesgsys->getBinaryDataFast(_PREHASH_LayerData, _PREHASH_Data, datap, size);
-	LLVLData *vl_datap = new LLVLData(regionp, type, datap, size);
-	if (mesgsys->getReceiveCompressedSize())
-	{
-		gVLManager.addLayerData(vl_datap, mesgsys->getReceiveCompressedSize());
-	}
-	else
-	{
-		gVLManager.addLayerData(vl_datap, mesgsys->getReceiveSize());
-	}
-}
-
-// S32 exported_object_count = 0;
-// S32 exported_image_count = 0;
-// S32 current_object_count = 0;
-// S32 current_image_count = 0;
-
-// extern LLNotifyBox *gExporterNotify;
-// extern LLUUID gExporterRequestID;
-// extern std::string gExportDirectory;
-
-// extern LLUploadDialog *gExportDialog;
-
-// std::string gExportedFile;
-
-// std::map<LLUUID, std::string> gImageChecksums;
-
-// void export_complete()
-// {
-// 		LLUploadDialog::modalUploadFinished();
-// 		gExporterRequestID.setNull();
-// 		gExportDirectory = "";
-
-// 		LLFILE* fXML = LLFile::fopen(gExportedFile, "rb");		/* Flawfinder: ignore */
-// 		fseek(fXML, 0, SEEK_END);
-// 		long length = ftell(fXML);
-// 		fseek(fXML, 0, SEEK_SET);
-// 		U8 *buffer = new U8[length + 1];
-// 		size_t nread = fread(buffer, 1, length, fXML);
-// 		if (nread < (size_t) length)
-// 		{
-// 			LL_WARNS("Messaging") << "Short read" << LL_ENDL;
-// 		}
-// 		buffer[nread] = '\0';
-// 		fclose(fXML);
-
-// 		char *pos = (char *)buffer;
-// 		while ((pos = strstr(pos+1, "<sl:image ")) != 0)
-// 		{
-// 			char *pos_check = strstr(pos, "checksum=\"");
-
-// 			if (pos_check)
-// 			{
-// 				char *pos_uuid = strstr(pos_check, "\">");
-
-// 				if (pos_uuid)
-// 				{
-// 					char image_uuid_str[UUID_STR_SIZE];		/* Flawfinder: ignore */
-// 					memcpy(image_uuid_str, pos_uuid+2, UUID_STR_SIZE-1);		/* Flawfinder: ignore */
-// 					image_uuid_str[UUID_STR_SIZE-1] = 0;
-					
-// 					LLUUID image_uuid(image_uuid_str);
-
-// 					LL_INFOS("Messaging") << "Found UUID: " << image_uuid << LL_ENDL;
-
-// 					std::map<LLUUID, std::string>::iterator itor = gImageChecksums.find(image_uuid);
-// 					if (itor != gImageChecksums.end())
-// 					{
-// 						LL_INFOS("Messaging") << "Replacing with checksum: " << itor->second << LL_ENDL;
-// 						if (!itor->second.empty())
-// 						{
-// 							memcpy(&pos_check[10], itor->second.c_str(), 32);		/* Flawfinder: ignore */
-// 						}
-// 					}
-// 				}
-// 			}
-// 		}
-
-// 		LLFILE* fXMLOut = LLFile::fopen(gExportedFile, "wb");		/* Flawfinder: ignore */
-// 		if (fwrite(buffer, 1, length, fXMLOut) != length)
-// 		{
-// 			LL_WARNS("Messaging") << "Short write" << LL_ENDL;
-// 		}
-// 		fclose(fXMLOut);
-
-// 		delete [] buffer;
-// }
-
-
-// void exported_item_complete(const LLTSCode status, void *user_data)
-// {
-// 	//std::string *filename = (std::string *)user_data;
-
-// 	if (status < LLTS_OK)
-// 	{
-// 		LL_WARNS("Messaging") << "Export failed!" << LL_ENDL;
-// 	}
-// 	else
-// 	{
-// 		++current_object_count;
-// 		if (current_image_count == exported_image_count && current_object_count == exported_object_count)
-// 		{
-// 			LL_INFOS("Messaging") << "*** Export complete ***" << LL_ENDL;
-
-// 			export_complete();
-// 		}
-// 		else
-// 		{
-// 			gExportDialog->setMessage(llformat("Exported %d/%d object files, %d/%d textures.", current_object_count, exported_object_count, current_image_count, exported_image_count));
-// 		}
-// 	}
-// }
-
-// struct exported_image_info
-// {
-// 	LLUUID image_id;
-// 	std::string filename;
-// 	U32 image_num;
-// };
-
-// void exported_j2c_complete(const LLTSCode status, void *user_data)
-// {
-// 	exported_image_info *info = (exported_image_info *)user_data;
-// 	LLUUID image_id = info->image_id;
-// 	U32 image_num = info->image_num;
-// 	std::string filename = info->filename;
-// 	delete info;
-
-// 	if (status < LLTS_OK)
-// 	{
-// 		LL_WARNS("Messaging") << "Image download failed!" << LL_ENDL;
-// 	}
-// 	else
-// 	{
-// 		LLFILE* fIn = LLFile::fopen(filename, "rb");		/* Flawfinder: ignore */
-// 		if (fIn) 
-// 		{
-// 			LLPointer<LLImageJ2C> ImageUtility = new LLImageJ2C;
-// 			LLPointer<LLImageTGA> TargaUtility = new LLImageTGA;
-
-// 			fseek(fIn, 0, SEEK_END);
-// 			S32 length = ftell(fIn);
-// 			fseek(fIn, 0, SEEK_SET);
-// 			U8 *buffer = ImageUtility->allocateData(length);
-// 			if (fread(buffer, 1, length, fIn) != length)
-// 			{
-// 				LL_WARNS("Messaging") << "Short read" << LL_ENDL;
-// 			}
-// 			fclose(fIn);
-// 			LLFile::remove(filename);
-
-// 			// Convert to TGA
-// 			LLPointer<LLImageRaw> image = new LLImageRaw();
-
-// 			ImageUtility->updateData();
-// 			ImageUtility->decode(image, 100000.0f);
-			
-// 			TargaUtility->encode(image);
-// 			U8 *data = TargaUtility->getData();
-// 			S32 data_size = TargaUtility->getDataSize();
-
-// 			std::string file_path = gDirUtilp->getDirName(filename);
-			
-// 			std::string output_file = llformat("%s/image-%03d.tga", file_path.c_str(), image_num);//filename;
-// 			//S32 name_len = output_file.length();
-// 			//strcpy(&output_file[name_len-3], "tga");
-// 			LLFILE* fOut = LLFile::fopen(output_file, "wb");		/* Flawfinder: ignore */
-// 			char md5_hash_string[33];		/* Flawfinder: ignore */
-// 			strcpy(md5_hash_string, "00000000000000000000000000000000");		/* Flawfinder: ignore */
-// 			if (fOut)
-// 			{
-// 				if (fwrite(data, 1, data_size, fOut) != data_size)
-// 				{
-// 					LL_WARNS("Messaging") << "Short write" << LL_ENDL;
-// 				}
-// 				fseek(fOut, 0, SEEK_SET);
-// 				fclose(fOut);
-// 				fOut = LLFile::fopen(output_file, "rb");		/* Flawfinder: ignore */
-// 				LLMD5 my_md5_hash(fOut);
-// 				my_md5_hash.hex_digest(md5_hash_string);
-// 			}
-
-// 			gImageChecksums.insert(std::pair<LLUUID, std::string>(image_id, md5_hash_string));
-// 		}
-// 	}
-
-// 	++current_image_count;
-// 	if (current_image_count == exported_image_count && current_object_count == exported_object_count)
-// 	{
-// 		LL_INFOS("Messaging") << "*** Export textures complete ***" << LL_ENDL;
-// 			export_complete();
-// 	}
-// 	else
-// 	{
-// 		gExportDialog->setMessage(llformat("Exported %d/%d object files, %d/%d textures.", current_object_count, exported_object_count, current_image_count, exported_image_count));
-// 	}
-//}
-
-void process_derez_ack(LLMessageSystem*, void**)
-{
-	if(gViewerWindow) gViewerWindow->getWindow()->decBusyCount();
-}
-
-void process_places_reply(LLMessageSystem* msg, void** data)
-{
-	LLUUID query_id;
-
-	msg->getUUID("AgentData", "QueryID", query_id);
-	if (query_id.isNull())
-	{
-		LLFloaterLandHoldings::processPlacesReply(msg, data);
-	}
-	else if(gAgent.isInGroup(query_id))
-	{
-		LLPanelGroupLandMoney::processPlacesReply(msg, data);
-	}
-	else
-	{
-		LL_WARNS("Messaging") << "Got invalid PlacesReply message" << LL_ENDL;
-	}
-}
-
-void send_sound_trigger(const LLUUID& sound_id, F32 gain)
-{
-	if (sound_id.isNull() || gAgent.getRegion() == NULL)
-	{
-		// disconnected agent or zero guids don't get sent (no sound)
-		return;
-	}
-
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_SoundTrigger);
-	msg->nextBlockFast(_PREHASH_SoundData);
-	msg->addUUIDFast(_PREHASH_SoundID, sound_id);
-	// Client untrusted, ids set on sim
-	msg->addUUIDFast(_PREHASH_OwnerID, LLUUID::null );
-	msg->addUUIDFast(_PREHASH_ObjectID, LLUUID::null );
-	msg->addUUIDFast(_PREHASH_ParentID, LLUUID::null );
-
-	msg->addU64Fast(_PREHASH_Handle, gAgent.getRegion()->getHandle());
-
-	LLVector3 position = gAgent.getPositionAgent();
-	msg->addVector3Fast(_PREHASH_Position, position);
-	msg->addF32Fast(_PREHASH_Gain, gain);
-
-	gAgent.sendMessage();
-}
-
-bool join_group_response(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	BOOL delete_context_data = TRUE;
-	bool accept_invite = false;
-
-	LLUUID group_id = notification["payload"]["group_id"].asUUID();
-	LLUUID transaction_id = notification["payload"]["transaction_id"].asUUID();
-	std::string name = notification["payload"]["name"].asString();
-	std::string message = notification["payload"]["message"].asString();
-	S32 fee = notification["payload"]["fee"].asInteger();
-
-	if (option == 2 && !group_id.isNull())
-	{
-		LLGroupActions::show(group_id);
-		LLSD args;
-		args["MESSAGE"] = message;
-		LLNotificationsUtil::add("JoinGroup", args, notification["payload"]);
-		return false;
-	}
-	if(option == 0 && !group_id.isNull())
-	{
-		// check for promotion or demotion.
-		S32 max_groups = gMaxAgentGroups;
-		if(gAgent.isInGroup(group_id)) ++max_groups;
-
-		if(gAgent.mGroups.count() < max_groups)
-		{
-			accept_invite = true;
-		}
-		else
-		{
-			delete_context_data = FALSE;
-			LLSD args;
-			args["NAME"] = name;
-			LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification["payload"]);
-		}
-	}
-
-	if (accept_invite)
-	{
-		// If there is a fee to join this group, make
-		// sure the user is sure they want to join.
-		if (fee > 0)
-		{
-			delete_context_data = FALSE;
-			LLSD args;
-			args["COST"] = llformat("%d", fee);
-			// Set the fee for next time to 0, so that we don't keep
-			// asking about a fee.
-			LLSD next_payload = notification["payload"];
-			next_payload["fee"] = 0;
-			LLNotificationsUtil::add("JoinGroupCanAfford",
-									args,
-									next_payload);
-		}
-		else
-		{
-			send_improved_im(group_id,
-							 std::string("name"),
-							 std::string("message"),
-							IM_ONLINE,
-							IM_GROUP_INVITATION_ACCEPT,
-							transaction_id);
-		}
-	}
-	else
-	{
-		send_improved_im(group_id,
-						 std::string("name"),
-						 std::string("message"),
-						IM_ONLINE,
-						IM_GROUP_INVITATION_DECLINE,
-						transaction_id);
-	}
-
-	return false;
-}
-
-static void highlight_inventory_items_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel)
-{
-	if (NULL == inventory_panel) return;
-
-	for (std::vector<LLUUID>::const_iterator item_iter = items.begin();
-		item_iter != items.end();
-		++item_iter)
-	{
-		const LLUUID& item_id = (*item_iter);
-		if(!highlight_offered_object(item_id))
-		{
-			continue;
-		}
-
-		LLInventoryItem* item = gInventory.getItem(item_id);
-		llassert(item);
-		if (!item) {
-			continue;
-		}
-
-		LL_DEBUGS("Inventory_Move") << "Highlighting inventory item: " << item->getName() << ", " << item_id  << LL_ENDL;
-		LLFolderView* fv = inventory_panel->getRootFolder();
-		if (fv)
-		{
-			LLFolderViewItem* fv_item = fv->getItemByID(item_id);
-			if (fv_item)
-			{
-				LLFolderViewItem* fv_folder = fv_item->getParentFolder();
-				if (fv_folder)
-				{
-					// Parent folders can be different in case of 2 consecutive drag and drop
-					// operations when the second one is started before the first one completes.
-					LL_DEBUGS("Inventory_Move") << "Open folder: " << fv_folder->getName() << LL_ENDL;
-					fv_folder->setOpen(TRUE);
-					if (fv_folder->isSelected())
-					{
-						fv->changeSelection(fv_folder, FALSE);
-					}
-				}
-				fv->changeSelection(fv_item, TRUE);
-			}
-		}
-	}
-}
-
-static LLNotificationFunctorRegistration jgr_1("JoinGroup", join_group_response);
-static LLNotificationFunctorRegistration jgr_2("JoinedTooManyGroupsMember", join_group_response);
-static LLNotificationFunctorRegistration jgr_3("JoinGroupCanAfford", join_group_response);
-
-
-//-----------------------------------------------------------------------------
-// Instant Message
-//-----------------------------------------------------------------------------
-class LLOpenAgentOffer : public LLInventoryFetchItemsObserver
-{
-public:
-	LLOpenAgentOffer(const LLUUID& object_id,
-					 const std::string& from_name) : 
-		LLInventoryFetchItemsObserver(object_id),
-		mFromName(from_name) {}
-	/*virtual*/ void startFetch()
-	{
-		for (uuid_vec_t::const_iterator it = mIDs.begin(); it < mIDs.end(); ++it)
-		{
-			LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
-			if (cat)
-			{
-				mComplete.push_back((*it));
-			}
-		}
-		LLInventoryFetchItemsObserver::startFetch();
-	}
-	/*virtual*/ void done()
-	{
-		open_inventory_offer(mComplete, mFromName);
-		gInventory.removeObserver(this);
-		delete this;
-	}
-private:
-	std::string mFromName;
-};
-
-/**
- * Class to observe adding of new items moved from the world to user's inventory to select them in inventory.
- *
- * We can't create it each time items are moved because "drop" event is sent separately for each
- * element even while multi-dragging. We have to have the only instance of the observer. See EXT-4347.
- */
-class LLViewerInventoryMoveFromWorldObserver : public LLInventoryAddItemByAssetObserver
-{
-public:
-	LLViewerInventoryMoveFromWorldObserver()
-		: LLInventoryAddItemByAssetObserver()
-		, mActivePanel(NULL)
-	{
-
-	}
-
-	void setMoveIntoFolderID(const LLUUID& into_folder_uuid) {mMoveIntoFolderID = into_folder_uuid; }
-
-private:
-	/*virtual */void onAssetAdded(const LLUUID& asset_id)
-	{
-		// Store active Inventory panel.
-		mActivePanel = LLInventoryPanel::getActiveInventoryPanel();
-
-		// Store selected items (without destination folder)
-		mSelectedItems.clear();
-		if (mActivePanel)
-		{
-			mSelectedItems = mActivePanel->getRootFolder()->getSelectionList();
-		}
-		mSelectedItems.erase(mMoveIntoFolderID);
-	}
-
-	/**
-	 * Selects added inventory items watched by their Asset UUIDs if selection was not changed since
-	 * all items were started to watch (dropped into a folder).
-	 */
-	void done()
-	{
-		// if selection is not changed since watch started lets hightlight new items.
-		if (mActivePanel && !isSelectionChanged())
-		{
-			LL_DEBUGS("Inventory_Move") << "Selecting new items..." << LL_ENDL;
-			mActivePanel->clearSelection();
-			highlight_inventory_items_in_panel(mAddedItems, mActivePanel);
-		}
-	}
-
-	/**
-	 * Returns true if selected inventory items were changed since moved inventory items were started to watch.
-	 */
-	bool isSelectionChanged()
-	{
-		const LLInventoryPanel * const current_active_panel = LLInventoryPanel::getActiveInventoryPanel();
-
-		if (NULL == mActivePanel || current_active_panel != mActivePanel)
-		{
-			return true;
-		}
-
-		// get selected items (without destination folder)
-		selected_items_t selected_items = mActivePanel->getRootFolder()->getSelectionList();
-		selected_items.erase(mMoveIntoFolderID);
-
-		// compare stored & current sets of selected items
-		selected_items_t different_items;
-		std::set_symmetric_difference(mSelectedItems.begin(), mSelectedItems.end(),
-			selected_items.begin(), selected_items.end(), std::inserter(different_items, different_items.begin()));
-
-		LL_DEBUGS("Inventory_Move") << "Selected firstly: " << mSelectedItems.size()
-			<< ", now: " << selected_items.size() << ", difference: " << different_items.size() << LL_ENDL;
-
-		return different_items.size() > 0;
-	}
-
-	LLInventoryPanel *mActivePanel;
-	typedef std::set<LLUUID> selected_items_t;
-	selected_items_t mSelectedItems;
-
-	/**
-	 * UUID of FolderViewFolder into which watched items are moved.
-	 *
-	 * Destination FolderViewFolder becomes selected while mouse hovering (when dragged items are dropped).
-	 * 
-	 * If mouse is moved out it set unselected and number of selected items is changed 
-	 * even if selected items in Inventory stay the same.
-	 * So, it is used to update stored selection list.
-	 *
-	 * @see onAssetAdded()
-	 * @see isSelectionChanged()
-	 */
-	LLUUID mMoveIntoFolderID;
-};
-
-LLViewerInventoryMoveFromWorldObserver* gInventoryMoveObserver = NULL;
-
-void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid)
-{
-	start_new_inventory_observer();
-
-	gInventoryMoveObserver->setMoveIntoFolderID(into_folder_uuid);
-	gInventoryMoveObserver->watchAsset(inv_item->getAssetUUID());
-}
-
-//unlike the FetchObserver for AgentOffer, we only make one 
-//instance of the AddedObserver for TaskOffers
-//and it never dies.  We do this because we don't know the UUID of 
-//task offers until they are accepted, so we don't wouldn't 
-//know what to watch for, so instead we just watch for all additions.
-class LLOpenTaskOffer : public LLInventoryAddedObserver
-{
-protected:
-	/*virtual*/ void done()
-	{
-		for (uuid_vec_t::iterator it = mAdded.begin(); it != mAdded.end();)
-		{
-			const LLUUID& item_uuid = *it;
-			bool was_moved = false;
-			LLInventoryObject* added_object = gInventory.getObject(item_uuid);
-			if (added_object)
-			{
-				// cast to item to get Asset UUID
-				LLInventoryItem* added_item = dynamic_cast<LLInventoryItem*>(added_object);
-				if (added_item)
-				{
-					const LLUUID& asset_uuid = added_item->getAssetUUID();
-					if (gInventoryMoveObserver->isAssetWatched(asset_uuid))
-					{
-						LL_DEBUGS("Inventory_Move") << "Found asset UUID: " << asset_uuid << LL_ENDL;
-						was_moved = true;
-					}
-				}
-			}
-
-			if (was_moved)
-			{
-				it = mAdded.erase(it);
-			}
-			else ++it;
-		}
-
-		open_inventory_offer(mAdded, "");
-		mAdded.clear();
-	}
- };
-
-class LLOpenTaskGroupOffer : public LLInventoryAddedObserver
-{
-protected:
-	/*virtual*/ void done()
-	{
-		open_inventory_offer(mAdded, "group_offer");
-		mAdded.clear();
-		gInventory.removeObserver(this);
-		delete this;
-	}
-};
-
-//one global instance to bind them
-LLOpenTaskOffer* gNewInventoryObserver=NULL;
-
-class LLNewInventoryHintObserver : public LLInventoryAddedObserver
-{
-protected:
-	/*virtual*/ void done()
-	{
-		LLFirstUse::newInventory();
-	}
-};
-
-void start_new_inventory_observer()
-{
-	if (!gNewInventoryObserver) //task offer observer 
-	{
-		// Observer is deleted by gInventory
-		gNewInventoryObserver = new LLOpenTaskOffer;
-		gInventory.addObserver(gNewInventoryObserver);
-	}
-
-	if (!gInventoryMoveObserver) //inventory move from the world observer 
-	{
-		// Observer is deleted by gInventory
-		gInventoryMoveObserver = new LLViewerInventoryMoveFromWorldObserver;
-		gInventory.addObserver(gInventoryMoveObserver);
-	}
-
-	gInventory.addObserver(new LLNewInventoryHintObserver());
-}
-
-class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver
-{
-	LOG_CLASS(LLDiscardAgentOffer);
-public:
-	LLDiscardAgentOffer(const LLUUID& folder_id, const LLUUID& object_id) :
-		LLInventoryFetchItemsObserver(object_id),
-		mFolderID(folder_id),
-		mObjectID(object_id) {}
-	virtual ~LLDiscardAgentOffer() {}
-	virtual void done()
-	{
-		LL_DEBUGS("Messaging") << "LLDiscardAgentOffer::done()" << LL_ENDL;
-		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
-		bool notify = false;
-		if(trash_id.notNull() && mObjectID.notNull())
-		{
-			LLInventoryModel::update_list_t update;
-			LLInventoryModel::LLCategoryUpdate old_folder(mFolderID, -1);
-			update.push_back(old_folder);
-			LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
-			update.push_back(new_folder);
-			gInventory.accountForUpdate(update);
-			gInventory.moveObject(mObjectID, trash_id);
-			LLInventoryObject* obj = gInventory.getObject(mObjectID);
-			if(obj)
-			{
-				// no need to restamp since this is already a freshly
-				// stamped item.
-				obj->updateParentOnServer(FALSE);
-				notify = true;
-			}
-		}
-		else
-		{
-			LL_WARNS("Messaging") << "DiscardAgentOffer unable to find: "
-					<< (trash_id.isNull() ? "trash " : "")
-					<< (mObjectID.isNull() ? "object" : "") << LL_ENDL;
-		}
-		gInventory.removeObserver(this);
-		if(notify)
-		{
-			gInventory.notifyObservers();
-		}
-		delete this;
-	}
-protected:
-	LLUUID mFolderID;
-	LLUUID mObjectID;
-};
-
-
-//Returns TRUE if we are OK, FALSE if we are throttled
-//Set check_only true if you want to know the throttle status 
-//without registering a hit
-bool check_offer_throttle(const std::string& from_name, bool check_only)
-{
-	static U32 throttle_count;
-	static bool throttle_logged;
-	LLChat chat;
-	std::string log_message;
-
-	if (!gSavedSettings.getBOOL("ShowNewInventory"))
-		return false;
-
-	if (check_only)
-	{
-		return gThrottleTimer.hasExpired();
-	}
-	
-	if(gThrottleTimer.checkExpirationAndReset(OFFER_THROTTLE_TIME))
-	{
-		LL_DEBUGS("Messaging") << "Throttle Expired" << LL_ENDL;
-		throttle_count=1;
-		throttle_logged=false;
-		return true;
-	}
-	else //has not expired
-	{
-		LL_DEBUGS("Messaging") << "Throttle Not Expired, Count: " << throttle_count << LL_ENDL;
-		// When downloading the initial inventory we get a lot of new items
-		// coming in and can't tell that from spam.
-		if (LLStartUp::getStartupState() >= STATE_STARTED
-			&& throttle_count >= OFFER_THROTTLE_MAX_COUNT)
-		{
-			if (!throttle_logged)
-			{
-				// Use the name of the last item giver, who is probably the person
-				// spamming you.
-
-				LLStringUtil::format_map_t arg;
-				std::string log_msg;
-				std::ostringstream time ;
-				time<<OFFER_THROTTLE_TIME;
-
-				arg["APP_NAME"] = LLAppViewer::instance()->getSecondLifeTitle();
-				arg["TIME"] = time.str();
-
-				if (!from_name.empty())
-				{
-					arg["FROM_NAME"] = from_name;
-					log_msg = LLTrans::getString("ItemsComingInTooFastFrom", arg);
-				}
-				else
-				{
-					log_msg = LLTrans::getString("ItemsComingInTooFast", arg);
-				}
-				
-				//this is kinda important, so actually put it on screen
-				LLSD args;
-				args["MESSAGE"] = log_msg;
-				LLNotificationsUtil::add("SystemMessage", args);
-
-				throttle_logged=true;
-			}
-			return false;
-		}
-		else
-		{
-			throttle_count++;
-			return true;
-		}
-	}
-}
- 
-void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_name)
-{
-	for (uuid_vec_t::const_iterator obj_iter = objects.begin();
-		 obj_iter != objects.end();
-		 ++obj_iter)
-	{
-		const LLUUID& obj_id = (*obj_iter);
-		if(!highlight_offered_object(obj_id))
-		{
-			continue;
-		}
-
-		const LLInventoryObject *obj = gInventory.getObject(obj_id);
-		if (!obj)
-		{
-			llwarns << "Cannot find object [ itemID:" << obj_id << " ] to open." << llendl;
-			continue;
-		}
-
-		const LLAssetType::EType asset_type = obj->getActualType();
-
-		// Either an inventory item or a category.
-		const LLInventoryItem* item = dynamic_cast<const LLInventoryItem*>(obj);
-		if (item)
-		{
-			////////////////////////////////////////////////////////////////////////////////
-			// Special handling for various types.
-			if (check_offer_throttle(from_name, false)) // If we are throttled, don't display
-			{
-				LL_DEBUGS("Messaging") << "Highlighting inventory item: " << item->getUUID()  << LL_ENDL;
-				// If we opened this ourselves, focus it
-				const BOOL take_focus = from_name.empty() ? TAKE_FOCUS_YES : TAKE_FOCUS_NO;
-				switch(asset_type)
-				{
-					case LLAssetType::AT_NOTECARD:
-					{
-						LLFloaterReg::showInstance("preview_notecard", LLSD(obj_id), take_focus);
-						break;
-					}
-					case LLAssetType::AT_LANDMARK:
-					{
-						LLInventoryCategory* parent_folder = gInventory.getCategory(item->getParentUUID());
-						if ("inventory_handler" == from_name)
-						{
-							//we have to filter inventory_handler messages to avoid notification displaying
-							LLSideTray::getInstance()->showPanel("panel_places",
-																 LLSD().with("type", "landmark").with("id", item->getUUID()));
-						}
-						else if("group_offer" == from_name)
-						{
-							// "group_offer" is passed by LLOpenTaskGroupOffer
-							// Notification about added landmark will be generated under the "from_name.empty()" called from LLOpenTaskOffer::done().
-							LLSD args;
-							args["type"] = "landmark";
-							args["id"] = obj_id;
-							LLSideTray::getInstance()->showPanel("panel_places", args);
-
-							continue;
-						}
-						else if(from_name.empty())
-						{
-							std::string folder_name;
-							if (parent_folder)
-							{
-								// Localize folder name.
-								// *TODO: share this code?
-								folder_name = parent_folder->getName();
-								if (LLFolderType::lookupIsProtectedType(parent_folder->getPreferredType()))
-								{
-									LLTrans::findString(folder_name, "InvFolder " + folder_name);
-								}
-							}
-							else
-							{
-								 folder_name = LLTrans::getString("Unknown");
-							}
-
-							// we receive a message from LLOpenTaskOffer, it mean that new landmark has been added.
-							LLSD args;
-							args["LANDMARK_NAME"] = item->getName();
-							args["FOLDER_NAME"] = folder_name;
-							LLNotificationsUtil::add("LandmarkCreated", args);
-						}
-					}
-					break;
-					case LLAssetType::AT_TEXTURE:
-					{
-						LLFloaterReg::showInstance("preview_texture", LLSD(obj_id), take_focus);
-						break;
-					}
-					case LLAssetType::AT_ANIMATION:
-						LLFloaterReg::showInstance("preview_anim", LLSD(obj_id), take_focus);
-						break;
-					case LLAssetType::AT_SCRIPT:
-						LLFloaterReg::showInstance("preview_script", LLSD(obj_id), take_focus);
-						break;
-					case LLAssetType::AT_SOUND:
-						LLFloaterReg::showInstance("preview_sound", LLSD(obj_id), take_focus);
-						break;
-					default:
-						break;
-				}
-			}
-		}
-
-		////////////////////////////////////////////////////////////////////////////////
-		// Highlight item
-		const BOOL auto_open = 
-			gSavedSettings.getBOOL("ShowInInventory") && // don't open if showininventory is false
-			!(asset_type == LLAssetType::AT_CALLINGCARD) && // don't open if it's a calling card
-			!from_name.empty(); // don't open if it's not from anyone.
-		LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open);
-		if(active_panel)
-		{
-			LL_DEBUGS("Messaging") << "Highlighting" << obj_id  << LL_ENDL;
-			LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus();
-			active_panel->setSelection(obj_id, TAKE_FOCUS_NO);
-			gFocusMgr.setKeyboardFocus(focus_ctrl);
-		}
-	}
-}
-
-bool highlight_offered_object(const LLUUID& obj_id)
-{
-	const LLInventoryObject* obj = gInventory.getObject(obj_id);
-	if(!obj)
-	{
-		LL_WARNS("Messaging") << "Unable to show inventory item: " << obj_id << LL_ENDL;
-		return false;
-	}
-
-	////////////////////////////////////////////////////////////////////////////////
-	// Don't highlight if it's in certain "quiet" folders which don't need UI
-	// notification (e.g. trash, cof, lost-and-found).
-	if(!gAgent.getAFK())
-	{
-		const LLViewerInventoryCategory *parent = gInventory.getFirstNondefaultParent(obj_id);
-		if (parent)
-		{
-			const LLFolderType::EType parent_type = parent->getPreferredType();
-			if (LLViewerFolderType::lookupIsQuietType(parent_type))
-			{
-				return false;
-			}
-		}
-	}
-
-	return true;
-}
-
-void inventory_offer_mute_callback(const LLUUID& blocked_id,
-								   const std::string& full_name,
-								   bool is_group,
-								   boost::shared_ptr<LLNotificationResponderInterface> offer_ptr)
-{
-	LLOfferInfo* offer =  dynamic_cast<LLOfferInfo*>(offer_ptr.get());
-	
-	std::string from_name = full_name;
-	LLMute::EType type;
-	if (is_group)
-	{
-		type = LLMute::GROUP;
-	}
-	else if(offer && offer->mFromObject)
-	{
-		//we have to block object by name because blocked_id is an id of owner
-		type = LLMute::BY_NAME;
-	}
-	else
-	{
-		type = LLMute::AGENT;
-	}
-
-	// id should be null for BY_NAME mute, see  LLMuteList::add for details  
-	LLMute mute(type == LLMute::BY_NAME ? LLUUID::null : blocked_id, from_name, type);
-	if (LLMuteList::getInstance()->add(mute))
-	{
-		LLPanelBlockedList::showPanelAndSelect(blocked_id);
-	}
-
-	// purge the message queue of any previously queued inventory offers from the same source.
-	class OfferMatcher : public LLNotificationsUI::LLScreenChannel::Matcher
-	{
-	public:
-		OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
-		bool matches(const LLNotificationPtr notification) const
-		{
-			if(notification->getName() == "ObjectGiveItem" 
-				|| notification->getName() == "UserGiveItem")
-			{
-				return (notification->getPayload()["from_id"].asUUID() == blocked_id);
-			}
-			return FALSE;
-		}
-	private:
-		const LLUUID& blocked_id;
-	};
-
-	LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID(
-			gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id));
-}
-
-LLOfferInfo::LLOfferInfo()
- : LLNotificationResponderInterface()
- , mFromGroup(FALSE)
- , mFromObject(FALSE)
- , mIM(IM_NOTHING_SPECIAL)
- , mType(LLAssetType::AT_NONE)
- , mPersist(false)
-{
-}
-
-LLOfferInfo::LLOfferInfo(const LLSD& sd)
-{
-	mIM = (EInstantMessage)sd["im_type"].asInteger();
-	mFromID = sd["from_id"].asUUID();
-	mFromGroup = sd["from_group"].asBoolean();
-	mFromObject = sd["from_object"].asBoolean();
-	mTransactionID = sd["transaction_id"].asUUID();
-	mFolderID = sd["folder_id"].asUUID();
-	mObjectID = sd["object_id"].asUUID();
-	mType = LLAssetType::lookup(sd["type"].asString().c_str());
-	mFromName = sd["from_name"].asString();
-	mDesc = sd["description"].asString();
-	mHost = LLHost(sd["sender"].asString());
-	mPersist = sd["persist"].asBoolean();
-}
-
-LLOfferInfo::LLOfferInfo(const LLOfferInfo& info)
-{
-	mIM = info.mIM;
-	mFromID = info.mFromID;
-	mFromGroup = info.mFromGroup;
-	mFromObject = info.mFromObject;
-	mTransactionID = info.mTransactionID;
-	mFolderID = info.mFolderID;
-	mObjectID = info.mObjectID;
-	mType = info.mType;
-	mFromName = info.mFromName;
-	mDesc = info.mDesc;
-	mHost = info.mHost;
-	mPersist = info.mPersist;
-}
-
-LLSD LLOfferInfo::asLLSD()
-{
-	LLSD sd;
-	sd["im_type"] = mIM;
-	sd["from_id"] = mFromID;
-	sd["from_group"] = mFromGroup;
-	sd["from_object"] = mFromObject;
-	sd["transaction_id"] = mTransactionID;
-	sd["folder_id"] = mFolderID;
-	sd["object_id"] = mObjectID;
-	sd["type"] = LLAssetType::lookup(mType);
-	sd["from_name"] = mFromName;
-	sd["description"] = mDesc;
-	sd["sender"] = mHost.getIPandPort();
-	sd["persist"] = mPersist;
-	return sd;
-}
-
-void LLOfferInfo::fromLLSD(const LLSD& params)
-{
-	*this = params;
-}
-
-void LLOfferInfo::send_auto_receive_response(void)
-{	
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_MessageBlock);
-	msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
-	msg->addUUIDFast(_PREHASH_ToAgentID, mFromID);
-	msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
-	msg->addUUIDFast(_PREHASH_ID, mTransactionID);
-	msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
-	std::string name;
-	LLAgentUI::buildFullname(name);
-	msg->addStringFast(_PREHASH_FromAgentName, name);
-	msg->addStringFast(_PREHASH_Message, ""); 
-	msg->addU32Fast(_PREHASH_ParentEstateID, 0);
-	msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
-	msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
-	
-	// Auto Receive Message. The math for the dialog works, because the accept
-	// for inventory_offered, task_inventory_offer or
-	// group_notice_inventory is 1 greater than the offer integer value.
-	// Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED, 
-	// or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
-	msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
-	msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
-						   sizeof(mFolderID.mData));
-	// send the message
-	msg->sendReliable(mHost);
-	
-	if(IM_INVENTORY_OFFERED == mIM)
-	{
-		// add buddy to recent people list
-		LLRecentPeople::instance().add(mFromID);
-	}
-}
-
-void LLOfferInfo::handleRespond(const LLSD& notification, const LLSD& response)
-{
-	initRespondFunctionMap();
-
-	const std::string name = notification["name"].asString();
-	if(mRespondFunctions.find(name) == mRespondFunctions.end())
-	{
-		llwarns << "Unexpected notification name : " << name << llendl;
-		llassert(!"Unexpected notification name");
-		return;
-	}
-
-	mRespondFunctions[name](notification, response);
-}
-
-bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& response)
-{
-	LLChat chat;
-	std::string log_message;
-	S32 button = LLNotificationsUtil::getSelectedOption(notification, response);
-	
-	LLInventoryObserver* opener = NULL;
-	LLViewerInventoryCategory* catp = NULL;
-	catp = (LLViewerInventoryCategory*)gInventory.getCategory(mObjectID);
-	LLViewerInventoryItem* itemp = NULL;
-	if(!catp)
-	{
-		itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
-	}
-	 
-	// For muting, we need to add the mute, then decline the offer.
-	// This must be done here because:
-	// * callback may be called immediately,
-	// * adding the mute sends a message,
-	// * we can't build two messages at once.
-	if (2 == button) // Block
-	{
-		LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
-
-		llassert(notification_ptr != NULL);
-		if (notification_ptr != NULL)
-		{
-			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
-		}
-	}
-
-	std::string from_string; // Used in the pop-up.
-	std::string chatHistory_string;  // Used in chat history.
-	
-	// TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here:
-	from_string = chatHistory_string = mFromName;
-	
-	bool busy=FALSE;
-	
-	switch(button)
-	{
-	case IOR_SHOW:
-		// we will want to open this item when it comes back.
-		LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
-				 << LL_ENDL;
-		switch (mIM)
-		{
-		case IM_INVENTORY_OFFERED:
-			{
-				// This is an offer from an agent. In this case, the back
-				// end has already copied the items into your inventory,
-				// so we can fetch it out of our inventory.
-				if (gSavedSettings.getBOOL("ShowOfferedInventory"))
-				{
-					LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(mObjectID, from_string);
-					open_agent_offer->startFetch();
-					if(catp || (itemp && itemp->isFinished()))
-					{
-						open_agent_offer->done();
-					}
-					else
-					{
-						opener = open_agent_offer;
-					}
-				}
-			}
-			break;
-		case IM_GROUP_NOTICE:
-			opener = new LLOpenTaskGroupOffer;
-			send_auto_receive_response();
-			break;
-		case IM_TASK_INVENTORY_OFFERED:
-		case IM_GROUP_NOTICE_REQUESTED:
-			// This is an offer from a task or group.
-			// We don't use a new instance of an opener
-			// We instead use the singular observer gOpenTaskOffer
-			// Since it already exists, we don't need to actually do anything
-			break;
-		default:
-			LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
-			break;
-		}
-		break;
-		// end switch (mIM)
-			
-	case IOR_ACCEPT:
-		//don't spam them if they are getting flooded
-		if (check_offer_throttle(mFromName, true))
-		{
-			log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
-			LLSD args;
-			args["MESSAGE"] = log_message;
-			LLNotificationsUtil::add("SystemMessage", args);
-		}
-		break;
-
-	case IOR_BUSY:
-		//Busy falls through to decline.  Says to make busy message.
-		busy=TRUE;
-	case IOR_MUTE:
-		// MUTE falls through to decline
-	case IOR_DECLINE:
-		{
-			{
-				LLStringUtil::format_map_t log_message_args;
-				log_message_args["DESC"] = mDesc;
-				log_message_args["NAME"] = mFromName;
-				log_message = LLTrans::getString("InvOfferDecline", log_message_args);
-			}
-			chat.mText = log_message;
-			if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) )  // muting for SL-42269
-			{
-				chat.mMuted = TRUE;
-			}
-
-			// *NOTE dzaporozhan
-			// Disabled logging to old chat floater to fix crash in group notices - EXT-4149
-			// LLFloaterChat::addChatHistory(chat);
-			
-			LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
-			discard_agent_offer->startFetch();
-			if (catp || (itemp && itemp->isFinished()))
-			{
-				discard_agent_offer->done();
-			}
-			else
-			{
-				opener = discard_agent_offer;
-			}
-			
-			
-			if (busy &&	(!mFromGroup && !mFromObject))
-			{
-				busy_message(gMessageSystem, mFromID);
-			}
-			break;
-		}
-	default:
-		// close button probably
-		// The item has already been fetched and is in your inventory, we simply won't highlight it
-		// OR delete it if the notification gets killed, since we don't want that to be a vector for 
-		// losing inventory offers.
-		break;
-	}
-
-	if(opener)
-	{
-		gInventory.addObserver(opener);
-	}
-
-	if(!mPersist)
-	{
-		delete this;
-	}
-	return false;
-}
-
-bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const LLSD& response)
-{
-	LLChat chat;
-	std::string log_message;
-	S32 button = LLNotification::getSelectedOption(notification, response);
-	
-	// For muting, we need to add the mute, then decline the offer.
-	// This must be done here because:
-	// * callback may be called immediately,
-	// * adding the mute sends a message,
-	// * we can't build two messages at once.
-	if (2 == button)
-	{
-		LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
-
-		llassert(notification_ptr != NULL);
-		if (notification_ptr != NULL)
-		{
-			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
-		}
-	}
-	
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_MessageBlock);
-	msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
-	msg->addUUIDFast(_PREHASH_ToAgentID, mFromID);
-	msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
-	msg->addUUIDFast(_PREHASH_ID, mTransactionID);
-	msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
-	std::string name;
-	LLAgentUI::buildFullname(name);
-	msg->addStringFast(_PREHASH_FromAgentName, name);
-	msg->addStringFast(_PREHASH_Message, ""); 
-	msg->addU32Fast(_PREHASH_ParentEstateID, 0);
-	msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
-	msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
-	LLInventoryObserver* opener = NULL;
-	
-	std::string from_string; // Used in the pop-up.
-	std::string chatHistory_string;  // Used in chat history.
-	if (mFromObject == TRUE)
-	{
-		if (mFromGroup)
-		{
-			std::string group_name;
-			if (gCacheName->getGroupName(mFromID, group_name))
-			{
-				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+"'" 
-				+ mFromName + LLTrans::getString("'") +" " + LLTrans::getString("InvOfferOwnedByGroup") 
-				+ " "+ "'" + group_name + "'";
-				
-				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByGroup") 
-				+ " " + group_name + "'";
-			}
-			else
-			{
-				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+"'"
-				+ mFromName +"'"+ " " + LLTrans::getString("InvOfferOwnedByUnknownGroup");
-				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByUnknownGroup");
-			}
-		}
-		else
-		{
-			std::string full_name;
-			if (gCacheName->getFullName(mFromID, full_name))
-			{
-				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+ LLTrans::getString("'") + mFromName 
-					+ LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + full_name;
-				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + full_name;
-			}
-			else
-			{
-				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+LLTrans::getString("'") 
-				+ mFromName + LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedByUnknownUser");
-				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByUnknownUser");
-			}
-		}
-	}
-	else
-	{
-		from_string = chatHistory_string = mFromName;
-	}
-	
-	bool busy=FALSE;
-	
-	switch(button)
-	{
-		case IOR_ACCEPT:
-			// ACCEPT. The math for the dialog works, because the accept
-			// for inventory_offered, task_inventory_offer or
-			// group_notice_inventory is 1 greater than the offer integer value.
-			// Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED, 
-			// or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
-			msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
-			msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
-								   sizeof(mFolderID.mData));
-			// send the message
-			msg->sendReliable(mHost);
-			
-			//don't spam them if they are getting flooded
-			if (check_offer_throttle(mFromName, true))
-			{
-				log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
-				LLSD args;
-				args["MESSAGE"] = log_message;
-				LLNotificationsUtil::add("SystemMessage", args);
-			}
-			
-			// we will want to open this item when it comes back.
-			LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
-			<< LL_ENDL;
-			switch (mIM)
-		{
-			case IM_TASK_INVENTORY_OFFERED:
-			case IM_GROUP_NOTICE:
-			case IM_GROUP_NOTICE_REQUESTED:
-			{
-				// This is an offer from a task or group.
-				// We don't use a new instance of an opener
-				// We instead use the singular observer gOpenTaskOffer
-				// Since it already exists, we don't need to actually do anything
-			}
-				break;
-			default:
-				LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
-				break;
-		}	// end switch (mIM)
-			break;
-			
-		case IOR_BUSY:
-			//Busy falls through to decline.  Says to make busy message.
-			busy=TRUE;
-		case IOR_MUTE:
-			// MUTE falls through to decline
-		case IOR_DECLINE:
-			// DECLINE. The math for the dialog works, because the decline
-			// for inventory_offered, task_inventory_offer or
-			// group_notice_inventory is 2 greater than the offer integer value.
-			// Generates IM_INVENTORY_DECLINED, IM_TASK_INVENTORY_DECLINED,
-			// or IM_GROUP_NOTICE_INVENTORY_DECLINED
-		default:
-			// close button probably (or any of the fall-throughs from above)
-			msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 2));
-			msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
-			// send the message
-			msg->sendReliable(mHost);
-
-			if (gSavedSettings.getBOOL("LogInventoryDecline"))
-			{
-				LLStringUtil::format_map_t log_message_args;
-				log_message_args["DESC"] = mDesc;
-				log_message_args["NAME"] = mFromName;
-				log_message = LLTrans::getString("InvOfferDecline", log_message_args);
-
-				LLSD args;
-				args["MESSAGE"] = log_message;
-				LLNotificationsUtil::add("SystemMessage", args);
-			}
-			
-			if (busy &&	(!mFromGroup && !mFromObject))
-			{
-				busy_message(msg,mFromID);
-			}
-			break;
-	}
-	
-	if(opener)
-	{
-		gInventory.addObserver(opener);
-	}
-
-	if(!mPersist)
-	{
-		delete this;
-	}
-	return false;
-}
-
-class LLPostponedOfferNotification: public LLPostponedNotification
-{
-protected:
-	/* virtual */
-	void modifyNotificationParams()
-	{
-		LLSD substitutions = mParams.substitutions;
-		substitutions["NAME"] = mName;
-		mParams.substitutions = substitutions;
-	}
-};
-
-void LLOfferInfo::initRespondFunctionMap()
-{
-	if(mRespondFunctions.empty())
-	{
-		mRespondFunctions["ObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
-		mRespondFunctions["UserGiveItem"] = boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2);
-	}
-}
-
-void inventory_offer_handler(LLOfferInfo* info)
-{
-	//Until throttling is implmented, busy mode should reject inventory instead of silently
-	//accepting it.  SEE SL-39554
-	if (gAgent.getBusy())
-	{
-		info->forceResponse(IOR_BUSY);
-		return;
-	}
-	
-	//If muted, don't even go through the messaging stuff.  Just curtail the offer here.
-	if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName))
-	{
-		info->forceResponse(IOR_MUTE);
-		return;
-	}
-
-	// Avoid the Accept/Discard dialog if the user so desires. JC
-	if (gSavedSettings.getBOOL("AutoAcceptNewInventory")
-		&& (info->mType == LLAssetType::AT_NOTECARD
-			|| info->mType == LLAssetType::AT_LANDMARK
-			|| info->mType == LLAssetType::AT_TEXTURE))
-	{
-		// For certain types, just accept the items into the inventory,
-		// and possibly open them on receipt depending upon "ShowNewInventory".
-		info->forceResponse(IOR_ACCEPT);
-		return;
-	}
-
-	// Strip any SLURL from the message display. (DEV-2754)
-	std::string msg = info->mDesc;
-	int indx = msg.find(" ( http://slurl.com/secondlife/");
-	if(indx == std::string::npos)
-	{
-		// try to find new slurl host
-		indx = msg.find(" ( http://maps.secondlife.com/secondlife/");
-	}
-	if(indx >= 0)
-	{
-		LLStringUtil::truncate(msg, indx);
-	}
-
-	LLSD args;
-	args["[OBJECTNAME]"] = msg;
-
-	LLSD payload;
-
-	// must protect against a NULL return from lookupHumanReadable()
-	std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
-	if (!typestr.empty())
-	{
-		// human readable matches string name from strings.xml
-		// lets get asset type localized name
-		args["OBJECTTYPE"] = LLTrans::getString(typestr);
-	}
-	else
-	{
-		LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL;
-		args["OBJECTTYPE"] = "";
-
-		// This seems safest, rather than propagating bogosity
-		LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL;
-		info->forceResponse(IOR_DECLINE);
-		return;
-	}
-
-	// If mObjectID is null then generate the object_id based on msg to prevent
-	// multiple creation of chiclets for same object.
-	LLUUID object_id = info->mObjectID;
-	if (object_id.isNull())
-		object_id.generate(msg);
-
-	payload["from_id"] = info->mFromID;
-	// Needed by LLScriptFloaterManager to bind original notification with 
-	// faked for toast one.
-	payload["object_id"] = object_id;
-	// Flag indicating that this notification is faked for toast.
-	payload["give_inventory_notification"] = FALSE;
-	args["OBJECTFROMNAME"] = info->mFromName;
-	args["NAME"] = info->mFromName;
-	if (info->mFromGroup)
-	{
-		args["NAME_SLURL"] = LLSLURL("group", info->mFromID, "about").getSLURLString();
-	}
-	else
-	{
-		args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString();
-	}
-	std::string verb = "select?name=" + LLURI::escape(msg);
-	args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
-
-	LLNotification::Params p("ObjectGiveItem");
-
-	// Object -> Agent Inventory Offer
-	if (info->mFromObject)
-	{
-		// Inventory Slurls don't currently work for non agent transfers, so only display the object name.
-		args["ITEM_SLURL"] = msg;
-		// Note: sets inventory_task_offer_callback as the callback
-		p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
-		info->mPersist = true;
-		p.name = "ObjectGiveItem";
-		// Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
-	    LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE);
-	}
-	else // Agent -> Agent Inventory Offer
-	{
-		p.responder = info;
-		// Note: sets inventory_offer_callback as the callback
-		// *TODO fix memory leak
-		// inventory_offer_callback() is not invoked if user received notification and 
-		// closes viewer(without responding the notification)
-		p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
-		info->mPersist = true;
-		p.name = "UserGiveItem";
-		
-		// Prefetch the item into your local inventory.
-		LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
-		fetch_item->startFetch();
-		if(fetch_item->isFinished())
-		{
-			fetch_item->done();
-		}
-		else
-		{
-			gInventory.addObserver(fetch_item);
-		}
-		
-		// In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages).
-		info->send_auto_receive_response();
-
-		// Inform user that there is a script floater via toast system
-		{
-			payload["give_inventory_notification"] = TRUE;
-		    p.payload = payload;
-		    LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
-		}
-	}
-
-	LLFirstUse::newInventory();
-}
-
-bool lure_callback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = 0;
-	if (response.isInteger()) 
-	{
-		option = response.asInteger();
-	}
-	else
-	{
-		option = LLNotificationsUtil::getSelectedOption(notification, response);
-	}
-	
-	LLUUID from_id = notification["payload"]["from_id"].asUUID();
-	LLUUID lure_id = notification["payload"]["lure_id"].asUUID();
-	BOOL godlike = notification["payload"]["godlike"].asBoolean();
-
-	switch(option)
-	{
-	case 0:
-		{
-			// accept
-			gAgent.teleportViaLure(lure_id, godlike);
-		}
-		break;
-	case 1:
-	default:
-		// decline
-		send_simple_im(from_id,
-					   LLStringUtil::null,
-					   IM_LURE_DECLINED,
-					   lure_id);
-		break;
-	}
-	return false;
-}
-static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback);
-
-bool goto_url_callback(const LLSD& notification, const LLSD& response)
-{
-	std::string url = notification["payload"]["url"].asString();
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if(1 == option)
-	{
-		LLWeb::loadURL(url);
-	}
-	return false;
-}
-static LLNotificationFunctorRegistration goto_url_callback_reg("GotoURL", goto_url_callback);
-
-bool inspect_remote_object_callback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::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);
-
-class LLPostponedServerObjectNotification: public LLPostponedNotification
-{
-protected:
-	/* virtual */
-	void modifyNotificationParams()
-	{
-		LLSD payload = mParams.payload;
-		mParams.payload = payload;
-	}
-};
-
-static bool parse_lure_bucket(const std::string& bucket,
-							  U64& region_handle,
-							  LLVector3& pos,
-							  LLVector3& look_at,
-							  U8& region_access)
-{
-	// tokenize the bucket
-	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
-	boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
-	tokenizer tokens(bucket, sep);
-	tokenizer::iterator iter = tokens.begin();
-
-	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())
-	{
-		std::string access_str((*iter).c_str());
-		LLStringUtil::trim(access_str);
-		if ( access_str == "A" )
-		{
-			region_access = SIM_ACCESS_ADULT;
-		}
-		else if ( access_str == "M" )
-		{
-			region_access = SIM_ACCESS_MATURE;
-		}
-		else if ( access_str == "PG" )
-		{
-			region_access = SIM_ACCESS_PG;
-		}
-	}
-
-	pos.setVec((F32)rx, (F32)ry, (F32)rz);
-	look_at.setVec((F32)lx, (F32)ly, (F32)lz);
-
-	region_handle = to_region_handle(gx, gy);
-	return true;
-}
-
-// Strip out "Resident" for display, but only if the message came from a user
-// (rather than a script)
-static std::string clean_name_from_im(const std::string& name, EInstantMessage type)
-{
-	switch(type)
-	{
-	case IM_NOTHING_SPECIAL:
-	case IM_MESSAGEBOX:
-	case IM_GROUP_INVITATION:
-	case IM_INVENTORY_OFFERED:
-	case IM_INVENTORY_ACCEPTED:
-	case IM_INVENTORY_DECLINED:
-	case IM_GROUP_VOTE:
-	case IM_GROUP_MESSAGE_DEPRECATED:
-	//IM_TASK_INVENTORY_OFFERED
-	//IM_TASK_INVENTORY_ACCEPTED
-	//IM_TASK_INVENTORY_DECLINED
-	case IM_NEW_USER_DEFAULT:
-	case IM_SESSION_INVITE:
-	case IM_SESSION_P2P_INVITE:
-	case IM_SESSION_GROUP_START:
-	case IM_SESSION_CONFERENCE_START:
-	case IM_SESSION_SEND:
-	case IM_SESSION_LEAVE:
-	//IM_FROM_TASK
-	case IM_BUSY_AUTO_RESPONSE:
-	case IM_CONSOLE_AND_CHAT_HISTORY:
-	case IM_LURE_USER:
-	case IM_LURE_ACCEPTED:
-	case IM_LURE_DECLINED:
-	case IM_GODLIKE_LURE_USER:
-	case IM_YET_TO_BE_USED:
-	case IM_GROUP_ELECTION_DEPRECATED:
-	//IM_GOTO_URL
-	//IM_FROM_TASK_AS_ALERT
-	case IM_GROUP_NOTICE:
-	case IM_GROUP_NOTICE_INVENTORY_ACCEPTED:
-	case IM_GROUP_NOTICE_INVENTORY_DECLINED:
-	case IM_GROUP_INVITATION_ACCEPT:
-	case IM_GROUP_INVITATION_DECLINE:
-	case IM_GROUP_NOTICE_REQUESTED:
-	case IM_FRIENDSHIP_OFFERED:
-	case IM_FRIENDSHIP_ACCEPTED:
-	case IM_FRIENDSHIP_DECLINED_DEPRECATED:
-	//IM_TYPING_START
-	//IM_TYPING_STOP
-		return LLCacheName::cleanFullName(name);
-	default:
-		return name;
-	}
-}
-
-static std::string clean_name_from_task_im(const std::string& msg,
-										   BOOL from_group)
-{
-	boost::smatch match;
-	static const boost::regex returned_exp(
-		"(.*been returned to your inventory lost and found folder by )(.+)( (from|near).*)");
-	if (boost::regex_match(msg, match, returned_exp))
-	{
-		// match objects are 1-based for groups
-		std::string final = match[1].str();
-		std::string name = match[2].str();
-		// Don't try to clean up group names
-		if (!from_group)
-		{
-			if (LLAvatarNameCache::useDisplayNames())
-			{
-				// ...just convert to username
-				final += LLCacheName::buildUsername(name);
-			}
-			else
-			{
-				// ...strip out legacy "Resident" name
-				final += LLCacheName::cleanFullName(name);
-			}
-		}
-		final += match[3].str();
-		return final;
-	}
-	return msg;
-}
-
-void notification_display_name_callback(const LLUUID& id,
-					  const LLAvatarName& av_name,
-					  const std::string& name, 
-					  LLSD& substitutions, 
-					  const LLSD& payload)
-{
-	substitutions["NAME"] = av_name.mDisplayName;
-	LLNotificationsUtil::add(name, substitutions, payload);
-}
-
-class LLPostponedIMSystemTipNotification: public LLPostponedNotification
-{
-protected:
-	/* virtual */
-	void modifyNotificationParams()
-	{
-		LLSD payload = mParams.payload;
-		payload["SESSION_NAME"] = mName;
-		mParams.payload = payload;
-	}
-
-};
-
-// Callback for name resolution of a god/estate message
-void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
-{	
-	LLSD args;
-	args["NAME"] = av_name.getCompleteName();
-	args["MESSAGE"] = message;
-	LLNotificationsUtil::add("GodMessage", args);
-
-	// Treat like a system message and put in chat history.
-	chat.mText = av_name.getCompleteName() + ": " + message;
-
-	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
-	if(nearby_chat)
-	{
-		nearby_chat->addMessage(chat);
-	}
-
-}
-
-void process_improved_im(LLMessageSystem *msg, void **user_data)
-{
-	if (gNoRender)
-	{
-		return;
-	}
-	LLUUID from_id;
-	BOOL from_group;
-	LLUUID to_id;
-	U8 offline;
-	U8 d = 0;
-	LLUUID session_id;
-	U32 timestamp;
-	std::string name;
-	std::string message;
-	U32 parent_estate_id = 0;
-	LLUUID region_id;
-	LLVector3 position;
-	U8 binary_bucket[MTUBYTES];
-	S32 binary_bucket_size;
-	LLChat chat;
-	std::string buffer;
-	
-	// *TODO: Translate - need to fix the full name to first/last (maybe)
-	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, from_id);
-	msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, from_group);
-	msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, to_id);
-	msg->getU8Fast(  _PREHASH_MessageBlock, _PREHASH_Offline, offline);
-	msg->getU8Fast(  _PREHASH_MessageBlock, _PREHASH_Dialog, d);
-	msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id);
-	msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, timestamp);
-	//msg->getData("MessageBlock", "Count",		&count);
-	msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name);
-	msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message,		message);
-	msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, parent_estate_id);
-	msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, region_id);
-	msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, position);
-	msg->getBinaryDataFast(  _PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES);
-	binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
-	EInstantMessage dialog = (EInstantMessage)d;
-
-    // make sure that we don't have an empty or all-whitespace name
-	LLStringUtil::trim(name);
-	if (name.empty())
-	{
-        name = LLTrans::getString("Unnamed");
-	}
-	// IDEVO convert new-style "Resident" names for display
-	name = clean_name_from_im(name, dialog);
-
-	BOOL is_busy = gAgent.getBusy();
-	BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat);
-	BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
-	BOOL is_owned_by_me = FALSE;
-	BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
-	BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
-	
-	chat.mMuted = is_muted && !is_linden;
-	chat.mFromID = from_id;
-	chat.mFromName = name;
-	chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
-
-	LLViewerObject *source = gObjectList.findObject(session_id); //Session ID is probably the wrong thing.
-	if (source)
-	{
-		is_owned_by_me = source->permYouOwner();
-	}
-
-	std::string separator_string(": ");
-
-	LLSD args;
-	LLSD payload;
-	LLNotification::Params params;
-
-	switch(dialog)
-	{
-	case IM_CONSOLE_AND_CHAT_HISTORY:
-		args["MESSAGE"] = message;
-		payload["from_id"] = from_id;
-
-		params.name = "IMSystemMessageTip";
-		params.substitutions = args;
-		params.payload = payload;
-	    LLPostponedNotification::add<LLPostponedIMSystemTipNotification>(params, from_id, false);
-		break;
-
-	case IM_NOTHING_SPECIAL: 
-		// Don't show dialog, just do IM
-		if (!gAgent.isGodlike()
-				&& gAgent.getRegion()->isPrelude() 
-				&& to_id.isNull() )
-		{
-			// do nothing -- don't distract newbies in
-			// Prelude with global IMs
-		}
-		else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM)
-		{
-			// return a standard "busy" message, but only do it to online IM 
-			// (i.e. not other auto responses and not store-and-forward IM)
-			if (!gIMMgr->hasSession(session_id))
-			{
-				// if there is not a panel for this conversation (i.e. it is a new IM conversation
-				// initiated by the other party) then...
-				std::string my_name;
-				LLAgentUI::buildFullname(my_name);
-				std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
-				pack_instant_message(
-					gMessageSystem,
-					gAgent.getID(),
-					FALSE,
-					gAgent.getSessionID(),
-					from_id,
-					my_name,
-					response,
-					IM_ONLINE,
-					IM_BUSY_AUTO_RESPONSE,
-					session_id);
-				gAgent.sendReliableMessage();
-			}
-
-			// now store incoming IM in chat history
-
-			buffer = message;
-	
-			LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
-
-			// add to IM panel, but do not bother the user
-			gIMMgr->addMessage(
-				session_id,
-				from_id,
-				name,
-				buffer,
-				LLStringUtil::null,
-				dialog,
-				parent_estate_id,
-				region_id,
-				position,
-				true);
-		}
-		else if (from_id.isNull())
-		{
-			LLSD args;
-			args["MESSAGE"] = message;
-			LLNotificationsUtil::add("SystemMessage", args);
-		}
-		else if (to_id.isNull())
-		{
-			// Message to everyone from GOD, look up the fullname since
-			// server always slams name to legacy names
-			LLAvatarNameCache::get(from_id, boost::bind(god_message_name_cb, _2, chat, message));
-		}
-		else
-		{
-			// standard message, not from system
-			std::string saved;
-			if(offline == IM_OFFLINE)
-			{
-				LLStringUtil::format_map_t args;
-				args["[LONG_TIMESTAMP]"] = formatted_time(timestamp);
-				saved = LLTrans::getString("Saved_message", args);
-			}
-			buffer = saved + message;
-
-			LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
-
-			bool mute_im = is_muted;
-			if(accept_im_from_only_friend&&!is_friend)
-			{
-				mute_im = true;
-			}
-			if (!mute_im || is_linden) 
-			{
-				gIMMgr->addMessage(
-					session_id,
-					from_id,
-					name,
-					buffer,
-					LLStringUtil::null,
-					dialog,
-					parent_estate_id,
-					region_id,
-					position,
-					true);
-			}
-			else
-			{
-				/*
-				EXT-5099
-				currently there is no way to store in history only...
-				using  LLNotificationsUtil::add will add message to Nearby Chat
-
-				// muted user, so don't start an IM session, just record line in chat
-				// history.  Pretend the chat is from a local agent,
-				// so it will go into the history but not be shown on screen.
-
-				LLSD args;
-				args["MESSAGE"] = buffer;
-				LLNotificationsUtil::add("SystemMessageTip", args);
-				*/
-			}
-		}
-		break;
-
-	case IM_TYPING_START:
-		{
-			LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
-			gIMMgr->processIMTypingStart(im_info);
-		}
-		break;
-
-	case IM_TYPING_STOP:
-		{
-			LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
-			gIMMgr->processIMTypingStop(im_info);
-		}
-		break;
-
-	case IM_MESSAGEBOX:
-		{
-			// This is a block, modeless dialog.
-			//*TODO: Translate
-			args["MESSAGE"] = message;
-			LLNotificationsUtil::add("SystemMessageTip", args);
-		}
-		break;
-	case IM_GROUP_NOTICE:
-	case IM_GROUP_NOTICE_REQUESTED:
-		{
-			LL_INFOS("Messaging") << "Received IM_GROUP_NOTICE message." << LL_ENDL;
-			// Read the binary bucket for more information.
-			struct notice_bucket_header_t
-			{
-				U8 has_inventory;
-				U8 asset_type;
-				LLUUID group_id;
-			};
-			struct notice_bucket_full_t
-			{
-				struct notice_bucket_header_t header;
-				U8 item_name[DB_INV_ITEM_NAME_BUF_SIZE];
-			}* notice_bin_bucket;
-
-			// Make sure the binary bucket is big enough to hold the header 
-			// and a null terminated item name.
-			if ( (binary_bucket_size < (S32)((sizeof(notice_bucket_header_t) + sizeof(U8))))
-				|| (binary_bucket[binary_bucket_size - 1] != '\0') )
-			{
-				LL_WARNS("Messaging") << "Malformed group notice binary bucket" << LL_ENDL;
-				break;
-			}
-
-			notice_bin_bucket = (struct notice_bucket_full_t*) &binary_bucket[0];
-			U8 has_inventory = notice_bin_bucket->header.has_inventory;
-			U8 asset_type = notice_bin_bucket->header.asset_type;
-			LLUUID group_id = notice_bin_bucket->header.group_id;
-			std::string item_name = ll_safe_string((const char*) notice_bin_bucket->item_name);
-
-			// If there is inventory, give the user the inventory offer.
-			LLOfferInfo* info = NULL;
-
-			if (has_inventory)
-			{
-				info = new LLOfferInfo();
-				
-				info->mIM = IM_GROUP_NOTICE;
-				info->mFromID = from_id;
-				info->mFromGroup = from_group;
-				info->mTransactionID = session_id;
-				info->mType = (LLAssetType::EType) asset_type;
-				info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
-				std::string from_name;
-
-				from_name += "A group member named ";
-				from_name += name;
-
-				info->mFromName = from_name;
-				info->mDesc = item_name;
-				info->mHost = msg->getSender();
-			}
-			
-			std::string str(message);
-
-			// Tokenize the string.
-			// TODO: Support escaped tokens ("||" -> "|")
-			typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
-			boost::char_separator<char> sep("|","",boost::keep_empty_tokens);
-			tokenizer tokens(str, sep);
-			tokenizer::iterator iter = tokens.begin();
-
-			std::string subj(*iter++);
-			std::string mes(*iter++);
-
-			// Send the notification down the new path.
-			// For requested notices, we don't want to send the popups.
-			if (dialog != IM_GROUP_NOTICE_REQUESTED)
-			{
-				payload["subject"] = subj;
-				payload["message"] = mes;
-				payload["sender_name"] = name;
-				payload["group_id"] = group_id;
-				payload["inventory_name"] = item_name;
-				payload["inventory_offer"] = info ? info->asLLSD() : LLSD();
-
-				LLSD args;
-				args["SUBJECT"] = subj;
-				args["MESSAGE"] = mes;
-				LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(timestamp));
-			}
-
-			// Also send down the old path for now.
-			if (IM_GROUP_NOTICE_REQUESTED == dialog)
-			{
-				
-				LLPanelGroup::showNotice(subj,mes,group_id,has_inventory,item_name,info);
-			}
-			else
-			{
-				delete info;
-			}
-		}
-		break;
-	case IM_GROUP_INVITATION:
-		{
-			//if (!is_linden && (is_busy || is_muted))
-			if ((is_busy || is_muted))
-			{
-				LLMessageSystem *msg = gMessageSystem;
-				busy_message(msg,from_id);
-			}
-			else
-			{
-				LL_INFOS("Messaging") << "Received IM_GROUP_INVITATION message." << LL_ENDL;
-				// Read the binary bucket for more information.
-				struct invite_bucket_t
-				{
-					S32 membership_fee;
-					LLUUID role_id;
-				}* invite_bucket;
-
-				// Make sure the binary bucket is the correct size.
-				if (binary_bucket_size != sizeof(invite_bucket_t))
-				{
-					LL_WARNS("Messaging") << "Malformed group invite binary bucket" << LL_ENDL;
-					break;
-				}
-
-				invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];
-				S32 membership_fee = ntohl(invite_bucket->membership_fee);
-
-				LLSD payload;
-				payload["transaction_id"] = session_id;
-				payload["group_id"] = from_id;
-				payload["name"] = name;
-				payload["message"] = message;
-				payload["fee"] = membership_fee;
-
-				LLSD args;
-				args["MESSAGE"] = message;
-				// we shouldn't pass callback functor since it is registered in LLFunctorRegistration
-				LLNotificationsUtil::add("JoinGroup", args, payload);
-			}
-		}
-		break;
-
-	case IM_INVENTORY_OFFERED:
-	case IM_TASK_INVENTORY_OFFERED:
-		// Someone has offered us some inventory.
-		{
-			LLOfferInfo* info = new LLOfferInfo;
-			if (IM_INVENTORY_OFFERED == dialog)
-			{
-				struct offer_agent_bucket_t
-				{
-					S8		asset_type;
-					LLUUID	object_id;
-				}* bucketp;
-
-				if (sizeof(offer_agent_bucket_t) != binary_bucket_size)
-				{
-					LL_WARNS("Messaging") << "Malformed inventory offer from agent" << LL_ENDL;
-					delete info;
-					break;
-				}
-				bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
-				info->mType = (LLAssetType::EType) bucketp->asset_type;
-				info->mObjectID = bucketp->object_id;
-			}
-			else
-			{
-				if (sizeof(S8) != binary_bucket_size)
-				{
-					LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
-					delete info;
-					break;
-				}
-				info->mType = (LLAssetType::EType) binary_bucket[0];
-				info->mObjectID = LLUUID::null;
-			}
-
-			info->mIM = dialog;
-			info->mFromID = from_id;
-			info->mFromGroup = from_group;
-			info->mTransactionID = session_id;
-			info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
-
-			if (dialog == IM_TASK_INVENTORY_OFFERED)
-			{
-				info->mFromObject = TRUE;
-			}
-			else
-			{
-				info->mFromObject = FALSE;
-			}
-			info->mFromName = name;
-			info->mDesc = message;
-			info->mHost = msg->getSender();
-			//if (((is_busy && !is_owned_by_me) || is_muted))
-			if (is_muted)
-			{
-				// Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
-				LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
-				fetch_item->startFetch();
-				delete fetch_item;
-
-				// Same as closing window
-				info->forceResponse(IOR_DECLINE);
-			}
-			else
-			{
-				inventory_offer_handler(info);
-			}
-		}
-		break;
-
-	case IM_INVENTORY_ACCEPTED:
-	{
-		args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
-		LLSD payload;
-		payload["from_id"] = from_id;
-		LLNotificationsUtil::add("InventoryAccepted", args, payload);
-		break;
-	}
-	case IM_INVENTORY_DECLINED:
-	{
-		args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
-		LLSD payload;
-		payload["from_id"] = from_id;
-		LLNotificationsUtil::add("InventoryDeclined", args, payload);
-		break;
-	}
-	// TODO: _DEPRECATED suffix as part of vote removal - DEV-24856
-	case IM_GROUP_VOTE:
-		{
-			LL_WARNS("Messaging") << "Received IM: IM_GROUP_VOTE_DEPRECATED" << LL_ENDL;
-		}
-		break;
-
-	case IM_GROUP_ELECTION_DEPRECATED:
-	{
-		LL_WARNS("Messaging") << "Received IM: IM_GROUP_ELECTION_DEPRECATED" << LL_ENDL;
-	}
-	break;
-	
-	case IM_SESSION_SEND:
-	{
-		if (!is_linden && is_busy)
-		{
-			return;
-		}
-
-		// Only show messages if we have a session open (which
-		// should happen after you get an "invitation"
-		if ( !gIMMgr->hasSession(session_id) )
-		{
-			return;
-		}
-
-		// standard message, not from system
-		std::string saved;
-		if(offline == IM_OFFLINE)
-		{
-			saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
-		}
-		buffer = saved + message;
-		BOOL is_this_agent = FALSE;
-		if(from_id == gAgentID)
-		{
-			is_this_agent = TRUE;
-		}
-		gIMMgr->addMessage(
-			session_id,
-			from_id,
-			name,
-			buffer,
-			ll_safe_string((char*)binary_bucket),
-			IM_SESSION_INVITE,
-			parent_estate_id,
-			region_id,
-			position,
-			true);
-	}
-	break;
-
-	case IM_FROM_TASK:
-		{
-			if (is_busy && !is_owned_by_me)
-			{
-				return;
-			}
-
-			// Build a link to open the object IM info window.
-			std::string location = ll_safe_string((char*)binary_bucket, binary_bucket_size-1);
-
-			if (session_id.notNull())
-			{
-				chat.mFromID = session_id;
-			}
-			else
-			{
-				// This message originated on a region without the updated code for task id and slurl information.
-				// We just need a unique ID for this object that isn't the owner ID.
-				// If it is the owner ID it will overwrite the style that contains the link to that owner's profile.
-				// This isn't ideal - it will make 1 style for all objects owned by the the same person/group.
-				// This works because the only thing we can really do in this case is show the owner name and link to their profile.
-				chat.mFromID = from_id ^ gAgent.getSessionID();
-			}
-
-			chat.mSourceType = CHAT_SOURCE_OBJECT;
-
-			if(SYSTEM_FROM == name)
-			{
-				// System's UUID is NULL (fixes EXT-4766)
-				chat.mFromID = LLUUID::null;
-				chat.mSourceType = CHAT_SOURCE_SYSTEM;
-			}
-
-			// IDEVO Some messages have embedded resident names
-			message = clean_name_from_task_im(message, from_group);
-
-			LLSD query_string;
-			query_string["owner"] = from_id;
-			query_string["slurl"] = location;
-			query_string["name"] = name;
-			if (from_group)
-			{
-				query_string["groupowned"] = "true";
-			}	
-
-			chat.mURL = LLSLURL("objectim", session_id, "").getSLURLString();
-			chat.mText = message;
-
-			// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
-			// IMs from obejcts don't open IM sessions.
-			LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
-			if(SYSTEM_FROM != name && nearby_chat)
-			{
-				chat.mOwnerID = from_id;
-				LLSD args;
-				args["slurl"] = location;
-				args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
-
-				// Look for IRC-style emotes here so object name formatting is correct
-				std::string prefix = message.substr(0, 4);
-				if (prefix == "/me " || prefix == "/me'")
-				{
-					chat.mChatStyle = CHAT_STYLE_IRC;
-				}
-
-				LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
-			}
-
-
-			//Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590)
-			if (SYSTEM_FROM != name) break;
-			
-			LLSD substitutions;
-			substitutions["NAME"] = name;
-			substitutions["MSG"] = message;
-
-			LLSD payload;
-			payload["object_id"] = session_id;
-			payload["owner_id"] = from_id;
-			payload["from_id"] = from_id;
-			payload["slurl"] = location;
-			payload["name"] = name;
-			std::string session_name;
-			if (from_group)
-			{
-				payload["group_owned"] = "true";
-			}
-
-			LLNotification::Params params("ServerObjectMessage");
-			params.substitutions = substitutions;
-			params.payload = payload;
-
-			LLPostponedNotification::add<LLPostponedServerObjectNotification>(params, from_id, from_group);
-		}
-		break;
-	case IM_FROM_TASK_AS_ALERT:
-		if (is_busy && !is_owned_by_me)
-		{
-			return;
-		}
-		{
-			// Construct a viewer alert for this message.
-			args["NAME"] = name;
-			args["MESSAGE"] = message;
-			LLNotificationsUtil::add("ObjectMessage", args);
-		}
-		break;
-	case IM_BUSY_AUTO_RESPONSE:
-		if (is_muted)
-		{
-			LL_DEBUGS("Messaging") << "Ignoring busy response from " << from_id << LL_ENDL;
-			return;
-		}
-		else
-		{
-			// TODO: after LLTrans hits release, get "busy response" into translatable file
-			buffer = llformat("%s (%s): %s", name.c_str(), "busy response", message.c_str());
-			gIMMgr->addMessage(session_id, from_id, name, buffer);
-		}
-		break;
-		
-	case IM_LURE_USER:
-		{
-			if (is_muted)
-			{ 
-				return;
-			}
-			else if (is_busy) 
-			{
-				busy_message(msg,from_id);
-			}
-			else
-			{
-				LLVector3 pos, look_at;
-				U64 region_handle;
-				U8 region_access = SIM_ACCESS_MIN;
-				std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
-				std::string region_access_str = LLStringUtil::null;
-				std::string region_access_icn = LLStringUtil::null;
-
-				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("agent", from_id, "about").getSLURLString();
-				args["MESSAGE"] = message;
-				args["MATURITY_STR"] = region_access_str;
-				args["MATURITY_ICON"] = region_access_icn;
-				LLSD payload;
-				payload["from_id"] = from_id;
-				payload["lure_id"] = session_id;
-				payload["godlike"] = FALSE;
-
-			    LLNotification::Params params("TeleportOffered");
-			    params.substitutions = args;
-			    params.payload = payload;
-			    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
-			}
-		}
-		break;
-
-	case IM_GODLIKE_LURE_USER:
-		{
-			LLSD payload;
-			payload["from_id"] = from_id;
-			payload["lure_id"] = session_id;
-			payload["godlike"] = TRUE;
-			// do not show a message box, because you're about to be
-			// teleported.
-			LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
-		}
-		break;
-
-	case IM_GOTO_URL:
-		{
-			LLSD args;
-			// n.b. this is for URLs sent by the system, not for
-			// URLs sent by scripts (i.e. llLoadURL)
-			if (binary_bucket_size <= 0)
-			{
-				LL_WARNS("Messaging") << "bad binary_bucket_size: "
-					<< binary_bucket_size
-					<< " - aborting function." << LL_ENDL;
-				return;
-			}
-
-			std::string url;
-			
-			url.assign((char*)binary_bucket, binary_bucket_size-1);
-			args["MESSAGE"] = message;
-			args["URL"] = url;
-			LLSD payload;
-			payload["url"] = url;
-			LLNotificationsUtil::add("GotoURL", args, payload );
-		}
-		break;
-
-	case IM_FRIENDSHIP_OFFERED:
-		{
-			LLSD payload;
-			payload["from_id"] = from_id;
-			payload["session_id"] = session_id;;
-			payload["online"] = (offline == IM_ONLINE);
-			payload["sender"] = msg->getSender().getIPandPort();
-
-			if (is_busy)
-			{
-				busy_message(msg, from_id);
-				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
-			}
-			else if (is_muted)
-			{
-				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
-			}
-			else
-			{
-				args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
-				if(message.empty())
-				{
-					//support for frienship offers from clients before July 2008
-				        LLNotificationsUtil::add("OfferFriendshipNoMessage", args, payload);
-				}
-				else
-				{
-					args["[MESSAGE]"] = message;
-				    LLNotification::Params params("OfferFriendship");
-				    params.substitutions = args;
-				    params.payload = payload;
-				    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
-				}
-			}
-		}
-		break;
-
-	case IM_FRIENDSHIP_ACCEPTED:
-		{
-			// In the case of an offline IM, the formFriendship() may be extraneous
-			// as the database should already include the relationship.  But it
-			// doesn't hurt for dupes.
-			LLAvatarTracker::formFriendship(from_id);
-			
-			std::vector<std::string> strings;
-			strings.push_back(from_id.asString());
-			send_generic_message("requestonlinenotification", strings);
-			
-			args["NAME"] = name;
-			LLSD payload;
-			payload["from_id"] = from_id;
-			LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback,
-														 _1,
-														 _2,
-														 "FriendshipAccepted",
-														 args,
-														 payload));
-		}
-		break;
-
-	case IM_FRIENDSHIP_DECLINED_DEPRECATED:
-	default:
-		LL_WARNS("Messaging") << "Instant message calling for unknown dialog "
-				<< (S32)dialog << LL_ENDL;
-		break;
-	}
-
-	LLWindow* viewer_window = gViewerWindow->getWindow();
-	if (viewer_window && viewer_window->getMinimized())
-	{
-		viewer_window->flashIcon(5.f);
-	}
-}
-
-void busy_message (LLMessageSystem* msg, LLUUID from_id) 
-{
-	if (gAgent.getBusy())
-	{
-		std::string my_name;
-		LLAgentUI::buildFullname(my_name);
-		std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
-		pack_instant_message(
-			gMessageSystem,
-			gAgent.getID(),
-			FALSE,
-			gAgent.getSessionID(),
-			from_id,
-			my_name,
-			response,
-			IM_ONLINE,
-			IM_BUSY_AUTO_RESPONSE);
-		gAgent.sendReliableMessage();
-	}
-}
-
-bool callingcard_offer_callback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	LLUUID fid;
-	LLUUID from_id;
-	LLMessageSystem* msg = gMessageSystem;
-	switch(option)
-	{
-	case 0:
-		// accept
-		msg->newMessageFast(_PREHASH_AcceptCallingCard);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->nextBlockFast(_PREHASH_TransactionBlock);
-		msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
-		fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
-		msg->nextBlockFast(_PREHASH_FolderData);
-		msg->addUUIDFast(_PREHASH_FolderID, fid);
-		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
-		break;
-	case 1:
-		// decline		
-		msg->newMessageFast(_PREHASH_DeclineCallingCard);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->nextBlockFast(_PREHASH_TransactionBlock);
-		msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
-		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
-		busy_message(msg, notification["payload"]["source_id"].asUUID());
-		break;
-	default:
-		// close button probably, possibly timed out
-		break;
-	}
-
-	return false;
-}
-static LLNotificationFunctorRegistration callingcard_offer_cb_reg("OfferCallingCard", callingcard_offer_callback);
-
-void process_offer_callingcard(LLMessageSystem* msg, void**)
-{
-	// someone has offered to form a friendship
-	LL_DEBUGS("Messaging") << "callingcard offer" << LL_ENDL;
-
-	LLUUID source_id;
-	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, source_id);
-	LLUUID tid;
-	msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_TransactionID, tid);
-
-	LLSD payload;
-	payload["transaction_id"] = tid;
-	payload["source_id"] = source_id;
-	payload["sender"] = msg->getSender().getIPandPort();
-
-	LLViewerObject* source = gObjectList.findObject(source_id);
-	LLSD args;
-	std::string source_name;
-	if(source && source->isAvatar())
-	{
-		LLNameValue* nvfirst = source->getNVPair("FirstName");
-		LLNameValue* nvlast  = source->getNVPair("LastName");
-		if (nvfirst && nvlast)
-		{
-			source_name = LLCacheName::buildFullName(
-				nvfirst->getString(), nvlast->getString());
-		}
-	}
-
-	if(!source_name.empty())
-	{
-		if (gAgent.getBusy() 
-			|| LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat))
-		{
-			// automatically decline offer
-			LLNotifications::instance().forceResponse(LLNotification::Params("OfferCallingCard").payload(payload), 1);
-		}
-		else
-		{
-			args["NAME"] = source_name;
-			LLNotificationsUtil::add("OfferCallingCard", args, payload);
-		}
-	}
-	else
-	{
-		LL_WARNS("Messaging") << "Calling card offer from an unknown source." << LL_ENDL;
-	}
-}
-
-void process_accept_callingcard(LLMessageSystem* msg, void**)
-{
-	LLNotificationsUtil::add("CallingCardAccepted");
-}
-
-void process_decline_callingcard(LLMessageSystem* msg, void**)
-{
-	LLNotificationsUtil::add("CallingCardDeclined");
-}
-
-class ChatTranslationReceiver : public LLTranslate::TranslationReceiver
-{
-public :
-	ChatTranslationReceiver(const std::string &from_lang, const std::string &to_lang, const std::string &mesg,
-							const LLChat &chat, const LLSD &toast_args)
-		: LLTranslate::TranslationReceiver(from_lang, to_lang),
-		m_chat(chat),
-		m_toastArgs(toast_args),
-		m_origMesg(mesg)
-	{
-	}
-
-	static boost::intrusive_ptr<ChatTranslationReceiver> build(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, const LLChat &chat, const LLSD &toast_args)
-	{
-		return boost::intrusive_ptr<ChatTranslationReceiver>(new ChatTranslationReceiver(from_lang, to_lang, mesg, chat, toast_args));
-	}
-
-protected:
-	void handleResponse(const std::string &translation, const std::string &detected_language)
-	{
-		// filter out non-interesting responeses
-		if ( !translation.empty()
-			&& (m_toLang != detected_language)
-			&& (LLStringUtil::compareInsensitive(translation, m_origMesg) != 0) )
-		{
-			m_chat.mText += " (" + translation + ")";
-		}
-
-		LLNotificationsUI::LLNotificationManager::instance().onChat(m_chat, m_toastArgs);
-	}
-
-	void handleFailure()
-	{
-		LLTranslate::TranslationReceiver::handleFailure();
-		m_chat.mText += " (?)";
-
-		LLNotificationsUI::LLNotificationManager::instance().onChat(m_chat, m_toastArgs);
-	}
-
-private:
-	LLChat m_chat;
-	std::string m_origMesg;
-	LLSD m_toastArgs;		
-};
-void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
-{
-	LLChat	chat;
-	std::string		mesg;
-	std::string		from_name;
-	U8			source_temp;
-	U8			type_temp;
-	U8			audible_temp;
-	LLColor4	color(1.0f, 1.0f, 1.0f, 1.0f);
-	LLUUID		from_id;
-	LLUUID		owner_id;
-	BOOL		is_owned_by_me = FALSE;
-	LLViewerObject*	chatter;
-
-	msg->getString("ChatData", "FromName", from_name);
-	
-	msg->getUUID("ChatData", "SourceID", from_id);
-	chat.mFromID = from_id;
-	
-	// Object owner for objects
-	msg->getUUID("ChatData", "OwnerID", owner_id);
-
-	msg->getU8Fast(_PREHASH_ChatData, _PREHASH_SourceType, source_temp);
-	chat.mSourceType = (EChatSourceType)source_temp;
-
-	msg->getU8("ChatData", "ChatType", type_temp);
-	chat.mChatType = (EChatType)type_temp;
-
-	msg->getU8Fast(_PREHASH_ChatData, _PREHASH_Audible, audible_temp);
-	chat.mAudible = (EChatAudible)audible_temp;
-	
-	chat.mTime = LLFrameTimer::getElapsedSeconds();
-	
-	// IDEVO Correct for new-style "Resident" names
-	if (chat.mSourceType == CHAT_SOURCE_AGENT)
-	{
-		// I don't know if it's OK to change this here, if 
-		// anything downstream does lookups by name, for instance
-		
-		LLAvatarName av_name;
-		if (LLAvatarNameCache::get(from_id, &av_name))
-		{
-			chat.mFromName = av_name.mDisplayName;
-		}
-		else
-		{
-			chat.mFromName = LLCacheName::cleanFullName(from_name);
-		}
-	}
-	else
-	{
-		chat.mFromName = from_name;
-	}
-
-	BOOL is_busy = gAgent.getBusy();
-
-	BOOL is_muted = FALSE;
-	BOOL is_linden = FALSE;
-	is_muted = LLMuteList::getInstance()->isMuted(
-		from_id,
-		from_name,
-		LLMute::flagTextChat) 
-		|| LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagTextChat);
-	is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
-		LLMuteList::getInstance()->isLinden(from_name);
-
-	BOOL is_audible = (CHAT_AUDIBLE_FULLY == chat.mAudible);
-	chatter = gObjectList.findObject(from_id);
-	if (chatter)
-	{
-		chat.mPosAgent = chatter->getPositionAgent();
-
-		// Make swirly things only for talking objects. (not script debug messages, though)
-		if (chat.mSourceType == CHAT_SOURCE_OBJECT 
-			&& chat.mChatType != CHAT_TYPE_DEBUG_MSG
-			&& gSavedSettings.getBOOL("EffectScriptChatParticles") )
-		{
-			LLPointer<LLViewerPartSourceChat> psc = new LLViewerPartSourceChat(chatter->getPositionAgent());
-			psc->setSourceObject(chatter);
-			psc->setColor(color);
-			//We set the particles to be owned by the object's owner, 
-			//just in case they should be muted by the mute list
-			psc->setOwnerUUID(owner_id);
-			LLViewerPartSim::getInstance()->addPartSource(psc);
-		}
-
-		// record last audible utterance
-		if (is_audible
-			&& (is_linden || (!is_muted && !is_busy)))
-		{
-			if (chat.mChatType != CHAT_TYPE_START 
-				&& chat.mChatType != CHAT_TYPE_STOP)
-			{
-				gAgent.heardChat(chat.mFromID);
-			}
-		}
-
-		is_owned_by_me = chatter->permYouOwner();
-	}
-
-	if (is_audible)
-	{
-		BOOL visible_in_chat_bubble = FALSE;
-		std::string verb;
-
-		color.setVec(1.f,1.f,1.f,1.f);
-		msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg);
-
-		BOOL ircstyle = FALSE;
-
-		// Look for IRC-style emotes here so chatbubbles work
-		std::string prefix = mesg.substr(0, 4);
-		if (prefix == "/me " || prefix == "/me'")
-		{
-			ircstyle = TRUE;
-		}
-		chat.mText = mesg;
-
-		// Look for the start of typing so we can put "..." in the bubbles.
-		if (CHAT_TYPE_START == chat.mChatType)
-		{
-			LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, TRUE);
-
-			// Might not have the avatar constructed yet, eg on login.
-			if (chatter && chatter->isAvatar())
-			{
-				((LLVOAvatar*)chatter)->startTyping();
-			}
-			return;
-		}
-		else if (CHAT_TYPE_STOP == chat.mChatType)
-		{
-			LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE);
-
-			// Might not have the avatar constructed yet, eg on login.
-			if (chatter && chatter->isAvatar())
-			{
-				((LLVOAvatar*)chatter)->stopTyping();
-			}
-			return;
-		}
-
-		// Look for IRC-style emotes
-		if (ircstyle)
-		{
-			// set CHAT_STYLE_IRC to avoid adding Avatar Name as author of message. See EXT-656
-			chat.mChatStyle = CHAT_STYLE_IRC;
-
-			// Do nothing, ircstyle is fixed above for chat bubbles
-		}
-		else
-		{
-			switch(chat.mChatType)
-			{
-			case CHAT_TYPE_WHISPER:
-				verb = LLTrans::getString("whisper") + " ";
-				break;
-			case CHAT_TYPE_DEBUG_MSG:
-			case CHAT_TYPE_OWNER:
-			case CHAT_TYPE_NORMAL:
-				verb = "";
-				break;
-			case CHAT_TYPE_SHOUT:
-				verb = LLTrans::getString("shout") + " ";
-				break;
-			case CHAT_TYPE_START:
-			case CHAT_TYPE_STOP:
-				LL_WARNS("Messaging") << "Got chat type start/stop in main chat processing." << LL_ENDL;
-				break;
-			default:
-				LL_WARNS("Messaging") << "Unknown type " << chat.mChatType << " in chat!" << LL_ENDL;
-				verb = "";
-				break;
-			}
-
-
-			chat.mText = "";
-			chat.mText += verb;
-			chat.mText += mesg;
-		}
-		
-		// We have a real utterance now, so can stop showing "..." and proceed.
-		if (chatter && chatter->isAvatar())
-		{
-			LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE);
-			((LLVOAvatar*)chatter)->stopTyping();
-			
-			if (!is_muted && !is_busy)
-			{
-				visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");
-				std::string formated_msg = "";
-				LLViewerChat::formatChatMsg(chat, formated_msg);
-				LLChat chat_bubble = chat;
-				chat_bubble.mText = formated_msg;
-				((LLVOAvatar*)chatter)->addChat(chat_bubble);
-			}
-		}
-		
-		if (chatter)
-		{
-			chat.mPosAgent = chatter->getPositionAgent();
-		}
-
-		// truth table:
-		// LINDEN	BUSY	MUTED	OWNED_BY_YOU	TASK		DISPLAY		STORE IN HISTORY
-		// F		F		F		F				*			Yes			Yes
-		// F		F		F		T				*			Yes			Yes
-		// F		F		T		F				*			No			No
-		// F		F		T		T				*			No			No
-		// F		T		F		F				*			No			Yes
-		// F		T		F		T				*			Yes			Yes
-		// F		T		T		F				*			No			No
-		// F		T		T		T				*			No			No
-		// T		*		*		*				F			Yes			Yes
-
-		chat.mMuted = is_muted && !is_linden;
-
-		// pass owner_id to chat so that we can display the remote
-		// object inspect for an object that is chatting with you
-		LLSD args;
-		args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
-		chat.mOwnerID = owner_id;
-
-		if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM)
-		{
-			if (chat.mChatStyle == CHAT_STYLE_IRC)
-			{
-				mesg = mesg.substr(4, std::string::npos);
-			}
-			const std::string from_lang = ""; // leave empty to trigger autodetect
-			const std::string to_lang = LLTranslate::getTranslateLanguage();
-
-			LLHTTPClient::ResponderPtr result = ChatTranslationReceiver::build(from_lang, to_lang, mesg, chat, args);
-			LLTranslate::translateMessage(result, from_lang, to_lang, mesg);
-		}
-		else
-		{
-			LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
-		}
-	}
-}
-
-
-// Simulator we're on is informing the viewer that the agent
-// is starting to teleport (perhaps to another sim, perhaps to the 
-// same sim). If we initiated the teleport process by sending some kind 
-// of TeleportRequest, then this info is redundant, but if the sim 
-// initiated the teleport (via a script call, being killed, etc.) 
-// then this info is news to us.
-void process_teleport_start(LLMessageSystem *msg, void**)
-{
-	// on teleport, don't tell them about destination guide anymore
-	LLFirstUse::notUsingDestinationGuide(false);
-	U32 teleport_flags = 0x0;
-	msg->getU32("Info", "TeleportFlags", teleport_flags);
-
-	LL_DEBUGS("Messaging") << "Got TeleportStart with TeleportFlags=" << teleport_flags << ". gTeleportDisplay: " << gTeleportDisplay << ", gAgent.mTeleportState: " << gAgent.getTeleportState() << LL_ENDL;
-
-	if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL)
-	{
-		gViewerWindow->setProgressCancelButtonVisible(FALSE);
-	}
-	else
-	{
-		gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Cancel"));
-	}
-
-	// Freeze the UI and show progress bar
-	// Note: could add data here to differentiate between normal teleport and death.
-
-	if( gAgent.getTeleportState() == LLAgent::TELEPORT_NONE )
-	{
-		gTeleportDisplay = TRUE;
-		gAgent.setTeleportState( LLAgent::TELEPORT_START );
-		make_ui_sound("UISndTeleportOut");
-		
-		LL_INFOS("Messaging") << "Teleport initiated by remote TeleportStart message with TeleportFlags: " <<  teleport_flags << LL_ENDL;
-		// Don't call LLFirstUse::useTeleport here because this could be
-		// due to being killed, which would send you home, not to a Telehub
-	}
-}
-
-void process_teleport_progress(LLMessageSystem* msg, void**)
-{
-	LLUUID agent_id;
-	msg->getUUID("AgentData", "AgentID", agent_id);
-	if((gAgent.getID() != agent_id)
-	   || (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE))
-	{
-		LL_WARNS("Messaging") << "Unexpected teleport progress message." << LL_ENDL;
-		return;
-	}
-	U32 teleport_flags = 0x0;
-	msg->getU32("Info", "TeleportFlags", teleport_flags);
-	if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL)
-	{
-		gViewerWindow->setProgressCancelButtonVisible(FALSE);
-	}
-	else
-	{
-		gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Cancel"));
-	}
-	std::string buffer;
-	msg->getString("Info", "Message", buffer);
-	LL_DEBUGS("Messaging") << "teleport progress: " << buffer << LL_ENDL;
-
-	//Sorta hacky...default to using simulator raw messages
-	//if we don't find the coresponding mapping in our progress mappings
-	std::string message = buffer;
-
-	if (LLAgent::sTeleportProgressMessages.find(buffer) != 
-		LLAgent::sTeleportProgressMessages.end() )
-	{
-		message = LLAgent::sTeleportProgressMessages[buffer];
-	}
-
-	gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages[message]);
-}
-
-class LLFetchInWelcomeArea : public LLInventoryFetchDescendentsObserver
-{
-public:
-	LLFetchInWelcomeArea(const uuid_vec_t &ids) :
-		LLInventoryFetchDescendentsObserver(ids)
-	{}
-	virtual void done()
-	{
-		LLIsType is_landmark(LLAssetType::AT_LANDMARK);
-		LLIsType is_card(LLAssetType::AT_CALLINGCARD);
-
-		LLInventoryModel::cat_array_t	card_cats;
-		LLInventoryModel::item_array_t	card_items;
-		LLInventoryModel::cat_array_t	land_cats;
-		LLInventoryModel::item_array_t	land_items;
-
-		uuid_vec_t::iterator it = mComplete.begin();
-		uuid_vec_t::iterator end = mComplete.end();
-		for(; it != end; ++it)
-		{
-			gInventory.collectDescendentsIf(
-				(*it),
-				land_cats,
-				land_items,
-				LLInventoryModel::EXCLUDE_TRASH,
-				is_landmark);
-			gInventory.collectDescendentsIf(
-				(*it),
-				card_cats,
-				card_items,
-				LLInventoryModel::EXCLUDE_TRASH,
-				is_card);
-		}
-		LLSD args;
-		if ( land_items.count() > 0 )
-		{	// Show notification that they can now teleport to landmarks.  Use a random landmark from the inventory
-			S32 random_land = ll_rand( land_items.count() - 1 );
-			args["NAME"] = land_items[random_land]->getName();
-			LLNotificationsUtil::add("TeleportToLandmark",args);
-		}
-		if ( card_items.count() > 0 )
-		{	// Show notification that they can now contact people.  Use a random calling card from the inventory
-			S32 random_card = ll_rand( card_items.count() - 1 );
-			args["NAME"] = card_items[random_card]->getName();
-			LLNotificationsUtil::add("TeleportToPerson",args);
-		}
-
-		gInventory.removeObserver(this);
-		delete this;
-	}
-};
-
-
-
-class LLPostTeleportNotifiers : public LLEventTimer 
-{
-public:
-	LLPostTeleportNotifiers();
-	virtual ~LLPostTeleportNotifiers();
-
-	//function to be called at the supplied frequency
-	virtual BOOL tick();
-};
-
-LLPostTeleportNotifiers::LLPostTeleportNotifiers() : LLEventTimer( 2.0 )
-{
-};
-
-LLPostTeleportNotifiers::~LLPostTeleportNotifiers()
-{
-}
-
-BOOL LLPostTeleportNotifiers::tick()
-{
-	BOOL all_done = FALSE;
-	if ( gAgent.getTeleportState() == LLAgent::TELEPORT_NONE )
-	{
-		// get callingcards and landmarks available to the user arriving.
-		uuid_vec_t folders;
-		const LLUUID callingcard_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
-		if(callingcard_id.notNull()) 
-			folders.push_back(callingcard_id);
-		const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
-		if(folder_id.notNull()) 
-			folders.push_back(folder_id);
-		if(!folders.empty())
-		{
-			LLFetchInWelcomeArea* fetcher = new LLFetchInWelcomeArea(folders);
-			fetcher->startFetch();
-			if(fetcher->isFinished())
-			{
-				fetcher->done();
-			}
-			else
-			{
-				gInventory.addObserver(fetcher);
-			}
-		}
-		all_done = TRUE;
-	}
-
-	return all_done;
-}
-
-
-
-// Teleport notification from the simulator
-// We're going to pretend to be a new agent
-void process_teleport_finish(LLMessageSystem* msg, void**)
-{
-	LL_DEBUGS("Messaging") << "Got teleport location message" << LL_ENDL;
-	LLUUID agent_id;
-	msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
-	if (agent_id != gAgent.getID())
-	{
-		LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
-		return;
-	}
-	
-	// Teleport is finished; it can't be cancelled now.
-	gViewerWindow->setProgressCancelButtonVisible(FALSE);
-
-	// Do teleport effect for where you're leaving
-	// VEFFECT: TeleportStart
-	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
-	effectp->setPositionGlobal(gAgent.getPositionGlobal());
-	effectp->setColor(LLColor4U(gAgent.getEffectColor()));
-	LLHUDManager::getInstance()->sendEffects();
-
-	U32 location_id;
-	U32 sim_ip;
-	U16 sim_port;
-	LLVector3 pos, look_at;
-	U64 region_handle;
-	msg->getU32Fast(_PREHASH_Info, _PREHASH_LocationID, location_id);
-	msg->getIPAddrFast(_PREHASH_Info, _PREHASH_SimIP, sim_ip);
-	msg->getIPPortFast(_PREHASH_Info, _PREHASH_SimPort, sim_port);
-	//msg->getVector3Fast(_PREHASH_Info, _PREHASH_Position, pos);
-	//msg->getVector3Fast(_PREHASH_Info, _PREHASH_LookAt, look_at);
-	msg->getU64Fast(_PREHASH_Info, _PREHASH_RegionHandle, region_handle);
-	U32 teleport_flags;
-	msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
-	
-	
-	std::string seedCap;
-	msg->getStringFast(_PREHASH_Info, _PREHASH_SeedCapability, seedCap);
-
-	// update home location if we are teleporting out of prelude - specific to teleporting to welcome area 
-	if((teleport_flags & TELEPORT_FLAGS_SET_HOME_TO_TARGET)
-	   && (!gAgent.isGodlike()))
-	{
-		gAgent.setHomePosRegion(region_handle, pos);
-
-		// Create a timer that will send notices when teleporting is all finished.  Since this is 
-		// based on the LLEventTimer class, it will be managed by that class and not orphaned or leaked.
-		new LLPostTeleportNotifiers();
-	}
-
-	LLHost sim_host(sim_ip, sim_port);
-
-	// Viewer trusts the simulator.
-	gMessageSystem->enableCircuit(sim_host, TRUE);
-	LLViewerRegion* regionp =  LLWorld::getInstance()->addRegion(region_handle, sim_host);
-
-/*
-	// send camera update to new region
-	gAgentCamera.updateCamera();
-
-	// likewise make sure the camera is behind the avatar
-	gAgentCamera.resetView(TRUE);
-	LLVector3 shift_vector = regionp->getPosRegionFromGlobal(gAgent.getRegion()->getOriginGlobal());
-	gAgent.setRegion(regionp);
-	gObjectList.shiftObjects(shift_vector);
-
-	if (isAgentAvatarValid())
-	{
-		gAgentAvatarp->clearChatText();
-		gAgentCamera.slamLookAt(look_at);
-	}
-	gAgent.setPositionAgent(pos);
-	gAssetStorage->setUpstream(sim);
-	gCacheName->setUpstream(sim);
-*/
-
-	// now, use the circuit info to tell simulator about us!
-	LL_INFOS("Messaging") << "process_teleport_finish() Enabling "
-			<< sim_host << " with code " << msg->mOurCircuitCode << LL_ENDL;
-	msg->newMessageFast(_PREHASH_UseCircuitCode);
-	msg->nextBlockFast(_PREHASH_CircuitCode);
-	msg->addU32Fast(_PREHASH_Code, msg->getOurCircuitCode());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
-	msg->sendReliable(sim_host);
-
-	send_complete_agent_movement(sim_host);
-	gAgent.setTeleportState( LLAgent::TELEPORT_MOVING );
-	gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["contacting"]);
-
-	regionp->setSeedCapability(seedCap);
-
-	// Don't send camera updates to the new region until we're
-	// actually there...
-
-
-	// Now do teleport effect for where you're going.
-	// VEFFECT: TeleportEnd
-	effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
-	effectp->setPositionGlobal(gAgent.getPositionGlobal());
-
-	effectp->setColor(LLColor4U(gAgent.getEffectColor()));
-	LLHUDManager::getInstance()->sendEffects();
-
-//	gTeleportDisplay = TRUE;
-//	gTeleportDisplayTimer.reset();
-//	gViewerWindow->setShowProgress(TRUE);
-}
-
-// stuff we have to do every time we get an AvatarInitComplete from a sim
-/*
-void process_avatar_init_complete(LLMessageSystem* msg, void**)
-{
-	LLVector3 agent_pos;
-	msg->getVector3Fast(_PREHASH_AvatarData, _PREHASH_Position, agent_pos);
-	agent_movement_complete(msg->getSender(), agent_pos);
-}
-*/
-
-void process_agent_movement_complete(LLMessageSystem* msg, void**)
-{
-	gAgentMovementCompleted = true;
-
-	LLUUID agent_id;
-	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
-	LLUUID session_id;
-	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
-	if((gAgent.getID() != agent_id) || (gAgent.getSessionID() != session_id))
-	{
-		LL_WARNS("Messaging") << "Incorrect id in process_agent_movement_complete()"
-				<< LL_ENDL;
-		return;
-	}
-
-	LL_DEBUGS("Messaging") << "process_agent_movement_complete()" << LL_ENDL;
-
-	// *TODO: check timestamp to make sure the movement compleation
-	// makes sense.
-	LLVector3 agent_pos;
-	msg->getVector3Fast(_PREHASH_Data, _PREHASH_Position, agent_pos);
-	LLVector3 look_at;
-	msg->getVector3Fast(_PREHASH_Data, _PREHASH_LookAt, look_at);
-	U64 region_handle;
-	msg->getU64Fast(_PREHASH_Data, _PREHASH_RegionHandle, region_handle);
-	
-	std::string version_channel;
-	msg->getString("SimData", "ChannelVersion", version_channel);
-
-	if (!isAgentAvatarValid())
-	{
-		// Could happen if you were immediately god-teleported away on login,
-		// maybe other cases.  Continue, but warn.
-		LL_WARNS("Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL;
-	}
-
-	F32 x, y;
-	from_region_handle(region_handle, &x, &y);
-	LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
-	if (!regionp)
-	{
-		if (gAgent.getRegion())
-		{
-			LL_WARNS("Messaging") << "current region " << gAgent.getRegion()->getOriginGlobal() << LL_ENDL;
-		}
-
-		LL_WARNS("Messaging") << "Agent being sent to invalid home region: " 
-			<< x << ":" << y 
-			<< " current pos " << gAgent.getPositionGlobal()
-			<< LL_ENDL;
-		LLAppViewer::instance()->forceDisconnect(LLTrans::getString("SentToInvalidRegion"));
-		return;
-
-	}
-
-	LL_INFOS("Messaging") << "Changing home region to " << x << ":" << y << LL_ENDL;
-
-	// set our upstream host the new simulator and shuffle things as
-	// appropriate.
-	LLVector3 shift_vector = regionp->getPosRegionFromGlobal(
-		gAgent.getRegion()->getOriginGlobal());
-	gAgent.setRegion(regionp);
-	gObjectList.shiftObjects(shift_vector);
-	gAssetStorage->setUpstream(msg->getSender());
-	gCacheName->setUpstream(msg->getSender());
-	gViewerThrottle.sendToSim();
-	gViewerWindow->sendShapeToSim();
-
-	bool is_teleport = gAgent.getTeleportState() == LLAgent::TELEPORT_MOVING;
-
-	if( is_teleport )
-	{
-		if (gAgent.getTeleportKeepsLookAt())
-		{
-			// *NOTE: the LookAt data we get from the sim here doesn't
-			// seem to be useful, so get it from the camera instead
-			look_at = LLViewerCamera::getInstance()->getAtAxis();
-		}
-		// Force the camera back onto the agent, don't animate.
-		gAgentCamera.setFocusOnAvatar(TRUE, FALSE);
-		gAgentCamera.slamLookAt(look_at);
-		gAgentCamera.updateCamera();
-
-		gAgent.setTeleportState( LLAgent::TELEPORT_START_ARRIVAL );
-
-		// set the appearance on teleport since the new sim does not
-		// know what you look like.
-		gAgent.sendAgentSetAppearance();
-
-		if (isAgentAvatarValid())
-		{
-			// Chat the "back" SLURL. (DEV-4907)
-
-			LLSLURL slurl;
-			gAgent.getTeleportSourceSLURL(slurl);
-			LLSD substitution = LLSD().with("[T_SLURL]", slurl.getSLURLString());
-			std::string completed_from = LLAgent::sTeleportProgressMessages["completed_from"];
-			LLStringUtil::format(completed_from, substitution);
-
-			LLSD args;
-			args["MESSAGE"] = completed_from;
-			LLNotificationsUtil::add("SystemMessageTip", args);
-
-			// Set the new position
-			gAgentAvatarp->setPositionAgent(agent_pos);
-			gAgentAvatarp->clearChat();
-			gAgentAvatarp->slamPosition();
-		}
-	}
-	else
-	{
-		// This is initial log-in or a region crossing
-		gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
-
-		if(LLStartUp::getStartupState() < STATE_STARTED)
-		{	// This is initial log-in, not a region crossing:
-			// Set the camera looking ahead of the AV so send_agent_update() below 
-			// will report the correct location to the server.
-			LLVector3 look_at_point = look_at;
-			look_at_point = agent_pos + look_at_point.rotVec(gAgent.getQuat());
-
-			static LLVector3 up_direction(0.0f, 0.0f, 1.0f);
-			LLViewerCamera::getInstance()->lookAt(agent_pos, look_at_point, up_direction);
-		}
-	}
-
-	if ( LLTracker::isTracking(NULL) )
-	{
-		// Check distance to beacon, if < 5m, remove beacon
-		LLVector3d beacon_pos = LLTracker::getTrackedPositionGlobal();
-		LLVector3 beacon_dir(agent_pos.mV[VX] - (F32)fmod(beacon_pos.mdV[VX], 256.0), agent_pos.mV[VY] - (F32)fmod(beacon_pos.mdV[VY], 256.0), 0);
-		if (beacon_dir.magVecSquared() < 25.f)
-		{
-			LLTracker::stopTracking(NULL);
-		}
-		else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() )
-		{
-			//look at the beacon
-			LLVector3 global_agent_pos = agent_pos;
-			global_agent_pos[0] += x;
-			global_agent_pos[1] += y;
-			look_at = (LLVector3)beacon_pos - global_agent_pos;
-			look_at.normVec();
-			gAgentCamera.slamLookAt(look_at);
-		}
-	}
-
-	// TODO: Put back a check for flying status! DK 12/19/05
-	// Sim tells us whether the new position is off the ground
-	/*
-	if (teleport_flags & TELEPORT_FLAGS_IS_FLYING)
-	{
-		gAgent.setFlying(TRUE);
-	}
-	else
-	{
-		gAgent.setFlying(FALSE);
-	}
-	*/
-
-	send_agent_update(TRUE, TRUE);
-
-	if (gAgent.getRegion()->getBlockFly())
-	{
-		gAgent.setFlying(gAgent.canFly());
-	}
-
-	// force simulator to recognize busy state
-	if (gAgent.getBusy())
-	{
-		gAgent.setBusy();
-	}
-	else
-	{
-		gAgent.clearBusy();
-	}
-
-	if (isAgentAvatarValid())
-	{
-		gAgentAvatarp->mFootPlane.clearVec();
-	}
-	
-	// send walk-vs-run status
-	gAgent.sendWalkRun(gAgent.getRunning() || gAgent.getAlwaysRun());
-
-	// If the server version has changed, display an info box and offer
-	// to display the release notes, unless this is the initial log in.
-	if (gLastVersionChannel == version_channel)
-	{
-		return;
-	}
-
-	gLastVersionChannel = version_channel;
-}
-
-void process_crossed_region(LLMessageSystem* msg, void**)
-{
-	LLUUID agent_id;
-	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
-	LLUUID session_id;
-	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
-	if((gAgent.getID() != agent_id) || (gAgent.getSessionID() != session_id))
-	{
-		LL_WARNS("Messaging") << "Incorrect id in process_crossed_region()"
-				<< LL_ENDL;
-		return;
-	}
-	LL_INFOS("Messaging") << "process_crossed_region()" << LL_ENDL;
-	gAgentAvatarp->resetRegionCrossingTimer();
-
-	U32 sim_ip;
-	msg->getIPAddrFast(_PREHASH_RegionData, _PREHASH_SimIP, sim_ip);
-	U16 sim_port;
-	msg->getIPPortFast(_PREHASH_RegionData, _PREHASH_SimPort, sim_port);
-	LLHost sim_host(sim_ip, sim_port);
-	U64 region_handle;
-	msg->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
-	
-	std::string seedCap;
-	msg->getStringFast(_PREHASH_RegionData, _PREHASH_SeedCapability, seedCap);
-
-	send_complete_agent_movement(sim_host);
-
-	LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host);
-	regionp->setSeedCapability(seedCap);
-}
-
-
-
-// Sends avatar and camera information to simulator.
-// Sent roughly once per frame, or 20 times per second, whichever is less often
-
-const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f;	// ~= 2.5 degrees -- if its less than this we need to update head_rot
-const F32 MAX_HEAD_ROT_QDOT = 0.99999f;			// ~= 0.5 degrees -- if its greater than this then no need to update head_rot
-												// between these values we delay the updates (but no more than one second)
-
-static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE_SEND("Send Message");
-
-void send_agent_update(BOOL force_send, BOOL send_reliable)
-{
-	if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
-	{
-		// We don't care if they want to send an agent update, they're not allowed to until the simulator
-		// that's the target is ready to receive them (after avatar_init_complete is received)
-		return;
-	}
-
-	// We have already requested to log out.  Don't send agent updates.
-	if(LLAppViewer::instance()->logoutRequestSent())
-	{
-		return;
-	}
-
-	// no region to send update to
-	if(gAgent.getRegion() == NULL)
-	{
-		return;
-	}
-
-	const F32 TRANSLATE_THRESHOLD = 0.01f;
-
-	// NOTA BENE: This is (intentionally?) using the small angle sine approximation to test for rotation
-	//			  Plus, there is an extra 0.5 in the mix since the perpendicular between last_camera_at and getAtAxis() bisects cam_rot_change
-	//			  Thus, we're actually testing against 0.2 degrees
-	const F32 ROTATION_THRESHOLD = 0.1f * 2.f*F_PI/360.f;			//  Rotation thresh 0.2 deg, see note above
-
-	const U8 DUP_MSGS = 1;				//  HACK!  number of times to repeat data on motionless agent
-
-	//  Store data on last sent update so that if no changes, no send
-	static LLVector3 last_camera_pos_agent, 
-					 last_camera_at, 
-					 last_camera_left,
-					 last_camera_up;
-	
-	static LLVector3 cam_center_chg,
-					 cam_rot_chg;
-
-	static LLQuaternion last_head_rot;
-	static U32 last_control_flags = 0;
-	static U8 last_render_state;
-	static U8 duplicate_count = 0;
-	static F32 head_rot_chg = 1.0;
-	static U8 last_flags;
-
-	LLMessageSystem	*msg = gMessageSystem;
-	LLVector3		camera_pos_agent;				// local to avatar's region
-	U8				render_state;
-
-	LLQuaternion body_rotation = gAgent.getFrameAgent().getQuaternion();
-	LLQuaternion head_rotation = gAgent.getHeadRotation();
-
-	camera_pos_agent = gAgentCamera.getCameraPositionAgent();
-
-	render_state = gAgent.getRenderState();
-
-	U32		control_flag_change = 0;
-	U8		flag_change = 0;
-
-	cam_center_chg = last_camera_pos_agent - camera_pos_agent;
-	cam_rot_chg = last_camera_at - LLViewerCamera::getInstance()->getAtAxis();
-
-	// If a modifier key is held down, turn off
-	// LBUTTON and ML_LBUTTON so that using the camera (alt-key) doesn't
-	// trigger a control event.
-	U32 control_flags = gAgent.getControlFlags();
-	MASK	key_mask = gKeyboard->currentMask(TRUE);
-	if (key_mask & MASK_ALT || key_mask & MASK_CONTROL)
-	{
-		control_flags &= ~(	AGENT_CONTROL_LBUTTON_DOWN |
-							AGENT_CONTROL_ML_LBUTTON_DOWN );
-		control_flags |= 	AGENT_CONTROL_LBUTTON_UP |
-							AGENT_CONTROL_ML_LBUTTON_UP ;
-	}
-
-	control_flag_change = last_control_flags ^ control_flags;
-
-	U8 flags = AU_FLAGS_NONE;
-	if (gAgent.isGroupTitleHidden())
-	{
-		flags |= AU_FLAGS_HIDETITLE;
-	}
-	if (gAgent.getAutoPilot())
-	{
-		flags |= AU_FLAGS_CLIENT_AUTOPILOT;
-	}
-
-	flag_change = last_flags ^ flags;
-
-	head_rot_chg = dot(last_head_rot, head_rotation);
-
-	if (force_send || 
-		(cam_center_chg.magVec() > TRANSLATE_THRESHOLD) || 
-		(head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) ||	
-		(last_render_state != render_state) ||
-		(cam_rot_chg.magVec() > ROTATION_THRESHOLD) ||
-		control_flag_change != 0 ||
-		flag_change != 0)  
-	{
-/*
-		if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT)
-		{
-			//LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL;
-			LL_INFOS("Messaging") << "head_rot_chg = " << head_rot_chg << LL_ENDL;
-		}
-		if (cam_rot_chg.magVec() > ROTATION_THRESHOLD) 
-		{
-			LL_INFOS("Messaging") << "cam rot " <<  cam_rot_chg.magVec() << LL_ENDL;
-		}
-		if (cam_center_chg.magVec() > TRANSLATE_THRESHOLD)
-		{
-			LL_INFOS("Messaging") << "cam center " << cam_center_chg.magVec() << LL_ENDL;
-		}
-//		if (drag_delta_chg.magVec() > TRANSLATE_THRESHOLD)
-//		{
-//			LL_INFOS("Messaging") << "drag delta " << drag_delta_chg.magVec() << LL_ENDL;
-//		}
-		if (control_flag_change)
-		{
-			LL_INFOS("Messaging") << "dcf = " << control_flag_change << LL_ENDL;
-		}
-*/
-
-		duplicate_count = 0;
-	}
-	else
-	{
-		duplicate_count++;
-
-		if (head_rot_chg < MAX_HEAD_ROT_QDOT  &&  duplicate_count < AGENT_UPDATES_PER_SECOND)
-		{
-			// The head_rotation is sent for updating things like attached guns.
-			// We only trigger a new update when head_rotation deviates beyond
-			// some threshold from the last update, however this can break fine
-			// adjustments when trying to aim an attached gun, so what we do here
-			// (where we would normally skip sending an update when nothing has changed)
-			// is gradually reduce the threshold to allow a better update to 
-			// eventually get sent... should update to within 0.5 degrees in less 
-			// than a second.
-			if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT + (MAX_HEAD_ROT_QDOT - THRESHOLD_HEAD_ROT_QDOT) * duplicate_count / AGENT_UPDATES_PER_SECOND)
-			{
-				duplicate_count = 0;
-			}
-			else
-			{
-				return;
-			}
-		}
-		else
-		{
-			return;
-		}
-	}
-
-	if (duplicate_count < DUP_MSGS && !gDisconnected)
-	{
-		LLFastTimer t(FTM_AGENT_UPDATE_SEND);
-		// Build the message
-		msg->newMessageFast(_PREHASH_AgentUpdate);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->addQuatFast(_PREHASH_BodyRotation, body_rotation);
-		msg->addQuatFast(_PREHASH_HeadRotation, head_rotation);
-		msg->addU8Fast(_PREHASH_State, render_state);
-		msg->addU8Fast(_PREHASH_Flags, flags);
-
-//		if (camera_pos_agent.mV[VY] > 255.f)
-//		{
-//			LL_INFOS("Messaging") << "Sending camera center " << camera_pos_agent << LL_ENDL;
-//		}
-		
-		msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent);
-		msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstance()->getAtAxis());
-		msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis());
-		msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis());
-		msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance);
-		
-		msg->addU32Fast(_PREHASH_ControlFlags, control_flags);
-
-		if (gDebugClicks)
-		{
-			if (control_flags & AGENT_CONTROL_LBUTTON_DOWN)
-			{
-				LL_INFOS("Messaging") << "AgentUpdate left button down" << LL_ENDL;
-			}
-
-			if (control_flags & AGENT_CONTROL_LBUTTON_UP)
-			{
-				LL_INFOS("Messaging") << "AgentUpdate left button up" << LL_ENDL;
-			}
-		}
-
-		gAgent.enableControlFlagReset();
-
-		if (!send_reliable)
-		{
-			gAgent.sendMessage();
-		}
-		else
-		{
-			gAgent.sendReliableMessage();
-		}
-
-//		LL_DEBUGS("Messaging") << "agent " << avatar_pos_agent << " cam " << camera_pos_agent << LL_ENDL;
-
-		// Copy the old data 
-		last_head_rot = head_rotation;
-		last_render_state = render_state;
-		last_camera_pos_agent = camera_pos_agent;
-		last_camera_at = LLViewerCamera::getInstance()->getAtAxis();
-		last_camera_left = LLViewerCamera::getInstance()->getLeftAxis();
-		last_camera_up = LLViewerCamera::getInstance()->getUpAxis();
-		last_control_flags = control_flags;
-		last_flags = flags;
-	}
-}
-
-
-
-// *TODO: Remove this dependency, or figure out a better way to handle
-// this hack.
-extern U32 gObjectBits;
-
-void process_object_update(LLMessageSystem *mesgsys, void **user_data)
-{	
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	// Update the data counters
-	if (mesgsys->getReceiveCompressedSize())
-	{
-		gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
-	}
-	else
-	{
-		gObjectBits += mesgsys->getReceiveSize() * 8;
-	}
-
-	// Update the object...
-	gObjectList.processObjectUpdate(mesgsys, user_data, OUT_FULL);
-}
-
-void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	// Update the data counters
-	if (mesgsys->getReceiveCompressedSize())
-	{
-		gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
-	}
-	else
-	{
-		gObjectBits += mesgsys->getReceiveSize() * 8;
-	}
-
-	// Update the object...
-	gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_FULL_COMPRESSED);
-}
-
-void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	// Update the data counters
-	if (mesgsys->getReceiveCompressedSize())
-	{
-		gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
-	}
-	else
-	{
-		gObjectBits += mesgsys->getReceiveSize() * 8;
-	}
-
-	// Update the object...
-	gObjectList.processCachedObjectUpdate(mesgsys, user_data, OUT_FULL_CACHED);
-}
-
-
-void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	if (mesgsys->getReceiveCompressedSize())
-	{
-		gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
-	}
-	else
-	{
-		gObjectBits += mesgsys->getReceiveSize() * 8;
-	}
-
-	gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
-}
-
-static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
-
-
-void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLFastTimer t(FTM_PROCESS_OBJECTS);
-
-	LLUUID		id;
-	U32			local_id;
-	S32			i;
-	S32			num_objects;
-
-	num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
-
-	for (i = 0; i < num_objects; i++)
-	{
-		mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
-
-		LLViewerObjectList::getUUIDFromLocal(id,
-											local_id,
-											gMessageSystem->getSenderIP(),
-											gMessageSystem->getSenderPort());
-		if (id == LLUUID::null)
-		{
-			LL_DEBUGS("Messaging") << "Unknown kill for local " << local_id << LL_ENDL;
-			gObjectList.mNumUnknownKills++;
-			continue;
-		}
-		else
-		{
-			LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;
-		}
-
-		LLSelectMgr::getInstance()->removeObjectFromSelections(id);
-
-		// ...don't kill the avatar
-		if (!(id == gAgentID))
-		{
-			LLViewerObject *objectp = gObjectList.findObject(id);
-			if (objectp)
-			{
-				// Display green bubble on kill
-				if ( gShowObjectUpdates )
-				{
-					LLViewerObject* newobject;
-					newobject = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, objectp->getRegion());
-
-					LLVOTextBubble* bubble = (LLVOTextBubble*) newobject;
-
-					bubble->mColor.setVec(0.f, 1.f, 0.f, 1.f);
-					bubble->setScale( 2.0f * bubble->getScale() );
-					bubble->setPositionGlobal(objectp->getPositionGlobal());
-					gPipeline.addObject(bubble);
-				}
-
-				// Do the kill
-				gObjectList.killObject(objectp);
-			}
-			else
-			{
-				LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL;
-				gObjectList.mNumUnknownKills++;
-			}
-		}
-	}
-}
-
-void process_time_synch(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLVector3 sun_direction;
-	LLVector3 sun_ang_velocity;
-	F32 phase;
-	U64	space_time_usec;
-
-    U32 seconds_per_day;
-    U32 seconds_per_year;
-
-	// "SimulatorViewerTimeMessage"
-	mesgsys->getU64Fast(_PREHASH_TimeInfo, _PREHASH_UsecSinceStart, space_time_usec);
-	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerDay, seconds_per_day);
-	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerYear, seconds_per_year);
-
-	// This should eventually be moved to an "UpdateHeavenlyBodies" message
-	mesgsys->getF32Fast(_PREHASH_TimeInfo, _PREHASH_SunPhase, phase);
-	mesgsys->getVector3Fast(_PREHASH_TimeInfo, _PREHASH_SunDirection, sun_direction);
-	mesgsys->getVector3Fast(_PREHASH_TimeInfo, _PREHASH_SunAngVelocity, sun_ang_velocity);
-
-	LLWorld::getInstance()->setSpaceTimeUSec(space_time_usec);
-
-	//LL_DEBUGS("Messaging") << "time_synch() - " << sun_direction << ", " << sun_ang_velocity
-	//		 << ", " << phase << LL_ENDL;
-
-	gSky.setSunPhase(phase);
-	gSky.setSunTargetDirection(sun_direction, sun_ang_velocity);
-	if (!gNoRender && !(gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || gSky.getOverrideSun()))
-	{
-		gSky.setSunDirection(sun_direction, sun_ang_velocity);
-	}
-}
-
-void process_sound_trigger(LLMessageSystem *msg, void **)
-{
-	if (!gAudiop) return;
-
-	U64		region_handle = 0;
-	F32		gain = 0;
-	LLUUID	sound_id;
-	LLUUID	owner_id;
-	LLUUID	object_id;
-	LLUUID	parent_id;
-	LLVector3	pos_local;
-
-	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_SoundID, sound_id);
-	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_OwnerID, owner_id);
-	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ObjectID, object_id);
-	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ParentID, parent_id);
-	msg->getU64Fast(_PREHASH_SoundData, _PREHASH_Handle, region_handle);
-	msg->getVector3Fast(_PREHASH_SoundData, _PREHASH_Position, pos_local);
-	msg->getF32Fast(_PREHASH_SoundData, _PREHASH_Gain, gain);
-
-	// adjust sound location to true global coords
-	LLVector3d	pos_global = from_region_handle(region_handle);
-	pos_global.mdV[VX] += pos_local.mV[VX];
-	pos_global.mdV[VY] += pos_local.mV[VY];
-	pos_global.mdV[VZ] += pos_local.mV[VZ];
-
-	// Don't play a trigger sound if you can't hear it due
-	// to parcel "local audio only" settings.
-	if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global)) return;
-
-	// Don't play sounds triggered by someone you muted.
-	if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
-	
-	// Don't play sounds from an object you muted
-	if (LLMuteList::getInstance()->isMuted(object_id)) return;
-
-	// Don't play sounds from an object whose parent you muted
-	if (parent_id.notNull()
-		&& LLMuteList::getInstance()->isMuted(parent_id))
-	{
-		return;
-	}
-
-	// Don't play sounds from a region with maturity above current agent maturity
-	if( !gAgent.canAccessMaturityInRegion( region_handle ) )
-	{
-		return;
-	}
-		
-	gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global);
-}
-
-void process_preload_sound(LLMessageSystem *msg, void **user_data)
-{
-	if (!gAudiop)
-	{
-		return;
-	}
-
-	LLUUID sound_id;
-	LLUUID object_id;
-	LLUUID owner_id;
-
-	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_SoundID, sound_id);
-	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id);
-	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id);
-
-	LLViewerObject *objectp = gObjectList.findObject(object_id);
-	if (!objectp) return;
-
-	if (LLMuteList::getInstance()->isMuted(object_id)) return;
-	if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
-	
-	LLAudioSource *sourcep = objectp->getAudioSource(owner_id);
-	if (!sourcep) return;
-	
-	LLAudioData *datap = gAudiop->getAudioData(sound_id);
-
-	// Note that I don't actually do any loading of the
-	// audio data into a buffer at this point, as it won't actually
-	// help us out.
-
-	// Don't play sounds from a region with maturity above current agent maturity
-	LLVector3d pos_global = objectp->getPositionGlobal();
-	if (gAgent.canAccessMaturityAtGlobal(pos_global))
-	{
-	// Add audioData starts a transfer internally.
-	sourcep->addAudioData(datap, FALSE);
-}
-}
-
-void process_attached_sound(LLMessageSystem *msg, void **user_data)
-{
-	F32 gain = 0;
-	LLUUID sound_id;
-	LLUUID object_id;
-	LLUUID owner_id;
-	U8 flags;
-
-	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_SoundID, sound_id);
-	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id);
-	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id);
-	msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain);
-	msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags);
-
-	LLViewerObject *objectp = gObjectList.findObject(object_id);
-	if (!objectp)
-	{
-		// we don't know about this object, just bail
-		return;
-	}
-	
-	if (LLMuteList::getInstance()->isMuted(object_id)) return;
-	
-	if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
-
-	
-	// Don't play sounds from a region with maturity above current agent maturity
-	LLVector3d pos = objectp->getPositionGlobal();
-	if( !gAgent.canAccessMaturityAtGlobal(pos) )
-	{
-		return;
-	}
-	
-	objectp->setAttachedSound(sound_id, owner_id, gain, flags);
-}
-
-
-void process_attached_sound_gain_change(LLMessageSystem *mesgsys, void **user_data)
-{
-	F32 gain = 0;
-	LLUUID object_guid;
-	LLViewerObject *objectp = NULL;
-
-	mesgsys->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_guid);
-
-	if (!((objectp = gObjectList.findObject(object_guid))))
-	{
-		// we don't know about this object, just bail
-		return;
-	}
-
- 	mesgsys->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain);
-
-	objectp->adjustAudioGain(gain);
-}
-
-
-void process_health_message(LLMessageSystem *mesgsys, void **user_data)
-{
-	F32 health;
-
-	mesgsys->getF32Fast(_PREHASH_HealthData, _PREHASH_Health, health);
-
-	if (gStatusBar)
-	{
-		gStatusBar->setHealth((S32)health);
-	}
-}
-
-
-void process_sim_stats(LLMessageSystem *msg, void **user_data)
-{	
-	S32 count = msg->getNumberOfBlocks("Stat");
-	for (S32 i = 0; i < count; ++i)
-	{
-		U32 stat_id;
-		F32 stat_value;
-		msg->getU32("Stat", "StatID", stat_id, i);
-		msg->getF32("Stat", "StatValue", stat_value, i);
-		switch (stat_id)
-		{
-		case LL_SIM_STAT_TIME_DILATION:
-			LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_FPS:
-			LLViewerStats::getInstance()->mSimFPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PHYSFPS:
-			LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_AGENTUPS:
-			LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_FRAMEMS:
-			LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NETMS:
-			LLViewerStats::getInstance()->mSimNetMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMOTHERMS:
-			LLViewerStats::getInstance()->mSimSimOtherMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMPHYSICSMS:
-			LLViewerStats::getInstance()->mSimSimPhysicsMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_AGENTMS:
-			LLViewerStats::getInstance()->mSimAgentMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_IMAGESMS:
-			LLViewerStats::getInstance()->mSimImagesMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SCRIPTMS:
-			LLViewerStats::getInstance()->mSimScriptMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NUMTASKS:
-			LLViewerStats::getInstance()->mSimObjects.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NUMTASKSACTIVE:
-			LLViewerStats::getInstance()->mSimActiveObjects.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NUMAGENTMAIN:
-			LLViewerStats::getInstance()->mSimMainAgents.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NUMAGENTCHILD:
-			LLViewerStats::getInstance()->mSimChildAgents.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NUMSCRIPTSACTIVE:
-			LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SCRIPT_EPS:
-			LLViewerStats::getInstance()->mSimScriptEPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_INPPS:
-			LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_OUTPPS:
-			LLViewerStats::getInstance()->mSimOutPPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PENDING_DOWNLOADS:
-			LLViewerStats::getInstance()->mSimPendingDownloads.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PENDING_UPLOADS:
-			LLViewerStats::getInstance()->mSimPendingUploads.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PENDING_LOCAL_UPLOADS:
-			LLViewerStats::getInstance()->mSimPendingLocalUploads.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_TOTAL_UNACKED_BYTES:
-			LLViewerStats::getInstance()->mSimTotalUnackedBytes.addValue(stat_value / 1024.f);
-			break;
-		case LL_SIM_STAT_PHYSICS_PINNED_TASKS:
-			LLViewerStats::getInstance()->mPhysicsPinnedTasks.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PHYSICS_LOD_TASKS:
-			LLViewerStats::getInstance()->mPhysicsLODTasks.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMPHYSICSSTEPMS:
-			LLViewerStats::getInstance()->mSimSimPhysicsStepMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMPHYSICSSHAPEMS:
-			LLViewerStats::getInstance()->mSimSimPhysicsShapeUpdateMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMPHYSICSOTHERMS:
-			LLViewerStats::getInstance()->mSimSimPhysicsOtherMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMPHYSICSMEMORY:
-			LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMSPARETIME:
-			LLViewerStats::getInstance()->mSimSpareMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMSLEEPTIME:
-			LLViewerStats::getInstance()->mSimSleepMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_IOPUMPTIME:
-			LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value);
-			break;
-		default:
-			// Used to be a commented out warning.
- 			LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL;
-		  break;
-		}
-	}
-
-	/*
-	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_PhysicsTimeDilation, time_dilation);
-	LLViewerStats::getInstance()->mSimTDStat.addValue(time_dilation);
-
-	// Process information
-	//	{	CpuUsage			F32				}
-	//	{	SimMemTotal			F32				}
-	//	{	SimMemRSS			F32				}
-	//	{	ProcessUptime		F32				}
-	F32 cpu_usage;
-	F32 sim_mem_total;
-	F32 sim_mem_rss;
-	F32 process_uptime;
-	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_CpuUsage, cpu_usage);
-	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemTotal, sim_mem_total);
-	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemRSS, sim_mem_rss);
-	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_ProcessUptime, process_uptime);
-	LLViewerStats::getInstance()->mSimCPUUsageStat.addValue(cpu_usage);
-	LLViewerStats::getInstance()->mSimMemTotalStat.addValue(sim_mem_total);
-	LLViewerStats::getInstance()->mSimMemRSSStat.addValue(sim_mem_rss);
-	*/
-
-	//
-	// Various hacks that aren't statistics, but are being handled here.
-	//
-	U32 max_tasks_per_region;
-	U32 region_flags;
-	msg->getU32("Region", "ObjectCapacity", max_tasks_per_region);
-	msg->getU32("Region", "RegionFlags", region_flags);
-
-	LLViewerRegion* regionp = gAgent.getRegion();
-	if (regionp)
-	{
-		BOOL was_flying = gAgent.getFlying();
-		regionp->setRegionFlags(region_flags);
-		regionp->setMaxTasks(max_tasks_per_region);
-		// HACK: This makes agents drop from the sky if the region is 
-		// set to no fly while people are still in the sim.
-		if (was_flying && regionp->getBlockFly())
-		{
-			gAgent.setFlying(gAgent.canFly());
-		}
-	}
-}
-
-
-
-void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLUUID	animation_id;
-	LLUUID	uuid;
-	S32		anim_sequence_id;
-	LLVOAvatar *avatarp;
-	
-	mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
-
-	//clear animation flags
-	avatarp = (LLVOAvatar *)gObjectList.findObject(uuid);
-
-	if (!avatarp)
-	{
-		// no agent by this ID...error?
-		LL_WARNS("Messaging") << "Received animation state for unknown avatar" << uuid << LL_ENDL;
-		return;
-	}
-
-	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
-	S32 num_source_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationSourceList);
-
-	avatarp->mSignaledAnimations.clear();
-	
-	if (avatarp->isSelf())
-	{
-		LLUUID object_id;
-
-		for( S32 i = 0; i < num_blocks; i++ )
-		{
-			mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
-			mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
-
-			LL_DEBUGS("Messaging") << "Anim sequence ID: " << anim_sequence_id << LL_ENDL;
-
-			avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
-
-			// *HACK: Disabling flying mode if it has been enabled shortly before the agent
-			// stand up animation is signaled. In this case we don't get a signal to start
-			// flying animation from server, the AGENT_CONTROL_FLY flag remains set but the
-			// avatar does not play flying animation, so we switch flying mode off.
-			// See LLAgent::setFlying(). This may cause "Stop Flying" button to blink.
-			// See EXT-2781.
-			if (animation_id == ANIM_AGENT_STANDUP && gAgent.getFlying())
-			{
-				gAgent.setFlying(FALSE);
-			}
-
-			if (i < num_source_blocks)
-			{
-				mesgsys->getUUIDFast(_PREHASH_AnimationSourceList, _PREHASH_ObjectID, object_id, i);
-			
-				LLViewerObject* object = gObjectList.findObject(object_id);
-				if (object)
-				{
-					object->mFlags |= FLAGS_ANIM_SOURCE;
-
-					BOOL anim_found = FALSE;
-					LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id);
-					for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it)
-					{
-						if (anim_it->second == animation_id)
-						{
-							anim_found = TRUE;
-							break;
-						}
-					}
-
-					if (!anim_found)
-					{
-						avatarp->mAnimationSources.insert(LLVOAvatar::AnimationSourceMap::value_type(object_id, animation_id));
-					}
-				}
-			}
-		}
-	}
-	else
-	{
-		for( S32 i = 0; i < num_blocks; i++ )
-		{
-			mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
-			mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
-			avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
-		}
-	}
-
-	if (num_blocks)
-	{
-		avatarp->processAnimationStateChanges();
-	}
-}
-
-void process_avatar_appearance(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLUUID uuid;
-	mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
-
-	LLVOAvatar* avatarp = (LLVOAvatar *)gObjectList.findObject(uuid);
-	if (avatarp)
-	{
-		avatarp->processAvatarAppearance( mesgsys );
-	}
-	else
-	{
-		LL_WARNS("Messaging") << "avatar_appearance sent for unknown avatar " << uuid << LL_ENDL;
-	}
-}
-
-void process_camera_constraint(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLVector4 cameraCollidePlane;
-	mesgsys->getVector4Fast(_PREHASH_CameraCollidePlane, _PREHASH_Plane, cameraCollidePlane);
-
-	gAgentCamera.setCameraCollidePlane(cameraCollidePlane);
-}
-
-void near_sit_object(BOOL success, void *data)
-{
-	if (success)
-	{
-		// Send message to sit on object
-		gMessageSystem->newMessageFast(_PREHASH_AgentSit);
-		gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		gAgent.sendReliableMessage();
-	}
-}
-
-void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLVector3 sitPosition;
-	LLQuaternion sitRotation;
-	LLUUID sitObjectID;
-	BOOL use_autopilot;
-	mesgsys->getUUIDFast(_PREHASH_SitObject, _PREHASH_ID, sitObjectID);
-	mesgsys->getBOOLFast(_PREHASH_SitTransform, _PREHASH_AutoPilot, use_autopilot);
-	mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_SitPosition, sitPosition);
-	mesgsys->getQuatFast(_PREHASH_SitTransform, _PREHASH_SitRotation, sitRotation);
-	LLVector3 camera_eye;
-	mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_CameraEyeOffset, camera_eye);
-	LLVector3 camera_at;
-	mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_CameraAtOffset, camera_at);
-	BOOL force_mouselook;
-	mesgsys->getBOOLFast(_PREHASH_SitTransform, _PREHASH_ForceMouselook, force_mouselook);
-
-	if (isAgentAvatarValid() && dist_vec_squared(camera_eye, camera_at) > 0.0001f)
-	{
-		gAgentCamera.setSitCamera(sitObjectID, camera_eye, camera_at);
-	}
-	
-	gAgentCamera.setForceMouselook(force_mouselook);
-	// Forcing turning off flying here to prevent flying after pressing "Stand"
-	// to stand up from an object. See EXT-1655.
-	gAgent.setFlying(FALSE);
-
-	LLViewerObject* object = gObjectList.findObject(sitObjectID);
-	if (object)
-	{
-		LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation());
-		if (!use_autopilot || isAgentAvatarValid() && gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == object->getRoot())
-		{
-			//we're already sitting on this object, so don't autopilot
-		}
-		else
-		{
-			gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(sit_spot), "Sit", &sitRotation, near_sit_object, NULL, 0.5f);
-		}
-	}
-	else
-	{
-		LL_WARNS("Messaging") << "Received sit approval for unknown object " << sitObjectID << LL_ENDL;
-	}
-}
-
-void process_clear_follow_cam_properties(LLMessageSystem *mesgsys, void **user_data)
-{
-	LLUUID		source_id;
-
-	mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, source_id);
-
-	LLFollowCamMgr::removeFollowCamParams(source_id);
-}
-
-void process_set_follow_cam_properties(LLMessageSystem *mesgsys, void **user_data)
-{
-	S32			type;
-	F32			value;
-	bool		settingPosition = false;
-	bool		settingFocus	= false;
-	bool		settingFocusOffset = false;
-	LLVector3	position;
-	LLVector3	focus;
-	LLVector3	focus_offset;
-
-	LLUUID		source_id;
-
-	mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, source_id);
-
-	LLViewerObject* objectp = gObjectList.findObject(source_id);
-	if (objectp)
-	{
-		objectp->mFlags |= FLAGS_CAMERA_SOURCE;
-	}
-
-	S32 num_objects = mesgsys->getNumberOfBlocks("CameraProperty");
-	for (S32 block_index = 0; block_index < num_objects; block_index++)
-	{
-		mesgsys->getS32("CameraProperty", "Type", type, block_index);
-		mesgsys->getF32("CameraProperty", "Value", value, block_index);
-		switch(type)
-		{
-		case FOLLOWCAM_PITCH:
-			LLFollowCamMgr::setPitch(source_id, value);
-			break;
-		case FOLLOWCAM_FOCUS_OFFSET_X:
-			focus_offset.mV[VX] = value;
-			settingFocusOffset = true;
-			break;
-		case FOLLOWCAM_FOCUS_OFFSET_Y:
-			focus_offset.mV[VY] = value;
-			settingFocusOffset = true;
-			break;
-		case FOLLOWCAM_FOCUS_OFFSET_Z:
-			focus_offset.mV[VZ] = value;
-			settingFocusOffset = true;
-			break;
-		case FOLLOWCAM_POSITION_LAG:
-			LLFollowCamMgr::setPositionLag(source_id, value);
-			break;
-		case FOLLOWCAM_FOCUS_LAG:
-			LLFollowCamMgr::setFocusLag(source_id, value);
-			break;
-		case FOLLOWCAM_DISTANCE:
-			LLFollowCamMgr::setDistance(source_id, value);
-			break;
-		case FOLLOWCAM_BEHINDNESS_ANGLE:
-			LLFollowCamMgr::setBehindnessAngle(source_id, value);
-			break;
-		case FOLLOWCAM_BEHINDNESS_LAG:
-			LLFollowCamMgr::setBehindnessLag(source_id, value);
-			break;
-		case FOLLOWCAM_POSITION_THRESHOLD:
-			LLFollowCamMgr::setPositionThreshold(source_id, value);
-			break;
-		case FOLLOWCAM_FOCUS_THRESHOLD:
-			LLFollowCamMgr::setFocusThreshold(source_id, value);
-			break;
-		case FOLLOWCAM_ACTIVE:
-			//if 1, set using followcam,. 
-			LLFollowCamMgr::setCameraActive(source_id, value != 0.f);
-			break;
-		case FOLLOWCAM_POSITION_X:
-			settingPosition = true;
-			position.mV[ 0 ] = value;
-			break;
-		case FOLLOWCAM_POSITION_Y:
-			settingPosition = true;
-			position.mV[ 1 ] = value;
-			break;
-		case FOLLOWCAM_POSITION_Z:
-			settingPosition = true;
-			position.mV[ 2 ] = value;
-			break;
-		case FOLLOWCAM_FOCUS_X:
-			settingFocus = true;
-			focus.mV[ 0 ] = value;
-			break;
-		case FOLLOWCAM_FOCUS_Y:
-			settingFocus = true;
-			focus.mV[ 1 ] = value;
-			break;
-		case FOLLOWCAM_FOCUS_Z:
-			settingFocus = true;
-			focus.mV[ 2 ] = value;
-			break;
-		case FOLLOWCAM_POSITION_LOCKED:
-			LLFollowCamMgr::setPositionLocked(source_id, value != 0.f);
-			break;
-		case FOLLOWCAM_FOCUS_LOCKED:
-			LLFollowCamMgr::setFocusLocked(source_id, value != 0.f);
-			break;
-
-		default:
-			break;
-		}
-	}
-
-	if ( settingPosition )
-	{
-		LLFollowCamMgr::setPosition(source_id, position);
-	}
-	if ( settingFocus )
-	{
-		LLFollowCamMgr::setFocus(source_id, focus);
-	}
-	if ( settingFocusOffset )
-	{
-		LLFollowCamMgr::setFocusOffset(source_id, focus_offset);
-	}
-}
-//end Ventrella 
-
-
-// Culled from newsim lltask.cpp
-void process_name_value(LLMessageSystem *mesgsys, void **user_data)
-{
-	std::string	temp_str;
-	LLUUID	id;
-	S32		i, num_blocks;
-
-	mesgsys->getUUIDFast(_PREHASH_TaskData, _PREHASH_ID, id);
-
-	LLViewerObject* object = gObjectList.findObject(id);
-
-	if (object)
-	{
-		num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_NameValueData);
-		for (i = 0; i < num_blocks; i++)
-		{
-			mesgsys->getStringFast(_PREHASH_NameValueData, _PREHASH_NVPair, temp_str, i);
-			LL_INFOS("Messaging") << "Added to object Name Value: " << temp_str << LL_ENDL;
-			object->addNVPair(temp_str);
-		}
-	}
-	else
-	{
-		LL_INFOS("Messaging") << "Can't find object " << id << " to add name value pair" << LL_ENDL;
-	}
-}
-
-void process_remove_name_value(LLMessageSystem *mesgsys, void **user_data)
-{
-	std::string	temp_str;
-	LLUUID	id;
-	S32		i, num_blocks;
-
-	mesgsys->getUUIDFast(_PREHASH_TaskData, _PREHASH_ID, id);
-
-	LLViewerObject* object = gObjectList.findObject(id);
-
-	if (object)
-	{
-		num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_NameValueData);
-		for (i = 0; i < num_blocks; i++)
-		{
-			mesgsys->getStringFast(_PREHASH_NameValueData, _PREHASH_NVPair, temp_str, i);
-			LL_INFOS("Messaging") << "Removed from object Name Value: " << temp_str << LL_ENDL;
-			object->removeNVPair(temp_str);
-		}
-	}
-	else
-	{
-		LL_INFOS("Messaging") << "Can't find object " << id << " to remove name value pair" << LL_ENDL;
-	}
-}
-
-void process_kick_user(LLMessageSystem *msg, void** /*user_data*/)
-{
-	std::string message;
-
-	msg->getStringFast(_PREHASH_UserInfo, _PREHASH_Reason, message);
-
-	LLAppViewer::instance()->forceDisconnect(message);
-}
-
-
-/*
-void process_user_list_reply(LLMessageSystem *msg, void **user_data)
-{
-	LLUserList::processUserListReply(msg, user_data);
-	return;
-	char	firstname[MAX_STRING+1];
-	char	lastname[MAX_STRING+1];
-	U8		status;
-	S32		user_count;
-
-	user_count = msg->getNumberOfBlocks("UserBlock");
-
-	for (S32 i = 0; i < user_count; i++)
-	{
-		msg->getData("UserBlock", i, "FirstName", firstname);
-		msg->getData("UserBlock", i, "LastName", lastname);
-		msg->getData("UserBlock", i, "Status", &status);
-
-		if (status & 0x01)
-		{
-			dialog_friends_add_friend(buffer, TRUE);
-		}
-		else
-		{
-			dialog_friends_add_friend(buffer, FALSE);
-		}
-	}
-
-	dialog_friends_done_adding();
-}
-*/
-
-// this is not handled in processUpdateMessage
-/*
-void process_time_dilation(LLMessageSystem *msg, void **user_data)
-{
-	// get the time_dilation
-	U16 foo;
-	msg->getData("TimeDilation", "TimeDilation", &foo);
-	F32 time_dilation = ((F32) foo) / 65535.f;
-
-	// get the pointer to the right region
-	U32 ip = msg->getSenderIP();
-	U32 port = msg->getSenderPort();
-	LLViewerRegion *regionp = LLWorld::getInstance()->getRegion(ip, port);
-	if (regionp)
-	{
-		regionp->setTimeDilation(time_dilation);
-	}
-}
-*/
-
-
-void process_money_balance_reply( LLMessageSystem* msg, void** )
-{
-	S32 balance = 0;
-	S32 credit = 0;
-	S32 committed = 0;
-	std::string desc;
-	LLUUID tid;
-
-	msg->getUUID("MoneyData", "TransactionID", tid);
-	msg->getS32("MoneyData", "MoneyBalance", balance);
-	msg->getS32("MoneyData", "SquareMetersCredit", credit);
-	msg->getS32("MoneyData", "SquareMetersCommitted", committed);
-	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_Description, desc);
-	LL_INFOS("Messaging") << "L$, credit, committed: " << balance << " " << credit << " "
-			<< committed << LL_ENDL;
-    
-	if (gStatusBar)
-	{
-		gStatusBar->setBalance(balance);
-		gStatusBar->setLandCredit(credit);
-		gStatusBar->setLandCommitted(committed);
-	}
-
-	if (desc.empty()
-		|| !gSavedSettings.getBOOL("NotifyMoneyChange"))
-	{
-		// ...nothing to display
-		return;
-	}
-
-	// Suppress duplicate messages about the same transaction
-	static std::deque<LLUUID> recent;
-	if (std::find(recent.rbegin(), recent.rend(), tid) != recent.rend())
-	{
-		return;
-	}
-
-	// Once the 'recent' container gets large enough, chop some
-	// off the beginning.
-	const U32 MAX_LOOKBACK = 30;
-	const S32 POP_FRONT_SIZE = 12;
-	if(recent.size() > MAX_LOOKBACK)
-	{
-		LL_DEBUGS("Messaging") << "Removing oldest transaction records" << LL_ENDL;
-		recent.erase(recent.begin(), recent.begin() + POP_FRONT_SIZE);
-	}
-	//LL_DEBUGS("Messaging") << "Pushing back transaction " << tid << LL_ENDL;
-	recent.push_back(tid);
-
-	if (msg->has("TransactionInfo"))
-	{
-		// ...message has extended info for localization
-		process_money_balance_reply_extended(msg);
-	}
-	else
-	{
-		// Only old dev grids will not supply the TransactionInfo block,
-		// so we can just use the hard-coded English string.
-		LLSD args;
-		args["MESSAGE"] = desc;
-		LLNotificationsUtil::add("SystemMessage", args);
-	}
-}
-
-static std::string reason_from_transaction_type(S32 transaction_type,
-												const std::string& item_desc)
-{
-	// *NOTE: The keys for the reason strings are unusual because
-	// an earlier version of the code used English language strings
-	// extracted from hard-coded server English descriptions.
-	// Keeping them so we don't have to re-localize them.
-	switch (transaction_type)
-	{
-		case TRANS_OBJECT_SALE:
-		{
-			LLStringUtil::format_map_t arg;
-			arg["ITEM"] = item_desc;
-			return LLTrans::getString("for item", arg);
-		}
-		case TRANS_LAND_SALE:
-			return LLTrans::getString("for a parcel of land");
-			
-		case TRANS_LAND_PASS_SALE:
-			return LLTrans::getString("for a land access pass");
-			
-		case TRANS_GROUP_LAND_DEED:
-			return LLTrans::getString("for deeding land");
-			
-		case TRANS_GROUP_CREATE:
-			return LLTrans::getString("to create a group");
-			
-		case TRANS_GROUP_JOIN:
-			return LLTrans::getString("to join a group");
-			
-		case TRANS_UPLOAD_CHARGE:
-			return LLTrans::getString("to upload");
-
-		case TRANS_CLASSIFIED_CHARGE:
-			return LLTrans::getString("to publish a classified ad");
-			
-		// These have no reason to display, but are expected and should not
-		// generate warnings
-		case TRANS_GIFT:
-		case TRANS_PAY_OBJECT:
-		case TRANS_OBJECT_PAYS:
-			return std::string();
-
-		default:
-			llwarns << "Unknown transaction type " 
-				<< transaction_type << llendl;
-			return std::string();
-	}
-}
-
-static void money_balance_group_notify(const LLUUID& group_id,
-									   const std::string& name,
-									   bool is_group,
-									   std::string notification,
-									   LLSD args,
-									   LLSD payload)
-{
-	// Message uses name SLURLs, don't actually have to substitute in
-	// the name.  We're just making sure it's available.
-	// Notification is either PaymentReceived or PaymentSent
-	LLNotificationsUtil::add(notification, args, payload);
-}
-
-static void money_balance_avatar_notify(const LLUUID& agent_id,
-										const LLAvatarName& av_name,
-									   	std::string notification,
-									   	LLSD args,
-									   	LLSD payload)
-{
-	// Message uses name SLURLs, don't actually have to substitute in
-	// the name.  We're just making sure it's available.
-	// Notification is either PaymentReceived or PaymentSent
-	LLNotificationsUtil::add(notification, args, payload);
-}
-
-static void process_money_balance_reply_extended(LLMessageSystem* msg)
-{
-    // Added in server 1.40 and viewer 2.1, support for localization
-    // and agent ids for name lookup.
-    S32 transaction_type = 0;
-    LLUUID source_id;
-	BOOL is_source_group = FALSE;
-    LLUUID dest_id;
-	BOOL is_dest_group = FALSE;
-    S32 amount = 0;
-    std::string item_description;
-
-    msg->getS32("TransactionInfo", "TransactionType", transaction_type);
-    msg->getUUID("TransactionInfo", "SourceID", source_id);
-	msg->getBOOL("TransactionInfo", "IsSourceGroup", is_source_group);
-    msg->getUUID("TransactionInfo", "DestID", dest_id);
-	msg->getBOOL("TransactionInfo", "IsDestGroup", is_dest_group);
-    msg->getS32("TransactionInfo", "Amount", amount);
-    msg->getString("TransactionInfo", "ItemDescription", item_description);
-    LL_INFOS("Money") << "MoneyBalanceReply source " << source_id 
-		<< " dest " << dest_id
-		<< " type " << transaction_type
-		<< " item " << item_description << LL_ENDL;
-
-	if (source_id.isNull() && dest_id.isNull())
-	{
-		// this is a pure balance update, no notification required
-		return;
-	}
-
-	std::string source_slurl;
-	if (is_source_group)
-	{
-		source_slurl =
-			LLSLURL( "group", source_id, "inspect").getSLURLString();
-	}
-	else
-	{
-		source_slurl =
-			LLSLURL( "agent", source_id, "completename").getSLURLString();
-	}
-
-	std::string dest_slurl;
-	if (is_dest_group)
-	{
-		dest_slurl =
-			LLSLURL( "group", dest_id, "inspect").getSLURLString();
-	}
-	else
-	{
-		dest_slurl =
-			LLSLURL( "agent", dest_id, "completename").getSLURLString();
-	}
-
-	std::string reason =
-		reason_from_transaction_type(transaction_type, item_description);
-	
-	LLStringUtil::format_map_t args;
-	args["REASON"] = reason; // could be empty
-	args["AMOUNT"] = llformat("%d", amount);
-	
-	// Need to delay until name looked up, so need to know whether or not
-	// is group
-	bool is_name_group = false;
-	LLUUID name_id;
-	std::string message;
-	std::string notification;
-	LLSD final_args;
-	LLSD payload;
-	
-	bool you_paid_someone = (source_id == gAgentID);
-	if (you_paid_someone)
-	{
-		args["NAME"] = dest_slurl;
-		is_name_group = is_dest_group;
-		name_id = dest_id;
-		if (!reason.empty())
-		{
-			if (dest_id.notNull())
-			{
-				message = LLTrans::getString("you_paid_ldollars", args);
-			}
-			else
-			{
-				// transaction fee to the system, eg, to create a group
-				message = LLTrans::getString("you_paid_ldollars_no_name", args);
-			}
-		}
-		else
-		{
-			if (dest_id.notNull())
-			{
-				message = LLTrans::getString("you_paid_ldollars_no_reason", args);
-			}
-			else
-			{
-				// no target, no reason, you just paid money
-				message = LLTrans::getString("you_paid_ldollars_no_info", args);
-			}
-		}
-		final_args["MESSAGE"] = message;
-		notification = "PaymentSent";
-	}
-	else {
-		// ...someone paid you
-		args["NAME"] = source_slurl;
-		is_name_group = is_source_group;
-		name_id = source_id;
-		if (!reason.empty())
-		{
-			message = LLTrans::getString("paid_you_ldollars", args);
-		}
-		else {
-			message = LLTrans::getString("paid_you_ldollars_no_reason", args);
-		}
-		final_args["MESSAGE"] = message;
-
-		// make notification loggable
-		payload["from_id"] = source_id;
-		notification = "PaymentReceived";
-	}
-
-	// Despite using SLURLs, wait until the name is available before
-	// showing the notification, otherwise the UI layout is strange and
-	// the user sees a "Loading..." message
-	if (is_name_group)
-	{
-		gCacheName->getGroup(name_id,
-						boost::bind(&money_balance_group_notify,
-									_1, _2, _3,
-									notification, final_args, payload));
-	}
-	else {
-		LLAvatarNameCache::get(name_id,
-							   boost::bind(&money_balance_avatar_notify,
-										   _1, _2,
-										   notification, final_args, payload));										   
-	}
-}
-
-
-
-bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	
-	if (0 == option)
-	{
-		// set the preference to the maturity of the region we're calling
-		int preferredMaturity = notification["payload"]["_region_access"].asInteger();
-		gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
-		gAgent.sendMaturityPreferenceToServer(preferredMaturity);
-
-		// notify user that the maturity preference has been changed
-		LLSD args;
-		args["RATING"] = LLViewerRegion::accessToString(preferredMaturity);
-		LLNotificationsUtil::add("PreferredMaturityChanged", args);
-	}
-	
-	return false;
-}
-
-// some of the server notifications need special handling. This is where we do that.
-bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
-{
-	int regionAccess = llsdBlock["_region_access"].asInteger();
-	llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess);
-	
-	// we're going to throw the LLSD in there in case anyone ever wants to use it
-	LLNotificationsUtil::add(notificationID+"_Notify", llsdBlock);
-	
-	if (regionAccess == SIM_ACCESS_MATURE)
-	{
-		if (gAgent.isTeen())
-		{
-			LLNotificationsUtil::add(notificationID+"_KB", llsdBlock);
-			return true;
-		}
-		else if (gAgent.prefersPG())
-		{
-			LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
-			return true;
-		}
-	}
-	else if (regionAccess == SIM_ACCESS_ADULT)
-	{
-		if (!gAgent.isAdult())
-		{
-			LLNotificationsUtil::add(notificationID+"_KB", llsdBlock);
-			return true;
-		}
-		else if (gAgent.prefersPG() || gAgent.prefersMature())
-		{
-			LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
-			return true;
-		}
-	}
-	return false;
-}
-
-bool attempt_standard_notification(LLMessageSystem* msgsystem)
-{
-	// if we have additional alert data
-	if (msgsystem->has(_PREHASH_AlertInfo) && msgsystem->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0)
-	{
-		// notification was specified using the new mechanism, so we can just handle it here
-		std::string notificationID;
-		std::string llsdRaw;
-		LLSD llsdBlock;
-		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
-		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsdRaw);
-		if (llsdRaw.length())
-		{
-			std::istringstream llsdData(llsdRaw);
-			if (!LLSDSerialize::deserialize(llsdBlock, llsdData, llsdRaw.length()))
-			{
-				llwarns << "attempt_standard_notification: Attempted to read notification parameter data into LLSD but failed:" << llsdRaw << llendl;
-			}
-		}
-		
-		if (
-			(notificationID == "RegionEntryAccessBlocked") ||
-			(notificationID == "LandClaimAccessBlocked") ||
-			(notificationID == "LandBuyAccessBlocked")
-		   )
-		{
-			/*---------------------------------------------------------------------
-			 (Commented so a grep will find the notification strings, since
-			 we construct them on the fly; if you add additional notifications,
-			 please update the comment.)
-			 
-			 Could throw any of the following notifications:
-			 
-				RegionEntryAccessBlocked
-				RegionEntryAccessBlocked_Notify
-				RegionEntryAccessBlocked_Change
-				RegionEntryAccessBlocked_KB
-				LandClaimAccessBlocked 
-				LandClaimAccessBlocked_Notify 
-				LandClaimAccessBlocked_Change 
-				LandClaimAccessBlocked_KB 
-				LandBuyAccessBlocked
-				LandBuyAccessBlocked_Notify
-				LandBuyAccessBlocked_Change
-				LandBuyAccessBlocked_KB
-			 
-			-----------------------------------------------------------------------*/ 
-			if (handle_special_notification(notificationID, llsdBlock))
-			{
-				return true;
-			}
-		}
-		
-		LLNotificationsUtil::add(notificationID, llsdBlock);
-		return true;
-	}	
-	return false;
-}
-
-
-void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data)
-{
-	// make sure the cursor is back to the usual default since the
-	// alert is probably due to some kind of error.
-	gViewerWindow->getWindow()->resetBusyCount();
-	
-	if (!attempt_standard_notification(msgsystem))
-	{
-		BOOL modal = FALSE;
-		msgsystem->getBOOL("AlertData", "Modal", modal);
-		std::string buffer;
-		msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
-		process_alert_core(buffer, modal);
-	}
-}
-
-// The only difference between this routine and the previous is the fact that
-// for this routine, the modal parameter is always false. Sadly, for the message
-// handled by this routine, there is no "Modal" parameter on the message, and
-// there's no API to tell if a message has the given parameter or not.
-// So we can't handle the messages with the same handler.
-void process_alert_message(LLMessageSystem *msgsystem, void **user_data)
-{
-	// make sure the cursor is back to the usual default since the
-	// alert is probably due to some kind of error.
-	gViewerWindow->getWindow()->resetBusyCount();
-		
-	if (!attempt_standard_notification(msgsystem))
-	{
-		BOOL modal = FALSE;
-		std::string buffer;
-		msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
-		process_alert_core(buffer, modal);
-	}
-}
-
-void process_alert_core(const std::string& message, BOOL modal)
-{
-	// HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml
-	if ( message == "You died and have been teleported to your home location")
-	{
-		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
-	}
-	else if( message == "Home position set." )
-	{
-		// save the home location image to disk
-		std::string snap_filename = gDirUtilp->getLindenUserDir();
-		snap_filename += gDirUtilp->getDirDelimiter();
-		snap_filename += SCREEN_HOME_FILENAME;
-		gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);
-	}
-
-	const std::string ALERT_PREFIX("ALERT: ");
-	const std::string NOTIFY_PREFIX("NOTIFY: ");
-	if (message.find(ALERT_PREFIX) == 0)
-	{
-		// Allow the server to spawn a named alert so that server alerts can be
-		// translated out of English.
-		std::string alert_name(message.substr(ALERT_PREFIX.length()));
-		LLNotificationsUtil::add(alert_name);
-	}
-	else if (message.find(NOTIFY_PREFIX) == 0)
-	{
-		// Allow the server to spawn a named notification so that server notifications can be
-		// translated out of English.
-		std::string notify_name(message.substr(NOTIFY_PREFIX.length()));
-		LLNotificationsUtil::add(notify_name);
-	}
-	else if (message[0] == '/')
-	{
-		// System message is important, show in upper-right box not tip
-		std::string text(message.substr(1));
-		LLSD args;
-		if (text.substr(0,17) == "RESTART_X_MINUTES")
-		{
-			S32 mins = 0;
-			LLStringUtil::convertToS32(text.substr(18), mins);
-			args["MINUTES"] = llformat("%d",mins);
-			LLNotificationsUtil::add("RegionRestartMinutes", args);
-		}
-		else if (text.substr(0,17) == "RESTART_X_SECONDS")
-		{
-			S32 secs = 0;
-			LLStringUtil::convertToS32(text.substr(18), secs);
-			args["SECONDS"] = llformat("%d",secs);
-			LLNotificationsUtil::add("RegionRestartSeconds", args);
-		}
-		else
-		{
-			std::string new_msg =LLNotifications::instance().getGlobalString(text);
-			args["MESSAGE"] = new_msg;
-			LLNotificationsUtil::add("SystemMessage", args);
-		}
-	}
-	else if (modal)
-	{
-		LLSD args;
-		std::string new_msg =LLNotifications::instance().getGlobalString(message);
-		args["ERROR_MESSAGE"] = new_msg;
-		LLNotificationsUtil::add("ErrorMessage", args);
-	}
-	else
-	{
-		LLSD args;
-		std::string new_msg =LLNotifications::instance().getGlobalString(message);
-		args["MESSAGE"] = new_msg;
-		LLNotificationsUtil::add("SystemMessageTip", args);
-	}
-}
-
-mean_collision_list_t				gMeanCollisionList;
-time_t								gLastDisplayedTime = 0;
-
-void handle_show_mean_events(void *)
-{
-	if (gNoRender)
-	{
-		return;
-	}
-	LLFloaterReg::showInstance("bumps");
-	//LLFloaterBump::showInstance();
-}
-
-void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_group)
-{
-	if (gNoRender)
-	{
-		return;
-	}
-
-	static const U32 max_collision_list_size = 20;
-	if (gMeanCollisionList.size() > max_collision_list_size)
-	{
-		mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
-		for (U32 i=0; i<max_collision_list_size; i++) iter++;
-		for_each(iter, gMeanCollisionList.end(), DeletePointer());
-		gMeanCollisionList.erase(iter, gMeanCollisionList.end());
-	}
-
-	for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
-		 iter != gMeanCollisionList.end(); ++iter)
-	{
-		LLMeanCollisionData *mcd = *iter;
-		if (mcd->mPerp == id)
-		{
-			mcd->mFullName = full_name;
-		}
-	}
-}
-
-void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **user_data)
-{
-	if (gAgent.inPrelude())
-	{
-		// In prelude, bumping is OK.  This dialog is rather confusing to 
-		// newbies, so we don't show it.  Drop the packet on the floor.
-		return;
-	}
-
-	// make sure the cursor is back to the usual default since the
-	// alert is probably due to some kind of error.
-	gViewerWindow->getWindow()->resetBusyCount();
-
-	LLUUID perp;
-	U32	   time;
-	U8	   u8type;
-	EMeanCollisionType	   type;
-	F32    mag;
-
-	S32 i, num = msgsystem->getNumberOfBlocks(_PREHASH_MeanCollision);
-
-	for (i = 0; i < num; i++)
-	{
-		msgsystem->getUUIDFast(_PREHASH_MeanCollision, _PREHASH_Perp, perp);
-		msgsystem->getU32Fast(_PREHASH_MeanCollision, _PREHASH_Time, time);
-		msgsystem->getF32Fast(_PREHASH_MeanCollision, _PREHASH_Mag, mag);
-		msgsystem->getU8Fast(_PREHASH_MeanCollision, _PREHASH_Type, u8type);
-
-		type = (EMeanCollisionType)u8type;
-
-		BOOL b_found = FALSE;
-
-		for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
-			 iter != gMeanCollisionList.end(); ++iter)
-		{
-			LLMeanCollisionData *mcd = *iter;
-			if ((mcd->mPerp == perp) && (mcd->mType == type))
-			{
-				mcd->mTime = time;
-				mcd->mMag = mag;
-				b_found = TRUE;
-				break;
-			}
-		}
-
-		if (!b_found)
-		{
-			LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag);
-			gMeanCollisionList.push_front(mcd);
-			gCacheName->get(perp, false, boost::bind(&mean_name_callback, _1, _2, _3));
-		}
-	}
-}
-
-void process_frozen_message(LLMessageSystem *msgsystem, void **user_data)
-{
-	// make sure the cursor is back to the usual default since the
-	// alert is probably due to some kind of error.
-	gViewerWindow->getWindow()->resetBusyCount();
-	BOOL b_frozen;
-	
-	msgsystem->getBOOL("FrozenData", "Data", b_frozen);
-
-	// TODO: make being frozen change view
-	if (b_frozen)
-	{
-	}
-	else
-	{
-	}
-}
-
-// do some extra stuff once we get our economy data
-void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
-{
-	LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance());
-
-	S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
-
-	LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL;
-
-	gMenuHolder->getChild<LLUICtrl>("Upload Image")->setLabelArg("[COST]", llformat("%d", upload_cost));
-	gMenuHolder->getChild<LLUICtrl>("Upload Sound")->setLabelArg("[COST]", llformat("%d", upload_cost));
-	gMenuHolder->getChild<LLUICtrl>("Upload Animation")->setLabelArg("[COST]", llformat("%d", upload_cost));
-	gMenuHolder->getChild<LLUICtrl>("Bulk Upload")->setLabelArg("[COST]", llformat("%d", upload_cost));
-}
-
-void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted)
-{
-	// only continue if at least some permissions were requested
-	if (orig_questions)
-	{
-		// check to see if the person we are asking
-
-		// "'[OBJECTNAME]', an object owned by '[OWNERNAME]', 
-		// located in [REGIONNAME] at [REGIONPOS], 
-		// has been <granted|denied> permission to: [PERMISSIONS]."
-
-		LLUIString notice(LLTrans::getString(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied"));
-
-		// always include the object name and owner name 
-		notice.setArg("[OBJECTNAME]", notification["payload"]["object_name"].asString());
-		notice.setArg("[OWNERNAME]", notification["payload"]["owner_name"].asString());
-
-		// try to lookup viewerobject that corresponds to the object that
-		// requested permissions (here, taskid->requesting object id)
-		BOOL foundpos = FALSE;
-		LLViewerObject* viewobj = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
-		if (viewobj)
-		{
-			// found the viewerobject, get it's position in its region
-			LLVector3 objpos(viewobj->getPosition());
-			
-			// try to lookup the name of the region the object is in
-			LLViewerRegion* viewregion = viewobj->getRegion();
-			if (viewregion)
-			{
-				// got the region, so include the region and 3d coordinates of the object
-				notice.setArg("[REGIONNAME]", viewregion->getName());				
-				std::string formatpos = llformat("%.1f, %.1f,%.1f", objpos[VX], objpos[VY], objpos[VZ]);
-				notice.setArg("[REGIONPOS]", formatpos);
-
-				foundpos = TRUE;
-			}
-		}
-
-		if (!foundpos)
-		{
-			// unable to determine location of the object
-			notice.setArg("[REGIONNAME]", "(unknown region)");
-			notice.setArg("[REGIONPOS]", "(unknown position)");
-		}
-
-		// check each permission that was requested, and list each 
-		// permission that has been flagged as a caution permission
-		BOOL caution = FALSE;
-		S32 count = 0;
-		std::string perms;
-		for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
-		{
-			if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && SCRIPT_QUESTION_IS_CAUTION[i])
-			{
-				count++;
-				caution = TRUE;
-
-				// add a comma before the permission description if it is not the first permission
-				// added to the list or the last permission to check
-				if ((count > 1) && (i < SCRIPT_PERMISSION_EOF))
-				{
-					perms.append(", ");
-				}
-
-				perms.append(LLTrans::getString(SCRIPT_QUESTIONS[i]));
-			}
-		}
-
-		notice.setArg("[PERMISSIONS]", perms);
-
-		// log a chat message as long as at least one requested permission
-		// is a caution permission
-		if (caution)
-		{
-			LLChat chat(notice.getString());
-	//		LLFloaterChat::addChat(chat, FALSE, FALSE);
-		}
-	}
-}
-
-bool script_question_cb(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	LLMessageSystem *msg = gMessageSystem;
-	S32 orig = notification["payload"]["questions"].asInteger();
-	S32 new_questions = orig;
-
-	// check whether permissions were granted or denied
-	BOOL allowed = TRUE;
-	// the "yes/accept" button is the first button in the template, making it button 0
-	// if any other button was clicked, the permissions were denied
-	if (option != 0)
-	{
-		new_questions = 0;
-		allowed = FALSE;
-	}	
-
-	LLUUID task_id = notification["payload"]["task_id"].asUUID();
-	LLUUID item_id = notification["payload"]["item_id"].asUUID();
-
-	// reply with the permissions granted or denied
-	msg->newMessageFast(_PREHASH_ScriptAnswerYes);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_Data);
-	msg->addUUIDFast(_PREHASH_TaskID, task_id);
-	msg->addUUIDFast(_PREHASH_ItemID, item_id);
-	msg->addS32Fast(_PREHASH_Questions, new_questions);
-	msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
-
-	// only log a chat message if caution prompts are enabled
-	if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
-	{
-		// log a chat message, if appropriate
-		notify_cautioned_script_question(notification, response, orig, allowed);
-	}
-
-	if ( response["Mute"] ) // mute
-	{
-		LLMuteList::getInstance()->add(LLMute(item_id, notification["payload"]["object_name"].asString(), LLMute::OBJECT));
-
-		// purge the message queue of any previously queued requests from the same source. DEV-4879
-		class OfferMatcher : public LLNotificationsUI::LLScreenChannel::Matcher
-		{
-		public:
-			OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
-			bool matches(const LLNotificationPtr notification) const
-			{
-				if (notification->getName() == "ScriptQuestionCaution"
-					|| notification->getName() == "ScriptQuestion")
-				{
-					return (notification->getPayload()["item_id"].asUUID() == blocked_id);
-				}
-				return false;
-			}
-		private:
-			const LLUUID& blocked_id;
-		};
-
-		LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID(
-				gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(item_id));
-	}
-
-	if (response["Details"])
-	{
-		// respawn notification...
-		LLNotificationsUtil::add(notification["name"], notification["substitutions"], notification["payload"]);
-
-		// ...with description on top
-		LLNotificationsUtil::add("DebitPermissionDetails");
-	}
-	return false;
-}
-static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb);
-static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb);
-
-void process_script_question(LLMessageSystem *msg, void **user_data)
-{
-	// *TODO: Translate owner name -> [FIRST] [LAST]
-
-	LLHost sender = msg->getSender();
-
-	LLUUID taskid;
-	LLUUID itemid;
-	S32		questions;
-	std::string object_name;
-	std::string owner_name;
-
-	// taskid -> object key of object requesting permissions
-	msg->getUUIDFast(_PREHASH_Data, _PREHASH_TaskID, taskid );
-	// itemid -> script asset key of script requesting permissions
-	msg->getUUIDFast(_PREHASH_Data, _PREHASH_ItemID, itemid );
-	msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectName, object_name);
-	msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectOwner, owner_name);
-	msg->getS32Fast(_PREHASH_Data, _PREHASH_Questions, questions );
-
-	// Special case. If the objects are owned by this agent, throttle per-object instead
-	// of per-owner. It's common for residents to reset a ton of scripts that re-request
-	// permissions, as with tier boxes. UUIDs can't be valid agent names and vice-versa,
-	// so we'll reuse the same namespace for both throttle types.
-	std::string throttle_name = owner_name;
-	std::string self_name;
-	LLAgentUI::buildFullname( self_name );
-	if( owner_name == self_name )
-	{
-		throttle_name = taskid.getString();
-	}
-	
-	// don't display permission requests if this object is muted
-	if (LLMuteList::getInstance()->isMuted(taskid)) return;
-	
-	// throttle excessive requests from any specific user's scripts
-	typedef LLKeyThrottle<std::string> LLStringThrottle;
-	static LLStringThrottle question_throttle( LLREQUEST_PERMISSION_THROTTLE_LIMIT, LLREQUEST_PERMISSION_THROTTLE_INTERVAL );
-
-	switch (question_throttle.noteAction(throttle_name))
-	{
-		case LLStringThrottle::THROTTLE_NEWLY_BLOCKED:
-			LL_INFOS("Messaging") << "process_script_question throttled"
-					<< " owner_name:" << owner_name
-					<< LL_ENDL;
-			// Fall through
-
-		case LLStringThrottle::THROTTLE_BLOCKED:
-			// Escape altogether until we recover
-			return;
-
-		case LLStringThrottle::THROTTLE_OK:
-			break;
-	}
-
-	std::string script_question;
-	if (questions)
-	{
-		BOOL caution = FALSE;
-		S32 count = 0;
-		LLSD args;
-		args["OBJECTNAME"] = object_name;
-		args["NAME"] = LLCacheName::cleanFullName(owner_name);
-
-		// check the received permission flags against each permission
-		for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
-		{
-			if (questions & LSCRIPTRunTimePermissionBits[i])
-			{
-				count++;
-				script_question += "    " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n";
-
-				// check whether permission question should cause special caution dialog
-				caution |= (SCRIPT_QUESTION_IS_CAUTION[i]);
-			}
-		}
-		args["QUESTIONS"] = script_question;
-
-		LLSD payload;
-		payload["task_id"] = taskid;
-		payload["item_id"] = itemid;
-		payload["sender"] = sender.getIPandPort();
-		payload["questions"] = questions;
-		payload["object_name"] = object_name;
-		payload["owner_name"] = owner_name;
-
-		// check whether cautions are even enabled or not
-		if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
-		{
-			// display the caution permissions prompt
-			LLNotificationsUtil::add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload);
-		}
-		else
-		{
-			// fall back to default behavior if cautions are entirely disabled
-			LLNotificationsUtil::add("ScriptQuestion", args, payload);
-		}
-
-	}
-}
-
-
-void process_derez_container(LLMessageSystem *msg, void**)
-{
-	LL_WARNS("Messaging") << "call to deprecated process_derez_container" << LL_ENDL;
-}
-
-void container_inventory_arrived(LLViewerObject* object,
-								 LLInventoryObject::object_list_t* inventory,
-								 S32 serial_num,
-								 void* data)
-{
-	LL_DEBUGS("Messaging") << "container_inventory_arrived()" << LL_ENDL;
-	if( gAgentCamera.cameraMouselook() )
-	{
-		gAgentCamera.changeCameraToDefault();
-	}
-
-	LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
-
-	if (inventory->size() > 2)
-	{
-		// create a new inventory category to put this in
-		LLUUID cat_id;
-		cat_id = gInventory.createNewCategory(gInventory.getRootFolderID(),
-											  LLFolderType::FT_NONE,
-											  LLTrans::getString("AcquiredItems"));
-
-		LLInventoryObject::object_list_t::const_iterator it = inventory->begin();
-		LLInventoryObject::object_list_t::const_iterator end = inventory->end();
-		for ( ; it != end; ++it)
-		{
-			if ((*it)->getType() != LLAssetType::AT_CATEGORY)
-			{
-				LLInventoryObject* obj = (LLInventoryObject*)(*it);
-				LLInventoryItem* item = (LLInventoryItem*)(obj);
-				LLUUID item_id;
-				item_id.generate();
-				time_t creation_date_utc = time_corrected();
-				LLPointer<LLViewerInventoryItem> new_item
-					= new LLViewerInventoryItem(item_id,
-												cat_id,
-												item->getPermissions(),
-												item->getAssetUUID(),
-												item->getType(),
-												item->getInventoryType(),
-												item->getName(),
-												item->getDescription(),
-												LLSaleInfo::DEFAULT,
-												item->getFlags(),
-												creation_date_utc);
-				new_item->updateServer(TRUE);
-				gInventory.updateItem(new_item);
-			}
-		}
-		gInventory.notifyObservers();
-		if(active_panel)
-		{
-			active_panel->setSelection(cat_id, TAKE_FOCUS_NO);
-		}
-	}
-	else if (inventory->size() == 2)
-	{
-		// we're going to get one fake root category as well as the
-		// one actual object
-		LLInventoryObject::object_list_t::iterator it = inventory->begin();
-
-		if ((*it)->getType() == LLAssetType::AT_CATEGORY)
-		{
-			++it;
-		}
-
-		LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
-		const LLUUID category = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(item->getType()));
-
-		LLUUID item_id;
-		item_id.generate();
-		time_t creation_date_utc = time_corrected();
-		LLPointer<LLViewerInventoryItem> new_item
-			= new LLViewerInventoryItem(item_id, category,
-										item->getPermissions(),
-										item->getAssetUUID(),
-										item->getType(),
-										item->getInventoryType(),
-										item->getName(),
-										item->getDescription(),
-										LLSaleInfo::DEFAULT,
-										item->getFlags(),
-										creation_date_utc);
-		new_item->updateServer(TRUE);
-		gInventory.updateItem(new_item);
-		gInventory.notifyObservers();
-		if(active_panel)
-		{
-			active_panel->setSelection(item_id, TAKE_FOCUS_NO);
-		}
-	}
-
-	// we've got the inventory, now delete this object if this was a take
-	BOOL delete_object = (BOOL)(intptr_t)data;
-	LLViewerRegion *region = gAgent.getRegion();
-	if (delete_object && region)
-	{
-		gMessageSystem->newMessageFast(_PREHASH_ObjectDelete);
-		gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		const U8 NO_FORCE = 0;
-		gMessageSystem->addU8Fast(_PREHASH_Force, NO_FORCE);
-		gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-		gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
-		gMessageSystem->sendReliable(region->getHost());
-	}
-}
-
-// method to format the time.
-std::string formatted_time(const time_t& the_time)
-{
-	std::string dateStr = "["+LLTrans::getString("LTimeWeek")+"] ["
-						+LLTrans::getString("LTimeMonth")+"] ["
-						+LLTrans::getString("LTimeDay")+"] ["
-						+LLTrans::getString("LTimeHour")+"]:["
-						+LLTrans::getString("LTimeMin")+"]:["
-						+LLTrans::getString("LTimeSec")+"] ["
-						+LLTrans::getString("LTimeYear")+"]";
-
-	LLSD substitution;
-	substitution["datetime"] = (S32) the_time;
-	LLStringUtil::format (dateStr, substitution);
-	return dateStr;
-}
-
-
-void process_teleport_failed(LLMessageSystem *msg, void**)
-{
-	std::string reason;
-	std::string big_reason;
-	LLSD args;
-
-	// if we have additional alert data
-	if (msg->has(_PREHASH_AlertInfo) && msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0)
-	{
-		// Get the message ID
-		msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, reason);
-		big_reason = LLAgent::sTeleportErrorMessages[reason];
-		if ( big_reason.size() > 0 )
-		{	// Substitute verbose reason from the local map
-			args["REASON"] = big_reason;
-		}
-		else
-		{	// Nothing found in the map - use what the server returned in the original message block
-			msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
-			args["REASON"] = reason;
-		}
-
-		LLSD llsd_block;
-		std::string llsd_raw;
-		msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsd_raw);
-		if (llsd_raw.length())
-		{
-			std::istringstream llsd_data(llsd_raw);
-			if (!LLSDSerialize::deserialize(llsd_block, llsd_data, llsd_raw.length()))
-			{
-				llwarns << "process_teleport_failed: Attempted to read alert parameter data into LLSD but failed:" << llsd_raw << llendl;
-			}
-			else
-			{
-				// change notification name in this special case
-				if (handle_special_notification("RegionEntryAccessBlocked", llsd_block))
-				{
-					if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
-					{
-						gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
-					}
-					return;
-				}
-			}
-		}
-
-	}
-	else
-	{
-		msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
-
-		big_reason = LLAgent::sTeleportErrorMessages[reason];
-		if ( big_reason.size() > 0 )
-		{	// Substitute verbose reason from the local map
-			args["REASON"] = big_reason;
-		}
-		else
-		{	// Nothing found in the map - use what the server returned
-			args["REASON"] = reason;
-		}
-	}
-
-	LLNotificationsUtil::add("CouldNotTeleportReason", args);
-
-	// Let the interested parties know that teleport failed.
-	LLViewerParcelMgr::getInstance()->onTeleportFailed();
-
-	if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
-	{
-		gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
-	}
-}
-
-void process_teleport_local(LLMessageSystem *msg,void**)
-{
-	LLUUID agent_id;
-	msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
-	if (agent_id != gAgent.getID())
-	{
-		LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
-		return;
-	}
-
-	U32 location_id;
-	LLVector3 pos, look_at;
-	U32 teleport_flags;
-	msg->getU32Fast(_PREHASH_Info, _PREHASH_LocationID, location_id);
-	msg->getVector3Fast(_PREHASH_Info, _PREHASH_Position, pos);
-	msg->getVector3Fast(_PREHASH_Info, _PREHASH_LookAt, look_at);
-	msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
-
-	if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
-	{
-		if( gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL )
-		{
-			// To prevent TeleportStart messages re-activating the progress screen right
-			// after tp, keep the teleport state and let progress screen clear it after a short delay
-			// (progress screen is active but not visible)  *TODO: remove when SVC-5290 is fixed
-			gTeleportDisplayTimer.reset();
-			gTeleportDisplay = TRUE;
-		}
-		else
-		{
-			gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
-		}
-	}
-
-	// Sim tells us whether the new position is off the ground
-	if (teleport_flags & TELEPORT_FLAGS_IS_FLYING)
-	{
-		gAgent.setFlying(TRUE);
-	}
-	else
-	{
-		gAgent.setFlying(FALSE);
-	}
-
-	gAgent.setPositionAgent(pos);
-	gAgentCamera.slamLookAt(look_at);
-
-	if ( !(gAgent.getTeleportKeepsLookAt() && LLViewerJoystick::getInstance()->getOverrideCamera()) )
-	{
-		gAgentCamera.resetView(TRUE, TRUE);
-	}
-
-	// send camera update to new region
-	gAgentCamera.updateCamera();
-
-	send_agent_update(TRUE, TRUE);
-
-	// Let the interested parties know we've teleported.
-	// Vadim *HACK: Agent position seems to get reset (to render position?)
-	//              on each frame, so we have to pass the new position manually.
-	LLViewerParcelMgr::getInstance()->onTeleportFinished(true, gAgent.getPosGlobalFromAgent(pos));
-}
-
-void send_simple_im(const LLUUID& to_id,
-					const std::string& message,
-					EInstantMessage dialog,
-					const LLUUID& id)
-{
-	std::string my_name;
-	LLAgentUI::buildFullname(my_name);
-	send_improved_im(to_id,
-					 my_name,
-					 message,
-					 IM_ONLINE,
-					 dialog,
-					 id,
-					 NO_TIMESTAMP,
-					 (U8*)EMPTY_BINARY_BUCKET,
-					 EMPTY_BINARY_BUCKET_SIZE);
-}
-
-void send_group_notice(const LLUUID& group_id,
-					   const std::string& subject,
-					   const std::string& message,
-					   const LLInventoryItem* item)
-{
-	// Put this notice into an instant message form.
-	// This will mean converting the item to a binary bucket,
-	// and the subject/message into a single field.
-	std::string my_name;
-	LLAgentUI::buildFullname(my_name);
-
-	// Combine subject + message into a single string.
-	std::ostringstream subject_and_message;
-	// TODO: turn all existing |'s into ||'s in subject and message.
-	subject_and_message << subject << "|" << message;
-
-	// Create an empty binary bucket.
-	U8 bin_bucket[MAX_INVENTORY_BUFFER_SIZE];
-	U8* bucket_to_send = bin_bucket;
-	bin_bucket[0] = '\0';
-	S32 bin_bucket_size = EMPTY_BINARY_BUCKET_SIZE;
-	// If there is an item being sent, pack it into the binary bucket.
-	if (item)
-	{
-		LLSD item_def;
-		item_def["item_id"] = item->getUUID();
-		item_def["owner_id"] = item->getPermissions().getOwner();
-		std::ostringstream ostr;
-		LLSDSerialize::serialize(item_def, ostr, LLSDSerialize::LLSD_XML);
-		bin_bucket_size = ostr.str().copy(
-			(char*)bin_bucket, ostr.str().size());
-		bin_bucket[bin_bucket_size] = '\0';
-	}
-	else
-	{
-		bucket_to_send = (U8*) EMPTY_BINARY_BUCKET;
-	}
-   
-
-	send_improved_im(
-			group_id,
-			my_name,
-			subject_and_message.str(),
-			IM_ONLINE,
-			IM_GROUP_NOTICE,
-			LLUUID::null,
-			NO_TIMESTAMP,
-			bucket_to_send,
-			bin_bucket_size);
-}
-
-bool handle_lure_callback(const LLSD& notification, const LLSD& response)
-{
-	std::string text = response["message"].asString();
-	LLSLURL slurl;
-	LLAgentUI::buildSLURL(slurl);
-	text.append("\r\n").append(slurl.getSLURLString());
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
-	if(0 == option)
-	{
-		LLMessageSystem* msg = gMessageSystem;
-		msg->newMessageFast(_PREHASH_StartLure);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->nextBlockFast(_PREHASH_Info);
-		msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
-		msg->addStringFast(_PREHASH_Message, text);
-		for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
-			it != notification["payload"]["ids"].endArray();
-			++it)
-		{
-			LLUUID target_id = it->asUUID();
-
-			msg->nextBlockFast(_PREHASH_TargetData);
-			msg->addUUIDFast(_PREHASH_TargetID, target_id);
-
-			// Record the offer.
-			{
-				std::string target_name;
-				gCacheName->getFullName(target_id, target_name);  // for im log filenames
-				LLSD args;
-				args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();;
-	
-				LLSD payload;
-				
-				//*TODO please rewrite all keys to the same case, lower or upper
-				payload["from_id"] = target_id;
-				payload["SUPPRESS_TOAST"] = true;
-				LLNotificationsUtil::add("TeleportOfferSent", args, payload);
-
-				// Add the recepient to the recent people list.
-				LLRecentPeople::instance().add(target_id);
-			}
-		}
-		gAgent.sendReliableMessage();
-	}
-
-	return false;
-}
-
-void handle_lure(const LLUUID& invitee)
-{
-	LLDynamicArray<LLUUID> ids;
-	ids.push_back(invitee);
-	handle_lure(ids);
-}
-
-// Prompt for a message to the invited user.
-void handle_lure(const uuid_vec_t& ids)
-{
-	if (ids.empty()) return;
-
-	if (!gAgent.getRegion()) return;
-
-	LLSD edit_args;
-	edit_args["REGION"] = gAgent.getRegion()->getName();
-
-	LLSD payload;
-	for (LLDynamicArray<LLUUID>::const_iterator it = ids.begin();
-		it != ids.end();
-		++it)
-	{
-		payload["ids"].append(*it);
-	}
-	if (gAgent.isGodlike())
-	{
-		LLNotificationsUtil::add("OfferTeleportFromGod", edit_args, payload, handle_lure_callback);
-	}
-	else
-	{
-		LLNotificationsUtil::add("OfferTeleport", edit_args, payload, handle_lure_callback);
-	}
-}
-
-
-void send_improved_im(const LLUUID& to_id,
-							const std::string& name,
-							const std::string& message,
-							U8 offline,
-							EInstantMessage dialog,
-							const LLUUID& id,
-							U32 timestamp, 
-							const U8* binary_bucket,
-							S32 binary_bucket_size)
-{
-	pack_instant_message(
-		gMessageSystem,
-		gAgent.getID(),
-		FALSE,
-		gAgent.getSessionID(),
-		to_id,
-		name,
-		message,
-		offline,
-		dialog,
-		id,
-		0,
-		LLUUID::null,
-		gAgent.getPositionAgent(),
-		timestamp,
-		binary_bucket,
-		binary_bucket_size);
-	gAgent.sendReliableMessage();
-}
-
-
-void send_places_query(const LLUUID& query_id,
-					   const LLUUID& trans_id,
-					   const std::string& query_text,
-					   U32 query_flags,
-					   S32 category,
-					   const std::string& sim_name)
-{
-	LLMessageSystem* msg = gMessageSystem;
-
-	msg->newMessage("PlacesQuery");
-	msg->nextBlock("AgentData");
-	msg->addUUID("AgentID", gAgent.getID());
-	msg->addUUID("SessionID", gAgent.getSessionID());
-	msg->addUUID("QueryID", query_id);
-	msg->nextBlock("TransactionData");
-	msg->addUUID("TransactionID", trans_id);
-	msg->nextBlock("QueryData");
-	msg->addString("QueryText", query_text);
-	msg->addU32("QueryFlags", query_flags);
-	msg->addS8("Category", (S8)category);
-	msg->addString("SimName", sim_name);
-	gAgent.sendReliableMessage();
-}
-
-
-void process_user_info_reply(LLMessageSystem* msg, void**)
-{
-	LLUUID agent_id;
-	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
-	if(agent_id != gAgent.getID())
-	{
-		LL_WARNS("Messaging") << "process_user_info_reply - "
-				<< "wrong agent id." << LL_ENDL;
-	}
-	
-	BOOL im_via_email;
-	msg->getBOOLFast(_PREHASH_UserData, _PREHASH_IMViaEMail, im_via_email);
-	std::string email;
-	msg->getStringFast(_PREHASH_UserData, _PREHASH_EMail, email);
-	std::string dir_visibility;
-	msg->getString( "UserData", "DirectoryVisibility", dir_visibility);
-
-	LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email);
-	LLFloaterPostcard::updateUserInfo(email);
-}
-
-
-//---------------------------------------------------------------------------
-// Script Dialog
-//---------------------------------------------------------------------------
-
-const S32 SCRIPT_DIALOG_MAX_BUTTONS = 12;
-const S32 SCRIPT_DIALOG_BUTTON_STR_SIZE = 24;
-const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512;
-const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n";
-
-bool callback_script_dialog(const LLSD& notification, const LLSD& response)
-{
-	LLNotificationForm form(notification["form"]);
-
-	std::string rtn_text;
-	S32 button_idx;
-	button_idx = LLNotification::getSelectedOption(notification, response);
-	if (response[TEXTBOX_MAGIC_TOKEN].isDefined())
-	{
-		if (response[TEXTBOX_MAGIC_TOKEN].isString())
-			rtn_text = response[TEXTBOX_MAGIC_TOKEN].asString();
-		else
-			rtn_text.clear(); // bool marks empty string
-	}
-	else
-	{
-		rtn_text = LLNotification::getSelectedOptionName(response);
-	}
-
-	// Didn't click "Ignore"
-	if (button_idx != -1)
-	{
-		LLMessageSystem* msg = gMessageSystem;
-		msg->newMessage("ScriptDialogReply");
-		msg->nextBlock("AgentData");
-		msg->addUUID("AgentID", gAgent.getID());
-		msg->addUUID("SessionID", gAgent.getSessionID());
-		msg->nextBlock("Data");
-		msg->addUUID("ObjectID", notification["payload"]["object_id"].asUUID());
-		msg->addS32("ChatChannel", notification["payload"]["chat_channel"].asInteger());
-		msg->addS32("ButtonIndex", button_idx);
-		msg->addString("ButtonLabel", rtn_text);
-		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
-	}
-
-	return false;
-}
-static LLNotificationFunctorRegistration callback_script_dialog_reg_1("ScriptDialog", callback_script_dialog);
-static LLNotificationFunctorRegistration callback_script_dialog_reg_2("ScriptDialogGroup", callback_script_dialog);
-
-void process_script_dialog(LLMessageSystem* msg, void**)
-{
-	S32 i;
-	LLSD payload;
-
-	LLUUID object_id;
-	msg->getUUID("Data", "ObjectID", object_id);
-
-	if (LLMuteList::getInstance()->isMuted(object_id))
-	{
-		return;
-	}
-
-	std::string message; 
-	std::string first_name;
-	std::string last_name;
-	std::string title;
-
-	S32 chat_channel;
-	msg->getString("Data", "FirstName", first_name);
-	msg->getString("Data", "LastName", last_name);
-	msg->getString("Data", "ObjectName", title);
-	msg->getString("Data", "Message", message);
-	msg->getS32("Data", "ChatChannel", chat_channel);
-
-		// unused for now
-	LLUUID image_id;
-	msg->getUUID("Data", "ImageID", image_id);
-
-	payload["sender"] = msg->getSender().getIPandPort();
-	payload["object_id"] = object_id;
-	payload["chat_channel"] = chat_channel;
-
-	// build up custom form
-	S32 button_count = msg->getNumberOfBlocks("Buttons");
-	if (button_count > SCRIPT_DIALOG_MAX_BUTTONS)
-	{
-		llwarns << "Too many script dialog buttons - omitting some" << llendl;
-		button_count = SCRIPT_DIALOG_MAX_BUTTONS;
-	}
-
-	LLNotificationForm form;
-	for (i = 0; i < button_count; i++)
-	{
-		std::string tdesc;
-		msg->getString("Buttons", "ButtonLabel", tdesc, i);
-		form.addElement("button", std::string(tdesc));
-	}
-
-	LLSD args;
-	args["TITLE"] = title;
-	args["MESSAGE"] = message;
-	LLNotificationPtr notification;
-	if (!first_name.empty())
-	{
-		args["NAME"] = LLCacheName::buildFullName(first_name, last_name);
-		notification = LLNotifications::instance().add(
-			LLNotification::Params("ScriptDialog").substitutions(args).payload(payload).form_elements(form.asLLSD()));
-	}
-	else
-	{
-		args["GROUPNAME"] = last_name;
-		notification = LLNotifications::instance().add(
-			LLNotification::Params("ScriptDialogGroup").substitutions(args).payload(payload).form_elements(form.asLLSD()));
-	}
-}
-
-//---------------------------------------------------------------------------
-
-
-std::vector<LLSD> gLoadUrlList;
-
-bool callback_load_url(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
-	if (0 == option)
-	{
-		LLWeb::loadURL(notification["payload"]["url"].asString());
-	}
-
-	return false;
-}
-static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", callback_load_url);
-
-
-// We've got the name of the person who owns the object hurling the url.
-// Display confirmation dialog.
-void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool is_group)
-{
-	std::vector<LLSD>::iterator it;
-	for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); )
-	{
-		LLSD load_url_info = *it;
-		if (load_url_info["owner_id"].asUUID() == id)
-		{
-			it = gLoadUrlList.erase(it);
-
-			std::string owner_name;
-			if (is_group)
-			{
-				owner_name = full_name + LLTrans::getString("Group");
-			}
-			else
-			{
-				owner_name = full_name;
-			}
-
-			// For legacy name-only mutes.
-			if (LLMuteList::getInstance()->isMuted(LLUUID::null, owner_name))
-			{
-				continue;
-			}
-			LLSD args;
-			args["URL"] = load_url_info["url"].asString();
-			args["MESSAGE"] = load_url_info["message"].asString();;
-			args["OBJECTNAME"] = load_url_info["object_name"].asString();
-			args["NAME"] = owner_name;
-
-			LLNotificationsUtil::add("LoadWebPage", args, load_url_info);
-		}
-		else
-		{
-			++it;
-		}
-	}
-}
-
-void process_load_url(LLMessageSystem* msg, void**)
-{
-	LLUUID object_id;
-	LLUUID owner_id;
-	BOOL owner_is_group;
-	char object_name[256];		/* Flawfinder: ignore */
-	char message[256];		/* Flawfinder: ignore */
-	char url[256];		/* Flawfinder: ignore */
-
-	msg->getString("Data", "ObjectName", 256, object_name);
-	msg->getUUID(  "Data", "ObjectID", object_id);
-	msg->getUUID(  "Data", "OwnerID", owner_id);
-	msg->getBOOL(  "Data", "OwnerIsGroup", owner_is_group);
-	msg->getString("Data", "Message", 256, message);
-	msg->getString("Data", "URL", 256, url);
-
-	LLSD payload;
-	payload["object_id"] = object_id;
-	payload["owner_id"] = owner_id;
-	payload["owner_is_group"] = owner_is_group;
-	payload["object_name"] = object_name;
-	payload["message"] = message;
-	payload["url"] = url;
-
-	// URL is safety checked in load_url above
-
-	// Check if object or owner is muted
-	if (LLMuteList::getInstance()->isMuted(object_id, object_name) ||
-	    LLMuteList::getInstance()->isMuted(owner_id))
-	{
-		LL_INFOS("Messaging")<<"Ignoring load_url from muted object/owner."<<LL_ENDL;
-		return;
-	}
-
-	// Add to list of pending name lookups
-	gLoadUrlList.push_back(payload);
-
-	gCacheName->get(owner_id, owner_is_group,
-		boost::bind(&callback_load_url_name, _1, _2, _3));
-}
-
-
-void callback_download_complete(void** data, S32 result, LLExtStat ext_status)
-{
-	std::string* filepath = (std::string*)data;
-	LLSD args;
-	args["DOWNLOAD_PATH"] = *filepath;
-	LLNotificationsUtil::add("FinishedRawDownload", args);
-	delete filepath;
-}
-
-
-void process_initiate_download(LLMessageSystem* msg, void**)
-{
-	LLUUID agent_id;
-	msg->getUUID("AgentData", "AgentID", agent_id);
-	if (agent_id != gAgent.getID())
-	{
-		LL_WARNS("Messaging") << "Initiate download for wrong agent" << LL_ENDL;
-		return;
-	}
-
-	std::string sim_filename;
-	std::string viewer_filename;
-	msg->getString("FileData", "SimFilename", sim_filename);
-	msg->getString("FileData", "ViewerFilename", viewer_filename);
-
-	if (!gXferManager->validateFileForRequest(viewer_filename))
-	{
-		llwarns << "SECURITY: Unauthorized download to local file " << viewer_filename << llendl;
-		return;
-	}
-	gXferManager->requestFile(viewer_filename,
-		sim_filename,
-		LL_PATH_NONE,
-		msg->getSender(),
-		FALSE,	// don't delete remote
-		callback_download_complete,
-		(void**)new std::string(viewer_filename));
-}
-
-
-void process_script_teleport_request(LLMessageSystem* msg, void**)
-{
-	if (!gSavedSettings.getBOOL("ScriptsCanShowUI")) return;
-
-	std::string object_name;
-	std::string sim_name;
-	LLVector3 pos;
-	LLVector3 look_at;
-
-	msg->getString("Data", "ObjectName", object_name);
-	msg->getString("Data", "SimName", sim_name);
-	msg->getVector3("Data", "SimPosition", pos);
-	msg->getVector3("Data", "LookAt", look_at);
-
-	LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
-	if(instance)
-	{
-		instance->trackURL(
-						   sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]);
-		LLFloaterReg::showInstance("world_map", "center");
-	}
-	
-	// remove above two lines and replace with below line
-	// to re-enable parcel browser for llMapDestination()
-	// LLURLDispatcher::dispatch(LLSLURL::buildSLURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]), FALSE);
-	
-}
-
-void process_covenant_reply(LLMessageSystem* msg, void**)
-{
-	LLUUID covenant_id, estate_owner_id;
-	std::string estate_name;
-	U32 covenant_timestamp;
-	msg->getUUID("Data", "CovenantID", covenant_id);
-	msg->getU32("Data", "CovenantTimestamp", covenant_timestamp);
-	msg->getString("Data", "EstateName", estate_name);
-	msg->getUUID("Data", "EstateOwnerID", estate_owner_id);
-
-	LLPanelEstateCovenant::updateEstateName(estate_name);
-	LLPanelLandCovenant::updateEstateName(estate_name);
-	LLFloaterBuyLand::updateEstateName(estate_name);
-
-	std::string owner_name =
-		LLSLURL("agent", estate_owner_id, "inspect").getSLURLString();
-	LLPanelEstateCovenant::updateEstateOwnerName(owner_name);
-	LLPanelLandCovenant::updateEstateOwnerName(owner_name);
-	LLFloaterBuyLand::updateEstateOwnerName(owner_name);
-
-	LLPanelPlaceProfile* panel = LLSideTray::getInstance()->getPanel<LLPanelPlaceProfile>("panel_place_profile");
-	if (panel)
-	{
-		panel->updateEstateName(estate_name);
-		panel->updateEstateOwnerName(owner_name);
-	}
-
-	// standard message, not from system
-	std::string last_modified;
-	if (covenant_timestamp == 0)
-	{
-		last_modified = LLTrans::getString("covenant_last_modified")+LLTrans::getString("never_text");
-	}
-	else
-	{
-		last_modified = LLTrans::getString("covenant_last_modified")+"["
-						+LLTrans::getString("LTimeWeek")+"] ["
-						+LLTrans::getString("LTimeMonth")+"] ["
-						+LLTrans::getString("LTimeDay")+"] ["
-						+LLTrans::getString("LTimeHour")+"]:["
-						+LLTrans::getString("LTimeMin")+"]:["
-						+LLTrans::getString("LTimeSec")+"] ["
-						+LLTrans::getString("LTimeYear")+"]";
-		LLSD substitution;
-		substitution["datetime"] = (S32) covenant_timestamp;
-		LLStringUtil::format (last_modified, substitution);
-	}
-
-	LLPanelEstateCovenant::updateLastModified(last_modified);
-	LLPanelLandCovenant::updateLastModified(last_modified);
-	LLFloaterBuyLand::updateLastModified(last_modified);
-
-	// load the actual covenant asset data
-	const BOOL high_priority = TRUE;
-	if (covenant_id.notNull())
-	{
-		gAssetStorage->getEstateAsset(gAgent.getRegionHost(),
-									gAgent.getID(),
-									gAgent.getSessionID(),
-									covenant_id,
-                                    LLAssetType::AT_NOTECARD,
-									ET_Covenant,
-                                    onCovenantLoadComplete,
-									NULL,
-									high_priority);
-	}
-	else
-	{
-		std::string covenant_text;
-		if (estate_owner_id.isNull())
-		{
-			// mainland
-			covenant_text = LLTrans::getString("RegionNoCovenant");
-		}
-		else
-		{
-			covenant_text = LLTrans::getString("RegionNoCovenantOtherOwner");
-		}
-		LLPanelEstateCovenant::updateCovenantText(covenant_text, covenant_id);
-		LLPanelLandCovenant::updateCovenantText(covenant_text);
-		LLFloaterBuyLand::updateCovenantText(covenant_text, covenant_id);
-		if (panel)
-		{
-			panel->updateCovenantText(covenant_text);
-		}
-	}
-}
-
-void onCovenantLoadComplete(LLVFS *vfs,
-					const LLUUID& asset_uuid,
-					LLAssetType::EType type,
-					void* user_data, S32 status, LLExtStat ext_status)
-{
-	LL_DEBUGS("Messaging") << "onCovenantLoadComplete()" << LL_ENDL;
-	std::string covenant_text;
-	if(0 == status)
-	{
-		LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
-		
-		S32 file_length = file.getSize();
-		
-		std::vector<char> buffer(file_length+1);
-		file.read((U8*)&buffer[0], file_length);		
-		// put a EOS at the end
-		buffer[file_length] = '\0';
-		
-		if( (file_length > 19) && !strncmp( &buffer[0], "Linden text version", 19 ) )
-		{
-			LLViewerTextEditor::Params params;
-			params.name("temp");
-			params.max_text_length(file_length+1);
-			LLViewerTextEditor * editor = LLUICtrlFactory::create<LLViewerTextEditor> (params);
-			if( !editor->importBuffer( &buffer[0], file_length+1 ) )
-			{
-				LL_WARNS("Messaging") << "Problem importing estate covenant." << LL_ENDL;
-				covenant_text = "Problem importing estate covenant.";
-			}
-			else
-			{
-				// Version 0 (just text, doesn't include version number)
-				covenant_text = editor->getText();
-			}
-			delete editor;
-		}
-		else
-		{
-			LL_WARNS("Messaging") << "Problem importing estate covenant: Covenant file format error." << LL_ENDL;
-			covenant_text = "Problem importing estate covenant: Covenant file format error.";
-		}
-	}
-	else
-	{
-		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
-		
-		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
-		    LL_ERR_FILE_EMPTY == status)
-		{
-			covenant_text = "Estate covenant notecard is missing from database.";
-		}
-		else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
-		{
-			covenant_text = "Insufficient permissions to view estate covenant.";
-		}
-		else
-		{
-			covenant_text = "Unable to load estate covenant at this time.";
-		}
-		
-		LL_WARNS("Messaging") << "Problem loading notecard: " << status << LL_ENDL;
-	}
-	LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid);
-	LLPanelLandCovenant::updateCovenantText(covenant_text);
-	LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid);
-
-	LLPanelPlaceProfile* panel = LLSideTray::getInstance()->getPanel<LLPanelPlaceProfile>("panel_place_profile");
-	if (panel)
-	{
-		panel->updateCovenantText(covenant_text);
-	}
-}
-
-
-void process_feature_disabled_message(LLMessageSystem* msg, void**)
-{
-	// Handle Blacklisted feature simulator response...
-	LLUUID	agentID;
-	LLUUID	transactionID;
-	std::string	messageText;
-	msg->getStringFast(_PREHASH_FailureInfo,_PREHASH_ErrorMessage, messageText,0);
-	msg->getUUIDFast(_PREHASH_FailureInfo,_PREHASH_AgentID,agentID);
-	msg->getUUIDFast(_PREHASH_FailureInfo,_PREHASH_TransactionID,transactionID);
-	
-	LL_WARNS("Messaging") << "Blacklisted Feature Response:" << messageText << LL_ENDL;
-}
-
-// ------------------------------------------------------------
-// Message system exception callbacks
-// ------------------------------------------------------------
-
-void invalid_message_callback(LLMessageSystem* msg,
-								   void*,
-								   EMessageException exception)
-{
-    LLAppViewer::instance()->badNetworkHandler();
-}
-
-// Please do not add more message handlers here. This file is huge.
-// Put them in a file related to the functionality you are implementing.
-
-void LLOfferInfo::forceResponse(InventoryOfferResponse response)
-{
-	LLNotification::Params params("UserGiveItem");
-	params.functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2));
-	LLNotifications::instance().forceResponse(params, response);
-}
-
+/** 
+ * @file llviewermessage.cpp
+ * @brief Dumping ground for viewer-side message system callbacks.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llviewermessage.h"
+#include "boost/lexical_cast.hpp"
+
+// Linden libraries
+#include "llanimationstates.h"
+#include "llaudioengine.h" 
+#include "llavataractions.h"
+#include "llavatarnamecache.h"		// IDEVO HACK
+#include "lscript_byteformat.h"
+#include "lleconomy.h"
+#include "lleventtimer.h"
+#include "llfloaterreg.h"
+#include "llfollowcamparams.h"
+#include "llinventorydefines.h"
+#include "lllslconstants.h"
+#include "llregionhandle.h"
+#include "llsdserialize.h"
+#include "llteleportflags.h"
+#include "lltransactionflags.h"
+#include "llvfile.h"
+#include "llvfs.h"
+#include "llxfermanager.h"
+#include "mean_collision_data.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llcallingcard.h"
+#include "llbuycurrencyhtml.h"
+#include "llfirstuse.h"
+#include "llfloaterbuyland.h"
+#include "llfloaterland.h"
+#include "llfloaterregioninfo.h"
+#include "llfloaterlandholdings.h"
+#include "llfloaterpostcard.h"
+#include "llfloaterpreference.h"
+#include "llhudeffecttrail.h"
+#include "llhudmanager.h"
+#include "llinventoryfunctions.h"
+#include "llinventoryobserver.h"
+#include "llinventorypanel.h"
+#include "llnearbychat.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llpanelgrouplandmoney.h"
+#include "llrecentpeople.h"
+#include "llscriptfloater.h"
+#include "llselectmgr.h"
+#include "llsidetray.h"
+#include "llstartup.h"
+#include "llsky.h"
+#include "llslurl.h"
+#include "llstatenums.h"
+#include "llstatusbar.h"
+#include "llimview.h"
+#include "llspeakers.h"
+#include "lltrans.h"
+#include "lltranslate.h"
+#include "llviewerfoldertype.h"
+#include "llvoavatar.h"				// IDEVO HACK
+#include "lluri.h"
+#include "llviewergenericmessage.h"
+#include "llviewermenu.h"
+#include "llviewerjoystick.h"
+#include "llviewerobjectlist.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerstats.h"
+#include "llviewertexteditor.h"
+#include "llviewerthrottle.h"
+#include "llviewerwindow.h"
+#include "llvlmanager.h"
+#include "llvoavatarself.h"
+#include "llvotextbubble.h"
+#include "llworld.h"
+#include "pipeline.h"
+#include "llfloaterworldmap.h"
+#include "llviewerdisplay.h"
+#include "llkeythrottle.h"
+#include "llgroupactions.h"
+#include "llagentui.h"
+#include "llpanelblockedlist.h"
+#include "llpanelplaceprofile.h"
+
+#include <boost/algorithm/string/split.hpp> //
+#include <boost/regex.hpp>
+
+#include "llnotificationmanager.h" //
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+//
+// Constants
+//
+const F32 BIRD_AUDIBLE_RADIUS = 32.0f;
+const F32 SIT_DISTANCE_FROM_TARGET = 0.25f;
+static const F32 LOGOUT_REPLY_TIME = 3.f;	// Wait this long after LogoutReply before quitting.
+
+// Determine how quickly residents' scripts can issue question dialogs
+// Allow bursts of up to 5 dialogs in 10 seconds. 10*2=20 seconds recovery if throttle kicks in
+static const U32 LLREQUEST_PERMISSION_THROTTLE_LIMIT	= 5;     // requests
+static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL	= 10.0f; // seconds
+
+extern BOOL gDebugClicks;
+
+// function prototypes
+bool check_offer_throttle(const std::string& from_name, bool check_only);
+static void process_money_balance_reply_extended(LLMessageSystem* msg);
+
+//inventory offer throttle globals
+LLFrameTimer gThrottleTimer;
+const U32 OFFER_THROTTLE_MAX_COUNT=5; //number of items per time period
+const F32 OFFER_THROTTLE_TIME=10.f; //time period in seconds
+
+//script permissions
+const std::string SCRIPT_QUESTIONS[SCRIPT_PERMISSION_EOF] = 
+	{ 
+		"ScriptTakeMoney",
+		"ActOnControlInputs",
+		"RemapControlInputs",
+		"AnimateYourAvatar",
+		"AttachToYourAvatar",
+		"ReleaseOwnership",
+		"LinkAndDelink",
+		"AddAndRemoveJoints",
+		"ChangePermissions",
+		"TrackYourCamera",
+		"ControlYourCamera"
+	};
+
+const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] = 
+{
+	TRUE,	// ScriptTakeMoney,
+	FALSE,	// ActOnControlInputs
+	FALSE,	// RemapControlInputs
+	FALSE,	// AnimateYourAvatar
+	FALSE,	// AttachToYourAvatar
+	FALSE,	// ReleaseOwnership,
+	FALSE,	// LinkAndDelink,
+	FALSE,	// AddAndRemoveJoints
+	FALSE,	// ChangePermissions
+	FALSE,	// TrackYourCamera,
+	FALSE	// ControlYourCamera
+};
+
+bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	LLMessageSystem* msg = gMessageSystem;
+	const LLSD& payload = notification["payload"];
+
+	// add friend to recent people list
+	LLRecentPeople::instance().add(payload["from_id"]);
+
+	switch(option)
+	{
+	case 0:
+	{
+		// accept
+		LLAvatarTracker::formFriendship(payload["from_id"]);
+
+		const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+
+		// This will also trigger an onlinenotification if the user is online
+		msg->newMessageFast(_PREHASH_AcceptFriendship);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->nextBlockFast(_PREHASH_TransactionBlock);
+		msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
+		msg->nextBlockFast(_PREHASH_FolderData);
+		msg->addUUIDFast(_PREHASH_FolderID, fid);
+		msg->sendReliable(LLHost(payload["sender"].asString()));
+
+		LLSD payload = notification["payload"];
+		payload["SUPPRESS_TOAST"] = true;
+		LLNotificationsUtil::add("FriendshipAcceptedByMe",
+				notification["substitutions"], payload);
+		break;
+	}
+	case 1: // Decline
+	{
+		LLSD payload = notification["payload"];
+		payload["SUPPRESS_TOAST"] = true;
+		LLNotificationsUtil::add("FriendshipDeclinedByMe",
+				notification["substitutions"], payload);
+	}
+	// fall-through
+	case 2: // Send IM - decline and start IM session
+		{
+			// decline
+			// We no longer notify other viewers, but we DO still send
+			// the rejection to the simulator to delete the pending userop.
+			msg->newMessageFast(_PREHASH_DeclineFriendship);
+			msg->nextBlockFast(_PREHASH_AgentData);
+			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			msg->nextBlockFast(_PREHASH_TransactionBlock);
+			msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
+			msg->sendReliable(LLHost(payload["sender"].asString()));
+
+			// start IM session
+			if(2 == option)
+			{
+				LLAvatarActions::startIM(payload["from_id"].asUUID());
+			}
+	}
+	default:
+		// close button probably, possibly timed out
+		break;
+	}
+
+	return false;
+}
+static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback);
+static LLNotificationFunctorRegistration friendship_offer_callback_reg_nm("OfferFriendshipNoMessage", friendship_offer_callback);
+
+//const char BUSY_AUTO_RESPONSE[] =	"The Resident you messaged is in 'busy mode' which means they have "
+//									"requested not to be disturbed. Your message will still be shown in their IM "
+//									"panel for later viewing.";
+
+//
+// Functions
+//
+
+void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group,
+				S32 trx_type, const std::string& desc)
+{
+	if(0 == amount || !region) return;
+	amount = abs(amount);
+	LL_INFOS("Messaging") << "give_money(" << uuid << "," << amount << ")"<< LL_ENDL;
+	if(can_afford_transaction(amount))
+	{
+//		gStatusBar->debitBalance(amount);
+		LLMessageSystem* msg = gMessageSystem;
+		msg->newMessageFast(_PREHASH_MoneyTransferRequest);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+        msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->nextBlockFast(_PREHASH_MoneyData);
+		msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID() );
+		msg->addUUIDFast(_PREHASH_DestID, uuid);
+		msg->addU8Fast(_PREHASH_Flags, pack_transaction_flags(FALSE, is_group));
+		msg->addS32Fast(_PREHASH_Amount, amount);
+		msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY);
+		msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY);
+		msg->addS32Fast(_PREHASH_TransactionType, trx_type );
+		msg->addStringFast(_PREHASH_Description, desc);
+		msg->sendReliable(region->getHost());
+	}
+	else
+	{
+		LLStringUtil::format_map_t args;
+		args["AMOUNT"] = llformat("%d", amount);
+		LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("giving", args), amount );
+	}
+}
+
+void send_complete_agent_movement(const LLHost& sim_host)
+{
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_CompleteAgentMovement);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addU32Fast(_PREHASH_CircuitCode, msg->mOurCircuitCode);
+	msg->sendReliable(sim_host);
+}
+
+void process_logout_reply(LLMessageSystem* msg, void**)
+{
+	// The server has told us it's ok to quit.
+	LL_DEBUGS("Messaging") << "process_logout_reply" << LL_ENDL;
+
+	LLUUID agent_id;
+	msg->getUUID("AgentData", "AgentID", agent_id);
+	LLUUID session_id;
+	msg->getUUID("AgentData", "SessionID", session_id);
+	if((agent_id != gAgent.getID()) || (session_id != gAgent.getSessionID()))
+	{
+		LL_WARNS("Messaging") << "Bogus Logout Reply" << LL_ENDL;
+	}
+
+	LLInventoryModel::update_map_t parents;
+	S32 count = msg->getNumberOfBlocksFast( _PREHASH_InventoryData );
+	for(S32 i = 0; i < count; ++i)
+	{
+		LLUUID item_id;
+		msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_ItemID, item_id, i);
+
+		if( (1 == count) && item_id.isNull() )
+		{
+			// Detect dummy item.  Indicates an empty list.
+			break;
+		}
+
+		// We do not need to track the asset ids, just account for an
+		// updated inventory version.
+		LL_INFOS("Messaging") << "process_logout_reply itemID=" << item_id << LL_ENDL;
+		LLInventoryItem* item = gInventory.getItem( item_id );
+		if( item )
+		{
+			parents[item->getParentUUID()] = 0;
+			gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
+		}
+		else
+		{
+			LL_INFOS("Messaging") << "process_logout_reply item not found: " << item_id << LL_ENDL;
+		}
+	}
+    LLAppViewer::instance()->forceQuit();
+}
+
+void process_layer_data(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLViewerRegion *regionp = LLWorld::getInstance()->getRegion(mesgsys->getSender());
+
+	if (!regionp || gNoRender)
+	{
+		return;
+	}
+
+
+	S32 size;
+	S8 type;
+
+	mesgsys->getS8Fast(_PREHASH_LayerID, _PREHASH_Type, type);
+	size = mesgsys->getSizeFast(_PREHASH_LayerData, _PREHASH_Data);
+	if (0 == size)
+	{
+		LL_WARNS("Messaging") << "Layer data has zero size." << LL_ENDL;
+		return;
+	}
+	if (size < 0)
+	{
+		// getSizeFast() is probably trying to tell us about an error
+		LL_WARNS("Messaging") << "getSizeFast() returned negative result: "
+			<< size
+			<< LL_ENDL;
+		return;
+	}
+	U8 *datap = new U8[size];
+	mesgsys->getBinaryDataFast(_PREHASH_LayerData, _PREHASH_Data, datap, size);
+	LLVLData *vl_datap = new LLVLData(regionp, type, datap, size);
+	if (mesgsys->getReceiveCompressedSize())
+	{
+		gVLManager.addLayerData(vl_datap, mesgsys->getReceiveCompressedSize());
+	}
+	else
+	{
+		gVLManager.addLayerData(vl_datap, mesgsys->getReceiveSize());
+	}
+}
+
+// S32 exported_object_count = 0;
+// S32 exported_image_count = 0;
+// S32 current_object_count = 0;
+// S32 current_image_count = 0;
+
+// extern LLNotifyBox *gExporterNotify;
+// extern LLUUID gExporterRequestID;
+// extern std::string gExportDirectory;
+
+// extern LLUploadDialog *gExportDialog;
+
+// std::string gExportedFile;
+
+// std::map<LLUUID, std::string> gImageChecksums;
+
+// void export_complete()
+// {
+// 		LLUploadDialog::modalUploadFinished();
+// 		gExporterRequestID.setNull();
+// 		gExportDirectory = "";
+
+// 		LLFILE* fXML = LLFile::fopen(gExportedFile, "rb");		/* Flawfinder: ignore */
+// 		fseek(fXML, 0, SEEK_END);
+// 		long length = ftell(fXML);
+// 		fseek(fXML, 0, SEEK_SET);
+// 		U8 *buffer = new U8[length + 1];
+// 		size_t nread = fread(buffer, 1, length, fXML);
+// 		if (nread < (size_t) length)
+// 		{
+// 			LL_WARNS("Messaging") << "Short read" << LL_ENDL;
+// 		}
+// 		buffer[nread] = '\0';
+// 		fclose(fXML);
+
+// 		char *pos = (char *)buffer;
+// 		while ((pos = strstr(pos+1, "<sl:image ")) != 0)
+// 		{
+// 			char *pos_check = strstr(pos, "checksum=\"");
+
+// 			if (pos_check)
+// 			{
+// 				char *pos_uuid = strstr(pos_check, "\">");
+
+// 				if (pos_uuid)
+// 				{
+// 					char image_uuid_str[UUID_STR_SIZE];		/* Flawfinder: ignore */
+// 					memcpy(image_uuid_str, pos_uuid+2, UUID_STR_SIZE-1);		/* Flawfinder: ignore */
+// 					image_uuid_str[UUID_STR_SIZE-1] = 0;
+					
+// 					LLUUID image_uuid(image_uuid_str);
+
+// 					LL_INFOS("Messaging") << "Found UUID: " << image_uuid << LL_ENDL;
+
+// 					std::map<LLUUID, std::string>::iterator itor = gImageChecksums.find(image_uuid);
+// 					if (itor != gImageChecksums.end())
+// 					{
+// 						LL_INFOS("Messaging") << "Replacing with checksum: " << itor->second << LL_ENDL;
+// 						if (!itor->second.empty())
+// 						{
+// 							memcpy(&pos_check[10], itor->second.c_str(), 32);		/* Flawfinder: ignore */
+// 						}
+// 					}
+// 				}
+// 			}
+// 		}
+
+// 		LLFILE* fXMLOut = LLFile::fopen(gExportedFile, "wb");		/* Flawfinder: ignore */
+// 		if (fwrite(buffer, 1, length, fXMLOut) != length)
+// 		{
+// 			LL_WARNS("Messaging") << "Short write" << LL_ENDL;
+// 		}
+// 		fclose(fXMLOut);
+
+// 		delete [] buffer;
+// }
+
+
+// void exported_item_complete(const LLTSCode status, void *user_data)
+// {
+// 	//std::string *filename = (std::string *)user_data;
+
+// 	if (status < LLTS_OK)
+// 	{
+// 		LL_WARNS("Messaging") << "Export failed!" << LL_ENDL;
+// 	}
+// 	else
+// 	{
+// 		++current_object_count;
+// 		if (current_image_count == exported_image_count && current_object_count == exported_object_count)
+// 		{
+// 			LL_INFOS("Messaging") << "*** Export complete ***" << LL_ENDL;
+
+// 			export_complete();
+// 		}
+// 		else
+// 		{
+// 			gExportDialog->setMessage(llformat("Exported %d/%d object files, %d/%d textures.", current_object_count, exported_object_count, current_image_count, exported_image_count));
+// 		}
+// 	}
+// }
+
+// struct exported_image_info
+// {
+// 	LLUUID image_id;
+// 	std::string filename;
+// 	U32 image_num;
+// };
+
+// void exported_j2c_complete(const LLTSCode status, void *user_data)
+// {
+// 	exported_image_info *info = (exported_image_info *)user_data;
+// 	LLUUID image_id = info->image_id;
+// 	U32 image_num = info->image_num;
+// 	std::string filename = info->filename;
+// 	delete info;
+
+// 	if (status < LLTS_OK)
+// 	{
+// 		LL_WARNS("Messaging") << "Image download failed!" << LL_ENDL;
+// 	}
+// 	else
+// 	{
+// 		LLFILE* fIn = LLFile::fopen(filename, "rb");		/* Flawfinder: ignore */
+// 		if (fIn) 
+// 		{
+// 			LLPointer<LLImageJ2C> ImageUtility = new LLImageJ2C;
+// 			LLPointer<LLImageTGA> TargaUtility = new LLImageTGA;
+
+// 			fseek(fIn, 0, SEEK_END);
+// 			S32 length = ftell(fIn);
+// 			fseek(fIn, 0, SEEK_SET);
+// 			U8 *buffer = ImageUtility->allocateData(length);
+// 			if (fread(buffer, 1, length, fIn) != length)
+// 			{
+// 				LL_WARNS("Messaging") << "Short read" << LL_ENDL;
+// 			}
+// 			fclose(fIn);
+// 			LLFile::remove(filename);
+
+// 			// Convert to TGA
+// 			LLPointer<LLImageRaw> image = new LLImageRaw();
+
+// 			ImageUtility->updateData();
+// 			ImageUtility->decode(image, 100000.0f);
+			
+// 			TargaUtility->encode(image);
+// 			U8 *data = TargaUtility->getData();
+// 			S32 data_size = TargaUtility->getDataSize();
+
+// 			std::string file_path = gDirUtilp->getDirName(filename);
+			
+// 			std::string output_file = llformat("%s/image-%03d.tga", file_path.c_str(), image_num);//filename;
+// 			//S32 name_len = output_file.length();
+// 			//strcpy(&output_file[name_len-3], "tga");
+// 			LLFILE* fOut = LLFile::fopen(output_file, "wb");		/* Flawfinder: ignore */
+// 			char md5_hash_string[33];		/* Flawfinder: ignore */
+// 			strcpy(md5_hash_string, "00000000000000000000000000000000");		/* Flawfinder: ignore */
+// 			if (fOut)
+// 			{
+// 				if (fwrite(data, 1, data_size, fOut) != data_size)
+// 				{
+// 					LL_WARNS("Messaging") << "Short write" << LL_ENDL;
+// 				}
+// 				fseek(fOut, 0, SEEK_SET);
+// 				fclose(fOut);
+// 				fOut = LLFile::fopen(output_file, "rb");		/* Flawfinder: ignore */
+// 				LLMD5 my_md5_hash(fOut);
+// 				my_md5_hash.hex_digest(md5_hash_string);
+// 			}
+
+// 			gImageChecksums.insert(std::pair<LLUUID, std::string>(image_id, md5_hash_string));
+// 		}
+// 	}
+
+// 	++current_image_count;
+// 	if (current_image_count == exported_image_count && current_object_count == exported_object_count)
+// 	{
+// 		LL_INFOS("Messaging") << "*** Export textures complete ***" << LL_ENDL;
+// 			export_complete();
+// 	}
+// 	else
+// 	{
+// 		gExportDialog->setMessage(llformat("Exported %d/%d object files, %d/%d textures.", current_object_count, exported_object_count, current_image_count, exported_image_count));
+// 	}
+//}
+
+void process_derez_ack(LLMessageSystem*, void**)
+{
+	if(gViewerWindow) gViewerWindow->getWindow()->decBusyCount();
+}
+
+void process_places_reply(LLMessageSystem* msg, void** data)
+{
+	LLUUID query_id;
+
+	msg->getUUID("AgentData", "QueryID", query_id);
+	if (query_id.isNull())
+	{
+		LLFloaterLandHoldings::processPlacesReply(msg, data);
+	}
+	else if(gAgent.isInGroup(query_id))
+	{
+		LLPanelGroupLandMoney::processPlacesReply(msg, data);
+	}
+	else
+	{
+		LL_WARNS("Messaging") << "Got invalid PlacesReply message" << LL_ENDL;
+	}
+}
+
+void send_sound_trigger(const LLUUID& sound_id, F32 gain)
+{
+	if (sound_id.isNull() || gAgent.getRegion() == NULL)
+	{
+		// disconnected agent or zero guids don't get sent (no sound)
+		return;
+	}
+
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_SoundTrigger);
+	msg->nextBlockFast(_PREHASH_SoundData);
+	msg->addUUIDFast(_PREHASH_SoundID, sound_id);
+	// Client untrusted, ids set on sim
+	msg->addUUIDFast(_PREHASH_OwnerID, LLUUID::null );
+	msg->addUUIDFast(_PREHASH_ObjectID, LLUUID::null );
+	msg->addUUIDFast(_PREHASH_ParentID, LLUUID::null );
+
+	msg->addU64Fast(_PREHASH_Handle, gAgent.getRegion()->getHandle());
+
+	LLVector3 position = gAgent.getPositionAgent();
+	msg->addVector3Fast(_PREHASH_Position, position);
+	msg->addF32Fast(_PREHASH_Gain, gain);
+
+	gAgent.sendMessage();
+}
+
+bool join_group_response(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	BOOL delete_context_data = TRUE;
+	bool accept_invite = false;
+
+	LLUUID group_id = notification["payload"]["group_id"].asUUID();
+	LLUUID transaction_id = notification["payload"]["transaction_id"].asUUID();
+	std::string name = notification["payload"]["name"].asString();
+	std::string message = notification["payload"]["message"].asString();
+	S32 fee = notification["payload"]["fee"].asInteger();
+
+	if (option == 2 && !group_id.isNull())
+	{
+		LLGroupActions::show(group_id);
+		LLSD args;
+		args["MESSAGE"] = message;
+		LLNotificationsUtil::add("JoinGroup", args, notification["payload"]);
+		return false;
+	}
+	if(option == 0 && !group_id.isNull())
+	{
+		// check for promotion or demotion.
+		S32 max_groups = gMaxAgentGroups;
+		if(gAgent.isInGroup(group_id)) ++max_groups;
+
+		if(gAgent.mGroups.count() < max_groups)
+		{
+			accept_invite = true;
+		}
+		else
+		{
+			delete_context_data = FALSE;
+			LLSD args;
+			args["NAME"] = name;
+			LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification["payload"]);
+		}
+	}
+
+	if (accept_invite)
+	{
+		// If there is a fee to join this group, make
+		// sure the user is sure they want to join.
+		if (fee > 0)
+		{
+			delete_context_data = FALSE;
+			LLSD args;
+			args["COST"] = llformat("%d", fee);
+			// Set the fee for next time to 0, so that we don't keep
+			// asking about a fee.
+			LLSD next_payload = notification["payload"];
+			next_payload["fee"] = 0;
+			LLNotificationsUtil::add("JoinGroupCanAfford",
+									args,
+									next_payload);
+		}
+		else
+		{
+			send_improved_im(group_id,
+							 std::string("name"),
+							 std::string("message"),
+							IM_ONLINE,
+							IM_GROUP_INVITATION_ACCEPT,
+							transaction_id);
+		}
+	}
+	else
+	{
+		send_improved_im(group_id,
+						 std::string("name"),
+						 std::string("message"),
+						IM_ONLINE,
+						IM_GROUP_INVITATION_DECLINE,
+						transaction_id);
+	}
+
+	return false;
+}
+
+static void highlight_inventory_items_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel)
+{
+	if (NULL == inventory_panel) return;
+
+	for (std::vector<LLUUID>::const_iterator item_iter = items.begin();
+		item_iter != items.end();
+		++item_iter)
+	{
+		const LLUUID& item_id = (*item_iter);
+		if(!highlight_offered_object(item_id))
+		{
+			continue;
+		}
+
+		LLInventoryItem* item = gInventory.getItem(item_id);
+		llassert(item);
+		if (!item) {
+			continue;
+		}
+
+		LL_DEBUGS("Inventory_Move") << "Highlighting inventory item: " << item->getName() << ", " << item_id  << LL_ENDL;
+		LLFolderView* fv = inventory_panel->getRootFolder();
+		if (fv)
+		{
+			LLFolderViewItem* fv_item = fv->getItemByID(item_id);
+			if (fv_item)
+			{
+				LLFolderViewItem* fv_folder = fv_item->getParentFolder();
+				if (fv_folder)
+				{
+					// Parent folders can be different in case of 2 consecutive drag and drop
+					// operations when the second one is started before the first one completes.
+					LL_DEBUGS("Inventory_Move") << "Open folder: " << fv_folder->getName() << LL_ENDL;
+					fv_folder->setOpen(TRUE);
+					if (fv_folder->isSelected())
+					{
+						fv->changeSelection(fv_folder, FALSE);
+					}
+				}
+				fv->changeSelection(fv_item, TRUE);
+			}
+		}
+	}
+}
+
+static LLNotificationFunctorRegistration jgr_1("JoinGroup", join_group_response);
+static LLNotificationFunctorRegistration jgr_2("JoinedTooManyGroupsMember", join_group_response);
+static LLNotificationFunctorRegistration jgr_3("JoinGroupCanAfford", join_group_response);
+
+
+//-----------------------------------------------------------------------------
+// Instant Message
+//-----------------------------------------------------------------------------
+class LLOpenAgentOffer : public LLInventoryFetchItemsObserver
+{
+public:
+	LLOpenAgentOffer(const LLUUID& object_id,
+					 const std::string& from_name) : 
+		LLInventoryFetchItemsObserver(object_id),
+		mFromName(from_name) {}
+	/*virtual*/ void startFetch()
+	{
+		for (uuid_vec_t::const_iterator it = mIDs.begin(); it < mIDs.end(); ++it)
+		{
+			LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
+			if (cat)
+			{
+				mComplete.push_back((*it));
+			}
+		}
+		LLInventoryFetchItemsObserver::startFetch();
+	}
+	/*virtual*/ void done()
+	{
+		open_inventory_offer(mComplete, mFromName);
+		gInventory.removeObserver(this);
+		delete this;
+	}
+private:
+	std::string mFromName;
+};
+
+/**
+ * Class to observe adding of new items moved from the world to user's inventory to select them in inventory.
+ *
+ * We can't create it each time items are moved because "drop" event is sent separately for each
+ * element even while multi-dragging. We have to have the only instance of the observer. See EXT-4347.
+ */
+class LLViewerInventoryMoveFromWorldObserver : public LLInventoryAddItemByAssetObserver
+{
+public:
+	LLViewerInventoryMoveFromWorldObserver()
+		: LLInventoryAddItemByAssetObserver()
+		, mActivePanel(NULL)
+	{
+
+	}
+
+	void setMoveIntoFolderID(const LLUUID& into_folder_uuid) {mMoveIntoFolderID = into_folder_uuid; }
+
+private:
+	/*virtual */void onAssetAdded(const LLUUID& asset_id)
+	{
+		// Store active Inventory panel.
+		mActivePanel = LLInventoryPanel::getActiveInventoryPanel();
+
+		// Store selected items (without destination folder)
+		mSelectedItems.clear();
+		if (mActivePanel)
+		{
+			mSelectedItems = mActivePanel->getRootFolder()->getSelectionList();
+		}
+		mSelectedItems.erase(mMoveIntoFolderID);
+	}
+
+	/**
+	 * Selects added inventory items watched by their Asset UUIDs if selection was not changed since
+	 * all items were started to watch (dropped into a folder).
+	 */
+	void done()
+	{
+		// if selection is not changed since watch started lets hightlight new items.
+		if (mActivePanel && !isSelectionChanged())
+		{
+			LL_DEBUGS("Inventory_Move") << "Selecting new items..." << LL_ENDL;
+			mActivePanel->clearSelection();
+			highlight_inventory_items_in_panel(mAddedItems, mActivePanel);
+		}
+	}
+
+	/**
+	 * Returns true if selected inventory items were changed since moved inventory items were started to watch.
+	 */
+	bool isSelectionChanged()
+	{
+		const LLInventoryPanel * const current_active_panel = LLInventoryPanel::getActiveInventoryPanel();
+
+		if (NULL == mActivePanel || current_active_panel != mActivePanel)
+		{
+			return true;
+		}
+
+		// get selected items (without destination folder)
+		selected_items_t selected_items = mActivePanel->getRootFolder()->getSelectionList();
+		selected_items.erase(mMoveIntoFolderID);
+
+		// compare stored & current sets of selected items
+		selected_items_t different_items;
+		std::set_symmetric_difference(mSelectedItems.begin(), mSelectedItems.end(),
+			selected_items.begin(), selected_items.end(), std::inserter(different_items, different_items.begin()));
+
+		LL_DEBUGS("Inventory_Move") << "Selected firstly: " << mSelectedItems.size()
+			<< ", now: " << selected_items.size() << ", difference: " << different_items.size() << LL_ENDL;
+
+		return different_items.size() > 0;
+	}
+
+	LLInventoryPanel *mActivePanel;
+	typedef std::set<LLUUID> selected_items_t;
+	selected_items_t mSelectedItems;
+
+	/**
+	 * UUID of FolderViewFolder into which watched items are moved.
+	 *
+	 * Destination FolderViewFolder becomes selected while mouse hovering (when dragged items are dropped).
+	 * 
+	 * If mouse is moved out it set unselected and number of selected items is changed 
+	 * even if selected items in Inventory stay the same.
+	 * So, it is used to update stored selection list.
+	 *
+	 * @see onAssetAdded()
+	 * @see isSelectionChanged()
+	 */
+	LLUUID mMoveIntoFolderID;
+};
+
+LLViewerInventoryMoveFromWorldObserver* gInventoryMoveObserver = NULL;
+
+void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid)
+{
+	start_new_inventory_observer();
+
+	gInventoryMoveObserver->setMoveIntoFolderID(into_folder_uuid);
+	gInventoryMoveObserver->watchAsset(inv_item->getAssetUUID());
+}
+
+//unlike the FetchObserver for AgentOffer, we only make one 
+//instance of the AddedObserver for TaskOffers
+//and it never dies.  We do this because we don't know the UUID of 
+//task offers until they are accepted, so we don't wouldn't 
+//know what to watch for, so instead we just watch for all additions.
+class LLOpenTaskOffer : public LLInventoryAddedObserver
+{
+protected:
+	/*virtual*/ void done()
+	{
+		for (uuid_vec_t::iterator it = mAdded.begin(); it != mAdded.end();)
+		{
+			const LLUUID& item_uuid = *it;
+			bool was_moved = false;
+			LLInventoryObject* added_object = gInventory.getObject(item_uuid);
+			if (added_object)
+			{
+				// cast to item to get Asset UUID
+				LLInventoryItem* added_item = dynamic_cast<LLInventoryItem*>(added_object);
+				if (added_item)
+				{
+					const LLUUID& asset_uuid = added_item->getAssetUUID();
+					if (gInventoryMoveObserver->isAssetWatched(asset_uuid))
+					{
+						LL_DEBUGS("Inventory_Move") << "Found asset UUID: " << asset_uuid << LL_ENDL;
+						was_moved = true;
+					}
+				}
+			}
+
+			if (was_moved)
+			{
+				it = mAdded.erase(it);
+			}
+			else ++it;
+		}
+
+		open_inventory_offer(mAdded, "");
+		mAdded.clear();
+	}
+ };
+
+class LLOpenTaskGroupOffer : public LLInventoryAddedObserver
+{
+protected:
+	/*virtual*/ void done()
+	{
+		open_inventory_offer(mAdded, "group_offer");
+		mAdded.clear();
+		gInventory.removeObserver(this);
+		delete this;
+	}
+};
+
+//one global instance to bind them
+LLOpenTaskOffer* gNewInventoryObserver=NULL;
+
+class LLNewInventoryHintObserver : public LLInventoryAddedObserver
+{
+protected:
+	/*virtual*/ void done()
+	{
+		LLFirstUse::newInventory();
+	}
+};
+
+void start_new_inventory_observer()
+{
+	if (!gNewInventoryObserver) //task offer observer 
+	{
+		// Observer is deleted by gInventory
+		gNewInventoryObserver = new LLOpenTaskOffer;
+		gInventory.addObserver(gNewInventoryObserver);
+	}
+
+	if (!gInventoryMoveObserver) //inventory move from the world observer 
+	{
+		// Observer is deleted by gInventory
+		gInventoryMoveObserver = new LLViewerInventoryMoveFromWorldObserver;
+		gInventory.addObserver(gInventoryMoveObserver);
+	}
+
+	gInventory.addObserver(new LLNewInventoryHintObserver());
+}
+
+class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver
+{
+	LOG_CLASS(LLDiscardAgentOffer);
+public:
+	LLDiscardAgentOffer(const LLUUID& folder_id, const LLUUID& object_id) :
+		LLInventoryFetchItemsObserver(object_id),
+		mFolderID(folder_id),
+		mObjectID(object_id) {}
+	virtual ~LLDiscardAgentOffer() {}
+	virtual void done()
+	{
+		LL_DEBUGS("Messaging") << "LLDiscardAgentOffer::done()" << LL_ENDL;
+		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+		bool notify = false;
+		if(trash_id.notNull() && mObjectID.notNull())
+		{
+			LLInventoryModel::update_list_t update;
+			LLInventoryModel::LLCategoryUpdate old_folder(mFolderID, -1);
+			update.push_back(old_folder);
+			LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
+			update.push_back(new_folder);
+			gInventory.accountForUpdate(update);
+			gInventory.moveObject(mObjectID, trash_id);
+			LLInventoryObject* obj = gInventory.getObject(mObjectID);
+			if(obj)
+			{
+				// no need to restamp since this is already a freshly
+				// stamped item.
+				obj->updateParentOnServer(FALSE);
+				notify = true;
+			}
+		}
+		else
+		{
+			LL_WARNS("Messaging") << "DiscardAgentOffer unable to find: "
+					<< (trash_id.isNull() ? "trash " : "")
+					<< (mObjectID.isNull() ? "object" : "") << LL_ENDL;
+		}
+		gInventory.removeObserver(this);
+		if(notify)
+		{
+			gInventory.notifyObservers();
+		}
+		delete this;
+	}
+protected:
+	LLUUID mFolderID;
+	LLUUID mObjectID;
+};
+
+
+//Returns TRUE if we are OK, FALSE if we are throttled
+//Set check_only true if you want to know the throttle status 
+//without registering a hit
+bool check_offer_throttle(const std::string& from_name, bool check_only)
+{
+	static U32 throttle_count;
+	static bool throttle_logged;
+	LLChat chat;
+	std::string log_message;
+
+	if (!gSavedSettings.getBOOL("ShowNewInventory"))
+		return false;
+
+	if (check_only)
+	{
+		return gThrottleTimer.hasExpired();
+	}
+	
+	if(gThrottleTimer.checkExpirationAndReset(OFFER_THROTTLE_TIME))
+	{
+		LL_DEBUGS("Messaging") << "Throttle Expired" << LL_ENDL;
+		throttle_count=1;
+		throttle_logged=false;
+		return true;
+	}
+	else //has not expired
+	{
+		LL_DEBUGS("Messaging") << "Throttle Not Expired, Count: " << throttle_count << LL_ENDL;
+		// When downloading the initial inventory we get a lot of new items
+		// coming in and can't tell that from spam.
+		if (LLStartUp::getStartupState() >= STATE_STARTED
+			&& throttle_count >= OFFER_THROTTLE_MAX_COUNT)
+		{
+			if (!throttle_logged)
+			{
+				// Use the name of the last item giver, who is probably the person
+				// spamming you.
+
+				LLStringUtil::format_map_t arg;
+				std::string log_msg;
+				std::ostringstream time ;
+				time<<OFFER_THROTTLE_TIME;
+
+				arg["APP_NAME"] = LLAppViewer::instance()->getSecondLifeTitle();
+				arg["TIME"] = time.str();
+
+				if (!from_name.empty())
+				{
+					arg["FROM_NAME"] = from_name;
+					log_msg = LLTrans::getString("ItemsComingInTooFastFrom", arg);
+				}
+				else
+				{
+					log_msg = LLTrans::getString("ItemsComingInTooFast", arg);
+				}
+				
+				//this is kinda important, so actually put it on screen
+				LLSD args;
+				args["MESSAGE"] = log_msg;
+				LLNotificationsUtil::add("SystemMessage", args);
+
+				throttle_logged=true;
+			}
+			return false;
+		}
+		else
+		{
+			throttle_count++;
+			return true;
+		}
+	}
+}
+ 
+void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_name)
+{
+	for (uuid_vec_t::const_iterator obj_iter = objects.begin();
+		 obj_iter != objects.end();
+		 ++obj_iter)
+	{
+		const LLUUID& obj_id = (*obj_iter);
+		if(!highlight_offered_object(obj_id))
+		{
+			continue;
+		}
+
+		const LLInventoryObject *obj = gInventory.getObject(obj_id);
+		if (!obj)
+		{
+			llwarns << "Cannot find object [ itemID:" << obj_id << " ] to open." << llendl;
+			continue;
+		}
+
+		const LLAssetType::EType asset_type = obj->getActualType();
+
+		// Either an inventory item or a category.
+		const LLInventoryItem* item = dynamic_cast<const LLInventoryItem*>(obj);
+		if (item)
+		{
+			////////////////////////////////////////////////////////////////////////////////
+			// Special handling for various types.
+			if (check_offer_throttle(from_name, false)) // If we are throttled, don't display
+			{
+				LL_DEBUGS("Messaging") << "Highlighting inventory item: " << item->getUUID()  << LL_ENDL;
+				// If we opened this ourselves, focus it
+				const BOOL take_focus = from_name.empty() ? TAKE_FOCUS_YES : TAKE_FOCUS_NO;
+				switch(asset_type)
+				{
+					case LLAssetType::AT_NOTECARD:
+					{
+						LLFloaterReg::showInstance("preview_notecard", LLSD(obj_id), take_focus);
+						break;
+					}
+					case LLAssetType::AT_LANDMARK:
+					{
+						LLInventoryCategory* parent_folder = gInventory.getCategory(item->getParentUUID());
+						if ("inventory_handler" == from_name)
+						{
+							//we have to filter inventory_handler messages to avoid notification displaying
+							LLSideTray::getInstance()->showPanel("panel_places",
+																 LLSD().with("type", "landmark").with("id", item->getUUID()));
+						}
+						else if("group_offer" == from_name)
+						{
+							// "group_offer" is passed by LLOpenTaskGroupOffer
+							// Notification about added landmark will be generated under the "from_name.empty()" called from LLOpenTaskOffer::done().
+							LLSD args;
+							args["type"] = "landmark";
+							args["id"] = obj_id;
+							LLSideTray::getInstance()->showPanel("panel_places", args);
+
+							continue;
+						}
+						else if(from_name.empty())
+						{
+							std::string folder_name;
+							if (parent_folder)
+							{
+								// Localize folder name.
+								// *TODO: share this code?
+								folder_name = parent_folder->getName();
+								if (LLFolderType::lookupIsProtectedType(parent_folder->getPreferredType()))
+								{
+									LLTrans::findString(folder_name, "InvFolder " + folder_name);
+								}
+							}
+							else
+							{
+								 folder_name = LLTrans::getString("Unknown");
+							}
+
+							// we receive a message from LLOpenTaskOffer, it mean that new landmark has been added.
+							LLSD args;
+							args["LANDMARK_NAME"] = item->getName();
+							args["FOLDER_NAME"] = folder_name;
+							LLNotificationsUtil::add("LandmarkCreated", args);
+						}
+					}
+					break;
+					case LLAssetType::AT_TEXTURE:
+					{
+						LLFloaterReg::showInstance("preview_texture", LLSD(obj_id), take_focus);
+						break;
+					}
+					case LLAssetType::AT_ANIMATION:
+						LLFloaterReg::showInstance("preview_anim", LLSD(obj_id), take_focus);
+						break;
+					case LLAssetType::AT_SCRIPT:
+						LLFloaterReg::showInstance("preview_script", LLSD(obj_id), take_focus);
+						break;
+					case LLAssetType::AT_SOUND:
+						LLFloaterReg::showInstance("preview_sound", LLSD(obj_id), take_focus);
+						break;
+					default:
+						break;
+				}
+			}
+		}
+
+		////////////////////////////////////////////////////////////////////////////////
+		// Highlight item
+		const BOOL auto_open = 
+			gSavedSettings.getBOOL("ShowInInventory") && // don't open if showininventory is false
+			!from_name.empty(); // don't open if it's not from anyone.
+		LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open);
+		if(active_panel)
+		{
+			LL_DEBUGS("Messaging") << "Highlighting" << obj_id  << LL_ENDL;
+			LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus();
+			active_panel->setSelection(obj_id, TAKE_FOCUS_NO);
+			gFocusMgr.setKeyboardFocus(focus_ctrl);
+		}
+	}
+}
+
+bool highlight_offered_object(const LLUUID& obj_id)
+{
+	const LLInventoryObject* obj = gInventory.getObject(obj_id);
+	if(!obj)
+	{
+		LL_WARNS("Messaging") << "Unable to show inventory item: " << obj_id << LL_ENDL;
+		return false;
+	}
+
+	////////////////////////////////////////////////////////////////////////////////
+	// Don't highlight if it's in certain "quiet" folders which don't need UI
+	// notification (e.g. trash, cof, lost-and-found).
+	if(!gAgent.getAFK())
+	{
+		const LLViewerInventoryCategory *parent = gInventory.getFirstNondefaultParent(obj_id);
+		if (parent)
+		{
+			const LLFolderType::EType parent_type = parent->getPreferredType();
+			if (LLViewerFolderType::lookupIsQuietType(parent_type))
+			{
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+void inventory_offer_mute_callback(const LLUUID& blocked_id,
+								   const std::string& full_name,
+								   bool is_group,
+								   boost::shared_ptr<LLNotificationResponderInterface> offer_ptr)
+{
+	LLOfferInfo* offer =  dynamic_cast<LLOfferInfo*>(offer_ptr.get());
+	
+	std::string from_name = full_name;
+	LLMute::EType type;
+	if (is_group)
+	{
+		type = LLMute::GROUP;
+	}
+	else if(offer && offer->mFromObject)
+	{
+		//we have to block object by name because blocked_id is an id of owner
+		type = LLMute::BY_NAME;
+	}
+	else
+	{
+		type = LLMute::AGENT;
+	}
+
+	// id should be null for BY_NAME mute, see  LLMuteList::add for details  
+	LLMute mute(type == LLMute::BY_NAME ? LLUUID::null : blocked_id, from_name, type);
+	if (LLMuteList::getInstance()->add(mute))
+	{
+		LLPanelBlockedList::showPanelAndSelect(blocked_id);
+	}
+
+	// purge the message queue of any previously queued inventory offers from the same source.
+	class OfferMatcher : public LLNotificationsUI::LLScreenChannel::Matcher
+	{
+	public:
+		OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
+		bool matches(const LLNotificationPtr notification) const
+		{
+			if(notification->getName() == "ObjectGiveItem" 
+				|| notification->getName() == "UserGiveItem")
+			{
+				return (notification->getPayload()["from_id"].asUUID() == blocked_id);
+			}
+			return FALSE;
+		}
+	private:
+		const LLUUID& blocked_id;
+	};
+
+	LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID(
+			gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id));
+}
+
+LLOfferInfo::LLOfferInfo()
+ : LLNotificationResponderInterface()
+ , mFromGroup(FALSE)
+ , mFromObject(FALSE)
+ , mIM(IM_NOTHING_SPECIAL)
+ , mType(LLAssetType::AT_NONE)
+ , mPersist(false)
+{
+}
+
+LLOfferInfo::LLOfferInfo(const LLSD& sd)
+{
+	mIM = (EInstantMessage)sd["im_type"].asInteger();
+	mFromID = sd["from_id"].asUUID();
+	mFromGroup = sd["from_group"].asBoolean();
+	mFromObject = sd["from_object"].asBoolean();
+	mTransactionID = sd["transaction_id"].asUUID();
+	mFolderID = sd["folder_id"].asUUID();
+	mObjectID = sd["object_id"].asUUID();
+	mType = LLAssetType::lookup(sd["type"].asString().c_str());
+	mFromName = sd["from_name"].asString();
+	mDesc = sd["description"].asString();
+	mHost = LLHost(sd["sender"].asString());
+	mPersist = sd["persist"].asBoolean();
+}
+
+LLOfferInfo::LLOfferInfo(const LLOfferInfo& info)
+{
+	mIM = info.mIM;
+	mFromID = info.mFromID;
+	mFromGroup = info.mFromGroup;
+	mFromObject = info.mFromObject;
+	mTransactionID = info.mTransactionID;
+	mFolderID = info.mFolderID;
+	mObjectID = info.mObjectID;
+	mType = info.mType;
+	mFromName = info.mFromName;
+	mDesc = info.mDesc;
+	mHost = info.mHost;
+	mPersist = info.mPersist;
+}
+
+LLSD LLOfferInfo::asLLSD()
+{
+	LLSD sd;
+	sd["im_type"] = mIM;
+	sd["from_id"] = mFromID;
+	sd["from_group"] = mFromGroup;
+	sd["from_object"] = mFromObject;
+	sd["transaction_id"] = mTransactionID;
+	sd["folder_id"] = mFolderID;
+	sd["object_id"] = mObjectID;
+	sd["type"] = LLAssetType::lookup(mType);
+	sd["from_name"] = mFromName;
+	sd["description"] = mDesc;
+	sd["sender"] = mHost.getIPandPort();
+	sd["persist"] = mPersist;
+	return sd;
+}
+
+void LLOfferInfo::fromLLSD(const LLSD& params)
+{
+	*this = params;
+}
+
+void LLOfferInfo::send_auto_receive_response(void)
+{	
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_MessageBlock);
+	msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
+	msg->addUUIDFast(_PREHASH_ToAgentID, mFromID);
+	msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
+	msg->addUUIDFast(_PREHASH_ID, mTransactionID);
+	msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
+	std::string name;
+	LLAgentUI::buildFullname(name);
+	msg->addStringFast(_PREHASH_FromAgentName, name);
+	msg->addStringFast(_PREHASH_Message, ""); 
+	msg->addU32Fast(_PREHASH_ParentEstateID, 0);
+	msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
+	msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
+	
+	// Auto Receive Message. The math for the dialog works, because the accept
+	// for inventory_offered, task_inventory_offer or
+	// group_notice_inventory is 1 greater than the offer integer value.
+	// Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED, 
+	// or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
+	msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
+	msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
+						   sizeof(mFolderID.mData));
+	// send the message
+	msg->sendReliable(mHost);
+	
+	if(IM_INVENTORY_OFFERED == mIM)
+	{
+		// add buddy to recent people list
+		LLRecentPeople::instance().add(mFromID);
+	}
+}
+
+void LLOfferInfo::handleRespond(const LLSD& notification, const LLSD& response)
+{
+	initRespondFunctionMap();
+
+	const std::string name = notification["name"].asString();
+	if(mRespondFunctions.find(name) == mRespondFunctions.end())
+	{
+		llwarns << "Unexpected notification name : " << name << llendl;
+		llassert(!"Unexpected notification name");
+		return;
+	}
+
+	mRespondFunctions[name](notification, response);
+}
+
+bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& response)
+{
+	LLChat chat;
+	std::string log_message;
+	S32 button = LLNotificationsUtil::getSelectedOption(notification, response);
+	
+	LLInventoryObserver* opener = NULL;
+	LLViewerInventoryCategory* catp = NULL;
+	catp = (LLViewerInventoryCategory*)gInventory.getCategory(mObjectID);
+	LLViewerInventoryItem* itemp = NULL;
+	if(!catp)
+	{
+		itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
+	}
+	 
+	// For muting, we need to add the mute, then decline the offer.
+	// This must be done here because:
+	// * callback may be called immediately,
+	// * adding the mute sends a message,
+	// * we can't build two messages at once.
+	if (2 == button) // Block
+	{
+		LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+
+		llassert(notification_ptr != NULL);
+		if (notification_ptr != NULL)
+		{
+			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
+		}
+	}
+
+	std::string from_string; // Used in the pop-up.
+	std::string chatHistory_string;  // Used in chat history.
+	
+	// TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here:
+	from_string = chatHistory_string = mFromName;
+	
+	bool busy=FALSE;
+	
+	switch(button)
+	{
+	case IOR_SHOW:
+		// we will want to open this item when it comes back.
+		LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
+				 << LL_ENDL;
+		switch (mIM)
+		{
+		case IM_INVENTORY_OFFERED:
+			{
+				// This is an offer from an agent. In this case, the back
+				// end has already copied the items into your inventory,
+				// so we can fetch it out of our inventory.
+				if (gSavedSettings.getBOOL("ShowOfferedInventory"))
+				{
+					LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(mObjectID, from_string);
+					open_agent_offer->startFetch();
+					if(catp || (itemp && itemp->isFinished()))
+					{
+						open_agent_offer->done();
+					}
+					else
+					{
+						opener = open_agent_offer;
+					}
+				}
+			}
+			break;
+		case IM_GROUP_NOTICE:
+			opener = new LLOpenTaskGroupOffer;
+			send_auto_receive_response();
+			break;
+		case IM_TASK_INVENTORY_OFFERED:
+		case IM_GROUP_NOTICE_REQUESTED:
+			// This is an offer from a task or group.
+			// We don't use a new instance of an opener
+			// We instead use the singular observer gOpenTaskOffer
+			// Since it already exists, we don't need to actually do anything
+			break;
+		default:
+			LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
+			break;
+		}
+		break;
+		// end switch (mIM)
+			
+	case IOR_ACCEPT:
+		//don't spam them if they are getting flooded
+		if (check_offer_throttle(mFromName, true))
+		{
+			log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
+			LLSD args;
+			args["MESSAGE"] = log_message;
+			LLNotificationsUtil::add("SystemMessage", args);
+		}
+		break;
+
+	case IOR_BUSY:
+		//Busy falls through to decline.  Says to make busy message.
+		busy=TRUE;
+	case IOR_MUTE:
+		// MUTE falls through to decline
+	case IOR_DECLINE:
+		{
+			{
+				LLStringUtil::format_map_t log_message_args;
+				log_message_args["DESC"] = mDesc;
+				log_message_args["NAME"] = mFromName;
+				log_message = LLTrans::getString("InvOfferDecline", log_message_args);
+			}
+			chat.mText = log_message;
+			if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) )  // muting for SL-42269
+			{
+				chat.mMuted = TRUE;
+			}
+
+			// *NOTE dzaporozhan
+			// Disabled logging to old chat floater to fix crash in group notices - EXT-4149
+			// LLFloaterChat::addChatHistory(chat);
+			
+			LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
+			discard_agent_offer->startFetch();
+			if (catp || (itemp && itemp->isFinished()))
+			{
+				discard_agent_offer->done();
+			}
+			else
+			{
+				opener = discard_agent_offer;
+			}
+			
+			
+			if (busy &&	(!mFromGroup && !mFromObject))
+			{
+				busy_message(gMessageSystem, mFromID);
+			}
+			break;
+		}
+	default:
+		// close button probably
+		// The item has already been fetched and is in your inventory, we simply won't highlight it
+		// OR delete it if the notification gets killed, since we don't want that to be a vector for 
+		// losing inventory offers.
+		break;
+	}
+
+	if(opener)
+	{
+		gInventory.addObserver(opener);
+	}
+
+	if(!mPersist)
+	{
+		delete this;
+	}
+	return false;
+}
+
+bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const LLSD& response)
+{
+	LLChat chat;
+	std::string log_message;
+	S32 button = LLNotification::getSelectedOption(notification, response);
+	
+	// For muting, we need to add the mute, then decline the offer.
+	// This must be done here because:
+	// * callback may be called immediately,
+	// * adding the mute sends a message,
+	// * we can't build two messages at once.
+	if (2 == button)
+	{
+		LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+
+		llassert(notification_ptr != NULL);
+		if (notification_ptr != NULL)
+		{
+			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
+		}
+	}
+	
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_MessageBlock);
+	msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
+	msg->addUUIDFast(_PREHASH_ToAgentID, mFromID);
+	msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
+	msg->addUUIDFast(_PREHASH_ID, mTransactionID);
+	msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
+	std::string name;
+	LLAgentUI::buildFullname(name);
+	msg->addStringFast(_PREHASH_FromAgentName, name);
+	msg->addStringFast(_PREHASH_Message, ""); 
+	msg->addU32Fast(_PREHASH_ParentEstateID, 0);
+	msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
+	msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
+	LLInventoryObserver* opener = NULL;
+	
+	std::string from_string; // Used in the pop-up.
+	std::string chatHistory_string;  // Used in chat history.
+	if (mFromObject == TRUE)
+	{
+		if (mFromGroup)
+		{
+			std::string group_name;
+			if (gCacheName->getGroupName(mFromID, group_name))
+			{
+				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+"'" 
+				+ mFromName + LLTrans::getString("'") +" " + LLTrans::getString("InvOfferOwnedByGroup") 
+				+ " "+ "'" + group_name + "'";
+				
+				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByGroup") 
+				+ " " + group_name + "'";
+			}
+			else
+			{
+				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+"'"
+				+ mFromName +"'"+ " " + LLTrans::getString("InvOfferOwnedByUnknownGroup");
+				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByUnknownGroup");
+			}
+		}
+		else
+		{
+			std::string full_name;
+			if (gCacheName->getFullName(mFromID, full_name))
+			{
+				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+ LLTrans::getString("'") + mFromName 
+					+ LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + full_name;
+				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + full_name;
+			}
+			else
+			{
+				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+LLTrans::getString("'") 
+				+ mFromName + LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedByUnknownUser");
+				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByUnknownUser");
+			}
+		}
+	}
+	else
+	{
+		from_string = chatHistory_string = mFromName;
+	}
+	
+	bool busy=FALSE;
+	
+	switch(button)
+	{
+		case IOR_ACCEPT:
+			// ACCEPT. The math for the dialog works, because the accept
+			// for inventory_offered, task_inventory_offer or
+			// group_notice_inventory is 1 greater than the offer integer value.
+			// Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED, 
+			// or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
+			msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
+			msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
+								   sizeof(mFolderID.mData));
+			// send the message
+			msg->sendReliable(mHost);
+			
+			//don't spam them if they are getting flooded
+			if (check_offer_throttle(mFromName, true))
+			{
+				log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
+				LLSD args;
+				args["MESSAGE"] = log_message;
+				LLNotificationsUtil::add("SystemMessage", args);
+			}
+			
+			// we will want to open this item when it comes back.
+			LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
+			<< LL_ENDL;
+			switch (mIM)
+		{
+			case IM_TASK_INVENTORY_OFFERED:
+			case IM_GROUP_NOTICE:
+			case IM_GROUP_NOTICE_REQUESTED:
+			{
+				// This is an offer from a task or group.
+				// We don't use a new instance of an opener
+				// We instead use the singular observer gOpenTaskOffer
+				// Since it already exists, we don't need to actually do anything
+			}
+				break;
+			default:
+				LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
+				break;
+		}	// end switch (mIM)
+			break;
+			
+		case IOR_BUSY:
+			//Busy falls through to decline.  Says to make busy message.
+			busy=TRUE;
+		case IOR_MUTE:
+			// MUTE falls through to decline
+		case IOR_DECLINE:
+			// DECLINE. The math for the dialog works, because the decline
+			// for inventory_offered, task_inventory_offer or
+			// group_notice_inventory is 2 greater than the offer integer value.
+			// Generates IM_INVENTORY_DECLINED, IM_TASK_INVENTORY_DECLINED,
+			// or IM_GROUP_NOTICE_INVENTORY_DECLINED
+		default:
+			// close button probably (or any of the fall-throughs from above)
+			msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 2));
+			msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
+			// send the message
+			msg->sendReliable(mHost);
+
+			if (gSavedSettings.getBOOL("LogInventoryDecline"))
+			{
+				LLStringUtil::format_map_t log_message_args;
+				log_message_args["DESC"] = mDesc;
+				log_message_args["NAME"] = mFromName;
+				log_message = LLTrans::getString("InvOfferDecline", log_message_args);
+
+				LLSD args;
+				args["MESSAGE"] = log_message;
+				LLNotificationsUtil::add("SystemMessage", args);
+			}
+			
+			if (busy &&	(!mFromGroup && !mFromObject))
+			{
+				busy_message(msg,mFromID);
+			}
+			break;
+	}
+	
+	if(opener)
+	{
+		gInventory.addObserver(opener);
+	}
+
+	if(!mPersist)
+	{
+		delete this;
+	}
+	return false;
+}
+
+class LLPostponedOfferNotification: public LLPostponedNotification
+{
+protected:
+	/* virtual */
+	void modifyNotificationParams()
+	{
+		LLSD substitutions = mParams.substitutions;
+		substitutions["NAME"] = mName;
+		mParams.substitutions = substitutions;
+	}
+};
+
+void LLOfferInfo::initRespondFunctionMap()
+{
+	if(mRespondFunctions.empty())
+	{
+		mRespondFunctions["ObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
+		mRespondFunctions["UserGiveItem"] = boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2);
+	}
+}
+
+void inventory_offer_handler(LLOfferInfo* info)
+{
+	//Until throttling is implmented, busy mode should reject inventory instead of silently
+	//accepting it.  SEE SL-39554
+	if (gAgent.getBusy())
+	{
+		info->forceResponse(IOR_BUSY);
+		return;
+	}
+	
+	//If muted, don't even go through the messaging stuff.  Just curtail the offer here.
+	if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName))
+	{
+		info->forceResponse(IOR_MUTE);
+		return;
+	}
+
+	// Avoid the Accept/Discard dialog if the user so desires. JC
+	if (gSavedSettings.getBOOL("AutoAcceptNewInventory")
+		&& (info->mType == LLAssetType::AT_NOTECARD
+			|| info->mType == LLAssetType::AT_LANDMARK
+			|| info->mType == LLAssetType::AT_TEXTURE))
+	{
+		// For certain types, just accept the items into the inventory,
+		// and possibly open them on receipt depending upon "ShowNewInventory".
+		info->forceResponse(IOR_ACCEPT);
+		return;
+	}
+
+	// Strip any SLURL from the message display. (DEV-2754)
+	std::string msg = info->mDesc;
+	int indx = msg.find(" ( http://slurl.com/secondlife/");
+	if(indx == std::string::npos)
+	{
+		// try to find new slurl host
+		indx = msg.find(" ( http://maps.secondlife.com/secondlife/");
+	}
+	if(indx >= 0)
+	{
+		LLStringUtil::truncate(msg, indx);
+	}
+
+	LLSD args;
+	args["[OBJECTNAME]"] = msg;
+
+	LLSD payload;
+
+	// must protect against a NULL return from lookupHumanReadable()
+	std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
+	if (!typestr.empty())
+	{
+		// human readable matches string name from strings.xml
+		// lets get asset type localized name
+		args["OBJECTTYPE"] = LLTrans::getString(typestr);
+	}
+	else
+	{
+		LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL;
+		args["OBJECTTYPE"] = "";
+
+		// This seems safest, rather than propagating bogosity
+		LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL;
+		info->forceResponse(IOR_DECLINE);
+		return;
+	}
+
+	// If mObjectID is null then generate the object_id based on msg to prevent
+	// multiple creation of chiclets for same object.
+	LLUUID object_id = info->mObjectID;
+	if (object_id.isNull())
+		object_id.generate(msg);
+
+	payload["from_id"] = info->mFromID;
+	// Needed by LLScriptFloaterManager to bind original notification with 
+	// faked for toast one.
+	payload["object_id"] = object_id;
+	// Flag indicating that this notification is faked for toast.
+	payload["give_inventory_notification"] = FALSE;
+	args["OBJECTFROMNAME"] = info->mFromName;
+	args["NAME"] = info->mFromName;
+	if (info->mFromGroup)
+	{
+		args["NAME_SLURL"] = LLSLURL("group", info->mFromID, "about").getSLURLString();
+	}
+	else
+	{
+		args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString();
+	}
+	std::string verb = "select?name=" + LLURI::escape(msg);
+	args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
+
+	LLNotification::Params p("ObjectGiveItem");
+
+	// Object -> Agent Inventory Offer
+	if (info->mFromObject)
+	{
+		// Inventory Slurls don't currently work for non agent transfers, so only display the object name.
+		args["ITEM_SLURL"] = msg;
+		// Note: sets inventory_task_offer_callback as the callback
+		p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
+		info->mPersist = true;
+		p.name = "ObjectGiveItem";
+		// Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
+	    LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE);
+	}
+	else // Agent -> Agent Inventory Offer
+	{
+		p.responder = info;
+		// Note: sets inventory_offer_callback as the callback
+		// *TODO fix memory leak
+		// inventory_offer_callback() is not invoked if user received notification and 
+		// closes viewer(without responding the notification)
+		p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
+		info->mPersist = true;
+		p.name = "UserGiveItem";
+		
+		// Prefetch the item into your local inventory.
+		LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
+		fetch_item->startFetch();
+		if(fetch_item->isFinished())
+		{
+			fetch_item->done();
+		}
+		else
+		{
+			gInventory.addObserver(fetch_item);
+		}
+		
+		// In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages).
+		info->send_auto_receive_response();
+
+		// Inform user that there is a script floater via toast system
+		{
+			payload["give_inventory_notification"] = TRUE;
+		    p.payload = payload;
+		    LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
+		}
+	}
+
+	LLFirstUse::newInventory();
+}
+
+bool lure_callback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = 0;
+	if (response.isInteger()) 
+	{
+		option = response.asInteger();
+	}
+	else
+	{
+		option = LLNotificationsUtil::getSelectedOption(notification, response);
+	}
+	
+	LLUUID from_id = notification["payload"]["from_id"].asUUID();
+	LLUUID lure_id = notification["payload"]["lure_id"].asUUID();
+	BOOL godlike = notification["payload"]["godlike"].asBoolean();
+
+	switch(option)
+	{
+	case 0:
+		{
+			// accept
+			gAgent.teleportViaLure(lure_id, godlike);
+		}
+		break;
+	case 1:
+	default:
+		// decline
+		send_simple_im(from_id,
+					   LLStringUtil::null,
+					   IM_LURE_DECLINED,
+					   lure_id);
+		break;
+	}
+	return false;
+}
+static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback);
+
+bool goto_url_callback(const LLSD& notification, const LLSD& response)
+{
+	std::string url = notification["payload"]["url"].asString();
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if(1 == option)
+	{
+		LLWeb::loadURL(url);
+	}
+	return false;
+}
+static LLNotificationFunctorRegistration goto_url_callback_reg("GotoURL", goto_url_callback);
+
+bool inspect_remote_object_callback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::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);
+
+class LLPostponedServerObjectNotification: public LLPostponedNotification
+{
+protected:
+	/* virtual */
+	void modifyNotificationParams()
+	{
+		LLSD payload = mParams.payload;
+		mParams.payload = payload;
+	}
+};
+
+static bool parse_lure_bucket(const std::string& bucket,
+							  U64& region_handle,
+							  LLVector3& pos,
+							  LLVector3& look_at,
+							  U8& region_access)
+{
+	// tokenize the bucket
+	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+	boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
+	tokenizer tokens(bucket, sep);
+	tokenizer::iterator iter = tokens.begin();
+
+	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())
+	{
+		std::string access_str((*iter).c_str());
+		LLStringUtil::trim(access_str);
+		if ( access_str == "A" )
+		{
+			region_access = SIM_ACCESS_ADULT;
+		}
+		else if ( access_str == "M" )
+		{
+			region_access = SIM_ACCESS_MATURE;
+		}
+		else if ( access_str == "PG" )
+		{
+			region_access = SIM_ACCESS_PG;
+		}
+	}
+
+	pos.setVec((F32)rx, (F32)ry, (F32)rz);
+	look_at.setVec((F32)lx, (F32)ly, (F32)lz);
+
+	region_handle = to_region_handle(gx, gy);
+	return true;
+}
+
+// Strip out "Resident" for display, but only if the message came from a user
+// (rather than a script)
+static std::string clean_name_from_im(const std::string& name, EInstantMessage type)
+{
+	switch(type)
+	{
+	case IM_NOTHING_SPECIAL:
+	case IM_MESSAGEBOX:
+	case IM_GROUP_INVITATION:
+	case IM_INVENTORY_OFFERED:
+	case IM_INVENTORY_ACCEPTED:
+	case IM_INVENTORY_DECLINED:
+	case IM_GROUP_VOTE:
+	case IM_GROUP_MESSAGE_DEPRECATED:
+	//IM_TASK_INVENTORY_OFFERED
+	//IM_TASK_INVENTORY_ACCEPTED
+	//IM_TASK_INVENTORY_DECLINED
+	case IM_NEW_USER_DEFAULT:
+	case IM_SESSION_INVITE:
+	case IM_SESSION_P2P_INVITE:
+	case IM_SESSION_GROUP_START:
+	case IM_SESSION_CONFERENCE_START:
+	case IM_SESSION_SEND:
+	case IM_SESSION_LEAVE:
+	//IM_FROM_TASK
+	case IM_BUSY_AUTO_RESPONSE:
+	case IM_CONSOLE_AND_CHAT_HISTORY:
+	case IM_LURE_USER:
+	case IM_LURE_ACCEPTED:
+	case IM_LURE_DECLINED:
+	case IM_GODLIKE_LURE_USER:
+	case IM_YET_TO_BE_USED:
+	case IM_GROUP_ELECTION_DEPRECATED:
+	//IM_GOTO_URL
+	//IM_FROM_TASK_AS_ALERT
+	case IM_GROUP_NOTICE:
+	case IM_GROUP_NOTICE_INVENTORY_ACCEPTED:
+	case IM_GROUP_NOTICE_INVENTORY_DECLINED:
+	case IM_GROUP_INVITATION_ACCEPT:
+	case IM_GROUP_INVITATION_DECLINE:
+	case IM_GROUP_NOTICE_REQUESTED:
+	case IM_FRIENDSHIP_OFFERED:
+	case IM_FRIENDSHIP_ACCEPTED:
+	case IM_FRIENDSHIP_DECLINED_DEPRECATED:
+	//IM_TYPING_START
+	//IM_TYPING_STOP
+		return LLCacheName::cleanFullName(name);
+	default:
+		return name;
+	}
+}
+
+static std::string clean_name_from_task_im(const std::string& msg,
+										   BOOL from_group)
+{
+	boost::smatch match;
+	static const boost::regex returned_exp(
+		"(.*been returned to your inventory lost and found folder by )(.+)( (from|near).*)");
+	if (boost::regex_match(msg, match, returned_exp))
+	{
+		// match objects are 1-based for groups
+		std::string final = match[1].str();
+		std::string name = match[2].str();
+		// Don't try to clean up group names
+		if (!from_group)
+		{
+			if (LLAvatarNameCache::useDisplayNames())
+			{
+				// ...just convert to username
+				final += LLCacheName::buildUsername(name);
+			}
+			else
+			{
+				// ...strip out legacy "Resident" name
+				final += LLCacheName::cleanFullName(name);
+			}
+		}
+		final += match[3].str();
+		return final;
+	}
+	return msg;
+}
+
+void notification_display_name_callback(const LLUUID& id,
+					  const LLAvatarName& av_name,
+					  const std::string& name, 
+					  LLSD& substitutions, 
+					  const LLSD& payload)
+{
+	substitutions["NAME"] = av_name.mDisplayName;
+	LLNotificationsUtil::add(name, substitutions, payload);
+}
+
+class LLPostponedIMSystemTipNotification: public LLPostponedNotification
+{
+protected:
+	/* virtual */
+	void modifyNotificationParams()
+	{
+		LLSD payload = mParams.payload;
+		payload["SESSION_NAME"] = mName;
+		mParams.payload = payload;
+	}
+
+};
+
+// Callback for name resolution of a god/estate message
+void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
+{	
+	LLSD args;
+	args["NAME"] = av_name.getCompleteName();
+	args["MESSAGE"] = message;
+	LLNotificationsUtil::add("GodMessage", args);
+
+	// Treat like a system message and put in chat history.
+	chat.mText = av_name.getCompleteName() + ": " + message;
+
+	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
+	if(nearby_chat)
+	{
+		nearby_chat->addMessage(chat);
+	}
+
+}
+
+void process_improved_im(LLMessageSystem *msg, void **user_data)
+{
+	if (gNoRender)
+	{
+		return;
+	}
+	LLUUID from_id;
+	BOOL from_group;
+	LLUUID to_id;
+	U8 offline;
+	U8 d = 0;
+	LLUUID session_id;
+	U32 timestamp;
+	std::string name;
+	std::string message;
+	U32 parent_estate_id = 0;
+	LLUUID region_id;
+	LLVector3 position;
+	U8 binary_bucket[MTUBYTES];
+	S32 binary_bucket_size;
+	LLChat chat;
+	std::string buffer;
+	
+	// *TODO: Translate - need to fix the full name to first/last (maybe)
+	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, from_id);
+	msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, from_group);
+	msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, to_id);
+	msg->getU8Fast(  _PREHASH_MessageBlock, _PREHASH_Offline, offline);
+	msg->getU8Fast(  _PREHASH_MessageBlock, _PREHASH_Dialog, d);
+	msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id);
+	msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, timestamp);
+	//msg->getData("MessageBlock", "Count",		&count);
+	msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name);
+	msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message,		message);
+	msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, parent_estate_id);
+	msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, region_id);
+	msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, position);
+	msg->getBinaryDataFast(  _PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES);
+	binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
+	EInstantMessage dialog = (EInstantMessage)d;
+
+    // make sure that we don't have an empty or all-whitespace name
+	LLStringUtil::trim(name);
+	if (name.empty())
+	{
+        name = LLTrans::getString("Unnamed");
+	}
+	// IDEVO convert new-style "Resident" names for display
+	name = clean_name_from_im(name, dialog);
+
+	BOOL is_busy = gAgent.getBusy();
+	BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat);
+	BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
+	BOOL is_owned_by_me = FALSE;
+	BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
+	BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
+	
+	chat.mMuted = is_muted && !is_linden;
+	chat.mFromID = from_id;
+	chat.mFromName = name;
+	chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
+
+	LLViewerObject *source = gObjectList.findObject(session_id); //Session ID is probably the wrong thing.
+	if (source)
+	{
+		is_owned_by_me = source->permYouOwner();
+	}
+
+	std::string separator_string(": ");
+
+	LLSD args;
+	LLSD payload;
+	LLNotification::Params params;
+
+	switch(dialog)
+	{
+	case IM_CONSOLE_AND_CHAT_HISTORY:
+		args["MESSAGE"] = message;
+		payload["from_id"] = from_id;
+
+		params.name = "IMSystemMessageTip";
+		params.substitutions = args;
+		params.payload = payload;
+	    LLPostponedNotification::add<LLPostponedIMSystemTipNotification>(params, from_id, false);
+		break;
+
+	case IM_NOTHING_SPECIAL: 
+		// Don't show dialog, just do IM
+		if (!gAgent.isGodlike()
+				&& gAgent.getRegion()->isPrelude() 
+				&& to_id.isNull() )
+		{
+			// do nothing -- don't distract newbies in
+			// Prelude with global IMs
+		}
+		else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM)
+		{
+			// return a standard "busy" message, but only do it to online IM 
+			// (i.e. not other auto responses and not store-and-forward IM)
+			if (!gIMMgr->hasSession(session_id))
+			{
+				// if there is not a panel for this conversation (i.e. it is a new IM conversation
+				// initiated by the other party) then...
+				std::string my_name;
+				LLAgentUI::buildFullname(my_name);
+				std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
+				pack_instant_message(
+					gMessageSystem,
+					gAgent.getID(),
+					FALSE,
+					gAgent.getSessionID(),
+					from_id,
+					my_name,
+					response,
+					IM_ONLINE,
+					IM_BUSY_AUTO_RESPONSE,
+					session_id);
+				gAgent.sendReliableMessage();
+			}
+
+			// now store incoming IM in chat history
+
+			buffer = message;
+	
+			LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+			// add to IM panel, but do not bother the user
+			gIMMgr->addMessage(
+				session_id,
+				from_id,
+				name,
+				buffer,
+				LLStringUtil::null,
+				dialog,
+				parent_estate_id,
+				region_id,
+				position,
+				true);
+		}
+		else if (from_id.isNull())
+		{
+			LLSD args;
+			args["MESSAGE"] = message;
+			LLNotificationsUtil::add("SystemMessage", args);
+		}
+		else if (to_id.isNull())
+		{
+			// Message to everyone from GOD, look up the fullname since
+			// server always slams name to legacy names
+			LLAvatarNameCache::get(from_id, boost::bind(god_message_name_cb, _2, chat, message));
+		}
+		else
+		{
+			// standard message, not from system
+			std::string saved;
+			if(offline == IM_OFFLINE)
+			{
+				LLStringUtil::format_map_t args;
+				args["[LONG_TIMESTAMP]"] = formatted_time(timestamp);
+				saved = LLTrans::getString("Saved_message", args);
+			}
+			buffer = saved + message;
+
+			LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+			bool mute_im = is_muted;
+			if(accept_im_from_only_friend&&!is_friend)
+			{
+				mute_im = true;
+			}
+			if (!mute_im || is_linden) 
+			{
+				gIMMgr->addMessage(
+					session_id,
+					from_id,
+					name,
+					buffer,
+					LLStringUtil::null,
+					dialog,
+					parent_estate_id,
+					region_id,
+					position,
+					true);
+			}
+			else
+			{
+				/*
+				EXT-5099
+				currently there is no way to store in history only...
+				using  LLNotificationsUtil::add will add message to Nearby Chat
+
+				// muted user, so don't start an IM session, just record line in chat
+				// history.  Pretend the chat is from a local agent,
+				// so it will go into the history but not be shown on screen.
+
+				LLSD args;
+				args["MESSAGE"] = buffer;
+				LLNotificationsUtil::add("SystemMessageTip", args);
+				*/
+			}
+		}
+		break;
+
+	case IM_TYPING_START:
+		{
+			LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
+			gIMMgr->processIMTypingStart(im_info);
+		}
+		break;
+
+	case IM_TYPING_STOP:
+		{
+			LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
+			gIMMgr->processIMTypingStop(im_info);
+		}
+		break;
+
+	case IM_MESSAGEBOX:
+		{
+			// This is a block, modeless dialog.
+			//*TODO: Translate
+			args["MESSAGE"] = message;
+			LLNotificationsUtil::add("SystemMessageTip", args);
+		}
+		break;
+	case IM_GROUP_NOTICE:
+	case IM_GROUP_NOTICE_REQUESTED:
+		{
+			LL_INFOS("Messaging") << "Received IM_GROUP_NOTICE message." << LL_ENDL;
+			// Read the binary bucket for more information.
+			struct notice_bucket_header_t
+			{
+				U8 has_inventory;
+				U8 asset_type;
+				LLUUID group_id;
+			};
+			struct notice_bucket_full_t
+			{
+				struct notice_bucket_header_t header;
+				U8 item_name[DB_INV_ITEM_NAME_BUF_SIZE];
+			}* notice_bin_bucket;
+
+			// Make sure the binary bucket is big enough to hold the header 
+			// and a null terminated item name.
+			if ( (binary_bucket_size < (S32)((sizeof(notice_bucket_header_t) + sizeof(U8))))
+				|| (binary_bucket[binary_bucket_size - 1] != '\0') )
+			{
+				LL_WARNS("Messaging") << "Malformed group notice binary bucket" << LL_ENDL;
+				break;
+			}
+
+			notice_bin_bucket = (struct notice_bucket_full_t*) &binary_bucket[0];
+			U8 has_inventory = notice_bin_bucket->header.has_inventory;
+			U8 asset_type = notice_bin_bucket->header.asset_type;
+			LLUUID group_id = notice_bin_bucket->header.group_id;
+			std::string item_name = ll_safe_string((const char*) notice_bin_bucket->item_name);
+
+			// If there is inventory, give the user the inventory offer.
+			LLOfferInfo* info = NULL;
+
+			if (has_inventory)
+			{
+				info = new LLOfferInfo();
+				
+				info->mIM = IM_GROUP_NOTICE;
+				info->mFromID = from_id;
+				info->mFromGroup = from_group;
+				info->mTransactionID = session_id;
+				info->mType = (LLAssetType::EType) asset_type;
+				info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
+				std::string from_name;
+
+				from_name += "A group member named ";
+				from_name += name;
+
+				info->mFromName = from_name;
+				info->mDesc = item_name;
+				info->mHost = msg->getSender();
+			}
+			
+			std::string str(message);
+
+			// Tokenize the string.
+			// TODO: Support escaped tokens ("||" -> "|")
+			typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+			boost::char_separator<char> sep("|","",boost::keep_empty_tokens);
+			tokenizer tokens(str, sep);
+			tokenizer::iterator iter = tokens.begin();
+
+			std::string subj(*iter++);
+			std::string mes(*iter++);
+
+			// Send the notification down the new path.
+			// For requested notices, we don't want to send the popups.
+			if (dialog != IM_GROUP_NOTICE_REQUESTED)
+			{
+				payload["subject"] = subj;
+				payload["message"] = mes;
+				payload["sender_name"] = name;
+				payload["group_id"] = group_id;
+				payload["inventory_name"] = item_name;
+				payload["inventory_offer"] = info ? info->asLLSD() : LLSD();
+
+				LLSD args;
+				args["SUBJECT"] = subj;
+				args["MESSAGE"] = mes;
+				LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(timestamp));
+			}
+
+			// Also send down the old path for now.
+			if (IM_GROUP_NOTICE_REQUESTED == dialog)
+			{
+				
+				LLPanelGroup::showNotice(subj,mes,group_id,has_inventory,item_name,info);
+			}
+			else
+			{
+				delete info;
+			}
+		}
+		break;
+	case IM_GROUP_INVITATION:
+		{
+			//if (!is_linden && (is_busy || is_muted))
+			if ((is_busy || is_muted))
+			{
+				LLMessageSystem *msg = gMessageSystem;
+				busy_message(msg,from_id);
+			}
+			else
+			{
+				LL_INFOS("Messaging") << "Received IM_GROUP_INVITATION message." << LL_ENDL;
+				// Read the binary bucket for more information.
+				struct invite_bucket_t
+				{
+					S32 membership_fee;
+					LLUUID role_id;
+				}* invite_bucket;
+
+				// Make sure the binary bucket is the correct size.
+				if (binary_bucket_size != sizeof(invite_bucket_t))
+				{
+					LL_WARNS("Messaging") << "Malformed group invite binary bucket" << LL_ENDL;
+					break;
+				}
+
+				invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];
+				S32 membership_fee = ntohl(invite_bucket->membership_fee);
+
+				LLSD payload;
+				payload["transaction_id"] = session_id;
+				payload["group_id"] = from_id;
+				payload["name"] = name;
+				payload["message"] = message;
+				payload["fee"] = membership_fee;
+
+				LLSD args;
+				args["MESSAGE"] = message;
+				// we shouldn't pass callback functor since it is registered in LLFunctorRegistration
+				LLNotificationsUtil::add("JoinGroup", args, payload);
+			}
+		}
+		break;
+
+	case IM_INVENTORY_OFFERED:
+	case IM_TASK_INVENTORY_OFFERED:
+		// Someone has offered us some inventory.
+		{
+			LLOfferInfo* info = new LLOfferInfo;
+			if (IM_INVENTORY_OFFERED == dialog)
+			{
+				struct offer_agent_bucket_t
+				{
+					S8		asset_type;
+					LLUUID	object_id;
+				}* bucketp;
+
+				if (sizeof(offer_agent_bucket_t) != binary_bucket_size)
+				{
+					LL_WARNS("Messaging") << "Malformed inventory offer from agent" << LL_ENDL;
+					delete info;
+					break;
+				}
+				bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
+				info->mType = (LLAssetType::EType) bucketp->asset_type;
+				info->mObjectID = bucketp->object_id;
+			}
+			else
+			{
+				if (sizeof(S8) != binary_bucket_size)
+				{
+					LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
+					delete info;
+					break;
+				}
+				info->mType = (LLAssetType::EType) binary_bucket[0];
+				info->mObjectID = LLUUID::null;
+			}
+
+			info->mIM = dialog;
+			info->mFromID = from_id;
+			info->mFromGroup = from_group;
+			info->mTransactionID = session_id;
+			info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
+
+			if (dialog == IM_TASK_INVENTORY_OFFERED)
+			{
+				info->mFromObject = TRUE;
+			}
+			else
+			{
+				info->mFromObject = FALSE;
+			}
+			info->mFromName = name;
+			info->mDesc = message;
+			info->mHost = msg->getSender();
+			//if (((is_busy && !is_owned_by_me) || is_muted))
+			if (is_muted)
+			{
+				// Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
+				LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
+				fetch_item->startFetch();
+				delete fetch_item;
+
+				// Same as closing window
+				info->forceResponse(IOR_DECLINE);
+			}
+			else
+			{
+				inventory_offer_handler(info);
+			}
+		}
+		break;
+
+	case IM_INVENTORY_ACCEPTED:
+	{
+		args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
+		LLSD payload;
+		payload["from_id"] = from_id;
+		LLNotificationsUtil::add("InventoryAccepted", args, payload);
+		break;
+	}
+	case IM_INVENTORY_DECLINED:
+	{
+		args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
+		LLSD payload;
+		payload["from_id"] = from_id;
+		LLNotificationsUtil::add("InventoryDeclined", args, payload);
+		break;
+	}
+	// TODO: _DEPRECATED suffix as part of vote removal - DEV-24856
+	case IM_GROUP_VOTE:
+		{
+			LL_WARNS("Messaging") << "Received IM: IM_GROUP_VOTE_DEPRECATED" << LL_ENDL;
+		}
+		break;
+
+	case IM_GROUP_ELECTION_DEPRECATED:
+	{
+		LL_WARNS("Messaging") << "Received IM: IM_GROUP_ELECTION_DEPRECATED" << LL_ENDL;
+	}
+	break;
+	
+	case IM_SESSION_SEND:
+	{
+		if (!is_linden && is_busy)
+		{
+			return;
+		}
+
+		// Only show messages if we have a session open (which
+		// should happen after you get an "invitation"
+		if ( !gIMMgr->hasSession(session_id) )
+		{
+			return;
+		}
+
+		// standard message, not from system
+		std::string saved;
+		if(offline == IM_OFFLINE)
+		{
+			saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
+		}
+		buffer = saved + message;
+		BOOL is_this_agent = FALSE;
+		if(from_id == gAgentID)
+		{
+			is_this_agent = TRUE;
+		}
+		gIMMgr->addMessage(
+			session_id,
+			from_id,
+			name,
+			buffer,
+			ll_safe_string((char*)binary_bucket),
+			IM_SESSION_INVITE,
+			parent_estate_id,
+			region_id,
+			position,
+			true);
+	}
+	break;
+
+	case IM_FROM_TASK:
+		{
+			if (is_busy && !is_owned_by_me)
+			{
+				return;
+			}
+
+			// Build a link to open the object IM info window.
+			std::string location = ll_safe_string((char*)binary_bucket, binary_bucket_size-1);
+
+			if (session_id.notNull())
+			{
+				chat.mFromID = session_id;
+			}
+			else
+			{
+				// This message originated on a region without the updated code for task id and slurl information.
+				// We just need a unique ID for this object that isn't the owner ID.
+				// If it is the owner ID it will overwrite the style that contains the link to that owner's profile.
+				// This isn't ideal - it will make 1 style for all objects owned by the the same person/group.
+				// This works because the only thing we can really do in this case is show the owner name and link to their profile.
+				chat.mFromID = from_id ^ gAgent.getSessionID();
+			}
+
+			chat.mSourceType = CHAT_SOURCE_OBJECT;
+
+			if(SYSTEM_FROM == name)
+			{
+				// System's UUID is NULL (fixes EXT-4766)
+				chat.mFromID = LLUUID::null;
+				chat.mSourceType = CHAT_SOURCE_SYSTEM;
+			}
+
+			// IDEVO Some messages have embedded resident names
+			message = clean_name_from_task_im(message, from_group);
+
+			LLSD query_string;
+			query_string["owner"] = from_id;
+			query_string["slurl"] = location;
+			query_string["name"] = name;
+			if (from_group)
+			{
+				query_string["groupowned"] = "true";
+			}	
+
+			chat.mURL = LLSLURL("objectim", session_id, "").getSLURLString();
+			chat.mText = message;
+
+			// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
+			// IMs from obejcts don't open IM sessions.
+			LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
+			if(SYSTEM_FROM != name && nearby_chat)
+			{
+				chat.mOwnerID = from_id;
+				LLSD args;
+				args["slurl"] = location;
+				args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
+
+				// Look for IRC-style emotes here so object name formatting is correct
+				std::string prefix = message.substr(0, 4);
+				if (prefix == "/me " || prefix == "/me'")
+				{
+					chat.mChatStyle = CHAT_STYLE_IRC;
+				}
+
+				LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
+			}
+
+
+			//Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590)
+			if (SYSTEM_FROM != name) break;
+			
+			LLSD substitutions;
+			substitutions["NAME"] = name;
+			substitutions["MSG"] = message;
+
+			LLSD payload;
+			payload["object_id"] = session_id;
+			payload["owner_id"] = from_id;
+			payload["from_id"] = from_id;
+			payload["slurl"] = location;
+			payload["name"] = name;
+			std::string session_name;
+			if (from_group)
+			{
+				payload["group_owned"] = "true";
+			}
+
+			LLNotification::Params params("ServerObjectMessage");
+			params.substitutions = substitutions;
+			params.payload = payload;
+
+			LLPostponedNotification::add<LLPostponedServerObjectNotification>(params, from_id, from_group);
+		}
+		break;
+	case IM_FROM_TASK_AS_ALERT:
+		if (is_busy && !is_owned_by_me)
+		{
+			return;
+		}
+		{
+			// Construct a viewer alert for this message.
+			args["NAME"] = name;
+			args["MESSAGE"] = message;
+			LLNotificationsUtil::add("ObjectMessage", args);
+		}
+		break;
+	case IM_BUSY_AUTO_RESPONSE:
+		if (is_muted)
+		{
+			LL_DEBUGS("Messaging") << "Ignoring busy response from " << from_id << LL_ENDL;
+			return;
+		}
+		else
+		{
+			// TODO: after LLTrans hits release, get "busy response" into translatable file
+			buffer = llformat("%s (%s): %s", name.c_str(), "busy response", message.c_str());
+			gIMMgr->addMessage(session_id, from_id, name, buffer);
+		}
+		break;
+		
+	case IM_LURE_USER:
+		{
+			if (is_muted)
+			{ 
+				return;
+			}
+			else if (is_busy) 
+			{
+				busy_message(msg,from_id);
+			}
+			else
+			{
+				LLVector3 pos, look_at;
+				U64 region_handle;
+				U8 region_access = SIM_ACCESS_MIN;
+				std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
+				std::string region_access_str = LLStringUtil::null;
+				std::string region_access_icn = LLStringUtil::null;
+
+				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("agent", from_id, "about").getSLURLString();
+				args["MESSAGE"] = message;
+				args["MATURITY_STR"] = region_access_str;
+				args["MATURITY_ICON"] = region_access_icn;
+				LLSD payload;
+				payload["from_id"] = from_id;
+				payload["lure_id"] = session_id;
+				payload["godlike"] = FALSE;
+
+			    LLNotification::Params params("TeleportOffered");
+			    params.substitutions = args;
+			    params.payload = payload;
+			    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
+			}
+		}
+		break;
+
+	case IM_GODLIKE_LURE_USER:
+		{
+			LLSD payload;
+			payload["from_id"] = from_id;
+			payload["lure_id"] = session_id;
+			payload["godlike"] = TRUE;
+			// do not show a message box, because you're about to be
+			// teleported.
+			LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
+		}
+		break;
+
+	case IM_GOTO_URL:
+		{
+			LLSD args;
+			// n.b. this is for URLs sent by the system, not for
+			// URLs sent by scripts (i.e. llLoadURL)
+			if (binary_bucket_size <= 0)
+			{
+				LL_WARNS("Messaging") << "bad binary_bucket_size: "
+					<< binary_bucket_size
+					<< " - aborting function." << LL_ENDL;
+				return;
+			}
+
+			std::string url;
+			
+			url.assign((char*)binary_bucket, binary_bucket_size-1);
+			args["MESSAGE"] = message;
+			args["URL"] = url;
+			LLSD payload;
+			payload["url"] = url;
+			LLNotificationsUtil::add("GotoURL", args, payload );
+		}
+		break;
+
+	case IM_FRIENDSHIP_OFFERED:
+		{
+			LLSD payload;
+			payload["from_id"] = from_id;
+			payload["session_id"] = session_id;;
+			payload["online"] = (offline == IM_ONLINE);
+			payload["sender"] = msg->getSender().getIPandPort();
+
+			if (is_busy)
+			{
+				busy_message(msg, from_id);
+				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
+			}
+			else if (is_muted)
+			{
+				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
+			}
+			else
+			{
+				args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
+				if(message.empty())
+				{
+					//support for frienship offers from clients before July 2008
+				        LLNotificationsUtil::add("OfferFriendshipNoMessage", args, payload);
+				}
+				else
+				{
+					args["[MESSAGE]"] = message;
+				    LLNotification::Params params("OfferFriendship");
+				    params.substitutions = args;
+				    params.payload = payload;
+				    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
+				}
+			}
+		}
+		break;
+
+	case IM_FRIENDSHIP_ACCEPTED:
+		{
+			// In the case of an offline IM, the formFriendship() may be extraneous
+			// as the database should already include the relationship.  But it
+			// doesn't hurt for dupes.
+			LLAvatarTracker::formFriendship(from_id);
+			
+			std::vector<std::string> strings;
+			strings.push_back(from_id.asString());
+			send_generic_message("requestonlinenotification", strings);
+			
+			args["NAME"] = name;
+			LLSD payload;
+			payload["from_id"] = from_id;
+			LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback,
+														 _1,
+														 _2,
+														 "FriendshipAccepted",
+														 args,
+														 payload));
+		}
+		break;
+
+	case IM_FRIENDSHIP_DECLINED_DEPRECATED:
+	default:
+		LL_WARNS("Messaging") << "Instant message calling for unknown dialog "
+				<< (S32)dialog << LL_ENDL;
+		break;
+	}
+
+	LLWindow* viewer_window = gViewerWindow->getWindow();
+	if (viewer_window && viewer_window->getMinimized())
+	{
+		viewer_window->flashIcon(5.f);
+	}
+}
+
+void busy_message (LLMessageSystem* msg, LLUUID from_id) 
+{
+	if (gAgent.getBusy())
+	{
+		std::string my_name;
+		LLAgentUI::buildFullname(my_name);
+		std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
+		pack_instant_message(
+			gMessageSystem,
+			gAgent.getID(),
+			FALSE,
+			gAgent.getSessionID(),
+			from_id,
+			my_name,
+			response,
+			IM_ONLINE,
+			IM_BUSY_AUTO_RESPONSE);
+		gAgent.sendReliableMessage();
+	}
+}
+
+bool callingcard_offer_callback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	LLUUID fid;
+	LLUUID from_id;
+	LLMessageSystem* msg = gMessageSystem;
+	switch(option)
+	{
+	case 0:
+		// accept
+		msg->newMessageFast(_PREHASH_AcceptCallingCard);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->nextBlockFast(_PREHASH_TransactionBlock);
+		msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
+		fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+		msg->nextBlockFast(_PREHASH_FolderData);
+		msg->addUUIDFast(_PREHASH_FolderID, fid);
+		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
+		break;
+	case 1:
+		// decline		
+		msg->newMessageFast(_PREHASH_DeclineCallingCard);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->nextBlockFast(_PREHASH_TransactionBlock);
+		msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
+		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
+		busy_message(msg, notification["payload"]["source_id"].asUUID());
+		break;
+	default:
+		// close button probably, possibly timed out
+		break;
+	}
+
+	return false;
+}
+static LLNotificationFunctorRegistration callingcard_offer_cb_reg("OfferCallingCard", callingcard_offer_callback);
+
+void process_offer_callingcard(LLMessageSystem* msg, void**)
+{
+	// someone has offered to form a friendship
+	LL_DEBUGS("Messaging") << "callingcard offer" << LL_ENDL;
+
+	LLUUID source_id;
+	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, source_id);
+	LLUUID tid;
+	msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_TransactionID, tid);
+
+	LLSD payload;
+	payload["transaction_id"] = tid;
+	payload["source_id"] = source_id;
+	payload["sender"] = msg->getSender().getIPandPort();
+
+	LLViewerObject* source = gObjectList.findObject(source_id);
+	LLSD args;
+	std::string source_name;
+	if(source && source->isAvatar())
+	{
+		LLNameValue* nvfirst = source->getNVPair("FirstName");
+		LLNameValue* nvlast  = source->getNVPair("LastName");
+		if (nvfirst && nvlast)
+		{
+			source_name = LLCacheName::buildFullName(
+				nvfirst->getString(), nvlast->getString());
+		}
+	}
+
+	if(!source_name.empty())
+	{
+		if (gAgent.getBusy() 
+			|| LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat))
+		{
+			// automatically decline offer
+			LLNotifications::instance().forceResponse(LLNotification::Params("OfferCallingCard").payload(payload), 1);
+		}
+		else
+		{
+			args["NAME"] = source_name;
+			LLNotificationsUtil::add("OfferCallingCard", args, payload);
+		}
+	}
+	else
+	{
+		LL_WARNS("Messaging") << "Calling card offer from an unknown source." << LL_ENDL;
+	}
+}
+
+void process_accept_callingcard(LLMessageSystem* msg, void**)
+{
+	LLNotificationsUtil::add("CallingCardAccepted");
+}
+
+void process_decline_callingcard(LLMessageSystem* msg, void**)
+{
+	LLNotificationsUtil::add("CallingCardDeclined");
+}
+
+class ChatTranslationReceiver : public LLTranslate::TranslationReceiver
+{
+public :
+	ChatTranslationReceiver(const std::string &from_lang, const std::string &to_lang, const std::string &mesg,
+							const LLChat &chat, const LLSD &toast_args)
+		: LLTranslate::TranslationReceiver(from_lang, to_lang),
+		m_chat(chat),
+		m_toastArgs(toast_args),
+		m_origMesg(mesg)
+	{
+	}
+
+	static boost::intrusive_ptr<ChatTranslationReceiver> build(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, const LLChat &chat, const LLSD &toast_args)
+	{
+		return boost::intrusive_ptr<ChatTranslationReceiver>(new ChatTranslationReceiver(from_lang, to_lang, mesg, chat, toast_args));
+	}
+
+protected:
+	void handleResponse(const std::string &translation, const std::string &detected_language)
+	{
+		// filter out non-interesting responeses
+		if ( !translation.empty()
+			&& (m_toLang != detected_language)
+			&& (LLStringUtil::compareInsensitive(translation, m_origMesg) != 0) )
+		{
+			m_chat.mText += " (" + translation + ")";
+		}
+
+		LLNotificationsUI::LLNotificationManager::instance().onChat(m_chat, m_toastArgs);
+	}
+
+	void handleFailure()
+	{
+		LLTranslate::TranslationReceiver::handleFailure();
+		m_chat.mText += " (?)";
+
+		LLNotificationsUI::LLNotificationManager::instance().onChat(m_chat, m_toastArgs);
+	}
+
+private:
+	LLChat m_chat;
+	std::string m_origMesg;
+	LLSD m_toastArgs;		
+};
+void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
+{
+	LLChat	chat;
+	std::string		mesg;
+	std::string		from_name;
+	U8			source_temp;
+	U8			type_temp;
+	U8			audible_temp;
+	LLColor4	color(1.0f, 1.0f, 1.0f, 1.0f);
+	LLUUID		from_id;
+	LLUUID		owner_id;
+	BOOL		is_owned_by_me = FALSE;
+	LLViewerObject*	chatter;
+
+	msg->getString("ChatData", "FromName", from_name);
+	
+	msg->getUUID("ChatData", "SourceID", from_id);
+	chat.mFromID = from_id;
+	
+	// Object owner for objects
+	msg->getUUID("ChatData", "OwnerID", owner_id);
+
+	msg->getU8Fast(_PREHASH_ChatData, _PREHASH_SourceType, source_temp);
+	chat.mSourceType = (EChatSourceType)source_temp;
+
+	msg->getU8("ChatData", "ChatType", type_temp);
+	chat.mChatType = (EChatType)type_temp;
+
+	msg->getU8Fast(_PREHASH_ChatData, _PREHASH_Audible, audible_temp);
+	chat.mAudible = (EChatAudible)audible_temp;
+	
+	chat.mTime = LLFrameTimer::getElapsedSeconds();
+	
+	// IDEVO Correct for new-style "Resident" names
+	if (chat.mSourceType == CHAT_SOURCE_AGENT)
+	{
+		// I don't know if it's OK to change this here, if 
+		// anything downstream does lookups by name, for instance
+		
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(from_id, &av_name))
+		{
+			chat.mFromName = av_name.mDisplayName;
+		}
+		else
+		{
+			chat.mFromName = LLCacheName::cleanFullName(from_name);
+		}
+	}
+	else
+	{
+		chat.mFromName = from_name;
+	}
+
+	BOOL is_busy = gAgent.getBusy();
+
+	BOOL is_muted = FALSE;
+	BOOL is_linden = FALSE;
+	is_muted = LLMuteList::getInstance()->isMuted(
+		from_id,
+		from_name,
+		LLMute::flagTextChat) 
+		|| LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagTextChat);
+	is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
+		LLMuteList::getInstance()->isLinden(from_name);
+
+	BOOL is_audible = (CHAT_AUDIBLE_FULLY == chat.mAudible);
+	chatter = gObjectList.findObject(from_id);
+	if (chatter)
+	{
+		chat.mPosAgent = chatter->getPositionAgent();
+
+		// Make swirly things only for talking objects. (not script debug messages, though)
+		if (chat.mSourceType == CHAT_SOURCE_OBJECT 
+			&& chat.mChatType != CHAT_TYPE_DEBUG_MSG
+			&& gSavedSettings.getBOOL("EffectScriptChatParticles") )
+		{
+			LLPointer<LLViewerPartSourceChat> psc = new LLViewerPartSourceChat(chatter->getPositionAgent());
+			psc->setSourceObject(chatter);
+			psc->setColor(color);
+			//We set the particles to be owned by the object's owner, 
+			//just in case they should be muted by the mute list
+			psc->setOwnerUUID(owner_id);
+			LLViewerPartSim::getInstance()->addPartSource(psc);
+		}
+
+		// record last audible utterance
+		if (is_audible
+			&& (is_linden || (!is_muted && !is_busy)))
+		{
+			if (chat.mChatType != CHAT_TYPE_START 
+				&& chat.mChatType != CHAT_TYPE_STOP)
+			{
+				gAgent.heardChat(chat.mFromID);
+			}
+		}
+
+		is_owned_by_me = chatter->permYouOwner();
+	}
+
+	if (is_audible)
+	{
+		BOOL visible_in_chat_bubble = FALSE;
+		std::string verb;
+
+		color.setVec(1.f,1.f,1.f,1.f);
+		msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg);
+
+		BOOL ircstyle = FALSE;
+
+		// Look for IRC-style emotes here so chatbubbles work
+		std::string prefix = mesg.substr(0, 4);
+		if (prefix == "/me " || prefix == "/me'")
+		{
+			ircstyle = TRUE;
+		}
+		chat.mText = mesg;
+
+		// Look for the start of typing so we can put "..." in the bubbles.
+		if (CHAT_TYPE_START == chat.mChatType)
+		{
+			LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, TRUE);
+
+			// Might not have the avatar constructed yet, eg on login.
+			if (chatter && chatter->isAvatar())
+			{
+				((LLVOAvatar*)chatter)->startTyping();
+			}
+			return;
+		}
+		else if (CHAT_TYPE_STOP == chat.mChatType)
+		{
+			LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE);
+
+			// Might not have the avatar constructed yet, eg on login.
+			if (chatter && chatter->isAvatar())
+			{
+				((LLVOAvatar*)chatter)->stopTyping();
+			}
+			return;
+		}
+
+		// Look for IRC-style emotes
+		if (ircstyle)
+		{
+			// set CHAT_STYLE_IRC to avoid adding Avatar Name as author of message. See EXT-656
+			chat.mChatStyle = CHAT_STYLE_IRC;
+
+			// Do nothing, ircstyle is fixed above for chat bubbles
+		}
+		else
+		{
+			switch(chat.mChatType)
+			{
+			case CHAT_TYPE_WHISPER:
+				verb = LLTrans::getString("whisper") + " ";
+				break;
+			case CHAT_TYPE_DEBUG_MSG:
+			case CHAT_TYPE_OWNER:
+			case CHAT_TYPE_NORMAL:
+				verb = "";
+				break;
+			case CHAT_TYPE_SHOUT:
+				verb = LLTrans::getString("shout") + " ";
+				break;
+			case CHAT_TYPE_START:
+			case CHAT_TYPE_STOP:
+				LL_WARNS("Messaging") << "Got chat type start/stop in main chat processing." << LL_ENDL;
+				break;
+			default:
+				LL_WARNS("Messaging") << "Unknown type " << chat.mChatType << " in chat!" << LL_ENDL;
+				verb = "";
+				break;
+			}
+
+
+			chat.mText = "";
+			chat.mText += verb;
+			chat.mText += mesg;
+		}
+		
+		// We have a real utterance now, so can stop showing "..." and proceed.
+		if (chatter && chatter->isAvatar())
+		{
+			LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE);
+			((LLVOAvatar*)chatter)->stopTyping();
+			
+			if (!is_muted && !is_busy)
+			{
+				visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");
+				std::string formated_msg = "";
+				LLViewerChat::formatChatMsg(chat, formated_msg);
+				LLChat chat_bubble = chat;
+				chat_bubble.mText = formated_msg;
+				((LLVOAvatar*)chatter)->addChat(chat_bubble);
+			}
+		}
+		
+		if (chatter)
+		{
+			chat.mPosAgent = chatter->getPositionAgent();
+		}
+
+		// truth table:
+		// LINDEN	BUSY	MUTED	OWNED_BY_YOU	TASK		DISPLAY		STORE IN HISTORY
+		// F		F		F		F				*			Yes			Yes
+		// F		F		F		T				*			Yes			Yes
+		// F		F		T		F				*			No			No
+		// F		F		T		T				*			No			No
+		// F		T		F		F				*			No			Yes
+		// F		T		F		T				*			Yes			Yes
+		// F		T		T		F				*			No			No
+		// F		T		T		T				*			No			No
+		// T		*		*		*				F			Yes			Yes
+
+		chat.mMuted = is_muted && !is_linden;
+
+		// pass owner_id to chat so that we can display the remote
+		// object inspect for an object that is chatting with you
+		LLSD args;
+		args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
+		chat.mOwnerID = owner_id;
+
+		if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM)
+		{
+			if (chat.mChatStyle == CHAT_STYLE_IRC)
+			{
+				mesg = mesg.substr(4, std::string::npos);
+			}
+			const std::string from_lang = ""; // leave empty to trigger autodetect
+			const std::string to_lang = LLTranslate::getTranslateLanguage();
+
+			LLHTTPClient::ResponderPtr result = ChatTranslationReceiver::build(from_lang, to_lang, mesg, chat, args);
+			LLTranslate::translateMessage(result, from_lang, to_lang, mesg);
+		}
+		else
+		{
+			LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
+		}
+	}
+}
+
+
+// Simulator we're on is informing the viewer that the agent
+// is starting to teleport (perhaps to another sim, perhaps to the 
+// same sim). If we initiated the teleport process by sending some kind 
+// of TeleportRequest, then this info is redundant, but if the sim 
+// initiated the teleport (via a script call, being killed, etc.) 
+// then this info is news to us.
+void process_teleport_start(LLMessageSystem *msg, void**)
+{
+	// on teleport, don't tell them about destination guide anymore
+	LLFirstUse::notUsingDestinationGuide(false);
+	U32 teleport_flags = 0x0;
+	msg->getU32("Info", "TeleportFlags", teleport_flags);
+
+	LL_DEBUGS("Messaging") << "Got TeleportStart with TeleportFlags=" << teleport_flags << ". gTeleportDisplay: " << gTeleportDisplay << ", gAgent.mTeleportState: " << gAgent.getTeleportState() << LL_ENDL;
+
+	if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL)
+	{
+		gViewerWindow->setProgressCancelButtonVisible(FALSE);
+	}
+	else
+	{
+		gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Cancel"));
+	}
+
+	// Freeze the UI and show progress bar
+	// Note: could add data here to differentiate between normal teleport and death.
+
+	if( gAgent.getTeleportState() == LLAgent::TELEPORT_NONE )
+	{
+		gTeleportDisplay = TRUE;
+		gAgent.setTeleportState( LLAgent::TELEPORT_START );
+		make_ui_sound("UISndTeleportOut");
+		
+		LL_INFOS("Messaging") << "Teleport initiated by remote TeleportStart message with TeleportFlags: " <<  teleport_flags << LL_ENDL;
+		// Don't call LLFirstUse::useTeleport here because this could be
+		// due to being killed, which would send you home, not to a Telehub
+	}
+}
+
+void process_teleport_progress(LLMessageSystem* msg, void**)
+{
+	LLUUID agent_id;
+	msg->getUUID("AgentData", "AgentID", agent_id);
+	if((gAgent.getID() != agent_id)
+	   || (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE))
+	{
+		LL_WARNS("Messaging") << "Unexpected teleport progress message." << LL_ENDL;
+		return;
+	}
+	U32 teleport_flags = 0x0;
+	msg->getU32("Info", "TeleportFlags", teleport_flags);
+	if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL)
+	{
+		gViewerWindow->setProgressCancelButtonVisible(FALSE);
+	}
+	else
+	{
+		gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Cancel"));
+	}
+	std::string buffer;
+	msg->getString("Info", "Message", buffer);
+	LL_DEBUGS("Messaging") << "teleport progress: " << buffer << LL_ENDL;
+
+	//Sorta hacky...default to using simulator raw messages
+	//if we don't find the coresponding mapping in our progress mappings
+	std::string message = buffer;
+
+	if (LLAgent::sTeleportProgressMessages.find(buffer) != 
+		LLAgent::sTeleportProgressMessages.end() )
+	{
+		message = LLAgent::sTeleportProgressMessages[buffer];
+	}
+
+	gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages[message]);
+}
+
+class LLFetchInWelcomeArea : public LLInventoryFetchDescendentsObserver
+{
+public:
+	LLFetchInWelcomeArea(const uuid_vec_t &ids) :
+		LLInventoryFetchDescendentsObserver(ids)
+	{}
+	virtual void done()
+	{
+		LLIsType is_landmark(LLAssetType::AT_LANDMARK);
+		LLIsType is_card(LLAssetType::AT_CALLINGCARD);
+
+		LLInventoryModel::cat_array_t	card_cats;
+		LLInventoryModel::item_array_t	card_items;
+		LLInventoryModel::cat_array_t	land_cats;
+		LLInventoryModel::item_array_t	land_items;
+
+		uuid_vec_t::iterator it = mComplete.begin();
+		uuid_vec_t::iterator end = mComplete.end();
+		for(; it != end; ++it)
+		{
+			gInventory.collectDescendentsIf(
+				(*it),
+				land_cats,
+				land_items,
+				LLInventoryModel::EXCLUDE_TRASH,
+				is_landmark);
+			gInventory.collectDescendentsIf(
+				(*it),
+				card_cats,
+				card_items,
+				LLInventoryModel::EXCLUDE_TRASH,
+				is_card);
+		}
+		LLSD args;
+		if ( land_items.count() > 0 )
+		{	// Show notification that they can now teleport to landmarks.  Use a random landmark from the inventory
+			S32 random_land = ll_rand( land_items.count() - 1 );
+			args["NAME"] = land_items[random_land]->getName();
+			LLNotificationsUtil::add("TeleportToLandmark",args);
+		}
+		if ( card_items.count() > 0 )
+		{	// Show notification that they can now contact people.  Use a random calling card from the inventory
+			S32 random_card = ll_rand( card_items.count() - 1 );
+			args["NAME"] = card_items[random_card]->getName();
+			LLNotificationsUtil::add("TeleportToPerson",args);
+		}
+
+		gInventory.removeObserver(this);
+		delete this;
+	}
+};
+
+
+
+class LLPostTeleportNotifiers : public LLEventTimer 
+{
+public:
+	LLPostTeleportNotifiers();
+	virtual ~LLPostTeleportNotifiers();
+
+	//function to be called at the supplied frequency
+	virtual BOOL tick();
+};
+
+LLPostTeleportNotifiers::LLPostTeleportNotifiers() : LLEventTimer( 2.0 )
+{
+};
+
+LLPostTeleportNotifiers::~LLPostTeleportNotifiers()
+{
+}
+
+BOOL LLPostTeleportNotifiers::tick()
+{
+	BOOL all_done = FALSE;
+	if ( gAgent.getTeleportState() == LLAgent::TELEPORT_NONE )
+	{
+		// get callingcards and landmarks available to the user arriving.
+		uuid_vec_t folders;
+		const LLUUID callingcard_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+		if(callingcard_id.notNull()) 
+			folders.push_back(callingcard_id);
+		const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
+		if(folder_id.notNull()) 
+			folders.push_back(folder_id);
+		if(!folders.empty())
+		{
+			LLFetchInWelcomeArea* fetcher = new LLFetchInWelcomeArea(folders);
+			fetcher->startFetch();
+			if(fetcher->isFinished())
+			{
+				fetcher->done();
+			}
+			else
+			{
+				gInventory.addObserver(fetcher);
+			}
+		}
+		all_done = TRUE;
+	}
+
+	return all_done;
+}
+
+
+
+// Teleport notification from the simulator
+// We're going to pretend to be a new agent
+void process_teleport_finish(LLMessageSystem* msg, void**)
+{
+	LL_DEBUGS("Messaging") << "Got teleport location message" << LL_ENDL;
+	LLUUID agent_id;
+	msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
+	if (agent_id != gAgent.getID())
+	{
+		LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
+		return;
+	}
+	
+	// Teleport is finished; it can't be cancelled now.
+	gViewerWindow->setProgressCancelButtonVisible(FALSE);
+
+	// Do teleport effect for where you're leaving
+	// VEFFECT: TeleportStart
+	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
+	effectp->setPositionGlobal(gAgent.getPositionGlobal());
+	effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+	LLHUDManager::getInstance()->sendEffects();
+
+	U32 location_id;
+	U32 sim_ip;
+	U16 sim_port;
+	LLVector3 pos, look_at;
+	U64 region_handle;
+	msg->getU32Fast(_PREHASH_Info, _PREHASH_LocationID, location_id);
+	msg->getIPAddrFast(_PREHASH_Info, _PREHASH_SimIP, sim_ip);
+	msg->getIPPortFast(_PREHASH_Info, _PREHASH_SimPort, sim_port);
+	//msg->getVector3Fast(_PREHASH_Info, _PREHASH_Position, pos);
+	//msg->getVector3Fast(_PREHASH_Info, _PREHASH_LookAt, look_at);
+	msg->getU64Fast(_PREHASH_Info, _PREHASH_RegionHandle, region_handle);
+	U32 teleport_flags;
+	msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
+	
+	
+	std::string seedCap;
+	msg->getStringFast(_PREHASH_Info, _PREHASH_SeedCapability, seedCap);
+
+	// update home location if we are teleporting out of prelude - specific to teleporting to welcome area 
+	if((teleport_flags & TELEPORT_FLAGS_SET_HOME_TO_TARGET)
+	   && (!gAgent.isGodlike()))
+	{
+		gAgent.setHomePosRegion(region_handle, pos);
+
+		// Create a timer that will send notices when teleporting is all finished.  Since this is 
+		// based on the LLEventTimer class, it will be managed by that class and not orphaned or leaked.
+		new LLPostTeleportNotifiers();
+	}
+
+	LLHost sim_host(sim_ip, sim_port);
+
+	// Viewer trusts the simulator.
+	gMessageSystem->enableCircuit(sim_host, TRUE);
+	LLViewerRegion* regionp =  LLWorld::getInstance()->addRegion(region_handle, sim_host);
+
+/*
+	// send camera update to new region
+	gAgentCamera.updateCamera();
+
+	// likewise make sure the camera is behind the avatar
+	gAgentCamera.resetView(TRUE);
+	LLVector3 shift_vector = regionp->getPosRegionFromGlobal(gAgent.getRegion()->getOriginGlobal());
+	gAgent.setRegion(regionp);
+	gObjectList.shiftObjects(shift_vector);
+
+	if (isAgentAvatarValid())
+	{
+		gAgentAvatarp->clearChatText();
+		gAgentCamera.slamLookAt(look_at);
+	}
+	gAgent.setPositionAgent(pos);
+	gAssetStorage->setUpstream(sim);
+	gCacheName->setUpstream(sim);
+*/
+
+	// now, use the circuit info to tell simulator about us!
+	LL_INFOS("Messaging") << "process_teleport_finish() Enabling "
+			<< sim_host << " with code " << msg->mOurCircuitCode << LL_ENDL;
+	msg->newMessageFast(_PREHASH_UseCircuitCode);
+	msg->nextBlockFast(_PREHASH_CircuitCode);
+	msg->addU32Fast(_PREHASH_Code, msg->getOurCircuitCode());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
+	msg->sendReliable(sim_host);
+
+	send_complete_agent_movement(sim_host);
+	gAgent.setTeleportState( LLAgent::TELEPORT_MOVING );
+	gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["contacting"]);
+
+	regionp->setSeedCapability(seedCap);
+
+	// Don't send camera updates to the new region until we're
+	// actually there...
+
+
+	// Now do teleport effect for where you're going.
+	// VEFFECT: TeleportEnd
+	effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
+	effectp->setPositionGlobal(gAgent.getPositionGlobal());
+
+	effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+	LLHUDManager::getInstance()->sendEffects();
+
+//	gTeleportDisplay = TRUE;
+//	gTeleportDisplayTimer.reset();
+//	gViewerWindow->setShowProgress(TRUE);
+}
+
+// stuff we have to do every time we get an AvatarInitComplete from a sim
+/*
+void process_avatar_init_complete(LLMessageSystem* msg, void**)
+{
+	LLVector3 agent_pos;
+	msg->getVector3Fast(_PREHASH_AvatarData, _PREHASH_Position, agent_pos);
+	agent_movement_complete(msg->getSender(), agent_pos);
+}
+*/
+
+void process_agent_movement_complete(LLMessageSystem* msg, void**)
+{
+	gAgentMovementCompleted = true;
+
+	LLUUID agent_id;
+	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+	LLUUID session_id;
+	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
+	if((gAgent.getID() != agent_id) || (gAgent.getSessionID() != session_id))
+	{
+		LL_WARNS("Messaging") << "Incorrect id in process_agent_movement_complete()"
+				<< LL_ENDL;
+		return;
+	}
+
+	LL_DEBUGS("Messaging") << "process_agent_movement_complete()" << LL_ENDL;
+
+	// *TODO: check timestamp to make sure the movement compleation
+	// makes sense.
+	LLVector3 agent_pos;
+	msg->getVector3Fast(_PREHASH_Data, _PREHASH_Position, agent_pos);
+	LLVector3 look_at;
+	msg->getVector3Fast(_PREHASH_Data, _PREHASH_LookAt, look_at);
+	U64 region_handle;
+	msg->getU64Fast(_PREHASH_Data, _PREHASH_RegionHandle, region_handle);
+	
+	std::string version_channel;
+	msg->getString("SimData", "ChannelVersion", version_channel);
+
+	if (!isAgentAvatarValid())
+	{
+		// Could happen if you were immediately god-teleported away on login,
+		// maybe other cases.  Continue, but warn.
+		LL_WARNS("Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL;
+	}
+
+	F32 x, y;
+	from_region_handle(region_handle, &x, &y);
+	LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
+	if (!regionp)
+	{
+		if (gAgent.getRegion())
+		{
+			LL_WARNS("Messaging") << "current region " << gAgent.getRegion()->getOriginGlobal() << LL_ENDL;
+		}
+
+		LL_WARNS("Messaging") << "Agent being sent to invalid home region: " 
+			<< x << ":" << y 
+			<< " current pos " << gAgent.getPositionGlobal()
+			<< LL_ENDL;
+		LLAppViewer::instance()->forceDisconnect(LLTrans::getString("SentToInvalidRegion"));
+		return;
+
+	}
+
+	LL_INFOS("Messaging") << "Changing home region to " << x << ":" << y << LL_ENDL;
+
+	// set our upstream host the new simulator and shuffle things as
+	// appropriate.
+	LLVector3 shift_vector = regionp->getPosRegionFromGlobal(
+		gAgent.getRegion()->getOriginGlobal());
+	gAgent.setRegion(regionp);
+	gObjectList.shiftObjects(shift_vector);
+	gAssetStorage->setUpstream(msg->getSender());
+	gCacheName->setUpstream(msg->getSender());
+	gViewerThrottle.sendToSim();
+	gViewerWindow->sendShapeToSim();
+
+	bool is_teleport = gAgent.getTeleportState() == LLAgent::TELEPORT_MOVING;
+
+	if( is_teleport )
+	{
+		if (gAgent.getTeleportKeepsLookAt())
+		{
+			// *NOTE: the LookAt data we get from the sim here doesn't
+			// seem to be useful, so get it from the camera instead
+			look_at = LLViewerCamera::getInstance()->getAtAxis();
+		}
+		// Force the camera back onto the agent, don't animate.
+		gAgentCamera.setFocusOnAvatar(TRUE, FALSE);
+		gAgentCamera.slamLookAt(look_at);
+		gAgentCamera.updateCamera();
+
+		gAgent.setTeleportState( LLAgent::TELEPORT_START_ARRIVAL );
+
+		// set the appearance on teleport since the new sim does not
+		// know what you look like.
+		gAgent.sendAgentSetAppearance();
+
+		if (isAgentAvatarValid())
+		{
+			// Chat the "back" SLURL. (DEV-4907)
+
+			LLSLURL slurl;
+			gAgent.getTeleportSourceSLURL(slurl);
+			LLSD substitution = LLSD().with("[T_SLURL]", slurl.getSLURLString());
+			std::string completed_from = LLAgent::sTeleportProgressMessages["completed_from"];
+			LLStringUtil::format(completed_from, substitution);
+
+			LLSD args;
+			args["MESSAGE"] = completed_from;
+			LLNotificationsUtil::add("SystemMessageTip", args);
+
+			// Set the new position
+			gAgentAvatarp->setPositionAgent(agent_pos);
+			gAgentAvatarp->clearChat();
+			gAgentAvatarp->slamPosition();
+		}
+	}
+	else
+	{
+		// This is initial log-in or a region crossing
+		gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
+
+		if(LLStartUp::getStartupState() < STATE_STARTED)
+		{	// This is initial log-in, not a region crossing:
+			// Set the camera looking ahead of the AV so send_agent_update() below 
+			// will report the correct location to the server.
+			LLVector3 look_at_point = look_at;
+			look_at_point = agent_pos + look_at_point.rotVec(gAgent.getQuat());
+
+			static LLVector3 up_direction(0.0f, 0.0f, 1.0f);
+			LLViewerCamera::getInstance()->lookAt(agent_pos, look_at_point, up_direction);
+		}
+	}
+
+	if ( LLTracker::isTracking(NULL) )
+	{
+		// Check distance to beacon, if < 5m, remove beacon
+		LLVector3d beacon_pos = LLTracker::getTrackedPositionGlobal();
+		LLVector3 beacon_dir(agent_pos.mV[VX] - (F32)fmod(beacon_pos.mdV[VX], 256.0), agent_pos.mV[VY] - (F32)fmod(beacon_pos.mdV[VY], 256.0), 0);
+		if (beacon_dir.magVecSquared() < 25.f)
+		{
+			LLTracker::stopTracking(NULL);
+		}
+		else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() )
+		{
+			//look at the beacon
+			LLVector3 global_agent_pos = agent_pos;
+			global_agent_pos[0] += x;
+			global_agent_pos[1] += y;
+			look_at = (LLVector3)beacon_pos - global_agent_pos;
+			look_at.normVec();
+			gAgentCamera.slamLookAt(look_at);
+		}
+	}
+
+	// TODO: Put back a check for flying status! DK 12/19/05
+	// Sim tells us whether the new position is off the ground
+	/*
+	if (teleport_flags & TELEPORT_FLAGS_IS_FLYING)
+	{
+		gAgent.setFlying(TRUE);
+	}
+	else
+	{
+		gAgent.setFlying(FALSE);
+	}
+	*/
+
+	send_agent_update(TRUE, TRUE);
+
+	if (gAgent.getRegion()->getBlockFly())
+	{
+		gAgent.setFlying(gAgent.canFly());
+	}
+
+	// force simulator to recognize busy state
+	if (gAgent.getBusy())
+	{
+		gAgent.setBusy();
+	}
+	else
+	{
+		gAgent.clearBusy();
+	}
+
+	if (isAgentAvatarValid())
+	{
+		gAgentAvatarp->mFootPlane.clearVec();
+	}
+	
+	// send walk-vs-run status
+	gAgent.sendWalkRun(gAgent.getRunning() || gAgent.getAlwaysRun());
+
+	// If the server version has changed, display an info box and offer
+	// to display the release notes, unless this is the initial log in.
+	if (gLastVersionChannel == version_channel)
+	{
+		return;
+	}
+
+	gLastVersionChannel = version_channel;
+}
+
+void process_crossed_region(LLMessageSystem* msg, void**)
+{
+	LLUUID agent_id;
+	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+	LLUUID session_id;
+	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
+	if((gAgent.getID() != agent_id) || (gAgent.getSessionID() != session_id))
+	{
+		LL_WARNS("Messaging") << "Incorrect id in process_crossed_region()"
+				<< LL_ENDL;
+		return;
+	}
+	LL_INFOS("Messaging") << "process_crossed_region()" << LL_ENDL;
+	gAgentAvatarp->resetRegionCrossingTimer();
+
+	U32 sim_ip;
+	msg->getIPAddrFast(_PREHASH_RegionData, _PREHASH_SimIP, sim_ip);
+	U16 sim_port;
+	msg->getIPPortFast(_PREHASH_RegionData, _PREHASH_SimPort, sim_port);
+	LLHost sim_host(sim_ip, sim_port);
+	U64 region_handle;
+	msg->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
+	
+	std::string seedCap;
+	msg->getStringFast(_PREHASH_RegionData, _PREHASH_SeedCapability, seedCap);
+
+	send_complete_agent_movement(sim_host);
+
+	LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host);
+	regionp->setSeedCapability(seedCap);
+}
+
+
+
+// Sends avatar and camera information to simulator.
+// Sent roughly once per frame, or 20 times per second, whichever is less often
+
+const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f;	// ~= 2.5 degrees -- if its less than this we need to update head_rot
+const F32 MAX_HEAD_ROT_QDOT = 0.99999f;			// ~= 0.5 degrees -- if its greater than this then no need to update head_rot
+												// between these values we delay the updates (but no more than one second)
+
+static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE_SEND("Send Message");
+
+void send_agent_update(BOOL force_send, BOOL send_reliable)
+{
+	if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
+	{
+		// We don't care if they want to send an agent update, they're not allowed to until the simulator
+		// that's the target is ready to receive them (after avatar_init_complete is received)
+		return;
+	}
+
+	// We have already requested to log out.  Don't send agent updates.
+	if(LLAppViewer::instance()->logoutRequestSent())
+	{
+		return;
+	}
+
+	// no region to send update to
+	if(gAgent.getRegion() == NULL)
+	{
+		return;
+	}
+
+	const F32 TRANSLATE_THRESHOLD = 0.01f;
+
+	// NOTA BENE: This is (intentionally?) using the small angle sine approximation to test for rotation
+	//			  Plus, there is an extra 0.5 in the mix since the perpendicular between last_camera_at and getAtAxis() bisects cam_rot_change
+	//			  Thus, we're actually testing against 0.2 degrees
+	const F32 ROTATION_THRESHOLD = 0.1f * 2.f*F_PI/360.f;			//  Rotation thresh 0.2 deg, see note above
+
+	const U8 DUP_MSGS = 1;				//  HACK!  number of times to repeat data on motionless agent
+
+	//  Store data on last sent update so that if no changes, no send
+	static LLVector3 last_camera_pos_agent, 
+					 last_camera_at, 
+					 last_camera_left,
+					 last_camera_up;
+	
+	static LLVector3 cam_center_chg,
+					 cam_rot_chg;
+
+	static LLQuaternion last_head_rot;
+	static U32 last_control_flags = 0;
+	static U8 last_render_state;
+	static U8 duplicate_count = 0;
+	static F32 head_rot_chg = 1.0;
+	static U8 last_flags;
+
+	LLMessageSystem	*msg = gMessageSystem;
+	LLVector3		camera_pos_agent;				// local to avatar's region
+	U8				render_state;
+
+	LLQuaternion body_rotation = gAgent.getFrameAgent().getQuaternion();
+	LLQuaternion head_rotation = gAgent.getHeadRotation();
+
+	camera_pos_agent = gAgentCamera.getCameraPositionAgent();
+
+	render_state = gAgent.getRenderState();
+
+	U32		control_flag_change = 0;
+	U8		flag_change = 0;
+
+	cam_center_chg = last_camera_pos_agent - camera_pos_agent;
+	cam_rot_chg = last_camera_at - LLViewerCamera::getInstance()->getAtAxis();
+
+	// If a modifier key is held down, turn off
+	// LBUTTON and ML_LBUTTON so that using the camera (alt-key) doesn't
+	// trigger a control event.
+	U32 control_flags = gAgent.getControlFlags();
+	MASK	key_mask = gKeyboard->currentMask(TRUE);
+	if (key_mask & MASK_ALT || key_mask & MASK_CONTROL)
+	{
+		control_flags &= ~(	AGENT_CONTROL_LBUTTON_DOWN |
+							AGENT_CONTROL_ML_LBUTTON_DOWN );
+		control_flags |= 	AGENT_CONTROL_LBUTTON_UP |
+							AGENT_CONTROL_ML_LBUTTON_UP ;
+	}
+
+	control_flag_change = last_control_flags ^ control_flags;
+
+	U8 flags = AU_FLAGS_NONE;
+	if (gAgent.isGroupTitleHidden())
+	{
+		flags |= AU_FLAGS_HIDETITLE;
+	}
+	if (gAgent.getAutoPilot())
+	{
+		flags |= AU_FLAGS_CLIENT_AUTOPILOT;
+	}
+
+	flag_change = last_flags ^ flags;
+
+	head_rot_chg = dot(last_head_rot, head_rotation);
+
+	if (force_send || 
+		(cam_center_chg.magVec() > TRANSLATE_THRESHOLD) || 
+		(head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) ||	
+		(last_render_state != render_state) ||
+		(cam_rot_chg.magVec() > ROTATION_THRESHOLD) ||
+		control_flag_change != 0 ||
+		flag_change != 0)  
+	{
+/*
+		if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT)
+		{
+			//LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL;
+			LL_INFOS("Messaging") << "head_rot_chg = " << head_rot_chg << LL_ENDL;
+		}
+		if (cam_rot_chg.magVec() > ROTATION_THRESHOLD) 
+		{
+			LL_INFOS("Messaging") << "cam rot " <<  cam_rot_chg.magVec() << LL_ENDL;
+		}
+		if (cam_center_chg.magVec() > TRANSLATE_THRESHOLD)
+		{
+			LL_INFOS("Messaging") << "cam center " << cam_center_chg.magVec() << LL_ENDL;
+		}
+//		if (drag_delta_chg.magVec() > TRANSLATE_THRESHOLD)
+//		{
+//			LL_INFOS("Messaging") << "drag delta " << drag_delta_chg.magVec() << LL_ENDL;
+//		}
+		if (control_flag_change)
+		{
+			LL_INFOS("Messaging") << "dcf = " << control_flag_change << LL_ENDL;
+		}
+*/
+
+		duplicate_count = 0;
+	}
+	else
+	{
+		duplicate_count++;
+
+		if (head_rot_chg < MAX_HEAD_ROT_QDOT  &&  duplicate_count < AGENT_UPDATES_PER_SECOND)
+		{
+			// The head_rotation is sent for updating things like attached guns.
+			// We only trigger a new update when head_rotation deviates beyond
+			// some threshold from the last update, however this can break fine
+			// adjustments when trying to aim an attached gun, so what we do here
+			// (where we would normally skip sending an update when nothing has changed)
+			// is gradually reduce the threshold to allow a better update to 
+			// eventually get sent... should update to within 0.5 degrees in less 
+			// than a second.
+			if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT + (MAX_HEAD_ROT_QDOT - THRESHOLD_HEAD_ROT_QDOT) * duplicate_count / AGENT_UPDATES_PER_SECOND)
+			{
+				duplicate_count = 0;
+			}
+			else
+			{
+				return;
+			}
+		}
+		else
+		{
+			return;
+		}
+	}
+
+	if (duplicate_count < DUP_MSGS && !gDisconnected)
+	{
+		LLFastTimer t(FTM_AGENT_UPDATE_SEND);
+		// Build the message
+		msg->newMessageFast(_PREHASH_AgentUpdate);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->addQuatFast(_PREHASH_BodyRotation, body_rotation);
+		msg->addQuatFast(_PREHASH_HeadRotation, head_rotation);
+		msg->addU8Fast(_PREHASH_State, render_state);
+		msg->addU8Fast(_PREHASH_Flags, flags);
+
+//		if (camera_pos_agent.mV[VY] > 255.f)
+//		{
+//			LL_INFOS("Messaging") << "Sending camera center " << camera_pos_agent << LL_ENDL;
+//		}
+		
+		msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent);
+		msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstance()->getAtAxis());
+		msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis());
+		msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis());
+		msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance);
+		
+		msg->addU32Fast(_PREHASH_ControlFlags, control_flags);
+
+		if (gDebugClicks)
+		{
+			if (control_flags & AGENT_CONTROL_LBUTTON_DOWN)
+			{
+				LL_INFOS("Messaging") << "AgentUpdate left button down" << LL_ENDL;
+			}
+
+			if (control_flags & AGENT_CONTROL_LBUTTON_UP)
+			{
+				LL_INFOS("Messaging") << "AgentUpdate left button up" << LL_ENDL;
+			}
+		}
+
+		gAgent.enableControlFlagReset();
+
+		if (!send_reliable)
+		{
+			gAgent.sendMessage();
+		}
+		else
+		{
+			gAgent.sendReliableMessage();
+		}
+
+//		LL_DEBUGS("Messaging") << "agent " << avatar_pos_agent << " cam " << camera_pos_agent << LL_ENDL;
+
+		// Copy the old data 
+		last_head_rot = head_rotation;
+		last_render_state = render_state;
+		last_camera_pos_agent = camera_pos_agent;
+		last_camera_at = LLViewerCamera::getInstance()->getAtAxis();
+		last_camera_left = LLViewerCamera::getInstance()->getLeftAxis();
+		last_camera_up = LLViewerCamera::getInstance()->getUpAxis();
+		last_control_flags = control_flags;
+		last_flags = flags;
+	}
+}
+
+
+
+// *TODO: Remove this dependency, or figure out a better way to handle
+// this hack.
+extern U32 gObjectBits;
+
+void process_object_update(LLMessageSystem *mesgsys, void **user_data)
+{	
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	// Update the data counters
+	if (mesgsys->getReceiveCompressedSize())
+	{
+		gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
+	}
+	else
+	{
+		gObjectBits += mesgsys->getReceiveSize() * 8;
+	}
+
+	// Update the object...
+	gObjectList.processObjectUpdate(mesgsys, user_data, OUT_FULL);
+}
+
+void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	// Update the data counters
+	if (mesgsys->getReceiveCompressedSize())
+	{
+		gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
+	}
+	else
+	{
+		gObjectBits += mesgsys->getReceiveSize() * 8;
+	}
+
+	// Update the object...
+	gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_FULL_COMPRESSED);
+}
+
+void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	// Update the data counters
+	if (mesgsys->getReceiveCompressedSize())
+	{
+		gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
+	}
+	else
+	{
+		gObjectBits += mesgsys->getReceiveSize() * 8;
+	}
+
+	// Update the object...
+	gObjectList.processCachedObjectUpdate(mesgsys, user_data, OUT_FULL_CACHED);
+}
+
+
+void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	if (mesgsys->getReceiveCompressedSize())
+	{
+		gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
+	}
+	else
+	{
+		gObjectBits += mesgsys->getReceiveSize() * 8;
+	}
+
+	gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
+}
+
+static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
+
+
+void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLFastTimer t(FTM_PROCESS_OBJECTS);
+
+	LLUUID		id;
+	U32			local_id;
+	S32			i;
+	S32			num_objects;
+
+	num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
+
+	for (i = 0; i < num_objects; i++)
+	{
+		mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
+
+		LLViewerObjectList::getUUIDFromLocal(id,
+											local_id,
+											gMessageSystem->getSenderIP(),
+											gMessageSystem->getSenderPort());
+		if (id == LLUUID::null)
+		{
+			LL_DEBUGS("Messaging") << "Unknown kill for local " << local_id << LL_ENDL;
+			gObjectList.mNumUnknownKills++;
+			continue;
+		}
+		else
+		{
+			LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;
+		}
+
+		LLSelectMgr::getInstance()->removeObjectFromSelections(id);
+
+		// ...don't kill the avatar
+		if (!(id == gAgentID))
+		{
+			LLViewerObject *objectp = gObjectList.findObject(id);
+			if (objectp)
+			{
+				// Display green bubble on kill
+				if ( gShowObjectUpdates )
+				{
+					LLViewerObject* newobject;
+					newobject = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, objectp->getRegion());
+
+					LLVOTextBubble* bubble = (LLVOTextBubble*) newobject;
+
+					bubble->mColor.setVec(0.f, 1.f, 0.f, 1.f);
+					bubble->setScale( 2.0f * bubble->getScale() );
+					bubble->setPositionGlobal(objectp->getPositionGlobal());
+					gPipeline.addObject(bubble);
+				}
+
+				// Do the kill
+				gObjectList.killObject(objectp);
+			}
+			else
+			{
+				LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL;
+				gObjectList.mNumUnknownKills++;
+			}
+		}
+	}
+}
+
+void process_time_synch(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLVector3 sun_direction;
+	LLVector3 sun_ang_velocity;
+	F32 phase;
+	U64	space_time_usec;
+
+    U32 seconds_per_day;
+    U32 seconds_per_year;
+
+	// "SimulatorViewerTimeMessage"
+	mesgsys->getU64Fast(_PREHASH_TimeInfo, _PREHASH_UsecSinceStart, space_time_usec);
+	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerDay, seconds_per_day);
+	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerYear, seconds_per_year);
+
+	// This should eventually be moved to an "UpdateHeavenlyBodies" message
+	mesgsys->getF32Fast(_PREHASH_TimeInfo, _PREHASH_SunPhase, phase);
+	mesgsys->getVector3Fast(_PREHASH_TimeInfo, _PREHASH_SunDirection, sun_direction);
+	mesgsys->getVector3Fast(_PREHASH_TimeInfo, _PREHASH_SunAngVelocity, sun_ang_velocity);
+
+	LLWorld::getInstance()->setSpaceTimeUSec(space_time_usec);
+
+	//LL_DEBUGS("Messaging") << "time_synch() - " << sun_direction << ", " << sun_ang_velocity
+	//		 << ", " << phase << LL_ENDL;
+
+	gSky.setSunPhase(phase);
+	gSky.setSunTargetDirection(sun_direction, sun_ang_velocity);
+	if (!gNoRender && !(gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || gSky.getOverrideSun()))
+	{
+		gSky.setSunDirection(sun_direction, sun_ang_velocity);
+	}
+}
+
+void process_sound_trigger(LLMessageSystem *msg, void **)
+{
+	if (!gAudiop) return;
+
+	U64		region_handle = 0;
+	F32		gain = 0;
+	LLUUID	sound_id;
+	LLUUID	owner_id;
+	LLUUID	object_id;
+	LLUUID	parent_id;
+	LLVector3	pos_local;
+
+	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_SoundID, sound_id);
+	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_OwnerID, owner_id);
+	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ObjectID, object_id);
+	msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ParentID, parent_id);
+	msg->getU64Fast(_PREHASH_SoundData, _PREHASH_Handle, region_handle);
+	msg->getVector3Fast(_PREHASH_SoundData, _PREHASH_Position, pos_local);
+	msg->getF32Fast(_PREHASH_SoundData, _PREHASH_Gain, gain);
+
+	// adjust sound location to true global coords
+	LLVector3d	pos_global = from_region_handle(region_handle);
+	pos_global.mdV[VX] += pos_local.mV[VX];
+	pos_global.mdV[VY] += pos_local.mV[VY];
+	pos_global.mdV[VZ] += pos_local.mV[VZ];
+
+	// Don't play a trigger sound if you can't hear it due
+	// to parcel "local audio only" settings.
+	if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global)) return;
+
+	// Don't play sounds triggered by someone you muted.
+	if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
+	
+	// Don't play sounds from an object you muted
+	if (LLMuteList::getInstance()->isMuted(object_id)) return;
+
+	// Don't play sounds from an object whose parent you muted
+	if (parent_id.notNull()
+		&& LLMuteList::getInstance()->isMuted(parent_id))
+	{
+		return;
+	}
+
+	// Don't play sounds from a region with maturity above current agent maturity
+	if( !gAgent.canAccessMaturityInRegion( region_handle ) )
+	{
+		return;
+	}
+		
+	gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global);
+}
+
+void process_preload_sound(LLMessageSystem *msg, void **user_data)
+{
+	if (!gAudiop)
+	{
+		return;
+	}
+
+	LLUUID sound_id;
+	LLUUID object_id;
+	LLUUID owner_id;
+
+	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_SoundID, sound_id);
+	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id);
+	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id);
+
+	LLViewerObject *objectp = gObjectList.findObject(object_id);
+	if (!objectp) return;
+
+	if (LLMuteList::getInstance()->isMuted(object_id)) return;
+	if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
+	
+	LLAudioSource *sourcep = objectp->getAudioSource(owner_id);
+	if (!sourcep) return;
+	
+	LLAudioData *datap = gAudiop->getAudioData(sound_id);
+
+	// Note that I don't actually do any loading of the
+	// audio data into a buffer at this point, as it won't actually
+	// help us out.
+
+	// Don't play sounds from a region with maturity above current agent maturity
+	LLVector3d pos_global = objectp->getPositionGlobal();
+	if (gAgent.canAccessMaturityAtGlobal(pos_global))
+	{
+	// Add audioData starts a transfer internally.
+	sourcep->addAudioData(datap, FALSE);
+}
+}
+
+void process_attached_sound(LLMessageSystem *msg, void **user_data)
+{
+	F32 gain = 0;
+	LLUUID sound_id;
+	LLUUID object_id;
+	LLUUID owner_id;
+	U8 flags;
+
+	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_SoundID, sound_id);
+	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id);
+	msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id);
+	msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain);
+	msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags);
+
+	LLViewerObject *objectp = gObjectList.findObject(object_id);
+	if (!objectp)
+	{
+		// we don't know about this object, just bail
+		return;
+	}
+	
+	if (LLMuteList::getInstance()->isMuted(object_id)) return;
+	
+	if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
+
+	
+	// Don't play sounds from a region with maturity above current agent maturity
+	LLVector3d pos = objectp->getPositionGlobal();
+	if( !gAgent.canAccessMaturityAtGlobal(pos) )
+	{
+		return;
+	}
+	
+	objectp->setAttachedSound(sound_id, owner_id, gain, flags);
+}
+
+
+void process_attached_sound_gain_change(LLMessageSystem *mesgsys, void **user_data)
+{
+	F32 gain = 0;
+	LLUUID object_guid;
+	LLViewerObject *objectp = NULL;
+
+	mesgsys->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_guid);
+
+	if (!((objectp = gObjectList.findObject(object_guid))))
+	{
+		// we don't know about this object, just bail
+		return;
+	}
+
+ 	mesgsys->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain);
+
+	objectp->adjustAudioGain(gain);
+}
+
+
+void process_health_message(LLMessageSystem *mesgsys, void **user_data)
+{
+	F32 health;
+
+	mesgsys->getF32Fast(_PREHASH_HealthData, _PREHASH_Health, health);
+
+	if (gStatusBar)
+	{
+		gStatusBar->setHealth((S32)health);
+	}
+}
+
+
+void process_sim_stats(LLMessageSystem *msg, void **user_data)
+{	
+	S32 count = msg->getNumberOfBlocks("Stat");
+	for (S32 i = 0; i < count; ++i)
+	{
+		U32 stat_id;
+		F32 stat_value;
+		msg->getU32("Stat", "StatID", stat_id, i);
+		msg->getF32("Stat", "StatValue", stat_value, i);
+		switch (stat_id)
+		{
+		case LL_SIM_STAT_TIME_DILATION:
+			LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_FPS:
+			LLViewerStats::getInstance()->mSimFPS.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_PHYSFPS:
+			LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_AGENTUPS:
+			LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_FRAMEMS:
+			LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_NETMS:
+			LLViewerStats::getInstance()->mSimNetMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_SIMOTHERMS:
+			LLViewerStats::getInstance()->mSimSimOtherMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_SIMPHYSICSMS:
+			LLViewerStats::getInstance()->mSimSimPhysicsMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_AGENTMS:
+			LLViewerStats::getInstance()->mSimAgentMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_IMAGESMS:
+			LLViewerStats::getInstance()->mSimImagesMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_SCRIPTMS:
+			LLViewerStats::getInstance()->mSimScriptMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_NUMTASKS:
+			LLViewerStats::getInstance()->mSimObjects.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_NUMTASKSACTIVE:
+			LLViewerStats::getInstance()->mSimActiveObjects.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_NUMAGENTMAIN:
+			LLViewerStats::getInstance()->mSimMainAgents.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_NUMAGENTCHILD:
+			LLViewerStats::getInstance()->mSimChildAgents.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_NUMSCRIPTSACTIVE:
+			LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_SCRIPT_EPS:
+			LLViewerStats::getInstance()->mSimScriptEPS.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_INPPS:
+			LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_OUTPPS:
+			LLViewerStats::getInstance()->mSimOutPPS.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_PENDING_DOWNLOADS:
+			LLViewerStats::getInstance()->mSimPendingDownloads.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_PENDING_UPLOADS:
+			LLViewerStats::getInstance()->mSimPendingUploads.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_PENDING_LOCAL_UPLOADS:
+			LLViewerStats::getInstance()->mSimPendingLocalUploads.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_TOTAL_UNACKED_BYTES:
+			LLViewerStats::getInstance()->mSimTotalUnackedBytes.addValue(stat_value / 1024.f);
+			break;
+		case LL_SIM_STAT_PHYSICS_PINNED_TASKS:
+			LLViewerStats::getInstance()->mPhysicsPinnedTasks.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_PHYSICS_LOD_TASKS:
+			LLViewerStats::getInstance()->mPhysicsLODTasks.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_SIMPHYSICSSTEPMS:
+			LLViewerStats::getInstance()->mSimSimPhysicsStepMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_SIMPHYSICSSHAPEMS:
+			LLViewerStats::getInstance()->mSimSimPhysicsShapeUpdateMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_SIMPHYSICSOTHERMS:
+			LLViewerStats::getInstance()->mSimSimPhysicsOtherMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_SIMPHYSICSMEMORY:
+			LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_SIMSPARETIME:
+			LLViewerStats::getInstance()->mSimSpareMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_SIMSLEEPTIME:
+			LLViewerStats::getInstance()->mSimSleepMsec.addValue(stat_value);
+			break;
+		case LL_SIM_STAT_IOPUMPTIME:
+			LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value);
+			break;
+		default:
+			// Used to be a commented out warning.
+ 			LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL;
+		  break;
+		}
+	}
+
+	/*
+	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_PhysicsTimeDilation, time_dilation);
+	LLViewerStats::getInstance()->mSimTDStat.addValue(time_dilation);
+
+	// Process information
+	//	{	CpuUsage			F32				}
+	//	{	SimMemTotal			F32				}
+	//	{	SimMemRSS			F32				}
+	//	{	ProcessUptime		F32				}
+	F32 cpu_usage;
+	F32 sim_mem_total;
+	F32 sim_mem_rss;
+	F32 process_uptime;
+	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_CpuUsage, cpu_usage);
+	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemTotal, sim_mem_total);
+	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemRSS, sim_mem_rss);
+	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_ProcessUptime, process_uptime);
+	LLViewerStats::getInstance()->mSimCPUUsageStat.addValue(cpu_usage);
+	LLViewerStats::getInstance()->mSimMemTotalStat.addValue(sim_mem_total);
+	LLViewerStats::getInstance()->mSimMemRSSStat.addValue(sim_mem_rss);
+	*/
+
+	//
+	// Various hacks that aren't statistics, but are being handled here.
+	//
+	U32 max_tasks_per_region;
+	U32 region_flags;
+	msg->getU32("Region", "ObjectCapacity", max_tasks_per_region);
+	msg->getU32("Region", "RegionFlags", region_flags);
+
+	LLViewerRegion* regionp = gAgent.getRegion();
+	if (regionp)
+	{
+		BOOL was_flying = gAgent.getFlying();
+		regionp->setRegionFlags(region_flags);
+		regionp->setMaxTasks(max_tasks_per_region);
+		// HACK: This makes agents drop from the sky if the region is 
+		// set to no fly while people are still in the sim.
+		if (was_flying && regionp->getBlockFly())
+		{
+			gAgent.setFlying(gAgent.canFly());
+		}
+	}
+}
+
+
+
+void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLUUID	animation_id;
+	LLUUID	uuid;
+	S32		anim_sequence_id;
+	LLVOAvatar *avatarp;
+	
+	mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
+
+	//clear animation flags
+	avatarp = (LLVOAvatar *)gObjectList.findObject(uuid);
+
+	if (!avatarp)
+	{
+		// no agent by this ID...error?
+		LL_WARNS("Messaging") << "Received animation state for unknown avatar" << uuid << LL_ENDL;
+		return;
+	}
+
+	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
+	S32 num_source_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationSourceList);
+
+	avatarp->mSignaledAnimations.clear();
+	
+	if (avatarp->isSelf())
+	{
+		LLUUID object_id;
+
+		for( S32 i = 0; i < num_blocks; i++ )
+		{
+			mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
+			mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
+
+			LL_DEBUGS("Messaging") << "Anim sequence ID: " << anim_sequence_id << LL_ENDL;
+
+			avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
+
+			// *HACK: Disabling flying mode if it has been enabled shortly before the agent
+			// stand up animation is signaled. In this case we don't get a signal to start
+			// flying animation from server, the AGENT_CONTROL_FLY flag remains set but the
+			// avatar does not play flying animation, so we switch flying mode off.
+			// See LLAgent::setFlying(). This may cause "Stop Flying" button to blink.
+			// See EXT-2781.
+			if (animation_id == ANIM_AGENT_STANDUP && gAgent.getFlying())
+			{
+				gAgent.setFlying(FALSE);
+			}
+
+			if (i < num_source_blocks)
+			{
+				mesgsys->getUUIDFast(_PREHASH_AnimationSourceList, _PREHASH_ObjectID, object_id, i);
+			
+				LLViewerObject* object = gObjectList.findObject(object_id);
+				if (object)
+				{
+					object->mFlags |= FLAGS_ANIM_SOURCE;
+
+					BOOL anim_found = FALSE;
+					LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id);
+					for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it)
+					{
+						if (anim_it->second == animation_id)
+						{
+							anim_found = TRUE;
+							break;
+						}
+					}
+
+					if (!anim_found)
+					{
+						avatarp->mAnimationSources.insert(LLVOAvatar::AnimationSourceMap::value_type(object_id, animation_id));
+					}
+				}
+			}
+		}
+	}
+	else
+	{
+		for( S32 i = 0; i < num_blocks; i++ )
+		{
+			mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
+			mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
+			avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
+		}
+	}
+
+	if (num_blocks)
+	{
+		avatarp->processAnimationStateChanges();
+	}
+}
+
+void process_avatar_appearance(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLUUID uuid;
+	mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
+
+	LLVOAvatar* avatarp = (LLVOAvatar *)gObjectList.findObject(uuid);
+	if (avatarp)
+	{
+		avatarp->processAvatarAppearance( mesgsys );
+	}
+	else
+	{
+		LL_WARNS("Messaging") << "avatar_appearance sent for unknown avatar " << uuid << LL_ENDL;
+	}
+}
+
+void process_camera_constraint(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLVector4 cameraCollidePlane;
+	mesgsys->getVector4Fast(_PREHASH_CameraCollidePlane, _PREHASH_Plane, cameraCollidePlane);
+
+	gAgentCamera.setCameraCollidePlane(cameraCollidePlane);
+}
+
+void near_sit_object(BOOL success, void *data)
+{
+	if (success)
+	{
+		// Send message to sit on object
+		gMessageSystem->newMessageFast(_PREHASH_AgentSit);
+		gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		gAgent.sendReliableMessage();
+	}
+}
+
+void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLVector3 sitPosition;
+	LLQuaternion sitRotation;
+	LLUUID sitObjectID;
+	BOOL use_autopilot;
+	mesgsys->getUUIDFast(_PREHASH_SitObject, _PREHASH_ID, sitObjectID);
+	mesgsys->getBOOLFast(_PREHASH_SitTransform, _PREHASH_AutoPilot, use_autopilot);
+	mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_SitPosition, sitPosition);
+	mesgsys->getQuatFast(_PREHASH_SitTransform, _PREHASH_SitRotation, sitRotation);
+	LLVector3 camera_eye;
+	mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_CameraEyeOffset, camera_eye);
+	LLVector3 camera_at;
+	mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_CameraAtOffset, camera_at);
+	BOOL force_mouselook;
+	mesgsys->getBOOLFast(_PREHASH_SitTransform, _PREHASH_ForceMouselook, force_mouselook);
+
+	if (isAgentAvatarValid() && dist_vec_squared(camera_eye, camera_at) > 0.0001f)
+	{
+		gAgentCamera.setSitCamera(sitObjectID, camera_eye, camera_at);
+	}
+	
+	gAgentCamera.setForceMouselook(force_mouselook);
+	// Forcing turning off flying here to prevent flying after pressing "Stand"
+	// to stand up from an object. See EXT-1655.
+	gAgent.setFlying(FALSE);
+
+	LLViewerObject* object = gObjectList.findObject(sitObjectID);
+	if (object)
+	{
+		LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation());
+		if (!use_autopilot || isAgentAvatarValid() && gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == object->getRoot())
+		{
+			//we're already sitting on this object, so don't autopilot
+		}
+		else
+		{
+			gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(sit_spot), "Sit", &sitRotation, near_sit_object, NULL, 0.5f);
+		}
+	}
+	else
+	{
+		LL_WARNS("Messaging") << "Received sit approval for unknown object " << sitObjectID << LL_ENDL;
+	}
+}
+
+void process_clear_follow_cam_properties(LLMessageSystem *mesgsys, void **user_data)
+{
+	LLUUID		source_id;
+
+	mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, source_id);
+
+	LLFollowCamMgr::removeFollowCamParams(source_id);
+}
+
+void process_set_follow_cam_properties(LLMessageSystem *mesgsys, void **user_data)
+{
+	S32			type;
+	F32			value;
+	bool		settingPosition = false;
+	bool		settingFocus	= false;
+	bool		settingFocusOffset = false;
+	LLVector3	position;
+	LLVector3	focus;
+	LLVector3	focus_offset;
+
+	LLUUID		source_id;
+
+	mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, source_id);
+
+	LLViewerObject* objectp = gObjectList.findObject(source_id);
+	if (objectp)
+	{
+		objectp->mFlags |= FLAGS_CAMERA_SOURCE;
+	}
+
+	S32 num_objects = mesgsys->getNumberOfBlocks("CameraProperty");
+	for (S32 block_index = 0; block_index < num_objects; block_index++)
+	{
+		mesgsys->getS32("CameraProperty", "Type", type, block_index);
+		mesgsys->getF32("CameraProperty", "Value", value, block_index);
+		switch(type)
+		{
+		case FOLLOWCAM_PITCH:
+			LLFollowCamMgr::setPitch(source_id, value);
+			break;
+		case FOLLOWCAM_FOCUS_OFFSET_X:
+			focus_offset.mV[VX] = value;
+			settingFocusOffset = true;
+			break;
+		case FOLLOWCAM_FOCUS_OFFSET_Y:
+			focus_offset.mV[VY] = value;
+			settingFocusOffset = true;
+			break;
+		case FOLLOWCAM_FOCUS_OFFSET_Z:
+			focus_offset.mV[VZ] = value;
+			settingFocusOffset = true;
+			break;
+		case FOLLOWCAM_POSITION_LAG:
+			LLFollowCamMgr::setPositionLag(source_id, value);
+			break;
+		case FOLLOWCAM_FOCUS_LAG:
+			LLFollowCamMgr::setFocusLag(source_id, value);
+			break;
+		case FOLLOWCAM_DISTANCE:
+			LLFollowCamMgr::setDistance(source_id, value);
+			break;
+		case FOLLOWCAM_BEHINDNESS_ANGLE:
+			LLFollowCamMgr::setBehindnessAngle(source_id, value);
+			break;
+		case FOLLOWCAM_BEHINDNESS_LAG:
+			LLFollowCamMgr::setBehindnessLag(source_id, value);
+			break;
+		case FOLLOWCAM_POSITION_THRESHOLD:
+			LLFollowCamMgr::setPositionThreshold(source_id, value);
+			break;
+		case FOLLOWCAM_FOCUS_THRESHOLD:
+			LLFollowCamMgr::setFocusThreshold(source_id, value);
+			break;
+		case FOLLOWCAM_ACTIVE:
+			//if 1, set using followcam,. 
+			LLFollowCamMgr::setCameraActive(source_id, value != 0.f);
+			break;
+		case FOLLOWCAM_POSITION_X:
+			settingPosition = true;
+			position.mV[ 0 ] = value;
+			break;
+		case FOLLOWCAM_POSITION_Y:
+			settingPosition = true;
+			position.mV[ 1 ] = value;
+			break;
+		case FOLLOWCAM_POSITION_Z:
+			settingPosition = true;
+			position.mV[ 2 ] = value;
+			break;
+		case FOLLOWCAM_FOCUS_X:
+			settingFocus = true;
+			focus.mV[ 0 ] = value;
+			break;
+		case FOLLOWCAM_FOCUS_Y:
+			settingFocus = true;
+			focus.mV[ 1 ] = value;
+			break;
+		case FOLLOWCAM_FOCUS_Z:
+			settingFocus = true;
+			focus.mV[ 2 ] = value;
+			break;
+		case FOLLOWCAM_POSITION_LOCKED:
+			LLFollowCamMgr::setPositionLocked(source_id, value != 0.f);
+			break;
+		case FOLLOWCAM_FOCUS_LOCKED:
+			LLFollowCamMgr::setFocusLocked(source_id, value != 0.f);
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	if ( settingPosition )
+	{
+		LLFollowCamMgr::setPosition(source_id, position);
+	}
+	if ( settingFocus )
+	{
+		LLFollowCamMgr::setFocus(source_id, focus);
+	}
+	if ( settingFocusOffset )
+	{
+		LLFollowCamMgr::setFocusOffset(source_id, focus_offset);
+	}
+}
+//end Ventrella 
+
+
+// Culled from newsim lltask.cpp
+void process_name_value(LLMessageSystem *mesgsys, void **user_data)
+{
+	std::string	temp_str;
+	LLUUID	id;
+	S32		i, num_blocks;
+
+	mesgsys->getUUIDFast(_PREHASH_TaskData, _PREHASH_ID, id);
+
+	LLViewerObject* object = gObjectList.findObject(id);
+
+	if (object)
+	{
+		num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_NameValueData);
+		for (i = 0; i < num_blocks; i++)
+		{
+			mesgsys->getStringFast(_PREHASH_NameValueData, _PREHASH_NVPair, temp_str, i);
+			LL_INFOS("Messaging") << "Added to object Name Value: " << temp_str << LL_ENDL;
+			object->addNVPair(temp_str);
+		}
+	}
+	else
+	{
+		LL_INFOS("Messaging") << "Can't find object " << id << " to add name value pair" << LL_ENDL;
+	}
+}
+
+void process_remove_name_value(LLMessageSystem *mesgsys, void **user_data)
+{
+	std::string	temp_str;
+	LLUUID	id;
+	S32		i, num_blocks;
+
+	mesgsys->getUUIDFast(_PREHASH_TaskData, _PREHASH_ID, id);
+
+	LLViewerObject* object = gObjectList.findObject(id);
+
+	if (object)
+	{
+		num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_NameValueData);
+		for (i = 0; i < num_blocks; i++)
+		{
+			mesgsys->getStringFast(_PREHASH_NameValueData, _PREHASH_NVPair, temp_str, i);
+			LL_INFOS("Messaging") << "Removed from object Name Value: " << temp_str << LL_ENDL;
+			object->removeNVPair(temp_str);
+		}
+	}
+	else
+	{
+		LL_INFOS("Messaging") << "Can't find object " << id << " to remove name value pair" << LL_ENDL;
+	}
+}
+
+void process_kick_user(LLMessageSystem *msg, void** /*user_data*/)
+{
+	std::string message;
+
+	msg->getStringFast(_PREHASH_UserInfo, _PREHASH_Reason, message);
+
+	LLAppViewer::instance()->forceDisconnect(message);
+}
+
+
+/*
+void process_user_list_reply(LLMessageSystem *msg, void **user_data)
+{
+	LLUserList::processUserListReply(msg, user_data);
+	return;
+	char	firstname[MAX_STRING+1];
+	char	lastname[MAX_STRING+1];
+	U8		status;
+	S32		user_count;
+
+	user_count = msg->getNumberOfBlocks("UserBlock");
+
+	for (S32 i = 0; i < user_count; i++)
+	{
+		msg->getData("UserBlock", i, "FirstName", firstname);
+		msg->getData("UserBlock", i, "LastName", lastname);
+		msg->getData("UserBlock", i, "Status", &status);
+
+		if (status & 0x01)
+		{
+			dialog_friends_add_friend(buffer, TRUE);
+		}
+		else
+		{
+			dialog_friends_add_friend(buffer, FALSE);
+		}
+	}
+
+	dialog_friends_done_adding();
+}
+*/
+
+// this is not handled in processUpdateMessage
+/*
+void process_time_dilation(LLMessageSystem *msg, void **user_data)
+{
+	// get the time_dilation
+	U16 foo;
+	msg->getData("TimeDilation", "TimeDilation", &foo);
+	F32 time_dilation = ((F32) foo) / 65535.f;
+
+	// get the pointer to the right region
+	U32 ip = msg->getSenderIP();
+	U32 port = msg->getSenderPort();
+	LLViewerRegion *regionp = LLWorld::getInstance()->getRegion(ip, port);
+	if (regionp)
+	{
+		regionp->setTimeDilation(time_dilation);
+	}
+}
+*/
+
+
+void process_money_balance_reply( LLMessageSystem* msg, void** )
+{
+	S32 balance = 0;
+	S32 credit = 0;
+	S32 committed = 0;
+	std::string desc;
+	LLUUID tid;
+
+	msg->getUUID("MoneyData", "TransactionID", tid);
+	msg->getS32("MoneyData", "MoneyBalance", balance);
+	msg->getS32("MoneyData", "SquareMetersCredit", credit);
+	msg->getS32("MoneyData", "SquareMetersCommitted", committed);
+	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_Description, desc);
+	LL_INFOS("Messaging") << "L$, credit, committed: " << balance << " " << credit << " "
+			<< committed << LL_ENDL;
+    
+	if (gStatusBar)
+	{
+		gStatusBar->setBalance(balance);
+		gStatusBar->setLandCredit(credit);
+		gStatusBar->setLandCommitted(committed);
+	}
+
+	if (desc.empty()
+		|| !gSavedSettings.getBOOL("NotifyMoneyChange"))
+	{
+		// ...nothing to display
+		return;
+	}
+
+	// Suppress duplicate messages about the same transaction
+	static std::deque<LLUUID> recent;
+	if (std::find(recent.rbegin(), recent.rend(), tid) != recent.rend())
+	{
+		return;
+	}
+
+	// Once the 'recent' container gets large enough, chop some
+	// off the beginning.
+	const U32 MAX_LOOKBACK = 30;
+	const S32 POP_FRONT_SIZE = 12;
+	if(recent.size() > MAX_LOOKBACK)
+	{
+		LL_DEBUGS("Messaging") << "Removing oldest transaction records" << LL_ENDL;
+		recent.erase(recent.begin(), recent.begin() + POP_FRONT_SIZE);
+	}
+	//LL_DEBUGS("Messaging") << "Pushing back transaction " << tid << LL_ENDL;
+	recent.push_back(tid);
+
+	if (msg->has("TransactionInfo"))
+	{
+		// ...message has extended info for localization
+		process_money_balance_reply_extended(msg);
+	}
+	else
+	{
+		// Only old dev grids will not supply the TransactionInfo block,
+		// so we can just use the hard-coded English string.
+		LLSD args;
+		args["MESSAGE"] = desc;
+		LLNotificationsUtil::add("SystemMessage", args);
+	}
+}
+
+static std::string reason_from_transaction_type(S32 transaction_type,
+												const std::string& item_desc)
+{
+	// *NOTE: The keys for the reason strings are unusual because
+	// an earlier version of the code used English language strings
+	// extracted from hard-coded server English descriptions.
+	// Keeping them so we don't have to re-localize them.
+	switch (transaction_type)
+	{
+		case TRANS_OBJECT_SALE:
+		{
+			LLStringUtil::format_map_t arg;
+			arg["ITEM"] = item_desc;
+			return LLTrans::getString("for item", arg);
+		}
+		case TRANS_LAND_SALE:
+			return LLTrans::getString("for a parcel of land");
+			
+		case TRANS_LAND_PASS_SALE:
+			return LLTrans::getString("for a land access pass");
+			
+		case TRANS_GROUP_LAND_DEED:
+			return LLTrans::getString("for deeding land");
+			
+		case TRANS_GROUP_CREATE:
+			return LLTrans::getString("to create a group");
+			
+		case TRANS_GROUP_JOIN:
+			return LLTrans::getString("to join a group");
+			
+		case TRANS_UPLOAD_CHARGE:
+			return LLTrans::getString("to upload");
+
+		case TRANS_CLASSIFIED_CHARGE:
+			return LLTrans::getString("to publish a classified ad");
+			
+		// These have no reason to display, but are expected and should not
+		// generate warnings
+		case TRANS_GIFT:
+		case TRANS_PAY_OBJECT:
+		case TRANS_OBJECT_PAYS:
+			return std::string();
+
+		default:
+			llwarns << "Unknown transaction type " 
+				<< transaction_type << llendl;
+			return std::string();
+	}
+}
+
+static void money_balance_group_notify(const LLUUID& group_id,
+									   const std::string& name,
+									   bool is_group,
+									   std::string notification,
+									   LLSD args,
+									   LLSD payload)
+{
+	// Message uses name SLURLs, don't actually have to substitute in
+	// the name.  We're just making sure it's available.
+	// Notification is either PaymentReceived or PaymentSent
+	LLNotificationsUtil::add(notification, args, payload);
+}
+
+static void money_balance_avatar_notify(const LLUUID& agent_id,
+										const LLAvatarName& av_name,
+									   	std::string notification,
+									   	LLSD args,
+									   	LLSD payload)
+{
+	// Message uses name SLURLs, don't actually have to substitute in
+	// the name.  We're just making sure it's available.
+	// Notification is either PaymentReceived or PaymentSent
+	LLNotificationsUtil::add(notification, args, payload);
+}
+
+static void process_money_balance_reply_extended(LLMessageSystem* msg)
+{
+    // Added in server 1.40 and viewer 2.1, support for localization
+    // and agent ids for name lookup.
+    S32 transaction_type = 0;
+    LLUUID source_id;
+	BOOL is_source_group = FALSE;
+    LLUUID dest_id;
+	BOOL is_dest_group = FALSE;
+    S32 amount = 0;
+    std::string item_description;
+
+    msg->getS32("TransactionInfo", "TransactionType", transaction_type);
+    msg->getUUID("TransactionInfo", "SourceID", source_id);
+	msg->getBOOL("TransactionInfo", "IsSourceGroup", is_source_group);
+    msg->getUUID("TransactionInfo", "DestID", dest_id);
+	msg->getBOOL("TransactionInfo", "IsDestGroup", is_dest_group);
+    msg->getS32("TransactionInfo", "Amount", amount);
+    msg->getString("TransactionInfo", "ItemDescription", item_description);
+    LL_INFOS("Money") << "MoneyBalanceReply source " << source_id 
+		<< " dest " << dest_id
+		<< " type " << transaction_type
+		<< " item " << item_description << LL_ENDL;
+
+	if (source_id.isNull() && dest_id.isNull())
+	{
+		// this is a pure balance update, no notification required
+		return;
+	}
+
+	std::string source_slurl;
+	if (is_source_group)
+	{
+		source_slurl =
+			LLSLURL( "group", source_id, "inspect").getSLURLString();
+	}
+	else
+	{
+		source_slurl =
+			LLSLURL( "agent", source_id, "completename").getSLURLString();
+	}
+
+	std::string dest_slurl;
+	if (is_dest_group)
+	{
+		dest_slurl =
+			LLSLURL( "group", dest_id, "inspect").getSLURLString();
+	}
+	else
+	{
+		dest_slurl =
+			LLSLURL( "agent", dest_id, "completename").getSLURLString();
+	}
+
+	std::string reason =
+		reason_from_transaction_type(transaction_type, item_description);
+	
+	LLStringUtil::format_map_t args;
+	args["REASON"] = reason; // could be empty
+	args["AMOUNT"] = llformat("%d", amount);
+	
+	// Need to delay until name looked up, so need to know whether or not
+	// is group
+	bool is_name_group = false;
+	LLUUID name_id;
+	std::string message;
+	std::string notification;
+	LLSD final_args;
+	LLSD payload;
+	
+	bool you_paid_someone = (source_id == gAgentID);
+	if (you_paid_someone)
+	{
+		args["NAME"] = dest_slurl;
+		is_name_group = is_dest_group;
+		name_id = dest_id;
+		if (!reason.empty())
+		{
+			if (dest_id.notNull())
+			{
+				message = LLTrans::getString("you_paid_ldollars", args);
+			}
+			else
+			{
+				// transaction fee to the system, eg, to create a group
+				message = LLTrans::getString("you_paid_ldollars_no_name", args);
+			}
+		}
+		else
+		{
+			if (dest_id.notNull())
+			{
+				message = LLTrans::getString("you_paid_ldollars_no_reason", args);
+			}
+			else
+			{
+				// no target, no reason, you just paid money
+				message = LLTrans::getString("you_paid_ldollars_no_info", args);
+			}
+		}
+		final_args["MESSAGE"] = message;
+		notification = "PaymentSent";
+	}
+	else {
+		// ...someone paid you
+		args["NAME"] = source_slurl;
+		is_name_group = is_source_group;
+		name_id = source_id;
+		if (!reason.empty())
+		{
+			message = LLTrans::getString("paid_you_ldollars", args);
+		}
+		else {
+			message = LLTrans::getString("paid_you_ldollars_no_reason", args);
+		}
+		final_args["MESSAGE"] = message;
+
+		// make notification loggable
+		payload["from_id"] = source_id;
+		notification = "PaymentReceived";
+	}
+
+	// Despite using SLURLs, wait until the name is available before
+	// showing the notification, otherwise the UI layout is strange and
+	// the user sees a "Loading..." message
+	if (is_name_group)
+	{
+		gCacheName->getGroup(name_id,
+						boost::bind(&money_balance_group_notify,
+									_1, _2, _3,
+									notification, final_args, payload));
+	}
+	else {
+		LLAvatarNameCache::get(name_id,
+							   boost::bind(&money_balance_avatar_notify,
+										   _1, _2,
+										   notification, final_args, payload));										   
+	}
+}
+
+
+
+bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	
+	if (0 == option)
+	{
+		// set the preference to the maturity of the region we're calling
+		int preferredMaturity = notification["payload"]["_region_access"].asInteger();
+		gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
+		gAgent.sendMaturityPreferenceToServer(preferredMaturity);
+
+		// notify user that the maturity preference has been changed
+		LLSD args;
+		args["RATING"] = LLViewerRegion::accessToString(preferredMaturity);
+		LLNotificationsUtil::add("PreferredMaturityChanged", args);
+	}
+	
+	return false;
+}
+
+// some of the server notifications need special handling. This is where we do that.
+bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
+{
+	int regionAccess = llsdBlock["_region_access"].asInteger();
+	llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess);
+	
+	// we're going to throw the LLSD in there in case anyone ever wants to use it
+	LLNotificationsUtil::add(notificationID+"_Notify", llsdBlock);
+	
+	if (regionAccess == SIM_ACCESS_MATURE)
+	{
+		if (gAgent.isTeen())
+		{
+			LLNotificationsUtil::add(notificationID+"_KB", llsdBlock);
+			return true;
+		}
+		else if (gAgent.prefersPG())
+		{
+			LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
+			return true;
+		}
+	}
+	else if (regionAccess == SIM_ACCESS_ADULT)
+	{
+		if (!gAgent.isAdult())
+		{
+			LLNotificationsUtil::add(notificationID+"_KB", llsdBlock);
+			return true;
+		}
+		else if (gAgent.prefersPG() || gAgent.prefersMature())
+		{
+			LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
+			return true;
+		}
+	}
+	return false;
+}
+
+bool attempt_standard_notification(LLMessageSystem* msgsystem)
+{
+	// if we have additional alert data
+	if (msgsystem->has(_PREHASH_AlertInfo) && msgsystem->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0)
+	{
+		// notification was specified using the new mechanism, so we can just handle it here
+		std::string notificationID;
+		std::string llsdRaw;
+		LLSD llsdBlock;
+		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
+		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsdRaw);
+		if (llsdRaw.length())
+		{
+			std::istringstream llsdData(llsdRaw);
+			if (!LLSDSerialize::deserialize(llsdBlock, llsdData, llsdRaw.length()))
+			{
+				llwarns << "attempt_standard_notification: Attempted to read notification parameter data into LLSD but failed:" << llsdRaw << llendl;
+			}
+		}
+		
+		if (
+			(notificationID == "RegionEntryAccessBlocked") ||
+			(notificationID == "LandClaimAccessBlocked") ||
+			(notificationID == "LandBuyAccessBlocked")
+		   )
+		{
+			/*---------------------------------------------------------------------
+			 (Commented so a grep will find the notification strings, since
+			 we construct them on the fly; if you add additional notifications,
+			 please update the comment.)
+			 
+			 Could throw any of the following notifications:
+			 
+				RegionEntryAccessBlocked
+				RegionEntryAccessBlocked_Notify
+				RegionEntryAccessBlocked_Change
+				RegionEntryAccessBlocked_KB
+				LandClaimAccessBlocked 
+				LandClaimAccessBlocked_Notify 
+				LandClaimAccessBlocked_Change 
+				LandClaimAccessBlocked_KB 
+				LandBuyAccessBlocked
+				LandBuyAccessBlocked_Notify
+				LandBuyAccessBlocked_Change
+				LandBuyAccessBlocked_KB
+			 
+			-----------------------------------------------------------------------*/ 
+			if (handle_special_notification(notificationID, llsdBlock))
+			{
+				return true;
+			}
+		}
+		
+		LLNotificationsUtil::add(notificationID, llsdBlock);
+		return true;
+	}	
+	return false;
+}
+
+
+void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data)
+{
+	// make sure the cursor is back to the usual default since the
+	// alert is probably due to some kind of error.
+	gViewerWindow->getWindow()->resetBusyCount();
+	
+	if (!attempt_standard_notification(msgsystem))
+	{
+		BOOL modal = FALSE;
+		msgsystem->getBOOL("AlertData", "Modal", modal);
+		std::string buffer;
+		msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
+		process_alert_core(buffer, modal);
+	}
+}
+
+// The only difference between this routine and the previous is the fact that
+// for this routine, the modal parameter is always false. Sadly, for the message
+// handled by this routine, there is no "Modal" parameter on the message, and
+// there's no API to tell if a message has the given parameter or not.
+// So we can't handle the messages with the same handler.
+void process_alert_message(LLMessageSystem *msgsystem, void **user_data)
+{
+	// make sure the cursor is back to the usual default since the
+	// alert is probably due to some kind of error.
+	gViewerWindow->getWindow()->resetBusyCount();
+		
+	if (!attempt_standard_notification(msgsystem))
+	{
+		BOOL modal = FALSE;
+		std::string buffer;
+		msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
+		process_alert_core(buffer, modal);
+	}
+}
+
+void process_alert_core(const std::string& message, BOOL modal)
+{
+	// HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml
+	if ( message == "You died and have been teleported to your home location")
+	{
+		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
+	}
+	else if( message == "Home position set." )
+	{
+		// save the home location image to disk
+		std::string snap_filename = gDirUtilp->getLindenUserDir();
+		snap_filename += gDirUtilp->getDirDelimiter();
+		snap_filename += SCREEN_HOME_FILENAME;
+		gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);
+	}
+
+	const std::string ALERT_PREFIX("ALERT: ");
+	const std::string NOTIFY_PREFIX("NOTIFY: ");
+	if (message.find(ALERT_PREFIX) == 0)
+	{
+		// Allow the server to spawn a named alert so that server alerts can be
+		// translated out of English.
+		std::string alert_name(message.substr(ALERT_PREFIX.length()));
+		LLNotificationsUtil::add(alert_name);
+	}
+	else if (message.find(NOTIFY_PREFIX) == 0)
+	{
+		// Allow the server to spawn a named notification so that server notifications can be
+		// translated out of English.
+		std::string notify_name(message.substr(NOTIFY_PREFIX.length()));
+		LLNotificationsUtil::add(notify_name);
+	}
+	else if (message[0] == '/')
+	{
+		// System message is important, show in upper-right box not tip
+		std::string text(message.substr(1));
+		LLSD args;
+		if (text.substr(0,17) == "RESTART_X_MINUTES")
+		{
+			S32 mins = 0;
+			LLStringUtil::convertToS32(text.substr(18), mins);
+			args["MINUTES"] = llformat("%d",mins);
+			LLNotificationsUtil::add("RegionRestartMinutes", args);
+		}
+		else if (text.substr(0,17) == "RESTART_X_SECONDS")
+		{
+			S32 secs = 0;
+			LLStringUtil::convertToS32(text.substr(18), secs);
+			args["SECONDS"] = llformat("%d",secs);
+			LLNotificationsUtil::add("RegionRestartSeconds", args);
+		}
+		else
+		{
+			std::string new_msg =LLNotifications::instance().getGlobalString(text);
+			args["MESSAGE"] = new_msg;
+			LLNotificationsUtil::add("SystemMessage", args);
+		}
+	}
+	else if (modal)
+	{
+		LLSD args;
+		std::string new_msg =LLNotifications::instance().getGlobalString(message);
+		args["ERROR_MESSAGE"] = new_msg;
+		LLNotificationsUtil::add("ErrorMessage", args);
+	}
+	else
+	{
+		LLSD args;
+		std::string new_msg =LLNotifications::instance().getGlobalString(message);
+		args["MESSAGE"] = new_msg;
+		LLNotificationsUtil::add("SystemMessageTip", args);
+	}
+}
+
+mean_collision_list_t				gMeanCollisionList;
+time_t								gLastDisplayedTime = 0;
+
+void handle_show_mean_events(void *)
+{
+	if (gNoRender)
+	{
+		return;
+	}
+	LLFloaterReg::showInstance("bumps");
+	//LLFloaterBump::showInstance();
+}
+
+void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_group)
+{
+	if (gNoRender)
+	{
+		return;
+	}
+
+	static const U32 max_collision_list_size = 20;
+	if (gMeanCollisionList.size() > max_collision_list_size)
+	{
+		mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
+		for (U32 i=0; i<max_collision_list_size; i++) iter++;
+		for_each(iter, gMeanCollisionList.end(), DeletePointer());
+		gMeanCollisionList.erase(iter, gMeanCollisionList.end());
+	}
+
+	for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
+		 iter != gMeanCollisionList.end(); ++iter)
+	{
+		LLMeanCollisionData *mcd = *iter;
+		if (mcd->mPerp == id)
+		{
+			mcd->mFullName = full_name;
+		}
+	}
+}
+
+void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **user_data)
+{
+	if (gAgent.inPrelude())
+	{
+		// In prelude, bumping is OK.  This dialog is rather confusing to 
+		// newbies, so we don't show it.  Drop the packet on the floor.
+		return;
+	}
+
+	// make sure the cursor is back to the usual default since the
+	// alert is probably due to some kind of error.
+	gViewerWindow->getWindow()->resetBusyCount();
+
+	LLUUID perp;
+	U32	   time;
+	U8	   u8type;
+	EMeanCollisionType	   type;
+	F32    mag;
+
+	S32 i, num = msgsystem->getNumberOfBlocks(_PREHASH_MeanCollision);
+
+	for (i = 0; i < num; i++)
+	{
+		msgsystem->getUUIDFast(_PREHASH_MeanCollision, _PREHASH_Perp, perp);
+		msgsystem->getU32Fast(_PREHASH_MeanCollision, _PREHASH_Time, time);
+		msgsystem->getF32Fast(_PREHASH_MeanCollision, _PREHASH_Mag, mag);
+		msgsystem->getU8Fast(_PREHASH_MeanCollision, _PREHASH_Type, u8type);
+
+		type = (EMeanCollisionType)u8type;
+
+		BOOL b_found = FALSE;
+
+		for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
+			 iter != gMeanCollisionList.end(); ++iter)
+		{
+			LLMeanCollisionData *mcd = *iter;
+			if ((mcd->mPerp == perp) && (mcd->mType == type))
+			{
+				mcd->mTime = time;
+				mcd->mMag = mag;
+				b_found = TRUE;
+				break;
+			}
+		}
+
+		if (!b_found)
+		{
+			LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag);
+			gMeanCollisionList.push_front(mcd);
+			gCacheName->get(perp, false, boost::bind(&mean_name_callback, _1, _2, _3));
+		}
+	}
+}
+
+void process_frozen_message(LLMessageSystem *msgsystem, void **user_data)
+{
+	// make sure the cursor is back to the usual default since the
+	// alert is probably due to some kind of error.
+	gViewerWindow->getWindow()->resetBusyCount();
+	BOOL b_frozen;
+	
+	msgsystem->getBOOL("FrozenData", "Data", b_frozen);
+
+	// TODO: make being frozen change view
+	if (b_frozen)
+	{
+	}
+	else
+	{
+	}
+}
+
+// do some extra stuff once we get our economy data
+void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
+{
+	LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance());
+
+	S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+
+	LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL;
+
+	gMenuHolder->getChild<LLUICtrl>("Upload Image")->setLabelArg("[COST]", llformat("%d", upload_cost));
+	gMenuHolder->getChild<LLUICtrl>("Upload Sound")->setLabelArg("[COST]", llformat("%d", upload_cost));
+	gMenuHolder->getChild<LLUICtrl>("Upload Animation")->setLabelArg("[COST]", llformat("%d", upload_cost));
+	gMenuHolder->getChild<LLUICtrl>("Bulk Upload")->setLabelArg("[COST]", llformat("%d", upload_cost));
+}
+
+void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted)
+{
+	// only continue if at least some permissions were requested
+	if (orig_questions)
+	{
+		// check to see if the person we are asking
+
+		// "'[OBJECTNAME]', an object owned by '[OWNERNAME]', 
+		// located in [REGIONNAME] at [REGIONPOS], 
+		// has been <granted|denied> permission to: [PERMISSIONS]."
+
+		LLUIString notice(LLTrans::getString(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied"));
+
+		// always include the object name and owner name 
+		notice.setArg("[OBJECTNAME]", notification["payload"]["object_name"].asString());
+		notice.setArg("[OWNERNAME]", notification["payload"]["owner_name"].asString());
+
+		// try to lookup viewerobject that corresponds to the object that
+		// requested permissions (here, taskid->requesting object id)
+		BOOL foundpos = FALSE;
+		LLViewerObject* viewobj = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
+		if (viewobj)
+		{
+			// found the viewerobject, get it's position in its region
+			LLVector3 objpos(viewobj->getPosition());
+			
+			// try to lookup the name of the region the object is in
+			LLViewerRegion* viewregion = viewobj->getRegion();
+			if (viewregion)
+			{
+				// got the region, so include the region and 3d coordinates of the object
+				notice.setArg("[REGIONNAME]", viewregion->getName());				
+				std::string formatpos = llformat("%.1f, %.1f,%.1f", objpos[VX], objpos[VY], objpos[VZ]);
+				notice.setArg("[REGIONPOS]", formatpos);
+
+				foundpos = TRUE;
+			}
+		}
+
+		if (!foundpos)
+		{
+			// unable to determine location of the object
+			notice.setArg("[REGIONNAME]", "(unknown region)");
+			notice.setArg("[REGIONPOS]", "(unknown position)");
+		}
+
+		// check each permission that was requested, and list each 
+		// permission that has been flagged as a caution permission
+		BOOL caution = FALSE;
+		S32 count = 0;
+		std::string perms;
+		for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
+		{
+			if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && SCRIPT_QUESTION_IS_CAUTION[i])
+			{
+				count++;
+				caution = TRUE;
+
+				// add a comma before the permission description if it is not the first permission
+				// added to the list or the last permission to check
+				if ((count > 1) && (i < SCRIPT_PERMISSION_EOF))
+				{
+					perms.append(", ");
+				}
+
+				perms.append(LLTrans::getString(SCRIPT_QUESTIONS[i]));
+			}
+		}
+
+		notice.setArg("[PERMISSIONS]", perms);
+
+		// log a chat message as long as at least one requested permission
+		// is a caution permission
+		if (caution)
+		{
+			LLChat chat(notice.getString());
+	//		LLFloaterChat::addChat(chat, FALSE, FALSE);
+		}
+	}
+}
+
+bool script_question_cb(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	LLMessageSystem *msg = gMessageSystem;
+	S32 orig = notification["payload"]["questions"].asInteger();
+	S32 new_questions = orig;
+
+	// check whether permissions were granted or denied
+	BOOL allowed = TRUE;
+	// the "yes/accept" button is the first button in the template, making it button 0
+	// if any other button was clicked, the permissions were denied
+	if (option != 0)
+	{
+		new_questions = 0;
+		allowed = FALSE;
+	}	
+
+	LLUUID task_id = notification["payload"]["task_id"].asUUID();
+	LLUUID item_id = notification["payload"]["item_id"].asUUID();
+
+	// reply with the permissions granted or denied
+	msg->newMessageFast(_PREHASH_ScriptAnswerYes);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_Data);
+	msg->addUUIDFast(_PREHASH_TaskID, task_id);
+	msg->addUUIDFast(_PREHASH_ItemID, item_id);
+	msg->addS32Fast(_PREHASH_Questions, new_questions);
+	msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
+
+	// only log a chat message if caution prompts are enabled
+	if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
+	{
+		// log a chat message, if appropriate
+		notify_cautioned_script_question(notification, response, orig, allowed);
+	}
+
+	if ( response["Mute"] ) // mute
+	{
+		LLMuteList::getInstance()->add(LLMute(item_id, notification["payload"]["object_name"].asString(), LLMute::OBJECT));
+
+		// purge the message queue of any previously queued requests from the same source. DEV-4879
+		class OfferMatcher : public LLNotificationsUI::LLScreenChannel::Matcher
+		{
+		public:
+			OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
+			bool matches(const LLNotificationPtr notification) const
+			{
+				if (notification->getName() == "ScriptQuestionCaution"
+					|| notification->getName() == "ScriptQuestion")
+				{
+					return (notification->getPayload()["item_id"].asUUID() == blocked_id);
+				}
+				return false;
+			}
+		private:
+			const LLUUID& blocked_id;
+		};
+
+		LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID(
+				gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(item_id));
+	}
+
+	if (response["Details"])
+	{
+		// respawn notification...
+		LLNotificationsUtil::add(notification["name"], notification["substitutions"], notification["payload"]);
+
+		// ...with description on top
+		LLNotificationsUtil::add("DebitPermissionDetails");
+	}
+	return false;
+}
+static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb);
+static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb);
+
+void process_script_question(LLMessageSystem *msg, void **user_data)
+{
+	// *TODO: Translate owner name -> [FIRST] [LAST]
+
+	LLHost sender = msg->getSender();
+
+	LLUUID taskid;
+	LLUUID itemid;
+	S32		questions;
+	std::string object_name;
+	std::string owner_name;
+
+	// taskid -> object key of object requesting permissions
+	msg->getUUIDFast(_PREHASH_Data, _PREHASH_TaskID, taskid );
+	// itemid -> script asset key of script requesting permissions
+	msg->getUUIDFast(_PREHASH_Data, _PREHASH_ItemID, itemid );
+	msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectName, object_name);
+	msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectOwner, owner_name);
+	msg->getS32Fast(_PREHASH_Data, _PREHASH_Questions, questions );
+
+	// Special case. If the objects are owned by this agent, throttle per-object instead
+	// of per-owner. It's common for residents to reset a ton of scripts that re-request
+	// permissions, as with tier boxes. UUIDs can't be valid agent names and vice-versa,
+	// so we'll reuse the same namespace for both throttle types.
+	std::string throttle_name = owner_name;
+	std::string self_name;
+	LLAgentUI::buildFullname( self_name );
+	if( owner_name == self_name )
+	{
+		throttle_name = taskid.getString();
+	}
+	
+	// don't display permission requests if this object is muted
+	if (LLMuteList::getInstance()->isMuted(taskid)) return;
+	
+	// throttle excessive requests from any specific user's scripts
+	typedef LLKeyThrottle<std::string> LLStringThrottle;
+	static LLStringThrottle question_throttle( LLREQUEST_PERMISSION_THROTTLE_LIMIT, LLREQUEST_PERMISSION_THROTTLE_INTERVAL );
+
+	switch (question_throttle.noteAction(throttle_name))
+	{
+		case LLStringThrottle::THROTTLE_NEWLY_BLOCKED:
+			LL_INFOS("Messaging") << "process_script_question throttled"
+					<< " owner_name:" << owner_name
+					<< LL_ENDL;
+			// Fall through
+
+		case LLStringThrottle::THROTTLE_BLOCKED:
+			// Escape altogether until we recover
+			return;
+
+		case LLStringThrottle::THROTTLE_OK:
+			break;
+	}
+
+	std::string script_question;
+	if (questions)
+	{
+		BOOL caution = FALSE;
+		S32 count = 0;
+		LLSD args;
+		args["OBJECTNAME"] = object_name;
+		args["NAME"] = LLCacheName::cleanFullName(owner_name);
+
+		// check the received permission flags against each permission
+		for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
+		{
+			if (questions & LSCRIPTRunTimePermissionBits[i])
+			{
+				count++;
+				script_question += "    " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n";
+
+				// check whether permission question should cause special caution dialog
+				caution |= (SCRIPT_QUESTION_IS_CAUTION[i]);
+			}
+		}
+		args["QUESTIONS"] = script_question;
+
+		LLSD payload;
+		payload["task_id"] = taskid;
+		payload["item_id"] = itemid;
+		payload["sender"] = sender.getIPandPort();
+		payload["questions"] = questions;
+		payload["object_name"] = object_name;
+		payload["owner_name"] = owner_name;
+
+		// check whether cautions are even enabled or not
+		if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
+		{
+			// display the caution permissions prompt
+			LLNotificationsUtil::add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload);
+		}
+		else
+		{
+			// fall back to default behavior if cautions are entirely disabled
+			LLNotificationsUtil::add("ScriptQuestion", args, payload);
+		}
+
+	}
+}
+
+
+void process_derez_container(LLMessageSystem *msg, void**)
+{
+	LL_WARNS("Messaging") << "call to deprecated process_derez_container" << LL_ENDL;
+}
+
+void container_inventory_arrived(LLViewerObject* object,
+								 LLInventoryObject::object_list_t* inventory,
+								 S32 serial_num,
+								 void* data)
+{
+	LL_DEBUGS("Messaging") << "container_inventory_arrived()" << LL_ENDL;
+	if( gAgentCamera.cameraMouselook() )
+	{
+		gAgentCamera.changeCameraToDefault();
+	}
+
+	LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
+
+	if (inventory->size() > 2)
+	{
+		// create a new inventory category to put this in
+		LLUUID cat_id;
+		cat_id = gInventory.createNewCategory(gInventory.getRootFolderID(),
+											  LLFolderType::FT_NONE,
+											  LLTrans::getString("AcquiredItems"));
+
+		LLInventoryObject::object_list_t::const_iterator it = inventory->begin();
+		LLInventoryObject::object_list_t::const_iterator end = inventory->end();
+		for ( ; it != end; ++it)
+		{
+			if ((*it)->getType() != LLAssetType::AT_CATEGORY)
+			{
+				LLInventoryObject* obj = (LLInventoryObject*)(*it);
+				LLInventoryItem* item = (LLInventoryItem*)(obj);
+				LLUUID item_id;
+				item_id.generate();
+				time_t creation_date_utc = time_corrected();
+				LLPointer<LLViewerInventoryItem> new_item
+					= new LLViewerInventoryItem(item_id,
+												cat_id,
+												item->getPermissions(),
+												item->getAssetUUID(),
+												item->getType(),
+												item->getInventoryType(),
+												item->getName(),
+												item->getDescription(),
+												LLSaleInfo::DEFAULT,
+												item->getFlags(),
+												creation_date_utc);
+				new_item->updateServer(TRUE);
+				gInventory.updateItem(new_item);
+			}
+		}
+		gInventory.notifyObservers();
+		if(active_panel)
+		{
+			active_panel->setSelection(cat_id, TAKE_FOCUS_NO);
+		}
+	}
+	else if (inventory->size() == 2)
+	{
+		// we're going to get one fake root category as well as the
+		// one actual object
+		LLInventoryObject::object_list_t::iterator it = inventory->begin();
+
+		if ((*it)->getType() == LLAssetType::AT_CATEGORY)
+		{
+			++it;
+		}
+
+		LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
+		const LLUUID category = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(item->getType()));
+
+		LLUUID item_id;
+		item_id.generate();
+		time_t creation_date_utc = time_corrected();
+		LLPointer<LLViewerInventoryItem> new_item
+			= new LLViewerInventoryItem(item_id, category,
+										item->getPermissions(),
+										item->getAssetUUID(),
+										item->getType(),
+										item->getInventoryType(),
+										item->getName(),
+										item->getDescription(),
+										LLSaleInfo::DEFAULT,
+										item->getFlags(),
+										creation_date_utc);
+		new_item->updateServer(TRUE);
+		gInventory.updateItem(new_item);
+		gInventory.notifyObservers();
+		if(active_panel)
+		{
+			active_panel->setSelection(item_id, TAKE_FOCUS_NO);
+		}
+	}
+
+	// we've got the inventory, now delete this object if this was a take
+	BOOL delete_object = (BOOL)(intptr_t)data;
+	LLViewerRegion *region = gAgent.getRegion();
+	if (delete_object && region)
+	{
+		gMessageSystem->newMessageFast(_PREHASH_ObjectDelete);
+		gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		const U8 NO_FORCE = 0;
+		gMessageSystem->addU8Fast(_PREHASH_Force, NO_FORCE);
+		gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+		gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
+		gMessageSystem->sendReliable(region->getHost());
+	}
+}
+
+// method to format the time.
+std::string formatted_time(const time_t& the_time)
+{
+	std::string dateStr = "["+LLTrans::getString("LTimeWeek")+"] ["
+						+LLTrans::getString("LTimeMonth")+"] ["
+						+LLTrans::getString("LTimeDay")+"] ["
+						+LLTrans::getString("LTimeHour")+"]:["
+						+LLTrans::getString("LTimeMin")+"]:["
+						+LLTrans::getString("LTimeSec")+"] ["
+						+LLTrans::getString("LTimeYear")+"]";
+
+	LLSD substitution;
+	substitution["datetime"] = (S32) the_time;
+	LLStringUtil::format (dateStr, substitution);
+	return dateStr;
+}
+
+
+void process_teleport_failed(LLMessageSystem *msg, void**)
+{
+	std::string reason;
+	std::string big_reason;
+	LLSD args;
+
+	// if we have additional alert data
+	if (msg->has(_PREHASH_AlertInfo) && msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0)
+	{
+		// Get the message ID
+		msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, reason);
+		big_reason = LLAgent::sTeleportErrorMessages[reason];
+		if ( big_reason.size() > 0 )
+		{	// Substitute verbose reason from the local map
+			args["REASON"] = big_reason;
+		}
+		else
+		{	// Nothing found in the map - use what the server returned in the original message block
+			msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
+			args["REASON"] = reason;
+		}
+
+		LLSD llsd_block;
+		std::string llsd_raw;
+		msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsd_raw);
+		if (llsd_raw.length())
+		{
+			std::istringstream llsd_data(llsd_raw);
+			if (!LLSDSerialize::deserialize(llsd_block, llsd_data, llsd_raw.length()))
+			{
+				llwarns << "process_teleport_failed: Attempted to read alert parameter data into LLSD but failed:" << llsd_raw << llendl;
+			}
+			else
+			{
+				// change notification name in this special case
+				if (handle_special_notification("RegionEntryAccessBlocked", llsd_block))
+				{
+					if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
+					{
+						gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
+					}
+					return;
+				}
+			}
+		}
+
+	}
+	else
+	{
+		msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
+
+		big_reason = LLAgent::sTeleportErrorMessages[reason];
+		if ( big_reason.size() > 0 )
+		{	// Substitute verbose reason from the local map
+			args["REASON"] = big_reason;
+		}
+		else
+		{	// Nothing found in the map - use what the server returned
+			args["REASON"] = reason;
+		}
+	}
+
+	LLNotificationsUtil::add("CouldNotTeleportReason", args);
+
+	// Let the interested parties know that teleport failed.
+	LLViewerParcelMgr::getInstance()->onTeleportFailed();
+
+	if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
+	{
+		gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
+	}
+}
+
+void process_teleport_local(LLMessageSystem *msg,void**)
+{
+	LLUUID agent_id;
+	msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
+	if (agent_id != gAgent.getID())
+	{
+		LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
+		return;
+	}
+
+	U32 location_id;
+	LLVector3 pos, look_at;
+	U32 teleport_flags;
+	msg->getU32Fast(_PREHASH_Info, _PREHASH_LocationID, location_id);
+	msg->getVector3Fast(_PREHASH_Info, _PREHASH_Position, pos);
+	msg->getVector3Fast(_PREHASH_Info, _PREHASH_LookAt, look_at);
+	msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
+
+	if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
+	{
+		if( gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL )
+		{
+			// To prevent TeleportStart messages re-activating the progress screen right
+			// after tp, keep the teleport state and let progress screen clear it after a short delay
+			// (progress screen is active but not visible)  *TODO: remove when SVC-5290 is fixed
+			gTeleportDisplayTimer.reset();
+			gTeleportDisplay = TRUE;
+		}
+		else
+		{
+			gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
+		}
+	}
+
+	// Sim tells us whether the new position is off the ground
+	if (teleport_flags & TELEPORT_FLAGS_IS_FLYING)
+	{
+		gAgent.setFlying(TRUE);
+	}
+	else
+	{
+		gAgent.setFlying(FALSE);
+	}
+
+	gAgent.setPositionAgent(pos);
+	gAgentCamera.slamLookAt(look_at);
+
+	if ( !(gAgent.getTeleportKeepsLookAt() && LLViewerJoystick::getInstance()->getOverrideCamera()) )
+	{
+		gAgentCamera.resetView(TRUE, TRUE);
+	}
+
+	// send camera update to new region
+	gAgentCamera.updateCamera();
+
+	send_agent_update(TRUE, TRUE);
+
+	// Let the interested parties know we've teleported.
+	// Vadim *HACK: Agent position seems to get reset (to render position?)
+	//              on each frame, so we have to pass the new position manually.
+	LLViewerParcelMgr::getInstance()->onTeleportFinished(true, gAgent.getPosGlobalFromAgent(pos));
+}
+
+void send_simple_im(const LLUUID& to_id,
+					const std::string& message,
+					EInstantMessage dialog,
+					const LLUUID& id)
+{
+	std::string my_name;
+	LLAgentUI::buildFullname(my_name);
+	send_improved_im(to_id,
+					 my_name,
+					 message,
+					 IM_ONLINE,
+					 dialog,
+					 id,
+					 NO_TIMESTAMP,
+					 (U8*)EMPTY_BINARY_BUCKET,
+					 EMPTY_BINARY_BUCKET_SIZE);
+}
+
+void send_group_notice(const LLUUID& group_id,
+					   const std::string& subject,
+					   const std::string& message,
+					   const LLInventoryItem* item)
+{
+	// Put this notice into an instant message form.
+	// This will mean converting the item to a binary bucket,
+	// and the subject/message into a single field.
+	std::string my_name;
+	LLAgentUI::buildFullname(my_name);
+
+	// Combine subject + message into a single string.
+	std::ostringstream subject_and_message;
+	// TODO: turn all existing |'s into ||'s in subject and message.
+	subject_and_message << subject << "|" << message;
+
+	// Create an empty binary bucket.
+	U8 bin_bucket[MAX_INVENTORY_BUFFER_SIZE];
+	U8* bucket_to_send = bin_bucket;
+	bin_bucket[0] = '\0';
+	S32 bin_bucket_size = EMPTY_BINARY_BUCKET_SIZE;
+	// If there is an item being sent, pack it into the binary bucket.
+	if (item)
+	{
+		LLSD item_def;
+		item_def["item_id"] = item->getUUID();
+		item_def["owner_id"] = item->getPermissions().getOwner();
+		std::ostringstream ostr;
+		LLSDSerialize::serialize(item_def, ostr, LLSDSerialize::LLSD_XML);
+		bin_bucket_size = ostr.str().copy(
+			(char*)bin_bucket, ostr.str().size());
+		bin_bucket[bin_bucket_size] = '\0';
+	}
+	else
+	{
+		bucket_to_send = (U8*) EMPTY_BINARY_BUCKET;
+	}
+   
+
+	send_improved_im(
+			group_id,
+			my_name,
+			subject_and_message.str(),
+			IM_ONLINE,
+			IM_GROUP_NOTICE,
+			LLUUID::null,
+			NO_TIMESTAMP,
+			bucket_to_send,
+			bin_bucket_size);
+}
+
+bool handle_lure_callback(const LLSD& notification, const LLSD& response)
+{
+	std::string text = response["message"].asString();
+	LLSLURL slurl;
+	LLAgentUI::buildSLURL(slurl);
+	text.append("\r\n").append(slurl.getSLURLString());
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+	if(0 == option)
+	{
+		LLMessageSystem* msg = gMessageSystem;
+		msg->newMessageFast(_PREHASH_StartLure);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->nextBlockFast(_PREHASH_Info);
+		msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
+		msg->addStringFast(_PREHASH_Message, text);
+		for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
+			it != notification["payload"]["ids"].endArray();
+			++it)
+		{
+			LLUUID target_id = it->asUUID();
+
+			msg->nextBlockFast(_PREHASH_TargetData);
+			msg->addUUIDFast(_PREHASH_TargetID, target_id);
+
+			// Record the offer.
+			{
+				std::string target_name;
+				gCacheName->getFullName(target_id, target_name);  // for im log filenames
+				LLSD args;
+				args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();;
+	
+				LLSD payload;
+				
+				//*TODO please rewrite all keys to the same case, lower or upper
+				payload["from_id"] = target_id;
+				payload["SUPPRESS_TOAST"] = true;
+				LLNotificationsUtil::add("TeleportOfferSent", args, payload);
+
+				// Add the recepient to the recent people list.
+				LLRecentPeople::instance().add(target_id);
+			}
+		}
+		gAgent.sendReliableMessage();
+	}
+
+	return false;
+}
+
+void handle_lure(const LLUUID& invitee)
+{
+	LLDynamicArray<LLUUID> ids;
+	ids.push_back(invitee);
+	handle_lure(ids);
+}
+
+// Prompt for a message to the invited user.
+void handle_lure(const uuid_vec_t& ids)
+{
+	if (ids.empty()) return;
+
+	if (!gAgent.getRegion()) return;
+
+	LLSD edit_args;
+	edit_args["REGION"] = gAgent.getRegion()->getName();
+
+	LLSD payload;
+	for (LLDynamicArray<LLUUID>::const_iterator it = ids.begin();
+		it != ids.end();
+		++it)
+	{
+		payload["ids"].append(*it);
+	}
+	if (gAgent.isGodlike())
+	{
+		LLNotificationsUtil::add("OfferTeleportFromGod", edit_args, payload, handle_lure_callback);
+	}
+	else
+	{
+		LLNotificationsUtil::add("OfferTeleport", edit_args, payload, handle_lure_callback);
+	}
+}
+
+
+void send_improved_im(const LLUUID& to_id,
+							const std::string& name,
+							const std::string& message,
+							U8 offline,
+							EInstantMessage dialog,
+							const LLUUID& id,
+							U32 timestamp, 
+							const U8* binary_bucket,
+							S32 binary_bucket_size)
+{
+	pack_instant_message(
+		gMessageSystem,
+		gAgent.getID(),
+		FALSE,
+		gAgent.getSessionID(),
+		to_id,
+		name,
+		message,
+		offline,
+		dialog,
+		id,
+		0,
+		LLUUID::null,
+		gAgent.getPositionAgent(),
+		timestamp,
+		binary_bucket,
+		binary_bucket_size);
+	gAgent.sendReliableMessage();
+}
+
+
+void send_places_query(const LLUUID& query_id,
+					   const LLUUID& trans_id,
+					   const std::string& query_text,
+					   U32 query_flags,
+					   S32 category,
+					   const std::string& sim_name)
+{
+	LLMessageSystem* msg = gMessageSystem;
+
+	msg->newMessage("PlacesQuery");
+	msg->nextBlock("AgentData");
+	msg->addUUID("AgentID", gAgent.getID());
+	msg->addUUID("SessionID", gAgent.getSessionID());
+	msg->addUUID("QueryID", query_id);
+	msg->nextBlock("TransactionData");
+	msg->addUUID("TransactionID", trans_id);
+	msg->nextBlock("QueryData");
+	msg->addString("QueryText", query_text);
+	msg->addU32("QueryFlags", query_flags);
+	msg->addS8("Category", (S8)category);
+	msg->addString("SimName", sim_name);
+	gAgent.sendReliableMessage();
+}
+
+
+void process_user_info_reply(LLMessageSystem* msg, void**)
+{
+	LLUUID agent_id;
+	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+	if(agent_id != gAgent.getID())
+	{
+		LL_WARNS("Messaging") << "process_user_info_reply - "
+				<< "wrong agent id." << LL_ENDL;
+	}
+	
+	BOOL im_via_email;
+	msg->getBOOLFast(_PREHASH_UserData, _PREHASH_IMViaEMail, im_via_email);
+	std::string email;
+	msg->getStringFast(_PREHASH_UserData, _PREHASH_EMail, email);
+	std::string dir_visibility;
+	msg->getString( "UserData", "DirectoryVisibility", dir_visibility);
+
+	LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email);
+	LLFloaterPostcard::updateUserInfo(email);
+}
+
+
+//---------------------------------------------------------------------------
+// Script Dialog
+//---------------------------------------------------------------------------
+
+const S32 SCRIPT_DIALOG_MAX_BUTTONS = 12;
+const S32 SCRIPT_DIALOG_BUTTON_STR_SIZE = 24;
+const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512;
+const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n";
+
+bool callback_script_dialog(const LLSD& notification, const LLSD& response)
+{
+	LLNotificationForm form(notification["form"]);
+
+	std::string rtn_text;
+	S32 button_idx;
+	button_idx = LLNotification::getSelectedOption(notification, response);
+	if (response[TEXTBOX_MAGIC_TOKEN].isDefined())
+	{
+		if (response[TEXTBOX_MAGIC_TOKEN].isString())
+			rtn_text = response[TEXTBOX_MAGIC_TOKEN].asString();
+		else
+			rtn_text.clear(); // bool marks empty string
+	}
+	else
+	{
+		rtn_text = LLNotification::getSelectedOptionName(response);
+	}
+
+	// Didn't click "Ignore"
+	if (button_idx != -1)
+	{
+		LLMessageSystem* msg = gMessageSystem;
+		msg->newMessage("ScriptDialogReply");
+		msg->nextBlock("AgentData");
+		msg->addUUID("AgentID", gAgent.getID());
+		msg->addUUID("SessionID", gAgent.getSessionID());
+		msg->nextBlock("Data");
+		msg->addUUID("ObjectID", notification["payload"]["object_id"].asUUID());
+		msg->addS32("ChatChannel", notification["payload"]["chat_channel"].asInteger());
+		msg->addS32("ButtonIndex", button_idx);
+		msg->addString("ButtonLabel", rtn_text);
+		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
+	}
+
+	return false;
+}
+static LLNotificationFunctorRegistration callback_script_dialog_reg_1("ScriptDialog", callback_script_dialog);
+static LLNotificationFunctorRegistration callback_script_dialog_reg_2("ScriptDialogGroup", callback_script_dialog);
+
+void process_script_dialog(LLMessageSystem* msg, void**)
+{
+	S32 i;
+	LLSD payload;
+
+	LLUUID object_id;
+	msg->getUUID("Data", "ObjectID", object_id);
+
+	if (LLMuteList::getInstance()->isMuted(object_id))
+	{
+		return;
+	}
+
+	std::string message; 
+	std::string first_name;
+	std::string last_name;
+	std::string title;
+
+	S32 chat_channel;
+	msg->getString("Data", "FirstName", first_name);
+	msg->getString("Data", "LastName", last_name);
+	msg->getString("Data", "ObjectName", title);
+	msg->getString("Data", "Message", message);
+	msg->getS32("Data", "ChatChannel", chat_channel);
+
+		// unused for now
+	LLUUID image_id;
+	msg->getUUID("Data", "ImageID", image_id);
+
+	payload["sender"] = msg->getSender().getIPandPort();
+	payload["object_id"] = object_id;
+	payload["chat_channel"] = chat_channel;
+
+	// build up custom form
+	S32 button_count = msg->getNumberOfBlocks("Buttons");
+	if (button_count > SCRIPT_DIALOG_MAX_BUTTONS)
+	{
+		llwarns << "Too many script dialog buttons - omitting some" << llendl;
+		button_count = SCRIPT_DIALOG_MAX_BUTTONS;
+	}
+
+	LLNotificationForm form;
+	for (i = 0; i < button_count; i++)
+	{
+		std::string tdesc;
+		msg->getString("Buttons", "ButtonLabel", tdesc, i);
+		form.addElement("button", std::string(tdesc));
+	}
+
+	LLSD args;
+	args["TITLE"] = title;
+	args["MESSAGE"] = message;
+	LLNotificationPtr notification;
+	if (!first_name.empty())
+	{
+		args["NAME"] = LLCacheName::buildFullName(first_name, last_name);
+		notification = LLNotifications::instance().add(
+			LLNotification::Params("ScriptDialog").substitutions(args).payload(payload).form_elements(form.asLLSD()));
+	}
+	else
+	{
+		args["GROUPNAME"] = last_name;
+		notification = LLNotifications::instance().add(
+			LLNotification::Params("ScriptDialogGroup").substitutions(args).payload(payload).form_elements(form.asLLSD()));
+	}
+}
+
+//---------------------------------------------------------------------------
+
+
+std::vector<LLSD> gLoadUrlList;
+
+bool callback_load_url(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+	if (0 == option)
+	{
+		LLWeb::loadURL(notification["payload"]["url"].asString());
+	}
+
+	return false;
+}
+static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", callback_load_url);
+
+
+// We've got the name of the person who owns the object hurling the url.
+// Display confirmation dialog.
+void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool is_group)
+{
+	std::vector<LLSD>::iterator it;
+	for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); )
+	{
+		LLSD load_url_info = *it;
+		if (load_url_info["owner_id"].asUUID() == id)
+		{
+			it = gLoadUrlList.erase(it);
+
+			std::string owner_name;
+			if (is_group)
+			{
+				owner_name = full_name + LLTrans::getString("Group");
+			}
+			else
+			{
+				owner_name = full_name;
+			}
+
+			// For legacy name-only mutes.
+			if (LLMuteList::getInstance()->isMuted(LLUUID::null, owner_name))
+			{
+				continue;
+			}
+			LLSD args;
+			args["URL"] = load_url_info["url"].asString();
+			args["MESSAGE"] = load_url_info["message"].asString();;
+			args["OBJECTNAME"] = load_url_info["object_name"].asString();
+			args["NAME"] = owner_name;
+
+			LLNotificationsUtil::add("LoadWebPage", args, load_url_info);
+		}
+		else
+		{
+			++it;
+		}
+	}
+}
+
+void process_load_url(LLMessageSystem* msg, void**)
+{
+	LLUUID object_id;
+	LLUUID owner_id;
+	BOOL owner_is_group;
+	char object_name[256];		/* Flawfinder: ignore */
+	char message[256];		/* Flawfinder: ignore */
+	char url[256];		/* Flawfinder: ignore */
+
+	msg->getString("Data", "ObjectName", 256, object_name);
+	msg->getUUID(  "Data", "ObjectID", object_id);
+	msg->getUUID(  "Data", "OwnerID", owner_id);
+	msg->getBOOL(  "Data", "OwnerIsGroup", owner_is_group);
+	msg->getString("Data", "Message", 256, message);
+	msg->getString("Data", "URL", 256, url);
+
+	LLSD payload;
+	payload["object_id"] = object_id;
+	payload["owner_id"] = owner_id;
+	payload["owner_is_group"] = owner_is_group;
+	payload["object_name"] = object_name;
+	payload["message"] = message;
+	payload["url"] = url;
+
+	// URL is safety checked in load_url above
+
+	// Check if object or owner is muted
+	if (LLMuteList::getInstance()->isMuted(object_id, object_name) ||
+	    LLMuteList::getInstance()->isMuted(owner_id))
+	{
+		LL_INFOS("Messaging")<<"Ignoring load_url from muted object/owner."<<LL_ENDL;
+		return;
+	}
+
+	// Add to list of pending name lookups
+	gLoadUrlList.push_back(payload);
+
+	gCacheName->get(owner_id, owner_is_group,
+		boost::bind(&callback_load_url_name, _1, _2, _3));
+}
+
+
+void callback_download_complete(void** data, S32 result, LLExtStat ext_status)
+{
+	std::string* filepath = (std::string*)data;
+	LLSD args;
+	args["DOWNLOAD_PATH"] = *filepath;
+	LLNotificationsUtil::add("FinishedRawDownload", args);
+	delete filepath;
+}
+
+
+void process_initiate_download(LLMessageSystem* msg, void**)
+{
+	LLUUID agent_id;
+	msg->getUUID("AgentData", "AgentID", agent_id);
+	if (agent_id != gAgent.getID())
+	{
+		LL_WARNS("Messaging") << "Initiate download for wrong agent" << LL_ENDL;
+		return;
+	}
+
+	std::string sim_filename;
+	std::string viewer_filename;
+	msg->getString("FileData", "SimFilename", sim_filename);
+	msg->getString("FileData", "ViewerFilename", viewer_filename);
+
+	if (!gXferManager->validateFileForRequest(viewer_filename))
+	{
+		llwarns << "SECURITY: Unauthorized download to local file " << viewer_filename << llendl;
+		return;
+	}
+	gXferManager->requestFile(viewer_filename,
+		sim_filename,
+		LL_PATH_NONE,
+		msg->getSender(),
+		FALSE,	// don't delete remote
+		callback_download_complete,
+		(void**)new std::string(viewer_filename));
+}
+
+
+void process_script_teleport_request(LLMessageSystem* msg, void**)
+{
+	if (!gSavedSettings.getBOOL("ScriptsCanShowUI")) return;
+
+	std::string object_name;
+	std::string sim_name;
+	LLVector3 pos;
+	LLVector3 look_at;
+
+	msg->getString("Data", "ObjectName", object_name);
+	msg->getString("Data", "SimName", sim_name);
+	msg->getVector3("Data", "SimPosition", pos);
+	msg->getVector3("Data", "LookAt", look_at);
+
+	LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
+	if(instance)
+	{
+		instance->trackURL(
+						   sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]);
+		LLFloaterReg::showInstance("world_map", "center");
+	}
+	
+	// remove above two lines and replace with below line
+	// to re-enable parcel browser for llMapDestination()
+	// LLURLDispatcher::dispatch(LLSLURL::buildSLURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]), FALSE);
+	
+}
+
+void process_covenant_reply(LLMessageSystem* msg, void**)
+{
+	LLUUID covenant_id, estate_owner_id;
+	std::string estate_name;
+	U32 covenant_timestamp;
+	msg->getUUID("Data", "CovenantID", covenant_id);
+	msg->getU32("Data", "CovenantTimestamp", covenant_timestamp);
+	msg->getString("Data", "EstateName", estate_name);
+	msg->getUUID("Data", "EstateOwnerID", estate_owner_id);
+
+	LLPanelEstateCovenant::updateEstateName(estate_name);
+	LLPanelLandCovenant::updateEstateName(estate_name);
+	LLFloaterBuyLand::updateEstateName(estate_name);
+
+	std::string owner_name =
+		LLSLURL("agent", estate_owner_id, "inspect").getSLURLString();
+	LLPanelEstateCovenant::updateEstateOwnerName(owner_name);
+	LLPanelLandCovenant::updateEstateOwnerName(owner_name);
+	LLFloaterBuyLand::updateEstateOwnerName(owner_name);
+
+	LLPanelPlaceProfile* panel = LLSideTray::getInstance()->getPanel<LLPanelPlaceProfile>("panel_place_profile");
+	if (panel)
+	{
+		panel->updateEstateName(estate_name);
+		panel->updateEstateOwnerName(owner_name);
+	}
+
+	// standard message, not from system
+	std::string last_modified;
+	if (covenant_timestamp == 0)
+	{
+		last_modified = LLTrans::getString("covenant_last_modified")+LLTrans::getString("never_text");
+	}
+	else
+	{
+		last_modified = LLTrans::getString("covenant_last_modified")+"["
+						+LLTrans::getString("LTimeWeek")+"] ["
+						+LLTrans::getString("LTimeMonth")+"] ["
+						+LLTrans::getString("LTimeDay")+"] ["
+						+LLTrans::getString("LTimeHour")+"]:["
+						+LLTrans::getString("LTimeMin")+"]:["
+						+LLTrans::getString("LTimeSec")+"] ["
+						+LLTrans::getString("LTimeYear")+"]";
+		LLSD substitution;
+		substitution["datetime"] = (S32) covenant_timestamp;
+		LLStringUtil::format (last_modified, substitution);
+	}
+
+	LLPanelEstateCovenant::updateLastModified(last_modified);
+	LLPanelLandCovenant::updateLastModified(last_modified);
+	LLFloaterBuyLand::updateLastModified(last_modified);
+
+	// load the actual covenant asset data
+	const BOOL high_priority = TRUE;
+	if (covenant_id.notNull())
+	{
+		gAssetStorage->getEstateAsset(gAgent.getRegionHost(),
+									gAgent.getID(),
+									gAgent.getSessionID(),
+									covenant_id,
+                                    LLAssetType::AT_NOTECARD,
+									ET_Covenant,
+                                    onCovenantLoadComplete,
+									NULL,
+									high_priority);
+	}
+	else
+	{
+		std::string covenant_text;
+		if (estate_owner_id.isNull())
+		{
+			// mainland
+			covenant_text = LLTrans::getString("RegionNoCovenant");
+		}
+		else
+		{
+			covenant_text = LLTrans::getString("RegionNoCovenantOtherOwner");
+		}
+		LLPanelEstateCovenant::updateCovenantText(covenant_text, covenant_id);
+		LLPanelLandCovenant::updateCovenantText(covenant_text);
+		LLFloaterBuyLand::updateCovenantText(covenant_text, covenant_id);
+		if (panel)
+		{
+			panel->updateCovenantText(covenant_text);
+		}
+	}
+}
+
+void onCovenantLoadComplete(LLVFS *vfs,
+					const LLUUID& asset_uuid,
+					LLAssetType::EType type,
+					void* user_data, S32 status, LLExtStat ext_status)
+{
+	LL_DEBUGS("Messaging") << "onCovenantLoadComplete()" << LL_ENDL;
+	std::string covenant_text;
+	if(0 == status)
+	{
+		LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
+		
+		S32 file_length = file.getSize();
+		
+		std::vector<char> buffer(file_length+1);
+		file.read((U8*)&buffer[0], file_length);		
+		// put a EOS at the end
+		buffer[file_length] = '\0';
+		
+		if( (file_length > 19) && !strncmp( &buffer[0], "Linden text version", 19 ) )
+		{
+			LLViewerTextEditor::Params params;
+			params.name("temp");
+			params.max_text_length(file_length+1);
+			LLViewerTextEditor * editor = LLUICtrlFactory::create<LLViewerTextEditor> (params);
+			if( !editor->importBuffer( &buffer[0], file_length+1 ) )
+			{
+				LL_WARNS("Messaging") << "Problem importing estate covenant." << LL_ENDL;
+				covenant_text = "Problem importing estate covenant.";
+			}
+			else
+			{
+				// Version 0 (just text, doesn't include version number)
+				covenant_text = editor->getText();
+			}
+			delete editor;
+		}
+		else
+		{
+			LL_WARNS("Messaging") << "Problem importing estate covenant: Covenant file format error." << LL_ENDL;
+			covenant_text = "Problem importing estate covenant: Covenant file format error.";
+		}
+	}
+	else
+	{
+		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+		
+		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
+		    LL_ERR_FILE_EMPTY == status)
+		{
+			covenant_text = "Estate covenant notecard is missing from database.";
+		}
+		else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
+		{
+			covenant_text = "Insufficient permissions to view estate covenant.";
+		}
+		else
+		{
+			covenant_text = "Unable to load estate covenant at this time.";
+		}
+		
+		LL_WARNS("Messaging") << "Problem loading notecard: " << status << LL_ENDL;
+	}
+	LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid);
+	LLPanelLandCovenant::updateCovenantText(covenant_text);
+	LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid);
+
+	LLPanelPlaceProfile* panel = LLSideTray::getInstance()->getPanel<LLPanelPlaceProfile>("panel_place_profile");
+	if (panel)
+	{
+		panel->updateCovenantText(covenant_text);
+	}
+}
+
+
+void process_feature_disabled_message(LLMessageSystem* msg, void**)
+{
+	// Handle Blacklisted feature simulator response...
+	LLUUID	agentID;
+	LLUUID	transactionID;
+	std::string	messageText;
+	msg->getStringFast(_PREHASH_FailureInfo,_PREHASH_ErrorMessage, messageText,0);
+	msg->getUUIDFast(_PREHASH_FailureInfo,_PREHASH_AgentID,agentID);
+	msg->getUUIDFast(_PREHASH_FailureInfo,_PREHASH_TransactionID,transactionID);
+	
+	LL_WARNS("Messaging") << "Blacklisted Feature Response:" << messageText << LL_ENDL;
+}
+
+// ------------------------------------------------------------
+// Message system exception callbacks
+// ------------------------------------------------------------
+
+void invalid_message_callback(LLMessageSystem* msg,
+								   void*,
+								   EMessageException exception)
+{
+    LLAppViewer::instance()->badNetworkHandler();
+}
+
+// Please do not add more message handlers here. This file is huge.
+// Put them in a file related to the functionality you are implementing.
+
+void LLOfferInfo::forceResponse(InventoryOfferResponse response)
+{
+	LLNotification::Params params("UserGiveItem");
+	params.functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2));
+	LLNotifications::instance().forceResponse(params, response);
+}
+