diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index d7c39ff78d85b01eb9d054068e16daf713ccdb97..fb217f218675441fb88037bfa0b998a2848dd003 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -320,6 +320,12 @@ LLAgent::LLAgent() :
 	mAgentAccess(new LLAgentAccess(gSavedSettings)),
 	mCanEditParcel(false),
 	mTeleportSourceSLURL(new LLSLURL),
+	mCurrentTeleportRequest(),
+	mFailedTeleportRequest(),
+	mTeleportFinishedSlot(),
+	mTeleportFailedSlot(),
+	mIsMaturityRatingChangingDuringTeleport(false),
+	mMaturityRatingChange(0),
 	mTeleportState( TELEPORT_NONE ),
 	mRegionp(NULL),
 
@@ -406,7 +412,14 @@ void LLAgent::init()
 	gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2));
 	gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2));
 
-	LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback));
+	if (!mTeleportFinishedSlot.connected())
+	{
+		mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this));
+	}
+	if (!mTeleportFailedSlot.connected())
+	{
+		mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this));
+	}
 
 	mInitialized = TRUE;
 }
@@ -417,6 +430,14 @@ void LLAgent::init()
 void LLAgent::cleanup()
 {
 	mRegionp = NULL;
+	if (mTeleportFinishedSlot.connected())
+	{
+		mTeleportFinishedSlot.disconnect();
+	}
+	if (mTeleportFailedSlot.connected())
+	{
+		mTeleportFailedSlot.disconnect();
+	}
 }
 
 //-----------------------------------------------------------------------------
@@ -2457,7 +2478,49 @@ int LLAgent::convertTextToMaturity(char text)
 	return LLAgentAccess::convertTextToMaturity(text);
 }
 
-bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity)
+class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
+{
+public:
+	LLMaturityPreferencesResponder(LLAgent::maturity_preferences_callback_t pMaturityPreferencesCallback);
+	virtual ~LLMaturityPreferencesResponder();
+
+	virtual void result(const LLSD &pContent);
+	virtual void error(U32 pStatus, const std::string& pReason);
+
+protected:
+
+private:
+	LLAgent::maturity_preferences_callback_t mMaturityPreferencesCallback;
+};
+
+LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent::maturity_preferences_callback_t pMaturityPreferencesCallback)
+	: LLHTTPClient::Responder(),
+	mMaturityPreferencesCallback(pMaturityPreferencesCallback)
+{
+}
+
+LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder()
+{
+}
+
+void LLMaturityPreferencesResponder::result(const LLSD &pContent)
+{
+	if (!mMaturityPreferencesCallback.empty())
+	{
+		mMaturityPreferencesCallback(pContent);
+	}
+}
+
+void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason)
+{
+	if (!mMaturityPreferencesCallback.empty())
+	{
+		LLSD empty;
+		mMaturityPreferencesCallback(empty);
+	}
+}
+
+bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity, maturity_preferences_callback_t pMaturityPreferencesCallback)
 {
 	if (!getRegion())
 		return false;
@@ -2485,7 +2548,8 @@ bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity)
 		body["access_prefs"] = access_prefs;
 		llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: "
 		<< url << llendl;
-		LLHTTPClient::post(url, body, new LLHTTPClient::Responder());    // Ignore response
+		LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(pMaturityPreferencesCallback));
+		LLHTTPClient::post(url, body, responderPtr);
 		return true;
 	}
 	return false;
@@ -3538,6 +3602,62 @@ bool LLAgent::teleportCore(bool is_local)
 	return true;
 }
 
