diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 1b0cf19c5a1f1ad8b95994ba7fdf92394cfd0574..726f0d1e28be2eb39a24c02ba6ccef1e7d24d269 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -420,6 +420,7 @@ set(viewer_SOURCE_FILES
     llpatchvertexarray.cpp
     llpathfindingcharacter.cpp
     llpathfindinglinkset.cpp
+    llpathfindinglinksetlist.cpp
     llpathfindingmanager.cpp
     llphysicsmotion.cpp
     llphysicsshapebuilderutil.cpp
@@ -974,6 +975,7 @@ set(viewer_HEADER_FILES
     llpatchvertexarray.h
     llpathfindingcharacter.h
     llpathfindinglinkset.h
+    llpathfindinglinksetlist.h
     llpathfindingmanager.h
     llphysicsmotion.h
     llphysicsshapebuilderutil.h
diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp
index aa0c78527d3c976c5dc654079d4d391fdc0527a3..73ab01a89f7101c128dc1bb072fd8a2135747199 100644
--- a/indra/newview/llfloaterpathfindinglinksets.cpp
+++ b/indra/newview/llfloaterpathfindinglinksets.cpp
@@ -34,7 +34,6 @@
 #include "v3math.h"
 #include "lltextvalidate.h"
 #include "llagent.h"
-#include "llhandle.h"
 #include "lltextbase.h"
 #include "lllineeditor.h"
 #include "llscrolllistitem.h"
@@ -48,9 +47,11 @@
 #include "llviewermenu.h"
 #include "llviewerobject.h"
 #include "llviewerobjectlist.h"
-#include "llhttpclient.h"
 #include "llpathfindinglinkset.h"
-#include "llfilteredpathfindinglinksets.h"
+#include "llpathfindinglinksetlist.h"
+#include "llpathfindingmanager.h"
+
+#include <boost/bind.hpp>
 
 #define XUI_LINKSET_USE_NONE             0
 #define XUI_LINKSET_USE_WALKABLE         1
@@ -60,48 +61,6 @@
 #define XUI_LINKSET_USE_EXCLUSION_VOLUME 5
 #define XUI_LINKSET_USE_DYNAMIC_PHANTOM  6
 
-//---------------------------------------------------------------------------
-// NavMeshDataGetResponder
-//---------------------------------------------------------------------------
-
-class NavMeshDataGetResponder : public LLHTTPClient::Responder
-{
-public:
-	NavMeshDataGetResponder(const std::string& pNavMeshDataGetURL,
-		const LLHandle<LLFloaterPathfindingLinksets> &pLinksetsHandle);
-	virtual ~NavMeshDataGetResponder();
-
-	virtual void result(const LLSD& pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
-
-private:
-	NavMeshDataGetResponder(const NavMeshDataGetResponder& pOther);
-
-	std::string                            mNavMeshDataGetURL;
-	LLHandle<LLFloaterPathfindingLinksets> mLinksetsFloaterHandle;
-};
-
-//---------------------------------------------------------------------------
-// NavMeshDataPutResponder
-//---------------------------------------------------------------------------
-
-class NavMeshDataPutResponder : public LLHTTPClient::Responder
-{
-public:
-	NavMeshDataPutResponder(const std::string& pNavMeshDataPutURL,
-		const LLHandle<LLFloaterPathfindingLinksets> &pLinksetsHandle);
-	virtual ~NavMeshDataPutResponder();
-
-	virtual void result(const LLSD& pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
-
-private:
-	NavMeshDataPutResponder(const NavMeshDataPutResponder& pOther);
-
-	std::string                            mNavMeshDataPutURL;
-	LLHandle<LLFloaterPathfindingLinksets> mLinksetsFloaterHandle;
-};
-
 //---------------------------------------------------------------------------
 // LLFloaterPathfindingLinksets
 //---------------------------------------------------------------------------
@@ -208,44 +167,38 @@ BOOL LLFloaterPathfindingLinksets::postBuild()
 	llassert(mApplyEditsButton != NULL);
 	mApplyEditsButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyChangesClicked, this));
 
-	setEnableActionAndEditFields(false);
-	setMessagingState(kMessagingInitial);
-
 	return LLFloater::postBuild();
 }
 
 void LLFloaterPathfindingLinksets::onOpen(const LLSD& pKey)
 {
-	sendNavMeshDataGetRequest();
+	LLFloater::onOpen(pKey);
+
+	requestGetLinksets();
 	selectNoneLinksets();
 	mLinksetsScrollList->setCommitOnSelectionChange(true);
+
+	if (!mAgentStateSlot.connected())
+	{
+		LLPathfindingManager::getInstance()->registerAgentStateSignal(boost::bind(&LLFloaterPathfindingLinksets::onAgentStateCB, this, _1));
+	}
 }
 
-void LLFloaterPathfindingLinksets::onClose(bool app_quitting)
+void LLFloaterPathfindingLinksets::onClose(bool pAppQuitting)
 {
+	if (mAgentStateSlot.connected())
+	{
+		mAgentStateSlot.disconnect();
+	}
+
 	mLinksetsScrollList->setCommitOnSelectionChange(false);
 	selectNoneLinksets();
 	if (mLinksetsSelection.notNull())
 	{
-		std::vector<LLViewerObject *> selectedObjects;
-
-		LLObjectSelection *linksetsSelected = mLinksetsSelection.get();
-		for (LLObjectSelection::valid_iterator linksetsIter = linksetsSelected->valid_begin();
-			linksetsIter != linksetsSelected->valid_end(); ++linksetsIter)
-		{
-			LLSelectNode *linksetsNode = *linksetsIter;
-			selectedObjects.push_back(linksetsNode->getObject());
-		}
-
-		for (std::vector<LLViewerObject *>::const_iterator selectedObjectIter = selectedObjects.begin();
-			selectedObjectIter != selectedObjects.end(); ++selectedObjectIter)
-		{
-			LLViewerObject *selectedObject = *selectedObjectIter;
-			LLSelectMgr::getInstance()->deselectObjectAndFamily(selectedObject);
-		}
-
 		mLinksetsSelection.clear();
 	}
+
+	LLFloater::onClose(pAppQuitting);
 }
 
 void LLFloaterPathfindingLinksets::draw()
@@ -289,31 +242,13 @@ LLFloaterPathfindingLinksets::EMessagingState LLFloaterPathfindingLinksets::getM
 	return mMessagingState;
 }
 
-BOOL LLFloaterPathfindingLinksets::isMessagingInProgress() const
+bool LLFloaterPathfindingLinksets::isMessagingInProgress() const
 {
-	BOOL retVal;
-	switch (getMessagingState())
-	{
-	case kMessagingFetchStarting :
-	case kMessagingFetchRequestSent :
-	case kMessagingFetchRequestSent_MultiRequested :
-	case kMessagingFetchReceived :
-	case kMessagingModifyStarting :
-	case kMessagingModifyRequestSent :
-	case kMessagingModifyReceived :
-		retVal = true;
-		break;
-	default :
-		retVal = false;
-		break;
-	}
-
-	return retVal;
+	return ((mMessagingState == kMessagingGetRequestSent) || (mMessagingState == kMessagingSetRequestSent));
 }
 
 LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
 	: LLFloater(pSeed),
-	mSelfHandle(),
 	mFilterByName(NULL),
 	mFilterByDescription(NULL),
 	mFilterByLinksetUse(NULL),
@@ -321,6 +256,8 @@ LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
 	mLinksetsStatus(NULL),
 	mRefreshListButton(NULL),
 	mSelectAllButton(NULL),
+	mSelectNoneButton(NULL),
+	mShowBeaconCheckBox(NULL),
 	mTakeButton(NULL),
 	mTakeCopyButton(NULL),
 	mReturnButton(NULL),
@@ -337,126 +274,89 @@ LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
 	mLabelEditD(NULL),
 	mEditD(NULL),
 	mApplyEditsButton(NULL),
-	mPathfindingLinksets(),
-	mMessagingState(kMessagingInitial),
-	mLinksetsSelection()
+	mMessagingState(kMessagingUnknown),
+	mLinksetsListPtr(),
+	mLinksetsSelection(),
+	mAgentStateSlot()
 {
-	mSelfHandle.bind(this);
 }
 
 LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets()
 {
 }
 
