From 71d28bdbf0baab9302c8f458e3bdbcfc60d656d4 Mon Sep 17 00:00:00 2001
From: Steven Bennetts <steve@lindenlab.com>
Date: Wed, 17 Jan 2007 23:02:00 +0000
Subject: [PATCH] merge release@56803 release-candidate@56833

---
 indra/llmessage/llassetstorage.cpp            |  96 ++++++--
 indra/llmessage/llassetstorage.h              |  30 ++-
 indra/llmessage/llhttpassetstorage.cpp        |   6 +-
 indra/llmessage/llinstantmessage.cpp          |   2 +-
 indra/llmessage/llqueryflags.h                |  49 ++--
 indra/llmessage/llregionflags.h               |   2 +
 indra/llmessage/lltransfermanager.cpp         | 150 +++++++++---
 indra/llmessage/lltransfermanager.h           |  30 ++-
 indra/llmessage/lltransfersourceasset.cpp     |  78 +++++--
 indra/llmessage/lltransfersourceasset.h       |  21 ++
 indra/llmessage/lltransfersourcefile.cpp      |   7 +-
 indra/llmessage/lltransfersourcefile.h        |   1 +
 indra/llmessage/lltransfertargetfile.cpp      |  13 +-
 indra/llmessage/lltransfertargetfile.h        |   3 +-
 indra/llmessage/lltransfertargetvfile.cpp     |  73 +++++-
 indra/llmessage/lltransfertargetvfile.h       |  32 ++-
 indra/llmessage/message.cpp                   |   8 +-
 indra/llui/llmenugl.cpp                       |  12 +-
 indra/llui/llmenugl.h                         |   2 +-
 indra/llui/llscrolllistctrl.cpp               |  93 ++++++--
 indra/llui/llscrolllistctrl.h                 |  12 +-
 indra/llvfs/llvfs.cpp                         |   6 +-
 indra/llvfs/llvfsthread.cpp                   |   1 +
 indra/newview/English.lproj/InfoPlist.strings |   4 +-
 indra/newview/Info-SecondLife.plist           |   2 +-
 indra/newview/llfloaterfriends.cpp            |  29 ++-
 indra/newview/llfloatergodtools.cpp           |   2 +
 indra/newview/llfloaterinspect.cpp            | 221 ++++++++++++++++++
 indra/newview/llfloaterinspect.h              |  47 ++++
 indra/newview/llfloaterregioninfo.cpp         |   6 +-
 indra/newview/llfloaterreporter.cpp           | 110 +++++++--
 indra/newview/llfloaterreporter.h             |   6 +
 indra/newview/llfloatertelehub.cpp            |   1 +
 indra/newview/llfloatertools.cpp              |  37 ++-
 indra/newview/llfloatertools.h                |   9 +-
 indra/newview/llinventorymodel.cpp            |  15 +-
 indra/newview/llinventorymodel.h              |   1 +
 indra/newview/llpanelpermissions.cpp          |   6 +-
 indra/newview/llpreviewscript.cpp             |   8 +-
 indra/newview/llselectmgr.cpp                 |  30 ++-
 indra/newview/llselectmgr.h                   |   2 +
 indra/newview/llstartup.cpp                   |   2 +
 indra/newview/lltoolcomp.cpp                  |  69 +++++-
 indra/newview/lltoolcomp.h                    |  24 +-
 indra/newview/lltoolmgr.cpp                   |  12 +
 indra/newview/llviewermenu.cpp                |  52 ++---
 indra/newview/llviewermessage.cpp             |  31 +--
 indra/newview/llviewernetwork.cpp             |   4 +
 indra/newview/llviewernetwork.h               |   1 +
 indra/newview/llviewerregion.cpp              |   2 +
 indra/newview/llviewerwindow.cpp              |  12 +-
 scripts/messages/message_template.msg         | 173 ++------------
 52 files changed, 1207 insertions(+), 438 deletions(-)
 create mode 100644 indra/newview/llfloaterinspect.cpp
 create mode 100644 indra/newview/llfloaterinspect.h

diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index b23567288d9..e2bfd0496b2 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -465,15 +465,29 @@ void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType at
 }
 
 
-void LLAssetStorage::downloadCompleteCallback(S32 result, void *user_data)
+void LLAssetStorage::downloadCompleteCallback(
+	S32 result,
+	const LLUUID& file_id,
+	LLAssetType::EType file_type,
+	void* user_data)
 {
-	LLAssetRequest* req = (LLAssetRequest *)user_data;
+	lldebugs << "LLAssetStorage::downloadCompleteCallback() for " << file_id
+		 << "," << LLAssetType::lookup(file_type) << llendl;
+	LLAssetRequest* req = (LLAssetRequest*)user_data;
+	if(!req)
+	{
+		llwarns << "LLAssetStorage::downloadCompleteCallback called without"
+			"a valid request." << llendl;
+		return;
+	}
 	if (!gAssetStorage)
 	{
 		llwarns << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << llendl;
 		return;
 	}
 
+	req->setUUID(file_id);
+	req->setType(file_type);
 	if (LL_ERR_NOERR == result)
 	{
 		// we might have gotten a zero-size file
@@ -601,15 +615,28 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen
 	}
 }
 
-void LLAssetStorage::downloadEstateAssetCompleteCallback(S32 result, void *user_data)
+void LLAssetStorage::downloadEstateAssetCompleteCallback(
+	S32 result,
+	const LLUUID& file_id,
+	LLAssetType::EType file_type,
+	void* user_data)
 {
-	LLEstateAssetRequest *req = (LLEstateAssetRequest *)user_data;
+	LLEstateAssetRequest *req = (LLEstateAssetRequest*)user_data;
+	if(!req)
+	{
+		llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
+			" without a valid request." << llendl;
+		return;
+	}
 	if (!gAssetStorage)
 	{
-		llwarns << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << llendl;
+		llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
+			" without any asset system, aborting!" << llendl;
 		return;
 	}
 
+	req->setUUID(file_id);
+	req->setType(file_type);
 	if (LL_ERR_NOERR == result)
 	{
 		// we might have gotten a zero-size file
@@ -636,29 +663,36 @@ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &age
 	//
 	// Probably will get rid of this early out?
 	//
-	if (asset_id.isNull())
+	//if (asset_id.isNull())
+	//{
+	//	// Special case early out for NULL uuid
+	//	if (callback)
+	//	{
+	//		callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE);
+	//	}
+	//	return;
+	//}
+
+	bool exists = false; 
+	U32 size = 0;
+
+	if(asset_id.notNull())
 	{
-		// Special case early out for NULL uuid
-		if (callback)
+		exists = mVFS->getExists(asset_id, atype);
+		LLVFile file(mVFS, asset_id, atype);
+		size = exists ? file.getSize() : 0;
+		if(exists && size < 1)
 		{
-			callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE);
+			llwarns << "Asset vfile " << asset_id << ":" << atype << " found with bad size " << file.getSize() << ", removing" << llendl;
+			file.remove();
 		}
-		return;
-	}
 
-	BOOL exists = mVFS->getExists(asset_id, atype);
-	LLVFile file(mVFS, asset_id, atype);
-	U32 size = exists ? file.getSize() : 0;
+	}
 
 	if (size < 1)
 	{
-		if (exists)
-		{
-			llwarns << "Asset vfile " << asset_id << ":" << atype << " found with bad size " << file.getSize() << ", removing" << llendl;
-			file.remove();
-		}
-
-		// See whether we should talk to the object's originating sim, or the upstream provider.
+		// See whether we should talk to the object's originating sim,
+		// or the upstream provider.
 		LLHost source_host;
 		if (object_sim.isOk())
 		{
@@ -688,7 +722,9 @@ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &age
 			tpvf.setAsset(asset_id, atype);
 			tpvf.setCallback(downloadInvItemCompleteCallback, req);
 
-			llinfos << "Starting transfer for " << asset_id << llendl;
+			llinfos << "Starting transfer for inventory asset "
+				<< item_id << " owned by " << owner_id << "," << task_id
+				<< llendl;
 			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET);
 			ttcp->requestTransfer(spi, tpvf, 100.f + (is_priority ? 1.f : 0.f));
 		}
@@ -715,15 +751,27 @@ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &age
 }
 
 
-void LLAssetStorage::downloadInvItemCompleteCallback(S32 result, void *user_data)
+void LLAssetStorage::downloadInvItemCompleteCallback(
+	S32 result,
+	const LLUUID& file_id,
+	LLAssetType::EType file_type,
+	void* user_data)
 {
-	LLInvItemRequest *req = (LLInvItemRequest *)user_data;
+	LLInvItemRequest *req = (LLInvItemRequest*)user_data;
+	if(!req)
+	{
+		llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
+			" without a valid request." << llendl;
+		return;
+	}
 	if (!gAssetStorage)
 	{
 		llwarns << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << llendl;
 		return;
 	}
 
+	req->setUUID(file_id);
+	req->setType(file_type);
 	if (LL_ERR_NOERR == result)
 	{
 		// we might have gotten a zero-size file
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h
index 4ccbb08abdd..59baddd69cc 100644
--- a/indra/llmessage/llassetstorage.h
+++ b/indra/llmessage/llassetstorage.h
@@ -68,6 +68,10 @@ class LLAssetRequest
 	
 	LLUUID getUUID() const					{ return mUUID; }
 	LLAssetType::EType getType() const		{ return mType; }
+
+	void setUUID(const LLUUID& id) { mUUID = id; }
+	void setType(LLAssetType::EType type) { mType = type; }
+
 protected:
 	LLUUID	mUUID;
 	LLAssetType::EType mType;
@@ -97,6 +101,10 @@ class LLInvItemRequest
 
 	LLUUID getUUID() const					{ return mUUID; }
 	LLAssetType::EType getType() const		{ return mType; }
+
+	void setUUID(const LLUUID& id) { mUUID = id; }
+	void setType(LLAssetType::EType type) { mType = type; }
+
 protected:
 	LLUUID	mUUID;
 	LLAssetType::EType mType;
@@ -122,6 +130,10 @@ class LLEstateAssetRequest
 
 	LLUUID getUUID() const					{ return mUUID; }
 	LLAssetType::EType getAType() const		{ return mAType; }
+
+	void setUUID(const LLUUID& id) { mUUID = id; }
+	void setType(LLAssetType::EType type) { mAType = type; }
+
 protected:
 	LLUUID	mUUID;
 	LLAssetType::EType mAType;
@@ -237,9 +249,21 @@ class LLAssetStorage
 	LLSD getPendingUploadTypes() const;
 
 	// download process callbacks
-	static void downloadCompleteCallback(const S32 result, void *user_data);
-	static void downloadEstateAssetCompleteCallback(const S32 result, void *user_data);
-	static void downloadInvItemCompleteCallback(const S32 result, void *user_data);
+	static void downloadCompleteCallback(
+		S32 result,
+		const LLUUID& file_id,
+		LLAssetType::EType file_type,
+		void* user_data);
+	static void downloadEstateAssetCompleteCallback(
+		S32 result,
+		const LLUUID& file_id,
+		LLAssetType::EType file_type,
+		void* user_data);
+	static void downloadInvItemCompleteCallback(
+		S32 result,
+		const LLUUID& file_id,
+		LLAssetType::EType file_type,
+		void* user_data);
 
 	// upload process callbacks
 	static void uploadCompleteCallback(const LLUUID&, void *user_data, S32 result);
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 856e79191fc..23beeafb138 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -670,7 +670,11 @@ void LLHTTPAssetStorage::checkForTimeouts()
 
 				// call the static callback for transfer completion
 				// this will cleanup all requests for this asset, including ours
-				downloadCompleteCallback(xfer_result, (void *)req);
+				downloadCompleteCallback(
+					xfer_result,
+					req->getUUID(),
+					req->getType(),
+					(void *)req);
 				// Pending download flag will get cleared when the request is deleted
 			}
 			else
diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp
index 2bfa82a0ce7..10ff8eb88d6 100644
--- a/indra/llmessage/llinstantmessage.cpp
+++ b/indra/llmessage/llinstantmessage.cpp
@@ -257,7 +257,7 @@ void LLIMInfo::unpackMessageBlock(LLMessageSystem* msg)
 		msg->getSizeFast(
 			_PREHASH_MessageBlock,
 			_PREHASH_BinaryBucket));
-	if(binary_bucket_size)
+	if(binary_bucket_size > 0)
 	{
 		std::vector<U8> bucket;
 		bucket.resize(binary_bucket_size);
diff --git a/indra/llmessage/llqueryflags.h b/indra/llmessage/llqueryflags.h
index be6c9acf671..064e42bae63 100644
--- a/indra/llmessage/llqueryflags.h
+++ b/indra/llmessage/llqueryflags.h
@@ -12,21 +12,38 @@
 // Binary flags used for Find queries, shared between viewer and dataserver.
 
 // DirFindQuery flags
-const U32 DFQ_PEOPLE			= 0x0001;
-const U32 DFQ_ONLINE			= 0x0002;
-//const U32 DFQ_PLACES			= 0x0004;
-const U32 DFQ_EVENTS			= 0x0008;
-const U32 DFQ_GROUPS			= 0x0010;
-const U32 DFQ_DATE_EVENTS		= 0x0020;
-
-const U32 DFQ_AGENT_OWNED		= 0x0040;
-const U32 DFQ_FOR_SALE			= 0x0080;
-const U32 DFQ_GROUP_OWNED		= 0x0100;
-//const U32 DFQ_AUCTION			= 0x0200;
-const U32 DFQ_DWELL_SORT		= 0x0400;
-const U32 DFQ_PG_SIMS_ONLY		= 0x0800;
-const U32 DFQ_PICTURES_ONLY		= 0x1000;
-const U32 DFQ_PG_EVENTS_ONLY	= 0x2000;
-const U32 DFQ_MATURE_SIMS_ONLY  = 0x4000;
+const U32 DFQ_PEOPLE			= 0x1 << 0;
+const U32 DFQ_ONLINE			= 0x1 << 1;
+//const U32 DFQ_PLACES			= 0x1 << 2;
+const U32 DFQ_EVENTS			= 0x1 << 3;
+const U32 DFQ_GROUPS			= 0x1 << 4;
+const U32 DFQ_DATE_EVENTS		= 0x1 << 5;
+
+const U32 DFQ_AGENT_OWNED		= 0x1 << 6;
+const U32 DFQ_FOR_SALE			= 0x1 << 7;
+const U32 DFQ_GROUP_OWNED		= 0x1 << 8;
+//const U32 DFQ_AUCTION			= 0x1 << 9;
+const U32 DFQ_DWELL_SORT		= 0x1 << 10;
+const U32 DFQ_PG_SIMS_ONLY		= 0x1 << 11;
+const U32 DFQ_PICTURES_ONLY		= 0x1 << 12;
+const U32 DFQ_PG_EVENTS_ONLY	= 0x1 << 13;
+const U32 DFQ_MATURE_SIMS_ONLY  = 0x1 << 14;
+
+const U32 DFQ_SORT_ASC			= 0x1 << 15;
+const U32 DFQ_PRICE_SORT		= 0x1 << 16;
+const U32 DFQ_PER_METER_SORT	= 0x1 << 17;
+const U32 DFQ_AREA_SORT			= 0x1 << 18;
+const U32 DFQ_NAME_SORT			= 0x1 << 19;
+
+const U32 DFQ_LIMIT_BY_PRICE	= 0x1 << 20;
+const U32 DFQ_LIMIT_BY_AREA		= 0x1 << 21;
+
+// Sell Type flags
+const U32 ST_AUCTION	= 0x1 << 1;
+const U32 ST_NEWBIE		= 0x1 << 2;
+const U32 ST_MAINLAND	= 0x1 << 3;
+const U32 ST_ESTATE		= 0x1 << 4;
+
+const U32 ST_ALL		= 0xFFFFFFFF;
 
 #endif
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index 3f37c72cee7..e7797ea1580 100644
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -66,6 +66,8 @@ const U32 REGION_FLAGS_DENY_TRANSACTED			= (1 << 25);
 
 const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES		= (1 << 26);
 
+const U32 REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER = (1 << 27);
+
 const U32 REGION_FLAGS_NULL_LAYER				= (1 << 9);
 
 const U32 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
diff --git a/indra/llmessage/lltransfermanager.cpp b/indra/llmessage/lltransfermanager.cpp
index 436363672e7..34344040b88 100644
--- a/indra/llmessage/lltransfermanager.cpp
+++ b/indra/llmessage/lltransfermanager.cpp
@@ -206,30 +206,43 @@ void LLTransferManager::processTransferRequest(LLMessageSystem *msgp, void **)
 		return;
 	}
 
