diff --git a/indra/test/llevents_tut.cpp b/indra/test/llevents_tut.cpp
index a9114075fc944467e18e6afec3cfbf2eddc046b9..16edab628229e6afad61886f43947fa2af17a167 100755
--- a/indra/test/llevents_tut.cpp
+++ b/indra/test/llevents_tut.cpp
@@ -48,10 +48,10 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/assign/list_of.hpp>
 // other Linden headers
+#include "tests/listener.h"             // must PRECEDE lltut.h
 #include "lltut.h"
 #include "catch_and_store_what_in.h"
 #include "stringize.h"
-#include "tests/listener.h"
 
 using boost::assign::list_of;
 
diff --git a/indra/test/lltut.cpp b/indra/test/lltut.cpp
index a183cef9a91ba4604ad4887ce8380149a3e30edb..2730fb34d7319a3ba4ac30c9e10bf1edd4e8c3fd 100755
--- a/indra/test/lltut.cpp
+++ b/indra/test/lltut.cpp
@@ -52,12 +52,25 @@ namespace tut
 			actual.asString(), expected.asString());
 	}
 
+	// The lexical param types here intentionally diverge from the declaration
+	// in our header file. In lltut.h, LLSD is only a forward-declared type;
+	// we have no access to its LLSD::Binary nested type, and so must restate
+	// it explicitly to declare this overload. However, an overload that does
+	// NOT match LLSD::Binary does us no good whatsoever: it would never be
+	// engaged. Stating LLSD::Binary for this definition at least means that
+	// if the LLSD::Binary type ever diverges from what we expect in lltut.h,
+	// that divergence will produce an error: no definition will match that
+	// declaration.
 	void ensure_equals(const char* msg,
-		const std::vector<U8>& actual, const std::vector<U8>& expected)
+		const LLSD::Binary& actual, const LLSD::Binary& expected)
 	{
-		std::string s(msg);
-		
-		ensure_equals(s + " size", actual.size(), expected.size());
+		ensure_equals(std::string(msg? msg : ""), actual, expected);
+	}
+
+	void ensure_equals(const std::string& msg,
+		const LLSD::Binary& actual, const LLSD::Binary& expected)
+	{
+		ensure_equals(msg + " size", actual.size(), expected.size());
 		
 		std::vector<U8>::const_iterator i, j;
 		int k;
@@ -65,14 +78,14 @@ namespace tut
 			i != actual.end();
 			++i, ++j, ++k)
 		{
-			ensure_equals(s + " field", *i, *j);
+			ensure_equals(msg + " field", *i, *j);
 		}
 	}
 
 	void ensure_equals(const char* m, const LLSD& actual,
 		const LLSD& expected)
     {
-        ensure_equals(std::string(m), actual, expected);
+        ensure_equals(std::string(m? m : ""), actual, expected);
     }
 
 	void ensure_equals(const std::string& msg, const LLSD& actual,
diff --git a/indra/test/lltut.h b/indra/test/lltut.h
index 5428be3719806d4dcaf20a3f8377df3832ef0460..6cb670b2a398e16d40cab3cb4a658da983408614 100755
--- a/indra/test/lltut.h
+++ b/indra/test/lltut.h
@@ -30,6 +30,60 @@
 #define LL_LLTUT_H
 
 #include "is_approx_equal_fraction.h" // instead of llmath.h
+#include <cstring>
+
+class LLDate;
+class LLSD;
+class LLURI;
+
+namespace tut
+{
+	template <class T,class Q>
+	void ensure_equals(const std::string& msg,
+		const Q& actual,const T& expected)
+		{ ensure_equals(msg.c_str(), actual, expected); }
+
+	void ensure_equals(const char* msg,
+		const LLDate& actual, const LLDate& expected);
+
+	void ensure_equals(const char* msg,
+		const LLURI& actual, const LLURI& expected);
+
+	// std::vector<U8> is the current definition of LLSD::Binary. Because
+	// we're only forward-declaring LLSD in this header file, we can't
+	// directly reference that nested type. If the build complains that
+	// there's no definition for either of these declarations, it could be
+	// that LLSD::Binary has changed, and that these declarations must be
+	// adjusted to match.
+	void ensure_equals(const char* msg,
+		const std::vector<U8>& actual, const std::vector<U8>& expected);
+
+	void ensure_equals(const std::string& msg,
+		const std::vector<U8>& actual, const std::vector<U8>& expected);
+
+	void ensure_equals(const char* msg,
+		const LLSD& actual, const LLSD& expected);
+
+	void ensure_equals(const std::string& msg,
+		const LLSD& actual, const LLSD& expected);
+	
+	void ensure_starts_with(const std::string& msg,
+		const std::string& actual, const std::string& expectedStart);
+
+	void ensure_ends_with(const std::string& msg,
+		const std::string& actual, const std::string& expectedEnd);
+
+	void ensure_contains(const std::string& msg,
+		const std::string& actual, const std::string& expectedSubString);
+
+	void ensure_does_not_contain(const std::string& msg,
+		const std::string& actual, const std::string& expectedSubString);
+}
+
+// This is an odd place to #include an important contributor -- but the usual
+// rules are reversed here. Instead of the overloads above referencing tut.hpp
+// features, we need calls in tut.hpp template functions to dispatch to our
+// overloads declared above.
 
 // turn off warnings about unused functions from clang for tut package
 #pragma clang diagnostic push
@@ -37,12 +91,7 @@
 #include <tut/tut.hpp>
 #pragma clang diagnostic pop
 
-#include <cstring>
-
-class LLDate;
-class LLSD;
-class LLURI;
-
+// The functions BELOW this point actually consume tut.hpp functionality.
 namespace tut
 {
 	inline void ensure_approximately_equals(const char* msg, F64 actual, F64 expected, U32 frac_bits)
@@ -112,40 +161,6 @@ namespace tut
 	{
 		ensure_not_equals(NULL, actual, expected);
 	}
-	
-	
-	template <class T,class Q>
-	void ensure_equals(const std::string& msg,
-		const Q& actual,const T& expected)
-		{ ensure_equals(msg.c_str(), actual, expected); }
-
-	void ensure_equals(const char* msg,
-		const LLDate& actual, const LLDate& expected);
-
-	void ensure_equals(const char* msg,
-		const LLURI& actual, const LLURI& expected);
-		
-	void ensure_equals(const char* msg,
-		const std::vector<U8>& actual, const std::vector<U8>& expected);
-
-	void ensure_equals(const char* msg,
-		const LLSD& actual, const LLSD& expected);
-
-	void ensure_equals(const std::string& msg,
-		const LLSD& actual, const LLSD& expected);
-	
-	void ensure_starts_with(const std::string& msg,
-		const std::string& actual, const std::string& expectedStart);
-
-	void ensure_ends_with(const std::string& msg,
-		const std::string& actual, const std::string& expectedEnd);
-
-	void ensure_contains(const std::string& msg,
-		const std::string& actual, const std::string& expectedSubString);
-
-	void ensure_does_not_contain(const std::string& msg,
-		const std::string& actual, const std::string& expectedSubString);
 }
 
-
 #endif // LL_LLTUT_H