-void LLFloaterPathfindingLinksets::sendNavMeshDataGetRequest()
+void LLFloaterPathfindingLinksets::setMessagingState(EMessagingState pMessagingState)
 {
-	if (isMessagingInProgress())
-	{
-		if (getMessagingState() == kMessagingFetchRequestSent)
-		{
-			setMessagingState(kMessagingFetchRequestSent_MultiRequested);
-		}
-	}
-	else
-	{
-		setMessagingState(kMessagingFetchStarting);
-		mPathfindingLinksets.clearPathfindingLinksets();
-		updateLinksetsList();
-
-		std::string navMeshDataURL = getCapabilityURL();
-		if (navMeshDataURL.empty())
-		{
-			setMessagingState(kMessagingServiceNotAvailable);
-			llwarns << "cannot query object navmesh properties from current region '" << getRegionName() << "'" << llendl;
-		}
-		else
-		{
-			setMessagingState(kMessagingFetchRequestSent);
-			LLHTTPClient::get(navMeshDataURL, new NavMeshDataGetResponder(navMeshDataURL, mSelfHandle));
-		}
-	}
+	mMessagingState = pMessagingState;
+	updateControls();
 }
 
-void LLFloaterPathfindingLinksets::sendNavMeshDataPutRequest(const LLSD& pPostData)
+void LLFloaterPathfindingLinksets::requestGetLinksets()
 {
+	llassert(!isMessagingInProgress());
 	if (!isMessagingInProgress())
 	{
-		setMessagingState(kMessagingModifyStarting);
-		std::string navMeshDataURL = getCapabilityURL();
-		if (navMeshDataURL.empty())
+		switch (LLPathfindingManager::getInstance()->requestGetLinksets(boost::bind(&LLFloaterPathfindingLinksets::handleNewLinksets, this, _1, _2)))
 		{
-			setMessagingState(kMessagingServiceNotAvailable);
-			llwarns << "cannot put object navmesh properties for current region '" << getRegionName() << "'" << llendl;
-		}
-		else
-		{
-			setMessagingState(kMessagingModifyRequestSent);
-			LLHTTPClient::put(navMeshDataURL, pPostData, new NavMeshDataPutResponder(navMeshDataURL, mSelfHandle));
+		case LLPathfindingManager::kLinksetsRequestStarted :
+			setMessagingState(kMessagingGetRequestSent);
+			break;
+		case LLPathfindingManager::kLinksetsRequestNotEnabled :
+			setMessagingState(kMessagingNotEnabled);
+			break;
+		case LLPathfindingManager::kLinksetsRequestError :
+			setMessagingState(kMessagingGetError);
+			break;
+		default :
+			setMessagingState(kMessagingGetError);
+			llassert(0);
+			break;
 		}
 	}
 }
 
-void LLFloaterPathfindingLinksets::handleNavMeshDataGetReply(const LLSD& pNavMeshData)
-{
-	setMessagingState(kMessagingFetchReceived);
-	mPathfindingLinksets.setPathfindingLinksets(pNavMeshData);
-	updateLinksetsList();
-	setMessagingState(kMessagingComplete);
-}
-
-void LLFloaterPathfindingLinksets::handleNavMeshDataGetError(const std::string& pURL, const std::string& pErrorReason)
-{
-	setMessagingState(kMessagingFetchError);
-	mPathfindingLinksets.clearPathfindingLinksets();
-	updateLinksetsList();
-	llwarns << "Error fetching object navmesh properties from URL '" << pURL << "' because " << pErrorReason << llendl;
-}
-
-void LLFloaterPathfindingLinksets::handleNavMeshDataPutReply(const LLSD& pModifiedData)
-{
-	setMessagingState(kMessagingModifyReceived);
-	mPathfindingLinksets.updatePathfindingLinksets(pModifiedData);
-	updateLinksetsList();
-	setMessagingState(kMessagingComplete);
-}
-
-void LLFloaterPathfindingLinksets::handleNavMeshDataPutError(const std::string& pURL, const std::string& pErrorReason)
+void LLFloaterPathfindingLinksets::requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD)
 {
-	setMessagingState(kMessagingModifyError);
-	llwarns << "Error putting object navmesh properties to URL '" << pURL << "' because " << pErrorReason << llendl;
-}
-
-std::string LLFloaterPathfindingLinksets::getRegionName() const
-{
-	std::string regionName("");
-
-	LLViewerRegion* region = gAgent.getRegion();
-	if (region != NULL)
+	llassert(!isMessagingInProgress());
+	if (!isMessagingInProgress())
 	{
-		regionName = region->getName();
+		switch (LLPathfindingManager::getInstance()->requestSetLinksets(pLinksetList, pLinksetUse, pA, pB, pC, pD, boost::bind(&LLFloaterPathfindingLinksets::handleNewLinksets, this, _1, _2)))
+		{
+		case LLPathfindingManager::kLinksetsRequestStarted :
+			setMessagingState(kMessagingSetRequestSent);
+			break;
+		case LLPathfindingManager::kLinksetsRequestNotEnabled :
+			setMessagingState(kMessagingNotEnabled);
+			break;
+		case LLPathfindingManager::kLinksetsRequestError :
+			setMessagingState(kMessagingSetError);
+			break;
+		default :
+			setMessagingState(kMessagingSetError);
+			llassert(0);
+			break;
+		}
 	}
-
-	return regionName;
 }
 
-std::string LLFloaterPathfindingLinksets::getCapabilityURL() const
+void LLFloaterPathfindingLinksets::handleNewLinksets(LLPathfindingManager::ELinksetsRequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr)
 {
-	std::string navMeshDataURL("");
+	mLinksetsListPtr = pLinksetsListPtr;
+	updateScrollList();
 
-	LLViewerRegion* region = gAgent.getRegion();
-	if (region != NULL)
+	switch (pLinksetsRequestStatus)
 	{
-		navMeshDataURL = region->getCapability("ObjectNavMeshProperties");
+	case LLPathfindingManager::kLinksetsRequestCompleted :
+		setMessagingState(kMessagingComplete);
+		break;
+	case LLPathfindingManager::kLinksetsRequestError :
+		setMessagingState(kMessagingGetError);
+		break;
+	default :
+		setMessagingState(kMessagingGetError);
+		llassert(0);
+		break;
 	}
-
-	return navMeshDataURL;
-}
-
-void LLFloaterPathfindingLinksets::setMessagingState(EMessagingState pMessagingState)
-{
-	mMessagingState = pMessagingState;
-	updateLinksetsStatusMessage();
-	updateActionAndEditFields();
 }
 
 void LLFloaterPathfindingLinksets::onApplyAllFilters()
@@ -500,13 +400,13 @@ void LLFloaterPathfindingLinksets::onLinksetsSelectionChange()
 		}
 	}
 
-	updateLinksetsStatusMessage();
-	updateActionAndEditFields();
+	updateEditFieldValues();
+	updateControls();
 }
 
 void LLFloaterPathfindingLinksets::onRefreshLinksetsClicked()
 {
-	sendNavMeshDataGetRequest();
+	requestGetLinksets();
 }
 
 void LLFloaterPathfindingLinksets::onSelectAllLinksetsClicked()
@@ -547,9 +447,9 @@ void LLFloaterPathfindingLinksets::onTeleportClicked()
 	{
 		std::vector<LLScrollListItem*>::const_reference selectedItemRef = selectedItems.front();
 		const LLScrollListItem *selectedItem = selectedItemRef;
-		LLFilteredPathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = mPathfindingLinksets.getFilteredLinksets().find(selectedItem->getUUID().asString());
-		const LLPathfindingLinkset &linkset = linksetIter->second;
-		LLVector3 linksetLocation = linkset.getLocation();
+		LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString());
+		const LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
+		const LLVector3 &linksetLocation = linksetPtr->getLocation();
 
 		LLViewerRegion* region = gAgent.getRegion();
 		if (region != NULL)
