diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index a5a90d72973f291714b8153e5ea40a2ee0c3b0db..38dd198ad319760c3be12230b1dfe2975421a9d9 100644
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
@@ -30,7 +30,6 @@
 #define LL_STRINGIZE_H
 
 #include <sstream>
-#include <boost/phoenix/phoenix.hpp>
 #include <llstring.h>
 
 /**
@@ -53,12 +52,7 @@ std::basic_string<CHARTYPE> gstringize(const T& item)
  */
 inline std::string stringize(const std::wstring& item)
 {
-    LL_WARNS() << "WARNING:  Possible narrowing" << LL_ENDL;
-    
-    std::string s;
-    
-    s = wstring_to_utf8str(item);
-    return gstringize<char>(s);
+    return wstring_to_utf8str(item);
 }
 
 /**
@@ -76,7 +70,10 @@ std::string stringize(const T& item)
  */
 inline std::wstring wstringize(const std::string& item)
 {
-    return gstringize<wchar_t>(item.c_str());
+    // utf8str_to_wstring() returns LLWString, which isn't necessarily the
+    // same as std::wstring
+    LLWString s(utf8str_to_wstring(item));
+    return std::wstring(s.begin(), s.end());
 }
 
 /**
@@ -91,10 +88,10 @@ std::wstring wstringize(const T& item)
 /**
  * stringize_f(functor)
  */
-template <typename Functor>
-std::string stringize_f(Functor const & f)
+template <typename CHARTYPE, typename Functor>
+std::basic_string<CHARTYPE> stringize_f(Functor const & f)
 {
-    std::ostringstream out;
+    std::basic_ostringstream<CHARTYPE> out;
     f(out);
     return out.str();
 }
@@ -108,31 +105,37 @@ std::string stringize_f(Functor const & f)
  * return out.str();
  * @endcode
  */
-#define STRINGIZE(EXPRESSION) (stringize_f(boost::phoenix::placeholders::arg1 << EXPRESSION))
+#define STRINGIZE(EXPRESSION) (stringize_f<char>([&](std::ostream& out){ out << EXPRESSION; }))
 
+/**
+ * WSTRINGIZE() is the wstring equivalent of STRINGIZE()
+ */
+#define WSTRINGIZE(EXPRESSION) (stringize_f<wchar_t>([&](std::wostream& out){ out << EXPRESSION; }))
 
 /**
  * destringize(str)
  * defined for symmetry with stringize
- * *NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
+ * @NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
  * leading/trailing whitespace and handling of bad_lexical_cast exceptions
+ * @NOTE - no need for dewstringize(), since passing std::wstring will Do The
+ * Right Thing
  */
-template <typename T>
-T destringize(std::string const & str)
+template <typename T, typename CHARTYPE>
+T destringize(std::basic_string<CHARTYPE> const & str)
 {
-	T val;
-    std::istringstream in(str);
-	in >> val;
+    T val;
+    std::basic_istringstream<CHARTYPE> in(str);
+    in >> val;
     return val;
 }
 
 /**
  * destringize_f(str, functor)
  */
-template <typename Functor>
-void destringize_f(std::string const & str, Functor const & f)
+template <typename CHARTYPE, typename Functor>
+void destringize_f(std::basic_string<CHARTYPE> const & str, Functor const & f)
 {
-    std::istringstream in(str);
+    std::basic_istringstream<CHARTYPE> in(str);
     f(in);
 }
 
@@ -143,8 +146,11 @@ void destringize_f(std::string const & str, Functor const & f)
  * std::istringstream in(str);
  * in >> item1 >> item2 >> item3 ... ;
  * @endcode
+ * @NOTE - once we get generic lambdas, we shouldn't need DEWSTRINGIZE() any
+ * more since DESTRINGIZE() should do the right thing with a std::wstring. But
+ * until then, the lambda we pass must accept the right std::basic_istream.
  */
-#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), (boost::phoenix::placeholders::arg1 >> EXPRESSION)))
-
+#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::istream& in){in >> EXPRESSION;}))
+#define DEWSTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::wistream& in){in >> EXPRESSION;}))
 
 #endif /* ! defined(LL_STRINGIZE_H) */
diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h
index 9a4bbbd630d002a6effa410c39e737f0dfc23d89..08fbf19b1cdccec7323769b515246737368de2d0 100644
--- a/indra/llcommon/tests/wrapllerrs.h
+++ b/indra/llcommon/tests/wrapllerrs.h
@@ -109,6 +109,12 @@ class CaptureLogRecorder : public LLError::Recorder, public boost::noncopyable
         mMessages.push_back(message);
     }
 
+    friend inline
+    std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
+    {
+        return log.streamto(out);
+    }
+
     /// Don't assume the message we want is necessarily the LAST log message
     /// emitted by the underlying code; search backwards through all messages
     /// for the sought string.
@@ -126,7 +132,7 @@ class CaptureLogRecorder : public LLError::Recorder, public boost::noncopyable
 
         throw tut::failure(STRINGIZE("failed to find '" << search
                                      << "' in captured log messages:\n"
-                                     << boost::ref(*this)));
+                                     << *this));
     }
 
     std::ostream& streamto(std::ostream& out) const
@@ -200,10 +206,4 @@ class CaptureLog : public boost::noncopyable
 	LLError::RecorderPtr mRecorder;
 };
 
-inline
-std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
-{
-    return log.streamto(out);
-}
-
 #endif /* ! defined(LL_WRAPLLERRS_H) */