diff --git a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl
index 28908a311d77b833a4b948ecb6c4d86b0171723e..0fad5b4b50be87187b9e320cd1aee3aa28e61db2 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl
@@ -10,7 +10,6 @@
 uniform sampler2DRect depthMap;
 uniform sampler2DRect normalMap;
 uniform sampler2DRect lightMap;
-uniform sampler2DRect edgeMap;
 
 uniform float dist_factor;
 uniform float blur_size;
@@ -46,53 +45,36 @@ void main()
 	
 	dlt /= max(-pos.z*dist_factor, 1.0);
 	
-	vec2 defined_weight = kern[0].xy; // special case the kern[0] (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
+	vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
 	vec4 col = defined_weight.xyxx * ccol;
-
-	float center_e = 1.0 - (texture2DRect(edgeMap, vary_fragcoord.xy).a+
-		      texture2DRect(edgeMap, vary_fragcoord.xy+dlt*0.333).a+
-	              texture2DRect(edgeMap, vary_fragcoord.xy-dlt*0.333).a);
 	
-	float e = center_e;
 	for (int i = 1; i < 4; i++)
 	{
 		vec2 tc = vary_fragcoord.xy + kern[i].z*dlt;
-		
-		e = max(e, 0.0);
-		
-		vec2 wght = kern[i].xy*e;
-		
-		col += texture2DRect(lightMap, tc)*wght.xyxx;
-		defined_weight += wght;
-		
-		e *= e;
-		e -= texture2DRect(edgeMap, tc.xy).a+
-			texture2DRect(edgeMap, tc.xy+dlt*0.333).a+
-			texture2DRect(edgeMap, tc.xy-dlt*0.333).a;
+	        vec3 samppos = getPosition(tc).xyz; 
+		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
+		if (d*d <= 0.003)
+		{
+			col += texture2DRect(lightMap, tc)*kern[i].xyxx;
+			defined_weight += kern[i].xy;
+		}
 	}
-
-	e = center_e;
 	for (int i = 1; i < 4; i++)
 	{
 		vec2 tc = vary_fragcoord.xy - kern[i].z*dlt;
-		
-		e = max(e, 0.0);
-		
-		vec2 wght = kern[i].xy*e;
-		
-		col += texture2DRect(lightMap, tc)*wght.xyxx;
-		defined_weight += wght;
-		
-		e *= e;
-		e -= texture2DRect(edgeMap, tc.xy).a+
-			texture2DRect(edgeMap, tc.xy+dlt*0.333).a+
-			texture2DRect(edgeMap, tc.xy-dlt*0.333).a;
+	        vec3 samppos = getPosition(tc).xyz; 
+		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
+		if (d*d <= 0.003)
+		{
+			col += texture2DRect(lightMap, tc)*kern[i].xyxx;
+			defined_weight += kern[i].xy;
+		}
 	}
 
 
+
 	col /= defined_weight.xyxx;
 	
 	gl_FragColor = col;
-	
-	//gl_FragColor = ccol;
 }
