diff --git a/.hgtags b/.hgtags
index 0f18172fe90b9358280f554b26893278ba22736a..fece298a2177bd3c89d438b8d3190000166deda2 100755
--- a/.hgtags
+++ b/.hgtags
@@ -440,3 +440,7 @@ adc360e6bf21390d2665380951d85937cd29a604 3.5.0-release
 1ada73295ed0eaa4a772ef079c29f57069342c32 DRTVWR-310
 0ca3910763cec967703e45bc6208a325dccb9f95 3.5.1-beta1
 20cdf370f5c8be6193bef6fb3a81cc3f81275191 3.5.1-beta1
+2319904200de367646b9a9442239a38d52c1eeb5 DRTVWR-313
+9d8726eca785acad694564516f16dd639faf45c0 3.5.1-beta2
+4b7fa963b80e2056ab648f83a4d61310b3cedb3d DRTVWR-314
+65ae89aeb7ea674a555e439e963f17949322ac94 3.5.1-beta3
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 3abf32b8b109d209bc96b52742ae6671eb1d6c9e..526cd4ea2829695e51857e71e0b12c43afcfec73 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -300,6 +300,7 @@ ChickyBabes Zuzu
 Christopher  Organiser
 Ciaran Laval
 Cinder Roxley
+    BUG-2326
     STORM-1703
 Clara Young
 Coaldust Numbers
@@ -900,6 +901,7 @@ NickyD
 Nicky Dasmijn
 	VWR-29228
 	MAINT-873