@@ -561,27 +461,80 @@ void LLFloaterPathfindingLinksets::onTeleportClicked()
 
 void LLFloaterPathfindingLinksets::onApplyChangesClicked()
 {
-	applyEditFields();
+	applyEdit();
+}
+
+void LLFloaterPathfindingLinksets::onAgentStateCB(LLPathfindingManager::EAgentState pAgentState)
+{
+	updateControls();
 }
 
 void LLFloaterPathfindingLinksets::applyFilters()
 {
-	mPathfindingLinksets.setNameFilter(mFilterByName->getText());
-	mPathfindingLinksets.setDescriptionFilter(mFilterByDescription->getText());
-	mPathfindingLinksets.setLinksetUseFilter(getFilterLinksetUse());
-	updateLinksetsList();
+#if 0
+	mLinksetsListPtr.setNameFilter(mFilterByName->getText());
+	mLinksetsListPtr.setDescriptionFilter(mFilterByDescription->getText());
+	mLinksetsListPtr.setLinksetUseFilter(getFilterLinksetUse());
+#endif
+	updateScrollList();
 }
 
 void LLFloaterPathfindingLinksets::clearFilters()
 {
-	mPathfindingLinksets.clearFilters();
-	mFilterByName->setText(LLStringExplicit(mPathfindingLinksets.getNameFilter()));
-	mFilterByDescription->setText(LLStringExplicit(mPathfindingLinksets.getDescriptionFilter()));
-	setFilterLinksetUse(mPathfindingLinksets.getLinksetUseFilter());
-	updateLinksetsList();
+#if 0
+	mLinksetsListPtr.clearFilters();
+	mFilterByName->setText(LLStringExplicit(mLinksetsListPtr.getNameFilter()));
+	mFilterByDescription->setText(LLStringExplicit(mLinksetsListPtr.getDescriptionFilter()));
+	setFilterLinksetUse(mLinksetsListPtr.getLinksetUseFilter());
+#endif
+	updateScrollList();
+}
+
+void LLFloaterPathfindingLinksets::selectAllLinksets()
+{
+	mLinksetsScrollList->selectAll();
+}
+
+void LLFloaterPathfindingLinksets::selectNoneLinksets()
+{
+	mLinksetsScrollList->deselectAllItems();
 }
 
-void LLFloaterPathfindingLinksets::updateLinksetsList()
+void LLFloaterPathfindingLinksets::updateControls()
+{
+	updateStatusMessage();
+	updateEnableStateOnListActions();
+	updateEnableStateOnEditFields();
+}
+
+void LLFloaterPathfindingLinksets::updateEditFieldValues()
+{
+	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
+	int numSelectedItems = selectedItems.size();
+	if (numSelectedItems <= 0)
+	{
+		mEditLinksetUse->clear();
+		mEditA->clear();
+		mEditB->clear();
+		mEditC->clear();
+		mEditD->clear();
+	}
+	else
+	{
+		LLScrollListItem *firstItem = selectedItems.front();
+
+		LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(firstItem->getUUID().asString());
+		const LLPathfindingLinksetPtr linksetPtr(linksetIter->second);
+
+		setEditLinksetUse(linksetPtr->getLinksetUse());
+		mEditA->setValue(LLSD(linksetPtr->getWalkabilityCoefficientA()));
+		mEditB->setValue(LLSD(linksetPtr->getWalkabilityCoefficientB()));
+		mEditC->setValue(LLSD(linksetPtr->getWalkabilityCoefficientC()));
+		mEditD->setValue(LLSD(linksetPtr->getWalkabilityCoefficientD()));
+	}
+}
+
+void LLFloaterPathfindingLinksets::updateScrollList()
 {
 	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
 	int numSelectedItems = selectedItems.size();
@@ -598,102 +551,94 @@ void LLFloaterPathfindingLinksets::updateLinksetsList()
 	}
 
 	mLinksetsScrollList->deleteAllItems();
-	updateLinksetsStatusMessage();
 
 	const LLVector3& avatarPosition = gAgent.getPositionAgent();
-	const LLFilteredPathfindingLinksets::PathfindingLinksetMap& linksetMap = mPathfindingLinksets.getFilteredLinksets();
-
-	for (LLFilteredPathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = linksetMap.begin();
-		linksetIter != linksetMap.end(); ++linksetIter)
+	for (LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->begin();
+		linksetIter != mLinksetsListPtr->end(); ++linksetIter)
 	{
-		const LLPathfindingLinkset& linkset(linksetIter->second);
+		const LLPathfindingLinksetPtr linksetPtr(linksetIter->second);
 
 		LLSD columns;
 
 		columns[0]["column"] = "name";
-		columns[0]["value"] = linkset.getName();
+		columns[0]["value"] = linksetPtr->getName();
 		columns[0]["font"] = "SANSSERIF";
 
 		columns[1]["column"] = "description";
-		columns[1]["value"] = linkset.getDescription();
+		columns[1]["value"] = linksetPtr->getDescription();
 		columns[1]["font"] = "SANSSERIF";
 
 		columns[2]["column"] = "land_impact";
-		columns[2]["value"] = llformat("%1d", linkset.getLandImpact());
+		columns[2]["value"] = llformat("%1d", linksetPtr->getLandImpact());
 		columns[2]["font"] = "SANSSERIF";
 
 		columns[3]["column"] = "dist_from_you";
-		columns[3]["value"] = llformat("%1.0f m", dist_vec(avatarPosition, linkset.getLocation()));
+		columns[3]["value"] = llformat("%1.0f m", dist_vec(avatarPosition, linksetPtr->getLocation()));
 		columns[3]["font"] = "SANSSERIF";
 
 		columns[4]["column"] = "linkset_use";
-		switch (linkset.getLinksetUse())
+		std::string linksetUse;
+		switch (linksetPtr->getLinksetUse())
 		{
 		case LLPathfindingLinkset::kWalkable :
-			columns[4]["value"] = getString("linkset_use_walkable");
+			linksetUse = getString("linkset_use_walkable");
 			break;
 		case LLPathfindingLinkset::kStaticObstacle :
-			columns[4]["value"] = getString("linkset_use_static_obstacle");
+			linksetUse = getString("linkset_use_static_obstacle");
 			break;
 		case LLPathfindingLinkset::kDynamicObstacle :
-			columns[4]["value"] = getString("linkset_use_dynamic_obstacle");
+			linksetUse = getString("linkset_use_dynamic_obstacle");
 			break;
 		case LLPathfindingLinkset::kMaterialVolume :
-			columns[4]["value"] = getString("linkset_use_material_volume");
+			linksetUse = getString("linkset_use_material_volume");
 			break;
 		case LLPathfindingLinkset::kExclusionVolume :
-			columns[4]["value"] = getString("linkset_use_exclusion_volume");
+			linksetUse = getString("linkset_use_exclusion_volume");
 			break;
 		case LLPathfindingLinkset::kDynamicPhantom :
-			columns[4]["value"] = getString("linkset_use_dynamic_phantom");
+			linksetUse = getString("linkset_use_dynamic_phantom");
 			break;
 		case LLPathfindingLinkset::kUnknown :
 		default :
-			columns[4]["value"] = getString("linkset_use_dynamic_obstacle");
+			linksetUse = getString("linkset_use_dynamic_obstacle");
 			llassert(0);
 			break;
 		}
+		if (linksetPtr->isLocked())
+		{
+			linksetUse += (" " + getString("linkset_is_locked_state"));
+		}
+		columns[4]["value"] = linksetUse;
 		columns[4]["font"] = "SANSSERIF";
 
 		columns[5]["column"] = "a_percent";
-		columns[5]["value"] = llformat("%3d", linkset.getWalkabilityCoefficientA());
+		columns[5]["value"] = llformat("%3d", linksetPtr->getWalkabilityCoefficientA());
 		columns[5]["font"] = "SANSSERIF";
 
 		columns[6]["column"] = "b_percent";
-		columns[6]["value"] = llformat("%3d", linkset.getWalkabilityCoefficientB());
+		columns[6]["value"] = llformat("%3d", linksetPtr->getWalkabilityCoefficientB());
 		columns[6]["font"] = "SANSSERIF";
 
 		columns[7]["column"] = "c_percent";
-		columns[7]["value"] = llformat("%3d", linkset.getWalkabilityCoefficientC());
+		columns[7]["value"] = llformat("%3d", linksetPtr->getWalkabilityCoefficientC());
 		columns[7]["font"] = "SANSSERIF";
 
 		columns[8]["column"] = "d_percent";
-		columns[8]["value"] = llformat("%3d", linkset.getWalkabilityCoefficientD());
+		columns[8]["value"] = llformat("%3d", linksetPtr->getWalkabilityCoefficientD());
 		columns[8]["font"] = "SANSSERIF";
 
 		LLSD element;
-		element["id"] = linkset.getUUID().asString();
+		element["id"] = linksetPtr->getUUID().asString();
 		element["column"] = columns;
 
 		mLinksetsScrollList->addElement(element);
 	}
 
 	mLinksetsScrollList->selectMultiple(selectedUUIDs);
-	updateLinksetsStatusMessage();
-	updateActionAndEditFields();
-}
-
-void LLFloaterPathfindingLinksets::selectAllLinksets()
-{
-	mLinksetsScrollList->selectAll();
-}
-
-void LLFloaterPathfindingLinksets::selectNoneLinksets()
-{
-	mLinksetsScrollList->deselectAllItems();
+	updateControls();
 }
 
