diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 3aef15a35c0848a0b87889147d2277aedef98be1..3c3dfb760ee32892ee92154048469fd845c30088 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -86,6 +86,7 @@
 #include "llviewermenu.h"
 #include "llviewerparcelmgr.h"
 #include "llviewerwindow.h"
+#include "llvovolume.h"
 #include "lluictrlfactory.h"
 
 // Globals
@@ -1079,21 +1080,45 @@ void LLFloaterTools::getMediaState()
 	}
 	
 	bool editable = (first_object->permModify() || selectedMediaEditable());
-	
+
+	// Check modify permissions and whether any selected objects are in
+	// the process of being fetched.  If they are, then we're not editable
+	if (editable)
+	{
+		LLObjectSelection::iterator iter = selected_objects->begin(); 
+		LLObjectSelection::iterator end = selected_objects->end();
+		for ( ; iter != end; ++iter)
+		{
+			LLSelectNode* node = *iter;
+			LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
+			if (NULL != object)
+			{
+				if (!object->permModify() || object->isMediaDataBeingFetched())
+				{
+					editable = false;
+					break;
+				}
+			}
+		}
+	}
+
 	// Media settings
-	U8 has_media = (U8)0;
-	struct media_functor : public LLSelectedTEGetFunctor<U8>
+	bool bool_has_media = false;
+	struct media_functor : public LLSelectedTEGetFunctor<bool>
 	{
-		U8 get(LLViewerObject* object, S32 face)
+		bool get(LLViewerObject* object, S32 face)
 		{
-			return (object->getTE(face)->getMediaTexGen());
+			LLTextureEntry *te = object->getTE(face);
+			if (te)
+			{
+				return te->hasMedia();
+			}
+			return false;
 		}
 	} func;
 	
 	// check if all faces have media(or, all dont have media)
-	LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, has_media );
-	bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA);
-
+	LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );
 	
 	const LLMediaEntry default_media_data;
 	
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 512104a2f420e0b43a14bfa7be77e852dc72ac0f..986c14acff7b3e1384fe9c0a94983324a913a82c 100755
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -324,6 +324,22 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::PriorityQueue
 	return s;
 }
 
+// find the given object in the queue.
+bool LLMediaDataClient::PriorityQueue::find(const LLMediaDataClientObject::ptr_t &obj) const
+{
+	std::vector<LLMediaDataClient::request_ptr_t>::const_iterator iter = c.begin();
+	std::vector<LLMediaDataClient::request_ptr_t>::const_iterator end = c.end();
+	while (iter < end)
+	{
+		if (obj->getID() == (*iter)->getObject()->getID())
+		{
+			return true;
+		}
+		iter++;
+	}
+	return false;
+}
+
 //////////////////////////////////////////////////////////////////////////////////////
 //
 // LLMediaDataClient::QueueTimer
@@ -491,6 +507,11 @@ bool LLMediaDataClient::isEmpty() const
 	return (NULL == pRequestQueue) ? true : pRequestQueue->empty();
 }
 
+bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object) const
+{
+	return (NULL == pRequestQueue) ? false : pRequestQueue->find(object);
+}
+
 //////////////////////////////////////////////////////////////////////////////////////
 //
 // LLObjectMediaDataClient
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index 9d0aa0981e77cb9a651f2fbf259467374dd838ab..0d1450ffbe53487ee52be734dad6f72b4eb777ca 100755
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -89,7 +89,10 @@ class LLMediaDataClient : public LLRefCount
 	F32 getRetryTimerDelay() const { return mRetryTimerDelay; }
 	
 	// Returns true iff the queue is empty
-	bool isEmpty() const; 
+	bool isEmpty() const;
+	
+	// Returns true iff the given object is in the queue
+	bool isInQueue(const LLMediaDataClientObject::ptr_t &object) const;
 	
 protected:
 	// Destructor
@@ -206,6 +209,9 @@ class LLMediaDataClient : public LLRefCount
 		Comparator >
 	{
 	public:
+		// Return whether the given object is in the queue
+		bool find(const LLMediaDataClientObject::ptr_t &obj) const;
+		
 		friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q);
 	};
     
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 5ac6dcce5a9d22c0167a554944c2be4e294b29e7..2def905bbba05bd11f29e8adcd8000c685912023 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -109,6 +109,7 @@ class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
 				{
 					result = te->getMediaData()->asLLSD();
 					// XXX HACK: workaround bug in asLLSD() where whitelist is not set properly
+					// See DEV-41949
 					if (!result.has(LLMediaEntry::WHITELIST_KEY))
 					{
 						result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray();
@@ -1668,6 +1669,13 @@ void LLVOVolume::requestMediaDataUpdate()
     sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this));
 }
 
+bool LLVOVolume::isMediaDataBeingFetched() const
+{
+	// I know what I'm doing by const_casting this away: this is just 
+	// a wrapper class that is only going to do a lookup.
+	return sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this)));
+}
+
 void LLVOVolume::cleanUpMediaImpls()
 {
 	// Iterate through our TEs and remove any Impls that are no longer used
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 784ef16ba363122795dab59529cef4e7ee1ab356..10fc8865fc5ba06c6bd4855410c5cd964c721a91 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -265,7 +265,10 @@ class LLVOVolume : public LLViewerObject
 	bool hasMedia() const;
 	
 	LLVector3 getApproximateFaceNormal(U8 face_id);
-
+	
+	// Returns 'true' iff the media data for this object is in flight
+	bool isMediaDataBeingFetched() const;
+	
 protected:
 	S32	computeLODDetail(F32	distance, F32 radius);
 	BOOL calcLOD();
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 445ec7aa344cd13f1f1903a8ed3bf262dea9f969..3ac631d96e3213a9df2b0051365f7d015f115e97 100644
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -497,5 +497,38 @@ namespace tut
 		ensure("REF COUNT", o->getNumRefs(), 1);
     }
 
-	
+	template<> template<>
+    void mediadataclient_object_t::test<7>()
+    {
+		// Test LLMediaDataClient::isInQueue()
+		LOG_TEST(7);
+		
+		LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(
+			_DATA(VALID_OBJECT_ID_1,"3.0","1.0"));
+		LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(
+			_DATA(VALID_OBJECT_ID_2,"1.0","1.0"));
+		int num_refs_start = o1->getNumRefs();
+		{
+			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
+			
+			ensure("not in queue yet 1", ! mdc->isInQueue(o1));
+			ensure("not in queue yet 2", ! mdc->isInQueue(o2));
+			
+			mdc->fetchMedia(o1);
+			
+			ensure("is in queue", mdc->isInQueue(o1));
+			ensure("is not in queue", ! mdc->isInQueue(o2));
+			
+			::pump_timers();
+			
+			ensure("not in queue anymore", ! mdc->isInQueue(o1));
+			ensure("still is not in queue", ! mdc->isInQueue(o2));
+			
+			ensure("queue empty", mdc->isEmpty());
+		}
+		
+		// Make sure everyone's destroyed properly
+		ensure("REF COUNT", o1->getNumRefs(), num_refs_start);
+		
+	}
 }