+	SUN-72
 	STORM-1935
 	STORM-1936
 	STORM-1937
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index bc615ed39ec593de0cda0d2bd3caa1639d7dad06..864b6e6975632d099f217ececae9a54841e6d116 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -853,7 +853,8 @@ llifstream::llifstream(const std::string& _Filename,
 #if LL_WINDOWS
 	std::istream(&_M_filebuf)
 {
-	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0)
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -872,7 +873,8 @@ llifstream::llifstream(const char* _Filename,
 #if LL_WINDOWS
 	std::istream(&_M_filebuf)
 {
-	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -917,8 +919,10 @@ bool llifstream::is_open() const
 
 void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
 {	// open a C stream with specified mode
-	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+
 #if LL_WINDOWS
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::in) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -927,6 +931,7 @@ void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
 		_Myios::clear();
 	}
 #else
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
 	{
 		this->setstate(ios_base::failbit);
 	}
@@ -969,7 +974,8 @@ llofstream::llofstream(const std::string& _Filename,
 #if LL_WINDOWS
 	std::ostream(&_M_filebuf)
 {
-	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0)
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -988,7 +994,8 @@ llofstream::llofstream(const char* _Filename,
 #if LL_WINDOWS
 	std::ostream(&_M_filebuf)
 {
-	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -1032,8 +1039,9 @@ bool llofstream::is_open() const
 
 void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
 {	// open a C stream with specified mode
-	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
 #if LL_WINDOWS
+	llutf16string wideName = utf8str_to_utf16str( _Filename );
+	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
 	{
 		_Myios::setstate(ios_base::failbit);
 	}
@@ -1042,6 +1050,7 @@ void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
 		_Myios::clear();
 	}
 #else
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
 	{
 		this->setstate(ios_base::failbit);
 	}
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 3e0e82b579e7de0a5d3bfc856689ae061b847c28..113aa9a8f2596c48e56f17f333a0be52e454742c 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -818,7 +818,14 @@ bool LLFloaterAvatarPicker::isSelectBtnEnabled()
 			uuid_vec_t avatar_ids;
 			std::vector<LLAvatarName> avatar_names;
 			getSelectedAvatarData(list, avatar_ids, avatar_names);
-			return mOkButtonValidateSignal(avatar_ids);
+			if (avatar_ids.size() >= 1) 
+			{
+				ret_val = mOkButtonValidateSignal(avatar_ids);
+			}
+			else
+			{
+				ret_val = false;
+			}
 		}
 	}
 
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index ac517f1fb71a28e83d2f85f8eadd459abac0f6ed..9dc9932c868109b3abe7dba402f4267e4df4ec4d 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2699,24 +2699,33 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
 	if(ft && (0 == error_code) &&
 	   (object = gObjectList.findObject(ft->mTaskID)))
 	{
-		object->loadTaskInvFile(ft->mFilename);
+		if (object->loadTaskInvFile(ft->mFilename))
+		{
 
-		LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
-		LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
-		std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
+			LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
+			LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
+			std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
 
-		for (; it != end && pending_lst.size(); ++it)
-		{
-			LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
-			if(item && item->getType() != LLAssetType::AT_CATEGORY)
+			for (; it != end && pending_lst.size(); ++it)
 			{
-				std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
-				if (id_it != pending_lst.end())
+				LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
+				if(item && item->getType() != LLAssetType::AT_CATEGORY)
 				{
-					pending_lst.erase(id_it);
+					std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
+					if (id_it != pending_lst.end())
+					{
+						pending_lst.erase(id_it);
+					}
 				}
 			}
 		}
+		else
+		{
+			// MAINT-2597 - crash when trying to edit a no-mod object
+			// Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?)
+			// Stated repro was specific to no-mod objects so failing without user interaction should be safe.
+			llwarns << "Trying to load invalid task inventory file. Ignoring file contents." << llendl;
+		}
 	}
 	else
 	{
@@ -2728,7 +2737,7 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
 	delete ft;
 }
 
-void LLViewerObject::loadTaskInvFile(const std::string& filename)
+BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)
 {
 	std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);
 	llifstream ifs(filename_and_local_path);
@@ -2775,8 +2784,11 @@ void LLViewerObject::loadTaskInvFile(const std::string& filename)
 	{
 		llwarns << "unable to load task inventory: " << filename_and_local_path
 				<< llendl;
+		return FALSE;
 	}
 	doInventoryCallback();
+
+	return TRUE;
 }
 
 void LLViewerObject::doInventoryCallback()
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 40e09a4f41f653858468cfb578cecf8890bc5fe1..9996c916a4a9f29f3922c8bec82b27090ddebd89 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -651,7 +651,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	//
 
 	static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
-	void loadTaskInvFile(const std::string& filename);
+	BOOL loadTaskInvFile(const std::string& filename);
 	void doInventoryCallback();
 	
 	BOOL isOnMap();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index a57679b71e9ee2bd0f7a06228c914e68c922a824..3c253390371f53bdbb0ba978498ebbbcd6691159 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -815,14 +815,14 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c
 //------------------------------------------------------------------------
 LLVOAvatar::~LLVOAvatar()
 {
-		if (!mFullyLoaded)
-		{
+	if (!mFullyLoaded)
+	{
 		debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud");
-		}
-		else
-		{
+	}
+	else
+	{
 		debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
-		}
+	}
 
 	logPendingPhases();
 	
@@ -6110,6 +6110,11 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
 
 void LLVOAvatar::logPendingPhases()
 {
+	if (!isAgentAvatarValid())
+	{
+		return;
+	}
+	
 	for (LLViewerStats::phase_map_t::iterator it = getPhases().begin();
 		 it != getPhases().end();
 		 ++it)
@@ -6144,6 +6149,11 @@ void LLVOAvatar::logPendingPhasesAllAvatars()
 
 void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed)
 {
+	if (!isAgentAvatarValid())
+	{
+		return;
+	}
+	
 	LLSD record;
 	record["timer_name"] = phase_name;
 	record["avatar_id"] = getID();
@@ -6160,13 +6170,6 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse
 	record["is_using_server_bakes"] = ((bool) isUsingServerBakes());
 	record["is_self"] = isSelf();
 	
-
-#if 0 // verbose logging
-	std::ostringstream ostr;
-	ostr << LLSDNotationStreamer(record);
-	LL_DEBUGS("Avatar") << "record\n" << ostr.str() << llendl;
-#endif
-
 	if (isAgentAvatarValid())
 	{
 		gAgentAvatarp->addMetricsTimerRecord(record);