diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 03c9bd4e4fd2a2da577952134b050feecea41244..c84ce12f8029f9f52a62ebf6c0f8f4968047252a 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -419,14 +419,38 @@ void LLFloaterTools::refresh()
 
 	// Refresh object and prim count labels
 	LLLocale locale(LLLocale::USER_LOCALE);
-	
-	F32 obj_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectCost();
-	F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost();
-
-	childSetTextArg("obj_count",  "[COUNT]", llformat("%.1f", obj_cost));	
-	childSetTextArg("prim_count", "[COUNT]", llformat("%.1f", link_cost));
 
-	// calculate selection rendering cost
+	// Get the number of objects selected
+	std::string root_object_count_string;
+	std::string object_count_string;
+
+	LLResMgr::getInstance()->getIntegerString(
+		root_object_count_string,
+		LLSelectMgr::getInstance()->getSelection()->getRootObjectCount());
+	LLResMgr::getInstance()->getIntegerString(
+		object_count_string,
+		LLSelectMgr::getInstance()->getSelection()->getObjectCount());
+
+	F32 obj_cost =
+		LLSelectMgr::getInstance()->getSelection()->getSelectedObjectCost();
+	F32 link_cost =
+		LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost();
+
+	// Update the text for the counts
+	childSetTextArg(
+		"linked_set_count",
+		"[COUNT]",
+		root_object_count_string);
+	childSetTextArg("object_count", "[COUNT]", object_count_string);
+
+	// Update the text for the resource costs
+	childSetTextArg(
+		"linked_set_cost",
+		"[COST]",
+		llformat("%.1f", link_cost));
+	childSetTextArg("object_cost", "[COST]", llformat("%.1f", obj_cost));
+
+	// Display rendering cost if needed
 	if (sShowObjectCost)
 	{
 		std::string prim_cost_string;
@@ -437,8 +461,10 @@ void LLFloaterTools::refresh()
 
 	// disable the object and prim counts if nothing selected
 	bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty();
-	childSetEnabled("obj_count", have_selection);
-	childSetEnabled("prim_count", have_selection);
+	childSetEnabled("linked_set_count", have_selection);
+	childSetEnabled("object_count", have_selection);
+	childSetEnabled("linked_set_cost", have_selection);
+	childSetEnabled("object_cost", have_selection);
 	childSetEnabled("RenderingCost", have_selection && sShowObjectCost);
 
 	// Refresh child tabs
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 6aadf0afd26d89706abe1ade70c946e62d75e45d..42f09f7396b9992fc1bbc1c437dd593f20fdbb3b 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6182,29 +6182,6 @@ S32 LLObjectSelection::getObjectCount(BOOL mesh_adjust)
 	cleanupNodes();
 	S32 count = mList.size();
 
-#if LL_MESH_ENABLED
-	if (mesh_adjust)
-	{
-		for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
-		{
-			LLSelectNode* node = *iter;
-			LLViewerObject* object = node->getObject();
-			
-			if (object && object->getVolume())
-			{
-				LLVOVolume* vobj = (LLVOVolume*) object;
-				if (vobj->isMesh())
-				{
-					LLUUID mesh_id = vobj->getVolume()->getParams().getSculptID();
-					U32 cost = gMeshRepo.getResourceCost(mesh_id);
-					count += cost-1;
-				}
-			}
-
-		}
-	}
-#endif
-
 	return count;
 }
 
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 900aa3ce12ea6e5543a59465ebbd864b0e456bb3..e6f1d8e728f0526b6cb15f884ef203a31f91063a 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -660,17 +660,86 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
 class LLObjectCostResponder : public LLCurl::Responder
 {
 public:
+	LLObjectCostResponder(const LLSD& object_ids)
+		: mObjectIDs(object_ids)
+	{
+	}
+
+	// Clear's the global object list's pending
+	// request list for all objects requested
+	void clear_object_list_pending_requests()
+	{
+		// TODO*: No more hard coding
+		for (
+			LLSD::array_iterator iter = mObjectIDs.beginArray();
+			iter != mObjectIDs.endArray();
+			++iter)
+		{
+			gObjectList.onObjectCostFetchFailure(iter->asUUID());
+		}
+	}
+
+	void error(U32 statusNum, const std::string& reason)
+	{
+		lldebugs
+			<< "Transport error requesting object cost "
+			<< "HTTP status: " << statusNum << ", reason: "
+			<< reason << "." << llendl;
+
+		// TODO*: Error message to user
+		// For now just clear the request from the pending list
+		clear_object_list_pending_requests();
+	}
+
 	void result(const LLSD& content)
 	{
-		for (LLSD::map_const_iterator iter = content.beginMap(); iter != content.endMap(); ++iter)
+		if ( !content.isMap() || content.has("error") )
+		{
+			// Improper response or the request had an error,
+			// show an error to the user?
+			lldebugs
+				<< "Application level error when fetching object "
+				<< "cost.  Message: " << content["error"]["message"].asString()
+				<< ", identifier: " << content["error"]["identifier"].asString()
+				<< llendl;
+
+			// TODO*: Adaptively adjust request size if the
+			// service says we've requested too many and retry
+
+			// TODO*: Error message if not retrying
+			clear_object_list_pending_requests();
+			return;
+		}
+
+		// Success, grab the resource cost and linked set costs
+		// for an object if one was returned
+		for (
+			LLSD::array_iterator iter = mObjectIDs.beginArray();
+			iter != mObjectIDs.endArray();
+			++iter)
 		{
-			LLUUID object_id = LLUUID(iter->first);
-			F32 link_cost = iter->second["LinksetResourceCost"].asReal();
-			F32 prim_cost = iter->second["PrimResourceCost"].asReal();
+			LLUUID object_id = iter->asUUID();
 
-			gObjectList.updateObjectCost(object_id, prim_cost, link_cost);
+			// Check to see if the request contains data for the object
+			if ( content.has(iter->asString()) )
+			{
+				F32 link_cost =
+					content[iter->asString()]["linked_set_resource_cost"].asReal();
+				F32 object_cost =
+					content[iter->asString()]["resource_cost"].asReal();
+
+				gObjectList.updateObjectCost(object_id, object_cost, link_cost);
+			}
+			else
+			{
+				// TODO*: Give user feedback about the missing data?
+				gObjectList.onObjectCostFetchFailure(object_id);
+			}
 		}
 	}
+
+private:
+	LLSD mObjectIDs;
 };
 
 void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