+	S32 size = msgp->getSize("TransferInfo", "Params");
+	if(size > MAX_PARAMS_SIZE)
+	{
+		llwarns << "LLTransferManager::processTransferRequest params too big."
+			<< llendl;
+		return;
+	}
 
 	//llinfos << transfer_id << ":" << source_type << ":" << channel_type << ":" << priority << llendl;
-	LLTransferSource *tsp = LLTransferSource::createSource(source_type, transfer_id, priority);
-	if (!tsp)
+	LLTransferSource* tsp = LLTransferSource::createSource(
+		source_type,
+		transfer_id,
+		priority);
+	if(!tsp)
 	{
-		llwarns << "LLTransferManager::processTransferRequest couldn't create transfer source!" << llendl;
+		llwarns << "LLTransferManager::processTransferRequest couldn't create"
+			<< " transfer source!" << llendl;
 		return;
 	}
-	tscp->addTransferSource(tsp);
-
 	U8 tmp[MAX_PARAMS_SIZE];
-	S32 size = msgp->getSize("TransferInfo", "Params");
-	gMessageSystem->getBinaryData("TransferInfo", "Params", tmp, size);
+	msgp->getBinaryData("TransferInfo", "Params", tmp, size);
 
 	LLDataPackerBinaryBuffer dpb(tmp, MAX_PARAMS_SIZE);
 	BOOL unpack_ok = tsp->unpackParams(dpb);
 	if (!unpack_ok)
 	{
-		llwarns << "Got bad parameters for a transfer request!" << llendl;
+		// This should only happen if the data is corrupt or
+		// incorrectly packed.
+		// *NOTE: We may want to call abortTransfer().
+		llwarns << "LLTransferManager::processTransferRequest: bad parameters."
+			<< llendl;
+		delete tsp;
+		return;
 	}
 
+	tscp->addTransferSource(tsp);
 	tsp->initTransfer();
-	// Don't use the status code from initTransfer for anything right now, was used before but the logic
-	// changed.
 }
 
 
@@ -277,6 +290,31 @@ void LLTransferManager::processTransferInfo(LLMessageSystem *msgp, void **)
 		return;
 	}
 
+	// unpack the params
+	S32 params_size = msgp->getSize("TransferInfo", "Params");
+	if(params_size > MAX_PARAMS_SIZE)
+	{
+		llwarns << "LLTransferManager::processTransferInfo params too big."
+			<< llendl;
+		return;
+	}
+	else if(params_size > 0)
+	{
+		U8 tmp[MAX_PARAMS_SIZE];
+		msgp->getBinaryData("TransferInfo", "Params", tmp, params_size);
+		LLDataPackerBinaryBuffer dpb(tmp, MAX_PARAMS_SIZE);
+		if (!ttp->unpackParams(dpb))
+		{
+			// This should only happen if the data is corrupt or
+			// incorrectly packed.
+			llwarns << "LLTransferManager::processTransferRequest: bad params."
+				<< llendl;
+			ttp->abortTransfer();
+			ttcp->deleteTransfer(ttp);
+			return;
+		}
+	}
+
 	llinfos << "Receiving " << transfer_id << ", size " << size << " bytes" << llendl;
 	ttp->setSize(size);
 	ttp->setGotInfo(TRUE);
@@ -373,9 +411,9 @@ void LLTransferManager::processTransferPacket(LLMessageSystem *msgp, void **)
 	LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id);
 	if (!ttp)
 	{
-		llwarns << "Didn't find matching transfer for " << transfer_id << ", aborting!" << llendl;
-		llwarns << "Packet ID: " << packet_id << llendl;
-		llwarns << "Should notify source of this!" << llendl;
+		llwarns << "Didn't find matching transfer for " << transfer_id
+			<< " processing packet " << packet_id
+			<< " from " << msgp->getSender() << llendl;
 		return;
 	}
 
@@ -407,11 +445,29 @@ void LLTransferManager::processTransferPacket(LLMessageSystem *msgp, void **)
 
 	if ((!ttp->gotInfo()) || (ttp->getNextPacketID() != packet_id))
 	{
-
-		llwarns << "Out of order packet in transfer " << transfer_id << ", got " << packet_id << " expecting " << ttp->getNextPacketID() << llendl;
-
 		// Put this on a list of packets to be delivered later.
-		ttp->addDelayedPacket(packet_id, status, tmp_data, size);
+		if(!ttp->addDelayedPacket(packet_id, status, tmp_data, size))
+		{
+			// Whoops - failed to add a delayed packet for some reason.
+			llwarns << "Too many delayed packets processing transfer "
+				<< transfer_id << " from " << msgp->getSender() << llendl;
+			ttp->abortTransfer();
+			ttcp->deleteTransfer(ttp);
+			return;
+		}
+		const S32 LL_TRANSFER_WARN_GAP = 10;
+		if(!ttp->gotInfo())
+		{
+			llwarns << "Got data packet before information in transfer "
+				<< transfer_id << " from " << msgp->getSender()
+				<< ", got " << packet_id << llendl;
+		}
+		else if((packet_id - ttp->getNextPacketID()) > LL_TRANSFER_WARN_GAP)
+		{
+			llwarns << "Out of order packet in transfer " << transfer_id
+				<< " from " << msgp->getSender() << ", got " << packet_id
+				<< " expecting " << ttp->getNextPacketID() << llendl;
+		}
 		return;
 	}
 
@@ -862,13 +918,17 @@ LLTransferTargetChannel::~LLTransferTargetChannel()
 }
 
 
-void LLTransferTargetChannel::requestTransfer(const LLTransferSourceParams &source_params,
-											  const LLTransferTargetParams &target_params,
-											  const F32 priority)
+void LLTransferTargetChannel::requestTransfer(
+	const LLTransferSourceParams& source_params,
+	const LLTransferTargetParams& target_params,
+	const F32 priority)
 {
 	LLUUID id;
 	id.generate();
-	LLTransferTarget *ttp = LLTransferTarget::createTarget(target_params.getType(), id);
+	LLTransferTarget* ttp = LLTransferTarget::createTarget(
+		target_params.getType(),
+		id,
+		source_params.getType());
 	if (!ttp)
 	{
 		llwarns << "LLTransferManager::requestTransfer aborting due to target creation failure!" << llendl;
@@ -988,6 +1048,11 @@ void LLTransferSource::sendTransferStatus(LLTSCode status)
 	gMessageSystem->addS32("ChannelType", mChannelp->getChannelType());
 	gMessageSystem->addS32("Status", status);
 	gMessageSystem->addS32("Size", mSize);
+	U8 tmp[MAX_PARAMS_SIZE];
+	LLDataPackerBinaryBuffer dp(tmp, MAX_PARAMS_SIZE);
+	packParams(dp);
+	S32 len = dp.getCurrentSize();
+	gMessageSystem->addBinaryData("Params", tmp, len);
 	gMessageSystem->sendReliable(mChannelp->getHost());
 
 	// Abort if there was as asset system issue.
@@ -1105,9 +1170,13 @@ LLTransferPacket::~LLTransferPacket()
 // LLTransferTarget implementation
 //
 
-LLTransferTarget::LLTransferTarget(LLTransferTargetType type, const LLUUID &id) :
+LLTransferTarget::LLTransferTarget(
+	LLTransferTargetType type,
+	const LLUUID& transfer_id,
+	LLTransferSourceType source_type) : 
 	mType(type),
-	mID(id),
+	mSourceType(source_type),
+	mID(transfer_id),
 	mGotInfo(FALSE),
 	mSize(0),
 	mLastPacketID(-1)
@@ -1143,27 +1212,48 @@ void LLTransferTarget::abortTransfer()
 	completionCallback(LLTS_ABORT);
 }
 
-void LLTransferTarget::addDelayedPacket(const S32 packet_id, const LLTSCode status, U8 *datap, const S32 size)
+bool LLTransferTarget::addDelayedPacket(
+	const S32 packet_id,
+	const LLTSCode status,
+	U8* datap,
+	const S32 size)
 {
-	LLTransferPacket *tpp = new LLTransferPacket(packet_id, status, datap, size);
+	const transfer_packet_map::size_type LL_MAX_DELAYED_PACKETS = 100;
+	if(mDelayedPacketMap.size() > LL_MAX_DELAYED_PACKETS)
+	{
+		// too many delayed packets
+		return false;
+	}
+
+	LLTransferPacket* tpp = new LLTransferPacket(
+		packet_id,
+		status,
+		datap,
+		size);
+
 #ifdef _DEBUG
 	if (mDelayedPacketMap.find(packet_id) != mDelayedPacketMap.end())
 	{
 		llerrs << "Packet ALREADY in delayed packet map!" << llendl;
 	}
 #endif
+
 	mDelayedPacketMap[packet_id] = tpp;
+	return true;
 }
 
 
-LLTransferTarget *LLTransferTarget::createTarget(const LLTransferTargetType type, const LLUUID &id)
+LLTransferTarget* LLTransferTarget::createTarget(
+	LLTransferTargetType type,
+	const LLUUID& id,
+	LLTransferSourceType source_type)
 {
 	switch (type)
 	{
 	case LLTTT_FILE:
-		return new LLTransferTargetFile(id);
+		return new LLTransferTargetFile(id, source_type);
 	case LLTTT_VFILE:
-		return new LLTransferTargetVFile(id);
+		return new LLTransferTargetVFile(id, source_type);
 	default:
 		llwarns << "Unknown transfer target type: " << type << llendl;
 		return NULL;
@@ -1200,6 +1290,7 @@ void LLTransferSourceParamsInvItem::setAsset(const LLUUID &asset_id, const LLAss
 
 void LLTransferSourceParamsInvItem::packParams(LLDataPacker &dp) const
 {
+	lldebugs << "LLTransferSourceParamsInvItem::packParams()" << llendl;
 	dp.packUUID(mAgentID, "AgentID");
 	dp.packUUID(mSessionID, "SessionID");
 	dp.packUUID(mOwnerID, "OwnerID");
@@ -1252,6 +1343,9 @@ void LLTransferSourceParamsEstate::setAsset(const LLUUID &asset_id, const LLAsse
 void LLTransferSourceParamsEstate::packParams(LLDataPacker &dp) const
 {
 	dp.packUUID(mAgentID, "AgentID");
+	// *NOTE: We do not want to pass the session id from the server to
+	// the client, but I am not sure if anyone expects this value to
+	// be set on the client.
 	dp.packUUID(mSessionID, "SessionID");
 	dp.packS32(mEstateAssetType, "EstateAssetType");
 }
diff --git a/indra/llmessage/lltransfermanager.h b/indra/llmessage/lltransfermanager.h
index 8c4c9f8ba7f..d258bd5f924 100644
--- a/indra/llmessage/lltransfermanager.h
+++ b/indra/llmessage/lltransfermanager.h
@@ -288,7 +288,8 @@ class LLTransferSource
 	// The completionCallback is GUARANTEED to be called before the destructor.
 	virtual void			completionCallback(const LLTSCode status) = 0;
 
-	virtual BOOL			unpackParams(LLDataPacker &dp) = 0;
+	virtual void packParams(LLDataPacker& dp) const = 0;
+	virtual BOOL unpackParams(LLDataPacker& dp) = 0;
 
 	virtual S32				getNextPacketID()						{ return mLastPacketID + 1; }
 	virtual void			setLastPacketID(const S32 packet_id)	{ mLastPacketID = packet_id; }
@@ -353,22 +354,32 @@ class LLTransferPacket
 class LLTransferTarget
 {
 public:
-	LLTransferTarget(LLTransferTargetType target_type, const LLUUID &transfer_id);
+	LLTransferTarget(
+		LLTransferTargetType target_type,
+		const LLUUID& transfer_id,
+		LLTransferSourceType source_type);
 	virtual ~LLTransferTarget();
 
-
 	// Accessors
 	LLUUID					getID() const			{ return mID; }
 	LLTransferTargetType	getType() const			{ return mType; }
 	LLTransferTargetChannel *getChannel() const		{ return mChannelp; }
+	LLTransferSourceType getSourceType() const { return mSourceType; }
+
+	// Static functionality
+	static LLTransferTarget* createTarget(
+		LLTransferTargetType target_type,
+		const LLUUID& request_id,
+		LLTransferSourceType source_type);
 
+	// friends
 	friend class LLTransferManager;
 	friend class LLTransferTargetChannel;
 
-	static LLTransferTarget *createTarget(const LLTransferTargetType type,
-										  const LLUUID &request_id);
 protected:
-	virtual void			applyParams(const LLTransferTargetParams &params) = 0;
+	// Implementation
+	virtual bool unpackParams(LLDataPacker& dp) = 0;
+	virtual void applyParams(const LLTransferTargetParams &params) = 0;
 	virtual LLTSCode		dataCallback(const S32 packet_id, U8 *in_datap, const S32 in_size) = 0;
 
 	// The completionCallback is GUARANTEED to be called before the destructor, so all handling
@@ -383,13 +394,18 @@ class LLTransferTarget
 	void					setGotInfo(const BOOL got_info)			{ mGotInfo = got_info; }
 	BOOL					gotInfo() const							{ return mGotInfo; }
 
-	void addDelayedPacket(const S32 packet_id, const LLTSCode status, U8 *datap, const S32 size);
+	bool addDelayedPacket(
+		const S32 packet_id,
+		const LLTSCode status,
+		U8* datap,
+		const S32 size);
 
 protected:
 	typedef std::map<S32, LLTransferPacket *> transfer_packet_map;
 	typedef std::map<S32, LLTransferPacket *>::iterator tpm_iter;
 
 	LLTransferTargetType	mType;
+	LLTransferSourceType mSourceType;
 	LLUUID					mID;
 	LLTransferTargetChannel *mChannelp;
 	BOOL					mGotInfo;
diff --git a/indra/llmessage/lltransfersourceasset.cpp b/indra/llmessage/lltransfersourceasset.cpp
index f7c6711bd06..635b7cffaf5 100644
--- a/indra/llmessage/lltransfersourceasset.cpp
+++ b/indra/llmessage/lltransfersourceasset.cpp
@@ -35,16 +35,9 @@ void LLTransferSourceAsset::initTransfer()
 		// *HACK: asset transfers will only be coming from the viewer
 		// to the simulator. This is subset of assets we allow to be
 		// simply pulled straight from the asset system.
-		// *FIX: Make this list smaller.
 		LLUUID* tidp;
-		switch(mParams.getAssetType())
+		if(is_asset_fetch_by_id_allowed(mParams.getAssetType()))
 		{
-		case LLAssetType::AT_SOUND:
-		case LLAssetType::AT_LANDMARK:
-		case LLAssetType::AT_CLOTHING:
-		case LLAssetType::AT_BODYPART:
-		case LLAssetType::AT_GESTURE:
-		case LLAssetType::AT_ANIMATION:
 			tidp = new LLUUID(getID());
 			gAssetStorage->getAssetData(
 				mParams.getAssetID(),
@@ -52,20 +45,20 @@ void LLTransferSourceAsset::initTransfer()
 				LLTransferSourceAsset::responderCallback,
 				tidp,
 				FALSE);
-			break;
-		default:
-		llwarns << "Attempted to request blocked asset "
-			<< mParams.getAssetID() << ":"
-			<< LLAssetType::lookupHumanReadable(mParams.getAssetType())
-			<< llendl;
+		}
+		else
+		{
+			llwarns << "Attempted to request blocked asset "
+				<< mParams.getAssetID() << ":"
+				<< LLAssetType::lookupHumanReadable(mParams.getAssetType())
+				<< llendl;
 			sendTransferStatus(LLTS_ERROR);
-			break;
 		}
 	}
 	else
 	{
-		llwarns << "Attempted to request asset "
-			<< mParams.getAssetID() << ":" << LLAssetType::lookupHumanReadable(mParams.getAssetType())
+		llwarns << "Attempted to request asset " << mParams.getAssetID()
+			<< ":" << LLAssetType::lookupHumanReadable(mParams.getAssetType())
 			<< " without an asset system!" << llendl;
 		sendTransferStatus(LLTS_ERROR);
 	}
@@ -147,10 +140,15 @@ void LLTransferSourceAsset::completionCallback(const LLTSCode status)
 	// we've got it open.
 }
 
+void LLTransferSourceAsset::packParams(LLDataPacker& dp) const
+{
+	//llinfos << "LLTransferSourceAsset::packParams" << llendl;
+	mParams.packParams(dp);
+}
+
 BOOL LLTransferSourceAsset::unpackParams(LLDataPacker &dp)
 {
 	//llinfos << "LLTransferSourceAsset::unpackParams" << llendl;
-
 	return mParams.unpackParams(dp);
 }
 
@@ -233,3 +231,47 @@ BOOL LLTransferSourceParamsAsset::unpackParams(LLDataPacker &dp)
 	return TRUE;
 }
 
+/**
+ * Helper functions
+ */
+bool is_asset_fetch_by_id_allowed(LLAssetType::EType type)
+{
+	// *FIX: Make this list smaller.
+	bool rv = false;
+	switch(type)
+	{
+	case LLAssetType::AT_SOUND:
+	case LLAssetType::AT_LANDMARK:
+	case LLAssetType::AT_CLOTHING:
+	case LLAssetType::AT_BODYPART:
+	case LLAssetType::AT_ANIMATION:
+	case LLAssetType::AT_GESTURE:
+		rv = true;
+		break;
+	default:
+		break;
+	}
+	return rv;
+}
+
+bool is_asset_id_knowable(LLAssetType::EType type)
+{
+	// *FIX: Make this list smaller.
+	bool rv = false;
+	switch(type)
+	{
+	case LLAssetType::AT_TEXTURE:
+	case LLAssetType::AT_SOUND:
+	case LLAssetType::AT_LANDMARK:
+	case LLAssetType::AT_CLOTHING:
+	case LLAssetType::AT_NOTECARD:
+	case LLAssetType::AT_BODYPART:
+	case LLAssetType::AT_ANIMATION:
+	case LLAssetType::AT_GESTURE:
+		rv = true;
+		break;
+	default:
+		break;
+	}
+	return rv;
+}
diff --git a/indra/llmessage/lltransfersourceasset.h b/indra/llmessage/lltransfersourceasset.h
index 931fc461f9b..446c9622b22 100644
--- a/indra/llmessage/lltransfersourceasset.h
+++ b/indra/llmessage/lltransfersourceasset.h
@@ -50,6 +50,7 @@ class LLTransferSourceAsset : public LLTransferSource
 									  BOOL &delete_returned);
 	/*virtual*/ void completionCallback(const LLTSCode status);
 
+	virtual void packParams(LLDataPacker& dp) const;
 	/*virtual*/ BOOL unpackParams(LLDataPacker &dp);
 
 protected:
@@ -59,4 +60,24 @@ class LLTransferSourceAsset : public LLTransferSource
 	S32 mCurPos;
 };
 
+/**
+ * @brief Quick check to see if the asset allows direct download.
+ *
+ * This might not be the right place for this function call, but it
+ * originally started life inside the LLTransferSourceAsset code.
+ * @param type The type of asset.
+ * @return Returns true if the asset can be fetched by id.
+ */
+bool is_asset_fetch_by_id_allowed(LLAssetType::EType type);
+
+/**
+ * @brief Quick check to see if all asset data can be known by the viewer.
+ *
+ * This might not be the right place for this function call, but it
+ * originally started life inside the LLTransferSourceAsset code.
+ * @param type The type of asset.
+ * @return Returns true if the asset id can be transmitted to the viewer.
+ */
+bool is_asset_id_knowable(LLAssetType::EType type);
+
 #endif // LL_LLTRANSFERSOURCEASSET_H
diff --git a/indra/llmessage/lltransfersourcefile.cpp b/indra/llmessage/lltransfersourcefile.cpp
index 45b03d7653b..c1df0f25aae 100644
--- a/indra/llmessage/lltransfersourcefile.cpp
+++ b/indra/llmessage/lltransfersourcefile.cpp
@@ -117,10 +117,15 @@ void LLTransferSourceFile::completionCallback(const LLTSCode status)
 	}
 }
 