-void LLFloaterPathfindingLinksets::updateLinksetsStatusMessage()
+void LLFloaterPathfindingLinksets::updateStatusMessage()
 {
 	static const LLColor4 warningColor = LLUIColorTable::instance().getColor("DrYellow");
 
@@ -702,36 +647,21 @@ void LLFloaterPathfindingLinksets::updateLinksetsStatusMessage()
 
 	switch (getMessagingState())
 	{
-	case kMessagingInitial:
+	case kMessagingUnknown:
 		statusText = getString("linksets_messaging_initial");
 		break;
-	case kMessagingFetchStarting :
-		statusText = getString("linksets_messaging_fetch_starting");
-		break;
-	case kMessagingFetchRequestSent :
-		statusText = getString("linksets_messaging_fetch_inprogress");
-		break;
-	case kMessagingFetchRequestSent_MultiRequested :
-		statusText = getString("linksets_messaging_fetch_inprogress_multi_request");
-		break;
-	case kMessagingFetchReceived :
-		statusText = getString("linksets_messaging_fetch_received");
+	case kMessagingGetRequestSent :
+		statusText = getString("linksets_messaging_get_inprogress");
 		break;
-	case kMessagingFetchError :
-		statusText = getString("linksets_messaging_fetch_error");
+	case kMessagingGetError :
+		statusText = getString("linksets_messaging_get_error");
 		styleParams.color = warningColor;
 		break;
-	case kMessagingModifyStarting :
-		statusText = getString("linksets_messaging_modify_starting");
+	case kMessagingSetRequestSent :
+		statusText = getString("linksets_messaging_set_inprogress");
 		break;
-	case kMessagingModifyRequestSent :
-		statusText = getString("linksets_messaging_modify_inprogress");
-		break;
-	case kMessagingModifyReceived :
-		statusText = getString("linksets_messaging_modify_received");
-		break;
-	case kMessagingModifyError :
-		statusText = getString("linksets_messaging_modify_error");
+	case kMessagingSetError :
+		statusText = getString("linksets_messaging_set_error");
 		styleParams.color = warningColor;
 		break;
 	case kMessagingComplete :
@@ -757,8 +687,8 @@ void LLFloaterPathfindingLinksets::updateLinksetsStatusMessage()
 			statusText = getString("linksets_messaging_complete_available", string_args);
 		}
 		break;
-	case kMessagingServiceNotAvailable :
-		statusText = getString("linksets_messaging_service_not_available");
+	case kMessagingNotEnabled :
+		statusText = getString("linksets_messaging_not_enabled");
 		styleParams.color = warningColor;
 		break;
 	default:
@@ -770,63 +700,72 @@ void LLFloaterPathfindingLinksets::updateLinksetsStatusMessage()
 	mLinksetsStatus->setText((LLStringExplicit)statusText, styleParams);
 }
 
-void LLFloaterPathfindingLinksets::updateActionAndEditFields()
+void LLFloaterPathfindingLinksets::updateEnableStateOnListActions()
 {
-	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
-	if (selectedItems.empty())
+	switch (getMessagingState())
 	{
-		mEditLinksetUse->clear();
-		mEditA->clear();
-		mEditB->clear();
-		mEditC->clear();
-		mEditD->clear();
-
-		setEnableActionAndEditFields(false);
+	case kMessagingUnknown:
+	case kMessagingGetRequestSent :
+	case kMessagingSetRequestSent :
+		mRefreshListButton->setEnabled(FALSE);
+		mSelectAllButton->setEnabled(FALSE);
+		mSelectNoneButton->setEnabled(FALSE);
+		break;
+	case kMessagingGetError :
+	case kMessagingSetError :
+	case kMessagingNotEnabled :
+		mRefreshListButton->setEnabled(TRUE);
+		mSelectAllButton->setEnabled(FALSE);
+		mSelectNoneButton->setEnabled(FALSE);
+		break;
+	case kMessagingComplete :
+		{
+			int numItems = mLinksetsScrollList->getItemCount();
+			int numSelectedItems = mLinksetsScrollList->getNumSelected();
+			mRefreshListButton->setEnabled(TRUE);
+			mSelectAllButton->setEnabled(numSelectedItems < numItems);
+			mSelectNoneButton->setEnabled(numSelectedItems > 0);
+		}
+		break;
+	default:
+		llassert(0);
+		break;
 	}
-	else
-	{
-		LLScrollListItem *firstItem = selectedItems.front();
+}
 
-		const LLFilteredPathfindingLinksets::PathfindingLinksetMap &linksetsMap = mPathfindingLinksets.getAllLinksets();
-		LLFilteredPathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = linksetsMap.find(firstItem->getUUID().asString());
-		const LLPathfindingLinkset &linkset(linksetIter->second);
+void LLFloaterPathfindingLinksets::updateEnableStateOnEditFields()
+{
+	int numSelectedItems = mLinksetsScrollList->getNumSelected();
+	bool isEditEnabled = ((numSelectedItems > 0) && LLPathfindingManager::getInstance()->isAllowAlterPermanent());
 
-		setEditLinksetUse(linkset.getLinksetUse());
-		mEditA->setValue(LLSD(linkset.getWalkabilityCoefficientA()));
-		mEditB->setValue(LLSD(linkset.getWalkabilityCoefficientB()));
-		mEditC->setValue(LLSD(linkset.getWalkabilityCoefficientC()));
-		mEditD->setValue(LLSD(linkset.getWalkabilityCoefficientD()));
+	mShowBeaconCheckBox->setEnabled(numSelectedItems > 0);
+	mTakeButton->setEnabled(isEditEnabled && tools_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);
 
-		setEnableActionAndEditFields(true);
-	}
-}
+	mEditLinksetUse->setEnabled(isEditEnabled);
 
-void LLFloaterPathfindingLinksets::setEnableActionAndEditFields(BOOL pEnabled)
-{
-	mTakeButton->setEnabled(pEnabled && tools_visible_take_object());
-	mTakeCopyButton->setEnabled(pEnabled && enable_object_take_copy());
-	mReturnButton->setEnabled(pEnabled && enable_object_return());
-	mDeleteButton->setEnabled(pEnabled && enable_object_delete());
-	mTeleportButton->setEnabled(pEnabled && (mLinksetsScrollList->getNumSelected() == 1));
-	mEditLinksetUse->setEnabled(pEnabled);
-	mLabelWalkabilityCoefficients->setEnabled(pEnabled);
-	mLabelEditA->setEnabled(pEnabled);
-	mLabelEditB->setEnabled(pEnabled);
-	mLabelEditC->setEnabled(pEnabled);
-	mLabelEditD->setEnabled(pEnabled);
-	mEditA->setEnabled(pEnabled);
-	mEditB->setEnabled(pEnabled);
-	mEditC->setEnabled(pEnabled);
-	mEditD->setEnabled(pEnabled);
-	mApplyEditsButton->setEnabled(pEnabled);
+	mLabelWalkabilityCoefficients->setEnabled(isEditEnabled);
+	mLabelEditA->setEnabled(isEditEnabled);
+	mLabelEditB->setEnabled(isEditEnabled);
+	mLabelEditC->setEnabled(isEditEnabled);
+	mLabelEditD->setEnabled(isEditEnabled);
+	mEditA->setEnabled(isEditEnabled);
+	mEditB->setEnabled(isEditEnabled);
+	mEditC->setEnabled(isEditEnabled);
+	mEditD->setEnabled(isEditEnabled);
+
+	mApplyEditsButton->setEnabled(isEditEnabled && (getMessagingState() == kMessagingComplete));
 }
 
-void LLFloaterPathfindingLinksets::applyEditFields()
+void LLFloaterPathfindingLinksets::applyEdit()
 {
 	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
 	if (!selectedItems.empty())
 	{
-		LLPathfindingLinkset::ELinksetUse pathState = getEditLinksetUse(); // XXX this and pathState
+		LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
 		const std::string &aString = mEditA->getText();
 		const std::string &bString = mEditB->getText();
 		const std::string &cString = mEditC->getText();
@@ -836,34 +775,20 @@ void LLFloaterPathfindingLinksets::applyEditFields()
 		S32 cValue = static_cast<S32>(atoi(cString.c_str()));
 		S32 dValue = static_cast<S32>(atoi(dString.c_str()));
 
-		const LLFilteredPathfindingLinksets::PathfindingLinksetMap &linksetsMap = mPathfindingLinksets.getAllLinksets();
-
-		LLSD editData;
+		LLPathfindingLinksetListPtr editListPtr(new LLPathfindingLinksetList());
 		for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin();
 			itemIter != selectedItems.end(); ++itemIter)
 		{
 			const LLScrollListItem *listItem = *itemIter;
 			LLUUID uuid = listItem->getUUID();
-
-			const LLFilteredPathfindingLinksets::PathfindingLinksetMap::const_iterator linksetIter = linksetsMap.find(uuid.asString());
-			const LLPathfindingLinkset &linkset = linksetIter->second;
-
-			LLSD itemData = linkset.encodeAlteredFields(pathState, aValue, bValue, cValue, dValue);
-
-			if (!itemData.isUndefined())
-			{
-				editData[uuid.asString()] = itemData;
-			}
+			const std::string &uuidString = uuid.asString();
+			LLPathfindingLinksetList::iterator linksetIter = mLinksetsListPtr->find(uuidString);
+			llassert(linksetIter != mLinksetsListPtr->end());
+			LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
+			editListPtr->insert(std::pair<std::string, LLPathfindingLinksetPtr>(uuidString, linksetPtr));
 		}
 
-		if (editData.isUndefined())
-		{
-			llwarns << "No PUT data specified" << llendl;
-		}
-		else
-		{
-			sendNavMeshDataPutRequest(editData);
-		}
+		requestSetLinksets(editListPtr, linksetUse, aValue, bValue, cValue, dValue);
 	}
 }
 