+
diff --git a/indra/newview/llcommanddispatcherlistener.cpp b/indra/newview/llcommanddispatcherlistener.cpp
index 00a20de30edc4639671fd432adfb938282c39275..91baeaf989adbaa26a2f67441f4e965c01748e1b 100644
--- a/indra/newview/llcommanddispatcherlistener.cpp
+++ b/indra/newview/llcommanddispatcherlistener.cpp
@@ -31,6 +31,11 @@ LLCommandDispatcherListener::LLCommandDispatcherListener(/* LLCommandDispatcher*
         "[\"query\"] map of parameters, as if from ?key1=val&key2=val\n"
         "[\"trusted\"] boolean indicating trusted browser [default true]",
         &LLCommandDispatcherListener::dispatch);
+    add("enumerate",
+        "Post to [\"reply\"] a map of registered LLCommandHandler instances, containing\n"
+        "name key and (e.g.) untrusted flag",
+        &LLCommandDispatcherListener::enumerate,
+        LLSD().with("reply", LLSD()));
 }
 
 void LLCommandDispatcherListener::dispatch(const LLSD& params) const
@@ -45,3 +50,11 @@ void LLCommandDispatcherListener::dispatch(const LLSD& params) const
     LLCommandDispatcher::dispatch(params["cmd"], params["params"], params["query"], NULL,
                                   trusted_browser);
 }
+
+void LLCommandDispatcherListener::enumerate(const LLSD& params) const
+{
+    LLReqID reqID(params);
+    LLSD response(LLCommandDispatcher::enumerate());
+    reqID.stamp(response);
+    LLEventPumps::instance().obtain(params["reply"]).post(response);
+}
diff --git a/indra/newview/llcommanddispatcherlistener.h b/indra/newview/llcommanddispatcherlistener.h
index d0070ddd711caf8d13fe3866e70b5cf7f0b2425d..9bcddebcc149b799d77450099123675ea51372d6 100644
--- a/indra/newview/llcommanddispatcherlistener.h
+++ b/indra/newview/llcommanddispatcherlistener.h
@@ -23,6 +23,7 @@ class LLCommandDispatcherListener: public LLEventAPI
 
 private:
     void dispatch(const LLSD& params) const;
+    void enumerate(const LLSD& params) const;
 
     //LLCommandDispatcher* mDispatcher;
 };
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 8c7e7bea83b91be92abf6a0680ddca920c787726..dc506a16925c238f565e071a5a67fc440ac8bc58 100644
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -36,6 +36,7 @@
 #include "llcommandhandler.h"
 #include "llnotificationsutil.h"
 #include "llcommanddispatcherlistener.h"
+#include "stringize.h"
 
 // system includes
 #include <boost/tokenizer.hpp>
@@ -67,6 +68,7 @@ class LLCommandHandlerRegistry
 				  bool trusted_browser);
 
 private:
+	friend LLSD LLCommandDispatcher::enumerate();
 	std::map<std::string, LLCommandHandlerInfo> mMap;
 };
 
@@ -175,3 +177,56 @@ bool LLCommandDispatcher::dispatch(const std::string& cmd,
 	return LLCommandHandlerRegistry::instance().dispatch(
 		cmd, params, query_map, web, trusted_browser);
 }
+
+static std::string lookup(LLCommandHandler::EUntrustedAccess value);
+
+LLSD LLCommandDispatcher::enumerate()
+{
+	LLSD response;
+	LLCommandHandlerRegistry& registry(LLCommandHandlerRegistry::instance());
+	for (std::map<std::string, LLCommandHandlerInfo>::const_iterator chi(registry.mMap.begin()),
+																	 chend(registry.mMap.end());
+		 chi != chend; ++chi)
+	{
+		LLSD info;
+		info["untrusted"] = chi->second.mUntrustedBrowserAccess;
+		info["untrusted_str"] = lookup(chi->second.mUntrustedBrowserAccess);
+		response[chi->first] = info;
+	}
+	return response;
+}
+
+/*------------------------------ lookup stuff ------------------------------*/
+struct symbol_info
+{
+	const char* name;
+	LLCommandHandler::EUntrustedAccess value;
+};
+
+#define ent(SYMBOL)										\
+	{													\
+		#SYMBOL + 28, /* skip "LLCommandHandler::UNTRUSTED_" prefix */	\
+		SYMBOL											\
+	}
+
+symbol_info symbols[] =
+{
+	ent(LLCommandHandler::UNTRUSTED_ALLOW),		  // allow commands from untrusted browsers
+	ent(LLCommandHandler::UNTRUSTED_BLOCK),		  // ignore commands from untrusted browsers
+	ent(LLCommandHandler::UNTRUSTED_THROTTLE)	  // allow untrusted, but only a few per min.
+};
+
+#undef ent
+
+static std::string lookup(LLCommandHandler::EUntrustedAccess value)
+{
+	for (symbol_info *sii(symbols), *siend(symbols + (sizeof(symbols)/sizeof(symbols[0])));
+		 sii != siend; ++sii)
+	{
+		if (sii->value == value)
+		{
+			return sii->name;
+		}
+	}
+	return STRINGIZE("UNTRUSTED_" << value);
+}
diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h
index 1bae6d94142545c973d7b141cae2f83f8172d2f8..a1d4c880f537b223c2730ebd00a4309455ff281e 100644
--- a/indra/newview/llcommandhandler.h
+++ b/indra/newview/llcommandhandler.h
@@ -34,6 +34,8 @@
 #ifndef LLCOMMANDHANDLER_H
 #define LLCOMMANDHANDLER_H
 
+#include "llsd.h"
+
 /* Example:  secondlife:///app/foo/<uuid>
    Command "foo" that takes one parameter, a UUID.
 
@@ -103,6 +105,9 @@ class LLCommandDispatcher
 		// Execute a command registered via the above mechanism,
 		// passing string parameters.
 		// Returns true if command was found and executed correctly.
+	/// Return an LLSD::Map of registered LLCommandHandlers and associated
+	/// info (e.g. EUntrustedAccess).
+	static LLSD enumerate();
 };
 
 #endif
diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp
index fd39bde1187c4a2834f2f7852e5af6114d1a2e13..90214a1bd7888122ad8238fb9d52ac35e16ecaf9 100644
--- a/indra/newview/llspeakbutton.cpp
+++ b/indra/newview/llspeakbutton.cpp
@@ -61,7 +61,9 @@ void LLSpeakButton::draw()
 {
 	// gVoiceClient is the authoritative global source of info regarding our open-mic state, we merely reflect that state.
 	bool openmic = gVoiceClient->getUserPTTState();
-	mSpeakBtn->setToggleState(openmic);
+	bool voiceenabled = gVoiceClient->voiceEnabled();
+	mSpeakBtn->setToggleState(openmic && voiceenabled);
+	mOutputMonitor->setIsMuted(!voiceenabled);
 	LLUICtrl::draw();
 }
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 73b5222ee3a5da76b7310b74e9f9fb221f7a3b74..4f4fc838191bb0fe9922e6e8931b3a931001ba58 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6352,7 +6352,8 @@ void LLPipeline::renderDeferredLighting()
 
 			mDeferredLight[0].flush();
 
-			if (gSavedSettings.getBOOL("RenderDeferredBlurLight"))
+			if (gSavedSettings.getBOOL("RenderDeferredBlurLight") &&
+			    gSavedSettings.getBOOL("RenderDeferredGI"))
 			{
 				LLFastTimer ftm(FTM_EDGE_DETECTION);
 				//get edge map