+void LLTransferSourceFile::packParams(LLDataPacker& dp) const
+{
+	//llinfos << "LLTransferSourceFile::packParams" << llendl;
+	mParams.packParams(dp);
+}
+
 BOOL LLTransferSourceFile::unpackParams(LLDataPacker &dp)
 {
 	//llinfos << "LLTransferSourceFile::unpackParams" << llendl;
-
 	return mParams.unpackParams(dp);
 }
 
diff --git a/indra/llmessage/lltransfersourcefile.h b/indra/llmessage/lltransfersourcefile.h
index ecaa6c908a7..fcb5743fb5b 100644
--- a/indra/llmessage/lltransfersourcefile.h
+++ b/indra/llmessage/lltransfersourcefile.h
@@ -48,6 +48,7 @@ class LLTransferSourceFile : public LLTransferSource
 									  BOOL &delete_returned);
 	/*virtual*/ void completionCallback(const LLTSCode status);
 
+	virtual void packParams(LLDataPacker& dp) const;
 	/*virtual*/ BOOL unpackParams(LLDataPacker &dp);
 
 protected:
diff --git a/indra/llmessage/lltransfertargetfile.cpp b/indra/llmessage/lltransfertargetfile.cpp
index 92776e081d3..57ce069128d 100644
--- a/indra/llmessage/lltransfertargetfile.cpp
+++ b/indra/llmessage/lltransfertargetfile.cpp
@@ -14,8 +14,10 @@
 
 
 
-LLTransferTargetFile::LLTransferTargetFile(const LLUUID &uuid) :
-	LLTransferTarget(LLTTT_FILE, uuid),
+LLTransferTargetFile::LLTransferTargetFile(
+	const LLUUID& uuid,
+	LLTransferSourceType src_type) :
+	LLTransferTarget(LLTTT_FILE, uuid, src_type),
 	mFP(NULL)
 {
 }
@@ -30,6 +32,13 @@ LLTransferTargetFile::~LLTransferTargetFile()
 	}
 }
 
+// virtual
+bool LLTransferTargetFile::unpackParams(LLDataPacker& dp)
+{
+	// we can safely ignore this call
+	return true;
+}
+
 void LLTransferTargetFile::applyParams(const LLTransferTargetParams &params)
 {
 	if (params.getType() != mType)
diff --git a/indra/llmessage/lltransfertargetfile.h b/indra/llmessage/lltransfertargetfile.h
index 63cc21262b4..eb000e527e8 100644
--- a/indra/llmessage/lltransfertargetfile.h
+++ b/indra/llmessage/lltransfertargetfile.h
@@ -33,7 +33,7 @@ class LLTransferTargetParamsFile : public LLTransferTargetParams
 class LLTransferTargetFile : public LLTransferTarget
 {
 public:
-	LLTransferTargetFile(const LLUUID &uuid);
+	LLTransferTargetFile(const LLUUID& uuid, LLTransferSourceType src_type);
 	virtual ~LLTransferTargetFile();
 
 	static void requestTransfer(LLTransferTargetChannel *channelp,
@@ -41,6 +41,7 @@ class LLTransferTargetFile : public LLTransferTarget
 								const LLTransferSourceParams &source_params,
 								LLTTFCompleteCallback callback);
 protected:
+	virtual bool unpackParams(LLDataPacker& dp);
 	/*virtual*/ void applyParams(const LLTransferTargetParams &params);
 	/*virtual*/ LLTSCode dataCallback(const S32 packet_id, U8 *in_datap, const S32 in_size);
 	/*virtual*/ void completionCallback(const LLTSCode status);
diff --git a/indra/llmessage/lltransfertargetvfile.cpp b/indra/llmessage/lltransfertargetvfile.cpp
index 9e323537d7d..b8c138886a8 100644
--- a/indra/llmessage/lltransfertargetvfile.cpp
+++ b/indra/llmessage/lltransfertargetvfile.cpp
@@ -9,8 +9,9 @@
 #include "linden_common.h"
 
 #include "lltransfertargetvfile.h"
-#include "llerror.h"
 
+#include "lldatapacker.h"
+#include "llerror.h"
 #include "llvfile.h"
 
 //static
@@ -27,7 +28,11 @@ void LLTransferTargetVFile::updateQueue(bool shutdown)
 		LLVFSThread::status_t s = LLVFile::getVFSThread()->getRequestStatus(params->mHandle);
 		if (s == LLVFSThread::STATUS_COMPLETE || s == LLVFSThread::STATUS_EXPIRED)
 		{
-			params->mCompleteCallback(params->mErrCode, params->mUserDatap);
+			params->mCompleteCallback(
+				params->mErrCode,
+				params->getAssetID(),
+				params->getAssetType(),
+				params->mUserDatap);
 			delete params;
 			iter = sCallbackQueue.erase(curiter);
 		}
@@ -50,7 +55,9 @@ LLTransferTargetParamsVFile::LLTransferTargetParamsVFile() :
 {
 }
 
-void LLTransferTargetParamsVFile::setAsset(const LLUUID &asset_id, const LLAssetType::EType asset_type)
+void LLTransferTargetParamsVFile::setAsset(
+	const LLUUID& asset_id,
+	LLAssetType::EType asset_type)
 {
 	mAssetID = asset_id;
 	mAssetType = asset_type;
@@ -62,9 +69,35 @@ void LLTransferTargetParamsVFile::setCallback(LLTTVFCompleteCallback cb, void *u
 	mUserDatap = user_data;
 }
 
+bool LLTransferTargetParamsVFile::unpackParams(LLDataPacker& dp)
+{
+	// if the source provided a new key, assign that to the asset id.
+	if(dp.hasNext())
+	{
+		LLUUID dummy_id;
+		dp.unpackUUID(dummy_id, "AgentID");
+		dp.unpackUUID(dummy_id, "SessionID");
+		dp.unpackUUID(dummy_id, "OwnerID");
+		dp.unpackUUID(dummy_id, "TaskID");
+		dp.unpackUUID(dummy_id, "ItemID");
+		dp.unpackUUID(mAssetID, "AssetID");
+		S32 dummy_type;
+		dp.unpackS32(dummy_type, "AssetType");
+	}
 
-LLTransferTargetVFile::LLTransferTargetVFile(const LLUUID &uuid) :
-	LLTransferTarget(LLTTT_VFILE, uuid),
+	// if we never got an asset id, this will always fail.
+	if(mAssetID.isNull())
+	{
+		return false;
+	}
+	return true;
+}
+
+
+LLTransferTargetVFile::LLTransferTargetVFile(
+	const LLUUID& uuid,
+	LLTransferSourceType src_type) :
+	LLTransferTarget(LLTTT_VFILE, uuid, src_type),
 	mNeedsCreate(TRUE)
 {
 	mTempID.generate();
@@ -76,6 +109,16 @@ LLTransferTargetVFile::~LLTransferTargetVFile()
 }
 
 
+// virtual
+bool LLTransferTargetVFile::unpackParams(LLDataPacker& dp)
+{
+	if(LLTST_SIM_INV_ITEM == mSourceType)
+	{
+		return mParams.unpackParams(dp);
+	}
+	return true;
+}
+
 void LLTransferTargetVFile::applyParams(const LLTransferTargetParams &params)
 {
 	if (params.getType() != mType)
@@ -132,13 +175,17 @@ void LLTransferTargetVFile::completionCallback(const LLTSCode status)
 	  case LLTS_DONE:
 		if (!mNeedsCreate)
 		{
-			handle = LLVFile::getVFSThread()->rename(gAssetStorage->mVFS,
-													 mTempID, mParams.getAssetType(),
-													 mParams.getAssetID(), mParams.getAssetType(),
-													 LLVFSThread::AUTO_DELETE);
+			handle = LLVFile::getVFSThread()->rename(
+				gAssetStorage->mVFS,
+				mTempID, mParams.getAssetType(),
+				mParams.getAssetID(), mParams.getAssetType(),
+				LLVFSThread::AUTO_DELETE);
 		}
 		err_code = LL_ERR_NOERR;
-		// 		llinfos << "Successful vfile transfer for " << mParams.getAssetID() << llendl;
+		lldebugs << "LLTransferTargetVFile::completionCallback for "
+			 << mParams.getAssetID() << ","
+			 << LLAssetType::lookup(mParams.getAssetType())
+			 << " with temp id " << mTempID << llendl;
 		break;
 	  case LLTS_ERROR:
 	  case LLTS_ABORT:
@@ -181,7 +228,11 @@ void LLTransferTargetVFile::completionCallback(const LLTSCode status)
 		}
 		else
 		{
-			mParams.mCompleteCallback(err_code, mParams.mUserDatap);
+			mParams.mCompleteCallback(
+				err_code,
+				mParams.getAssetID(),
+				mParams.getAssetType(),
+				mParams.mUserDatap);
 		}
 	}
 }
diff --git a/indra/llmessage/lltransfertargetvfile.h b/indra/llmessage/lltransfertargetvfile.h
index 76140211793..57eaeca3784 100644
--- a/indra/llmessage/lltransfertargetvfile.h
+++ b/indra/llmessage/lltransfertargetvfile.h
@@ -17,26 +17,32 @@ class LLVFile;
 
 // Lame, an S32 for now until I figure out the deal with how we want to do
 // error codes.
-typedef void (*LLTTVFCompleteCallback)(const S32 status, void *user_data);
+typedef void (*LLTTVFCompleteCallback)(
+	S32 status,
+	const LLUUID& file_id,
+	LLAssetType::EType file_type,
+	void* user_data);
 
 class LLTransferTargetParamsVFile : public LLTransferTargetParams
 {
 public:
 	LLTransferTargetParamsVFile();
-	
-	void setAsset(const LLUUID &asset_id, const LLAssetType::EType asset_type);
-	void setCallback(LLTTVFCompleteCallback cb, void *user_data);
+
+	void setAsset(const LLUUID& asset_id, LLAssetType::EType asset_type);
+	void setCallback(LLTTVFCompleteCallback cb, void* user_data);
 
 	LLUUID getAssetID() const						{ return mAssetID; }
 	LLAssetType::EType getAssetType() const			{ return mAssetType; }
 
 	friend class LLTransferTargetVFile;
 protected:
+	bool unpackParams(LLDataPacker& dp);
+
 	LLUUID				mAssetID;
 	LLAssetType::EType	mAssetType;
 
 	LLTTVFCompleteCallback	mCompleteCallback;
-	void *					mUserDatap;
+	void*					mUserDatap;
 	S32						mErrCode;
 	LLVFSThread::handle_t	mHandle;
 };
@@ -45,18 +51,20 @@ class LLTransferTargetParamsVFile : public LLTransferTargetParams
 class LLTransferTargetVFile : public LLTransferTarget
 {
 public:
-	LLTransferTargetVFile(const LLUUID &uuid);
+	LLTransferTargetVFile(const LLUUID& uuid, LLTransferSourceType src_type);
 	virtual ~LLTransferTargetVFile();
 
-	static void requestTransfer(LLTransferTargetChannel *channelp,
-								const char *local_filename,
-								const LLTransferSourceParams &source_params,
-								LLTTVFCompleteCallback callback);
+	//static void requestTransfer(LLTransferTargetChannel* channelp,
+	//							const char* local_filename,
+	//							const LLTransferSourceParams& source_params,
+	//							LLTTVFCompleteCallback callback);
+
 	static void updateQueue(bool shutdown = false);
 	
 protected:
-	/*virtual*/ void applyParams(const LLTransferTargetParams &params);
-	/*virtual*/ LLTSCode dataCallback(const S32 packet_id, U8 *in_datap, const S32 in_size);
+	virtual bool unpackParams(LLDataPacker& dp);
+	/*virtual*/ void applyParams(const LLTransferTargetParams& params);
+	/*virtual*/ LLTSCode dataCallback(const S32 packet_id, U8* in_datap, const S32 in_size);
 	/*virtual*/ void completionCallback(const LLTSCode status);
 
 	LLTransferTargetParamsVFile mParams;
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 99cfc7439bf..73cda52fa02 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -4451,7 +4451,13 @@ void process_create_trusted_circuit(LLMessageSystem *msg, void **)
 	}
 
 	char their_digest[MD5HEX_STR_SIZE];
-	msg->getBinaryDataFast(_PREHASH_DataBlock, _PREHASH_Digest, their_digest, 32);
+	S32 size = msg->getSizeFast(_PREHASH_DataBlock, _PREHASH_Digest);
+	if(size != MD5HEX_STR_BYTES)
+	{
+		// ignore requests which pack the wrong amount of data.
+		return;
+	}
+	msg->getBinaryDataFast(_PREHASH_DataBlock, _PREHASH_Digest, their_digest, MD5HEX_STR_BYTES);
 	their_digest[MD5HEX_STR_SIZE - 1] = '\0';
 	if(msg->isMatchingDigestForWindowAndUUIDs(their_digest, TRUST_TIME_WINDOW, local_id, remote_id))
 	{
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 8607d1d7525..7d2df53f9b8 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -385,7 +385,12 @@ void LLMenuItemGL::doIt( void )
 {
 	// close all open menus by default
 	// if parent menu is actually visible (and we are not triggering menu item via accelerator)
-	if (!getMenu()->getTornOff() && getMenu()->getVisible())
+	// HACK: do not call hidemenus() from a pie menu item, as most pie menu operations
+	// assume that the thing you clicked on stays selected (parcel and/or object) after the
+	// pie menu is gone --RN
+	if (getMenu()->getWidgetType() != WIDGET_TYPE_PIE_MENU 
+		&& !getMenu()->getTornOff() 
+		&& getMenu()->getVisible())
 	{
 		((LLMenuHolderGL*)getMenu()->getParent())->hideMenus();
 	}
@@ -4103,6 +4108,11 @@ BOOL LLMenuBarGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
 	{
 		mAltKeyTrigger = TRUE;
 	}
+	else // if any key other than ALT hit, clear out waiting for Alt key mode
+	{
+		mAltKeyTrigger = FALSE;
+	}
+
 	// before processing any other key, check to see if ALT key has triggered menu access
 	checkMenuTrigger();
 
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index c15f417e657..b9f7d033ac2 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -680,9 +680,9 @@ class LLMenuHolderGL : public LLPanel
 	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
 
 	static void setActivatedItem(LLMenuItemGL* item);
-protected:
 	BOOL hasVisibleMenu();
 
+protected:
 	static LLViewHandle sItemLastSelectedHandle;
 	static LLFrameTimer sItemActivationTimer;
 
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 5d11973b885..95ea2cbc37e 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -32,16 +32,13 @@
 
 const S32 LIST_BORDER_PAD = 2;		// white space inside the border and to the left of the scrollbar
 
-U32 LLScrollListCtrl::sSortColumn = 1;
-BOOL LLScrollListCtrl::sSortAscending = TRUE; 
-
 // local structures & classes.
 struct SortScrollListItem
 {
 	SortScrollListItem(const S32 sort_col, BOOL sort_ascending)
 	{
 		mSortCol = sort_col;
-		sSortAscending = sort_ascending;
+		mSortAscending = sort_ascending;
 	}
 
 	bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2)
@@ -53,7 +50,7 @@ struct SortScrollListItem
 		cell2 = i2->getColumn(mSortCol);
 		
 		S32 order = 1;
-		if (!sSortAscending)
+		if (!mSortAscending)
 		{
 			order = -1;
 		}
@@ -70,7 +67,7 @@ struct SortScrollListItem
 
 protected:
 	S32 mSortCol;
-	S32 sSortAscending;
+	S32 mSortAscending;
 };
 
 
@@ -362,16 +359,20 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect,
 	mFgUnselectedColor( LLUI::sColorsGroup->getColor("ScrollUnselectedColor") ),
 	mFgDisabledColor( LLUI::sColorsGroup->getColor("ScrollDisabledColor") ),
 	mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ),
+	mHighlightedItem(-1),
 	mBorderThickness( 2 ),
 	mOnDoubleClickCallback( NULL ),
 	mOnMaximumSelectCallback( NULL ),
-	mHighlightedItem(-1),
+	mOnSortChangedCallback( NULL ),
+	mDrewSelected(FALSE),
 	mBorder(NULL),
-	mDefaultColumn("SIMPLE"),
 	mSearchColumn(0),
+	mDefaultColumn("SIMPLE"),
+
 	mNumDynamicWidthColumns(0),
 	mTotalStaticColumnWidth(0),
-	mDrewSelected(FALSE)
+	mSortColumn(0),
+	mSortAscending(TRUE)
 {
 	mItemListRect.setOriginAndSize(
 		mBorderThickness + LIST_BORDER_PAD,
@@ -585,10 +586,10 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos )
 			break;
 	
 		case ADD_SORTED:
-			LLScrollListCtrl::sSortColumn = 0;
-			LLScrollListCtrl::sSortAscending = TRUE;
+			mSortColumn = 0;
+			mSortAscending = TRUE;
 			mItemList.push_back(item);
-			std::sort(mItemList.begin(), mItemList.end(), SortScrollListItem(sSortColumn, sSortAscending));
+			std::sort(mItemList.begin(), mItemList.end(), SortScrollListItem(mSortColumn, mSortAscending));
 			break;
 	
 		case ADD_BOTTOM:
@@ -863,6 +864,33 @@ void LLScrollListCtrl::highlightNthItem(S32 target_index)
 	}
 }
 
