diff --git a/autobuild.xml b/autobuild.xml
index 628141c4e69cf9e768e9c7e7b80e9506c737d392..11f0cf4b66d2eb6414e4605696e8e4a931d98a49 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1110,9 +1110,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7bec0b4904ce36a2e3c2f5cf38446c9d</string>
+              <string>8e17ced77750d284ccf7fa707429dbad</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/stinson_llpathinglibrary/rev/253279/arch/Darwin/installer/llphysicsextensions-0.1-darwin-20120406.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/stinson_llpathinglibrary/rev/253348/arch/Darwin/installer/llphysicsextensions-0.1-darwin-20120409.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin</string>
@@ -1122,9 +1122,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e6fe146ac8b11f380a6fb64604fe7f4f</string>
+              <string>30a6958667476cbffc61e907e16c5ebb</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/stinson_llpathinglibrary/rev/253279/arch/Linux/installer/llphysicsextensions-0.1-linux-20120407.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/stinson_llpathinglibrary/rev/253348/arch/Linux/installer/llphysicsextensions-0.1-linux-20120409.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -1134,9 +1134,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6d83c4aa41354d1d76eca6b7911823e0</string>
+              <string>f8e1f36c14aae6e538e0df670e3b09e8</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/stinson_llpathinglibrary/rev/253279/arch/CYGWIN/installer/llphysicsextensions-0.1-windows-20120406.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/stinson_llpathinglibrary/rev/253348/arch/CYGWIN/installer/llphysicsextensions-0.1-windows-20120409.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
diff --git a/indra/newview/llpathfindingnavmeshzone.cpp b/indra/newview/llpathfindingnavmeshzone.cpp
index f8712044543aad772721393d9ee54d3cce5e3af9..4f8ca399878343bba474eb3961e8097c4cc6a2a0 100644
--- a/indra/newview/llpathfindingnavmeshzone.cpp
+++ b/indra/newview/llpathfindingnavmeshzone.cpp
@@ -1,465 +1,465 @@
-/** 
- * @file llpathfindingnavmeshzone.cpp
- * @author William Todd Stinson
- * @brief A class for representing the zone of navmeshes containing and possible surrounding the current region.
- *
- * $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 "llsd.h"
-#include "lluuid.h"
-#include "llagent.h"
-#include "llviewerregion.h"
-#include "llpathfindingnavmesh.h"
-#include "llpathfindingnavmeshzone.h"
-#include "llpathfindingmanager.h"
-#include "llviewercontrol.h"
-
-#include "LLPathingLib.h"
-
-#include <string>
-#include <vector>
-
-#include <boost/bind.hpp>
-
-#define CENTER_REGION 99
-
-//---------------------------------------------------------------------------
-// LLPathfindingNavMeshZone
-//---------------------------------------------------------------------------
-
-LLPathfindingNavMeshZone::LLPathfindingNavMeshZone()
-	: mNavMeshLocationPtrs(),
-	mNavMeshZoneRequestStatus(kNavMeshZoneRequestUnknown),
-	mNavMeshZoneSignal()
-{
-}
-
-LLPathfindingNavMeshZone::~LLPathfindingNavMeshZone()
-{
-}
-
-LLPathfindingNavMeshZone::navmesh_zone_slot_t LLPathfindingNavMeshZone::registerNavMeshZoneListener(navmesh_zone_callback_t pNavMeshZoneCallback)
-{
-	return mNavMeshZoneSignal.connect(pNavMeshZoneCallback);
-}
-
-void LLPathfindingNavMeshZone::initialize()
-{
-	mNavMeshLocationPtrs.clear();
-
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-	LLViewerRegion *currentRegion = gAgent.getRegion();
-	if (currentRegion != NULL)
-	{
-		llinfos << "STINSON DEBUG: currentRegion: '" << currentRegion->getName() << "' (" << currentRegion->getRegionID().asString() << ")" << llendl;
-		std::vector<S32> availableRegions;
-		currentRegion->getNeighboringRegionsStatus( availableRegions );
-		std::vector<LLViewerRegion*> neighborRegionsPtrs;
-		currentRegion->getNeighboringRegions( neighborRegionsPtrs );
-		for (std::vector<S32>::const_iterator statusIter = availableRegions.begin();
-			statusIter != availableRegions.end(); ++statusIter)
-		{
-			LLViewerRegion *region = neighborRegionsPtrs[statusIter - availableRegions.begin()];
-			llinfos << "STINSON DEBUG: region #" << *statusIter << ": '" << region->getName() << "' (" << region->getRegionID().asString() << ")" << llendl;
-		}
- 	}
-
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-	NavMeshLocationPtr centerNavMeshPtr(new NavMeshLocation(CENTER_REGION, boost::bind(&LLPathfindingNavMeshZone::handleNavMeshLocation, this)));
-	mNavMeshLocationPtrs.push_back(centerNavMeshPtr);
-
-	U32 neighborRegionDir = gSavedSettings.getU32("RetrieveNeighboringRegion");
-	if (neighborRegionDir != CENTER_REGION)
-	{
-		NavMeshLocationPtr neighborNavMeshPtr(new NavMeshLocation(neighborRegionDir, boost::bind(&LLPathfindingNavMeshZone::handleNavMeshLocation, this)));
-		mNavMeshLocationPtrs.push_back(neighborNavMeshPtr);
-	}
-}
-
-void LLPathfindingNavMeshZone::enable()
-{
-	for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
-		navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
-	{
-		NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
-		navMeshLocationPtr->enable();
-	}
-}
-
-void LLPathfindingNavMeshZone::disable()
-{
-	for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
-		navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
-	{
-		NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
-		navMeshLocationPtr->disable();
-	}
-}
-
-void LLPathfindingNavMeshZone::refresh()
-{
-	llassert(LLPathingLib::getInstance() != NULL);
-	if (LLPathingLib::getInstance() != NULL)
-	{
-		LLPathingLib::getInstance()->cleanupResidual();
-	}
-
-	for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
-		navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
-	{
-		NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
-		navMeshLocationPtr->refresh();
-	}
-}
-
-LLPathfindingNavMeshZone::ENavMeshZoneStatus LLPathfindingNavMeshZone::getNavMeshZoneStatus() const
-{
-	bool hasPending = false;
-	bool hasBuilding = false;
-	bool hasComplete = false;
-	bool hasRepending = false;
-
-	for (NavMeshLocationPtrs::const_iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
-		navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
-	{
-		const NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
-
-		switch (navMeshLocationPtr->getNavMeshStatus())
-		{
-		case LLPathfindingNavMeshStatus::kPending :
-			hasPending = true;
-			break;
-		case LLPathfindingNavMeshStatus::kBuilding :
-			hasBuilding = true;
-			break;
-		case LLPathfindingNavMeshStatus::kComplete :
-			hasComplete = true;
-			break;
-		case LLPathfindingNavMeshStatus::kRepending :
-			hasRepending = true;
-			break;
-		default :
-			hasPending = true;
-			llassert(0);
-			break;
-		}
-	}
-
-	ENavMeshZoneStatus zoneStatus = kNavMeshZoneComplete;
-	if (hasRepending || (hasPending && hasBuilding))
-	{
-		zoneStatus = kNavMeshZonePendingAndBuilding;
-	}
-	else if (hasComplete)
-	{
-		if (hasPending)
-		{
-			zoneStatus = kNavMeshZoneSomePending;
-		}
-		else if (hasBuilding)
-		{
-			zoneStatus = kNavMeshZoneSomeBuilding;
-		}
-		else
-		{
-			zoneStatus = kNavMeshZoneComplete;
-		}
-	}
-	else if (hasPending)
-	{
-		zoneStatus = kNavMeshZonePending;
-	}
-	else if (hasBuilding)
-	{
-		zoneStatus = kNavMeshZoneBuilding;
-	}
-
-	return zoneStatus;
-}
-
-void LLPathfindingNavMeshZone::handleNavMeshLocation()
-{
-	updateStatus();
-}
-
-void LLPathfindingNavMeshZone::updateStatus()
-{
-	bool hasRequestUnknown = false;
-	bool hasRequestChecking = false;
-	bool hasRequestNeedsUpdate = false;
-	bool hasRequestStarted = false;
-	bool hasRequestCompleted = false;
-	bool hasRequestNotEnabled = false;
-	bool hasRequestError = false;
-
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-	llinfos << "STINSON DEBUG: Navmesh zone update BEGIN" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-	for (NavMeshLocationPtrs::const_iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
-		navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
-	{
-		const NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG:    region #" << navMeshLocationPtr->getDirection() << ": region(" << navMeshLocationPtr->getRegionUUID().asString() << ") status:" << navMeshLocationPtr->getRequestStatus() << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-		switch (navMeshLocationPtr->getRequestStatus())
-		{
-		case LLPathfindingNavMesh::kNavMeshRequestUnknown :
-			hasRequestUnknown = true;
-			break;
-		case LLPathfindingNavMesh::kNavMeshRequestChecking :
-			hasRequestChecking = true;
-			break;
-		case LLPathfindingNavMesh::kNavMeshRequestNeedsUpdate :
-			hasRequestNeedsUpdate = true;
-			break;
-		case LLPathfindingNavMesh::kNavMeshRequestStarted :
-			hasRequestStarted = true;
-			break;
-		case LLPathfindingNavMesh::kNavMeshRequestCompleted :
-			hasRequestCompleted = true;
-			break;
-		case LLPathfindingNavMesh::kNavMeshRequestNotEnabled :
-			hasRequestNotEnabled = true;
-			break;
-		case LLPathfindingNavMesh::kNavMeshRequestError :
-			hasRequestError = true;
-			break;
-		default :
-			hasRequestError = true;
-			llassert(0);
-			break;
-		}
-	}
-
-	ENavMeshZoneRequestStatus zoneRequestStatus = kNavMeshZoneRequestUnknown;
-	if (hasRequestNeedsUpdate)
-	{
-		zoneRequestStatus = kNavMeshZoneRequestNeedsUpdate;
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG: Navmesh zone update is NEEDS UPDATE" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-	}
-	else if (hasRequestChecking)
-	{
-		zoneRequestStatus = kNavMeshZoneRequestChecking;
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG: Navmesh zone update is CHECKING" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-	}
-	else if (hasRequestStarted)
-	{
-		zoneRequestStatus = kNavMeshZoneRequestStarted;
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG: Navmesh zone update is STARTED" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-	}
-	else if (hasRequestError)
-	{
-		zoneRequestStatus = kNavMeshZoneRequestError;
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG: Navmesh zone update is ERROR" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-	}
-	else if (hasRequestUnknown)
-	{
-		zoneRequestStatus = kNavMeshZoneRequestUnknown;
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG: Navmesh zone update is UNKNOWN" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-	}
-	else if (hasRequestCompleted)
-	{
-		zoneRequestStatus = kNavMeshZoneRequestCompleted;
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG: Navmesh zone update is COMPLETED" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-	}
-	else if (hasRequestNotEnabled)
-	{
-		zoneRequestStatus = kNavMeshZoneRequestNotEnabled;
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG: Navmesh zone update is NOT ENABLED" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-	}
-	else
-	{
-		zoneRequestStatus = kNavMeshZoneRequestError;
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG: Navmesh zone update is BAD ERROR" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llassert(0);
-	}
-
-	if ((mNavMeshZoneRequestStatus != kNavMeshZoneRequestCompleted) &&
-		(zoneRequestStatus == kNavMeshZoneRequestCompleted))
-	{
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG: Navmesh zone update is stitching" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llassert(LLPathingLib::getInstance() != NULL);
-		if (LLPathingLib::getInstance() != NULL)
-		{
-			LLPathingLib::getInstance()->stitchNavMeshes( gSavedSettings.getBOOL("EnableVBOForNavMeshVisualization") );
-		}
-#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
-		llinfos << "STINSON DEBUG: Navmesh zone update stitching is done" << llendl;
-#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
-	}
-
-	mNavMeshZoneRequestStatus = zoneRequestStatus;
-	mNavMeshZoneSignal(mNavMeshZoneRequestStatus);
-}
-
-//---------------------------------------------------------------------------
-// LLPathfindingNavMeshZone::NavMeshLocation
-//---------------------------------------------------------------------------
-
-LLPathfindingNavMeshZone::NavMeshLocation::NavMeshLocation(S32 pDirection, navmesh_location_callback_t pLocationCallback)
-	: mDirection(pDirection),
-	mRegionUUID(),
-	mHasNavMesh(false),
-	mNavMeshVersion(0U),
-	mNavMeshStatus(LLPathfindingNavMeshStatus::kComplete),
-	mLocationCallback(pLocationCallback),
-	mRequestStatus(LLPathfindingNavMesh::kNavMeshRequestUnknown),
-	mNavMeshSlot()
-{
-}
-
-LLPathfindingNavMeshZone::NavMeshLocation::~NavMeshLocation()
-{
-}
-
-void LLPathfindingNavMeshZone::NavMeshLocation::enable()
-{
-	clear();
-
-	LLViewerRegion *region = getRegion();
-	if (region == NULL)
-	{
-		mRegionUUID.setNull();
-	}
-	else
-	{
-		mRegionUUID = region->getRegionID();
-		mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(region, boost::bind(&LLPathfindingNavMeshZone::NavMeshLocation::handleNavMesh, this, _1, _2, _3));
-	}
-}
-
-void LLPathfindingNavMeshZone::NavMeshLocation::refresh()
-{
-	LLViewerRegion *region = getRegion();
-
-	if (region == NULL)
-	{
-		llassert(mRegionUUID.isNull());
-		LLPathfindingNavMeshStatus newNavMeshStatus(mRegionUUID);
-		LLSD::Binary nullData;
-		handleNavMesh(LLPathfindingNavMesh::kNavMeshRequestNotEnabled, newNavMeshStatus, nullData);
-	}
-	else
-	{
-		llassert(mRegionUUID == region->getRegionID());
-		LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(region);
-	}
-}
-
-void LLPathfindingNavMeshZone::NavMeshLocation::disable()
-{
-	clear();
-}
-
-LLPathfindingNavMesh::ENavMeshRequestStatus LLPathfindingNavMeshZone::NavMeshLocation::getRequestStatus() const
-{
-	return mRequestStatus;
-}
-
-LLPathfindingNavMeshStatus::ENavMeshStatus LLPathfindingNavMeshZone::NavMeshLocation::getNavMeshStatus() const
-{
-	return mNavMeshStatus;
-}
-
-void LLPathfindingNavMeshZone::NavMeshLocation::handleNavMesh(LLPathfindingNavMesh::ENavMeshRequestStatus pNavMeshRequestStatus, const LLPathfindingNavMeshStatus &pNavMeshStatus, const LLSD::Binary &pNavMeshData)
-{
-	llassert(mRegionUUID == pNavMeshStatus.getRegionUUID());
-
-	if ((pNavMeshRequestStatus == LLPathfindingNavMesh::kNavMeshRequestCompleted) &&
-		(!mHasNavMesh || (mNavMeshVersion != pNavMeshStatus.getVersion())))
-	{
-		llassert(!pNavMeshData.empty());
-		mHasNavMesh = true;
-		mNavMeshVersion = pNavMeshStatus.getVersion();
-		llassert(LLPathingLib::getInstance() != NULL);
-		if (LLPathingLib::getInstance() != NULL)
-		{
-			LLPathingLib::getInstance()->extractNavMeshSrcFromLLSD(pNavMeshData, mDirection);
-		}
-	}
-
-	mRequestStatus = pNavMeshRequestStatus;
-	mNavMeshStatus = pNavMeshStatus.getStatus();
-	mLocationCallback();
-}
-
-void LLPathfindingNavMeshZone::NavMeshLocation::clear()
-{
-	mHasNavMesh = false;
-	mRequestStatus = LLPathfindingNavMesh::kNavMeshRequestUnknown;
-	mNavMeshStatus = LLPathfindingNavMeshStatus::kComplete;
-	if (mNavMeshSlot.connected())
-	{
-		mNavMeshSlot.disconnect();
-	}
-}
-
-LLViewerRegion *LLPathfindingNavMeshZone::NavMeshLocation::getRegion() const
-{
-	LLViewerRegion *region = NULL;
-
-	LLViewerRegion *currentRegion = gAgent.getRegion();
-	if (currentRegion != NULL)
-	{
-		if (mDirection == CENTER_REGION)
-		{
-			region = currentRegion;
-		}
-		else
-		{
-			//User wants to pull in a neighboring region
-			std::vector<S32> availableRegions;
-			currentRegion->getNeighboringRegionsStatus( availableRegions );
-			//Is the desired region in the available list
-			std::vector<S32>::iterator foundElem = std::find(availableRegions.begin(),availableRegions.end(),mDirection); 
-			if ( foundElem != availableRegions.end() )
-			{
-				std::vector<LLViewerRegion*> neighborRegionsPtrs;
-				currentRegion->getNeighboringRegions( neighborRegionsPtrs );
-				region = neighborRegionsPtrs[foundElem - availableRegions.begin()];
-			}
-		}
-	}
-
-	return region;
-}
+/** 
+ * @file llpathfindingnavmeshzone.cpp
+ * @author William Todd Stinson
+ * @brief A class for representing the zone of navmeshes containing and possible surrounding the current region.
+ *
+ * $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 "llsd.h"
+#include "lluuid.h"
+#include "llagent.h"
+#include "llviewerregion.h"
+#include "llpathfindingnavmesh.h"
+#include "llpathfindingnavmeshzone.h"
+#include "llpathfindingmanager.h"
+#include "llviewercontrol.h"
+
+#include "LLPathingLib.h"
+
+#include <string>
+#include <vector>
+
+#include <boost/bind.hpp>
+
+#define CENTER_REGION 99
+
+//---------------------------------------------------------------------------
+// LLPathfindingNavMeshZone
+//---------------------------------------------------------------------------
+
+LLPathfindingNavMeshZone::LLPathfindingNavMeshZone()
+	: mNavMeshLocationPtrs(),
+	mNavMeshZoneRequestStatus(kNavMeshZoneRequestUnknown),
+	mNavMeshZoneSignal()
+{
+}
+
+LLPathfindingNavMeshZone::~LLPathfindingNavMeshZone()
+{
+}
+
+LLPathfindingNavMeshZone::navmesh_zone_slot_t LLPathfindingNavMeshZone::registerNavMeshZoneListener(navmesh_zone_callback_t pNavMeshZoneCallback)
+{
+	return mNavMeshZoneSignal.connect(pNavMeshZoneCallback);
+}
+
+void LLPathfindingNavMeshZone::initialize()
+{
+	mNavMeshLocationPtrs.clear();
+
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+	LLViewerRegion *currentRegion = gAgent.getRegion();
+	if (currentRegion != NULL)
+	{
+		llinfos << "STINSON DEBUG: currentRegion: '" << currentRegion->getName() << "' (" << currentRegion->getRegionID().asString() << ")" << llendl;
+		std::vector<S32> availableRegions;
+		currentRegion->getNeighboringRegionsStatus( availableRegions );
+		std::vector<LLViewerRegion*> neighborRegionsPtrs;
+		currentRegion->getNeighboringRegions( neighborRegionsPtrs );
+		for (std::vector<S32>::const_iterator statusIter = availableRegions.begin();
+			statusIter != availableRegions.end(); ++statusIter)
+		{
+			LLViewerRegion *region = neighborRegionsPtrs[statusIter - availableRegions.begin()];
+			llinfos << "STINSON DEBUG: region #" << *statusIter << ": '" << region->getName() << "' (" << region->getRegionID().asString() << ")" << llendl;
+		}
+ 	}
+
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+	NavMeshLocationPtr centerNavMeshPtr(new NavMeshLocation(CENTER_REGION, boost::bind(&LLPathfindingNavMeshZone::handleNavMeshLocation, this)));
+	mNavMeshLocationPtrs.push_back(centerNavMeshPtr);
+
+	U32 neighborRegionDir = gSavedSettings.getU32("RetrieveNeighboringRegion");
+	if (neighborRegionDir != CENTER_REGION)
+	{
+		NavMeshLocationPtr neighborNavMeshPtr(new NavMeshLocation(neighborRegionDir, boost::bind(&LLPathfindingNavMeshZone::handleNavMeshLocation, this)));
+		mNavMeshLocationPtrs.push_back(neighborNavMeshPtr);
+	}
+}
+
+void LLPathfindingNavMeshZone::enable()
+{
+	for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
+		navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
+	{
+		NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+		navMeshLocationPtr->enable();
+	}
+}
+
+void LLPathfindingNavMeshZone::disable()
+{
+	for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
+		navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
+	{
+		NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+		navMeshLocationPtr->disable();
+	}
+}
+
+void LLPathfindingNavMeshZone::refresh()
+{
+	llassert(LLPathingLib::getInstance() != NULL);
+	if (LLPathingLib::getInstance() != NULL)
+	{
+		LLPathingLib::getInstance()->cleanupResidual();
+	}
+
+	for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
+		navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
+	{
+		NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+		navMeshLocationPtr->refresh();
+	}
+}
+
+LLPathfindingNavMeshZone::ENavMeshZoneStatus LLPathfindingNavMeshZone::getNavMeshZoneStatus() const
+{
+	bool hasPending = false;
+	bool hasBuilding = false;
+	bool hasComplete = false;
+	bool hasRepending = false;
+
+	for (NavMeshLocationPtrs::const_iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
+		navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
+	{
+		const NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+
+		switch (navMeshLocationPtr->getNavMeshStatus())
+		{
+		case LLPathfindingNavMeshStatus::kPending :
+			hasPending = true;
+			break;
+		case LLPathfindingNavMeshStatus::kBuilding :
+			hasBuilding = true;
+			break;
+		case LLPathfindingNavMeshStatus::kComplete :
+			hasComplete = true;
+			break;
+		case LLPathfindingNavMeshStatus::kRepending :
+			hasRepending = true;
+			break;
+		default :
+			hasPending = true;
+			llassert(0);
+			break;
+		}
+	}
+
+	ENavMeshZoneStatus zoneStatus = kNavMeshZoneComplete;
+	if (hasRepending || (hasPending && hasBuilding))
+	{
+		zoneStatus = kNavMeshZonePendingAndBuilding;
+	}
+	else if (hasComplete)
+	{
+		if (hasPending)
+		{
+			zoneStatus = kNavMeshZoneSomePending;
+		}
+		else if (hasBuilding)
+		{
+			zoneStatus = kNavMeshZoneSomeBuilding;
+		}
+		else
+		{
+			zoneStatus = kNavMeshZoneComplete;
+		}
+	}
+	else if (hasPending)
+	{
+		zoneStatus = kNavMeshZonePending;
+	}
+	else if (hasBuilding)
+	{
+		zoneStatus = kNavMeshZoneBuilding;
+	}
+
+	return zoneStatus;
+}
+
+void LLPathfindingNavMeshZone::handleNavMeshLocation()
+{
+	updateStatus();
+}
+
+void LLPathfindingNavMeshZone::updateStatus()
+{
+	bool hasRequestUnknown = false;
+	bool hasRequestChecking = false;
+	bool hasRequestNeedsUpdate = false;
+	bool hasRequestStarted = false;
+	bool hasRequestCompleted = false;
+	bool hasRequestNotEnabled = false;
+	bool hasRequestError = false;
+
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+	llinfos << "STINSON DEBUG: Navmesh zone update BEGIN" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+	for (NavMeshLocationPtrs::const_iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
+		navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
+	{
+		const NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG:    region #" << navMeshLocationPtr->getDirection() << ": region(" << navMeshLocationPtr->getRegionUUID().asString() << ") status:" << navMeshLocationPtr->getRequestStatus() << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+		switch (navMeshLocationPtr->getRequestStatus())
+		{
+		case LLPathfindingNavMesh::kNavMeshRequestUnknown :
+			hasRequestUnknown = true;
+			break;
+		case LLPathfindingNavMesh::kNavMeshRequestChecking :
+			hasRequestChecking = true;
+			break;
+		case LLPathfindingNavMesh::kNavMeshRequestNeedsUpdate :
+			hasRequestNeedsUpdate = true;
+			break;
+		case LLPathfindingNavMesh::kNavMeshRequestStarted :
+			hasRequestStarted = true;
+			break;
+		case LLPathfindingNavMesh::kNavMeshRequestCompleted :
+			hasRequestCompleted = true;
+			break;
+		case LLPathfindingNavMesh::kNavMeshRequestNotEnabled :
+			hasRequestNotEnabled = true;
+			break;
+		case LLPathfindingNavMesh::kNavMeshRequestError :
+			hasRequestError = true;
+			break;
+		default :
+			hasRequestError = true;
+			llassert(0);
+			break;
+		}
+	}
+
+	ENavMeshZoneRequestStatus zoneRequestStatus = kNavMeshZoneRequestUnknown;
+	if (hasRequestNeedsUpdate)
+	{
+		zoneRequestStatus = kNavMeshZoneRequestNeedsUpdate;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG: Navmesh zone update is NEEDS UPDATE" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+	}
+	else if (hasRequestChecking)
+	{
+		zoneRequestStatus = kNavMeshZoneRequestChecking;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG: Navmesh zone update is CHECKING" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+	}
+	else if (hasRequestStarted)
+	{
+		zoneRequestStatus = kNavMeshZoneRequestStarted;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG: Navmesh zone update is STARTED" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+	}
+	else if (hasRequestError)
+	{
+		zoneRequestStatus = kNavMeshZoneRequestError;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG: Navmesh zone update is ERROR" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+	}
+	else if (hasRequestUnknown)
+	{
+		zoneRequestStatus = kNavMeshZoneRequestUnknown;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG: Navmesh zone update is UNKNOWN" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+	}
+	else if (hasRequestCompleted)
+	{
+		zoneRequestStatus = kNavMeshZoneRequestCompleted;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG: Navmesh zone update is COMPLETED" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+	}
+	else if (hasRequestNotEnabled)
+	{
+		zoneRequestStatus = kNavMeshZoneRequestNotEnabled;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG: Navmesh zone update is NOT ENABLED" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+	}
+	else
+	{
+		zoneRequestStatus = kNavMeshZoneRequestError;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG: Navmesh zone update is BAD ERROR" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llassert(0);
+	}
+
+	if ((mNavMeshZoneRequestStatus != kNavMeshZoneRequestCompleted) &&
+		(zoneRequestStatus == kNavMeshZoneRequestCompleted))
+	{
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG: Navmesh zone update is stitching" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llassert(LLPathingLib::getInstance() != NULL);
+		if (LLPathingLib::getInstance() != NULL)
+		{
+			LLPathingLib::getInstance()->stitchNavMeshes();
+		}
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+		llinfos << "STINSON DEBUG: Navmesh zone update stitching is done" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+	}
+
+	mNavMeshZoneRequestStatus = zoneRequestStatus;
+	mNavMeshZoneSignal(mNavMeshZoneRequestStatus);
+}
+
+//---------------------------------------------------------------------------
+// LLPathfindingNavMeshZone::NavMeshLocation
+//---------------------------------------------------------------------------
+
+LLPathfindingNavMeshZone::NavMeshLocation::NavMeshLocation(S32 pDirection, navmesh_location_callback_t pLocationCallback)
+	: mDirection(pDirection),
+	mRegionUUID(),
+	mHasNavMesh(false),
+	mNavMeshVersion(0U),
+	mNavMeshStatus(LLPathfindingNavMeshStatus::kComplete),
+	mLocationCallback(pLocationCallback),
+	mRequestStatus(LLPathfindingNavMesh::kNavMeshRequestUnknown),
+	mNavMeshSlot()
+{
+}
+
+LLPathfindingNavMeshZone::NavMeshLocation::~NavMeshLocation()
+{
+}
+
+void LLPathfindingNavMeshZone::NavMeshLocation::enable()
+{
+	clear();
+
+	LLViewerRegion *region = getRegion();
+	if (region == NULL)
+	{
+		mRegionUUID.setNull();
+	}
+	else
+	{
+		mRegionUUID = region->getRegionID();
+		mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(region, boost::bind(&LLPathfindingNavMeshZone::NavMeshLocation::handleNavMesh, this, _1, _2, _3));
+	}
+}
+
+void LLPathfindingNavMeshZone::NavMeshLocation::refresh()
+{
+	LLViewerRegion *region = getRegion();
+
+	if (region == NULL)
+	{
+		llassert(mRegionUUID.isNull());
+		LLPathfindingNavMeshStatus newNavMeshStatus(mRegionUUID);
+		LLSD::Binary nullData;
+		handleNavMesh(LLPathfindingNavMesh::kNavMeshRequestNotEnabled, newNavMeshStatus, nullData);
+	}
+	else
+	{
+		llassert(mRegionUUID == region->getRegionID());
+		LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(region);
+	}
+}
+
+void LLPathfindingNavMeshZone::NavMeshLocation::disable()
+{
+	clear();
+}
+
+LLPathfindingNavMesh::ENavMeshRequestStatus LLPathfindingNavMeshZone::NavMeshLocation::getRequestStatus() const
+{
+	return mRequestStatus;
+}
+
+LLPathfindingNavMeshStatus::ENavMeshStatus LLPathfindingNavMeshZone::NavMeshLocation::getNavMeshStatus() const
+{
+	return mNavMeshStatus;
+}
+
+void LLPathfindingNavMeshZone::NavMeshLocation::handleNavMesh(LLPathfindingNavMesh::ENavMeshRequestStatus pNavMeshRequestStatus, const LLPathfindingNavMeshStatus &pNavMeshStatus, const LLSD::Binary &pNavMeshData)
+{
+	llassert(mRegionUUID == pNavMeshStatus.getRegionUUID());
+
+	if ((pNavMeshRequestStatus == LLPathfindingNavMesh::kNavMeshRequestCompleted) &&
+		(!mHasNavMesh || (mNavMeshVersion != pNavMeshStatus.getVersion())))
+	{
+		llassert(!pNavMeshData.empty());
+		mHasNavMesh = true;
+		mNavMeshVersion = pNavMeshStatus.getVersion();
+		llassert(LLPathingLib::getInstance() != NULL);
+		if (LLPathingLib::getInstance() != NULL)
+		{
+			LLPathingLib::getInstance()->extractNavMeshSrcFromLLSD(pNavMeshData, mDirection);
+		}
+	}
+
+	mRequestStatus = pNavMeshRequestStatus;
+	mNavMeshStatus = pNavMeshStatus.getStatus();
+	mLocationCallback();
+}
+
+void LLPathfindingNavMeshZone::NavMeshLocation::clear()
+{
+	mHasNavMesh = false;
+	mRequestStatus = LLPathfindingNavMesh::kNavMeshRequestUnknown;
+	mNavMeshStatus = LLPathfindingNavMeshStatus::kComplete;
+	if (mNavMeshSlot.connected())
+	{
+		mNavMeshSlot.disconnect();
+	}
+}
+
+LLViewerRegion *LLPathfindingNavMeshZone::NavMeshLocation::getRegion() const
+{
+	LLViewerRegion *region = NULL;
+
+	LLViewerRegion *currentRegion = gAgent.getRegion();
+	if (currentRegion != NULL)
+	{
+		if (mDirection == CENTER_REGION)
+		{
+			region = currentRegion;
+		}
+		else
+		{
+			//User wants to pull in a neighboring region
+			std::vector<S32> availableRegions;
+			currentRegion->getNeighboringRegionsStatus( availableRegions );
+			//Is the desired region in the available list
+			std::vector<S32>::iterator foundElem = std::find(availableRegions.begin(),availableRegions.end(),mDirection); 
+			if ( foundElem != availableRegions.end() )
+			{
+				std::vector<LLViewerRegion*> neighborRegionsPtrs;
+				currentRegion->getNeighboringRegions( neighborRegionsPtrs );
+				region = neighborRegionsPtrs[foundElem - availableRegions.begin()];
+			}
+		}
+	}
+
+	return region;
+}