diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 500163c030adad9e20d66023aa31150b1f128f4b..dad8e8e97ab342d84538f7b64d44bfa2c4b38c99 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -417,6 +417,7 @@ set(viewer_SOURCE_FILES
     llparticipantlist.cpp
     llpatchvertexarray.cpp
     llpathfindingcharacter.cpp
+    llpathfindingcharacterlist.cpp
     llpathfindinglinkset.cpp
     llpathfindinglinksetlist.cpp
     llpathfindingmanager.cpp
@@ -973,6 +974,7 @@ set(viewer_HEADER_FILES
     llparticipantlist.h
     llpatchvertexarray.h
     llpathfindingcharacter.h
+    llpathfindingcharacterlist.h
     llpathfindinglinkset.h
     llpathfindinglinksetlist.h
     llpathfindingmanager.h
diff --git a/indra/newview/llfloaterpathfindingcharacters.cpp b/indra/newview/llfloaterpathfindingcharacters.cpp
index fd84af74e1196da547bd49f9bb0a5fc3706f8f51..d174d822cd1a572a29c9fa135fefbdde809248a0 100644
--- a/indra/newview/llfloaterpathfindingcharacters.cpp
+++ b/indra/newview/llfloaterpathfindingcharacters.cpp
@@ -1,7 +1,7 @@
 /** 
  * @file llfloaterpathfindingcharacters.cpp
  * @author William Todd Stinson
- * @brief "Pathfinding linksets" floater, allowing manipulation of the Havok AI pathfinding settings.
+ * @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage.
  *
  * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -28,7 +28,7 @@
 #include "llviewerprecompiledheaders.h"
 #include "llfloater.h"
 #include "llfloaterpathfindingcharacters.h"
-#include "llpathfindingcharacter.h"
+#include "llpathfindingcharacterlist.h"
 #include "llsd.h"
 #include "llagent.h"
 #include "llhandle.h"
@@ -48,37 +48,12 @@
 #include "llviewermenu.h"
 #include "llselectmgr.h"
 
-//---------------------------------------------------------------------------
-// CharactersGetResponder
-//---------------------------------------------------------------------------
-
-class CharactersGetResponder : public LLHTTPClient::Responder
-{
-public:
-	CharactersGetResponder(const std::string& pCharactersDataGetURL,
-		const LLHandle<LLFloaterPathfindingCharacters> &pCharactersFloaterHandle);
-	virtual ~CharactersGetResponder();
-
-	virtual void result(const LLSD& pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
-
-private:
-	CharactersGetResponder(const CharactersGetResponder& pOther);
-
-	std::string                              mCharactersDataGetURL;
-	LLHandle<LLFloaterPathfindingCharacters> mCharactersFloaterHandle;
-};
-
 //---------------------------------------------------------------------------
 // LLFloaterPathfindingCharacters
 //---------------------------------------------------------------------------
 
 BOOL LLFloaterPathfindingCharacters::postBuild()
 {
-	childSetAction("refresh_characters_list", boost::bind(&LLFloaterPathfindingCharacters::onRefreshCharactersClicked, this));
-	childSetAction("select_all_characters", boost::bind(&LLFloaterPathfindingCharacters::onSelectAllCharactersClicked, this));
-	childSetAction("select_none_characters", boost::bind(&LLFloaterPathfindingCharacters::onSelectNoneCharactersClicked, this));
-
 	mCharactersScrollList = findChild<LLScrollListCtrl>("pathfinding_characters");
 	llassert(mCharactersScrollList != NULL);
 	mCharactersScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onCharactersSelectionChange, this));
@@ -87,82 +62,73 @@ BOOL LLFloaterPathfindingCharacters::postBuild()
 	mCharactersStatus = findChild<LLTextBase>("characters_status");
 	llassert(mCharactersStatus != NULL);
 
-	mLabelActions = findChild<LLTextBase>("actions_label");
-	llassert(mLabelActions != NULL);
+	mRefreshListButton = findChild<LLButton>("refresh_characters_list");
+	llassert(mRefreshListButton != NULL);
+	mRefreshListButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onRefreshCharactersClicked, this));
+
+	mSelectAllButton = findChild<LLButton>("select_all_characters");
+	llassert(mSelectAllButton != NULL);
+	mSelectAllButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onSelectAllCharactersClicked, this));
+
+	mSelectNoneButton = findChild<LLButton>("select_none_characters");
+	llassert(mSelectNoneButton != NULL);
+	mSelectNoneButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onSelectNoneCharactersClicked, this));
 
 	mShowBeaconCheckBox = findChild<LLCheckBoxCtrl>("show_beacon");
 	llassert(mShowBeaconCheckBox != NULL);
 
-	mTakeBtn = findChild<LLButton>("take_characters");
-	llassert(mTakeBtn != NULL)
-	mTakeBtn->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCharactersClicked, this));
-
-	mTakeCopyBtn = findChild<LLButton>("take_copy_characters");
-	llassert(mTakeCopyBtn != NULL)
-	mTakeCopyBtn->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCopyCharactersClicked, this));
+	mTakeButton = findChild<LLButton>("take_characters");
+	llassert(mTakeButton != NULL)
+	mTakeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCharactersClicked, this));
 
-	mReturnBtn = findChild<LLButton>("return_characters");
-	llassert(mReturnBtn != NULL)
-	mReturnBtn->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onReturnCharactersClicked, this));
+	mTakeCopyButton = findChild<LLButton>("take_copy_characters");
+	llassert(mTakeCopyButton != NULL)
+	mTakeCopyButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCopyCharactersClicked, this));
 
-	mDeleteBtn = findChild<LLButton>("delete_characters");
-	llassert(mDeleteBtn != NULL)
-	mDeleteBtn->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onDeleteCharactersClicked, this));
+	mReturnButton = findChild<LLButton>("return_characters");
+	llassert(mReturnButton != NULL)
+	mReturnButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onReturnCharactersClicked, this));
 
-	mTeleportBtn = findChild<LLButton>("teleport_to_character");
-	llassert(mTeleportBtn != NULL)
-	mTeleportBtn->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked, this));
+	mDeleteButton = findChild<LLButton>("delete_characters");
+	llassert(mDeleteButton != NULL)
+	mDeleteButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onDeleteCharactersClicked, this));
 
-	setEnableActionFields(false);
-	setMessagingState(kMessagingInitial);
+	mTeleportButton = findChild<LLButton>("teleport_to_character");
+	llassert(mTeleportButton != NULL)
+	mTeleportButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked, this));
 
 	return LLFloater::postBuild();
 }
 
 void LLFloaterPathfindingCharacters::onOpen(const LLSD& pKey)
 {
-	sendCharactersDataGetRequest();
+	LLFloater::onOpen(pKey);
+
+	requestGetCharacters();
 	selectNoneCharacters();
+	mCharactersScrollList->setCommitOnSelectionChange(true);
 
 	if (!mSelectionUpdateSlot.connected())
 	{
-		mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingCharacters::updateActionFields, this));
+		mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingCharacters::updateControls, this));
 	}
-
-	mCharactersScrollList->setCommitOnSelectionChange(true);
 }
 
-void LLFloaterPathfindingCharacters::onClose(bool app_quitting)
+void LLFloaterPathfindingCharacters::onClose(bool pAppQuitting)
 {
-	mCharactersScrollList->setCommitOnSelectionChange(false);
-
 	if (mSelectionUpdateSlot.connected())
 	{
 		mSelectionUpdateSlot.disconnect();
 	}
 
+	mCharactersScrollList->setCommitOnSelectionChange(false);
 	selectNoneCharacters();
 	if (mCharacterSelection.notNull())
 	{
-		std::vector<LLViewerObject *> selectedObjects;
-
-		LLObjectSelection *charactersSelected = mCharacterSelection.get();
-		for (LLObjectSelection::valid_iterator characterIter = charactersSelected->valid_begin();
-			characterIter != charactersSelected->valid_end();  ++characterIter)
-		{
-			LLSelectNode *characterNode = *characterIter;
-			selectedObjects.push_back(characterNode->getObject());
-		}
-
-		for (std::vector<LLViewerObject *>::const_iterator selectedObjectIter = selectedObjects.begin();
-			selectedObjectIter != selectedObjects.end(); ++selectedObjectIter)
-		{
-			LLViewerObject *selectedObject = *selectedObjectIter;
-			LLSelectMgr::getInstance()->deselectObjectAndFamily(selectedObject);
-		}
-
 		mCharacterSelection.clear();
 	}
+
+	LLFloater::onClose(pAppQuitting);
 }
 
 void LLFloaterPathfindingCharacters::draw()
@@ -208,141 +174,88 @@ LLFloaterPathfindingCharacters::EMessagingState LLFloaterPathfindingCharacters::
 
 BOOL LLFloaterPathfindingCharacters::isMessagingInProgress() const
 {
-	BOOL retVal;
-	switch (getMessagingState())
-	{
-	case kMessagingFetchStarting :
-	case kMessagingFetchRequestSent :
-	case kMessagingFetchRequestSent_MultiRequested :
-	case kMessagingFetchReceived :
-		retVal = true;
-		break;
-	default :
-		retVal = false;
-		break;
-	}
-
-	return retVal;
+	return (mMessagingState == kMessagingGetRequestSent);
 }
 
 LLFloaterPathfindingCharacters::LLFloaterPathfindingCharacters(const LLSD& pSeed)
 	: LLFloater(pSeed),
-	mSelfHandle(),
-	mPathfindingCharacters(),
-	mMessagingState(kMessagingInitial),
 	mCharactersScrollList(NULL),
 	mCharactersStatus(NULL),
-	mLabelActions(NULL),
+	mRefreshListButton(NULL),
+	mSelectAllButton(NULL),
+	mSelectNoneButton(NULL),
 	mShowBeaconCheckBox(NULL),
-	mTakeBtn(NULL),
-	mTakeCopyBtn(NULL),
-	mReturnBtn(NULL),
-	mDeleteBtn(NULL),
-	mTeleportBtn(NULL),
+	mTakeButton(NULL),
+	mTakeCopyButton(NULL),
+	mReturnButton(NULL),
+	mDeleteButton(NULL),
+	mTeleportButton(NULL),
+	mMessagingState(kMessagingUnknown),
+	mCharacterListPtr(),
 	mCharacterSelection(),
 	mSelectionUpdateSlot()
 {
-	mSelfHandle.bind(this);
 }
 
 LLFloaterPathfindingCharacters::~LLFloaterPathfindingCharacters()
 {
-	mPathfindingCharacters.clear();
-	mCharacterSelection.clear();
-}
-
-void LLFloaterPathfindingCharacters::sendCharactersDataGetRequest()
-{
-	if (isMessagingInProgress())
-	{
-		if (getMessagingState() == kMessagingFetchRequestSent)
-		{
-			setMessagingState(kMessagingFetchRequestSent_MultiRequested);
-		}
-	}
-	else
-	{
-		setMessagingState(kMessagingFetchStarting);
-		mPathfindingCharacters.clear();
-		updateCharactersList();
-
-		std::string charactersDataURL = getCapabilityURL();
-		if (charactersDataURL.empty())
-		{
-			setMessagingState(kMessagingServiceNotAvailable);
-			llwarns << "cannot query pathfinding characters from current region '" << getRegionName() << "'" << llendl;
-		}
-		else
-		{
-			setMessagingState(kMessagingFetchRequestSent);
-			LLHTTPClient::get(charactersDataURL, new CharactersGetResponder(charactersDataURL, mSelfHandle));
-		}
-	}
-}
-
-void LLFloaterPathfindingCharacters::handleCharactersDataGetReply(const LLSD& pCharactersData)
-{
-	setMessagingState(kMessagingFetchReceived);
-	mPathfindingCharacters.clear();
-	parseCharactersData(pCharactersData);
-	updateCharactersList();
-	setMessagingState(kMessagingComplete);
 }
 
-void LLFloaterPathfindingCharacters::handleCharactersDataGetError(const std::string& pURL, const std::string& pErrorReason)
+void LLFloaterPathfindingCharacters::setMessagingState(EMessagingState pMessagingState)
 {
-	setMessagingState(kMessagingFetchError);
-	mPathfindingCharacters.clear();
-	updateCharactersList();
-	llwarns << "Error fetching pathfinding characters from URL '" << pURL << "' because " << pErrorReason << llendl;
+	mMessagingState = pMessagingState;
+	updateControls();
 }
 
-std::string LLFloaterPathfindingCharacters::getRegionName() const
+void LLFloaterPathfindingCharacters::requestGetCharacters()
 {
-	std::string regionName("");
-
-	LLViewerRegion* region = gAgent.getRegion();
-	if (region != NULL)
+	llassert(!isMessagingInProgress());
+	if (!isMessagingInProgress())
 	{
-		regionName = region->getName();
+		switch (LLPathfindingManager::getInstance()->requestGetCharacters(boost::bind(&LLFloaterPathfindingCharacters::handleNewCharacters, this, _1, _2)))
+		{
+		case LLPathfindingManager::kRequestStarted :
+			setMessagingState(kMessagingGetRequestSent);
+			break;
+		case LLPathfindingManager::kRequestCompleted :
+			clearCharacters();
+			setMessagingState(kMessagingComplete);
+			break;
+		case LLPathfindingManager::kRequestNotEnabled :
+			clearCharacters();
+			setMessagingState(kMessagingNotEnabled);
+			break;
+		case LLPathfindingManager::kRequestError :
+			setMessagingState(kMessagingGetError);
+			break;
+		default :
+			setMessagingState(kMessagingGetError);
+			llassert(0);
+			break;
+		}
 	}
-
-	return regionName;
 }
 
-std::string LLFloaterPathfindingCharacters::getCapabilityURL() const
+void LLFloaterPathfindingCharacters::handleNewCharacters(LLPathfindingManager::ERequestStatus pCharacterRequestStatus, LLPathfindingCharacterListPtr pCharacterListPtr)
 {
-	std::string charactersDataURL("");
-
-	LLViewerRegion* region = gAgent.getRegion();
-	if (region != NULL)
-	{
-		charactersDataURL = region->getCapability("CharacterProperties");
-	}
-
-	return charactersDataURL;
-}
+	mCharacterListPtr = pCharacterListPtr;
+	updateScrollList();
 
-void LLFloaterPathfindingCharacters::parseCharactersData(const LLSD &pCharactersData)
-{
-	for (LLSD::map_const_iterator characterItemIter = pCharactersData.beginMap();
-		characterItemIter != pCharactersData.endMap(); ++characterItemIter)
+	switch (pCharacterRequestStatus)
 	{
-		const std::string &uuid(characterItemIter->first);
-		const LLSD &characterData(characterItemIter->second);
-		LLPathfindingCharacter character(uuid, characterData);
-
-		mPathfindingCharacters.insert(std::pair<std::string, LLPathfindingCharacter>(uuid, character));
+	case LLPathfindingManager::kRequestCompleted :
+		setMessagingState(kMessagingComplete);
+		break;
+	case LLPathfindingManager::kRequestError :
+		setMessagingState(kMessagingGetError);
+		break;
+	default :
+		setMessagingState(kMessagingGetError);
+		llassert(0);
+		break;
 	}
 }
 
-void LLFloaterPathfindingCharacters::setMessagingState(EMessagingState pMessagingState)
-{
-	mMessagingState = pMessagingState;
-	updateCharactersList();
-	updateActionFields();
-}
-
 void LLFloaterPathfindingCharacters::onCharactersSelectionChange()
 {
 	mCharacterSelection.clear();
@@ -374,13 +287,12 @@ void LLFloaterPathfindingCharacters::onCharactersSelectionChange()
 		}
 	}
 
-	updateCharactersStatusMessage();
-	updateActionFields();
+	updateControls();
 }
 
 void LLFloaterPathfindingCharacters::onRefreshCharactersClicked()
 {
-	sendCharactersDataGetRequest();
+	requestGetCharacters();
 }
 
 void LLFloaterPathfindingCharacters::onSelectAllCharactersClicked()
@@ -421,9 +333,9 @@ void LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked()
 	{
 		std::vector<LLScrollListItem*>::const_reference selectedItemRef = selectedItems.front();
 		const LLScrollListItem *selectedItem = selectedItemRef;
-		PathfindingCharacterMap::const_iterator characterIter = mPathfindingCharacters.find(selectedItem->getUUID().asString());
-		const LLPathfindingCharacter &character = characterIter->second;
-		LLVector3 characterLocation = character.getLocation();
+		LLPathfindingCharacterList::const_iterator characterIter = mCharacterListPtr->find(selectedItem->getUUID().asString());
+		const LLPathfindingCharacterPtr &characterPtr = characterIter->second;
+		const LLVector3 &characterLocation = characterPtr->getLocation();
 
 		LLViewerRegion* region = gAgent.getRegion();
 		if (region != NULL)
@@ -433,7 +345,33 @@ void LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked()
 	}
 }
 
-void LLFloaterPathfindingCharacters::updateCharactersList()
+void LLFloaterPathfindingCharacters::selectAllCharacters()
+{
+	mCharactersScrollList->selectAll();
+}
+
+void LLFloaterPathfindingCharacters::selectNoneCharacters()
+{
+	mCharactersScrollList->deselectAllItems();
+}
+
+void LLFloaterPathfindingCharacters::clearCharacters()
+{
+	if (mCharacterListPtr != NULL)
+	{
+		mCharacterListPtr->clear();
+	}
+	updateScrollList();
+}
+
+void LLFloaterPathfindingCharacters::updateControls()
+{
+	updateStatusMessage();
+	updateEnableStateOnListActions();
+	updateEnableStateOnEditFields();
+}
+
+void LLFloaterPathfindingCharacters::updateScrollList()
 {
 	std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected();
 	int numSelectedItems = selectedItems.size();
@@ -449,65 +387,62 @@ void LLFloaterPathfindingCharacters::updateCharactersList()
 		}
 	}
 
+	S32 origScrollPosition = mCharactersScrollList->getScrollPos();
 	mCharactersScrollList->deleteAllItems();
-	updateCharactersStatusMessage();
 
-	LLLocale locale(LLStringUtil::getLocale());
-	for (PathfindingCharacterMap::const_iterator characterIter = mPathfindingCharacters.begin();
-		characterIter != mPathfindingCharacters.end(); ++characterIter)
+	if (mCharacterListPtr != NULL)
 	{
-		const LLPathfindingCharacter& character(characterIter->second);
-
-		LLSD columns;
-
-		columns[0]["column"] = "name";
-		columns[0]["value"] = character.getName();
-		columns[0]["font"] = "SANSSERIF";
+		for (LLPathfindingCharacterList::const_iterator characterIter = mCharacterListPtr->begin();
+			characterIter != mCharacterListPtr->end(); ++characterIter)
+		{
+			const LLPathfindingCharacterPtr& character(characterIter->second);
+			LLSD element = buildCharacterScrollListElement(character);
+			mCharactersScrollList->addElement(element);
+		}
+	}
 
-		columns[1]["column"] = "description";
-		columns[1]["value"] = character.getDescription();
-		columns[1]["font"] = "SANSSERIF";
+	mCharactersScrollList->selectMultiple(selectedUUIDs);
+	mCharactersScrollList->setScrollPos(origScrollPosition);
+	updateControls();
+}
 
-		columns[2]["column"] = "owner";
-		columns[2]["value"] = character.getOwnerName();
-		columns[2]["font"] = "SANSSERIF";
+LLSD LLFloaterPathfindingCharacters::buildCharacterScrollListElement(const LLPathfindingCharacterPtr pCharacterPtr) const
+{
+	LLSD columns;
 
-		S32 cpuTime = llround(character.getCPUTime());
-		std::string cpuTimeString = llformat("%d", cpuTime);
-		LLStringUtil::format_map_t string_args;
-		string_args["[CPU_TIME]"] = cpuTimeString;
+	columns[0]["column"] = "name";
+	columns[0]["value"] = pCharacterPtr->getName();
+	columns[0]["font"] = "SANSSERIF";
 
-		columns[3]["column"] = "cpu_time";
-		columns[3]["value"] = getString("character_cpu_time", string_args);
-		columns[3]["font"] = "SANSSERIF";
+	columns[1]["column"] = "description";
+	columns[1]["value"] = pCharacterPtr->getDescription();
+	columns[1]["font"] = "SANSSERIF";
 
-		columns[4]["column"] = "altitude";
-		columns[4]["value"] = llformat("%1.0f m", character.getLocation()[2]);
-		columns[4]["font"] = "SANSSERIF";
+	columns[2]["column"] = "owner";
+	columns[2]["value"] = pCharacterPtr->getOwnerName();
+	columns[2]["font"] = "SANSSERIF";
 
-		LLSD element;
-		element["id"] = character.getUUID().asString();
-		element["column"] = columns;
+	S32 cpuTime = llround(pCharacterPtr->getCPUTime());
+	std::string cpuTimeString = llformat("%d", cpuTime);
+	LLStringUtil::format_map_t string_args;
+	string_args["[CPU_TIME]"] = cpuTimeString;
 
-		mCharactersScrollList->addElement(element);
-	}
+	columns[3]["column"] = "cpu_time";
+	columns[3]["value"] = getString("character_cpu_time", string_args);
+	columns[3]["font"] = "SANSSERIF";
 
-	mCharactersScrollList->selectMultiple(selectedUUIDs);
-	updateCharactersStatusMessage();
-	updateActionFields();
-}
+	columns[4]["column"] = "altitude";
+	columns[4]["value"] = llformat("%1.0f m", pCharacterPtr->getLocation()[2]);
+	columns[4]["font"] = "SANSSERIF";
 
-void LLFloaterPathfindingCharacters::selectAllCharacters()
-{
-	mCharactersScrollList->selectAll();
-}
+	LLSD element;
+	element["id"] = pCharacterPtr->getUUID().asString();
+	element["column"] = columns;
 
-void LLFloaterPathfindingCharacters::selectNoneCharacters()
-{
-	mCharactersScrollList->deselectAllItems();
+	return element;
 }
 
-void LLFloaterPathfindingCharacters::updateCharactersStatusMessage()
+void LLFloaterPathfindingCharacters::updateStatusMessage()
 {
 	static const LLColor4 warningColor = LLUIColorTable::instance().getColor("DrYellow");
 
@@ -516,23 +451,14 @@ void LLFloaterPathfindingCharacters::updateCharactersStatusMessage()
 
 	switch (getMessagingState())
 	{
-	case kMessagingInitial:
+	case kMessagingUnknown:
 		statusText = getString("characters_messaging_initial");
 		break;
-	case kMessagingFetchStarting :
-		statusText = getString("characters_messaging_fetch_starting");
-		break;
-	case kMessagingFetchRequestSent :
-		statusText = getString("characters_messaging_fetch_inprogress");
+	case kMessagingGetRequestSent :
+		statusText = getString("characters_messaging_get_inprogress");
 		break;
-	case kMessagingFetchRequestSent_MultiRequested :
-		statusText = getString("characters_messaging_fetch_inprogress_multi_request");
-		break;
-	case kMessagingFetchReceived :
-		statusText = getString("characters_messaging_fetch_received");
-		break;
-	case kMessagingFetchError :
-		statusText = getString("characters_messaging_fetch_error");
+	case kMessagingGetError :
+		statusText = getString("characters_messaging_get_error");
 		styleParams.color = warningColor;
 		break;
 	case kMessagingComplete :
@@ -558,8 +484,8 @@ void LLFloaterPathfindingCharacters::updateCharactersStatusMessage()
 			statusText = getString("characters_messaging_complete_available", string_args);
 		}
 		break;
-	case kMessagingServiceNotAvailable:
-		statusText = getString("characters_messaging_service_not_available");
+	case kMessagingNotEnabled:
+		statusText = getString("characters_messaging_not_enabled");
 		styleParams.color = warningColor;
 		break;
 	default:
@@ -571,52 +497,46 @@ void LLFloaterPathfindingCharacters::updateCharactersStatusMessage()
 	mCharactersStatus->setText((LLStringExplicit)statusText, styleParams);
 }
 
-void LLFloaterPathfindingCharacters::updateActionFields()
-{
-	std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected();
-	setEnableActionFields(!selectedItems.empty());
-}
-
-void LLFloaterPathfindingCharacters::setEnableActionFields(BOOL pEnabled)
-{
-	mLabelActions->setEnabled(pEnabled);
-	mShowBeaconCheckBox->setEnabled(pEnabled);
-	mTakeBtn->setEnabled(pEnabled && visible_take_object());
-	mTakeCopyBtn->setEnabled(pEnabled && enable_object_take_copy());
-	mReturnBtn->setEnabled(pEnabled && enable_object_return());
-	mDeleteBtn->setEnabled(pEnabled && enable_object_delete());
-	mTeleportBtn->setEnabled(pEnabled && (mCharactersScrollList->getNumSelected() == 1));
-}
-
-//---------------------------------------------------------------------------
-// CharactersGetResponder
-//---------------------------------------------------------------------------
-
-CharactersGetResponder::CharactersGetResponder(const std::string& pCharactersDataGetURL,
-	const LLHandle<LLFloaterPathfindingCharacters> &pCharactersFloaterHandle)
-	: mCharactersDataGetURL(pCharactersDataGetURL),
-	mCharactersFloaterHandle(pCharactersFloaterHandle)
-{
-}
-
-CharactersGetResponder::~CharactersGetResponder()
-{
-}
-
-void CharactersGetResponder::result(const LLSD& pContent)
+void LLFloaterPathfindingCharacters::updateEnableStateOnListActions()
 {
-	LLFloaterPathfindingCharacters *charactersFloater = mCharactersFloaterHandle.get();
-	if (charactersFloater != NULL)
+	switch (getMessagingState())
 	{
-		charactersFloater->handleCharactersDataGetReply(pContent);
+	case kMessagingUnknown:
+	case kMessagingGetRequestSent :
+		mRefreshListButton->setEnabled(FALSE);
+		mSelectAllButton->setEnabled(FALSE);
+		mSelectNoneButton->setEnabled(FALSE);
+		break;
+	case kMessagingGetError :
+	case kMessagingNotEnabled :
+		mRefreshListButton->setEnabled(TRUE);
+		mSelectAllButton->setEnabled(FALSE);
+		mSelectNoneButton->setEnabled(FALSE);
+		break;
+	case kMessagingComplete :
+		{
+			int numItems = mCharactersScrollList->getItemCount();
+			int numSelectedItems = mCharactersScrollList->getNumSelected();
+			mRefreshListButton->setEnabled(TRUE);
+			mSelectAllButton->setEnabled(numSelectedItems < numItems);
+			mSelectNoneButton->setEnabled(numSelectedItems > 0);
+		}
+		break;
+	default:
+		llassert(0);
+		break;
 	}
 }
 
-void CharactersGetResponder::error(U32 status, const std::string& reason)
+void LLFloaterPathfindingCharacters::updateEnableStateOnEditFields()
 {
-	LLFloaterPathfindingCharacters *charactersFloater = mCharactersFloaterHandle.get();
-	if (charactersFloater != NULL)
-	{
-		charactersFloater->handleCharactersDataGetError(mCharactersDataGetURL, reason);
-	}
+	int numSelectedItems = mCharactersScrollList->getNumSelected();
+	bool isEditEnabled = (numSelectedItems > 0);
+
+	mShowBeaconCheckBox->setEnabled(isEditEnabled);
+	mTakeButton->setEnabled(isEditEnabled && visible_take_object());
+	mTakeCopyButton->setEnabled(isEditEnabled && enable_object_take_copy());
+	mReturnButton->setEnabled(isEditEnabled && enable_object_return());
+	mDeleteButton->setEnabled(isEditEnabled && enable_object_delete());
+	mTeleportButton->setEnabled(numSelectedItems == 1);
 }
diff --git a/indra/newview/llfloaterpathfindingcharacters.h b/indra/newview/llfloaterpathfindingcharacters.h
index c381492784ba7bdc8068025c1fdfbf376dd991e9..a242a5503fab3e932ac7602e9c169fe1e77bb21c 100644
--- a/indra/newview/llfloaterpathfindingcharacters.h
+++ b/indra/newview/llfloaterpathfindingcharacters.h
@@ -1,29 +1,29 @@
 /** 
- * @file llfloaterpathfindingcharacters.h
- * @author William Todd Stinson
- * @brief "Pathfinding linksets" floater, allowing manipulation of the Havok AI pathfinding settings.
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
+* @file llfloaterpathfindingcharacters.h
+* @author William Todd Stinson
+* @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage.
+*
+* $LicenseInfo:firstyear=2002&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+* 
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
 
 #ifndef LL_LLFLOATERPATHFINDINGCHARACTERS_H
 #define LL_LLFLOATERPATHFINDINGCHARACTERS_H
@@ -31,9 +31,10 @@
 #include <string>
 #include <map>
 
-#include "llhandle.h"
 #include "llfloater.h"
 #include "llpathfindingcharacter.h"
+#include "llpathfindingcharacterlist.h"
+#include "llpathfindingmanager.h"
 #include "llselectmgr.h"
 
 #include <boost/signals2.hpp>
@@ -46,27 +47,23 @@ class LLRadioGroup;
 class LLButton;
 
 class LLFloaterPathfindingCharacters
-:	public LLFloater
+	:	public LLFloater
 {
 	friend class LLFloaterReg;
-	friend class CharactersGetResponder;
 
 public:
 	typedef enum
 	{
-		kMessagingInitial,
-		kMessagingFetchStarting,
-		kMessagingFetchRequestSent,
-		kMessagingFetchRequestSent_MultiRequested,
-		kMessagingFetchReceived,
-		kMessagingFetchError,
+		kMessagingUnknown,
+		kMessagingGetRequestSent,
+		kMessagingGetError,
 		kMessagingComplete,
-		kMessagingServiceNotAvailable
+		kMessagingNotEnabled
 	} EMessagingState;
 
 	virtual BOOL postBuild();
 	virtual void onOpen(const LLSD& pKey);
-	virtual void onClose(bool app_quitting);
+	virtual void onClose(bool pAppQuitting);
 	virtual void draw();
 
 	static void openCharactersViewer();
@@ -77,38 +74,31 @@ class LLFloaterPathfindingCharacters
 protected:
 
 private:
-	typedef std::map<std::string, LLPathfindingCharacter> PathfindingCharacterMap;
-
-	LLRootHandle<LLFloaterPathfindingCharacters> mSelfHandle;
-	PathfindingCharacterMap                      mPathfindingCharacters;
-	EMessagingState                              mMessagingState;
-	LLScrollListCtrl                             *mCharactersScrollList;
-	LLTextBase                                   *mCharactersStatus;
-	LLTextBase                                   *mLabelActions;
-	LLCheckBoxCtrl                               *mShowBeaconCheckBox;
-	LLButton                                     *mTakeBtn;
-	LLButton                                     *mTakeCopyBtn;
-	LLButton                                     *mReturnBtn;
-	LLButton                                     *mDeleteBtn;
-	LLButton                                     *mTeleportBtn;
-	LLObjectSelectionHandle                      mCharacterSelection;
-	boost::signals2::connection                  mSelectionUpdateSlot;
+	LLScrollListCtrl *mCharactersScrollList;
+	LLTextBase       *mCharactersStatus;
+	LLButton         *mRefreshListButton;
+	LLButton         *mSelectAllButton;
+	LLButton         *mSelectNoneButton;
+	LLCheckBoxCtrl   *mShowBeaconCheckBox;
+	LLButton         *mTakeButton;
+	LLButton         *mTakeCopyButton;
+	LLButton         *mReturnButton;
+	LLButton         *mDeleteButton;
+	LLButton         *mTeleportButton;
+
+	EMessagingState               mMessagingState;
+	LLPathfindingCharacterListPtr mCharacterListPtr;
+	LLObjectSelectionHandle       mCharacterSelection;
+	boost::signals2::connection   mSelectionUpdateSlot;
 
 	// Does its own instance management, so clients not allowed
 	// to allocate or destroy.
 	LLFloaterPathfindingCharacters(const LLSD& pSeed);
 	virtual ~LLFloaterPathfindingCharacters();
 
-	void sendCharactersDataGetRequest();
-	void handleCharactersDataGetReply(const LLSD& pCharactersData);
-	void handleCharactersDataGetError(const std::string& pURL, const std::string& pErrorReason);
-
-	std::string getRegionName() const;
-	std::string getCapabilityURL() const;
-
-	void parseCharactersData(const LLSD &pCharactersData);
-
 	void setMessagingState(EMessagingState pMessagingState);
+	void requestGetCharacters();
+	void handleNewCharacters(LLPathfindingManager::ERequestStatus pCharacterRequestStatus, LLPathfindingCharacterListPtr pCharacterListPtr);
 
 	void onCharactersSelectionChange();
 	void onRefreshCharactersClicked();
@@ -120,14 +110,17 @@ class LLFloaterPathfindingCharacters
 	void onDeleteCharactersClicked();
 	void onTeleportCharacterToMeClicked();
 
-	void updateCharactersList();
 	void selectAllCharacters();
 	void selectNoneCharacters();
+	void clearCharacters();
 
-	void updateCharactersStatusMessage();
+	void updateControls();
+	void updateScrollList();
+	LLSD buildCharacterScrollListElement(const LLPathfindingCharacterPtr pCharacterPtr) const;
 
-	void updateActionFields();
-	void setEnableActionFields(BOOL pEnabled);
+	void updateStatusMessage();
+	void updateEnableStateOnListActions();
+	void updateEnableStateOnEditFields();
 };
 
 #endif // LL_LLFLOATERPATHFINDINGCHARACTERS_H
diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp
index 42a8f4e95108d55b9e520dc8ed854eddfe804d03..547db078b16de45c86fc114ac6fb4827708b477b 100644
--- a/indra/newview/llfloaterpathfindinglinksets.cpp
+++ b/indra/newview/llfloaterpathfindinglinksets.cpp
@@ -1,29 +1,29 @@
 /** 
- * @file llfloaterpathfindinglinksets.cpp
- * @author William Todd Stinson
- * @brief "Pathfinding linksets" floater, allowing manipulation of the Havok AI pathfinding settings.
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
+* @file llfloaterpathfindinglinksets.cpp
+* @author William Todd Stinson
+* @brief "Pathfinding linksets" floater, allowing manipulation of the Havok AI pathfinding settings.
+*
+* $LicenseInfo:firstyear=2002&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+* 
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
 
 #include "llviewerprecompiledheaders.h"
 #include "llfloater.h"
@@ -339,18 +339,18 @@ void LLFloaterPathfindingLinksets::requestGetLinksets()
 	{
 		switch (LLPathfindingManager::getInstance()->requestGetLinksets(boost::bind(&LLFloaterPathfindingLinksets::handleNewLinksets, this, _1, _2)))
 		{
-		case LLPathfindingManager::kLinksetsRequestStarted :
+		case LLPathfindingManager::kRequestStarted :
 			setMessagingState(kMessagingGetRequestSent);
 			break;
-		case LLPathfindingManager::kLinksetsRequestCompleted :
+		case LLPathfindingManager::kRequestCompleted :
 			clearLinksets();
 			setMessagingState(kMessagingComplete);
 			break;
-		case LLPathfindingManager::kLinksetsRequestNotEnabled :
+		case LLPathfindingManager::kRequestNotEnabled :
 			clearLinksets();
 			setMessagingState(kMessagingNotEnabled);
 			break;
-		case LLPathfindingManager::kLinksetsRequestError :
+		case LLPathfindingManager::kRequestError :
 			setMessagingState(kMessagingGetError);
 			break;
 		default :
@@ -368,17 +368,17 @@ void LLFloaterPathfindingLinksets::requestSetLinksets(LLPathfindingLinksetListPt
 	{
 		switch (LLPathfindingManager::getInstance()->requestSetLinksets(pLinksetList, pLinksetUse, pA, pB, pC, pD, boost::bind(&LLFloaterPathfindingLinksets::handleUpdateLinksets, this, _1, _2)))
 		{
-		case LLPathfindingManager::kLinksetsRequestStarted :
+		case LLPathfindingManager::kRequestStarted :
 			setMessagingState(kMessagingSetRequestSent);
 			break;
-		case LLPathfindingManager::kLinksetsRequestCompleted :
+		case LLPathfindingManager::kRequestCompleted :
 			setMessagingState(kMessagingComplete);
 			break;
-		case LLPathfindingManager::kLinksetsRequestNotEnabled :
+		case LLPathfindingManager::kRequestNotEnabled :
 			clearLinksets();
 			setMessagingState(kMessagingNotEnabled);
 			break;
-		case LLPathfindingManager::kLinksetsRequestError :
+		case LLPathfindingManager::kRequestError :
 			setMessagingState(kMessagingSetError);
 			break;
 		default :
@@ -389,17 +389,17 @@ void LLFloaterPathfindingLinksets::requestSetLinksets(LLPathfindingLinksetListPt
 	}
 }
 
-void LLFloaterPathfindingLinksets::handleNewLinksets(LLPathfindingManager::ELinksetsRequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr)
+void LLFloaterPathfindingLinksets::handleNewLinksets(LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr)
 {
 	mLinksetsListPtr = pLinksetsListPtr;
 	updateScrollList();
 
 	switch (pLinksetsRequestStatus)
 	{
-	case LLPathfindingManager::kLinksetsRequestCompleted :
+	case LLPathfindingManager::kRequestCompleted :
 		setMessagingState(kMessagingComplete);
 		break;
-	case LLPathfindingManager::kLinksetsRequestError :
+	case LLPathfindingManager::kRequestError :
 		setMessagingState(kMessagingGetError);
 		break;
 	default :
@@ -409,7 +409,7 @@ void LLFloaterPathfindingLinksets::handleNewLinksets(LLPathfindingManager::ELink
 	}
 }
 
-void LLFloaterPathfindingLinksets::handleUpdateLinksets(LLPathfindingManager::ELinksetsRequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr)
+void LLFloaterPathfindingLinksets::handleUpdateLinksets(LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr)
 {
 	if (mLinksetsListPtr == NULL)
 	{
@@ -423,10 +423,10 @@ void LLFloaterPathfindingLinksets::handleUpdateLinksets(LLPathfindingManager::EL
 
 	switch (pLinksetsRequestStatus)
 	{
-	case LLPathfindingManager::kLinksetsRequestCompleted :
+	case LLPathfindingManager::kRequestCompleted :
 		setMessagingState(kMessagingComplete);
 		break;
-	case LLPathfindingManager::kLinksetsRequestError :
+	case LLPathfindingManager::kRequestError :
 		setMessagingState(kMessagingSetError);
 		break;
 	default :
@@ -702,21 +702,21 @@ void LLFloaterPathfindingLinksets::updateScrollList()
 LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListElement(const LLPathfindingLinksetPtr pLinksetPtr, const LLVector3 &pAvatarPosition) const
 {
 	LLSD columns;
-	
+
 	if (pLinksetPtr->isTerrain())
 	{
 		columns[0]["column"] = "name";
 		columns[0]["value"] = getString("linkset_terrain_name");
 		columns[0]["font"] = "SANSSERIF";
-		
+
 		columns[1]["column"] = "description";
 		columns[1]["value"] = getString("linkset_terrain_description");
 		columns[1]["font"] = "SANSSERIF";
-		
+
 		columns[2]["column"] = "land_impact";
 		columns[2]["value"] = getString("linkset_terrain_land_impact");
 		columns[2]["font"] = "SANSSERIF";
-		
+
 		columns[3]["column"] = "dist_from_you";
 		columns[3]["value"] = getString("linkset_terrain_dist_from_you");
 		columns[3]["font"] = "SANSSERIF";
@@ -726,15 +726,15 @@ LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListElement(const LLPathfin
 		columns[0]["column"] = "name";
 		columns[0]["value"] = pLinksetPtr->getName();
 		columns[0]["font"] = "SANSSERIF";
-		
+
 		columns[1]["column"] = "description";
 		columns[1]["value"] = pLinksetPtr->getDescription();
 		columns[1]["font"] = "SANSSERIF";
-		
+
 		columns[2]["column"] = "land_impact";
 		columns[2]["value"] = llformat("%1d", pLinksetPtr->getLandImpact());
 		columns[2]["font"] = "SANSSERIF";
-		
+
 		columns[3]["column"] = "dist_from_you";
 		columns[3]["value"] = llformat("%1.0f m", dist_vec(pAvatarPosition, pLinksetPtr->getLocation()));
 		columns[3]["font"] = "SANSSERIF";
@@ -787,12 +787,12 @@ LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListElement(const LLPathfin
 LLSD LLFloaterPathfindingLinksets::buildLinksetUseScrollListElement(const std::string &label, S32 value) const
 {
 	LLSD columns;
-	
+
 	columns[0]["column"] = "name";
 	columns[0]["relwidth"] = static_cast<LLSD::Real>(100.0f);
 	columns[0]["value"] = label;
 	columns[0]["font"] = "SANSSERIF";
-		
+
 	LLSD element;
 	element["value"] = value;
 	element["column"] = columns;
@@ -1172,7 +1172,7 @@ void LLFloaterPathfindingLinksets::setEditLinksetUse(LLPathfindingLinkset::ELink
 LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::convertToLinksetUse(LLSD pXuiValue) const
 {
 	LLPathfindingLinkset::ELinksetUse linkUse;
-	
+
 	switch (pXuiValue.asInteger())
 	{
 	case XUI_LINKSET_USE_NONE :
diff --git a/indra/newview/llfloaterpathfindinglinksets.h b/indra/newview/llfloaterpathfindinglinksets.h
index fdc47e3d400c766e8e9a54910a01ad8d5fe6f173..0cf9b2162b0e9da321f33cdc1584c7628db10155 100644
--- a/indra/newview/llfloaterpathfindinglinksets.h
+++ b/indra/newview/llfloaterpathfindinglinksets.h
@@ -124,8 +124,8 @@ class LLFloaterPathfindingLinksets
 	void setMessagingState(EMessagingState pMessagingState);
 	void requestGetLinksets();
 	void requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD);
-	void handleNewLinksets(LLPathfindingManager::ELinksetsRequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr);
-	void handleUpdateLinksets(LLPathfindingManager::ELinksetsRequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr);
+	void handleNewLinksets(LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr);
+	void handleUpdateLinksets(LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr);
 
 	void onApplyAllFilters();
 	void onClearFiltersClicked();
diff --git a/indra/newview/llpathfindingcharacter.cpp b/indra/newview/llpathfindingcharacter.cpp
index afa07457bc92f2367b83aa5153ca9545f0d3f4d0..4600f661f8617393efdf8ab38d1c5b9c5e95e35e 100644
--- a/indra/newview/llpathfindingcharacter.cpp
+++ b/indra/newview/llpathfindingcharacter.cpp
@@ -33,11 +33,11 @@
 #include "llavatarname.h"
 #include "llavatarnamecache.h"
 
-#define CHARACTER_NAME_FIELD          "name"
-#define CHARACTER_DESCRIPTION_FIELD   "description"
-#define CHARACTER_OWNER_FIELD         "owner"
-#define CHARACTER_CPU_TIME_FIELD      "cpu_time"
-#define CHARACTER_POSITION_FIELD      "position"
+#define CHARACTER_NAME_FIELD        "name"
+#define CHARACTER_DESCRIPTION_FIELD "description"
+#define CHARACTER_OWNER_FIELD       "owner"
+#define CHARACTER_CPU_TIME_FIELD    "cpu_time"
+#define CHARACTER_POSITION_FIELD    "position"
 
 //---------------------------------------------------------------------------
 // LLPathfindingCharacter
@@ -50,7 +50,7 @@ LLPathfindingCharacter::LLPathfindingCharacter(const std::string &pUUID, const L
 	mOwnerUUID(),
 	mOwnerName(),
 	mCPUTime(0U),
-	mLocation()
+	mLocation(LLVector3::zero)
 {
 	llassert(pCharacterItem.has(CHARACTER_NAME_FIELD));
 	llassert(pCharacterItem.get(CHARACTER_NAME_FIELD).isString());
diff --git a/indra/newview/llpathfindingcharacter.h b/indra/newview/llpathfindingcharacter.h
index 9b0a7bae30964c0457e58ba1b9cf3511bc617df0..5be52ebc4576171d067327e78cf91076e667c583 100644
--- a/indra/newview/llpathfindingcharacter.h
+++ b/indra/newview/llpathfindingcharacter.h
@@ -32,8 +32,12 @@
 #include "lluuid.h"
 #include "llavatarname.h"
 
+#include <boost/shared_ptr.hpp>
+
 class LLSD;
-class LLAvatarName;
+class LLPathfindingCharacter;
+
+typedef boost::shared_ptr<LLPathfindingCharacter> LLPathfindingCharacterPtr;
 
 class LLPathfindingCharacter
 {
@@ -44,12 +48,12 @@ class LLPathfindingCharacter
 
 	LLPathfindingCharacter& operator = (const LLPathfindingCharacter& pOther);
 
-	inline const LLUUID&      getUUID() const                     {return mUUID;};
-	inline const std::string& getName() const                     {return mName;};
-	inline const std::string& getDescription() const              {return mDescription;};
-	inline const std::string  getOwnerName() const                {return mOwnerName.getCompleteName();};
-	inline F32                getCPUTime() const                  {return mCPUTime;};
-	inline const LLVector3&   getLocation() const                 {return mLocation;};
+	inline const LLUUID&      getUUID() const        {return mUUID;};
+	inline const std::string& getName() const        {return mName;};
+	inline const std::string& getDescription() const {return mDescription;};
+	inline const std::string  getOwnerName() const   {return mOwnerName.getCompleteName();};
+	inline F32                getCPUTime() const     {return mCPUTime;};
+	inline const LLVector3&   getLocation() const    {return mLocation;};
 
 protected:
 
diff --git a/indra/newview/llpathfindingcharacterlist.cpp b/indra/newview/llpathfindingcharacterlist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..64fddd490cbc75c0a7031960e1d0b5de335527cb
--- /dev/null
+++ b/indra/newview/llpathfindingcharacterlist.cpp
@@ -0,0 +1,63 @@
+/** 
+ * @file llpathfindingcharacterlist.cpp
+ * @author William Todd Stinson
+ * @brief Class to implement the list of a set of pathfinding characters
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include <string>
+#include <map>
+
+#include "llsd.h"
+#include "lluuid.h"
+#include "llpathfindingcharacter.h"
+#include "llpathfindingcharacterlist.h"
+
+//---------------------------------------------------------------------------
+// LLPathfindingCharacterList
+//---------------------------------------------------------------------------
+
+LLPathfindingCharacterList::LLPathfindingCharacterList()
+	: LLPathfindingCharacterMap()
+{
+}
+
+LLPathfindingCharacterList::LLPathfindingCharacterList(const LLSD& pCharacterItems)
+	: LLPathfindingCharacterMap()
+{
+	for (LLSD::map_const_iterator characterItemIter = pCharacterItems.beginMap();
+		characterItemIter != pCharacterItems.endMap(); ++characterItemIter)
+	{
+		const std::string& uuid(characterItemIter->first);
+		const LLSD& characterData = characterItemIter->second;
+		LLPathfindingCharacterPtr character(new LLPathfindingCharacter(uuid, characterData));
+		insert(std::pair<std::string, LLPathfindingCharacterPtr>(uuid, character));
+	}
+}
+
+LLPathfindingCharacterList::~LLPathfindingCharacterList()
+{
+	clear();
+}
diff --git a/indra/newview/llpathfindingcharacterlist.h b/indra/newview/llpathfindingcharacterlist.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce6ec816159bfa1b3734c50542723b6de2650a7d
--- /dev/null
+++ b/indra/newview/llpathfindingcharacterlist.h
@@ -0,0 +1,56 @@
+/** 
+ * @file llpathfindingcharacterlist.h
+ * @author William Todd Stinson
+ * @brief Class to implement the list of a set of pathfinding characters
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPATHFINDINGCHARACTERLIST_H
+#define LL_LLPATHFINDINGCHARACTERLIST_H
+
+#include <string>
+#include <map>
+#include "llpathfindingcharacter.h"
+
+#include <boost/shared_ptr.hpp>
+
+class LLSD;
+class LLPathfindingCharacterList;
+
+typedef boost::shared_ptr<LLPathfindingCharacterList> LLPathfindingCharacterListPtr;
+typedef std::map<std::string, LLPathfindingCharacterPtr> LLPathfindingCharacterMap;
+
+class LLPathfindingCharacterList : public LLPathfindingCharacterMap
+{
+public:
+	LLPathfindingCharacterList();
+	LLPathfindingCharacterList(const LLSD& pCharacterItems);
+	virtual ~LLPathfindingCharacterList();
+
+protected:
+
+private:
+
+};
+
+#endif // LL_LLPATHFINDINGCHARACTERLIST_H
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index e3242de8129840b2379edd23a517c6ab934ffbd5..fdff380050ca33f607eccbcdcddf98443a2e021f 100644
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -40,6 +40,7 @@
 #include "llpathfindingnavmeshstatus.h"
 #include "llpathfindinglinkset.h"
 #include "llpathfindinglinksetlist.h"
+#include "llpathfindingcharacterlist.h"
 #include "llhttpnode.h"
 
 #include <boost/function.hpp>
@@ -56,6 +57,8 @@
 #define CAP_SERVICE_OBJECT_LINKSETS  "ObjectNavMeshProperties"
 #define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties"
 
+#define CAP_SERVICE_CHARACTERS  "CharacterProperties"
+
 #define SIM_MESSAGE_NAVMESH_STATUS_UPDATE "/message/NavMeshStatusUpdate"
 #define SIM_MESSAGE_AGENT_STATE_UPDATE    "/message/AgentPreferencesUpdate"
 #define SIM_MESSAGE_BODY_FIELD            "body"
@@ -225,6 +228,26 @@ class TerrainLinksetsResponder : public LLHTTPClient::Responder
 	LinksetsResponderPtr mLinksetsResponsderPtr;
 };
 
+//---------------------------------------------------------------------------
+// CharactersResponder
+//---------------------------------------------------------------------------
+
+class CharactersResponder : public LLHTTPClient::Responder
+{
+public:
+	CharactersResponder(const std::string &pCapabilityURL, LLPathfindingManager::characters_callback_t pCharactersCallback);
+	virtual ~CharactersResponder();
+	
+	virtual void result(const LLSD &pContent);
+	virtual void error(U32 pStatus, const std::string &pReason);
+	
+protected:
+	
+private:
+	std::string                                 mCapabilityURL;
+	LLPathfindingManager::characters_callback_t mCharactersCallback;
+};
+
 //---------------------------------------------------------------------------
 // LLPathfindingManager
 //---------------------------------------------------------------------------
@@ -311,41 +334,6 @@ void LLPathfindingManager::requestGetNavMeshForRegion(LLViewerRegion *pRegion)
 	}
 }
 
-void LLPathfindingManager::handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion)
-{
-	LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID());
-
-	if (!pNavMeshStatus.isValid())
-	{
-		navMeshPtr->handleNavMeshError();
-	}
-	else
-	{
-		if (navMeshPtr->hasNavMeshVersion(pNavMeshStatus))
-		{
-			navMeshPtr->handleRefresh(pNavMeshStatus);
-		}
-		else
-		{
-			sendRequestGetNavMeshForRegion(navMeshPtr, pRegion, pNavMeshStatus);
-		}
-	}
-}
-
-void LLPathfindingManager::handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus)
-{
-	LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID());
-
-	if (!pNavMeshStatus.isValid())
-	{
-		navMeshPtr->handleNavMeshError();
-	}
-	else
-	{
-		navMeshPtr->handleNavMeshNewVersion(pNavMeshStatus);
-	}
-}
-
 LLPathfindingManager::agent_state_slot_t LLPathfindingManager::registerAgentStateListener(agent_state_callback_t pAgentStateCallback)
 {
 	return mAgentStateSignal.connect(pAgentStateCallback);
@@ -395,15 +383,15 @@ void LLPathfindingManager::requestSetAgentState(EAgentState pRequestedAgentState
 	}
 }
 
-LLPathfindingManager::ELinksetsRequestStatus LLPathfindingManager::requestGetLinksets(linksets_callback_t pLinksetsCallback) const
+LLPathfindingManager::ERequestStatus LLPathfindingManager::requestGetLinksets(linksets_callback_t pLinksetsCallback) const
 {
-	ELinksetsRequestStatus status;
+	ERequestStatus status;
 
 	std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion();
 	std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
 	if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
 	{
-		status = kLinksetsRequestNotEnabled;
+		status = kRequestNotEnabled;
 	}
 	else
 	{
@@ -419,21 +407,21 @@ LLPathfindingManager::ELinksetsRequestStatus LLPathfindingManager::requestGetLin
 			LLHTTPClient::get(terrainLinksetsURL, terrainLinksetsResponder);
 		}
 
-		status = kLinksetsRequestStarted;
+		status = kRequestStarted;
 	}
 
 	return status;
 }
 
-LLPathfindingManager::ELinksetsRequestStatus LLPathfindingManager::requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, linksets_callback_t pLinksetsCallback) const
+LLPathfindingManager::ERequestStatus LLPathfindingManager::requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, linksets_callback_t pLinksetsCallback) const
 {
-	ELinksetsRequestStatus status = kLinksetsRequestNotEnabled;
+	ERequestStatus status = kRequestNotEnabled;
 
 	std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion();
 	std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
 	if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
 	{
-		status = kLinksetsRequestNotEnabled;
+		status = kRequestNotEnabled;
 	}
 	else
 	{
@@ -446,7 +434,7 @@ LLPathfindingManager::ELinksetsRequestStatus LLPathfindingManager::requestSetLin
 
 		if (objectPostData.isUndefined() && terrainPostData.isUndefined())
 		{
-			status = kLinksetsRequestCompleted;
+			status = kRequestCompleted;
 		}
 		else
 		{
@@ -464,13 +452,33 @@ LLPathfindingManager::ELinksetsRequestStatus LLPathfindingManager::requestSetLin
 				LLHTTPClient::put(terrainLinksetsURL, terrainPostData, terrainLinksetsResponder);
 			}
 
-			status = kLinksetsRequestStarted;
+			status = kRequestStarted;
 		}
 	}
 
 	return status;
 }
 
+LLPathfindingManager::ERequestStatus LLPathfindingManager::requestGetCharacters(characters_callback_t pCharactersCallback) const
+{
+	ERequestStatus status;
+
+	std::string charactersURL = getCharactersURLForCurrentRegion();
+	if (charactersURL.empty())
+	{
+		status = kRequestNotEnabled;
+	}
+	else
+	{
+		LLHTTPClient::ResponderPtr charactersResponder = new CharactersResponder(charactersURL, pCharactersCallback);
+		LLHTTPClient::get(charactersURL, charactersResponder);
+
+		status = kRequestStarted;
+	}
+
+	return status;
+}
+
 void LLPathfindingManager::sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPtr navMeshPtr, LLViewerRegion *pRegion, const LLPathfindingNavMeshStatus &pNavMeshStatus)
 {
 	if ((pRegion == NULL) || !pRegion->isAlive())
@@ -496,6 +504,41 @@ void LLPathfindingManager::sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPt
 	}
 }
 
+void LLPathfindingManager::handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion)
+{
+	LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID());
+
+	if (!pNavMeshStatus.isValid())
+	{
+		navMeshPtr->handleNavMeshError();
+	}
+	else
+	{
+		if (navMeshPtr->hasNavMeshVersion(pNavMeshStatus))
+		{
+			navMeshPtr->handleRefresh(pNavMeshStatus);
+		}
+		else
+		{
+			sendRequestGetNavMeshForRegion(navMeshPtr, pRegion, pNavMeshStatus);
+		}
+	}
+}
+
+void LLPathfindingManager::handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+	LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID());
+
+	if (!pNavMeshStatus.isValid())
+	{
+		navMeshPtr->handleNavMeshError();
+	}
+	else
+	{
+		navMeshPtr->handleNavMeshNewVersion(pNavMeshStatus);
+	}
+}
+
 LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(const LLUUID &pRegionUUID)
 {
 	LLPathfindingNavMeshPtr navMeshPtr;
@@ -626,6 +669,11 @@ std::string LLPathfindingManager::getTerrainLinksetsURLForCurrentRegion() const
 	return getCapabilityURLForCurrentRegion(CAP_SERVICE_TERRAIN_LINKSETS);
 }
 
+std::string LLPathfindingManager::getCharactersURLForCurrentRegion() const
+{
+	return getCapabilityURLForCurrentRegion(CAP_SERVICE_CHARACTERS);
+}
+
 std::string LLPathfindingManager::getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const
 {
 	return getCapabilityURLForRegion(getCurrentRegion(), pCapabilityName);
@@ -688,7 +736,8 @@ void LLAgentStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, c
 //---------------------------------------------------------------------------
 
 NavMeshStatusResponder::NavMeshStatusResponder(const std::string &pCapabilityURL, LLViewerRegion *pRegion)
-	: mCapabilityURL(pCapabilityURL),
+	: LLHTTPClient::Responder(),
+	mCapabilityURL(pCapabilityURL),
 	mRegion(pRegion),
 	mRegionUUID()
 {
@@ -723,7 +772,8 @@ void NavMeshStatusResponder::error(U32 pStatus, const std::string& pReason)
 //---------------------------------------------------------------------------
 
 NavMeshResponder::NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr)
-	: mCapabilityURL(pCapabilityURL),
+	: LLHTTPClient::Responder(),
+	mCapabilityURL(pCapabilityURL),
 	mNavMeshVersion(pNavMeshVersion),
 	mNavMeshPtr(pNavMeshPtr)
 {
@@ -830,10 +880,10 @@ void LinksetsResponder::sendCallback()
 {
 	llassert(mObjectMessagingState != kWaiting);
 	llassert(mTerrainMessagingState != kWaiting);
-	LLPathfindingManager::ELinksetsRequestStatus requestStatus =
+	LLPathfindingManager::ERequestStatus requestStatus =
 		((((mObjectMessagingState == kReceivedGood) || (mObjectMessagingState == kNotRequested)) &&
 		  ((mTerrainMessagingState == kReceivedGood) || (mTerrainMessagingState == kNotRequested))) ?
-		 LLPathfindingManager::kLinksetsRequestCompleted : LLPathfindingManager::kLinksetsRequestError);
+		 LLPathfindingManager::kRequestCompleted : LLPathfindingManager::kRequestError);
 
 	if (mObjectMessagingState != kReceivedGood)
 	{
@@ -853,7 +903,8 @@ void LinksetsResponder::sendCallback()
 //---------------------------------------------------------------------------
 
 ObjectLinksetsResponder::ObjectLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr)
-	: mCapabilityURL(pCapabilityURL),
+	: LLHTTPClient::Responder(),
+	mCapabilityURL(pCapabilityURL),
 	mLinksetsResponsderPtr(pLinksetsResponsderPtr)
 {
 }
@@ -877,8 +928,9 @@ void ObjectLinksetsResponder::error(U32 pStatus, const std::string &pReason)
 //---------------------------------------------------------------------------
 
 TerrainLinksetsResponder::TerrainLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr)
-: mCapabilityURL(pCapabilityURL),
-mLinksetsResponsderPtr(pLinksetsResponsderPtr)
+	: LLHTTPClient::Responder(),
+	mCapabilityURL(pCapabilityURL),
+	mLinksetsResponsderPtr(pLinksetsResponsderPtr)
 {
 }
 
@@ -895,3 +947,32 @@ void TerrainLinksetsResponder::error(U32 pStatus, const std::string &pReason)
 {
 	mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, mCapabilityURL);
 }
+	
+//---------------------------------------------------------------------------
+// CharactersResponder
+//---------------------------------------------------------------------------
+
+CharactersResponder::CharactersResponder(const std::string &pCapabilityURL, LLPathfindingManager::characters_callback_t pCharactersCallback)
+	: LLHTTPClient::Responder(),
+	mCapabilityURL(pCapabilityURL),
+	mCharactersCallback(pCharactersCallback)
+{
+}
+
+CharactersResponder::~CharactersResponder()
+{
+}
+
+void CharactersResponder::result(const LLSD &pContent)
+{
+	LLPathfindingCharacterListPtr characterListPtr = LLPathfindingCharacterListPtr(new LLPathfindingCharacterList(pContent));
+	mCharactersCallback(LLPathfindingManager::kRequestCompleted, characterListPtr);
+}
+
+void CharactersResponder::error(U32 pStatus, const std::string &pReason)
+{
+	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+
+	LLPathfindingCharacterListPtr characterListPtr;
+	mCharactersCallback(LLPathfindingManager::kRequestError, characterListPtr);
+}
diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h
index b458d6513ab97bd93f238a299dfb363e2acd394b..d906a94d44a39aba03dd4ba5605a77c803edd38a 100644
--- a/indra/newview/llpathfindingmanager.h
+++ b/indra/newview/llpathfindingmanager.h
@@ -33,6 +33,7 @@
 #include "llpathfindingnavmesh.h"
 #include "llpathfindinglinkset.h"
 #include "llpathfindinglinksetlist.h"
+#include "llpathfindingcharacterlist.h"
 
 #include <string>
 #include <map>
@@ -46,8 +47,10 @@ class LLPathfindingNavMeshStatus;
 
 class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 {
-	friend class AgentStateResponder;
+	friend class LLNavMeshSimStateChangeNode;
 	friend class LLAgentStateChangeNode;
+	friend class NavMeshStatusResponder;
+	friend class AgentStateResponder;
 public:
 	typedef std::map<LLUUID, LLPathfindingNavMeshPtr> NavMeshMap;
 
@@ -64,13 +67,14 @@ class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 	typedef boost::signals2::connection                 agent_state_slot_t;
 
 	typedef enum {
-		kLinksetsRequestStarted,
-		kLinksetsRequestCompleted,
-		kLinksetsRequestNotEnabled,
-		kLinksetsRequestError
-	} ELinksetsRequestStatus;
+		kRequestStarted,
+		kRequestCompleted,
+		kRequestNotEnabled,
+		kRequestError
+	} ERequestStatus;
 
-	typedef boost::function<void (ELinksetsRequestStatus, LLPathfindingLinksetListPtr)> linksets_callback_t;
+	typedef boost::function<void (ERequestStatus, LLPathfindingLinksetListPtr)>   linksets_callback_t;
+	typedef boost::function<void (ERequestStatus, LLPathfindingCharacterListPtr)> characters_callback_t;
 
 	LLPathfindingManager();
 	virtual ~LLPathfindingManager();
@@ -87,22 +91,24 @@ class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 	LLPathfindingNavMesh::navmesh_slot_t registerNavMeshListenerForRegion(LLViewerRegion *pRegion, LLPathfindingNavMesh::navmesh_callback_t pNavMeshCallback);
 	void requestGetNavMeshForRegion(LLViewerRegion *pRegion);
 
-	void handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion);
-	void handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus);
-
 	agent_state_slot_t registerAgentStateListener(agent_state_callback_t pAgentStateCallback);
 	EAgentState        getAgentState();
 	EAgentState        getLastKnownNonErrorAgentState() const;
 	void               requestSetAgentState(EAgentState pAgentState);
 
-	ELinksetsRequestStatus requestGetLinksets(linksets_callback_t pLinksetsCallback) const;
-	ELinksetsRequestStatus requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, linksets_callback_t pLinksetsCallback) const;
+	ERequestStatus requestGetLinksets(linksets_callback_t pLinksetsCallback) const;
+	ERequestStatus requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, linksets_callback_t pLinksetsCallback) const;
+
+	ERequestStatus requestGetCharacters(characters_callback_t pCharactersCallback) const;
 
 protected:
 
 private:
 	void sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPtr navMeshPtr, LLViewerRegion *pRegion, const LLPathfindingNavMeshStatus &pNavMeshStatus);
 
+	void handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion);
+	void handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus);
+
 	LLPathfindingNavMeshPtr getNavMeshForRegion(const LLUUID &pRegionUUID);
 	LLPathfindingNavMeshPtr getNavMeshForRegion(LLViewerRegion *pRegion);
 
@@ -119,6 +125,7 @@ class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 	std::string getAgentStateURLForCurrentRegion() const;
 	std::string getObjectLinksetsURLForCurrentRegion() const;
 	std::string getTerrainLinksetsURLForCurrentRegion() const;
+	std::string getCharactersURLForCurrentRegion() const;
 
 	std::string    getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const;
 	std::string    getCapabilityURLForRegion(LLViewerRegion *pRegion, const std::string &pCapabilityName) const;
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml
index e9d58c7a337b1d4365abad3c462ca51ace152733..f643913b6d2d2f86f0d72425de0f5919757015e2 100644
--- a/indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml
@@ -15,165 +15,180 @@
     single_instance="true"
     title="Pathfinding characters">
   <floater.string name="characters_messaging_initial"></floater.string>
-  <floater.string name="characters_messaging_fetch_starting">Building query for pathfinding characters ...</floater.string>
-  <floater.string name="characters_messaging_fetch_inprogress">Querying for pathfinding characters ...</floater.string>
-  <floater.string name="characters_messaging_fetch_inprogress_multi_request">Querying for pathfinding characters (already in progress) ...</floater.string>
-  <floater.string name="characters_messaging_fetch_received">Loading pathfinding characters data from response ...</floater.string>
-  <floater.string name="characters_messaging_fetch_error">Error detected while querying for pathfinding characters</floater.string>
-  <floater.string name="characters_messaging_complete_none_found">No pathfinding characters</floater.string>
-  <floater.string name="characters_messaging_complete_available">[NUM_SELECTED] characters selected out of [NUM_TOTAL]</floater.string>
-  <floater.string name="characters_messaging_service_not_available">Required capability is not available in current region</floater.string>
+  <floater.string name="characters_messaging_get_inprogress">Querying for pathfinding characters ...</floater.string>
+  <floater.string name="characters_messaging_get_error">Error detected while querying for pathfinding characters.</floater.string>
+  <floater.string name="characters_messaging_complete_none_found">No pathfinding characters.</floater.string>
+  <floater.string name="characters_messaging_complete_available">[NUM_SELECTED] characters selected out of [NUM_TOTAL].</floater.string>
+  <floater.string name="characters_messaging_not_enabled">This region is not enabled for pathfinding.</floater.string>
   <floater.string name="character_cpu_time">[CPU_TIME] µs</floater.string>
-  <scroll_list
-      column_padding="0"
-      draw_heading="true"
-      follows="all"
-      height="135"
-      layout="topleft"
-      left="18"
-      top="10"
-      multi_select="true"
-      name="pathfinding_characters"
-      width="600">
-    <scroll_list.columns
-        label="Name"
-        name="name"
-        dynamic_width="true" />
-    <scroll_list.columns
-        label="Description"
-        name="description"
-        width="172" />
-    <scroll_list.columns
-        label="Owner"
-        name="owner"
-        width="141" />
-    <scroll_list.columns
-        label="CPU"
-        name="cpu_time"
-        width="60" />
-    <scroll_list.columns
-        label="Altitude"
-        name="altitude"
-        width="64" />
-  </scroll_list>
-  <text
-      height="26"
-      word_wrap="true"
-      use_ellipses="false"
-      type="string"
-      text_color="LabelTextColor"
-      length="1"
-      follows="left|bottom"
-      layout="topleft"
-      name="characters_status"
-      top="161"
-      width="240">
-    Characters:
-  </text>
-  <button
-      follows="right|bottom"
-      height="21"
-      label="Refresh list"
-      layout="topleft"
-      name="refresh_characters_list"
-      top="161"
-      left="257"
-      width="115"/>
-  <button
-      follows="right|bottom"
-      height="21"
-      label="Select all"
-      layout="topleft"
-      name="select_all_characters"
-      top="161"
-      left="378"
-      width="115"/>
-  <button
-      follows="right|bottom"
-      height="21"
-      label="Select none"
+  <panel
+      border="false"
+      bevel_style="none"
+      follows="left|top|right|bottom"
       layout="topleft"
-      name="select_none_characters"
-      top="161"
-      left="502"
-      width="115"/>
+      height="191"
+      width="635">
+    <scroll_list
+        column_padding="0"
+        draw_heading="true"
+        follows="all"
+        height="135"
+        layout="topleft"
+        left="18"
+        top_pad="10"
+        multi_select="true"
+        name="pathfinding_characters"
+        width="600">
+      <scroll_list.columns
+          label="Name"
+          name="name"
+          dynamic_width="true" />
+      <scroll_list.columns
+          label="Description"
+          name="description"
+          width="172" />
+      <scroll_list.columns
+          label="Owner"
+          name="owner"
+          width="141" />
+      <scroll_list.columns
+          label="CPU"
+          name="cpu_time"
+          width="60" />
+      <scroll_list.columns
+          label="Altitude"
+          name="altitude"
+          width="64" />
+    </scroll_list>
+    <text
+        height="26"
+        word_wrap="true"
+        use_ellipses="false"
+        type="string"
+        text_color="LabelTextColor"
+        length="1"
+        follows="left|bottom|right"
+        layout="topleft"
+        name="characters_status"
+        top_pad="17"
+        width="238">
+      Characters:
+    </text>
+    <button
+        follows="right|bottom"
+        height="21"
+        label="Refresh list"
+        layout="topleft"
+        name="refresh_characters_list"
+        top_pad="-29"
+        left_pad="0"
+        width="115"/>
+    <button
+        follows="right|bottom"
+        height="21"
+        label="Select all"
+        layout="topleft"
+        name="select_all_characters"
+        top_pad="-21"
+        left_pad="8"
+        width="115"/>
+    <button
+        follows="right|bottom"
+        height="21"
+        label="Select none"
+        layout="topleft"
+        name="select_none_characters"
+        top_pad="-21"
+        left_pad="8"
+        width="115"/>
+  </panel>
   <view_border
       bevel_style="none"
       follows="left|right|bottom"
       height="0"
       layout="topleft"
       name="horiz_separator"
-      top="196"
-      left="20"
+      top_pad="0"
+      left="18"
       width="600"/>
-  <text
-      height="13"
-      word_wrap="false"
-      use_ellipses="false"
-      type="string"
-      text_color="LabelTextColor"
-      text_readonly_color="LabelDisabledColor"
-      length="1"
-      follows="left|bottom"
-      layout="topleft"
-      name="actions_label"
-      top_pad="12"
-      width="242">
-    Actions on selected characters:
-  </text>
-  <check_box
-      height="19"
-      follows="left|bottom"
-      label="Show beacon"
-      layout="topleft"
-      name="show_beacon"
-      top="208"
-      left="259"
-      width="90" />
-  <button
-      follows="left|bottom"
-      height="22"
-      label="Take"
-      layout="topleft"
-      name="take_characters"
-      top="232"
-      left="17"
-      width="94"/>
-  <button
-      follows="left|bottom"
-      height="22"
-      label="Take copy"
-      layout="topleft"
-      name="take_copy_characters"
-      top="232"
-      left="119"
-      width="94"/>
-  <button
-      follows="left|bottom"
-      height="22"
-      label="Return"
-      layout="topleft"
-      name="return_characters"
-      top="233"
-      left="220"
-      width="94"/>
-  <button
-      follows="left|bottom"
-      height="22"
-      label="Delete"
-      layout="topleft"
-      name="delete_characters"
-      top="233"
-      left="322"
-      width="94"/>
-  <button
-      follows="left|bottom"
-      height="22"
-      label="Teleport me to it"
+  <panel
+      border="false"
+      bevel_style="none"
+      follows="left|right|bottom"
       layout="topleft"
-      name="teleport_to_character"
-      tool_tip="Enabled only when one character is selected."
-      top="233"
-      left="420"
-      width="159"/>
+      left="0"
+      height="67"
+      width="635">
+    <text
+        height="13"
+        word_wrap="false"
+        use_ellipses="false"
+        type="string"
+        text_color="LabelTextColor"
+        text_readonly_color="LabelDisabledColor"
+        length="1"
+        follows="left|bottom|right"
+        layout="topleft"
+        name="actions_label"
+        left="18"
+        top_pad="8"
+        width="242">
+      Actions on selected characters:
+    </text>
+    <check_box
+        height="19"
+        follows="left|bottom"
+        label="Show beacon"
+        layout="topleft"
+        name="show_beacon"
+        top_pad="-16"
+        left_pad="0"
+        width="90" />
+    <button
+        follows="left|bottom"
+        height="22"
+        label="Take"
+        layout="topleft"
+        name="take_characters"
+        top_pad="9"
+        left="18"
+        width="94"/>
+    <button
+        follows="left|bottom"
+        height="22"
+        label="Take copy"
+        layout="topleft"
+        name="take_copy_characters"
+        top_pad="-22"
+        left_pad="6"
+        width="94"/>
+    <button
+        follows="left|bottom"
+        height="22"
+        label="Return"
+        layout="topleft"
+        name="return_characters"
+        top_pad="-22"
+        left_pad="6"
+        width="94"/>
+    <button
+        follows="left|bottom"
+        height="22"
+        label="Delete"
+        layout="topleft"
+        name="delete_characters"
+        top_pad="-22"
+        left_pad="6"
+        width="94"/>
+    <button
+        follows="left|bottom"
+        height="22"
+        label="Teleport me to it"
+        layout="topleft"
+        name="teleport_to_character"
+        tool_tip="Enabled only when one character is selected."
+        top_pad="-22"
+        left_pad="6"
+        width="159"/>
+  </panel>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
index a672ecce8ec4982f0be1d6d41cc28f5274996847..6cd07ef7b62a3a56789549903053fce899439075 100644
--- a/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
@@ -60,6 +60,7 @@
       use_ellipses="false"
       type="string"
       text_color="LabelTextColor"
+      text_readonly_color="LabelDisabledColor"
       length="1"
       follows="left|top"
       layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
index 7cd6c32f7e40d9034094aaa4b42af7cdbab2bafa..cefef1c5099bb0cbda19751616aa52e3bf7773e5 100644
--- a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
@@ -16,11 +16,11 @@
     title="Pathfinding linksets">
   <floater.string name="linksets_messaging_initial"></floater.string>
   <floater.string name="linksets_messaging_get_inprogress">Querying for pathfinding linksets ...</floater.string>
-  <floater.string name="linksets_messaging_get_error">Error detected while querying for pathfinding linksets</floater.string>
+  <floater.string name="linksets_messaging_get_error">Error detected while querying for pathfinding linksets.</floater.string>
   <floater.string name="linksets_messaging_set_inprogress">Modifying selected pathfinding linksets ...</floater.string>
-  <floater.string name="linksets_messaging_set_error">Error detected while modifying selected pathfinding linksets</floater.string>
-  <floater.string name="linksets_messaging_complete_none_found">No pathfinding linksets</floater.string>
-  <floater.string name="linksets_messaging_complete_available">[NUM_SELECTED] linksets selected out of [NUM_TOTAL]</floater.string>
+  <floater.string name="linksets_messaging_set_error">Error detected while modifying selected pathfinding linksets.</floater.string>
+  <floater.string name="linksets_messaging_complete_none_found">No pathfinding linksets.</floater.string>
+  <floater.string name="linksets_messaging_complete_available">[NUM_SELECTED] linksets selected out of [NUM_TOTAL].</floater.string>
   <floater.string name="linksets_messaging_not_enabled">This region is not enabled for pathfinding.</floater.string>
   <floater.string name="linkset_terrain_name">[Terrain]</floater.string>
   <floater.string name="linkset_terrain_description">--</floater.string>
@@ -217,7 +217,7 @@
         type="string"
         text_color="LabelTextColor"
         length="1"
-        follows="left|bottom"
+        follows="left|bottom|right"
         layout="topleft"
         name="linksets_status"
         top_pad="17"
@@ -275,13 +275,14 @@
         use_ellipses="false"
         type="string"
         text_color="LabelTextColor"
+        text_readonly_color="LabelDisabledColor"
         length="1"
         left="18"
         follows="left|bottom|right"
         layout="topleft"
         top_pad="8"
         width="580">
-      Actions on selected linksets (If a linkset is removed from the world, its attributes will be lost):
+      Actions on selected linksets (If a linkset is removed from the world, its attributes may be lost):
     </text>
     <check_box
         height="19"