@@ -958,69 +883,3 @@ LLSD LLFloaterPathfindingLinksets::convertToXuiValue(LLPathfindingLinkset::ELink
 
 	return xuiValue;
 }
-
-//---------------------------------------------------------------------------
-// NavMeshDataGetResponder
-//---------------------------------------------------------------------------
-
-NavMeshDataGetResponder::NavMeshDataGetResponder(const std::string& pNavMeshDataGetURL,
-	const LLHandle<LLFloaterPathfindingLinksets> &pLinksetsHandle)
-	: mNavMeshDataGetURL(pNavMeshDataGetURL),
-	mLinksetsFloaterHandle(pLinksetsHandle)
-{
-}
-
-NavMeshDataGetResponder::~NavMeshDataGetResponder()
-{
-}
-
-void NavMeshDataGetResponder::result(const LLSD& pContent)
-{
-	LLFloaterPathfindingLinksets *linksetsFloater = mLinksetsFloaterHandle.get();
-	if (linksetsFloater != NULL)
-	{
-		linksetsFloater->handleNavMeshDataGetReply(pContent);
-	}
-}
-
-void NavMeshDataGetResponder::error(U32 status, const std::string& reason)
-{
-	LLFloaterPathfindingLinksets *linksetsFloater = mLinksetsFloaterHandle.get();
-	if (linksetsFloater != NULL)
-	{
-		linksetsFloater->handleNavMeshDataGetError(mNavMeshDataGetURL, reason);
-	}
-}
-
-//---------------------------------------------------------------------------
-// NavMeshDataPutResponder
-//---------------------------------------------------------------------------
-
-NavMeshDataPutResponder::NavMeshDataPutResponder(const std::string& pNavMeshDataPutURL,
-	const LLHandle<LLFloaterPathfindingLinksets> &pLinksetsHandle)
-	: mNavMeshDataPutURL(pNavMeshDataPutURL),
-	mLinksetsFloaterHandle(pLinksetsHandle)
-{
-}
-
-NavMeshDataPutResponder::~NavMeshDataPutResponder()
-{
-}
-
-void NavMeshDataPutResponder::result(const LLSD& pContent)
-{
-	LLFloaterPathfindingLinksets *linksetsFloater = mLinksetsFloaterHandle.get();
-	if (linksetsFloater != NULL)
-	{
-		linksetsFloater->handleNavMeshDataPutReply(pContent);
-	}
-}
-
-void NavMeshDataPutResponder::error(U32 status, const std::string& reason)
-{
-	LLFloaterPathfindingLinksets *linksetsFloater = mLinksetsFloaterHandle.get();
-	if (linksetsFloater != NULL)
-	{
-		linksetsFloater->handleNavMeshDataPutError(mNavMeshDataPutURL, reason);
-	}
-}
diff --git a/indra/newview/llfloaterpathfindinglinksets.h b/indra/newview/llfloaterpathfindinglinksets.h
index c47ad878cc0380e36f23acdc8e0ac92c4622cd1c..f4758e233510ce5b898511a6236e5dffe4c3bde1 100644
--- a/indra/newview/llfloaterpathfindinglinksets.h
+++ b/indra/newview/llfloaterpathfindinglinksets.h
@@ -28,12 +28,12 @@
 #ifndef LL_LLFLOATERPATHFINDINGLINKSETS_H
 #define LL_LLFLOATERPATHFINDINGLINKSETS_H
 
-#include "llhandle.h"
 #include "llfloater.h"
 #include "lluuid.h"
 #include "llselectmgr.h"
 #include "llpathfindinglinkset.h"
-#include "llfilteredpathfindinglinksets.h"
+#include "llpathfindinglinksetlist.h"
+#include "llpathfindingmanager.h"
 
 class LLSD;
 class LLTextBase;
@@ -47,85 +47,72 @@ class LLFloaterPathfindingLinksets
 :	public LLFloater
 {
 	friend class LLFloaterReg;
-	friend class NavMeshDataGetResponder;
-	friend class NavMeshDataPutResponder;
 
 public:
 	typedef enum
 	{
-		kMessagingInitial,
-		kMessagingFetchStarting,
-		kMessagingFetchRequestSent,
-		kMessagingFetchRequestSent_MultiRequested,
-		kMessagingFetchReceived,
-		kMessagingFetchError,
-		kMessagingModifyStarting,
-		kMessagingModifyRequestSent,
-		kMessagingModifyReceived,
-		kMessagingModifyError,
+		kMessagingUnknown,
+		kMessagingGetRequestSent,
+		kMessagingGetError,
+		kMessagingSetRequestSent,
+		kMessagingSetError,
 		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 openLinksetsEditor();
 
 	EMessagingState getMessagingState() const;
-	BOOL            isMessagingInProgress() const;
+	bool            isMessagingInProgress() const;
 
 protected:
 
 private:
-	LLRootHandle<LLFloaterPathfindingLinksets> mSelfHandle;
-	LLLineEditor                               *mFilterByName;
-	LLLineEditor                               *mFilterByDescription;
-	LLComboBox                                 *mFilterByLinksetUse;
-	LLScrollListCtrl                           *mLinksetsScrollList;
-	LLTextBase                                 *mLinksetsStatus;
-	LLButton                                   *mRefreshListButton;
-	LLButton                                   *mSelectAllButton;
-	LLButton                                   *mSelectNoneButton;
-	LLCheckBoxCtrl                             *mShowBeaconCheckBox;
-	LLButton                                   *mTakeButton;
-	LLButton                                   *mTakeCopyButton;
-	LLButton                                   *mReturnButton;
-	LLButton                                   *mDeleteButton;
-	LLButton                                   *mTeleportButton;
-	LLComboBox                                 *mEditLinksetUse;
-	LLTextBase                                 *mLabelWalkabilityCoefficients;
-	LLTextBase                                 *mLabelEditA;
-	LLLineEditor                               *mEditA;
-	LLTextBase                                 *mLabelEditB;
-	LLLineEditor                               *mEditB;
-	LLTextBase                                 *mLabelEditC;
-	LLLineEditor                               *mEditC;
-	LLTextBase                                 *mLabelEditD;
-	LLLineEditor                               *mEditD;
-	LLButton                                   *mApplyEditsButton;
-	LLFilteredPathfindingLinksets              mPathfindingLinksets;
-	EMessagingState                            mMessagingState;
-	LLObjectSelectionHandle                    mLinksetsSelection;
+	LLLineEditor     *mFilterByName;
+	LLLineEditor     *mFilterByDescription;
+	LLComboBox       *mFilterByLinksetUse;
+	LLScrollListCtrl *mLinksetsScrollList;
+	LLTextBase       *mLinksetsStatus;
+	LLButton         *mRefreshListButton;
+	LLButton         *mSelectAllButton;
+	LLButton         *mSelectNoneButton;
+	LLCheckBoxCtrl   *mShowBeaconCheckBox;
+	LLButton         *mTakeButton;
+	LLButton         *mTakeCopyButton;
+	LLButton         *mReturnButton;
+	LLButton         *mDeleteButton;
+	LLButton         *mTeleportButton;
+	LLComboBox       *mEditLinksetUse;
+	LLTextBase       *mLabelWalkabilityCoefficients;
+	LLTextBase       *mLabelEditA;
+	LLLineEditor     *mEditA;
+	LLTextBase       *mLabelEditB;
+	LLLineEditor     *mEditB;
+	LLTextBase       *mLabelEditC;
+	LLLineEditor     *mEditC;
+	LLTextBase       *mLabelEditD;
+	LLLineEditor     *mEditD;
+	LLButton         *mApplyEditsButton;
+
+	EMessagingState                          mMessagingState;
+	LLPathfindingLinksetListPtr              mLinksetsListPtr;
+	LLObjectSelectionHandle                  mLinksetsSelection;
+	LLPathfindingManager::agent_state_slot_t mAgentStateSlot;
 
 	// Does its own instance management, so clients not allowed
 	// to allocate or destroy.
 	LLFloaterPathfindingLinksets(const LLSD& pSeed);
 	virtual ~LLFloaterPathfindingLinksets();
 
-	void sendNavMeshDataGetRequest();
-	void sendNavMeshDataPutRequest(const LLSD& pPostData);
-	void handleNavMeshDataGetReply(const LLSD& pNavMeshData);
-	void handleNavMeshDataGetError(const std::string& pURL, const std::string& pErrorReason);
-	void handleNavMeshDataPutReply(const LLSD& pModifiedData);
-	void handleNavMeshDataPutError(const std::string& pURL, const std::string& pErrorReason);
-
-	std::string getRegionName() const;
-	std::string getCapabilityURL() const;
-
 	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 onApplyAllFilters();
 	void onClearFiltersClicked();
@@ -139,19 +126,23 @@ class LLFloaterPathfindingLinksets
 	void onDeleteClicked();
 	void onTeleportClicked();
 	void onApplyChangesClicked();
+	void onAgentStateCB(LLPathfindingManager::EAgentState pAgentState);
 
 	void applyFilters();
 	void clearFilters();
 
-	void updateLinksetsList();
 	void selectAllLinksets();
 	void selectNoneLinksets();
 
-	void updateLinksetsStatusMessage();
+	void updateControls();
+	void updateEditFieldValues();
+	void updateScrollList();
+
+	void updateStatusMessage();
+	void updateEnableStateOnListActions();
+	void updateEnableStateOnEditFields();
 
-	void updateActionAndEditFields();
-	void setEnableActionAndEditFields(BOOL pEnabled);
-	void applyEditFields();
+	void applyEdit();
 
 	LLPathfindingLinkset::ELinksetUse getFilterLinksetUse() const;
 	void                              setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse);
diff --git a/indra/newview/llpathfindinglinkset.cpp b/indra/newview/llpathfindinglinkset.cpp
index de17edbf610b992f9e938f4a164699296bf2f79b..d775ec2feff6078b8628f04972c938041e92e861 100644
--- a/indra/newview/llpathfindinglinkset.cpp
+++ b/indra/newview/llpathfindinglinkset.cpp
@@ -34,6 +34,7 @@
 #define LINKSET_NAME_FIELD          "name"
 #define LINKSET_DESCRIPTION_FIELD   "description"
 #define LINKSET_LAND_IMPACT_FIELD   "landimpact"
+#define LINKSET_MODIFIABLE_FIELD    "modifiable"
 #define LINKSET_PERMANENT_FIELD     "permanent"
 #define LINKSET_WALKABLE_FIELD      "walkable"
 #define LINKSET_PHANTOM_FIELD       "phantom"
@@ -55,7 +56,8 @@ LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD&
 	mName(),
 	mDescription(),
 	mLandImpact(0U),
-	mLocation(),
+	mLocation(LLVector3::zero),
+	mIsLocked(FALSE),
 	mLinksetUse(kUnknown),
 	mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE),
 	mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE),