@@ -769,7 +838,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
 		}
 	}
 
-	//issue http request for stale object physics costs
+	// issue http request for stale object physics costs
 	if (!mStaleObjectCost.empty())
 	{
 		LLViewerRegion* regionp = gAgent.getRegion();
@@ -781,21 +850,40 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
 			if (!url.empty())
 			{
 				LLSD id_list;
-				U32 idx = 0;
-				for (std::set<LLUUID>::iterator iter = mStaleObjectCost.begin(); iter != mStaleObjectCost.end(); ++iter)
+				U32 object_index = 0;
+
+				for (
+					std::set<LLUUID>::iterator iter = mStaleObjectCost.begin();
+					iter != mStaleObjectCost.end();
+					++iter)
 				{
-					if (mPendingObjectCost.find(*iter) == mPendingObjectCost.end())
+					// Check to see if a request for this object
+					// has already been made.
+					if ( mPendingObjectCost.find(*iter) ==
+						 mPendingObjectCost.end() )
 					{
+						// Why is this line here if
+						// we set mPendingObjectCost to be
+						// mStaleObjectCost below?
 						mPendingObjectCost.insert(*iter);
-						id_list[idx++] = *iter;
+						id_list[object_index++] = *iter;
 					}
 				}
-				mPendingObjectCost = mStaleObjectCost;
+
+				// id_list should now contain all
+				// requests in mStaleObjectCost before, so clear
+				// it now
 				mStaleObjectCost.clear();
 
-				if (id_list.size() > 0)
+				if ( id_list.size() > 0 )
 				{
-					LLHTTPClient::post(url, id_list, new LLObjectCostResponder());
+					LLSD post_data = LLSD::emptyMap();
+
+					post_data["object_ids"] = id_list;
+					LLHTTPClient::post(
+						url,
+						post_data,
+						new LLObjectCostResponder(id_list));
 				}
 			}
 			else
@@ -1099,18 +1187,23 @@ void LLViewerObjectList::updateObjectCost(LLViewerObject* object)
 	mStaleObjectCost.insert(object->getID());
 }
 