+S32	LLScrollListCtrl::selectMultiple( LLDynamicArray<LLUUID> ids )
+{
+	item_list::iterator iter;
+	S32 count = 0;
+	for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+	{
+		LLScrollListItem* item = *iter;
+		LLDynamicArray<LLUUID>::iterator iditr;
+		for(iditr = ids.begin(); iditr != ids.end(); ++iditr)
+		{
+			if (item->getEnabled() && (item->getUUID() == (*iditr)))
+			{
+				selectItem(item,FALSE);
+				++count;
+				break;
+			}
+		}
+		if(ids.end() != iditr) ids.erase(iditr);
+	}
+
+	if (mCommitOnSelectionChange)
+	{
+		commitIfChanged();
+	}
+	return count;
+}
+
 S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item )
 {
 	S32 index = 0;
@@ -1933,13 +1961,19 @@ void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void
 // First column is column 0
 void  LLScrollListCtrl::sortByColumn(U32 column, BOOL ascending)
 {
-	LLScrollListCtrl::sSortColumn = column;
-	LLScrollListCtrl::sSortAscending = ascending;
-	std::sort(mItemList.begin(), mItemList.end(), SortScrollListItem(sSortColumn, sSortAscending));
+	mSortColumn = column;
+	mSortAscending = ascending;
+	std::sort(mItemList.begin(), mItemList.end(), SortScrollListItem(mSortColumn, mSortAscending));
 }
 
 void LLScrollListCtrl::sortByColumn(LLString name, BOOL ascending)
 {
+	if (name.empty())
+	{
+		sortByColumn(mSortColumn, mSortAscending);
+		return;
+	}
+
 	std::map<LLString, LLScrollListColumn>::iterator itor = mColumns.find(name);
 	if (itor != mColumns.end())
 	{
@@ -2437,26 +2471,41 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
 	LLScrollListColumn *info = (LLScrollListColumn*)userdata;
 	if (!info) return;
 
+	LLScrollListCtrl *parent = info->mParentCtrl;
+	if (!parent) return;
+
 	U32 column_index = info->mIndex;
 
-	LLScrollListColumn* column = info->mParentCtrl->mColumnsIndexed[info->mIndex];
+	LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex];
 	if (column->mSortingColumn != column->mName)
 	{
-		if (info->mParentCtrl->mColumns.find(column->mSortingColumn) != info->mParentCtrl->mColumns.end())
+		if (parent->mColumns.find(column->mSortingColumn) != parent->mColumns.end())
 		{
-			LLScrollListColumn& info_redir = info->mParentCtrl->mColumns[column->mSortingColumn];
+			LLScrollListColumn& info_redir = parent->mColumns[column->mSortingColumn];
 			column_index = info_redir.mIndex;
 		}
 	}
 
-	// TomY TODO: shouldn't these be non-static members?
 	bool ascending = true;
-	if (column_index == LLScrollListCtrl::sSortColumn)
+	if (column_index == parent->mSortColumn)
 	{
-		ascending = !LLScrollListCtrl::sSortAscending;
+		ascending = !parent->mSortAscending;
 	}
 
-	info->mParentCtrl->sortByColumn(column_index, ascending);
+	parent->sortByColumn(column_index, ascending);
+
+	if (parent->mOnSortChangedCallback)
+	{
+		parent->mOnSortChangedCallback(parent->getCallbackUserData());
+	}
+}
+
+std::string LLScrollListCtrl::getSortColumnName()
+{
+	LLScrollListColumn* column = mColumnsIndexed[mSortColumn];
+
+	if (column) return column->mName;
+	else return "";
 }
 
 void LLScrollListCtrl::clearColumns()
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 426e817215d..805efe8679b 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -14,6 +14,7 @@
 
 #include "lluictrl.h"
 #include "llctrlselectioninterface.h"
+#include "lldarray.h"
 #include "llfontgl.h"
 #include "llui.h"
 #include "llstring.h"
@@ -298,6 +299,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	void			highlightNthItem( S32 index );
 	void			setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; }
 	void			setMaxiumumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; }
+	void			setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; }
 
 	void			swapWithNext(S32 index);
 	void			swapWithPrevious(S32 index);
@@ -436,6 +438,11 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	void setNumDynamicColumns(int num) { mNumDynamicWidthColumns = num; }
 	void setTotalStaticColumnWidth(int width) { mTotalStaticColumnWidth = width; }
 
+	std::string     getSortColumnName();
+	BOOL			getSortAscending() { return mSortAscending; }
+
+	S32		selectMultiple( LLDynamicArray<LLUUID> ids );
+
 protected:
 	void			selectPrevItem(BOOL extend_selection);
 	void			selectNextItem(BOOL extend_selection);
@@ -494,6 +501,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	S32				mBorderThickness;
 	void			(*mOnDoubleClickCallback)(void* userdata);
 	void			(*mOnMaximumSelectCallback)(void* userdata );
+	void			(*mOnSortChangedCallback)(void* userdata);
 
 	S32				mHighlightedItem;
 	LLViewBorder*	mBorder;
@@ -507,8 +515,8 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	S32				mNumDynamicWidthColumns;
 	S32				mTotalStaticColumnWidth;
 
-	static U32      sSortColumn;
-	static BOOL     sSortAscending;
+	U32      mSortColumn;
+	BOOL     mSortAscending;
 
 	std::map<LLString, LLScrollListColumn> mColumns;
 	std::vector<LLScrollListColumn*> mColumnsIndexed;
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index 39b12035c93..89ad65be9f8 100644
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -915,7 +915,11 @@ void LLVFS::renameFile(const LLUUID &file_id, const LLAssetType::EType file_type
 
 			for (S32 i = 0; i < (S32)VFSLOCK_COUNT; i++)
 			{
-				src_block->mLocks[(EVFSLock)i] = dest_block->mLocks[(EVFSLock)i];
+				if(dest_block->mLocks[i])
+				{
+					llerrs << "Renaming VFS block to a locked file." << llendl;
+				}
+				dest_block->mLocks[i] = src_block->mLocks[i];
 			}
 			
 			mFileBlocks.erase(new_spec);
diff --git a/indra/llvfs/llvfsthread.cpp b/indra/llvfs/llvfsthread.cpp
index 8ea98ab4629..619c1b9bb39 100644
--- a/indra/llvfs/llvfsthread.cpp
+++ b/indra/llvfs/llvfsthread.cpp
@@ -281,6 +281,7 @@ bool LLVFSThread::Request::processIO()
 		LLUUID* new_idp = (LLUUID*)mBuffer;
 		LLAssetType::EType new_type = (LLAssetType::EType)mBytes;
 		mVFS->renameFile(mFileID, mFileType, *new_idp, new_type);
+		mFileID = *new_idp;
 		complete = true;
 		//llinfos << llformat("LLVFSThread::WRITE '%s': %d bytes arg:%d",getFilename(),mBytesRead) << llendl;
 	}
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings
index f3d59db32a1..ccb92f9fbab 100644
--- a/indra/newview/English.lproj/InfoPlist.strings
+++ b/indra/newview/English.lproj/InfoPlist.strings
@@ -1,5 +1,5 @@
 /* Localized versions of Info.plist keys */
 
 CFBundleName = "Second Life";
-CFBundleShortVersionString = "Second Life version 1.13.1.7";
-CFBundleGetInfoString = "Second Life version 1.13.1.7, Copyright 2004-2006 Linden Research, Inc.";
+CFBundleShortVersionString = "Second Life version 1.13.2.11";
+CFBundleGetInfoString = "Second Life version 1.13.2.11, Copyright 2004-2006 Linden Research, Inc.";
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index 8e1570561eb..458c5e1b7dd 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -32,7 +32,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>1.13.1.7</string>
+	<string>1.13.2.11</string>
 	<key>CSResourcesFileMapped</key>
 	<true/>
 </dict>
diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp
index e5aac8b2524..8efc833004d 100644
--- a/indra/newview/llfloaterfriends.cpp
+++ b/indra/newview/llfloaterfriends.cpp
@@ -142,7 +142,7 @@ void LLFloaterFriends::updateFriends(U32 changed_mask)
 	{
 		refreshNames();
 	}