+void LLAgent::restartFailedTeleportRequest()
+{
+	// XXX stinson 05/11/2012 llassert(hasFailedTeleportRequest());
+	if (hasFailedTeleportRequest())
+	{
+		mFailedTeleportRequest->doTeleport();
+	}
+}
+
+void LLAgent::clearFailedTeleportRequest()
+{
+	// XXX stinson 05/11/2012 llassert(hasFailedTeleportRequest());
+	if (hasFailedTeleportRequest())
+	{
+		mFailedTeleportRequest.reset();
+	}
+}
+
+void LLAgent::setMaturityRatingChangeDuringTeleport(int pMaturityRatingChange)
+{
+	mIsMaturityRatingChangingDuringTeleport = true;
+	mMaturityRatingChange = pMaturityRatingChange;
+}
+
+void LLAgent::handleTeleportFinished()
+{
+	// XXX stinson 05/11/2012 llassert(hasCurrentTeleportRequest());
+	if (hasCurrentTeleportRequest())
+	{
+		mCurrentTeleportRequest.reset();
+	}
+	if (hasFailedTeleportRequest())
+	{
+		clearFailedTeleportRequest();
+	}
+	if (mIsMaturityRatingChangingDuringTeleport)
+	{
+		// notify user that the maturity preference has been changed
+		LLSD args;
+		args["RATING"] = LLViewerRegion::accessToString(mMaturityRatingChange);
+		LLNotificationsUtil::add("PreferredMaturityChanged", args);
+		mIsMaturityRatingChangingDuringTeleport = false;
+	}
+}
+
+void LLAgent::handleTeleportFailed()
+{
+	// XXX stinson 05/11/2012 llassert(hasCurrentTeleportRequest());
+	// XXX stinson 05/11/2012 llassert(!hasFailedTeleportRequest());
+	if (hasCurrentTeleportRequest())
+	{
+		mFailedTeleportRequest = mCurrentTeleportRequest;
+	}
+	mIsMaturityRatingChangingDuringTeleport = false;
+}
+
 void LLAgent::teleportRequest(
 	const U64& region_handle,
 	const LLVector3& pos_local,
@@ -3570,9 +3690,9 @@ void LLAgent::teleportRequest(
 // Landmark ID = LLUUID::null means teleport home
 void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
 {
-	llassert(mTeleportRequest == NULL);
-	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id));
-	mTeleportRequest->doTeleport();
+	// XXX stinson 05/11/2012 llassert(!hasCurrentTeleportRequest());
+	mCurrentTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id));
+	mCurrentTeleportRequest->doTeleport();
 }
 
 void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
@@ -3592,9 +3712,9 @@ void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
 
 void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
 {
-	llassert(mTeleportRequest == NULL);
-	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike));
-	mTeleportRequest->doTeleport();
+	// XXX stinson 05/11/2012 llassert(!hasCurrentTeleportRequest());
+	mCurrentTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike));
+	mCurrentTeleportRequest->doTeleport();
 }
 
 void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike)
@@ -3648,9 +3768,9 @@ void LLAgent::teleportCancel()
 
 void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
 {
-	llassert(mTeleportRequest == NULL);
-	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global));
-	mTeleportRequest->doTeleport();
+	// XXX stinson 05/11/2012 llassert(!hasCurrentTeleportRequest());
+	mCurrentTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global));
+	mCurrentTeleportRequest->doTeleport();
 }
 
 void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
@@ -3697,9 +3817,9 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
 // Teleport to global position, but keep facing in the same direction 
 void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global)
 {
-	llassert(mTeleportRequest == NULL);
-	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global));
-	mTeleportRequest->doTeleport();
+	// XXX stinson 05/11/2012 llassert(!hasCurrentTeleportRequest());
+	mCurrentTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global));
+	mCurrentTeleportRequest->doTeleport();
 }
 
 void LLAgent::doTeleportViaLocationLookAt(const LLVector3d& pos_global)