-void LLViewerObjectList::updateObjectCost(LLUUID object_id, F32 prim_cost, F32 link_cost)
+void LLViewerObjectList::updateObjectCost(LLUUID object_id, F32 object_cost, F32 link_cost)
 {
 	mPendingObjectCost.erase(object_id);
 
 	LLViewerObject* object = findObject(object_id);
 	if (object)
 	{
-		object->setObjectCost(prim_cost);
+		object->setObjectCost(object_cost);
 		object->setLinksetCost(link_cost);
 	}
 }
 
+void LLViewerObjectList::onObjectCostFetchFailure(LLUUID object_id)
+{
+	mPendingObjectCost.erase(object_id);
+}
+
 void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
 {
 	// This is called when we shift our origin when we cross region boundaries...
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 4064a68eb21004fb17b5b7a516a9f3c5bb54deb2..0f58e543ac081760944d239197036a839abda984 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -92,7 +92,8 @@ class LLViewerObjectList
 	void update(LLAgent &agent, LLWorld &world);
 
 	void updateObjectCost(LLViewerObject* object);
-	void updateObjectCost(LLUUID object_id, F32 prim_cost, F32 link_cost);
+	void updateObjectCost(LLUUID object_id, F32 object_cost, F32 link_cost);
+	void onObjectCostFetchFailure(LLUUID object_id);
 
 	void shiftObjects(const LLVector3 &offset);
 
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index b0e8f29a0a061474567691391a30f361e41d0149..bbb90eba6e07ae1df2b445892a876d0fb7062a85 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -730,11 +730,25 @@
      follows="left|top"
      halign="right"
      layout="topleft"
-     right="-10"
-     name="obj_count"
+     right="-100"
+     name="linked_set_count"
      top_pad="5"
-     width="143">
-        Objects: [COUNT]
+     width="80">
+        Linked Sets: [COUNT]
+    </text>
+    <text
+    text_color="LtGray_50"
+     type="string"
+     length="1"
+     height="10"
+     follows="left"
+     halign="right"
+     layout="topleft"
+	 top_delta="0"
+     right="-10"
+     name="linked_set_cost"
+     width="80">
+        Cost: [COST]
     </text>
     <text
     text_color="LtGray_50"
@@ -743,11 +757,51 @@
      follows="left|top"
      halign="right"
      layout="topleft"
+	 top_pad="5"
+     right="-100"
+     name="object_count"
+     width="80">
+        Objects: [COUNT]
+    </text>
+    <text
+    text_color="LtGray_50"
+     type="string"
+     length="1"
+     follows="left"
+     halign="right"
+     layout="topleft"
+	 top_delta="0"
      right="-10"
-     name="prim_count"
-     width="143">
-        Prims: [COUNT]
+     name="object_cost"
+     width="80">
+        Cost: [COST]
     </text>
+    <!-- <text -->
+    <!-- text_color="LtGray_50" -->
+    <!--  type="string" -->
+    <!--  length="1" -->
+    <!--  height="10" -->
+    <!--  follows="left|top" -->
+    <!--  halign="right" -->
+    <!--  layout="topleft" -->
+    <!--  right="-10" -->
+    <!--  name="obj_count" -->
+    <!--  top_pad="5" -->
+    <!--  width="143"> -->
+    <!--     Objects: [COUNT] -->
+    <!-- </text> -->
+    <!-- <text -->
+    <!-- text_color="LtGray_50" -->
+    <!--  type="string" -->
+    <!--  length="1" -->
+    <!--  follows="left|top" -->
+    <!--  halign="right" -->
+    <!--  layout="topleft" -->
+    <!--  right="-10" -->
+    <!--  name="prim_count" -->
+    <!--  width="143"> -->
+    <!--     Prims: [COUNT] -->
+    <!-- </text> -->
     <tab_container
      follows="left|top"
      height="610"