diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 5302ae2636142de5f88ed79fbc915dd6e05abf49..6ee8f26b9fa6b2887d45bf11cfd9087686920f61 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -850,7 +850,6 @@ boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_cal
 //-----------------------------------------------------------------------------
 void LLAgent::setRegion(LLViewerRegion *regionp)
 {
-	bool teleport = true;
 	bool notifyRegionChange;
 	
 	llassert(regionp);
@@ -888,9 +887,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 			{
 				gSky.mVOGroundp->setRegion(regionp);
 			}
-
-			// Notify windlight managers
-			teleport = (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE);
 		}
 		else
 		{
@@ -938,15 +934,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 
 	LLFloaterMove::sUpdateFlyingStatus();
 
-	if (teleport)
-	{
-		LLEnvManagerNew::instance().onTeleport();
-	}
-	else
-	{
-		LLEnvManagerNew::instance().onRegionCrossing();
-	}
-
 	// If the newly entered region is using server bakes, and our
 	// current appearance is non-baked, request appearance update from
 	// server.
diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp
index 86fe6754dc8d652217d50bc6226552d440d06d22..589cf28615ac2a0e1d1342b3cb680765c93284a8 100755
--- a/indra/newview/llenvmanager.cpp
+++ b/indra/newview/llenvmanager.cpp
@@ -92,9 +92,11 @@ void LLEnvPrefs::setUseDayCycle(const std::string& name)
 }
 
 //=============================================================================
-LLEnvManagerNew::LLEnvManagerNew()
+LLEnvManagerNew::LLEnvManagerNew():
+	mInterpNextChangeMessage(true),
+	mCurRegionUUID(LLUUID::null),
+	mLastReceivedID(LLUUID::null)
 {
-	mInterpNextChangeMessage = true;
 
 	// Set default environment settings.
 	mUserPrefs.mUseRegionSettings = true;
@@ -102,6 +104,9 @@ LLEnvManagerNew::LLEnvManagerNew()
 	mUserPrefs.mWaterPresetName = "Default";
 	mUserPrefs.mSkyPresetName = "Default";
 	mUserPrefs.mDayCycleName = "Default";
+
+	LL_DEBUGS("Windlight")<<LL_ENDL;
+	gAgent.addRegionChangedCallback(boost::bind(&LLEnvManagerNew::onRegionChange, this));
 }
 
 bool LLEnvManagerNew::getUseRegionSettings() const
@@ -300,6 +305,11 @@ void LLEnvManagerNew::loadUserPrefs()
 
 	mUserPrefs.mUseRegionSettings	= gSavedSettings.getBOOL("UseEnvironmentFromRegion");
 	mUserPrefs.mUseDayCycle			= gSavedSettings.getBOOL("UseDayCycle");
+
+	if (mUserPrefs.mUseRegionSettings)
+	{
+		requestRegionSettings();
+	}
 }
 
 void LLEnvManagerNew::saveUserPrefs()
@@ -398,6 +408,7 @@ void LLEnvManagerNew::dumpPresets()
 
 void LLEnvManagerNew::requestRegionSettings()
 {
+	LL_DEBUGS("Windlight") << LL_ENDL;
 	LLEnvironmentRequest::initiate();
 }
 
@@ -422,11 +433,6 @@ boost::signals2::connection LLEnvManagerNew::setRegionSettingsChangeCallback(con
 	return mRegionSettingsChangeSignal.connect(cb);
 }
 
-boost::signals2::connection LLEnvManagerNew::setRegionChangeCallback(const region_change_signal_t::slot_type& cb)
-{
-	return mRegionChangeSignal.connect(cb);
-}
-
 boost::signals2::connection LLEnvManagerNew::setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb)
 {
 	return mRegionSettingsAppliedSignal.connect(cb);
@@ -457,25 +463,13 @@ const std::string LLEnvManagerNew::getScopeString(LLEnvKey::EScope scope)
 	}
 }
 