@@ -3723,7 +3843,6 @@ void LLAgent::setTeleportState(ETeleportState state)
 	{
 		case TELEPORT_NONE:
 			mbTeleportKeepsLookAt = false;
-			mTeleportRequest.reset();
 			break;
 
 		case TELEPORT_MOVING:
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 3b27d48928add234aa1b296b04064f084d1f2c63..07ceaf11b10c35e240d33016f57b4e9279315f2c 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -35,6 +35,7 @@
 #include "llcoordframe.h"			// for mFrameAgent
 #include "llvoavatardefines.h"
 
+#include <boost/function.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/signals2.hpp>
 
@@ -570,12 +571,32 @@ class LLAgent : public LLOldEvents::LLObservable
 protected:
 	bool 			teleportCore(bool is_local = false); 					// Stuff for all teleports; returns true if the teleport can proceed
 
+	//--------------------------------------------------------------------
+	// Teleport State
+	//--------------------------------------------------------------------
+
+public:
+	inline bool     hasCurrentTeleportRequest() {return (mCurrentTeleportRequest != NULL);};
+	inline bool     hasFailedTeleportRequest() {return (mFailedTeleportRequest != NULL);};
+	void            restartFailedTeleportRequest();
+	void            clearFailedTeleportRequest();
+	void            setMaturityRatingChangeDuringTeleport(int pMaturityRatingChange);
+
 private:
 	friend class LLTeleportRequest;
 	friend class LLTeleportRequestViaLandmark;
 	friend class LLTeleportRequestViaLure;
 	friend class LLTeleportRequestViaLocation;
 	friend class LLTeleportRequestViaLocationLookAt;
+
+	LLTeleportRequestPtr mCurrentTeleportRequest;
+	LLTeleportRequestPtr mFailedTeleportRequest;
+	boost::signals2::connection mTeleportFinishedSlot;
+	boost::signals2::connection mTeleportFailedSlot;
+
+	bool            mIsMaturityRatingChangingDuringTeleport;
+	int             mMaturityRatingChange;
+
 	void 			teleportRequest(const U64& region_handle,
 									const LLVector3& pos_local,				// Go to a named location home
 									bool look_at_from_camera = false);
@@ -584,6 +605,9 @@ class LLAgent : public LLOldEvents::LLObservable
 	void 			doTeleportViaLocation(const LLVector3d& pos_global);		// To a global location - this will probably need to be deprecated
 	void			doTeleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation
 
+	void            handleTeleportFinished();
+	void            handleTeleportFailed();
+
 	//--------------------------------------------------------------------
 	// Teleport State
 	//--------------------------------------------------------------------
@@ -592,7 +616,6 @@ class LLAgent : public LLOldEvents::LLObservable
 	void			setTeleportState(ETeleportState state);
 private:
 	ETeleportState	mTeleportState;
-	LLTeleportRequestPtr mTeleportRequest;
 
 	//--------------------------------------------------------------------
 	// Teleport Message
@@ -668,8 +691,10 @@ class LLAgent : public LLOldEvents::LLObservable
 	bool 			isAdult() const;
 	void 			setTeen(bool teen);
 	void 			setMaturity(char text);
-	static int 		convertTextToMaturity(char text); 
-	bool 			sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"?
+	static int 		convertTextToMaturity(char text);
+
+	typedef boost::function<void (const LLSD &pResponse)> maturity_preferences_callback_t;
+	bool 			sendMaturityPreferenceToServer(int preferredMaturity, maturity_preferences_callback_t pMaturityPreferencesCallback = NULL); // ! "U8" instead of "int"?
 
 	// Maturity callbacks for PreferredMaturity control variable
 	void 			handleMaturity(const LLSD& newvalue);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 2917fee62e978519f585c2d51bda430c82f8f7e7..3712e56f7c3d66ce706a20065b5dfbeb63d12dda 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -5385,7 +5385,20 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
 	}
 }
 
-
+void handle_maturity_preference_change(const LLSD &pResponse, int pMaturityRatingChange)
+{
+	if (pResponse.isUndefined())
+	{
+		// XXX stinson 05/11/2012 llinfos << "Maturity response ==> <null>" << llendl;
+		gAgent.clearFailedTeleportRequest();
+	}
+	else
+	{
+		// XXX stinson 05/11/2012 linfos << "Maturity response ==> '" << pResponse << "'" << llendl;
+		gAgent.setMaturityRatingChangeDuringTeleport(pMaturityRatingChange);
+		gAgent.restartFailedTeleportRequest();
+	}
+}
 
 bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)
 {
@@ -5396,12 +5409,11 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD&
 		// set the preference to the maturity of the region we're calling
 		int preferredMaturity = notification["payload"]["_region_access"].asInteger();
 		gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
-		gAgent.sendMaturityPreferenceToServer(preferredMaturity);
-
-		// notify user that the maturity preference has been changed
-		LLSD args;
-		args["RATING"] = LLViewerRegion::accessToString(preferredMaturity);
-		LLNotificationsUtil::add("PreferredMaturityChanged", args);
+		gAgent.sendMaturityPreferenceToServer(preferredMaturity, boost::bind(&handle_maturity_preference_change, _1, preferredMaturity));
+	}
+	else
+	{
+		gAgent.clearFailedTeleportRequest();
 	}
 	
 	return false;
@@ -6147,6 +6159,9 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
 	std::string big_reason;
 	LLSD args;
 
+	// Let the interested parties know that teleport failed.
+	LLViewerParcelMgr::getInstance()->onTeleportFailed();
+
 	// if we have additional alert data
 	if (msg->has(_PREHASH_AlertInfo) && msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0)
 	{
@@ -6205,9 +6220,6 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
 
 	LLNotificationsUtil::add("CouldNotTeleportReason", args);
 
-	// Let the interested parties know that teleport failed.
-	LLViewerParcelMgr::getInstance()->onTeleportFailed();
-
 	if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
 	{
 		gAgent.setTeleportState( LLAgent::TELEPORT_NONE );