@@ -75,6 +77,12 @@ LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD&
 	llassert(pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).asInteger() >= 0);
 	mLandImpact = pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).asInteger();
 
+	if (pLinksetItem.has(LINKSET_MODIFIABLE_FIELD))
+	{
+		llassert(pLinksetItem.get(LINKSET_MODIFIABLE_FIELD).isBoolean());
+		mIsLocked = !pLinksetItem.get(LINKSET_MODIFIABLE_FIELD).asBoolean();
+	}
+
 	llassert(pLinksetItem.has(LINKSET_PHANTOM_FIELD));
 	llassert(pLinksetItem.get(LINKSET_PHANTOM_FIELD).isBoolean());
 	bool isPhantom = pLinksetItem.get(LINKSET_PHANTOM_FIELD).asBoolean();
@@ -124,6 +132,7 @@ LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& pOther)
 	mDescription(pOther.mDescription),
 	mLandImpact(pOther.mLandImpact),
 	mLocation(pOther.mLocation),
+	mIsLocked(pOther.mIsLocked),
 	mLinksetUse(pOther.mLinksetUse),
 	mWalkabilityCoefficientA(pOther.mWalkabilityCoefficientA),
 	mWalkabilityCoefficientB(pOther.mWalkabilityCoefficientB),
@@ -143,6 +152,7 @@ LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkse
 	mDescription = pOther.mDescription;
 	mLandImpact = pOther.mLandImpact;
 	mLocation = pOther.mLocation;
+	// mIsLocked = pOther.mIsLocked;  XXX stinson 02/23/2012 : disabling temporarily until all sim-service responses include the modifiable state
 	mLinksetUse = pOther.mLinksetUse;
 	mWalkabilityCoefficientA = pOther.mWalkabilityCoefficientA;
 	mWalkabilityCoefficientB = pOther.mWalkabilityCoefficientB;
@@ -152,33 +162,16 @@ LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkse
 	return *this;
 }
 