-void LLEnvManagerNew::onRegionCrossing()
-{
-	LL_DEBUGS("Windlight") << "Crossed region" << LL_ENDL;
-	onRegionChange(true);
-}
-
-void LLEnvManagerNew::onTeleport()
-{
-	LL_DEBUGS("Windlight") << "Teleported" << LL_ENDL;
-	onRegionChange(false);
-}
-
 void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content)
 {
 	// If the message was valid, grab the UUID from it and save it for next outbound update message.
 	mLastReceivedID = content[0]["messageID"].asUUID();
 
 	// Refresh cached region settings.
-	LL_DEBUGS("Windlight") << "Caching region environment settings: " << content << LL_ENDL;
+	LL_DEBUGS("Windlight") << "Received region environment settings: " << content << LL_ENDL;
 	F32 sun_hour = 0; // *TODO
 	LLEnvironmentSettings new_settings(content[1], content[2], content[3], sun_hour);
 	mCachedRegionPrefs = new_settings;
@@ -594,6 +588,7 @@ void LLEnvManagerNew::updateWaterFromPrefs(bool interpolate)
 
 void LLEnvManagerNew::updateManagersFromPrefs(bool interpolate)
 {
+	LL_DEBUGS("Windlight")<<LL_ENDL;
 	// Apply water settings.
 	updateWaterFromPrefs(interpolate);
 
@@ -651,28 +646,35 @@ bool LLEnvManagerNew::useDefaultWater()
 }
 
 
-void LLEnvManagerNew::onRegionChange(bool interpolate)
+void LLEnvManagerNew::onRegionChange()
 {
 	// Avoid duplicating region setting requests
 	// by checking whether the region is actually changing.
 	LLViewerRegion* regionp = gAgent.getRegion();
 	LLUUID region_uuid = regionp ? regionp->getRegionID() : LLUUID::null;
-	if (region_uuid == mCurRegionUUID)
+	if (region_uuid != mCurRegionUUID)
 	{
-		return;
+		// Clear locally modified region settings.
+		mNewRegionPrefs.clear();
+
+		// *TODO: clear environment settings of the previous region?
+
+		// Request environment settings of the new region.
+		mCurRegionUUID = region_uuid;
+		// for region crossings, interpolate the change; for teleports, don't
+		mInterpNextChangeMessage = (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE);
+		LL_DEBUGS("Windlight") << (mInterpNextChangeMessage ? "Crossed" : "Teleported")
+							   << " to new region: " << region_uuid
+							   << LL_ENDL;
+		requestRegionSettings();
+	}
+	else
+	{
+		LL_DEBUGS("Windlight") << "disregarding region change; interp: "
+							   << (mInterpNextChangeMessage ? "true" : "false")
+							   << " regionp: " << regionp
+							   << " old: " << mCurRegionUUID
+							   << " new: " << region_uuid
+							   << LL_ENDL;
 	}
-
-	// Clear locally modified region settings.
-	mNewRegionPrefs.clear();
-
-	// *TODO: clear environment settings of the previous region?
-
-	// Request environment settings of the new region.
-	LL_DEBUGS("Windlight") << "New viewer region: " << region_uuid << LL_ENDL;
-	mCurRegionUUID = region_uuid;
-	mInterpNextChangeMessage = interpolate;
-	requestRegionSettings();
-
-	// Let interested parties know agent region has been changed.
-	mRegionChangeSignal();
 }
diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h
index ad56761bc772e2a5c4921fd63667e629503c6d7c..c7877303fc1a507ed2b234b781d950b5706edade 100755
--- a/indra/newview/llenvmanager.h
+++ b/indra/newview/llenvmanager.h
@@ -166,7 +166,6 @@ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew>
 public:
 	typedef boost::signals2::signal<void()> prefs_change_signal_t;
 	typedef boost::signals2::signal<void()> region_settings_change_signal_t;
-	typedef boost::signals2::signal<void()> region_change_signal_t;
 	typedef boost::signals2::signal<void(bool)> region_settings_applied_signal_t;
 
 	LLEnvManagerNew();
@@ -222,15 +221,12 @@ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew>
 	bool sendRegionSettings(const LLEnvironmentSettings& new_settings);
 	boost::signals2::connection setPreferencesChangeCallback(const prefs_change_signal_t::slot_type& cb);
 	boost::signals2::connection setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb);
-	boost::signals2::connection setRegionChangeCallback(const region_change_signal_t::slot_type& cb);
 	boost::signals2::connection setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb);
 
 	static bool canEditRegionSettings(); /// @return true if we have access to editing region environment
 	static const std::string getScopeString(LLEnvKey::EScope scope);
 
 	// Public callbacks.
-	void onRegionCrossing();
-	void onTeleport();
 	void onRegionSettingsResponse(const LLSD& content);
 	void onRegionSettingsApplyResponse(bool ok);
 
@@ -251,7 +247,7 @@ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew>
 	bool useDefaultSky();
 	bool useDefaultWater();
 
-	void onRegionChange(bool interpolate);
+	void onRegionChange();
 
 	/// Emitted when user environment preferences change.
 	prefs_change_signal_t mUsePrefsChangeSignal;