-	else if(LLFriendObserver::POWERS)
+	else if(changed_mask & LLFriendObserver::POWERS)
 	{
 		--mNumRightsChanged;
 		if(mNumRightsChanged > 0)
@@ -255,10 +255,6 @@ void LLFloaterFriends::addFriend(const std::string& name, const LLUUID& agent_id
 	mFriendsList->addElement(element, ADD_BOTTOM);
 }
 
-void LLFloaterFriends::reloadNames()
-{
-}
-
 void LLFloaterFriends::refreshRightsChangeList(U8 state)
 {
 	LLDynamicArray<LLUUID> friends = getSelectedIDs();
@@ -293,7 +289,7 @@ void LLFloaterFriends::refreshRightsChangeList(U8 state)
 			childSetEnabled("offer_teleport_btn", false);
 		}
 		can_change_visibility = true;
-		can_change_modify = true;
+		can_change_modify = true;		
 	}
 	else if (state == 2)
 	{
@@ -363,13 +359,15 @@ void LLFloaterFriends::refreshRightsChangeList(U8 state)
 
 void LLFloaterFriends::refreshNames()
 {
-	S32 pos = mFriendsList->getScrollPos();
+	LLDynamicArray<LLUUID> selected_ids = getSelectedIDs();	
+	S32 pos = mFriendsList->getScrollPos();	
 	mFriendsList->operateOnAll(LLCtrlListInterface::OP_DELETE);
 	
 	LLCollectAllBuddies collect;
 	LLAvatarTracker::instance().applyFunctor(collect);
 	LLCollectAllBuddies::buddy_map_t::const_iterator it = collect.mOnline.begin();
 	LLCollectAllBuddies::buddy_map_t::const_iterator end = collect.mOnline.end();
+	
 	for ( ; it != end; ++it)
 	{
 		const std::string& name = it->first;
@@ -384,6 +382,7 @@ void LLFloaterFriends::refreshNames()
 		const LLUUID& agent_id = it->second;
 		addFriend(name, agent_id);
 	}
+	mFriendsList->selectMultiple(selected_ids);
 	mFriendsList->setScrollPos(pos);
 }
 
@@ -396,8 +395,22 @@ void LLFloaterFriends::refreshUI()
 	if(num_selected > 0)
 	{
 		single_selected = TRUE;
-		if(num_selected > 1) multiple_selected = TRUE;		
+		if(num_selected > 1)
+		{
+			childSetText("friend_name_label", "Multiple friends...");
+			multiple_selected = TRUE;		
+		}
+		else
+		{			
+			childSetText("friend_name_label", mFriendsList->getFirstSelected()->getColumn(LIST_FRIEND_NAME)->getText() + "...");
+		}
 	}
+	else
+	{
+		childSetText("friend_name_label", "");
+	}
+
+
 	//Options that can only be performed with one friend selected
 	childSetEnabled("profile_btn", single_selected && !multiple_selected);
 	childSetEnabled("pay_btn", single_selected && !multiple_selected);
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index 7c29460f0ed..685cf94430b 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -966,6 +966,7 @@ void LLPanelGridTools::flushMapVisibilityCachesConfirm(S32 option, void* data)
 	msg->nextBlockFast(_PREHASH_AgentData);
 	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
 	msg->nextBlock("MethodData");
 	msg->addString("Method", "refreshmapvisibility");
 	msg->addUUID("Invoice", LLUUID::null);
@@ -1358,6 +1359,7 @@ void LLPanelRequestTools::sendRequest(const char *request,
 	msg->nextBlockFast(_PREHASH_AgentData);
 	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
 	msg->nextBlock("MethodData");
 	msg->addString("Method", request);
 	msg->addUUID("Invoice", LLUUID::null);
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
new file mode 100644
index 00000000000..40132ce3751
--- /dev/null
+++ b/indra/newview/llfloaterinspect.cpp
@@ -0,0 +1,221 @@
+#include "llviewerprecompiledheaders.h"
+#include "llfloateravatarinfo.h"
+#include "llfloaterinspect.h"
+#include "llfloatertools.h"
+#include "llcachename.h"
+#include "llscrolllistctrl.h"
+#include "llselectmgr.h"
+#include "lltoolcomp.h"
+#include "lltoolmgr.h"
+#include "llviewercontrol.h"
+#include "llviewerobject.h"
+#include "llvieweruictrlfactory.h"
+
+LLFloaterInspect* LLFloaterInspect::sInstance = NULL;
+
+LLFloaterInspect::LLFloaterInspect(void) :
+	LLFloater("Inspect Object"),
+	mDirty(FALSE)
+{
+	sInstance = this;
+	gUICtrlFactory->buildFloater(this, "floater_inspect.xml");
+}
+
+LLFloaterInspect::~LLFloaterInspect(void)
+{
+	if(!gFloaterTools->getVisible())
+	{
+		if(gToolMgr->getCurrentTool(MASK_NONE) == gToolInspect)
+		{
+			select_tool(gToolNull);
+		}
+		gSelectMgr->deselectAll();
+		// Switch back to basic toolset
+		gCurrentToolset = gBasicToolset;
+		gBasicToolset->selectFirstTool();
+		gToolMgr->useSelectedTool( gBasicToolset );
+	}
+	else
+	{
+		gFloaterTools->setFocus(TRUE);
+	}
+	sInstance = NULL;
+}
+
+BOOL LLFloaterInspect::isVisible()
+{
+	return (!!sInstance);
+}
+
+void LLFloaterInspect::show(void* ignored)
+{
+	if(sInstance)
+	{
+		sInstance->open();
+	}
+	else
+	{
+		LLFloaterInspect* self = new LLFloaterInspect;
+		self->open();
+	}
+	select_tool(gToolInspect);
+}
+
+void LLFloaterInspect::onClickCreatorProfile(void* ctrl)
+{
+	if(sInstance->mObjectList->getAllSelected().size() == 0) return;
+	LLSelectNode* obj = gSelectMgr->getFirstNode();
+	LLUUID obj_id, creator_id;
+	obj_id = sInstance->mObjectList->getFirstSelected()->getUUID();
+	while(obj)
+	{
+		if(obj_id == obj->getObject()->getID())
+		{
+			creator_id = obj->mPermissions->getCreator();
+			break;
+		}
+		obj = gSelectMgr->getNextNode();
+	}
+	if(obj)
+	{
+		LLFloaterAvatarInfo::showFromDirectory(creator_id);
+	}
+}
+
+void LLFloaterInspect::onClickOwnerProfile(void* ctrl)
+{
+	if(sInstance->mObjectList->getAllSelected().size() == 0) return;
+	LLSelectNode* obj = gSelectMgr->getFirstNode();
+	LLUUID obj_id, owner_id;
+	obj_id = sInstance->mObjectList->getFirstSelected()->getUUID();
+	while(obj)
+	{
+		if(obj_id == obj->getObject()->getID())
+		{
+			owner_id = obj->mPermissions->getOwner();
+			break;
+		}
+		obj = gSelectMgr->getNextNode();
+	}
+	if(obj)
+	{
+		LLFloaterAvatarInfo::showFromDirectory(owner_id);
+	}
+}
+
+BOOL LLFloaterInspect::postBuild()
+{
+	mObjectList = LLUICtrlFactory::getScrollListByName(this, "object_list");
+	childSetAction("button owner",onClickOwnerProfile, this);
+	childSetAction("button creator",onClickCreatorProfile, this);
+	childSetCommitCallback("object_list", onSelectObject);
+	refresh();
+	return TRUE;
+}
+
+void LLFloaterInspect::onSelectObject(LLUICtrl* ctrl, void* user_data)
+{
+	if(LLFloaterInspect::getSelectedUUID() != LLUUID::null)
+	{
+		sInstance->childSetEnabled("button owner", true);
+		sInstance->childSetEnabled("button creator", true);
+	}
+}
+
+LLUUID LLFloaterInspect::getSelectedUUID()
+{
+	if(sInstance)
+	{
+		if(sInstance->mObjectList->getAllSelected().size() > 0) return sInstance->mObjectList->getFirstSelected()->getUUID();
+	}
+	return LLUUID::null;
+}
+
+void LLFloaterInspect::refresh()
+{
+	LLUUID creator_id;
+	LLString creator_name;
+	S32 pos = mObjectList->getScrollPos();
+	childSetEnabled("button owner", false);
+	childSetEnabled("button creator", false);
+	LLUUID selected_uuid;
+	S32 selected_index = mObjectList->getFirstSelectedIndex();
+	if(selected_index > -1) selected_uuid = mObjectList->getFirstSelected()->getUUID();
+	mObjectList->operateOnAll(LLScrollListCtrl::OP_DELETE);
+	//List all transient objects, then all linked objects
+	LLSelectNode* obj = gSelectMgr->getFirstNode();
+	LLSD row;
+	while(obj)
+	{
+		char owner_first_name[MAX_STRING], owner_last_name[MAX_STRING];
+		char creator_first_name[MAX_STRING], creator_last_name[MAX_STRING];
+		char time[MAX_STRING];
+		std::ostringstream owner_name, creator_name, date;
+		time_t timestamp = (time_t) (obj->mCreationDate/1000000);
+		LLString::copy(time, ctime(&timestamp), MAX_STRING);
+		time[24] = '\0';
+		date << obj->mCreationDate;
+		gCacheName->getName(obj->mPermissions->getOwner(), owner_first_name, owner_last_name);
+		owner_name << owner_first_name << " " << owner_last_name;
+		gCacheName->getName(obj->mPermissions->getCreator(), creator_first_name, creator_last_name);
+		creator_name << creator_first_name << " " << creator_last_name;
+		row["id"] = obj->getObject()->getID();
+		row["columns"][0]["column"] = "object_name";
+		row["columns"][0]["type"] = "text";
+		// make sure we're either at the top of the link chain
+		// or top of the editable chain, for attachments
+		if(!(obj->getObject()->isRoot() || obj->getObject()->isRootEdit()))
+		{
+			row["columns"][0]["value"] = LLString("   ") + obj->mName;
+		}
+		else
+		{
+			row["columns"][0]["value"] = obj->mName;
+		}
+		row["columns"][1]["column"] = "owner_name";
+		row["columns"][1]["type"] = "text";
+		row["columns"][1]["value"] = owner_name.str().c_str();
+		row["columns"][2]["column"] = "creator_name";
+		row["columns"][2]["type"] = "text";
+		row["columns"][2]["value"] = creator_name.str().c_str();
+		row["columns"][3]["column"] = "creation_date";
+		row["columns"][3]["type"] = "text";
+		row["columns"][3]["value"] = time;
+		mObjectList->addElement(row, ADD_TOP);
+		obj = gSelectMgr->getNextNode();
+	}
+	if(selected_index > -1 && mObjectList->getItemIndex(selected_uuid) == selected_index)
+	{
+		mObjectList->selectNthItem(selected_index);
+	}
+	else
+	{
+		mObjectList->selectNthItem(0);
+	}
+	onSelectObject(this, NULL);
+	mObjectList->setScrollPos(pos);
+}
+
+void LLFloaterInspect::onFocusReceived()
+{
+	select_tool(gToolInspect);
+}
+
+void LLFloaterInspect::dirty()
+{
+	if(sInstance)
+	{
+		sInstance->setDirty();
+	}
+}
+
+void LLFloaterInspect::draw()
+{
+	if (mDirty)
+	{
+		refresh();
+		mDirty = FALSE;
+	}
+
+	LLFloater::draw();
+}
\ No newline at end of file
diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h
new file mode 100644
index 00000000000..68c4f729bb3
--- /dev/null
+++ b/indra/newview/llfloaterinspect.h
@@ -0,0 +1,47 @@
+/** 
+* @file llfloaterfriends.h
+* @author Cube
+* @date 2006-12-16
+* @brief Declaration of class for displaying object attributes
+*
+* Copyright (c) 2005-$CurrentYear$, Linden Research, Inc.
+* $License$
+*/
+
+#ifndef LL_LLFLOATERINSPECT_H
+#define LL_LLFLOATERINSPECT_H
+
+#include "llfloater.h"
+
+//class LLTool;
+class LLScrollListCtrl;
+class LLUICtrl;
+
+class LLFloaterInspect : public LLFloater
+{
+public:
+	virtual ~LLFloaterInspect(void);
+	static void show(void* ignored = NULL);
+	virtual BOOL postBuild();
+	static void dirty();
+	static LLUUID getSelectedUUID();
+	virtual void draw();
+	virtual void refresh();
+	static BOOL isVisible();
+	virtual void onFocusReceived();
+	static void onClickCreatorProfile(void* ctrl);
+	static void onClickOwnerProfile(void* ctrl);
+	static void onSelectObject(LLUICtrl* ctrl, void* user_data);
+	LLScrollListCtrl* mObjectList;
+protected:
+	// protected members
+	LLFloaterInspect();
+	void setDirty() { mDirty = TRUE; }
+	bool mDirty;
+
+private:
+	// static data
+	static LLFloaterInspect* sInstance;
+};
+
+#endif //LL_LLFLOATERINSPECT_H
\ No newline at end of file
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 4bd3a4ee495..297d5941f2b 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -448,6 +448,7 @@ void LLPanelRegionInfo::sendEstateOwnerMessage(
 	msg->nextBlockFast(_PREHASH_AgentData);
 	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
 	msg->nextBlock("MethodData");
 	msg->addString("Method", request);
 	msg->addUUID("Invoice", invoice);
@@ -1788,6 +1789,7 @@ void LLPanelEstateInfo::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_
 	msg->nextBlockFast(_PREHASH_AgentData);
 	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
 
 	msg->nextBlock("MethodData");
 	msg->addString("Method", "estateaccessdelta");
@@ -2045,6 +2047,7 @@ void LLPanelEstateInfo::commitEstateInfo()
 	msg->nextBlockFast(_PREHASH_AgentData);
 	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
 
 	msg->nextBlock("MethodData");
 	msg->addString("Method", "estatechangeinfo");
@@ -2082,7 +2085,7 @@ void LLPanelEstateInfo::setEstateFlags(U32 flags)
 	childSetValue("deny_anonymous", LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) );
 	childSetValue("deny_identified", LLSD(flags & REGION_FLAGS_DENY_IDENTIFIED ? TRUE : FALSE) );
 	childSetValue("deny_transacted", LLSD(flags & REGION_FLAGS_DENY_TRANSACTED ? TRUE : FALSE) );
-
+	childSetVisible("abuse_email_text", flags & REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER);
 }
 
 U32 LLPanelEstateInfo::computeEstateFlags()
@@ -2604,6 +2607,7 @@ void LLPanelEstateCovenant::sendChangeCovenantID(const LLUUID &asset_id)
 		msg->nextBlockFast(_PREHASH_AgentData);
 		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
 
 		msg->nextBlock("MethodData");
 		msg->addString("Method", "estatechangecovenantid");
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 3b76aa038b0..5dadac22bee 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -35,6 +35,7 @@
 #include "llscrolllistctrl.h"
 #include "llimview.h"
 #include "lltextbox.h"
+#include "lldispatcher.h"
 #include "llviewertexteditor.h"
 #include "llviewerobject.h"
 #include "llviewerregion.h"
@@ -51,6 +52,7 @@
 #include "llviewermenu.h"		// for LLResourceData
 #include "llviewerwindow.h"
 #include "llviewerimagelist.h"
+#include "llworldmap.h"
 #include "llfilepicker.h"
 #include "llfloateravatarpicker.h"
 #include "lldir.h"
@@ -70,6 +72,13 @@ const U32 INCLUDE_SCREENSHOT  = 0x01 << 0;
 // there can only be one instance of each reporter type
 LLMap< EReportType, LLFloaterReporter* > gReporterInstances;
 
+// keeps track of where email is going to - global to avoid a pile
+// of static/non-static access outside my control
+namespace {
+	static BOOL gEmailToEstateOwner = FALSE;
+	static BOOL gDialogVisible = FALSE;
+}
+
 //-----------------------------------------------------------------------------
 // Member functions
 //-----------------------------------------------------------------------------
@@ -81,8 +90,9 @@ LLFloaterReporter::LLFloaterReporter(
 	:	
 	LLFloater(name, rect, title),
 	mReportType(report_type),
-	mObjectID( ),
+	mObjectID(),
 	mScreenID(),
+	mAbuserID(),
 	mDeselectOnClose( FALSE ),
 	mPicking( FALSE), 
 	mPosition(),
@@ -101,7 +111,9 @@ LLFloaterReporter::LLFloaterReporter(
 	if (regionp)
 	{
 		childSetText("sim_field", regionp->getName() );
+		childSetText("abuse_location_edit", regionp->getName() );
 	}
+
 	LLButton* pick_btn = LLUICtrlFactory::getButtonByName(this, "pick_btn");
 	if (pick_btn)
 	{
@@ -113,6 +125,7 @@ LLFloaterReporter::LLFloaterReporter(
 
 	if (report_type != BUG_REPORT)
 	{
+		// abuser name is selected from a list
 		LLLineEditor* le = (LLLineEditor*)getCtrlByNameAndType("abuser_name_edit", WIDGET_TYPE_LINE_EDITOR);
 		le->setEnabled( FALSE );
 	}
@@ -146,8 +159,40 @@ LLFloaterReporter::LLFloaterReporter(
 	childSetFocus("summary_edit");
 
 	mDefaultSummary = childGetText("details_edit");
+
+	gDialogVisible = TRUE;
+
+	// only request details for abuse reports (not BUG reports)
+	if (report_type != BUG_REPORT)
+	{
+		// send a message and ask for information about this region - 
+		// result comes back in processRegionInfo(..)
+		LLMessageSystem* msg = gMessageSystem;
+		msg->newMessage("RequestRegionInfo");
+		msg->nextBlock("AgentData");
+		msg->addUUID("AgentID", gAgent.getID());
+		msg->addUUID("SessionID", gAgent.getSessionID());
+		gAgent.sendReliableMessage();
+	};
 }
 
+// static
+void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
+{
+	U32 region_flags;
+	msg->getU32("RegionInfo", "RegionFlags", region_flags);
+	gEmailToEstateOwner = ( region_flags & REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER );
+
+	if ( gDialogVisible )
+	{
+		if ( gEmailToEstateOwner )
+		{
+			gViewerWindow->alertXml("HelpReportAbuseEmailEO");
+		}
+		else
+			gViewerWindow->alertXml("HelpReportAbuseEmailLL");
+	};
+}
 
 // virtual
 LLFloaterReporter::~LLFloaterReporter()
@@ -170,8 +215,28 @@ LLFloaterReporter::~LLFloaterReporter()
 	{
 		gSelectMgr->deselectTransient();
 	}
+
+	gDialogVisible = FALSE;
 }
 
+// virtual
+void LLFloaterReporter::draw()
+{
+	// this is set by a static callback sometime after the dialog is created.
+	// Only disable screenshot for abuse reports to estate owners - bug reports always
+	// allow screenshots to be taken.
+	if ( gEmailToEstateOwner && ( mReportType != BUG_REPORT ) )
+	{
+		childSetValue("screen_check", FALSE );
+		childSetEnabled("screen_check", FALSE );
+	}
+	else
+	{
+		childSetEnabled("screen_check", TRUE );
+	}
+
+	LLFloater::draw();
+}
 
 void LLFloaterReporter::enableControls(BOOL enable)
 {
@@ -190,7 +255,6 @@ void LLFloaterReporter::enableControls(BOOL enable)
 	childSetEnabled("cancel_btn",	enable);
 }
 
-
 void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
 {
 	// TODO -- 
@@ -274,6 +338,7 @@ void LLFloaterReporter::onClickSelectAbuser(void *userdata)
 	gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, userdata, FALSE, TRUE ));
 }
 
+// static
 void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data)
 {
 	LLFloaterReporter* self = (LLFloaterReporter*) data;
@@ -285,6 +350,8 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,
 	{
 		self->childSetText("abuser_name_edit", names[0] );
 
+		self->mAbuserID = ids[0];
+
 		self->refresh();
 	};
 }
@@ -400,7 +467,7 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
 		}
 		else
 		{
-			gViewerWindow->alertXml("HelpReportAbuse");
+			// popup for abuse reports is triggered elsewhere
 		}
 
 		// grab the user's name
