diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 80df91a5c18d83ba8c2ac0bf6d1f55942e31b879..9910281b649b472107be29397c4293f80377ab53 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -115,6 +115,7 @@ set(llcommon_HEADER_FILES
     indra_constants.h
     linden_common.h
     linked_lists.h
+    llaccountingquota.h
     llallocator.h
     llallocator_heap_profile.h
     llagentconstants.h
diff --git a/indra/llcommon/llaccountingquota.h b/indra/llcommon/llaccountingquota.h
new file mode 100644
index 0000000000000000000000000000000000000000..f52d94f868392eb3f5e3e2ed1a57c004d94d28f3
--- /dev/null
+++ b/indra/llcommon/llaccountingquota.h
@@ -0,0 +1,78 @@
+/** 
+ * @file llaccountingquota.h
+ * @
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_ACCOUNTINGQUOTA_H
+#define LL_ACCOUNTINGQUOTA_H
+
+struct ParcelQuota
+{
+	ParcelQuota( F32 ownerRenderCost, F32 ownerPhysicsCost, F32 ownerNetworkCost, F32 ownerSimulationCost,
+				F32 groupRenderCost, F32 groupPhysicsCost, F32 groupNetworkCost, F32 groupSimulationCost,
+				F32 otherRenderCost, F32 otherPhysicsCost, F32 otherNetworkCost, F32 otherSimulationCost,
+				F32 totalRenderCost, F32 totalPhysicsCost, F32 totalNetworkCost, F32 totalSimulationCost)
+	: mOwnerRenderCost( ownerRenderCost ), mOwnerPhysicsCost( ownerPhysicsCost ) 
+	, mOwnerNetworkCost( ownerNetworkCost ), mOwnerSimulationCost( ownerSimulationCost )
+	, mGroupRenderCost( groupRenderCost ), mGroupPhysicsCost( groupPhysicsCost )
+	, mGroupNetworkCost( groupNetworkCost ), mGroupSimulationCost( groupSimulationCost )
+	, mOtherRenderCost( otherRenderCost ), mOtherPhysicsCost( otherPhysicsCost )
+	, mOtherNetworkCost( otherNetworkCost ), mOtherSimulationCost( otherSimulationCost )
+	, mTotalRenderCost( totalRenderCost ), mTotalPhysicsCost( totalPhysicsCost ) 
+	, mTotalNetworkCost( totalNetworkCost ), mTotalSimulationCost( totalSimulationCost )
+	{
+	}
+	ParcelQuota(){}			
+	F32 mOwnerRenderCost, mOwnerPhysicsCost, mOwnerNetworkCost, mOwnerSimulationCost;
+	F32 mGroupRenderCost, mGroupPhysicsCost, mGroupNetworkCost, mGroupSimulationCost;
+	F32 mOtherRenderCost, mOtherPhysicsCost, mOtherNetworkCost, mOtherSimulationCost;
+	F32 mTotalRenderCost, mTotalPhysicsCost, mTotalNetworkCost, mTotalSimulationCost;
+};
+
+struct SelectionQuota
+{
+	SelectionQuota( S32 localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost )
+	: mLocalId( localId)
+	, mRenderCost( renderCost )
+	, mPhysicsCost( physicsCost )
+	, mNetworkCost( networkCost )
+	, mSimulationCost( simulationCost )
+	{
+	}
+	SelectionQuota() {}
+	
+	F32 mRenderCost, mPhysicsCost, mNetworkCost, mSimulationCost;	
+	S32 mLocalId;
+};
+
+#endif
+
+
+
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index 0a4cd51ea091a7e44a7a6faeb66e86b9e0658a4c..e8cd871157bfed75cc51a11b2f5f1ebd39a68d01 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -1348,3 +1348,12 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s)
     // is a distinct option from "None" and "Other"
     return LLParcel::C_ANY;
 }
+
+void LLParcel::updateQuota( const LLUUID& objectId,  const ParcelQuota& quota )
+{
+	if ( mID == objectId )
+	{
+		mQuota = quota;
+	}
+}
+
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index 71b65d99ced3c90a4a879b443d9bb481f68590dc..48933379677ba94c429eb46fb611cd3ffab6655d 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -34,7 +34,7 @@
 #include "llpermissions.h"
 #include "lltimer.h"
 #include "v3math.h"
-
+#include "llaccountingquota.h"
 
 // Grid out of which parcels taken is stepped every 4 meters.
 const F32 PARCEL_GRID_STEP_METERS	= 4.f;
@@ -586,7 +586,11 @@ class LLParcel
 	LLUUID	getPreviousOwnerID() const		{ return mPreviousOwnerID; }
 	BOOL	getPreviouslyGroupOwned() const	{ return mPreviouslyGroupOwned; }
 	BOOL	getSellWithObjects() const		{ return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; }
-
+	
+	
+			void		 updateQuota( const LLUUID& objectId, const ParcelQuota& quota );
+	const	ParcelQuota& getQuota( void ) { return mQuota; }	
+	
 protected:
 	LLUUID mID;
 	LLUUID				mOwnerID;
@@ -657,8 +661,9 @@ class LLParcel
 	BOOL				mRegionPushOverride;
 	BOOL				mRegionDenyAnonymousOverride;
 	BOOL				mRegionDenyAgeUnverifiedOverride;
-
-
+	
+	ParcelQuota			mQuota;
+	
 public:
 	// HACK, make private
 	S32					mLocalID;
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 57ac7a143f3f6206e192f264378b580d4cc0aaad..030a61cd551deb9eafc753003aa271948e27d4a1 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1778,7 +1778,7 @@ void LLModel::updateHullCenters()
 	if (mHullPoints > 0)
 	{
 		mCenterOfHullCenters *= 1.f / mHullPoints;
-		llassert(mPhysics.asLLSD().has("HullList"));
+		llassert(mPhysics.hasHullList());
 	}
 }
 
@@ -2127,6 +2127,11 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
 	}
 }
 
+bool LLModel::Decomposition::hasHullList() const
+{
+	return !mHull.empty() ;
+}
+
 LLSD LLModel::Decomposition::asLLSD() const
 {
 	LLSD ret;
@@ -2208,14 +2213,17 @@ LLSD LLModel::Decomposition::asLLSD() const
 					//convert to 16-bit normalized across domain
 					U16 val = (U16) (((mHull[i][j].mV[k]-min.mV[k])/range.mV[k])*65535);
 
-					switch (k)
+					if(valid.size() < 3)
 					{
-						case 0: test = test | (U64) val; break;
-						case 1: test = test | ((U64) val << 16); break;
-						case 2: test = test | ((U64) val << 32); break;
-					};
+						switch (k)
+						{
+							case 0: test = test | (U64) val; break;
+							case 1: test = test | ((U64) val << 16); break;
+							case 2: test = test | ((U64) val << 32); break;
+						};
 
-					valid.insert(test);
+						valid.insert(test);
+					}
 					
 					U8* buff = (U8*) &val;
 					//write to binary buffer
@@ -2227,8 +2235,8 @@ LLSD LLModel::Decomposition::asLLSD() const
 				}
 			}
 
-			//must have at least 4 unique points
-			llassert(valid.size() > 3);
+			//must have at least 3 unique points
+			llassert(valid.size() > 2);
 		}
 
 		ret["Position"] = p;
@@ -2290,10 +2298,5 @@ void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs)
 	{ //take physics shape mesh from rhs
 		mPhysicsShapeMesh = rhs->mPhysicsShapeMesh;
 	}
-
-	if (!mHull.empty())
-	{ //verify
-		llassert(asLLSD().has("HullList"));
-	}
 }
 
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 23f4b5cb42733a0565fc4d15d19f9976266d4595..ebca1f9d9d253b881629f2c73f52164a8821f13f 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -106,6 +106,7 @@ class LLModel : public LLVolume
 		Decomposition(LLSD& data);
 		void fromLLSD(LLSD& data);
 		LLSD asLLSD() const;
+		bool hasHullList() const;
 
 		void merge(const Decomposition* rhs);
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index cbf22b75e8cd26aee1940aa115579a8f781e88cb..769dcf845716dca6767f536f611f450a6e0a1757 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -77,6 +77,7 @@ include_directories(
 
 set(viewer_SOURCE_FILES
     groupchatlistener.cpp
+    llaccountingquotamanager.cpp
     llagent.cpp
     llagentaccess.cpp
     llagentcamera.cpp
@@ -626,6 +627,7 @@ set(viewer_HEADER_FILES
     CMakeLists.txt
     ViewerInstall.cmake
     groupchatlistener.h
+    llaccountingquotamanager.h
     llagent.h
     llagentaccess.h
     llagentcamera.h
diff --git a/indra/newview/llaccountingquotamanager.cpp b/indra/newview/llaccountingquotamanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ada74ea44ca33ed0551afe748ab36519063c78e1
--- /dev/null
+++ b/indra/newview/llaccountingquotamanager.cpp
@@ -0,0 +1,264 @@
+/** 
+ * @file LLAccountingQuotaManager.cpp
+ * @ Handles the setting and accessing for costs associated with mesh 
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llaccountingquotamanager.h"
+#include "llagent.h"
+#include "llviewerregion.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewerparcelmgr.h"
+#include "llparcel.h"
+
+//===============================================================================
+LLAccountingQuotaManager::LLAccountingQuotaManager()
+{	
+}
+//===============================================================================
+class LLAccountingQuotaResponder : public LLCurl::Responder
+{
+public:
+	LLAccountingQuotaResponder( const LLSD& objectIDs )
+	: mObjectIDs( objectIDs )
+	{
+	}
+		
+	void clearPendingRequests ( void )
+	{
+		for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
+		{
+			LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( iter->asUUID() );
+		}
+	}
+	
+	void error( U32 statusNum, const std::string& reason )
+	{
+		llwarns	<< "Transport error "<<reason<<llendl;	
+		//prep#do we really want to remove all because of one failure - verify
+		clearPendingRequests();
+	}
+	
+	void result( const LLSD& content )
+	{
+		if ( !content.isMap() || content.has("error") )
+		{
+			llwarns	<< "Error on fetched data"<< llendl;
+			//prep#do we really want to remove all because of one failure - verify
+			clearPendingRequests();
+			return;
+		}
+		
+		//Differentiate what the incoming caps could be from the data
+		//bool VOContent  = content.has("Objects");
+		bool containsParcel    = content.has("parcel");
+		bool containsSelection = content.has("selected");
+		//bool VORegion   = content.has("region");
+				
+		//Loop over the stored object ids checking against the incoming data
+		for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
+		{
+			LLUUID objectID = iter->asUUID();
+						
+			LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID );
+				
+			if ( containsParcel )
+			{
+					//Typically should be one
+					S32 dataCount = content["parcel"].size();
+					for(S32 i = 0; i < dataCount; i++)
+					{
+						//prep#todo verify that this is safe, otherwise just add a bool
+						S32 parcelId = 0;
+						S32 parcelOwner = 0;
+						if ( content["parcel"][i].has("parcel_id") )
+						{
+							parcelId = content["parcel"][i]["parcel_id"].asInteger();
+						}
+						if ( content["parcel"][i].has("parcel_owner") )
+						{
+							parcelOwner = content["parcel"][i]["parcel_owner"].asInteger();
+						}
+											
+						F32 ownerRenderCost		= 0;
+						F32 ownerPhysicsCost	= 0;
+						F32 ownerNetworkCost	= 0;
+						F32 ownerSimulationCost = 0;
+						
+						F32 groupRenderCost		= 0;
+						F32 groupPhysicsCost	= 0;
+						F32 groupNetworkCost	= 0;
+						F32 groupSimulationCost = 0;
+						
+						F32 otherRenderCost		= 0;
+						F32 otherPhysicsCost	= 0;
+						F32 otherNetworkCost	= 0;
+						F32 otherSimulationCost = 0;
+						
+						F32 totalRenderCost		= 0;
+						F32 totalPhysicsCost	= 0;
+						F32 totalNetworkCost	= 0;
+						F32 totalSimulationCost = 0;
+						
+						if ( content["parcel"][i].has("owner") )
+						{
+							ownerRenderCost		= content["parcel"][i]["owner"]["render"].asReal();
+							ownerPhysicsCost	= content["parcel"][i]["owner"]["physics"].asReal();
+							ownerNetworkCost	= content["parcel"][i]["owner"]["network"].asReal();
+							ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal();
+							
+						}
+						if ( content["parcel"][i].has("group") )
+						{
+							groupRenderCost		= content["parcel"][i]["group"]["render"].asReal();
+							groupPhysicsCost	= content["parcel"][i]["group"]["physics"].asReal();
+							groupNetworkCost	= content["parcel"][i]["group"]["network"].asReal();
+							groupSimulationCost = content["parcel"][i]["group"]["simulation"].asReal();
+							
+						}
+						if ( content["parcel"][i].has("other") )
+						{
+							otherRenderCost		= content["parcel"][i]["other"]["render"].asReal();
+							otherPhysicsCost	= content["parcel"][i]["other"]["physics"].asReal();
+							otherNetworkCost	= content["parcel"][i]["other"]["network"].asReal();
+							otherSimulationCost = content["parcel"][i]["other"]["simulation"].asReal();
+						}
+						
+						if ( content["parcel"][i].has("total") )
+						{
+							totalRenderCost		= content["parcel"][i]["total"]["render"].asReal();
+							totalPhysicsCost	= content["parcel"][i]["total"]["physics"].asReal();
+							totalNetworkCost	= content["parcel"][i]["total"]["network"].asReal();
+							totalSimulationCost = content["parcel"][i]["total"]["simulation"].asReal();
+							
+						}
+						
+						ParcelQuota parcelQuota( ownerRenderCost, ownerPhysicsCost, ownerNetworkCost, ownerSimulationCost,
+												 groupRenderCost, groupPhysicsCost, groupNetworkCost, groupSimulationCost,
+												 otherRenderCost, otherPhysicsCost, otherNetworkCost, otherSimulationCost,
+												 totalRenderCost, totalPhysicsCost, totalNetworkCost, totalSimulationCost );
+						//Update the Parcel						
+						LLParcel* pParcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
+						if ( pParcel )
+						{
+							pParcel->updateQuota( objectID, parcelQuota ); 
+						}
+					}					
+				}
+			else 
+			if ( containsSelection )
+			{
+				S32 dataCount = content["selected"].size();
+				for(S32 i = 0; i < dataCount; i++)
+				{
+					
+					F32 renderCost		= 0;
+					F32 physicsCost		= 0;
+					F32 networkCost		= 0;
+					F32 simulationCost	= 0;
+					
+					S32 localId = 0;
+					
+					localId			= content["selected"][i]["local_id"].asInteger();
+					renderCost		= content["selected"][i]["render"].asReal();
+					physicsCost		= content["selected"][i]["physics"].asReal();
+					networkCost		= content["selected"][i]["network"].asReal();
+					simulationCost	= content["selected"][i]["simulation"].asReal();
+					
+					SelectionQuota selectionQuota( localId, renderCost, physicsCost, networkCost, simulationCost );
+					
+					//Update the objects					
+					//gObjectList.updateQuota( localId, selectionQuota ); 
+					
+				}
+			}
+			else
+			{
+				//Nothing in string 
+				LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID );
+			}
+		}
+	}
+	
+private:
+	//List of posted objects
+	LLSD mObjectIDs;
+};
+//===============================================================================
+void LLAccountingQuotaManager::fetchQuotas( const std::string& url )
+{
+	// Invoking system must have already determined capability availability
+	if ( !url.empty() )
+	{
+		LLSD objectList;
+		U32  objectIndex = 0;
+		IDIt IDIter = mUpdateObjectQuota.begin();
+		IDIt IDIterEnd = mUpdateObjectQuota.end();
+		
+		for ( ; IDIter != IDIterEnd; ++IDIter )
+		{
+			// Check to see if a request for this object has already been made.
+			if ( mPendingObjectQuota.find( *IDIter ) ==	mPendingObjectQuota.end() )
+			{
+				mPendingObjectQuota.insert( *IDIter );	
+				objectList[objectIndex++] = *IDIter;
+			}
+		}
+	
+		mUpdateObjectQuota.clear();
+		
+		//Post results
+		if ( objectList.size() > 0 )
+		{
+			LLSD dataToPost = LLSD::emptyMap();			
+			dataToPost["object_ids"] = objectList;
+			LLHTTPClient::post( url, dataToPost, new LLAccountingQuotaResponder( objectList ));
+		}
+	}
+	else
+	{
+		//url was empty - warn & continue
+		llwarns<<"Supplied url is empty "<<llendl;
+		mUpdateObjectQuota.clear();
+		mPendingObjectQuota.clear();
+	}
+}
+//===============================================================================
+void LLAccountingQuotaManager::updateObjectCost( const LLUUID& objectID )
+{
+	mUpdateObjectQuota.insert( objectID );
+}
+//===============================================================================
+void LLAccountingQuotaManager::removePendingObjectQuota( const LLUUID& objectID )
+{
+	mPendingObjectQuota.erase( objectID );
+}
+//===============================================================================
diff --git a/indra/newview/llaccountingquotamanager.h b/indra/newview/llaccountingquotamanager.h
new file mode 100644
index 0000000000000000000000000000000000000000..f605d1e6b2809a06316d1d05c243c772e3c5b881
--- /dev/null
+++ b/indra/newview/llaccountingquotamanager.h
@@ -0,0 +1,60 @@
+/** 
+ * @file lllAccountingQuotaManager.h
+ * @
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_ACCOUNTINGQUOTAMANAGER_H
+#define LL_ACCOUNTINGQUOTAMANAGER_H
+//===============================================================================
+#include "llaccountingquota.h"
+//===============================================================================
+class LLAccountingQuotaManager : public LLSingleton<LLAccountingQuotaManager>
+{
+public:
+	//Ctor
+	LLAccountingQuotaManager();
+	//Store an object that will be eventually fetched
+	void updateObjectCost( const LLUUID& objectID );
+	//Request quotas for object list
+	void fetchQuotas( const std::string& url );
+	//Delete a specific object from the pending list
+	void removePendingObjectQuota( const LLUUID& objectID );
+	
+private:
+	//Set of objects that need to update their cost
+	std::set<LLUUID> mUpdateObjectQuota;
+	//During fetchQuota we move object into a the pending set to signify that 
+	//a fetch has been instigated.
+	std::set<LLUUID> mPendingObjectQuota;
+	typedef std::set<LLUUID>::iterator IDIt;
+};
+//===============================================================================
+
+#endif
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 9dd5269a6b4811519a3558bc73d966e2d797a6f6..2a3bd37129b767a15ea25fce214c04a7992e6393 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -4962,9 +4962,12 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
 	if (mdl)
 	{
 		U16 index_offset = 0;
+		U16 tri[3] ;
 
 		mPositions.clear();
 		mIndices.clear();
+		mBBox[1] = LLVector3(F32_MIN, F32_MIN, F32_MIN) ;
+		mBBox[0] = LLVector3(F32_MAX, F32_MAX, F32_MAX) ;
 
 		//queue up vertex positions and indices
 		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
@@ -4978,12 +4981,28 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
 			for (U32 j = 0; j < face.mNumVertices; ++j)
 			{
 				mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr()));
+				for(U32 k = 0 ; k < 3 ; k++)
+				{
+					mBBox[0].mV[k] = llmin(mBBox[0].mV[k], mPositions[j].mV[k]) ;
+					mBBox[1].mV[k] = llmax(mBBox[1].mV[k], mPositions[j].mV[k]) ;
+				}
 			}
 
-			for (U32 j = 0; j < face.mNumIndices; ++j)
+			updateTriangleAreaThreshold() ;
+
+			for (U32 j = 0; j+2 < face.mNumIndices; j += 3)
 			{
-				mIndices.push_back(face.mIndices[j]+index_offset);
-			}
+				tri[0] = face.mIndices[j] + index_offset ;
+				tri[1] = face.mIndices[j + 1] + index_offset ;
+				tri[2] = face.mIndices[j + 2] + index_offset ;
+				
+				if(isValidTriangle(tri[0], tri[1], tri[2]))
+				{
+					mIndices.push_back(tri[0]);
+					mIndices.push_back(tri[1]);
+					mIndices.push_back(tri[2]);
+				}
+			}			
 
 			index_offset += face.mNumVertices;
 		}
diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp
index faf81dbc5c3cef62fb519439de92b04c2c101c41..e44737f39e41152c04b33c2e74a268e893c30e44 100644
--- a/indra/newview/llfloatermodelwizard.cpp
+++ b/indra/newview/llfloatermodelwizard.cpp
@@ -441,10 +441,13 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM
 	if (mdl)
 	{
 		U16 index_offset = 0;
+		U16 tri[3] ;
 
 		mPositions.clear();
 		mIndices.clear();
-
+		mBBox[1] = LLVector3(F32_MIN, F32_MIN, F32_MIN) ;
+		mBBox[0] = LLVector3(F32_MAX, F32_MAX, F32_MAX) ;
+		
 		//queue up vertex positions and indices
 		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
 		{
@@ -457,11 +460,27 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM
 			for (U32 j = 0; j < face.mNumVertices; ++j)
 			{
 				mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr()));
+				for(U32 k = 0 ; k < 3 ; k++)
+				{
+					mBBox[0].mV[k] = llmin(mBBox[0].mV[k], mPositions[j].mV[k]) ;
+					mBBox[1].mV[k] = llmax(mBBox[1].mV[k], mPositions[j].mV[k]) ;
+				}
 			}
 
-			for (U32 j = 0; j < face.mNumIndices; ++j)
+			updateTriangleAreaThreshold() ;
+
+			for (U32 j = 0; j+2 < face.mNumIndices; j += 3)
 			{
-				mIndices.push_back(face.mIndices[j]+index_offset);
+				tri[0] = face.mIndices[j] + index_offset ;
+				tri[1] = face.mIndices[j + 1] + index_offset ;
+				tri[2] = face.mIndices[j + 2] + index_offset ;
+				
+				if(isValidTriangle(tri[0], tri[1], tri[2]))
+				{
+					mIndices.push_back(tri[0]);
+					mIndices.push_back(tri[1]);
+					mIndices.push_back(tri[2]);
+				}
 			}
 
 			index_offset += face.mNumVertices;
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 73c1f99fa04df5f167f70e598e2440589fd596a8..061a42ab571ad824460a863ecef8708df55de9b0 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -85,6 +85,7 @@
 #include "llviewerwindow.h"
 #include "llvovolume.h"
 #include "lluictrlfactory.h"
+#include "llaccountingquotamanager.h"
 
 // Globals
 LLFloaterTools *gFloaterTools = NULL;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index b5180854efbe73340b71dd627ba5023b850e0c58..318beafe657a97e1e029c98036468d353a9267f4 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -632,10 +632,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
 	}
 
 	// We're hiding mesh types
+#if 0
 	if (item->getType() == LLAssetType::AT_MESH)
 	{
 		return mask;
 	}
+#endif
 
 	LLViewerInventoryItem* old_item = getItem(item->getUUID());
 	LLPointer<LLViewerInventoryItem> new_item;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d9a58d56fe799009408b17de9bc26948034ddbd6..b79f120eda4f9d7f9af87bd39721c0d58cace10c 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -498,18 +498,29 @@ class LLWholeModelFeeResponder: public LLCurl::Responder
 		//assert_main_thread();
 		llinfos << "completed" << llendl;
 		mThread->mPendingUploads--;
-		dumpLLSDToFile(content,"whole_model_response.xml");
+		dumpLLSDToFile(content,"whole_model_fee_response.xml");
+		if (isGoodStatus(status))
+		{
+			mThread->mWholeModelUploadURL = content["uploader"].asString(); 
+		}
+		else
+		{
+			llinfos << "upload failed" << llendl;
+			mThread->mWholeModelUploadURL = "";
+		}
 
-		mThread->mWholeModelUploadURL = content["uploader"].asString(); 
 	}
 };
 
 class LLWholeModelUploadResponder: public LLCurl::Responder
 {
 	LLMeshUploadThread* mThread;
+	LLSD mPostData;
+	
 public:
-	LLWholeModelUploadResponder(LLMeshUploadThread* thread):
-		mThread(thread)
+	LLWholeModelUploadResponder(LLMeshUploadThread* thread, LLSD& post_data):
+		mThread(thread),
+		mPostData(post_data)
 	{
 	}
 	virtual void completed(U32 status,
@@ -520,6 +531,10 @@ class LLWholeModelUploadResponder: public LLCurl::Responder
 		llinfos << "upload completed" << llendl;
 		mThread->mPendingUploads--;
 		dumpLLSDToFile(content,"whole_model_upload_response.xml");
+		// requested "mesh" asset type isn't actually the type
+		// of the resultant object, fix it up here.
+		mPostData["asset_type"] = "object";
+		gMeshRepo.updateInventory(LLMeshRepository::inventory_data(mPostData,content));
 	}
 };
 
@@ -1386,108 +1401,131 @@ void LLMeshUploadThread::run()
 	}
 }
 
-#if 1
 void dumpLLSDToFile(const LLSD& content, std::string filename)
 {
+#if 1
 	std::ofstream of(filename.c_str());
 	LLSDSerialize::toPrettyXML(content,of);
-}
 #endif
+}
 
 void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 {
-	// TODO where do textures go?
-
 	LLSD result;
 
 	LLSD res;
 	result["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
 	result["asset_type"] = "mesh";
 	result["inventory_type"] = "object";
-	result["name"] = "your name here";
+	result["name"] = "mesh model";
 	result["description"] = "your description here";
 
-	// TODO "optional" fields from the spec
-	
 	res["mesh_list"] = LLSD::emptyArray();
-// TODO Textures
-	//res["texture_list"] = LLSD::emptyArray();
+	res["texture_list"] = LLSD::emptyArray();
+	res["instance_list"] = LLSD::emptyArray();
 	S32 mesh_num = 0;
 	S32 texture_num = 0;
 	
 	std::set<LLViewerTexture* > textures;
+	std::map<LLViewerTexture*,S32> texture_index;
 
+	std::map<LLModel*,S32> mesh_index;
+
+	S32 instance_num = 0;
+	
 	for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
 	{
 		LLMeshUploadData data;
 		data.mBaseModel = iter->first;
-
 		LLModelInstance& instance = *(iter->second.begin());
+		LLModel* model = instance.mModel;
+		if (mesh_index.find(model) == mesh_index.end())
+		{
+			// Have not seen this model before - create a new mesh_list entry for it.
+			std::string model_name = data.mBaseModel->getName();
+			if (!model_name.empty())
+			{
+				result["name"] = model_name;
+			}
 
+			std::stringstream ostr;
+			
+			LLModel::Decomposition& decomp =
+				data.mModel[LLModel::LOD_PHYSICS].notNull() ? 
+				data.mModel[LLModel::LOD_PHYSICS]->mPhysics : 
+				data.mBaseModel->mPhysics;
+
+			decomp.mBaseHull = mHullMap[data.mBaseModel];
+
+			LLSD mesh_header = LLModel::writeModel(
+				ostr,  
+				data.mModel[LLModel::LOD_PHYSICS],
+				data.mModel[LLModel::LOD_HIGH],
+				data.mModel[LLModel::LOD_MEDIUM],
+				data.mModel[LLModel::LOD_LOW],
+				data.mModel[LLModel::LOD_IMPOSTOR], 
+				decomp,
+				mUploadSkin,
+				mUploadJoints);
+
+			data.mAssetData = ostr.str();
+			std::string str = ostr.str();
+
+			res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end()); 
+			mesh_index[model] = mesh_num;
+			mesh_num++;
+		}
+		
+		LLSD instance_entry;
+		
 		for (S32 i = 0; i < 5; i++)
 		{
 			data.mModel[i] = instance.mLOD[i];
 		}
-
-		std::stringstream ostr;
-
-		LLModel::Decomposition& decomp =
-			data.mModel[LLModel::LOD_PHYSICS].notNull() ? 
-			data.mModel[LLModel::LOD_PHYSICS]->mPhysics : 
-			data.mBaseModel->mPhysics;
-
-		decomp.mBaseHull = mHullMap[data.mBaseModel];
-
-		LLSD mesh_header = LLModel::writeModel(
-			ostr,  
-			data.mModel[LLModel::LOD_PHYSICS],
-			data.mModel[LLModel::LOD_HIGH],
-			data.mModel[LLModel::LOD_MEDIUM],
-			data.mModel[LLModel::LOD_LOW],
-			data.mModel[LLModel::LOD_IMPOSTOR], 
-			decomp,
-			mUploadSkin,
-			mUploadJoints);
-
-		data.mAssetData = ostr.str();
-
-		LLSD mesh_entry;
-
+		
 		LLVector3 pos, scale;
 		LLQuaternion rot;
 		LLMatrix4 transformation = instance.mTransform;
 		decomposeMeshMatrix(transformation,pos,rot,scale);
+		instance_entry["position"] = ll_sd_from_vector3(pos);
+		instance_entry["rotation"] = ll_sd_from_quaternion(rot);
+		instance_entry["scale"] = ll_sd_from_vector3(scale);
+		
+		instance_entry["material"] = LL_MCODE_WOOD;
+		LLPermissions perm;
+		perm.setOwnerAndGroup(gAgent.getID(), gAgent.getID(), LLUUID::null, false);
+		perm.setCreator(gAgent.getID());
+		
+		perm.initMasks(PERM_ITEM_UNRESTRICTED | PERM_MOVE, //base
+					   PERM_ITEM_UNRESTRICTED | PERM_MOVE, //owner
+					   LLFloaterPerms::getEveryonePerms(),
+					   LLFloaterPerms::getGroupPerms(),
+					   LLFloaterPerms::getNextOwnerPerms());
+		instance_entry["permissions"] = ll_create_sd_from_permissions(perm);
+		instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
+		instance_entry["mesh"] = mesh_index[model];
 
-#if 0
-		mesh_entry["childpos"] = ll_sd_from_vector3(pos);
-		mesh_entry["childrot"] = ll_sd_from_quaternion(rot);
-		mesh_entry["scale"] = ll_sd_from_vector3(scale);
-#endif
-		mesh_entry["position"] = ll_sd_from_vector3(LLVector3());
-		mesh_entry["rotation"] = ll_sd_from_quaternion(rot);
-		mesh_entry["scale"] = ll_sd_from_vector3(scale);
-
-		// TODO should be binary.
-		std::string str = ostr.str();
-		mesh_entry["mesh_data"] = LLSD::Binary(str.begin(),str.end()); 
-
-		res["mesh_list"][mesh_num] = mesh_entry;
-
-		// TODO how do textures in the list map to textures in the meshes?
 		if (mUploadTextures)
 		{
-			for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin();
-				material_iter != instance.mMaterial.end(); ++material_iter)
-			{
+			instance_entry["face_list"] = LLSD::emptyArray();
 
-				if (textures.find(material_iter->mDiffuseMap.get()) == textures.end())
+			for (S32 face_num = 0; face_num < model->getNumVolumeFaces(); face_num++)
+			{
+				LLImportMaterial& material = instance.mMaterial[face_num];
+				LLSD face_entry = LLSD::emptyMap();
+				LLViewerFetchedTexture *texture = material.mDiffuseMap.get();
+				
+				if (texture != NULL)
 				{
-					textures.insert(material_iter->mDiffuseMap.get());
+					if (textures.find(texture) == textures.end())
+					{
+						textures.insert(texture);
+					}
 
 					std::stringstream ostr;
 					if (include_textures) // otherwise data is blank.
 					{
-						LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel);
+						LLTextureUploadData data(texture, material.mDiffuseMapLabel);
 						if (!data.mTexture->isRawImageValid())
 						{
 							data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel());
@@ -1497,21 +1535,38 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
 							LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage());
 						ostr.write((const char*) upload_file->getData(), upload_file->getDataSize());
 					}
-					LLSD texture_entry;
-					texture_entry["texture_data"] = ostr.str();
-					res["texture_list"][texture_num] = texture_entry;
-					texture_num++;
+
+					if (texture_index.find(texture) == texture_index.end())
+					{
+						texture_index[texture] = texture_num;
+						std::string str = ostr.str();
+						res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
+						texture_num++;
+					}
 				}
+
+				// Subset of TextureEntry fields.
+				if (texture)
+				{
+					face_entry["image"] = texture_index[texture];
+				}
+				face_entry["scales"] = 1.0;
+				face_entry["scalet"] = 1.0;
+				face_entry["offsets"] = 0.0;
+				face_entry["offsett"] = 0.0;
+				face_entry["imagerot"] = 0.0;
+				face_entry["colors"] = ll_sd_from_color4(material.mDiffuseColor);
+				face_entry["fullbright"] = material.mFullbright;
+				instance_entry["face_list"][face_num] = face_entry;
 			}
 		}
 
-		mesh_num++;
+		res["instance_list"][instance_num] = instance_entry;
+		instance_num++;
 	}
 
 	result["asset_resources"] = res;
-#if 1	
 	dumpLLSDToFile(result,"whole_model.xml");
-#endif
 
 	dest = result;
 }
@@ -1563,9 +1618,9 @@ void LLMeshUploadThread::doWholeModelUpload()
 		apr_sleep(100);
 	}
 
-	bool do_include_textures = false; // not needed for initial cost/validation check.
 	LLSD model_data;
-	wholeModelToLLSD(model_data, do_include_textures);
+	wholeModelToLLSD(model_data,false);
+	dumpLLSDToFile(model_data,"whole_model_fee_request.xml");
 
 	mPendingUploads++;
 	LLCurlRequest::headers_t headers;
@@ -1577,12 +1632,24 @@ void LLMeshUploadThread::doWholeModelUpload()
 		mCurlRequest->process();
 	} while (mCurlRequest->getQueued() > 0);
 
-	mCurlRequest->post(mWholeModelUploadURL, headers, model_data["asset_resources"], new LLWholeModelUploadResponder(this));
-	
-	do
+
+	if (mWholeModelUploadURL.empty())
 	{
-		mCurlRequest->process();
-	} while (mCurlRequest->getQueued() > 0);
+		llinfos << "unable to upload, fee request failed" << llendl;
+	}
+	else
+	{
+		LLSD full_model_data;
+		wholeModelToLLSD(full_model_data, true);
+		LLSD body = full_model_data["asset_resources"];
+		dumpLLSDToFile(body,"whole_model_body.xml");
+		mCurlRequest->post(mWholeModelUploadURL, headers, body,
+						   new LLWholeModelUploadResponder(this, model_data));
+		do
+		{
+			mCurlRequest->process();
+		} while (mCurlRequest->getQueued() > 0);
+	}
 
 	delete mCurlRequest;
 	mCurlRequest = NULL;
@@ -3243,6 +3310,8 @@ bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const
 void LLMeshRepository::updateInventory(inventory_data data)
 {
 	LLMutexLock lock(mMeshMutex);
+	dumpLLSDToFile(data.mPostData,"update_inventory_post_data.xml");
+	dumpLLSDToFile(data.mResponse,"update_inventory_response.xml");
 	mInventoryQ.push(data);
 }
 
@@ -3751,6 +3820,25 @@ void LLPhysicsDecomp::run()
 	mDone = true;
 }
 
+void LLPhysicsDecomp::Request::updateTriangleAreaThreshold() 
+{
+	F32 range = mBBox[1].mV[0] - mBBox[0].mV[0] ;
+	range = llmin(range, mBBox[1].mV[1] - mBBox[0].mV[1]) ;
+	range = llmin(range, mBBox[1].mV[2] - mBBox[0].mV[2]) ;
+
+	mTriangleAreaThreshold = llmin(0.0002f, range * 0.000002f) ;
+}
+
+//check if the triangle area is large enough to qualify for a valid triangle
+bool LLPhysicsDecomp::Request::isValidTriangle(U16 idx1, U16 idx2, U16 idx3) 
+{
+	LLVector3 a = mPositions[idx2] - mPositions[idx1] ;
+	LLVector3 b = mPositions[idx3] - mPositions[idx1] ;
+	F32 c = a * b ;
+
+	return ((a*a) * (b*b) - c * c) > mTriangleAreaThreshold ;
+}
+
 void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg)
 {
 	mStatusMessage = msg;
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index f859e29c0789778440fdb1158324024348dad163..0a6954bade52fa371bda5a4bb494db742322346e 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -152,7 +152,7 @@ class LLPhysicsDecomp : public LLThread
 		std::string mStatusMessage;
 		std::vector<LLModel::PhysicsMesh> mHullMesh;
 		LLModel::convex_hull_decomposition mHull;
-		
+			
 		//status message callback, called from decomposition thread
 		virtual S32 statusCallback(const char* status, S32 p1, S32 p2) = 0;
 
@@ -160,6 +160,14 @@ class LLPhysicsDecomp : public LLThread
 		virtual void completed() = 0;
 
 		virtual void setStatusMessage(const std::string& msg);
+
+	protected:
+		//internal use
+		LLVector3 mBBox[2] ;
+		F32 mTriangleAreaThreshold ;
+
+		void updateTriangleAreaThreshold() ;
+		bool isValidTriangle(U16 idx1, U16 idx2, U16 idx3) ;
 	};
 
 	LLCondition* mSignal;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index f5fee662e61a3b2f394f8135bf3c677fac09b0e4..e7878d8adfd785dda95ba01d3c8c1be4b5ecc9b3 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -102,6 +102,7 @@
 #include "lltrans.h"
 #include "llsdutil.h"
 #include "llmediaentry.h"
+#include "llaccountingquota.h"
 
 //#define DEBUG_UPDATE_TYPE
 
@@ -5702,3 +5703,10 @@ class ObjectPhysicsProperties : public LLHTTPNode
 
 LLHTTPRegistration<ObjectPhysicsProperties>
 	gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties");
+
+
+void LLViewerObject::updateQuota( const SelectionQuota& quota )
+{
+	//update quotas
+	mSelectionQuota = quota;
+}
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 21198f7dd122f5f4f3a14294317cab052cb5b476..a0ad52df6b9e586cad632680d5b08d51af4effa8 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -43,6 +43,7 @@
 #include "v3dmath.h"
 #include "v3math.h"
 #include "llvertexbuffer.h"
+#include "llaccountingquota.h"
 
 class LLAgent;			// TODO: Get rid of this.
 class LLAudioSource;
@@ -643,7 +644,11 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id);
 	void deleteParticleSource();
 	void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
-
+	
+public:
+	void  updateQuota(  const SelectionQuota& quota );
+	const SelectionQuota& getQuota( void ) { return mSelectionQuota; }
+	
 private:
 	void setNameValueList(const std::string& list);		// clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string
 	void deleteTEImages(); // correctly deletes list of images
@@ -705,6 +710,8 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	F32 mPhysicsCost;
 	F32 mLinksetPhysicsCost;
 
+	SelectionQuota mSelectionQuota;
+	
 	bool mCostStale;
 	mutable bool mPhysicsShapeUnknown;
 
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index ab2e07e4df010b7cc2a9dbe9027dadc8810e567d..007b3416f17a28b04fa67f34e36d8c025b74a0e9 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1418,6 +1418,15 @@ void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id)
 	mPendingObjectCost.erase(object_id);
 }
 
+void LLViewerObjectList::updateQuotaCost( const LLUUID& objectId, const SelectionQuota& quota  )
+{
+	LLViewerObject* pVO = findObject( objectId );
+	if ( pVO )
+	{
+		//pVO->updateQuota( quota );
+	}
+}
+
 void LLViewerObjectList::updatePhysicsFlags(const LLViewerObject* object)
 {
 	mStalePhysicsFlags.insert(object->getID());
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 65374bca70f89f6170abd20c2845ff6f2bbea075..8e211eaf7380cbab38ccd48f60319a91f4a71dce 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -36,6 +36,7 @@
 
 // project includes
 #include "llviewerobject.h"
+#include "llaccountingquota.h"
 
 class LLCamera;
 class LLNetMap;
@@ -101,6 +102,8 @@ class LLViewerObjectList
 									F32 restitution,
 									F32 gravity_multiplier);
 
+	void updateQuotaCost( const LLUUID& objectId, const SelectionQuota& costs );
+	
 	void shiftObjects(const LLVector3 &offset);
 
 	bool hasMapObjectInRegion(LLViewerRegion* regionp) ;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index f835351c04306f7047363afc238be2ee9b25e308..fb608b3a4f0d7ce9e8d17a757ec8c6667b1f213d 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1508,6 +1508,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	capabilityNames.append("LandResources");
 	capabilityNames.append("MapLayer");
 	capabilityNames.append("MapLayerGod");
+	capabilityNames.append("NewAccountingEnabled");
 	capabilityNames.append("NewFileAgentInventory");
 	capabilityNames.append("NewFileAgentInventoryVariablePrice");
 	capabilityNames.append("ObjectAdd");
@@ -1545,6 +1546,10 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	capabilityNames.append("ViewerMetrics");
 	capabilityNames.append("ViewerStartAuction");
 	capabilityNames.append("ViewerStats");
+	//prep# Finalize these!!!!!!!!!
+	capabilityNames.append("AccountingParcel");
+	capabilityNames.append("AccountingSelection");
+	
 	// Please add new capabilities alphabetically to reduce
 	// merge conflicts.
 
@@ -1658,3 +1663,4 @@ std::string LLViewerRegion::getDescription() const
 {
     return stringize(*this);
 }
+
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 9c5b85b77f58a745abfdf757a0770d557ae2865b..a6e5c47b866af8ba36e67eea701e3cd30e3813d1 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -275,6 +275,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	F32 getLandHeightRegion(const LLVector3& region_pos);
 
 	void getInfo(LLSD& info);
+	
 
 	typedef enum
 	{
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index ec2b5a4c9800cc7ac7bd3711bc7984971d04151a..dc355362ce21906d39d524b6d10f98b5036be7d7 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -4968,19 +4968,6 @@ void LLVOAvatar::resetSpecificJointPosition( const std::string& name )
 //-----------------------------------------------------------------------------
 void LLVOAvatar::resetJointPositionsToDefault( void )
 {
-	const LLVector3& avPos = getCharacterPosition();
-	
-	//Reposition the pelvis
-	LLJoint* pPelvis = mRoot.findJoint("mPelvis");
-	if ( pPelvis )
-	{
-		pPelvis->setPosition( avPos + pPelvis->getPosition() );
-	}
-	else 
-	{
-		llwarns<<"Can't get pelvis joint."<<llendl;	
-		return;
-	}
 
 	//Subsequent joints are relative to pelvis
 	for( S32 i = 0; i < (S32)mNumJoints; ++i )
@@ -4991,7 +4978,7 @@ void LLVOAvatar::resetJointPositionsToDefault( void )
 
 			pJoint->setId( LLUUID::null );
 			//restore joints to default positions, however skip over the pelvis
-			if ( pJoint && pPelvis != pJoint )
+			if ( pJoint )
 			{
 				pJoint->restoreOldXform();
 			}
@@ -6028,6 +6015,14 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
 					if ( bindCnt > 0 )
 					{
 						LLVOAvatar::resetJointPositionsToDefault();
+						//Need to handle the repositioning of the cam, updating rig data etc during outfit editing 
+						//This handles the case where we detach a replacement rig.
+						if ( gAgentCamera.cameraCustomizeAvatar() )
+						{
+							gAgent.unpauseAnimation();
+							//Still want to refocus on head bone
+							gAgentCamera.changeCameraToCustomizeAvatar();
+						}
 					}
 				}
 			}