-void LLPathfindingLinkset::setWalkabilityCoefficientA(S32 pA)
-{
-	mWalkabilityCoefficientA = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
-}
-
-void LLPathfindingLinkset::setWalkabilityCoefficientB(S32 pB)
-{
-	mWalkabilityCoefficientB = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
-}
-
-void LLPathfindingLinkset::setWalkabilityCoefficientC(S32 pC)
-{
-	mWalkabilityCoefficientC = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
-}
-
-void LLPathfindingLinkset::setWalkabilityCoefficientD(S32 pD)
-{
-	mWalkabilityCoefficientD = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
-}
-
 LLSD LLPathfindingLinkset::encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const
 {
 	LLSD itemData;
 
 	if ((pLinksetUse != kUnknown) && (mLinksetUse != pLinksetUse))
 	{
-		itemData[LINKSET_PHANTOM_FIELD] = static_cast<bool>(LLPathfindingLinkset::isPhantom(pLinksetUse));
+		if (!mIsLocked)
+		{
+			itemData[LINKSET_PHANTOM_FIELD] = static_cast<bool>(LLPathfindingLinkset::isPhantom(pLinksetUse));
+		}
 		itemData[LINKSET_PERMANENT_FIELD] = static_cast<bool>(LLPathfindingLinkset::isPermanent(pLinksetUse));
 		itemData[LINKSET_WALKABLE_FIELD] = static_cast<bool>(LLPathfindingLinkset::isWalkable(pLinksetUse));
 	}
diff --git a/indra/newview/llpathfindinglinkset.h b/indra/newview/llpathfindinglinkset.h
index 50bc07218bbe7131bdb79cf33f1f8dc9f2822b92..ea6cf710b1630b85c8e8d69b91eaf897ba7cf181 100644
--- a/indra/newview/llpathfindinglinkset.h
+++ b/indra/newview/llpathfindinglinkset.h
@@ -31,7 +31,12 @@
 #include "v3math.h"
 #include "lluuid.h"
 
+#include <boost/shared_ptr.hpp>
+
 class LLSD;
+class LLPathfindingLinkset;
+
+typedef boost::shared_ptr<LLPathfindingLinkset> LLPathfindingLinksetPtr;
 
 class LLPathfindingLinkset
 {
@@ -53,26 +58,19 @@ class LLPathfindingLinkset
 
 	LLPathfindingLinkset& operator = (const LLPathfindingLinkset& 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 U32                getLandImpact() const                  {return mLandImpact;};
-	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 U32                getLandImpact() const               {return mLandImpact;};
+	inline const LLVector3&   getLocation() const                 {return mLocation;};
+	BOOL                      isLocked() const                    {return mIsLocked;};
 
-	inline ELinksetUse        getLinksetUse() const                  {return mLinksetUse;};
-	inline void               setLinksetUse(ELinksetUse pLinksetUse) {mLinksetUse = pLinksetUse;};
+	inline ELinksetUse        getLinksetUse() const               {return mLinksetUse;};
 
 	inline S32                getWalkabilityCoefficientA() const  {return mWalkabilityCoefficientA;};
-	void                      setWalkabilityCoefficientA(S32 pA);
-
 	inline S32                getWalkabilityCoefficientB() const  {return mWalkabilityCoefficientB;};
-	void                      setWalkabilityCoefficientB(S32 pB);
-
 	inline S32                getWalkabilityCoefficientC() const  {return mWalkabilityCoefficientC;};
-	void                      setWalkabilityCoefficientC(S32 pC);
-
 	inline S32                getWalkabilityCoefficientD() const  {return mWalkabilityCoefficientD;};
-	void                      setWalkabilityCoefficientD(S32 pD);
 
 	LLSD                      encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const;
 
@@ -92,6 +90,7 @@ class LLPathfindingLinkset
 	std::string  mDescription;
 	U32          mLandImpact;
 	LLVector3    mLocation;
+	BOOL         mIsLocked;
 	ELinksetUse  mLinksetUse;
 	S32          mWalkabilityCoefficientA;
 	S32          mWalkabilityCoefficientB;
diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e67b7b800c20330edb1b13fc69cf1a4405e1e4fd
--- /dev/null
+++ b/indra/newview/llpathfindinglinksetlist.cpp
@@ -0,0 +1,103 @@
+/** 
+ * @file llpathfindinglinksetlist.cpp
+ * @author William Todd Stinson
+ * @brief Class to implement the list of a set of pathfinding linksets
+ *
+ * $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 "llpathfindinglinkset.h"
+#include "llpathfindinglinksetlist.h"
+
+//---------------------------------------------------------------------------
+// LLPathfindingLinksetList
+//---------------------------------------------------------------------------
+
+LLPathfindingLinksetList::LLPathfindingLinksetList()
+	: LLPathfindingLinksetMap()
+{
+}
+
+LLPathfindingLinksetList::LLPathfindingLinksetList(const LLSD& pLinksetItems)
+	: LLPathfindingLinksetMap()
+{
+	for (LLSD::map_const_iterator linksetItemIter = pLinksetItems.beginMap();
+		linksetItemIter != pLinksetItems.endMap(); ++linksetItemIter)
+	{
+		const std::string& uuid(linksetItemIter->first);
+		const LLSD& linksetData = linksetItemIter->second;
+		LLPathfindingLinksetPtr linkset(new LLPathfindingLinkset(uuid, linksetData));
+		insert(std::pair<std::string, LLPathfindingLinksetPtr>(uuid, linkset));
+	}
+}
+
+LLPathfindingLinksetList::~LLPathfindingLinksetList()
+{
+	clear();
+}
+
+void LLPathfindingLinksetList::update(const LLSD& pLinksetItems)
+{
+	for (LLSD::map_const_iterator linksetItemIter = pLinksetItems.beginMap();
+		linksetItemIter != pLinksetItems.endMap(); ++linksetItemIter)
+	{
+		const std::string& uuid(linksetItemIter->first);
+		const LLSD& linksetData = linksetItemIter->second;
+		LLPathfindingLinksetMap::iterator linksetIter = this->find(uuid);
+		if (linksetIter == end())
+		{
+			LLPathfindingLinksetPtr linkset(new LLPathfindingLinkset(uuid, linksetData));
+			insert(std::pair<std::string, LLPathfindingLinksetPtr>(uuid, linkset));
+		}
+		else
+		{
+			LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
+			const LLPathfindingLinkset newLinkset(uuid, linksetData);
+			*linksetPtr = newLinkset;
+		}
+	}
+}
+
+LLSD LLPathfindingLinksetList::encodeAlteredFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const
+{
+	LLSD listData;
+
+	for (LLPathfindingLinksetMap::const_iterator linksetIter = begin(); linksetIter != end(); ++linksetIter)
+	{
+		const LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
+		LLSD linksetData = linksetPtr->encodeAlteredFields(pLinksetUse, pA, pB, pC, pD);
+		if (!linksetData.isUndefined())
+		{
+			const std::string& uuid(linksetIter->first);
+			listData[uuid] = linksetData;
+		}
+	}
+
+	return listData;
+}
diff --git a/indra/newview/llpathfindinglinksetlist.h b/indra/newview/llpathfindinglinksetlist.h
new file mode 100644
index 0000000000000000000000000000000000000000..9ec36c2431cce9bb7e614df710a183362eac3561
--- /dev/null
+++ b/indra/newview/llpathfindinglinksetlist.h
@@ -0,0 +1,60 @@
+/** 
+ * @file llpathfindinglinksetlist.h
+ * @author William Todd Stinson
+ * @brief Class to implement the list of a set of pathfinding linksets
+ *
+ * $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_LLPATHFINDINGLINKSETLIST_H
+#define LL_LLPATHFINDINGLINKSETLIST_H
+
+#include <string>
+#include <map>
+#include "llpathfindinglinkset.h"
+
+#include <boost/shared_ptr.hpp>
+
+class LLSD;
+class LLPathfindingLinksetList;
+
+typedef boost::shared_ptr<LLPathfindingLinksetList> LLPathfindingLinksetListPtr;
+typedef std::map<std::string, LLPathfindingLinksetPtr> LLPathfindingLinksetMap;
+
+class LLPathfindingLinksetList : public LLPathfindingLinksetMap
+{
+public:
+	LLPathfindingLinksetList();
+	LLPathfindingLinksetList(const LLSD& pLinksetItems);
+	virtual ~LLPathfindingLinksetList();
+
+	void update(const LLSD& pLinksetItems);
+
+	LLSD encodeAlteredFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const;
+
+protected:
+
+private:
+
+};
+
+#endif // LL_LLPATHFINDINGLINKSETLIST_H
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index 76766c4e09556cf8ddf332875a344612eafde8c1..aafa2eaa10dafcb2d32296927a0d8f5f04a8ee5c 100644
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -33,6 +33,8 @@
 #include "llhttpclient.h"
 #include "llagent.h"
 #include "llviewerregion.h"
+#include "llpathfindinglinkset.h"
+#include "llpathfindinglinksetlist.h"
 
 #include <boost/function.hpp>
 #include <boost/signals2.hpp>
@@ -42,6 +44,8 @@
 #define CAP_SERVICE_AGENT_STATE       "AgentPreferences"
 #define ALTER_PERMANENT_OBJECTS_FIELD "alter_permanent_objects"
 
+#define CAP_SERVICE_LINKSETS          "ObjectNavMeshProperties"
+
 //---------------------------------------------------------------------------
 // AgentStateResponder
 //---------------------------------------------------------------------------
@@ -62,6 +66,26 @@ class AgentStateResponder : public LLHTTPClient::Responder
 	LLPathfindingManager::EAgentState mRequestedAgentState;
 };
 
+//---------------------------------------------------------------------------
+// LinksetsResponder
+//---------------------------------------------------------------------------
+
+class LinksetsResponder : public LLHTTPClient::Responder
+{
+public:
+	LinksetsResponder(const std::string &pCapabilityURL, LLPathfindingManager::linksets_callback_t pLinksetsCallback);
+	virtual ~LinksetsResponder();
+
+	virtual void result(const LLSD &pContent);
+	virtual void error(U32 pStatus, const std::string &pReason);
+
+protected:
+
+private:
+	std::string                               mCapabilityURL;
+	LLPathfindingManager::linksets_callback_t mLinksetsCallback;
+};
+
 //---------------------------------------------------------------------------
 // LLPathfindingManager
 //---------------------------------------------------------------------------
@@ -84,6 +108,11 @@ bool LLPathfindingManager::isPathfindingEnabledForCurrentRegion() const
 	return !retrieveNavMeshURL.empty();
 }
 
+bool LLPathfindingManager::isAllowAlterPermanent()
+{
+	return (!isPathfindingEnabledForCurrentRegion() || (getAgentState() == kAgentStateUnfrozen));
+}
+
 LLPathfindingManager::agent_state_slot_t LLPathfindingManager::registerAgentStateSignal(agent_state_callback_t pAgentStateCallback)
 {
 	return mAgentStateSignal.connect(pAgentStateCallback);
@@ -130,6 +159,45 @@ void LLPathfindingManager::requestSetAgentState(EAgentState pRequestedAgentState
 	}
 }
 
+LLPathfindingManager::ELinksetsRequestStatus LLPathfindingManager::requestGetLinksets(linksets_callback_t pLinksetsCallback) const
+{
+	ELinksetsRequestStatus status;
+
+	std::string linksetsURL = getLinksetsURLForCurrentRegion();
+	if (linksetsURL.empty())
+	{;
+		status = kLinksetsRequestNotEnabled;
+	}
+	else
+	{
+		LLHTTPClient::ResponderPtr responder = new LinksetsResponder(linksetsURL, pLinksetsCallback);
+		LLHTTPClient::get(linksetsURL, responder);
+		status = kLinksetsRequestStarted;
+	}
+
+	return status;
+}
+
+LLPathfindingManager::ELinksetsRequestStatus LLPathfindingManager::requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, linksets_callback_t pLinksetsCallback) const
+{
+	ELinksetsRequestStatus status;
+
+	std::string linksetsURL = getLinksetsURLForCurrentRegion();
+	if (linksetsURL.empty())
+	{
+		status = kLinksetsRequestNotEnabled;
+	}
+	else
+	{
+		LLHTTPClient::ResponderPtr responder = new LinksetsResponder(linksetsURL, pLinksetsCallback);
+		LLSD postData = pLinksetList->encodeAlteredFields(pLinksetUse, pA, pB, pC, pD);
+		LLHTTPClient::put(linksetsURL, postData, responder);
+		status = kLinksetsRequestStarted;
+	}
+
+	return status;
+}
+
 bool LLPathfindingManager::isValidAgentState(EAgentState pAgentState)
 {
 	return ((pAgentState == kAgentStateFrozen) || (pAgentState == kAgentStateUnfrozen));
@@ -183,6 +251,19 @@ void LLPathfindingManager::handleAgentStateError(U32 pStatus, const std::string
 	setAgentState(kAgentStateError);
 }
 
+void LLPathfindingManager::handleLinksetsResult(const LLSD &pContent, linksets_callback_t pLinksetsCallback) const
+{
+	LLPathfindingLinksetListPtr linksetListPtr(new LLPathfindingLinksetList(pContent));
+	pLinksetsCallback(kLinksetsRequestCompleted, linksetListPtr);
+}
+
+void LLPathfindingManager::handleLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL, linksets_callback_t pLinksetsCallback) const
+{
+	llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	LLPathfindingLinksetListPtr linksetListPtr(new LLPathfindingLinksetList());
+	pLinksetsCallback(kLinksetsRequestError, linksetListPtr);
+}
+
 std::string LLPathfindingManager::getRetrieveNavMeshURLForCurrentRegion() const
 {
 	return getCapabilityURLForCurrentRegion(CAP_SERVICE_RETRIEVE_NAVMESH);
@@ -193,6 +274,11 @@ std::string LLPathfindingManager::getAgentStateURLForCurrentRegion() const
 	return getCapabilityURLForCurrentRegion(CAP_SERVICE_AGENT_STATE);
 }
 
+std::string LLPathfindingManager::getLinksetsURLForCurrentRegion() const
+{
+	return getCapabilityURLForCurrentRegion(CAP_SERVICE_LINKSETS);
+}
+
 std::string LLPathfindingManager::getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const
 {
 	std::string capabilityURL("");
@@ -236,3 +322,28 @@ void AgentStateResponder::error(U32 pStatus, const std::string &pReason)
 {
 	LLPathfindingManager::getInstance()->handleAgentStateError(pStatus, pReason, mCapabilityURL);
 }
+
+//---------------------------------------------------------------------------
+// LinksetsResponder
+//---------------------------------------------------------------------------
+
+LinksetsResponder::LinksetsResponder(const std::string &pCapabilityURL, LLPathfindingManager::linksets_callback_t pLinksetsCallback)
+	: LLHTTPClient::Responder(),
+	mCapabilityURL(pCapabilityURL),
+	mLinksetsCallback(pLinksetsCallback)
+{
+}
+
+LinksetsResponder::~LinksetsResponder()
+{
+}
+
+void LinksetsResponder::result(const LLSD &pContent)
+{
+	LLPathfindingManager::getInstance()->handleLinksetsResult(pContent, mLinksetsCallback);
+}
+
+void LinksetsResponder::error(U32 pStatus, const std::string &pReason)
+{
+	LLPathfindingManager::getInstance()->handleLinksetsError(pStatus, pReason, mCapabilityURL, mLinksetsCallback);
+}
diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h
index a9432f90774f8899e2f862c3d9bab12acc58c96d..cef2b7c058971eea47768cd6240cd491740ce138 100644
--- a/indra/newview/llpathfindingmanager.h
+++ b/indra/newview/llpathfindingmanager.h
@@ -34,12 +34,15 @@
 #include <boost/signals2.hpp>
 
 #include "llsingleton.h"
+#include "llpathfindinglinkset.h"
+#include "llpathfindinglinksetlist.h"
 
 class LLFloater;
 
 class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 {
 	friend class AgentStateResponder;
+	friend class LinksetsResponder;
 public:
 	typedef enum {
 		kAgentStateUnknown,
@@ -49,20 +52,34 @@ class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 		kAgentStateError
 	} EAgentState;
 
-	typedef boost::function<void (EAgentState pAgentState)>         agent_state_callback_t;
-	typedef boost::signals2::signal<void (EAgentState pAgentState)> agent_state_signal_t;
-	typedef boost::signals2::connection                             agent_state_slot_t;
+	typedef boost::function<void (EAgentState)>         agent_state_callback_t;
+	typedef boost::signals2::signal<void (EAgentState)> agent_state_signal_t;
+	typedef boost::signals2::connection                 agent_state_slot_t;
+
+	typedef enum {
+		kLinksetsRequestStarted,
+		kLinksetsRequestCompleted,
+		kLinksetsRequestNotEnabled,
+		kLinksetsRequestError
+	} ELinksetsRequestStatus;
+
+	typedef boost::function<void (ELinksetsRequestStatus, LLPathfindingLinksetListPtr)> linksets_callback_t;
 
 	LLPathfindingManager();
 	virtual ~LLPathfindingManager();
 
 	bool isPathfindingEnabledForCurrentRegion() const;
 
+	bool isAllowAlterPermanent();
+
 	agent_state_slot_t registerAgentStateSignal(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;
+
 protected:
 
 private:
@@ -70,12 +87,15 @@ class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 
 	void requestGetAgentState();
 	void setAgentState(EAgentState pAgentState);
-
 	void handleAgentStateResult(const LLSD &pContent, EAgentState pRequestedAgentState);
 	void handleAgentStateError(U32 pStatus, const std::string &pReason, const std::string &pURL);
 
+	void handleLinksetsResult(const LLSD &pContent, linksets_callback_t pLinksetsCallback) const;
+	void handleLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL, linksets_callback_t pLinksetsCallback) const;
+
 	std::string getRetrieveNavMeshURLForCurrentRegion() const;
 	std::string getAgentStateURLForCurrentRegion() const;
+	std::string getLinksetsURLForCurrentRegion() const;
 
 	std::string getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const;
 
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 60d547c5f467042cc1f12f6f93951072530d88e3..f7e78a91ccb0ce7c5bc34c4245e47bc1d27e140e 100644
--- a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
@@ -15,24 +15,20 @@
     single_instance="true"
     title="Pathfinding linksets">
   <floater.string name="linksets_messaging_initial"></floater.string>
-  <floater.string name="linksets_messaging_fetch_starting">Building query for pathfinding linksets ...</floater.string>
-  <floater.string name="linksets_messaging_fetch_inprogress">Querying for pathfinding linksets ...</floater.string>
-  <floater.string name="linksets_messaging_fetch_inprogress_multi_request">Querying for pathfinding linksets (already in progress) ...</floater.string>
-  <floater.string name="linksets_messaging_fetch_received">Loading pathfinding linksets data from response ...</floater.string>
-  <floater.string name="linksets_messaging_fetch_error">Error detected while querying for pathfinding linksets</floater.string>
-  <floater.string name="linksets_messaging_modify_starting">Building modify message for selected pathfinding linksets ...</floater.string>
-  <floater.string name="linksets_messaging_modify_inprogress">Modifying selected pathfinding linksets ...</floater.string>
-  <floater.string name="linksets_messaging_modify_received">Loading modified pathfinding linksets data from response ...</floater.string>
-  <floater.string name="linksets_messaging_modify_error">Error detected while modifying for pathfinding linksets</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_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_service_not_available">Required capability is not available in current region</floater.string>
+  <floater.string name="linksets_messaging_not_enabled">This region is not enabled for pathfinding.</floater.string>
   <floater.string name="linkset_use_walkable">Walkable</floater.string>
   <floater.string name="linkset_use_static_obstacle">Static obstacle</floater.string>
   <floater.string name="linkset_use_dynamic_obstacle">Dynamic obstacle</floater.string>
   <floater.string name="linkset_use_material_volume">Material volume</floater.string>
   <floater.string name="linkset_use_exclusion_volume">Exclusion volume</floater.string>
   <floater.string name="linkset_use_dynamic_phantom">Dynamic phantom</floater.string>
+  <floater.string name="linkset_is_locked_state">[locked]</floater.string>
   <panel
       border="false"
       bevel_style="none"