@@ -550,10 +617,31 @@ void LLFloaterReporter::sendReport()
 	msg->addU8(_PREHASH_Category, category);
 	msg->addVector3Fast(_PREHASH_Position, 	mPosition);
 	msg->addU8Fast(_PREHASH_CheckFlags, 	(U8) check_flags);
-	LLSD screenshot_id = childGetValue("screenshot");
+
+	// only send a screenshot ID if we're asked too and the email is 
+	// going to LL - Estate Owners cannot see the screenshot asset
+	LLSD screenshot_id = LLUUID::null;
+	if (childGetValue("screen_check"))
+	{
+		if ( mReportType != BUG_REPORT )
+		{
+			if ( gEmailToEstateOwner == FALSE )
+			{
+				screenshot_id = childGetValue("screenshot");
+			}
+		}
+		else
+		{
+			screenshot_id = childGetValue("screenshot");
+		};
+	};
 	msg->addUUIDFast(_PREHASH_ScreenshotID, screenshot_id);
 	msg->addUUIDFast(_PREHASH_ObjectID, 	mObjectID);
-	
+
+	msg->addUUID("AbuserID", mAbuserID );
+	msg->addString("AbuseRegionName", "");
+	msg->addUUID("AbuseRegionID", LLUUID::null);
+
 	std::ostringstream summary;
 	if (!gInProductionGrid)
 	{
@@ -622,7 +710,7 @@ void LLFloaterReporter::sendReport()
 	if ( mReportType != BUG_REPORT )
 	{
 		details << "Abuser name: " << childGetText("abuser_name_edit") << " \n";
-		details << " Abuser location: " << childGetText("abuse_location_edit") << " \n";
+		details << "Abuser location: " << childGetText("abuse_location_edit") << " \n";
 	};
 
 	details << childGetValue("details_edit").asString();
@@ -640,16 +728,6 @@ void LLFloaterReporter::sendReport()
 			gGLManager.mDriverVersionVendorString.c_str());
 	msg->addString("VersionString", version_string);
 
-	std::list<LLMeanCollisionData*>::iterator it;
-	for (it = mMCDList.begin(); it != mMCDList.end(); ++it)
-	{
-		LLMeanCollisionData *mcd = *it;
-		msg->nextBlockFast(_PREHASH_MeanCollision);
-		msg->addUUIDFast(_PREHASH_Perp, mcd->mPerp);
-		msg->addU32Fast(_PREHASH_Time, mcd->mTime);
-		msg->addF32Fast(_PREHASH_Mag, mcd->mMag);
-		msg->addU8Fast(_PREHASH_Type, mcd->mType);
-	}
 	msg->sendReliable(regionp->getHost());
 
 	close();
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index a23424f9b47..795ef45e530 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -62,6 +62,8 @@ class LLFloaterReporter
 					  EReportType = UNKNOWN_REPORT);
 	/*virtual*/ ~LLFloaterReporter();
 
+	virtual void draw();
+
 	// Enables all buttons
 	static void showFromMenu(EReportType report_type);
 
@@ -81,6 +83,9 @@ class LLFloaterReporter
 	static LLFloaterReporter* createNewAbuseReporter();
 	static LLFloaterReporter* createNewBugReporter();
 
+	// static
+	static void processRegionInfo(LLMessageSystem* msg);
+	
 	void setPickedObjectProperties(const char *object_name, const char *owner_name);
 	void uploadScreenshot();
 
@@ -96,6 +101,7 @@ class LLFloaterReporter
 	EReportType		mReportType;
 	LLUUID 			mObjectID;
 	LLUUID			mScreenID;
+	LLUUID			mAbuserID;
 	BOOL			mDeselectOnClose;
 	BOOL 			mPicking;
 	LLVector3		mPosition;
diff --git a/indra/newview/llfloatertelehub.cpp b/indra/newview/llfloatertelehub.cpp
index f27cf55b3a1..9c2fb04f46c 100644
--- a/indra/newview/llfloatertelehub.cpp
+++ b/indra/newview/llfloatertelehub.cpp
@@ -211,6 +211,7 @@ void LLFloaterTelehub::onClickRemoveSpawnPoint(void* data)
 	{
 		msg->newMessage("EstateOwnerMessage");
 	}
+	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
 	msg->nextBlock("AgentData");
 	msg->addUUID("AgentID", gAgent.getID());
 	msg->addUUID("SessionID", gAgent.getSessionID());
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 6f675236b37..11665f484a4 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -164,15 +164,15 @@ BOOL	LLFloaterTools::postBuild()
 
 	LLRect rect;
 	mBtnFocus = LLUICtrlFactory::getButtonByName(this,"button focus");//btn;
-	childSetAction("button focus",select_tool, (void*)gToolCamera);
+	childSetAction("button focus",LLFloaterTools::setEditTool, (void*)gToolCamera);
 	mBtnMove = LLUICtrlFactory::getButtonByName(this,"button move");
-	childSetAction("button move",select_tool, (void*)gToolGrab);
+	childSetAction("button move",LLFloaterTools::setEditTool, (void*)gToolGrab);
 	mBtnEdit = LLUICtrlFactory::getButtonByName(this,"button edit");
-	childSetAction("button edit",select_tool, (void*)gToolTranslate);
+	childSetAction("button edit",LLFloaterTools::setEditTool, (void*)gToolTranslate);
 	mBtnCreate = LLUICtrlFactory::getButtonByName(this,"button create");
-	childSetAction("button create",select_tool, (void*)gToolCreate);
+	childSetAction("button create",LLFloaterTools::setEditTool, (void*)gToolCreate);
 	mBtnLand = LLUICtrlFactory::getButtonByName(this, "button land" );
-	childSetAction("button land",select_tool, (void*)gToolParcel);
+	childSetAction("button land",LLFloaterTools::setEditTool, (void*)gToolParcel);
 	mTextStatus = LLUICtrlFactory::getTextBoxByName(this,"text status");
 	mRadioZoom = LLUICtrlFactory::getCheckBoxByName(this,"radio zoom");
 	mSliderZoom = LLViewerUICtrlFactory::getVolumeSliderByName(this,"slider zoom");
@@ -364,7 +364,8 @@ LLFloaterTools::LLFloaterTools()
 	mPanelLandInfo(NULL),
 
 	mTabLand(NULL),
-	mDirty(TRUE)
+	mDirty(TRUE),
+	mLastTool(gToolNull)
 {
 	mAutoFocus = FALSE;
 	LLCallbackMap::map_t factory_map;
@@ -392,7 +393,6 @@ LLFloaterTools::~LLFloaterTools()
 	// children automatically deleted
 }
 
-
 void LLFloaterTools::setStatusText(const LLString& text)
 {
 	mTextStatus->setText(text);
@@ -852,7 +852,7 @@ void click_popup_dozer_mode(LLUICtrl *, void *user)
 {
 	S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
 	S32 mode = (S32)(intptr_t) user;
-	select_tool( gToolLand );
+	gFloaterTools->setEditTool( gToolLand );
 	gSavedSettings.setS32("RadioLandBrushAction", mode);
 	gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
 }
@@ -877,7 +877,7 @@ void click_apply_to_selection(void* user)
 void commit_select_tool(LLUICtrl *ctrl, void *data)
 {
 	S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
-	select_tool(data);
+	gFloaterTools->setEditTool(data);
 	gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
 }
 
@@ -929,3 +929,22 @@ void LLFloaterTools::onClickGridOptions(void* data)
 	// RN: this makes grid options dependent on build tools window
 	//floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE);
 }
+
+void LLFloaterTools::saveLastTool()
+{
+	mLastTool = gToolMgr->getCurrentTool( MASK_NONE );
+}
+
+void LLFloaterTools::setEditTool(void* tool_pointer)
+{
+	select_tool(tool_pointer);
+	if(gFloaterTools && tool_pointer != gToolNull)
+	{
+		gFloaterTools->saveLastTool();
+	}
+}
+
+void LLFloaterTools::onFocusReceived()
+{
+	select_tool(mLastTool);
+}
\ No newline at end of file
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index 092a8d7715d..c1bb050c2c1 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -14,6 +14,7 @@
 
 class LLButton;
 class LLTextBox;
+class LLTool;
 class LLCheckBoxCtrl;
 class LLTabContainer;
 class LLPanelPermissions;
@@ -69,9 +70,12 @@ class LLFloaterTools
 	void showPanel(EInfoPanel panel);
 
 	void setStatusText(const LLString& text);
-
+	virtual void onFocusReceived();
+	static void setEditTool(void* data);
+	void saveLastTool();
 private:
 	static void setObjectType( void* data );
+	
 	void refresh();
 
 	static void onClickGridOptions(void* data);
@@ -152,7 +156,8 @@ class LLFloaterTools
 	LLPanelLandInfo			*mPanelLandInfo;
 
 	LLTabContainer*			mTabLand;
-
+	LLTool*					mLastTool;
+	
 private:
 	BOOL					mDirty;
 	S32						mSmallHeight;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index f1c4f0d918e..cf9ae97b5ff 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -2535,23 +2535,24 @@ void LLInventoryModel::processSaveAssetIntoInventory(LLMessageSystem* msg,
 
 	LLUUID item_id;
 	msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_ItemID, item_id);
-	LLUUID new_asset_id;
-	msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_NewAssetID, new_asset_id);
-
-	lldebugs << "LLInventoryModel::processSaveAssetIntoInventory itemID=" << item_id << llendl;
 
+	// The viewer ignores the asset id because this message is only
+	// used for attachments/objects, so the asset id is not used in
+	// the viewer anyway.
+	lldebugs << "LLInventoryModel::processSaveAssetIntoInventory itemID="
+		<< item_id << llendl;
 	LLViewerInventoryItem* item = gInventory.getItem( item_id );
 	if( item )
 	{
-		item->setAssetUUID(new_asset_id);
 		LLCategoryUpdate up(item->getParentUUID(), 0);
 		gInventory.accountForUpdate(up);
-		gInventory.addChangedMask( LLInventoryObserver::INTERNAL, item_id );
+		gInventory.addChangedMask( LLInventoryObserver::INTERNAL, item_id);
 		gInventory.notifyObservers();
 	}
 	else
 	{
-		llinfos << "LLInventoryModel::processSaveAssetIntoInventory item not found: " << item_id << llendl;
+		llinfos << "LLInventoryModel::processSaveAssetIntoInventory item"
+			" not found: " << item_id << llendl;
 	}
 	if(gViewerWindow)
 	{
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 25f08322be9..b8bd5597043 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -291,6 +291,7 @@ class LLInventoryModel
 	struct LLInitializedS32
 	{
 		LLInitializedS32() : mValue(0) {}
+		LLInitializedS32(S32 value) : mValue(value) {}
 		S32 mValue;
 		LLInitializedS32& operator++() { ++mValue; return *this; }
 		LLInitializedS32& operator--() { --mValue; return *this; }
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 9e23b977d9c..d3642838b21 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -137,11 +137,11 @@ void LLPanelPermissions::refresh()
 		root_selected = FALSE;
 	}
 
-	BOOL attachment_selected = gSelectMgr->selectionIsAttachment();
-
+	//BOOL attachment_selected = gSelectMgr->selectionIsAttachment();
+	//attachment_selected = false;
 	LLViewerObject* objectp = NULL;
 	if(nodep) objectp = nodep->getObject();
-	if(!nodep || !objectp || attachment_selected)
+	if(!nodep || !objectp)// || attachment_selected)
 	{
 		// ...nothing selected
 		childSetEnabled("perm_modify",false);
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 175824d8663..934b73000b4 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -847,7 +847,7 @@ void LLPreviewLSL::loadAsset()
 		// do the more generic search.
 		getItem();
 	}
-	if(item && !(item->getAssetUUID().isNull()))
+	if(item)
 	{
 		BOOL is_copyable = gAgent.allowOperation(PERM_COPY, 
 								item->getPermissions(), GP_OBJECT_MANIPULATE);
@@ -1153,6 +1153,8 @@ void LLPreviewLSL::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_d
 void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type,
 								   void* user_data, S32 status)
 {
+	lldebugs << "LLPreviewLSL::onLoadComplete: got uuid " << asset_uuid
+		 << llendl;
 	LLUUID* item_uuid = (LLUUID*)user_data;
 	LLPreviewLSL* preview = LLPreviewLSL::getInstance(*item_uuid);
 	if( preview )
@@ -1357,7 +1359,7 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
 				mScriptEd->mEditor->makePristine();
 				mScriptEd->mEditor->setEnabled(FALSE);
 			}
-			else if(mItem.notNull() && mItem->getAssetUUID().notNull())
+			else if(mItem.notNull())
 			{
 				// request the text from the object
 				LLUUID* user_data = new LLUUID(mItemID ^ mObjectID);
@@ -1435,6 +1437,8 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id,
 									 LLAssetType::EType type,
 									 void* user_data, S32 status)
 {
+	lldebugs << "LLLiveLSLEditor::onLoadComplete: got uuid " << asset_id
+		 << llendl;
 	LLLiveLSLEditor* instance = NULL;
 	LLUUID* xored_id = (LLUUID*)user_data;
 
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 8f4df36f590..e1a17618cf9 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -30,6 +30,7 @@
 #include "llagent.h"
 #include "llviewerwindow.h"
 #include "lldrawable.h"
+#include "llfloaterinspect.h"
 #include "llfloaterproperties.h"
 #include "llfloaterrate.h"
 #include "llfloaterreporter.h"
@@ -97,6 +98,7 @@ F32	LLSelectMgr::sHighlightUAnim = 0.f;
 F32	LLSelectMgr::sHighlightVAnim = 0.f;
 LLColor4 LLSelectMgr::sSilhouetteParentColor;
 LLColor4 LLSelectMgr::sSilhouetteChildColor;
+LLColor4 LLSelectMgr::sHighlightInspectColor;
 LLColor4 LLSelectMgr::sHighlightParentColor;
 LLColor4 LLSelectMgr::sHighlightChildColor;
 LLColor4 LLSelectMgr::sContextSilhouetteColor;
@@ -145,6 +147,7 @@ LLSelectMgr::LLSelectMgr()
 	sSilhouetteChildColor = gColors.getColor("SilhouetteChildColor");
 	sHighlightParentColor = gColors.getColor("HighlightParentColor");
 	sHighlightChildColor = gColors.getColor("HighlightChildColor");
+	sHighlightInspectColor = gColors.getColor("HighlightInspectColor");
 	sContextSilhouetteColor = gColors.getColor("ContextSilhouetteColor")*0.5f;
 
 	sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
@@ -2810,7 +2813,7 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& id, LLString& name)
 	if(!node->mValid) return FALSE;
 	LLViewerObject* obj = node->getObject();
 	if(!obj) return FALSE;
-	if(!(obj->isRoot() || obj->isJointChild())) return FALSE;
+	if(!(obj->isRootEdit() || obj->isRoot() || obj->isJointChild())) return FALSE;
 
 	BOOL group_owner = FALSE;
 	id.setNull();
@@ -4660,6 +4663,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
 		LLUUID owner_id;
 		LLUUID group_id;
 		LLUUID last_owner_id;
+		U64 creation_date;
 		LLUUID extra_id;
 		U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask;
 		LLSaleInfo sale_info;
@@ -4671,6 +4675,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
 		msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_CreatorID, creator_id, i);
 		msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, i);
 		msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id, i);