@@ -259,9 +255,6 @@ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew>
 	/// Emitted when region environment settings update comes.
 	region_settings_change_signal_t	mRegionSettingsChangeSignal;
 
-	/// Emitted when agent region changes. Move to LLAgent?
-	region_change_signal_t	mRegionChangeSignal;
-
 	/// Emitted when agent region changes. Move to LLAgent?
 	region_settings_applied_signal_t mRegionSettingsAppliedSignal;
 
diff --git a/indra/newview/llfloatereditdaycycle.cpp b/indra/newview/llfloatereditdaycycle.cpp
index b63677b258e8ad264c85fabb51aecdc7c6ff857d..78e20e3bf0652bff13e6be6af0ffc57d253c3b87 100755
--- a/indra/newview/llfloatereditdaycycle.cpp
+++ b/indra/newview/llfloatereditdaycycle.cpp
@@ -145,7 +145,7 @@ void LLFloaterEditDayCycle::initCallbacks(void)
 	// Connect to env manager events.
 	LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
 	env_mgr.setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsChange, this));
-	env_mgr.setRegionChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionChange, this));
+	gAgent.addRegionChangedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionChange, this));
 	env_mgr.setRegionSettingsAppliedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsApplied, this, _1));
 
 	// Connect to day cycle manager events.
diff --git a/indra/newview/llfloaterpathfindingconsole.cpp b/indra/newview/llfloaterpathfindingconsole.cpp
index 298454724b8f9fcce39d3edb1d068a2255bd79e5..161259d0495ced768d98f0b15cf01bf420c8623d 100755
--- a/indra/newview/llfloaterpathfindingconsole.cpp
+++ b/indra/newview/llfloaterpathfindingconsole.cpp
@@ -34,11 +34,11 @@
 
 #include <boost/signals2.hpp>
 
+#include "llagent.h"
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
 #include "llcombobox.h"
 #include "llcontrol.h"
-#include "llenvmanager.h"
 #include "llfloaterpathfindingcharacters.h"
 #include "llfloaterpathfindinglinksets.h"
 #include "llfloaterreg.h"
@@ -224,7 +224,7 @@ void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey)
 
 	if (!mRegionBoundarySlot.connected())
 	{
-		mRegionBoundarySlot = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterPathfindingConsole::onRegionBoundaryCross, this));
+		mRegionBoundarySlot = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterPathfindingConsole::onRegionBoundaryCross, this));
 	}
 
 	if (!mTeleportFailedSlot.connected())
diff --git a/indra/newview/llfloaterpathfindingobjects.cpp b/indra/newview/llfloaterpathfindingobjects.cpp
index 20c1215bcb66f92594c962b570cc55ba23c1fdf7..d72ee073e10bc24efc23b7528b251341d40eb9e7 100755
--- a/indra/newview/llfloaterpathfindingobjects.cpp
+++ b/indra/newview/llfloaterpathfindingobjects.cpp
@@ -41,7 +41,6 @@
 #include "llavatarnamecache.h"
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
-#include "llenvmanager.h"
 #include "llfloater.h"
 #include "llfontgl.h"
 #include "llnotifications.h"
@@ -85,7 +84,7 @@ void LLFloaterPathfindingObjects::onOpen(const LLSD &pKey)
 
 	if (!mRegionBoundaryCrossingSlot.connected())
 	{
-		mRegionBoundaryCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLFloaterPathfindingObjects::onRegionBoundaryCrossed, this));
+		mRegionBoundaryCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterPathfindingObjects::onRegionBoundaryCrossed, this));
 	}
 
 	if (!mGodLevelChangeSlot.connected())
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 66bf49331b7e06200d56d9909f0ee6941eabf251..ed0209f90ba340d2c19d1e505c7c955e847217b5 100755
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -219,7 +219,7 @@ BOOL LLFloaterRegionInfo::postBuild()
 		&processEstateOwnerRequest);
 
 	// Request region info when agent region changes.
-	LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterRegionInfo::requestRegionInfo, this));
+	gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::requestRegionInfo, this));
 
 	return TRUE;
 }
diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
index a567d1217a1b049db2695c742ec54c9e4bc906e3..8879cfd7fbf8ed593b4ba58df20737bbdf3766c0 100755
--- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
+++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
@@ -79,7 +79,7 @@ void LLMenuOptionPathfindingRebakeNavmesh::initialize()
 
 		if ( !mRegionCrossingSlot.connected() )
 		{
-			mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this));
+			mRegionCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this));
 		}
 
 		if (!mAgentStateSlot.connected())