+		msg->getU64Fast(_PREHASH_ObjectData, _PREHASH_CreationDate, creation_date, i);
 		msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask, i);
 		msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask, i);
 		msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_GroupMask, group_mask, i);
@@ -4789,6 +4794,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
 			node->mPermissions->init(creator_id, owner_id,
 									 last_owner_id, group_id);
 			node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask);
+			node->mCreationDate = creation_date;
 			node->mItemID = item_id;
 			node->mFolderID = folder_id;
 			node->mFromTaskID = from_task_id;
@@ -5013,22 +5019,8 @@ void LLSelectMgr::updateSilhouettes()
 						}
 					}
 				}
-
-				//if (!gFloaterTools || !gFloaterTools->getVisible())
-				//{
-				//	node->renderOneSilhouette(sContextSilhouetteColor);
-				//}
-				//else if (objectp->isRootEdit())
-				//{
-				//	node->renderOneSilhouette(sSilhouetteParentColor);
-				//}
-				//else
-				//{
-				//	node->renderOneSilhouette(sSilhouetteChildColor);
-				//}
 			}
 		}
-		//mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D);
 	}
 
 	if (mRectSelectedObjects.size() > 0)
@@ -5245,6 +5237,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 	if (mSelectedObjects.getNumNodes())
 	{
 		glPushAttrib(GL_FOG_BIT);
+		LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID();
 		for (S32 pass = 0; pass < 2; pass++)
 		{
 			for (node = mSelectedObjects.getFirstNode(); node; node = mSelectedObjects.getNextNode() )
@@ -5254,7 +5247,11 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 				{
 					continue;
 				}
-				if (node->isTransient())
+				if(objectp->getID() == inspect_item_id)
+				{
+					node->renderOneSilhouette(sHighlightInspectColor);
+				}
+				else if (node->isTransient())
 				{
 					BOOL oldHidden = LLSelectMgr::sRenderHiddenSelections;
 					LLSelectMgr::sRenderHiddenSelections = FALSE;
@@ -5850,6 +5847,7 @@ void dialog_refresh_all()
 	}
 
 	LLFloaterProperties::dirtyAll();
+	LLFloaterInspect::dirty();
 }
 
 S32 get_family_count(LLViewerObject *parent)
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 77039213d49..77c1206b894 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -166,6 +166,7 @@ class LLSelectMgr : public LLEditMenuHandler
 	static LLColor4				sSilhouetteChildColor;
 	static LLColor4				sHighlightParentColor;
 	static LLColor4				sHighlightChildColor;
+	static LLColor4				sHighlightInspectColor;
 	static LLColor4				sContextSilhouetteColor;
 public:
 	LLSelectMgr();
@@ -605,6 +606,7 @@ class LLSelectNode
 	LLUUID			mFromTaskID;
 	LLString		mTouchName;
 	LLString		mSitName;
+	U64				mCreationDate;
 	std::vector<LLColor4>	mSavedColors;
 	std::vector<LLUUID>		mSavedTextures;
 	std::vector<LLVector3>  mTextureScaleRatios;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 74c1d443297..2119bf2d706 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -796,6 +796,7 @@ BOOL idle_startup()
 		case USERSERVER_DURGA:
 		case USERSERVER_SOMA:
 		case USERSERVER_GANGA:
+		case USERSERVER_UMA:
 		{
 				const char* host_name = gUserServerDomainName[gUserServerChoice].mName;
 				sprintf(gUserServerName,"%s", host_name);
@@ -2547,6 +2548,7 @@ void login_show()
 	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_DURGA].mLabel,	USERSERVER_DURGA );
 	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SHAKTI].mLabel,	USERSERVER_SHAKTI );
 	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_GANGA].mLabel,	USERSERVER_GANGA );
+	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_UMA].mLabel,	USERSERVER_UMA );
 	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SOMA].mLabel,	USERSERVER_SOMA );
 }
 
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index f295c66ee1c..945a172b1ce 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -39,6 +39,7 @@ const S32 BUTTON_WIDTH_BIG = 48;
 const S32 HPAD = 4;
 
 // Globals
+LLToolCompInspect   *gToolInspect = NULL;
 LLToolCompTranslate	*gToolTranslate = NULL;
 LLToolCompScale		*gToolStretch = NULL;
 LLToolCompRotate	*gToolRotate = NULL;
@@ -47,6 +48,7 @@ LLToolCompGun		*gToolGun = NULL;
 
 extern LLControlGroup gSavedSettings;
 
+
 //-----------------------------------------------------------------------
 // LLToolComposite
 
@@ -108,6 +110,64 @@ void LLToolComposite::handleSelect()
 	mSelected = TRUE; 
 }
 
+//----------------------------------------------------------------------------
+// LLToolCompInspect
+//----------------------------------------------------------------------------
+
+LLToolCompInspect::LLToolCompInspect()
+: LLToolComposite("Inspect")
+{
+	mSelectRect		= new LLToolSelectRect(this);
+	mDefault = mSelectRect;
+}
+
+
+LLToolCompInspect::~LLToolCompInspect()
+{
+	delete mSelectRect;
+	mSelectRect = NULL;
+}
+
+BOOL LLToolCompInspect::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	mMouseDown = TRUE;
+	gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback);
+	return TRUE;
+}
+
+void LLToolCompInspect::pickCallback(S32 x, S32 y, MASK mask)
+{
+	LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
+
+	if (!gToolInspect->mMouseDown)
+	{
+		// fast click on object, but mouse is already up...just do select
+		gToolInspect->mSelectRect->handleObjectSelection(hit_obj, mask, !gSavedSettings.getBOOL("SelectLinkedSet"), FALSE);
+		return;
+	}
+
+	if( hit_obj )
+	{
+		if (gSelectMgr->getObjectCount())
+		{
+			gEditMenuHandler = gSelectMgr;
+		}
+		gToolInspect->setCurrentTool( gToolInspect->mSelectRect );
+		gToolInspect->mSelectRect->handleMouseDown( x, y, mask );
+
+	}
+	else
+	{
+		gToolInspect->setCurrentTool( gToolInspect->mSelectRect );
+		gToolInspect->mSelectRect->handleMouseDown( x, y, mask);
+	}
+}
+
+BOOL LLToolCompInspect::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+	return TRUE;
+}
+
 //----------------------------------------------------------------------------
 // LLToolCompTranslate
 //----------------------------------------------------------------------------
@@ -202,12 +262,9 @@ BOOL LLToolCompTranslate::handleDoubleClick(S32 x, S32 y, MASK mask)
 		gFloaterTools->showPanel(LLFloaterTools::PANEL_CONTENTS);
 		return TRUE;
 	}
-	else
-	{
-		// Nothing selected means the first mouse click was probably
-		// bad, so try again.
-		return FALSE;
-	}
+	// Nothing selected means the first mouse click was probably
+	// bad, so try again.
+	return FALSE;
 }
 
 
diff --git a/indra/newview/lltoolcomp.h b/indra/newview/lltoolcomp.h
index cb1ec33f1b8..c319904ee88 100644
--- a/indra/newview/lltoolcomp.h
+++ b/indra/newview/lltoolcomp.h
@@ -78,6 +78,22 @@ class LLToolComposite : public LLTool
 };
 
 
+//-----------------------------------------------------------------------
+// LLToolCompTranslate
+
+class LLToolCompInspect : public LLToolComposite
+{
+public:
+	LLToolCompInspect();
+	virtual ~LLToolCompInspect();
+
+	// Overridden from LLToolComposite
+    virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
+    virtual BOOL		handleDoubleClick(S32 x, S32 y, MASK mask);
+
+	static void pickCallback(S32 x, S32 y, MASK mask);
+};
+
 //-----------------------------------------------------------------------
 // LLToolCompTranslate
 
@@ -88,16 +104,15 @@ class LLToolCompTranslate : public LLToolComposite
 	virtual ~LLToolCompTranslate();
 
 	// Overridden from LLToolComposite
-    virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
-    virtual BOOL		handleDoubleClick(S32 x, S32 y, MASK mask);
-    virtual BOOL		handleHover(S32 x, S32 y, MASK mask);
+	virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
+	virtual BOOL		handleDoubleClick(S32 x, S32 y, MASK mask);
+	virtual BOOL		handleHover(S32 x, S32 y, MASK mask);
 	virtual BOOL		handleMouseUp(S32 x, S32 y, MASK mask);			// Returns to the default tool
 	virtual void		render();
 
 	static void pickCallback(S32 x, S32 y, MASK mask);
 };
 
-
 //-----------------------------------------------------------------------
 // LLToolCompScale
 
@@ -191,6 +206,7 @@ class LLToolCompGun : public LLToolComposite
 	LLTool*				mNull;
 };
 
+extern LLToolCompInspect	*gToolInspect;
 extern LLToolCompTranslate	*gToolTranslate;
 extern LLToolCompScale		*gToolStretch;
 extern LLToolCompRotate		*gToolRotate;
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index 99271e18c5e..2c69db10c54 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -159,6 +159,12 @@ void LLToolMgr::initTools()
 	gToolGun = new LLToolCompGun();
 	gMouselookToolset->addTool( gToolGun );
 
+	//
+	// Inspect tool
+	//
+	gToolInspect = new LLToolCompInspect();
+	gBasicToolset->addTool( gToolInspect );
+
 	//
 	// Face edit tool
 	//
@@ -328,6 +334,12 @@ LLTool* LLToolMgr::getCurrentTool(MASK override_mask)
 		mOverrideTool = NULL;
 		return mCurrentTool;
 	}
+	else if (mCurrentTool == gToolInspect)
+	{
+		// ...can't switch out of grab
+		mOverrideTool = NULL;
+		return mCurrentTool;
+	}
 	else
 	{
 		// ...can switch between editing tools
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index a305c1cfa44..a899d3d3d2c 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -84,6 +84,7 @@
 #include "llfloaterhtmlhelp.h"
 #include "llfloaterhtmlfind.h"
 #include "llfloaterimport.h"
+#include "llfloaterinspect.h"
 #include "llfloaterland.h"
 #include "llfloaterlandholdings.h"
 #include "llfloatermap.h"
@@ -920,31 +921,6 @@ void init_client_menu(LLMenuGL* menu)
 	menu->createJumpKeys();
 }
 
-void handle_upload_data(void*)
-{
-	LLFilePicker& picker = LLFilePicker::instance();
-	if(!picker.getOpenFile())
-	{
-		llwarns << "No file" << llendl;
-		return;
-	}
- 	const char* filename = picker.getFirstFile();
-	S32 index = strlen(filename);
-	char delim = gDirUtilp->getDirDelimiter()[0];
-	while(index && filename[index--] != delim);
-	index += 2;
-	const char* basename = &filename[index];
-
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessage("InitiateUpload");
-	msg->nextBlock("AgentData");
-	msg->addUUID("AgentID", gAgent.getID());
-	msg->nextBlock("FileData");
-	msg->addString("BaseFilename", basename);
-	msg->addString("SourceFilename", filename);
-	gAgent.sendReliableMessage();
-}
-
 void init_debug_world_menu(LLMenuGL* menu)
 {
 	menu->append(new LLMenuItemCheckGL("Mouse Moves Sun", 
@@ -1414,14 +1390,6 @@ void init_server_menu(LLMenuGL* menu)
 
 	menu->appendSeparator();
 
-	menu->append(new LLMenuItemCallGL("Upload Data File...", 
-									  &handle_upload_data,
-									  &enable_god_customer_service,
-									  NULL));
-
-
-	menu->appendSeparator();
-
 	menu->append(new LLMenuItemCallGL("Save Region State", 
 		&LLPanelRegionTools::onSaveState, &enable_god_customer_service, NULL));
 
@@ -1801,7 +1769,7 @@ class LLObjectEdit : public view_listener_t
 		gFloaterTools->open();
 	
 		gCurrentToolset = gBasicToolset;
-		gCurrentToolset->selectTool( gToolTranslate );
+		gFloaterTools->setEditTool( gToolTranslate );
 
 		// Could be first use
 		LLFirstUse::useBuild();
@@ -1809,6 +1777,16 @@ class LLObjectEdit : public view_listener_t
 	}
 };
 
+class LLObjectInspect : public view_listener_t
+{
+	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+	{
+		gSelectMgr->convertTransient();
+		LLFloaterInspect::show();
+		return true;
+	}
+};
+
 
 //---------------------------------------------------------------------------
 // Land pie menu
@@ -2454,12 +2432,14 @@ void handle_buy_object(LLSaleInfo sale_info)
 		return;
 	}
 
+	gSelectMgr->convertTransient();
 	LLFloaterBuy::show(sale_info);
 }
 
 
 void handle_buy_contents(LLSaleInfo sale_info)
 {
+	gSelectMgr->convertTransient();
 	LLFloaterBuyContents::show(sale_info);
 }
 
@@ -2575,7 +2555,7 @@ void set_god_level(U8 god_level)
 		gParcelMgr->notifyObservers();
 
 		// Some classifieds change visibility on god mode
-		LLFloaterDirectory::requestClassified();
+		LLFloaterDirectory::requestClassifieds();
 
 		// God mode changes sim visibility
 		gWorldMap->reset();
@@ -3409,6 +3389,7 @@ void handle_claim_public_land(void*)
 	msg->nextBlock("AgentData");
 	msg->addUUID("AgentID", gAgent.getID());
 	msg->addUUID("SessionID", gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
 	msg->nextBlock("MethodData");
 	msg->addString("Method", "claimpublicland");
 	msg->addUUID("Invoice", LLUUID::null);
@@ -8771,6 +8752,7 @@ void initialize_menu_actions()
 	(new LLObjectMute())->registerListener(gMenuHolder, "Object.Mute");
 	(new LLObjectBuy())->registerListener(gMenuHolder, "Object.Buy");
 	(new LLObjectEdit())->registerListener(gMenuHolder, "Object.Edit");
+	(new LLObjectInspect())->registerListener(gMenuHolder, "Object.Inspect");
 
 	(new LLObjectEnableOpen())->registerListener(gMenuHolder, "Object.EnableOpen");
 	(new LLObjectEnableTouch())->registerListener(gMenuHolder, "Object.EnableTouch");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 994a2a4659d..eabc81994f8 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -206,8 +206,9 @@ void process_logout_reply(LLMessageSystem* msg, void**)
 		llwarns << "Bogus Logout Reply" << llendl;
 	}
 
+	LLInventoryModel::update_map_t parents;
 	S32 count = msg->getNumberOfBlocksFast( _PREHASH_InventoryData );
-	for( S32 i = 0; i < count; i++ )
+	for(S32 i = 0; i < count; ++i)
 	{
 		LLUUID item_id;
 		msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_ItemID, item_id, i);
@@ -218,36 +219,25 @@ void process_logout_reply(LLMessageSystem* msg, void**)
 			break;
 		}
 
-
-		// Update our the asset ids of the inventory items we're currently wearing.
-		LLUUID new_asset_id;
-		msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_NewAssetID, new_asset_id, i);
-
+		// We do not need to track the asset ids, just account for an
+		// updated inventory version.
 		llinfos << "process_logout_reply itemID=" << item_id << llendl;
 		LLInventoryItem* item = gInventory.getItem( item_id );
 		if( item )
 		{
-			item->setAssetUUID(new_asset_id);
-
-			gInventory.addChangedMask( LLInventoryObserver::INTERNAL, item_id );
-			gInventory.notifyObservers();
+			parents[item->getParentUUID()] = 0;
+			gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
 		}
 		else
 		{
 			llinfos << "process_logout_reply item not found: " << item_id << llendl;
 		}
 	}
-
-	/*
-	gLogoutTimer.reset();
-	gLogoutMaxTime = LOGOUT_REPLY_TIME;
-	gViewerWindow->setProgressString("Logging out...");
-
-	if (gNoRender)
+	if(!parents.empty())
 	{
-		// Hack so drones can quit with new logout process
-		*/
-	
+		gInventory.accountForUpdate(parents);
+		gInventory.notifyObservers();
+	}
 	app_force_quit(NULL);
 }
 
@@ -4950,6 +4940,7 @@ void send_generic_message(const char* method,
 	msg->nextBlockFast(_PREHASH_AgentData);
 	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
 	msg->nextBlock("MethodData");
 	msg->addString("Method", method);
 	msg->addUUID("Invoice", invoice);
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index aecc015e0e4..93c2c7e3f38 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -46,6 +46,10 @@ LLUserServerData gUserServerDomainName[USERSERVER_COUNT] =
 	  "userserver.ganga.lindenlab.com",
 	  "https://login.ganga.lindenlab.com/cgi-bin/login.cgi",
 	  "http://ganga-secondlife.webdev.lindenlab.com/helpers/" },
+	{ "Uma",
+	  "userserver.uma.lindenlab.com",
+	  "https://login.uma.lindenlab.com/cgi-bin/login.cgi",
+	  "http://uma-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Local", 
 	  "localhost", 
 	  "https://login.dmz.lindenlab.com/cgi-bin/login.cgi",
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index acb1b53525a..2de06bf9410 100644
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -23,6 +23,7 @@ enum EUserServerDomain
 	USERSERVER_SHAKTI,
 	USERSERVER_SOMA,
 	USERSERVER_GANGA,
+	USERSERVER_UMA,
 	USERSERVER_LOCAL,
 	USERSERVER_OTHER, // IP address set via -user or other command line option
 	USERSERVER_COUNT
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index bcbc81ce5ce..09cbf494bcb 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -27,6 +27,7 @@
 #include "lldir.h"
 #include "lleventpoll.h"
 #include "llfloatergodtools.h"
+#include "llfloaterreporter.h"
 #include "llfloaterregioninfo.h"
 #include "llhttpnode.h"
 #include "llnetmap.h"
@@ -547,6 +548,7 @@ void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**)
 	// send it to 'observers'
 	LLFloaterGodTools::processRegionInfo(msg);
 	LLFloaterRegionInfo::processRegionInfo(msg);
+	LLFloaterReporter::processRegionInfo(msg);
 }
 
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 74a239e827d..dc00fe7585b 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -74,6 +74,7 @@
 #include "llfloatercustomize.h"
 #include "llfloatereditui.h" // HACK JAMESDEBUG for ui editor
 #include "llfloaterland.h"
+#include "llfloaterinspect.h"
 #include "llfloatermap.h"
 #include "llfloatermute.h"
 #include "llfloaternamedesc.h"
@@ -2513,10 +2514,10 @@ BOOL LLViewerWindow::handlePerFrameHover()
 		}
 	}		
 
-	if (tool != gToolNull && tool != gToolDragAndDrop && !gSavedSettings.getBOOL("FreezeTime"))
+	if (tool != gToolNull  && tool != gToolInspect && tool != gToolCamera && tool != gToolDragAndDrop && !gSavedSettings.getBOOL("FreezeTime"))
 	{ 
 		LLMouseHandler *captor = gFocusMgr.getMouseCapture();
-		// With the null tool or drag and drop tool, don't muck
+		// With the null, inspect, or drag and drop tool, don't muck
 		// with visibility.
 
 		if (gFloaterTools->isMinimized() ||
@@ -2525,11 +2526,11 @@ BOOL LLViewerWindow::handlePerFrameHover()
 			&& !mSuppressToolbox					// not override in third person
 			&& gCurrentToolset != gFaceEditToolset	// not special mode
 			&& gCurrentToolset != gMouselookToolset
-			&& (!captor || captor->isView()))		// not dragging
-			)			
+			&& (!captor || captor->isView())) // not dragging
+			)
 		{
 			// Force floater tools to be visible (unless minimized)
-			if (!gFloaterTools->isMinimized() && !gFloaterTools->getVisible())
+			if (!gFloaterTools->getVisible())
 			{
 				gFloaterTools->open();
 			}
@@ -2675,6 +2676,7 @@ BOOL LLViewerWindow::handlePerFrameHover()
 
 	// sync land selection with edit and about land dialogs
 	if (gParcelMgr
+		&& !gMenuHolder->hasVisibleMenu()
 		&& !LLFloaterLand::floaterVisible()
 		&& !LLFloaterBuyLand::isOpen()
 		&& (!gFloaterTools || !gFloaterTools->getVisible()))
diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg
index bd44513c93f..b44b099c331 100644
--- a/scripts/messages/message_template.msg
+++ b/scripts/messages/message_template.msg
@@ -657,18 +657,14 @@ sim -> dataserver
 		{   OwnerID			LLUUID  }
 		{   LastOwnerID		LLUUID  }
 		{   CreatorID		LLUUID  }
-		{	SimName			Variable	1	}
+		{	RegionID		LLUUID	}
+		{   AbuserID		LLUUID  }
+		{	AbuseRegionName	Variable	1	}
+		{	AbuseRegionID	LLUUID	}
 		{   Summary			Variable	1   }
 		{   Details 		Variable	2   }
 		{	VersionString	Variable	1	}
 	}
-	{
-		MeanCollision		Variable
-		{	Perp			LLUUID	}
-		{	Time			U32		}
-		{	Mag				F32		}
-		{	Type			U8		}
-	}
 }
 
 // SetSimStatusInDatabase
@@ -1044,6 +1040,7 @@ sim -> dataserver
 		{	QueryText		Variable	1	}
 		{	QueryFlags		U32				}
 		{	Category		U32				}
+		{	QueryStart	S32					}
 	}
 }
 
@@ -1063,6 +1060,7 @@ sim -> dataserver
 		{	Category		U32				}
 		{	EstateID		U32				}
 		{	Godlike			BOOL			}
+		{	QueryStart	S32					}
 	}
 }
 
@@ -1294,9 +1292,10 @@ sim -> dataserver
 		QueryData			Single
 		{	QueryID			LLUUID	}
 		{	QueryFlags		U32		}
-		{	ForSale			BOOL	}
-		{	Auction			BOOL	}
-		{	ReservedNewbie	BOOL	}
+		{	SearchType		U32		}
+		{	Price			S32		}
+		{	Area			S32		}
+		{	QueryStart		S32		}
 	}
 }
 
@@ -1312,9 +1311,10 @@ sim -> dataserver
 		QueryData			Single
 		{	QueryID			LLUUID	}
 		{	QueryFlags		U32		}
-		{	ForSale			BOOL	}
-		{	Auction			BOOL	}
-		{	ReservedNewbie	BOOL	}
+		{	SearchType		U32		}
+		{	Price			S32		}
+		{	Area			S32		}
+		{	QueryStart		S32		}
 		{	EstateID		U32		}
 		{	Godlike			BOOL	}
 	}
@@ -3144,115 +3144,6 @@ sim -> dataserver
 	}
 }
 
-
-// Grant agents the ability to modify your stuff. This message is sent
-// to the simulator, and then passed along to the dataserver for
-// persistance. The dataserver will push live updates through
-// AddModifyAbility messages to the simulator.
-// viewer -> simulator -> dataserver
-//{
-//	GrantModification Low NotTrusted Unencoded
-//	{
-//		AgentData			Single
-//		{	AgentID			LLUUID	}
-//		{	SessionID		LLUUID	}
-//		{	GranterName		Variable	1	}
-//	}
-//	{
-//		EmpoweredBlock		Variable
-//		{	EmpoweredID		LLUUID	}
-//	}
-//}
-// Revoke the ability to modify your stuff. This message is sent to
-// the simulator, and then passed along to the dataserver for
-// persistance. The dataserver will push live updates through
-// RemoveModifyAbility messages to the simulator.
-// viewer -> simulator -> dataserver
-//{
-//	RevokeModification Low NotTrusted Unencoded
-//	{
-//		AgentData			Single
-//		{	AgentID			LLUUID	}
-//		{	SessionID		LLUUID	}
-//		{	GranterName		Variable	1	}
-//	}
-//	{
-//		RevokedBlock		Variable
-//		{	RevokedID		LLUUID	}
-//	}
-//}
-
-// This message is sent from viewer->simulator->dataserver, which responds with
-// the complete list of all granted agents in the GrantedProxies message.
-//{
-//	RequestGrantedProxies Low NotTrusted Unencoded
-//	{
-//		AgentData			Single
-//		{	AgentID			LLUUID	}
-//		{	SessionID		LLUUID	}
-//	}
-//}
-
-// response to the message above
-//{
-//	GrantedProxies Low Trusted Unencoded
-//	{
-//		AgentData			Single
-//		{	AgentID			LLUUID	}
-//	}
-//	{
-//		EmpoweredBlock			Variable
-//		{	EmpoweredID		LLUUID	}
-//	}
-//	{
-//		GranterBlock			Variable
-//		{	GranterID		LLUUID	}
-//	}
-//}
-
-// This message is sent from the dataserver to the simulator to let
-// AgentID know that they can modify GranterID's stuff. This message is
-// percolated out to child cameras and the viewer. This message is
-// in response to GrantModification messages, request, or login.
-// ROUTED dataserver -> simulator -> spaceserver -> simulator
-// reliable
-//{
-//	AddModifyAbility Low Trusted Zerocoded
-//	{
-//		TargetBlock			Single
-//		{	TargetIP		IPADDR	}	// U32 encoded IP
-//		{	TargetPort		IPPORT	}
-//	}
-//	{
-//		AgentBlock			Single
-//		{	AgentID			LLUUID	}
-//	}
-//	{
-//		GranterBlock		Variable
-//		{	GranterID		LLUUID	}
-//	}
-//}
-
-// This message is sent from the dataserver to the simulator to let
-// AgentID know that they can no longer modify GranterID's stuff. This
-// message is percolated out to child cameras and the viewer. This
-// message is in response to RevokeModification messages.
-// ROUTED dataserver -> simulator -> spaceserver -> simulator
-// reliable
-//{
-//	RemoveModifyAbility Low Trusted Unencoded
-//	{
-//		TargetBlock			Single
-//		{	TargetIP		IPADDR	}	// U32 encoded IP
-//		{	TargetPort		IPPORT	}
-//	}
-//	{
-//		AgentBlock			Single
-//		{	AgentID			LLUUID	}
-//		{	RevokerID		LLUUID	}
-//	}
-//}
-
 // end viewer to simulator section
 
 {
@@ -3343,17 +3234,13 @@ sim -> dataserver
 		{   CheckFlags		U8	} // checkboxflags
 		{   ScreenshotID	LLUUID  }
 		{   ObjectID		LLUUID  }
+		{   AbuserID		LLUUID  }
+		{	AbuseRegionName	Variable	1	}
+		{	AbuseRegionID	LLUUID	}
 		{   Summary			Variable	1   }
 		{   Details 		Variable	2   }
 		{	VersionString	Variable	1	}
 	}
-	{
-		MeanCollision		Variable
-		{	Perp			LLUUID	}
-		{	Time			U32		}
-		{	Mag				F32		}
-		{	Type			U8		}
-	}
 }
 
 
@@ -3952,6 +3839,7 @@ sim -> dataserver
 		{	TargetType		S32	}
 		{	Status			S32	}
 		{	Size			S32	}
+		{	Params			Variable	2	}
 	}
 }
 
@@ -4153,6 +4041,7 @@ sim -> dataserver
 		{	CreatorID		LLUUID	}
 		{	OwnerID			LLUUID	}
 		{	GroupID			LLUUID	}
+		{	CreationDate	U64	}
 		{	BaseMask		U32	}
 		{	OwnerMask		U32	}
 		{	GroupMask		U32	}
@@ -6230,7 +6119,6 @@ sim -> dataserver
 	{
 		InventoryData		Variable
 		{	ItemID			LLUUID	}  // null if list is actually empty (but has one entry 'cause it can't have none)
-		{	NewAssetID		LLUUID	}
 	}
 }
 
@@ -6361,6 +6249,7 @@ sim -> dataserver
 		AgentData 		Single
 		{   AgentID     LLUUID  }
 		{	SessionID	LLUUID		}
+		{	TransactionID	LLUUID	}
 	}
 	{
 		MethodData 	Single
@@ -6381,6 +6270,7 @@ sim -> dataserver
 		AgentData 		Single
 		{   AgentID     LLUUID  	}
 		{	SessionID	LLUUID		}
+		{	TransactionID	LLUUID	}
 	}
 	{
 		MethodData 	Single
@@ -6402,6 +6292,7 @@ sim -> dataserver
 		AgentData 		Single
 		{   AgentID     LLUUID  	}
 		{	SessionID	LLUUID		}
+		{	TransactionID	LLUUID	}
 	}
 	{
 		MethodData 	Single
@@ -6637,8 +6528,10 @@ sim -> dataserver
 //
 // Sim outgoing only (to dataserver, to viewer)
 // NOT viewer to sim, sim should not have handler, ever
+// This message is currently only uses objects, so the viewer ignores
+// the asset id.
 {
-	SaveAssetIntoInventory Low NotTrusted Unencoded
+	SaveAssetIntoInventory Low Trusted Unencoded
 	{
 		AgentData		Single
 		{	AgentID			LLUUID	}
@@ -9589,22 +9482,6 @@ sim -> dataserver
 	}
 }
 
-
-// viewer -> sim 
-// initiate upload. primarily used for uploading raw files.
-{
-	InitiateUpload	Low		NotTrusted Unencoded
-	{
-		AgentData	Single
-		{	AgentID		LLUUID	}
-	}
-	{
-		FileData	Single
-		{	BaseFilename	Variable	1	}	// string
-		{	SourceFilename	Variable	1	}	// string
-	}
-}
-
 // sim -> viewer
 // initiate upload. primarily used for uploading raw files.
 {
-- 
GitLab