diff --git a/BuildParams b/BuildParams
index aeea3b1246868b59c1a58f3b4d3ff6b6347b79c8..7aff447ddaec679146a99d8e76e8d8e354c7afc4 100755
--- a/BuildParams
+++ b/BuildParams
@@ -4,7 +4,7 @@
 #  https://wiki.secondlife.com/wiki/Automated_Build_System
 
 
-# Global setting for now...
+# Global setting for now....
 Darwin.symbolfiles = "newview/Release/secondlife-symbols-darwin.tar.bz2"
 CYGWIN.symbolfiles = "newview/Release/secondlife-symbols-windows.tar.bz2"
 Linux.symbolfiles = "newview/secondlife-symbols-linux.tar.bz2"
diff --git a/autobuild.xml b/autobuild.xml
index 52d750f64d66a074096d58a75d02f2c428a3ac67..ff8bde0ea78cdd9e9df989d7d080bad0606bae8b 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -266,9 +266,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d1c5125650a339a5209f429c70f4d395</string>
+              <string>89db4a1aa22599cf377ae49630b7b5b1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/curl_3p-update-curl/rev/297172/arch/Darwin/installer/curl-7.38.0.297172-darwin-297172.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/curl_3p-update-curl/rev/301717/arch/Darwin/installer/curl-7.42.1.301717-darwin-301717.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin</string>
@@ -278,9 +278,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ee6c089ee193e551040d610befc5d1c1</string>
+              <string>de9e0c855ff6ee30c9e027a70bbef032</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/curl_3p-update-curl/rev/297172/arch/Linux/installer/curl-7.38.0.297172-linux-297172.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/curl_3p-update-curl/rev/301717/arch/Linux/installer/curl-7.42.1.301717-linux-301717.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -290,16 +290,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>fdeca7cbc074a88d2701d74a31d21bd8</string>
+              <string>98d15713de8c439b7f54cc14f2df07ac</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/curl_3p-update-curl/rev/297172/arch/CYGWIN/installer/curl-7.38.0.297172-windows-297172.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/curl_3p-update-curl/rev/301717/arch/CYGWIN/installer/curl-7.42.1.301717-windows-301717.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
           </map>
         </map>
         <key>version</key>
-        <string>7.38.0.297172</string>
+        <string>7.42.1.301717</string>
       </map>
       <key>db</key>
       <map>
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
index c0fc1b2be0ecce2bceb1b2263c6e29a77c3ca09f..81d14c695b13c3ab9f18576117f14f6c156a7b63 100755
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ b/indra/linux_crash_logger/CMakeLists.txt
@@ -4,6 +4,7 @@ project(linux_crash_logger)
 
 include(00-Common)
 include(GLH)
+include(LLCoreHttp)
 include(LLCommon)
 include(LLCrashLogger)
 include(LLMath)
@@ -13,8 +14,10 @@ include(LLXML)
 include(Linking)
 include(UI)
 include(FreeType)
+include(Boost)
 
 include_directories(
+    ${LLCOREHTTP_INCLUDE_DIRS}
     ${LLCOMMON_INCLUDE_DIRS}
     ${LLCRASHLOGGER_INCLUDE_DIRS}
     ${LLMATH_INCLUDE_DIRS}
@@ -53,6 +56,10 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
 
 add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES})
 
+# llcommon uses `clock_gettime' which is provided by librt on linux.
+set(LIBRT_LIBRARY rt)
+
+
 target_link_libraries(linux-crash-logger
     ${LLCRASHLOGGER_LIBRARIES}
     ${LLVFS_LIBRARIES}
@@ -60,10 +67,14 @@ target_link_libraries(linux-crash-logger
     ${LLMESSAGE_LIBRARIES}
     ${LLVFS_LIBRARIES}
     ${LLMATH_LIBRARIES}
+    ${LLCOREHTTP_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
+    ${BOOST_CONTEXT_LIBRARY}
+    ${BOOST_COROUTINE_LIBRARY}
     ${UI_LIBRARIES}
     ${DB_LIBRARIES}
     ${FREETYPE_LIBRARIES}
+    ${LIBRT_LIBRARY}
     )
 
 add_custom_target(linux-crash-logger-target ALL
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 1459b9ada2785be76b7a8183123832be4895a2b1..9757679ce1bf57991bc182898d6e6b085a0fd95d 100755
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -8,6 +8,7 @@ include(LLCommon)
 include(Linking)
 include(Boost)
 include(LLSharedLibs)
+include(JsonCpp)
 include(GoogleBreakpad)
 include(GooglePerfTools)
 include(Copy3rdPartyLibs)
@@ -17,6 +18,7 @@ include(URIPARSER)
 include_directories(
     ${EXPAT_INCLUDE_DIRS}
     ${LLCOMMON_INCLUDE_DIRS}
+    ${JSONCPP_INCLUDE_DIR}
     ${ZLIB_INCLUDE_DIRS}
     ${BREAKPAD_INCLUDE_DIRECTORIES}
     ${URIPARSER_INCLUDE_DIRS}
@@ -85,6 +87,7 @@ set(llcommon_SOURCE_FILES
     llrefcount.cpp
     llrun.cpp
     llsd.cpp
+    llsdjson.cpp
     llsdparam.cpp
     llsdserialize.cpp
     llsdserialize_xml.cpp
@@ -193,6 +196,7 @@ set(llcommon_HEADER_FILES
     llrefcount.h
     llsafehandle.h
     llsd.h
+    llsdjson.h
     llsdparam.h
     llsdserialize.h
     llsdserialize_xml.h
@@ -260,6 +264,7 @@ target_link_libraries(
     ${APRUTIL_LIBRARIES}
     ${APR_LIBRARIES}
     ${EXPAT_LIBRARIES}
+    ${JSONCPP_LIBRARIES}
     ${ZLIB_LIBRARIES}
     ${WINDOWS_LIBRARIES}
     ${BOOST_PROGRAM_OPTIONS_LIBRARY}
diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h
index 5cfcdab41cd331c43df806e628e0ace851492b89..e5a913a6a99c56214fc7365b2c13957aae0a810b 100755
--- a/indra/llcommon/linden_common.h
+++ b/indra/llcommon/linden_common.h
@@ -51,6 +51,7 @@
 #include <cstdlib>
 #include <ctime>
 #include <iosfwd>
+#include <memory>
 
 // Linden only libs in alpha-order other than stdtypes.h
 // *NOTE: Please keep includes here to a minimum, see above.
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index baaddcaed1ea64d1cbc425336b84000b55227cd6..957fe034e156e474f79bb892a244d946acee7ef1 100755
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -34,11 +34,65 @@
 // std headers
 // external library headers
 #include <boost/bind.hpp>
+#include <boost/thread/tss.hpp>
 // other Linden headers
 #include "llevents.h"
 #include "llerror.h"
 #include "stringize.h"
 
+namespace {
+
+// do nothing, when we need nothing done
+void no_cleanup(LLCoros::coro::self*) {}
+
+// When the dcoroutine library calls a top-level callable, it implicitly
+// passes coro::self& as the first parameter. All our consumer code used to
+// explicitly pass coro::self& down through all levels of call stack, because
+// at the leaf level we need it for context-switching. But since coroutines
+// are based on cooperative switching, we can cause the top-level entry point
+// to stash a static pointer to the currently-running coroutine, and manage it
+// appropriately as we switch out and back in. That eliminates the need to
+// pass it as an explicit parameter down through every level, which is
+// unfortunately viral in nature. Finding it implicitly rather than explicitly
+// allows minor maintenance in which a leaf-level function adds a new async
+// I/O call that suspends the calling coroutine, WITHOUT having to propagate
+// coro::self& through every function signature down to that point -- and of
+// course through every other caller of every such function.
+// We use a boost::thread_specific_ptr because each thread potentially has its
+// own distinct pool of coroutines.
+// This thread_specific_ptr does NOT own the 'self' object! It merely
+// identifies it. For this reason we instantiate it with a no-op cleanup
+// function.
+static boost::thread_specific_ptr<LLCoros::coro::self>
+sCurrentSelf(no_cleanup);
+
+} // anonymous
+
+//static
+LLCoros::coro::self& llcoro::get_self()
+{
+    LLCoros::coro::self* current_self = sCurrentSelf.get();
+    if (! current_self)
+    {
+        LL_ERRS("LLCoros") << "Calling get_self() from non-coroutine context!" << LL_ENDL;
+    }
+    return *current_self;
+}
+
+llcoro::Suspending::Suspending():
+    mSuspended(sCurrentSelf.get())
+{
+    // For the duration of our time away from this coroutine, sCurrentSelf
+    // must NOT refer to this coroutine.
+    sCurrentSelf.reset();
+}
+
+llcoro::Suspending::~Suspending()
+{
+    // Okay, we're back, reinstate previous value of sCurrentSelf.
+    sCurrentSelf.reset(mSuspended);
+}
+
 LLCoros::LLCoros():
     // MAINT-2724: default coroutine stack size too small on Windows.
     // Previously we used
@@ -60,7 +114,7 @@ bool LLCoros::cleanup(const LLSD&)
         // since last tick?
         if (mi->second->exited())
         {
-			   LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;
+            LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;
             // The erase() call will invalidate its passed iterator value --
             // so increment mi FIRST -- but pass its original value to
             // erase(). This is what postincrement is all about.
@@ -94,7 +148,7 @@ std::string LLCoros::generateDistinctName(const std::string& prefix) const
     {
         if (mCoros.find(name) == mCoros.end())
         {
-			   LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;
+            LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;
             return name;
         }
     }
@@ -114,10 +168,10 @@ bool LLCoros::kill(const std::string& name)
     return true;
 }
 
-std::string LLCoros::getNameByID(const void* self_id) const
+std::string LLCoros::getName() const
 {
-    // Walk the existing coroutines, looking for one from which the 'self_id'
-    // passed to us comes.
+    // Walk the existing coroutines, looking for the current one.
+    void* self_id = llcoro::get_self().get_id();
     for (CoroMap::const_iterator mi(mCoros.begin()), mend(mCoros.end()); mi != mend; ++mi)
     {
         namespace coro_private = boost::dcoroutines::detail;
@@ -136,10 +190,24 @@ void LLCoros::setStackSize(S32 stacksize)
     mStackSize = stacksize;
 }
 
+namespace {
+
+// Top-level wrapper around caller's coroutine callable. This function accepts
+// the coroutine library's implicit coro::self& parameter and sets sCurrentSelf
+// but does not pass it down to the caller's callable.
+void toplevel(LLCoros::coro::self& self, const LLCoros::callable_t& callable)
+{
+    sCurrentSelf.reset(&self);
+    callable();
+    sCurrentSelf.reset();
+}
+
+} // anonymous
+
 /*****************************************************************************
 *   MUST BE LAST
 *****************************************************************************/
-// Turn off MSVC optimizations for just LLCoros::launchImpl() -- see
+// Turn off MSVC optimizations for just LLCoros::launch() -- see
 // DEV-32777. But MSVC doesn't support push/pop for optimization flags as it
 // does for warning suppression, and we really don't want to force
 // optimization ON for other code even in Debug or RelWithDebInfo builds.
@@ -150,9 +218,13 @@ void LLCoros::setStackSize(S32 stacksize)
 #pragma optimize("", off)
 #endif // LL_MSVC
 
-std::string LLCoros::launchImpl(const std::string& prefix, coro* newCoro)
+std::string LLCoros::launch(const std::string& prefix, const callable_t& callable)
 {
     std::string name(generateDistinctName(prefix));
+    // Wrap the caller's callable in our toplevel() function so we can manage
+    // sCurrentSelf appropriately at startup and shutdown of each coroutine.
+    coro* newCoro = new coro(boost::bind(toplevel, _1, callable), mStackSize);
+    // Store it in our pointer map
     mCoros.insert(name, newCoro);
     /* Run the coroutine until its first wait, then return here */
     (*newCoro)(std::nothrow);
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 01ee11da1ac180419c87b7b6d26d9e0667e0399c..e478600f00ba44102abff771728b4753cdd6612c 100755
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -32,10 +32,8 @@
 #include <boost/dcoroutine/coroutine.hpp>
 #include "llsingleton.h"
 #include <boost/ptr_container/ptr_map.hpp>
+#include <boost/function.hpp>
 #include <string>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/iteration/local.hpp>
 #include <stdexcept>
 
 /**
@@ -80,8 +78,8 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
 public:
     /// Canonical boost::dcoroutines::coroutine signature we use
     typedef boost::dcoroutines::coroutine<void()> coro;
-    /// Canonical 'self' type
-    typedef coro::self self;
+    /// Canonical callable type
+    typedef boost::function<void()> callable_t;
 
     /**
      * Create and start running a new coroutine with specified name. The name
@@ -94,39 +92,33 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
      * {
      * public:
      *     ...
-     *     // Do NOT NOT NOT accept reference params other than 'self'!
+     *     // Do NOT NOT NOT accept reference params!
      *     // Pass by value only!
-     *     void myCoroutineMethod(LLCoros::self& self, std::string, LLSD);
+     *     void myCoroutineMethod(std::string, LLSD);
      *     ...
      * };
      * ...
      * std::string name = LLCoros::instance().launch(
-     *    "mycoro", boost::bind(&MyClass::myCoroutineMethod, this, _1,
+     *    "mycoro", boost::bind(&MyClass::myCoroutineMethod, this,
      *                          "somestring", LLSD(17));
      * @endcode
      *
-     * Your function/method must accept LLCoros::self& as its first parameter.
-     * It can accept any other parameters you want -- but ONLY BY VALUE!
-     * Other reference parameters are a BAD IDEA! You Have Been Warned. See
+     * Your function/method can accept any parameters you want -- but ONLY BY
+     * VALUE! Reference parameters are a BAD IDEA! You Have Been Warned. See
      * DEV-32777 comments for an explanation.
      *
-     * Pass a callable that accepts the single LLCoros::self& parameter. It
-     * may work to pass a free function whose only parameter is 'self'; for
-     * all other cases use boost::bind(). Of course, for a non-static class
-     * method, the first parameter must be the class instance. Use the
-     * placeholder _1 for the 'self' parameter. Any other parameters should be
-     * passed via the bind() expression.
+     * Pass a nullary callable. It works to directly pass a nullary free
+     * function (or static method); for all other cases use boost::bind(). Of
+     * course, for a non-static class method, the first parameter must be the
+     * class instance. Any other parameters should be passed via the bind()
+     * expression.
      *
      * launch() tweaks the suggested name so it won't collide with any
      * existing coroutine instance, creates the coroutine instance, registers
      * it with the tweaked name and runs it until its first wait. At that
      * point it returns the tweaked name.
      */
-    template <typename CALLABLE>
-    std::string launch(const std::string& prefix, const CALLABLE& callable)
-    {
-        return launchImpl(prefix, new coro(callable, mStackSize));
-    }
+    std::string launch(const std::string& prefix, const callable_t& callable);
 
     /**
      * Abort a running coroutine by name. Normally, when a coroutine either
@@ -138,27 +130,19 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
     bool kill(const std::string& name);
 
     /**
-     * From within a coroutine, pass its @c self object to look up the
-     * (tweaked) name string by which this coroutine is registered. Returns
-     * the empty string if not found (e.g. if the coroutine was launched by
-     * hand rather than using LLCoros::launch()).
+     * From within a coroutine, look up the (tweaked) name string by which
+     * this coroutine is registered. Returns the empty string if not found
+     * (e.g. if the coroutine was launched by hand rather than using
+     * LLCoros::launch()).
      */
-    template <typename COROUTINE_SELF>
-    std::string getName(const COROUTINE_SELF& self) const
-    {
-        return getNameByID(self.get_id());
-    }
-
-    /// getName() by self.get_id()
-    std::string getNameByID(const void* self_id) const;
+    std::string getName() const;
 
     /// for delayed initialization
     void setStackSize(S32 stacksize);
 
 private:
-    friend class LLSingleton<LLCoros>;
     LLCoros();
-    std::string launchImpl(const std::string& prefix, coro* newCoro);
+    friend class LLSingleton<LLCoros>;
     std::string generateDistinctName(const std::string& prefix) const;
     bool cleanup(const LLSD&);
 
@@ -167,4 +151,24 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
     CoroMap mCoros;
 };
 
+namespace llcoro
+{
+
+/// get the current coro::self& for those who really really care
+LLCoros::coro::self& get_self();
+
+/// Instantiate one of these in a block surrounding any leaf point when
+/// control literally switches away from this coroutine.
+class Suspending
+{
+public:
+    Suspending();
+    ~Suspending();
+
+private:
+    LLCoros::coro::self* mSuspended;
+};
+
+} // namespace llcoro
+
 #endif /* ! defined(LL_LLCOROS_H) */
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index 63040e1772a15b4a9239127df183e1b15a3a0df8..b1b5e9be7d7a913be6160cfa49a8cebb701becc7 100755
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -354,6 +354,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
 #define LL_WARNS(...)	lllog(LLError::LEVEL_WARN, false, ##__VA_ARGS__)
 #define LL_ERRS(...)	lllog(LLError::LEVEL_ERROR, false, ##__VA_ARGS__)
 // alternative to llassert_always that prints explanatory message
+#define LL_WARNS_IF(exp, ...)	if (exp) LL_WARNS(##__VA_ARGS__) << "(" #exp ")"
 #define LL_ERRS_IF(exp, ...)	if (exp) LL_ERRS(##__VA_ARGS__) << "(" #exp ")"
 
 // Only print the log message once (good for warnings or infos that would otherwise
diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp
index 81cc33fbbaca018c6f26100e230075579f037e9e..ad02e139b896aef993c8992eb427eed5a3690cbc 100755
--- a/indra/llcommon/lleventcoro.cpp
+++ b/indra/llcommon/lleventcoro.cpp
@@ -34,38 +34,63 @@
 #include <map>
 // std headers
 // external library headers
+#include <boost/dcoroutine/coroutine.hpp>
+#include <boost/dcoroutine/future.hpp>
 // other Linden headers
 #include "llsdserialize.h"
 #include "llerror.h"
 #include "llcoros.h"
 
-std::string LLEventDetail::listenerNameForCoroImpl(const void* self_id)
+namespace
 {
-    // First, if this coroutine was launched by LLCoros::launch(), find that name.
-    std::string name(LLCoros::instance().getNameByID(self_id));
+
+/**
+ * waitForEventOn() permits a coroutine to temporarily listen on an
+ * LLEventPump any number of times. We don't really want to have to ask
+ * the caller to label each such call with a distinct string; the whole
+ * point of waitForEventOn() is to present a nice sequential interface to
+ * the underlying LLEventPump-with-named-listeners machinery. So we'll use
+ * LLEventPump::inventName() to generate a distinct name for each
+ * temporary listener. On the other hand, because a given coroutine might
+ * call waitForEventOn() any number of times, we don't really want to
+ * consume an arbitrary number of generated inventName()s: that namespace,
+ * though large, is nonetheless finite. So we memoize an invented name for
+ * each distinct coroutine instance.
+ */
+std::string listenerNameForCoro()
+{
+    // If this coroutine was launched by LLCoros::launch(), find that name.
+    std::string name(LLCoros::instance().getName());
     if (! name.empty())
     {
         return name;
     }
-    // Apparently this coroutine wasn't launched by LLCoros::launch(). Check
-    // whether we have a memo for this self_id.
-    typedef std::map<const void*, std::string> MapType;
-    static MapType memo;
-    MapType::const_iterator found = memo.find(self_id);
-    if (found != memo.end())
-    {
-        // this coroutine instance has called us before, reuse same name
-        return found->second;
-    }
     // this is the first time we've been called for this coroutine instance
     name = LLEventPump::inventName("coro");
-    memo[self_id] = name;
-    LL_INFOS("LLEventCoro") << "listenerNameForCoroImpl(" << self_id << "): inventing coro name '"
+    LL_INFOS("LLEventCoro") << "listenerNameForCoro(): inventing coro name '"
                             << name << "'" << LL_ENDL;
     return name;
 }
 
-void LLEventDetail::storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD& value)
+/**
+ * Implement behavior described for postAndWait()'s @a replyPumpNamePath
+ * parameter:
+ *
+ * * If <tt>path.isUndefined()</tt>, do nothing.
+ * * If <tt>path.isString()</tt>, @a dest is an LLSD map: store @a value
+ *   into <tt>dest[path.asString()]</tt>.
+ * * If <tt>path.isInteger()</tt>, @a dest is an LLSD array: store @a
+ *   value into <tt>dest[path.asInteger()]</tt>.
+ * * If <tt>path.isArray()</tt>, iteratively apply the rules above to step
+ *   down through the structure of @a dest. The last array entry in @a
+ *   path specifies the entry in the lowest-level structure in @a dest
+ *   into which to store @a value.
+ *
+ * @note
+ * In the degenerate case in which @a path is an empty array, @a dest will
+ * @em become @a value rather than @em containing it.
+ */
+void storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD& value)
 {
     if (rawPath.isUndefined())
     {
@@ -118,6 +143,155 @@ void LLEventDetail::storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD&
     *pdest = value;
 }
 
+} // anonymous
+
+void llcoro::yield()
+{
+    // By viewer convention, we post an event on the "mainloop" LLEventPump
+    // each iteration of the main event-handling loop. So waiting for a single
+    // event on "mainloop" gives us a one-frame yield.
+    waitForEventOn("mainloop");
+}
+
+LLSD llcoro::postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,
+                         const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath)
+{
+    // declare the future
+    boost::dcoroutines::future<LLSD> future(llcoro::get_self());
+    // make a callback that will assign a value to the future, and listen on
+    // the specified LLEventPump with that callback
+    std::string listenerName(listenerNameForCoro());
+    LLTempBoundListener connection(
+        replyPump.getPump().listen(listenerName,
+                                   voidlistener(boost::dcoroutines::make_callback(future))));
+    // skip the "post" part if requestPump is default-constructed
+    if (requestPump)
+    {
+        // If replyPumpNamePath is non-empty, store the replyPump name in the
+        // request event.
+        LLSD modevent(event);
+        storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName());
+        LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
+                                 << " posting to " << requestPump.getPump().getName()
+                                 << LL_ENDL;
+
+        // *NOTE:Mani - Removed because modevent could contain user's hashed passwd.
+        //                         << ": " << modevent << LL_ENDL;
+        requestPump.getPump().post(modevent);
+    }
+    LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
+                             << " about to wait on LLEventPump " << replyPump.getPump().getName()
+                             << LL_ENDL;
+    // trying to dereference ("resolve") the future makes us wait for it
+    LLSD value;
+    {
+        // instantiate Suspending to manage the "current" coroutine
+        llcoro::Suspending suspended;
+        value = *future;
+    } // destroy Suspending as soon as we're back
+    LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
+                             << " resuming with " << value << LL_ENDL;
+    // returning should disconnect the connection
+    return value;
+}
+
+namespace
+{
+
+/**
+ * This helper is specifically for the two-pump version of waitForEventOn().
+ * We use a single future object, but we want to listen on two pumps with it.
+ * Since we must still adapt from (the callable constructed by)
+ * boost::dcoroutines::make_callback() (void return) to provide an event
+ * listener (bool return), we've adapted VoidListener for the purpose. The
+ * basic idea is that we construct a distinct instance of WaitForEventOnHelper
+ * -- binding different instance data -- for each of the pumps. Then, when a
+ * pump delivers an LLSD value to either WaitForEventOnHelper, it can combine
+ * that LLSD with its discriminator to feed the future object.
+ */
+template <typename LISTENER>
+class WaitForEventOnHelper
+{
+public:
+    WaitForEventOnHelper(const LISTENER& listener, int discriminator):
+        mListener(listener),
+        mDiscrim(discriminator)
+    {}
+    // this signature is required for an LLEventPump listener
+    bool operator()(const LLSD& event)
+    {
+        // our future object is defined to accept LLEventWithID
+        mListener(LLEventWithID(event, mDiscrim));
+        // don't swallow the event, let other listeners see it
+        return false;
+    }
+private:
+    LISTENER mListener;
+    const int mDiscrim;
+};
+
+/// WaitForEventOnHelper type-inference helper
+template <typename LISTENER>
+WaitForEventOnHelper<LISTENER> wfeoh(const LISTENER& listener, int discriminator)
+{
+    return WaitForEventOnHelper<LISTENER>(listener, discriminator);
+}
+
+} // anonymous
+
+namespace llcoro
+{
+
+LLEventWithID postAndWait2(const LLSD& event,
+                           const LLEventPumpOrPumpName& requestPump,
+                           const LLEventPumpOrPumpName& replyPump0,
+                           const LLEventPumpOrPumpName& replyPump1,
+                           const LLSD& replyPump0NamePath,
+                           const LLSD& replyPump1NamePath)
+{
+    // declare the future
+    boost::dcoroutines::future<LLEventWithID> future(llcoro::get_self());
+    // either callback will assign a value to this future; listen on
+    // each specified LLEventPump with a callback
+    std::string name(listenerNameForCoro());
+    LLTempBoundListener connection0(
+        replyPump0.getPump().listen(name + "a",
+                                    wfeoh(boost::dcoroutines::make_callback(future), 0)));
+    LLTempBoundListener connection1(
+        replyPump1.getPump().listen(name + "b",
+                                    wfeoh(boost::dcoroutines::make_callback(future), 1)));
+    // skip the "post" part if requestPump is default-constructed
+    if (requestPump)
+    {
+        // If either replyPumpNamePath is non-empty, store the corresponding
+        // replyPump name in the request event.
+        LLSD modevent(event);
+        storeToLLSDPath(modevent, replyPump0NamePath,
+                        replyPump0.getPump().getName());
+        storeToLLSDPath(modevent, replyPump1NamePath,
+                        replyPump1.getPump().getName());
+        LL_DEBUGS("lleventcoro") << "postAndWait2(): coroutine " << name
+                                 << " posting to " << requestPump.getPump().getName()
+                                 << ": " << modevent << LL_ENDL;
+        requestPump.getPump().post(modevent);
+    }
+    LL_DEBUGS("lleventcoro") << "postAndWait2(): coroutine " << name
+                             << " about to wait on LLEventPumps " << replyPump0.getPump().getName()
+                             << ", " << replyPump1.getPump().getName() << LL_ENDL;
+    // trying to dereference ("resolve") the future makes us wait for it
+    LLEventWithID value;
+    {
+        // instantiate Suspending to manage "current" coroutine
+        llcoro::Suspending suspended;
+        value = *future;
+    } // destroy Suspending as soon as we're back
+    LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << name
+                             << " resuming with (" << value.first << ", " << value.second << ")"
+                             << LL_ENDL;
+    // returning should disconnect both connections
+    return value;
+}
+
 LLSD errorException(const LLEventWithID& result, const std::string& desc)
 {
     // If the result arrived on the error pump (pump 1), instead of
@@ -144,3 +318,5 @@ LLSD errorLog(const LLEventWithID& result, const std::string& desc)
     // A simple return must therefore be from the reply pump (pump 0).
     return result.first;
 }
+
+} // namespace llcoro
diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h
index abbeeaa3739d8ef2ae3ce04b88a3f1976fc71044..e2ce4bb193320911c120086fd36631bb4d7da68b 100755
--- a/indra/llcommon/lleventcoro.h
+++ b/indra/llcommon/lleventcoro.h
@@ -29,8 +29,6 @@
 #if ! defined(LL_LLEVENTCORO_H)
 #define LL_LLEVENTCORO_H
 
-#include <boost/dcoroutine/coroutine.hpp>
-#include <boost/dcoroutine/future.hpp>
 #include <boost/optional.hpp>
 #include <string>
 #include <stdexcept>
@@ -74,13 +72,16 @@ class LLEventPumpOrPumpName
     boost::optional<LLEventPump&> mPump;
 };
 
+namespace llcoro
+{
+
 /// This is an adapter for a signature like void LISTENER(const LLSD&), which
 /// isn't a valid LLEventPump listener: such listeners should return bool.
 template <typename LISTENER>
-class LLVoidListener
+class VoidListener
 {
 public:
-    LLVoidListener(const LISTENER& listener):
+    VoidListener(const LISTENER& listener):
         mListener(listener)
     {}
     bool operator()(const LLSD& event)
@@ -93,65 +94,19 @@ class LLVoidListener
     LISTENER mListener;
 };
 
-/// LLVoidListener helper function to infer the type of the LISTENER
+/// VoidListener helper function to infer the type of the LISTENER
 template <typename LISTENER>
-LLVoidListener<LISTENER> voidlistener(const LISTENER& listener)
+VoidListener<LISTENER> voidlistener(const LISTENER& listener)
 {
-    return LLVoidListener<LISTENER>(listener);
+    return VoidListener<LISTENER>(listener);
 }
 
-namespace LLEventDetail
-{
-    /// Implementation for listenerNameForCoro(), see below
-    LL_COMMON_API std::string listenerNameForCoroImpl(const void* self_id);
-
-    /**
-     * waitForEventOn() permits a coroutine to temporarily listen on an
-     * LLEventPump any number of times. We don't really want to have to ask
-     * the caller to label each such call with a distinct string; the whole
-     * point of waitForEventOn() is to present a nice sequential interface to
-     * the underlying LLEventPump-with-named-listeners machinery. So we'll use
-     * LLEventPump::inventName() to generate a distinct name for each
-     * temporary listener. On the other hand, because a given coroutine might
-     * call waitForEventOn() any number of times, we don't really want to
-     * consume an arbitrary number of generated inventName()s: that namespace,
-     * though large, is nonetheless finite. So we memoize an invented name for
-     * each distinct coroutine instance (each different 'self' object). We
-     * can't know the type of 'self', because it depends on the coroutine
-     * body's signature. So we cast its address to void*, looking for distinct
-     * pointer values. Yes, that means that an early coroutine could cache a
-     * value here, then be destroyed, only to be supplanted by a later
-     * coroutine (of the same or different type), and we'll end up
-     * "recognizing" the second one and reusing the listener name -- but
-     * that's okay, since it won't collide with any listener name used by the
-     * earlier coroutine since that earlier coroutine no longer exists.
-     */
-    template <typename COROUTINE_SELF>
-    std::string listenerNameForCoro(COROUTINE_SELF& self)
-    {
-        return listenerNameForCoroImpl(self.get_id());
-    }
-
-    /**
-     * Implement behavior described for postAndWait()'s @a replyPumpNamePath
-     * parameter:
-     *
-     * * If <tt>path.isUndefined()</tt>, do nothing.
-     * * If <tt>path.isString()</tt>, @a dest is an LLSD map: store @a value
-     *   into <tt>dest[path.asString()]</tt>.
-     * * If <tt>path.isInteger()</tt>, @a dest is an LLSD array: store @a
-     *   value into <tt>dest[path.asInteger()]</tt>.
-     * * If <tt>path.isArray()</tt>, iteratively apply the rules above to step
-     *   down through the structure of @a dest. The last array entry in @a
-     *   path specifies the entry in the lowest-level structure in @a dest
-     *   into which to store @a value.
-     *
-     * @note
-     * In the degenerate case in which @a path is an empty array, @a dest will
-     * @em become @a value rather than @em containing it.
-     */
-    LL_COMMON_API void storeToLLSDPath(LLSD& dest, const LLSD& path, const LLSD& value);
-} // namespace LLEventDetail
+/**
+ * Yield control from a coroutine for one "mainloop" tick. If your coroutine
+ * runs without suspending for nontrivial time, sprinkle in calls to this
+ * function to avoid stalling the rest of the viewer processing.
+ */
+void yield();
 
 /**
  * Post specified LLSD event on the specified LLEventPump, then wait for a
@@ -159,7 +114,7 @@ namespace LLEventDetail
  * convenience: the difference between this function and the sequence
  * @code
  * requestPump.post(myEvent);
- * LLSD reply = waitForEventOn(self, replyPump);
+ * LLSD reply = waitForEventOn(replyPump);
  * @endcode
  * is that the sequence above fails if the reply is posted immediately on
  * @a replyPump, that is, before <tt>requestPump.post()</tt> returns. In the
@@ -201,97 +156,25 @@ namespace LLEventDetail
  *   @a replyPumpNamePath specifies the entry in the lowest-level structure in
  *   @a event into which to store <tt>replyPump.getName()</tt>.
  */
-template <typename SELF>
-LLSD postAndWait(SELF& self, const LLSD& event, const LLEventPumpOrPumpName& requestPump,
-                 const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath=LLSD())
-{
-    // declare the future
-    boost::dcoroutines::future<LLSD> future(self);
-    // make a callback that will assign a value to the future, and listen on
-    // the specified LLEventPump with that callback
-    std::string listenerName(LLEventDetail::listenerNameForCoro(self));
-    LLTempBoundListener connection(
-        replyPump.getPump().listen(listenerName,
-                                   voidlistener(boost::dcoroutines::make_callback(future))));
-    // skip the "post" part if requestPump is default-constructed
-    if (requestPump)
-    {
-        // If replyPumpNamePath is non-empty, store the replyPump name in the
-        // request event.
-        LLSD modevent(event);
-        LLEventDetail::storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName());
-		LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
-                                 << " posting to " << requestPump.getPump().getName()
-								 << LL_ENDL;
-
-		// *NOTE:Mani - Removed because modevent could contain user's hashed passwd.
-		//                         << ": " << modevent << LL_ENDL;
-        requestPump.getPump().post(modevent);
-    }
-    LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
-                             << " about to wait on LLEventPump " << replyPump.getPump().getName()
-                             << LL_ENDL;
-    // trying to dereference ("resolve") the future makes us wait for it
-    LLSD value(*future);
-    LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
-                             << " resuming with " << value << LL_ENDL;
-    // returning should disconnect the connection
-    return value;
-}
+LLSD postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,
+                 const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath=LLSD());
 
 /// Wait for the next event on the specified LLEventPump. Pass either the
 /// LLEventPump& or its string name.
-template <typename SELF>
-LLSD waitForEventOn(SELF& self, const LLEventPumpOrPumpName& pump)
+inline
+LLSD waitForEventOn(const LLEventPumpOrPumpName& pump)
 {
     // This is now a convenience wrapper for postAndWait().
-    return postAndWait(self, LLSD(), LLEventPumpOrPumpName(), pump);
+    return postAndWait(LLSD(), LLEventPumpOrPumpName(), pump);
 }
 
+} // namespace llcoro
+
 /// return type for two-pump variant of waitForEventOn()
 typedef std::pair<LLSD, int> LLEventWithID;
 
-namespace LLEventDetail
+namespace llcoro
 {
-    /**
-     * This helper is specifically for the two-pump version of waitForEventOn().
-     * We use a single future object, but we want to listen on two pumps with it.
-     * Since we must still adapt from (the callable constructed by)
-     * boost::dcoroutines::make_callback() (void return) to provide an event
-     * listener (bool return), we've adapted LLVoidListener for the purpose. The
-     * basic idea is that we construct a distinct instance of WaitForEventOnHelper
-     * -- binding different instance data -- for each of the pumps. Then, when a
-     * pump delivers an LLSD value to either WaitForEventOnHelper, it can combine
-     * that LLSD with its discriminator to feed the future object.
-     */
-    template <typename LISTENER>
-    class WaitForEventOnHelper
-    {
-    public:
-        WaitForEventOnHelper(const LISTENER& listener, int discriminator):
-            mListener(listener),
-            mDiscrim(discriminator)
-        {}
-        // this signature is required for an LLEventPump listener
-        bool operator()(const LLSD& event)
-        {
-            // our future object is defined to accept LLEventWithID
-            mListener(LLEventWithID(event, mDiscrim));
-            // don't swallow the event, let other listeners see it
-            return false;
-        }
-    private:
-        LISTENER mListener;
-        const int mDiscrim;
-    };
-
-    /// WaitForEventOnHelper type-inference helper
-    template <typename LISTENER>
-    WaitForEventOnHelper<LISTENER> wfeoh(const LISTENER& listener, int discriminator)
-    {
-        return WaitForEventOnHelper<LISTENER>(listener, discriminator);
-    }
-} // namespace LLEventDetail
 
 /**
  * This function waits for a reply on either of two specified LLEventPumps.
@@ -313,7 +196,7 @@ namespace LLEventDetail
  * I'd have preferred to overload the name postAndWait() for both signatures.
  * But consider the following ambiguous call:
  * @code
- * postAndWait(self, LLSD(), requestPump, replyPump, "someString");
+ * postAndWait(LLSD(), requestPump, replyPump, "someString");
  * @endcode
  * "someString" could be converted to either LLSD (@a replyPumpNamePath for
  * the single-pump function) or LLEventOrPumpName (@a replyPump1 for two-pump
@@ -322,69 +205,29 @@ namespace LLEventDetail
  * It seems less burdensome to write postAndWait2() than to write either
  * LLSD("someString") or LLEventOrPumpName("someString").
  */
-template <typename SELF>
-LLEventWithID postAndWait2(SELF& self, const LLSD& event,
+LLEventWithID postAndWait2(const LLSD& event,
                            const LLEventPumpOrPumpName& requestPump,
                            const LLEventPumpOrPumpName& replyPump0,
                            const LLEventPumpOrPumpName& replyPump1,
                            const LLSD& replyPump0NamePath=LLSD(),
-                           const LLSD& replyPump1NamePath=LLSD())
-{
-    // declare the future
-    boost::dcoroutines::future<LLEventWithID> future(self);
-    // either callback will assign a value to this future; listen on
-    // each specified LLEventPump with a callback
-    std::string name(LLEventDetail::listenerNameForCoro(self));
-    LLTempBoundListener connection0(
-        replyPump0.getPump().listen(name + "a",
-                               LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 0)));
-    LLTempBoundListener connection1(
-        replyPump1.getPump().listen(name + "b",
-                               LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 1)));
-    // skip the "post" part if requestPump is default-constructed
-    if (requestPump)
-    {
-        // If either replyPumpNamePath is non-empty, store the corresponding
-        // replyPump name in the request event.
-        LLSD modevent(event);
-        LLEventDetail::storeToLLSDPath(modevent, replyPump0NamePath,
-                                       replyPump0.getPump().getName());
-        LLEventDetail::storeToLLSDPath(modevent, replyPump1NamePath,
-                                       replyPump1.getPump().getName());
-        LL_DEBUGS("lleventcoro") << "postAndWait2(): coroutine " << name
-                                 << " posting to " << requestPump.getPump().getName()
-                                 << ": " << modevent << LL_ENDL;
-        requestPump.getPump().post(modevent);
-    }
-    LL_DEBUGS("lleventcoro") << "postAndWait2(): coroutine " << name
-                             << " about to wait on LLEventPumps " << replyPump0.getPump().getName()
-                             << ", " << replyPump1.getPump().getName() << LL_ENDL;
-    // trying to dereference ("resolve") the future makes us wait for it
-    LLEventWithID value(*future);
-    LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << name
-                             << " resuming with (" << value.first << ", " << value.second << ")"
-                             << LL_ENDL;
-    // returning should disconnect both connections
-    return value;
-}
+                           const LLSD& replyPump1NamePath=LLSD());
 
 /**
  * Wait for the next event on either of two specified LLEventPumps.
  */
-template <typename SELF>
+inline
 LLEventWithID
-waitForEventOn(SELF& self,
-               const LLEventPumpOrPumpName& pump0, const LLEventPumpOrPumpName& pump1)
+waitForEventOn(const LLEventPumpOrPumpName& pump0, const LLEventPumpOrPumpName& pump1)
 {
     // This is now a convenience wrapper for postAndWait2().
-    return postAndWait2(self, LLSD(), LLEventPumpOrPumpName(), pump0, pump1);
+    return postAndWait2(LLSD(), LLEventPumpOrPumpName(), pump0, pump1);
 }
 
 /**
  * Helper for the two-pump variant of waitForEventOn(), e.g.:
  *
  * @code
- * LLSD reply = errorException(waitForEventOn(self, replyPump, errorPump),
+ * LLSD reply = errorException(waitForEventOn(replyPump, errorPump),
  *                             "error response from login.cgi");
  * @endcode
  *
@@ -400,6 +243,8 @@ waitForEventOn(SELF& self,
  */
 LLSD errorException(const LLEventWithID& result, const std::string& desc);
 
+} // namespace llcoro
+
 /**
  * Exception thrown by errorException(). We don't call this LLEventError
  * because it's not an error in event processing: rather, this exception
@@ -420,12 +265,17 @@ class LL_COMMON_API LLErrorEvent: public std::runtime_error
     LLSD mData;
 };
 
+namespace llcoro
+{
+
 /**
  * Like errorException(), save that this trips a fatal error using LL_ERRS
  * rather than throwing an exception.
  */
 LL_COMMON_API LLSD errorLog(const LLEventWithID& result, const std::string& desc);
 
+} // namespace llcoro
+
 /**
  * Certain event APIs require the name of an LLEventPump on which they should
  * post results. While it works to invent a distinct name and let
@@ -454,26 +304,16 @@ class LL_COMMON_API LLCoroEventPump
 
     /**
      * Wait for an event on this LLEventPump.
-     *
-     * @note
-     * The other major usage pattern we considered was to bind @c self at
-     * LLCoroEventPump construction time, which would avoid passing the
-     * parameter to each wait() call. But if we were going to bind @c self as
-     * a class member, we'd need to specify a class template parameter
-     * indicating its type. The big advantage of passing it to the wait() call
-     * is that the type can be implicit.
      */
-    template <typename SELF>
-    LLSD wait(SELF& self)
+    LLSD wait()
     {
-        return waitForEventOn(self, mPump);
+        return llcoro::waitForEventOn(mPump);
     }
 
-    template <typename SELF>
-    LLSD postAndWait(SELF& self, const LLSD& event, const LLEventPumpOrPumpName& requestPump,
+    LLSD postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,
                      const LLSD& replyPumpNamePath=LLSD())
     {
-        return ::postAndWait(self, event, requestPump, mPump, replyPumpNamePath);
+        return llcoro::postAndWait(event, requestPump, mPump, replyPumpNamePath);
     }
 
 private:
@@ -509,57 +349,51 @@ class LL_COMMON_API LLCoroEventPumps
     /// request pump 1
     LLEventPump& getPump1() { return mPump1; }
 
-    /// waitForEventOn(self, either of our two LLEventPumps)
-    template <typename SELF>
-    LLEventWithID wait(SELF& self)
+    /// waitForEventOn(either of our two LLEventPumps)
+    LLEventWithID wait()
     {
-        return waitForEventOn(self, mPump0, mPump1);
+        return llcoro::waitForEventOn(mPump0, mPump1);
     }
 
-    /// errorException(wait(self))
-    template <typename SELF>
-    LLSD waitWithException(SELF& self)
+    /// errorException(wait())
+    LLSD waitWithException()
     {
-        return errorException(wait(self), std::string("Error event on ") + getName1());
+        return llcoro::errorException(wait(), std::string("Error event on ") + getName1());
     }
 
-    /// errorLog(wait(self))
-    template <typename SELF>
-    LLSD waitWithLog(SELF& self)
+    /// errorLog(wait())
+    LLSD waitWithLog()
     {
-        return errorLog(wait(self), std::string("Error event on ") + getName1());
+        return llcoro::errorLog(wait(), std::string("Error event on ") + getName1());
     }
 
-    template <typename SELF>
-    LLEventWithID postAndWait(SELF& self, const LLSD& event,
+    LLEventWithID postAndWait(const LLSD& event,
                               const LLEventPumpOrPumpName& requestPump,
                               const LLSD& replyPump0NamePath=LLSD(),
                               const LLSD& replyPump1NamePath=LLSD())
     {
-        return postAndWait2(self, event, requestPump, mPump0, mPump1,
-                            replyPump0NamePath, replyPump1NamePath);
+        return llcoro::postAndWait2(event, requestPump, mPump0, mPump1,
+                                    replyPump0NamePath, replyPump1NamePath);
     }
 
-    template <typename SELF>
-    LLSD postAndWaitWithException(SELF& self, const LLSD& event,
+    LLSD postAndWaitWithException(const LLSD& event,
                                   const LLEventPumpOrPumpName& requestPump,
                                   const LLSD& replyPump0NamePath=LLSD(),
                                   const LLSD& replyPump1NamePath=LLSD())
     {
-        return errorException(postAndWait(self, event, requestPump,
-                                          replyPump0NamePath, replyPump1NamePath),
-                              std::string("Error event on ") + getName1());
+        return llcoro::errorException(postAndWait(event, requestPump,
+                                                  replyPump0NamePath, replyPump1NamePath),
+                                      std::string("Error event on ") + getName1());
     }
 
-    template <typename SELF>
-    LLSD postAndWaitWithLog(SELF& self, const LLSD& event,
+    LLSD postAndWaitWithLog(const LLSD& event,
                             const LLEventPumpOrPumpName& requestPump,
                             const LLSD& replyPump0NamePath=LLSD(),
                             const LLSD& replyPump1NamePath=LLSD())
     {
-        return errorLog(postAndWait(self, event, requestPump,
-                                    replyPump0NamePath, replyPump1NamePath),
-                        std::string("Error event on ") + getName1());
+        return llcoro::errorLog(postAndWait(event, requestPump,
+                                            replyPump0NamePath, replyPump1NamePath),
+                                std::string("Error event on ") + getName1());
     }
 
 private:
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index 3836a9b5fbe85555ec8afde55fa0b3755d0d82c8..11079735691b58be85916e4e34db789d456d8cb8 100755
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -143,15 +143,10 @@ class LL_COMMON_API LLThreadSafeRefCount
 	LLAtomic32< S32	> mRef; 
 };
 
-/**
- * intrusive pointer support
- * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
- */
 /**
  * intrusive pointer support for LLThreadSafeRefCount
  * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
  */
-
 inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p) 
 {
 	p->ref();
@@ -162,6 +157,10 @@ inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
 	p->unref(); 
 }
 
+/**
+ * intrusive pointer support
+ * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
+ */
 inline void intrusive_ptr_add_ref(LLRefCount* p) 
 {
 	p->ref();
diff --git a/indra/llcommon/llsdjson.cpp b/indra/llcommon/llsdjson.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2afdba388aead21dbb0dfe8f38cb3ea8b7a1dd42
--- /dev/null
+++ b/indra/llcommon/llsdjson.cpp
@@ -0,0 +1,78 @@
+/** 
+ * @file llsdjson.cpp
+ * @brief LLSD flexible data system
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2015, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+// Must turn on conditional declarations in header file so definitions end up
+// with proper linkage.
+#define LLSD_DEBUG_INFO
+#include "linden_common.h"
+
+#include "llsdjson.h"
+
+#include "llerror.h"
+#include "../llmath/llmath.h"
+
+//=========================================================================
+LLSD LlsdFromJson(const Json::Value &val)
+{
+    LLSD result;
+
+    switch (val.type())
+    {
+    default:
+    case Json::nullValue:
+        break;
+    case Json::intValue:
+        result = LLSD(static_cast<LLSD::Integer>(val.asInt()));
+        break;
+    case Json::uintValue:
+        result = LLSD(static_cast<LLSD::Integer>(val.asUInt()));
+        break;
+    case Json::realValue:
+        result = LLSD(static_cast<LLSD::Real>(val.asDouble()));
+        break;
+    case Json::stringValue:
+        result = LLSD(static_cast<LLSD::String>(val.asString()));
+        break;
+    case Json::booleanValue:
+        result = LLSD(static_cast<LLSD::Boolean>(val.asBool()));
+        break;
+    case Json::arrayValue:
+        result = LLSD::emptyArray();
+        for (Json::ValueConstIterator it = val.begin(); it != val.end(); ++it)
+        {
+            result.append(LlsdFromJson((*it)));
+        }
+        break;
+    case Json::objectValue:
+        result = LLSD::emptyMap();
+        for (Json::ValueConstIterator it = val.begin(); it != val.end(); ++it)
+        {
+            result[it.memberName()] = LlsdFromJson((*it));
+        }
+        break;
+    }
+    return result;
+}
diff --git a/indra/llcommon/llsdjson.h b/indra/llcommon/llsdjson.h
new file mode 100644
index 0000000000000000000000000000000000000000..cdf9fed500794350755140d39b425ba709c1f445
--- /dev/null
+++ b/indra/llcommon/llsdjson.h
@@ -0,0 +1,59 @@
+/** 
+ * @file llsdjson.cpp
+ * @brief LLSD flexible data system
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2015, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSDJSON_H
+#define LL_LLSDJSON_H
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "stdtypes.h"
+
+#include "llsd.h"
+#include "value.h"
+
+/// Convert a parsed JSON structure into LLSD maintaining member names and 
+/// array indexes.
+/// JSON/JavaScript types are converted as follows:
+/// 
+/// JSON Type     | LLSD Type
+/// --------------+--------------
+///  null         |  undefined
+///  integer      |  LLSD::Integer
+///  unsigned     |  LLSD::Integer
+///  real/numeric |  LLSD::Real
+///  string       |  LLSD::String
+///  boolean      |  LLSD::Boolean
+///  array        |  LLSD::Array
+///  object       |  LLSD::Map
+///  
+/// For maps and arrays child entries will be converted and added to the structure.
+/// Order is preserved for an array but not for objects.
+LLSD LlsdFromJson(const Json::Value &val);
+
+
+#endif // LL_LLSDJSON_H
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 0177f48bf5d08a722abb8de1f72c34bb9a3714fc..393f6d7a8c1534ef0c796079c04f7136d8fb1bcd 100755
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -1394,6 +1394,7 @@ BOOL LLStringUtilBase<T>::containsNonprintable(const string_type& string)
 	return rv;
 }
 
+// *TODO: reimplement in terms of algorithm 
 //static
 template<class T> 
 void LLStringUtilBase<T>::stripNonprintable(string_type& string)
@@ -1427,6 +1428,7 @@ void LLStringUtilBase<T>::stripNonprintable(string_type& string)
 	delete []c_string;
 }
 
+// *TODO: reimplement in terms of algorithm 
 template<class T>
 std::basic_string<T> LLStringUtilBase<T>::quote(const string_type& str,
 												const string_type& triggers,
diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp
index 2096807e53effcfc49e5bd288e30f4fe8675f458..00be5035f26b84afb894a051c6f5101ef081abd5 100755
--- a/indra/llcommon/tests/lleventcoro_test.cpp
+++ b/indra/llcommon/tests/lleventcoro_test.cpp
@@ -59,17 +59,20 @@
 //  http://www.boost.org/LICENSE_1_0.txt)
 /*****************************************************************************/
 
+#define BOOST_RESULT_OF_USE_TR1 1
 // On some platforms, Boost.Coroutine must #define magic symbols before
 // #including platform-API headers. Naturally, that's ineffective unless the
 // Boost.Coroutine #include is the *first* #include of the platform header.
 // That means that client code must generally #include Boost.Coroutine headers
 // before anything else.
+#define BOOST_RESULT_OF_USE_TR1 1
 #include <boost/dcoroutine/coroutine.hpp>
 // Normally, lleventcoro.h obviates future.hpp. We only include this because
 // we implement a "by hand" test of future functionality.
 #include <boost/dcoroutine/future.hpp>
 #include <boost/bind.hpp>
 #include <boost/range.hpp>
+#include <boost/utility.hpp>
 
 #include "linden_common.h"
 
@@ -82,9 +85,12 @@
 #include "llevents.h"
 #include "tests/wrapllerrs.h"
 #include "stringize.h"
+#include "llcoros.h"
 #include "lleventcoro.h"
 #include "../test/debug.h"
 
+using namespace llcoro;
+
 /*****************************************************************************
 *   from the banana.cpp example program borrowed for test<1>()
 *****************************************************************************/
@@ -121,9 +127,6 @@ typedef coroutine<std::string::iterator(void)> match_coroutine_type;
 /*****************************************************************************
 *   Test helpers
 *****************************************************************************/
-// I suspect this will be typical of coroutines used in Linden software
-typedef boost::dcoroutines::coroutine<void()> coroutine_type;
-
 /// Simulate an event API whose response is immediate: sent on receipt of the
 /// initial request, rather than after some delay. This is the case that
 /// distinguishes postAndWait() from calling post(), then calling
@@ -162,306 +165,7 @@ class ImmediateAPI
 *****************************************************************************/
 namespace tut
 {
-    struct coroutine_data
-    {
-        // Define coroutine bodies as methods here so they can use ensure*()
-
-        void explicit_wait(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                // ... do whatever preliminary stuff must happen ...
-
-                // declare the future
-                boost::dcoroutines::future<LLSD> future(self);
-                // tell the future what to wait for
-                LLTempBoundListener connection(
-                    LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::dcoroutines::make_callback(future))));
-                ensure("Not yet", ! future);
-                // attempting to dereference ("resolve") the future causes the calling
-                // coroutine to wait for it
-                debug("about to wait");
-                result = *future;
-                ensure("Got it", future);
-            }
-            END
-        }
-
-        void waitForEventOn1(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                result = waitForEventOn(self, "source");
-            }
-            END
-        }
-
-        void waitForEventOn2(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLEventWithID pair = waitForEventOn(self, "reply", "error");
-                result = pair.first;
-                which  = pair.second;
-                debug(STRINGIZE("result = " << result << ", which = " << which));
-            }
-            END
-        }
-
-        void postAndWait1(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                result = postAndWait(self,
-                                     LLSDMap("value", 17),       // request event
-                                     immediateAPI.getPump(),     // requestPump
-                                     "reply1",                   // replyPump
-                                     "reply");                   // request["reply"] = name
-            }
-            END
-        }
-
-        void postAndWait2(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLEventWithID pair = ::postAndWait2(self,
-                                                    LLSDMap("value", 18),
-                                                    immediateAPI.getPump(),
-                                                    "reply2",
-                                                    "error2",
-                                                    "reply",
-                                                    "error");
-                result = pair.first;
-                which  = pair.second;
-                debug(STRINGIZE("result = " << result << ", which = " << which));
-            }
-            END
-        }
-
-        void postAndWait2_1(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLEventWithID pair = ::postAndWait2(self,
-                                                    LLSDMap("value", 18)("fail", LLSD()),
-                                                    immediateAPI.getPump(),
-                                                    "reply2",
-                                                    "error2",
-                                                    "reply",
-                                                    "error");
-                result = pair.first;
-                which  = pair.second;
-                debug(STRINGIZE("result = " << result << ", which = " << which));
-            }
-            END
-        }
-
-        void coroPump(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPump waiter;
-                replyName = waiter.getName();
-                result = waiter.wait(self);
-            }
-            END
-        }
-
-        void coroPumpPost(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPump waiter;
-                result = waiter.postAndWait(self, LLSDMap("value", 17),
-                                            immediateAPI.getPump(), "reply");
-            }
-            END
-        }
-
-        void coroPumps(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                replyName = waiter.getName0();
-                errorName = waiter.getName1();
-                LLEventWithID pair(waiter.wait(self));
-                result = pair.first;
-                which  = pair.second;
-            }
-            END
-        }
-
-        void coroPumpsNoEx(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                replyName = waiter.getName0();
-                errorName = waiter.getName1();
-                result = waiter.waitWithException(self);
-            }
-            END
-        }
-
-        void coroPumpsEx(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                replyName = waiter.getName0();
-                errorName = waiter.getName1();
-                try
-                {
-                    result = waiter.waitWithException(self);
-                    debug("no exception");
-                }
-                catch (const LLErrorEvent& e)
-                {
-                    debug(STRINGIZE("exception " << e.what()));
-                    errordata = e.getData();
-                }
-            }
-            END
-        }
-
-        void coroPumpsNoLog(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                replyName = waiter.getName0();
-                errorName = waiter.getName1();
-                result = waiter.waitWithLog(self);
-            }
-            END
-        }
-
-        void coroPumpsLog(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                replyName = waiter.getName0();
-                errorName = waiter.getName1();
-                WrapLLErrs capture;
-                try
-                {
-                    result = waiter.waitWithLog(self);
-                    debug("no exception");
-                }
-                catch (const WrapLLErrs::FatalException& e)
-                {
-                    debug(STRINGIZE("exception " << e.what()));
-                    threw = e.what();
-                }
-            }
-            END
-        }
-
-        void coroPumpsPost(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                LLEventWithID pair(waiter.postAndWait(self, LLSDMap("value", 23),
-                                                      immediateAPI.getPump(), "reply", "error"));
-                result = pair.first;
-                which  = pair.second;
-            }
-            END
-        }
-
-        void coroPumpsPost_1(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                LLEventWithID pair(
-                    waiter.postAndWait(self, LLSDMap("value", 23)("fail", LLSD()),
-                                       immediateAPI.getPump(), "reply", "error"));
-                result = pair.first;
-                which  = pair.second;
-            }
-            END
-        }
-
-        void coroPumpsPostNoEx(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                result = waiter.postAndWaitWithException(self, LLSDMap("value", 8),
-                                                         immediateAPI.getPump(), "reply", "error");
-            }
-            END
-        }
-
-        void coroPumpsPostEx(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                try
-                {
-                    result = waiter.postAndWaitWithException(self,
-                        LLSDMap("value", 9)("fail", LLSD()),
-                        immediateAPI.getPump(), "reply", "error");
-                    debug("no exception");
-                }
-                catch (const LLErrorEvent& e)
-                {
-                    debug(STRINGIZE("exception " << e.what()));
-                    errordata = e.getData();
-                }
-            }
-            END
-        }
-
-        void coroPumpsPostNoLog(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                result = waiter.postAndWaitWithLog(self, LLSDMap("value", 30),
-                                                   immediateAPI.getPump(), "reply", "error");
-            }
-            END
-        }
-
-        void coroPumpsPostLog(coroutine_type::self& self)
-        {
-            BEGIN
-            {
-                LLCoroEventPumps waiter;
-                WrapLLErrs capture;
-                try
-                {
-                    result = waiter.postAndWaitWithLog(self,
-                        LLSDMap("value", 31)("fail", LLSD()),
-                        immediateAPI.getPump(), "reply", "error");
-                    debug("no exception");
-                }
-                catch (const WrapLLErrs::FatalException& e)
-                {
-                    debug(STRINGIZE("exception " << e.what()));
-                    threw = e.what();
-                }
-            }
-            END
-        }
-
-        void ensure_done(coroutine_type& coro)
-        {
-            ensure("coroutine complete", ! coro);
-        }
-
-        ImmediateAPI immediateAPI;
-        std::string replyName, errorName, threw;
-        LLSD result, errordata;
-        int which;
-    };
+    struct coroutine_data {};
     typedef test_group<coroutine_data> coroutine_group;
     typedef coroutine_group::object object;
     coroutine_group coroutinegrp("coroutine");
@@ -511,16 +215,56 @@ namespace tut
         ensure("done", ! matcher);
     }
 
+    // use static data so we can intersperse coroutine functions with the
+    // tests that engage them
+    ImmediateAPI immediateAPI;
+    std::string replyName, errorName, threw;
+    LLSD result, errordata;
+    int which;
+
+    // reinit vars at the start of each test
+    void clear()
+    {
+        replyName.clear();
+        errorName.clear();
+        threw.clear();
+        result = LLSD();
+        errordata = LLSD();
+        which = 0;
+    }
+
+    void explicit_wait(boost::dcoroutines::coroutine<void()>::self& self)
+    {
+        BEGIN
+        {
+            // ... do whatever preliminary stuff must happen ...
+
+            // declare the future
+            boost::dcoroutines::future<LLSD> future(self);
+            // tell the future what to wait for
+            LLTempBoundListener connection(
+                LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::dcoroutines::make_callback(future))));
+            ensure("Not yet", ! future);
+            // attempting to dereference ("resolve") the future causes the calling
+            // coroutine to wait for it
+            debug("about to wait");
+            result = *future;
+            ensure("Got it", future);
+        }
+        END
+    }
+
     template<> template<>
     void object::test<2>()
     {
+        clear();
         set_test_name("explicit_wait");
         DEBUG;
 
         // Construct the coroutine instance that will run explicit_wait.
         // Pass the ctor a callable that accepts the coroutine_type::self
         // param passed by the library.
-        coroutine_type coro(boost::bind(&coroutine_data::explicit_wait, this, _1));
+        boost::dcoroutines::coroutine<void()> coro(explicit_wait);
         // Start the coroutine
         coro(std::nothrow);
         // When the coroutine waits for the event pump, it returns here.
@@ -528,37 +272,56 @@ namespace tut
         // Satisfy the wait.
         LLEventPumps::instance().obtain("source").post("received");
         // Now wait for the coroutine to complete.
-        ensure_done(coro);
+        ensure("coroutine complete", ! coro);
         // ensure the coroutine ran and woke up again with the intended result
         ensure_equals(result.asString(), "received");
     }
 
+    void waitForEventOn1()
+    {
+        BEGIN
+        {
+            result = waitForEventOn("source");
+        }
+        END
+    }
+
     template<> template<>
     void object::test<3>()
     {
+        clear();
         set_test_name("waitForEventOn1");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn1, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<3>", waitForEventOn1);
         debug("about to send");
         LLEventPumps::instance().obtain("source").post("received");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "received");
     }
 
+    void waitForEventOn2()
+    {
+        BEGIN
+        {
+            LLEventWithID pair = waitForEventOn("reply", "error");
+            result = pair.first;
+            which  = pair.second;
+            debug(STRINGIZE("result = " << result << ", which = " << which));
+        }
+        END
+    }
+
     template<> template<>
     void object::test<4>()
     {
+        clear();
         set_test_name("waitForEventOn2 reply");
         {
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<4>", waitForEventOn2);
         debug("about to send");
         LLEventPumps::instance().obtain("reply").post("received");
         debug("back from send");
-        ensure_done(coro);
         }
         ensure_equals(result.asString(), "received");
         ensure_equals("which pump", which, 0);
@@ -567,43 +330,65 @@ namespace tut
     template<> template<>
     void object::test<5>()
     {
+        clear();
         set_test_name("waitForEventOn2 error");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<5>", waitForEventOn2);
         debug("about to send");
         LLEventPumps::instance().obtain("error").post("badness");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "badness");
         ensure_equals("which pump", which, 1);
     }
 
+    void coroPump()
+    {
+        BEGIN
+        {
+            LLCoroEventPump waiter;
+            replyName = waiter.getName();
+            result = waiter.wait();
+        }
+        END
+    }
+
     template<> template<>
     void object::test<6>()
     {
+        clear();
         set_test_name("coroPump");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPump, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<6>", coroPump);
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "received");
     }
 
+    void coroPumps()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            replyName = waiter.getName0();
+            errorName = waiter.getName1();
+            LLEventWithID pair(waiter.wait());
+            result = pair.first;
+            which  = pair.second;
+        }
+        END
+    }
+
     template<> template<>
     void object::test<7>()
     {
+        clear();
         set_test_name("coroPumps reply");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<7>", coroPumps);
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "received");
         ensure_equals("which pump", which, 0);
     }
@@ -611,188 +396,389 @@ namespace tut
     template<> template<>
     void object::test<8>()
     {
+        clear();
         set_test_name("coroPumps error");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<8>", coroPumps);
         debug("about to send");
         LLEventPumps::instance().obtain(errorName).post("badness");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "badness");
         ensure_equals("which pump", which, 1);
     }
 
+    void coroPumpsNoEx()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            replyName = waiter.getName0();
+            errorName = waiter.getName1();
+            result = waiter.waitWithException();
+        }
+        END
+    }
+
     template<> template<>
     void object::test<9>()
     {
+        clear();
         set_test_name("coroPumpsNoEx");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoEx, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<9>", coroPumpsNoEx);
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "received");
     }
 
+    void coroPumpsEx()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            replyName = waiter.getName0();
+            errorName = waiter.getName1();
+            try
+            {
+                result = waiter.waitWithException();
+                debug("no exception");
+            }
+            catch (const LLErrorEvent& e)
+            {
+                debug(STRINGIZE("exception " << e.what()));
+                errordata = e.getData();
+            }
+        }
+        END
+    }
+
     template<> template<>
     void object::test<10>()
     {
+        clear();
         set_test_name("coroPumpsEx");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsEx, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<10>", coroPumpsEx);
         debug("about to send");
         LLEventPumps::instance().obtain(errorName).post("badness");
         debug("back from send");
-        ensure_done(coro);
         ensure("no result", result.isUndefined());
         ensure_equals("got error", errordata.asString(), "badness");
     }
 
+    void coroPumpsNoLog()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            replyName = waiter.getName0();
+            errorName = waiter.getName1();
+            result = waiter.waitWithLog();
+        }
+        END
+    }
+
     template<> template<>
     void object::test<11>()
     {
+        clear();
         set_test_name("coroPumpsNoLog");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoLog, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<11>", coroPumpsNoLog);
         debug("about to send");
         LLEventPumps::instance().obtain(replyName).post("received");
         debug("back from send");
-        ensure_done(coro);
         ensure_equals(result.asString(), "received");
     }
 
+    void coroPumpsLog()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            replyName = waiter.getName0();
+            errorName = waiter.getName1();
+            WrapLLErrs capture;
+            try
+            {
+                result = waiter.waitWithLog();
+                debug("no exception");
+            }
+            catch (const WrapLLErrs::FatalException& e)
+            {
+                debug(STRINGIZE("exception " << e.what()));
+                threw = e.what();
+            }
+        }
+        END
+    }
+
     template<> template<>
     void object::test<12>()
     {
+        clear();
         set_test_name("coroPumpsLog");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsLog, this, _1));
-        coro(std::nothrow);
+        LLCoros::instance().launch("test<12>", coroPumpsLog);
         debug("about to send");
         LLEventPumps::instance().obtain(errorName).post("badness");
         debug("back from send");
-        ensure_done(coro);
         ensure("no result", result.isUndefined());
         ensure_contains("got error", threw, "badness");
     }
 
+    void postAndWait1()
+    {
+        BEGIN
+        {
+            result = postAndWait(LLSDMap("value", 17),       // request event
+                                 immediateAPI.getPump(),     // requestPump
+                                 "reply1",                   // replyPump
+                                 "reply");                   // request["reply"] = name
+        }
+        END
+    }
+
     template<> template<>
     void object::test<13>()
     {
+        clear();
         set_test_name("postAndWait1");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::postAndWait1, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<13>", postAndWait1);
         ensure_equals(result.asInteger(), 18);
     }
 
+    void postAndWait2()
+    {
+        BEGIN
+        {
+            LLEventWithID pair = ::postAndWait2(LLSDMap("value", 18),
+                                                immediateAPI.getPump(),
+                                                "reply2",
+                                                "error2",
+                                                "reply",
+                                                "error");
+            result = pair.first;
+            which  = pair.second;
+            debug(STRINGIZE("result = " << result << ", which = " << which));
+        }
+        END
+    }
+
     template<> template<>
     void object::test<14>()
     {
+        clear();
         set_test_name("postAndWait2");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::postAndWait2, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<14>", postAndWait2);
         ensure_equals(result.asInteger(), 19);
         ensure_equals(which, 0);
     }
 
+    void postAndWait2_1()
+    {
+        BEGIN
+        {
+            LLEventWithID pair = ::postAndWait2(LLSDMap("value", 18)("fail", LLSD()),
+                                                immediateAPI.getPump(),
+                                                "reply2",
+                                                "error2",
+                                                "reply",
+                                                "error");
+            result = pair.first;
+            which  = pair.second;
+            debug(STRINGIZE("result = " << result << ", which = " << which));
+        }
+        END
+    }
+
     template<> template<>
     void object::test<15>()
     {
+        clear();
         set_test_name("postAndWait2_1");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::postAndWait2_1, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<15>", postAndWait2_1);
         ensure_equals(result.asInteger(), 19);
         ensure_equals(which, 1);
     }
 
+    void coroPumpPost()
+    {
+        BEGIN
+        {
+            LLCoroEventPump waiter;
+            result = waiter.postAndWait(LLSDMap("value", 17),
+                                        immediateAPI.getPump(), "reply");
+        }
+        END
+    }
+
     template<> template<>
     void object::test<16>()
     {
+        clear();
         set_test_name("coroPumpPost");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpPost, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<16>", coroPumpPost);
         ensure_equals(result.asInteger(), 18);
     }
 
+    void coroPumpsPost()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            LLEventWithID pair(waiter.postAndWait(LLSDMap("value", 23),
+                                                  immediateAPI.getPump(), "reply", "error"));
+            result = pair.first;
+            which  = pair.second;
+        }
+        END
+    }
+
     template<> template<>
     void object::test<17>()
     {
+        clear();
         set_test_name("coroPumpsPost reply");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<17>", coroPumpsPost);
         ensure_equals(result.asInteger(), 24);
         ensure_equals("which pump", which, 0);
     }
 
+    void coroPumpsPost_1()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            LLEventWithID pair(
+                waiter.postAndWait(LLSDMap("value", 23)("fail", LLSD()),
+                                   immediateAPI.getPump(), "reply", "error"));
+            result = pair.first;
+            which  = pair.second;
+        }
+        END
+    }
+
     template<> template<>
     void object::test<18>()
     {
+        clear();
         set_test_name("coroPumpsPost error");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost_1, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<18>", coroPumpsPost_1);
         ensure_equals(result.asInteger(), 24);
         ensure_equals("which pump", which, 1);
     }
 
+    void coroPumpsPostNoEx()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            result = waiter.postAndWaitWithException(LLSDMap("value", 8),
+                                                     immediateAPI.getPump(), "reply", "error");
+        }
+        END
+    }
+
     template<> template<>
     void object::test<19>()
     {
+        clear();
         set_test_name("coroPumpsPostNoEx");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoEx, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<19>", coroPumpsPostNoEx);
         ensure_equals(result.asInteger(), 9);
     }
 
+    void coroPumpsPostEx()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            try
+            {
+                result = waiter.postAndWaitWithException(
+                    LLSDMap("value", 9)("fail", LLSD()),
+                    immediateAPI.getPump(), "reply", "error");
+                debug("no exception");
+            }
+            catch (const LLErrorEvent& e)
+            {
+                debug(STRINGIZE("exception " << e.what()));
+                errordata = e.getData();
+            }
+        }
+        END
+    }
+
     template<> template<>
     void object::test<20>()
     {
+        clear();
         set_test_name("coroPumpsPostEx");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostEx, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<20>", coroPumpsPostEx);
         ensure("no result", result.isUndefined());
         ensure_equals("got error", errordata.asInteger(), 10);
     }
 
+    void coroPumpsPostNoLog()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            result = waiter.postAndWaitWithLog(LLSDMap("value", 30),
+                                               immediateAPI.getPump(), "reply", "error");
+        }
+        END
+    }
+
     template<> template<>
     void object::test<21>()
     {
+        clear();
         set_test_name("coroPumpsPostNoLog");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoLog, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<21>", coroPumpsPostNoLog);
         ensure_equals(result.asInteger(), 31);
     }
 
+    void coroPumpsPostLog()
+    {
+        BEGIN
+        {
+            LLCoroEventPumps waiter;
+            WrapLLErrs capture;
+            try
+            {
+                result = waiter.postAndWaitWithLog(
+                    LLSDMap("value", 31)("fail", LLSD()),
+                    immediateAPI.getPump(), "reply", "error");
+                debug("no exception");
+            }
+            catch (const WrapLLErrs::FatalException& e)
+            {
+                debug(STRINGIZE("exception " << e.what()));
+                threw = e.what();
+            }
+        }
+        END
+    }
+
     template<> template<>
     void object::test<22>()
     {
+        clear();
         set_test_name("coroPumpsPostLog");
         DEBUG;
-        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostLog, this, _1));
-        coro(std::nothrow);
-        ensure_done(coro);
+        LLCoros::instance().launch("test<22>", coroPumpsPostLog);
         ensure("no result", result.isUndefined());
         ensure_contains("got error", threw, "32");
     }
diff --git a/indra/llcorehttp/_httpinternal.h b/indra/llcorehttp/_httpinternal.h
index a2a60ca05677eb5d611b04789b7b5e01ed30b540..79c89d6c920f9950ca8171bf81c6cd6cfc58e37b 100755
--- a/indra/llcorehttp/_httpinternal.h
+++ b/indra/llcorehttp/_httpinternal.h
@@ -104,8 +104,9 @@ namespace LLCore
 {
 
 // Maxium number of policy classes that can be defined.
-// *TODO:  Currently limited to the default class + 1, extend.
-const int HTTP_POLICY_CLASS_LIMIT = 8;
+// *TODO:  Currently limited to the default class + 1, extend. 
+// (TSN: should this be more dynamically sized.  Is there a reason to hard limit the number of policies?)
+const int HTTP_POLICY_CLASS_LIMIT = 32;
 
 // Debug/informational tracing.  Used both
 // as a global option and in per-request traces.
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index b9632a7921a23ca1869f6da5cd11061ee32cace6..799587ff22536b61a927e191eb57025b81335e66 100755
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -139,7 +139,8 @@ HttpOpRequest::HttpOpRequest()
 	  mPolicyRetries(0),
 	  mPolicy503Retries(0),
 	  mPolicyRetryAt(HttpTime(0)),
-	  mPolicyRetryLimit(HTTP_RETRY_COUNT_DEFAULT)
+	  mPolicyRetryLimit(HTTP_RETRY_COUNT_DEFAULT),
+	  mCallbackSSLVerify(NULL)
 {
 	// *NOTE:  As members are added, retry initialization/cleanup
 	// may need to be extended in @see prepareRequest().
@@ -259,7 +260,9 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
 		response->setStatus(mStatus);
 		response->setBody(mReplyBody);
 		response->setHeaders(mReplyHeaders);
-		if (mReplyOffset || mReplyLength)
+        response->setRequestURL(mReqURL);
+
+        if (mReplyOffset || mReplyLength)
 		{
 			// Got an explicit offset/length in response
 			response->setRange(mReplyOffset, mReplyLength, mReplyFullLength);
@@ -267,6 +270,14 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
 		response->setContentType(mReplyConType);
 		response->setRetries(mPolicyRetries, mPolicy503Retries);
 		
+		HttpResponse::TransferStats::ptr_t stats = HttpResponse::TransferStats::ptr_t(new HttpResponse::TransferStats);
+
+		curl_easy_getinfo(mCurlHandle, CURLINFO_SIZE_DOWNLOAD, &stats->mSizeDownload);
+		curl_easy_getinfo(mCurlHandle, CURLINFO_TOTAL_TIME, &stats->mTotalTime);
+		curl_easy_getinfo(mCurlHandle, CURLINFO_SPEED_DOWNLOAD, &stats->mSpeedDownload);
+
+		response->setTransferStats(stats);
+
 		mUserHandler->onCompleted(static_cast<HttpHandle>(this), response);
 
 		response->release();
@@ -346,6 +357,46 @@ HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id,
 }
 
 
+HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id,
+    HttpRequest::priority_t priority,
+    const std::string & url,
+    HttpOptions * options,
+    HttpHeaders * headers)
+{
+    setupCommon(policy_id, priority, url, NULL, options, headers);
+    mReqMethod = HOR_DELETE;
+
+    return HttpStatus();
+}
+
+
+HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id,
+    HttpRequest::priority_t priority,
+    const std::string & url,
+    BufferArray * body,
+    HttpOptions * options,
+    HttpHeaders * headers)
+{
+    setupCommon(policy_id, priority, url, body, options, headers);
+    mReqMethod = HOR_PATCH;
+
+    return HttpStatus();
+}
+
+
+HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id,
+    HttpRequest::priority_t priority,
+    const std::string & url,
+    HttpOptions * options,
+    HttpHeaders * headers)
+{
+    setupCommon(policy_id, priority, url, NULL, options, headers);
+    mReqMethod = HOR_COPY;
+
+    return HttpStatus();
+}
+
+
 void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
 								HttpRequest::priority_t priority,
 								const std::string & url,
@@ -452,18 +503,8 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
 	check_curl_easy_code(code, CURLOPT_ENCODING);
 
-	// The Linksys WRT54G V5 router has an issue with frequent
-	// DNS lookups from LAN machines.  If they happen too often,
-	// like for every HTTP request, the router gets annoyed after
-	// about 700 or so requests and starts issuing TCP RSTs to
-	// new connections.  Reuse the DNS lookups for even a few
-	// seconds and no RSTs.
-	code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15);
-	check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT);
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1);
 	check_curl_easy_code(code, CURLOPT_AUTOREFERER);
-	code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, 1);
-	check_curl_easy_code(code, CURLOPT_FOLLOWLOCATION);
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
 	check_curl_easy_code(code, CURLOPT_MAXREDIRS);
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
@@ -474,11 +515,57 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	check_curl_easy_code(code, CURLOPT_READFUNCTION);
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, this);
 	check_curl_easy_code(code, CURLOPT_READDATA);
-	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, 1);
+    code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKFUNCTION, seekCallback);
+    check_curl_easy_code(code, CURLOPT_SEEKFUNCTION);
+    code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKDATA, this);
+    check_curl_easy_code(code, CURLOPT_SEEKDATA);
+
+	code = curl_easy_setopt(mCurlHandle, CURLOPT_COOKIEFILE, "");
+	check_curl_easy_code(code, CURLOPT_COOKIEFILE);
+
+	if (gpolicy.mSslCtxCallback)
+	{
+		code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_FUNCTION, curlSslCtxCallback);
+		check_curl_easy_code(code, CURLOPT_SSL_CTX_FUNCTION);
+		code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_DATA, this);
+		check_curl_easy_code(code, CURLOPT_SSL_CTX_DATA);
+		mCallbackSSLVerify = gpolicy.mSslCtxCallback;
+	}
+
+	long follow_redirect(1L);
+	long sslPeerV(0L);
+	long sslHostV(0L);
+    long dnsCacheTimeout(-1L);
+    long nobody(0L);
+
+	if (mReqOptions)
+	{
+		follow_redirect = mReqOptions->getFollowRedirects() ? 1L : 0L;
+		sslPeerV = mReqOptions->getSSLVerifyPeer() ? 1L : 0L;
+		sslHostV = mReqOptions->getSSLVerifyHost() ? 2L : 0L;
+		dnsCacheTimeout = mReqOptions->getDNSCacheTimeout();
+        nobody = mReqOptions->getHeadersOnly() ? 1L : 0L;
+	}
+	code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
+	check_curl_easy_code(code, CURLOPT_FOLLOWLOCATION);
+
+	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, sslPeerV);
 	check_curl_easy_code(code, CURLOPT_SSL_VERIFYPEER);
-	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, 0);
+	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, sslHostV);
 	check_curl_easy_code(code, CURLOPT_SSL_VERIFYHOST);
 
+    code = curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody);
+    check_curl_easy_code(code, CURLOPT_NOBODY);
+
+	// The Linksys WRT54G V5 router has an issue with frequent
+	// DNS lookups from LAN machines.  If they happen too often,
+	// like for every HTTP request, the router gets annoyed after
+	// about 700 or so requests and starts issuing TCP RSTs to
+	// new connections.  Reuse the DNS lookups for even a few
+	// seconds and no RSTs.
+	code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout);
+	check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT);
+
 	if (gpolicy.mUseLLProxy)
 	{
 		// Use the viewer-based thread-safe API which has a
@@ -509,10 +596,9 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	switch (mReqMethod)
 	{
 	case HOR_GET:
-		code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
+        if (nobody == 0)
+            code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
 		check_curl_easy_code(code, CURLOPT_HTTPGET);
-		mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
-		mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
 		break;
 		
 	case HOR_POST:
@@ -531,12 +617,14 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 			code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);
 			check_curl_easy_code(code, CURLOPT_POSTFIELDSIZE);
 			mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
-			mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
-			mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
 		}
 		break;
 		
-	case HOR_PUT:
+    case HOR_PATCH:
+        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "PATCH");
+        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
+        // fall through.  The rest is the same as PUT
+    case HOR_PUT:
 		{
 			code = curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1);
 			check_curl_easy_code(code, CURLOPT_UPLOAD);
@@ -547,15 +635,20 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 			}
 			code = curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
 			check_curl_easy_code(code, CURLOPT_INFILESIZE);
-			code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, (void *) NULL);
-			check_curl_easy_code(code, CURLOPT_POSTFIELDS);
 			mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
-			// *TODO: Should this be 'Keep-Alive' ?
-			mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
-			mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
 		}
 		break;
 		
+    case HOR_DELETE:
+        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
+        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
+        break;
+
+    case HOR_COPY:
+        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "COPY");
+        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
+        break;
+
 	default:
 		LL_ERRS(LOG_CORE) << "Invalid HTTP method in request:  "
 						  << int(mReqMethod)  << ".  Can't recover."
@@ -563,6 +656,11 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 		break;
 	}
 
+
+    // *TODO: Should this be 'Keep-Alive' ?
+    mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
+    mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
+
 	// Tracing
 	if (mTracing >= HTTP_TRACE_CURL_HEADERS)
 	{
@@ -723,6 +821,37 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void
 	return read_size;
 }
 
+
+int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin)
+{
+    HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
+
+    if (!op->mReqBody)
+    {
+        return 0;
+    }
+
+    size_t newPos = 0;
+    if (origin == SEEK_SET)
+        newPos = offset;
+    else if (origin == SEEK_END)
+        newPos = static_cast<curl_off_t>(op->mReqBody->size()) + offset;
+    else if (origin == SEEK_CUR)
+        newPos = static_cast<curl_off_t>(op->mCurlBodyPos) + offset;
+    else
+        return 2;
+
+    if (newPos >= op->mReqBody->size())
+    {
+        LL_WARNS(LOG_CORE) << "Attempt to seek to position outside post body." << LL_ENDL;
+        return 2;
+    }
+
+    op->mCurlBodyPos = (size_t)newPos;
+
+    return 0;
+}
+
 		
 size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, void * userdata)
 {
@@ -873,6 +1002,35 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi
 }
 
 
+CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userdata)
+{
+	HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
+
+	if (op->mCallbackSSLVerify)
+	{
+		SSL_CTX * ctx = (SSL_CTX *)sslctx;
+		// disable any default verification for server certs
+		SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
+		// set the verification callback.
+		SSL_CTX_set_cert_verify_callback(ctx, sslCertVerifyCallback, userdata);
+		// the calls are void
+	}
+
+	return CURLE_OK;
+}
+
+int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
+{
+	HttpOpRequest * op(static_cast<HttpOpRequest *>(param));
+
+	if (op->mCallbackSSLVerify)
+	{
+		op->mStatus = op->mCallbackSSLVerify(op->mReqURL, op->mUserHandler, ctx);
+	}
+
+	return (op->mStatus) ? 1 : 0;
+}
+
 int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffer, size_t len, void * userdata)
 {
 	HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
index 2f628b5abad58f9fd850a3499d9a5ce71a589d88..b1bb101bea65c59c6cb9b7a4496a1d780e762ed0 100755
--- a/indra/llcorehttp/_httpoprequest.h
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -33,6 +33,9 @@
 #include <string>
 #include <curl/curl.h>
 
+#include <openssl/x509_vfy.h>
+#include <openssl/ssl.h>
+
 #include "httpcommon.h"
 #include "httprequest.h"
 #include "_httpoperation.h"
@@ -77,7 +80,10 @@ class HttpOpRequest : public HttpOperation
 	{
 		HOR_GET,
 		HOR_POST,
-		HOR_PUT
+		HOR_PUT,
+        HOR_DELETE,
+        HOR_PATCH,
+        HOR_COPY
 	};
 	
 	virtual void stageFromRequest(HttpService *);
@@ -123,7 +129,26 @@ class HttpOpRequest : public HttpOperation
 						HttpOptions * options,
 						HttpHeaders * headers);
 
-	// Internal method used to setup the libcurl options for a request.
+    HttpStatus setupDelete(HttpRequest::policy_t policy_id,
+                        HttpRequest::priority_t priority,
+                        const std::string & url,
+                        HttpOptions * options,
+                        HttpHeaders * headers);
+
+    HttpStatus setupPatch(HttpRequest::policy_t policy_id,
+                        HttpRequest::priority_t priority,
+                        const std::string & url,
+                        BufferArray * body,
+                        HttpOptions * options,
+                        HttpHeaders * headers);
+
+    HttpStatus setupCopy(HttpRequest::policy_t policy_id,
+                        HttpRequest::priority_t priority,
+                        const std::string & url,
+                        HttpOptions * options,
+                        HttpHeaders * headers);
+
+    // Internal method used to setup the libcurl options for a request.
 	// Does all the libcurl handle setup in one place.
 	//
 	// Threading:  called by worker thread
@@ -150,7 +175,11 @@ class HttpOpRequest : public HttpOperation
 	//
 	static size_t writeCallback(void * data, size_t size, size_t nmemb, void * userdata);
 	static size_t readCallback(void * data, size_t size, size_t nmemb, void * userdata);
+    static int seekCallback(void *data, curl_off_t offset, int origin);
 	static size_t headerCallback(void * data, size_t size, size_t nmemb, void * userdata);
+	static CURLcode curlSslCtxCallback(CURL *curl, void *ssl_ctx, void *userptr);
+	static int sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param);
+
 	static int debugCallback(CURL *, curl_infotype info, char * buffer, size_t len, void * userdata);
 
 protected:
@@ -159,6 +188,8 @@ class HttpOpRequest : public HttpOperation
 	static const unsigned int	PF_SAVE_HEADERS = 0x00000002U;
 	static const unsigned int	PF_USE_RETRY_AFTER = 0x00000004U;
 
+	HttpRequest::policyCallback_t	mCallbackSSLVerify;
+
 public:
 	// Request data
 	EMethod				mReqMethod;
diff --git a/indra/llcorehttp/_httppolicyglobal.cpp b/indra/llcorehttp/_httppolicyglobal.cpp
index 1dc95f3dce113ec9542f8fc6556320aa0fc45973..3d0df96ade3067b3f3353949ad6e765d4f478c0b 100755
--- a/indra/llcorehttp/_httppolicyglobal.cpp
+++ b/indra/llcorehttp/_httppolicyglobal.cpp
@@ -106,6 +106,20 @@ HttpStatus HttpPolicyGlobal::set(HttpRequest::EPolicyOption opt, const std::stri
 	return HttpStatus();
 }
 
+HttpStatus HttpPolicyGlobal::set(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t value)
+{
+	switch (opt)
+	{
+	case HttpRequest::PO_SSL_VERIFY_CALLBACK:
+		mSslCtxCallback = value;
+		break;
+
+	default:
+		return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+	}
+
+	return HttpStatus();
+}
 
 HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, long * value) const
 {
@@ -154,4 +168,20 @@ HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, std::string * v
 	return HttpStatus();
 }
 
+
+HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t * value) const
+{
+	switch (opt)
+	{
+	case HttpRequest::PO_SSL_VERIFY_CALLBACK:
+		*value = mSslCtxCallback;
+		break;
+
+	default:
+		return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+	}
+
+	return HttpStatus();
+}
+
 }  // end namespace LLCore
diff --git a/indra/llcorehttp/_httppolicyglobal.h b/indra/llcorehttp/_httppolicyglobal.h
index 67c4ba9481d21b5b4366c106543b75fa6ddbaabe..e02da4386a1c776cd6311e83ee72b1faccde0925 100755
--- a/indra/llcorehttp/_httppolicyglobal.h
+++ b/indra/llcorehttp/_httppolicyglobal.h
@@ -60,8 +60,10 @@ class HttpPolicyGlobal
 public:
 	HttpStatus set(HttpRequest::EPolicyOption opt, long value);
 	HttpStatus set(HttpRequest::EPolicyOption opt, const std::string & value);
+	HttpStatus set(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t value);
 	HttpStatus get(HttpRequest::EPolicyOption opt, long * value) const;
 	HttpStatus get(HttpRequest::EPolicyOption opt, std::string * value) const;
+	HttpStatus get(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t * value) const;
 	
 public:
 	long				mConnectionLimit;
@@ -70,6 +72,7 @@ class HttpPolicyGlobal
 	std::string			mHttpProxy;
 	long				mTrace;
 	long				mUseLLProxy;
+	HttpRequest::policyCallback_t	mSslCtxCallback;
 };  // end class HttpPolicyGlobal
 
 }  // end namespace LLCore
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index c673e1be1d316f3e7c85b8f0b7be1c897ef9cac0..252db78c899efaaf98fddaea5bfe392e01b4e9e6 100755
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -53,15 +53,16 @@ namespace LLCore
 
 const HttpService::OptionDescriptor HttpService::sOptionDesc[] =
 { //    isLong     isDynamic  isGlobal    isClass
-	{	true,		true,		true,		true	},		// PO_CONNECTION_LIMIT
-	{	true,		true,		false,		true	},		// PO_PER_HOST_CONNECTION_LIMIT
-	{	false,		false,		true,		false	},		// PO_CA_PATH
-	{	false,		false,		true,		false	},		// PO_CA_FILE
-	{	false,		true,		true,		false	},		// PO_HTTP_PROXY
-	{	true,		true,		true,		false	},		// PO_LLPROXY
-	{	true,		true,		true,		false	},		// PO_TRACE
-	{	true,		true,		false,		true	},		// PO_ENABLE_PIPELINING
-	{	true,		true,		false,		true	}		// PO_THROTTLE_RATE
+	{	true,		true,		true,		true,		false	},		// PO_CONNECTION_LIMIT
+	{	true,		true,		false,		true,		false	},		// PO_PER_HOST_CONNECTION_LIMIT
+	{	false,		false,		true,		false,		false	},		// PO_CA_PATH
+	{	false,		false,		true,		false,		false	},		// PO_CA_FILE
+	{	false,		true,		true,		false,		false	},		// PO_HTTP_PROXY
+	{	true,		true,		true,		false,		false	},		// PO_LLPROXY
+	{	true,		true,		true,		false,		false	},		// PO_TRACE
+	{	true,		true,		false,		true,		false	},		// PO_ENABLE_PIPELINING
+	{	true,		true,		false,		true,		false	},		// PO_THROTTLE_RATE
+	{   false,		false,		true,		false,		true	}		// PO_SSL_VERIFY_CALLBACK
 };
 HttpService * HttpService::sInstance(NULL);
 volatile HttpService::EState HttpService::sState(NOT_INITIALIZED);
@@ -413,6 +414,34 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 	return status;
 }
 
+HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+	HttpRequest::policyCallback_t * ret_value)
+{
+	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range
+		|| opt >= HttpRequest::PO_LAST													// ditto
+		|| (sOptionDesc[opt].mIsLong)													// datatype is string
+		|| (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy)			// pclass in valid range
+		|| (pclass == HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsGlobal)	// global setting permitted
+		|| (pclass != HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsClass))	// class setting permitted
+		// can always get, no dynamic check
+	{
+		return status;
+	}
+
+	// Only global has callback values
+	if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+	{
+		HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+		status = opts.get(opt, ret_value);
+	}
+
+	return status;
+}
+
+
 
 HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
 										long value, long * ret_value)
@@ -489,6 +518,37 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 
 	return status;
 }
-	
+
+HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+	HttpRequest::policyCallback_t value, HttpRequest::policyCallback_t * ret_value)
+{
+	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range
+		|| opt >= HttpRequest::PO_LAST													// ditto
+		|| (sOptionDesc[opt].mIsLong)													// datatype is string
+		|| (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy)			// pclass in valid range
+		|| (pclass == HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsGlobal)	// global setting permitted
+		|| (pclass != HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsClass)		// class setting permitted
+		|| (RUNNING == sState && !sOptionDesc[opt].mIsDynamic))						// dynamic setting permitted
+	{
+		return status;
+	}
+
+	// Callbacks values are always global (at this time).
+	if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+	{
+		HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+		status = opts.set(opt, value);
+		if (status && ret_value)
+		{
+			status = opts.get(opt, ret_value);
+		}
+	}
+
+	return status;
+}
+
 
 }  // end namespace LLCore
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
index cf23f3ab61f48274d5197daabf2e7f398439eee7..ac518a5de7405022ee270ac6a16b81586b13a56a 100755
--- a/indra/llcorehttp/_httpservice.h
+++ b/indra/llcorehttp/_httpservice.h
@@ -201,17 +201,24 @@ class HttpService
 		bool		mIsDynamic;
 		bool		mIsGlobal;
 		bool		mIsClass;
+		bool		mIsCallback;
 	};
 		
 	HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
 							   long * ret_value);
 	HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
 							   std::string * ret_value);
+	HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
+								HttpRequest::policyCallback_t * ret_value);
+
 	HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
 							   long value, long * ret_value);
 	HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
 							   const std::string & value, std::string * ret_value);
-	
+	HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
+								HttpRequest::policyCallback_t value, 
+								HttpRequest::policyCallback_t * ret_value);
+
 protected:
 	static const OptionDescriptor		sOptionDesc[HttpRequest::PO_LAST];
 	static HttpService *				sInstance;
diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h
index 402e7251524d1642b5a333b1534a8b49cb35c6aa..7f713f229836a7c2f34ba6ba01a42b850ad315f6 100755
--- a/indra/llcorehttp/_refcounted.h
+++ b/indra/llcorehttp/_refcounted.h
@@ -32,6 +32,7 @@
 
 #include "fix_macros.h"
 #include <boost/thread.hpp>
+#include <boost/intrusive_ptr.hpp>
 
 #include "llapr.h"
 
@@ -120,7 +121,36 @@ inline void RefCounted::destroySelf()
 	delete this;
 }
 
+/**
+ * boost::intrusive_ptr may be used to manage RefCounted classes.
+ * Unfortunately RefCounted and boost::intrusive_ptr use different conventions
+ * for the initial refcount value. To avoid leaky (immortal) objects, you
+ * should really construct boost::intrusive_ptr<RefCounted*>(rawptr, false).
+ * IntrusivePtr<T> encapsulates that for you.
+ */
+template <typename T>
+struct IntrusivePtr: public boost::intrusive_ptr<T>
+{
+	IntrusivePtr():
+		boost::intrusive_ptr<T>()
+	{}
+	IntrusivePtr(T* p):
+		boost::intrusive_ptr<T>(p, false)
+	{}
+};
+
+inline void intrusive_ptr_add_ref(RefCounted* p)
+{
+	p->addRef();
+}
+
+inline void intrusive_ptr_release(RefCounted* p)
+{
+	p->release();
+}
+
 } // end namespace LLCoreInt
 
+
 #endif	// LLCOREINT__REFCOUNTED_H_
 
diff --git a/indra/llcorehttp/bufferarray.h b/indra/llcorehttp/bufferarray.h
index 1094a435b42246a01b4bd93d76211557ea0fd1f3..320adf2b8b5c9a59dfb197f6f542f0eecb12a1e4 100755
--- a/indra/llcorehttp/bufferarray.h
+++ b/indra/llcorehttp/bufferarray.h
@@ -30,6 +30,7 @@
 
 #include <cstdlib>
 #include <vector>
+#include "boost/intrusive_ptr.hpp"
 
 #include "_refcounted.h"
 
@@ -73,6 +74,8 @@ class BufferArray : public LLCoreInt::RefCounted
 	
 	BufferArray();
 
+	typedef LLCoreInt::IntrusivePtr<BufferArray> ptr_t;
+
 protected:
 	virtual ~BufferArray();						// Use release()
 
@@ -129,6 +132,7 @@ class BufferArray : public LLCoreInt::RefCounted
 
 	container_t			mBlocks;
 	size_t				mLen;
+
 };  // end class BufferArray
 
 
diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index 7907e958a44d0b5a944c0ccbd5bbe777ecf1c2c5..99238ea9205a7d4886c252bf995be8806ec85e47 100755
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -42,7 +42,7 @@ HttpStatus::operator unsigned long() const
 {
 	static const int shift(sizeof(unsigned long) * 4);
 
-	unsigned long result(((unsigned long) mType) << shift | (unsigned long) (int) mStatus);
+	unsigned long result(((unsigned long)mDetails->mType) << shift | (unsigned long)(int)mDetails->mStatus);
 	return result;
 }
 
@@ -131,30 +131,34 @@ std::string HttpStatus::toString() const
 	{
 		return std::string("");
 	}
-	switch (mType)
+	switch (getType())
 	{
 	case EXT_CURL_EASY:
-		return std::string(curl_easy_strerror(CURLcode(mStatus)));
+		return std::string(curl_easy_strerror(CURLcode(getStatus())));
 
 	case EXT_CURL_MULTI:
-		return std::string(curl_multi_strerror(CURLMcode(mStatus)));
+		return std::string(curl_multi_strerror(CURLMcode(getStatus())));
 
 	case LLCORE:
-		if (mStatus >= 0 && mStatus < llcore_errors_count)
+		if (getStatus() >= 0 && getStatus() < llcore_errors_count)
 		{
-			return std::string(llcore_errors[mStatus]);
+			return std::string(llcore_errors[getStatus()]);
 		}
 		break;
 
 	default:
 		if (isHttpStatus())
 		{
+			// special handling for status 499 "Linden Catchall"
+			if ((getType() == 499) && (!getMessage().empty()))
+				return getMessage();
+
 			// Binary search for the error code and string
 			int bottom(0), top(http_errors_count);
 			while (true)
 			{
 				int at((bottom + top) / 2);
-				if (mType == http_errors[at].mCode)
+				if (getType() == http_errors[at].mCode)
 				{
 					return std::string(http_errors[at].mText);
 				}
@@ -162,7 +166,7 @@ std::string HttpStatus::toString() const
 				{
 					break;
 				}
-				else if (mType < http_errors[at].mCode)
+				else if (getType() < http_errors[at].mCode)
 				{
 					top = at;
 				}
@@ -182,9 +186,9 @@ std::string HttpStatus::toTerseString() const
 {
 	std::ostringstream result;
 
-	unsigned int error_value((unsigned short) mStatus);
+	unsigned int error_value((unsigned short)getStatus());
 	
-	switch (mType)
+	switch (getType())
 	{
 	case EXT_CURL_EASY:
 		result << "Easy_";
@@ -202,7 +206,7 @@ std::string HttpStatus::toTerseString() const
 		if (isHttpStatus())
 		{
 			result << "Http_";
-			error_value = mType;
+			error_value = getType();
 		}
 		else
 		{
@@ -244,7 +248,7 @@ bool HttpStatus::isRetryable() const
 	// Disable the '*this == inv_status' test and look for 'Core_9'
 	// failures in log files.
 
-	return ((isHttpStatus() && mType >= 499 && mType <= 599) ||	// Include special 499 in retryables
+	return ((isHttpStatus() && getType() >= 499 && getType() <= 599) ||	// Include special 499 in retryables
 			*this == cant_connect ||	// Connection reset/endpoint problems
 			*this == cant_res_proxy ||	// DNS problems
 			*this == cant_res_host ||	// DNS problems
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index 9601f94125f70f4924e1dd11a00c64ea64060458..898d3d47fa3fd33df1879ac1f81f76feeea4a972 100755
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -188,10 +188,12 @@
 ///
 
 #include "linden_common.h"		// Modifies curl/curl.h interfaces
-
+#include "boost/intrusive_ptr.hpp"
+#include "boost/shared_ptr.hpp"
+#include "boost/weak_ptr.hpp"
+#include "boost/function.hpp"
 #include <string>
 
-
 namespace LLCore
 {
 
@@ -286,52 +288,63 @@ enum HttpError
 /// 5.  Construct an HTTP 301 status code to be treated as success:
 ///				HttpStatus(301, HE_SUCCESS);
 ///
+/// 6.	Construct a failed status of HTTP Status 499 with a custom error message
+///				HttpStatus(499, "Failed LLSD Response");
 
 struct HttpStatus
 {
 	typedef unsigned short type_enum_t;
 	
 	HttpStatus()
-		: mType(LLCORE),
-		  mStatus(HE_SUCCESS)
-		{}
+	{
+		mDetails = boost::shared_ptr<Details>(new Details(LLCORE, HE_SUCCESS));
+    }
 
 	HttpStatus(type_enum_t type, short status)
-		: mType(type),
-		  mStatus(status)
-		{}
+	{
+        mDetails = boost::shared_ptr<Details>(new Details(type, status));
+	}
 	
 	HttpStatus(int http_status)
-		: mType(http_status),
-		  mStatus(http_status >= 200 && http_status <= 299
-				  ? HE_SUCCESS
-				  : HE_REPLY_ERROR)
-		{
-			llassert(http_status >= 100 && http_status <= 999);
-		}
+	{
+        mDetails = boost::shared_ptr<Details>(new Details(http_status, 
+			(http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR));
+		llassert(http_status >= 100 && http_status <= 999);
+	}
+
+	HttpStatus(int http_status, const std::string &message)
+	{
+        mDetails = boost::shared_ptr<Details>(new Details(http_status,
+			(http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR));
+		llassert(http_status >= 100 && http_status <= 999);
+		mDetails->mMessage = message;
+	}
 	
 	HttpStatus(const HttpStatus & rhs)
-		: mType(rhs.mType),
-		  mStatus(rhs.mStatus)
-		{}
+	{
+		mDetails = rhs.mDetails;
+	}
+
+	~HttpStatus()
+	{
+	}
 
 	HttpStatus & operator=(const HttpStatus & rhs)
-		{
-			// Don't care if lhs & rhs are the same object
+	{
+        mDetails = rhs.mDetails;
+		return *this;
+	}
 
-			mType = rhs.mType;
-			mStatus = rhs.mStatus;
-			return *this;
-		}
+    HttpStatus & clone(const HttpStatus &rhs)
+    {
+        mDetails = boost::shared_ptr<Details>(new Details(*rhs.mDetails));
+        return *this;
+    }
 	
 	static const type_enum_t EXT_CURL_EASY = 0;			///< mStatus is an error from a curl_easy_*() call
 	static const type_enum_t EXT_CURL_MULTI = 1;		///< mStatus is an error from a curl_multi_*() call
 	static const type_enum_t LLCORE = 2;				///< mStatus is an HE_* error code
 														///< 100-999 directly represent HTTP status codes
-	
-	type_enum_t			mType;
-	short				mStatus;
-
 	/// Test for successful status in the code regardless
 	/// of error source (internal, libcurl).
 	///
@@ -339,7 +352,7 @@ struct HttpStatus
 	///
 	operator bool() const
 	{
-		return 0 == mStatus;
+		return 0 == mDetails->mStatus;
 	}
 
 	/// Inverse of previous operator.
@@ -347,14 +360,14 @@ struct HttpStatus
 	/// @return			'true' on any error condition
 	bool operator !() const
 	{
-		return 0 != mStatus;
+		return 0 != mDetails->mStatus;
 	}
 
 	/// Equality and inequality tests to bypass bool conversion
 	/// which will do the wrong thing in conditional expressions.
 	bool operator==(const HttpStatus & rhs) const
 	{
-		return mType == rhs.mType && mStatus == rhs.mStatus;
+        return (*mDetails == *rhs.mDetails); 
 	}
 
 	bool operator!=(const HttpStatus & rhs) const
@@ -395,7 +408,7 @@ struct HttpStatus
 	/// HTTP response status (100 - 999).
 	bool isHttpStatus() const
 	{
-		return 	mType >= type_enum_t(100) && mType <= type_enum_t(999);
+		return 	mDetails->mType >= type_enum_t(100) && mDetails->mType <= type_enum_t(999);
 	}
 
 	/// Returns true if the status is one that will be retried
@@ -403,7 +416,78 @@ struct HttpStatus
 	/// where that logic needs to be replicated.  Only applies
 	/// to failed statuses, successful statuses will return false.
 	bool isRetryable() const;
-	
+
+	/// Returns the currently set status code as a raw number
+	///
+	short getStatus() const
+	{
+		return mDetails->mStatus;
+	}
+
+	/// Returns the currently set status type 
+	/// 
+	type_enum_t getType() const
+	{
+		return mDetails->mType;
+	}
+
+	/// Returns an optional error message if one has been set.
+	///
+	std::string getMessage() const
+	{
+		return mDetails->mMessage;
+	}
+
+	/// Sets an optional error message
+	/// 
+	void setMessage(const std::string &message)
+	{
+		mDetails->mMessage = message;
+	}
+
+	/// Retrieves an optionally recorded SSL certificate.
+	void * getErrorData() const
+	{
+		return mDetails->mErrorData;
+	}
+
+	/// Optionally sets an SSL certificate on this status.
+	void setErrorData(void *data)
+	{
+		mDetails->mErrorData = data;
+	}
+
+private:
+
+	struct Details
+	{
+		Details(type_enum_t type, short status):
+			mType(type),
+			mStatus(status),
+			mMessage(),
+			mErrorData(NULL)
+		{}
+
+		Details(const Details &rhs) :
+			mType(rhs.mType),
+			mStatus(rhs.mStatus),
+			mMessage(rhs.mMessage),
+			mErrorData(rhs.mErrorData)
+		{}
+
+        bool operator == (const Details &rhs) const
+        {
+            return (mType == rhs.mType) && (mStatus == rhs.mStatus);
+        }
+
+		type_enum_t	mType;
+		short		mStatus;
+		std::string	mMessage;
+		void *		mErrorData;
+	};
+
+    boost::shared_ptr<Details> mDetails;
+
 }; // end struct HttpStatus
 
 }  // end namespace LLCore
diff --git a/indra/llcorehttp/httphandler.h b/indra/llcorehttp/httphandler.h
index 9171e4e7b930252a6bb0e9e8d62adaa085c9d5f5..7bc9096703029aa0999a54659bab6d2f325b1e18 100755
--- a/indra/llcorehttp/httphandler.h
+++ b/indra/llcorehttp/httphandler.h
@@ -45,7 +45,7 @@ class HttpResponse;
 /// be shared by any number of requests and across instances
 /// of HttpRequest running in the same thread.
 ///
-/// Threading:  HttpHandler itself is pure interface and is
+/// Threading:  HttpHandler itself is interface and is
 /// tread-compatible.  Most derivations, however, will have
 /// different constraints.
 ///
@@ -53,12 +53,13 @@ class HttpResponse;
 /// that is rarely a good idea.  Queued requests and replies keep
 /// a naked pointer to the handler and this can result in a
 /// dangling pointer if lifetimes aren't managed correctly.
-
-class HttpHandler
+///
+/// *TODO: public std::enable_shared_from_this<HttpHandler>
+class HttpHandler 
 {
 public:
 	virtual ~HttpHandler()
-		{}
+	{ }
 
 	/// Method invoked during calls to @see update().  Each invocation
 	/// represents the completion of some requested operation.  Caller
diff --git a/indra/llcorehttp/httpheaders.cpp b/indra/llcorehttp/httpheaders.cpp
index 23ebea361c1246b7589918cab569e2527be70d5e..e03b1b080dfd2c5fb87657baa896b96b5b9aa0bc 100755
--- a/indra/llcorehttp/httpheaders.cpp
+++ b/indra/llcorehttp/httpheaders.cpp
@@ -105,7 +105,7 @@ void HttpHeaders::appendNormal(const char * header, size_t size)
 
 // Find from end to simulate a tradition of using single-valued
 // std::map for this in the past.
-const std::string * HttpHeaders::find(const char * name) const
+const std::string * HttpHeaders::find(const std::string &name) const
 {
 	const_reverse_iterator iend(rend());
 	for (const_reverse_iterator iter(rbegin()); iend != iter; ++iter)
@@ -118,6 +118,24 @@ const std::string * HttpHeaders::find(const char * name) const
 	return NULL;
 }
 
+void HttpHeaders::remove(const char *name)
+{
+    remove(std::string(name));
+}
+
+void HttpHeaders::remove(const std::string &name)
+{
+    iterator iend(end());
+    for (iterator iter(begin()); iend != iter; ++iter)
+    {
+        if ((*iter).first == name)
+        {
+            mHeaders.erase(iter);
+            return;
+        }
+    }
+}
+
 
 // Standard Iterators
 HttpHeaders::iterator HttpHeaders::begin()
diff --git a/indra/llcorehttp/httpheaders.h b/indra/llcorehttp/httpheaders.h
index f70cd898f3949eb641991bd76fdd3650c5abe885..8f14568fa339009c80ae9f42fc6af94186536385 100755
--- a/indra/llcorehttp/httpheaders.h
+++ b/indra/llcorehttp/httpheaders.h
@@ -28,8 +28,8 @@
 #define	_LLCORE_HTTP_HEADERS_H_
 
 
+#include "httpcommon.h"
 #include <string>
-
 #include "_refcounted.h"
 
 
@@ -92,6 +92,7 @@ class HttpHeaders : public LLCoreInt::RefCounted
 	/// the instance.
 	HttpHeaders();
 
+	typedef LLCoreInt::IntrusivePtr<HttpHeaders> ptr_t;
 protected:
 	virtual ~HttpHeaders();						// Use release()
 
@@ -145,8 +146,16 @@ class HttpHeaders : public LLCoreInt::RefCounted
 	//					a pointer to a std::string in the container.
 	//					Pointer is valid only for the lifetime of
 	//					the container or until container is modifed.
-	//
-	const std::string * find(const char * name) const;
+	const std::string * find(const std::string &name) const;
+	const std::string * find(const char * name) const
+	{
+		return find(std::string(name));
+	}
+
+    // Remove the header from the list if found.
+    // 
+    void remove(const std::string &name);
+    void remove(const char *name);
 
 	// Count of headers currently in the list.
 	size_type size() const
diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp
index 5bf1ecb4a5a98376a47c5f6b50a2aad68a3412a3..3459a37aff8464bf8bd202857ff5a3828c32da92 100755
--- a/indra/llcorehttp/httpoptions.cpp
+++ b/indra/llcorehttp/httpoptions.cpp
@@ -25,7 +25,7 @@
  */
 
 #include "httpoptions.h"
-
+#include "lldefs.h"
 #include "_httpinternal.h"
 
 
@@ -33,14 +33,18 @@ namespace LLCore
 {
 
 
-HttpOptions::HttpOptions()
-	: RefCounted(true),
-	  mWantHeaders(false),
-	  mTracing(HTTP_TRACE_OFF),
-	  mTimeout(HTTP_REQUEST_TIMEOUT_DEFAULT),
-	  mTransferTimeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT),
-	  mRetries(HTTP_RETRY_COUNT_DEFAULT),
-	  mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT)
+HttpOptions::HttpOptions() : RefCounted(true),
+    mWantHeaders(false),
+    mTracing(HTTP_TRACE_OFF),
+    mTimeout(HTTP_REQUEST_TIMEOUT_DEFAULT),
+    mTransferTimeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT),
+    mRetries(HTTP_RETRY_COUNT_DEFAULT),
+    mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT),
+    mFollowRedirects(true),
+    mVerifyPeer(false),
+    mVerifyHost(false),
+    mDNSCacheTimeout(-1L),
+    mNoBody(false)
 {}
 
 
@@ -82,5 +86,31 @@ void HttpOptions::setUseRetryAfter(bool use_retry)
 	mUseRetryAfter = use_retry;
 }
 
+void HttpOptions::setFollowRedirects(bool follow_redirect)
+{
+	mFollowRedirects = follow_redirect;
+}
+
+void HttpOptions::setSSLVerifyPeer(bool verify)
+{
+	mVerifyPeer = verify;
+}
+
+void HttpOptions::setSSLVerifyHost(bool verify)
+{
+	mVerifyHost = verify;
+}
+
+void HttpOptions::setDNSCacheTimeout(int timeout)
+{
+	mDNSCacheTimeout = timeout;
+}
+
+void HttpOptions::setHeadersOnly(bool nobody)
+{
+    mNoBody = nobody;
+    if (mNoBody)
+        setWantHeaders(true);
+}
 
 }   // end namespace LLCore
diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h
index 4ab5ff18c43ba29ec1b68dde1b1406989ae14818..2fe05a65ffd49334a898c84ce9ebd61c251c1d3c 100755
--- a/indra/llcorehttp/httpoptions.h
+++ b/indra/llcorehttp/httpoptions.h
@@ -29,7 +29,6 @@
 
 
 #include "httpcommon.h"
-
 #include "_refcounted.h"
 
 
@@ -61,6 +60,8 @@ class HttpOptions : public LLCoreInt::RefCounted
 public:
 	HttpOptions();
 
+	typedef LLCoreInt::IntrusivePtr<HttpOptions> ptr_t;
+
 protected:
 	virtual ~HttpOptions();						// Use release()
 	
@@ -68,47 +69,95 @@ class HttpOptions : public LLCoreInt::RefCounted
 	void operator=(const HttpOptions &);		// Not defined
 
 public:
+
 	// Default:   false
 	void				setWantHeaders(bool wanted);
 	bool				getWantHeaders() const
-		{
-			return mWantHeaders;
-		}
+	{
+		return mWantHeaders;
+	}
 
 	// Default:  0
 	void				setTrace(int long);
 	int					getTrace() const
-		{
-			return mTracing;
-		}
+	{
+		return mTracing;
+	}
 
 	// Default:  30
 	void				setTimeout(unsigned int timeout);
 	unsigned int		getTimeout() const
-		{
-			return mTimeout;
-		}
+	{
+		return mTimeout;
+	}
 
 	// Default:  0
 	void				setTransferTimeout(unsigned int timeout);
 	unsigned int		getTransferTimeout() const
-		{
-			return mTransferTimeout;
-		}
+	{
+		return mTransferTimeout;
+	}
 
+    /// Sets the number of retries on an LLCore::HTTPRequest before the 
+    /// request fails.
 	// Default:  8
 	void				setRetries(unsigned int retries);
 	unsigned int		getRetries() const
-		{
-			return mRetries;
-		}
+	{
+		return mRetries;
+	}
 
 	// Default:  true
 	void				setUseRetryAfter(bool use_retry);
 	bool				getUseRetryAfter() const
-		{
-			return mUseRetryAfter;
-		}
+	{
+		return mUseRetryAfter;
+	}
+
+    /// Instructs the LLCore::HTTPRequest to follow redirects 
+	/// Default: false
+	void				setFollowRedirects(bool follow_redirect);
+	bool				getFollowRedirects() const
+	{
+		return mFollowRedirects;
+	}
+
+    /// Instructs the LLCore::HTTPRequest to verify that the exchanged security
+    /// certificate is authentic. 
+    /// Default: false
+    void				setSSLVerifyPeer(bool verify);
+	bool				getSSLVerifyPeer() const
+	{
+		return mVerifyPeer;
+	}
+
+    /// Instructs the LLCore::HTTPRequest to verify that the name in the 
+    /// security certificate matches the name of the host contacted.
+    /// Default: false
+    void				setSSLVerifyHost(bool verify);
+	bool	        	getSSLVerifyHost() const
+	{
+		return mVerifyHost;
+	}
+
+    /// Sets the time for DNS name caching in seconds.  Setting this value
+    /// to 0 will disable name caching.  Setting this value to -1 causes the 
+    /// name cache to never time out.
+    /// Default: -1
+	void				setDNSCacheTimeout(int timeout);
+	int					getDNSCacheTimeout() const
+	{
+		return mDNSCacheTimeout;
+	}
+
+    /// Retrieve only the headers and status from the request. Setting this 
+    /// to true implies setWantHeaders(true) as well.
+    /// Default: false
+    void                setHeadersOnly(bool nobody);
+    bool                getHeadersOnly() const
+    {
+        return mNoBody;
+    }
 	
 protected:
 	bool				mWantHeaders;
@@ -117,6 +166,11 @@ class HttpOptions : public LLCoreInt::RefCounted
 	unsigned int		mTransferTimeout;
 	unsigned int		mRetries;
 	bool				mUseRetryAfter;
+	bool				mFollowRedirects;
+	bool				mVerifyPeer;
+	bool        		mVerifyHost;
+	int					mDNSCacheTimeout;
+    bool                mNoBody;
 }; // end class HttpOptions
 
 
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
index 7b1888e3ebad9a16bed8511498c6d83ecf24367c..d4c60a6f14a89ccecf8ef1c7d22a62fec43640e5 100755
--- a/indra/llcorehttp/httprequest.cpp
+++ b/indra/llcorehttp/httprequest.cpp
@@ -117,6 +117,15 @@ HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass
 	return HttpService::instanceOf()->setPolicyOption(opt, pclass, value, ret_value);
 }
 
+HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass, policyCallback_t value, policyCallback_t * ret_value)
+{
+	if (HttpService::RUNNING == HttpService::instanceOf()->getState())
+	{
+		return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
+	}
+
+	return HttpService::instanceOf()->setPolicyOption(opt, pclass, value, ret_value);
+}
 
 HttpHandle HttpRequest::setPolicyOption(EPolicyOption opt, policy_t pclass,
 										long value, HttpHandler * handler)
@@ -316,6 +325,100 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,
 	return handle;
 }
 
+HttpHandle HttpRequest::requestDelete(policy_t policy_id,
+    priority_t priority,
+    const std::string & url,
+    HttpOptions * options,
+    HttpHeaders * headers,
+    HttpHandler * user_handler)
+{
+    HttpStatus status;
+    HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+    HttpOpRequest * op = new HttpOpRequest();
+    if (!(status = op->setupDelete(policy_id, priority, url, options, headers)))
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+    op->setReplyPath(mReplyQueue, user_handler);
+    if (!(status = mRequestQueue->addOp(op)))			// transfers refcount
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+
+    mLastReqStatus = status;
+    handle = static_cast<HttpHandle>(op);
+
+    return handle;
+}
+
+HttpHandle HttpRequest::requestPatch(policy_t policy_id,
+    priority_t priority,
+    const std::string & url,
+    BufferArray * body,
+    HttpOptions * options,
+    HttpHeaders * headers,
+    HttpHandler * user_handler)
+{
+    HttpStatus status;
+    HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+    HttpOpRequest * op = new HttpOpRequest();
+    if (!(status = op->setupPatch(policy_id, priority, url, body, options, headers)))
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+    op->setReplyPath(mReplyQueue, user_handler);
+    if (!(status = mRequestQueue->addOp(op)))			// transfers refcount
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+
+    mLastReqStatus = status;
+    handle = static_cast<HttpHandle>(op);
+
+    return handle;
+}
+
+HttpHandle HttpRequest::requestCopy(policy_t policy_id,
+    priority_t priority,
+    const std::string & url,
+    HttpOptions * options,
+    HttpHeaders * headers,
+    HttpHandler * user_handler)
+{
+    HttpStatus status;
+    HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+    HttpOpRequest * op = new HttpOpRequest();
+    if (!(status = op->setupCopy(policy_id, priority, url, options, headers)))
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+    op->setReplyPath(mReplyQueue, user_handler);
+    if (!(status = mRequestQueue->addOp(op)))			// transfers refcount
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+
+    mLastReqStatus = status;
+    handle = static_cast<HttpHandle>(op);
+
+    return handle;
+}
+
 
 HttpHandle HttpRequest::requestNoOp(HttpHandler * user_handler)
 {
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index 7f23723b0b005a5f44a4380594d49f605a444423..e87a8b691a7202bf48b8797e2fb922df6ce5efee 100755
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -97,6 +97,8 @@ class HttpRequest
 	typedef unsigned int policy_t;
 	typedef unsigned int priority_t;
 	
+	typedef boost::shared_ptr<HttpRequest> ptr_t;
+    typedef boost::weak_ptr<HttpRequest>   wptr_t;
 public:
 	/// @name PolicyMethods
 	/// @{
@@ -163,7 +165,7 @@ class HttpRequest
 
 		/// Long value that if non-zero enables the use of the
 		/// traditional LLProxy code for http/socks5 support.  If
-		// enabled, has priority over GP_HTTP_PROXY.
+		/// enabled, has priority over GP_HTTP_PROXY.
 		///
 		/// Global only
 		PO_LLPROXY,
@@ -219,15 +221,25 @@ class HttpRequest
 		/// Controls whether client-side throttling should be
 		/// performed on this policy class.  Positive values
 		/// enable throttling and specify the request rate
-		/// (requests per second) that should be targetted.
+		/// (requests per second) that should be targeted.
 		/// A value of zero, the default, specifies no throttling.
 		///
 		/// Per-class only
 		PO_THROTTLE_RATE,
 		
+		/// Controls the callback function used to control SSL CTX 
+		/// certificate verification.
+		///
+		/// Global only
+		PO_SSL_VERIFY_CALLBACK,
+
 		PO_LAST  // Always at end
 	};
 
+	/// Prototype for policy based callbacks.  The callback methods will be executed
+	/// on the worker thread so no modifications should be made to the HttpHandler object.
+    typedef boost::function<HttpStatus(const std::string &, HttpHandler const * const, void *)> policyCallback_t;
+
 	/// Set a policy option for a global or class parameter at
 	/// startup time (prior to thread start).
 	///
@@ -243,6 +255,8 @@ class HttpRequest
 											long value, long * ret_value);
 	static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
 											const std::string & value, std::string * ret_value);
+	static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
+											policyCallback_t value, policyCallback_t * ret_value);;
 
 	/// Set a parameter on a class-based policy option.  Calls
 	/// made after the start of the servicing thread are
@@ -464,7 +478,68 @@ class HttpRequest
 						  HttpHandler * handler);
 
 
-	/// Queue a NoOp request.
+    /// Queue a full HTTP PUT.  Query arguments and body may
+    /// be provided.  Caller is responsible for escaping and
+    /// encoding and communicating the content types.
+    ///
+    /// @param	policy_id		@see requestGet()
+    /// @param	priority		"
+    /// @param	url				"
+    /// @param	options			@see requestGet()K(optional)
+    /// @param	headers			"
+    /// @param	handler			"
+    /// @return					"
+    ///
+    HttpHandle requestDelete(policy_t policy_id,
+            priority_t priority,
+            const std::string & url,
+            HttpOptions * options,
+            HttpHeaders * headers,
+            HttpHandler * user_handler);
+
+    /// Queue a full HTTP PUT.  Query arguments and body may
+    /// be provided.  Caller is responsible for escaping and
+    /// encoding and communicating the content types.
+    ///
+    /// @param	policy_id		@see requestGet()
+    /// @param	priority		"
+    /// @param	url				"
+    /// @param	body			Byte stream to be sent as the body.  No
+    ///							further encoding or escaping will be done
+    ///							to the content.
+    /// @param	options			@see requestGet()K(optional)
+    /// @param	headers			"
+    /// @param	handler			"
+    /// @return					"
+    ///
+    HttpHandle requestPatch(policy_t policy_id,
+            priority_t priority,
+            const std::string & url,
+            BufferArray * body,
+            HttpOptions * options,
+            HttpHeaders * headers,
+            HttpHandler * user_handler);
+
+    /// Queue a full HTTP PUT.  Query arguments and body may
+    /// be provided.  Caller is responsible for escaping and
+    /// encoding and communicating the content types.
+    ///
+    /// @param	policy_id		@see requestGet()
+    /// @param	priority		"
+    /// @param	url				"
+    /// @param	options			@see requestGet()K(optional)
+    /// @param	headers			"
+    /// @param	handler			"
+    /// @return					"
+    ///
+    HttpHandle requestCopy(policy_t policy_id,
+            priority_t priority,
+            const std::string & url,
+            HttpOptions * options,
+            HttpHeaders * headers,
+            HttpHandler * user_handler);
+       
+    /// Queue a NoOp request.
 	/// The request is queued and serviced by the working thread which
 	/// immediately processes it and returns the request to the reply
 	/// queue.
diff --git a/indra/llcorehttp/httpresponse.cpp b/indra/llcorehttp/httpresponse.cpp
index c974395b0a53c60bc334d7cb91d3da9dd032c546..7d88f025279f547abb63d34af6e5959fcd94faa9 100755
--- a/indra/llcorehttp/httpresponse.cpp
+++ b/indra/llcorehttp/httpresponse.cpp
@@ -41,7 +41,8 @@ HttpResponse::HttpResponse()
 	  mBufferArray(NULL),
 	  mHeaders(NULL),
 	  mRetries(0U),
-	  m503Retries(0U)
+	  m503Retries(0U),
+      mRequestUrl()
 {}
 
 
@@ -89,5 +90,9 @@ void HttpResponse::setHeaders(HttpHeaders * headers)
 	mHeaders = headers;
 }
 
+size_t HttpResponse::getBodySize() const
+{
+	return (mBufferArray) ? mBufferArray->size() : 0;
+}
 
 }   // end namespace LLCore
diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h
index aee64e28784b99c63342abed863ea11f2f588b75..6c3b4da5e6973368c271e55ebde5e7325571a32b 100755
--- a/indra/llcorehttp/httpresponse.h
+++ b/indra/llcorehttp/httpresponse.h
@@ -69,6 +69,18 @@ class HttpResponse : public LLCoreInt::RefCounted
 	void operator=(const HttpResponse &);				// Not defined
 	
 public:
+	/// Statistics for the HTTP 
+	struct TransferStats
+	{
+		typedef boost::shared_ptr<TransferStats> ptr_t;
+
+		TransferStats() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {}
+		F64 mSizeDownload;
+		F64 mTotalTime;
+		F64 mSpeedDownload;
+	};
+
+
 	/// Returns the final status of the requested operation.
 	///
 	HttpStatus getStatus() const
@@ -92,6 +104,10 @@ class HttpResponse : public LLCoreInt::RefCounted
 			return mBufferArray;
 		}
 
+	/// Safely get the size of the body buffer.  If the body buffer is missing
+	/// return 0 as the size.
+	size_t getBodySize() const;
+
 	/// Set the response data in the instance.  Will drop the reference
 	/// count to any existing data and increment the count of that passed
 	/// in.  It is legal to set the data to NULL.
@@ -168,6 +184,27 @@ class HttpResponse : public LLCoreInt::RefCounted
 			m503Retries = retries_503;
 		}
 
+	void setTransferStats(TransferStats::ptr_t &stats) 
+		{
+			mStats = stats;
+		}
+
+	TransferStats::ptr_t getTransferStats()
+		{
+			return mStats;
+		}
+
+    void setRequestURL(const std::string &url)
+        {
+            mRequestUrl = url;
+        }
+
+    const std::string &getRequestURL() const
+        {
+            return mRequestUrl;
+        }
+
+
 protected:
 	// Response data here
 	HttpStatus			mStatus;
@@ -179,6 +216,9 @@ class HttpResponse : public LLCoreInt::RefCounted
 	std::string			mContentType;
 	unsigned int		mRetries;
 	unsigned int		m503Retries;
+    std::string         mRequestUrl;
+
+	TransferStats::ptr_t	mStats;
 };
 
 
diff --git a/indra/llcorehttp/tests/test_httpstatus.hpp b/indra/llcorehttp/tests/test_httpstatus.hpp
index 0b379836c9c14945f2d89c5cf25012ba405c13e3..4502d32fe1f0f6c9eb96bb3bebca02442aab3be8 100755
--- a/indra/llcorehttp/tests/test_httpstatus.hpp
+++ b/indra/llcorehttp/tests/test_httpstatus.hpp
@@ -55,77 +55,68 @@ void HttpStatusTestObjectType::test<1>()
 	
 	// auto allocation fine for this
 	HttpStatus status;
-	status.mType = HttpStatus::EXT_CURL_EASY;
-	status.mStatus = 0;
+
+	status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0);
 	
 	ensure(bool(status));
 	ensure(false == !(status));
 
-	status.mType = HttpStatus::EXT_CURL_MULTI;
-	status.mStatus = 0;
+	status = HttpStatus(HttpStatus::EXT_CURL_MULTI, 0);
 
 	ensure(bool(status));
 	ensure(false == !(status));
-	
-	status.mType = HttpStatus::LLCORE;
-	status.mStatus = HE_SUCCESS;
+
+	status = HttpStatus(HttpStatus::LLCORE, HE_SUCCESS);
 	
 	ensure(bool(status));
 	ensure(false == !(status));
 
-	status.mType = HttpStatus::EXT_CURL_MULTI;
-	status.mStatus = -1;
+	status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -1);
 
 	ensure(false == bool(status));
 	ensure(!(status));
 
-	status.mType = HttpStatus::EXT_CURL_EASY;
-	status.mStatus = CURLE_BAD_DOWNLOAD_RESUME;
+	status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_DOWNLOAD_RESUME);
 
 	ensure(false == bool(status));
 	ensure(!(status));
 }
 
 
-template <> template <>
-void HttpStatusTestObjectType::test<2>()
-{
-	set_test_name("HttpStatus memory structure");
-
-	// Require that an HttpStatus object can be trivially
-	// returned as a function return value in registers.
-	// One should fit in an int on all platforms.
-
-	ensure(sizeof(HttpStatus) <= sizeof(int));
-}
+// template <> template <>
+// void HttpStatusTestObjectType::test<2>()
+// {
+// 	set_test_name("HttpStatus memory structure");
+// 
+// 	// Require that an HttpStatus object can be trivially
+// 	// returned as a function return value in registers.
+// 	// One should fit in an int on all platforms.
+// 
+// 	//ensure(sizeof(HttpStatus) <= sizeof(int));
+// }
 
 
 template <> template <>
-void HttpStatusTestObjectType::test<3>()
+void HttpStatusTestObjectType::test<2>()
 {
 	set_test_name("HttpStatus valid status string conversion");
 	
-	HttpStatus status;
-	status.mType = HttpStatus::EXT_CURL_EASY;
-	status.mStatus = 0;
+	HttpStatus status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0);
 	std::string msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(msg.empty());
-	
-	status.mType = HttpStatus::EXT_CURL_EASY;
-	status.mStatus = CURLE_BAD_FUNCTION_ARGUMENT;
+
+	status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_FUNCTION_ARGUMENT);
 	msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
 
-	status.mType = HttpStatus::EXT_CURL_MULTI;
-	status.mStatus = CURLM_OUT_OF_MEMORY;
+	status = HttpStatus(HttpStatus::EXT_CURL_MULTI, CURLM_OUT_OF_MEMORY);
 	msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
 
-	status.mType = HttpStatus::LLCORE;
-	status.mStatus = HE_SHUTTING_DOWN;
+	status = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
 	msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
@@ -133,32 +124,28 @@ void HttpStatusTestObjectType::test<3>()
 
 
 template <> template <>
-void HttpStatusTestObjectType::test<4>()
+void HttpStatusTestObjectType::test<3>()
 {
 	set_test_name("HttpStatus invalid status string conversion");
 	
-	HttpStatus status;
-	status.mType = HttpStatus::EXT_CURL_EASY;
-	status.mStatus = 32726;
+	HttpStatus status = HttpStatus(HttpStatus::EXT_CURL_EASY, 32726);
 	std::string msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
-	
-	status.mType = HttpStatus::EXT_CURL_MULTI;
-	status.mStatus = -470;
+
+	status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -470);
 	msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
 
-	status.mType = HttpStatus::LLCORE;
-	status.mStatus = 923;
+	status = HttpStatus(HttpStatus::LLCORE, 923);
 	msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
 }
 
 template <> template <>
-void HttpStatusTestObjectType::test<5>()
+void HttpStatusTestObjectType::test<4>()
 {
 	set_test_name("HttpStatus equality/inequality testing");
 
@@ -170,62 +157,55 @@ void HttpStatusTestObjectType::test<5>()
 	HttpStatus status2(HttpStatus::EXT_CURL_EASY, HE_SUCCESS);
 	ensure(status1 != status2);
 
-	status1.mType = HttpStatus::LLCORE;
-	status1.mStatus = HE_REPLY_ERROR;
-	status2.mType = HttpStatus::LLCORE;
-	status2.mStatus= HE_SHUTTING_DOWN;
+	status1 = HttpStatus(HttpStatus::LLCORE, HE_REPLY_ERROR);
+	status1 = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
+
 	ensure(status1 != status2);
 }
 
 template <> template <>
-void HttpStatusTestObjectType::test<6>()
+void HttpStatusTestObjectType::test<5>()
 {
 	set_test_name("HttpStatus basic HTTP status encoding");
 	
 	HttpStatus status;
-	status.mType = 200;
-	status.mStatus = HE_SUCCESS;
+
+	status = HttpStatus(200, HE_SUCCESS);
 	std::string msg = status.toString();
 	ensure(msg.empty());
 	ensure(bool(status));
 
 	// Normally a success but application says error
-	status.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(200, HE_REPLY_ERROR);
 	msg = status.toString();
 	ensure(! msg.empty());
 	ensure(! bool(status));
 	ensure(status.toULong() > 1UL);				// Biggish number, not a bool-to-ulong
 
 	// Same statuses with distinct success/fail are distinct
-	status.mType = 200;
-	status.mStatus = HE_SUCCESS;
+	status = HttpStatus(200, HE_SUCCESS);
 	HttpStatus status2(200, HE_REPLY_ERROR);
 	ensure(status != status2);
 
 	// Normally an error but application says okay
-	status.mType = 406;
-	status.mStatus = HE_SUCCESS;
+	status = HttpStatus(406, HE_SUCCESS);
 	msg = status.toString();
 	ensure(msg.empty());
 	ensure(bool(status));
 
 	// Different statuses but both successful are distinct
-	status.mType = 200;
-	status.mStatus = HE_SUCCESS;
-	status2.mType = 201;
-	status2.mStatus = HE_SUCCESS;
+	status = HttpStatus(200, HE_SUCCESS);
+	status2 = HttpStatus(201, HE_SUCCESS);
 	ensure(status != status2);
 
 	// Different statuses but both failed are distinct
-	status.mType = 200;
-	status.mStatus = HE_REPLY_ERROR;
-	status2.mType = 201;
-	status2.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(200, HE_REPLY_ERROR);
+	status2 = HttpStatus(201, HE_REPLY_ERROR);
 	ensure(status != status2);
 }
 
 template <> template <>
-void HttpStatusTestObjectType::test<7>()
+void HttpStatusTestObjectType::test<6>()
 {
 	set_test_name("HttpStatus HTTP status text strings");
 
@@ -234,34 +214,30 @@ void HttpStatusTestObjectType::test<7>()
 	ensure(! msg.empty());				// Should be something
 	ensure(msg == "Continue");
 
-	status.mStatus = HE_SUCCESS;
+	status = HttpStatus(200, HE_SUCCESS);
 	msg = status.toString();
 	ensure(msg.empty());				// Success is empty
 
-	status.mType = 199;
-	status.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(199, HE_REPLY_ERROR);
 	msg = status.toString();
 	ensure(msg == "Unknown error");
 
-	status.mType = 505;					// Last defined string
-	status.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(505, HE_REPLY_ERROR);
 	msg = status.toString();
 	ensure(msg == "HTTP Version not supported");
 
-	status.mType = 506;					// One beyond
-	status.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(506, HE_REPLY_ERROR);
 	msg = status.toString();
 	ensure(msg == "Unknown error");
 
-	status.mType = 999;					// Last HTTP status
-	status.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(999, HE_REPLY_ERROR);
 	msg = status.toString();
 	ensure(msg == "Unknown error");
 }
 
 
 template <> template <>
-void HttpStatusTestObjectType::test<8>()
+void HttpStatusTestObjectType::test<7>()
 {
 	set_test_name("HttpStatus toHex() nominal function");
 	
@@ -273,7 +249,7 @@ void HttpStatusTestObjectType::test<8>()
 
 
 template <> template <>
-void HttpStatusTestObjectType::test<9>()
+void HttpStatusTestObjectType::test<8>()
 {
 	set_test_name("HttpStatus toTerseString() nominal function");
 	
diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt
index ba4e34d92b0e04f3f37eb8962b3914c44fe7b3a9..da23b46b7b1ad99b45ad2a4bd7205fbbef8c2fd2 100755
--- a/indra/llcrashlogger/CMakeLists.txt
+++ b/indra/llcrashlogger/CMakeLists.txt
@@ -3,6 +3,7 @@
 project(llcrashlogger)
 
 include(00-Common)
+include(LLCoreHttp)
 include(LLCommon)
 include(LLMath)
 include(LLMessage)
@@ -10,6 +11,7 @@ include(LLVFS)
 include(LLXML)
 
 include_directories(
+    ${LLCOREHTTP_INCLUDE_DIRS}
     ${LLCOMMON_INCLUDE_DIRS}
     ${LLMATH_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 7a97c16ea7048c6a0b1c86ccc64352795f2b8c7b..cb05c4ff0356147f9caaf1a0695b51c6a7230e6b 100755
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -40,38 +40,45 @@
 #include "lldir.h"
 #include "llfile.h"
 #include "llsdserialize.h"
-#include "lliopipe.h"
-#include "llpumpio.h"
-#include "llhttpclient.h"
 #include "llsdserialize.h"
 #include "llproxy.h"
- 
-LLPumpIO* gServicePump = NULL;
+#include "llcorehttputil.h"
+#include "llhttpsdhandler.h"
+#include "httpcommon.h"
+#include "httpresponse.h"
+
+#include <curl/curl.h>
+#include <openssl/crypto.h>
+
 BOOL gBreak = false;
 BOOL gSent = false;
 
-class LLCrashLoggerResponder : public LLHTTPClient::Responder
+int LLCrashLogger::ssl_mutex_count = 0;
+LLCoreInt::HttpMutex ** LLCrashLogger::ssl_mutex_list = NULL;
+
+class LLCrashLoggerHandler : public LLHttpSDHandler
 {
-	LOG_CLASS(LLCrashLoggerResponder);
+    LOG_CLASS(LLCrashLoggerHandler);
 public:
-	LLCrashLoggerResponder() 
-	{
-	}
+    LLCrashLoggerHandler() {}
 
 protected:
-	virtual void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-		gBreak = true;
-	}
+    virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
+    virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
 
-	virtual void httpSuccess()
-	{
-		gBreak = true;
-		gSent = true;
-	}
 };
 
+void LLCrashLoggerHandler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
+{
+    gBreak = true;
+    gSent = true;
+}
+
+void LLCrashLoggerHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
+{
+    gBreak = true;
+}
+
 LLCrashLogger::LLCrashLogger() :
 	mCrashBehavior(CRASH_BEHAVIOR_ALWAYS_SEND),
 	mCrashInPreviousExec(false),
@@ -389,14 +396,23 @@ bool LLCrashLogger::saveCrashBehaviorSetting(S32 crash_behavior)
 
 bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout)
 {
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
 	gBreak = false;
+    httpOpts->setTimeout(timeout);
+
 	for(int i = 0; i < retries; ++i)
 	{
 		updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));
-		LLHTTPClient::post(host, data, new LLCrashLoggerResponder(), timeout);
-		while(!gBreak)
+
+        LLCoreHttpUtil::requestPostWithLLSD(httpRequest.get(), LLCore::HttpRequest::DEFAULT_POLICY_ID, 0,
+            host, data, httpOpts.get(), NULL, new LLCrashLoggerHandler);
+
+        while(!gBreak)
 		{
 			updateApplication(); // No new message, just pump the IO
+            httpRequest->update(0L);
 		}
 		if(gSent)
 		{
@@ -510,8 +526,6 @@ bool LLCrashLogger::sendCrashLogs()
 
 void LLCrashLogger::updateApplication(const std::string& message)
 {
-	gServicePump->pump();
-    gServicePump->callback();
 	if (!message.empty()) LL_INFOS() << message << LL_ENDL;
 }
 
@@ -576,16 +590,74 @@ bool LLCrashLogger::init()
 		return false;
 	}
     
-	gServicePump = new LLPumpIO(gAPRPoolp);
-	gServicePump->prime(gAPRPoolp);
-	LLHTTPClient::setPump(*gServicePump);
- 	
+    init_curl();
+    LLCore::HttpRequest::createService();
+    LLCore::HttpRequest::startThread();
+
 	return true;
 }
 
 // For cleanup code common to all platforms.
 void LLCrashLogger::commonCleanup()
 {
+    term_curl();
 	LLError::logToFile("");   //close crashreport.log
 	LLProxy::cleanupClass();
 }
+
+void LLCrashLogger::init_curl()
+{
+    curl_global_init(CURL_GLOBAL_ALL);
+
+    ssl_mutex_count = CRYPTO_num_locks();
+    if (ssl_mutex_count > 0)
+    {
+        ssl_mutex_list = new LLCoreInt::HttpMutex *[ssl_mutex_count];
+
+        for (int i(0); i < ssl_mutex_count; ++i)
+        {
+            ssl_mutex_list[i] = new LLCoreInt::HttpMutex;
+        }
+
+        CRYPTO_set_locking_callback(ssl_locking_callback);
+        CRYPTO_set_id_callback(ssl_thread_id_callback);
+    }
+}
+
+
+void LLCrashLogger::term_curl()
+{
+    CRYPTO_set_locking_callback(NULL);
+    for (int i(0); i < ssl_mutex_count; ++i)
+    {
+        delete ssl_mutex_list[i];
+    }
+    delete[] ssl_mutex_list;
+}
+
+
+unsigned long LLCrashLogger::ssl_thread_id_callback(void)
+{
+#if LL_WINDOWS
+    return (unsigned long)GetCurrentThread();
+#else
+    return (unsigned long)pthread_self();
+#endif
+}
+
+
+void LLCrashLogger::ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */)
+{
+    if (type >= 0 && type < ssl_mutex_count)
+    {
+        if (mode & CRYPTO_LOCK)
+        {
+            ssl_mutex_list[type]->lock();
+        }
+        else
+        {
+            ssl_mutex_list[type]->unlock();
+        }
+    }
+}
+
diff --git a/indra/llcrashlogger/llcrashlogger.h b/indra/llcrashlogger/llcrashlogger.h
index a06bf1d6ac24dd53f99a3d7e48aa0bb8f4021bcf..f5383daefc1c5104ac0b99cf5480f30dd8fe9003 100755
--- a/indra/llcrashlogger/llcrashlogger.h
+++ b/indra/llcrashlogger/llcrashlogger.h
@@ -34,6 +34,7 @@
 #include "llsd.h"
 #include "llcontrol.h"
 #include "llcrashlock.h"
+#include "_mutex.h"
 
 // Crash reporter behavior
 const S32 CRASH_BEHAVIOR_ASK = 0;
@@ -66,6 +67,11 @@ class LLCrashLogger : public LLApp
 	bool readMinidump(std::string minidump_path);
 
 protected:
+    static void init_curl();
+    static void term_curl();
+    static unsigned long ssl_thread_id_callback(void);
+    static void ssl_locking_callback(int mode, int type, const char * file, int line);
+
 	S32 mCrashBehavior;
 	BOOL mCrashInPreviousExec;
 	std::map<std::string, std::string> mFileMap;
@@ -78,6 +84,10 @@ class LLCrashLogger : public LLApp
 	LLSD mDebugLog;
 	bool mSentCrashLogs;
     LLCrashLock mKeyMaster;
+
+    static int ssl_mutex_count;
+    static LLCoreInt::HttpMutex ** ssl_mutex_list;
+
 };
 
 #endif //LLCRASHLOGGER_H
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 0a308fbf10170db13ff669e07589e79b60dcd052..fc51d147a6394c321265734f1d262aba06833fc2 100755
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -14,6 +14,7 @@ include(LLAddBuildTest)
 include(Python)
 include(Tut)
 include(Python)
+include(JsonCpp)
 
 include_directories (${CMAKE_CURRENT_SOURCE_DIR})
 
@@ -23,6 +24,7 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
+    ${JSONCPP_INCLUDE_DIR}
     )
 
 set(llmessage_SOURCE_FILES
@@ -47,9 +49,9 @@ set(llmessage_SOURCE_FILES
     llhost.cpp
     llhttpassetstorage.cpp
     llhttpclient.cpp
-    llhttpclientadapter.cpp
     llhttpconstants.cpp
     llhttpnode.cpp
+    llhttpsdhandler.cpp
     llhttpsender.cpp
     llinstantmessage.cpp
     lliobuffer.cpp
@@ -74,7 +76,6 @@ set(llmessage_SOURCE_FILES
     llpumpio.cpp
     llsdappservices.cpp
     llsdhttpserver.cpp
-    llsdmessage.cpp
     llsdmessagebuilder.cpp
     llsdmessagereader.cpp
     llsdrpcclient.cpp
@@ -142,10 +143,10 @@ set(llmessage_HEADER_FILES
     llhttpassetstorage.h
     llhttpclient.h
     llhttpclientinterface.h
-    llhttpclientadapter.h
     llhttpconstants.h
     llhttpnode.h
     llhttpnodeadapter.h
+    llhttpsdhandler.h
     llhttpsender.h
     llinstantmessage.h
     llinvite.h
@@ -176,7 +177,6 @@ set(llmessage_HEADER_FILES
     llregionhandle.h
     llsdappservices.h
     llsdhttpserver.h
-    llsdmessage.h
     llsdmessagebuilder.h
     llsdmessagereader.h
     llsdrpcclient.h
@@ -226,9 +226,10 @@ target_link_libraries(
   llmessage
   ${CURL_LIBRARIES}
   ${LLCOMMON_LIBRARIES}
-  ${LLVFS_LIBRARES}
+  ${LLVFS_LIBRARIES}
   ${LLMATH_LIBRARIES}
   ${CARES_LIBRARIES}
+  ${JSONCPP_LIBRARIES}
   ${OPENSSL_LIBRARIES}
   ${CRYPTO_LIBRARIES}
   ${XMLRPCEPI_LIBRARIES}
@@ -243,36 +244,25 @@ if (LL_TESTS)
     )
   LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}")
 
+  
   #    set(TEST_DEBUG on)
+  
   set(test_libs
-    ${CURL_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
     ${WINDOWS_LIBRARIES}
     ${LLVFS_LIBRARIES}
     ${LLMATH_LIBRARIES}
+    ${CURL_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
-      ${GOOGLEMOCK_LIBRARIES}
-    )
-
-  LL_ADD_INTEGRATION_TEST(
-    llsdmessage
-    "llsdmessage.cpp"
-    "${test_libs}"
-    ${PYTHON_EXECUTABLE}
-    "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py"
-    )
-
-  LL_ADD_INTEGRATION_TEST(
-    llhttpclient
-    "llhttpclient.cpp"
-    "${test_libs}"
-    ${PYTHON_EXECUTABLE}
-    "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py"
+    ${LLMESSAGE_LIBRARIES}
+    ${LLCOREHTTP_LIBRARIES}
+    ${JSONCPP_LIBRARIES}
+    ${BOOST_COROUTINE_LIBRARY}
+    ${BOOST_CONTEXT_LIBRARY}
+    ${GOOGLEMOCK_LIBRARIES}
     )
 
-  LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}")
+  #LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llhost "" "${test_libs}")
-  LL_ADD_INTEGRATION_TEST(llhttpclientadapter "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llpartdata "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llxfer_file "" "${test_libs}")
 endif (LL_TESTS)
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 549708097ab45b6ce27f25eff9762670adf63fa3..d262862c80aec10d3d03b02c34763d2a14d41313 100755
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -30,12 +30,20 @@
 
 #include "llcachename.h"		// we wrap this system
 #include "llframetimer.h"
-#include "llhttpclient.h"
 #include "llsd.h"
 #include "llsdserialize.h"
-
+#include "httpresponse.h"
+#include "llhttpsdhandler.h"
 #include <boost/tokenizer.hpp>
 
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llcorehttputil.h"
+
 #include <map>
 #include <set>
 
@@ -90,6 +98,12 @@ namespace LLAvatarNameCache
 	// Time-to-live for a temp cache entry.
 	const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
 
+    LLCore::HttpRequest::ptr_t		sHttpRequest;
+    LLCore::HttpHeaders::ptr_t		sHttpHeaders;
+    LLCore::HttpOptions::ptr_t		sHttpOptions;
+    LLCore::HttpRequest::policy_t	sHttpPolicy;
+    LLCore::HttpRequest::priority_t	sHttpPriority;
+
 	//-----------------------------------------------------------------------
 	// Internal methods
 	//-----------------------------------------------------------------------
@@ -121,7 +135,12 @@ namespace LLAvatarNameCache
 	// Erase expired names from cache
 	void eraseUnrefreshed();
 
-	bool expirationFromCacheControl(const LLSD& headers, F64 *expires);
+    bool expirationFromCacheControl(const LLSD& headers, F64 *expires);
+
+    // This is a coroutine.
+    void requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds);
+
+    void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult);
 }
 
 /* Sample response:
@@ -163,94 +182,117 @@ namespace LLAvatarNameCache
 </llsd>
 */
 
-class LLAvatarNameResponder : public LLHTTPClient::Responder
+// Coroutine for sending and processing avatar name cache requests.  
+// Do not call directly.  See documentation in lleventcoro.h and llcoro.h for
+// further explanation.
+void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds)
 {
-	LOG_CLASS(LLAvatarNameResponder);
-private:
-	// need to store agent ids that are part of this request in case of
-	// an error, so we can flag them as unavailable
-	std::vector<LLUUID> mAgentIDs;
-
-public:
-	LLAvatarNameResponder(const std::vector<LLUUID>& agent_ids)
-	:	mAgentIDs(agent_ids)
-	{ }
-	
-protected:
-	/*virtual*/ void httpSuccess()
-	{
-		const LLSD& content = getContent();
-		if (!content.isMap())
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		// Pull expiration out of headers if available
-		F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(getResponseHeaders());
-		F64 now = LLFrameTimer::getTotalSeconds();
+    LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName()
+        << " with url '" << url << "', requesting " << agentIds.size() << " Agent Ids" << LL_ENDL;
 
-		const LLSD& agents = content["agents"];
-		LLSD::array_const_iterator it = agents.beginArray();
-		for ( ; it != agents.endArray(); ++it)
-		{
-			const LLSD& row = *it;
-			LLUUID agent_id = row["id"].asUUID();
+    try
+    {
+        bool success = true;
 
-			LLAvatarName av_name;
-			av_name.fromLLSD(row);
+        LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", LLAvatarNameCache::sHttpPolicy);
+        LLSD results = httpAdapter.getAndYield(sHttpRequest, url);
+        LLSD httpResults;
 
-			// Use expiration time from header
-			av_name.mExpires = expires;
+        LL_DEBUGS() << results << LL_ENDL;
 
-			LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL;
-			av_name.dump();
-			
-			// cache it and fire signals
-			LLAvatarNameCache::processName(agent_id, av_name);
-		}
+        if (!results.isMap())
+        {
+            LL_WARNS("AvNameCache") << " Invalid result returned from LLCoreHttpUtil::HttpCoroHandler." << LL_ENDL;
+            success = false;
+        }
+        else
+        {
+            httpResults = results["http_result"];
+            success = httpResults["success"].asBoolean();
+            if (!success)
+            {
+                LL_WARNS("AvNameCache") << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
+                    << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL;
+            }
+        }
 
-		// Same logic as error response case
-		const LLSD& unresolved_agents = content["bad_ids"];
-		S32  num_unresolved = unresolved_agents.size();
-		if (num_unresolved > 0)
-		{
-            LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " << num_unresolved << " unresolved ids; "
-                                    << "expires in " << expires - now << " seconds"
-                                    << LL_ENDL;
-			it = unresolved_agents.beginArray();
-			for ( ; it != unresolved_agents.endArray(); ++it)
-			{
-				const LLUUID& agent_id = *it;
+        if (!success)
+        {   // on any sort of failure add dummy records for any agent IDs 
+            // in this request that we do not have cached already
+            std::vector<LLUUID>::const_iterator it = agentIds.begin();
+            for ( ; it != agentIds.end(); ++it)
+            {
+                const LLUUID& agent_id = *it;
+                LLAvatarNameCache::handleAgentError(agent_id);
+            }
+            return;
+        }
 
-				LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result "
-                                        << "failed id " << agent_id
-                                        << LL_ENDL;
+        LLAvatarNameCache::handleAvNameCacheSuccess(results, httpResults);
 
-                LLAvatarNameCache::handleAgentError(agent_id);
-			}
-		}
-        LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result " 
-                                 << LLAvatarNameCache::sCache.size() << " cached names"
-                                 << LL_ENDL;
     }
+    catch (std::exception e)
+    {
+        LL_WARNS() << "Caught exception '" << e.what() << "'" << LL_ENDL;
+    }
+    catch (...)
+    {
+        LL_WARNS() << "Caught unknown exception." << LL_ENDL;
+    }
+}
 
-	/*virtual*/ void httpFailure()
-	{
-		// If there's an error, it might be caused by PeopleApi,
-		// or when loading textures on startup and using a very slow 
-		// network, this query may time out.
-		// What we should do depends on whether or not we have a cached name
-		LL_WARNS("AvNameCache") << dumpResponse() << LL_ENDL;
-
-		// Add dummy records for any agent IDs in this request that we do not have cached already
-		std::vector<LLUUID>::const_iterator it = mAgentIDs.begin();
-		for ( ; it != mAgentIDs.end(); ++it)
-		{
-			const LLUUID& agent_id = *it;
-			LLAvatarNameCache::handleAgentError(agent_id);
-		}
-	}
-};
+void LLAvatarNameCache::handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult)
+{
+
+    LLSD headers = httpResult["headers"];
+    // Pull expiration out of headers if available
+    F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(headers);
+    F64 now = LLFrameTimer::getTotalSeconds();
+
+    const LLSD& agents = data["agents"];
+    LLSD::array_const_iterator it = agents.beginArray();
+    for (; it != agents.endArray(); ++it)
+    {
+        const LLSD& row = *it;
+        LLUUID agent_id = row["id"].asUUID();
+
+        LLAvatarName av_name;
+        av_name.fromLLSD(row);
+
+        // Use expiration time from header
+        av_name.mExpires = expires;
+
+        LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL;
+        av_name.dump();
+
+        // cache it and fire signals
+        LLAvatarNameCache::processName(agent_id, av_name);
+    }
+
+    // Same logic as error response case
+    const LLSD& unresolved_agents = data["bad_ids"];
+    S32  num_unresolved = unresolved_agents.size();
+    if (num_unresolved > 0)
+    {
+        LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " << num_unresolved << " unresolved ids; "
+            << "expires in " << expires - now << " seconds"
+            << LL_ENDL;
+        it = unresolved_agents.beginArray();
+        for (; it != unresolved_agents.endArray(); ++it)
+        {
+            const LLUUID& agent_id = *it;
+
+            LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result "
+                << "failed id " << agent_id
+                << LL_ENDL;
+
+            LLAvatarNameCache::handleAgentError(agent_id);
+        }
+    }
+    LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result "
+        << LLAvatarNameCache::sCache.size() << " cached names"
+        << LL_ENDL;
+}
 
 // Provide some fallback for agents that return errors
 void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
@@ -353,10 +395,15 @@ void LLAvatarNameCache::requestNamesViaCapability()
 		}
 	}
 
-	if (!url.empty())
-	{
-		LL_INFOS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability getting " << ids << " ids" << LL_ENDL;
-		LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
+    if (!url.empty())
+    {
+        LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested " << ids << " ids" << LL_ENDL;
+
+        std::string coroname = 
+            LLCoros::instance().launch("LLAvatarNameCache::requestAvatarNameCache_",
+            boost::bind(&LLAvatarNameCache::requestAvatarNameCache_, url, agent_ids));
+        LL_DEBUGS("AvNameCache") << coroname << " with  url '" << url << "', agent_ids.size()=" << agent_ids.size() << LL_ENDL;
+
 	}
 }
 
@@ -419,11 +466,20 @@ void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI)
 {
 	sRunning = running;
 	sUsePeopleAPI = usePeopleAPI;
+
+    sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+    sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
+    sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
+    sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
+    sHttpPriority = 0;
 }
 
 void LLAvatarNameCache::cleanupClass()
 {
-	sCache.clear();
+    sHttpRequest.reset();
+    sHttpHeaders.reset();
+    sHttpOptions.reset();
+    sCache.clear();
 }
 
 bool LLAvatarNameCache::importFile(std::istream& istr)
@@ -698,6 +754,50 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na
 	sCache[agent_id] = av_name;
 }
 
+#if 0
+F64 LLAvatarNameCache::nameExpirationFromHeaders(LLCore::HttpHeaders *headers)
+{
+    F64 expires = 0.0;
+    if (expirationFromCacheControl(headers, &expires))
+    {
+        return expires;
+    }
+    else
+    {
+        // With no expiration info, default to an hour
+        const F64 DEFAULT_EXPIRES = 60.0 * 60.0;
+        F64 now = LLFrameTimer::getTotalSeconds();
+        return now + DEFAULT_EXPIRES;
+    }
+}
+
+bool LLAvatarNameCache::expirationFromCacheControl(LLCore::HttpHeaders *headers, F64 *expires)
+{
+    bool fromCacheControl = false;
+    F64 now = LLFrameTimer::getTotalSeconds();
+
+    // Allow the header to override the default
+    const std::string *cache_control;
+    
+    cache_control = headers->find(HTTP_IN_HEADER_CACHE_CONTROL);
+
+    if (cache_control && !cache_control->empty())
+    {
+        S32 max_age = 0;
+        if (max_age_from_cache_control(*cache_control, &max_age))
+        {
+            *expires = now + (F64)max_age;
+            fromCacheControl = true;
+        }
+    }
+    LL_DEBUGS("AvNameCache")
+        << ( fromCacheControl ? "expires based on cache control " : "default expiration " )
+        << "in " << *expires - now << " seconds"
+        << LL_ENDL;
+
+    return fromCacheControl;
+}
+#else
 F64 LLAvatarNameCache::nameExpirationFromHeaders(const LLSD& headers)
 {
 	F64 expires = 0.0;
@@ -742,7 +842,7 @@ bool LLAvatarNameCache::expirationFromCacheControl(const LLSD& headers, F64 *exp
 	
 	return fromCacheControl;
 }
-
+#endif
 
 void LLAvatarNameCache::addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb) 
 { 
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 5a10053a69288180032d7a12d8d8de3ecaf855c9..bd2715e9567607d7f15d57124c63190dea6d5513 100755
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -29,7 +29,6 @@
 #define LLAVATARNAMECACHE_H
 
 #include "llavatarname.h"	// for convenience
-
 #include <boost/signals2.hpp>
 
 class LLSD;
@@ -49,7 +48,7 @@ namespace LLAvatarNameCache
 	bool importFile(std::istream& istr);
 	void exportFile(std::ostream& ostr);
 
-	// On the viewer, usually a simulator capabilitity.
+	// On the viewer, usually a simulator capabilities.
 	// If empty, name cache will fall back to using legacy name lookup system.
 	void setNameLookupURL(const std::string& name_lookup_url);
 
@@ -90,7 +89,7 @@ namespace LLAvatarNameCache
 
 	// Compute name expiration time from HTTP Cache-Control header,
 	// or return default value, in seconds from epoch.
-	F64 nameExpirationFromHeaders(const LLSD& headers);
+    F64 nameExpirationFromHeaders(const LLSD& headers);
 
 	void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb);
 }
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index ee80b0fd949c572ac462813af37af9003e4ae887..cd3c5272415a2887995778c07784e827248d4bec 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -28,112 +28,985 @@
 #include "linden_common.h"
 
 #include <sstream>
-
+#include <algorithm>
+#include <iterator>
 #include "llcorehttputil.h"
+#include "llhttpconstants.h"
+#include "llsd.h"
+#include "llsdjson.h"
 #include "llsdserialize.h"
+#include "reader.h" 
+#include "llvfile.h"
 
+#include "message.h" // for getting the port
 
 using namespace LLCore;
 
 
 namespace LLCoreHttpUtil
 {
+void logMessageSuccess(std::string logAuth, std::string url, std::string message)
+{
+    LL_INFOS() << logAuth << " Success '" << message << "' for " << url << LL_ENDL;
+}
+
+void logMessageFail(std::string logAuth, std::string url, std::string message)
+{
+    LL_WARNS() << logAuth << " Failure '" << message << "' for " << url << LL_ENDL;
+}
+
+//=========================================================================
+/// The HttpRequestPumper is a utility class. When constructed it will poll the 
+/// supplied HttpRequest once per frame until it is destroyed.
+/// 
+class HttpRequestPumper
+{
+public:
+    HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request);
+    ~HttpRequestPumper();
+
+private:
+    bool                       pollRequest(const LLSD&);
 
+    LLTempBoundListener        mBoundListener;
+    LLCore::HttpRequest::ptr_t mHttpRequest;
+};
+
+
+//=========================================================================
 // *TODO:  Currently converts only from XML content.  A mode
 // to convert using fromBinary() might be useful as well.  Mesh
 // headers could use it.
 bool responseToLLSD(HttpResponse * response, bool log, LLSD & out_llsd)
 {
-	// Convert response to LLSD
-	BufferArray * body(response->getBody());
-	if (! body || ! body->size())
-	{
-		return false;
-	}
+    // Convert response to LLSD
+    BufferArray * body(response->getBody());
+    if (!body || !body->size())
+    {
+        return false;
+    }
 
-	LLCore::BufferArrayStream bas(body);
-	LLSD body_llsd;
-	S32 parse_status(LLSDSerialize::fromXML(body_llsd, bas, log));
-	if (LLSDParser::PARSE_FAILURE == parse_status){
-		return false;
-	}
-	out_llsd = body_llsd;
-	return true;
+    LLCore::BufferArrayStream bas(body);
+    LLSD body_llsd;
+    S32 parse_status(LLSDSerialize::fromXML(body_llsd, bas, log));
+    if (LLSDParser::PARSE_FAILURE == parse_status){
+        return false;
+    }
+    out_llsd = body_llsd;
+    return true;
 }
 
 
 HttpHandle requestPostWithLLSD(HttpRequest * request,
-							   HttpRequest::policy_t policy_id,
-							   HttpRequest::priority_t priority,
-							   const std::string & url,
-							   const LLSD & body,
-							   HttpOptions * options,
-							   HttpHeaders * headers,
-							   HttpHandler * handler)
+    HttpRequest::policy_t policy_id,
+    HttpRequest::priority_t priority,
+    const std::string & url,
+    const LLSD & body,
+    HttpOptions * options,
+    HttpHeaders * headers,
+    HttpHandler * handler)
 {
-	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+    HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
-	BufferArray * ba = new BufferArray();
-	BufferArrayStream bas(ba);
-	LLSDSerialize::toXML(body, bas);
+    BufferArray * ba = new BufferArray();
+    BufferArrayStream bas(ba);
+    LLSDSerialize::toXML(body, bas);
 
-	handle = request->requestPost(policy_id,
-								  priority,
-								  url,
-								  ba,
-								  options,
-								  headers,
-								  handler);
-	ba->release();
-	return handle;
+    handle = request->requestPost(policy_id,
+        priority,
+        url,
+        ba,
+        options,
+        headers,
+        handler);
+    ba->release();
+    return handle;
+}
+
+
+HttpHandle requestPutWithLLSD(HttpRequest * request,
+    HttpRequest::policy_t policy_id,
+    HttpRequest::priority_t priority,
+    const std::string & url,
+    const LLSD & body,
+    HttpOptions * options,
+    HttpHeaders * headers,
+    HttpHandler * handler)
+{
+    HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+    BufferArray * ba = new BufferArray();
+    BufferArrayStream bas(ba);
+    LLSDSerialize::toXML(body, bas);
+
+    handle = request->requestPut(policy_id,
+        priority,
+        url,
+        ba,
+        options,
+        headers,
+        handler);
+    ba->release();
+    return handle;
+}
+
+HttpHandle requestPatchWithLLSD(HttpRequest * request,
+    HttpRequest::policy_t policy_id,
+    HttpRequest::priority_t priority,
+    const std::string & url,
+    const LLSD & body,
+    HttpOptions * options,
+    HttpHeaders * headers,
+    HttpHandler * handler)
+{
+    HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+    BufferArray * ba = new BufferArray();
+    BufferArrayStream bas(ba);
+    LLSDSerialize::toXML(body, bas);
+
+    handle = request->requestPatch(policy_id,
+        priority,
+        url,
+        ba,
+        options,
+        headers,
+        handler);
+    ba->release();
+    return handle;
 }
 
 
 std::string responseToString(LLCore::HttpResponse * response)
 {
-	static const std::string empty("[Empty]");
-
-	if (! response)
-	{
-		return empty;
-	}
-
-	BufferArray * body(response->getBody());
-	if (! body || ! body->size())
-	{
-		return empty;
-	}
-
-	// Attempt to parse as LLSD regardless of content-type
-	LLSD body_llsd;
-	if (responseToLLSD(response, false, body_llsd))
-	{
-		std::ostringstream tmp;
-
-		LLSDSerialize::toPrettyNotation(body_llsd, tmp);
-		std::size_t temp_len(tmp.tellp());
-		
-		if (temp_len)
-		{
-			return tmp.str().substr(0, std::min(temp_len, std::size_t(1024)));
-		}
-	}
-	else
-	{
-		// *TODO:  More elaborate forms based on Content-Type as needed.
-		char content[1024];
-
-		size_t len(body->read(0, content, sizeof(content)));
-		if (len)
-		{
-			return std::string(content, 0, len);
-		}
-	}
-
-	// Default
-	return empty;
+    static const std::string empty("[Empty]");
+
+    if (!response)
+    {
+        return empty;
+    }
+
+    BufferArray * body(response->getBody());
+    if (!body || !body->size())
+    {
+        return empty;
+    }
+
+    // Attempt to parse as LLSD regardless of content-type
+    LLSD body_llsd;
+    if (responseToLLSD(response, false, body_llsd))
+    {
+        std::ostringstream tmp;
+
+        LLSDSerialize::toPrettyNotation(body_llsd, tmp);
+        std::size_t temp_len(tmp.tellp());
+
+        if (temp_len)
+        {
+            return tmp.str().substr(0, std::min(temp_len, std::size_t(1024)));
+        }
+    }
+    else
+    {
+        // *TODO:  More elaborate forms based on Content-Type as needed.
+        char content[1024];
+
+        size_t len(body->read(0, content, sizeof(content)));
+        if (len)
+        {
+            return std::string(content, 0, len);
+        }
+    }
+
+    // Default
+    return empty;
+}
+
+//========================================================================
+
+HttpCoroHandler::HttpCoroHandler(LLEventStream &reply) :
+    mReplyPump(reply)
+{
+}
+
+void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+{
+    LLSD result;
+
+    LLCore::HttpStatus status = response->getStatus();
+
+    if (status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_HANDLE_NOT_FOUND))
+    {   // A response came in for a canceled request and we have not processed the 
+        // cancel yet.  Patience!
+        return;
+    }
+
+    if (!status)
+    {
+        result = LLSD::emptyMap();
+        LL_WARNS()
+            << "\n--------------------------------------------------------------------------\n"
+            << " Error[" << status.getType() << "] cannot access url '" << response->getRequestURL()
+            << "' because " << status.toString()
+            << "\n--------------------------------------------------------------------------"
+            << LL_ENDL;
+    }
+    else
+    {
+        result = this->handleSuccess(response, status);
+    }
+
+    buildStatusEntry(response, status, result);
+
+#if 1
+    // commenting out, but keeping since this can be useful for debugging
+    if (!status)
+    {
+        LLSD &httpStatus = result[HttpCoroutineAdapter::HTTP_RESULTS];
+
+        LLCore::BufferArray *body = response->getBody();
+        LLCore::BufferArrayStream bas(body);
+        LLSD::String bodyData;
+        bodyData.reserve(response->getBodySize());
+        bas >> std::noskipws;
+        bodyData.assign(std::istream_iterator<U8>(bas), std::istream_iterator<U8>());
+        httpStatus["error_body"] = LLSD(bodyData);
+
+        LL_WARNS() << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL;
+    }
+#endif
+
+    mReplyPump.post(result);
+}
+
+void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result)
+{
+    LLSD httpresults = LLSD::emptyMap();
+
+    writeStatusCodes(status, response->getRequestURL(), httpresults);
+
+    LLSD httpHeaders = LLSD::emptyMap();
+    LLCore::HttpHeaders * hdrs = response->getHeaders();
+
+    if (hdrs)
+    {
+        for (LLCore::HttpHeaders::iterator it = hdrs->begin(); it != hdrs->end(); ++it)
+        {
+            if (!(*it).second.empty())
+            {
+                httpHeaders[(*it).first] = (*it).second;
+            }
+            else
+            {
+                httpHeaders[(*it).first] = static_cast<LLSD::Boolean>(true);
+            }
+        }
+    }
+
+    httpresults[HttpCoroutineAdapter::HTTP_RESULTS_HEADERS] = httpHeaders;
+    result[HttpCoroutineAdapter::HTTP_RESULTS] = httpresults;
+}
+
+void HttpCoroHandler::writeStatusCodes(LLCore::HttpStatus status, const std::string &url, LLSD &result)
+{
+    result[HttpCoroutineAdapter::HTTP_RESULTS_SUCCESS] = static_cast<LLSD::Boolean>(status);
+    result[HttpCoroutineAdapter::HTTP_RESULTS_TYPE] = static_cast<LLSD::Integer>(status.getType());
+    result[HttpCoroutineAdapter::HTTP_RESULTS_STATUS] = static_cast<LLSD::Integer>(status.getStatus());
+    result[HttpCoroutineAdapter::HTTP_RESULTS_MESSAGE] = static_cast<LLSD::String>(status.getMessage());
+    result[HttpCoroutineAdapter::HTTP_RESULTS_URL] = static_cast<LLSD::String>(url);
+
+}
+
+//=========================================================================
+/// The HttpCoroLLSDHandler is a specialization of the LLCore::HttpHandler for 
+/// interacting with coroutines. When the request is completed the response 
+/// will be posted onto the supplied Event Pump.
+/// 
+/// If the LLSD retrieved from through the HTTP connection is not in the form
+/// of a LLSD::map it will be returned as in an llsd["content"] element.
+/// 
+/// The LLSD posted back to the coroutine will have the following additions:
+/// llsd["http_result"] -+- ["message"] - An error message returned from the HTTP status
+///                      +- ["status"]  - The status code associated with the HTTP call
+///                      +- ["success"] - Success of failure of the HTTP call and LLSD parsing.
+///                      +- ["type"]    - The LLCore::HttpStatus type associted with the HTTP call
+///                      +- ["url"]     - The URL used to make the call.
+///                      +- ["headers"] - A map of name name value pairs with the HTTP headers.
+///                      
+class HttpCoroLLSDHandler : public HttpCoroHandler
+{
+public:
+    HttpCoroLLSDHandler(LLEventStream &reply);
+
+protected:
+    virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status);
+};
+
+//-------------------------------------------------------------------------
+HttpCoroLLSDHandler::HttpCoroLLSDHandler(LLEventStream &reply):
+    HttpCoroHandler(reply)
+{
+}
+    
+
+LLSD HttpCoroLLSDHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status)
+{
+    LLSD result;
+
+    const bool emit_parse_errors = false;
+
+    bool parsed = !((response->getBodySize() == 0) ||
+        !LLCoreHttpUtil::responseToLLSD(response, emit_parse_errors, result));
+
+    if (!parsed)
+    {
+        // Only emit a warning if we failed to parse when 'content-type' == 'application/llsd+xml'
+        LLCore::HttpHeaders::ptr_t headers(response->getHeaders());
+        const std::string *contentType = (headers) ? headers->find(HTTP_IN_HEADER_CONTENT_TYPE) : NULL;
+
+        if (contentType && (HTTP_CONTENT_LLSD_XML == *contentType))
+        {
+            std::string thebody = LLCoreHttpUtil::responseToString(response);
+            LL_WARNS() << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] "
+                << " body: " << thebody << LL_ENDL;
+
+            // Replace the status with a new one indicating the failure.
+            status = LLCore::HttpStatus(499, "Failed to deserialize LLSD.");
+        }
+    }
+
+    if (result.isUndefined())
+    {   // If we've gotten to this point and the result LLSD is still undefined 
+        // either there was an issue deserializing the body or the response was
+        // blank.  Create an empty map to hold the result either way.
+        result = LLSD::emptyMap();
+    }
+    else if (!result.isMap())
+    {   // The results are not themselves a map.  Move them down so that 
+        // this method can return a map to the caller.
+        // *TODO: Should it always do this?
+        LLSD newResult = LLSD::emptyMap();
+        newResult[HttpCoroutineAdapter::HTTP_RESULTS_CONTENT] = result;
+        result = newResult;
+    }
+
+    return result;
+}
+
+//========================================================================
+/// The HttpCoroRawHandler is a specialization of the LLCore::HttpHandler for 
+/// interacting with coroutines. 
+/// 
+/// In addition to the normal "http_results" the returned LLSD will contain 
+/// an entry keyed with "raw" containing the unprocessed results of the HTTP
+/// call.
+///                      
+class HttpCoroRawHandler : public HttpCoroHandler
+{
+public:
+    HttpCoroRawHandler(LLEventStream &reply);
+
+    virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status);
+};
+
+//-------------------------------------------------------------------------
+HttpCoroRawHandler::HttpCoroRawHandler(LLEventStream &reply):
+    HttpCoroHandler(reply)
+{
 }
 
+LLSD HttpCoroRawHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status)
+{
+    LLSD result = LLSD::emptyMap();
+
+    BufferArray * body(response->getBody());
+    if (!body || !body->size())
+    {
+        return result;
+    }
+
+    size_t size = body->size();
+
+    LLCore::BufferArrayStream bas(body);
+
+#if 1
+    // This is the slower implementation.  It is safe vis-a-vi the const_cast<> and modification
+    // of a LLSD managed array but contains an extra (potentially large) copy.
+    // 
+    // *TODO: https://jira.secondlife.com/browse/MAINT-5221
+    
+    LLSD::Binary data;
+    data.reserve(size);
+    bas >> std::noskipws;
+    data.assign(std::istream_iterator<U8>(bas), std::istream_iterator<U8>());
+
+    result[HttpCoroutineAdapter::HTTP_RESULTS_RAW] = data;
+
+#else
+    // This is disabled because it's dangerous.  See the other case for an 
+    // alternate implementation.
+    // We create a new LLSD::Binary object and assign it to the result map.
+    // The LLSD has created it's own copy so we retrieve it asBinary and const cast 
+    // the reference so that we can modify it.
+    // *TODO: This is potentially dangerous... but I am trying to avoid a potentially 
+    // large copy.
+    result[HttpCoroutineAdapter::HTTP_RESULTS_RAW] = LLSD::Binary();
+    LLSD::Binary &data = const_cast<LLSD::Binary &>( result[HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary() );
+
+    data.reserve(size);
+    bas >> std::noskipws;
+    data.assign(std::istream_iterator<U8>(bas), std::istream_iterator<U8>());
+#endif
+
+    return result;
+}
+
+//========================================================================
+/// The HttpCoroJSONHandler is a specialization of the LLCore::HttpHandler for 
+/// interacting with coroutines. 
+/// 
+/// In addition to the normal "http_results" the returned LLSD will contain 
+/// JSON entries will be converted into an LLSD map.  All results are considered 
+/// strings
+///                      
+class HttpCoroJSONHandler : public HttpCoroHandler
+{
+public:
+    HttpCoroJSONHandler(LLEventStream &reply);
+
+    virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status);
+};
+
+//-------------------------------------------------------------------------
+HttpCoroJSONHandler::HttpCoroJSONHandler(LLEventStream &reply) :
+    HttpCoroHandler(reply)
+{
+}
+
+LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status)
+{
+    LLSD result = LLSD::emptyMap();
+
+    BufferArray * body(response->getBody());
+    if (!body || !body->size())
+    {
+        return result;
+    }
+
+    LLCore::BufferArrayStream bas(body);
+    Json::Value jsonRoot;
+
+    try
+    {
+        bas >> jsonRoot;
+    }
+    catch (std::runtime_error e)
+    {   // deserialization failed.  Record the reason and pass back an empty map for markup.
+        status = LLCore::HttpStatus(499, std::string(e.what()));
+        return result;
+    }
+
+    // Convert the JSON structure to LLSD
+    result = LlsdFromJson(jsonRoot);
+
+    return result;
+}
+
+
+//========================================================================
+HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request) :
+    mHttpRequest(request)
+{
+    mBoundListener = LLEventPumps::instance().obtain("mainloop").
+        listen(LLEventPump::inventName(), boost::bind(&HttpRequestPumper::pollRequest, this, _1));
+}
+
+HttpRequestPumper::~HttpRequestPumper()
+{
+    if (mBoundListener.connected())
+    {
+        mBoundListener.disconnect();
+    }
+}
+
+bool HttpRequestPumper::pollRequest(const LLSD&)
+{
+    if (mHttpRequest->getStatus() != HttpStatus(HttpStatus::LLCORE, HE_OP_CANCELED))
+    {
+        mHttpRequest->update(0L);
+    }
+    return false;
+}
+
+//========================================================================
+const std::string HttpCoroutineAdapter::HTTP_RESULTS("http_result");
+const std::string HttpCoroutineAdapter::HTTP_RESULTS_SUCCESS("success");
+const std::string HttpCoroutineAdapter::HTTP_RESULTS_TYPE("type");
+const std::string HttpCoroutineAdapter::HTTP_RESULTS_STATUS("status");
+const std::string HttpCoroutineAdapter::HTTP_RESULTS_MESSAGE("message");
+const std::string HttpCoroutineAdapter::HTTP_RESULTS_URL("url");
+const std::string HttpCoroutineAdapter::HTTP_RESULTS_HEADERS("headers");
+const std::string HttpCoroutineAdapter::HTTP_RESULTS_CONTENT("content");
+const std::string HttpCoroutineAdapter::HTTP_RESULTS_RAW("raw");
+
+HttpCoroutineAdapter::HttpCoroutineAdapter(const std::string &name,
+    LLCore::HttpRequest::policy_t policyId, LLCore::HttpRequest::priority_t priority) :
+    mAdapterName(name),
+    mPolicyId(policyId),
+    mPriority(priority),
+    mYieldingHandle(LLCORE_HTTP_HANDLE_INVALID),
+    mWeakRequest(),
+    mWeakHandler()
+{
+}
+
+HttpCoroutineAdapter::~HttpCoroutineAdapter()
+{
+    cancelYieldingOperation();
+}
+
+LLSD HttpCoroutineAdapter::postAndYield(LLCore::HttpRequest::ptr_t request,
+    const std::string & url, const LLSD & body,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLEventStream  replyPump(mAdapterName, true);
+    HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroLLSDHandler(replyPump));
+
+    return postAndYield_(request, url, body, options, headers, httpHandler);
+}
+
+LLSD HttpCoroutineAdapter::postAndYield_(LLCore::HttpRequest::ptr_t &request,
+    const std::string & url, const LLSD & body,
+    LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers,
+    HttpCoroHandler::ptr_t &handler)
+{
+    HttpRequestPumper pumper(request);
+
+    checkDefaultHeaders(headers);
+
+    // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
+    // pointer from the smart pointer is safe in this case.
+    LLCore::HttpHandle hhandle = requestPostWithLLSD(request,
+        mPolicyId, mPriority, url, body, options, headers,
+        handler.get());
+
+    if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
+    {
+        return HttpCoroutineAdapter::buildImmediateErrorResult(request, url);
+    }
+
+    saveState(hhandle, request, handler);
+    LLSD results = llcoro::waitForEventOn(handler->getReplyPump());
+    cleanState();
+
+    return results;
+}
+
+LLSD HttpCoroutineAdapter::postAndYield(LLCore::HttpRequest::ptr_t request,
+    const std::string & url, LLCore::BufferArray::ptr_t rawbody,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLEventStream  replyPump(mAdapterName, true);
+    HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroLLSDHandler(replyPump));
+
+    return postAndYield_(request, url, rawbody, options, headers, httpHandler);
+}
+
+LLSD HttpCoroutineAdapter::postRawAndYield(LLCore::HttpRequest::ptr_t request,
+    const std::string & url, LLCore::BufferArray::ptr_t rawbody,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLEventStream  replyPump(mAdapterName, true);
+    HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroRawHandler(replyPump));
+
+    return postAndYield_(request, url, rawbody, options, headers, httpHandler);
+}
+
+// *TODO: This functionality could be moved into the LLCore::Http library itself 
+// by having the CURL layer read the file directly.
+LLSD HttpCoroutineAdapter::postFileAndYield(LLCore::HttpRequest::ptr_t request,
+    const std::string & url, std::string fileName,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLCore::BufferArray::ptr_t fileData(new LLCore::BufferArray);
+
+    // scoping for our streams so that they go away when we no longer need them.
+    {
+        LLCore::BufferArrayStream outs(fileData.get());
+        llifstream ins(fileName.c_str(), std::iostream::binary | std::iostream::out);
+
+        if (ins.is_open())
+        {
+
+            ins.seekg(0, std::ios::beg);
+            ins >> std::noskipws;
+
+            std::copy(std::istream_iterator<U8>(ins), std::istream_iterator<U8>(),
+                    std::ostream_iterator<U8>(outs));
+
+            ins.close();
+        }
+    }
+
+    return postAndYield(request, url, fileData, options, headers);
+}
+
+// *TODO: This functionality could be moved into the LLCore::Http library itself 
+// by having the CURL layer read the file directly.
+LLSD HttpCoroutineAdapter::postFileAndYield(LLCore::HttpRequest::ptr_t request,
+    const std::string & url, LLUUID assetId, LLAssetType::EType assetType,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLCore::BufferArray::ptr_t fileData(new LLCore::BufferArray);
+
+    // scoping for our streams so that they go away when we no longer need them.
+    {
+        LLCore::BufferArrayStream outs(fileData.get());
+        LLVFile vfile(gVFS, assetId, assetType, LLVFile::READ);
+
+        S32 fileSize = vfile.getSize();
+        U8* fileBuffer;
+        fileBuffer = new U8[fileSize];
+        vfile.read(fileBuffer, fileSize);
+        
+        outs.write((char*)fileBuffer, fileSize);
+        delete[] fileBuffer;
+    }
+
+    return postAndYield(request, url, fileData, options, headers);
+}
+
+
+LLSD HttpCoroutineAdapter::postAndYield_(LLCore::HttpRequest::ptr_t &request,
+    const std::string & url, LLCore::BufferArray::ptr_t &rawbody,
+    LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers,
+    HttpCoroHandler::ptr_t &handler)
+{
+    HttpRequestPumper pumper(request);
+
+    checkDefaultHeaders(headers);
+
+    // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
+    // pointer from the smart pointer is safe in this case.
+    LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, mPriority, url, rawbody.get(),
+        options.get(), headers.get(), handler.get());
+
+    if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
+    {
+        return HttpCoroutineAdapter::buildImmediateErrorResult(request, url);
+    }
+
+    saveState(hhandle, request, handler);
+    LLSD results = llcoro::waitForEventOn(handler->getReplyPump());
+    cleanState();
+
+    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;
+    return results;
+}
+
+LLSD HttpCoroutineAdapter::putAndYield(LLCore::HttpRequest::ptr_t request,
+    const std::string & url, const LLSD & body,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLEventStream  replyPump(mAdapterName + "Reply", true);
+    HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroLLSDHandler(replyPump));
+
+    return putAndYield_(request, url, body, options, headers, httpHandler);
+}
+
+LLSD HttpCoroutineAdapter::putAndYield_(LLCore::HttpRequest::ptr_t &request,
+    const std::string & url, const LLSD & body,
+    LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers,
+    HttpCoroHandler::ptr_t &handler)
+{
+    HttpRequestPumper pumper(request);
+
+    checkDefaultHeaders(headers);
+
+    // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
+    // pointer from the smart pointer is safe in this case.
+    LLCore::HttpHandle hhandle = requestPutWithLLSD(request,
+        mPolicyId, mPriority, url, body, options, headers,
+        handler.get());
+
+    if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
+    {
+        return HttpCoroutineAdapter::buildImmediateErrorResult(request, url);
+    }
+
+    saveState(hhandle, request, handler);
+    LLSD results = llcoro::waitForEventOn(handler->getReplyPump());
+    cleanState();
+    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;
+    return results;
+}
+
+LLSD HttpCoroutineAdapter::getAndYield(LLCore::HttpRequest::ptr_t request,
+    const std::string & url,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLEventStream  replyPump(mAdapterName + "Reply", true);
+    HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroLLSDHandler(replyPump));
+
+    return getAndYield_(request, url, options, headers, httpHandler);
+}
+
+LLSD HttpCoroutineAdapter::getRawAndYield(LLCore::HttpRequest::ptr_t request,
+    const std::string & url,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLEventStream  replyPump(mAdapterName + "Reply", true);
+    HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroRawHandler(replyPump));
+
+    return getAndYield_(request, url, options, headers, httpHandler);
+}
+
+LLSD HttpCoroutineAdapter::getJsonAndYield(LLCore::HttpRequest::ptr_t request,
+    const std::string & url, LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLEventStream  replyPump(mAdapterName + "Reply", true);
+    HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroJSONHandler(replyPump));
+
+    return getAndYield_(request, url, options, headers, httpHandler);
+}
+
+
+LLSD HttpCoroutineAdapter::getAndYield_(LLCore::HttpRequest::ptr_t &request,
+    const std::string & url,
+    LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, 
+    HttpCoroHandler::ptr_t &handler)
+{
+    HttpRequestPumper pumper(request);
+    checkDefaultHeaders(headers);
+
+    // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
+    // pointer from the smart pointer is safe in this case.
+    LLCore::HttpHandle hhandle = request->requestGet(mPolicyId, mPriority,
+        url, options.get(), headers.get(), handler.get());
+
+    if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
+    {
+        return HttpCoroutineAdapter::buildImmediateErrorResult(request, url);
+    }
+
+    saveState(hhandle, request, handler);
+    LLSD results = llcoro::waitForEventOn(handler->getReplyPump());
+    cleanState();
+    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;
+    return results;
+}
+
+
+LLSD HttpCoroutineAdapter::deleteAndYield(LLCore::HttpRequest::ptr_t request,
+    const std::string & url,
+    LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
+{
+    LLEventStream  replyPump(mAdapterName + "Reply", true);
+    HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroLLSDHandler(replyPump));
+
+    return deleteAndYield_(request, url, options, headers, httpHandler);
+}
+
+LLSD HttpCoroutineAdapter::deleteAndYield_(LLCore::HttpRequest::ptr_t &request,
+    const std::string & url, LLCore::HttpOptions::ptr_t &options, 
+    LLCore::HttpHeaders::ptr_t &headers, HttpCoroHandler::ptr_t &handler)
+{
+    HttpRequestPumper pumper(request);
+
+    checkDefaultHeaders(headers);
+    // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
+    // pointer from the smart pointer is safe in this case.
+    LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId, mPriority,
+        url, options.get(), headers.get(), handler.get());
+
+    if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
+    {
+        return HttpCoroutineAdapter::buildImmediateErrorResult(request, url);
+    }
+
+    saveState(hhandle, request, handler);
+    LLSD results = llcoro::waitForEventOn(handler->getReplyPump());
+    cleanState();
+    //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;
+    return results;
+}
+
+void HttpCoroutineAdapter::checkDefaultHeaders(LLCore::HttpHeaders::ptr_t &headers)
+{
+    if (!headers)
+        headers.reset(new LLCore::HttpHeaders);
+    if (!headers->find(HTTP_OUT_HEADER_ACCEPT))
+    {
+        headers->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_LLSD_XML);
+    }
+
+    if (!headers->find("X-SecondLife-UDP-Listen-Port") && gMessageSystem)
+    {
+        headers->append("X-SecondLife-UDP-Listen-Port", llformat("%d", gMessageSystem->mPort));
+    }
+}
+
+
+void HttpCoroutineAdapter::cancelYieldingOperation()
+{
+    LLCore::HttpRequest::ptr_t request = mWeakRequest.lock();
+    HttpCoroHandler::ptr_t handler = mWeakHandler.lock();
+    if ((request) && (handler) && (mYieldingHandle != LLCORE_HTTP_HANDLE_INVALID))
+    {
+        cleanState();
+        LL_INFOS() << "Canceling yielding request!" << LL_ENDL;
+        request->requestCancel(mYieldingHandle, handler.get());
+    }
+}
+
+void HttpCoroutineAdapter::saveState(LLCore::HttpHandle yieldingHandle, 
+    LLCore::HttpRequest::ptr_t &request, HttpCoroHandler::ptr_t &handler)
+{
+    mWeakRequest = request;
+    mWeakHandler = handler;
+    mYieldingHandle = yieldingHandle;
+}
+
+void HttpCoroutineAdapter::cleanState()
+{
+    mWeakRequest.reset();
+    mWeakHandler.reset();
+    mYieldingHandle = LLCORE_HTTP_HANDLE_INVALID;
+}
+
+/*static*/
+LLSD HttpCoroutineAdapter::buildImmediateErrorResult(const LLCore::HttpRequest::ptr_t &request, 
+    const std::string &url) 
+{
+    LLCore::HttpStatus status = request->getStatus();
+    LL_WARNS() << "Error posting to " << url << " Status=" << status.getStatus() <<
+        " message = " << status.getMessage() << LL_ENDL;
+
+    // Mimic the status results returned from an http error that we had 
+    // to wait on 
+    LLSD httpresults = LLSD::emptyMap();
+
+    HttpCoroHandler::writeStatusCodes(status, url, httpresults);
+
+    LLSD errorres = LLSD::emptyMap();
+    errorres["http_result"] = httpresults;
+
+    return errorres;
+}
+
+/*static*/
+LLCore::HttpStatus HttpCoroutineAdapter::getStatusFromLLSD(const LLSD &httpResults)
+{
+    LLCore::HttpStatus::type_enum_t type = static_cast<LLCore::HttpStatus::type_enum_t>(httpResults[HttpCoroutineAdapter::HTTP_RESULTS_TYPE].asInteger());
+    short code = static_cast<short>(httpResults[HttpCoroutineAdapter::HTTP_RESULTS_STATUS].asInteger());
+
+    return LLCore::HttpStatus(type, code);
+}
+
+/*static*/
+void HttpCoroutineAdapter::callbackHttpGet(const std::string &url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success, completionCallback_t failure)
+{
+    LLCoros::instance().launch("HttpCoroutineAdapter::genericGetCoro",
+        boost::bind(&HttpCoroutineAdapter::trivialGetCoro, url, policyId, success, failure));
+}
+
+/*static*/
+void HttpCoroutineAdapter::messageHttpGet(const std::string &url, const std::string &success, const std::string &failure)
+{
+    completionCallback_t cbSuccess = (success.empty()) ? NULL : 
+        static_cast<completionCallback_t>(boost::bind(&logMessageSuccess, "HttpCoroutineAdapter", url, success));
+    completionCallback_t cbFailure = (failure.empty()) ? NULL :
+        static_cast<completionCallback_t>(boost::bind(&logMessageFail, "HttpCoroutineAdapter", url, failure));
+    callbackHttpGet(url, cbSuccess, cbFailure);
+}
+
+/*static*/
+void HttpCoroutineAdapter::trivialGetCoro(std::string url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success, completionCallback_t failure)
+{
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericGetCoro", policyId));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+
+    LL_INFOS("HttpCoroutineAdapter", "genericGetCoro") << "Generic GET for " << url << LL_ENDL;
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url, httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {   
+        if (failure)
+        {
+            failure(httpResults);
+        }
+    }
+    else
+    {
+        if (success)
+        {
+            success(result);
+        }
+    }
+}
+
+/*static*/
+void HttpCoroutineAdapter::callbackHttpPost(const std::string &url, LLCore::HttpRequest::policy_t policyId, const LLSD &postData, completionCallback_t success, completionCallback_t failure)
+{
+    LLCoros::instance().launch("HttpCoroutineAdapter::genericPostCoro",
+        boost::bind(&HttpCoroutineAdapter::trivialPostCoro, url, policyId, postData, success, failure));
+}
+
+/*static*/
+void HttpCoroutineAdapter::messageHttpPost(const std::string &url, const LLSD &postData, const std::string &success, const std::string &failure)
+{
+    completionCallback_t cbSuccess = (success.empty()) ? NULL :
+        static_cast<completionCallback_t>(boost::bind(&logMessageSuccess, "HttpCoroutineAdapter", url, success));
+    completionCallback_t cbFailure = (failure.empty()) ? NULL :
+        static_cast<completionCallback_t>(boost::bind(&logMessageFail, "HttpCoroutineAdapter", url, failure));
+
+    callbackHttpPost(url, postData, cbSuccess, cbFailure);
+}
+
+/*static*/
+void HttpCoroutineAdapter::trivialPostCoro(std::string url, LLCore::HttpRequest::policy_t policyId, LLSD postData, completionCallback_t success, completionCallback_t failure)
+{
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", policyId));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+
+    LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData, httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        // If a failure routine is provided do it.
+        if (failure)
+        {
+            failure(httpResults);
+        }
+    }
+    else
+    {
+        // If a success routine is provided do it.
+        if (success)
+        {
+            success(result);
+        }
+    }
+}
+
+
 
 } // end namespace LLCoreHttpUtil
 
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index d40172bc7a7865ec086bcfe3ea66d518bed0e780..cf35177e486686349003b11228a29eebb5515c23 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -36,9 +36,15 @@
 #include "httpheaders.h"
 #include "httpoptions.h"
 #include "httphandler.h"
+#include "llhttpconstants.h" // *TODO: move to llcorehttp
 #include "bufferarray.h"
 #include "bufferstream.h"
 #include "llsd.h"
+#include "llevents.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llassettype.h"
+#include "lluuid.h"
 
 ///
 /// The base llcorehttp library implements many HTTP idioms
@@ -109,7 +115,415 @@ LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,
 									   LLCore::HttpHeaders * headers,
 									   LLCore::HttpHandler * handler);
 
-} // end namespace LLCoreHttpUtil
+inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request,
+	LLCore::HttpRequest::policy_t policy_id,
+	LLCore::HttpRequest::priority_t priority,
+	const std::string & url,
+	const LLSD & body,
+	LLCore::HttpOptions::ptr_t & options,
+	LLCore::HttpHeaders::ptr_t & headers,
+	LLCore::HttpHandler * handler)
+{
+    return requestPostWithLLSD(request.get(), policy_id, priority,
+        url, body, options.get(), headers.get(), handler);
+}
+
+inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request,
+    LLCore::HttpRequest::policy_t policy_id,
+    LLCore::HttpRequest::priority_t priority,
+    const std::string & url,
+    const LLSD & body,
+    LLCore::HttpHandler * handler)
+{
+    return requestPostWithLLSD(request.get(), policy_id, priority,
+        url, body, NULL, NULL, handler);
+}
+
+
+/// Issue a standard HttpRequest::requestPut() call but using
+/// and LLSD object as the request body.  Conventions are the
+/// same as with that method.  Caller is expected to provide
+/// an HttpHeaders object with a correct 'Content-Type:' header.
+/// One will not be provided by this call.
+///
+/// @return				If request is successfully issued, the
+///						HttpHandle representing the request.
+///						On error, LLCORE_HTTP_HANDLE_INVALID
+///						is returned and caller can fetch detailed
+///						status with the getStatus() method on the
+///						request object.  In case of error, no
+///						request is queued and caller may need to
+///						perform additional cleanup such as freeing
+///						a now-useless HttpHandler object.
+///
+LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request,
+	LLCore::HttpRequest::policy_t policy_id,
+	LLCore::HttpRequest::priority_t priority,
+	const std::string & url,
+	const LLSD & body,
+	LLCore::HttpOptions * options,
+	LLCore::HttpHeaders * headers,
+	LLCore::HttpHandler * handler);
+
+inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
+	LLCore::HttpRequest::policy_t policy_id,
+	LLCore::HttpRequest::priority_t priority,
+	const std::string & url,
+	const LLSD & body,
+	LLCore::HttpOptions::ptr_t & options,
+	LLCore::HttpHeaders::ptr_t & headers,
+	LLCore::HttpHandler * handler)
+{
+    return requestPutWithLLSD(request.get(), policy_id, priority,
+        url, body, options.get(), headers.get(), handler);
+}
+
+inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
+    LLCore::HttpRequest::policy_t policy_id,
+    LLCore::HttpRequest::priority_t priority,
+    const std::string & url,
+    const LLSD & body,
+    LLCore::HttpHandler * handler)
+{
+    return requestPutWithLLSD(request.get(), policy_id, priority,
+        url, body, NULL, NULL, handler);
+}
+
+/// Issue a standard HttpRequest::requestPatch() call but using
+/// and LLSD object as the request body.  Conventions are the
+/// same as with that method.  Caller is expected to provide
+/// an HttpHeaders object with a correct 'Content-Type:' header.
+/// One will not be provided by this call.
+///
+/// @return				If request is successfully issued, the
+///						HttpHandle representing the request.
+///						On error, LLCORE_HTTP_HANDLE_INVALID
+///						is returned and caller can fetch detailed
+///						status with the getStatus() method on the
+///						request object.  In case of error, no
+///						request is queued and caller may need to
+///						perform additional cleanup such as freeing
+///						a now-useless HttpHandler object.
+///
+LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request,
+    LLCore::HttpRequest::policy_t policy_id,
+    LLCore::HttpRequest::priority_t priority,
+    const std::string & url,
+    const LLSD & body,
+    LLCore::HttpOptions * options,
+    LLCore::HttpHeaders * headers,
+    LLCore::HttpHandler * handler);
+
+inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,
+    LLCore::HttpRequest::policy_t policy_id,
+    LLCore::HttpRequest::priority_t priority,
+    const std::string & url,
+    const LLSD & body,
+    LLCore::HttpOptions::ptr_t & options,
+    LLCore::HttpHeaders::ptr_t & headers,
+    LLCore::HttpHandler * handler)
+{
+    return requestPatchWithLLSD(request.get(), policy_id, priority,
+        url, body, options.get(), headers.get(), handler);
+}
+
+inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,
+    LLCore::HttpRequest::policy_t policy_id,
+    LLCore::HttpRequest::priority_t priority,
+    const std::string & url,
+    const LLSD & body,
+    LLCore::HttpHandler * handler)
+{
+    return requestPatchWithLLSD(request.get(), policy_id, priority,
+        url, body, NULL, NULL, handler);
+}
+
+//=========================================================================
+/// The HttpCoroHandler is a specialization of the LLCore::HttpHandler for 
+/// interacting with coroutines. When the request is completed the response 
+/// will be posted onto the supplied Event Pump.
+/// 
+/// The LLSD posted back to the coroutine will have the following additions:
+/// llsd["http_result"] -+- ["message"] - An error message returned from the HTTP status
+///                      +- ["status"]  - The status code associated with the HTTP call
+///                      +- ["success"] - Success of failure of the HTTP call and LLSD parsing.
+///                      +- ["type"]    - The LLCore::HttpStatus type associted with the HTTP call
+///                      +- ["url"]     - The URL used to make the call.
+///                      +- ["headers"] - A map of name name value pairs with the HTTP headers.
+///                      
+class HttpCoroHandler : public LLCore::HttpHandler
+{
+public:
+
+    typedef boost::shared_ptr<HttpCoroHandler>  ptr_t;
+    typedef boost::weak_ptr<HttpCoroHandler>    wptr_t;
 
+    HttpCoroHandler(LLEventStream &reply);
+
+    static void writeStatusCodes(LLCore::HttpStatus status, const std::string &url, LLSD &result);
+
+    virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+
+    inline LLEventStream &getReplyPump()
+    {
+        return mReplyPump;
+    }
+
+protected:
+    /// this method may modify the status value
+    virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) = 0;
+
+private:
+    void buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result);
+
+    LLEventStream &mReplyPump;
+};
+
+//=========================================================================
+/// An adapter to handle some of the boilerplate code surrounding HTTP and coroutine 
+/// interaction.
+/// 
+/// Construct an HttpCoroutineAdapter giving it a name and policy Id. After 
+/// any application specific setup call the post, put or get method.  The request 
+/// will be automatically pumped and the method will return with an LLSD describing
+/// the result of the operation.  See HttpCoroHandler for a description of the 
+/// decoration done to the returned LLSD.
+/// 
+/// Posting through the adapter will automatically add the following headers to 
+/// the request if they have not been previously specified in a supplied 
+/// HttpHeaders object:
+///     "Accept=application/llsd+xml"
+///     "X-SecondLife-UDP-Listen-Port=###"
+///     
+class HttpCoroutineAdapter
+{
+public:
+    static const std::string HTTP_RESULTS;
+    static const std::string HTTP_RESULTS_SUCCESS;
+    static const std::string HTTP_RESULTS_TYPE;
+    static const std::string HTTP_RESULTS_STATUS;
+    static const std::string HTTP_RESULTS_MESSAGE;
+    static const std::string HTTP_RESULTS_URL;
+    static const std::string HTTP_RESULTS_HEADERS;
+    static const std::string HTTP_RESULTS_CONTENT;
+    static const std::string HTTP_RESULTS_RAW;
+
+    typedef boost::shared_ptr<HttpCoroutineAdapter> ptr_t;
+    typedef boost::weak_ptr<HttpCoroutineAdapter>   wptr_t;
+
+    HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId,
+        LLCore::HttpRequest::priority_t priority = 0L);
+    ~HttpCoroutineAdapter();
+
+    /// Execute a Post transaction on the supplied URL and yield execution of 
+    /// the coroutine until a result is available. 
+    /// 
+    /// @Note: the request's smart pointer is passed by value so that it will
+    /// not be deallocated during the yield.
+    LLSD postAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url, const LLSD & body,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()));
+    LLSD postAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url, LLCore::BufferArray::ptr_t rawbody,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()));
+    LLSD postAndYield(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, const LLSD & body,
+        LLCore::HttpHeaders::ptr_t &headers)
+    {
+        return postAndYield(request, url, body,
+            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers);
+    }
+
+    LLSD postAndYield(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, LLCore::BufferArray::ptr_t &rawbody,
+        LLCore::HttpHeaders::ptr_t &headers)
+    {
+        return postAndYield(request, url, rawbody,
+            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers);
+    }
+
+    LLSD postRawAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url, LLCore::BufferArray::ptr_t rawbody,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()));
+
+    LLSD postRawAndYield(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, LLCore::BufferArray::ptr_t &rawbody,
+        LLCore::HttpHeaders::ptr_t &headers)
+    {
+        return postRawAndYield(request, url, rawbody,
+            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers);
+    }
+
+    LLSD postFileAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url, std::string fileName,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()));
+
+    LLSD postFileAndYield(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, std::string fileName,
+        LLCore::HttpHeaders::ptr_t &headers)
+    {
+        return postFileAndYield(request, url, fileName,
+            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers);
+    }
+
+
+    LLSD postFileAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url, LLUUID assetId, LLAssetType::EType assetType,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()));
+
+    LLSD postFileAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url, LLUUID assetId, LLAssetType::EType assetType,
+        LLCore::HttpHeaders::ptr_t &headers)
+    {
+        return postFileAndYield(request, url, assetId, assetType,
+            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers);
+    }
+
+
+    /// Execute a Put transaction on the supplied URL and yield execution of 
+    /// the coroutine until a result is available.
+    /// 
+    /// @Note: the request's smart pointer is passed by value so that it will
+    /// not be deallocated during the yield.
+    LLSD putAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url, const LLSD & body,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()));
+
+    /// Execute a Get transaction on the supplied URL and yield execution of 
+    /// the coroutine until a result is available.
+    /// 
+    /// @Note: the request's smart pointer is passed by value so that it will
+    /// not be deallocated during the yield.
+    LLSD getAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()));
+    LLSD getAndYield(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, LLCore::HttpHeaders::ptr_t &headers)
+    {
+        return getAndYield(request, url,
+            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+            headers);
+    }
+
+    LLSD getRawAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()));
+    LLSD getRawAndYield(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, LLCore::HttpHeaders::ptr_t &headers)
+    {
+        return getRawAndYield(request, url,
+            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+            headers);
+    }
+
+    LLSD getJsonAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()));
+    LLSD getJsonndYield(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, LLCore::HttpHeaders::ptr_t &headers)
+    {
+        return getJsonAndYield(request, url,
+            LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+            headers);
+    }
+
+
+    /// Execute a DELETE transaction on the supplied URL and yield execution of 
+    /// the coroutine until a result is available.
+    /// 
+    /// @Note: the request's smart pointer is passed by value so that it will
+    /// not be deallocated during the yield.
+    LLSD deleteAndYield(LLCore::HttpRequest::ptr_t request,
+        const std::string & url,
+        LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()),
+        LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()));
+
+    ///
+    void cancelYieldingOperation();
+
+    static LLCore::HttpStatus getStatusFromLLSD(const LLSD &httpResults);
+
+    /// The convenience routines below can be provided with callback functors 
+    /// which will be invoked in the case of success or failure.  These callbacks
+    /// should match this form.
+    /// @sa callbackHttpGet
+    /// @sa callbackHttpPost
+    typedef boost::function<void(const LLSD &)> completionCallback_t;
+
+    static void callbackHttpGet(const std::string &url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success = NULL, completionCallback_t failure = NULL);
+    static void callbackHttpGet(const std::string &url, completionCallback_t success = NULL, completionCallback_t failure = NULL)
+    {
+        callbackHttpGet(url, LLCore::HttpRequest::DEFAULT_POLICY_ID, success, failure);
+    }
+    static void callbackHttpPost(const std::string &url, LLCore::HttpRequest::policy_t policyId, const LLSD &postData, completionCallback_t success = NULL, completionCallback_t failure = NULL);
+    static void callbackHttpPost(const std::string &url, const LLSD &postData, completionCallback_t success = NULL, completionCallback_t failure = NULL)
+    {
+        callbackHttpPost(url, LLCore::HttpRequest::DEFAULT_POLICY_ID, postData, success, failure);
+    }
+
+    /// Generic Get and post routines for HTTP via coroutines.
+    /// These static methods do all required setup for the GET or POST operation.
+    /// When the operation completes successfully they will put the success message in the log at INFO level, 
+    /// If the operation fails the failure message is written to the log at WARN level.
+    /// 
+    static void messageHttpGet(const std::string &url, const std::string &success = std::string(), const std::string &failure = std::string());
+    static void messageHttpPost(const std::string &url, const LLSD &postData, const std::string &success, const std::string &failure);
+
+
+private:
+    static LLSD buildImmediateErrorResult(const LLCore::HttpRequest::ptr_t &request, const std::string &url);
+
+    void saveState(LLCore::HttpHandle yieldingHandle, LLCore::HttpRequest::ptr_t &request,
+            HttpCoroHandler::ptr_t &handler);
+    void cleanState();
+
+    LLSD postAndYield_(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, const LLSD & body,
+        LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers,
+        HttpCoroHandler::ptr_t &handler);
+
+    LLSD postAndYield_(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, LLCore::BufferArray::ptr_t &rawbody,
+        LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers,
+        HttpCoroHandler::ptr_t &handler);
+
+    LLSD putAndYield_(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, const LLSD & body,
+        LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers,
+        HttpCoroHandler::ptr_t &handler);
+
+    LLSD getAndYield_(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, LLCore::HttpOptions::ptr_t &options, 
+        LLCore::HttpHeaders::ptr_t &headers, HttpCoroHandler::ptr_t &handler);
+
+    LLSD deleteAndYield_(LLCore::HttpRequest::ptr_t &request,
+        const std::string & url, LLCore::HttpOptions::ptr_t &options,
+        LLCore::HttpHeaders::ptr_t &headers, HttpCoroHandler::ptr_t &handler);
+
+    static void trivialGetCoro(std::string url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success, completionCallback_t failure);
+    static void trivialPostCoro(std::string url, LLCore::HttpRequest::policy_t policyId, LLSD postData, completionCallback_t success, completionCallback_t failure);
+
+    void checkDefaultHeaders(LLCore::HttpHeaders::ptr_t &headers);
+
+    std::string                     mAdapterName;
+    LLCore::HttpRequest::priority_t mPriority;
+    LLCore::HttpRequest::policy_t   mPolicyId;
+
+    LLCore::HttpHandle              mYieldingHandle;
+    LLCore::HttpRequest::wptr_t     mWeakRequest;
+    HttpCoroHandler::wptr_t         mWeakHandler;
+};
+
+
+} // end namespace LLCoreHttpUtil
 
 #endif // LL_LLCOREHTTPUTIL_H
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 73df47b933f91db8f06d44ad450feb59025535f1..ef28a4d2113644c84ee99dfd1c2561243398beba 100755
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -69,13 +69,15 @@
 	do this.
  */
 
+// *TODO: TSN remove the commented code from this file
 //////////////////////////////////////////////////////////////////////////////
 
 static const U32 EASY_HANDLE_POOL_SIZE		= 5;
 static const S32 MULTI_PERFORM_CALL_REPEAT	= 5;
 static const S32 CURL_REQUEST_TIMEOUT = 120; // seconds per operation
 static const S32 CURL_CONNECT_TIMEOUT = 30; //seconds to wait for a connection
-static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
+
+//static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
 
 // DEBUG //
 S32 gCurlEasyCount = 0;
@@ -676,6 +678,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
 }
 
 ////////////////////////////////////////////////////////////////////////////
+#if 1
 LLCurl::Multi::Multi(F32 idle_time_out)
 	: mQueued(0),
 	  mErrorCount(0),
@@ -1056,6 +1059,7 @@ void LLCurl::Multi::removeEasy(Easy* easy)
 	easyFree(easy);
 }
 
+#endif
 //------------------------------------------------------------
 //LLCurlThread
 LLCurlThread::CurlRequest::CurlRequest(handle_t handle, LLCurl::Multi* multi, LLCurlThread* curl_thread) :
@@ -1176,428 +1180,428 @@ std::string LLCurl::strerror(CURLcode errorcode)
 // For generating a simple request for data
 // using one multi and one easy per request 
 
-LLCurlRequest::LLCurlRequest() :
-	mActiveMulti(NULL),
-	mActiveRequestCount(0)
-{
-	mProcessing = FALSE;
-}
-
-LLCurlRequest::~LLCurlRequest()
-{
-	//stop all Multi handle background threads
-	for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter)
-	{
-		LLCurl::getCurlThread()->killMulti(*iter) ;
-	}
-	mMultiSet.clear() ;
-}
-
-void LLCurlRequest::addMulti()
-{
-	LLCurl::Multi* multi = new LLCurl::Multi();
-	if(!multi->isValid())
-	{
-		LLCurl::getCurlThread()->killMulti(multi) ;
-		mActiveMulti = NULL ;
-		mActiveRequestCount = 0 ;
-		return;
-	}
-	
-	mMultiSet.insert(multi);
-	mActiveMulti = multi;
-	mActiveRequestCount = 0;
-}
-
-LLCurl::Easy* LLCurlRequest::allocEasy()
-{
-	if (!mActiveMulti ||
-		mActiveRequestCount	>= MAX_ACTIVE_REQUEST_COUNT ||
-		mActiveMulti->mErrorCount > 0)
-	{
-		addMulti();
-	}
-	if(!mActiveMulti)
-	{
-		return NULL ;
-	}
-
-	//llassert_always(mActiveMulti);
-	++mActiveRequestCount;
-	LLCurl::Easy* easy = mActiveMulti->allocEasy();
-	return easy;
-}
-
-bool LLCurlRequest::addEasy(LLCurl::Easy* easy)
-{
-	llassert_always(mActiveMulti);
-	
-	if (mProcessing)
-	{
-		LL_ERRS() << "Posting to a LLCurlRequest instance from within a responder is not allowed (causes DNS timeouts)." << LL_ENDL;
-	}
-	bool res = mActiveMulti->addEasy(easy);
-	return res;
-}
-
-void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder)
-{
-	getByteRange(url, headers_t(), 0, -1, responder);
-}
-
-// Note: (length==0) is interpreted as "the rest of the file", i.e. the whole file if (offset==0) or
-// the remainder of the file if not.
-bool LLCurlRequest::getByteRange(const std::string& url,
-								 const headers_t& headers,
-								 S32 offset, S32 length,
-								 LLCurl::ResponderPtr responder)
-{
-	llassert(LLCurl::sNotQuitting);
-	LLCurl::Easy* easy = allocEasy();
-	if (!easy)
-	{
-		return false;
-	}
-	easy->prepRequest(url, headers, responder);
-	easy->setopt(CURLOPT_HTTPGET, 1);
-	if (length > 0)
-	{
-		std::string range = llformat("bytes=%d-%d", offset,offset+length-1);
-		easy->slist_append(HTTP_OUT_HEADER_RANGE, range);
-	}
-	else if (offset > 0)
-	{
-		std::string range = llformat("bytes=%d-", offset);
-		easy->slist_append(HTTP_OUT_HEADER_RANGE, range);
-	}
-	easy->setHeaders();
-	bool res = addEasy(easy);
-	return res;
-}
-
-bool LLCurlRequest::post(const std::string& url,
-						 const headers_t& headers,
-						 const LLSD& data,
-						 LLCurl::ResponderPtr responder, S32 time_out)
-{
-	llassert(LLCurl::sNotQuitting);
-	LLCurl::Easy* easy = allocEasy();
-	if (!easy)
-	{
-		return false;
-	}
-	easy->prepRequest(url, headers, responder, time_out);
-
-	LLSDSerialize::toXML(data, easy->getInput());
-	S32 bytes = easy->getInput().str().length();
-	
-	easy->setopt(CURLOPT_POST, 1);
-	easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
-	easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
-
-	easy->slist_append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
-	easy->setHeaders();
-
-	LL_DEBUGS() << "POSTING: " << bytes << " bytes." << LL_ENDL;
-	bool res = addEasy(easy);
-	return res;
-}
-
-bool LLCurlRequest::post(const std::string& url,
-						 const headers_t& headers,
-						 const std::string& data,
-						 LLCurl::ResponderPtr responder, S32 time_out)
-{
-	llassert(LLCurl::sNotQuitting);
-	LLCurl::Easy* easy = allocEasy();
-	if (!easy)
-	{
-		return false;
-	}
-	easy->prepRequest(url, headers, responder, time_out);
-
-	easy->getInput().write(data.data(), data.size());
-	S32 bytes = easy->getInput().str().length();
-	
-	easy->setopt(CURLOPT_POST, 1);
-	easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
-	easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
-
-	easy->slist_append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_OCTET_STREAM);
-	easy->setHeaders();
-
-	LL_DEBUGS() << "POSTING: " << bytes << " bytes." << LL_ENDL;
-	bool res = addEasy(easy);
-	return res;
-}
-
-// Note: call once per frame
-S32 LLCurlRequest::process()
-{
-	S32 res = 0;
-
-	mProcessing = TRUE;
-	for (curlmulti_set_t::iterator iter = mMultiSet.begin();
-		 iter != mMultiSet.end(); )
-	{
-		curlmulti_set_t::iterator curiter = iter++;
-		LLCurl::Multi* multi = *curiter;
-
-		if(!multi->isValid())
-		{
-			if(multi == mActiveMulti)
-			{				
-				mActiveMulti = NULL ;
-				mActiveRequestCount = 0 ;
-			}
-			mMultiSet.erase(curiter) ;
-			LLCurl::getCurlThread()->killMulti(multi) ;
-			continue ;
-		}
-
-		S32 tres = multi->process();
-		res += tres;
-		if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
-		{
-			mMultiSet.erase(curiter);
-			LLCurl::getCurlThread()->killMulti(multi);
-		}
-	}
-	mProcessing = FALSE;
-	return res;
-}
-
-S32 LLCurlRequest::getQueued()
-{
-	S32 queued = 0;
-	for (curlmulti_set_t::iterator iter = mMultiSet.begin();
-		 iter != mMultiSet.end(); )
-	{
-		curlmulti_set_t::iterator curiter = iter++;
-		LLCurl::Multi* multi = *curiter;
-		
-		if(!multi->isValid())
-		{
-			if(multi == mActiveMulti)
-			{				
-				mActiveMulti = NULL ;
-				mActiveRequestCount = 0 ;
-			}
-			LLCurl::getCurlThread()->killMulti(multi);
-			mMultiSet.erase(curiter) ;
-			continue ;
-		}
-
-		queued += multi->mQueued;
-		if (multi->getState() != LLCurl::Multi::STATE_READY)
-		{
-			++queued;
-		}
-	}
-	return queued;
-}
-
-LLCurlTextureRequest::LLCurlTextureRequest(S32 concurrency) : 
-	LLCurlRequest(), 
-	mConcurrency(concurrency),
-	mInQueue(0),
-	mMutex(NULL),
-	mHandleCounter(1),
-	mTotalIssuedRequests(0),
-	mTotalReceivedBits(0)
-{
-	mGlobalTimer.reset();
-}
-
-LLCurlTextureRequest::~LLCurlTextureRequest()
-{
-	mRequestMap.clear();
-
-	for(req_queue_t::iterator iter = mCachedRequests.begin(); iter != mCachedRequests.end(); ++iter)
-	{
-		delete *iter;
-	}
-	mCachedRequests.clear();
-}
-
-//return 0: success
-// > 0: cached handle
-U32 LLCurlTextureRequest::getByteRange(const std::string& url,
-								 const headers_t& headers,
-								 S32 offset, S32 length, U32 pri,
-								 LLCurl::ResponderPtr responder, F32 delay_time)
-{
-	U32 ret_val = 0;
-	bool success = false;	
-
-	if(mInQueue < mConcurrency && delay_time < 0.f)
-	{
-		success = LLCurlRequest::getByteRange(url, headers, offset, length, responder);		
-	}
-
-	LLMutexLock lock(&mMutex);
-
-	if(success)
-	{
-		mInQueue++;
-		mTotalIssuedRequests++;
-	}
-	else
-	{
-		request_t* request = new request_t(mHandleCounter, url, headers, offset, length, pri, responder);
-		if(delay_time > 0.f)
-		{
-			request->mStartTime = mGlobalTimer.getElapsedTimeF32() + delay_time;
-		}
-
-		mCachedRequests.insert(request);
-		mRequestMap[mHandleCounter] = request;
-		ret_val = mHandleCounter;
-		mHandleCounter++;
-
-		if(!mHandleCounter)
-		{
-			mHandleCounter = 1;
-		}
-	}
-
-	return ret_val;
-}
-
-void LLCurlTextureRequest::completeRequest(S32 received_bytes)
-{
-	LLMutexLock lock(&mMutex);
-
-	llassert_always(mInQueue > 0);
-
-	mInQueue--;
-	mTotalReceivedBits += received_bytes * 8;
-}
-
-void LLCurlTextureRequest::nextRequests()
-{
-	if(mCachedRequests.empty() || mInQueue >= mConcurrency)
-	{
-		return;
-	}
-
-	F32 cur_time = mGlobalTimer.getElapsedTimeF32();
-
-	req_queue_t::iterator iter;	
-	{
-		LLMutexLock lock(&mMutex);
-		iter = mCachedRequests.begin();
-	}
-	while(1)
-	{
-		request_t* request = *iter;
-		if(request->mStartTime < cur_time)
-		{
-			if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder))
-			{
-				break;
-			}
-
-			LLMutexLock lock(&mMutex);
-			++iter;
-			mInQueue++;
-			mTotalIssuedRequests++;
-			mCachedRequests.erase(request);
-			mRequestMap.erase(request->mHandle);
-			delete request;
-
-			if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
-			{
-				break;
-			}
-		}
-		else
-		{
-			LLMutexLock lock(&mMutex);
-			++iter;
-			if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
-			{
-				break;
-			}
-		}
-	}
-
-	return;
-}
-
-void LLCurlTextureRequest::updatePriority(U32 handle, U32 pri)
-{
-	if(!handle)
-	{
-		return;
-	}
-
-	LLMutexLock lock(&mMutex);
-
-	std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
-	if(iter != mRequestMap.end())
-	{
-		request_t* req = iter->second;
-		
-		if(req->mPriority != pri)
-		{
-			mCachedRequests.erase(req);
-			req->mPriority = pri;
-			mCachedRequests.insert(req);
-		}
-	}
-}
-
-void LLCurlTextureRequest::removeRequest(U32 handle)
-{
-	if(!handle)
-	{
-		return;
-	}
-
-	LLMutexLock lock(&mMutex);
-
-	std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
-	if(iter != mRequestMap.end())
-	{
-		request_t* req = iter->second;
-		mRequestMap.erase(iter);
-		mCachedRequests.erase(req);
-		delete req;
-	}
-}
-
-bool LLCurlTextureRequest::isWaiting(U32 handle)
-{
-	if(!handle)
-	{
-		return false;
-	}
-
-	LLMutexLock lock(&mMutex);
-	return mRequestMap.find(handle) != mRequestMap.end();
-}
-
-U32 LLCurlTextureRequest::getTotalReceivedBits()
-{
-	LLMutexLock lock(&mMutex);
-
-	U32 bits = mTotalReceivedBits;
-	mTotalReceivedBits = 0;
-	return bits;
-}
-
-U32 LLCurlTextureRequest::getTotalIssuedRequests()
-{
-	LLMutexLock lock(&mMutex);
-	return mTotalIssuedRequests;
-}
-
-S32 LLCurlTextureRequest::getNumRequests()
-{
-	LLMutexLock lock(&mMutex);
-	return mInQueue;
-}
+// LLCurlRequest::LLCurlRequest() :
+// 	mActiveMulti(NULL),
+// 	mActiveRequestCount(0)
+// {
+// 	mProcessing = FALSE;
+// }
+// 
+// LLCurlRequest::~LLCurlRequest()
+// {
+// 	//stop all Multi handle background threads
+// 	for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter)
+// 	{
+// 		LLCurl::getCurlThread()->killMulti(*iter) ;
+// 	}
+// 	mMultiSet.clear() ;
+// }
+// 
+// void LLCurlRequest::addMulti()
+// {
+// 	LLCurl::Multi* multi = new LLCurl::Multi();
+// 	if(!multi->isValid())
+// 	{
+// 		LLCurl::getCurlThread()->killMulti(multi) ;
+// 		mActiveMulti = NULL ;
+// 		mActiveRequestCount = 0 ;
+// 		return;
+// 	}
+// 	
+// 	mMultiSet.insert(multi);
+// 	mActiveMulti = multi;
+// 	mActiveRequestCount = 0;
+// }
+// 
+// LLCurl::Easy* LLCurlRequest::allocEasy()
+// {
+// 	if (!mActiveMulti ||
+// 		mActiveRequestCount	>= MAX_ACTIVE_REQUEST_COUNT ||
+// 		mActiveMulti->mErrorCount > 0)
+// 	{
+// 		addMulti();
+// 	}
+// 	if(!mActiveMulti)
+// 	{
+// 		return NULL ;
+// 	}
+// 
+// 	//llassert_always(mActiveMulti);
+// 	++mActiveRequestCount;
+// 	LLCurl::Easy* easy = mActiveMulti->allocEasy();
+// 	return easy;
+// }
+// 
+// bool LLCurlRequest::addEasy(LLCurl::Easy* easy)
+// {
+// 	llassert_always(mActiveMulti);
+// 	
+// 	if (mProcessing)
+// 	{
+// 		LL_ERRS() << "Posting to a LLCurlRequest instance from within a responder is not allowed (causes DNS timeouts)." << LL_ENDL;
+// 	}
+// 	bool res = mActiveMulti->addEasy(easy);
+// 	return res;
+// }
+// 
+// void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder)
+// {
+// 	getByteRange(url, headers_t(), 0, -1, responder);
+// }
+// 
+// // Note: (length==0) is interpreted as "the rest of the file", i.e. the whole file if (offset==0) or
+// // the remainder of the file if not.
+// bool LLCurlRequest::getByteRange(const std::string& url,
+// 								 const headers_t& headers,
+// 								 S32 offset, S32 length,
+// 								 LLCurl::ResponderPtr responder)
+// {
+// 	llassert(LLCurl::sNotQuitting);
+// 	LLCurl::Easy* easy = allocEasy();
+// 	if (!easy)
+// 	{
+// 		return false;
+// 	}
+// 	easy->prepRequest(url, headers, responder);
+// 	easy->setopt(CURLOPT_HTTPGET, 1);
+// 	if (length > 0)
+// 	{
+// 		std::string range = llformat("bytes=%d-%d", offset,offset+length-1);
+// 		easy->slist_append(HTTP_OUT_HEADER_RANGE, range);
+// 	}
+// 	else if (offset > 0)
+// 	{
+// 		std::string range = llformat("bytes=%d-", offset);
+// 		easy->slist_append(HTTP_OUT_HEADER_RANGE, range);
+// 	}
+// 	easy->setHeaders();
+// 	bool res = addEasy(easy);
+// 	return res;
+// }
+// 
+// bool LLCurlRequest::post(const std::string& url,
+// 						 const headers_t& headers,
+// 						 const LLSD& data,
+// 						 LLCurl::ResponderPtr responder, S32 time_out)
+// {
+// 	llassert(LLCurl::sNotQuitting);
+// 	LLCurl::Easy* easy = allocEasy();
+// 	if (!easy)
+// 	{
+// 		return false;
+// 	}
+// 	easy->prepRequest(url, headers, responder, time_out);
+// 
+// 	LLSDSerialize::toXML(data, easy->getInput());
+// 	S32 bytes = easy->getInput().str().length();
+// 	
+// 	easy->setopt(CURLOPT_POST, 1);
+// 	easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
+// 	easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
+// 
+// 	easy->slist_append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
+// 	easy->setHeaders();
+// 
+// 	LL_DEBUGS() << "POSTING: " << bytes << " bytes." << LL_ENDL;
+// 	bool res = addEasy(easy);
+// 	return res;
+// }
+// 
+// bool LLCurlRequest::post(const std::string& url,
+// 						 const headers_t& headers,
+// 						 const std::string& data,
+// 						 LLCurl::ResponderPtr responder, S32 time_out)
+// {
+// 	llassert(LLCurl::sNotQuitting);
+// 	LLCurl::Easy* easy = allocEasy();
+// 	if (!easy)
+// 	{
+// 		return false;
+// 	}
+// 	easy->prepRequest(url, headers, responder, time_out);
+// 
+// 	easy->getInput().write(data.data(), data.size());
+// 	S32 bytes = easy->getInput().str().length();
+// 	
+// 	easy->setopt(CURLOPT_POST, 1);
+// 	easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
+// 	easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
+// 
+// 	easy->slist_append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_OCTET_STREAM);
+// 	easy->setHeaders();
+// 
+// 	LL_DEBUGS() << "POSTING: " << bytes << " bytes." << LL_ENDL;
+// 	bool res = addEasy(easy);
+// 	return res;
+// }
+// 
+// // Note: call once per frame
+// S32 LLCurlRequest::process()
+// {
+// 	S32 res = 0;
+// 
+// 	mProcessing = TRUE;
+// 	for (curlmulti_set_t::iterator iter = mMultiSet.begin();
+// 		 iter != mMultiSet.end(); )
+// 	{
+// 		curlmulti_set_t::iterator curiter = iter++;
+// 		LLCurl::Multi* multi = *curiter;
+// 
+// 		if(!multi->isValid())
+// 		{
+// 			if(multi == mActiveMulti)
+// 			{				
+// 				mActiveMulti = NULL ;
+// 				mActiveRequestCount = 0 ;
+// 			}
+// 			mMultiSet.erase(curiter) ;
+// 			LLCurl::getCurlThread()->killMulti(multi) ;
+// 			continue ;
+// 		}
+// 
+// 		S32 tres = multi->process();
+// 		res += tres;
+// 		if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
+// 		{
+// 			mMultiSet.erase(curiter);
+// 			LLCurl::getCurlThread()->killMulti(multi);
+// 		}
+// 	}
+// 	mProcessing = FALSE;
+// 	return res;
+// }
+// 
+// S32 LLCurlRequest::getQueued()
+// {
+// 	S32 queued = 0;
+// 	for (curlmulti_set_t::iterator iter = mMultiSet.begin();
+// 		 iter != mMultiSet.end(); )
+// 	{
+// 		curlmulti_set_t::iterator curiter = iter++;
+// 		LLCurl::Multi* multi = *curiter;
+// 		
+// 		if(!multi->isValid())
+// 		{
+// 			if(multi == mActiveMulti)
+// 			{				
+// 				mActiveMulti = NULL ;
+// 				mActiveRequestCount = 0 ;
+// 			}
+// 			LLCurl::getCurlThread()->killMulti(multi);
+// 			mMultiSet.erase(curiter) ;
+// 			continue ;
+// 		}
+// 
+// 		queued += multi->mQueued;
+// 		if (multi->getState() != LLCurl::Multi::STATE_READY)
+// 		{
+// 			++queued;
+// 		}
+// 	}
+// 	return queued;
+// }
+
+// LLCurlTextureRequest::LLCurlTextureRequest(S32 concurrency) : 
+// 	LLCurlRequest(), 
+// 	mConcurrency(concurrency),
+// 	mInQueue(0),
+// 	mMutex(NULL),
+// 	mHandleCounter(1),
+// 	mTotalIssuedRequests(0),
+// 	mTotalReceivedBits(0)
+// {
+// 	mGlobalTimer.reset();
+// }
+// 
+// LLCurlTextureRequest::~LLCurlTextureRequest()
+// {
+// 	mRequestMap.clear();
+// 
+// 	for(req_queue_t::iterator iter = mCachedRequests.begin(); iter != mCachedRequests.end(); ++iter)
+// 	{
+// 		delete *iter;
+// 	}
+// 	mCachedRequests.clear();
+// }
+// 
+// //return 0: success
+// // > 0: cached handle
+// U32 LLCurlTextureRequest::getByteRange(const std::string& url,
+// 								 const headers_t& headers,
+// 								 S32 offset, S32 length, U32 pri,
+// 								 LLCurl::ResponderPtr responder, F32 delay_time)
+// {
+// 	U32 ret_val = 0;
+// 	bool success = false;	
+// 
+// 	if(mInQueue < mConcurrency && delay_time < 0.f)
+// 	{
+// 		success = LLCurlRequest::getByteRange(url, headers, offset, length, responder);		
+// 	}
+// 
+// 	LLMutexLock lock(&mMutex);
+// 
+// 	if(success)
+// 	{
+// 		mInQueue++;
+// 		mTotalIssuedRequests++;
+// 	}
+// 	else
+// 	{
+// 		request_t* request = new request_t(mHandleCounter, url, headers, offset, length, pri, responder);
+// 		if(delay_time > 0.f)
+// 		{
+// 			request->mStartTime = mGlobalTimer.getElapsedTimeF32() + delay_time;
+// 		}
+// 
+// 		mCachedRequests.insert(request);
+// 		mRequestMap[mHandleCounter] = request;
+// 		ret_val = mHandleCounter;
+// 		mHandleCounter++;
+// 
+// 		if(!mHandleCounter)
+// 		{
+// 			mHandleCounter = 1;
+// 		}
+// 	}
+// 
+// 	return ret_val;
+// }
+// 
+// void LLCurlTextureRequest::completeRequest(S32 received_bytes)
+// {
+// 	LLMutexLock lock(&mMutex);
+// 
+// 	llassert_always(mInQueue > 0);
+// 
+// 	mInQueue--;
+// 	mTotalReceivedBits += received_bytes * 8;
+// }
+// 
+// void LLCurlTextureRequest::nextRequests()
+// {
+// 	if(mCachedRequests.empty() || mInQueue >= mConcurrency)
+// 	{
+// 		return;
+// 	}
+// 
+// 	F32 cur_time = mGlobalTimer.getElapsedTimeF32();
+// 
+// 	req_queue_t::iterator iter;	
+// 	{
+// 		LLMutexLock lock(&mMutex);
+// 		iter = mCachedRequests.begin();
+// 	}
+// 	while(1)
+// 	{
+// 		request_t* request = *iter;
+// 		if(request->mStartTime < cur_time)
+// 		{
+// 			if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder))
+// 			{
+// 				break;
+// 			}
+// 
+// 			LLMutexLock lock(&mMutex);
+// 			++iter;
+// 			mInQueue++;
+// 			mTotalIssuedRequests++;
+// 			mCachedRequests.erase(request);
+// 			mRequestMap.erase(request->mHandle);
+// 			delete request;
+// 
+// 			if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
+// 			{
+// 				break;
+// 			}
+// 		}
+// 		else
+// 		{
+// 			LLMutexLock lock(&mMutex);
+// 			++iter;
+// 			if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
+// 			{
+// 				break;
+// 			}
+// 		}
+// 	}
+// 
+// 	return;
+// }
+// 
+// void LLCurlTextureRequest::updatePriority(U32 handle, U32 pri)
+// {
+// 	if(!handle)
+// 	{
+// 		return;
+// 	}
+// 
+// 	LLMutexLock lock(&mMutex);
+// 
+// 	std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
+// 	if(iter != mRequestMap.end())
+// 	{
+// 		request_t* req = iter->second;
+// 		
+// 		if(req->mPriority != pri)
+// 		{
+// 			mCachedRequests.erase(req);
+// 			req->mPriority = pri;
+// 			mCachedRequests.insert(req);
+// 		}
+// 	}
+// }
+// 
+// void LLCurlTextureRequest::removeRequest(U32 handle)
+// {
+// 	if(!handle)
+// 	{
+// 		return;
+// 	}
+// 
+// 	LLMutexLock lock(&mMutex);
+// 
+// 	std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
+// 	if(iter != mRequestMap.end())
+// 	{
+// 		request_t* req = iter->second;
+// 		mRequestMap.erase(iter);
+// 		mCachedRequests.erase(req);
+// 		delete req;
+// 	}
+// }
+// 
+// bool LLCurlTextureRequest::isWaiting(U32 handle)
+// {
+// 	if(!handle)
+// 	{
+// 		return false;
+// 	}
+// 
+// 	LLMutexLock lock(&mMutex);
+// 	return mRequestMap.find(handle) != mRequestMap.end();
+// }
+// 
+// U32 LLCurlTextureRequest::getTotalReceivedBits()
+// {
+// 	LLMutexLock lock(&mMutex);
+// 
+// 	U32 bits = mTotalReceivedBits;
+// 	mTotalReceivedBits = 0;
+// 	return bits;
+// }
+// 
+// U32 LLCurlTextureRequest::getTotalIssuedRequests()
+// {
+// 	LLMutexLock lock(&mMutex);
+// 	return mTotalIssuedRequests;
+// }
+// 
+// S32 LLCurlTextureRequest::getNumRequests()
+// {
+// 	LLMutexLock lock(&mMutex);
+// 	return mInQueue;
+// }
 
 ////////////////////////////////////////////////////////////////////////////
 // For generating one easy request
@@ -1988,10 +1992,10 @@ void LLCurlFF::check_easy_code(CURLcode code)
 {
 	check_curl_code(code);
 }
-void LLCurlFF::check_multi_code(CURLMcode code)
-{
-	check_curl_multi_code(code);
-}
+// void LLCurlFF::check_multi_code(CURLMcode code)
+// {
+// 	check_curl_multi_code(code);
+// }
 
 
 // Static
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 385d9fffa8990beb1f07dad83e994eb2ccd53b7d..06b3ce45e1479e1b3c9a2152e6129f0c534f06c1 100755
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -418,100 +418,6 @@ class LLCurlThread : public LLQueuedThread
 } ;
 
 
-class LLCurlRequest
-{
-public:
-	typedef std::vector<std::string> headers_t;
-	
-	LLCurlRequest();
-	~LLCurlRequest();
-
-	void get(const std::string& url, LLCurl::ResponderPtr responder);
-	bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder);
-	bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder, S32 time_out = 0);
-	bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder, S32 time_out = 0);
-	
-	S32  process();
-	S32  getQueued();
-
-private:
-	void addMulti();
-	LLCurl::Easy* allocEasy();
-	bool addEasy(LLCurl::Easy* easy);
-	
-private:
-	typedef std::set<LLCurl::Multi*> curlmulti_set_t;
-	curlmulti_set_t mMultiSet;
-	LLCurl::Multi* mActiveMulti;
-	S32 mActiveRequestCount;
-	BOOL mProcessing;
-};
-
-//for texture fetch only
-class LLCurlTextureRequest : public LLCurlRequest
-{
-public:
-	LLCurlTextureRequest(S32 concurrency);
-	~LLCurlTextureRequest();
-
-	U32 getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder, F32 delay_time = -1.f);
-	void nextRequests();
-	void completeRequest(S32 received_bytes);
-
-	void updatePriority(U32 handle, U32 pri);
-	void removeRequest(U32 handle);
-
-	U32 getTotalReceivedBits();
-	U32 getTotalIssuedRequests();
-	S32 getNumRequests();
-	bool isWaiting(U32 handle);
-	
-private:
-	LLMutex mMutex;
-	S32 mConcurrency;
-	S32 mInQueue; //request currently in queue.
-	U32 mHandleCounter;
-	U32 mTotalIssuedRequests;
-	U32 mTotalReceivedBits;
-
-	typedef struct _request_t
-	{
-		_request_t(U32 handle, const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder) :
-				mHandle(handle), mUrl(url), mHeaders(headers), mOffset(offset), mLength(length), mPriority(pri), mResponder(responder), mStartTime(0.f)
-				{}
-
-		U32  mHandle;
-		std::string mUrl;
-		LLCurlRequest::headers_t mHeaders;
-		S32 mOffset;
-		S32 mLength;
-		LLCurl::ResponderPtr mResponder;
-		U32 mPriority;
-		F32 mStartTime; //start time to issue this request
-	} request_t;
-
-	struct request_compare
-	{
-		bool operator()(const request_t* lhs, const request_t* rhs) const
-		{
-			if(lhs->mPriority != rhs->mPriority)
-			{
-				return lhs->mPriority > rhs->mPriority; // higher priority in front of queue (set)
-			}
-			else
-			{
-				return (U32)lhs < (U32)rhs;
-			}
-		}
-	};
-
-	typedef std::set<request_t*, request_compare> req_queue_t;
-	req_queue_t mCachedRequests;
-	std::map<S32, request_t*> mRequestMap;
-
-	LLFrameTimer mGlobalTimer;
-};
-
 class LLCurlEasyRequest
 {
 public:
@@ -550,7 +456,7 @@ class LLCurlEasyRequest
 namespace LLCurlFF
 {
 	void check_easy_code(CURLcode code);
-	void check_multi_code(CURLMcode code);
+	//void check_multi_code(CURLMcode code);
 }
 
 #endif // LL_LLCURL_H
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index f8db3dded2b711bec718a639f0d5c6beedfa0791..7f70e6a3f51dec7931b70c137cf810ec3eca8637 100755
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -38,6 +38,10 @@
 #include "lluri.h"
 
 #include "message.h"
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httpoptions.h"
+
 #include <curl/curl.h>
 
 
diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp
deleted file mode 100755
index b56a804f9422ad5a475d2fbd051a6c801e36dc0d..0000000000000000000000000000000000000000
--- a/indra/llmessage/llhttpclientadapter.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/** 
- * @file llhttpclientadapter.cpp
- * @brief 
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llhttpclientadapter.h"
-#include "llhttpclient.h"
-
-LLHTTPClientAdapter::~LLHTTPClientAdapter() 
-{
-}
-
-void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder) 
-{
-	LLSD empty_pragma_header;
-	// Pragma is required to stop curl adding "no-cache"
-	// Space is required to stop llurlrequest from turning off proxying
-	empty_pragma_header[HTTP_OUT_HEADER_PRAGMA] = " "; 
-	LLHTTPClient::get(url, responder, empty_pragma_header);
-}
-
-void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) 
-{
-	LLSD empty_pragma_header = headers;
-	if (!empty_pragma_header.has(HTTP_OUT_HEADER_PRAGMA))
-	{
-		// as above
-		empty_pragma_header[HTTP_OUT_HEADER_PRAGMA] = " ";
-	}
-	LLHTTPClient::get(url, responder, empty_pragma_header);
-}
-
-void LLHTTPClientAdapter::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) 
-{
-	LLHTTPClient::put(url, body, responder);
-}
-
-void LLHTTPClientAdapter::put(
-		const std::string& url,
-		const LLSD& body,
-		LLCurl::ResponderPtr responder,
-		const LLSD& headers)
-{
-	LLHTTPClient::put(url, body, responder, headers);
-}
-
-void LLHTTPClientAdapter::del(
-	const std::string& url,
-	LLCurl::ResponderPtr responder)
-{
-	LLHTTPClient::del(url, responder);
-}
diff --git a/indra/llmessage/llhttpclientadapter.h b/indra/llmessage/llhttpclientadapter.h
deleted file mode 100755
index 270282c66fb43ed6ee2a516d7572e744e226e6ed..0000000000000000000000000000000000000000
--- a/indra/llmessage/llhttpclientadapter.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/** 
- * @file llhttpclientadepter.h
- * @brief 
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_HTTPCLIENTADAPTER_H
-#define LL_HTTPCLIENTADAPTER_H
-
-#include "llhttpclientinterface.h"
-#include "llsingleton.h"	// LLSingleton<>
-
-class LLHTTPClientAdapter : public LLHTTPClientInterface, public LLSingleton<LLHTTPClientAdapter>
-{
-public:
-	virtual ~LLHTTPClientAdapter();
-	virtual void get(const std::string& url, LLCurl::ResponderPtr responder);
-	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers);
-	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder);
-	virtual void put(
-		const std::string& url,
-		const LLSD& body,
-		LLCurl::ResponderPtr responder,
-		const LLSD& headers);
-	virtual void del(
-		const std::string& url,
-		LLCurl::ResponderPtr responder);
-};
-
-#endif
-
diff --git a/indra/llmessage/llhttpclientinterface.h b/indra/llmessage/llhttpclientinterface.h
index 12a3857a61d4fa2bbec60779384a092a815dd1ac..9c1c8e7c113ca10abf68c6541c07067ec34a6d8c 100755
--- a/indra/llmessage/llhttpclientinterface.h
+++ b/indra/llmessage/llhttpclientinterface.h
@@ -32,14 +32,14 @@
 
 #include <string>
 
-class LLHTTPClientInterface
-{
-public:
-	virtual ~LLHTTPClientInterface() {}
-	virtual void get(const std::string& url, LLCurl::ResponderPtr responder) = 0;
-	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) = 0;
-	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) = 0;
-};
+// class LLHTTPClientInterface
+// {
+// public:
+// 	virtual ~LLHTTPClientInterface() {}
+// 	virtual void get(const std::string& url, LLCurl::ResponderPtr responder) = 0;
+// 	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) = 0;
+// 	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) = 0;
+// };
 
 #endif // LL_LLHTTPCLIENTINTERFACE_H
 
diff --git a/indra/llmessage/llhttpsdhandler.cpp b/indra/llmessage/llhttpsdhandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d99bdd3f667b4921d1a4e6b248cee3fb3d85101a
--- /dev/null
+++ b/indra/llmessage/llhttpsdhandler.cpp
@@ -0,0 +1,105 @@
+/**
+* @file llhttpsdhandler.h
+* @brief Public-facing declarations for the HttpHandler class
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "linden_common.h"
+#include "llhttpconstants.h"
+
+#include "llhttpsdhandler.h"
+#include "httpresponse.h"
+#include "httpheaders.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "bufferstream.h"
+#include "llcorehttputil.h"
+
+//========================================================================
+LLHttpSDHandler::LLHttpSDHandler(bool selfDelete):
+    mSelfDelete(selfDelete)
+{
+}
+
+void LLHttpSDHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+{
+	LLCore::HttpStatus status = response->getStatus();
+
+	if (!status)
+	{
+		this->onFailure(response, status);
+	}
+	else
+	{
+		LLSD resplsd;
+		const bool emit_parse_errors = false;
+
+		bool parsed = !((response->getBodySize() == 0) ||
+			!LLCoreHttpUtil::responseToLLSD(response, emit_parse_errors, resplsd));
+
+		if (!parsed) 
+		{
+			// Only emit a warning if we failed to parse when 'content-type' == 'application/llsd+xml'
+			LLCore::HttpHeaders::ptr_t headers(response->getHeaders());
+			const std::string *contentType = (headers) ? headers->find(HTTP_IN_HEADER_CONTENT_TYPE) : NULL;
+
+			if (contentType && (HTTP_CONTENT_LLSD_XML == *contentType))
+			{
+				std::string thebody = LLCoreHttpUtil::responseToString(response);
+
+				LL_WARNS() << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] "
+					<< " body: " << thebody << LL_ENDL;
+			}
+		}
+
+		this->onSuccess(response, resplsd);
+	}
+
+	// The handler must destroy itself when it is done. 
+	// *TODO: I'm not fond of this pattern. A class shooting itself in the head 
+	// outside of a smart pointer always makes me nervous.
+    if (mSelfDelete)
+    	delete this;
+}
+
+//========================================================================
+LLHttpSDGenericHandler::LLHttpSDGenericHandler(const std::string &name, bool selfDelete):
+	LLHttpSDHandler(selfDelete),
+	mName(name)
+{
+}
+
+void LLHttpSDGenericHandler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
+{
+	LL_DEBUGS() << mName << " Success." << LL_ENDL;
+}
+
+void LLHttpSDGenericHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
+{
+	LL_WARNS()
+		<< "\n--------------------------------------------------------------------------\n"
+		<< mName << " Error[" << status.toULong() << "] cannot access cap with url '" 
+		<< response->getRequestURL() << "' because " << status.toString()
+		<< "\n--------------------------------------------------------------------------"
+		<< LL_ENDL;
+}
diff --git a/indra/llmessage/llhttpsdhandler.h b/indra/llmessage/llhttpsdhandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..3b81dc66b9652ac995b61f2ced604c72639eb77f
--- /dev/null
+++ b/indra/llmessage/llhttpsdhandler.h
@@ -0,0 +1,72 @@
+/**
+* @file llhttpsdhandler.h
+* @brief Public-facing declarations for the HttpHandler class
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef	_LLHTTPSDHANDLER_H_
+#define	_LLHTTPSDHANDLER_H_
+#include "httpcommon.h"
+#include "httphandler.h"
+#include "lluri.h"
+
+/// Handler class LLCore's HTTP library. Splitting with separate success and 
+/// failure routines and parsing the result body into LLSD on success.  It 
+/// is intended to be subclassed for specific capability handling.
+/// 
+// *TODO: This class self deletes at the end of onCompleted method.  This is 
+// less than ideal and should be revisited.
+class LLHttpSDHandler : public LLCore::HttpHandler //,
+//    public std::enable_shared_from_this<LLHttpSDHandler>
+{
+public:
+
+	virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+	
+protected:
+    LLHttpSDHandler(bool selfDelete = true);
+
+	virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content) = 0;
+	virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status) = 0;
+
+private:
+    bool mSelfDelete;
+
+};
+
+/// A trivial implementation of LLHttpSDHandler. This success and failure 
+/// methods log the action taken, the URI accessed and the status code returned 
+/// in the response.
+class LLHttpSDGenericHandler : public LLHttpSDHandler
+{
+public: 
+	LLHttpSDGenericHandler(const std::string &name, bool selfDelete = true);
+
+protected:
+	virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
+	virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
+
+private:
+	std::string mName;
+};
+#endif
diff --git a/indra/llmessage/llsdmessage.cpp b/indra/llmessage/llsdmessage.cpp
deleted file mode 100755
index 61fcc5dd2f1791bc5816e7ece4a7104bfd47f2b1..0000000000000000000000000000000000000000
--- a/indra/llmessage/llsdmessage.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * @file   llsdmessage.cpp
- * @author Nat Goodspeed
- * @date   2008-10-31
- * @brief  Implementation for llsdmessage.
- * 
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#if LL_WINDOWS
-#pragma warning (disable : 4675) // "resolved by ADL" -- just as I want!
-#endif
-
-// Precompiled header
-#include "linden_common.h"
-// associated header
-#include "llsdmessage.h"
-// STL headers
-// std headers
-// external library headers
-// other Linden headers
-#include "llevents.h"
-#include "llsdserialize.h"
-#include "llhttpclient.h"
-#include "llmessageconfig.h"
-#include "llhost.h"
-#include "message.h"
-#include "llsdutil.h"
-
-// Declare a static LLSDMessage instance to ensure that we have a listener as
-// soon as someone tries to post on our canonical LLEventPump name.
-static LLSDMessage httpListener;
-
-LLSDMessage::LLSDMessage():
-    // Instantiating our own local LLEventPump with a string name the
-    // constructor is NOT allowed to tweak is a way of ensuring Singleton
-    // semantics: attempting to instantiate a second LLSDMessage object would
-    // throw LLEventPump::DupPumpName.
-    mEventPump("LLHTTPClient")
-{
-    mEventPump.listen("self", boost::bind(&LLSDMessage::httpListener, this, _1));
-}
-
-bool LLSDMessage::httpListener(const LLSD& request)
-{
-    // Extract what we want from the request object. We do it all up front
-    // partly to document what we expect.
-    LLSD::String url(request["url"]);
-    LLSD payload(request["payload"]);
-    LLSD::String reply(request["reply"]);
-    LLSD::String error(request["error"]);
-    LLSD::Real timeout(request["timeout"]);
-    // If the LLSD doesn't even have a "url" key, we doubt it was intended for
-    // this listener.
-    if (url.empty())
-    {
-        std::ostringstream out;
-        out << "request event without 'url' key to '" << mEventPump.getName() << "'";
-        throw ArgError(out.str());
-    }
-    // Establish default timeout. This test relies on LLSD::asReal() returning
-    // exactly 0.0 for an undef value.
-    if (! timeout)
-    {
-        timeout = HTTP_REQUEST_EXPIRY_SECS;
-    }
-    LLHTTPClient::post(url, payload,
-                       new LLSDMessage::EventResponder(LLEventPumps::instance(),
-                                                       request,
-                                                       url, "POST", reply, error),
-                       LLSD(),      // headers
-                       (F32)timeout);
-    return false;
-}
-
-void LLSDMessage::EventResponder::httpSuccess()
-{
-    // If our caller passed an empty replyPump name, they're not
-    // listening: this is a fire-and-forget message. Don't bother posting
-    // to the pump whose name is "".
-    if (! mReplyPump.empty())
-    {
-        LLSD response(getContent());
-        mReqID.stamp(response);
-        mPumps.obtain(mReplyPump).post(response);
-    }
-    else                            // default success handling
-    {
-        LL_INFOS("LLSDMessage::EventResponder")
-            << "'" << mMessage << "' to '" << mTarget << "' succeeded"
-            << LL_ENDL;
-    }
-}
-
-void LLSDMessage::EventResponder::httpFailure()
-{
-    // If our caller passed an empty errorPump name, they're not
-    // listening: "default error handling is acceptable." Only post to an
-    // explicit pump name.
-    if (! mErrorPump.empty())
-    {
-        LLSD info(mReqID.makeResponse());
-        info["target"]  = mTarget;
-        info["message"] = mMessage;
-        info["status"]  = getStatus();
-        info["reason"]  = getReason();
-        info["content"] = getContent();
-        mPumps.obtain(mErrorPump).post(info);
-    }
-    else                        // default error handling
-    {
-        // convention seems to be to use LL_INFOS(), but that seems a bit casual?
-        LL_WARNS("LLSDMessage::EventResponder")
-            << "'" << mMessage << "' to '" << mTarget
-            << "' failed " << dumpResponse() << LL_ENDL;
-    }
-}
-
-LLSDMessage::ResponderAdapter::ResponderAdapter(LLHTTPClient::ResponderPtr responder,
-                                                const std::string& name):
-    mResponder(responder),
-    mReplyPump(name + ".reply", true), // tweak name for uniqueness
-    mErrorPump(name + ".error", true)
-{
-    mReplyPump.listen("self", boost::bind(&ResponderAdapter::listener, this, _1, true));
-    mErrorPump.listen("self", boost::bind(&ResponderAdapter::listener, this, _1, false));
-}
-
-bool LLSDMessage::ResponderAdapter::listener(const LLSD& payload, bool success)
-{
-    if (success)
-    {
-        mResponder->successResult(payload);
-    }
-    else
-    {
-        mResponder->failureResult(payload["status"].asInteger(), payload["reason"], payload["content"]);
-    }
-
-    /*---------------- MUST BE LAST STATEMENT BEFORE RETURN ----------------*/
-    delete this;
-    // Destruction of mResponder will usually implicitly free its referent as well
-    /*------------------------- NOTHING AFTER THIS -------------------------*/
-    return false;
-}
-
-void LLSDMessage::link()
-{
-}
diff --git a/indra/llmessage/llsdmessage.h b/indra/llmessage/llsdmessage.h
deleted file mode 100755
index e5d532d6a42c100823a36bd36d617e9e01f894f0..0000000000000000000000000000000000000000
--- a/indra/llmessage/llsdmessage.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * @file   llsdmessage.h
- * @author Nat Goodspeed
- * @date   2008-10-30
- * @brief  API intended to unify sending capability, UDP and TCP messages:
- *         https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes
- * 
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#if ! defined(LL_LLSDMESSAGE_H)
-#define LL_LLSDMESSAGE_H
-
-#include "llerror.h"                // LOG_CLASS()
-#include "llevents.h"               // LLEventPumps
-#include "llhttpclient.h"
-#include <string>
-#include <stdexcept>
-
-class LLSD;
-
-/**
- * Class managing the messaging API described in
- * https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes
- */
-class LLSDMessage
-{
-    LOG_CLASS(LLSDMessage);
-
-public:
-    LLSDMessage();
-
-    /// Exception if you specify arguments badly
-    struct ArgError: public std::runtime_error
-    {
-        ArgError(const std::string& what):
-            std::runtime_error(std::string("ArgError: ") + what) {}
-    };
-
-    /**
-     * The response idiom used by LLSDMessage -- LLEventPump names on which to
-     * post reply or error -- is designed for the case in which your
-     * reply/error handlers are methods on the same class as the method
-     * sending the message. Any state available to the sending method that
-     * must be visible to the reply/error methods can conveniently be stored
-     * on that class itself, if it's not already.
-     *
-     * The LLHTTPClient::Responder idiom requires a separate instance of a
-     * separate class so that it can dispatch to the code of interest by
-     * calling canonical virtual methods. Interesting state must be copied
-     * into that new object. 
-     *
-     * With some trepidation, because existing response code is packaged in
-     * LLHTTPClient::Responder subclasses, we provide this adapter class
-     * <i>for transitional purposes only.</i> Instantiate a new heap
-     * ResponderAdapter with your new LLHTTPClient::ResponderPtr. Pass
-     * ResponderAdapter::getReplyName() and/or getErrorName() in your
-     * LLSDMessage (or LLViewerRegion::getCapAPI()) request event. The
-     * ResponderAdapter will call the appropriate Responder method, then
-     * @c delete itself.
-     */
-    class ResponderAdapter
-    {
-    public:
-        /**
-         * Bind the new LLHTTPClient::Responder subclass instance.
-         *
-         * Passing the constructor a name other than the default is only
-         * interesting if you suspect some usage will lead to an exception or
-         * log message.
-         */
-        ResponderAdapter(LLHTTPClient::ResponderPtr responder,
-                         const std::string& name="ResponderAdapter");
-
-        /// EventPump name on which LLSDMessage should post reply event
-        std::string getReplyName() const { return mReplyPump.getName(); }
-        /// EventPump name on which LLSDMessage should post error event
-        std::string getErrorName() const { return mErrorPump.getName(); }
-
-    private:
-        // We have two different LLEventStreams, though we route them both to
-        // the same listener, so that we can bind an extra flag identifying
-        // which case (reply or error) reached that listener.
-        bool listener(const LLSD&, bool success);
-
-        LLHTTPClient::ResponderPtr mResponder;
-        LLEventStream mReplyPump, mErrorPump;
-    };
-
-    /**
-     * Force our implementation file to be linked with caller. The .cpp file
-     * contains a static instance of this class, which must be linked into the
-     * executable to support the canonical listener. But since the primary
-     * interface to that static instance is via a named LLEventPump rather
-     * than by direct reference, the linker doesn't necessarily perceive the
-     * necessity to bring in the translation unit. Referencing this dummy
-     * method forces the issue.
-     */
-    static void link();
-
-private:
-    friend class LLCapabilityListener;
-    /// Responder used for internal purposes by LLSDMessage and
-    /// LLCapabilityListener. Others should use higher-level APIs.
-    class EventResponder: public LLHTTPClient::Responder
-    {
-        LOG_CLASS(EventResponder);
-    public:
-        /**
-         * LLHTTPClient::Responder that dispatches via named LLEventPump instances.
-         * We bind LLEventPumps, even though it's an LLSingleton, for testability.
-         * We bind the string names of the desired LLEventPump instances rather
-         * than actually obtain()ing them so we only obtain() the one we're going
-         * to use. If the caller doesn't bother to listen() on it, the other pump
-         * may never materialize at all.
-         * @a target and @a message are only to clarify error processing.
-         * For a capability message, @a target should be the region description,
-         * @a message should be the capability name.
-         * For a service with a visible URL, pass the URL as @a target and the HTTP verb
-         * (e.g. "POST") as @a message.
-         */
-        EventResponder(LLEventPumps& pumps,
-                       const LLSD& request,
-                       const std::string& target, const std::string& message,
-                       const std::string& replyPump, const std::string& errorPump):
-            mPumps(pumps),
-            mReqID(request),
-            mTarget(target),
-            mMessage(message),
-            mReplyPump(replyPump),
-            mErrorPump(errorPump)
-        {}
-    
-    protected:
-        virtual void httpSuccess();
-        virtual void httpFailure();
-    
-    private:
-        LLEventPumps& mPumps;
-        LLReqID mReqID;
-        const std::string mTarget, mMessage, mReplyPump, mErrorPump;
-    };
-
-private:
-    bool httpListener(const LLSD&);
-    LLEventStream mEventPump;
-};
-
-#endif /* ! defined(LL_LLSDMESSAGE_H) */
diff --git a/indra/llmessage/llsdrpcclient.h b/indra/llmessage/llsdrpcclient.h
index c4e0333ca3250f6ca733a24c7cb0b5ed561b6bdf..d097ecdff718d6b7bed1bf97a1fb2a1d473fd9e8 100755
--- a/indra/llmessage/llsdrpcclient.h
+++ b/indra/llmessage/llsdrpcclient.h
@@ -37,7 +37,9 @@
 #include "llchainio.h"
 #include "llfiltersd2xmlrpc.h"
 #include "lliopipe.h"
-#include "llurlrequest.h"
+#if 0
+//#include "llurlrequest.h"
+#endif
 
 /** 
  * @class LLSDRPCClientResponse
@@ -218,6 +220,7 @@ class LLSDRPCClient : public LLIOPipe
 	LLIOPipe::ptr_t mResponse;
 };
 
+#if 0
 /** 
  * @class LLSDRPCClientFactory
  * @brief Basic implementation for making an SD RPC client factory
@@ -267,7 +270,9 @@ class LLSDRPCClientFactory : public LLChainIOFactory
 protected:
 	std::string mURL;
 };
+#endif
 
+#if 0
 /** 
  * @class LLXMLSDRPCClientFactory
  * @brief Basic implementation for making an XMLRPC to SD RPC client factory
@@ -319,5 +324,6 @@ class LLXMLSDRPCClientFactory : public LLChainIOFactory
 protected:
 	std::string mURL;
 };
+#endif
 
 #endif // LL_LLSDRPCCLIENT_H
diff --git a/indra/llmessage/tests/llhttpclientadapter_test.cpp b/indra/llmessage/tests/llhttpclientadapter_test.cpp
deleted file mode 100755
index e9ce116bb38cb2053ea266a26fbdfb30f34ff92f..0000000000000000000000000000000000000000
--- a/indra/llmessage/tests/llhttpclientadapter_test.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-/** 
- * @file llhttpclientadapter_test.cpp
- * @brief Tests for LLHTTPClientAdapter
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llhttpclientadapter.h"
-
-#include "../test/lltut.h"
-#include "llhttpclient.h"
-#include "llcurl_stub.cpp"
-
-float const HTTP_REQUEST_EXPIRY_SECS = 1.0F;
-
-std::vector<std::string> get_urls;
-std::vector< LLCurl::ResponderPtr > get_responders;
-void LLHTTPClient::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers, const F32 timeout, bool follow_redirects)
-{
-	get_urls.push_back(url);
-	get_responders.push_back(responder);
-}
-
-std::vector<std::string> put_urls;
-std::vector<LLSD> put_body;
-std::vector<LLSD> put_headers;
-std::vector<LLCurl::ResponderPtr> put_responders;
-
-void LLHTTPClient::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder, const LLSD& headers, const F32 timeout)
-{
-	put_urls.push_back(url);
-	put_responders.push_back(responder);
-	put_body.push_back(body);
-	put_headers.push_back(headers);
-
-}
-
-std::vector<std::string> delete_urls;
-std::vector<LLCurl::ResponderPtr> delete_responders;
-
-void LLHTTPClient::del(
-	const std::string& url,
-	LLCurl::ResponderPtr responder,
-	const LLSD& headers,
-	const F32 timeout)
-{
-	delete_urls.push_back(url);
-	delete_responders.push_back(responder);
-}
-
-namespace tut
-{
-	struct LLHTTPClientAdapterData
-	{
-		LLHTTPClientAdapterData()
-		{
-			get_urls.clear();
-			get_responders.clear();
-			put_urls.clear();
-			put_responders.clear();
-			put_body.clear();
-			put_headers.clear();
-			delete_urls.clear();
-			delete_responders.clear();
-		}
-	};
-
-	typedef test_group<LLHTTPClientAdapterData> factory;
-	typedef factory::object object;
-}
-
-namespace
-{
-	tut::factory tf("LLHTTPClientAdapterData");
-}
-
-namespace tut
-{
-	// Ensure we can create the object
-	template<> template<>
-	void object::test<1>()
-	{
-		LLHTTPClientAdapter adapter;
-	}
-
-	// Does the get pass the appropriate arguments to the LLHTTPClient
-	template<> template<>
-	void object::test<2>()
-	{
-		LLHTTPClientAdapter adapter;
-
-		LLCurl::ResponderPtr responder = new LLCurl::Responder();
-
-		adapter.get("Made up URL", responder);
-		ensure_equals(get_urls.size(), 1);
-		ensure_equals(get_urls[0], "Made up URL");
-	}
-
-	// Ensure the responder matches the one passed to get
-	template<> template<>
-	void object::test<3>()
-	{
-		LLHTTPClientAdapter adapter;
-		LLCurl::ResponderPtr responder = new LLCurl::Responder();
-
-		adapter.get("Made up URL", responder);
-
-		ensure_equals(get_responders.size(), 1);
-		ensure_equals(get_responders[0].get(), responder.get());
-	}
-	
-	// Ensure the correct url is used in the put
-	template<> template<>
-	void object::test<4>()
-	{
-		LLHTTPClientAdapter adapter;
-
-		LLCurl::ResponderPtr responder = new LLCurl::Responder();
-
-		LLSD body;
-		body["TestBody"] = "Foobar";
-
-		adapter.put("Made up URL", body, responder);
-		ensure_equals(put_urls.size(), 1);
-		ensure_equals(put_urls[0], "Made up URL");
-	}
-
-	// Ensure the correct responder is used by put
-	template<> template<>
-	void object::test<5>()
-	{
-		LLHTTPClientAdapter adapter;
-
-		LLCurl::ResponderPtr responder = new LLCurl::Responder();
-
-		LLSD body;
-		body["TestBody"] = "Foobar";
-
-		adapter.put("Made up URL", body, responder);
-
-		ensure_equals(put_responders.size(), 1);
-		ensure_equals(put_responders[0].get(), responder.get());
-	}
-
-	// Ensure the message body is passed through the put properly
-	template<> template<>
-	void object::test<6>()
-	{
-		LLHTTPClientAdapter adapter;
-
-		LLCurl::ResponderPtr responder = new LLCurl::Responder();
-
-		LLSD body;
-		body["TestBody"] = "Foobar";
-
-		adapter.put("Made up URL", body, responder);
-
-		ensure_equals(put_body.size(), 1);
-		ensure_equals(put_body[0]["TestBody"].asString(), "Foobar");
-	}
-
-	// Ensure that headers are passed through put properly
-	template<> template<>
-	void object::test<7>()
-	{
-		LLHTTPClientAdapter adapter;
-
-		LLCurl::ResponderPtr responder = new LLCurl::Responder();
-
-		LLSD body = LLSD::emptyMap();
-		body["TestBody"] = "Foobar";
-
-		LLSD headers = LLSD::emptyMap();
-		headers["booger"] = "omg";
-
-		adapter.put("Made up URL", body, responder, headers);
-
-		ensure_equals("Header count", put_headers.size(), 1);
-		ensure_equals(
-			"First header",
-			put_headers[0]["booger"].asString(),
-			"omg");
-	}
-
-	// Ensure that del() passes appropriate arguments to the LLHTTPClient
-	template<> template<>
-	void object::test<8>()
-	{
-		LLHTTPClientAdapter adapter;
-
-		LLCurl::ResponderPtr responder = new LLCurl::Responder();
-
-		adapter.del("Made up URL", responder);
-
-		ensure_equals("URL count", delete_urls.size(), 1);
-		ensure_equals("Received URL", delete_urls[0], "Made up URL");
-
-		ensure_equals("Responder count", delete_responders.size(), 1);
-		//ensure_equals("Responder", delete_responders[0], responder);
-	}
-}
-
diff --git a/indra/llmessage/tests/llsdmessage_test.cpp b/indra/llmessage/tests/llsdmessage_test.cpp
deleted file mode 100755
index 44b024a83f28fe994e1d161f04a2e3e648dcd6dd..0000000000000000000000000000000000000000
--- a/indra/llmessage/tests/llsdmessage_test.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * @file   llsdmessage_test.cpp
- * @author Nat Goodspeed
- * @date   2008-12-22
- * @brief  Test of llsdmessage.h
- * 
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#if LL_WINDOWS
-#pragma warning (disable : 4675) // "resolved by ADL" -- just as I want!
-#endif
-
-// Precompiled header
-#include "linden_common.h"
-// associated header
-#include "llsdmessage.h"
-// STL headers
-#include <iostream>
-// std headers
-#include <stdexcept>
-#include <typeinfo>
-// external library headers
-// other Linden headers
-#include "../test/lltut.h"
-#include "../test/catch_and_store_what_in.h"
-#include "llsdserialize.h"
-#include "llevents.h"
-#include "stringize.h"
-#include "llhost.h"
-#include "tests/networkio.h"
-#include "tests/commtest.h"
-
-/*****************************************************************************
-*   TUT
-*****************************************************************************/
-namespace tut
-{
-    struct llsdmessage_data: public commtest_data
-    {
-        LLEventPump& httpPump;
-
-        llsdmessage_data():
-            httpPump(pumps.obtain("LLHTTPClient"))
-        {
-            LLCurl::initClass();
-            LLSDMessage::link();
-        }
-    };
-    typedef test_group<llsdmessage_data> llsdmessage_group;
-    typedef llsdmessage_group::object llsdmessage_object;
-    llsdmessage_group llsdmgr("llsdmessage");
-
-    template<> template<>
-    void llsdmessage_object::test<1>()
-    {
-        std::string threw;
-        // This should fail...
-        try
-        {
-            LLSDMessage localListener;
-        }
-        CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupPumpName)
-        ensure("second LLSDMessage should throw", ! threw.empty());
-    }
-
-    template<> template<>
-    void llsdmessage_object::test<2>()
-    {
-        LLSD request, body;
-        body["data"] = "yes";
-        request["payload"] = body;
-        request["reply"] = replyPump.getName();
-        request["error"] = errorPump.getName();
-        bool threw = false;
-        try
-        {
-            httpPump.post(request);
-        }
-        catch (const LLSDMessage::ArgError&)
-        {
-            threw = true;
-        }
-        ensure("missing URL", threw);
-    }
-
-    template<> template<>
-    void llsdmessage_object::test<3>()
-    {
-        LLSD request, body;
-        body["data"] = "yes";
-        request["url"] = server + "got-message";
-        request["payload"] = body;
-        request["reply"] = replyPump.getName();
-        request["error"] = errorPump.getName();
-        httpPump.post(request);
-        ensure("got response", netio.pump());
-        ensure("success response", success);
-        ensure_equals(result["reply"].asString(), "success");
-
-        body["status"] = 499;
-        body["reason"] = "custom error message";
-        request["url"] = server + "fail";
-        request["payload"] = body;
-        httpPump.post(request);
-        ensure("got response", netio.pump());
-        ensure("failure response", ! success);
-        ensure_equals(result["status"].asInteger(), body["status"].asInteger());
-        ensure_equals(result["reason"].asString(),  body["reason"].asString());
-    }
-} // namespace tut
diff --git a/indra/llmessage/tests/lltesthttpclientadapter.cpp b/indra/llmessage/tests/lltesthttpclientadapter.cpp
deleted file mode 100755
index 4539e4a540cfd7a76a374d336493819e222ca2cd..0000000000000000000000000000000000000000
--- a/indra/llmessage/tests/lltesthttpclientadapter.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/** 
- * @file 
- * @brief 
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-#include "lltesthttpclientadapter.h"
-
-LLTestHTTPClientAdapter::LLTestHTTPClientAdapter()
-{
-}
-
-LLTestHTTPClientAdapter::~LLTestHTTPClientAdapter()
-{
-}
-
-void LLTestHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder)
-{
-	mGetUrl.push_back(url);
-	mGetResponder.push_back(responder);
-}
-
-void LLTestHTTPClientAdapter::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder)
-{
-	mPutUrl.push_back(url);
-	mPutBody.push_back(body);
-	mPutResponder.push_back(responder);
-}
-
-U32 LLTestHTTPClientAdapter::putCalls() const 
-{ 
-	return mPutUrl.size(); 
-}
-
-void LLTestHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers)
-{
-	mGetUrl.push_back(url);
-	mGetHeaders.push_back(headers);
-	mGetResponder.push_back(responder);
-}
-
-
diff --git a/indra/llmessage/tests/lltesthttpclientadapter.h b/indra/llmessage/tests/lltesthttpclientadapter.h
deleted file mode 100755
index c29cbb3a2a99648d6d82b5cd22f5c321b796e63a..0000000000000000000000000000000000000000
--- a/indra/llmessage/tests/lltesthttpclientadapter.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/** 
- * @file 
- * @brief 
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-/* Macro Definitions */
-#ifndef LL_LLTESTHTTPCLIENTADAPTER_H
-#define LL_LLTESTHTTPCLIENTADAPTER_H
-
-
-#include "linden_common.h"
-#include "llhttpclientinterface.h"
-
-class LLTestHTTPClientAdapter : public LLHTTPClientInterface
-{
-public:
-	LLTestHTTPClientAdapter();
-	virtual ~LLTestHTTPClientAdapter();
-	virtual void get(const std::string& url, LLCurl::ResponderPtr responder);
-	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers);
-
-	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder);
-	U32 putCalls() const;
-
-	std::vector<LLSD> mPutBody;
-	std::vector<LLSD> mGetHeaders;
-	std::vector<std::string> mPutUrl;
-	std::vector<std::string> mGetUrl;
-	std::vector<LLCurl::ResponderPtr> mPutResponder;
-	std::vector<LLCurl::ResponderPtr> mGetResponder;
-};
-
-
-
-#endif //LL_LLSIMULATORPRESENCESENDER_H
-
diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt
index c59645bd70e45b7d3d9a5fdbcbea3de6a7727821..ab2038826101bf3e1bb1f1fce3fbe9267e711c8e 100755
--- a/indra/mac_crash_logger/CMakeLists.txt
+++ b/indra/mac_crash_logger/CMakeLists.txt
@@ -4,6 +4,7 @@ project(mac_crash_logger)
 
 include(00-Common)
 include(LLCommon)
+include(LLCoreHttp)
 include(LLCrashLogger)
 include(LLMath)
 include(LLMessage)
@@ -11,8 +12,10 @@ include(LLVFS)
 include(LLXML)
 include(Linking)
 include(LLSharedLibs)
+include(Boost)
 
 include_directories(
+    ${LLCOREHTTP_INCLUDE_DIRS}
     ${LLCOMMON_INCLUDE_DIRS}
     ${LLCRASHLOGGER_INCLUDE_DIRS}
     ${LLMATH_INCLUDE_DIRS}
@@ -71,7 +74,10 @@ target_link_libraries(mac-crash-logger
     ${LLMESSAGE_LIBRARIES}
     ${LLVFS_LIBRARIES}
     ${LLMATH_LIBRARIES}
+    ${LLCOREHTTP_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
+    ${BOOST_CONTEXT_LIBRARY}
+    ${BOOST_COROUTINE_LIBRARY}
     )
 
 add_custom_command(
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 67c00576bea03c86aa2dbc431b1e152ad63b3501..7a6267251eb7e5e73b7b2f1edd75f6e3e2332e5b 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -142,7 +142,6 @@ set(viewer_SOURCE_FILES
     llbuycurrencyhtml.cpp
     llcallbacklist.cpp
     llcallingcard.cpp
-    llcapabilitylistener.cpp
     llcaphttpsender.cpp
     llchannelmanager.cpp
     llchatbar.cpp
@@ -152,7 +151,6 @@ set(viewer_SOURCE_FILES
     llchiclet.cpp
     llchicletbar.cpp
     llclassifiedinfo.cpp
-    llclassifiedstatsresponder.cpp
     llcofwearables.cpp
     llcolorswatch.cpp
     llcommanddispatcherlistener.cpp
@@ -166,6 +164,7 @@ set(viewer_SOURCE_FILES
     llconversationloglistitem.cpp
     llconversationmodel.cpp
     llconversationview.cpp
+    llcoproceduremanager.cpp
     llcurrencyuimanager.cpp
     llcylinder.cpp
     lldateutil.cpp
@@ -234,7 +233,6 @@ set(viewer_SOURCE_FILES
     llfloaterconversationpreview.cpp
     llfloaterdeleteenvpreset.cpp
     llfloaterdestinations.cpp
-    llfloaterdisplayname.cpp
     llfloatereditdaycycle.cpp
     llfloatereditsky.cpp
     llfloatereditwater.cpp
@@ -333,7 +331,6 @@ set(viewer_SOURCE_FILES
     llgroupmgr.cpp
     llhasheduniqueid.cpp
     llhints.cpp
-    llhomelocationresponder.cpp
     llhttpretrypolicy.cpp
     llhudeffect.cpp
     llhudeffectbeam.cpp
@@ -604,7 +601,6 @@ set(viewer_SOURCE_FILES
     lltwitterconnect.cpp
     lluilistener.cpp
     lluploaddialog.cpp
-    lluploadfloaterobservers.cpp
     llurl.cpp
     llurldispatcher.cpp
     llurldispatcherlistener.cpp
@@ -617,6 +613,7 @@ set(viewer_SOURCE_FILES
     llviewerassetstats.cpp
     llviewerassetstorage.cpp
     llviewerassettype.cpp
+    llviewerassetupload.cpp
     llviewerattachmenu.cpp
     llvieweraudio.cpp
     llviewercamera.cpp
@@ -624,7 +621,6 @@ set(viewer_SOURCE_FILES
     llviewercontrol.cpp
     llviewercontrollistener.cpp
     llviewerdisplay.cpp
-    llviewerdisplayname.cpp
     llviewerfloaterreg.cpp
     llviewerfoldertype.cpp
     llviewergenericmessage.cpp
@@ -757,7 +753,6 @@ set(viewer_HEADER_FILES
     llbuycurrencyhtml.h
     llcallbacklist.h
     llcallingcard.h
-    llcapabilitylistener.h
     llcapabilityprovider.h
     llcaphttpsender.h
     llchannelmanager.h
@@ -768,7 +763,6 @@ set(viewer_HEADER_FILES
     llchiclet.h
     llchicletbar.h
     llclassifiedinfo.h
-    llclassifiedstatsresponder.h
     llcofwearables.h
     llcolorswatch.h
     llcommanddispatcherlistener.h
@@ -782,6 +776,7 @@ set(viewer_HEADER_FILES
     llconversationloglistitem.h
     llconversationmodel.h
     llconversationview.h
+    llcoproceduremanager.h
     llcurrencyuimanager.h
     llcylinder.h
     lldateutil.h
@@ -850,7 +845,6 @@ set(viewer_HEADER_FILES
     llfloaterconversationpreview.h
     llfloaterdeleteenvpreset.h
     llfloaterdestinations.h
-    llfloaterdisplayname.h
     llfloatereditdaycycle.h
     llfloatereditsky.h
     llfloatereditwater.h
@@ -952,7 +946,6 @@ set(viewer_HEADER_FILES
     llhasheduniqueid.h
     llhints.h
     llhttpretrypolicy.h
-    llhomelocationresponder.h
     llhudeffect.h
     llhudeffectbeam.h
     llhudeffectlookat.h
@@ -1225,6 +1218,7 @@ set(viewer_HEADER_FILES
     llviewerassetstats.h
     llviewerassetstorage.h
     llviewerassettype.h
+    llviewerassetupload.h
     llviewerattachmenu.h
     llvieweraudio.h
     llviewercamera.h
@@ -1232,7 +1226,6 @@ set(viewer_HEADER_FILES
     llviewercontrol.h
     llviewercontrollistener.h
     llviewerdisplay.h
-    llviewerdisplayname.h
     llviewerfloaterreg.h
     llviewerfoldertype.h
     llviewergenericmessage.h
@@ -2238,9 +2231,9 @@ if (LL_TESTS)
   SET(viewer_TEST_SOURCE_FILES
     llagentaccess.cpp
     lldateutil.cpp
-    llmediadataclient.cpp
+#    llmediadataclient.cpp
     lllogininstance.cpp
-    llremoteparcelrequest.cpp
+#    llremoteparcelrequest.cpp
     lltranslate.cpp
     llviewerhelputil.cpp
     llversioninfo.cpp
@@ -2271,7 +2264,7 @@ if (LL_TESTS)
   set_source_files_properties(
     llmediadataclient.cpp
     PROPERTIES
-    LL_TEST_ADDITIONAL_LIBRARIES "${CURL_LIBRARIES}"
+    LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}"
   )
 
   set_source_files_properties(
@@ -2327,7 +2320,6 @@ if (LL_TESTS)
   LL_ADD_PROJECT_UNIT_TESTS(${VIEWER_BINARY_NAME} "${viewer_TEST_SOURCE_FILES}")
 
   #set(TEST_DEBUG on)
-  set(test_sources llcapabilitylistener.cpp)
   ##################################################
   # DISABLING PRECOMPILED HEADERS USAGE FOR TESTS
   ##################################################
@@ -2343,26 +2335,29 @@ if (LL_TESTS)
     ${GOOGLEMOCK_LIBRARIES}
     )
 
-  LL_ADD_INTEGRATION_TEST(llcapabilitylistener
-    "${test_sources}"
-    "${test_libs}"
-    ${PYTHON_EXECUTABLE}
-    "${CMAKE_SOURCE_DIR}/llmessage/tests/test_llsdmessage_peer.py"
-    )
+  if (LINUX)
+    # llcommon uses `clock_gettime' which is provided by librt on linux.
+    set(LIBRT_LIBRARY
+      rt
+      )
+  endif (LINUX)
 
   set(test_libs
-    ${LLMESSAGE_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
     ${WINDOWS_LIBRARIES}
     ${LLVFS_LIBRARIES}
     ${LLMATH_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${LLCOREHTTP_LIBRARIES}
     ${GOOGLEMOCK_LIBRARIES}
     ${OPENSSL_LIBRARIES}
     ${CRYPTO_LIBRARIES}
+    ${LIBRT_LIBRARY}
+    ${BOOST_CONTEXT_LIBRARY}
+    ${BOOST_COROUTINE_LIBRARY}
   )
 
-    LL_ADD_INTEGRATION_TEST(llsechandler_basic
+  LL_ADD_INTEGRATION_TEST(llsechandler_basic
     llsechandler_basic.cpp
     "${test_libs}"
     )
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 9d9bc43bd758aa8a73edeeb09b00b437fc776d04..2180a7f1a15390c787cfa3ba2bd75c29cb209fdb 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2370,6 +2370,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+  <key>DebugSlshareLogTag</key>
+    <map>
+      <key>Comment</key>
+      <string>Request slshare-service debug logging</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string/>
+    </map>
   <key>DebugStatModeFPS</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index a42286a9e4aabc2fb9b5c7e58df02537784acd98..cd9146ea16e01c585bb42aa4bacd29c61546412b 100755
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -27,90 +27,150 @@
 #include "llviewerprecompiledheaders.h"
 #include "llaccountingcostmanager.h"
 #include "llagent.h"
-#include "llcurl.h"
-#include "llhttpclient.h"
+#include "httpcommon.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llcorehttputil.h"
+
 //===============================================================================
-LLAccountingCostManager::LLAccountingCostManager()
+LLAccountingCostManager::LLAccountingCostManager():
+    mHttpRequest(),
+    mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
 {	
+    mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+    //mHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
+
 }
-//===============================================================================
-class LLAccountingCostResponder : public LLCurl::Responder
+
+// Coroutine for sending and processing avatar name cache requests.  
+// Do not call directly.  See documentation in lleventcoro.h and llcoro.h for
+// further explanation.
+void LLAccountingCostManager::accountingCostCoro(std::string url,
+    eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle)
 {
-	LOG_CLASS(LLAccountingCostResponder);
-public:
-	LLAccountingCostResponder( const LLSD& objectIDs, const LLHandle<LLAccountingCostObserver>& observer_handle )
-	: mObjectIDs( objectIDs ),
-	  mObserverHandle( observer_handle )
-	{
-		LLAccountingCostObserver* observer = mObserverHandle.get();
-		if (observer)
-		{
-			mTransactionID = observer->getTransactionID();
-		}
-	}
+    LL_DEBUGS("LLAccountingCostManager") << "Entering coroutine " << LLCoros::instance().getName()
+        << " with url '" << url << LL_ENDL;
 
-	void clearPendingRequests ( void )
-	{
-		for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
-		{
-			LLAccountingCostManager::getInstance()->removePendingObject( iter->asUUID() );
-		}
-	}
-	
-protected:
-	void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-		clearPendingRequests();
-
-		LLAccountingCostObserver* observer = mObserverHandle.get();
-		if (observer && observer->getTransactionID() == mTransactionID)
-		{
-			observer->setErrorStatus(getStatus(), getReason());
-		}
-	}
-	
-	void httpSuccess()
-	{
-		const LLSD& content = getContent();
-		//Check for error
-		if ( !content.isMap() || content.has("error") )
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Error on fetched data", content);
-			return;
-		}
-		else if (content.has("selected"))
-		{
-			F32 physicsCost		= 0.0f;
-			F32 networkCost		= 0.0f;
-			F32 simulationCost	= 0.0f;
-
-			physicsCost		= content["selected"]["physics"].asReal();
-			networkCost		= content["selected"]["streaming"].asReal();
-			simulationCost	= content["selected"]["simulation"].asReal();
-				
-			SelectionCost selectionCost( /*transactionID,*/ physicsCost, networkCost, simulationCost );
-
-			LLAccountingCostObserver* observer = mObserverHandle.get();
-			if (observer && observer->getTransactionID() == mTransactionID)
-			{
-				observer->onWeightsUpdate(selectionCost);
-			}
-		}
-
-		clearPendingRequests();
-	}
-	
-private:
-	//List of posted objects
-	LLSD mObjectIDs;
+    try
+    {
+        LLSD objectList;
+        U32  objectIndex = 0;
+
+        IDIt IDIter = mObjectList.begin();
+        IDIt IDIterEnd = mObjectList.end();
+
+        for (; IDIter != IDIterEnd; ++IDIter)
+        {
+            // Check to see if a request for this object has already been made.
+            if (mPendingObjectQuota.find(*IDIter) == mPendingObjectQuota.end())
+            {
+                mPendingObjectQuota.insert(*IDIter);
+                objectList[objectIndex++] = *IDIter;
+            }
+        }
+
+        mObjectList.clear();
+
+        //Post results
+        if (objectList.size() == 0)
+            return;
+
+        std::string keystr;
+        if (selectionType == Roots)
+        {
+            keystr = "selected_roots";
+        }
+        else if (selectionType == Prims)
+        {
+            keystr = "selected_prims";
+        }
+        else
+        {
+            LL_INFOS() << "Invalid selection type " << LL_ENDL;
+            mObjectList.clear();
+            mPendingObjectQuota.clear();
+            return;
+        }
 
-	// Current request ID
-	LLUUID mTransactionID;
+        LLSD dataToPost = LLSD::emptyMap();
+        dataToPost[keystr.c_str()] = objectList;
+
+        LLAccountingCostObserver* observer = observerHandle.get();
+        LLUUID transactionId = observer->getTransactionID();
+        observer = NULL;
+
+        LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("AccountingCost", mHttpPolicy);
+
+        LLSD results = httpAdapter.postAndYield(mHttpRequest, url, dataToPost);
+
+        LLSD httpResults;
+        httpResults = results["http_result"];
+
+        // do/while(false) allows error conditions to break out of following 
+        // block while normal flow goes forward once.
+        do 
+        {
+            observer = observerHandle.get();
+            if ((!observer) || (observer->getTransactionID() != transactionId))
+            {   // *TODO: Rider: I've noticed that getTransactionID() does not 
+                // always match transactionId (the new transaction Id does not show a 
+                // corresponding request.) (ask Vir)
+                if (!observer)
+                    break;
+                LL_WARNS() << "Request transaction Id(" << transactionId
+                    << ") does not match observer's transaction Id("
+                    << observer->getTransactionID() << ")." << LL_ENDL;
+                break;
+            }
+
+            if (!httpResults["success"].asBoolean())
+            {
+                LL_WARNS() << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
+                    << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL;
+                if (observer)
+                {
+                    observer->setErrorStatus(httpResults["status"].asInteger(), httpResults["message"].asStringRef());
+                }
+                break;
+            }
+
+            if (!results.isMap() || results.has("error"))
+            {
+                LL_WARNS() << "Error on fetched data" << LL_ENDL;
+                observer->setErrorStatus(499, "Error on fetched data");
+                break;
+            }
+
+            if (results.has("selected"))
+            {
+                F32 physicsCost = 0.0f;
+                F32 networkCost = 0.0f;
+                F32 simulationCost = 0.0f;
+
+                physicsCost = results["selected"]["physics"].asReal();
+                networkCost = results["selected"]["streaming"].asReal();
+                simulationCost = results["selected"]["simulation"].asReal();
+
+                SelectionCost selectionCost( physicsCost, networkCost, simulationCost);
+
+                observer->onWeightsUpdate(selectionCost);
+            }
+
+        } while (false);
+
+    }
+    catch (std::exception e)
+    {
+        LL_WARNS() << "Caught exception '" << e.what() << "'" << LL_ENDL;
+    }
+    catch (...)
+    {
+        LL_WARNS() << "Caught unknown exception." << LL_ENDL;
+    }
+
+    mPendingObjectQuota.clear();
+}
 
-	// Cost update observer handle
-	LLHandle<LLAccountingCostObserver> mObserverHandle;
-};
 //===============================================================================
 void LLAccountingCostManager::fetchCosts( eSelectionType selectionType,
 										  const std::string& url,
@@ -119,50 +179,11 @@ void LLAccountingCostManager::fetchCosts( eSelectionType selectionType,
 	// Invoking system must have already determined capability availability
 	if ( !url.empty() )
 	{
-		LLSD objectList;
-		U32  objectIndex = 0;
-		
-		IDIt IDIter = mObjectList.begin();
-		IDIt IDIterEnd = mObjectList.end();
-		
-		for ( ; IDIter != IDIterEnd; ++IDIter )
-		{
-			// Check to see if a request for this object has already been made.
-			if ( mPendingObjectQuota.find( *IDIter ) ==	mPendingObjectQuota.end() )
-			{
-				mPendingObjectQuota.insert( *IDIter );
-				objectList[objectIndex++] = *IDIter;
-			}
-		}
-	
-		mObjectList.clear();
-		
-		//Post results
-		if ( objectList.size() > 0 )
-		{
-			std::string keystr;
-			if ( selectionType == Roots ) 
-			{ 
-				keystr="selected_roots"; 
-			}
-			else
-			if ( selectionType == Prims ) 
-			{ 
-				keystr="selected_prims";
-			}
-			else 
-			{
-				LL_INFOS()<<"Invalid selection type "<<LL_ENDL;
-				mObjectList.clear();
-				mPendingObjectQuota.clear();
-				return;
-			}
-			
-			LLSD dataToPost = LLSD::emptyMap();		
-			dataToPost[keystr.c_str()] = objectList;
-
-			LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList, observer_handle ));
-		}
+        std::string coroname = 
+            LLCoros::instance().launch("LLAccountingCostManager::accountingCostCoro",
+            boost::bind(&LLAccountingCostManager::accountingCostCoro, this, url, selectionType, observer_handle));
+        LL_DEBUGS() << coroname << " with  url '" << url << LL_ENDL;
+
 	}
 	else
 	{
diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h
index 3ade34c81d0a6c7a1be2faa010e7ffd06df4427c..d5a94f6fda5ebcc170d77e02887d34af6aba6f26 100755
--- a/indra/newview/llaccountingcostmanager.h
+++ b/indra/newview/llaccountingcostmanager.h
@@ -30,6 +30,13 @@
 #include "llhandle.h"
 
 #include "llaccountingcost.h"
+#include "httpcommon.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "httprequest.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
+
 //===============================================================================
 // An interface class for panels which display the parcel accounting information.
 class LLAccountingCostObserver
@@ -69,6 +76,11 @@ class LLAccountingCostManager : public LLSingleton<LLAccountingCostManager>
 	//a fetch has been instigated.
 	std::set<LLUUID> mPendingObjectQuota;
 	typedef std::set<LLUUID>::iterator IDIt;
+
+    void accountingCostCoro(std::string url, eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle);
+
+    LLCore::HttpRequest::ptr_t		mHttpRequest;
+    LLCore::HttpRequest::policy_t	mHttpPolicy;
 };
 //===============================================================================
 
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 359171c5bd3899aff71a3e1b3261aac12c0bbcb1..2060065c75e1065556073bcabce7fba0f6533aeb 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -38,7 +38,6 @@
 #include "llappearancemgr.h"
 #include "llanimationstates.h"
 #include "llcallingcard.h"
-#include "llcapabilitylistener.h"
 #include "llchannelmanager.h"
 #include "llchicletbar.h"
 #include "llconsole.h"
@@ -52,7 +51,6 @@
 #include "llfloatertools.h"
 #include "llgroupactions.h"
 #include "llgroupmgr.h"
-#include "llhomelocationresponder.h"
 #include "llhudmanager.h"
 #include "lljoystickbutton.h"
 #include "llmorphview.h"
@@ -63,7 +61,6 @@
 #include "llpaneltopinfobar.h"
 #include "llparcel.h"
 #include "llrendersphere.h"
-#include "llsdmessage.h"
 #include "llsdutil.h"
 #include "llsky.h"
 #include "llslurl.h"
@@ -95,6 +92,7 @@
 #include "lscript_byteformat.h"
 #include "stringize.h"
 #include "boost/foreach.hpp"
+#include "llcorehttputil.h"
 
 using namespace LLAvatarAppearanceDefines;
 
@@ -361,7 +359,8 @@ LLAgent::LLAgent() :
 	mMaturityPreferenceNumRetries(0U),
 	mLastKnownRequestMaturity(SIM_ACCESS_MIN),
 	mLastKnownResponseMaturity(SIM_ACCESS_MIN),
-	mTeleportState( TELEPORT_NONE ),
+	mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+	mTeleportState(TELEPORT_NONE),
 	mRegionp(NULL),
 
 	mAgentOriginGlobal(),
@@ -461,6 +460,10 @@ void LLAgent::init()
 		mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this));
 	}
 
+	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
+
+	mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_AGENT);
+
 	mInitialized = TRUE;
 }
 
@@ -2326,27 +2329,9 @@ void LLAgent::setStartPosition( U32 location_id )
 
     body["HomeLocation"] = homeLocation;
 
-    // This awkward idiom warrants explanation.
-    // For starters, LLSDMessage::ResponderAdapter is ONLY for testing the new
-    // LLSDMessage functionality with a pre-existing LLHTTPClient::Responder.
-    // In new code, define your reply/error methods on the same class as the
-    // sending method, bind them to local LLEventPump objects and pass those
-    // LLEventPump names in the request LLSD object.
-    // When testing old code, the new LLHomeLocationResponder object
-    // is referenced by an LLHTTPClient::ResponderPtr, so when the
-    // ResponderAdapter is deleted, the LLHomeLocationResponder will be too.
-    // We must trust that the underlying LLHTTPClient code will eventually
-    // fire either the reply callback or the error callback; either will cause
-    // the ResponderAdapter to delete itself.
-    LLSDMessage::ResponderAdapter*
-        adapter(new LLSDMessage::ResponderAdapter(new LLHomeLocationResponder()));
-
-    request["message"] = "HomeLocation";
-    request["payload"] = body;
-    request["reply"]   = adapter->getReplyName();
-    request["error"]   = adapter->getErrorName();
-
-    gAgent.getRegion()->getCapAPI().post(request);
+    if (!requestPostCapability("HomeLocation", body, 
+            boost::bind(&LLAgent::setStartPositionSuccess, this, _1)))
+        LL_WARNS() << "Unable to post to HomeLocation capability." << LL_ENDL;
 
     const U32 HOME_INDEX = 1;
     if( HOME_INDEX == location_id )
@@ -2355,32 +2340,51 @@ void LLAgent::setStartPosition( U32 location_id )
     }
 }
 
-struct HomeLocationMapper: public LLCapabilityListener::CapabilityMapper
+void LLAgent::setStartPositionSuccess(const LLSD &result)
 {
-    // No reply message expected
-    HomeLocationMapper(): LLCapabilityListener::CapabilityMapper("HomeLocation") {}
-    virtual void buildMessage(LLMessageSystem* msg,
-                              const LLUUID& agentID,
-                              const LLUUID& sessionID,
-                              const std::string& capabilityName,
-                              const LLSD& payload) const
+    LLVector3 agent_pos;
+    bool      error = true;
+
+    do {
+        // was the call to /agent/<agent-id>/home-location successful?
+        // If not, we keep error set to true
+        if (!result.has("success"))
+            break;
+
+        if (0 != strncmp("true", result["success"].asString().c_str(), 4))
+            break;
+
+        // did the simulator return a "justified" home location?
+        // If no, we keep error set to true
+        if (!result.has("HomeLocation"))
+            break;
+
+        if ((!result["HomeLocation"].has("LocationPos")) ||
+                (!result["HomeLocation"]["LocationPos"].has("X")) ||
+                (!result["HomeLocation"]["LocationPos"].has("Y")) ||
+                (!result["HomeLocation"]["LocationPos"].has("Z")))
+            break;
+
+        agent_pos.mV[VX] = result["HomeLocation"]["LocationPos"]["X"].asInteger();
+        agent_pos.mV[VY] = result["HomeLocation"]["LocationPos"]["Y"].asInteger();
+        agent_pos.mV[VZ] = result["HomeLocation"]["LocationPos"]["Z"].asInteger();
+
+        error = false;
+
+    } while (0);
+
+    if (error)
     {
-        msg->newMessageFast(_PREHASH_SetStartLocationRequest);
-        msg->nextBlockFast( _PREHASH_AgentData);
-        msg->addUUIDFast(_PREHASH_AgentID, agentID);
-        msg->addUUIDFast(_PREHASH_SessionID, sessionID);
-        msg->nextBlockFast( _PREHASH_StartLocationData);
-        // corrected by sim
-        msg->addStringFast(_PREHASH_SimName, "");
-        msg->addU32Fast(_PREHASH_LocationID, payload["HomeLocation"]["LocationId"].asInteger());
-        msg->addVector3Fast(_PREHASH_LocationPos,
-                            ll_vector3_from_sdmap(payload["HomeLocation"]["LocationPos"]));
-        msg->addVector3Fast(_PREHASH_LocationLookAt,
-                            ll_vector3_from_sdmap(payload["HomeLocation"]["LocationLookAt"]));
+        LL_WARNS() << "Error in response to home position set." << LL_ENDL;
     }
-};
-// Need an instance of this class so it will self-register
-static HomeLocationMapper homeLocationMapper;
+    else
+    {
+        LL_INFOS() << "setting home position" << LL_ENDL;
+
+        LLViewerRegion *viewer_region = gAgent.getRegion();
+        setHomePosRegion(viewer_region->getHandle(), agent_pos);
+    }
+}
 
 void LLAgent::requestStopMotion( LLMotion* motion )
 {
@@ -2517,87 +2521,6 @@ int LLAgent::convertTextToMaturity(char text)
 	return LLAgentAccess::convertTextToMaturity(text);
 }
 
-class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLMaturityPreferencesResponder);
-public:
-	LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity);
-	virtual ~LLMaturityPreferencesResponder();
-
-protected:
-	virtual void httpSuccess();
-	virtual void httpFailure();
-
-protected:
-
-private:
-	U8 parseMaturityFromServerResponse(const LLSD &pContent) const;
-
-	LLAgent                                  *mAgent;
-	U8                                       mPreferredMaturity;
-	U8                                       mPreviousMaturity;
-};
-
-LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity)
-	: LLHTTPClient::Responder(),
-	mAgent(pAgent),
-	mPreferredMaturity(pPreferredMaturity),
-	mPreviousMaturity(pPreviousMaturity)
-{
-}
-
-LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder()
-{
-}
-
-void LLMaturityPreferencesResponder::httpSuccess()
-{
-	U8 actualMaturity = parseMaturityFromServerResponse(getContent());
-
-	if (actualMaturity != mPreferredMaturity)
-	{
-		LL_WARNS() << "while attempting to change maturity preference from '"
-				   << LLViewerRegion::accessToString(mPreviousMaturity)
-				   << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) 
-				   << "', the server responded with '"
-				   << LLViewerRegion::accessToString(actualMaturity) 
-				   << "' [value:" << static_cast<U32>(actualMaturity) 
-				   << "], " << dumpResponse() << LL_ENDL;
-	}
-	mAgent->handlePreferredMaturityResult(actualMaturity);
-}
-
-void LLMaturityPreferencesResponder::httpFailure()
-{
-	LL_WARNS() << "while attempting to change maturity preference from '" 
-			   << LLViewerRegion::accessToString(mPreviousMaturity)
-			   << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) 
-			<< "', " << dumpResponse() << LL_ENDL;
-	mAgent->handlePreferredMaturityError();
-}
-
-U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent) const
-{
-	U8 maturity = SIM_ACCESS_MIN;
-
-	llassert(pContent.isDefined());
-	llassert(pContent.isMap());
-	llassert(pContent.has("access_prefs"));
-	llassert(pContent.get("access_prefs").isMap());
-	llassert(pContent.get("access_prefs").has("max"));
-	llassert(pContent.get("access_prefs").get("max").isString());
-	if (pContent.isDefined() && pContent.isMap() && pContent.has("access_prefs")
-		&& pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max")
-		&& pContent.get("access_prefs").get("max").isString())
-	{
-		LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
-		LLStringUtil::trim(actualPreference);
-		maturity = LLViewerRegion::shortStringToAccess(actualPreference);
-	}
-
-	return maturity;
-}
-
 void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
 {
 	// Update the number of responses received
@@ -2726,42 +2649,96 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
 		// Update the last know maturity request
 		mLastKnownRequestMaturity = pPreferredMaturity;
 
-		// Create a response handler
-		LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity));
-
 		// If we don't have a region, report it as an error
 		if (getRegion() == NULL)
 		{
-			responderPtr->failureResult(0U, "region is not defined", LLSD());
+			LL_WARNS("Agent") << "Region is not defined, can not change Maturity setting." << LL_ENDL;
+			return;
 		}
-		else
-		{
-			// Find the capability to send maturity preference
-			std::string url = getRegion()->getCapability("UpdateAgentInformation");
 
-			// If the capability is not defined, report it as an error
-			if (url.empty())
-			{
-				responderPtr->failureResult(0U, 
-							"capability 'UpdateAgentInformation' is not defined for region", LLSD());
-			}
-			else
-			{
-				// Set new access preference
-				LLSD access_prefs = LLSD::emptyMap();
-				access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity);
-
-				LLSD body = LLSD::emptyMap();
-				body["access_prefs"] = access_prefs;
-				LL_INFOS() << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity)
-					<< "' via capability to: " << url << LL_ENDL;
-				LLSD headers;
-				LLHTTPClient::post(url, body, responderPtr, headers, 30.0f);
-			}
-		}
+		LLSD access_prefs = LLSD::emptyMap();
+		access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity);
+
+		LLSD postData = LLSD::emptyMap();
+		postData["access_prefs"] = access_prefs;
+		LL_INFOS() << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity) << LL_ENDL;
+
+        if (!requestPostCapability("UpdateAgentInformation", postData,
+            static_cast<httpCallback_t>(boost::bind(&LLAgent::processMaturityPreferenceFromServer, this, _1, pPreferredMaturity)),
+            static_cast<httpCallback_t>(boost::bind(&LLAgent::handlePreferredMaturityError, this))
+            ))
+        {
+            LL_WARNS("Agent") << "Maturity request post failed." << LL_ENDL;
+        }
 	}
 }
 
+
+void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferredMaturity)
+{
+    U8 maturity = SIM_ACCESS_MIN;
+
+    llassert(result.isDefined());
+    llassert(result.isMap());
+    llassert(result.has("access_prefs"));
+    llassert(result.get("access_prefs").isMap());
+    llassert(result.get("access_prefs").has("max"));
+    llassert(result.get("access_prefs").get("max").isString());
+    if (result.isDefined() && result.isMap() && result.has("access_prefs")
+        && result.get("access_prefs").isMap() && result.get("access_prefs").has("max")
+        && result.get("access_prefs").get("max").isString())
+    {
+        LLSD::String actualPreference = result.get("access_prefs").get("max").asString();
+        LLStringUtil::trim(actualPreference);
+        maturity = LLViewerRegion::shortStringToAccess(actualPreference);
+    }
+
+    if (maturity != perferredMaturity)
+    {
+        LL_WARNS() << "while attempting to change maturity preference from '"
+            << LLViewerRegion::accessToString(mLastKnownResponseMaturity)
+            << "' to '" << LLViewerRegion::accessToString(perferredMaturity)
+            << "', the server responded with '"
+            << LLViewerRegion::accessToString(maturity)
+            << "' [value:" << static_cast<U32>(maturity)
+            << "], " << LL_ENDL;
+    }
+    handlePreferredMaturityResult(maturity);
+}
+
+
+bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure)
+{
+    std::string url;
+
+    url = getRegion()->getCapability(capName);
+
+    if (url.empty())
+    {
+        LL_WARNS("Agent") << "Could not retrieve region capability \"" << capName << "\"" << LL_ENDL;
+        return false;
+    }
+
+    LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, mHttpPolicy, postData, cbSuccess, cbFailure);
+    return true;
+}
+
+bool LLAgent::requestGetCapability(const std::string &capName, httpCallback_t cbSuccess, httpCallback_t cbFailure)
+{
+    std::string url;
+
+    url = getRegion()->getCapability(capName);
+
+    if (url.empty())
+    {
+        LL_WARNS("Agent") << "Could not retrieve region capability \"" << capName << "\"" << LL_ENDL;
+        return false;
+    }
+
+    LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(url, mHttpPolicy, cbSuccess, cbFailure);
+    return true;
+}
+
 BOOL LLAgent::getAdminOverride() const	
 { 
 	return mAgentAccess->getAdminOverride(); 
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 4830cb754b6654dd89f6db6d366d1f3eb7e289cb..0ba3dea42783a965177b4e676035b3818bfc45f0 100755
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -34,7 +34,9 @@
 #include "llcoordframe.h"			// for mFrameAgent
 #include "llavatarappearancedefines.h"
 #include "llpermissionsflags.h"
+#include "llevents.h"
 #include "v3dmath.h"
+#include "llcorehttputil.h"
 
 #include <boost/function.hpp>
 #include <boost/shared_ptr.hpp>
@@ -61,6 +63,8 @@ class LLPauseRequestHandle;
 class LLUIColor;
 class LLTeleportRequest;
 
+
+
 typedef boost::shared_ptr<LLTeleportRequest> LLTeleportRequestPtr;
 
 //--------------------------------------------------------------------
@@ -112,6 +116,8 @@ class LLAgent : public LLOldEvents::LLObservable
 	void			init();
 	void			cleanup();
 
+private:
+
 	//--------------------------------------------------------------------
 	// Login
 	//--------------------------------------------------------------------
@@ -227,6 +233,8 @@ class LLAgent : public LLOldEvents::LLObservable
 	void			setHomePosRegion(const U64& region_handle, const LLVector3& pos_region);
 	BOOL			getHomePosGlobal(LLVector3d* pos_global);
 private:
+    void            setStartPositionSuccess(const LLSD &result);
+
 	BOOL 			mHaveHomePosition;
 	U64				mHomeRegionHandle;
 	LLVector3		mHomePosRegion;
@@ -631,6 +639,8 @@ class LLAgent : public LLOldEvents::LLObservable
 	void            setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange);
 
 private:
+
+
 	friend class LLTeleportRequest;
 	friend class LLTeleportRequestViaLandmark;
 	friend class LLTeleportRequestViaLure;
@@ -758,11 +768,12 @@ class LLAgent : public LLOldEvents::LLObservable
 	unsigned int                    mMaturityPreferenceNumRetries;
 	U8                              mLastKnownRequestMaturity;
 	U8                              mLastKnownResponseMaturity;
+	LLCore::HttpRequest::policy_t	mHttpPolicy;
 
 	bool            isMaturityPreferenceSyncedWithServer() const;
 	void 			sendMaturityPreferenceToServer(U8 pPreferredMaturity);
+    void            processMaturityPreferenceFromServer(const LLSD &result, U8 perferredMaturity);
 
-	friend class LLMaturityPreferencesResponder;
 	void            handlePreferredMaturityResult(U8 pServerMaturity);
 	void            handlePreferredMaturityError();
 	void            reportPreferredMaturitySuccess();
@@ -909,6 +920,22 @@ class LLAgent : public LLOldEvents::LLObservable
  **                                                                            **
  *******************************************************************************/
 
+/********************************************************************************
+ **                                                                            **
+ **                    UTILITY
+ **/
+public:
+    typedef LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t httpCallback_t;
+
+	/// Utilities for allowing the the agent sub managers to post and get via
+	/// HTTP using the agent's policy settings and headers.  
+    bool requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess = NULL, httpCallback_t cbFailure = NULL);
+    bool requestGetCapability(const std::string &capName, httpCallback_t cbSuccess = NULL, httpCallback_t cbFailure = NULL);
+
+/**                    Utility
+ **                                                                            **
+ *******************************************************************************/
+
 /********************************************************************************
  **                                                                            **
  **                    DEBUGGING
diff --git a/indra/newview/llagentlanguage.cpp b/indra/newview/llagentlanguage.cpp
index fe6236a32a5aaac13158ffe011d7add5e7f7a737..cdb0e3302dbafdd7fc60ec3abc3c5782636a94e3 100755
--- a/indra/newview/llagentlanguage.cpp
+++ b/indra/newview/llagentlanguage.cpp
@@ -32,6 +32,7 @@
 #include "llviewerregion.h"
 // library includes
 #include "llui.h"					// getLanguage()
+#include "httpcommon.h"
 
 // static
 void LLAgentLanguage::init()
@@ -54,22 +55,17 @@ void LLAgentLanguage::onChange()
 // static
 bool LLAgentLanguage::update()
 {
-	LLSD body;
-	std::string url;
+    LLSD body;
 
-	if (gAgent.getRegion())
-	{
-		url = gAgent.getRegion()->getCapability("UpdateAgentLanguage");
-	}
-
-	if (!url.empty())
-	{
-		std::string language = LLUI::getLanguage();
+	std::string language = LLUI::getLanguage();
 		
-		body["language"] = language;
-		body["language_is_public"] = gSavedSettings.getBOOL("LanguageIsPublic");
+	body["language"] = language;
+	body["language_is_public"] = gSavedSettings.getBOOL("LanguageIsPublic");
 		
-		LLHTTPClient::post(url, body, new LLHTTPClient::Responder);
-	}
+    if (!gAgent.requestPostCapability("UpdateAgentLanguage", body))
+    {
+        LL_WARNS("Language") << "Language capability unavailable." << LL_ENDL;
+    }
+
     return true;
 }
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index f5f224b83ed8295aedc23375f701b216c4be9952..51cca273d83ef4fcc0e35ddd2c5cdfe8688f9c76 100755
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -31,6 +31,10 @@
 #include "llappviewer.h"
 #include "llviewercontrol.h"
 
+#include <openssl/x509_vfy.h>
+#include <openssl/ssl.h>
+#include "llsecapi.h"
+#include <curl/curl.h>
 
 // Here is where we begin to get our connection usage under control.
 // This establishes llcorehttp policy classes that, among other
@@ -93,6 +97,16 @@ static const struct
 		4,		1,		4,		0,		false,
 		"",
 		"inventory"
+	},
+	{ // AP_MATERIALS
+		2,		1,		8,		0,		false,
+		"RenderMaterials",
+		"material manager requests"
+	},
+	{ // AP_AGENT
+		2,		1,		32,		0,		true,
+		"Agent",
+		"Agent requests"
 	}
 };
 
@@ -151,6 +165,15 @@ void LLAppCoreHttp::init()
 						 << LL_ENDL;
 	}
 
+	// Set up SSL Verification call back.
+	status = LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_SSL_VERIFY_CALLBACK,
+														LLCore::HttpRequest::GLOBAL_POLICY_ID,
+														sslVerify, NULL);
+	if (!status)
+	{
+		LL_WARNS("Init") << "Failed to set SSL Verification.  Reason:  " << status.toString() << LL_ENDL;
+	}
+
 	// Tracing levels for library & libcurl (note that 2 & 3 are beyond spammy):
 	// 0 - None
 	// 1 - Basic start, stop simple transitions
@@ -182,6 +205,8 @@ void LLAppCoreHttp::init()
 		}
 
 		mHttpClasses[app_policy].mPolicy = LLCore::HttpRequest::createPolicyClass();
+		// We have run out of available HTTP policies. Adjust HTTP_POLICY_CLASS_LIMIT in _httpinternal.h
+		llassert(mHttpClasses[app_policy].mPolicy != LLCore::HttpRequest::INVALID_POLICY_ID);
 		if (! mHttpClasses[app_policy].mPolicy)
 		{
 			// Use default policy (but don't accidentally modify default)
@@ -457,6 +482,62 @@ void LLAppCoreHttp::refreshSettings(bool initial)
 	}
 }
 
+LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url, 
+	LLCore::HttpHandler const * const handler, void *appdata)
+{
+	X509_STORE_CTX *ctx = static_cast<X509_STORE_CTX *>(appdata);
+	LLCore::HttpStatus result;
+	LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
+	LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
+	LLSD validation_params = LLSD::emptyMap();
+	LLURI uri(url);
+
+	validation_params[CERT_HOSTNAME] = uri.hostName();
+
+	// *TODO: In the case of an exception while validating the cert, we need a way
+	// to pass the offending(?) cert back out. *Rider*
+
+	try
+	{
+		// don't validate hostname.  Let libcurl do it instead.  That way, it'll handle redirects
+		store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params);
+	}
+	catch (LLCertValidationTrustException &cert_exception)
+	{
+		// this exception is is handled differently than the general cert
+		// exceptions, as we allow the user to actually add the certificate
+		// for trust.
+		// therefore we pass back a different error code
+		// NOTE: We're currently 'wired' to pass around CURL error codes.  This is
+		// somewhat clumsy, as we may run into errors that do not map directly to curl
+		// error codes.  Should be refactored with login refactoring, perhaps.
+		result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_CACERT);
+		result.setMessage(cert_exception.getMessage());
+		LLPointer<LLCertificate> cert = cert_exception.getCert();
+		cert->ref(); // adding an extra ref here
+		result.setErrorData(cert.get());
+		// We should probably have a more generic way of passing information
+		// back to the error handlers.
+	}
+	catch (LLCertException &cert_exception)
+	{
+		result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_PEER_CERTIFICATE);
+		result.setMessage(cert_exception.getMessage());
+		LLPointer<LLCertificate> cert = cert_exception.getCert();
+		cert->ref(); // adding an extra ref here
+		result.setErrorData(cert.get());
+	}
+	catch (...)
+	{
+		// any other odd error, we just handle as a connect error.
+		result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_CONNECT_ERROR);
+	}
+
+	return result;
+}
+
+
+
 
 void LLAppCoreHttp::onCompleted(LLCore::HttpHandle, LLCore::HttpResponse *)
 {
diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h
index 37d7a737e774bb4124145b489b838cdc04690edc..410d7c6b0796ae0dedce981f7ac44e60f38790e9 100755
--- a/indra/newview/llappcorehttp.h
+++ b/indra/newview/llappcorehttp.h
@@ -164,7 +164,29 @@ class LLAppCoreHttp : public LLCore::HttpHandler
 		/// Pipelined:       no
 		AP_INVENTORY,
 		AP_REPORTING = AP_INVENTORY,	// Piggy-back on inventory
-		
+
+		/// Material resource requests and puts.  
+		///
+		/// Destination:     simhost:12043
+		/// Protocol:        https:
+		/// Transfer size:   KB
+		/// Long poll:       no
+		/// Concurrency:     low
+		/// Request rate:    low
+		/// Pipelined:       no
+		AP_MATERIALS,
+
+		/// Appearance resource requests and puts.  
+		///
+		/// Destination:     simhost:12043
+		/// Protocol:        https:
+		/// Transfer size:   KB
+		/// Long poll:       no
+		/// Concurrency:     mid
+		/// Request rate:    low
+		/// Pipelined:       yes
+		AP_AGENT,
+
 		AP_COUNT						// Must be last
 	};
 	
@@ -233,7 +255,9 @@ class LLAppCoreHttp : public LLCore::HttpHandler
 	bool						mStopped;
 	HttpClass					mHttpClasses[AP_COUNT];
 	bool						mPipelined;				// Global setting
-	boost::signals2::connection mPipelinedSignal;		// Signal for 'HttpPipelining' setting
+	boost::signals2::connection	mPipelinedSignal;		// Signal for 'HttpPipelining' setting
+
+	static LLCore::HttpStatus	sslVerify(const std::string &uri, LLCore::HttpHandler const * const handler, void *appdata);
 };
 
 
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index b3317e937ec7905a7139c71ff83ad73328b1e3b4..5ad71369c34a925d52de6806b1e9c154a3bd09fe 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -23,7 +23,7 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
-
+ 
 #include "llviewerprecompiledheaders.h"
 
 #include <boost/lexical_cast.hpp>
@@ -54,6 +54,9 @@
 #include "llsdserialize.h"
 #include "llhttpretrypolicy.h"
 #include "llaisapi.h"
+#include "llhttpsdhandler.h"
+#include "llcorehttputil.h"
+#include "llappviewer.h"
 
 #if LL_MSVC
 // disable boost::lexical_cast warning
@@ -1242,6 +1245,8 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
 	items = new_items;
 }
 
+//=========================================================================
+
 const LLUUID LLAppearanceMgr::getCOF() const
 {
 	return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
@@ -3233,276 +3238,6 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id,
 		
 }
 
-class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder
-{
-	LOG_CLASS(RequestAgentUpdateAppearanceResponder);
-
-	friend class LLAppearanceMgr;
-	
-public:
-	RequestAgentUpdateAppearanceResponder();
-
-	virtual ~RequestAgentUpdateAppearanceResponder();
-
-private:
-	// Called when sendServerAppearanceUpdate called. May or may not
-	// trigger a request depending on various bits of state.
-	void onRequestRequested();
-
-	// Post the actual appearance request to cap.
-	void sendRequest();
-
-	void debugCOF(const LLSD& content);
-
-protected:
-	// Successful completion.
-	/* virtual */ void httpSuccess();
-
-	// Error
-	/*virtual*/ void httpFailure();
-
-	void onFailure();
-	void onSuccess();
-
-	S32 mInFlightCounter;
-	LLTimer mInFlightTimer;
-	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
-};
-
-RequestAgentUpdateAppearanceResponder::RequestAgentUpdateAppearanceResponder()
-{
-	bool retry_on_4xx = true;
-	mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10, retry_on_4xx);
-	mInFlightCounter = 0;
-}
-
-RequestAgentUpdateAppearanceResponder::~RequestAgentUpdateAppearanceResponder()
-{
-}
-
-void RequestAgentUpdateAppearanceResponder::onRequestRequested()
-{
-	// If we have already received an update for this or higher cof version, ignore.
-	S32 cof_version = LLAppearanceMgr::instance().getCOFVersion();
-	S32 last_rcv = gAgentAvatarp->mLastUpdateReceivedCOFVersion;
-	S32 last_req = gAgentAvatarp->mLastUpdateRequestCOFVersion;
-	LL_DEBUGS("Avatar") << "cof_version " << cof_version
-						<< " last_rcv " << last_rcv
-						<< " last_req " << last_req
-						<< " in flight " << mInFlightCounter << LL_ENDL;
-	if ((mInFlightCounter>0) && (mInFlightTimer.hasExpired()))
-	{
-		LL_WARNS("Avatar") << "in flight timer expired, resetting " << LL_ENDL;
-		mInFlightCounter = 0;
-	}
-	if (cof_version < last_rcv)
-	{
-		LL_DEBUGS("Avatar") << "Have already received update for cof version " << last_rcv
-							<< " will not request for " << cof_version << LL_ENDL;
-		return;
-	}
-	if (mInFlightCounter>0 && last_req >= cof_version)
-	{
-		LL_DEBUGS("Avatar") << "Request already in flight for cof version " << last_req 
-							<< " will not request for " << cof_version << LL_ENDL;
-		return;
-	}
-
-	// Actually send the request.
-	LL_DEBUGS("Avatar") << "Will send request for cof_version " << cof_version << LL_ENDL;
-	mRetryPolicy->reset();
-	sendRequest();
-}
-	
-void RequestAgentUpdateAppearanceResponder::sendRequest()
-{
-	if (gAgentAvatarp->isEditingAppearance()) 
-	{
-		// don't send out appearance updates if in appearance editing mode
-		return;
-	}
-
-	if (!gAgent.getRegion())
-	{
-		LL_WARNS() << "Region not set, cannot request server appearance update" << LL_ENDL;
-		return;
-	}
-	if (gAgent.getRegion()->getCentralBakeVersion()==0)
-	{
-		LL_WARNS() << "Region does not support baking" << LL_ENDL;
-	}
-	std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance");	
-	if (url.empty())
-	{
-		LL_WARNS() << "No cap for UpdateAvatarAppearance." << LL_ENDL;
-		return;
-	}
-	
-	LLSD body;
-	S32 cof_version = LLAppearanceMgr::instance().getCOFVersion();
-	if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
-	{
-		body = LLAppearanceMgr::instance().dumpCOF();
-	}
-	else
-	{
-		body["cof_version"] = cof_version;
-		if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
-		{
-			body["cof_version"] = cof_version+999;
-		}
-	}
-	LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << LL_ENDL;
-
-	mInFlightCounter++;
-	mInFlightTimer.setTimerExpirySec(60.0);
-	LLHTTPClient::post(url, body, this);
-	llassert(cof_version >= gAgentAvatarp->mLastUpdateRequestCOFVersion);
-	gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version;
-}
-
-void RequestAgentUpdateAppearanceResponder::debugCOF(const LLSD& content)
-{
-	LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger()
-					   << " ================================= " << LL_ENDL;
-	std::set<LLUUID> ais_items, local_items;
-	const LLSD& cof_raw = content["cof_raw"];
-	for (LLSD::array_const_iterator it = cof_raw.beginArray();
-		 it != cof_raw.endArray(); ++it)
-	{
-		const LLSD& item = *it;
-		if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
-		{
-			ais_items.insert(item["item_id"].asUUID());
-			if (item["type"].asInteger() == 24) // link
-			{
-				LL_INFOS("Avatar") << "AIS Link: item_id: " << item["item_id"].asUUID()
-								   << " linked_item_id: " << item["asset_id"].asUUID()
-								   << " name: " << item["name"].asString()
-								   << LL_ENDL; 
-			}
-			else if (item["type"].asInteger() == 25) // folder link
-			{
-				LL_INFOS("Avatar") << "AIS Folder link: item_id: " << item["item_id"].asUUID()
-								   << " linked_item_id: " << item["asset_id"].asUUID()
-								   << " name: " << item["name"].asString()
-								   << LL_ENDL; 
-			}
-			else
-			{
-				LL_INFOS("Avatar") << "AIS Other: item_id: " << item["item_id"].asUUID()
-								   << " linked_item_id: " << item["asset_id"].asUUID()
-								   << " name: " << item["name"].asString()
-								   << " type: " << item["type"].asInteger()
-								   << LL_ENDL; 
-			}
-		}
-	}
-	LL_INFOS("Avatar") << LL_ENDL;
-	LL_INFOS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger() 
-					   << " ================================= " << LL_ENDL;
-	LLInventoryModel::cat_array_t cat_array;
-	LLInventoryModel::item_array_t item_array;
-	gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
-								  cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
-	for (S32 i=0; i<item_array.size(); i++)
-	{
-		const LLViewerInventoryItem* inv_item = item_array.at(i).get();
-		local_items.insert(inv_item->getUUID());
-		LL_INFOS("Avatar") << "LOCAL: item_id: " << inv_item->getUUID()
-						   << " linked_item_id: " << inv_item->getLinkedUUID()
-						   << " name: " << inv_item->getName()
-						   << " parent: " << inv_item->getParentUUID()
-						   << LL_ENDL;
-	}
-	LL_INFOS("Avatar") << " ================================= " << LL_ENDL;
-	S32 local_only = 0, ais_only = 0;
-	for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
-	{
-		if (ais_items.find(*it) == ais_items.end())
-		{
-			LL_INFOS("Avatar") << "LOCAL ONLY: " << *it << LL_ENDL;
-			local_only++;
-		}
-	}
-	for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
-	{
-		if (local_items.find(*it) == local_items.end())
-		{
-			LL_INFOS("Avatar") << "AIS ONLY: " << *it << LL_ENDL;
-			ais_only++;
-		}
-	}
-	if (local_only==0 && ais_only==0)
-	{
-		LL_INFOS("Avatar") << "COF contents identical, only version numbers differ (req "
-						   << content["observed"].asInteger()
-						   << " rcv " << content["expected"].asInteger()
-						   << ")" << LL_ENDL;
-	}
-}
-
-/* virtual */ void RequestAgentUpdateAppearanceResponder::httpSuccess()
-{
-	const LLSD& content = getContent();
-	if (!content.isMap())
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
-	if (content["success"].asBoolean())
-	{
-		LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL;
-		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
-		{
-			dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_ok", content);
-		}
-
-		onSuccess();
-	}
-	else
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Non-success response", content);
-	}
-}
-
-void RequestAgentUpdateAppearanceResponder::onSuccess()
-{
-	mInFlightCounter = llmax(mInFlightCounter-1,0);
-}
-
-/*virtual*/ void RequestAgentUpdateAppearanceResponder::httpFailure()
-{
-	LL_WARNS("Avatar") << "appearance update request failed, status "
-					   << getStatus() << " reason " << getReason() << LL_ENDL;
-
-	if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
-	{
-		const LLSD& content = getContent();
-		dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
-		debugCOF(content);
-	}
-	onFailure();
-}
-
-void RequestAgentUpdateAppearanceResponder::onFailure()
-{
-	mInFlightCounter = llmax(mInFlightCounter-1,0);
-
-	F32 seconds_to_wait;
-	mRetryPolicy->onFailure(getStatus(), getResponseHeaders());
-	if (mRetryPolicy->shouldRetry(seconds_to_wait))
-	{
-		LL_INFOS() << "retrying" << LL_ENDL;
-		doAfterInterval(boost::bind(&RequestAgentUpdateAppearanceResponder::sendRequest,this),
-						seconds_to_wait);
-	}
-	else
-	{
-		LL_WARNS() << "giving up after too many retries" << LL_ENDL;
-	}
-}	
-
 
 LLSD LLAppearanceMgr::dumpCOF() const
 {
@@ -3569,102 +3304,201 @@ LLSD LLAppearanceMgr::dumpCOF() const
 
 void LLAppearanceMgr::requestServerAppearanceUpdate()
 {
-	mAppearanceResponder->onRequestRequested();
-}
 
-class LLIncrementCofVersionResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLIncrementCofVersionResponder);
-public:
-	LLIncrementCofVersionResponder() : LLHTTPClient::Responder()
+	if (!testCOFRequestVersion())
 	{
-		mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 16.0, 2.0, 5);
+		// *TODO: LL_LOG message here
+		return;
 	}
 
-	virtual ~LLIncrementCofVersionResponder()
+	if ((mInFlightCounter > 0) && (mInFlightTimer.hasExpired()))
 	{
+		LL_WARNS("Avatar") << "in flight timer expired, resetting " << LL_ENDL;
+		mInFlightCounter = 0;
 	}
 
-protected:
-	virtual void httpSuccess()
+	if (gAgentAvatarp->isEditingAppearance())
 	{
-		LL_INFOS() << "Successfully incremented agent's COF." << LL_ENDL;
-		const LLSD& content = getContent();
-		if (!content.isMap())
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		S32 new_version = content["category"]["version"].asInteger();
-
-		// cof_version should have increased
-		llassert(new_version > gAgentAvatarp->mLastUpdateRequestCOFVersion);
-
-		gAgentAvatarp->mLastUpdateRequestCOFVersion = new_version;
+		LL_WARNS("Avatar") << "Avatar editing appearance, not sending request." << LL_ENDL;
+		// don't send out appearance updates if in appearance editing mode
+		return;
 	}
 
-	virtual void httpFailure()
+	if (!gAgent.getRegion())
 	{
-		LL_WARNS("Avatar") << "While attempting to increment the agent's cof we got an error "
-						   << dumpResponse() << LL_ENDL;
-		F32 seconds_to_wait;
-		mRetryPolicy->onFailure(getStatus(), getResponseHeaders());
-		if (mRetryPolicy->shouldRetry(seconds_to_wait))
-		{
-			LL_INFOS() << "retrying" << LL_ENDL;
-			doAfterInterval(boost::bind(&LLAppearanceMgr::incrementCofVersion,
-										LLAppearanceMgr::getInstance(),
-										LLHTTPClient::ResponderPtr(this)),
-										seconds_to_wait);
-		}
-		else
-		{
-			LL_WARNS() << "giving up after too many retries" << LL_ENDL;
-		}
+		LL_WARNS("Avatar") << "Region not set, cannot request server appearance update" << LL_ENDL;
+		return;
 	}
-
-private:
-	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
-};
-
-void LLAppearanceMgr::incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr)
-{
-	// If we don't have a region, report it as an error
-	if (gAgent.getRegion() == NULL)
+	if (gAgent.getRegion()->getCentralBakeVersion() == 0)
 	{
-		LL_WARNS() << "Region not set, cannot request cof_version increment" << LL_ENDL;
-		return;
+		LL_WARNS("Avatar") << "Region does not support baking" << LL_ENDL;
 	}
 
-	std::string url = gAgent.getRegion()->getCapability("IncrementCofVersion");
-	if (url.empty())
+	LLSD postData;
+	S32 cof_version = LLAppearanceMgr::instance().getCOFVersion();
+	if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
 	{
-		LL_WARNS() << "No cap for IncrementCofVersion." << LL_ENDL;
-		return;
+		postData = LLAppearanceMgr::instance().dumpCOF();
 	}
-
-	LL_INFOS() << "Requesting cof_version be incremented via capability to: "
-			<< url << LL_ENDL;
-	LLSD headers;
-	LLSD body = LLSD::emptyMap();
-
-	if (!responder_ptr.get())
+	else
 	{
-		responder_ptr = LLHTTPClient::ResponderPtr(new LLIncrementCofVersionResponder());
+		postData["cof_version"] = cof_version;
+		if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
+		{
+			postData["cof_version"] = cof_version + 999;
+		}
 	}
 
-	LLHTTPClient::get(url, body, responder_ptr, headers, 30.0f);
+	mInFlightCounter++;
+	mInFlightTimer.setTimerExpirySec(60.0);
+
+	llassert(cof_version >= gAgentAvatarp->mLastUpdateRequestCOFVersion);
+	gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version;
+
+    if (!gAgent.requestPostCapability("UpdateAvatarAppearance", postData, 
+        static_cast<LLAgent::httpCallback_t>(boost::bind(&LLAppearanceMgr::serverAppearanceUpdateSuccess, this, _1)), 
+        static_cast<LLAgent::httpCallback_t>(boost::bind(&LLAppearanceMgr::decrementInFlightCounter, this))))
+    {
+        LL_WARNS("Avatar") << "Unable to access UpdateAvatarAppearance in this region." << LL_ENDL;
+    }
 }
 
-U32 LLAppearanceMgr::getNumAttachmentsInCOF()
+void LLAppearanceMgr::serverAppearanceUpdateSuccess(const LLSD &result)
 {
-	const LLUUID cof = getCOF();
-	LLInventoryModel::item_array_t obj_items;
-	getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT);
-	return obj_items.size();
+    decrementInFlightCounter();
+    if (result["success"].asBoolean())
+    {
+        LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL;
+        if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+        {
+            dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_ok", result);
+        }
+    }
+    else
+    {
+        LL_WARNS("Avatar") << "Non success response for change appearance" << LL_ENDL;
+        if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+        {
+            debugAppearanceUpdateCOF(result);
+        }
+    }
+}
+
+/*static*/
+void LLAppearanceMgr::debugAppearanceUpdateCOF(const LLSD& content)
+{
+    dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
+
+    LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger()
+        << " ================================= " << LL_ENDL;
+    std::set<LLUUID> ais_items, local_items;
+    const LLSD& cof_raw = content["cof_raw"];
+    for (LLSD::array_const_iterator it = cof_raw.beginArray();
+        it != cof_raw.endArray(); ++it)
+    {
+        const LLSD& item = *it;
+        if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
+        {
+            ais_items.insert(item["item_id"].asUUID());
+            if (item["type"].asInteger() == 24) // link
+            {
+                LL_INFOS("Avatar") << "AIS Link: item_id: " << item["item_id"].asUUID()
+                    << " linked_item_id: " << item["asset_id"].asUUID()
+                    << " name: " << item["name"].asString()
+                    << LL_ENDL;
+            }
+            else if (item["type"].asInteger() == 25) // folder link
+            {
+                LL_INFOS("Avatar") << "AIS Folder link: item_id: " << item["item_id"].asUUID()
+                    << " linked_item_id: " << item["asset_id"].asUUID()
+                    << " name: " << item["name"].asString()
+                    << LL_ENDL;
+            }
+            else
+            {
+                LL_INFOS("Avatar") << "AIS Other: item_id: " << item["item_id"].asUUID()
+                    << " linked_item_id: " << item["asset_id"].asUUID()
+                    << " name: " << item["name"].asString()
+                    << " type: " << item["type"].asInteger()
+                    << LL_ENDL;
+            }
+        }
+    }
+    LL_INFOS("Avatar") << LL_ENDL;
+    LL_INFOS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger()
+        << " ================================= " << LL_ENDL;
+    LLInventoryModel::cat_array_t cat_array;
+    LLInventoryModel::item_array_t item_array;
+    gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
+        cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH);
+    for (S32 i = 0; i < item_array.size(); i++)
+    {
+        const LLViewerInventoryItem* inv_item = item_array.at(i).get();
+        local_items.insert(inv_item->getUUID());
+        LL_INFOS("Avatar") << "LOCAL: item_id: " << inv_item->getUUID()
+            << " linked_item_id: " << inv_item->getLinkedUUID()
+            << " name: " << inv_item->getName()
+            << " parent: " << inv_item->getParentUUID()
+            << LL_ENDL;
+    }
+    LL_INFOS("Avatar") << " ================================= " << LL_ENDL;
+    S32 local_only = 0, ais_only = 0;
+    for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
+    {
+        if (ais_items.find(*it) == ais_items.end())
+        {
+            LL_INFOS("Avatar") << "LOCAL ONLY: " << *it << LL_ENDL;
+            local_only++;
+        }
+    }
+    for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
+    {
+        if (local_items.find(*it) == local_items.end())
+        {
+            LL_INFOS("Avatar") << "AIS ONLY: " << *it << LL_ENDL;
+            ais_only++;
+        }
+    }
+    if (local_only == 0 && ais_only == 0)
+    {
+        LL_INFOS("Avatar") << "COF contents identical, only version numbers differ (req "
+            << content["observed"].asInteger()
+            << " rcv " << content["expected"].asInteger()
+            << ")" << LL_ENDL;
+    }
 }
 
 
+bool LLAppearanceMgr::testCOFRequestVersion() const
+{
+	// If we have already received an update for this or higher cof version, ignore.
+	S32 cof_version = getCOFVersion();
+	S32 last_rcv = gAgentAvatarp->mLastUpdateReceivedCOFVersion;
+	S32 last_req = gAgentAvatarp->mLastUpdateRequestCOFVersion;
+
+	LL_DEBUGS("Avatar") << "cof_version " << cof_version
+		<< " last_rcv " << last_rcv
+		<< " last_req " << last_req
+		<< " in flight " << mInFlightCounter 
+		<< LL_ENDL;
+	if (cof_version < last_rcv)
+	{
+		LL_DEBUGS("Avatar") << "Have already received update for cof version " << last_rcv
+			<< " will not request for " << cof_version << LL_ENDL;
+		return false;
+	}
+	if (/*mInFlightCounter > 0 &&*/ last_req >= cof_version)
+	{
+		LL_DEBUGS("Avatar") << "Request already in flight for cof version " << last_req
+			<< " will not request for " << cof_version << LL_ENDL;
+		return false;
+	}
+
+	// Actually send the request.
+	LL_DEBUGS("Avatar") << "Will send request for cof_version " << cof_version << LL_ENDL;
+	return true;
+}
+
 std::string LLAppearanceMgr::getAppearanceServiceURL() const
 {
 	if (gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride").empty())
@@ -3929,15 +3763,17 @@ void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items,
 	}
 }
 
+bool LLAppearanceMgr::mActive = true;
+
 LLAppearanceMgr::LLAppearanceMgr():
 	mAttachmentInvLinkEnabled(false),
 	mOutfitIsDirty(false),
 	mOutfitLocked(false),
-	mIsInUpdateAppearanceFromCOF(false),
-	mAppearanceResponder(new RequestAgentUpdateAppearanceResponder)
+	mInFlightCounter(0),
+	mInFlightTimer(),
+	mIsInUpdateAppearanceFromCOF(false)
 {
 	LLOutfitObserver& outfit_observer = LLOutfitObserver::instance();
-
 	// unlock outfit on save operation completed
 	outfit_observer.addCOFSavedCallback(boost::bind(
 			&LLAppearanceMgr::setOutfitLocked, this, false));
@@ -3945,11 +3781,12 @@ LLAppearanceMgr::LLAppearanceMgr():
 	mUnlockOutfitTimer.reset(new LLOutfitUnLockTimer(gSavedSettings.getS32(
 			"OutfitOperationsTimeout")));
 
-	gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle,NULL);
+	gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle, NULL);
 }
 
 LLAppearanceMgr::~LLAppearanceMgr()
 {
+	mActive = false;
 }
 
 void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index ee9d3b7209b85ec3c884581b2649067267063f90..3d9a1f1518a1ef2afe6a99395c40c7d9751b5bee 100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -34,12 +34,10 @@
 #include "llinventorymodel.h"
 #include "llinventoryobserver.h"
 #include "llviewerinventory.h"
-#include "llhttpclient.h"
 
 class LLWearableHoldingPattern;
 class LLInventoryCallback;
 class LLOutfitUnLockTimer;
-class RequestAgentUpdateAppearanceResponder;
 
 class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 {
@@ -54,7 +52,6 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	void updateAppearanceFromCOF(bool enforce_item_restrictions = true,
 								 bool enforce_ordering = true,
 								 nullary_func_t post_update_func = no_op);
-	bool needToSaveCOF();
 	void updateCOF(const LLUUID& category, bool append = false);
 	void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append);
 	void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append);
@@ -224,20 +221,23 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 
 	void requestServerAppearanceUpdate();
 
-	void incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr = NULL);
+	void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
+	std::string getAppearanceServiceURL() const;
 
-	U32 getNumAttachmentsInCOF();
 
-	// *HACK Remove this after server side texture baking is deployed on all sims.
-	void incrementCofVersionLegacy();
+	bool testCOFRequestVersion() const;
+	void decrementInFlightCounter()
+	{
+		mInFlightCounter = llmax(mInFlightCounter - 1, 0);
+	}
 
-	void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
-	std::string getAppearanceServiceURL() const;
 
 private:
+    void serverAppearanceUpdateSuccess(const LLSD &result);
+    static void debugAppearanceUpdateCOF(const LLSD& content);
+
 	std::string		mAppearanceServiceURL;
 	
-
 protected:
 	LLAppearanceMgr();
 	~LLAppearanceMgr();
@@ -261,13 +261,14 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	bool mOutfitIsDirty;
 	bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
 
-	LLPointer<RequestAgentUpdateAppearanceResponder> mAppearanceResponder;
-
 	/**
 	 * Lock for blocking operations on outfit until server reply or timeout exceed
 	 * to avoid unsynchronized outfit state or performing duplicate operations.
 	 */
 	bool mOutfitLocked;
+	S32  mInFlightCounter;
+	LLTimer mInFlightTimer;
+	static bool mActive;
 
 	std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
 
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index d2b1dcbf359d3365263d8720934067be261d95c4..e492b8cf5d3ae4145731f4530185e456dce5a375 100755
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -674,6 +674,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
 }
 
 
+#if 0
 /////////////////////////////////////////////////////
 // LLNewAgentInventoryVariablePriceResponder::Impl //
 /////////////////////////////////////////////////////
@@ -1144,5 +1145,5 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(
 				LLPointer<LLNewAgentInventoryVariablePriceResponder>(this)));
 	}
 }
-
+#endif
 
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index 7fbebc7481c1f585dacf23f1c13be02276da9aee..18968bb1af980ae750a56147d1222ffb9d414845 100755
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -79,6 +79,7 @@ class LLNewAgentInventoryResponder : public LLAssetUploadResponder
 	virtual void httpFailure();
 };
 
+#if 0
 // A base class which goes through and performs some default
 // actions for variable price uploads.  If more specific actions
 // are needed (such as different confirmation messages, etc.)
@@ -115,6 +116,7 @@ class LLNewAgentInventoryVariablePriceResponder :
 	class Impl;
 	Impl* mImpl;
 };
+#endif
 
 class LLUpdateAgentInventoryResponder : public LLAssetUploadResponder
 {
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index 38e153137c99c9fe27a64482021d597619e5f2ac..e2601422544a21d809aafca086acef5b67daf30d 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -35,7 +35,6 @@
 // external library headers
 // other Linden headers
 #include "llcharacter.h"
-#include "llhttpclient.h"
 #include "lltimer.h"
 #include "llviewercontrol.h"
 #include "llviewermenu.h"
@@ -43,7 +42,10 @@
 #include "llviewerregion.h"
 #include "llvoavatar.h"
 #include "llworld.h"
-
+#include "llhttpsdhandler.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
+#include "llcorehttputil.h"
 
 static	const std::string KEY_AGENTS = "agents";			// map
 static 	const std::string KEY_WEIGHT = "weight";			// integer
@@ -55,166 +57,178 @@ static	const std::string KEY_ERROR = "error";
 
 // Send data updates about once per minute, only need per-frame resolution
 LLFrameTimer LLAvatarRenderInfoAccountant::sRenderInfoReportTimer;
+//LLCore::HttpRequest::ptr_t LLAvatarRenderInfoAccountant::sHttpRequest;
 
-
-// HTTP responder class for GET request for avatar render weight information
-class LLAvatarRenderInfoGetResponder : public LLHTTPClient::Responder
+//=========================================================================
+void LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro(std::string url, U64 regionHandle)
 {
-public:
-	LLAvatarRenderInfoGetResponder(U64 region_handle) : mRegionHandle(region_handle)
-	{
-	}
-
-	virtual void error(U32 statusNum, const std::string& reason)
-	{
-		LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if (regionp)
-		{
-			LL_WARNS() << "HTTP error result for avatar weight GET: " << statusNum 
-				<< ", " << reason
-				<< " returned by region " << regionp->getName()
-				<< LL_ENDL;
-		}
-		else
-		{
-			LL_WARNS() << "Avatar render weight GET error recieved but region not found for " 
-				<< mRegionHandle 
-				<< ", error " << statusNum 
-				<< ", " << reason
-				<< LL_ENDL;
-		}
-
-	}
-
-	virtual void result(const LLSD& content)
-	{
-		LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if (regionp)
-		{
-			if (LLAvatarRenderInfoAccountant::logRenderInfo())
-			{
-				LL_INFOS() << "LRI: Result for avatar weights request for region " << regionp->getName() << ":" << LL_ENDL;
-			}
-
-			if (content.isMap())
-			{
-				if (content.has(KEY_AGENTS))
-				{
-					const LLSD & agents = content[KEY_AGENTS];
-					if (agents.isMap())
-					{
-						LLSD::map_const_iterator	report_iter = agents.beginMap();
-						while (report_iter != agents.endMap())
-						{
-							LLUUID target_agent_id = LLUUID(report_iter->first);
-							const LLSD & agent_info_map = report_iter->second;
-							LLViewerObject* avatarp = gObjectList.findObject(target_agent_id);
-							if (avatarp && 
-								avatarp->isAvatar() &&
-								agent_info_map.isMap())
-							{	// Extract the data for this avatar
-
-								if (LLAvatarRenderInfoAccountant::logRenderInfo())
-								{
-									LL_INFOS() << "LRI:  Agent " << target_agent_id 
-										<< ": " << agent_info_map << LL_ENDL;
-								}
-
-								if (agent_info_map.has(KEY_WEIGHT))
-								{
-									((LLVOAvatar *) avatarp)->setReportedVisualComplexity(agent_info_map[KEY_WEIGHT].asInteger());
-								}
-							}
-							report_iter++;
-						}
-					}
-				}	// has "agents"
-				else if (content.has(KEY_ERROR))
-				{
-					const LLSD & error = content[KEY_ERROR];
-					LL_WARNS() << "Avatar render info GET error: "
-						<< error[KEY_IDENTIFIER]
-						<< ": " << error[KEY_MESSAGE] 
-						<< " from region " << regionp->getName()
-						<< LL_ENDL;
-				}
-			}
-		}
-		else
-		{
-			LL_INFOS() << "Avatar render weight info recieved but region not found for " 
-				<< mRegionHandle << LL_ENDL;
-		}
-	}
-
-private:
-	U64		mRegionHandle;
-};
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t 
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("AvatarRenderInfoAccountant", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+    if (!regionp)
+    {
+        LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render weight info received but region not found for " 
+                << regionHandle << LL_ENDL;
+        return;
+    }
+
+    LLSD httpResults = result["http_result"];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("AvatarRenderInfoAccountant") << "HTTP status, " << status.toTerseString() << LL_ENDL;
+        return;
+    }
+
+    if (result.has(KEY_AGENTS))
+    {
+        const LLSD & agents = result[KEY_AGENTS];
+        if (agents.isMap())
+        {
+            LLSD::map_const_iterator	report_iter = agents.beginMap();
+            while (report_iter != agents.endMap())
+            {
+                LLUUID target_agent_id = LLUUID(report_iter->first);
+                const LLSD & agent_info_map = report_iter->second;
+                LLViewerObject* avatarp = gObjectList.findObject(target_agent_id);
+                if (avatarp && 
+                    avatarp->isAvatar() &&
+                    agent_info_map.isMap())
+                {	// Extract the data for this avatar
+
+                    if (LLAvatarRenderInfoAccountant::logRenderInfo())
+                    {
+                        LL_INFOS() << "LRI:  Agent " << target_agent_id 
+                            << ": " << agent_info_map << LL_ENDL;
+                    }
+
+                    if (agent_info_map.has(KEY_WEIGHT))
+                    {
+                        ((LLVOAvatar *) avatarp)->setReportedVisualComplexity(agent_info_map[KEY_WEIGHT].asInteger());
+                    }
+                }
+                report_iter++;
+            }
+        }
+    }	// has "agents"
+    else if (result.has(KEY_ERROR))
+    {
+        const LLSD & error = result[KEY_ERROR];
+        LL_WARNS() << "Avatar render info GET error: "
+            << error[KEY_IDENTIFIER]
+            << ": " << error[KEY_MESSAGE] 
+            << " from region " << regionp->getName()
+            << LL_ENDL;
+    }
 
+}
 
-// HTTP responder class for POST request for avatar render weight information
-class LLAvatarRenderInfoPostResponder : public LLHTTPClient::Responder
+//-------------------------------------------------------------------------
+void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(std::string url, U64 regionHandle)
 {
-public:
-	LLAvatarRenderInfoPostResponder(U64 region_handle) : mRegionHandle(region_handle)
-	{
-	}
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("AvatarRenderInfoAccountant", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+    if (!regionp)
+    {
+        LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render weight calculation but region not found for "
+            << regionHandle << LL_ENDL;
+        return;
+    }
+
+    if (logRenderInfo())
+    {
+        LL_INFOS("AvatarRenderInfoAccountant") << "LRI: Sending avatar render info to region " << regionp->getName()
+                << " from " << url << LL_ENDL;
+    }
+
+    // Build the render info to POST to the region
+    LLSD report = LLSD::emptyMap();
+    LLSD agents = LLSD::emptyMap();
+
+    std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+    while( iter != LLCharacter::sInstances.end() )
+    {
+        LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*iter);
+        if (avatar &&
+            avatar->getRezzedStatus() >= 2 &&					// Mostly rezzed (maybe without baked textures downloaded)
+            !avatar->isDead() &&								// Not dead yet
+            avatar->getObjectHost() == regionp->getHost())		// Ensure it's on the same region
+        {
+            avatar->calculateUpdateRenderCost();			// Make sure the numbers are up-to-date
+
+            LLSD info = LLSD::emptyMap();
+            if (avatar->getVisualComplexity() > 0)
+            {
+                info[KEY_WEIGHT] = avatar->getVisualComplexity();
+                agents[avatar->getID().asString()] = info;
+
+                if (logRenderInfo())
+                {
+                    LL_INFOS("AvatarRenderInfoAccountant") << "LRI: Sending avatar render info for " << avatar->getID()
+                            << ": " << info << LL_ENDL;
+                    LL_INFOS("AvatarRenderInfoAccountant") << "LRI: other info geometry " << avatar->getAttachmentGeometryBytes()
+                            << ", area " << avatar->getAttachmentSurfaceArea()
+                            << LL_ENDL;
+                }
+            }
+        }
+        iter++;
+    }
+
+    if (agents.size() == 0)
+        return;
+
+    report[KEY_AGENTS] = agents;
+    regionp = NULL;
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, report);
+
+    regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+    if (!regionp)
+    {
+        LL_INFOS("AvatarRenderInfoAccountant") << "Avatar render weight POST result received but region not found for "
+                << regionHandle << LL_ENDL;
+        return;
+    }
+
+    LLSD httpResults = result["http_result"];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+    if (!status)
+    {
+        LL_WARNS("AvatarRenderInfoAccountant") << "HTTP status, " << status.toTerseString() << LL_ENDL;
+        return;
+    }
+
+    if (LLAvatarRenderInfoAccountant::logRenderInfo())
+    {
+        LL_INFOS("AvatarRenderInfoAccountant") << "LRI: Result for avatar weights POST for region " << regionp->getName()
+            << ": " << result << LL_ENDL;
+    }
+
+    if (result.isMap())
+    {
+        if (result.has(KEY_ERROR))
+        {
+            const LLSD & error = result[KEY_ERROR];
+            LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render info POST error: "
+                << error[KEY_IDENTIFIER]
+                << ": " << error[KEY_MESSAGE] 
+                << " from region " << regionp->getName()
+                << LL_ENDL;
+        }
+    }
 
-	virtual void error(U32 statusNum, const std::string& reason)
-	{
-		LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if (regionp)
-		{
-			LL_WARNS() << "HTTP error result for avatar weight POST: " << statusNum 
-				<< ", " << reason
-				<< " returned by region " << regionp->getName()
-				<< LL_ENDL;
-		}
-		else
-		{
-			LL_WARNS() << "Avatar render weight POST error recieved but region not found for " 
-				<< mRegionHandle 
-				<< ", error " << statusNum 
-				<< ", " << reason
-				<< LL_ENDL;
-		}
-	}
-
-	virtual void result(const LLSD& content)
-	{
-		LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if (regionp)
-		{
-			if (LLAvatarRenderInfoAccountant::logRenderInfo())
-			{
-				LL_INFOS() << "LRI: Result for avatar weights POST for region " << regionp->getName()
-					<< ": " << content << LL_ENDL;
-			}
-
-			if (content.isMap())
-			{
-				if (content.has(KEY_ERROR))
-				{
-					const LLSD & error = content[KEY_ERROR];
-					LL_WARNS() << "Avatar render info POST error: "
-						<< error[KEY_IDENTIFIER]
-						<< ": " << error[KEY_MESSAGE] 
-						<< " from region " << regionp->getName()
-						<< LL_ENDL;
-				}
-			}
-		}
-		else
-		{
-			LL_INFOS() << "Avatar render weight POST result recieved but region not found for " 
-				<< mRegionHandle << LL_ENDL;
-		}
-	}
-
-private:
-	U64		mRegionHandle;
-};
 
+}
 
 // static 
 // Send request for one region, no timer checks
@@ -223,53 +237,9 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
 	std::string url = regionp->getCapability("AvatarRenderInfo");
 	if (!url.empty())
 	{
-		if (logRenderInfo())
-		{
-			LL_INFOS() << "LRI: Sending avatar render info to region "
-				<< regionp->getName() 
-				<< " from " << url
-				<< LL_ENDL;
-		}
-
-		// Build the render info to POST to the region
-		LLSD report = LLSD::emptyMap();
-		LLSD agents = LLSD::emptyMap();
-				
-		std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
-		while( iter != LLCharacter::sInstances.end() )
-		{
-			LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*iter);
-			if (avatar &&
-				avatar->getRezzedStatus() >= 2 &&					// Mostly rezzed (maybe without baked textures downloaded)
-				!avatar->isDead() &&								// Not dead yet
-				avatar->getObjectHost() == regionp->getHost())		// Ensure it's on the same region
-			{
-				avatar->calculateUpdateRenderCost();			// Make sure the numbers are up-to-date
-
-				LLSD info = LLSD::emptyMap();
-				if (avatar->getVisualComplexity() > 0)
-				{
-					info[KEY_WEIGHT] = avatar->getVisualComplexity();
-					agents[avatar->getID().asString()] = info;
-
-					if (logRenderInfo())
-					{
-						LL_INFOS() << "LRI: Sending avatar render info for " << avatar->getID()
-							<< ": " << info << LL_ENDL;
-						LL_INFOS() << "LRI: other info geometry " << avatar->getAttachmentGeometryBytes()
-							<< ", area " << avatar->getAttachmentSurfaceArea()
-							<< LL_ENDL;
-					}
-				}
-			}
-			iter++;
-		}
-
-		report[KEY_AGENTS] = agents;
-		if (agents.size() > 0)
-		{
-			LLHTTPClient::post(url, report, new LLAvatarRenderInfoPostResponder(regionp->getHandle()));
-		}
+        std::string coroname =
+            LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
+            boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
 	}
 }
 
@@ -292,7 +262,9 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
 		}
 
 		// First send a request to get the latest data
-		LLHTTPClient::get(url, new LLAvatarRenderInfoGetResponder(regionp->getHandle()));
+        std::string coroname =
+            LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
+            boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
 	}
 }
 
@@ -301,6 +273,9 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
 // Called every frame - send render weight requests to every region
 void LLAvatarRenderInfoAccountant::idle()
 {
+//	if (!LLAvatarRenderInfoAccountant::sHttpRequest)
+//		sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+
 	if (sRenderInfoReportTimer.hasExpired())
 	{
 		const F32 SECS_BETWEEN_REGION_SCANS   =  5.f;		// Scan the region list every 5 seconds
@@ -393,6 +368,7 @@ void LLAvatarRenderInfoAccountant::expireRenderInfoReportTimer(const LLUUID& reg
 // static 
 bool LLAvatarRenderInfoAccountant::logRenderInfo()
 {
-	static LLCachedControl<bool> render_mute_logging_enabled(gSavedSettings, "RenderAutoMuteLogging", false);
-	return render_mute_logging_enabled;
+    return true;
+// 	static LLCachedControl<bool> render_mute_logging_enabled(gSavedSettings, "RenderAutoMuteLogging", false);
+// 	return render_mute_logging_enabled;
 }
diff --git a/indra/newview/llavatarrenderinfoaccountant.h b/indra/newview/llavatarrenderinfoaccountant.h
index d68f2dccfbdd8f7cb140bf54ec328c769c5d1aaa..f7a04cca2c214922548b8bb45fb2303bfff6dfc2 100644
--- a/indra/newview/llavatarrenderinfoaccountant.h
+++ b/indra/newview/llavatarrenderinfoaccountant.h
@@ -29,6 +29,9 @@
 #if ! defined(LL_llavatarrenderinfoaccountant_H)
 #define LL_llavatarrenderinfoaccountant_H
 
+#include "httpcommon.h"
+#include "llcoros.h"
+
 class LLViewerRegion;
 
 // Class to gather avatar rendering information 
@@ -36,8 +39,6 @@ class LLViewerRegion;
 class LLAvatarRenderInfoAccountant
 {
 public:
-	LLAvatarRenderInfoAccountant()	{};
-	~LLAvatarRenderInfoAccountant()	{};
 
 	static void sendRenderInfoToRegion(LLViewerRegion * regionp);
 	static void getRenderInfoFromRegion(LLViewerRegion * regionp);
@@ -49,8 +50,16 @@ class LLAvatarRenderInfoAccountant
 	static bool logRenderInfo();
 
 private:
+	LLAvatarRenderInfoAccountant() {};
+	~LLAvatarRenderInfoAccountant()	{};
+
 	// Send data updates about once per minute, only need per-frame resolution
 	static LLFrameTimer sRenderInfoReportTimer;
+
+    static void avatarRenderInfoGetCoro(std::string url, U64 regionHandle);
+    static void avatarRenderInfoReportCoro(std::string url, U64 regionHandle);
+
+
 };
 
 #endif /* ! defined(LL_llavatarrenderinfoaccountant_H) */
diff --git a/indra/newview/llcapabilitylistener.cpp b/indra/newview/llcapabilitylistener.cpp
deleted file mode 100755
index ef9b910ae5fcf1dfe0b553f95bddd145ce08b047..0000000000000000000000000000000000000000
--- a/indra/newview/llcapabilitylistener.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * @file   llcapabilitylistener.cpp
- * @author Nat Goodspeed
- * @date   2009-01-07
- * @brief  Implementation for llcapabilitylistener.
- * 
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-// Precompiled header
-#include "llviewerprecompiledheaders.h"
-// associated header
-#include "llcapabilitylistener.h"
-// STL headers
-#include <map>
-// std headers
-// external library headers
-#include <boost/bind.hpp>
-// other Linden headers
-#include "stringize.h"
-#include "llcapabilityprovider.h"
-#include "message.h"
-
-class LLCapabilityListener::CapabilityMappers: public LLSingleton<LLCapabilityListener::CapabilityMappers>
-{
-public:
-    void registerMapper(const LLCapabilityListener::CapabilityMapper*);
-    void unregisterMapper(const LLCapabilityListener::CapabilityMapper*);
-    const LLCapabilityListener::CapabilityMapper* find(const std::string& cap) const;
-
-    struct DupCapMapper: public std::runtime_error
-    {
-        DupCapMapper(const std::string& what):
-            std::runtime_error(std::string("DupCapMapper: ") + what)
-        {}
-    };
-
-private:
-    friend class LLSingleton<LLCapabilityListener::CapabilityMappers>;
-    CapabilityMappers();
-
-    typedef std::map<std::string, const LLCapabilityListener::CapabilityMapper*> CapabilityMap;
-    CapabilityMap mMap;
-};
-
-LLCapabilityListener::LLCapabilityListener(const std::string& name,
-                                           LLMessageSystem* messageSystem,
-                                           const LLCapabilityProvider& provider,
-                                           const LLUUID& agentID,
-                                           const LLUUID& sessionID):
-    mEventPump(name),
-    mMessageSystem(messageSystem),
-    mProvider(provider),
-    mAgentID(agentID),
-    mSessionID(sessionID)
-{
-    mEventPump.listen("self", boost::bind(&LLCapabilityListener::capListener, this, _1));
-}
-
-bool LLCapabilityListener::capListener(const LLSD& request)
-{
-    // Extract what we want from the request object. We do it all up front
-    // partly to document what we expect.
-    LLSD::String cap(request["message"]);
-    LLSD payload(request["payload"]);
-    LLSD::String reply(request["reply"]);
-    LLSD::String error(request["error"]);
-    LLSD::Real timeout(request["timeout"]);
-    // If the LLSD doesn't even have a "message" key, we doubt it was intended
-    // for this listener.
-    if (cap.empty())
-    {
-        LL_ERRS("capListener") << "capability request event without 'message' key to '"
-                               << getCapAPI().getName()
-                               << "' on region\n" << mProvider.getDescription()
-                               << LL_ENDL;
-        return false;               // in case fatal-error function isn't
-    }
-    // Establish default timeout. This test relies on LLSD::asReal() returning
-    // exactly 0.0 for an undef value.
-    if (! timeout)
-    {
-        timeout = HTTP_REQUEST_EXPIRY_SECS;
-    }
-    // Look up the url for the requested capability name.
-    std::string url = mProvider.getCapability(cap);
-    if (! url.empty())
-    {
-        // This capability is supported by the region to which we're talking.
-        LLHTTPClient::post(url, payload,
-                           new LLSDMessage::EventResponder(LLEventPumps::instance(),
-                                                           request,
-                                                           mProvider.getDescription(),
-                                                           cap, reply, error),
-                           LLSD(),  // headers
-                           timeout);
-    }
-    else
-    {
-        // Capability not supported -- do we have a registered mapper?
-        const CapabilityMapper* mapper = CapabilityMappers::instance().find(cap);
-        if (! mapper)               // capability neither supported nor mapped
-        {
-            LL_ERRS("capListener") << "unsupported capability '" << cap << "' request to '"
-                                   << getCapAPI().getName() << "' on region\n"
-                                   << mProvider.getDescription()
-                                   << LL_ENDL;
-        }
-        else if (! mapper->getReplyName().empty()) // mapper expects reply support
-        {
-            LL_ERRS("capListener") << "Mapper for capability '" << cap
-                                   << "' requires unimplemented support for reply message '"
-                                   << mapper->getReplyName()
-                                   << "' on '" << getCapAPI().getName() << "' on region\n"
-                                   << mProvider.getDescription()
-                                   << LL_ENDL;
-        }
-        else
-        {
-            LL_INFOS("capListener") << "fallback invoked for capability '" << cap
-                                    << "' request to '" << getCapAPI().getName()
-                                    << "' on region\n" << mProvider.getDescription()
-                                    << LL_ENDL;
-            mapper->buildMessage(mMessageSystem, mAgentID, mSessionID, cap, payload);
-            mMessageSystem->sendReliable(mProvider.getHost());
-        }
-    }
-    return false;
-}
-
-LLCapabilityListener::CapabilityMapper::CapabilityMapper(const std::string& cap, const std::string& reply):
-    mCapName(cap),
-    mReplyName(reply)
-{
-    LLCapabilityListener::CapabilityMappers::instance().registerMapper(this);
-}
-
-LLCapabilityListener::CapabilityMapper::~CapabilityMapper()
-{
-    LLCapabilityListener::CapabilityMappers::instance().unregisterMapper(this);
-}
-
-LLSD LLCapabilityListener::CapabilityMapper::readResponse(LLMessageSystem* messageSystem) const
-{
-    return LLSD();
-}
-
-LLCapabilityListener::CapabilityMappers::CapabilityMappers() {}
-
-void LLCapabilityListener::CapabilityMappers::registerMapper(const LLCapabilityListener::CapabilityMapper* mapper)
-{
-    // Try to insert a new map entry by which we can look up the passed mapper
-    // instance.
-    std::pair<CapabilityMap::iterator, bool> inserted =
-        mMap.insert(CapabilityMap::value_type(mapper->getCapName(), mapper));
-    // If we already have a mapper for that name, insert() merely located the
-    // existing iterator and returned false. It is a coding error to try to
-    // register more than one mapper for the same capability name.
-    if (! inserted.second)
-    {
-        throw DupCapMapper(std::string("Duplicate capability name ") + mapper->getCapName());
-    }
-}
-
-void LLCapabilityListener::CapabilityMappers::unregisterMapper(const LLCapabilityListener::CapabilityMapper* mapper)
-{
-    CapabilityMap::iterator found = mMap.find(mapper->getCapName());
-    if (found != mMap.end())
-    {
-        mMap.erase(found);
-    }
-}
-
-const LLCapabilityListener::CapabilityMapper*
-LLCapabilityListener::CapabilityMappers::find(const std::string& cap) const
-{
-    CapabilityMap::const_iterator found = mMap.find(cap);
-    if (found != mMap.end())
-    {
-        return found->second;
-    }
-    return NULL;
-}
diff --git a/indra/newview/llcapabilitylistener.h b/indra/newview/llcapabilitylistener.h
deleted file mode 100755
index e7535013e7bacba29db361e09df5a0753e0cfd57..0000000000000000000000000000000000000000
--- a/indra/newview/llcapabilitylistener.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * @file   llcapabilitylistener.h
- * @author Nat Goodspeed
- * @date   2009-01-07
- * @brief  Provide an event-based API for capability requests
- * 
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#if ! defined(LL_LLCAPABILITYLISTENER_H)
-#define LL_LLCAPABILITYLISTENER_H
-
-#include "llevents.h"               // LLEventPump
-#include "llsdmessage.h"            // LLSDMessage::ArgError
-#include "llerror.h"                // LOG_CLASS()
-
-class LLCapabilityProvider;
-class LLMessageSystem;
-class LLSD;
-
-class LLCapabilityListener
-{
-    LOG_CLASS(LLCapabilityListener);
-public:
-    LLCapabilityListener(const std::string& name, LLMessageSystem* messageSystem,
-                         const LLCapabilityProvider& provider,
-                         const LLUUID& agentID, const LLUUID& sessionID);
-
-    /// Capability-request exception
-    typedef LLSDMessage::ArgError ArgError;
-    /// Get LLEventPump on which we listen for capability requests
-    /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
-    LLEventPump& getCapAPI() { return mEventPump; }
-
-    /**
-     * Base class for mapping an as-yet-undeployed capability name to a (pair
-     * of) LLMessageSystem message(s). To map a capability name to such
-     * messages, derive a subclass of CapabilityMapper and declare a static
-     * instance in a translation unit known to be loaded. The mapping is not
-     * region-specific. If an LLViewerRegion's capListener() receives a
-     * request for a supported capability, it will use the capability's URL.
-     * If not, it will look for an applicable CapabilityMapper subclass
-     * instance.
-     */
-    class CapabilityMapper
-    {
-    public:
-        /**
-         * Base-class constructor. Typically your subclass constructor will
-         * pass these parameters as literals.
-         * @param cap the capability name handled by this (subclass) instance
-         * @param reply the name of the response LLMessageSystem message. Omit
-         * if the LLMessageSystem message you intend to send doesn't prompt a
-         * reply message, or if you already handle that message in some other
-         * way.
-         */
-        CapabilityMapper(const std::string& cap, const std::string& reply = "");
-        virtual ~CapabilityMapper();
-        /// query the capability name
-        std::string getCapName() const { return mCapName; }
-        /// query the reply message name
-        std::string getReplyName() const { return mReplyName; }
-        /**
-         * Override this method to build the LLMessageSystem message we should
-         * send instead of the requested capability message. DO NOT send that
-         * message: that will be handled by the caller.
-         */
-        virtual void buildMessage(LLMessageSystem* messageSystem,
-                                  const LLUUID& agentID,
-                                  const LLUUID& sessionID,
-                                  const std::string& capabilityName,
-                                  const LLSD& payload) const = 0;
-        /**
-         * Override this method if you pass a non-empty @a reply
-         * LLMessageSystem message name to the constructor: that is, if you
-         * expect to receive an LLMessageSystem message in response to the
-         * message you constructed in buildMessage(). If you don't pass a @a
-         * reply message name, you need not override this method as it won't
-         * be called.
-         *
-         * Using LLMessageSystem message-reading operations, your
-         * readResponse() override should construct and return an LLSD object
-         * of the form you expect to receive from the real implementation of
-         * the capability you intend to invoke, when it finally goes live.
-         */
-        virtual LLSD readResponse(LLMessageSystem* messageSystem) const;
-
-    private:
-        const std::string mCapName;
-        const std::string mReplyName;
-    };
-
-private:
-    /// Bind the LLCapabilityProvider passed to our ctor
-    const LLCapabilityProvider& mProvider;
-
-    /// Post an event to this LLEventPump to invoke a capability message on
-    /// the bound LLCapabilityProvider's server
-    /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
-    LLEventStream mEventPump;
-
-    LLMessageSystem* mMessageSystem;
-    LLUUID mAgentID, mSessionID;
-
-    /// listener to process capability requests
-    bool capListener(const LLSD&);
-
-    /// helper class for capListener()
-    class CapabilityMappers;
-};
-
-#endif /* ! defined(LL_LLCAPABILITYLISTENER_H) */
diff --git a/indra/newview/llclassifiedstatsresponder.cpp b/indra/newview/llclassifiedstatsresponder.cpp
deleted file mode 100755
index f1ef8e9a035a404a881fa93d156649909d2fdb02..0000000000000000000000000000000000000000
--- a/indra/newview/llclassifiedstatsresponder.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/** 
- * @file llclassifiedstatsresponder.cpp
- * @brief Receives information about classified ad click-through
- * counts for display in the classified information UI.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llclassifiedstatsresponder.h"
-
-#include "llpanelclassified.h"
-#include "llpanel.h"
-#include "llhttpclient.h"
-#include "llsdserialize.h"
-#include "llviewerregion.h"
-#include "llview.h"
-#include "message.h"
-
-LLClassifiedStatsResponder::LLClassifiedStatsResponder(LLUUID classified_id)
-:	mClassifiedID(classified_id)
-{}
-
-/*virtual*/
-void LLClassifiedStatsResponder::httpSuccess()
-{
-	const LLSD& content = getContent();
-	if (!content.isMap())
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
-	S32 teleport = content["teleport_clicks"].asInteger();
-	S32 map = content["map_clicks"].asInteger();
-	S32 profile = content["profile_clicks"].asInteger();
-	S32 search_teleport = content["search_teleport_clicks"].asInteger();
-	S32 search_map = content["search_map_clicks"].asInteger();
-	S32 search_profile = content["search_profile_clicks"].asInteger();
-
-	LLPanelClassifiedInfo::setClickThrough(	mClassifiedID, 
-											teleport + search_teleport, 
-											map + search_map,
-											profile + search_profile,
-											true);
-}
-
-/*virtual*/
-void LLClassifiedStatsResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-}
-
diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h
deleted file mode 100755
index efa4d82411d2df7dd4d598476a02ef107ed206d9..0000000000000000000000000000000000000000
--- a/indra/newview/llclassifiedstatsresponder.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/** 
- * @file llclassifiedstatsresponder.h
- * @brief Receives information about classified ad click-through
- * counts for display in the classified information UI.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-#ifndef LL_LLCLASSIFIEDSTATSRESPONDER_H
-#define LL_LLCLASSIFIEDSTATSRESPONDER_H
-
-#include "llhttpclient.h"
-#include "llview.h"
-#include "lluuid.h"
-
-class LLClassifiedStatsResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLClassifiedStatsResponder);
-public:
-	LLClassifiedStatsResponder(LLUUID classified_id);
-
-protected:
-	//If we get back a normal response, handle it here
-	virtual void httpSuccess();
-	//If we get back an error (not found, etc...), handle it here
-	virtual void httpFailure();
-
-protected:
-	LLUUID mClassifiedID;
-};
-
-#endif // LL_LLCLASSIFIEDSTATSRESPONDER_H
diff --git a/indra/newview/llcoproceduremanager.cpp b/indra/newview/llcoproceduremanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d3168985f87a32980f7178fc391cafb723525f65
--- /dev/null
+++ b/indra/newview/llcoproceduremanager.cpp
@@ -0,0 +1,176 @@
+/**
+* @file llcoproceduremanager.cpp
+* @author Rider Linden
+* @brief Singleton class for managing asset uploads to the sim.
+*
+* $LicenseInfo:firstyear=2015&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2015, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "linden_common.h" 
+
+#include "llviewercontrol.h"
+
+#include "llcoproceduremanager.h"
+
+//=========================================================================
+#define COROCOUNT 1
+
+//=========================================================================
+LLCoprocedureManager::LLCoprocedureManager():
+    LLSingleton<LLCoprocedureManager>(),
+    mPendingCoprocs(),
+    mShutdown(false),
+    mWakeupTrigger("CoprocedureManager", true),
+    mCoroMapping(),
+    mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
+{
+
+    // *TODO: Retrieve the actual number of concurrent coroutines fro gSavedSettings and
+    // clamp to a "reasonable" number.
+    for (int count = 0; count < COROCOUNT; ++count)
+    {
+        LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter =
+            LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t(
+            new LLCoreHttpUtil::HttpCoroutineAdapter("uploadPostAdapter", mHTTPPolicy));
+
+        std::string uploadCoro = LLCoros::instance().launch("LLCoprocedureManager::coprocedureInvokerCoro",
+            boost::bind(&LLCoprocedureManager::coprocedureInvokerCoro, this, httpAdapter));
+
+        mCoroMapping.insert(CoroAdapterMap_t::value_type(uploadCoro, httpAdapter));
+    }
+
+    mWakeupTrigger.post(LLSD());
+}
+
+LLCoprocedureManager::~LLCoprocedureManager() 
+{
+    shutdown();
+}
+
+//=========================================================================
+
+void LLCoprocedureManager::shutdown(bool hardShutdown)
+{
+    CoroAdapterMap_t::iterator it;
+
+    for (it = mCoroMapping.begin(); it != mCoroMapping.end(); ++it)
+    {
+        if (!(*it).first.empty())
+        {
+            if (hardShutdown)
+            {
+                LLCoros::instance().kill((*it).first);
+            }
+        }
+        if ((*it).second)
+        {
+            (*it).second->cancelYieldingOperation();
+        }
+    }
+
+    mShutdown = true;
+    mCoroMapping.clear();
+    mPendingCoprocs.clear();
+}
+
+//=========================================================================
+LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &name, LLCoprocedureManager::CoProcedure_t proc)
+{
+    LLUUID id(LLUUID::generateNewID());
+
+    mPendingCoprocs.push_back(QueuedCoproc::ptr_t(new QueuedCoproc(name, id, proc)));
+    LL_INFOS() << "Coprocedure(" << name << ") enqueued with id=" << id.asString() << LL_ENDL;
+
+    mWakeupTrigger.post(LLSD());
+
+    return id;
+}
+
+void LLCoprocedureManager::cancelCoprocedure(const LLUUID &id)
+{
+    // first check the active coroutines.  If there, remove it and return.
+    ActiveCoproc_t::iterator itActive = mActiveCoprocs.find(id);
+    if (itActive != mActiveCoprocs.end())
+    {
+        LL_INFOS() << "Found and canceling active coprocedure with id=" << id.asString() << LL_ENDL;
+        (*itActive).second->cancelYieldingOperation();
+        mActiveCoprocs.erase(itActive);
+        return;
+    }
+
+    for (CoprocQueue_t::iterator it = mPendingCoprocs.begin(); it != mPendingCoprocs.end(); ++it)
+    {
+        if ((*it)->mId == id)
+        {
+            LL_INFOS() << "Found and removing queued coroutine(" << (*it)->mName << ") with Id=" << id.asString() << LL_ENDL;
+            mPendingCoprocs.erase(it);
+            return;
+        }
+    }
+
+    LL_INFOS() << "Coprocedure with Id=" << id.asString() << " was not found." << LL_ENDL;
+}
+
+//=========================================================================
+void LLCoprocedureManager::coprocedureInvokerCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter)
+{
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    while (!mShutdown)
+    {
+        llcoro::waitForEventOn(mWakeupTrigger);
+        if (mShutdown)
+            break;
+        
+        while (!mPendingCoprocs.empty())
+        {
+            QueuedCoproc::ptr_t coproc = mPendingCoprocs.front();
+            mPendingCoprocs.pop_front();
+            mActiveCoprocs.insert(ActiveCoproc_t::value_type(coproc->mId, httpAdapter));
+
+            LL_INFOS() << "Dequeued and invoking coprocedure(" << coproc->mName << ") with id=" << coproc->mId.asString() << LL_ENDL;
+
+            try
+            {
+                coproc->mProc(httpAdapter, coproc->mId);
+            }
+            catch (std::exception &e)
+            {
+                LL_WARNS() << "Coprocedure(" << coproc->mName << ") id=" << coproc->mId.asString() <<
+                    " threw an exception! Message=\"" << e.what() << "\"" << LL_ENDL;
+            }
+            catch (...)
+            {
+                LL_WARNS() << "A non std::exception was thrown from " << coproc->mName << " with id=" << coproc->mId << "." << LL_ENDL;
+            }
+
+            LL_INFOS() << "Finished coprocedure(" << coproc->mName << ")" << LL_ENDL;
+
+            ActiveCoproc_t::iterator itActive = mActiveCoprocs.find(coproc->mId);
+            if (itActive != mActiveCoprocs.end())
+            {
+                mActiveCoprocs.erase(itActive);
+            }
+        }
+    }
+}
diff --git a/indra/newview/llcoproceduremanager.h b/indra/newview/llcoproceduremanager.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ba3891e879f9919e2c841c0bf59168c7b6314f2
--- /dev/null
+++ b/indra/newview/llcoproceduremanager.h
@@ -0,0 +1,117 @@
+/**
+* @file llcoproceduremanager.h
+* @author Rider Linden
+* @brief Singleton class for managing asset uploads to the sim.
+*
+* $LicenseInfo:firstyear=2015&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2015, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_COPROCEDURE_MANAGER_H
+#define LL_COPROCEDURE_MANAGER_H
+
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "llcorehttputil.h"
+#include "lluuid.h"
+
+class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager >
+{
+public:
+    typedef boost::function<void(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, const LLUUID &id)> CoProcedure_t;
+
+    LLCoprocedureManager();
+    virtual ~LLCoprocedureManager();
+
+    /// Places the coprocedure on the queue for processing. 
+    /// 
+    /// @param name Is used for debugging and should identify this coroutine.
+    /// @param proc Is a bound function to be executed 
+    /// 
+    /// @return This method returns a UUID that can be used later to cancel execution.
+    LLUUID enqueueCoprocedure(const std::string &name, CoProcedure_t proc);
+
+    /// Cancel a coprocedure. If the coprocedure is already being actively executed 
+    /// this method calls cancelYieldingOperation() on the associated HttpAdapter
+    /// If it has not yet been dequeued it is simply removed from the queue.
+    void cancelCoprocedure(const LLUUID &id);
+
+    /// Requests a shutdown of the upload manager. Passing 'true' will perform 
+    /// an immediate kill on the upload coroutine.
+    void shutdown(bool hardShutdown = false);
+
+    /// Returns the number of coprocedures in the queue awaiting processing.
+    ///
+    inline size_t countPending() const
+    {
+        return mPendingCoprocs.size();
+    }
+
+    /// Returns the number of coprocedures actively being processed.
+    ///
+    inline size_t countActive() const
+    {
+        return mActiveCoprocs.size();
+    }
+
+    /// Returns the total number of coprocedures either queued or in active processing.
+    ///
+    inline size_t count() const
+    {
+        return countPending() + countActive();
+    }
+
+private:
+    struct QueuedCoproc
+    {
+        typedef boost::shared_ptr<QueuedCoproc> ptr_t;
+
+        QueuedCoproc(const std::string &name, const LLUUID &id, CoProcedure_t proc):
+            mName(name),
+            mId(id),
+            mProc(proc)
+        {}
+
+        std::string mName;
+        LLUUID mId;
+        CoProcedure_t mProc;
+    };
+    
+    // we use a deque here rather than std::queue since we want to be able to 
+    // iterate through the queue and potentially erase an entry from the middle.
+    typedef std::deque<QueuedCoproc::ptr_t>  CoprocQueue_t;  
+    typedef std::map<LLUUID, LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t> ActiveCoproc_t;
+
+    CoprocQueue_t   mPendingCoprocs;
+    ActiveCoproc_t  mActiveCoprocs;
+    bool            mShutdown;
+    LLEventStream   mWakeupTrigger;
+
+
+    typedef std::map<std::string, LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t> CoroAdapterMap_t;
+    LLCore::HttpRequest::policy_t mHTTPPolicy;
+
+    CoroAdapterMap_t mCoroMapping;
+
+    void coprocedureInvokerCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter);
+};
+
+#endif
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
index 78d619a315b1a17f113a410c21c2d359c9fcc94d..884d1579e643c1e548d9094d4e54291daa7d27c4 100755
--- a/indra/newview/llestateinfomodel.cpp
+++ b/indra/newview/llestateinfomodel.cpp
@@ -29,7 +29,6 @@
 #include "llestateinfomodel.h"
 
 // libs
-#include "llhttpclient.h"
 #include "llregionflags.h"
 #include "message.h"
 
@@ -38,6 +37,8 @@
 #include "llfloaterregioninfo.h" // for invoice id
 #include "llviewerregion.h"
 
+#include "llcorehttputil.h"
+
 LLEstateInfoModel::LLEstateInfoModel()
 :	mID(0)
 ,	mFlags(0)
@@ -110,24 +111,6 @@ void LLEstateInfoModel::notifyCommit()
 
 //== PRIVATE STUFF ============================================================
 
-class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLEstateChangeInfoResponder);
-protected:
-	// if we get a normal response, handle it here
-	virtual void httpSuccesss()
-	{
-		LL_INFOS() << "Committed estate info" << LL_ENDL;
-		LLEstateInfoModel::instance().notifyCommit();
-	}
-
-	// if we get an error response
-	virtual void httpFailure()
-	{
-		LL_WARNS() << "Failed to commit estate info " << dumpResponse() << LL_ENDL;
-	}
-};
-
 // tries to send estate info using a cap; returns true if it succeeded
 bool LLEstateInfoModel::commitEstateInfoCaps()
 {
@@ -139,29 +122,53 @@ bool LLEstateInfoModel::commitEstateInfoCaps()
 		return false;
 	}
 
-	LLSD body;
-	body["estate_name"          ] = getName();
-	body["sun_hour"             ] = getSunHour();
+    LLCoros::instance().launch("LLEstateInfoModel::commitEstateInfoCapsCoro",
+        boost::bind(&LLEstateInfoModel::commitEstateInfoCapsCoro, this, url));
 
-	body["is_sun_fixed"         ] = getUseFixedSun();
-	body["is_externally_visible"] = getIsExternallyVisible();
-	body["allow_direct_teleport"] = getAllowDirectTeleport();
-	body["deny_anonymous"       ] = getDenyAnonymous();
-	body["deny_age_unverified"  ] = getDenyAgeUnverified();
-	body["allow_voice_chat"     ] = getAllowVoiceChat();
-
-	body["invoice"              ] = LLFloaterRegionInfo::getLastInvoice();
-
-	LL_DEBUGS("Windlight Sync") << "Sending estate caps: "
-		<< "is_sun_fixed = " << getUseFixedSun()
-		<< ", sun_hour = " << getSunHour() << LL_ENDL;
-	LL_DEBUGS() << body << LL_ENDL;
-
-	// we use a responder so that we can re-get the data after committing to the database
-	LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder);
     return true;
 }
 
+void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EstateChangeInfo", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD body;
+    body["estate_name"] = getName();
+    body["sun_hour"] = getSunHour();
+
+    body["is_sun_fixed"] = getUseFixedSun();
+    body["is_externally_visible"] = getIsExternallyVisible();
+    body["allow_direct_teleport"] = getAllowDirectTeleport();
+    body["deny_anonymous"] = getDenyAnonymous();
+    body["deny_age_unverified"] = getDenyAgeUnverified();
+    body["allow_voice_chat"] = getAllowVoiceChat();
+
+    body["invoice"] = LLFloaterRegionInfo::getLastInvoice();
+
+    LL_DEBUGS("Windlight Sync") << "Sending estate caps: "
+        << "is_sun_fixed = " << getUseFixedSun()
+        << ", sun_hour = " << getSunHour() << LL_ENDL;
+    LL_DEBUGS() << body << LL_ENDL;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, body);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (status)
+    {
+        LL_INFOS() << "Committed estate info" << LL_ENDL;
+        LLEstateInfoModel::instance().notifyCommit();
+    }
+    else
+    {
+        LL_WARNS() << "Failed to commit estate info " << LL_ENDL;
+    }
+}
+
 /* This is the old way of doing things, is deprecated, and should be
    deleted when the dataserver model can be removed */
 // key = "estatechangeinfo"
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
index 538f2f7c756f868fb58a6746da963974e6b40592..fcfbd1ce7db2c9c0abd88ae6c33353948ac52141 100755
--- a/indra/newview/llestateinfomodel.h
+++ b/indra/newview/llestateinfomodel.h
@@ -30,6 +30,8 @@
 class LLMessageSystem;
 
 #include "llsingleton.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
 
 /**
  * Contains estate info, notifies interested parties of its changes.
@@ -73,7 +75,6 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 
 	friend class LLSingleton<LLEstateInfoModel>;
 	friend class LLDispatchEstateUpdateInfo;
-	friend class LLEstateChangeInfoResponder;
 
 	LLEstateInfoModel();
 
@@ -99,6 +100,8 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 
 	update_signal_t mUpdateSignal; /// emitted when we receive update from sim
 	update_signal_t mCommitSignal; /// emitted when our update gets applied to sim
+
+    void commitEstateInfoCapsCoro(std::string url);
 };
 
 inline bool LLEstateInfoModel::getFlag(U64 flag) const
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 4de6ad4d2f4bc75bc89c3cbcc16d343710539216..0aad1d5ba90ba27d97cd0646ed4303945cfe3e4d 100755
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -30,261 +30,248 @@
 #include "llappviewer.h"
 #include "llagent.h"
 
-#include "llhttpclient.h"
-#include "llhttpconstants.h"
 #include "llsdserialize.h"
 #include "lleventtimer.h"
 #include "llviewerregion.h"
 #include "message.h"
 #include "lltrans.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llcorehttputil.h"
+#include "lleventfilter.h"
 
-namespace
+namespace LLEventPolling
 {
-	// We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error.
-	// This means we attempt to recover relatively quickly but back off giving more time to recover
-	// until we finally give up after MAX_EVENT_POLL_HTTP_ERRORS attempts.
-	const F32 EVENT_POLL_ERROR_RETRY_SECONDS = 15.f; // ~ half of a normal timeout.
-	const F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC = 5.f; // ~ half of a normal timeout.
-	const S32 MAX_EVENT_POLL_HTTP_ERRORS = 10; // ~5 minutes, by the above rules.
-
-	class LLEventPollResponder : public LLHTTPClient::Responder
-	{
-		LOG_CLASS(LLEventPollResponder);
-	public:
-		
-		static LLHTTPClient::ResponderPtr start(const std::string& pollURL, const LLHost& sender);
-		void stop();
-		
-		void makeRequest();
-
-		/* virtual */ void completedRaw(const LLChannelDescriptors& channels,
-								  const LLIOPipe::buffer_ptr_t& buffer);
-
-	private:
-		LLEventPollResponder(const std::string&	pollURL, const LLHost& sender);
-		~LLEventPollResponder();
-
-		
-		void handleMessage(const LLSD& content);
-
-		/* virtual */ void httpFailure();
-		/* virtual */ void httpSuccess();
-
-	private:
-
-		bool	mDone;
-
-		std::string			mPollURL;
-		std::string			mSender;
-		
-		LLSD	mAcknowledge;
-		
-		// these are only here for debugging so	we can see which poller	is which
-		static int sCount;
-		int	mCount;
-		S32 mErrorCount;
-	};
-
-	class LLEventPollEventTimer : public LLEventTimer
-	{
-		typedef LLPointer<LLEventPollResponder> EventPollResponderPtr;
-
-	public:
-		LLEventPollEventTimer(F32 period, EventPollResponderPtr responder)
-			: LLEventTimer(period), mResponder(responder)
-		{ }
-
-		virtual BOOL tick()
-		{
-			mResponder->makeRequest();
-			return TRUE;	// Causes this instance to be deleted.
-		}
-
-	private:
-		
-		EventPollResponderPtr mResponder;
-	};
-
-	//static
-	LLHTTPClient::ResponderPtr LLEventPollResponder::start(
-		const std::string& pollURL, const LLHost& sender)
-	{
-		LLHTTPClient::ResponderPtr result = new LLEventPollResponder(pollURL, sender);
-		LL_INFOS()	<< "LLEventPollResponder::start <" << sCount << "> "
-				<< pollURL << LL_ENDL;
-		return result;
-	}
-
-	void LLEventPollResponder::stop()
-	{
-		LL_INFOS()	<< "LLEventPollResponder::stop	<" << mCount <<	"> "
-				<< mPollURL	<< LL_ENDL;
-		// there should	be a way to	stop a LLHTTPClient	request	in progress
-		mDone =	true;
-	}
-
-	int	LLEventPollResponder::sCount =	0;
-
-	LLEventPollResponder::LLEventPollResponder(const std::string& pollURL, const LLHost& sender)
-		: mDone(false),
-		  mPollURL(pollURL),
-		  mCount(++sCount),
-		  mErrorCount(0)
-	{
-		//extract host and port of simulator to set as sender
-		LLViewerRegion *regionp = gAgent.getRegion();
-		if (!regionp)
-		{
-			LL_ERRS() << "LLEventPoll initialized before region is added." << LL_ENDL;
-		}
-		mSender = sender.getIPandPort();
-		LL_INFOS() << "LLEventPoll initialized with sender " << mSender << LL_ENDL;
-		makeRequest();
-	}
-
-	LLEventPollResponder::~LLEventPollResponder()
-	{
-		stop();
-		LL_DEBUGS() <<	"LLEventPollResponder::~Impl <" <<	mCount << "> "
-				 <<	mPollURL <<	LL_ENDL;
-	}
-
-	// virtual 
-	void LLEventPollResponder::completedRaw(const LLChannelDescriptors& channels,
-											const LLIOPipe::buffer_ptr_t& buffer)
-	{
-		if (getStatus() == HTTP_BAD_GATEWAY)
-		{
-			// These errors are not parsable as LLSD, 
-			// which LLHTTPClient::Responder::completedRaw will try to do.
-			httpCompleted();
-		}
-		else
-		{
-			LLHTTPClient::Responder::completedRaw(channels,buffer);
-		}
-	}
-
-	void LLEventPollResponder::makeRequest()
-	{
-		LLSD request;
-		request["ack"] = mAcknowledge;
-		request["done"]	= mDone;
-		
-		LL_DEBUGS() <<	"LLEventPollResponder::makeRequest	<" << mCount <<	"> ack = "
-				 <<	LLSDXMLStreamer(mAcknowledge) << LL_ENDL;
-		LLHTTPClient::post(mPollURL, request, this);
-	}
-
-	void LLEventPollResponder::handleMessage(const	LLSD& content)
-	{
-		std::string	msg_name	= content["message"];
-		LLSD message;
-		message["sender"] = mSender;
-		message["body"] = content["body"];
-		LLMessageSystem::dispatch(msg_name, message);
-	}
-
-	//virtual
-	void LLEventPollResponder::httpFailure()
-	{
-		if (mDone) return;
-
-		// A HTTP_BAD_GATEWAY (502) error is our standard timeout response
-		// we get this when there are no events.
-		if ( getStatus() == HTTP_BAD_GATEWAY )
-		{
-			mErrorCount = 0;
-			makeRequest();
-		}
-		else if (mErrorCount < MAX_EVENT_POLL_HTTP_ERRORS)
-		{
-			++mErrorCount;
-			
-			// The 'tick' will return TRUE causing the timer to delete this.
-			new LLEventPollEventTimer(EVENT_POLL_ERROR_RETRY_SECONDS
-										+ mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC
-									, this);
-
-			LL_WARNS() << dumpResponse() << LL_ENDL;
-		}
-		else
-		{
-			LL_WARNS() << dumpResponse()
-					   << " [count:" << mCount << "] "
-					   << (mDone ? " -- done" : "") << LL_ENDL;
-			stop();
-
-			// At this point we have given up and the viewer will not receive HTTP messages from the simulator.
-			// IMs, teleports, about land, selecing land, region crossing and more will all fail.
-			// They are essentially disconnected from the region even though some things may still work.
-			// Since things won't get better until they relog we force a disconnect now.
-
-			// *NOTE:Mani - The following condition check to see if this failing event poll
-			// is attached to the Agent's main region. If so we disconnect the viewer.
-			// Else... its a child region and we just leave the dead event poll stopped and 
-			// continue running.
-			if(gAgent.getRegion() && gAgent.getRegion()->getHost().getIPandPort() == mSender)
-			{
-				LL_WARNS() << "Forcing disconnect due to stalled main region event poll."  << LL_ENDL;
-				LLAppViewer::instance()->forceDisconnect(LLTrans::getString("AgentLostConnection"));
-			}
-		}
-	}
-
-	//virtual
-	void LLEventPollResponder::httpSuccess()
-	{
-		LL_DEBUGS() <<	"LLEventPollResponder::result <" << mCount	<< ">"
-				 <<	(mDone ? " -- done"	: "") << LL_ENDL;
-		
-		if (mDone) return;
-
-		mErrorCount = 0;
-
-		const LLSD& content = getContent();
-		if (!content.isMap() ||
-			!content.get("events") ||
-			!content.get("id"))
-		{
-			LL_WARNS() << "received event poll with no events or id key: " << dumpResponse() << LL_ENDL;
-			makeRequest();
-			return;
-		}
-		
-		mAcknowledge = content["id"];
-		LLSD events	= content["events"];
-
-		if(mAcknowledge.isUndefined())
-		{
-			LL_WARNS() << "LLEventPollResponder: id undefined" << LL_ENDL;
-		}
-		
-		// was LL_INFOS() but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
-		LL_DEBUGS()  << "LLEventPollResponder::httpSuccess <" <<	mCount << "> " << events.size() << "events (id "
-					 <<	LLSDXMLStreamer(mAcknowledge) << ")" << LL_ENDL;
-		
-		LLSD::array_const_iterator i = events.beginArray();
-		LLSD::array_const_iterator end = events.endArray();
-		for	(; i !=	end; ++i)
-		{
-			if (i->has("message"))
-			{
-				handleMessage(*i);
-			}
-		}
-		
-		makeRequest();
-	}	
+namespace Details
+{
+
+    class LLEventPollImpl
+    {
+    public:
+        LLEventPollImpl(const LLHost &sender);
+
+        void start(const std::string &url);
+        void stop();
+
+    private:
+        // We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error.
+        // This means we attempt to recover relatively quickly but back off giving more time to recover
+        // until we finally give up after MAX_EVENT_POLL_HTTP_ERRORS attempts.
+        static const F32                EVENT_POLL_ERROR_RETRY_SECONDS;
+        static const F32                EVENT_POLL_ERROR_RETRY_SECONDS_INC;
+        static const S32                MAX_EVENT_POLL_HTTP_ERRORS;
+
+        void                            eventPollCoro(std::string url);
+
+        void                            handleMessage(const LLSD &content);
+
+        bool                            mDone;
+        LLCore::HttpRequest::ptr_t      mHttpRequest;
+        LLCore::HttpRequest::policy_t   mHttpPolicy;
+        std::string                     mSenderIp;
+        int                             mCounter;
+        LLCoreHttpUtil::HttpCoroutineAdapter::wptr_t mAdapter;
+
+        static int                      sNextCounter;
+    };
+
+
+    const F32 LLEventPollImpl::EVENT_POLL_ERROR_RETRY_SECONDS = 15.f; // ~ half of a normal timeout.
+    const F32 LLEventPollImpl::EVENT_POLL_ERROR_RETRY_SECONDS_INC = 5.f; // ~ half of a normal timeout.
+    const S32 LLEventPollImpl::MAX_EVENT_POLL_HTTP_ERRORS = 10; // ~5 minutes, by the above rules.
+
+    int LLEventPollImpl::sNextCounter = 1;
+
+
+    LLEventPollImpl::LLEventPollImpl(const LLHost &sender) :
+        mDone(false),
+        mHttpRequest(),
+        mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+        mSenderIp(),
+        mCounter(sNextCounter++)
+
+    {
+        LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
+
+        mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest);
+        mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_LONG_POLL);
+        mSenderIp = sender.getIPandPort();
+    }
+
+    void LLEventPollImpl::handleMessage(const LLSD& content)
+    {
+        std::string	msg_name = content["message"];
+        LLSD message;
+        message["sender"] = mSenderIp;
+        message["body"] = content["body"];
+        LLMessageSystem::dispatch(msg_name, message);
+    }
+
+    void LLEventPollImpl::start(const std::string &url)
+    {
+        if (!url.empty())
+        {
+            std::string coroname =
+                LLCoros::instance().launch("LLEventPollImpl::eventPollCoro",
+                boost::bind(&LLEventPollImpl::eventPollCoro, this, url));
+            LL_INFOS("LLEventPollImpl") << coroname << " with  url '" << url << LL_ENDL;
+        }
+    }
+
+    void LLEventPollImpl::stop()
+    {
+        LL_INFOS() << "requesting stop for event poll coroutine <" << mCounter << ">" << LL_ENDL;
+        mDone = true;
+
+        LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter = mAdapter.lock();
+        if (adapter)
+        {
+            // cancel the yielding operation if any.
+            adapter->cancelYieldingOperation();
+        }
+    }
+
+    void LLEventPollImpl::eventPollCoro(std::string url)
+    {
+        LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EventPoller", mHttpPolicy));
+        LLSD acknowledge;
+        int errorCount = 0;
+        int counter = mCounter; // saved on the stack for logging. 
+
+        LL_INFOS("LLEventPollImpl") << " <" << counter << "> entering coroutine." << LL_ENDL;
+
+        mAdapter = httpAdapter;
+
+        // continually poll for a server update until we've been flagged as 
+        // finished 
+        while (!mDone)
+        {
+            LLSD request;
+            request["ack"] = acknowledge;
+            request["done"] = mDone;
+
+//          LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> request = "
+//              << LLSDXMLStreamer(request) << LL_ENDL;
+
+            LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> posting and yielding." << LL_ENDL;
+            LLSD result = httpAdapter->postAndYield(mHttpRequest, url, request);
+
+//          LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> result = "
+//              << LLSDXMLStreamer(result) << LL_ENDL;
+
+            LLSD httpResults = result["http_result"];
+            LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+            if (!status)
+            {
+                if (status == LLCore::HttpStatus(HTTP_BAD_GATEWAY))
+                {   // A HTTP_BAD_GATEWAY (502) error is our standard timeout response
+                    // we get this when there are no events.
+                    errorCount = 0;
+                    continue;
+                }
+                else if ((status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_OP_CANCELED)) || 
+                        (status == LLCore::HttpStatus(HTTP_NOT_FOUND)))
+                {   // Event polling for this server has been canceled.  In 
+                    // some cases the server gets ahead of the viewer and will 
+                    // return a 404 error (Not Found) before the cancel event
+                    // comes back in the queue
+                    LL_WARNS() << "Canceling coroutine" << LL_ENDL;
+                    break;
+                }
+                LL_WARNS("LLEventPollImpl") << "<" << counter << "> Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
+                    << status.toTerseString() << ": '" << httpResults["message"] << "'" << LL_ENDL;
+
+                if (errorCount < MAX_EVENT_POLL_HTTP_ERRORS)
+                {   // An unanticipated error has been received from our poll 
+                    // request. Calculate a timeout and wait for it to expire(sleep)
+                    // before trying again.  The sleep time is increased by 5 seconds
+                    // for each consecutive error.
+                    LLEventTimeout timeout;
+                    ++errorCount;
+
+                    F32 waitToRetry = EVENT_POLL_ERROR_RETRY_SECONDS
+                        + errorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC;
+
+                    LL_WARNS("LLEventPollImpl") << "<" << counter << "> Retrying in " << waitToRetry <<
+                        " seconds, error count is now " << errorCount << LL_ENDL;
+
+                    timeout.eventAfter(waitToRetry, LLSD());
+                    llcoro::waitForEventOn(timeout);
+                    
+                    if (mDone)
+                        break;
+                    LL_INFOS("LLEventPollImpl") << "<" << counter << "> About to retry request." << LL_ENDL;
+                    continue;
+                }
+                else
+                {
+                    // At this point we have given up and the viewer will not receive HTTP messages from the simulator.
+                    // IMs, teleports, about land, selecting land, region crossing and more will all fail.
+                    // They are essentially disconnected from the region even though some things may still work.
+                    // Since things won't get better until they relog we force a disconnect now.
+                    mDone = true;
+
+                    // *NOTE:Mani - The following condition check to see if this failing event poll
+                    // is attached to the Agent's main region. If so we disconnect the viewer.
+                    // Else... its a child region and we just leave the dead event poll stopped and 
+                    // continue running.
+                    if (gAgent.getRegion() && gAgent.getRegion()->getHost().getIPandPort() == mSenderIp)
+                    {
+                        LL_WARNS("LLEventPollImpl") << "< " << counter << "> Forcing disconnect due to stalled main region event poll." << LL_ENDL;
+                        LLAppViewer::instance()->forceDisconnect(LLTrans::getString("AgentLostConnection"));
+                    }
+                    break;
+                }
+            }
+
+            errorCount = 0;
+
+            if (!result.isMap() ||
+                !result.get("events") ||
+                !result.get("id"))
+            {
+                LL_WARNS("LLEventPollImpl") << " <" << counter << "> received event poll with no events or id key: " << LLSDXMLStreamer(result) << LL_ENDL;
+                continue;
+            }
+
+            acknowledge = result["id"];
+            LLSD events = result["events"];
+
+            if (acknowledge.isUndefined())
+            {
+                LL_WARNS("LLEventPollImpl") << " id undefined" << LL_ENDL;
+            }
+
+            // was LL_INFOS() but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
+            LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> " << events.size() << "events (id " << LLSDXMLStreamer(acknowledge) << ")" << LL_ENDL;
+
+            LLSD::array_const_iterator i = events.beginArray();
+            LLSD::array_const_iterator end = events.endArray();
+            for (; i != end; ++i)
+            {
+                if (i->has("message"))
+                {
+                    handleMessage(*i);
+                }
+            }
+        }
+        LL_INFOS("LLEventPollImpl") << " <" << counter << "> Leaving coroutine." << LL_ENDL;
+    }
+
+}
 }
 
-LLEventPoll::LLEventPoll(const std::string&	poll_url, const LLHost& sender)
-	: mImpl(LLEventPollResponder::start(poll_url, sender))
-	{ }
+LLEventPoll::LLEventPoll(const std::string&	poll_url, const LLHost& sender):
+    mImpl()
+{ 
+    mImpl = boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl>
+            (new LLEventPolling::Details::LLEventPollImpl(sender));
+    mImpl->start(poll_url);
+}
 
 LLEventPoll::~LLEventPoll()
 {
-	LLHTTPClient::Responder* responderp = mImpl.get();
-	LLEventPollResponder* event_poll_responder = dynamic_cast<LLEventPollResponder*>(responderp);
-	if (event_poll_responder) event_poll_responder->stop();
+    mImpl->stop();
+
 }
diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h
index e8d98062aaee1bce518e08c6b368e2a2a6983640..e32b4ed322eeba57e65f8ae5b93c067ca02388e6 100755
--- a/indra/newview/lleventpoll.h
+++ b/indra/newview/lleventpoll.h
@@ -28,9 +28,23 @@
 #define LL_LLEVENTPOLL_H
 
 #include "llhttpclient.h"
+#include "boost/move/unique_ptr.hpp"
+
+namespace boost
+{
+    using ::boost::movelib::unique_ptr; // move unique_ptr into the boost namespace.
+}
 
 class LLHost;
 
+namespace LLEventPolling
+{
+namespace Details
+{
+    class LLEventPollImpl;
+}
+}
+
 
 class LLEventPoll
 	///< implements the viewer side of server-to-viewer pushed events.
@@ -40,11 +54,11 @@ class LLEventPoll
 		///< Start polling the URL.
 
 	virtual ~LLEventPoll();
-		///< will stop polling, cancelling any poll in progress.
+		///< will stop polling, canceling any poll in progress.
 
 
 private:
-	LLHTTPClient::ResponderPtr mImpl;
+    boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl>    mImpl;
 };
 
 
diff --git a/indra/newview/llfacebookconnect.cpp b/indra/newview/llfacebookconnect.cpp
index 28319564e456863841255be346c1a780b220a4d3..136e02953cdc52986d71e51118583d57fd27eb15 100755
--- a/indra/newview/llfacebookconnect.cpp
+++ b/indra/newview/llfacebookconnect.cpp
@@ -34,7 +34,6 @@
 #include "llagent.h"
 #include "llcallingcard.h"			// for LLAvatarTracker
 #include "llcommandhandler.h"
-#include "llhttpclient.h"
 #include "llnotificationsutil.h"
 #include "llurlaction.h"
 #include "llimagepng.h"
@@ -42,9 +41,11 @@
 #include "lltrans.h"
 #include "llevents.h"
 #include "llviewerregion.h"
+#include "llviewercontrol.h"
 
 #include "llfloaterwebcontent.h"
 #include "llfloaterreg.h"
+#include "llcorehttputil.h"
 
 boost::scoped_ptr<LLEventPump> LLFacebookConnect::sStateWatcher(new LLEventStream("FacebookConnectState"));
 boost::scoped_ptr<LLEventPump> LLFacebookConnect::sInfoWatcher(new LLEventStream("FacebookConnectInfo"));
@@ -67,6 +68,24 @@ void toast_user_for_facebook_success()
     LLNotificationsUtil::add("FacebookConnect", args);
 }
 
+LLCore::HttpHeaders::ptr_t get_headers()
+{
+    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+    // The DebugSlshareLogTag mechanism is intended to trigger slshare-service
+    // debug logging. slshare-service is coded to respond to an X-debug-tag
+    // header by engaging debug logging for that request only. This way a
+    // developer need not muck with the slshare-service image to engage debug
+    // logging. Moreover, the value of X-debug-tag is embedded in each such
+    // log line so the developer can quickly find the log lines pertinent to
+    // THIS session.
+    std::string logtag(gSavedSettings.getString("DebugSlshareLogTag"));
+    if (! logtag.empty())
+    {
+        httpHeaders->append("X-debug-tag", logtag);
+    }
+    return httpHeaders;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 //
 class LLFacebookConnectHandler : public LLCommandHandler
@@ -125,266 +144,354 @@ LLFacebookConnectHandler gFacebookConnectHandler;
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLFacebookConnectResponder : public LLHTTPClient::Responder
+void LLFacebookConnect::facebookConnectCoro(std::string authCode, std::string authState)
 {
-	LOG_CLASS(LLFacebookConnectResponder);
-public:
-	
-    LLFacebookConnectResponder()
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    LLSD putData;
+    if (!authCode.empty())
     {
-        LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
+        putData["code"] = authCode;
+    }
+    if (!authState.empty())
+    {
+        putData["state"] = authState;
     }
-    
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("FacebookConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
-		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTED);
-	}
 
-	/* virtual */ void httpFailure()
-	{
-		if ( HTTP_FOUND == getStatus() )
-		{
-			const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (location.empty())
-			{
-				LL_WARNS("FacebookConnect") << "Missing Location header " << dumpResponse()
-							 << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			}
-			else
-			{
-				LLFacebookConnect::instance().openFacebookWeb(location);
-			}
-		}
-		else
-		{
-			LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
-			LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
-			const LLSD& content = getContent();
-			log_facebook_connect_error("Connect", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
+
+    LLSD result = httpAdapter->putAndYield(httpRequest, getFacebookConnectURL("/connection"), putData, httpOpts, get_headers());
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+    if (!status)
+    {
+        if (status == LLCore::HttpStatus(HTTP_FOUND))
+        {
+            std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+            if (location.empty())
+            {
+                LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
+            }
+            else
+            {
+                openFacebookWeb(location);
+            }
+        }
+    }
+    else
+    {
+        LL_INFOS("FacebookConnect") << "Connect successful. " << LL_ENDL;
+        setConnectionState(LLFacebookConnect::FB_CONNECTED);
+    }
+
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLFacebookShareResponder : public LLHTTPClient::Responder
+bool LLFacebookConnect::testShareStatus(LLSD &result)
 {
-	LOG_CLASS(LLFacebookShareResponder);
-public:
-    
-	LLFacebookShareResponder()
-	{
-		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POSTING);
-	}
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
 
-	/* virtual */ void httpSuccess()
-	{
-		toast_user_for_facebook_success();
-		LL_DEBUGS("FacebookConnect") << "Post successful. " << dumpResponse() << LL_ENDL;
-		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POSTED);
-	}
+    if (status)
+        return true;
 
-	/* virtual */ void httpFailure()
-	{
-		if ( HTTP_FOUND == getStatus() )
-		{
-			const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (location.empty())
-			{
-				LL_WARNS("FacebookConnect") << "Missing Location header " << dumpResponse()
-							 << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			}
-			else
-			{
-				LLFacebookConnect::instance().openFacebookWeb(location);
-			}
-		}
-		else if ( HTTP_NOT_FOUND == getStatus() )
-		{
-			LLFacebookConnect::instance().connectToFacebook();
-		}
-		else
-		{
-			LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
-			LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POST_FAILED);
-			const LLSD& content = getContent();
-			log_facebook_connect_error("Share", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+    if (status == LLCore::HttpStatus(HTTP_FOUND))
+    {
+        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+        if (location.empty())
+        {
+            LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
+        }
+        else
+        {
+            openFacebookWeb(location);
+        }
+    }
+    if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+    {
+        LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL;
+        connectToFacebook();
+    }
+    else
+    {
+        LL_WARNS("FacebookConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
+        setConnectionState(LLFacebookConnect::FB_POST_FAILED);
+        log_facebook_connect_error("Share", status.getStatus(), status.toString(),
+            result.get("error_code"), result.get("error_description"));
+    }
+    return false;
+}
 
-///////////////////////////////////////////////////////////////////////////////
-//
-class LLFacebookDisconnectResponder : public LLHTTPClient::Responder
+void LLFacebookConnect::facebookShareCoro(std::string route, LLSD share)
 {
-	LOG_CLASS(LLFacebookDisconnectResponder);
-public:
- 
-	LLFacebookDisconnectResponder()
-	{
-		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_DISCONNECTING);
-	}
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
 
-	void setUserDisconnected()
-	{
-		// Clear data
-		LLFacebookConnect::instance().clearInfo();
-		LLFacebookConnect::instance().clearContent();
-		//Notify state change
-		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
-	}
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
 
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("FacebookConnect") << "Disconnect successful. " << dumpResponse() << LL_ENDL;
-		setUserDisconnected();
-	}
+    setConnectionState(LLFacebookConnect::FB_POSTING);
 
-	/* virtual */ void httpFailure()
-	{
-		//User not found so already disconnected
-		if ( HTTP_NOT_FOUND == getStatus() )
-		{
-			LL_DEBUGS("FacebookConnect") << "Already disconnected. " << dumpResponse() << LL_ENDL;
-			setUserDisconnected();
-		}
-		else
-		{
-			LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
-			LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
-			const LLSD& content = getContent();
-			log_facebook_connect_error("Disconnect", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+    LLSD result = httpAdapter->postAndYield(httpRequest, getFacebookConnectURL(route, true), share, httpOpts, get_headers());
+
+    if (testShareStatus(result))
+    {
+        toast_user_for_facebook_success();
+        LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL;
+        setConnectionState(LLFacebookConnect::FB_POSTED);
+    }
+}
+
+void LLFacebookConnect::facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpHeaders::ptr_t httpHeaders(get_headers());
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    std::string imageFormat;
+    if (dynamic_cast<LLImagePNG*>(image.get()))
+    {
+        imageFormat = "png";
+    }
+    else if (dynamic_cast<LLImageJPEG*>(image.get()))
+    {
+        imageFormat = "jpg";
+    }
+    else
+    {
+        LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
+        return;
+    }
+
+    // All this code is mostly copied from LLWebProfile::post()
+    static const std::string boundary = "----------------------------0123abcdefab";
+
+    std::string contentType = "multipart/form-data; boundary=" + boundary;
+    httpHeaders->append("Content-Type", contentType.c_str());
+
+    LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); // 
+    LLCore::BufferArrayStream body(raw.get());
+
+    // *NOTE: The order seems to matter.
+    body << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"caption\"\r\n\r\n"
+        << caption << "\r\n";
+
+    body << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
+        << "Content-Type: image/" << imageFormat << "\r\n\r\n";
+
+    // Insert the image data.
+    // *FIX: Treating this as a string will probably screw it up ...
+    U8* image_data = image->getData();
+    for (S32 i = 0; i < image->getDataSize(); ++i)
+    {
+        body << image_data[i];
+    }
+
+    body << "\r\n--" << boundary << "--\r\n";
+
+    setConnectionState(LLFacebookConnect::FB_POSTING);
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, getFacebookConnectURL(route, true), raw, httpOpts, httpHeaders);
+
+    if (testShareStatus(result))
+    {
+        toast_user_for_facebook_success();
+        LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL;
+        setConnectionState(LLFacebookConnect::FB_POSTED);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLFacebookConnectedResponder : public LLHTTPClient::Responder
+void LLFacebookConnect::facebookDisconnectCoro()
 {
-	LOG_CLASS(LLFacebookConnectedResponder);
-public:
-    
-	LLFacebookConnectedResponder(bool auto_connect) : mAutoConnect(auto_connect)
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    setConnectionState(LLFacebookConnect::FB_DISCONNECTING);
+    httpOpts->setFollowRedirects(false);
+
+    LLSD result = httpAdapter->deleteAndYield(httpRequest, getFacebookConnectURL("/connection"), httpOpts, get_headers());
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+    if (!status && (status != LLCore::HttpStatus(HTTP_FOUND)))
+    {
+        LL_WARNS("FacebookConnect") << "Failed to disconnect:" << status.toTerseString() << LL_ENDL;
+        setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
+        log_facebook_connect_error("Disconnect", status.getStatus(), status.toString(),
+            result.get("error_code"), result.get("error_description"));
+    }
+    else
     {
-		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
+        LL_DEBUGS("FacebookConnect") << "Facebook Disconnect successful. " << LL_ENDL;
+        clearInfo();
+        clearContent();
+        //Notify state change
+        setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
     }
 
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("FacebookConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
-		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTED);
-	}
+}
 
-	/* virtual */ void httpFailure()
-	{
-		// show the facebook login page if not connected yet
-		if ( HTTP_NOT_FOUND == getStatus() )
-		{
-			LL_DEBUGS("FacebookConnect") << "Not connected. " << dumpResponse() << LL_ENDL;
-			if (mAutoConnect)
-			{
-				LLFacebookConnect::instance().connectToFacebook();
-			}
-			else
-			{
-				LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
-			}
-		}
-		else
-		{
-			LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
-			LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
-			const LLSD& content = getContent();
-			log_facebook_connect_error("Connected", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-    
-private:
-	bool mAutoConnect;
-};
+///////////////////////////////////////////////////////////////////////////////
+//
+void LLFacebookConnect::facebookConnectedCheckCoro(bool autoConnect)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
+
+    httpOpts->setFollowRedirects(false);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, getFacebookConnectURL("/connection", true), httpOpts, get_headers());
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        if ( status == LLCore::HttpStatus(HTTP_NOT_FOUND) )
+        {
+            LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL;
+            if (autoConnect)
+            {
+                connectToFacebook();
+            }
+            else
+            {
+                setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
+            }
+        }
+        else
+        {
+            LL_WARNS("FacebookConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
+
+            setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
+            log_facebook_connect_error("Connected", status.getStatus(), status.toString(),
+                result.get("error_code"), result.get("error_description"));
+        }
+    }
+    else
+    {
+        LL_DEBUGS("FacebookConnect") << "Connect successful. " << LL_ENDL;
+        setConnectionState(LLFacebookConnect::FB_CONNECTED);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLFacebookInfoResponder : public LLHTTPClient::Responder
+void LLFacebookConnect::facebookConnectInfoCoro()
 {
-	LOG_CLASS(LLFacebookInfoResponder);
-public:
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
 
-	/* virtual */ void httpSuccess()
-	{
-		LL_INFOS("FacebookConnect") << "Facebook: Info received" << LL_ENDL;
-		LL_DEBUGS("FacebookConnect") << "Getting Facebook info successful. " << dumpResponse() << LL_ENDL;
-		LLFacebookConnect::instance().storeInfo(getContent());
-	}
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
 
-	/* virtual */ void httpFailure()
-	{
-		if ( HTTP_FOUND == getStatus() )
-		{
-			const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (location.empty())
-			{
-				LL_WARNS("FacebookConnect") << "Missing Location header " << dumpResponse()
-                << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			}
-			else
-			{
-				LLFacebookConnect::instance().openFacebookWeb(location);
-			}
-		}
-		else
-		{
-			LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
-			const LLSD& content = getContent();
-			log_facebook_connect_error("Info", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+    LLSD result = httpAdapter->getAndYield(httpRequest, getFacebookConnectURL("/info", true), httpOpts, get_headers());
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (status == LLCore::HttpStatus(HTTP_FOUND))
+    {
+        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+        if (location.empty())
+        {
+            LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
+        }
+        else
+        {
+            openFacebookWeb(location);
+        }
+    }
+    else if (!status)
+    {
+        LL_WARNS("FacebookConnect") << "Facebook Info failed: " << status.toString() << LL_ENDL;
+        log_facebook_connect_error("Info", status.getStatus(), status.toString(),
+            result.get("error_code"), result.get("error_description"));
+    }
+    else
+    {
+        LL_INFOS("FacebookConnect") << "Facebook: Info received" << LL_ENDL;
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        storeInfo(result);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLFacebookFriendsResponder : public LLHTTPClient::Responder
+void LLFacebookConnect::facebookConnectFriendsCoro()
 {
-	LOG_CLASS(LLFacebookFriendsResponder);
-public:
-    
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("FacebookConnect") << "Getting Facebook friends successful. " << dumpResponse() << LL_ENDL;
-		LLFacebookConnect::instance().storeContent(getContent());
-	}
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
 
-	/* virtual */ void httpFailure()
-	{
-		if ( HTTP_FOUND == getStatus() )
-		{
-			const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (location.empty())
-			{
-				LL_WARNS("FacebookConnect") << "Missing Location header " << dumpResponse()
-							 << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			}
-			else
-			{
-				LLFacebookConnect::instance().openFacebookWeb(location);
-			}
-		}
-		else
-		{
-			LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
-			const LLSD& content = getContent();
-			log_facebook_connect_error("Friends", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+    httpOpts->setFollowRedirects(false);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, getFacebookConnectURL("/friends", true), httpOpts, get_headers());
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (status == LLCore::HttpStatus(HTTP_FOUND))
+    {
+        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+        if (location.empty())
+        {
+            LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
+        }
+        else
+        {
+            openFacebookWeb(location);
+        }
+    }
+    else if (!status)
+    {
+        LL_WARNS("FacebookConnect") << "Facebook Friends failed: " << status.toString() << LL_ENDL;
+        log_facebook_connect_error("Info", status.getStatus(), status.toString(),
+            result.get("error_code"), result.get("error_description"));
+    }
+    else
+    {
+        LL_INFOS("FacebookConnect") << "Facebook: Friends received" << LL_ENDL;
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        LLSD content = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
+        storeContent(content);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
@@ -439,40 +546,28 @@ std::string LLFacebookConnect::getFacebookConnectURL(const std::string& route, b
 
 void LLFacebookConnect::connectToFacebook(const std::string& auth_code, const std::string& auth_state)
 {
-	LLSD body;
-	if (!auth_code.empty())
-    {
-		body["code"] = auth_code;
-    }
-	if (!auth_state.empty())
-    {
-		body["state"] = auth_state;
-    }
-    
-	LLHTTPClient::put(getFacebookConnectURL("/connection"), body, new LLFacebookConnectResponder());
+    LLCoros::instance().launch("LLFacebookConnect::facebookConnectCoro",
+        boost::bind(&LLFacebookConnect::facebookConnectCoro, this, auth_code, auth_state));
 }
 
 void LLFacebookConnect::disconnectFromFacebook()
 {
-	LLHTTPClient::del(getFacebookConnectURL("/connection"), new LLFacebookDisconnectResponder());
+    LLCoros::instance().launch("LLFacebookConnect::facebookDisconnectCoro",
+        boost::bind(&LLFacebookConnect::facebookDisconnectCoro, this));
 }
 
 void LLFacebookConnect::checkConnectionToFacebook(bool auto_connect)
 {
-	const bool follow_redirects = false;
-	const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
-	LLHTTPClient::get(getFacebookConnectURL("/connection", true), new LLFacebookConnectedResponder(auto_connect),
-						LLSD(), timeout, follow_redirects);
+    LLCoros::instance().launch("LLFacebookConnect::facebookConnectedCheckCoro",
+        boost::bind(&LLFacebookConnect::facebookConnectedCheckCoro, this, auto_connect));
 }
 
 void LLFacebookConnect::loadFacebookInfo()
 {
 	if(mRefreshInfo)
 	{
-		const bool follow_redirects = false;
-		const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
-		LLHTTPClient::get(getFacebookConnectURL("/info", true), new LLFacebookInfoResponder(),
-			LLSD(), timeout, follow_redirects);
+        LLCoros::instance().launch("LLFacebookConnect::facebookConnectInfoCoro",
+            boost::bind(&LLFacebookConnect::facebookConnectInfoCoro, this));
 	}
 }
 
@@ -480,14 +575,13 @@ void LLFacebookConnect::loadFacebookFriends()
 {
 	if(mRefreshContent)
 	{
-		const bool follow_redirects = false;
-		const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
-		LLHTTPClient::get(getFacebookConnectURL("/friends", true), new LLFacebookFriendsResponder(),
-			LLSD(), timeout, follow_redirects);
+        LLCoros::instance().launch("LLFacebookConnect::facebookConnectFriendsCoro",
+            boost::bind(&LLFacebookConnect::facebookConnectFriendsCoro, this));
 	}
 }
 
-void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& image, const std::string& message)
+void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name, 
+    const std::string& description, const std::string& image, const std::string& message)
 {
 	LLSD body;
 	if (!location.empty())
@@ -511,80 +605,34 @@ void LLFacebookConnect::postCheckin(const std::string& location, const std::stri
 		body["message"] = message;
     }
 
-	// Note: we can use that route for different publish action. We should be able to use the same responder.
-	LLHTTPClient::post(getFacebookConnectURL("/share/checkin", true), body, new LLFacebookShareResponder());
+    LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
+        boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/checkin", body));
 }
 
 void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::string& caption)
 {
+    // *TODO: I could not find an instace where this method is used.  Remove?
 	LLSD body;
 	body["image"] = image_url;
 	body["caption"] = caption;
 	
-    // Note: we can use that route for different publish action. We should be able to use the same responder.
-	LLHTTPClient::post(getFacebookConnectURL("/share/photo", true), body, new LLFacebookShareResponder());
+    LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
+        boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/photo", body));
 }
 
 void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption)
 {
-	std::string imageFormat;
-	if (dynamic_cast<LLImagePNG*>(image.get()))
-	{
-		imageFormat = "png";
-	}
-	else if (dynamic_cast<LLImageJPEG*>(image.get()))
-	{
-		imageFormat = "jpg";
-	}
-	else
-	{
-		LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
-		return;
-	}
-	
-	// All this code is mostly copied from LLWebProfile::post()
-	const std::string boundary = "----------------------------0123abcdefab";
-
-	LLSD headers;
-	headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
-
-	std::ostringstream body;
-
-	// *NOTE: The order seems to matter.
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"caption\"\r\n\r\n"
-			<< caption << "\r\n";
-
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
-			<< "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
-	// Insert the image data.
-	// *FIX: Treating this as a string will probably screw it up ...
-	U8* image_data = image->getData();
-	for (S32 i = 0; i < image->getDataSize(); ++i)
-	{
-		body << image_data[i];
-	}
-
-	body <<	"\r\n--" << boundary << "--\r\n";
-
-	// postRaw() takes ownership of the buffer and releases it later.
-	size_t size = body.str().size();
-	U8 *data = new U8[size];
-	memcpy(data, body.str().data(), size);
-	
-    // Note: we can use that route for different publish action. We should be able to use the same responder.
-	LLHTTPClient::postRaw(getFacebookConnectURL("/share/photo", true), data, size, new LLFacebookShareResponder(), headers);
+    LLCoros::instance().launch("LLFacebookConnect::facebookShareImageCoro",
+        boost::bind(&LLFacebookConnect::facebookShareImageCoro, this, "/share/photo", image, caption));
 }
 
 void LLFacebookConnect::updateStatus(const std::string& message)
 {
 	LLSD body;
 	body["message"] = message;
-	
-    // Note: we can use that route for different publish action. We should be able to use the same responder.
-	LLHTTPClient::post(getFacebookConnectURL("/share/wall", true), body, new LLFacebookShareResponder());
+
+    LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
+        boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/wall", body));
 }
 
 void LLFacebookConnect::storeInfo(const LLSD& info)
diff --git a/indra/newview/llfacebookconnect.h b/indra/newview/llfacebookconnect.h
index c157db21781b7ff101297656f62dd5e4b0e128c2..2a2cdb54991d432344412720500b5f2a9bb1b353 100644
--- a/indra/newview/llfacebookconnect.h
+++ b/indra/newview/llfacebookconnect.h
@@ -30,6 +30,8 @@
 
 #include "llsingleton.h"
 #include "llimage.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
 
 class LLEventPump;
 
@@ -101,6 +103,15 @@ class LLFacebookConnect : public LLSingleton<LLFacebookConnect>
 	static boost::scoped_ptr<LLEventPump> sStateWatcher;
 	static boost::scoped_ptr<LLEventPump> sInfoWatcher;
 	static boost::scoped_ptr<LLEventPump> sContentWatcher;
+
+    bool testShareStatus(LLSD &results);
+    void facebookConnectCoro(std::string authCode, std::string authState);
+    void facebookConnectedCheckCoro(bool autoConnect);
+    void facebookDisconnectCoro();
+    void facebookShareCoro(std::string route, LLSD share);
+    void facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption);
+    void facebookConnectInfoCoro();
+    void facebookConnectFriendsCoro();
 };
 
 #endif // LL_LLFACEBOOKCONNECT_H
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index ea39f812fd14cffa71991b0ae53b123227a6f0bf..0b76ca16a904856607aa3a9db493aade78225d91 100755
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -40,7 +40,6 @@
 
 #include "llappviewer.h"
 #include "llbufferstream.h"
-#include "llhttpclient.h"
 #include "llnotificationsutil.h"
 #include "llviewercontrol.h"
 #include "llworld.h"
@@ -55,6 +54,7 @@
 #include "llviewershadermgr.h"
 #include "llstring.h"
 #include "stringize.h"
+#include "llcorehttputil.h"
 
 #if LL_WINDOWS
 #include "lldxhardware.h"
@@ -492,95 +492,70 @@ bool LLFeatureManager::loadGPUClass()
 	return true; // indicates that a gpu value was established
 }
 
-	
-// responder saves table into file
-class LLHTTPFeatureTableResponder : public LLHTTPClient::Responder
+void LLFeatureManager::fetchFeatureTableCoro(std::string tableName)
 {
-	LOG_CLASS(LLHTTPFeatureTableResponder);
-public:
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FeatureManagerHTTPTable", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
 
-	LLHTTPFeatureTableResponder(std::string filename) :
-		mFilename(filename)
-	{
-	}
+    const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable");
 
-	
-	virtual void completedRaw(const LLChannelDescriptors& channels,
-							  const LLIOPipe::buffer_ptr_t& buffer)
-	{
-		if (isGoodStatus())
-		{
-			// write to file
-
-			LL_INFOS() << "writing feature table to " << mFilename << LL_ENDL;
-			
-			S32 file_size = buffer->countAfter(channels.in(), NULL);
-			if (file_size > 0)
-			{
-				// read from buffer
-				U8* copy_buffer = new U8[file_size];
-				buffer->readAfter(channels.in(), NULL, copy_buffer, file_size);
-
-				// write to file
-				LLAPRFile out(mFilename, LL_APR_WB);
-				out.write(copy_buffer, file_size);
-				out.close();
-			}
-		}
-		else
-		{
-			char body[1025]; 
-			body[1024] = '\0';
-			LLBufferStream istr(channels, buffer.get());
-			istr.get(body,1024);
-			if (strlen(body) > 0)
-			{
-				mContent["body"] = body;
-			}
-			LL_WARNS() << dumpResponse() << LL_ENDL;
-		}
-	}
-	
-private:
-	std::string mFilename;
-};
-
-void fetch_feature_table(std::string table)
-{
-	const std::string base       = gSavedSettings.getString("FeatureManagerHTTPTable");
 
 #if LL_WINDOWS
-	std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
-	std::string filename;
-	if (os_string.find("Microsoft Windows XP") == 0)
-	{
-		filename = llformat(table.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
-	}
-	else
-	{
-		filename = llformat(table.c_str(), "", LLVersionInfo::getVersion().c_str());
-	}
+    std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+    std::string filename;
+
+    if (os_string.find("Microsoft Windows XP") == 0)
+    {
+        filename = llformat(tableName.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
+    }
+    else
+    {
+        filename = llformat(tableName.c_str(), "", LLVersionInfo::getVersion().c_str());
+    }
 #else
-	const std::string filename   = llformat(table.c_str(), LLVersionInfo::getVersion().c_str());
+    const std::string filename   = llformat(tableName.c_str(), LLVersionInfo::getVersion().c_str());
 #endif
 
-	const std::string url        = base + "/" + filename;
+    std::string url        = base + "/" + filename;
+    // testing url below
+    //url = "http://viewer-settings.secondlife.com/featuretable.2.1.1.208406.txt";
+    const std::string path       = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
 
-	const std::string path       = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
 
-	LL_INFOS() << "LLFeatureManager fetching " << url << " into " << path << LL_ENDL;
-	
-	LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
-}
+    LL_INFOS() << "LLFeatureManager fetching " << url << " into " << path << LL_ENDL;
+
+    LLSD result = httpAdapter->getRawAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (status)
+    {   // There was a newer feature table on the server. We've grabbed it and now should write it.
+        // write to file
+        const LLSD::Binary &raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
 
+        LL_INFOS() << "writing feature table to " << filename << LL_ENDL;
+
+        S32 size = raw.size();
+        if (size > 0)
+        {
+            // write to file
+            LLAPRFile out(filename, LL_APR_WB);
+            out.write(raw.data(), size);
+            out.close();
+        }
+    }
+}
 
 // fetch table(s) from a website (S3)
 void LLFeatureManager::fetchHTTPTables()
 {
-	fetch_feature_table(FEATURE_TABLE_VER_FILENAME);
+    LLCoros::instance().launch("LLFeatureManager::fetchFeatureTableCoro",
+        boost::bind(&LLFeatureManager::fetchFeatureTableCoro, this, FEATURE_TABLE_VER_FILENAME));
 }
 
-
 void LLFeatureManager::cleanupFeatureTables()
 {
 	std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 69078ccc21504848965fa42aba6514fc506dd140..12ea691b491f0363ab19d6f62b98c1b69e253481 100755
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -32,6 +32,8 @@
 #include "llsingleton.h"
 #include "llstring.h"
 #include <map>
+#include "llcoros.h"
+#include "lleventcoro.h"
 
 typedef enum EGPUClass
 {
@@ -164,6 +166,7 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag
 
 	void initBaseMask();
 
+    void fetchFeatureTableCoro(std::string name);
 
 	std::map<std::string, LLFeatureList *> mMaskList;
 	std::set<std::string> mSkippedFeatures;
diff --git a/indra/newview/llflickrconnect.cpp b/indra/newview/llflickrconnect.cpp
index b75660ea003a2635699c2fb081a14f987df4e9e4..83e4f19191debd9c7ff1745332f761f2318c722e 100644
--- a/indra/newview/llflickrconnect.cpp
+++ b/indra/newview/llflickrconnect.cpp
@@ -32,7 +32,6 @@
 #include "llagent.h"
 #include "llcallingcard.h"			// for LLAvatarTracker
 #include "llcommandhandler.h"
-#include "llhttpclient.h"
 #include "llnotificationsutil.h"
 #include "llurlaction.h"
 #include "llimagepng.h"
@@ -43,6 +42,7 @@
 
 #include "llfloaterwebcontent.h"
 #include "llfloaterreg.h"
+#include "llcorehttputil.h"
 
 boost::scoped_ptr<LLEventPump> LLFlickrConnect::sStateWatcher(new LLEventStream("FlickrConnectState"));
 boost::scoped_ptr<LLEventPump> LLFlickrConnect::sInfoWatcher(new LLEventStream("FlickrConnectInfo"));
@@ -67,228 +67,324 @@ void toast_user_for_flickr_success()
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLFlickrConnectResponder : public LLHTTPClient::Responder
+void LLFlickrConnect::flickrConnectCoro(std::string requestToken, std::string oauthVerifier)
 {
-	LOG_CLASS(LLFlickrConnectResponder);
-public:
-	
-    LLFlickrConnectResponder()
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    LLSD body;
+    if (!requestToken.empty())
+        body["request_token"] = requestToken;
+    if (!oauthVerifier.empty())
+        body["oauth_verifier"] = oauthVerifier;
+
+    setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
+
+    LLSD result = httpAdapter->putAndYield(httpRequest, getFlickrConnectURL("/connection"), body, httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        if ( status == LLCore::HttpStatus(HTTP_FOUND) )
+        {
+            std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+            if (location.empty())
+            {
+                LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
+            }
+            else
+            {
+                openFlickrWeb(location);
+            }
+        }
+        else
+        {
+            LL_WARNS("FlickrConnect") << "Connection failed " << status.toString() << LL_ENDL;
+            setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
+            log_flickr_connect_error("Connect", status.getStatus(), status.toString(),
+                result.get("error_code"), result.get("error_description"));
+        }
+    }
+    else
     {
-        LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
+        LL_DEBUGS("FlickrConnect") << "Connect successful. " << LL_ENDL;
+        setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
     }
-    
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("FlickrConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
-        LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
-	}
-    
-	/* virtual */ void httpFailure()
-	{
-		if ( HTTP_FOUND == getStatus() )
-		{
-			const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (location.empty())
-			{
-				LL_WARNS("FlickrConnect") << "Missing Location header " << dumpResponse()
-                << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			}
-			else
-			{
-                LLFlickrConnect::instance().openFlickrWeb(location);
-			}
-		}
-		else
-		{
-			LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
-            LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
-			const LLSD& content = getContent();
-			log_flickr_connect_error("Connect", getStatus(), getReason(),
-                                      content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLFlickrShareResponder : public LLHTTPClient::Responder
+bool LLFlickrConnect::testShareStatus(LLSD &result)
 {
-	LOG_CLASS(LLFlickrShareResponder);
-public:
-    
-	LLFlickrShareResponder()
-	{
-		LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POSTING);
-	}
-	
-	/* virtual */ void httpSuccess()
-	{
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (status)
+        return true;
+
+    if (status == LLCore::HttpStatus(HTTP_FOUND))
+    {
+        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+        if (location.empty())
+        {
+            LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
+        }
+        else
+        {
+            openFlickrWeb(location);
+        }
+    }
+    if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+    {
+        LL_DEBUGS("FlickrConnect") << "Not connected. " << LL_ENDL;
+        connectToFlickr();
+    }
+    else
+    {
+        LL_WARNS("FlickrConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
+        setConnectionState(LLFlickrConnect::FLICKR_POST_FAILED);
+        log_flickr_connect_error("Share", status.getStatus(), status.toString(),
+            result.get("error_code"), result.get("error_description"));
+    }
+    return false;
+}
+
+void LLFlickrConnect::flickrShareCoro(LLSD share)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    setConnectionState(LLFlickrConnect::FLICKR_POSTING);
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, getFlickrConnectURL("/share/photo", true), share, httpOpts);
+
+    if (testShareStatus(result))
+    {
         toast_user_for_flickr_success();
-		LL_DEBUGS("FlickrConnect") << "Post successful. " << dumpResponse() << LL_ENDL;
-        LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POSTED);
-	}
-    
-	/* virtual */ void httpFailure()
-	{
-		if ( HTTP_FOUND == getStatus() )
-		{
-			const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (location.empty())
-			{
-				LL_WARNS("FlickrConnect") << "Missing Location header " << dumpResponse()
-                << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			}
-			else
-			{
-                LLFlickrConnect::instance().openFlickrWeb(location);
-			}
-		}
-		else if ( HTTP_NOT_FOUND == getStatus() )
-		{
-			LLFlickrConnect::instance().connectToFlickr();
-		}
-		else
-		{
-			LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
-            LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POST_FAILED);
-			const LLSD& content = getContent();
-			log_flickr_connect_error("Share", getStatus(), getReason(),
-                                      content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+        LL_DEBUGS("FlickrConnect") << "Post successful. " << LL_ENDL;
+        setConnectionState(LLFlickrConnect::FLICKR_POSTED);
+    }
+
+}
+
+void LLFlickrConnect::flickrShareImageCoro(LLPointer<LLImageFormatted> image, std::string title, std::string description, std::string tags, int safetyLevel)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    std::string imageFormat;
+    if (dynamic_cast<LLImagePNG*>(image.get()))
+    {
+        imageFormat = "png";
+    }
+    else if (dynamic_cast<LLImageJPEG*>(image.get()))
+    {
+        imageFormat = "jpg";
+    }
+    else
+    {
+        LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
+        return;
+    }
+
+    // All this code is mostly copied from LLWebProfile::post()
+    const std::string boundary = "----------------------------0123abcdefab";
+
+    std::string contentType = "multipart/form-data; boundary=" + boundary;
+    httpHeaders->append("Content-Type", contentType.c_str());
+
+    LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); // 
+    LLCore::BufferArrayStream body(raw.get());
+
+    // *NOTE: The order seems to matter.
+    body << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"title\"\r\n\r\n"
+        << title << "\r\n";
+
+    body << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"description\"\r\n\r\n"
+        << description << "\r\n";
+
+    body << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"tags\"\r\n\r\n"
+        << tags << "\r\n";
+
+    body << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"safety_level\"\r\n\r\n"
+        << safetyLevel << "\r\n";
+
+    body << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
+        << "Content-Type: image/" << imageFormat << "\r\n\r\n";
+
+    // Insert the image data.
+    // *FIX: Treating this as a string will probably screw it up ...
+    U8* image_data = image->getData();
+    for (S32 i = 0; i < image->getDataSize(); ++i)
+    {
+        body << image_data[i];
+    }
+
+    body << "\r\n--" << boundary << "--\r\n";
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, getFlickrConnectURL("/share/photo", true), raw, httpOpts, httpHeaders);
+
+    if (testShareStatus(result))
+    {
+        toast_user_for_flickr_success();
+        LL_DEBUGS("FlickrConnect") << "Post successful. " << LL_ENDL;
+        setConnectionState(LLFlickrConnect::FLICKR_POSTED);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLFlickrDisconnectResponder : public LLHTTPClient::Responder
+void LLFlickrConnect::flickrDisconnectCoro()
 {
-	LOG_CLASS(LLFlickrDisconnectResponder);
-public:
- 
-	LLFlickrDisconnectResponder()
-	{
-		LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_DISCONNECTING);
-	}
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
 
-	void setUserDisconnected()
-	{
-		// Clear data
-		LLFlickrConnect::instance().clearInfo();
+    setConnectionState(LLFlickrConnect::FLICKR_DISCONNECTING);
+    httpOpts->setFollowRedirects(false);
 
-		//Notify state change
-		LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
-	}
+    LLSD result = httpAdapter->deleteAndYield(httpRequest, getFlickrConnectURL("/connection"), httpOpts);
 
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("FlickrConnect") << "Disconnect successful. " << dumpResponse() << LL_ENDL;
-		setUserDisconnected();
-	}
-    
-	/* virtual */ void httpFailure()
-	{
-		//User not found so already disconnected
-		if ( HTTP_NOT_FOUND == getStatus() )
-		{
-			LL_DEBUGS("FlickrConnect") << "Already disconnected. " << dumpResponse() << LL_ENDL;
-			setUserDisconnected();
-		}
-		else
-		{
-			LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
-			LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_DISCONNECT_FAILED);
-			const LLSD& content = getContent();
-			log_flickr_connect_error("Disconnect", getStatus(), getReason(),
-                                      content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status && (status != LLCore::HttpStatus(HTTP_NOT_FOUND)))
+    {
+        LL_WARNS("FlickrConnect") << "Disconnect failed!" << LL_ENDL;
+        setConnectionState(LLFlickrConnect::FLICKR_DISCONNECT_FAILED);
+
+        log_flickr_connect_error("Disconnect", status.getStatus(), status.toString(),
+            result.get("error_code"), result.get("error_description"));
+    }
+    else
+    {
+        LL_DEBUGS("FlickrConnect") << "Disconnect successful. " << LL_ENDL;
+        clearInfo();
+        setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLFlickrConnectedResponder : public LLHTTPClient::Responder
+void LLFlickrConnect::flickrConnectedCoro(bool autoConnect)
 {
-	LOG_CLASS(LLFlickrConnectedResponder);
-public:
-    
-	LLFlickrConnectedResponder(bool auto_connect) : mAutoConnect(auto_connect)
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
+
+    httpOpts->setFollowRedirects(false);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, getFlickrConnectURL("/connection", true), httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
     {
-		LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
+        if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+        {
+            LL_DEBUGS("FlickrConnect") << "Not connected. " << LL_ENDL;
+            if (autoConnect)
+            {
+                connectToFlickr();
+            }
+            else
+            {
+                setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
+            }
+        }
+        else
+        {
+            LL_WARNS("FlickrConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
+
+            setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
+            log_flickr_connect_error("Connected", status.getStatus(), status.toString(),
+                result.get("error_code"), result.get("error_description"));
+        }
     }
-    
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("FlickrConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
-        LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
-	}
-    
-	/* virtual */ void httpFailure()
-	{
-		// show the facebook login page if not connected yet
-		if ( HTTP_NOT_FOUND == getStatus() )
-		{
-			LL_DEBUGS("FlickrConnect") << "Not connected. " << dumpResponse() << LL_ENDL;
-			if (mAutoConnect)
-			{
-                LLFlickrConnect::instance().connectToFlickr();
-			}
-			else
-			{
-                LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
-			}
-		}
-		else
-		{
-			LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
-            LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
-			const LLSD& content = getContent();
-			log_flickr_connect_error("Connected", getStatus(), getReason(),
-                                      content.get("error_code"), content.get("error_description"));
-		}
-	}
-    
-private:
-	bool mAutoConnect;
-};
+    else
+    {
+        LL_DEBUGS("FlickrConnect") << "Connect successful. " << LL_ENDL;
+        setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
+    }
+
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLFlickrInfoResponder : public LLHTTPClient::Responder
+void LLFlickrConnect::flickrInfoCoro()
 {
-	LOG_CLASS(LLFlickrInfoResponder);
-public:
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
 
-	/* virtual */ void httpSuccess()
-	{
-		LL_INFOS("FlickrConnect") << "Flickr: Info received" << LL_ENDL;
-		LL_DEBUGS("FlickrConnect") << "Getting Flickr info successful. " << dumpResponse() << LL_ENDL;
-        LLFlickrConnect::instance().storeInfo(getContent());
-	}
-    
-	/* virtual */ void httpFailure()
-	{
-		if ( HTTP_FOUND == getStatus() )
-		{
-			const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (location.empty())
-			{
-				LL_WARNS("FlickrConnect") << "Missing Location header " << dumpResponse()
-                << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			}
-			else
-			{
-                LLFlickrConnect::instance().openFlickrWeb(location);
-			}
-		}
-		else
-		{
-			LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
-			const LLSD& content = getContent();
-			log_flickr_connect_error("Info", getStatus(), getReason(),
-                                      content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, getFlickrConnectURL("/info", true), httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (status == LLCore::HttpStatus(HTTP_FOUND))
+    {
+        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+        if (location.empty())
+        {
+            LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
+        }
+        else
+        {
+            openFlickrWeb(location);
+        }
+    }
+    else if (!status)
+    {
+        LL_WARNS("FlickrConnect") << "Flickr Info failed: " << status.toString() << LL_ENDL;
+        log_flickr_connect_error("Info", status.getStatus(), status.toString(),
+            result.get("error_code"), result.get("error_description"));
+    }
+    else
+    {
+        LL_INFOS("FlickrConnect") << "Flickr: Info received" << LL_ENDL;
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        storeInfo(result);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
@@ -341,36 +437,28 @@ std::string LLFlickrConnect::getFlickrConnectURL(const std::string& route, bool
 
 void LLFlickrConnect::connectToFlickr(const std::string& request_token, const std::string& oauth_verifier)
 {
-	LLSD body;
-	if (!request_token.empty())
-		body["request_token"] = request_token;
-	if (!oauth_verifier.empty())
-		body["oauth_verifier"] = oauth_verifier;
-    
-	LLHTTPClient::put(getFlickrConnectURL("/connection"), body, new LLFlickrConnectResponder());
+    LLCoros::instance().launch("LLFlickrConnect::flickrConnectCoro",
+        boost::bind(&LLFlickrConnect::flickrConnectCoro, this, request_token, oauth_verifier));
 }
 
 void LLFlickrConnect::disconnectFromFlickr()
 {
-	LLHTTPClient::del(getFlickrConnectURL("/connection"), new LLFlickrDisconnectResponder());
+    LLCoros::instance().launch("LLFlickrConnect::flickrDisconnectCoro",
+        boost::bind(&LLFlickrConnect::flickrDisconnectCoro, this));
 }
 
 void LLFlickrConnect::checkConnectionToFlickr(bool auto_connect)
 {
-	const bool follow_redirects = false;
-	const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
-	LLHTTPClient::get(getFlickrConnectURL("/connection", true), new LLFlickrConnectedResponder(auto_connect),
-						LLSD(), timeout, follow_redirects);
+    LLCoros::instance().launch("LLFlickrConnect::flickrConnectedCoro",
+        boost::bind(&LLFlickrConnect::flickrConnectedCoro, this, auto_connect));
 }
 
 void LLFlickrConnect::loadFlickrInfo()
 {
 	if(mRefreshInfo)
 	{
-		const bool follow_redirects = false;
-		const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
-		LLHTTPClient::get(getFlickrConnectURL("/info", true), new LLFlickrInfoResponder(),
-			LLSD(), timeout, follow_redirects);
+        LLCoros::instance().launch("LLFlickrConnect::flickrInfoCoro",
+            boost::bind(&LLFlickrConnect::flickrInfoCoro, this));
 	}
 }
 
@@ -382,74 +470,17 @@ void LLFlickrConnect::uploadPhoto(const std::string& image_url, const std::strin
 	body["description"] = description;
 	body["tags"] = tags;
 	body["safety_level"] = safety_level;
-	
-    // Note: we can use that route for different publish action. We should be able to use the same responder.
-	LLHTTPClient::post(getFlickrConnectURL("/share/photo", true), body, new LLFlickrShareResponder());
+
+    LLCoros::instance().launch("LLFlickrConnect::flickrShareCoro",
+        boost::bind(&LLFlickrConnect::flickrShareCoro, this, body));
 }
 
 void LLFlickrConnect::uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& title, const std::string& description, const std::string& tags, int safety_level)
 {
-	std::string imageFormat;
-	if (dynamic_cast<LLImagePNG*>(image.get()))
-	{
-		imageFormat = "png";
-	}
-	else if (dynamic_cast<LLImageJPEG*>(image.get()))
-	{
-		imageFormat = "jpg";
-	}
-	else
-	{
-		LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
-		return;
-	}
-	
-	// All this code is mostly copied from LLWebProfile::post()
-	const std::string boundary = "----------------------------0123abcdefab";
-
-	LLSD headers;
-	headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
-
-	std::ostringstream body;
-
-	// *NOTE: The order seems to matter.
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"title\"\r\n\r\n"
-			<< title << "\r\n";
-
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"description\"\r\n\r\n"
-			<< description << "\r\n";
-
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"tags\"\r\n\r\n"
-			<< tags << "\r\n";
-
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"safety_level\"\r\n\r\n"
-			<< safety_level << "\r\n";
-
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
-			<< "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
-	// Insert the image data.
-	// *FIX: Treating this as a string will probably screw it up ...
-	U8* image_data = image->getData();
-	for (S32 i = 0; i < image->getDataSize(); ++i)
-	{
-		body << image_data[i];
-	}
-
-	body <<	"\r\n--" << boundary << "--\r\n";
 
-	// postRaw() takes ownership of the buffer and releases it later.
-	size_t size = body.str().size();
-	U8 *data = new U8[size];
-	memcpy(data, body.str().data(), size);
-	
-    // Note: we can use that route for different publish action. We should be able to use the same responder.
-	LLHTTPClient::postRaw(getFlickrConnectURL("/share/photo", true), data, size, new LLFlickrShareResponder(), headers);
+    LLCoros::instance().launch("LLFlickrConnect::flickrShareImageCoro",
+        boost::bind(&LLFlickrConnect::flickrShareImageCoro, this, image, 
+        title, description, tags, safety_level));
 }
 
 void LLFlickrConnect::storeInfo(const LLSD& info)
diff --git a/indra/newview/llflickrconnect.h b/indra/newview/llflickrconnect.h
index b127e6e10405deb936e49b310b555fe1bd29d5da..0155804da0f95e766822374b5e416435de6a9728 100644
--- a/indra/newview/llflickrconnect.h
+++ b/indra/newview/llflickrconnect.h
@@ -30,6 +30,8 @@
 
 #include "llsingleton.h"
 #include "llimage.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
 
 class LLEventPump;
 
@@ -93,6 +95,15 @@ class LLFlickrConnect : public LLSingleton<LLFlickrConnect>
 	static boost::scoped_ptr<LLEventPump> sStateWatcher;
 	static boost::scoped_ptr<LLEventPump> sInfoWatcher;
 	static boost::scoped_ptr<LLEventPump> sContentWatcher;
+
+    bool testShareStatus(LLSD &result);
+    void flickrConnectCoro(std::string requestToken, std::string oauthVerifier);
+    void flickrShareCoro(LLSD share);
+    void flickrShareImageCoro(LLPointer<LLImageFormatted> image, std::string title, std::string description, std::string tags, int safetyLevel);
+    void flickrDisconnectCoro();
+    void flickrConnectedCoro(bool autoConnect);
+    void flickrInfoCoro();
+
 };
 
 #endif // LL_LLFLICKRCONNECT_H
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index b342d8fdf36ef8dd6aa8df30146e57af4d204b29..f58a5881a885b9cac0ff04b3f5c24eddddd29468 100755
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -61,6 +61,7 @@
 #include "stringize.h"
 #include "llsdutil_math.h"
 #include "lleventapi.h"
+#include "llcorehttputil.h"
 
 #if LL_WINDOWS
 #include "lldxhardware.h"
@@ -69,18 +70,6 @@
 extern LLMemoryInfo gSysMemory;
 extern U32 gPacketsIn;
 
-///----------------------------------------------------------------------------
-/// Class LLServerReleaseNotesURLFetcher
-///----------------------------------------------------------------------------
-class LLServerReleaseNotesURLFetcher : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLServerReleaseNotesURLFetcher);
-public:
-	static void startFetch();
-private:
-	/* virtual */ void httpCompleted();
-};
-
 ///----------------------------------------------------------------------------
 /// Class LLFloaterAbout
 ///----------------------------------------------------------------------------
@@ -102,6 +91,9 @@ class LLFloaterAbout
 
 private:
 	void setSupportText(const std::string& server_release_notes_url);
+
+    static void startFetchServerReleaseNotes();
+    static void handleServerReleaseNotes(LLSD results);
 };
 
 
@@ -138,7 +130,7 @@ BOOL LLFloaterAbout::postBuild()
 	{
 		// start fetching server release notes URL
 		setSupportText(LLTrans::getString("RetrievingData"));
-		LLServerReleaseNotesURLFetcher::startFetch();
+        startFetchServerReleaseNotes();
 	}
 	else // not logged in
 	{
@@ -201,6 +193,50 @@ LLSD LLFloaterAbout::getInfo()
 	return LLAppViewer::instance()->getViewerInfo();
 }
 
+/*static*/
+void LLFloaterAbout::startFetchServerReleaseNotes()
+{
+    LLViewerRegion* region = gAgent.getRegion();
+    if (!region) return;
+
+    // We cannot display the URL returned by the ServerReleaseNotes capability
+    // because opening it in an external browser will trigger a warning about untrusted
+    // SSL certificate.
+    // So we query the URL ourselves, expecting to find
+    // an URL suitable for external browsers in the "Location:" HTTP header.
+    std::string cap_url = region->getCapability("ServerReleaseNotes");
+
+    LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(cap_url,
+        &LLFloaterAbout::handleServerReleaseNotes, &LLFloaterAbout::handleServerReleaseNotes);
+
+}
+
+/*static*/
+void LLFloaterAbout::handleServerReleaseNotes(LLSD results)
+{
+    LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about");
+    if (floater_about)
+    {
+        LLSD http_headers;
+        if (results.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS))
+        {
+            LLSD http_results = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+            http_headers = http_results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+        }
+        else
+        {
+            http_headers = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+        }
+        
+        std::string location = http_headers[HTTP_IN_HEADER_LOCATION].asString();
+        if (location.empty())
+        {
+            location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL");
+        }
+        LLAppViewer::instance()->setServerReleaseNotesURL(location);
+    }
+}
+
 class LLFloaterAboutListener: public LLEventAPI
 {
 public:
@@ -264,40 +300,3 @@ void LLFloaterAboutUtil::registerFloater()
 		&LLFloaterReg::build<LLFloaterAbout>);
 
 }
-
-///----------------------------------------------------------------------------
-/// Class LLServerReleaseNotesURLFetcher implementation
-///----------------------------------------------------------------------------
-// static
-void LLServerReleaseNotesURLFetcher::startFetch()
-{
-	LLViewerRegion* region = gAgent.getRegion();
-	if (!region) return;
-
-	// We cannot display the URL returned by the ServerReleaseNotes capability
-	// because opening it in an external browser will trigger a warning about untrusted
-	// SSL certificate.
-	// So we query the URL ourselves, expecting to find
-	// an URL suitable for external browsers in the "Location:" HTTP header.
-	std::string cap_url = region->getCapability("ServerReleaseNotes");
-	LLHTTPClient::get(cap_url, new LLServerReleaseNotesURLFetcher);
-}
-
-// virtual
-void LLServerReleaseNotesURLFetcher::httpCompleted()
-{
-	LL_DEBUGS("ServerReleaseNotes") << dumpResponse() 
-									<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
-
-	LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about");
-	if (floater_about)
-	{
-		std::string location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-		if (location.empty())
-		{
-			location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL");
-		}
-		LLAppViewer::instance()->setServerReleaseNotesURL(location);
-	}
-}
-
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index b661fed2760f97dda952ca856ca09b048b51cadb..56619e818af2526f399da48e11796809130da5c5 100755
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -57,6 +57,7 @@
 #include "llsdutil.h"
 #include "llsdutil_math.h"
 #include "lltrans.h"
+#include "llcorehttputil.h"
 
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
@@ -361,7 +362,10 @@ void LLFloaterAuction::doResetParcel()
 
 		LL_INFOS() << "Sending parcel update to reset for auction via capability to: "
 			<< mParcelUpdateCapUrl << LL_ENDL;
-		LLHTTPClient::post(mParcelUpdateCapUrl, body, new LLHTTPClient::Responder());
+
+        LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
+            "Parcel reset for auction",
+            "Parcel not set for auction.");
 
 		// Send a message to clear the object return time
 		LLMessageSystem *msg = gMessageSystem;
@@ -490,7 +494,10 @@ void LLFloaterAuction::doSellToAnyone()
 
 		LL_INFOS() << "Sending parcel update to sell to anyone for L$1 via capability to: "
 			<< mParcelUpdateCapUrl << LL_ENDL;
-		LLHTTPClient::post(mParcelUpdateCapUrl, body, new LLHTTPClient::Responder());
+
+        LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
+            "Parcel set as sell to everyone.",
+            "Parcel sell to everyone failed.");
 
 		// clean up floater, and get out
 		cleanupAndClose();
diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
index 6e56e929df606d194bd889db9b4b91c1422b4ebd..5830f2f711cca1f0ddc236b0672a0f9fe7b6b7e2 100755
--- a/indra/newview/llfloaterautoreplacesettings.cpp
+++ b/indra/newview/llfloaterautoreplacesettings.cpp
@@ -36,7 +36,6 @@
 #include "llcolorswatch.h"
 #include "llcombobox.h"
 #include "llview.h"
-#include "llhttpclient.h"
 #include "llbufferstream.h"
 #include "llcheckboxctrl.h"
 #include "llviewercontrol.h"
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 566a3c9cd3950dc4b90241c58312f1a536976f2c..2824038f7766a0126b02c099577543b8f1ff5445 100755
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -42,7 +42,6 @@
 #include "llavatarnamecache.h"	// IDEVO
 #include "llbutton.h"
 #include "llcachename.h"
-#include "llhttpclient.h"		// IDEVO
 #include "lllineeditor.h"
 #include "llscrolllistctrl.h"
 #include "llscrolllistitem.h"
@@ -52,6 +51,7 @@
 #include "llfocusmgr.h"
 #include "lldraghandle.h"
 #include "message.h"
+#include "llcorehttputil.h"
 
 //#include "llsdserialize.h"
 
@@ -456,39 +456,33 @@ BOOL LLFloaterAvatarPicker::visibleItemsSelected() const
 	return FALSE;
 }
 
-class LLAvatarPickerResponder : public LLHTTPClient::Responder
+/*static*/
+void LLFloaterAvatarPicker::findCoro(std::string url, LLUUID queryID, std::string name)
 {
-	LOG_CLASS(LLAvatarPickerResponder);
-public:
-	LLUUID mQueryID;
-    std::string mName;
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
 
-	LLAvatarPickerResponder(const LLUUID& id, const std::string& name) : mQueryID(id), mName(name) { }
+    LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
 
-protected:
-	/*virtual*/ void httpCompleted()
-	{
-		//std::ostringstream ss;
-		//LLSDSerialize::toPrettyXML(content, ss);
-		//LL_INFOS() << ss.str() << LL_ENDL;
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (status || (status == LLCore::HttpStatus(HTTP_BAD_REQUEST)))
+    {
+        LLFloaterAvatarPicker* floater =
+            LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", name);
+        if (floater)
+        {
+            result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+            floater->processResponse(queryID, result);
+        }
+    }
+}
 
-		// in case of invalid characters, the avatar picker returns a 400
-		// just set it to process so it displays 'not found'
-		if (isGoodStatus() || getStatus() == HTTP_BAD_REQUEST)
-		{
-			LLFloaterAvatarPicker* floater =
-				LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", mName);
-			if (floater)
-			{
-				floater->processResponse(mQueryID, getContent());
-			}
-		}
-		else
-		{
-			LL_WARNS() << "avatar picker failed " << dumpResponse() << LL_ENDL;
-		}
-	}
-};
 
 void LLFloaterAvatarPicker::find()
 {
@@ -517,7 +511,9 @@ void LLFloaterAvatarPicker::find()
 		std::replace(text.begin(), text.end(), '.', ' ');
 		url += LLURI::escape(text);
 		LL_INFOS() << "avatar picker " << url << LL_ENDL;
-		LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID, getKey().asString()));
+
+        LLCoros::instance().launch("LLFloaterAvatarPicker::findCoro",
+            boost::bind(&LLFloaterAvatarPicker::findCoro, url, mQueryID, getKey().asString()));
 	}
 	else
 	{
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index ed3e51c56f163823a8dfdd6fc1c1c4132638672f..fbee61b0549ca432893012322f24735e231f4869 100755
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -28,6 +28,8 @@
 #define LLFLOATERAVATARPICKER_H
 
 #include "llfloater.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 #include <vector>
 
@@ -84,6 +86,7 @@ class LLFloaterAvatarPicker :public LLFloater
 	void populateFriend();
 	BOOL visibleItemsSelected() const; // Returns true if any items in the current tab are selected.
 
+    static void findCoro(std::string url, LLUUID mQueryID, std::string mName);
 	void find();
 	void setAllowMultiple(BOOL allow_multiple);
 	LLScrollListCtrl* getActiveList();
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index 669ffa7c599814253c6324b38128463aa9a5b55f..39b5a40efc77e37d63b7231b894fa226daf96f88 100755
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -992,20 +992,16 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata)
 			{
 				std::string name = floaterp->getChild<LLUICtrl>("name_form")->getValue().asString();
 				std::string desc = floaterp->getChild<LLUICtrl>("description_form")->getValue().asString();
-				LLAssetStorage::LLStoreAssetCallback callback = NULL;
 				S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
-				void *userdata = NULL;
-				upload_new_resource(floaterp->mTransactionID, // tid
-						    LLAssetType::AT_ANIMATION,
-						    name,
-						    desc,
-						    0,
-						    LLFolderType::FT_NONE,
-						    LLInventoryType::IT_ANIMATION,
-						    LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
-						    name,
-						    callback, expected_upload_cost, userdata);
 
+                NewResourceUploadInfo::ptr_t assetUpdloadInfo(new NewResourceUploadInfo(
+                    floaterp->mTransactionID, LLAssetType::AT_ANIMATION,
+                    name, desc, 0,
+                    LLFolderType::FT_NONE, LLInventoryType::IT_ANIMATION,
+                    LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
+                    expected_upload_cost));
+
+                upload_new_resource(assetUpdloadInfo);
 			}
 			else
 			{
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
deleted file mode 100755
index 596e8c0dbef7b88f7b28dfcf329549926a08d1c9..0000000000000000000000000000000000000000
--- a/indra/newview/llfloaterdisplayname.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/** 
- * @file llfloaterdisplayname.cpp
- * @author Leyla Farazha
- * @brief Implementation of the LLFloaterDisplayName class.
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-
-#include "llviewerprecompiledheaders.h"
-#include "llfloaterreg.h"
-#include "llfloater.h"
-
-#include "llnotificationsutil.h"
-#include "llviewerdisplayname.h"
-
-#include "llnotifications.h"
-#include "llfloaterdisplayname.h"
-#include "llavatarnamecache.h"
-
-#include "llagent.h"
-
-
-class LLFloaterDisplayName : public LLFloater
-{
-public:
-	LLFloaterDisplayName(const LLSD& key);
-	virtual ~LLFloaterDisplayName() { }
-	/*virtual*/	BOOL	postBuild();
-	void onSave();
-	void onReset();
-	void onCancel();
-	/*virtual*/ void onOpen(const LLSD& key);
-	
-private:
-	
-	void onCacheSetName(bool success,
-										  const std::string& reason,
-										  const LLSD& content);
-};
-
-LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
-	LLFloater(key)
-{
-}
-
-void LLFloaterDisplayName::onOpen(const LLSD& key)
-{
-	getChild<LLUICtrl>("display_name_editor")->clear();
-	getChild<LLUICtrl>("display_name_confirm")->clear();
-
-	LLAvatarName av_name;
-	LLAvatarNameCache::get(gAgent.getID(), &av_name);
-
-	F64 now_secs = LLDate::now().secondsSinceEpoch();
-
-	if (now_secs < av_name.mNextUpdate)
-	{
-		// ...can't update until some time in the future
-		F64 next_update_local_secs =
-			av_name.mNextUpdate - LLStringOps::getLocalTimeOffset();
-		LLDate next_update_local(next_update_local_secs);
-		// display as "July 18 12:17 PM"
-		std::string next_update_string =
-		next_update_local.toHTTPDateString("%B %d %I:%M %p");
-		getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string);
-		getChild<LLUICtrl>("lockout_text")->setVisible(true);
-		getChild<LLUICtrl>("save_btn")->setEnabled(false);
-		getChild<LLUICtrl>("display_name_editor")->setEnabled(false);
-		getChild<LLUICtrl>("display_name_confirm")->setEnabled(false);
-		getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE);
-		
-	}
-	else
-	{
-		getChild<LLUICtrl>("lockout_text")->setVisible(false);
-		getChild<LLUICtrl>("save_btn")->setEnabled(true);
-		getChild<LLUICtrl>("display_name_editor")->setEnabled(true);
-		getChild<LLUICtrl>("display_name_confirm")->setEnabled(true);
-
-	}
-}
-
-BOOL LLFloaterDisplayName::postBuild()
-{
-	getChild<LLUICtrl>("reset_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onReset, this));	
-	getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));	
-	getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));	
-	
-	center();
-
-	return TRUE;
-}
-
-void LLFloaterDisplayName::onCacheSetName(bool success,
-										  const std::string& reason,
-										  const LLSD& content)
-{
-	if (success)
-	{
-		// Inform the user that the change took place, but will take a while
-		// to percolate.
-		LLSD args;
-		args["DISPLAY_NAME"] = content["display_name"];
-		LLNotificationsUtil::add("SetDisplayNameSuccess", args);
-		return;
-	}
-
-	// Request failed, notify the user
-	std::string error_tag = content["error_tag"].asString();
-	LL_INFOS() << "set name failure error_tag " << error_tag << LL_ENDL;
-
-	// We might have a localized string for this message
-	// error_args will usually be empty from the server.
-	if (!error_tag.empty()
-		&& LLNotifications::getInstance()->templateExists(error_tag))
-	{
-		LLNotificationsUtil::add(error_tag);
-		return;
-	}
-
-	// The server error might have a localized message for us
-	std::string lang_code = LLUI::getLanguage();
-	LLSD error_desc = content["error_description"];
-	if (error_desc.has( lang_code ))
-	{
-		LLSD args;
-		args["MESSAGE"] = error_desc[lang_code].asString();
-		LLNotificationsUtil::add("GenericAlert", args);
-		return;
-	}
-
-	// No specific error, throw a generic one
-	LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
-}
-
-void LLFloaterDisplayName::onCancel()
-{
-	setVisible(false);
-}
-
-void LLFloaterDisplayName::onReset()
-{
-	if (LLAvatarNameCache::hasNameLookupURL())
-	{
-		LLViewerDisplayName::set("",boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
-	}	
-	else
-	{
-		LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
-	}
-	
-	setVisible(false);
-}
-
-
-void LLFloaterDisplayName::onSave()
-{
-	std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
-	std::string display_name_confirm = getChild<LLUICtrl>("display_name_confirm")->getValue().asString();
-
-	if (display_name_utf8.compare(display_name_confirm))
-	{
-		LLNotificationsUtil::add("SetDisplayNameMismatch");
-		return;
-	}
-
-	const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
-	LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);
-	if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH)
-	{
-		LLSD args;
-		args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH);
-		LLNotificationsUtil::add("SetDisplayNameFailedLength", args);
-		return;
-	}
-	
-	if (LLAvatarNameCache::hasNameLookupURL())
-	{
-		LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));	
-	}
-	else
-	{
-		LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
-	}
-
-	setVisible(false);
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// LLInspectObjectUtil
-//////////////////////////////////////////////////////////////////////////////
-void LLFloaterDisplayNameUtil::registerFloater()
-{
-	LLFloaterReg::add("display_name", "floater_display_name.xml",
-					  &LLFloaterReg::build<LLFloaterDisplayName>);
-}
diff --git a/indra/newview/llfloaterdisplayname.h b/indra/newview/llfloaterdisplayname.h
deleted file mode 100755
index a00bf56712ce3dfbed1707f92ff971d4cfa71446..0000000000000000000000000000000000000000
--- a/indra/newview/llfloaterdisplayname.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/** 
- * @file llfloaterdisplayname.h
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LLFLOATERDISPLAYNAME_H
-#define LLFLOATERDISPLAYNAME_H
-
-
-namespace LLFloaterDisplayNameUtil
-{
-	// Register with LLFloaterReg
-	void registerFloater();
-}
-
-
-
-#endif
diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp
index 8908626de6a737aa7cd46ef32ed00f51b76a42ac..003a22fa0418b4c8f921eee56544fb86d56fd815 100755
--- a/indra/newview/llfloaterhoverheight.cpp
+++ b/indra/newview/llfloaterhoverheight.cpp
@@ -31,7 +31,6 @@
 #include "llsliderctrl.h"
 #include "llviewercontrol.h"
 #include "llsdserialize.h"
-#include "llhttpclient.h"
 #include "llagent.h"
 #include "llviewerregion.h"
 #include "llvoavatarself.h"
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index fc7fcf3ab9b3328574a6847787d8bab4f059af04..6623ce0f807ee910d2a150f0c8e4f31565d00d12 100755
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -41,7 +41,6 @@
 #include "llchicletbar.h"
 #include "lldonotdisturbnotificationstorage.h"
 #include "llfloaterreg.h"
-#include "llhttpclient.h"
 #include "llfloateravatarpicker.h"
 #include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
 #include "llinventoryfunctions.h"
@@ -62,6 +61,7 @@
 #include "llviewerchat.h"
 #include "llnotificationmanager.h"
 #include "llautoreplace.h"
+#include "llcorehttputil.h"
 
 const F32 ME_TYPING_TIMEOUT = 4.0f;
 const F32 OTHER_TYPING_TIMEOUT = 9.0f;
@@ -1178,26 +1178,6 @@ BOOL LLFloaterIMSession::isInviteAllowed() const
 			 || mIsP2PChat);
 }
 
-class LLSessionInviteResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLSessionInviteResponder);
-public:
-	LLSessionInviteResponder(const LLUUID& session_id)
-	{
-		mSessionID = session_id;
-	}
-
-protected:
-	void httpFailure()
-	{
-		LL_WARNS() << "Error inviting all agents to session " << dumpResponse() << LL_ENDL;
-		//throw something back to the viewer here?
-	}
-
-private:
-	LLUUID mSessionID;
-};
-
 BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids)
 {
 	LLViewerRegion* region = gAgent.getRegion();
@@ -1221,7 +1201,9 @@ BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids)
 			}
 			data["method"] = "invite";
 			data["session-id"] = mSessionID;
-			LLHTTPClient::post(url,	data,new LLSessionInviteResponder(mSessionID));
+
+            LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data,
+                "Session invite sent", "Session invite failed");
 		}
 		else
 		{
diff --git a/indra/newview/llfloatermodeluploadbase.cpp b/indra/newview/llfloatermodeluploadbase.cpp
index 22a8ac47057b636530235ff15322ec57116757ff..e2f84fd990466c76fc7a4786307f614ca57b61c9 100755
--- a/indra/newview/llfloatermodeluploadbase.cpp
+++ b/indra/newview/llfloatermodeluploadbase.cpp
@@ -30,6 +30,7 @@
 #include "llagent.h"
 #include "llviewerregion.h"
 #include "llnotificationsutil.h"
+#include "llcorehttputil.h"
 
 LLFloaterModelUploadBase::LLFloaterModelUploadBase(const LLSD& key)
 :LLFloater(key),
@@ -47,7 +48,8 @@ void LLFloaterModelUploadBase::requestAgentUploadPermissions()
 		LL_INFOS()<< typeid(*this).name()
 				  << "::requestAgentUploadPermissions() requesting for upload model permissions from: "
 				  << url << LL_ENDL;
-		LLHTTPClient::get(url, new LLUploadModelPermissionsResponder(getPermObserverHandle()));
+        LLCoros::instance().launch("LLFloaterModelUploadBase::requestAgentUploadPermissionsCoro",
+            boost::bind(&LLFloaterModelUploadBase::requestAgentUploadPermissionsCoro, this, url, getPermObserverHandle()));
 	}
 	else
 	{
@@ -58,3 +60,34 @@ void LLFloaterModelUploadBase::requestAgentUploadPermissions()
 		mHasUploadPerm = true;
 	}
 }
+
+void LLFloaterModelUploadBase::requestAgentUploadPermissionsCoro(std::string url,
+    LLHandle<LLUploadPermissionsObserver> observerHandle)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("MeshUploadFlag", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    LLUploadPermissionsObserver* observer = observerHandle.get();
+
+    if (!observer)
+    { 
+        LL_WARNS("MeshUploadFlag") << "Unable to get observer after call to '" << url << "' aborting." << LL_ENDL;
+    }
+
+    if (!status)
+    {
+        observer->setPermissonsErrorStatus(status.getStatus(), status.getMessage());
+        return;
+    }
+
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+    observer->onPermissionsReceived(result);
+}
diff --git a/indra/newview/llfloatermodeluploadbase.h b/indra/newview/llfloatermodeluploadbase.h
index d9a887968783f06749466660c6aa463e9ad562fc..0d4c834122325d56ab1bc62457ca1fbfc0465ac5 100755
--- a/indra/newview/llfloatermodeluploadbase.h
+++ b/indra/newview/llfloatermodeluploadbase.h
@@ -28,6 +28,8 @@
 #define LL_LLFLOATERMODELUPLOADBASE_H
 
 #include "lluploadfloaterobservers.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
 
 class LLFloaterModelUploadBase : public LLFloater, public LLUploadPermissionsObserver, public LLWholeModelFeeObserver, public LLWholeModelUploadObserver
 {
@@ -54,6 +56,8 @@ class LLFloaterModelUploadBase : public LLFloater, public LLUploadPermissionsObs
 	// requests agent's permissions to upload model
 	void requestAgentUploadPermissions();
 
+    void requestAgentUploadPermissionsCoro(std::string url, LLHandle<LLUploadPermissionsObserver> observerHandle);
+
 	std::string mUploadModelUrl;
 	bool mHasUploadPerm;
 };
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index 0cca715fe25d94ebd2673c37f010d838ffb80df5..4960ecf5fe1a87df172308f5da58c46fa9942e4c 100755
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -164,6 +164,19 @@ void LLFloaterNameDesc::onBtnOK( )
 	void *nruserdata = NULL;
 	std::string display_name = LLStringUtil::null;
 
+    NewResourceUploadInfo::ptr_t uploadInfo(new NewFileResourceUploadInfo(
+            mFilenameAndPath,
+            getChild<LLUICtrl>("name_form")->getValue().asString(), 
+            getChild<LLUICtrl>("description_form")->getValue().asString(), 0,
+            LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+            LLFloaterPerms::getNextOwnerPerms("Uploads"),
+            LLFloaterPerms::getGroupPerms("Uploads"),
+            LLFloaterPerms::getEveryonePerms("Uploads"),
+            expected_upload_cost));
+
+    upload_new_resource(uploadInfo, callback, nruserdata);
+
+#if 0
 	upload_new_resource(mFilenameAndPath, // file
 			    getChild<LLUICtrl>("name_form")->getValue().asString(), 
 			    getChild<LLUICtrl>("description_form")->getValue().asString(), 
@@ -172,6 +185,8 @@ void LLFloaterNameDesc::onBtnOK( )
 				LLFloaterPerms::getGroupPerms("Uploads"),
 				LLFloaterPerms::getEveryonePerms("Uploads"),
 			    display_name, callback, expected_upload_cost, nruserdata);
+#endif
+
 	closeFloater(false);
 }
 
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 042cf470704a5fe27e937245e3a6930e11b76764..16bb449fdb8e790812985e5485a2bcee3c6b6e94 100755
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -37,6 +37,7 @@
 #include "llnotificationsutil.h"
 #include "llsdserialize.h"
 #include "llvoavatar.h"
+#include "llcorehttputil.h"
 
 LLFloaterPerms::LLFloaterPerms(const LLSD& seed)
 : LLFloater(seed)
@@ -166,41 +167,6 @@ void LLFloaterPermsDefault::onCommitCopy(const LLSD& user_data)
 	xfer->setEnabled(copyable);
 }
 
-class LLFloaterPermsResponder : public LLHTTPClient::Responder
-{
-public:
-	LLFloaterPermsResponder(): LLHTTPClient::Responder() {}
-private:
-	static	std::string sPreviousReason;
-
-	void httpFailure()
-	{
-		const std::string& reason = getReason();
-		// Do not display the same error more than once in a row
-		if (reason != sPreviousReason)
-		{
-			sPreviousReason = reason;
-			LLSD args;
-			args["REASON"] = reason;
-			LLNotificationsUtil::add("DefaultObjectPermissions", args);
-		}
-	}
-
-	void httpSuccess()
-	{
-		//const LLSD& content = getContent();
-		//dump_sequential_xml("perms_responder_result.xml", content);
-
-		// Since we have had a successful POST call be sure to display the next error message
-		// even if it is the same as a previous one.
-		sPreviousReason = "";
-		LLFloaterPermsDefault::setCapSent(true);
-		LL_INFOS("ObjectPermissionsFloater") << "Default permissions successfully sent to simulator" << LL_ENDL;
-	}
-};
-
-	std::string	LLFloaterPermsResponder::sPreviousReason;
-
 void LLFloaterPermsDefault::sendInitialPerms()
 {
 	if(!mCapSent)
@@ -215,23 +181,8 @@ void LLFloaterPermsDefault::updateCap()
 
 	if(!object_url.empty())
 	{
-		LLSD report = LLSD::emptyMap();
-		report["default_object_perm_masks"]["Group"] =
-			(LLSD::Integer)LLFloaterPerms::getGroupPerms(sCategoryNames[CAT_OBJECTS]);
-		report["default_object_perm_masks"]["Everyone"] =
-			(LLSD::Integer)LLFloaterPerms::getEveryonePerms(sCategoryNames[CAT_OBJECTS]);
-		report["default_object_perm_masks"]["NextOwner"] =
-			(LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]);
-
-        {
-            LL_DEBUGS("ObjectPermissionsFloater") << "Sending default permissions to '"
-                                                  << object_url << "'\n";
-            std::ostringstream sent_perms_log;
-            LLSDSerialize::toPrettyXML(report, sent_perms_log);
-            LL_CONT << sent_perms_log.str() << LL_ENDL;
-        }
-    
-		LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder());
+        LLCoros::instance().launch("LLFloaterPermsDefault::updateCapCoro",
+            boost::bind(&LLFloaterPermsDefault::updateCapCoro, object_url));
 	}
     else
     {
@@ -239,6 +190,57 @@ void LLFloaterPermsDefault::updateCap()
     }
 }
 
+/*static*/
+void LLFloaterPermsDefault::updateCapCoro(std::string url)
+{
+    static std::string previousReason;
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD postData = LLSD::emptyMap();
+    postData["default_object_perm_masks"]["Group"] =
+        (LLSD::Integer)LLFloaterPerms::getGroupPerms(sCategoryNames[CAT_OBJECTS]);
+    postData["default_object_perm_masks"]["Everyone"] =
+        (LLSD::Integer)LLFloaterPerms::getEveryonePerms(sCategoryNames[CAT_OBJECTS]);
+    postData["default_object_perm_masks"]["NextOwner"] =
+        (LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]);
+
+    {
+        LL_DEBUGS("ObjectPermissionsFloater") << "Sending default permissions to '"
+            << url << "'\n";
+        std::ostringstream sent_perms_log;
+        LLSDSerialize::toPrettyXML(postData, sent_perms_log);
+        LL_CONT << sent_perms_log.str() << LL_ENDL;
+    }
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        const std::string& reason = status.toString();
+        // Do not display the same error more than once in a row
+        if (reason != previousReason)
+        {
+            previousReason = reason;
+            LLSD args;
+            args["REASON"] = reason;
+            LLNotificationsUtil::add("DefaultObjectPermissions", args);
+        }
+        return;
+    }
+
+    // Since we have had a successful POST call be sure to display the next error message
+    // even if it is the same as a previous one.
+    previousReason.clear();
+    LLFloaterPermsDefault::setCapSent(true);
+    LL_INFOS("ObjectPermissionsFloater") << "Default permissions successfully sent to simulator" << LL_ENDL;
+}
+
 void LLFloaterPermsDefault::setCapSent(bool cap_sent)
 {
 	mCapSent = cap_sent;
diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h
index 2bb0a19dc1c21db96b11b5b3ec99706e7d54a70f..e866b6de7de11314c6ec44d15854d685227645a5 100755
--- a/indra/newview/llfloaterperms.h
+++ b/indra/newview/llfloaterperms.h
@@ -29,6 +29,8 @@
 #define LL_LLFLOATERPERMPREFS_H
 
 #include "llfloater.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 class LLFloaterPerms : public LLFloater
 {
@@ -80,6 +82,8 @@ enum Categories
 	void refresh();
 
 	static const std::string sCategoryNames[CAT_LAST]; 
+    static void updateCapCoro(std::string url);
+
 
 	// cached values only for implementing cancel.
 	bool mShareWithGroup[CAT_LAST];
diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp
index 40757a4d049dcd1a59e3bdbbad6bcd5ad56e147c..271fb2f9a356559587b09c472c68f820b2289785 100755
--- a/indra/newview/llfloaterregiondebugconsole.cpp
+++ b/indra/newview/llfloaterregiondebugconsole.cpp
@@ -30,11 +30,11 @@
 #include "llfloaterregiondebugconsole.h"
 
 #include "llagent.h"
-#include "llhttpclient.h"
 #include "llhttpnode.h"
 #include "lllineeditor.h"
 #include "lltexteditor.h"
 #include "llviewerregion.h"
+#include "llcorehttputil.h"
 
 // Two versions of the sim console API are supported.
 //
@@ -68,58 +68,6 @@ namespace
 	const std::string CONSOLE_NOT_SUPPORTED(
 		"This region does not support the simulator console.");
 
-	// This responder handles the initial response. Unless error() is called
-	// we assume that the simulator has received our request. Error will be
-	// called if this request times out.
-	class AsyncConsoleResponder : public LLHTTPClient::Responder
-	{
-		LOG_CLASS(AsyncConsoleResponder);
-	protected:
-		/* virtual */
-		void httpFailure()
-		{
-			LL_WARNS("Console") << dumpResponse() << LL_ENDL;
-			sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);
-		}
-	};
-
-	class ConsoleResponder : public LLHTTPClient::Responder
-	{
-		LOG_CLASS(ConsoleResponder);
-	public:
-		ConsoleResponder(LLTextEditor *output) : mOutput(output)
-		{
-		}
-
-	protected:
-		/*virtual*/
-		void httpFailure()
-		{
-			LL_WARNS("Console") << dumpResponse() << LL_ENDL;
-			if (mOutput)
-			{
-				mOutput->appendText(
-					UNABLE_TO_SEND_COMMAND + PROMPT,
-					false);
-			}
-		}
-
-		/*virtual*/
-		void httpSuccess()
-		{
-			const LLSD& content = getContent();
-			LL_DEBUGS("Console") << content << LL_ENDL;
-			if (mOutput)
-			{
-				mOutput->appendText(
-					content.asString() + PROMPT, false);
-			}
-		}
-
-	public:
-		LLTextEditor * mOutput;
-	};
-
 	// This handles responses for console commands sent via the asynchronous
 	// API.
 	class ConsoleResponseNode : public LLHTTPNode
@@ -202,26 +150,57 @@ void LLFloaterRegionDebugConsole::onInput(LLUICtrl* ctrl, const LLSD& param)
 		}
 		else
 		{
-			// Using SimConsole (deprecated)
-			LLHTTPClient::post(
-				url,
-				LLSD(input->getText()),
-				new ConsoleResponder(mOutput));
+            LLSD postData = LLSD(input->getText());
+            LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, postData,
+                boost::bind(&LLFloaterRegionDebugConsole::onConsoleSuccess, this, _1),
+                boost::bind(&LLFloaterRegionDebugConsole::onConsoleError, this, _1));
 		}
 	}
 	else
 	{
-		// Using SimConsoleAsync
-		LLHTTPClient::post(
-			url,
-			LLSD(input->getText()),
-			new AsyncConsoleResponder);
+        LLSD postData = LLSD(input->getText());
+        LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, postData,
+            NULL,
+            boost::bind(&LLFloaterRegionDebugConsole::onAsyncConsoleError, this, _1));
+
 	}
 
 	mOutput->appendText(text, false);
 	input->clear();
 }
 
+void LLFloaterRegionDebugConsole::onAsyncConsoleError(LLSD result)
+{
+    LL_WARNS("Console") << UNABLE_TO_SEND_COMMAND << LL_ENDL;
+    sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);
+}
+
+void LLFloaterRegionDebugConsole::onConsoleError(LLSD result)
+{
+    LL_WARNS("Console") << UNABLE_TO_SEND_COMMAND << LL_ENDL;
+    if (mOutput)
+    {
+        mOutput->appendText(
+            UNABLE_TO_SEND_COMMAND + PROMPT,
+            false);
+    }
+
+}
+
+void LLFloaterRegionDebugConsole::onConsoleSuccess(LLSD result)
+{
+    if (mOutput)
+    {
+        LLSD response = result;
+        if (response.isMap() && response.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT))
+        {
+            response = response[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
+        }
+        mOutput->appendText(
+            response.asString() + PROMPT, false);
+    }
+}
+
 void LLFloaterRegionDebugConsole::onReplyReceived(const std::string& output)
 {
 	mOutput->appendText(output + PROMPT, false);
diff --git a/indra/newview/llfloaterregiondebugconsole.h b/indra/newview/llfloaterregiondebugconsole.h
index fd3af4152e94873d083257bf58a31b6de7e1893a..f55d9649243d1b8f117f441f9ca2c0cde5340c45 100755
--- a/indra/newview/llfloaterregiondebugconsole.h
+++ b/indra/newview/llfloaterregiondebugconsole.h
@@ -31,14 +31,13 @@
 #include <boost/signals2.hpp>
 
 #include "llfloater.h"
-#include "llhttpclient.h"
 
 class LLTextEditor;
 
 typedef boost::signals2::signal<
 	void (const std::string& output)> console_reply_signal_t;
 
-class LLFloaterRegionDebugConsole : public LLFloater, public LLHTTPClient::Responder
+class LLFloaterRegionDebugConsole : public LLFloater
 {
 public:
 	LLFloaterRegionDebugConsole(LLSD const & key);
@@ -56,6 +55,10 @@ class LLFloaterRegionDebugConsole : public LLFloater, public LLHTTPClient::Respo
  private:
 	void onReplyReceived(const std::string& output);
 
+    void onAsyncConsoleError(LLSD result);
+    void onConsoleError(LLSD result);
+    void onConsoleSuccess(LLSD result);
+
 	boost::signals2::connection mReplySignalConnection;
 };
 
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 5d1e01c1f7a864aa5e969e845738f638cfe3e558..37e934429f1bcd0dba2353e6e25eab606846d965 100755
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -97,6 +97,7 @@
 #include "llpanelexperiencepicker.h"
 #include "llexperiencecache.h"
 #include "llpanelexperiences.h"
+#include "llcorehttputil.h"
 
 const S32 TERRAIN_TEXTURE_COUNT = 4;
 const S32 CORNER_COUNT = 4;
@@ -803,30 +804,6 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L
 	return false;
 }
 
-class ConsoleRequestResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(ConsoleRequestResponder);
-protected:
-	/*virtual*/
-	void httpFailure()
-	{
-		LL_WARNS() << "error requesting mesh_rez_enabled " << dumpResponse() << LL_ENDL;
-	}
-};
-
-
-// called if this request times out.
-class ConsoleUpdateResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(ConsoleUpdateResponder);
-protected:
-	/* virtual */
-	void httpFailure()
-	{
-		LL_WARNS() << "error updating mesh enabled region setting " << dumpResponse() << LL_ENDL;
-	}
-};
-
 void LLFloaterRegionInfo::requestMeshRezInfo()
 {
 	std::string sim_console_url = gAgent.getRegion()->getCapability("SimConsoleAsync");
@@ -835,10 +812,8 @@ void LLFloaterRegionInfo::requestMeshRezInfo()
 	{
 		std::string request_str = "get mesh_rez_enabled";
 		
-		LLHTTPClient::post(
-			sim_console_url,
-			LLSD(request_str),
-			new ConsoleRequestResponder);
+        LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(sim_console_url, LLSD(request_str),
+            "Requested mesh_rez_enabled", "Error requesting mesh_rez_enabled");
 	}
 }
 
@@ -874,7 +849,8 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate()
 		body["allow_parcel_changes"] = getChild<LLUICtrl>("allow_parcel_changes_check")->getValue();
 		body["block_parcel_search"] = getChild<LLUICtrl>("block_parcel_search_check")->getValue();
 
-		LLHTTPClient::post(url, body, new LLHTTPClient::Responder());
+        LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+            "Region info update posted.", "Region info update not posted.");
 	}
 	else
 	{
@@ -2303,36 +2279,6 @@ void LLPanelEstateInfo::getEstateOwner()
 }
 */
 
-class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLEstateChangeInfoResponder);
-public:
-	LLEstateChangeInfoResponder(LLPanelEstateInfo* panel)
-	{
-		mpPanel = panel->getHandle();
-	}
-	
-protected:
-	// if we get a normal response, handle it here
-	virtual void httpSuccess()
-	{
-		LL_INFOS("Windlight") << "Successfully committed estate info" << LL_ENDL;
-
-	    // refresh the panel from the database
-		LLPanelEstateInfo* panel = dynamic_cast<LLPanelEstateInfo*>(mpPanel.get());
-		if (panel)
-			panel->refresh();
-	}
-	
-	// if we get an error response
-	virtual void httpFailure()
-	{
-		LL_WARNS("Windlight") << dumpResponse() << LL_ENDL;
-	}
-private:
-	LLHandle<LLPanel> mpPanel;
-};
-
 const std::string LLPanelEstateInfo::getOwnerName() const
 {
 	return getChild<LLUICtrl>("estate_owner")->getValue().asString();
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index e7b49d8553e616c08659227283cd43088819375b..90f115faaf3ef4e1e4063d8263266e5a821a4402 100755
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -36,6 +36,7 @@
 #include "llextendedstatus.h"
 
 #include "llenvmanager.h" // for LLEnvironmentSettings
+#include "lleventcoro.h"
 
 class LLAvatarName;
 class LLDispatcher;
@@ -107,6 +108,8 @@ class LLFloaterRegionInfo : public LLFloater
 	
 	LLFloaterRegionInfo(const LLSD& seed);
 	~LLFloaterRegionInfo();
+
+
 	
 protected:
 	void onTabSelected(const LLSD& param);
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index 5fbdd75e970a829db7ff67265b641bf37e33be9f..14719a77f91df134eb137951201c3730e26316ab 100755
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -50,6 +50,7 @@
 #include "llviewerparcelmgr.h"
 #include "llviewerregion.h"
 #include "llviewerwindow.h"
+#include "llcorehttputil.h"
 
 ///----------------------------------------------------------------------------
 /// LLFloaterScriptLimits
@@ -179,372 +180,6 @@ void LLPanelScriptLimitsInfo::updateChild(LLUICtrl* child_ctr)
 {
 }
 
-///----------------------------------------------------------------------------
-// Responders
-///----------------------------------------------------------------------------
-
-void fetchScriptLimitsRegionInfoResponder::httpSuccess()
-{
-	const LLSD& content = getContent();
-	if (!content.isMap())
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
-	//we don't need to test with a fake respose here (shouldn't anyway)
-
-#ifdef DUMP_REPLIES_TO_LLINFOS
-
-	LLSDNotationStreamer notation_streamer(content);
-	std::ostringstream nice_llsd;
-	nice_llsd << notation_streamer;
-
-	OSMessageBox(nice_llsd.str(), "main cap response:", 0);
-
-	LL_INFOS() << "main cap response:" << content << LL_ENDL;
-
-#endif
-
-	// at this point we have an llsd which should contain ether one or two urls to the services we want.
-	// first we look for the details service:
-	if(content.has("ScriptResourceDetails"))
-	{
-		LLHTTPClient::get(content["ScriptResourceDetails"], new fetchScriptLimitsRegionDetailsResponder(mInfo));
-	}
-	else
-	{
-		LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
-		if(!instance)
-		{
-			LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
-		}
-	}
-
-	// then the summary service:
-	if(content.has("ScriptResourceSummary"))
-	{
-		LLHTTPClient::get(content["ScriptResourceSummary"], new fetchScriptLimitsRegionSummaryResponder(mInfo));
-	}
-}
-
-void fetchScriptLimitsRegionInfoResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-}
-
-void fetchScriptLimitsRegionSummaryResponder::httpSuccess()
-{
-	const LLSD& content_ref = getContent();
-#ifdef USE_FAKE_RESPONSES
-
-	LLSD fake_content;
-	LLSD summary = LLSD::emptyMap();
-	LLSD available = LLSD::emptyArray();
-	LLSD available_urls = LLSD::emptyMap();
-	LLSD available_memory = LLSD::emptyMap();
-	LLSD used = LLSD::emptyArray();
-	LLSD used_urls = LLSD::emptyMap();
-	LLSD used_memory = LLSD::emptyMap();
-
-	used_urls["type"] = "urls";
-	used_urls["amount"] = FAKE_NUMBER_OF_URLS;
-	available_urls["type"] = "urls";
-	available_urls["amount"] = FAKE_AVAILABLE_URLS;
-	used_memory["type"] = "memory";
-	used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY;
-	available_memory["type"] = "memory";
-	available_memory["amount"] = FAKE_AVAILABLE_MEMORY;
-
-//summary response:{'summary':{'available':[{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'},{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'}],'used':[{'amount':i329,'type':'urls'},{'amount':i66741,'type':'memory'}]}}
-
-	used.append(used_urls);
-	used.append(used_memory);
-	available.append(available_urls);
-	available.append(available_memory);
-
-	summary["available"] = available;
-	summary["used"] = used;
-	
-	fake_content["summary"] = summary;
-
-	const LLSD& content = fake_content;
-
-#else
-
-	const LLSD& content = content_ref;
-
-#endif
-
-	if (!content.isMap())
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
-
-
-#ifdef DUMP_REPLIES_TO_LLINFOS
-
-	LLSDNotationStreamer notation_streamer(content);
-	std::ostringstream nice_llsd;
-	nice_llsd << notation_streamer;
-
-	OSMessageBox(nice_llsd.str(), "summary response:", 0);
-
-	LL_WARNS() << "summary response:" << *content << LL_ENDL;
-
-#endif
-
-	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
-	if(!instance)
-	{
-		LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
-	}
-	else
-	{
-		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
-		if(tab)
-		{
-			LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
-			if(panel_memory)
-			{
-				panel_memory->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
-
-				LLButton* btn = panel_memory->getChild<LLButton>("refresh_list_btn");
-				if(btn)
-				{
-					btn->setEnabled(true);
-				}
-
-				panel_memory->setRegionSummary(content);
-			}
-		}
-	}
-}
-
-void fetchScriptLimitsRegionSummaryResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-}
-
-void fetchScriptLimitsRegionDetailsResponder::httpSuccess()
-{
-	const LLSD& content_ref = getContent();
-#ifdef USE_FAKE_RESPONSES
-/*
-Updated detail service, ** denotes field added:
-
-result (map)
-+-parcels (array of maps)
-  +-id (uuid)
-  +-local_id (S32)**
-  +-name (string)
-  +-owner_id (uuid) (in ERS as owner, but owner_id in code)
-  +-objects (array of maps)
-    +-id (uuid)
-    +-name (string)
-	+-owner_id (uuid) (in ERS as owner, in code as owner_id)
-	+-owner_name (sting)**
-	+-location (map)**
-	  +-x (float)
-	  +-y (float)
-	  +-z (float)
-    +-resources (map) (this is wrong in the ERS but right in code)
-      +-type (string)
-      +-amount (int)
-*/
-	LLSD fake_content;
-	LLSD resource = LLSD::emptyMap();
-	LLSD location = LLSD::emptyMap();
-	LLSD object = LLSD::emptyMap();
-	LLSD objects = LLSD::emptyArray();
-	LLSD parcel = LLSD::emptyMap();
-	LLSD parcels = LLSD::emptyArray();
-
-	resource["urls"] = FAKE_NUMBER_OF_URLS;
-	resource["memory"] = FAKE_AMOUNT_OF_MEMORY;
-	
-	location["x"] = 128.0f;
-	location["y"] = 128.0f;
-	location["z"] = 0.0f;
-	
-	object["id"] = LLUUID("d574a375-0c6c-fe3d-5733-da669465afc7");
-	object["name"] = "Gabs fake Object!";
-	object["owner_id"] = LLUUID("8dbf2d41-69a0-4e5e-9787-0c9d297bc570");
-	object["owner_name"] = "Gabs Linden";
-	object["location"] = location;
-	object["resources"] = resource;
-
-	objects.append(object);
-
-	parcel["id"] = LLUUID("da05fb28-0d20-e593-2728-bddb42dd0160");
-	parcel["local_id"] = 42;
-	parcel["name"] = "Gabriel Linden\'s Sub Plot";
-	parcel["objects"] = objects;
-	parcels.append(parcel);
-
-	fake_content["parcels"] = parcels;
-	const LLSD& content = fake_content;
-
-#else
-
-	const LLSD& content = content_ref;
-
-#endif
-
-	if (!content.isMap())
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
-
-#ifdef DUMP_REPLIES_TO_LLINFOS
-
-	LLSDNotationStreamer notation_streamer(content);
-	std::ostringstream nice_llsd;
-	nice_llsd << notation_streamer;
-
-	OSMessageBox(nice_llsd.str(), "details response:", 0);
-
-	LL_INFOS() << "details response:" << content << LL_ENDL;
-
-#endif
-
-	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
-
-	if(!instance)
-	{
-		LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
-	}
-	else
-	{
-		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
-		if(tab)
-		{
-			LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
-			if(panel_memory)
-			{
-				panel_memory->setRegionDetails(content);
-			}
-			else
-			{
-				LL_WARNS() << "Failed to get scriptlimits memory panel" << LL_ENDL;
-			}
-		}
-		else
-		{
-			LL_WARNS() << "Failed to get scriptlimits_panels" << LL_ENDL;
-		}
-	}
-}
-
-void fetchScriptLimitsRegionDetailsResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-}
-
-void fetchScriptLimitsAttachmentInfoResponder::httpSuccess()
-{
-	const LLSD& content_ref = getContent();
-
-#ifdef USE_FAKE_RESPONSES
-
-	// just add the summary, as that's all I'm testing currently!
-	LLSD fake_content = LLSD::emptyMap();
-	LLSD summary = LLSD::emptyMap();
-	LLSD available = LLSD::emptyArray();
-	LLSD available_urls = LLSD::emptyMap();
-	LLSD available_memory = LLSD::emptyMap();
-	LLSD used = LLSD::emptyArray();
-	LLSD used_urls = LLSD::emptyMap();
-	LLSD used_memory = LLSD::emptyMap();
-
-	used_urls["type"] = "urls";
-	used_urls["amount"] = FAKE_NUMBER_OF_URLS;
-	available_urls["type"] = "urls";
-	available_urls["amount"] = FAKE_AVAILABLE_URLS;
-	used_memory["type"] = "memory";
-	used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY;
-	available_memory["type"] = "memory";
-	available_memory["amount"] = FAKE_AVAILABLE_MEMORY;
-
-	used.append(used_urls);
-	used.append(used_memory);
-	available.append(available_urls);
-	available.append(available_memory);
-
-	summary["available"] = available;
-	summary["used"] = used;
-	
-	fake_content["summary"] = summary;
-	fake_content["attachments"] = content_ref["attachments"];
-
-	const LLSD& content = fake_content;
-
-#else
-
-	const LLSD& content = content_ref;
-
-#endif
-
-	if (!content.isMap())
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
-
-#ifdef DUMP_REPLIES_TO_LLINFOS
-
-	LLSDNotationStreamer notation_streamer(content);
-	std::ostringstream nice_llsd;
-	nice_llsd << notation_streamer;
-
-	OSMessageBox(nice_llsd.str(), "attachment response:", 0);
-	
-	LL_INFOS() << "attachment response:" << content << LL_ENDL;
-
-#endif
-
-	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
-
-	if(!instance)
-	{
-		LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
-	}
-	else
-	{
-		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
-		if(tab)
-		{
-			LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel");
-			if(panel)
-			{
-				panel->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
-
-				LLButton* btn = panel->getChild<LLButton>("refresh_list_btn");
-				if(btn)
-				{
-					btn->setEnabled(true);
-				}
-			
-				panel->setAttachmentDetails(content);
-			}
-			else
-			{
-				LL_WARNS() << "Failed to get script_limits_my_avatar_panel" << LL_ENDL;
-			}
-		}
-		else
-		{
-			LL_WARNS() << "Failed to get scriptlimits_panels" << LL_ENDL;
-		}
-	}
-}
-
-void fetchScriptLimitsAttachmentInfoResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-}
-
 ///----------------------------------------------------------------------------
 // Memory Panel
 ///----------------------------------------------------------------------------
@@ -564,12 +199,8 @@ BOOL LLPanelScriptLimitsRegionMemory::getLandScriptResources()
 	std::string url = gAgent.getRegion()->getCapability("LandResources");
 	if (!url.empty())
 	{
-		body["parcel_id"] = mParcelId;
-
-		LLSD info;
-		info["parcel_id"] = mParcelId;
-		LLHTTPClient::post(url, body, new fetchScriptLimitsRegionInfoResponder(info));
-				
+        LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro",
+            boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro, this, url));
 		return TRUE;
 	}
 	else
@@ -578,6 +209,147 @@ BOOL LLPanelScriptLimitsRegionMemory::getLandScriptResources()
 	}
 }
 
+void LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptResourcesCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD postData;
+
+    postData["parcel_id"] = mParcelId;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS() << "Failed to get script resource info" << LL_ENDL;
+        return;
+    }
+
+    // We could retrieve these sequentially inline from this coroutine. But 
+    // since the original code retrieved them in parallel I'll spawn two 
+    // coroutines to do the retrieval. 
+
+    // The summary service:
+    if (result.has("ScriptResourceSummary"))
+    {
+        std::string urlResourceSummary = result["ScriptResourceSummary"].asString();
+        LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro",
+            boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro, this, urlResourceSummary));
+    }
+
+    if (result.has("ScriptResourceDetails"))
+    {
+        std::string urlResourceDetails = result["ScriptResourceDetails"].asString();
+        LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro",
+            boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro, this, urlResourceDetails));
+    }
+
+   
+}
+
+void LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptSummaryCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS() << "Unable to retrieve script summary." << LL_ENDL;
+        return;
+    }
+
+    LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
+    if (!instance)
+    {
+        LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
+        return;
+    }
+
+    LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
+    if (!tab)
+    {
+        LL_WARNS() << "Unable to access script limits tab" << LL_ENDL;
+        return;
+    }
+
+    LLPanelScriptLimitsRegionMemory* panelMemory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
+    if (!panelMemory)
+    {
+        LL_WARNS() << "Unable to get memory panel." << LL_ENDL;
+        return;
+    }
+
+    panelMemory->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
+
+    LLButton* btn = panelMemory->getChild<LLButton>("refresh_list_btn");
+    if (btn)
+    {
+        btn->setEnabled(true);
+    }
+
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+    panelMemory->setRegionSummary(result);
+
+}
+
+void LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptDetailsCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS() << "Unable to retrieve script details." << LL_ENDL;
+        return;
+    }
+
+    LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
+
+    if (!instance)
+    {
+        LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
+        return;
+    }
+
+    LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
+    if (!tab)
+    {
+        LL_WARNS() << "Unable to access script limits tab" << LL_ENDL;
+        return;
+    }
+
+    LLPanelScriptLimitsRegionMemory* panelMemory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
+
+    if (!panelMemory)
+    {
+        LL_WARNS() << "Unable to get memory panel." << LL_ENDL;
+        return;
+    }
+
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+    panelMemory->setRegionDetails(result);
+}
+
 void LLPanelScriptLimitsRegionMemory::processParcelInfo(const LLParcelData& parcel_data)
 {
 	if(!getLandScriptResources())
@@ -935,17 +707,8 @@ BOOL LLPanelScriptLimitsRegionMemory::StartRequestChain()
 		std::string url = region->getCapability("RemoteParcelRequest");
 		if (!url.empty())
 		{
-			body["location"] = ll_sd_from_vector3(parcel_center);
-			if (!region_id.isNull())
-			{
-				body["region_id"] = region_id;
-			}
-			if (!pos_global.isExactlyZero())
-			{
-				U64 region_handle = to_region_handle(pos_global);
-				body["region_handle"] = ll_sd_from_U64(region_handle);
-			}
-			LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
+            LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url, 
+                region_id, parcel_center, pos_global, getObserverHandle());
 		}
 		else
 		{
@@ -1183,7 +946,8 @@ BOOL LLPanelScriptLimitsAttachment::requestAttachmentDetails()
 	std::string url = gAgent.getRegion()->getCapability("AttachmentResources");
 	if (!url.empty())
 	{
-		LLHTTPClient::get(url, body, new fetchScriptLimitsAttachmentInfoResponder());
+        LLCoros::instance().launch("LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro",
+            boost::bind(&LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro, this, url));
 		return TRUE;
 	}
 	else
@@ -1192,6 +956,59 @@ BOOL LLPanelScriptLimitsAttachment::requestAttachmentDetails()
 	}
 }
 
+void LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS() << "Unable to retrieve attachment limits." << LL_ENDL;
+        return;
+    }
+
+    LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
+
+    if (!instance)
+    {
+        LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
+        return;
+    }
+
+    LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
+    if (!tab)
+    {
+        LL_WARNS() << "Failed to get scriptlimits_panels" << LL_ENDL;
+        return;
+    }
+
+    LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel");
+    if (!panel)
+    {
+        LL_WARNS() << "Failed to get script_limits_my_avatar_panel" << LL_ENDL;
+        return;
+    }
+
+    panel->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
+
+    LLButton* btn = panel->getChild<LLButton>("refresh_list_btn");
+    if (btn)
+    {
+        btn->setEnabled(true);
+    }
+
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+    panel->setAttachmentDetails(result);
+}
+
+
 void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content)
 {
 	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index 5ba0185d329e2e132c54fefabf1edb85305f160e..e3cbbd185fc64b73d8b4f61ce7e7d4ee6f776c9e 100755
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -33,6 +33,8 @@
 #include "llhost.h"
 #include "llpanel.h"
 #include "llremoteparcelrequest.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 class LLPanelScriptLimitsInfo;
 class LLTabContainer;
@@ -79,57 +81,6 @@ class LLPanelScriptLimitsInfo : public LLPanel
 	LLHost mHost;
 };
 
-/////////////////////////////////////////////////////////////////////////////
-// Responders
-/////////////////////////////////////////////////////////////////////////////
-
-class fetchScriptLimitsRegionInfoResponder: public LLHTTPClient::Responder
-{
-	LOG_CLASS(fetchScriptLimitsRegionInfoResponder);
-public:
-	fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {};
-
-private:
-	/* virtual */ void httpSuccess();
-	/* virtual */ void httpFailure();
-	LLSD mInfo;
-};
-
-class fetchScriptLimitsRegionSummaryResponder: public LLHTTPClient::Responder
-{
-	LOG_CLASS(fetchScriptLimitsRegionSummaryResponder);
-public:
-	fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {};
-
-private:
-	/* virtual */ void httpSuccess();
-	/* virtual */ void httpFailure();
-	LLSD mInfo;
-};
-
-class fetchScriptLimitsRegionDetailsResponder: public LLHTTPClient::Responder
-{
-	LOG_CLASS(fetchScriptLimitsRegionDetailsResponder);
-public:
-	fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {};
-
-private:
-	/* virtual */ void httpSuccess();
-	/* virtual */ void httpFailure();
-	LLSD mInfo;
-};
-
-class fetchScriptLimitsAttachmentInfoResponder: public LLHTTPClient::Responder
-{
-	LOG_CLASS(fetchScriptLimitsAttachmentInfoResponder);
-public:
-	fetchScriptLimitsAttachmentInfoResponder() {};
-
-private:
-	/* virtual */ void httpSuccess();
-	/* virtual */ void httpFailure();
-};
-
 /////////////////////////////////////////////////////////////////////////////
 // Memory panel
 /////////////////////////////////////////////////////////////////////////////
@@ -181,6 +132,10 @@ class LLPanelScriptLimitsRegionMemory : public LLPanelScriptLimitsInfo, LLRemote
 
 	std::vector<LLSD> mObjectListItems;
 
+    void getLandScriptResourcesCoro(std::string url);
+    void getLandScriptSummaryCoro(std::string url);
+    void getLandScriptDetailsCoro(std::string url);
+
 protected:
 
 // LLRemoteParcelInfoObserver interface:
@@ -225,6 +180,7 @@ class LLPanelScriptLimitsAttachment : public LLPanelScriptLimitsInfo
 	void clearList();
 
 private:
+    void getAttachmentLimitsCoro(std::string url);
 
 	bool mGotAttachmentMemoryUsed;
 	S32 mAttachmentMemoryMax;
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index c1c21c593e5b0071f61098150cb535e053c04c48..6dc08417d7e7bcc3084f06a7fe363e83638a02c6 100755
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -35,8 +35,6 @@
 // linden library includes
 #include "llbutton.h"
 #include "llevents.h"
-#include "llhttpclient.h"
-#include "llhttpconstants.h"
 #include "llnotificationsutil.h"
 #include "llradiogroup.h"
 #include "lltextbox.h"
@@ -45,7 +43,7 @@
 #include "llvfile.h"
 #include "message.h"
 #include "llstartup.h"              // login_alert_done
-
+#include "llcorehttputil.h"
 
 LLFloaterTOS::LLFloaterTOS(const LLSD& data)
 :	LLModalDialog( data["message"].asString() ),
@@ -57,57 +55,6 @@ LLFloaterTOS::LLFloaterTOS(const LLSD& data)
 {
 }
 
-// helper class that trys to download a URL from a web site and calls a method 
-// on parent class indicating if the web server is working or not
-class LLIamHere : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLIamHere);
-private:
-	LLIamHere( LLFloaterTOS* parent ) :
-	   mParent( parent )
-	{}
-
-	LLFloaterTOS* mParent;
-
-public:
-	static LLIamHere* build( LLFloaterTOS* parent )
-	{
-		return new LLIamHere( parent );
-	}
-	
-	virtual void  setParent( LLFloaterTOS* parentIn )
-	{
-		mParent = parentIn;
-	}
-	
-protected:
-	virtual void httpSuccess()
-	{
-		if ( mParent )
-		{
-			mParent->setSiteIsAlive( true );
-		}
-	}
-
-	virtual void httpFailure()
-	{
-		LL_DEBUGS("LLIamHere") << dumpResponse() << LL_ENDL;
-		if ( mParent )
-		{
-			// *HACK: For purposes of this alive check, 302 Found
-			// (aka Moved Temporarily) is considered alive.  The web site
-			// redirects this link to a "cache busting" temporary URL. JC
-			bool alive = (getStatus() == HTTP_FOUND);
-			mParent->setSiteIsAlive( alive );
-		}
-	}
-};
-
-// this is global and not a class member to keep crud out of the header file
-namespace {
-	LLPointer< LLIamHere > gResponsePtr = 0;
-};
-
 BOOL LLFloaterTOS::postBuild()
 {	
 	childSetAction("Continue", onContinue, this);
@@ -180,9 +127,6 @@ void LLFloaterTOS::setSiteIsAlive( bool alive )
 
 LLFloaterTOS::~LLFloaterTOS()
 {
-	// tell the responder we're not here anymore
-	if ( gResponsePtr )
-		gResponsePtr->setParent( 0 );
 }
 
 // virtual
@@ -243,9 +187,10 @@ void LLFloaterTOS::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
 		if(!mLoadingScreenLoaded)
 		{
 			mLoadingScreenLoaded = true;
+            std::string url(getString("real_url"));
 
-			gResponsePtr = LLIamHere::build( this );
-			LLHTTPClient::get( getString( "real_url" ), gResponsePtr );
+            LLCoros::instance().launch("LLFloaterTOS::testSiteIsAliveCoro",
+                boost::bind(&LLFloaterTOS::testSiteIsAliveCoro, this, url));
 		}
 		else if(mRealNavigateBegun)
 		{
@@ -257,3 +202,26 @@ void LLFloaterTOS::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
 	}
 }
 
+void LLFloaterTOS::testSiteIsAliveCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+
+    LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    // double not.  
+    // First ! returns a boolean error status, second ! is true if success result.
+    setSiteIsAlive(!!status); 
+}
+
+
diff --git a/indra/newview/llfloatertos.h b/indra/newview/llfloatertos.h
index 47126d06a64859be60c6fdef68c9b60e00493b4b..2748b205130946cf8a9da286ad9828dced603c72 100755
--- a/indra/newview/llfloatertos.h
+++ b/indra/newview/llfloatertos.h
@@ -31,6 +31,8 @@
 #include "llassetstorage.h"
 #include "llmediactrl.h"
 #include <boost/function.hpp>
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 class LLButton;
 class LLRadioGroup;
@@ -60,12 +62,15 @@ class LLFloaterTOS :
 	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
 
 private:
+    void testSiteIsAliveCoro(std::string url);
 
 	std::string		mMessage;
 	bool			mLoadingScreenLoaded;
 	bool			mSiteAlive;
 	bool			mRealNavigateBegun;
 	std::string		mReplyPumpName;
+
+
 };
 
 #endif // LL_LLFLOATERTOS_H
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index e02e8eeb5ac800e8572a79260d887789e8c6278d..6683a6e6e68c1b0983e3f9fa70a1a180b7d6ed8a 100755
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -26,8 +26,6 @@
 
 #include "llviewerprecompiledheaders.h"
 
-#include "llhttpclient.h"
-
 #include "llfloaterurlentry.h"
 
 #include "llpanellandmedia.h"
@@ -40,40 +38,10 @@
 #include "lluictrlfactory.h"
 #include "llwindow.h"
 #include "llviewerwindow.h"
+#include "llcorehttputil.h"
 
 static LLFloaterURLEntry* sInstance = NULL;
 
-// Move this to its own file.
-// helper class that tries to download a URL from a web site and calls a method
-// on the Panel Land Media and to discover the MIME type
-class LLMediaTypeResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLMediaTypeResponder);
-public:
-	LLMediaTypeResponder( const LLHandle<LLFloater> parent ) :
-		mParent( parent )
-	{}
-
-	LLHandle<LLFloater> mParent;
-
-private:
-	/* virtual */ void httpCompleted()
-	{
-		const std::string& media_type = getResponseHeader(HTTP_IN_HEADER_CONTENT_TYPE);
-		std::string::size_type idx1 = media_type.find_first_of(";");
-		std::string mime_type = media_type.substr(0, idx1);
-
-		// Set empty type to none/none.  Empty string is reserved for legacy parcels
-		// which have no mime type set.
-		std::string resolved_mime_type = ! mime_type.empty() ? mime_type : LLMIMETypes::getDefaultMimeType();
-		LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mParent.get();
-		if ( floater_url_entry )
-		{
-			floater_url_entry->headerFetchComplete( getStatus(), resolved_mime_type );
-		}
-	}
-};
-
 //-----------------------------------------------------------------------------
 // LLFloaterURLEntry()
 //-----------------------------------------------------------------------------
@@ -225,8 +193,8 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
 	if(!media_url.empty() && 
 	   (scheme == "http" || scheme == "https"))
 	{
-		LLHTTPClient::getHeaderOnly( media_url,
-			new LLMediaTypeResponder(self->getHandle()));
+        LLCoros::instance().launch("LLFloaterURLEntry::getMediaTypeCoro",
+            boost::bind(&LLFloaterURLEntry::getMediaTypeCoro, media_url, self->getHandle()));
 	}
 	else
 	{
@@ -239,6 +207,58 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
 	self->getChildView("media_entry")->setEnabled(false);
 }
 
+// static
+void LLFloaterURLEntry::getMediaTypeCoro(std::string url, LLHandle<LLFloater> parentHandle)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getMediaTypeCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+    httpOpts->setHeadersOnly(true);
+
+    LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url, httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    LLFloaterURLEntry* floaterUrlEntry = (LLFloaterURLEntry*)parentHandle.get();
+    if (!floaterUrlEntry)
+    {
+        LL_WARNS() << "Could not get URL entry floater." << LL_ENDL;
+        return;
+    }
+
+    // Set empty type to none/none.  Empty string is reserved for legacy parcels
+    // which have no mime type set.
+    std::string resolvedMimeType = LLMIMETypes::getDefaultMimeType();
+
+    if (!status)
+    {
+        floaterUrlEntry->headerFetchComplete(status.getType(), resolvedMimeType);
+        return;
+    }
+
+    LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+
+    if (resultHeaders.has(HTTP_IN_HEADER_CONTENT_TYPE))
+    {
+        const std::string& mediaType = resultHeaders[HTTP_IN_HEADER_CONTENT_TYPE];
+        std::string::size_type idx1 = mediaType.find_first_of(";");
+        std::string mimeType = mediaType.substr(0, idx1);
+        if (!mimeType.empty())
+        {
+            resolvedMimeType = mimeType;
+        }
+    }
+
+    floaterUrlEntry->headerFetchComplete(status.getType(), resolvedMimeType);
+
+}
+
 // static
 //-----------------------------------------------------------------------------
 // onBtnCancel()
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index bdd1ebe5921f5dbd01a48d694ab6c5a9e7c5ec57..20f4604907acceb12b84e2eb0b36906782841751 100755
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
@@ -29,6 +29,8 @@
 
 #include "llfloater.h"
 #include "llpanellandmedia.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 class LLLineEditor;
 class LLComboBox;
@@ -56,7 +58,10 @@ class LLFloaterURLEntry : public LLFloater
 	static void		onBtnOK(void*);
 	static void		onBtnCancel(void*);
 	static void		onBtnClear(void*);
-	bool		callback_clear_url_list(const LLSD& notification, const LLSD& response);
+	bool		    callback_clear_url_list(const LLSD& notification, const LLSD& response);
+
+    static void     getMediaTypeCoro(std::string url, LLHandle<LLFloater> parentHandle);
+
 };
 
 #endif  // LL_LLFLOATERURLENTRY_H
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 56e671d902e44fb380640e13d7514718ea8a7a6c..edae0bfd19cba40715a260ab9d6ab75bc7d74f5e 100755
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -53,6 +53,7 @@
 #include "lltrans.h"
 #include "llviewerregion.h"
 #include <boost/regex.hpp>
+#include "llcorehttputil.h"
 
 #if LL_MSVC
 #pragma warning(push)   
@@ -768,9 +769,9 @@ void LLGroupMgrGroupData::removeBanEntry(const LLUUID& ban_id)
 // LLGroupMgr
 //
 
-LLGroupMgr::LLGroupMgr()
+LLGroupMgr::LLGroupMgr():
+    mMemberRequestInFlight(false)
 {
-	mLastGroupMembersRequestFrame = 0;
 }
 
 LLGroupMgr::~LLGroupMgr()
@@ -1861,49 +1862,94 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
 	group_datap->mMemberVersion.generate();
 }
 
-
-// Responder class for capability group management
-class GroupBanDataResponder : public LLHTTPClient::Responder
+void LLGroupMgr::getGroupBanRequestCoro(std::string url, LLUUID groupId)
 {
-public:
-	GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh=false);
-	virtual ~GroupBanDataResponder() {}
-	virtual void httpSuccess();
-	virtual void httpFailure();
-private:
-	LLUUID mGroupID;
-	BOOL mForceRefresh;
-};
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
 
-GroupBanDataResponder::GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh) :
-	mGroupID(gropup_id),
-	mForceRefresh(force_refresh)
-{}
+    std::string finalUrl = url + "?group_id=" + groupId.asString();
 
-void GroupBanDataResponder::httpFailure()
-{
-	LL_WARNS("GrpMgr") << "Error receiving group member data [status:" 
-		<< mStatus << "]: " << mContent << LL_ENDL;
+    LLSD result = httpAdapter->getAndYield(httpRequest, finalUrl);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("GrpMgr") << "Error receiving group member data " << LL_ENDL;
+        return;
+    }
+
+    if (result.has("ban_list"))
+    {
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        // group ban data received
+        processGroupBanRequest(result);
+    }
 }
 
-void GroupBanDataResponder::httpSuccess()
+void LLGroupMgr::postGroupBanRequestCoro(std::string url, LLUUID groupId,
+    U32 action, uuid_vec_t banList, bool update)
 {
-	if (mContent.has("ban_list"))
-	{
-		// group ban data received
-		LLGroupMgr::processGroupBanRequest(mContent);
-	}
-	else if (mForceRefresh)
-	{
-		// no ban data received, refreshing data after successful operation 
-		LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID);
-	}
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+    LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions);
+
+    httpOptions->setFollowRedirects(false);
+
+    httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
+
+
+    std::string finalUrl = url + "?group_id=" + groupId.asString();
+
+    LLSD postData = LLSD::emptyMap();
+    postData["ban_action"] = (LLSD::Integer)action;
+    // Add our list of potential banned residents to the list
+    postData["ban_ids"] = LLSD::emptyArray();
+    LLSD banEntry;
+
+    uuid_vec_t::const_iterator it = banList.begin();
+    for (; it != banList.end(); ++it)
+    {
+        banEntry = (*it);
+        postData["ban_ids"].append(banEntry);
+    }
+
+    LL_WARNS() << "post: " << ll_pretty_print_sd(postData) << LL_ENDL;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, finalUrl, postData, httpOptions, httpHeaders);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("GrpMgr") << "Error posting group member data " << LL_ENDL;
+        return;
+    }
+
+    if (result.has("ban_list"))
+    {
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        // group ban data received
+        processGroupBanRequest(result);
+    }
+
+    if (update)
+    {
+        getGroupBanRequestCoro(url, groupId);
+    }
 }
 
 void LLGroupMgr::sendGroupBanRequest(	EBanRequestType request_type, 
 										const LLUUID& group_id, 
 										U32 ban_action, /* = BAN_NO_ACTION */
-										const std::vector<LLUUID> ban_list) /* = std::vector<LLUUID>() */
+										const std::vector<LLUUID> &ban_list) /* = std::vector<LLUUID>() */
 {
 	LLViewerRegion* currentRegion = gAgent.getRegion();
 	if(!currentRegion)
@@ -1925,37 +1971,27 @@ void LLGroupMgr::sendGroupBanRequest(	EBanRequestType request_type,
 	{
 		return;
 	}
-	cap_url += "?group_id=" + group_id.asString();
-
-	LLSD body = LLSD::emptyMap();
-	body["ban_action"]  = (LLSD::Integer)(ban_action & ~BAN_UPDATE);
-	// Add our list of potential banned residents to the list
-	body["ban_ids"]	= LLSD::emptyArray();
-	LLSD ban_entry;
 
-	uuid_vec_t::const_iterator iter = ban_list.begin();
-	for(;iter != ban_list.end(); ++iter)
-	{
-		ban_entry = (*iter);
-		body["ban_ids"].append(ban_entry);
-	}
+    U32 action = ban_action & ~BAN_UPDATE;
+    bool update = ((ban_action & BAN_UPDATE) == BAN_UPDATE);
 
-	LLHTTPClient::ResponderPtr grp_ban_responder = new GroupBanDataResponder(group_id, ban_action & BAN_UPDATE);
-	switch(request_type)
-	{
-	case REQUEST_GET:
-		LLHTTPClient::get(cap_url, grp_ban_responder);
-		break;
-	case REQUEST_POST:
-		LLHTTPClient::post(cap_url, body, grp_ban_responder);
-		break;
-	case REQUEST_PUT:
-	case REQUEST_DEL:
-		break;
-	}
+    switch (request_type)
+    {
+    case REQUEST_GET:
+        LLCoros::instance().launch("LLGroupMgr::getGroupBanRequestCoro",
+            boost::bind(&LLGroupMgr::getGroupBanRequestCoro, this, cap_url, group_id));
+        break;
+    case REQUEST_POST:
+        LLCoros::instance().launch("LLGroupMgr::postGroupBanRequestCoro",
+            boost::bind(&LLGroupMgr::postGroupBanRequestCoro, this, cap_url, group_id, 
+            action, ban_list, update));
+        break;
+    case REQUEST_PUT:
+    case REQUEST_DEL:
+        break;
+    }
 }
 
-
 void LLGroupMgr::processGroupBanRequest(const LLSD& content)
 {
 	// Did we get anything in content?
@@ -1992,45 +2028,42 @@ void LLGroupMgr::processGroupBanRequest(const LLSD& content)
 	LLGroupMgr::getInstance()->notifyObservers(GC_BANLIST);
 }
 
+void LLGroupMgr::groupMembersRequestCoro(std::string url, LLUUID groupId)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
 
+    mMemberRequestInFlight = true;
 
-// Responder class for capability group management
-class GroupMemberDataResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(GroupMemberDataResponder);
-public:
-	GroupMemberDataResponder() {}
-	virtual ~GroupMemberDataResponder() {}
+    LLSD postData = LLSD::emptyMap();
+    postData["group_id"] = groupId;
 
-private:
-	/* virtual */ void httpSuccess();
-	/* virtual */ void httpFailure();
-	LLSD mMemberData;
-};
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData, httpOpts);
 
-void GroupMemberDataResponder::httpFailure()
-{
-	LL_WARNS("GrpMgr") << "Error receiving group member data "
-		<< dumpResponse() << LL_ENDL;
-}
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
 
-void GroupMemberDataResponder::httpSuccess()
-{
-	const LLSD& content = getContent();
-	if (!content.isMap())
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
-	LLGroupMgr::processCapGroupMembersRequest(content);
-}
+    if (!status)
+    {
+        LL_WARNS("GrpMgr") << "Error receiving group member data " << LL_ENDL;
+        mMemberRequestInFlight = false;
+        return;
+    }
 
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+    LLGroupMgr::processCapGroupMembersRequest(result);
+    mMemberRequestInFlight = false;
+}
 
-// static
 void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 {
+    static U32 lastGroupMemberRequestFrame = 0;
+
 	// Have we requested the information already this frame?
-	if(mLastGroupMembersRequestFrame == gFrameCount)
+    if ((lastGroupMemberRequestFrame == gFrameCount) || (mMemberRequestInFlight))
 		return;
 	
 	LLViewerRegion* currentRegion = gAgent.getRegion();
@@ -2059,20 +2092,13 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 		return;
 	}
 
-	// Post to our service.  Add a body containing the group_id.
-	LLSD body = LLSD::emptyMap();
-	body["group_id"]	= group_id;
+    lastGroupMemberRequestFrame = gFrameCount;
 
-	LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder();
-	
-	// This could take a while to finish, timeout after 5 minutes.
-	LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 300);
-
-	mLastGroupMembersRequestFrame = gFrameCount;
+    LLCoros::instance().launch("LLGroupMgr::groupMembersRequestCoro",
+        boost::bind(&LLGroupMgr::groupMembersRequestCoro, this, cap_url, group_id));
 }
 
 
-// static
 void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 {
 	// Did we get anything in content?
@@ -2089,7 +2115,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 	
 	LLUUID group_id = content["group_id"].asUUID();
 
-	LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
+	LLGroupMgrGroupData* group_datap = getGroupData(group_id);
 	if(!group_datap)
 	{
 		LL_WARNS("GrpMgr") << "Received incorrect, possibly stale, group or request id" << LL_ENDL;
@@ -2183,7 +2209,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 	// TODO:
 	// Refactor to reduce multiple calls for data we already have.
 	if(group_datap->mTitles.size() < 1)
-		LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id);
+		sendGroupTitlesRequest(group_id);
 
 
 	group_datap->mMemberDataComplete = true;
@@ -2192,11 +2218,11 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 	if (group_datap->mPendingRoleMemberRequest || !group_datap->mRoleMemberDataComplete)
 	{
 		group_datap->mPendingRoleMemberRequest = false;
-		LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id);
+		sendGroupRoleMembersRequest(group_id);
 	}
 
 	group_datap->mChanged = TRUE;
-	LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
+	notifyObservers(GC_MEMBER_DATA);
 
 }
 
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index 2e94e8d9a0d359484f6b50658f434ecbc8b828c0..fd0c2de854e47cf56464cb7baf6e1830a70fd01d 100755
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -32,6 +32,8 @@
 #include <vector>
 #include <string>
 #include <map>
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 // Forward Declarations
 class LLMessageSystem;
@@ -362,6 +364,7 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr>
 		BAN_UPDATE		= 4
 	};
 
+
 public:
 	LLGroupMgr();
 	~LLGroupMgr();
@@ -396,15 +399,13 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr>
 	static void sendGroupMemberEjects(const LLUUID& group_id,
 									  uuid_vec_t& member_ids);
 	
-	static void sendGroupBanRequest(EBanRequestType request_type, 
+	void sendGroupBanRequest(EBanRequestType request_type, 
 									const LLUUID& group_id,	
 									U32 ban_action = BAN_NO_ACTION,
-									const uuid_vec_t ban_list = uuid_vec_t());
+									const uuid_vec_t &ban_list = uuid_vec_t());
 
-	static void processGroupBanRequest(const LLSD& content);
 
 	void sendCapGroupMembersRequest(const LLUUID& group_id);
-	static void processCapGroupMembersRequest(const LLSD& content);
 
 	void cancelGroupRoleChanges(const LLUUID& group_id);
 
@@ -427,6 +428,14 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr>
 	void clearGroupData(const LLUUID& group_id);
 
 private:
+    void groupMembersRequestCoro(std::string url, LLUUID groupId);
+    void processCapGroupMembersRequest(const LLSD& content);
+
+    void getGroupBanRequestCoro(std::string url, LLUUID groupId);
+    void postGroupBanRequestCoro(std::string url, LLUUID groupId, U32 action, uuid_vec_t banList, bool update);
+
+    static void processGroupBanRequest(const LLSD& content);
+
 	void notifyObservers(LLGroupChange gc);
 	void notifyObserver(const LLUUID& group_id, LLGroupChange gc);
 	void addGroup(LLGroupMgrGroupData* group_datap);
@@ -442,7 +451,7 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr>
 	typedef std::map<LLUUID,observer_set_t> observer_map_t;
 	observer_map_t mParticularObservers;
 
-	S32 mLastGroupMembersRequestFrame;
+    bool mMemberRequestInFlight;
 };
 
 
diff --git a/indra/newview/llhomelocationresponder.cpp b/indra/newview/llhomelocationresponder.cpp
deleted file mode 100755
index d0492bcdb438b0e190fcb982b07c9f9d7e1141ce..0000000000000000000000000000000000000000
--- a/indra/newview/llhomelocationresponder.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/** 
- * @file llhomelocationresponder.cpp
- * @author Meadhbh Hamrick
- * @brief Processes responses to the HomeLocation CapReq
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-/* File Inclusions */
-#include "llviewerprecompiledheaders.h"
-
-#include "llhomelocationresponder.h"
-#include "llsdutil.h"
-#include "llagent.h"
-#include "llviewerregion.h"
-
-void LLHomeLocationResponder::httpSuccess()
-{
-  const LLSD& content = getContent();
-  LLVector3 agent_pos;
-  bool      error = true;
-
-  do {
-
-    // was the call to /agent/<agent-id>/home-location successful?
-    // If not, we keep error set to true
-    if( ! content.has("success") )
-    {
-      break;
-    }
-
-    if( 0 != strncmp("true", content["success"].asString().c_str(), 4 ) )
-    {
-      break;
-    }
-
-    // did the simulator return a "justified" home location?
-    // If no, we keep error set to true
-    if( ! content.has( "HomeLocation" ) )
-    {
-      break;
-    }
-
-    if( ! content["HomeLocation"].has("LocationPos") )
-    {
-      break;
-    }
-
-    if( ! content["HomeLocation"]["LocationPos"].has("X") )
-    {
-      break;
-    }
-
-    agent_pos.mV[VX] = content["HomeLocation"]["LocationPos"]["X"].asInteger();
-
-    if( ! content["HomeLocation"]["LocationPos"].has("Y") )
-    {
-      break;
-    }
-
-    agent_pos.mV[VY] = content["HomeLocation"]["LocationPos"]["Y"].asInteger();
-
-    if( ! content["HomeLocation"]["LocationPos"].has("Z") )
-    {
-      break;
-    }
-
-    agent_pos.mV[VZ] = content["HomeLocation"]["LocationPos"]["Z"].asInteger();
-
-    error = false;
-  } while( 0 );
-
-  if( error )
-  {
-    failureResult(HTTP_INTERNAL_ERROR, "Invalid server response content", content);
-  }
-  else
-  {
-    LL_INFOS() << "setting home position" << LL_ENDL;
-
-    LLViewerRegion *viewer_region = gAgent.getRegion();
-    gAgent.setHomePosRegion( viewer_region->getHandle(), agent_pos );
-  }
-}
-
-void LLHomeLocationResponder::httpFailure()
-{
-  LL_WARNS() << dumpResponse() << LL_ENDL;
-}
diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h
deleted file mode 100755
index adc6c8cb58109b11e5333c63b9dafbc0ae2ccb55..0000000000000000000000000000000000000000
--- a/indra/newview/llhomelocationresponder.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/** 
- * @file llhomelocationresponder.h
- * @author Meadhbh Hamrick
- * @brief Processes responses to the HomeLocation CapReq
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
- /* Macro Definitions */
-#ifndef LL_LLHOMELOCATIONRESPONDER_H
-#define LL_LLHOMELOCATIONRESPONDER_H
-
-/* File Inclusions */
-#include "llhttpclient.h"
-
-/* Typedef, Enum, Class, Struct, etc. */
-class LLHomeLocationResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLHomeLocationResponder);
-private:
-	/* virtual */ void httpSuccess();
-	/* virtual */ void httpFailure();
-};
-
-#endif
diff --git a/indra/newview/llhttpretrypolicy.cpp b/indra/newview/llhttpretrypolicy.cpp
index 2d4ce6c883a2c6bec31265b2fd3420ddbdf2ead2..530eb685fa3185a4b9567fd71f55051ab84985d8 100755
--- a/indra/newview/llhttpretrypolicy.cpp
+++ b/indra/newview/llhttpretrypolicy.cpp
@@ -87,7 +87,7 @@ void LLAdaptiveRetryPolicy::onFailure(const LLCore::HttpResponse *response)
 	F32 retry_header_time;
 	const LLCore::HttpHeaders *headers = response->getHeaders();
 	bool has_retry_header_time = getRetryAfter(headers,retry_header_time);
-	onFailureCommon(response->getStatus().mType, has_retry_header_time, retry_header_time);
+	onFailureCommon(response->getStatus().getType(), has_retry_header_time, retry_header_time);
 }
 
 void LLAdaptiveRetryPolicy::onFailureCommon(S32 status, bool has_retry_header_time, F32 retry_header_time)
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5d3a11e2451b9fd9dea52550fe9b052cbe2d78df..8d670d0b0a7a51a62c2fc27e7aa2f7343018cf55 100755
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -37,7 +37,6 @@
 #include "llrect.h"
 #include "llerror.h"
 #include "llbutton.h"
-#include "llhttpclient.h"
 #include "llsdutil_math.h"
 #include "llstring.h"
 #include "lltextutil.h"
@@ -69,6 +68,7 @@
 #include "llconversationlog.h"
 #include "message.h"
 #include "llviewerregion.h"
+#include "llcorehttputil.h"
 
 
 const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -79,6 +79,10 @@ const static std::string NEARBY_P2P_BY_AGENT("nearby_P2P_by_agent");
 /** Timeout of outgoing session initialization (in seconds) */
 const static U32 SESSION_INITIALIZATION_TIMEOUT = 30;
 
+void startConfrenceCoro(std::string url, LLUUID tempSessionId, LLUUID creatorId, LLUUID otherParticipantId, LLSD agents);
+void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType);
+void start_deprecated_conference_chat(const LLUUID& temp_session_id, const LLUUID& creator_id, const LLUUID& other_participant_id, const LLSD& agents_to_invite);
+
 std::string LLCallDialogManager::sPreviousSessionlName = "";
 LLIMModel::LLIMSession::SType LLCallDialogManager::sPreviousSessionType = LLIMModel::LLIMSession::P2P_SESSION;
 std::string LLCallDialogManager::sCurrentSessionlName = "";
@@ -110,7 +114,7 @@ void process_dnd_im(const LLSD& notification)
 {
     LLSD data = notification["substitutions"];
     LLUUID sessionID = data["SESSION_ID"].asUUID();
-	LLUUID fromID = data["FROM_ID"].asUUID();
+    LLUUID fromID = data["FROM_ID"].asUUID();
 
     //re-create the IM session if needed 
     //(when coming out of DND mode upon app restart)
@@ -131,12 +135,10 @@ void process_dnd_im(const LLSD& notification)
             fromID, 
             false, 
             false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
-		}
-
-	notify_of_message(data, true);
     }
 
-
+    notify_of_message(data, true);
+}
 
 
 static void on_avatar_name_cache_toast(const LLUUID& agent_id,
@@ -387,6 +389,130 @@ void on_new_message(const LLSD& msg)
 	notify_of_message(msg, false);
 }
 
+void startConfrenceCoro(std::string url,
+    LLUUID tempSessionId, LLUUID creatorId, LLUUID otherParticipantId, LLSD agents)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD postData;
+    postData["method"] = "start conference";
+    postData["session-id"] = tempSessionId;
+    postData["params"] = agents;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("LLIMModel") << "Failed to start conference" << LL_ENDL;
+        //try an "old school" way.
+        // *TODO: What about other error status codes?  4xx 5xx?
+        if (status == LLCore::HttpStatus(HTTP_BAD_REQUEST))
+        {
+            start_deprecated_conference_chat(
+                tempSessionId,
+                creatorId,
+                otherParticipantId,
+                agents);
+        }
+
+        //else throw an error back to the client?
+        //in theory we should have just have these error strings
+        //etc. set up in this file as opposed to the IMMgr,
+        //but the error string were unneeded here previously
+        //and it is not worth the effort switching over all
+        //the possible different language translations
+    }
+}
+
+void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD postData;
+    postData["method"] = "accept invitation";
+    postData["session-id"] = sessionId;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!gIMMgr)
+    {
+        LL_WARNS("") << "Global IM Manager is NULL" << LL_ENDL;
+        return;
+    }
+
+    if (!status)
+    {
+        LL_WARNS("LLIMModel") << "Bad HTTP response in chatterBoxInvitationCoro" << LL_ENDL;
+        //throw something back to the viewer here?
+
+        gIMMgr->clearPendingAgentListUpdates(sessionId);
+        gIMMgr->clearPendingInvitation(sessionId);
+
+        if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+        {
+            static const std::string error_string("session_does_not_exist_error");
+            gIMMgr->showSessionStartError(error_string, sessionId);
+        }
+        return;
+    }
+
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+
+    LLIMSpeakerMgr* speakerMgr = LLIMModel::getInstance()->getSpeakerManager(sessionId);
+    if (speakerMgr)
+    {
+        //we've accepted our invitation
+        //and received a list of agents that were
+        //currently in the session when the reply was sent
+        //to us.  Now, it is possible that there were some agents
+        //to slip in/out between when that message was sent to us
+        //and now.
+
+        //the agent list updates we've received have been
+        //accurate from the time we were added to the session
+        //but unfortunately, our base that we are receiving here
+        //may not be the most up to date.  It was accurate at
+        //some point in time though.
+        speakerMgr->setSpeakers(result);
+
+        //we now have our base of users in the session
+        //that was accurate at some point, but maybe not now
+        //so now we apply all of the updates we've received
+        //in case of race conditions
+        speakerMgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(sessionId));
+    }
+
+    if (LLIMMgr::INVITATION_TYPE_VOICE == invitationType)
+    {
+        gIMMgr->startCall(sessionId, LLVoiceChannel::INCOMING_CALL);
+    }
+
+    if ((invitationType == LLIMMgr::INVITATION_TYPE_VOICE
+        || invitationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE)
+        && LLIMModel::getInstance()->findIMSession(sessionId))
+    {
+        // TODO remove in 2010, for voice calls we do not open an IM window
+        //LLFloaterIMSession::show(mSessionID);
+    }
+
+    gIMMgr->clearPendingAgentListUpdates(sessionId);
+    gIMMgr->clearPendingInvitation(sessionId);
+
+}
+
+
 LLIMModel::LLIMModel() 
 {
 	addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
@@ -1459,54 +1585,6 @@ void start_deprecated_conference_chat(
 	delete[] bucket;
 }
 
-class LLStartConferenceChatResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLStartConferenceChatResponder);
-public:
-	LLStartConferenceChatResponder(
-		const LLUUID& temp_session_id,
-		const LLUUID& creator_id,
-		const LLUUID& other_participant_id,
-		const LLSD& agents_to_invite)
-	{
-		mTempSessionID = temp_session_id;
-		mCreatorID = creator_id;
-		mOtherParticipantID = other_participant_id;
-		mAgents = agents_to_invite;
-	}
-
-protected:
-	virtual void httpFailure()
-	{
-		//try an "old school" way.
-		// *TODO: What about other error status codes?  4xx 5xx?
-		if ( getStatus() == HTTP_BAD_REQUEST )
-		{
-			start_deprecated_conference_chat(
-				mTempSessionID,
-				mCreatorID,
-				mOtherParticipantID,
-				mAgents);
-		}
-
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-
-		//else throw an error back to the client?
-		//in theory we should have just have these error strings
-		//etc. set up in this file as opposed to the IMMgr,
-		//but the error string were unneeded here previously
-		//and it is not worth the effort switching over all
-		//the possible different language translations
-	}
-
-private:
-	LLUUID mTempSessionID;
-	LLUUID mCreatorID;
-	LLUUID mOtherParticipantID;
-
-	LLSD mAgents;
-};
-
 // Returns true if any messages were sent, false otherwise.
 // Is sort of equivalent to "does the server need to do anything?"
 bool LLIMModel::sendStartSession(
@@ -1543,20 +1621,10 @@ bool LLIMModel::sendStartSession(
 		{
 			std::string url = region->getCapability(
 				"ChatSessionRequest");
-			LLSD data;
-			data["method"] = "start conference";
-			data["session-id"] = temp_session_id;
-
-			data["params"] = agents;
 
-			LLHTTPClient::post(
-				url,
-				data,
-				new LLStartConferenceChatResponder(
-					temp_session_id,
-					gAgent.getID(),
-					other_participant_id,
-					data["params"]));
+            LLCoros::instance().launch("startConfrenceCoro",
+                boost::bind(&startConfrenceCoro, url,
+                temp_session_id, gAgent.getID(), other_participant_id, agents));
 		}
 		else
 		{
@@ -1574,97 +1642,6 @@ bool LLIMModel::sendStartSession(
 	return false;
 }
 
-//
-// Helper Functions
-//
-
-class LLViewerChatterBoxInvitationAcceptResponder :
-	public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLViewerChatterBoxInvitationAcceptResponder);
-public:
-	LLViewerChatterBoxInvitationAcceptResponder(
-		const LLUUID& session_id,
-		LLIMMgr::EInvitationType invitation_type)
-	{
-		mSessionID = session_id;
-		mInvitiationType = invitation_type;
-	}
-
-private:
-	void httpSuccess()
-	{
-		const LLSD& content = getContent();
-		if (!content.isMap())
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		if ( gIMMgr)
-		{
-			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-			if (speaker_mgr)
-			{
-				//we've accepted our invitation
-				//and received a list of agents that were
-				//currently in the session when the reply was sent
-				//to us.  Now, it is possible that there were some agents
-				//to slip in/out between when that message was sent to us
-				//and now.
-
-				//the agent list updates we've received have been
-				//accurate from the time we were added to the session
-				//but unfortunately, our base that we are receiving here
-				//may not be the most up to date.  It was accurate at
-				//some point in time though.
-				speaker_mgr->setSpeakers(content);
-
-				//we now have our base of users in the session
-				//that was accurate at some point, but maybe not now
-				//so now we apply all of the udpates we've received
-				//in case of race conditions
-				speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
-			}
-
-			if (LLIMMgr::INVITATION_TYPE_VOICE == mInvitiationType)
-			{
-				gIMMgr->startCall(mSessionID, LLVoiceChannel::INCOMING_CALL);
-			}
-
-			if ((mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE 
-				|| mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE)
-				&& LLIMModel::getInstance()->findIMSession(mSessionID))
-			{
-				// TODO remove in 2010, for voice calls we do not open an IM window
-				//LLFloaterIMSession::show(mSessionID);
-			}
-
-			gIMMgr->clearPendingAgentListUpdates(mSessionID);
-			gIMMgr->clearPendingInvitation(mSessionID);
-		}
-	}
-
-	void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-		//throw something back to the viewer here?
-		if ( gIMMgr )
-		{
-			gIMMgr->clearPendingAgentListUpdates(mSessionID);
-			gIMMgr->clearPendingInvitation(mSessionID);
-			if ( HTTP_NOT_FOUND == getStatus() )
-			{
-				static const std::string error_string("session_does_not_exist_error");
-				gIMMgr->showSessionStartError(error_string, mSessionID);
-			}
-		}
-	}
-
-private:
-	LLUUID mSessionID;
-	LLIMMgr::EInvitationType mInvitiationType;
-};
-
 
 // the other_participant_id is either an agent_id, a group_id, or an inventory
 // folder item_id (collection of calling cards)
@@ -2490,15 +2467,9 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 
 			if (voice)
 			{
-				LLSD data;
-				data["method"] = "accept invitation";
-				data["session-id"] = session_id;
-				LLHTTPClient::post(
-					url,
-					data,
-					new LLViewerChatterBoxInvitationAcceptResponder(
-						session_id,
-						inv_type));
+                LLCoros::instance().launch("chatterBoxInvitationCoro",
+                    boost::bind(&chatterBoxInvitationCoro, url,
+                    session_id, inv_type));
 
 				// send notification message to the corresponding chat 
 				if (payload["notify_box_type"].asString() == "VoiceInviteGroup" || payload["notify_box_type"].asString() == "VoiceInviteAdHoc")
@@ -2533,10 +2504,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 			LLSD data;
 			data["method"] = "decline invitation";
 			data["session-id"] = session_id;
-			LLHTTPClient::post(
-				url,
-				data,
-				NULL);
+
+            LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data,
+                "Invitation declined", 
+                "Invitation decline failed.");
 		}
 	}
 
@@ -2583,15 +2554,9 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 				std::string url = gAgent.getRegion()->getCapability(
 					"ChatSessionRequest");
 
-				LLSD data;
-				data["method"] = "accept invitation";
-				data["session-id"] = session_id;
-				LLHTTPClient::post(
-					url,
-					data,
-					new LLViewerChatterBoxInvitationAcceptResponder(
-						session_id,
-						inv_type));
+                LLCoros::instance().launch("chatterBoxInvitationCoro",
+                    boost::bind(&chatterBoxInvitationCoro, url,
+                    session_id, inv_type));
 			}
 		}
 		break;
@@ -2621,10 +2586,9 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 			LLSD data;
 			data["method"] = "decline invitation";
 			data["session-id"] = session_id;
-			LLHTTPClient::post(
-				url,
-				data,
-				NULL);				
+            LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data, 
+                "Invitation declined.", 
+                "Invitation decline failed.");
 		}
 	}
 
@@ -3681,15 +3645,9 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 
 			if ( url != "" )
 			{
-				LLSD data;
-				data["method"] = "accept invitation";
-				data["session-id"] = session_id;
-				LLHTTPClient::post(
-					url,
-					data,
-					new LLViewerChatterBoxInvitationAcceptResponder(
-						session_id,
-						LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE));
+                LLCoros::instance().launch("chatterBoxInvitationCoro",
+                    boost::bind(&chatterBoxInvitationCoro, url,
+                    session_id, LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE));
 			}
 		} //end if invitation has instant message
 		else if ( input["body"].has("voice") )
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index f92eff48458167219cdbd574f9587edad5d3bf69..41a8813acb2b4ac2cb933c673eca32735f017c52 100755
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -34,6 +34,9 @@
 #include "lllogchat.h"
 #include "llvoicechannel.h"
 
+#include "llcoros.h"
+#include "lleventcoro.h"
+
 class LLAvatarName;
 class LLFriendObserver;
 class LLCallDialogManager;	
@@ -292,6 +295,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	 * Add message to a list of message associated with session specified by session_id
 	 */
 	bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
+
 };
 
 class LLIMSessionObserver
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index f92332dea5d9ec1ef9840fb86670f8275be4ee20..25450f23174cce0f341279937ffcf2ce0f7d57d6 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -524,59 +524,6 @@ const LLUUID LLInventoryModel::findLibraryCategoryUUIDForType(LLFolderType::ETyp
 	return findCategoryUUIDForTypeInRoot(preferred_type, create_folder, gInventory.getLibraryRootFolderID());
 }
 
-class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLCreateInventoryCategoryResponder);
-public:
-	LLCreateInventoryCategoryResponder(LLInventoryModel* model, 
-									   boost::optional<inventory_func_type> callback):
-		mModel(model),
-		mCallback(callback) 
-	{
-	}
-	
-protected:
-	virtual void httpFailure()
-	{
-		LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL;
-	}
-	
-	virtual void httpSuccess()
-	{
-		//Server has created folder.
-		const LLSD& content = getContent();
-		if (!content.isMap() || !content.has("folder_id"))
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		LLUUID category_id = content["folder_id"].asUUID();
-		
-		LL_DEBUGS(LOG_INV) << ll_pretty_print_sd(content) << LL_ENDL;
-		// Add the category to the internal representation
-		LLPointer<LLViewerInventoryCategory> cat =
-		new LLViewerInventoryCategory( category_id, 
-									  content["parent_id"].asUUID(),
-									  (LLFolderType::EType)content["type"].asInteger(),
-									  content["name"].asString(), 
-									  gAgent.getID() );
-		cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
-		cat->setDescendentCount(0);
-		LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
-		mModel->accountForUpdate(update);
-		mModel->updateCategory(cat);
-
-		if (mCallback)
-		{
-			mCallback.get()(category_id);
-		}
-	}
-	
-private:
-	boost::optional<inventory_func_type> mCallback;
-	LLInventoryModel* mModel;
-};
-
 // Convenience function to create a new category. You could call
 // updateCategory() with a newly generated UUID category, but this
 // version will take care of details like what the name should be
@@ -584,7 +531,7 @@ class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
 LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
 										   LLFolderType::EType preferred_type,
 										   const std::string& pname,
-										   boost::optional<inventory_func_type> callback)
+										   inventory_func_type callback)
 {
 	
 	LLUUID id;
@@ -616,7 +563,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
 	if ( viewer_region )
 		url = viewer_region->getCapability("CreateInventoryCategory");
 	
-	if (!url.empty() && callback.get_ptr())
+	if (!url.empty() && callback)
 	{
 		//Let's use the new capability.
 		
@@ -630,11 +577,8 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
 		request["payload"] = body;
 
 		LL_DEBUGS(LOG_INV) << "create category request: " << ll_pretty_print_sd(request) << LL_ENDL;
-		//		viewer_region->getCapAPI().post(request);
-		LLHTTPClient::post(
-			url,
-			body,
-			new LLCreateInventoryCategoryResponder(this, callback) );
+        LLCoros::instance().launch("LLInventoryModel::createNewCategoryCoro",
+            boost::bind(&LLInventoryModel::createNewCategoryCoro, this, url, body, callback));
 
 		return LLUUID::null;
 	}
@@ -663,6 +607,57 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
 	return id;
 }
 
+void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inventory_func_type callback)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("createNewCategoryCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+    
+
+    httpOpts->setWantHeaders(true);
+
+    LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData, httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS() << "HTTP failure attempting to create category." << LL_ENDL;
+        return;
+    }
+
+    if (!result.has("folder_id"))
+    {
+        LL_WARNS() << "Malformed response contents" << ll_pretty_print_sd(result) << LL_ENDL;
+        return;
+    }
+
+    LLUUID categoryId = result["folder_id"].asUUID();
+
+    // Add the category to the internal representation
+    LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
+        result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
+        result["name"].asString(), gAgent.getID());
+
+    cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
+    cat->setDescendentCount(0);
+    LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+    
+    accountForUpdate(update);
+    updateCategory(cat);
+
+    if (callback)
+    {
+        callback(categoryId);
+    }
+
+}
+
 // This is optimized for the case that we just want to know whether a
 // category has any immediate children meeting a condition, without
 // needing to recurse or build up any lists.
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index ac336e347cca2f8e7ca7382e730e90a8aa243e8a..1f1c686ef1e33955c0e19614a342e035198fb7a9 100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -46,6 +46,8 @@
 #include "httpoptions.h"
 #include "httpheaders.h"
 #include "httphandler.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 class LLInventoryObserver;
 class LLInventoryObject;
@@ -207,14 +209,14 @@ class LLInventoryModel
  **/
 
 	//--------------------------------------------------------------------
-	// Descendents
+	// Descendants
 	//--------------------------------------------------------------------
 public:
-	// Make sure we have the descendents in the structure.  Returns true
+	// Make sure we have the descendants in the structure.  Returns true
 	// if a fetch was performed.
 	bool fetchDescendentsOf(const LLUUID& folder_id) const;
 
-	// Return the direct descendents of the id provided.Set passed
+	// Return the direct descendants of the id provided.Set passed
 	// in values to NULL if the call fails.
 	//    NOTE: The array provided points straight into the guts of
 	//    this object, and should only be used for read operations, since
@@ -223,10 +225,10 @@ class LLInventoryModel
 								cat_array_t*& categories,
 								item_array_t*& items) const;
 
-	// Compute a hash of direct descendent names (for detecting child name changes)
+	// Compute a hash of direct descendant names (for detecting child name changes)
 	LLMD5 hashDirectDescendentNames(const LLUUID& cat_id) const;
 	
-	// Starting with the object specified, add its descendents to the
+	// Starting with the object specified, add its descendants to the
 	// array provided, but do not add the inventory object specified
 	// by id. There is no guaranteed order. 
 	//    NOTE: Neither array will be erased before adding objects to it. 
@@ -340,7 +342,7 @@ class LLInventoryModel
 	U32 updateItem(const LLViewerInventoryItem* item, U32 mask = 0);
 
 	// Change an existing item with the matching id or add
-	// the category. No notifcation will be sent to observers. This
+	// the category. No notification will be sent to observers. This
 	// method will only generate network traffic if the item had to be
 	// reparented.
 	//    NOTE: In usage, you will want to perform cache accounting
@@ -378,7 +380,7 @@ class LLInventoryModel
 								   bool update_parent_version = true,
 								   bool do_notify_observers = true);
 
-	// Update model after all descendents removed from server.
+	// Update model after all descendants removed from server.
 	void onDescendentsPurgedFromServer(const LLUUID& object_id, bool fix_broken_links = true);
 
 	// Update model after an existing item gets updated on server.
@@ -409,7 +411,7 @@ class LLInventoryModel
 	// Changes items order by insertion of the item identified by src_item_id
 	// before (or after) the item identified by dest_item_id. Both items must exist in items array.
 	// Sorting is stored after method is finished. Only src_item_id is moved before (or after) dest_item_id.
-	// The parameter "insert_before" controls on which side of dest_item_id src_item_id gets rensinserted.
+	// The parameter "insert_before" controls on which side of dest_item_id src_item_id gets reinserted.
 	static void updateItemsOrder(LLInventoryModel::item_array_t& items, 
 								 const LLUUID& src_item_id, 
 								 const LLUUID& dest_item_id,
@@ -433,7 +435,7 @@ class LLInventoryModel
 	LLUUID createNewCategory(const LLUUID& parent_id,
 							 LLFolderType::EType preferred_type,
 							 const std::string& name,
-							 boost::optional<inventory_func_type> callback = boost::optional<inventory_func_type>());
+							 inventory_func_type callback = NULL);
 protected:
 	// Internal methods that add inventory and make sure that all of
 	// the internal data structures are consistent. These methods
@@ -441,6 +443,8 @@ class LLInventoryModel
 	// instance will take over the memory management from there.
 	void addCategory(LLViewerInventoryCategory* category);
 	void addItem(LLViewerInventoryItem* item);
+
+    void createNewCategoryCoro(std::string url, LLSD postData, inventory_func_type callback);
 	
 /**                    Mutators
  **                                                                            **
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 4a7a4e268d33cccff9d744e7c901cf2350b0339e..38c4382654434ee529340748b404069b0035d9f0 100755
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -36,7 +36,9 @@
 #include "llviewercontrol.h"
 #include "llviewermedia.h"
 #include "llviewernetwork.h"
-
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "llcorehttputil.h"
 
 //
 // Helpers
@@ -117,11 +119,76 @@ namespace LLMarketplaceImport
 	static S32 sImportResultStatus = 0;
 	static LLSD sImportResults = LLSD::emptyMap();
 
+#if 0
 	static LLTimer slmGetTimer;
 	static LLTimer slmPostTimer;
-
+#endif
 	// Responders
-	
+
+#if 1
+    void marketplacePostCoro(std::string url)
+    {
+        LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+        LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+            httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("marketplacePostCoro", httpPolicy));
+        LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+        LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+        LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+        httpOpts->setWantHeaders(true);
+        httpOpts->setFollowRedirects(true);
+
+        httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+        httpHeaders->append(HTTP_OUT_HEADER_CONNECTION, "Keep-Alive");
+        httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sMarketplaceCookie);
+        httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_XML);
+        httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, LLViewerMedia::getCurrentUserAgent());
+
+        LLSD result = httpAdapter->postAndYield(httpRequest, url, LLSD(), httpOpts, httpHeaders);
+
+        LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+        LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+        S32 httpCode = status.getType();
+        if ((httpCode == MarketplaceErrorCodes::IMPORT_REDIRECT) ||
+            (httpCode == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
+            // MAINT-2301 : we determined we can safely ignore that error in that context
+            (httpCode == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
+        {
+            if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+            {
+                LL_INFOS() << " SLM POST : Ignoring time out status and treating it as success" << LL_ENDL;
+            }
+            httpCode = MarketplaceErrorCodes::IMPORT_DONE;
+        }
+
+        if (httpCode >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
+        {
+            if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+            {
+                LL_INFOS() << " SLM POST clearing marketplace cookie due to client or server error" << LL_ENDL;
+            }
+            sMarketplaceCookie.clear();
+        }
+
+        sImportInProgress = (httpCode == MarketplaceErrorCodes::IMPORT_DONE);
+        sImportPostPending = false;
+        sImportResultStatus = httpCode;
+
+        {
+            std::stringstream str;
+            LLSDSerialize::toPrettyXML(result, str);
+
+            LL_INFOS() << "Full results:\n" << str.str() << "\n" << LL_ENDL;
+        }
+
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        sImportId = result;
+
+    }
+
+
+#else
 	class LLImportPostResponder : public LLHTTPClient::Responder
 	{
 		LOG_CLASS(LLImportPostResponder);
@@ -167,7 +234,75 @@ namespace LLMarketplaceImport
 			sImportId = getContent();
 		}
 	};
-	
+#endif
+
+#if 1
+    void marketplaceGetCoro(std::string url, bool buildHeaders)
+    {
+        LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+        LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+            httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("marketplaceGetCoro", httpPolicy));
+        LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+        LLCore::HttpHeaders::ptr_t httpHeaders; 
+        LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+        httpOpts->setWantHeaders(true);
+        httpOpts->setFollowRedirects(!sMarketplaceCookie.empty());
+
+        if (buildHeaders)
+        {
+            httpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
+
+            httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+            httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sMarketplaceCookie);
+            httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
+            httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, LLViewerMedia::getCurrentUserAgent());
+        }
+        else
+        {
+            httpHeaders = LLViewerMedia::getHttpHeaders();
+        }
+
+        LLSD result = httpAdapter->getAndYield(httpRequest, url, httpOpts, httpHeaders);
+
+        LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+        LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+        LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+
+        if (sMarketplaceCookie.empty() && resultHeaders.has(HTTP_IN_HEADER_SET_COOKIE))
+        {
+            sMarketplaceCookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asString();
+        }
+
+        // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS : Happens when trying to import objects with wrong permissions
+        // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initially empty
+        S32 httpCode = status.getType();
+        if ((httpCode >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) &&
+            (httpCode != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) &&
+            (httpCode != MarketplaceErrorCodes::IMPORT_NOT_FOUND))
+        {
+            if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+            {
+                LL_INFOS() << " SLM GET clearing marketplace cookie due to client or server error" << LL_ENDL;
+            }
+            sMarketplaceCookie.clear();
+        }
+        else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (httpCode >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST))
+        {
+            LL_INFOS() << " SLM GET : Got error status = " << httpCode << ", but marketplace cookie not cleared." << LL_ENDL;
+        }
+
+        sImportInProgress = (httpCode == MarketplaceErrorCodes::IMPORT_PROCESSING);
+        sImportGetPending = false;
+        sImportResultStatus = httpCode;
+
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        sImportResults = result;
+
+
+    }
+
+#else
 	class LLImportGetResponder : public LLHTTPClient::Responder
 	{
 		LOG_CLASS(LLImportGetResponder);
@@ -193,7 +328,7 @@ namespace LLMarketplaceImport
 			}
 			
             // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS : Happens when trying to import objects with wrong permissions
-            // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initally empty
+            // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initially empty
 			S32 status = getStatus();
 			if ((status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) &&
                 (status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) &&
@@ -216,6 +351,7 @@ namespace LLMarketplaceImport
 			sImportResults = getContent();
 		}
 	};
+#endif
 
 	// Basic API
 
@@ -266,8 +402,13 @@ namespace LLMarketplaceImport
 		sImportGetPending = true;
 		
 		std::string url = getInventoryImportURL();
-		
-		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+
+#if 1
+        LLCoros::instance().launch("marketplaceGetCoro",
+            boost::bind(&marketplaceGetCoro, url, false));
+
+#else
+    	if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 		{
             LL_INFOS() << " SLM GET: establishMarketplaceSessionCookie, LLHTTPClient::get, url = " << url << LL_ENDL;
             LLSD headers = LLViewerMedia::getHeaders();
@@ -279,7 +420,7 @@ namespace LLMarketplaceImport
 
 		slmGetTimer.start();
 		LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders());
-		
+#endif		
 		return true;
 	}
 	
@@ -296,6 +437,11 @@ namespace LLMarketplaceImport
 
 		url += sImportId.asString();
 
+#if 1
+        LLCoros::instance().launch("marketplaceGetCoro",
+            boost::bind(&marketplaceGetCoro, url, true));
+        
+#else
 		// Make the headers for the post
 		LLSD headers = LLSD::emptyMap();
 		headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
@@ -315,7 +461,7 @@ namespace LLMarketplaceImport
 
 		slmGetTimer.start();
 		LLHTTPClient::get(url, new LLImportGetResponder(), headers);
-		
+#endif		
 		return true;
 	}
 	
@@ -334,6 +480,11 @@ namespace LLMarketplaceImport
 
 		std::string url = getInventoryImportURL();
 		
+#if 1
+        LLCoros::instance().launch("marketplacePostCoro",
+            boost::bind(&marketplacePostCoro, url));
+
+#else
 		// Make the headers for the post
 		LLSD headers = LLSD::emptyMap();
 		headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
@@ -353,7 +504,7 @@ namespace LLMarketplaceImport
 
 		slmPostTimer.start();
         LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);
-		
+#endif		
 		return true;
 	}
 }
@@ -362,7 +513,6 @@ namespace LLMarketplaceImport
 //
 // Interface class
 //
-
 static const F32 MARKET_IMPORTER_UPDATE_FREQUENCY = 1.0f;
 
 //static
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index a1f6a01aa0d279934c071d8a2059b31639b4c4aa..aef5bcf0dd9d4218f8b94193cf6ca4299bb6eab9 100755
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -36,6 +36,9 @@
 #include "llviewerobjectlist.h"
 #include "llviewerregion.h"
 #include "llworld.h"
+#include "llhttpsdhandler.h"
+#include "httpcommon.h"
+#include "llcorehttputil.h"
 
 /**
  * Materials cap parameters
@@ -59,56 +62,51 @@
 #define MATERIALS_PUT_THROTTLE_SECS               1.f
 #define MATERIALS_PUT_MAX_ENTRIES                 50
 
-/**
- * LLMaterialsResponder helper class
- */
 
-class LLMaterialsResponder : public LLHTTPClient::Responder
+
+class LLMaterialHttpHandler : public LLHttpSDHandler
 {
-public:
-	typedef boost::function<void (bool, const LLSD&)> CallbackFunction;
+public: 
+	typedef boost::function<void(bool, const LLSD&)> CallbackFunction;
+	typedef boost::shared_ptr<LLMaterialHttpHandler> ptr_t;
+
+	LLMaterialHttpHandler(const std::string& method, CallbackFunction cback);
 
-	LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback);
-	virtual ~LLMaterialsResponder();
+	virtual ~LLMaterialHttpHandler();
 
-	virtual void httpSuccess();
-	virtual void httpFailure();
+protected:
+	virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
+	virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
 
 private:
 	std::string      mMethod;
-	std::string      mCapabilityURL;
 	CallbackFunction mCallback;
 };
 
-LLMaterialsResponder::LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback)
-	: LLHTTPClient::Responder()
-	, mMethod(pMethod)
-	, mCapabilityURL(pCapabilityURL)
-	, mCallback(pCallback)
+LLMaterialHttpHandler::LLMaterialHttpHandler(const std::string& method, CallbackFunction cback):
+	LLHttpSDHandler(),
+	mMethod(method),
+	mCallback(cback)
 {
+
 }
 
-LLMaterialsResponder::~LLMaterialsResponder()
+LLMaterialHttpHandler::~LLMaterialHttpHandler()
 {
 }
 
-void LLMaterialsResponder::httpSuccess()
+void LLMaterialHttpHandler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
 {
-	const LLSD& pContent = getContent();
-
 	LL_DEBUGS("Materials") << LL_ENDL;
-	mCallback(true, pContent);
+	mCallback(true, content);
 }
 
-void LLMaterialsResponder::httpFailure()
+void LLMaterialHttpHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
 {
-	U32 pStatus = (U32) getStatus();
-	const std::string& pReason = getReason();
-	
 	LL_WARNS("Materials")
 		<< "\n--------------------------------------------------------------------------\n"
-		<< mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
-		<< "'\n  with url '" << mCapabilityURL	<< "' because " << pReason 
+		<< mMethod << " Error[" << status.toULong() << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
+		<< "'\n  with url '" << response->getRequestURL() << "' because " << status.toString()
 		<< "\n--------------------------------------------------------------------------"
 		<< LL_ENDL;
 
@@ -116,12 +114,35 @@ void LLMaterialsResponder::httpFailure()
 	mCallback(false, emptyResult);
 }
 
+
+
 /**
  * LLMaterialMgr class
  */
-
-LLMaterialMgr::LLMaterialMgr()
+LLMaterialMgr::LLMaterialMgr():
+	mGetQueue(),
+	mGetPending(),
+	mGetCallbacks(),
+	mGetTECallbacks(),
+	mGetAllQueue(),
+	mGetAllRequested(),
+	mGetAllPending(),
+	mGetAllCallbacks(),
+	mPutQueue(),
+	mMaterials(),
+	mHttpRequest(),
+	mHttpHeaders(),
+	mHttpOptions(),
+	mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+	mHttpPriority(0)
 {
+	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
+
+	mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+	mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
+	mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
+	mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_MATERIALS);
+
 	mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(LLMaterialID::null, LLMaterialPtr(NULL)));
 	gIdleCallbacks.addFunction(&LLMaterialMgr::onIdle, NULL);
 	LLWorld::instance().setRegionRemovedCallback(boost::bind(&LLMaterialMgr::onRegionRemoved, this, _1));
@@ -554,6 +575,8 @@ void LLMaterialMgr::onIdle(void*)
 	{
 		instancep->processPutQueue();
 	}
+
+	instancep->mHttpRequest->update(0L);
 }
 
 void LLMaterialMgr::processGetQueue()
@@ -629,10 +652,26 @@ void LLMaterialMgr::processGetQueue()
 		LLSD postData = LLSD::emptyMap();
 		postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
 
-		LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id));
-		LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials." 
+		LLMaterialHttpHandler * handler = 
+				new LLMaterialHttpHandler("POST",
+				boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id)
+				);
+
+		LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '" << capURL << " for " << materialsData.size() << " materials."
 			<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
-		LLHTTPClient::post(capURL, postData, materialsResponder);
+
+		LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, 
+				mHttpPolicy, mHttpPriority, capURL, 
+				postData, mHttpOptions, mHttpHeaders, handler);
+
+		if (handle == LLCORE_HTTP_HANDLE_INVALID)
+		{
+			delete handler;
+			LLCore::HttpStatus status = mHttpRequest->getStatus();
+			LL_ERRS("Meterials") << "Failed to execute material POST. Status = " <<
+				status.toULong() << "\"" << status.toString() << "\"" << LL_ENDL;
+		}
+
 		regionp->resetMaterialsCapThrottle();
 	}
 }
@@ -667,8 +706,22 @@ void LLMaterialMgr::processGetAllQueue()
 		}
 
 		LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL;
-		LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion));
-		LLHTTPClient::get(capURL, materialsResponder);
+		LLMaterialHttpHandler *handler = 
+			new LLMaterialHttpHandler("GET",
+			boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion)
+			);
+
+		LLCore::HttpHandle handle = mHttpRequest->requestGet(mHttpPolicy, mHttpPriority, capURL,
+				mHttpOptions.get(), mHttpHeaders.get(), handler);
+
+		if (handle == LLCORE_HTTP_HANDLE_INVALID)
+		{
+			delete handler;
+			LLCore::HttpStatus status = mHttpRequest->getStatus();
+			LL_ERRS("Meterials") << "Failed to execute material GET. Status = " <<
+				status.toULong() << "\"" << status.toString() << "\"" << LL_ENDL;
+		}
+
 		regionp->resetMaterialsCapThrottle();
 		mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
 		mGetAllQueue.erase(itRegion);	// Invalidates region_id
@@ -755,8 +808,24 @@ void LLMaterialMgr::processPutQueue()
 			putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
 
 			LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
-			LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
-			LLHTTPClient::put(capURL, putData, materialsResponder);
+
+			LLMaterialHttpHandler * handler =
+					new LLMaterialHttpHandler("PUT",
+					boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2)
+					);
+
+			LLCore::HttpHandle handle = LLCoreHttpUtil::requestPutWithLLSD(
+				mHttpRequest, mHttpPolicy, mHttpPriority, capURL,
+				putData, mHttpOptions, mHttpHeaders, handler);
+
+			if (handle == LLCORE_HTTP_HANDLE_INVALID)
+			{
+				delete handler;
+				LLCore::HttpStatus status = mHttpRequest->getStatus();
+				LL_ERRS("Meterials") << "Failed to execute material PUT. Status = " << 
+					status.toULong() << "\"" << status.toString() << "\"" << LL_ENDL;
+			}
+
 			regionp->resetMaterialsCapThrottle();
 		}
 		else
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index e83f1f4e01464f1d5912867dbc7e87b99fcb4405..ef202d24baf5d847a211d74d084521e10badfba8 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -30,6 +30,9 @@
 #include "llmaterial.h"
 #include "llmaterialid.h"
 #include "llsingleton.h"
+#include "httprequest.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
 
 class LLViewerRegion;
 
@@ -56,7 +59,7 @@ class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
 	void put(const LLUUID& object_id, const U8 te, const LLMaterial& material);
 	void remove(const LLUUID& object_id, const U8 te);
 
-protected:
+private:
 	void clearGetQueues(const LLUUID& region_id);
 	bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const;
 	bool isGetAllPending(const LLUUID& region_id) const;
@@ -72,16 +75,7 @@ class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
 	void onPutResponse(bool success, const LLSD& content);
 	void onRegionRemoved(LLViewerRegion* regionp);
 
-protected:
-	typedef std::set<LLMaterialID> material_queue_t;
-	typedef std::map<LLUUID, material_queue_t> get_queue_t;
-	get_queue_t        mGetQueue;
-	typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
-	typedef std::map<const pending_material_t, F64> get_pending_map_t;
-	get_pending_map_t  mGetPending;
-	typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
-	get_callback_map_t mGetCallbacks;
-
+private:
 	// struct for TE-specific material ID query
 	class TEMaterialPair
 	{
@@ -108,22 +102,37 @@ class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
 		bool   operator()(const TEMaterialPair& left, const TEMaterialPair& right) const { return left < right; }
 	};
 
-	typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*, TEMaterialPairHasher> get_callback_te_map_t;
-	get_callback_te_map_t mGetTECallbacks;
+	typedef std::set<LLMaterialID> material_queue_t;
+	typedef std::map<LLUUID, material_queue_t> get_queue_t;
+	typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
+	typedef std::map<const pending_material_t, F64> get_pending_map_t;
+	typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
+
 
+	typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*, TEMaterialPairHasher> get_callback_te_map_t;
 	typedef std::set<LLUUID> getall_queue_t;
-	getall_queue_t        mGetAllQueue;
-	getall_queue_t        mGetAllRequested;
 	typedef std::map<LLUUID, F64> getall_pending_map_t;
-	getall_pending_map_t  mGetAllPending;
 	typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t;
-	getall_callback_map_t mGetAllCallbacks;
-
 	typedef std::map<U8, LLMaterial> facematerial_map_t;
 	typedef std::map<LLUUID, facematerial_map_t> put_queue_t;
-	put_queue_t mPutQueue;
 
-	material_map_t mMaterials;
+	get_queue_t				mGetQueue;
+	get_pending_map_t		mGetPending;
+	get_callback_map_t		mGetCallbacks;
+
+	get_callback_te_map_t	mGetTECallbacks;
+	getall_queue_t			mGetAllQueue;
+	getall_queue_t			mGetAllRequested;
+	getall_pending_map_t	mGetAllPending;
+	getall_callback_map_t	mGetAllCallbacks;
+	put_queue_t				mPutQueue;
+	material_map_t			mMaterials;
+
+	LLCore::HttpRequest::ptr_t		mHttpRequest;
+	LLCore::HttpHeaders::ptr_t		mHttpHeaders;
+	LLCore::HttpOptions::ptr_t		mHttpOptions;
+	LLCore::HttpRequest::policy_t	mHttpPolicy;
+	LLCore::HttpRequest::priority_t	mHttpPriority;
 
 	U32 getMaxEntries(const LLViewerRegion* regionp);
 };
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 2fb9e60b29e957d6615e48c38518c5707222094b..b8ff76aa6d48f4ef27a9802484da7ce3c508cd56 100755
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -33,6 +33,7 @@
 #pragma warning (disable:4702)
 #endif
 
+#include <algorithm>
 #include <boost/lexical_cast.hpp>
 
 #include "llhttpconstants.h"
@@ -40,6 +41,7 @@
 #include "llmediaentry.h"
 #include "lltextureentry.h"
 #include "llviewerregion.h"
+#include "llcorehttputil.h"
 
 //
 // When making a request
@@ -91,52 +93,74 @@ const U32 LLMediaDataClient::MAX_ROUND_ROBIN_QUEUE_SIZE = 10000;
 std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q);
 std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &q);
 
-template <typename T>
-typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type)
+
+//=========================================================================
+/// Uniary Predicate for matching requests in collections by either the request
+/// or by UUID
+/// 
+class PredicateMatchRequest
 {
-	for(typename T::iterator iter = c.begin(); iter != c.end(); ++iter)
-	{
-		if(request->isMatch(*iter, match_type))
-		{
-			return iter;
-		}
-	}
-	
-	return c.end();
+public:
+    PredicateMatchRequest(const LLMediaDataClient::Request::ptr_t &request, LLMediaDataClient::Request::Type matchType = LLMediaDataClient::Request::ANY);
+    PredicateMatchRequest(const LLUUID &id, LLMediaDataClient::Request::Type matchType = LLMediaDataClient::Request::ANY);
+
+    PredicateMatchRequest(const PredicateMatchRequest &other);
+
+    bool operator()(const LLMediaDataClient::Request::ptr_t &test) const;
+
+private:
+    LLMediaDataClient::Request::ptr_t mRequest;
+    LLMediaDataClient::Request::Type  mMatchType;
+    LLUUID                            mId;
+};
+
+
+PredicateMatchRequest::PredicateMatchRequest(const LLMediaDataClient::Request::ptr_t &request, LLMediaDataClient::Request::Type matchType) :
+    mRequest(request),
+    mMatchType(matchType),
+    mId()
+{}
+    
+PredicateMatchRequest::PredicateMatchRequest(const LLUUID &id, LLMediaDataClient::Request::Type matchType) :
+    mRequest(),
+    mMatchType(matchType),
+    mId(id)
+{}
+
+PredicateMatchRequest::PredicateMatchRequest(const PredicateMatchRequest &other)
+{
+    mRequest = other.mRequest;
+    mMatchType = other.mMatchType;
+    mId = other.mId;
 }
 
-template <typename T>
-typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type)
+bool PredicateMatchRequest::operator()(const LLMediaDataClient::Request::ptr_t &test) const
 {
-	for(typename T::iterator iter = c.begin(); iter != c.end(); ++iter)
-	{
-		if(((*iter)->getID() == id) && ((match_type == LLMediaDataClient::Request::ANY) || (match_type == (*iter)->getType())))
-		{
-			return iter;
-		}
-	}
-	
-	return c.end();
+    if (mRequest)
+        return (mRequest->isMatch(test, mMatchType));
+    else if (!mId.isNull())
+        return ((test->getID() == mId) && ((mMatchType == LLMediaDataClient::Request::ANY) || (mMatchType == test->getType())));
+    return false;
 }
 
-// NOTE: remove_matching_requests will not work correctly for containers where deleting an element may invalidate iterators
-// to other elements in the container (such as std::vector).
-// If the implementation is changed to use a container with this property, this will need to be revisited.
+//=========================================================================
+/// 
 template <typename T>
-void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type)
+void mark_dead_and_remove_if(T &c, const PredicateMatchRequest &matchPred)
 {
-	for(typename T::iterator iter = c.begin(); iter != c.end();)
-	{
-		typename T::value_type i = *iter;
-		typename T::iterator next = iter;
-		next++;
-		if((i->getID() == id) && ((match_type == LLMediaDataClient::Request::ANY) || (match_type == i->getType())))
-		{
-			i->markDead();
-			c.erase(iter);
-		}
-		iter = next;
-	}
+    for (typename T::iterator it = c.begin(); it != c.end();)
+    {
+        if (matchPred(*it))
+        {
+            (*it)->markDead();
+            // *TDOO: When C++11 is in change the following line to: it = c.erase(it);
+            c.erase(it++);
+        }
+        else
+        {
+            ++it;
+        }
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////////////
@@ -145,18 +169,20 @@ void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request
 //
 //////////////////////////////////////////////////////////////////////////////////////
 
-LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay,
-									 F32 retry_timer_delay,
-									 U32 max_retries,
-									 U32 max_sorted_queue_size,
-									 U32 max_round_robin_queue_size)
-	: mQueueTimerDelay(queue_timer_delay),
-	  mRetryTimerDelay(retry_timer_delay),
-	  mMaxNumRetries(max_retries),
-	  mMaxSortedQueueSize(max_sorted_queue_size),
-	  mMaxRoundRobinQueueSize(max_round_robin_queue_size),
-	  mQueueTimerIsRunning(false)
+LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay, F32 retry_timer_delay,  
+        U32 max_retries, U32 max_sorted_queue_size, U32 max_round_robin_queue_size):
+    mQueueTimerDelay(queue_timer_delay),
+    mRetryTimerDelay(retry_timer_delay),
+    mMaxNumRetries(max_retries),
+    mMaxSortedQueueSize(max_sorted_queue_size),
+    mMaxRoundRobinQueueSize(max_round_robin_queue_size),
+    mQueueTimerIsRunning(false),
+    mHttpRequest(new LLCore::HttpRequest()),
+    mHttpHeaders(new LLCore::HttpHeaders()),
+    mHttpOpts(new LLCore::HttpOptions()),
+    mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
 {
+    // *TODO: Look up real Policy ID
 }
 
 LLMediaDataClient::~LLMediaDataClient()
@@ -171,20 +197,23 @@ bool LLMediaDataClient::isEmpty() const
 
 bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object)
 {
-	if(find_matching_request(mQueue, object->getID(), LLMediaDataClient::Request::ANY) != mQueue.end())
-		return true;
-	
-	if(find_matching_request(mUnQueuedRequests, object->getID(), LLMediaDataClient::Request::ANY) != mUnQueuedRequests.end())
-		return true;
-	
+    PredicateMatchRequest upred(object->getID());
+
+    if (std::find_if(mQueue.begin(), mQueue.end(), upred) != mQueue.end())
+        return true;
+    if (std::find_if(mUnQueuedRequests.begin(), mUnQueuedRequests.end(), upred) != mUnQueuedRequests.end())
+        return true;
+    
 	return false;
 }
 
 void LLMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr_t &object)
 {
 	LL_DEBUGS("LLMediaDataClient") << "removing requests matching ID " << object->getID() << LL_ENDL;
-	remove_matching_requests(mQueue, object->getID(), LLMediaDataClient::Request::ANY);
-	remove_matching_requests(mUnQueuedRequests, object->getID(), LLMediaDataClient::Request::ANY);
+    PredicateMatchRequest upred(object->getID());
+
+    mark_dead_and_remove_if(mQueue, upred);
+    mark_dead_and_remove_if(mUnQueuedRequests, upred);
 }
 
 void LLMediaDataClient::startQueueTimer() 
@@ -207,23 +236,24 @@ void LLMediaDataClient::stopQueueTimer()
 
 bool LLMediaDataClient::processQueueTimer()
 {
-	if(isEmpty())
+    if (isDoneProcessing())
 		return true;
 
 	LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() started, queue size is:	  " << mQueue.size() << LL_ENDL;
 	LL_DEBUGS("LLMediaDataClientQueue") << "QueueTimer::tick() started, SORTED queue is:	  " << mQueue << LL_ENDL;
 			
 	serviceQueue();
-	
+    serviceHttp();
+
 	LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, queue size is:	  " << mQueue.size() << LL_ENDL;
 	LL_DEBUGS("LLMediaDataClientQueue") << "QueueTimer::tick() finished, SORTED queue is:	  " << mQueue << LL_ENDL;
 	
-	return isEmpty();
+    return isDoneProcessing();
 }
 
-LLMediaDataClient::request_ptr_t LLMediaDataClient::dequeue()
+LLMediaDataClient::Request::ptr_t LLMediaDataClient::dequeue()
 {
-	request_ptr_t request;
+	Request::ptr_t request;
 	request_queue_t *queue_p = getQueue();
 	
 	if (queue_p->empty())
@@ -242,20 +272,20 @@ LLMediaDataClient::request_ptr_t LLMediaDataClient::dequeue()
 		else
 		{
 			// Don't return this request -- it's not ready to be serviced.
-			request = NULL;
+            request.reset();
 		}
 	}
 
 	return request;
 }
 
-void LLMediaDataClient::pushBack(request_ptr_t request)
+void LLMediaDataClient::pushBack(Request::ptr_t request)
 {
 	request_queue_t *queue_p = getQueue();
 	queue_p->push_front(request);
 }
 
-void LLMediaDataClient::trackRequest(request_ptr_t request)
+void LLMediaDataClient::trackRequest(Request::ptr_t request)
 {
 	request_set_t::iterator iter = mUnQueuedRequests.find(request);
 	
@@ -269,7 +299,7 @@ void LLMediaDataClient::trackRequest(request_ptr_t request)
 	}
 }
 
-void LLMediaDataClient::stopTrackingRequest(request_ptr_t request)
+void LLMediaDataClient::stopTrackingRequest(Request::ptr_t request)
 {
 	request_set_t::iterator iter = mUnQueuedRequests.find(request);
 	
@@ -283,16 +313,22 @@ void LLMediaDataClient::stopTrackingRequest(request_ptr_t request)
 	}
 }
 
+bool LLMediaDataClient::isDoneProcessing() const
+{
+    return (isEmpty() && mUnQueuedRequests.empty());
+}
+
+
 void LLMediaDataClient::serviceQueue()
 {	
 	// Peel one off of the items from the queue and execute it
-	request_ptr_t request;
+	Request::ptr_t request;
 	
 	do
 	{
 		request = dequeue();
 
-		if(request.isNull())
+		if(!request)
 		{
 			// Queue is empty.
 			return;
@@ -317,7 +353,18 @@ void LLMediaDataClient::serviceQueue()
 		trackRequest(request);
 		
 		// and make the post
-		LLHTTPClient::post(url, sd_payload, request->createResponder());
+        LLHttpSDHandler *handler = request->createHandler();
+        LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, 0,
+            url, sd_payload, mHttpOpts, mHttpHeaders, handler);
+
+        if (handle == LLCORE_HTTP_HANDLE_INVALID)
+        {
+            // *TODO: Change this metaphore to use boost::shared_ptr<> for handlers.  Requires change in LLCore::HTTP
+            delete handler;
+            LLCore::HttpStatus status = mHttpRequest->getStatus();
+            LL_WARNS("LLMediaDataClient") << "'" << url << "' request POST failed. Reason "
+                << status.toTerseString() << " \"" << status.toString() << "\"" << LL_ENDL;
+        }
 	}
 	else 
 	{
@@ -332,13 +379,17 @@ void LLMediaDataClient::serviceQueue()
 		}
 		else
 		{
-			// This request has exceeded its maxumim retry count.  It will be dropped.
+			// This request has exceeded its maximum retry count.  It will be dropped.
 			LL_WARNS("LLMediaDataClient") << "Could not send request " << *request << " for " << mMaxNumRetries << " tries, dropping request." << LL_ENDL; 
 		}
 
 	}
 }
 
+void LLMediaDataClient::serviceHttp()
+{
+    mHttpRequest->update(0);
+}
 
 // dump the queue
 std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q)
@@ -395,7 +446,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()
 //
 //////////////////////////////////////////////////////////////////////////////////////
 
-LLMediaDataClient::RetryTimer::RetryTimer(F32 time, request_ptr_t request)
+LLMediaDataClient::RetryTimer::RetryTimer(F32 time, Request::ptr_t request)
 : LLEventTimer(time), mRequest(request)
 {
 	mRequest->startTracking();
@@ -417,7 +468,7 @@ BOOL LLMediaDataClient::RetryTimer::tick()
 	}
 	
 	// Release the ref to the request.
-	mRequest = NULL;
+    mRequest.reset();
 
 	// Don't fire again
 	return TRUE;
@@ -490,7 +541,7 @@ void LLMediaDataClient::Request::reEnqueue()
 {
 	if(mMDC)
 	{
-		mMDC->enqueue(this);
+		mMDC->enqueue(shared_from_this());
 	}
 }
 
@@ -533,13 +584,13 @@ bool LLMediaDataClient::Request::isDead()
 void LLMediaDataClient::Request::startTracking() 
 { 
 	if(mMDC) 
-		mMDC->trackRequest(this); 
+        mMDC->trackRequest(shared_from_this());
 }
 
 void LLMediaDataClient::Request::stopTracking() 
 { 
 	if(mMDC) 
-		mMDC->stopTrackingRequest(this); 
+        mMDC->stopTrackingRequest(shared_from_this());
 }
 
 std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &r)
@@ -551,79 +602,67 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &r)
 	<< " #retries=" << r.getRetryCount();
 	return s;
 }
-			
-//////////////////////////////////////////////////////////////////////////////////////
-//
-// LLMediaDataClient::Responder
-//
-//////////////////////////////////////////////////////////////////////////////////////
 
-LLMediaDataClient::Responder::Responder(const request_ptr_t &request)
-: mRequest(request)
+//========================================================================
+
+LLMediaDataClient::Handler::Handler(const Request::ptr_t &request):
+    mRequest(request)
 {
 }
 
-/*virtual*/
-void LLMediaDataClient::Responder::httpFailure()
+
+void LLMediaDataClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
 {
-	mRequest->stopTracking();
+    mRequest->stopTracking();
 
-	if(mRequest->isDead())
-	{
-		LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
-		return;
-	}
-	
-	if (getStatus() == HTTP_SERVICE_UNAVAILABLE)
-	{
-		F32 retry_timeout;
-#if 0
-		// *TODO: Honor server Retry-After header.
-		if (!hasResponseHeader(HTTP_IN_HEADER_RETRY_AFTER)
-			|| !getSecondsUntilRetryAfter(getResponseHeader(HTTP_IN_HEADER_RETRY_AFTER), retry_timeout))
-#endif
-		{
-			retry_timeout = mRequest->getRetryTimerDelay();
-		}
-		
-		mRequest->incRetryCount();
-		
-		if (mRequest->getRetryCount() < mRequest->getMaxNumRetries()) 
-		{
-			LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retrying in " << retry_timeout << " seconds" << LL_ENDL;
-			
-			// Start timer (instances are automagically tracked by
-			// InstanceTracker<> and LLEventTimer)
-			new RetryTimer(F32(retry_timeout/*secs*/), mRequest);
-		}
-		else 
-		{
-			LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retry count " 
-				<< mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL;
-		}
-	}
-	// *TODO: Redirect on 3xx status codes.
-	else 
-	{
-		LL_WARNS("LLMediaDataClient") << *mRequest << " http failure "
-				<< dumpResponse() << LL_ENDL;
-	}
+    if (mRequest->isDead())
+    {
+        LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
+        return;
+    }
+
+    LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << LL_ENDL;
 }
 
-/*virtual*/
-void LLMediaDataClient::Responder::httpSuccess()
+void LLMediaDataClient::Handler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
 {
-	mRequest->stopTracking();
+    mRequest->stopTracking();
 
-	if(mRequest->isDead())
-	{
-		LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
-		return;
-	}
+    if (status == LLCore::HttpStatus(HTTP_SERVICE_UNAVAILABLE))
+    {
+        F32 retry_timeout;
+#if 0
+        // *TODO: Honor server Retry-After header.
+        if (!hasResponseHeader(HTTP_IN_HEADER_RETRY_AFTER)
+            || !getSecondsUntilRetryAfter(getResponseHeader(HTTP_IN_HEADER_RETRY_AFTER), retry_timeout))
+#endif
+        {
+            retry_timeout = mRequest->getRetryTimerDelay();
+        }
+
+        mRequest->incRetryCount();
 
-	LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << " " << dumpResponse() << LL_ENDL;
+        if (mRequest->getRetryCount() < mRequest->getMaxNumRetries()) 
+        {
+            LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retrying in " << retry_timeout << " seconds" << LL_ENDL;
+
+            // Start timer (instances are automagically tracked by
+            // InstanceTracker<> and LLEventTimer)
+            new RetryTimer(F32(retry_timeout/*secs*/), mRequest);
+        }
+        else 
+        {
+            LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retry count " 
+                << mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL;
+        }
+    }
+    else
+    {
+        LL_WARNS("LLMediaDataClient") << *mRequest << " HTTP failure " << LL_ENDL;
+    }
 }
 
+
 //////////////////////////////////////////////////////////////////////////////////////
 //
 // LLObjectMediaDataClient
@@ -634,7 +673,7 @@ void LLMediaDataClient::Responder::httpSuccess()
 void LLObjectMediaDataClient::fetchMedia(LLMediaDataClientObject *object)
 {
 	// Create a get request and put it in the queue.
-	enqueue(new RequestGet(object, this));
+	enqueue(Request::ptr_t(new RequestGet(object, this)));
 }
 
 const char *LLObjectMediaDataClient::getCapabilityName() const 
@@ -678,14 +717,14 @@ void LLObjectMediaDataClient::sortQueue()
 }
 
 // static
-bool LLObjectMediaDataClient::compareRequestScores(const request_ptr_t &o1, const request_ptr_t &o2)
+bool LLObjectMediaDataClient::compareRequestScores(const Request::ptr_t &o1, const Request::ptr_t &o2)
 {
-	if (o2.isNull()) return true;
-	if (o1.isNull()) return false;
+	if (!o2) return true;
+	if (!o1) return false;
 	return ( o1->getScore() > o2->getScore() );
 }
 
-void LLObjectMediaDataClient::enqueue(Request *request)
+void LLObjectMediaDataClient::enqueue(Request::ptr_t request)
 {
 	if(request->isDead())
 	{
@@ -703,9 +742,10 @@ void LLObjectMediaDataClient::enqueue(Request *request)
 	{
 		// For GET requests that are not new, if a matching request is already in the round robin queue, 
 		// in flight, or being retried, leave it at its current position.
-		request_queue_t::iterator iter = find_matching_request(mRoundRobinQueue, request->getID(), Request::GET);
-		request_set_t::iterator iter2 = find_matching_request(mUnQueuedRequests, request->getID(), Request::GET);
-		
+        PredicateMatchRequest upred(request->getID(), Request::GET);
+        request_queue_t::iterator iter = std::find_if(mRoundRobinQueue.begin(), mRoundRobinQueue.end(), upred);
+        request_set_t::iterator iter2 = std::find_if(mUnQueuedRequests.begin(), mUnQueuedRequests.end(), upred);
+
 		if( (iter != mRoundRobinQueue.end()) || (iter2 != mUnQueuedRequests.end()) )
 		{
 			LL_DEBUGS("LLMediaDataClient") << "ALREADY THERE: NOT Queuing request for " << *request << LL_ENDL;
@@ -718,9 +758,11 @@ void LLObjectMediaDataClient::enqueue(Request *request)
 	// IF the update will cause an object update message to be sent out at some point in the future, it probably should.
 	
 	// Remove any existing requests of this type for this object
-	remove_matching_requests(mQueue, request->getID(), request->getType());
-	remove_matching_requests(mRoundRobinQueue, request->getID(), request->getType());
-	remove_matching_requests(mUnQueuedRequests, request->getID(), request->getType());
+    PredicateMatchRequest upred(request->getID(), request->getType());
+
+    mark_dead_and_remove_if(mQueue, upred);
+    mark_dead_and_remove_if(mRoundRobinQueue, upred);
+    mark_dead_and_remove_if(mUnQueuedRequests, upred);
 
 	if (is_new)
 	{
@@ -749,7 +791,7 @@ void LLObjectMediaDataClient::enqueue(Request *request)
 	startQueueTimer();
 }
 
-bool LLObjectMediaDataClient::canServiceRequest(request_ptr_t request) 
+bool LLObjectMediaDataClient::canServiceRequest(Request::ptr_t request) 
 {
 	if(mCurrentQueueIsTheSortedQueue)
 	{
@@ -785,9 +827,9 @@ bool LLObjectMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &ob
 	if(LLMediaDataClient::isInQueue(object))
 		return true;
 
-	if(find_matching_request(mRoundRobinQueue, object->getID(), LLMediaDataClient::Request::ANY) != mRoundRobinQueue.end())
-		return true;
-	
+    if (std::find_if(mRoundRobinQueue.begin(), mRoundRobinQueue.end(), PredicateMatchRequest(object->getID())) != mRoundRobinQueue.end())
+        return true;
+
 	return false;
 }
 
@@ -796,12 +838,12 @@ void LLObjectMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr
 	// First, call parent impl.
 	LLMediaDataClient::removeFromQueue(object);
 	
-	remove_matching_requests(mRoundRobinQueue, object->getID(), LLMediaDataClient::Request::ANY);
+    mark_dead_and_remove_if(mRoundRobinQueue, PredicateMatchRequest(object->getID()));
 }
 
 bool LLObjectMediaDataClient::processQueueTimer()
 {
-	if(isEmpty())
+    if (isDoneProcessing())
 		return true;
 		
 	LL_DEBUGS("LLMediaDataClient") << "started, SORTED queue size is:	  " << mQueue.size() 
@@ -816,6 +858,7 @@ bool LLObjectMediaDataClient::processQueueTimer()
 	LL_DEBUGS("LLMediaDataClientQueue") << "after sort, SORTED queue is:	  " << mQueue << LL_ENDL;
 	
 	serviceQueue();
+    serviceHttp();
 
 	swapCurrentQueue();
 	
@@ -824,7 +867,7 @@ bool LLObjectMediaDataClient::processQueueTimer()
 	LL_DEBUGS("LLMediaDataClientQueue") << "    SORTED queue is:	  " << mQueue << LL_ENDL;
 	LL_DEBUGS("LLMediaDataClientQueue") << "    RR queue is:	  " << mRoundRobinQueue << LL_ENDL;
 	
-	return isEmpty();
+    return isDoneProcessing();
 }
 
 LLObjectMediaDataClient::RequestGet::RequestGet(LLMediaDataClientObject *obj, LLMediaDataClient *mdc):
@@ -841,16 +884,16 @@ LLSD LLObjectMediaDataClient::RequestGet::getPayload() const
 	return result;
 }
 
-LLMediaDataClient::Responder *LLObjectMediaDataClient::RequestGet::createResponder()
+LLHttpSDHandler *LLObjectMediaDataClient::RequestGet::createHandler()
 {
-	return new LLObjectMediaDataClient::Responder(this);
+	return new LLObjectMediaDataClient::Handler(shared_from_this());
 }
 
 
 void LLObjectMediaDataClient::updateMedia(LLMediaDataClientObject *object)
 {
 	// Create an update request and put it in the queue.
-	enqueue(new RequestUpdate(object, this));
+	enqueue(Request::ptr_t(new RequestUpdate(object, this)));
 }
 
 LLObjectMediaDataClient::RequestUpdate::RequestUpdate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc):
@@ -877,60 +920,58 @@ LLSD LLObjectMediaDataClient::RequestUpdate::getPayload() const
 	return result;
 }
 
-LLMediaDataClient::Responder *LLObjectMediaDataClient::RequestUpdate::createResponder()
+LLHttpSDHandler *LLObjectMediaDataClient::RequestUpdate::createHandler()
 {
 	// This just uses the base class's responder.
-	return new LLMediaDataClient::Responder(this);
+	return new LLMediaDataClient::Handler(shared_from_this());
 }
 
-
-/*virtual*/
-void LLObjectMediaDataClient::Responder::httpSuccess()
+void LLObjectMediaDataClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
 {
-	getRequest()->stopTracking();
-
-	if(getRequest()->isDead())
-	{
-		LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
-		return;
-	}
-
-	const LLSD& content = getContent();
-	if (!content.isMap())
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
+    LLMediaDataClient::Handler::onSuccess(response, content);
+
+    if (getRequest()->isDead())
+    {   // warning emitted from base method.
+        return;
+    }
+
+    if (!content.isMap())
+    {
+        onFailure(response, LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"));
+        return;
+    }
+
+    // This responder is only used for GET requests, not UPDATE.
+    LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << LL_ENDL;
+
+    // Look for an error
+    if (content.has("error"))
+    {
+        const LLSD &error = content["error"];
+        LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error getting media data for object: code=" << 
+            error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
+
+        // XXX Warn user?
+    }
+    else 
+    {
+        // Check the data
+        const LLUUID &object_id = content[LLTextureEntry::OBJECT_ID_KEY];
+        if (object_id != getRequest()->getObject()->getID()) 
+        {
+            // NOT good, wrong object id!!
+            LL_WARNS("LLMediaDataClient") << *(getRequest()) << " DROPPING response with wrong object id (" << object_id << ")" << LL_ENDL;
+            return;
+        }
+
+        // Otherwise, update with object media data
+        getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY],
+            content[LLTextureEntry::MEDIA_VERSION_KEY]);
+    }
 
-	// This responder is only used for GET requests, not UPDATE.
-	LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << dumpResponse() << LL_ENDL;
-
-	// Look for an error
-	if (content.has("error"))
-	{
-		const LLSD &error = content["error"];
-		LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error getting media data for object: code=" << 
-			error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
-		
-		// XXX Warn user?
-	}
-	else 
-	{
-		// Check the data
-		const LLUUID &object_id = content[LLTextureEntry::OBJECT_ID_KEY];
-		if (object_id != getRequest()->getObject()->getID()) 
-		{
-			// NOT good, wrong object id!!
-			LL_WARNS("LLMediaDataClient") << *(getRequest()) << " DROPPING response with wrong object id (" << object_id << ")" << LL_ENDL;
-			return;
-		}
-		
-		// Otherwise, update with object media data
-		getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY],
-														 content[LLTextureEntry::MEDIA_VERSION_KEY]);
-	}
 }
 
+
 //////////////////////////////////////////////////////////////////////////////////////
 //
 // LLObjectMediaNavigateClient
@@ -943,16 +984,18 @@ const char *LLObjectMediaNavigateClient::getCapabilityName() const
 	return "ObjectMediaNavigate";
 }
 
-void LLObjectMediaNavigateClient::enqueue(Request *request)
+void LLObjectMediaNavigateClient::enqueue(Request::ptr_t request)
 {
 	if(request->isDead())
 	{
-		LL_DEBUGS("LLMediaDataClient") << "not queueing dead request " << *request << LL_ENDL;
+		LL_DEBUGS("LLMediaDataClient") << "not queuing dead request " << *request << LL_ENDL;
 		return;
 	}
 	
+    PredicateMatchRequest upred(request);
+
 	// If there's already a matching request in the queue, remove it.
-	request_queue_t::iterator iter = find_matching_request(mQueue, request, LLMediaDataClient::Request::ANY);
+    request_queue_t::iterator iter = std::find_if(mQueue.begin(), mQueue.end(), upred);
 	if(iter != mQueue.end())
 	{
 		LL_DEBUGS("LLMediaDataClient") << "removing matching queued request " << (**iter) << LL_ENDL;
@@ -960,7 +1003,7 @@ void LLObjectMediaNavigateClient::enqueue(Request *request)
 	}
 	else
 	{
-		request_set_t::iterator set_iter = find_matching_request(mUnQueuedRequests, request, LLMediaDataClient::Request::ANY);
+        request_set_t::iterator set_iter = std::find_if(mUnQueuedRequests.begin(), mUnQueuedRequests.end(), upred);
 		if(set_iter != mUnQueuedRequests.end())
 		{
 			LL_DEBUGS("LLMediaDataClient") << "removing matching unqueued request " << (**set_iter) << LL_ENDL;
@@ -979,7 +1022,7 @@ void LLObjectMediaNavigateClient::enqueue(Request *request)
 	else
 #endif
 	{
-		LL_DEBUGS("LLMediaDataClient") << "queueing new request " << (*request) << LL_ENDL;
+		LL_DEBUGS("LLMediaDataClient") << "queuing new request " << (*request) << LL_ENDL;
 		mQueue.push_back(request);
 		
 		// Start the timer if not already running
@@ -993,7 +1036,7 @@ void LLObjectMediaNavigateClient::navigate(LLMediaDataClientObject *object, U8 t
 //	LL_INFOS("LLMediaDataClient") << "navigate() initiated: " << ll_print_sd(sd_payload) << LL_ENDL;
 	
 	// Create a get request and put it in the queue.
-	enqueue(new RequestNavigate(object, this, texture_index, url));
+	enqueue(Request::ptr_t(new RequestNavigate(object, this, texture_index, url)));
 }
 
 LLObjectMediaNavigateClient::RequestNavigate::RequestNavigate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc, U8 texture_index, const std::string &url):
@@ -1012,75 +1055,67 @@ LLSD LLObjectMediaNavigateClient::RequestNavigate::getPayload() const
 	return result;
 }
 
-LLMediaDataClient::Responder *LLObjectMediaNavigateClient::RequestNavigate::createResponder()
+LLHttpSDHandler *LLObjectMediaNavigateClient::RequestNavigate::createHandler()
 {
-	return new LLObjectMediaNavigateClient::Responder(this);
+	return new LLObjectMediaNavigateClient::Handler(shared_from_this());
 }
 
-/*virtual*/
-void LLObjectMediaNavigateClient::Responder::httpFailure()
+void LLObjectMediaNavigateClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
 {
-	getRequest()->stopTracking();
+    LLMediaDataClient::Handler::onSuccess(response, content);
 
-	if(getRequest()->isDead())
-	{
-		LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
-		return;
-	}
+    if (getRequest()->isDead())
+    {   // already warned.
+        return;
+    }
+
+    LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned" << LL_ENDL;
+
+    if (content.has("error"))
+    {
+        const LLSD &error = content["error"];
+        int error_code = error["code"];
+
+        if (ERROR_PERMISSION_DENIED_CODE == error_code)
+        {
+            mediaNavigateBounceBack();
+        }
+        else
+        {
+            LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: code=" <<
+                error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
+        }
+
+        // XXX Warn user?
+    }
+    else
+    {
+        // No action required.
+        LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << LL_ENDL;
+    }
 
-	// Bounce back (unless HTTP_SERVICE_UNAVAILABLE, in which case call base
-	// class
-	if (getStatus() == HTTP_SERVICE_UNAVAILABLE)
-	{
-		LLMediaDataClient::Responder::httpFailure();
-	}
-	else
-	{
-		// bounce the face back
-		LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: " << dumpResponse() << LL_ENDL;
-		const LLSD &payload = getRequest()->getPayload();
-		// bounce the face back
-		getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
-	}
 }
 
-/*virtual*/
-void LLObjectMediaNavigateClient::Responder::httpSuccess()
+void LLObjectMediaNavigateClient::Handler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
 {
-	getRequest()->stopTracking();
+    LLMediaDataClient::Handler::onFailure(response, status);
 
-	if(getRequest()->isDead())
-	{
-		LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
-		return;
-	}
+    if (getRequest()->isDead())
+    {   // already warned.
+        return;
+    }
 
-	LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << dumpResponse() << LL_ENDL;
-	
-	const LLSD& content = getContent();
-	if (content.has("error"))
-	{
-		const LLSD &error = content["error"];
-		int error_code = error["code"];
-		
-		if (ERROR_PERMISSION_DENIED_CODE == error_code)
-		{
-			LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Navigation denied: bounce back" << LL_ENDL;
-			const LLSD &payload = getRequest()->getPayload();
-			// bounce the face back
-			getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
-		}
-		else
-		{
-			LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: code=" << 
-				error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
-		}			 
+    if (status != LLCore::HttpStatus(HTTP_SERVICE_UNAVAILABLE))
+    {
+        mediaNavigateBounceBack();
+    }
+}
 
-		// XXX Warn user?
-	}
-	else 
-	{
-		// No action required.
-		LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << dumpResponse() << LL_ENDL;
-	}
+void LLObjectMediaNavigateClient::Handler::mediaNavigateBounceBack()
+{
+    LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating or denied." << LL_ENDL;
+    const LLSD &payload = getRequest()->getPayload();
+    
+    // bounce the face back
+    getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
 }
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index 80dd5198124c9f126d72d44412ed5dbcea67cb2b..9907897613b4826f9dc6354a1f10cc9117c972e7 100755
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -27,12 +27,15 @@
 #ifndef LL_LLMEDIADATACLIENT_H
 #define LL_LLMEDIADATACLIENT_H
 
-#include "llhttpclient.h"
 #include <set>
 #include "llrefcount.h"
 #include "llpointer.h"
 #include "lleventtimer.h"
-
+#include "llhttpsdhandler.h"
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httpoptions.h"
+#include "httpheaders.h"
 
 // Link seam for LLVOVolume
 class LLMediaDataClientObject : public LLRefCount
@@ -74,6 +77,8 @@ class LLMediaDataClientObject : public LLRefCount
 // Abstracts the Cap URL, the request, and the responder
 class LLMediaDataClient : public LLRefCount
 {
+    friend class PredicateMatchRequest;
+
 protected:
     LOG_CLASS(LLMediaDataClient);
 public:
@@ -109,26 +114,30 @@ class LLMediaDataClient : public LLRefCount
 	// Destructor
 	virtual ~LLMediaDataClient(); // use unref
     
-	class Responder;
-	
 	// Request (pure virtual base class for requests in the queue)
-	class Request : public LLRefCount
-	{
-	public:
-		// Subclasses must implement this to build a payload for their request type.
-		virtual LLSD getPayload() const = 0;
-		// and must create the correct type of responder.
-		virtual Responder *createResponder() = 0;
+    class Request: 
+        public boost::enable_shared_from_this<Request>
+    {
+    public:
+        typedef boost::shared_ptr<Request> ptr_t;
 
-		virtual std::string getURL() { return ""; }
+        // Subclasses must implement this to build a payload for their request type.
+        virtual LLSD getPayload() const = 0;
+        // and must create the correct type of responder.
+        virtual LLHttpSDHandler *createHandler() = 0;
+
+        virtual std::string getURL() { return ""; }
 
         enum Type {
             GET,
             UPDATE,
             NAVIGATE,
-			ANY
+            ANY
         };
-        
+
+        virtual ~Request()
+        { }
+
 	protected:
 		// The only way to create one of these is through a subclass.
 		Request(Type in_type, LLMediaDataClientObject *obj, LLMediaDataClient *mdc, S32 face = -1);
@@ -166,7 +175,7 @@ class LLMediaDataClient : public LLRefCount
 		const LLUUID &getID() const { return mObjectID; }
 		S32 getFace() const { return mFace; }
 		
-		bool isMatch (const Request* other, Type match_type = ANY) const 
+		bool isMatch (const Request::ptr_t &other, Type match_type = ANY) const 
 		{ 
 			return ((match_type == ANY) || (mType == other->mType)) && 
 					(mFace == other->mFace) && 
@@ -188,61 +197,62 @@ class LLMediaDataClient : public LLRefCount
 		// Back pointer to the MDC...not a ref!
 		LLMediaDataClient *mMDC;
 	};
-	typedef LLPointer<Request> request_ptr_t;
+	//typedef LLPointer<Request> request_ptr_t;
 
-	// Responder
-	class Responder : public LLHTTPClient::Responder
-	{
-		LOG_CLASS(Responder);
-	public:
-		Responder(const request_ptr_t &request);
-		request_ptr_t &getRequest() { return mRequest; }
+    class Handler : public LLHttpSDHandler
+    {
+        LOG_CLASS(Handler);
+    public:
+        Handler(const Request::ptr_t &request);
+        Request::ptr_t getRequest() const { return mRequest; }
 
-	protected:
-		//If we get back an error (not found, etc...), handle it here
-		virtual void httpFailure();
-		//If we get back a normal response, handle it here.	 Default just logs it.
-		virtual void httpSuccess();
+    protected:
+        virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
+        virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
+
+    private:
+        Request::ptr_t mRequest;
+    };
 
-	private:
-		request_ptr_t mRequest;
-	};
 
 	class RetryTimer : public LLEventTimer
 	{
 	public:
-		RetryTimer(F32 time, request_ptr_t);
+		RetryTimer(F32 time, Request::ptr_t);
 		virtual BOOL tick();
 	private:
 		// back-pointer
-		request_ptr_t mRequest;
+		Request::ptr_t mRequest;
 	};
 		
 	
 protected:
-	typedef std::list<request_ptr_t> request_queue_t;
-	typedef std::set<request_ptr_t> request_set_t;
+	typedef std::list<Request::ptr_t> request_queue_t;
+	typedef std::set<Request::ptr_t> request_set_t;
 
 	// Subclasses must override to return a cap name
 	virtual const char *getCapabilityName() const = 0;
 
 	// Puts the request into a queue, appropriately handling duplicates, etc.
-	virtual void enqueue(Request*) = 0;
+    virtual void enqueue(Request::ptr_t) = 0;
 	
 	virtual void serviceQueue();
+    virtual void serviceHttp();
 
 	virtual request_queue_t *getQueue() { return &mQueue; };
 
 	// Gets the next request, removing it from the queue
-	virtual request_ptr_t dequeue();
+	virtual Request::ptr_t dequeue();
 	
-	virtual bool canServiceRequest(request_ptr_t request) { return true; };
+	virtual bool canServiceRequest(Request::ptr_t request) { return true; };
 
 	// Returns a request to the head of the queue (should only be used for requests that came from dequeue
-	virtual void pushBack(request_ptr_t request);
+	virtual void pushBack(Request::ptr_t request);
 	
-	void trackRequest(request_ptr_t request);
-	void stopTrackingRequest(request_ptr_t request);
+	void trackRequest(Request::ptr_t request);
+	void stopTrackingRequest(Request::ptr_t request);
+
+    bool isDoneProcessing() const;
 	
 	request_queue_t mQueue;
 
@@ -260,6 +270,11 @@ class LLMediaDataClient : public LLRefCount
 	void startQueueTimer();
 	void stopQueueTimer();
 
+    LLCore::HttpRequest::ptr_t  mHttpRequest;
+    LLCore::HttpHeaders::ptr_t  mHttpHeaders;
+    LLCore::HttpOptions::ptr_t  mHttpOpts;
+    LLCore::HttpRequest::policy_t mHttpPolicy;
+
 private:
 	
 	static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj);
@@ -281,9 +296,9 @@ class LLMediaDataClient : public LLRefCount
 		
 	bool mQueueTimerIsRunning;
 
-	template <typename T> friend typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type);
-	template <typename T> friend typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type);
-	template <typename T> friend void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type);
+// 	template <typename T> friend typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type);
+// 	template <typename T> friend typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type);
+// 	template <typename T> friend void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type);
 };
 
 // MediaDataClient specific for the ObjectMedia cap
@@ -309,7 +324,7 @@ class LLObjectMediaDataClient : public LLMediaDataClient
 	public:
 		RequestGet(LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
 		/*virtual*/ LLSD getPayload() const;
-		/*virtual*/ Responder *createResponder();
+        /*virtual*/ LLHttpSDHandler *createHandler();
 	};
 
 	class RequestUpdate: public Request
@@ -317,7 +332,7 @@ class LLObjectMediaDataClient : public LLMediaDataClient
 	public:
 		RequestUpdate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
 		/*virtual*/ LLSD getPayload() const;
-		/*virtual*/ Responder *createResponder();
+        /*virtual*/ LLHttpSDHandler *createHandler();
 	};
 
 	// Returns true iff the queue is empty
@@ -331,7 +346,7 @@ class LLObjectMediaDataClient : public LLMediaDataClient
 
 	virtual bool processQueueTimer();
 
-	virtual bool canServiceRequest(request_ptr_t request);
+	virtual bool canServiceRequest(Request::ptr_t request);
 
 protected:
 	// Subclasses must override to return a cap name
@@ -340,17 +355,20 @@ class LLObjectMediaDataClient : public LLMediaDataClient
 	virtual request_queue_t *getQueue();
 
 	// Puts the request into the appropriate queue
-	virtual void enqueue(Request*);
+	virtual void enqueue(Request::ptr_t);
 		    
-    class Responder : public LLMediaDataClient::Responder
+    class Handler: public LLMediaDataClient::Handler
     {
-        LOG_CLASS(Responder);
+        LOG_CLASS(Handler);
     public:
-        Responder(const request_ptr_t &request)
-            : LLMediaDataClient::Responder(request) {}
+        Handler(const Request::ptr_t &request):
+            LLMediaDataClient::Handler(request)
+        {}
+
     protected:
-        virtual void httpSuccess();
+        virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
     };
+
 private:
 	// The Get/Update data client needs a second queue to avoid object updates starving load-ins.
 	void swapCurrentQueue();
@@ -359,7 +377,7 @@ class LLObjectMediaDataClient : public LLMediaDataClient
 	bool mCurrentQueueIsTheSortedQueue;
 
 	// Comparator for sorting
-	static bool compareRequestScores(const request_ptr_t &o1, const request_ptr_t &o2);
+	static bool compareRequestScores(const Request::ptr_t &o1, const Request::ptr_t &o2);
 	void sortQueue();
 };
 
@@ -384,14 +402,14 @@ class LLObjectMediaNavigateClient : public LLMediaDataClient
     void navigate(LLMediaDataClientObject *object, U8 texture_index, const std::string &url);
 
 	// Puts the request into the appropriate queue
-	virtual void enqueue(Request*);
+    virtual void enqueue(Request::ptr_t);
 
 	class RequestNavigate: public Request
 	{
 	public:
 		RequestNavigate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc, U8 texture_index, const std::string &url);
 		/*virtual*/ LLSD getPayload() const;
-		/*virtual*/ Responder *createResponder();
+        /*virtual*/ LLHttpSDHandler *createHandler();
 		/*virtual*/ std::string getURL() { return mURL; }
 	private:
 		std::string mURL;
@@ -401,15 +419,18 @@ class LLObjectMediaNavigateClient : public LLMediaDataClient
 	// Subclasses must override to return a cap name
 	virtual const char *getCapabilityName() const;
 
-    class Responder : public LLMediaDataClient::Responder
+    class Handler : public LLMediaDataClient::Handler
     {
-        LOG_CLASS(Responder);
+        LOG_CLASS(Handler);
     public:
-        Responder(const request_ptr_t &request)
-            : LLMediaDataClient::Responder(request) {}
+        Handler(const Request::ptr_t &request):
+            LLMediaDataClient::Handler(request)
+        {}
+
     protected:
-        virtual void httpFailure();
-        virtual void httpSuccess();
+        virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
+        virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
+
     private:
         void mediaNavigateBounceBack();
     };
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 878f1af9efae0da5e6113eff2da2795273a0f480..5d1ae4ff10c4b4e9928b58b4a5cc9a137c5eadf5 100755
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -34,14 +34,12 @@
 
 #include "lldispatcher.h"
 #include "llfloaterreg.h"
-#include "llhttpclient.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llparcel.h"
 
 #include "llagent.h"
 #include "llclassifiedflags.h"
-#include "llclassifiedstatsresponder.h"
 #include "llcommandhandler.h" // for classified HTML detail page click tracking
 #include "lliconctrl.h"
 #include "lllineeditor.h"
@@ -57,6 +55,7 @@
 #include "llscrollcontainer.h"
 #include "llstatusbar.h"
 #include "llviewertexture.h"
+#include "llcorehttputil.h"
 
 const S32 MINIMUM_PRICE_FOR_LISTING = 50;	// L$
 
@@ -91,19 +90,6 @@ class LLDispatchClassifiedClickThrough : public LLDispatchHandler
 };
 static LLDispatchClassifiedClickThrough sClassifiedClickThrough;
 
-// Just to debug errors. Can be thrown away later.
-class LLClassifiedClickMessageResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLClassifiedClickMessageResponder);
-
-protected:
-	// If we get back an error (not found, etc...), handle it here
-	virtual void httpFailure()
-	{
-		LL_WARNS() << "Sending click message failed " << dumpResponse() << LL_ENDL;
-	}
-};
-
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -229,8 +215,10 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key)
 	{
 		LL_INFOS() << "Classified stat request via capability" << LL_ENDL;
 		LLSD body;
-		body["classified_id"] = getClassifiedId();
-		LLHTTPClient::post(url, body, new LLClassifiedStatsResponder(getClassifiedId()));
+        LLUUID classifiedId = getClassifiedId();
+		body["classified_id"] = classifiedId;
+        LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body,
+            boost::bind(&LLPanelClassifiedInfo::handleSearchStatResponse, classifiedId, _1));
 	}
 
 	// Update classified click stats.
@@ -240,6 +228,23 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key)
 	setInfoLoaded(false);
 }
 
+/*static*/
+void LLPanelClassifiedInfo::handleSearchStatResponse(LLUUID classifiedId, LLSD result)
+{
+    S32 teleport = result["teleport_clicks"].asInteger();
+    S32 map = result["map_clicks"].asInteger();
+    S32 profile = result["profile_clicks"].asInteger();
+    S32 search_teleport = result["search_teleport_clicks"].asInteger();
+    S32 search_map = result["search_map_clicks"].asInteger();
+    S32 search_profile = result["search_profile_clicks"].asInteger();
+
+    LLPanelClassifiedInfo::setClickThrough(classifiedId,
+        teleport + search_teleport,
+        map + search_map,
+        profile + search_profile,
+        true);
+}
+
 void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType type)
 {
 	if(APT_CLASSIFIED_INFO == type)
@@ -548,7 +553,8 @@ void LLPanelClassifiedInfo::sendClickMessage(
 	std::string url = gAgent.getRegion()->getCapability("SearchStatTracking");
 	LL_INFOS() << "Sending click msg via capability (url=" << url << ")" << LL_ENDL;
 	LL_INFOS() << "body: [" << body << "]" << LL_ENDL;
-	LLHTTPClient::post(url, body, new LLClassifiedClickMessageResponder());
+    LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+        "SearchStatTracking Click report sent.", "SearchStatTracking Click report NOT sent.");
 }
 
 void LLPanelClassifiedInfo::sendClickMessage(const std::string& type)
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index cedd65c405a93dac67a68441dda8be66ceb67b96..b29278261543123e1464e013f75044b9ea974f34 100755
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -37,6 +37,8 @@
 #include "llrect.h"
 #include "lluuid.h"
 #include "v3dmath.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
 
 class LLScrollContainer;
 class LLTextureCtrl;
@@ -193,6 +195,9 @@ class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
 	S32 mMapClicksNew;
 	S32 mProfileClicksNew;
 
+    static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
+
+
 	typedef std::list<LLPanelClassifiedInfo*> panel_list_t;
 	static panel_list_t sAllPanels;
 };
diff --git a/indra/newview/llpanelexperiencepicker.cpp b/indra/newview/llpanelexperiencepicker.cpp
index 70d826a407f8d7e8e731df07a51fc45669211405..c7a353a6afecfbce787f62c73c1651a015b6664c 100644
--- a/indra/newview/llpanelexperiencepicker.cpp
+++ b/indra/newview/llpanelexperiencepicker.cpp
@@ -42,6 +42,7 @@
 #include "llviewercontrol.h"
 #include "llfloater.h"
 #include "lltrans.h"
+#include "llhttpclient.h"  // *TODO: Rider, remove when converting
 
 #define BTN_FIND		"find"
 #define BTN_OK			"ok_btn"
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 1d73d4bd6ed219a6223bd1fccdc858aa8ed69b0d..cd1dc0f0701de1e5173fe84d353a9449060df4c8 100755
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -1352,17 +1352,8 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
 	std::string url = region->getCapability("RemoteParcelRequest");
 	if (!url.empty())
 	{
-		body["location"] = ll_sd_from_vector3(region_pos);
-		if (!region_id.isNull())
-		{
-			body["region_id"] = region_id;
-		}
-		if (!pos_global.isExactlyZero())
-		{
-			U64 region_handle = to_region_handle(pos_global);
-			body["region_handle"] = ll_sd_from_U64(region_handle);
-		}
-		LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
+        LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url,
+            region_id, region_pos, pos_global, getObserverHandle());
 	}
 	else
 	{
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index cc8c3edd51a8435ca105b88235cedf94e40dab8d..99c9fad82dfd90cabf0a143f613002b36ba028e2 100755
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -59,7 +59,6 @@
 #include "llviewernetwork.h"
 #include "llviewerwindow.h"			// to link into child list
 #include "lluictrlfactory.h"
-#include "llhttpclient.h"
 #include "llweb.h"
 #include "llmediactrl.h"
 #include "llrootview.h"
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index cedd3025fc479dddd9ca630e6eae49027166ae13..55e4ffff5e10c5753dab5cfc0ee60e3301c47400 100755
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -37,7 +37,6 @@
 #include "llfloaterreg.h"
 #include "llhints.h"
 #include "llviewercontrol.h"
-#include "llviewerdisplayname.h"
 
 // Linden libraries
 #include "llavatarnamecache.h"		// IDEVO
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index e62b5a4f1d6b384d2a9c41fe095723e1ac592461..cec56a7ae78773bafeed57da62674f6a3045eb75 100755
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -45,6 +45,7 @@
 #include "llpanelpick.h"
 #include "lltexturectrl.h"
 #include "llviewerregion.h"
+#include "llhttpconstants.h"
 
 LLPanelPlaceInfo::LLPanelPlaceInfo()
 :	LLPanel(),
@@ -150,17 +151,8 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLUUID& region_id,
 	std::string url = region->getCapability("RemoteParcelRequest");
 	if (!url.empty())
 	{
-		body["location"] = ll_sd_from_vector3(mPosRegion);
-		if (!region_id.isNull())
-		{
-			body["region_id"] = region_id;
-		}
-		if (!pos_global.isExactlyZero())
-		{
-			U64 region_handle = to_region_handle(pos_global);
-			body["region_handle"] = ll_sd_from_U64(region_handle);
-		}
-		LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
+        LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url,
+            region_id, mPosRegion, pos_global, getObserverHandle());
 	}
 	else
 	{
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index 4977a72dc692afcf655e1ebd74fa24af59ab34ba..2e6937a79fd163592c5d20dc4a844fe869a3d556 100755
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -39,7 +39,6 @@
 #include <boost/signals2.hpp>
 
 #include "llagent.h"
-#include "llhttpclient.h"
 #include "llhttpnode.h"
 #include "llnotificationsutil.h"
 #include "llpathfindingcharacterlist.h"
@@ -55,6 +54,8 @@
 #include "lluuid.h"
 #include "llviewerregion.h"
 #include "llweb.h"
+#include "llcorehttputil.h"
+#include "llworld.h"
 
 #define CAP_SERVICE_RETRIEVE_NAVMESH        "RetrieveNavMeshSrc"
 
@@ -97,82 +98,6 @@ class LLAgentStateChangeNode : public LLHTTPNode
 
 LLHTTPRegistration<LLAgentStateChangeNode> gHTTPRegistrationAgentStateChangeNode(SIM_MESSAGE_AGENT_STATE_UPDATE);
 
-//---------------------------------------------------------------------------
-// NavMeshStatusResponder
-//---------------------------------------------------------------------------
-
-class NavMeshStatusResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(NavMeshStatusResponder);
-public:
-	NavMeshStatusResponder(LLViewerRegion *pRegion, bool pIsGetStatusOnly);
-	virtual ~NavMeshStatusResponder();
-
-protected:
-	virtual void httpSuccess();
-	virtual void httpFailure();
-
-private:
-	LLViewerRegion *mRegion;
-	LLUUID         mRegionUUID;
-	bool           mIsGetStatusOnly;
-};
-
-//---------------------------------------------------------------------------
-// NavMeshResponder
-//---------------------------------------------------------------------------
-
-class NavMeshResponder : public LLHTTPClient::Responder
-{
-    LOG_CLASS(NavMeshResponder);
-public:
-	NavMeshResponder(U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr);
-	virtual ~NavMeshResponder();
-
-protected:
-	virtual void httpSuccess();
-	virtual void httpFailure();
-
-private:
-	U32                     mNavMeshVersion;
-	LLPathfindingNavMeshPtr mNavMeshPtr;
-};
-
-//---------------------------------------------------------------------------
-// AgentStateResponder
-//---------------------------------------------------------------------------
-
-class AgentStateResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(AgentStateResponder);
-public:
-	AgentStateResponder();
-	virtual ~AgentStateResponder();
-
-protected:
-	virtual void httpSuccess();
-	virtual void httpFailure();
-};
-
-
-//---------------------------------------------------------------------------
-// NavMeshRebakeResponder
-//---------------------------------------------------------------------------
-class NavMeshRebakeResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(NavMeshRebakeResponder);
-public:
-	NavMeshRebakeResponder(LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback);
-	virtual ~NavMeshRebakeResponder();
-
-protected:
-	virtual void httpSuccess();
-	virtual void httpFailure();
-
-private:
-	LLPathfindingManager::rebake_navmesh_callback_t mRebakeNavMeshCallback;
-};
-
 //---------------------------------------------------------------------------
 // LinksetsResponder
 //---------------------------------------------------------------------------
@@ -188,6 +113,8 @@ class LinksetsResponder
 	void handleTerrainLinksetsResult(const LLSD &pContent);
 	void handleTerrainLinksetsError();
 
+    typedef boost::shared_ptr<LinksetsResponder> ptr_t;
+
 protected:
 
 private:
@@ -213,64 +140,6 @@ class LinksetsResponder
 
 typedef boost::shared_ptr<LinksetsResponder> LinksetsResponderPtr;
 
-//---------------------------------------------------------------------------
-// ObjectLinksetsResponder
-//---------------------------------------------------------------------------
-
-class ObjectLinksetsResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(ObjectLinksetsResponder);
-public:
-	ObjectLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr);
-	virtual ~ObjectLinksetsResponder();
-
-protected:
-	virtual void httpSuccess();
-	virtual void httpFailure();
-
-private:
-	LinksetsResponderPtr mLinksetsResponsderPtr;
-};
-
-//---------------------------------------------------------------------------
-// TerrainLinksetsResponder
-//---------------------------------------------------------------------------
-
-class TerrainLinksetsResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(TerrainLinksetsResponder);
-public:
-	TerrainLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr);
-	virtual ~TerrainLinksetsResponder();
-
-protected:
-	virtual void httpSuccess();
-	virtual void httpFailure();
-
-private:
-	LinksetsResponderPtr mLinksetsResponsderPtr;
-};
-
-//---------------------------------------------------------------------------
-// CharactersResponder
-//---------------------------------------------------------------------------
-
-class CharactersResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(TerrainLinksetsResponder);
-public:
-	CharactersResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback);
-	virtual ~CharactersResponder();
-
-protected:
-	virtual void httpSuccess();
-	virtual void httpFailure();
-
-private:
-	LLPathfindingManager::request_id_t              mRequestId;
-	LLPathfindingManager::object_request_callback_t mCharactersCallback;
-};
-
 //---------------------------------------------------------------------------
 // LLPathfindingManager
 //---------------------------------------------------------------------------
@@ -350,11 +219,13 @@ void LLPathfindingManager::requestGetNavMeshForRegion(LLViewerRegion *pRegion, b
 	}
 	else
 	{
-		std::string navMeshStatusURL = getNavMeshStatusURLForRegion(pRegion);
-		llassert(!navMeshStatusURL.empty());
-		navMeshPtr->handleNavMeshCheckVersion();
-		LLHTTPClient::ResponderPtr navMeshStatusResponder = new NavMeshStatusResponder(pRegion, pIsGetStatusOnly);
-		LLHTTPClient::get(navMeshStatusURL, navMeshStatusResponder);
+        std::string navMeshStatusURL = getNavMeshStatusURLForRegion(pRegion);
+        llassert(!navMeshStatusURL.empty());
+        navMeshPtr->handleNavMeshCheckVersion();
+
+        U64 regionHandle = pRegion->getHandle();
+        std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navMeshStatusRequestCoro",
+            boost::bind(&LLPathfindingManager::navMeshStatusRequestCoro, this, navMeshStatusURL, regionHandle, pIsGetStatusOnly));
 	}
 }
 
@@ -385,15 +256,15 @@ void LLPathfindingManager::requestGetLinksets(request_id_t pRequestId, object_re
 			pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr);
 
 			bool doRequestTerrain = isAllowViewTerrainProperties();
-			LinksetsResponderPtr linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, true, doRequestTerrain));
+			LinksetsResponder::ptr_t linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, true, doRequestTerrain));
 
-			LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(linksetsResponderPtr);
-			LLHTTPClient::get(objectLinksetsURL, objectLinksetsResponder);
+            std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetObjectsCoro",
+                boost::bind(&LLPathfindingManager::linksetObjectsCoro, this, objectLinksetsURL, linksetsResponderPtr, LLSD()));
 
-			if (doRequestTerrain)
+            if (doRequestTerrain)
 			{
-				LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(linksetsResponderPtr);
-				LLHTTPClient::get(terrainLinksetsURL, terrainLinksetsResponder);
+                std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetTerrainCoro",
+                    boost::bind(&LLPathfindingManager::linksetTerrainCoro, this, terrainLinksetsURL, linksetsResponderPtr, LLSD()));
 			}
 		}
 	}
@@ -432,18 +303,18 @@ void LLPathfindingManager::requestSetLinksets(request_id_t pRequestId, const LLP
 		{
 			pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr);
 
-			LinksetsResponderPtr linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, !objectPostData.isUndefined(), !terrainPostData.isUndefined()));
+			LinksetsResponder::ptr_t linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, !objectPostData.isUndefined(), !terrainPostData.isUndefined()));
 
 			if (!objectPostData.isUndefined())
 			{
-				LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(linksetsResponderPtr);
-				LLHTTPClient::put(objectLinksetsURL, objectPostData, objectLinksetsResponder);
+                std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetObjectsCoro",
+                    boost::bind(&LLPathfindingManager::linksetObjectsCoro, this, objectLinksetsURL, linksetsResponderPtr, objectPostData));
 			}
 
 			if (!terrainPostData.isUndefined())
 			{
-				LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(linksetsResponderPtr);
-				LLHTTPClient::put(terrainLinksetsURL, terrainPostData, terrainLinksetsResponder);
+                std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetTerrainCoro",
+                    boost::bind(&LLPathfindingManager::linksetTerrainCoro, this, terrainLinksetsURL, linksetsResponderPtr, terrainPostData));
 			}
 		}
 	}
@@ -475,8 +346,8 @@ void LLPathfindingManager::requestGetCharacters(request_id_t pRequestId, object_
 		{
 			pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr);
 
-			LLHTTPClient::ResponderPtr charactersResponder = new CharactersResponder(pRequestId, pCharactersCallback);
-			LLHTTPClient::get(charactersURL, charactersResponder);
+            std::string coroname = LLCoros::instance().launch("LLPathfindingManager::charactersCoro",
+                boost::bind(&LLPathfindingManager::charactersCoro, this, charactersURL, pRequestId, pCharactersCallback));
 		}
 	}
 }
@@ -508,8 +379,9 @@ void LLPathfindingManager::requestGetAgentState()
 		{
 			std::string agentStateURL = getAgentStateURLForRegion(currentRegion);
 			llassert(!agentStateURL.empty());
-			LLHTTPClient::ResponderPtr responder = new AgentStateResponder();
-			LLHTTPClient::get(agentStateURL, responder);
+
+            std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navAgentStateRequestCoro",
+                boost::bind(&LLPathfindingManager::navAgentStateRequestCoro, this, agentStateURL));
 		}
 	}
 }
@@ -530,35 +402,9 @@ void LLPathfindingManager::requestRebakeNavMesh(rebake_navmesh_callback_t pRebak
 	{
 		std::string navMeshStatusURL = getNavMeshStatusURLForCurrentRegion();
 		llassert(!navMeshStatusURL.empty());
-		LLSD postData;			
-		postData["command"] = "rebuild";
-		LLHTTPClient::ResponderPtr responder = new NavMeshRebakeResponder(pRebakeNavMeshCallback);
-		LLHTTPClient::post(navMeshStatusURL, postData, responder);
-	}
-}
-
-void LLPathfindingManager::sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPtr navMeshPtr, LLViewerRegion *pRegion, const LLPathfindingNavMeshStatus &pNavMeshStatus)
-{
-	if ((pRegion == NULL) || !pRegion->isAlive())
-	{
-		navMeshPtr->handleNavMeshNotEnabled();
-	}
-	else
-	{
-		std::string navMeshURL = getRetrieveNavMeshURLForRegion(pRegion);
-
-		if (navMeshURL.empty())
-		{
-			navMeshPtr->handleNavMeshNotEnabled();
-		}
-		else
-		{
-			navMeshPtr->handleNavMeshStart(pNavMeshStatus);
-			LLHTTPClient::ResponderPtr responder = new NavMeshResponder(pNavMeshStatus.getVersion(), navMeshPtr);
 
-			LLSD postData;
-			LLHTTPClient::post(navMeshURL, postData, responder);
-		}
+        std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navMeshRebakeCoro",
+                boost::bind(&LLPathfindingManager::navMeshRebakeCoro, this, navMeshStatusURL, pRebakeNavMeshCallback));
 	}
 }
 
@@ -602,29 +448,250 @@ void LLPathfindingManager::handleDeferredGetCharactersForRegion(const LLUUID &pR
 	}
 }
 
-void LLPathfindingManager::handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion, bool pIsGetStatusOnly)
+void LLPathfindingManager::navMeshStatusRequestCoro(std::string url, U64 regionHandle, bool isGetStatusOnly)
 {
-	LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID());
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavMeshStatusRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLViewerRegion *region = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+    if (!region)
+    {
+        LL_WARNS("PathfindingManager") << "Attempting to retrieve navmesh status for region that has gone away." << LL_ENDL;
+        return;
+    }
+    LLUUID regionUUID = region->getRegionID();
+
+    region = NULL;
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    region = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
 
-	if (!pNavMeshStatus.isValid())
-	{
-		navMeshPtr->handleNavMeshError();
-	}
-	else
-	{
-		if (navMeshPtr->hasNavMeshVersion(pNavMeshStatus))
-		{
-			navMeshPtr->handleRefresh(pNavMeshStatus);
-		}
-		else if (pIsGetStatusOnly)
-		{
-			navMeshPtr->handleNavMeshNewVersion(pNavMeshStatus);
-		}
-		else
-		{
-			sendRequestGetNavMeshForRegion(navMeshPtr, pRegion, pNavMeshStatus);
-		}
-	}
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    LLPathfindingNavMeshStatus navMeshStatus(regionUUID);
+    if (!status)
+    {
+        LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() << 
+            ". Building using empty status." << LL_ENDL;
+    }
+    else
+    {
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        navMeshStatus = LLPathfindingNavMeshStatus(regionUUID, result);
+    }
+
+    LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(regionUUID);
+
+    if (!navMeshStatus.isValid())
+    {
+        navMeshPtr->handleNavMeshError();
+        return;
+    }
+    else if (navMeshPtr->hasNavMeshVersion(navMeshStatus))
+    {
+        navMeshPtr->handleRefresh(navMeshStatus);
+        return;
+    }
+    else if (isGetStatusOnly)
+    {
+        navMeshPtr->handleNavMeshNewVersion(navMeshStatus);
+        return;
+    }
+
+    if ((!region) || !region->isAlive())
+    {
+        LL_WARNS("PathfindingManager") << "About to update navmesh status for region that has gone away." << LL_ENDL;
+        navMeshPtr->handleNavMeshNotEnabled();
+        return;
+    }
+
+    std::string navMeshURL = getRetrieveNavMeshURLForRegion(region);
+
+    if (navMeshURL.empty())
+    {
+        navMeshPtr->handleNavMeshNotEnabled();
+        return;
+    }
+
+    navMeshPtr->handleNavMeshStart(navMeshStatus);
+
+    LLSD postData;
+    result = httpAdapter->postAndYield(httpRequest, navMeshURL, postData);
+
+    U32 navMeshVersion = navMeshStatus.getVersion();
+
+    if (!status)
+    {
+        LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+            ". reporting error." << LL_ENDL;
+        navMeshPtr->handleNavMeshError(navMeshVersion);
+    }
+    else
+    {
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        navMeshPtr->handleNavMeshResult(result, navMeshVersion);
+
+    }
+
+}
+
+void LLPathfindingManager::navAgentStateRequestCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavAgentStateRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    bool canRebake = false;
+    if (!status)
+    {
+        LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+            ". Building using empty status." << LL_ENDL;
+    }
+    else
+    {
+        llassert(result.has(AGENT_STATE_CAN_REBAKE_REGION_FIELD));
+        llassert(result.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean());
+        canRebake = result.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean();
+    }
+
+    handleAgentState(canRebake);
+}
+
+void LLPathfindingManager::navMeshRebakeCoro(std::string url, rebake_navmesh_callback_t rebakeNavMeshCallback)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavMeshRebake", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+
+    LLSD postData = LLSD::emptyMap();
+    postData["command"] = "rebuild";
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    bool success = true;
+    if (!status)
+    {
+        LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+            ". Rebake failed." << LL_ENDL;
+        success = false;
+    }
+       
+    rebakeNavMeshCallback(success);
+}
+
+// If called with putData undefined this coroutine will issue a get.  If there 
+// is data in putData it will be PUT to the URL.
+void LLPathfindingManager::linksetObjectsCoro(std::string url, LinksetsResponder::ptr_t linksetsResponsderPtr, LLSD putData) const
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetObjects", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result;
+
+    if (putData.isUndefined())
+    {
+        result = httpAdapter->getAndYield(httpRequest, url);
+    }
+    else 
+    {
+        result = httpAdapter->putAndYield(httpRequest, url, putData);
+    }
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+            ". linksetObjects failed." << LL_ENDL;
+        linksetsResponsderPtr->handleObjectLinksetsError();
+    }
+    else
+    {
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        linksetsResponsderPtr->handleObjectLinksetsResult(result);
+    }
+}
+
+// If called with putData undefined this coroutine will issue a GET.  If there 
+// is data in putData it will be PUT to the URL.
+void LLPathfindingManager::linksetTerrainCoro(std::string url, LinksetsResponder::ptr_t linksetsResponsderPtr, LLSD putData) const
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetTerrain", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result;
+
+    if (putData.isUndefined())
+    {
+        result = httpAdapter->getAndYield(httpRequest, url);
+    }
+    else 
+    {
+        result = httpAdapter->putAndYield(httpRequest, url, putData);
+    }
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+            ". linksetTerrain failed." << LL_ENDL;
+        linksetsResponsderPtr->handleTerrainLinksetsError();
+    }
+    else
+    {
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        linksetsResponsderPtr->handleTerrainLinksetsResult(result);
+    }
+
+}
+
+void LLPathfindingManager::charactersCoro(std::string url, request_id_t requestId, object_request_callback_t callback) const
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetTerrain", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+            ". characters failed." << LL_ENDL;
+
+        LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList());
+        callback(requestId, LLPathfindingManager::kRequestError, characterListPtr);
+    }
+    else
+    {
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(result));
+        callback(requestId, LLPathfindingManager::kRequestCompleted, characterListPtr);
+    }
 }
 
 void LLPathfindingManager::handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus)
@@ -764,122 +831,9 @@ void LLAgentStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, c
 	LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion);
 }
 
-//---------------------------------------------------------------------------
-// NavMeshStatusResponder
-//---------------------------------------------------------------------------
-
-NavMeshStatusResponder::NavMeshStatusResponder(LLViewerRegion *pRegion, bool pIsGetStatusOnly)
-	: LLHTTPClient::Responder(),
-	mRegion(pRegion),
-	mRegionUUID(),
-	mIsGetStatusOnly(pIsGetStatusOnly)
-{
-	if (mRegion != NULL)
-	{
-		mRegionUUID = mRegion->getRegionID();
-	}
-}
-
-NavMeshStatusResponder::~NavMeshStatusResponder()
-{
-}
-
-void NavMeshStatusResponder::httpSuccess()
-{
-	LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID, getContent());
-	LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
-}
-
-void NavMeshStatusResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-	LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID);
-	LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
-}
-
-//---------------------------------------------------------------------------
-// NavMeshResponder
-//---------------------------------------------------------------------------
-
-NavMeshResponder::NavMeshResponder(U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr)
-	: LLHTTPClient::Responder(),
-	mNavMeshVersion(pNavMeshVersion),
-	mNavMeshPtr(pNavMeshPtr)
-{
-}
-
-NavMeshResponder::~NavMeshResponder()
-{
-}
-
-void NavMeshResponder::httpSuccess()
-{
-	mNavMeshPtr->handleNavMeshResult(getContent(), mNavMeshVersion);
-}
-
-void NavMeshResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-	mNavMeshPtr->handleNavMeshError(mNavMeshVersion);
-}
-
-//---------------------------------------------------------------------------
-// AgentStateResponder
-//---------------------------------------------------------------------------
-
-AgentStateResponder::AgentStateResponder()
-: LLHTTPClient::Responder()
-{
-}
-
-AgentStateResponder::~AgentStateResponder()
-{
-}
-
-void AgentStateResponder::httpSuccess()
-{
-	const LLSD& pContent = getContent();
-	llassert(pContent.has(AGENT_STATE_CAN_REBAKE_REGION_FIELD));
-	llassert(pContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean());
-	BOOL canRebakeRegion = pContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean();
-	LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion);
-}
-
-void AgentStateResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-	LLPathfindingManager::getInstance()->handleAgentState(FALSE);
-}
-
-
-//---------------------------------------------------------------------------
-// navmesh rebake responder
-//---------------------------------------------------------------------------
-NavMeshRebakeResponder::NavMeshRebakeResponder(LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback)
-	: LLHTTPClient::Responder(),
-	mRebakeNavMeshCallback(pRebakeNavMeshCallback)
-{
-}
-
-NavMeshRebakeResponder::~NavMeshRebakeResponder()
-{
-}
-
-void NavMeshRebakeResponder::httpSuccess()
-{
-	mRebakeNavMeshCallback(true);
-}
-
-void NavMeshRebakeResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-	mRebakeNavMeshCallback(false);
-}
-
 //---------------------------------------------------------------------------
 // LinksetsResponder
 //---------------------------------------------------------------------------
-
 LinksetsResponder::LinksetsResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pLinksetsCallback, bool pIsObjectRequested, bool pIsTerrainRequested)
 	: mRequestId(pRequestId),
 	mLinksetsCallback(pLinksetsCallback),
@@ -957,82 +911,3 @@ void LinksetsResponder::sendCallback()
 
 	mLinksetsCallback(mRequestId, requestStatus, mObjectLinksetListPtr);
 }
-
-//---------------------------------------------------------------------------
-// ObjectLinksetsResponder
-//---------------------------------------------------------------------------
-
-ObjectLinksetsResponder::ObjectLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr)
-	: LLHTTPClient::Responder(),
-	mLinksetsResponsderPtr(pLinksetsResponsderPtr)
-{
-}
-
-ObjectLinksetsResponder::~ObjectLinksetsResponder()
-{
-}
-
-void ObjectLinksetsResponder::httpSuccess()
-{
-	mLinksetsResponsderPtr->handleObjectLinksetsResult(getContent());
-}
-
-void ObjectLinksetsResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-	mLinksetsResponsderPtr->handleObjectLinksetsError();
-}
-
-//---------------------------------------------------------------------------
-// TerrainLinksetsResponder
-//---------------------------------------------------------------------------
-
-TerrainLinksetsResponder::TerrainLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr)
-	: LLHTTPClient::Responder(),
-	mLinksetsResponsderPtr(pLinksetsResponsderPtr)
-{
-}
-
-TerrainLinksetsResponder::~TerrainLinksetsResponder()
-{
-}
-
-void TerrainLinksetsResponder::httpSuccess()
-{
-	mLinksetsResponsderPtr->handleTerrainLinksetsResult(getContent());
-}
-
-void TerrainLinksetsResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-	mLinksetsResponsderPtr->handleTerrainLinksetsError();
-}
-
-//---------------------------------------------------------------------------
-// CharactersResponder
-//---------------------------------------------------------------------------
-
-CharactersResponder::CharactersResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback)
-	: LLHTTPClient::Responder(),
-	mRequestId(pRequestId),
-	mCharactersCallback(pCharactersCallback)
-{
-}
-
-CharactersResponder::~CharactersResponder()
-{
-}
-
-void CharactersResponder::httpSuccess()
-{
-	LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(getContent()));
-	mCharactersCallback(mRequestId, LLPathfindingManager::kRequestCompleted, characterListPtr);
-}
-
-void CharactersResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-
-	LLPathfindingObjectListPtr characterListPtr =  LLPathfindingObjectListPtr(new LLPathfindingCharacterList());
-	mCharactersCallback(mRequestId, LLPathfindingManager::kRequestError, characterListPtr);
-}
diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h
index c61ff244fc1a4549db5c78535cad9633823d28a1..e8fad590ba7c9e8cb0a04fe7d87d82be37a3e970 100755
--- a/indra/newview/llpathfindingmanager.h
+++ b/indra/newview/llpathfindingmanager.h
@@ -37,11 +37,15 @@
 #include "llpathfindingobjectlist.h"
 #include "llpathfindingnavmesh.h"
 #include "llsingleton.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
 
 class LLPathfindingNavMeshStatus;
 class LLUUID;
 class LLViewerRegion;
 
+class LinksetsResponder;
+
 class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 {
 	friend class LLNavMeshSimStateChangeNode;
@@ -92,16 +96,22 @@ class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 protected:
 
 private:
-	typedef std::map<LLUUID, LLPathfindingNavMeshPtr> NavMeshMap;
 
-	void sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPtr navMeshPtr, LLViewerRegion *pRegion, const LLPathfindingNavMeshStatus &pNavMeshStatus);
+	typedef std::map<LLUUID, LLPathfindingNavMeshPtr> NavMeshMap;
 
 	void handleDeferredGetAgentStateForRegion(const LLUUID &pRegionUUID);
 	void handleDeferredGetNavMeshForRegion(const LLUUID &pRegionUUID, bool pIsGetStatusOnly);
 	void handleDeferredGetLinksetsForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const;
 	void handleDeferredGetCharactersForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pCharactersCallback) const;
 
-	void handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion, bool pIsGetStatusOnly);
+    void navMeshStatusRequestCoro(std::string url, U64 regionHandle, bool isGetStatusOnly);
+    void navAgentStateRequestCoro(std::string url);
+    void navMeshRebakeCoro(std::string url, rebake_navmesh_callback_t rebakeNavMeshCallback);
+    void linksetObjectsCoro(std::string url, boost::shared_ptr<LinksetsResponder> linksetsResponsderPtr, LLSD putData) const;
+    void linksetTerrainCoro(std::string url, boost::shared_ptr<LinksetsResponder> linksetsResponsderPtr, LLSD putData) const;
+    void charactersCoro(std::string url, request_id_t requestId, object_request_callback_t callback) const;
+
+	//void handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion, bool pIsGetStatusOnly);
 	void handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus);
 
 	void handleAgentState(BOOL pCanRebakeRegion);
diff --git a/indra/newview/llproductinforequest.cpp b/indra/newview/llproductinforequest.cpp
index e92bf4590d1096d2a2ce2de4805f5da54169ff18..467e9df482a029170b7d45f37bb5250beb8e1d7f 100755
--- a/indra/newview/llproductinforequest.cpp
+++ b/indra/newview/llproductinforequest.cpp
@@ -32,31 +32,10 @@
 #include "llagent.h"  // for gAgent
 #include "lltrans.h"
 #include "llviewerregion.h"
+#include "llcorehttputil.h"
 
-class LLProductInfoRequestResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLProductInfoRequestResponder);
-private:
-	//If we get back a normal response, handle it here
-	/* virtual */ void httpSuccess()
-	{
-		const LLSD& content = getContent();
-		if (!content.isArray())
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		LLProductInfoRequestManager::instance().setSkuDescriptions(getContent());
-	}
-
-	//If we get back an error (not found, etc...), handle it here
-	/* virtual */ void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-	}
-};
-
-LLProductInfoRequestManager::LLProductInfoRequestManager() : mSkuDescriptions()
+LLProductInfoRequestManager::LLProductInfoRequestManager(): 
+    mSkuDescriptions()
 {
 }
 
@@ -65,15 +44,11 @@ void LLProductInfoRequestManager::initSingleton()
 	std::string url = gAgent.getRegion()->getCapability("ProductInfoRequest");
 	if (!url.empty())
 	{
-		LLHTTPClient::get(url, new LLProductInfoRequestResponder());
+        LLCoros::instance().launch("LLProductInfoRequestManager::getLandDescriptionsCoro",
+            boost::bind(&LLProductInfoRequestManager::getLandDescriptionsCoro, this, url));
 	}
 }
 
-void LLProductInfoRequestManager::setSkuDescriptions(const LLSD& content)
-{
-	mSkuDescriptions = content;
-}
-
 std::string LLProductInfoRequestManager::getDescriptionForSku(const std::string& sku)
 {
 	// The description LLSD is an array of maps; each array entry
@@ -90,3 +65,31 @@ std::string LLProductInfoRequestManager::getDescriptionForSku(const std::string&
 	}
 	return LLTrans::getString("land_type_unknown");
 }
+
+void LLProductInfoRequestManager::getLandDescriptionsCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        return;
+    }
+
+    if (result.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT) &&
+        result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT].isArray())
+    {
+        mSkuDescriptions = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
+    }
+    else
+    {
+        LL_WARNS() << "Land SKU description response is malformed" << LL_ENDL;
+    }
+}
diff --git a/indra/newview/llproductinforequest.h b/indra/newview/llproductinforequest.h
index fe8f7093b0452621f83c0c2d3311c64364c3a6a8..75dbf220d17cdf140bba4aea684e9b3a101293a7 100755
--- a/indra/newview/llproductinforequest.h
+++ b/indra/newview/llproductinforequest.h
@@ -28,27 +28,29 @@
 #ifndef LL_LLPRODUCTINFOREQUEST_H
 #define LL_LLPRODUCTINFOREQUEST_H
 
-#include "llhttpclient.h"
 #include "llmemory.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
-/* 
- This is a singleton to manage a cache of information about land types.
- The land system provides a capability to get information about the
- set of possible land sku, name, and description information.
- We use description in the UI, but the sku is provided in the various
- messages; this tool provides translation between the systems.
+/** 
+ * This is a singleton to manage a cache of information about land types.
+ * The land system provides a capability to get information about the
+ * set of possible land sku, name, and description information.
+ * We use description in the UI, but the sku is provided in the various
+ * messages; this tool provides translation between the systems.
  */
-
 class LLProductInfoRequestManager : public LLSingleton<LLProductInfoRequestManager>
 {
 public:
 	LLProductInfoRequestManager();
-	void setSkuDescriptions(const LLSD& content);
 	std::string getDescriptionForSku(const std::string& sku);
+
 private:
 	friend class LLSingleton<LLProductInfoRequestManager>;	
 	/* virtual */ void initSingleton();
-	LLSD mSkuDescriptions;
+
+    void getLandDescriptionsCoro(std::string url);
+    LLSD mSkuDescriptions;
 };
 
 #endif // LL_LLPRODUCTINFOREQUEST_H
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 29dcc12f9e315f3e96fd70c5fc3ab36773731595..06bf90c7cb93a1ddbf98e6c396ff712ba95c76f6 100755
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -31,55 +31,16 @@
 #include "message.h"
 
 #include "llpanel.h"
-#include "llhttpclient.h"
 #include "llsdserialize.h"
 #include "llurlentry.h"
 #include "llviewerregion.h"
 #include "llview.h"
-
+#include "llsdutil.h"
+#include "llsdutil_math.h"
+#include "llregionhandle.h"
 #include "llagent.h"
 #include "llremoteparcelrequest.h"
-
-
-LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandle<LLRemoteParcelInfoObserver> observer_handle)
-	 : mObserverHandle(observer_handle)
-{}
-
-//If we get back a normal response, handle it here
-//virtual
-void LLRemoteParcelRequestResponder::httpSuccess()
-{
-	const LLSD& content = getContent();
-	if (!content.isMap() || !content.has("parcel_id"))
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
-	LLUUID parcel_id = getContent()["parcel_id"];
-
-	// Panel inspecting the information may be closed and destroyed
-	// before this response is received.
-	LLRemoteParcelInfoObserver* observer = mObserverHandle.get();
-	if (observer)
-	{
-		observer->setParcelID(parcel_id);
-	}
-}
-
-//If we get back an error (not found, etc...), handle it here
-//virtual
-void LLRemoteParcelRequestResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-
-	// Panel inspecting the information may be closed and destroyed
-	// before this response is received.
-	LLRemoteParcelInfoObserver* observer = mObserverHandle.get();
-	if (observer)
-	{
-		observer->setErrorStatus(getStatus(), getReason());
-	}
-}
+#include "llcorehttputil.h"
 
 void LLRemoteParcelInfoProcessor::addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer)
 {
@@ -200,3 +161,64 @@ void LLRemoteParcelInfoProcessor::sendParcelInfoRequest(const LLUUID& parcel_id)
 	msg->addUUID("ParcelID", parcel_id);
 	gAgent.sendReliableMessage();
 }
+
+bool LLRemoteParcelInfoProcessor::requestRegionParcelInfo(const std::string &url, 
+    const LLUUID &regionId, const LLVector3 &regionPos, const LLVector3d&globalPos,
+    LLHandle<LLRemoteParcelInfoObserver> observerHandle)
+{
+
+    if (!url.empty())
+    {
+        LLCoros::instance().launch("LLRemoteParcelInfoProcessor::regionParcelInfoCoro",
+            boost::bind(&LLRemoteParcelInfoProcessor::regionParcelInfoCoro, this, url,
+            regionId, regionPos, globalPos, observerHandle));
+        return true;
+    }
+
+    return false;
+}
+
+void LLRemoteParcelInfoProcessor::regionParcelInfoCoro(std::string url, 
+    LLUUID regionId, LLVector3 posRegion, LLVector3d posGlobal, 
+    LLHandle<LLRemoteParcelInfoObserver> observerHandle)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("RemoteParcelRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD bodyData;
+
+    bodyData["location"] = ll_sd_from_vector3(posRegion);
+    if (!regionId.isNull())
+    {
+        bodyData["region_id"] = regionId;
+    }
+    if (!posGlobal.isExactlyZero())
+    {
+        U64 regionHandle = to_region_handle(posGlobal);
+        bodyData["region_handle"] = ll_sd_from_U64(regionHandle);
+    }
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, bodyData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    LLRemoteParcelInfoObserver* observer = observerHandle.get();
+    // Panel inspecting the information may be closed and destroyed
+    // before this response is received.
+    if (!observer)
+        return;
+
+    if (!status)
+    {
+        observer->setErrorStatus(status.getStatus(), status.getMessage());
+    }
+    else 
+    {
+        LLUUID parcel_id = result["parcel_id"];
+        observer->setParcelID(parcel_id);
+    }
+
+}
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index 35348b69ffabb6de663366d2e0f62248928fb36e..cb5af50c5f083e737a7f5aab4a693b18fa466794 100755
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -29,29 +29,14 @@
 #ifndef LL_LLREMOTEPARCELREQUEST_H
 #define LL_LLREMOTEPARCELREQUEST_H
 
-#include "llhttpclient.h"
 #include "llhandle.h"
 #include "llsingleton.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
 
 class LLMessageSystem;
 class LLRemoteParcelInfoObserver;
 
-class LLRemoteParcelRequestResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLRemoteParcelRequestResponder);
-public:
-	LLRemoteParcelRequestResponder(LLHandle<LLRemoteParcelInfoObserver> observer_handle);
-
-private:
-	//If we get back a normal response, handle it here
-	/*virtual*/ void httpSuccess();
-
-	//If we get back an error (not found, etc...), handle it here
-	/*virtual*/ void httpFailure();
-
-	LLHandle<LLRemoteParcelInfoObserver> mObserverHandle;
-};
-
 struct LLParcelData
 {
 	LLUUID		parcel_id;
@@ -99,9 +84,14 @@ class LLRemoteParcelInfoProcessor : public LLSingleton<LLRemoteParcelInfoProcess
 
 	static void processParcelInfoReply(LLMessageSystem* msg, void**);
 
+    bool requestRegionParcelInfo(const std::string &url, const LLUUID &regionId, 
+        const LLVector3 &regionPos, const LLVector3d& globalPos, LLHandle<LLRemoteParcelInfoObserver> observerHandle);
+
 private:
 	typedef std::multimap<LLUUID, LLHandle<LLRemoteParcelInfoObserver> > observer_multimap_t;
 	observer_multimap_t mObservers;
+
+    void regionParcelInfoCoro(std::string url, LLUUID regionId, LLVector3 posRegion, LLVector3d posGlobal, LLHandle<LLRemoteParcelInfoObserver> observerHandle);
 };
 
 #endif // LL_LLREMOTEPARCELREQUEST_H
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 0ae8a338e08f5c3f1ad4f219bf475f53ee1dede9..bbb5db4a0aa83a0efd0978a1f23e415cf981a855 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -1004,9 +1004,23 @@ void LLSnapshotLivePreview::saveTexture()
 		LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);
 		std::string who_took_it;
 		LLAgentUI::buildFullname(who_took_it);
-		LLAssetStorage::LLStoreAssetCallback callback = NULL;
 		S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
-		void *userdata = NULL;
+#if 1
+        std::string name = "Snapshot: " + pos_string;
+        std::string desc = "Taken by " + who_took_it + " at " + pos_string;
+
+        NewResourceUploadInfo::ptr_t assetUploadInfo(new NewResourceUploadInfo(
+            tid, LLAssetType::AT_TEXTURE, name, desc, 0,
+            LLFolderType::FT_SNAPSHOT_CATEGORY, LLInventoryType::IT_SNAPSHOT,
+            PERM_ALL, LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
+            expected_upload_cost));
+
+        upload_new_resource(assetUploadInfo);
+
+#else
+        LLAssetStorage::LLStoreAssetCallback callback = NULL;
+        void *userdata = NULL;
+
 		upload_new_resource(tid,	// tid
 			LLAssetType::AT_TEXTURE,
 			"Snapshot : " + pos_string,
@@ -1019,6 +1033,7 @@ void LLSnapshotLivePreview::saveTexture()
 			LLFloaterPerms::getEveryonePerms("Uploads"),
 			"Snapshot : " + pos_string,
 			callback, expected_upload_cost, userdata);
+#endif
 		gViewerWindow->playSnapshotAnimAndSound();
 	}
 	else
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 7867e1573ca9c57cf32e96962d7b5d4d4ab6dd30..3b060d8343db98cd5969d88e6f7618e8cc0ed47e 100755
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -34,11 +34,11 @@
 #include "llgroupmgr.h"
 #include "llsdutil.h"
 #include "lluicolortable.h"
-#include "llhttpclient.h"
 #include "llviewerobjectlist.h"
 #include "llviewerregion.h"
 #include "llvoavatar.h"
 #include "llworld.h"
+#include "llcorehttputil.h"
 
 extern LLControlGroup gSavedSettings;
 
@@ -264,49 +264,6 @@ bool LLSpeakersDelayActionsStorage::isTimerStarted(const LLUUID& speaker_id)
 	return (mActionTimersMap.size() > 0) && (mActionTimersMap.find(speaker_id) != mActionTimersMap.end());
 }
 
-//
-// ModerationResponder
-//
-
-class ModerationResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(ModerationResponder);
-public:
-	ModerationResponder(const LLUUID& session_id)
-	{
-		mSessionID = session_id;
-	}
-	
-protected:
-	virtual void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-		
-		if ( gIMMgr )
-		{
-			//403 == you're not a mod
-			//should be disabled if you're not a moderator
-			if ( HTTP_FORBIDDEN == getStatus() )
-			{
-				gIMMgr->showSessionEventError(
-											  "mute",
-											  "not_a_mod_error",
-											  mSessionID);
-			}
-			else
-			{
-				gIMMgr->showSessionEventError(
-											  "mute",
-											  "generic_request_error",
-											  mSessionID);
-			}
-		}
-	}
-	
-private:
-	LLUUID mSessionID;
-};
-
 //
 // LLSpeakerMgr
 //
@@ -883,7 +840,8 @@ void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
 	//current value represents ability to type, so invert
 	data["params"]["mute_info"]["text"] = !speakerp->mModeratorMutedText;
 
-	LLHTTPClient::post(url, data, new ModerationResponder(getSessionID()));
+    LLCoros::instance().launch("LLIMSpeakerMgr::moderationActionCoro",
+        boost::bind(&LLIMSpeakerMgr::moderationActionCoro, this, url, data));
 }
 
 void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
@@ -907,10 +865,50 @@ void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmu
 	data["params"]["mute_info"] = LLSD::emptyMap();
 	data["params"]["mute_info"]["voice"] = !unmute;
 
-	LLHTTPClient::post(
-		url,
-		data,
-		new ModerationResponder(getSessionID()));
+    LLCoros::instance().launch("LLIMSpeakerMgr::moderationActionCoro",
+        boost::bind(&LLIMSpeakerMgr::moderationActionCoro, this, url, data));
+}
+
+void LLIMSpeakerMgr::moderationActionCoro(std::string url, LLSD action)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("moderationActionCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+
+    LLUUID sessionId = action["session-id"];
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, action, httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        if (gIMMgr)
+        {
+            //403 == you're not a mod
+            //should be disabled if you're not a moderator
+            if (status == LLCore::HttpStatus(HTTP_FORBIDDEN))
+            {
+                gIMMgr->showSessionEventError(
+                    "mute",
+                    "not_a_mod_error",
+                    sessionId);
+            }
+            else
+            {
+                gIMMgr->showSessionEventError(
+                    "mute",
+                    "generic_request_error",
+                    sessionId);
+            }
+        }
+        return;
+    }
 }
 
 void LLIMSpeakerMgr::moderateVoiceAllParticipants( bool unmute_everyone )
@@ -949,7 +947,8 @@ void LLIMSpeakerMgr::moderateVoiceSession(const LLUUID& session_id, bool disallo
 	data["params"]["update_info"]["moderated_mode"] = LLSD::emptyMap();
 	data["params"]["update_info"]["moderated_mode"]["voice"] = disallow_voice;
 
-	LLHTTPClient::post(url, data, new ModerationResponder(session_id));
+    LLCoros::instance().launch("LLIMSpeakerMgr::moderationActionCoro",
+        boost::bind(&LLIMSpeakerMgr::moderationActionCoro, this, url, data));
 }
 
 void LLIMSpeakerMgr::forceVoiceModeratedMode(bool should_be_muted)
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 0e691841250ff23a78fa225d4d84dcfe7bc0a2fc..5cff70f37767cdf42aace17853c62923a548f2b0 100755
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -30,6 +30,8 @@
 #include "llevent.h"
 #include "lleventtimer.h"
 #include "llvoicechannel.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 class LLSpeakerMgr;
 
@@ -333,6 +335,8 @@ class LLIMSpeakerMgr : public LLSpeakerMgr
 	 */
 	void forceVoiceModeratedMode(bool should_be_muted);
 
+    void moderationActionCoro(std::string url, LLSD action);
+
 };
 
 class LLActiveSpeakerMgr : public LLSpeakerMgr, public LLSingleton<LLActiveSpeakerMgr>
diff --git a/indra/newview/llsyntaxid.cpp b/indra/newview/llsyntaxid.cpp
index 802dff1ead9780710f3594cc36d4c56832f0f74b..7f286044d69140e0feec78bfd3f5641e3798e0da 100644
--- a/indra/newview/llsyntaxid.cpp
+++ b/indra/newview/llsyntaxid.cpp
@@ -31,69 +31,10 @@
 #include "llsyntaxid.h"
 #include "llagent.h"
 #include "llappviewer.h"
-#include "llhttpclient.h"
 #include "llsdserialize.h"
 #include "llviewerregion.h"
+#include "llcorehttputil.h"
 
-//-----------------------------------------------------------------------------
-// fetchKeywordsFileResponder
-//-----------------------------------------------------------------------------
-class fetchKeywordsFileResponder : public LLHTTPClient::Responder
-{
-public:
-	fetchKeywordsFileResponder(const std::string& filespec)
-	: mFileSpec(filespec)
-	{
-		LL_DEBUGS("SyntaxLSL") << "Instantiating with file saving to: '" << filespec << "'" << LL_ENDL;
-	}
-
-	/* virtual */ void httpFailure()
-	{
-		LL_WARNS("SyntaxLSL") << "failed to fetch syntax file [status:" << getStatus() << "]: " << getContent() << LL_ENDL;
-	}
-
-	/* virtual */ void httpSuccess()
-	{
-		// Continue only if a valid LLSD object was returned.
-		const LLSD& content = getContent();
-		if (content.isMap())
-		{
-			if (LLSyntaxIdLSL::getInstance()->isSupportedVersion(content))
-			{
-				LLSyntaxIdLSL::getInstance()->setKeywordsXml(content);
-
-				cacheFile(content);
-				LLSyntaxIdLSL::getInstance()->handleFileFetched(mFileSpec);
-			}
-			else
-			{
-				LL_WARNS("SyntaxLSL") << "Unknown or unsupported version of syntax file." << LL_ENDL;
-			}
-		}
-		else
-		{
-			LL_WARNS("SyntaxLSL") << "Syntax file '" << mFileSpec << "' contains invalid LLSD." << LL_ENDL;
-		}
-	}
-
-	void cacheFile(const LLSD& content_ref)
-	{
-		std::stringstream str;
-		LLSDSerialize::toXML(content_ref, str);
-		const std::string xml = str.str();
-
-		// save the str to disk, usually to the cache.
-		llofstream file(mFileSpec.c_str(), std::ios_base::out);
-		file.write(xml.c_str(), str.str().size());
-		file.close();
-
-		LL_DEBUGS("SyntaxLSL") << "Syntax file received, saving as: '" << mFileSpec << "'" << LL_ENDL;
-	}
-	
-private:
-	std::string mFileSpec;
-};
-	
 //-----------------------------------------------------------------------------
 // LLSyntaxIdLSL
 //-----------------------------------------------------------------------------
@@ -166,13 +107,72 @@ bool LLSyntaxIdLSL::syntaxIdChanged()
 //-----------------------------------------------------------------------------
 void LLSyntaxIdLSL::fetchKeywordsFile(const std::string& filespec)
 {
-	mInflightFetches.push_back(filespec);
-	LLHTTPClient::get(mCapabilityURL,
-					  new fetchKeywordsFileResponder(filespec),
-					  LLSD(), 30.f);
+    LLCoros::instance().launch("LLSyntaxIdLSL::fetchKeywordsFileCoro",
+        boost::bind(&LLSyntaxIdLSL::fetchKeywordsFileCoro, this, mCapabilityURL, filespec));
 	LL_DEBUGS("SyntaxLSL") << "LSLSyntaxId capability URL is: " << mCapabilityURL << ". Filename to use is: '" << filespec << "'." << LL_ENDL;
 }
 
+//-----------------------------------------------------------------------------
+// fetchKeywordsFileCoro
+//-----------------------------------------------------------------------------
+void LLSyntaxIdLSL::fetchKeywordsFileCoro(std::string url, std::string fileSpec)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    std::pair<std::set<std::string>::iterator, bool> insrt = mInflightFetches.insert(fileSpec);
+    if (!insrt.second)
+    {
+        LL_WARNS("SyntaxLSL") << "Already downloading keyword file called \"" << fileSpec << "\"." << LL_ENDL;
+        return;
+    }
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    mInflightFetches.erase(fileSpec);
+
+    if (!status)
+    {
+        LL_WARNS("SyntaxLSL") << "Failed to fetch syntax file \"" << fileSpec << "\"" << LL_ENDL;
+        return;
+    }
+
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+
+    if (isSupportedVersion(result))
+    {
+        setKeywordsXml(result);
+        cacheFile(fileSpec, result);
+        loadKeywordsIntoLLSD();
+    }
+    else
+    {
+        LL_WARNS("SyntaxLSL") << "Unknown or unsupported version of syntax file." << LL_ENDL;
+    }
+
+}
+
+//-----------------------------------------------------------------------------
+// cacheFile
+//-----------------------------------------------------------------------------
+void LLSyntaxIdLSL::cacheFile(const std::string &fileSpec, const LLSD& content_ref)
+{
+    std::stringstream str;
+    LLSDSerialize::toXML(content_ref, str);
+    const std::string xml = str.str();
+
+    // save the str to disk, usually to the cache.
+    llofstream file(fileSpec.c_str(), std::ios_base::out);
+    file.write(xml.c_str(), str.str().size());
+    file.close();
+
+    LL_DEBUGS("SyntaxLSL") << "Syntax file received, saving as: '" << fileSpec << "'" << LL_ENDL;
+}
 
 //-----------------------------------------------------------------------------
 // initialize
@@ -260,8 +260,8 @@ void LLSyntaxIdLSL::loadDefaultKeywordsIntoLLSD()
 // loadKeywordsFileIntoLLSD
 //-----------------------------------------------------------------------------
 /**
- * @brief	Load xml serialised LLSD
- * @desc	Opens the specified filespec and attempts to deserialise the
+ * @brief	Load xml serialized LLSD
+ * @desc	Opens the specified filespec and attempts to deserializes the
  *			contained data to the specified LLSD object. indicate success/failure with
  *			sLoaded/sLoadFailed members.
  */
@@ -276,7 +276,7 @@ void LLSyntaxIdLSL::loadKeywordsIntoLLSD()
 		{
 			if (isSupportedVersion(content))
 			{
-				LL_DEBUGS("SyntaxLSL") << "Deserialised: " << mFullFileSpec << LL_ENDL;
+				LL_DEBUGS("SyntaxLSL") << "Deserialized: " << mFullFileSpec << LL_ENDL;
 			}
 			else
 			{
@@ -317,12 +317,6 @@ void LLSyntaxIdLSL::handleCapsReceived(const LLUUID& region_uuid)
 	}
 }
 
-void LLSyntaxIdLSL::handleFileFetched(const std::string& filepath)
-{
-	mInflightFetches.remove(filepath);
-	loadKeywordsIntoLLSD();
-}
-
 boost::signals2::connection LLSyntaxIdLSL::addSyntaxIDCallback(const syntax_id_changed_signal_t::slot_type& cb)
 {
 	return mSyntaxIDChangedSignal.connect(cb);
diff --git a/indra/newview/llsyntaxid.h b/indra/newview/llsyntaxid.h
index 504fb0997e1dda391186864920c4693acb1c4000..0afa6dc04ba2868e21f7600351991fea1a0c83ae 100644
--- a/indra/newview/llsyntaxid.h
+++ b/indra/newview/llsyntaxid.h
@@ -31,6 +31,8 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llsingleton.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 class fetchKeywordsFileResponder;
 
@@ -40,7 +42,7 @@ class LLSyntaxIdLSL : public LLSingleton<LLSyntaxIdLSL>
 	friend class fetchKeywordsFileResponder;
 	
 private:
-	std::list<std::string> mInflightFetches;
+    std::set<std::string> mInflightFetches;
 	typedef boost::signals2::signal<void()> syntax_id_changed_signal_t;
 	syntax_id_changed_signal_t mSyntaxIDChangedSignal;
 	boost::signals2::connection mRegionChangedCallback;
@@ -49,13 +51,15 @@ class LLSyntaxIdLSL : public LLSingleton<LLSyntaxIdLSL>
 	bool	isSupportedVersion(const LLSD& content);
 	void	handleRegionChanged();
 	void	handleCapsReceived(const LLUUID& region_uuid);
-	void	handleFileFetched(const std::string& filepath);
 	void	setKeywordsXml(const LLSD& content) { mKeywordsXml = content; };
 	void	buildFullFileSpec();
 	void	fetchKeywordsFile(const std::string& filespec);
 	void	loadDefaultKeywordsIntoLLSD();
 	void	loadKeywordsIntoLLSD();
-	
+
+    void    fetchKeywordsFileCoro(std::string url, std::string fileSpec);
+    void    cacheFile(const std::string &fileSpec, const LLSD& content_ref);
+
 	std::string		mCapabilityURL;
 	std::string		mFullFileSpec;
 	ELLPath			mFilePath;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index fab4203ec3199faaa7fd364c576b35088204be58..f4b1ff73138de6371ca0e04b075ae1836fa725ff 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -35,7 +35,6 @@
 #include "lltexturefetch.h"
 
 #include "lldir.h"
-#include "llhttpclient.h"
 #include "llhttpconstants.h"
 #include "llimage.h"
 #include "llimagej2c.h"
diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp
index e983bc883f1452e92dc8f4f95537287745a6b533..c6a0a1575968ca57f8389ee19710962105e0e908 100644
--- a/indra/newview/lltwitterconnect.cpp
+++ b/indra/newview/lltwitterconnect.cpp
@@ -32,7 +32,6 @@
 #include "llagent.h"
 #include "llcallingcard.h"			// for LLAvatarTracker
 #include "llcommandhandler.h"
-#include "llhttpclient.h"
 #include "llnotificationsutil.h"
 #include "llurlaction.h"
 #include "llimagepng.h"
@@ -43,6 +42,7 @@
 
 #include "llfloaterwebcontent.h"
 #include "llfloaterreg.h"
+#include "llcorehttputil.h"
 
 boost::scoped_ptr<LLEventPump> LLTwitterConnect::sStateWatcher(new LLEventStream("TwitterConnectState"));
 boost::scoped_ptr<LLEventPump> LLTwitterConnect::sInfoWatcher(new LLEventStream("TwitterConnectInfo"));
@@ -67,228 +67,311 @@ void toast_user_for_twitter_success()
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLTwitterConnectResponder : public LLHTTPClient::Responder
+void LLTwitterConnect::twitterConnectCoro(std::string requestToken, std::string oauthVerifier)
 {
-	LOG_CLASS(LLTwitterConnectResponder);
-public:
-	
-    LLTwitterConnectResponder()
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    LLSD body;
+    if (!requestToken.empty())
+        body["request_token"] = requestToken;
+    if (!oauthVerifier.empty())
+        body["oauth_verifier"] = oauthVerifier;
+
+    setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
+
+    LLSD result = httpAdapter->putAndYield(httpRequest, getTwitterConnectURL("/connection"), body, httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
     {
-        LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
+        if ( status == LLCore::HttpStatus(HTTP_FOUND) )
+        {
+            std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+            if (location.empty())
+            {
+                LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
+            }
+            else
+            {
+                openTwitterWeb(location);
+            }
+        }
+        else
+        {
+            LL_WARNS("TwitterConnect") << "Connection failed " << status.toString() << LL_ENDL;
+            setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
+            log_twitter_connect_error("Connect", status.getStatus(), status.toString(),
+                result.get("error_code"), result.get("error_description"));
+        }
     }
-    
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("TwitterConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
-        LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
-	}
-    
-	/* virtual */ void httpFailure()
-	{
-		if ( HTTP_FOUND == getStatus() )
-		{
-			const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (location.empty())
-			{
-				LL_WARNS("TwitterConnect") << "Missing Location header " << dumpResponse()
-                << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			}
-			else
-			{
-                LLTwitterConnect::instance().openTwitterWeb(location);
-			}
-		}
-		else
-		{
-			LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
-			LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
-			const LLSD& content = getContent();
-			log_twitter_connect_error("Connect", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+    else
+    {
+        LL_DEBUGS("TwitterConnect") << "Connect successful. " << LL_ENDL;
+        setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLTwitterShareResponder : public LLHTTPClient::Responder
+bool LLTwitterConnect::testShareStatus(LLSD &result)
 {
-	LOG_CLASS(LLTwitterShareResponder);
-public:
-    
-	LLTwitterShareResponder()
-	{
-		LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POSTING);
-	}
-	
-	/* virtual */ void httpSuccess()
-	{
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (status)
+        return true;
+
+    if (status == LLCore::HttpStatus(HTTP_FOUND))
+    {
+        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+        if (location.empty())
+        {
+            LL_WARNS("TwitterConnect") << "Missing Location header " << LL_ENDL;
+        }
+        else
+        {
+            openTwitterWeb(location);
+        }
+    }
+    if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+    {
+        LL_DEBUGS("TwitterConnect") << "Not connected. " << LL_ENDL;
+        connectToTwitter();
+    }
+    else
+    {
+        LL_WARNS("TwitterConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
+        setConnectionState(LLTwitterConnect::TWITTER_POST_FAILED);
+        log_twitter_connect_error("Share", status.getStatus(), status.toString(),
+            result.get("error_code"), result.get("error_description"));
+    }
+    return false;
+}
+
+void LLTwitterConnect::twitterShareCoro(std::string route, LLSD share)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    setConnectionState(LLTwitterConnect::TWITTER_POSTING);
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, getTwitterConnectURL(route, true), share, httpOpts);
+
+    if (testShareStatus(result))
+    {
         toast_user_for_twitter_success();
-		LL_DEBUGS("TwitterConnect") << "Post successful. " << dumpResponse() << LL_ENDL;
-        LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POSTED);
-	}
-    
-	/* virtual */ void httpFailure()
-	{
-		if ( HTTP_FOUND == getStatus() )
-		{
-			const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (location.empty())
-			{
-				LL_WARNS("TwitterConnect") << "Missing Location header " << dumpResponse()
-                << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			}
-			else
-			{
-                LLTwitterConnect::instance().openTwitterWeb(location);
-			}
-		}
-		else if ( HTTP_NOT_FOUND == getStatus() )
-		{
-			LLTwitterConnect::instance().connectToTwitter();
-		}
-		else
-		{
-			LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
-            LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POST_FAILED);
-			const LLSD& content = getContent();
-			log_twitter_connect_error("Share", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+        LL_DEBUGS("TwitterConnect") << "Post successful. " << LL_ENDL;
+        setConnectionState(LLTwitterConnect::TWITTER_POSTED);
+    }
+}
+
+void LLTwitterConnect::twitterShareImageCoro(LLPointer<LLImageFormatted> image, std::string status)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    std::string imageFormat;
+    if (dynamic_cast<LLImagePNG*>(image.get()))
+    {
+        imageFormat = "png";
+    }
+    else if (dynamic_cast<LLImageJPEG*>(image.get()))
+    {
+        imageFormat = "jpg";
+    }
+    else
+    {
+        LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
+        return;
+    }
+
+    // All this code is mostly copied from LLWebProfile::post()
+    const std::string boundary = "----------------------------0123abcdefab";
+
+    std::string contentType = "multipart/form-data; boundary=" + boundary;
+    httpHeaders->append("Content-Type", contentType.c_str());
+
+    LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); // 
+    LLCore::BufferArrayStream body(raw.get());
+
+    // *NOTE: The order seems to matter.
+    body << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"status\"\r\n\r\n"
+        << status << "\r\n";
+
+    body << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
+        << "Content-Type: image/" << imageFormat << "\r\n\r\n";
+
+    // Insert the image data.
+    // *FIX: Treating this as a string will probably screw it up ...
+    U8* image_data = image->getData();
+    for (S32 i = 0; i < image->getDataSize(); ++i)
+    {
+        body << image_data[i];
+    }
+
+    body << "\r\n--" << boundary << "--\r\n";
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, getTwitterConnectURL("/share/photo", true), raw, httpOpts, httpHeaders);
+
+    if (testShareStatus(result))
+    {
+        toast_user_for_twitter_success();
+        LL_DEBUGS("TwitterConnect") << "Post successful. " << LL_ENDL;
+        setConnectionState(LLTwitterConnect::TWITTER_POSTED);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLTwitterDisconnectResponder : public LLHTTPClient::Responder
+void LLTwitterConnect::twitterDisconnectCoro()
 {
-	LOG_CLASS(LLTwitterDisconnectResponder);
-public:
- 
-	LLTwitterDisconnectResponder()
-	{
-		LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_DISCONNECTING);
-	}
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
 
-	void setUserDisconnected()
-	{
-		// Clear data
-		LLTwitterConnect::instance().clearInfo();
+    httpOpts->setFollowRedirects(false);
 
-		//Notify state change
-		LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
-	}
+    setConnectionState(LLTwitterConnect::TWITTER_DISCONNECTING);
 
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("TwitterConnect") << "Disconnect successful. " << dumpResponse() << LL_ENDL;
-		setUserDisconnected();
-	}
-    
-	/* virtual */ void httpFailure()
-	{
-		//User not found so already disconnected
-		if ( HTTP_NOT_FOUND == getStatus() )
-		{
-			LL_DEBUGS("TwitterConnect") << "Already disconnected. " << dumpResponse() << LL_ENDL;
-			setUserDisconnected();
-		}
-		else
-		{
-			LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
-			LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_DISCONNECT_FAILED);
-			const LLSD& content = getContent();
-			log_twitter_connect_error("Disconnect", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+    LLSD result = httpAdapter->deleteAndYield(httpRequest, getTwitterConnectURL("/connection"), httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status && (status != LLCore::HttpStatus(HTTP_NOT_FOUND)))
+    {
+        LL_WARNS("TwitterConnect") << "Disconnect failed!" << LL_ENDL;
+        setConnectionState(LLTwitterConnect::TWITTER_DISCONNECT_FAILED);
+
+        log_twitter_connect_error("Disconnect", status.getStatus(), status.toString(),
+            result.get("error_code"), result.get("error_description"));
+    }
+    else
+    {
+        LL_DEBUGS("TwitterConnect") << "Disconnect successful. " << LL_ENDL;
+        clearInfo();
+        setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLTwitterConnectedResponder : public LLHTTPClient::Responder
+void LLTwitterConnect::twitterConnectedCoro(bool autoConnect)
 {
-	LOG_CLASS(LLTwitterConnectedResponder);
-public:
-    
-	LLTwitterConnectedResponder(bool auto_connect) : mAutoConnect(auto_connect)
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setFollowRedirects(false);
+    setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, getTwitterConnectURL("/connection", true), httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
     {
-		LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
+        if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+        {
+            LL_DEBUGS("TwitterConnect") << "Not connected. " << LL_ENDL;
+            if (autoConnect)
+            {
+                connectToTwitter();
+            }
+            else
+            {
+                setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
+            }
+        }
+        else
+        {
+            LL_WARNS("TwitterConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
+
+            setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
+            log_twitter_connect_error("Connected", status.getStatus(), status.toString(),
+                result.get("error_code"), result.get("error_description"));
+        }
+    }
+    else
+    {
+        LL_DEBUGS("TwitterConnect") << "Connect successful. " << LL_ENDL;
+        setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
     }
-    
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("TwitterConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
-        LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
-	}
-    
-	/* virtual */ void httpFailure()
-	{
-		// show the facebook login page if not connected yet
-		if ( HTTP_NOT_FOUND == getStatus() )
-		{
-			LL_DEBUGS("TwitterConnect") << "Not connected. " << dumpResponse() << LL_ENDL;
-			if (mAutoConnect)
-			{
-                LLTwitterConnect::instance().connectToTwitter();
-			}
-			else
-			{
-                LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
-			}
-		}
-		else
-		{
-			LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
-            LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
-			const LLSD& content = getContent();
-			log_twitter_connect_error("Connected", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-    
-private:
-	bool mAutoConnect;
-};
+
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLTwitterInfoResponder : public LLHTTPClient::Responder
+void LLTwitterConnect::twitterInfoCoro()
 {
-	LOG_CLASS(LLTwitterInfoResponder);
-public:
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
 
-	/* virtual */ void httpSuccess()
-	{
-		LL_INFOS("TwitterConnect") << "Twitter: Info received" << LL_ENDL;
-		LL_DEBUGS("TwitterConnect") << "Getting Twitter info successful. " << dumpResponse() << LL_ENDL;
-        LLTwitterConnect::instance().storeInfo(getContent());
-	}
-    
-	/* virtual */ void httpFailure()
-	{
-		if ( HTTP_FOUND == getStatus() )
-		{
-			const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (location.empty())
-			{
-				LL_WARNS("TwitterConnect") << "Missing Location header " << dumpResponse()
-                << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			}
-			else
-			{
-                LLTwitterConnect::instance().openTwitterWeb(location);
-			}
-		}
-		else
-		{
-			LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
-			const LLSD& content = getContent();
-			log_twitter_connect_error("Info", getStatus(), getReason(),
-									   content.get("error_code"), content.get("error_description"));
-		}
-	}
-};
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, getTwitterConnectURL("/info", true), httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (status == LLCore::HttpStatus(HTTP_FOUND))
+    {
+        std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+        if (location.empty())
+        {
+            LL_WARNS("TwitterConnect") << "Missing Location header " << LL_ENDL;
+        }
+        else
+        {
+            openTwitterWeb(location);
+        }
+    }
+    else if (!status)
+    {
+        LL_WARNS("TwitterConnect") << "Twitter Info failed: " << status.toString() << LL_ENDL;
+        log_twitter_connect_error("Info", status.getStatus(), status.toString(),
+            result.get("error_code"), result.get("error_description"));
+    }
+    else
+    {
+        LL_INFOS("TwitterConnect") << "Twitter: Info received" << LL_ENDL;
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+        storeInfo(result);
+    }
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 //
@@ -341,36 +424,28 @@ std::string LLTwitterConnect::getTwitterConnectURL(const std::string& route, boo
 
 void LLTwitterConnect::connectToTwitter(const std::string& request_token, const std::string& oauth_verifier)
 {
-	LLSD body;
-	if (!request_token.empty())
-		body["request_token"] = request_token;
-	if (!oauth_verifier.empty())
-		body["oauth_verifier"] = oauth_verifier;
-    
-	LLHTTPClient::put(getTwitterConnectURL("/connection"), body, new LLTwitterConnectResponder());
+    LLCoros::instance().launch("LLTwitterConnect::twitterConnectCoro",
+        boost::bind(&LLTwitterConnect::twitterConnectCoro, this, request_token, oauth_verifier));
 }
 
 void LLTwitterConnect::disconnectFromTwitter()
 {
-	LLHTTPClient::del(getTwitterConnectURL("/connection"), new LLTwitterDisconnectResponder());
+    LLCoros::instance().launch("LLTwitterConnect::twitterDisconnectCoro",
+        boost::bind(&LLTwitterConnect::twitterDisconnectCoro, this));
 }
 
 void LLTwitterConnect::checkConnectionToTwitter(bool auto_connect)
 {
-	const bool follow_redirects = false;
-	const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
-	LLHTTPClient::get(getTwitterConnectURL("/connection", true), new LLTwitterConnectedResponder(auto_connect),
-						LLSD(), timeout, follow_redirects);
+    LLCoros::instance().launch("LLTwitterConnect::twitterConnectedCoro",
+        boost::bind(&LLTwitterConnect::twitterConnectedCoro, this, auto_connect));
 }
 
 void LLTwitterConnect::loadTwitterInfo()
 {
 	if(mRefreshInfo)
 	{
-		const bool follow_redirects = false;
-		const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
-		LLHTTPClient::get(getTwitterConnectURL("/info", true), new LLTwitterInfoResponder(),
-			LLSD(), timeout, follow_redirects);
+        LLCoros::instance().launch("LLTwitterConnect::twitterInfoCoro",
+            boost::bind(&LLTwitterConnect::twitterInfoCoro, this));
 	}
 }
 
@@ -379,62 +454,15 @@ void LLTwitterConnect::uploadPhoto(const std::string& image_url, const std::stri
 	LLSD body;
 	body["image"] = image_url;
 	body["status"] = status;
-	
-    // Note: we can use that route for different publish action. We should be able to use the same responder.
-	LLHTTPClient::post(getTwitterConnectURL("/share/photo", true), body, new LLTwitterShareResponder());
+
+    LLCoros::instance().launch("LLTwitterConnect::twitterShareCoro",
+        boost::bind(&LLTwitterConnect::twitterShareCoro, this, "/share/photo", body));
 }
 
 void LLTwitterConnect::uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& status)
 {
-	std::string imageFormat;
-	if (dynamic_cast<LLImagePNG*>(image.get()))
-	{
-		imageFormat = "png";
-	}
-	else if (dynamic_cast<LLImageJPEG*>(image.get()))
-	{
-		imageFormat = "jpg";
-	}
-	else
-	{
-		LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
-		return;
-	}
-	
-	// All this code is mostly copied from LLWebProfile::post()
-	const std::string boundary = "----------------------------0123abcdefab";
-
-	LLSD headers;
-	headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
-
-	std::ostringstream body;
-
-	// *NOTE: The order seems to matter.
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"status\"\r\n\r\n"
-			<< status << "\r\n";
-
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
-			<< "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
-	// Insert the image data.
-	// *FIX: Treating this as a string will probably screw it up ...
-	U8* image_data = image->getData();
-	for (S32 i = 0; i < image->getDataSize(); ++i)
-	{
-		body << image_data[i];
-	}
-
-	body <<	"\r\n--" << boundary << "--\r\n";
-
-	// postRaw() takes ownership of the buffer and releases it later.
-	size_t size = body.str().size();
-	U8 *data = new U8[size];
-	memcpy(data, body.str().data(), size);
-	
-    // Note: we can use that route for different publish action. We should be able to use the same responder.
-	LLHTTPClient::postRaw(getTwitterConnectURL("/share/photo", true), data, size, new LLTwitterShareResponder(), headers);
+    LLCoros::instance().launch("LLTwitterConnect::twitterShareImageCoro",
+        boost::bind(&LLTwitterConnect::twitterShareImageCoro, this, image, status));
 }
 
 void LLTwitterConnect::updateStatus(const std::string& status)
@@ -442,8 +470,8 @@ void LLTwitterConnect::updateStatus(const std::string& status)
 	LLSD body;
 	body["status"] = status;
 	
-    // Note: we can use that route for different publish action. We should be able to use the same responder.
-	LLHTTPClient::post(getTwitterConnectURL("/share/status", true), body, new LLTwitterShareResponder());
+    LLCoros::instance().launch("LLTwitterConnect::twitterShareCoro",
+        boost::bind(&LLTwitterConnect::twitterShareCoro, this, "/share/status", body));
 }
 
 void LLTwitterConnect::storeInfo(const LLSD& info)
diff --git a/indra/newview/lltwitterconnect.h b/indra/newview/lltwitterconnect.h
index c1df13f18cf558ea934ebe35983c770a6f84bc2e..be481a17c10b9f4e27f97dea1cd8c79145f2150f 100644
--- a/indra/newview/lltwitterconnect.h
+++ b/indra/newview/lltwitterconnect.h
@@ -30,6 +30,8 @@
 
 #include "llsingleton.h"
 #include "llimage.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
 
 class LLEventPump;
 
@@ -94,6 +96,14 @@ class LLTwitterConnect : public LLSingleton<LLTwitterConnect>
 	static boost::scoped_ptr<LLEventPump> sStateWatcher;
 	static boost::scoped_ptr<LLEventPump> sInfoWatcher;
 	static boost::scoped_ptr<LLEventPump> sContentWatcher;
+
+    bool testShareStatus(LLSD &result);
+    void twitterConnectCoro(std::string requestToken, std::string oauthVerifier);
+    void twitterDisconnectCoro();
+    void twitterConnectedCoro(bool autoConnect);
+    void twitterInfoCoro();
+    void twitterShareCoro(std::string route, LLSD share);
+    void twitterShareImageCoro(LLPointer<LLImageFormatted> image, std::string status);
 };
 
 #endif // LL_LLTWITTERCONNECT_H
diff --git a/indra/newview/lluploadfloaterobservers.cpp b/indra/newview/lluploadfloaterobservers.cpp
deleted file mode 100755
index 69b9b1f9f1aba978cb185f1a40da55ff86c8a1fd..0000000000000000000000000000000000000000
--- a/indra/newview/lluploadfloaterobservers.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file lluploadfloaterobservers.cpp
- * @brief LLUploadModelPermissionsResponder definition
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "lluploadfloaterobservers.h"
-
-LLUploadModelPermissionsResponder::LLUploadModelPermissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer)
-:mObserverHandle(observer)
-{
-}
-
-void LLUploadModelPermissionsResponder::httpFailure()
-{
-	LL_WARNS() << dumpResponse() << LL_ENDL;
-
-	LLUploadPermissionsObserver* observer = mObserverHandle.get();
-
-	if (observer)
-	{
-		observer->setPermissonsErrorStatus(getStatus(), getReason());
-	}
-}
-
-void LLUploadModelPermissionsResponder::httpSuccess()
-{
-	const LLSD& content = getContent();
-	if (!content.isMap())
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
-	LLUploadPermissionsObserver* observer = mObserverHandle.get();
-
-	if (observer)
-	{
-		observer->onPermissionsReceived(content);
-	}
-}
-
diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h
index 4ff4a827a5ee5f9a409e5f4052909a9d064add6d..02baf8f1c07b1a3a5489b7eb6f084e98d2435165 100755
--- a/indra/newview/lluploadfloaterobservers.h
+++ b/indra/newview/lluploadfloaterobservers.h
@@ -79,18 +79,4 @@ class LLWholeModelUploadObserver
 	LLRootHandle<LLWholeModelUploadObserver> mWholeModelUploadObserverHandle;
 };
 
-
-class LLUploadModelPermissionsResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLUploadModelPermissionsResponder);
-public:
-	LLUploadModelPermissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer);
-
-private:
-	/* virtual */ void httpSuccess();
-	/* virtual */ void httpFailure();
-
-	LLHandle<LLUploadPermissionsObserver> mObserverHandle;
-};
-
 #endif /* LL_LLUPLOADFLOATEROBSERVERS_H */
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..717b14bb72f25f19512d82df19477d4f679c7dad
--- /dev/null
+++ b/indra/newview/llviewerassetupload.cpp
@@ -0,0 +1,205 @@
+/**
+* @file llviewerassetupload.cpp
+* @author optional
+* @brief brief description of the file
+*
+* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2011, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "linden_common.h"
+#include "llviewerassetupload.h"
+#include "llviewertexturelist.h"
+#include "llimage.h"
+#include "lltrans.h"
+#include "lluuid.h"
+#include "llvorbisencode.h"
+#include "lluploaddialog.h"
+#include "llpreviewscript.h"
+#include "llnotificationsutil.h"
+#include "lleconomy.h"
+#include "llagent.h"
+#include "llfloaterreg.h"
+#include "llstatusbar.h"
+#include "llinventorypanel.h"
+#include "llsdutil.h"
+
+//=========================================================================
+/*static*/
+void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, const LLUUID &id,
+    std::string url, NewResourceUploadInfo::ptr_t uploadInfo)
+{
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = uploadInfo->prepareUpload();
+    uploadInfo->logPreparedUpload();
+
+    if (result.has("error"))
+    {
+        HandleUploadError(LLCore::HttpStatus(499), result, uploadInfo);
+        return;
+    }
+
+    //self.yield();
+
+    std::string uploadMessage = "Uploading...\n\n";
+    uploadMessage.append(uploadInfo->getDisplayName());
+    LLUploadDialog::modalUploadDialog(uploadMessage);
+
+    LLSD body = uploadInfo->generatePostBody();
+
+    result = httpAdapter->postAndYield(httpRequest, url, body);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if ((!status) || (result.has("error")))
+    {
+        HandleUploadError(status, result, uploadInfo);
+        LLUploadDialog::modalUploadFinished();
+        return;
+    }
+
+    std::string uploader = result["uploader"].asString();
+
+    result = httpAdapter->postFileAndYield(httpRequest, uploader, uploadInfo->getAssetId(), uploadInfo->getAssetType());
+    httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        HandleUploadError(status, result, uploadInfo);
+        LLUploadDialog::modalUploadFinished();
+        return;
+    }
+
+    S32 uploadPrice = 0;
+
+    // Update L$ and ownership credit information
+    // since it probably changed on the server
+    if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE ||
+        uploadInfo->getAssetType() == LLAssetType::AT_SOUND ||
+        uploadInfo->getAssetType() == LLAssetType::AT_ANIMATION ||
+        uploadInfo->getAssetType() == LLAssetType::AT_MESH)
+    {
+        uploadPrice = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+    }
+
+    bool success = false;
+
+    if (uploadPrice > 0)
+    {
+        // this upload costed us L$, update our balance
+        // and display something saying that it cost L$
+        LLStatusBar::sendMoneyBalanceRequest();
+
+        LLSD args;
+        args["AMOUNT"] = llformat("%d", uploadPrice);
+        LLNotificationsUtil::add("UploadPayment", args);
+    }
+
+    LLUUID serverInventoryItem = uploadInfo->finishUpload(result);
+
+    if (serverInventoryItem.notNull())
+    {
+        success = true;
+
+        // Show the preview panel for textures and sounds to let
+        // user know that the image (or snapshot) arrived intact.
+        LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel();
+        if (panel)
+        {
+            LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
+            panel->setSelection(serverInventoryItem, TAKE_FOCUS_NO);
+
+            // restore keyboard focus
+            gFocusMgr.setKeyboardFocus(focus);
+        }
+    }
+    else
+    {
+        LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL;
+    }
+
+    // remove the "Uploading..." message
+    LLUploadDialog::modalUploadFinished();
+
+    // Let the Snapshot floater know we have finished uploading a snapshot to inventory.
+    LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
+    if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot)
+    {
+        floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
+    }
+}
+
+//=========================================================================
+/*static*/
+void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &result, NewResourceUploadInfo::ptr_t &uploadInfo)
+{
+    std::string reason;
+    std::string label("CannotUploadReason");
+
+    LL_WARNS() << ll_pretty_print_sd(result) << LL_ENDL;
+
+    if (result.has("label"))
+    {
+        label = result["label"].asString();
+    }
+
+    if (result.has("message"))
+    {
+        reason = result["message"].asString();
+    }
+    else
+    {
+        if (status.getType() == 499)
+        {
+            reason = "The server is experiencing unexpected difficulties.";
+        }
+        else
+        {
+            reason = "Error in upload request.  Please visit "
+                "http://secondlife.com/support for help fixing this problem.";
+        }
+    }
+
+    LLSD args;
+    args["FILE"] = uploadInfo->getDisplayName();
+    args["REASON"] = reason;
+
+    LLNotificationsUtil::add(label, args);
+
+    // unfreeze script preview
+    if (uploadInfo->getAssetType() == LLAssetType::AT_LSL_TEXT)
+    {
+        LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>("preview_script", 
+            uploadInfo->getItemId());
+        if (preview)
+        {
+            LLSD errors;
+            errors.append(LLTrans::getString("UploadFailed") + reason);
+            preview->callbackLSLCompileFailed(errors);
+        }
+    }
+
+}
diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h
new file mode 100644
index 0000000000000000000000000000000000000000..38167fc0c7b316de140961af0c837dd29f285124
--- /dev/null
+++ b/indra/newview/llviewerassetupload.h
@@ -0,0 +1,51 @@
+/**
+* @file llviewerassetupload.h
+* @author optional
+* @brief brief description of the file
+*
+* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2011, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_VIEWER_ASSET_UPLOAD_H
+#define LL_VIEWER_ASSET_UPLOAD_H
+
+#include "llfoldertype.h"
+#include "llassettype.h"
+#include "llinventorytype.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "llcorehttputil.h"
+
+#include "llviewermenufile.h"
+
+class LLViewerAssetUpload
+{
+public:
+
+    static void AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, const LLUUID &id,
+        std::string url, NewResourceUploadInfo::ptr_t uploadInfo);
+
+private:
+    static void HandleUploadError(LLCore::HttpStatus status, LLSD &result, NewResourceUploadInfo::ptr_t &uploadInfo);
+};
+
+#endif // !VIEWER_ASSET_UPLOAD_H
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
deleted file mode 100755
index e390e8776db446a2c67d0ca5c1cb20500642c8e4..0000000000000000000000000000000000000000
--- a/indra/newview/llviewerdisplayname.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/** 
- * @file llviewerdisplayname.cpp
- * @brief Wrapper for display name functionality
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llviewerdisplayname.h"
-
-// viewer includes
-#include "llagent.h"
-#include "llviewerregion.h"
-#include "llvoavatar.h"
-
-// library includes
-#include "llavatarnamecache.h"
-#include "llhttpclient.h"
-#include "llhttpnode.h"
-#include "llnotificationsutil.h"
-#include "llui.h"					// getLanguage()
-
-namespace LLViewerDisplayName
-{
-	// Fired when viewer receives server response to display name change
-	set_name_signal_t sSetDisplayNameSignal;
-
-	// Fired when there is a change in the agent's name
-	name_changed_signal_t sNameChangedSignal;
-
-	void addNameChangedCallback(const name_changed_signal_t::slot_type& cb) 
-	{ 
-		sNameChangedSignal.connect(cb); 
-	}
-
-	void doNothing() { }
-}
-
-class LLSetDisplayNameResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLSetDisplayNameResponder);
-private:
-	// only care about errors
-	/*virtual*/ void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-		LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
-		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
-	}
-};
-
-void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot)
-{
-	// TODO: simple validation here
-
-	LLViewerRegion* region = gAgent.getRegion();
-	llassert(region);
-	std::string cap_url = region->getCapability("SetDisplayName");
-	if (cap_url.empty())
-	{
-		// this server does not support display names, report error
-		slot(false, "unsupported", LLSD());
-		return;
-	}
-
-	// People API can return localized error messages.  Indicate our
-	// language preference via header.
-	LLSD headers;
-	headers[HTTP_OUT_HEADER_ACCEPT_LANGUAGE] = LLUI::getLanguage();
-
-	// People API requires both the old and new value to change a variable.
-	// Our display name will be in cache before the viewer's UI is available
-	// to request a change, so we can use direct lookup without callback.
-	LLAvatarName av_name;
-	if (!LLAvatarNameCache::get( gAgent.getID(), &av_name))
-	{
-		slot(false, "name unavailable", LLSD());
-		return;
-	}
-
-	// People API expects array of [ "old value", "new value" ]
-	LLSD change_array = LLSD::emptyArray();
-	change_array.append(av_name.getDisplayName());
-	change_array.append(display_name);
-	
-	LL_INFOS() << "Set name POST to " << cap_url << LL_ENDL;
-
-	// Record our caller for when the server sends back a reply
-	sSetDisplayNameSignal.connect(slot);
-	
-	// POST the requested change.  The sim will not send a response back to
-	// this request directly, rather it will send a separate message after it
-	// communicates with the back-end.
-	LLSD body;
-	body["display_name"] = change_array;
-	LLHTTPClient::post(cap_url, body, new LLSetDisplayNameResponder, headers);
-}
-
-class LLSetDisplayNameReply : public LLHTTPNode
-{
-	LOG_CLASS(LLSetDisplayNameReply);
-public:
-	/*virtual*/ void post(
-		LLHTTPNode::ResponsePtr response,
-		const LLSD& context,
-		const LLSD& input) const
-	{
-		LLSD body = input["body"];
-
-		S32 status = body["status"].asInteger();
-		bool success = (status == HTTP_OK);
-		std::string reason = body["reason"].asString();
-		LLSD content = body["content"];
-
-		LL_INFOS() << "status " << status << " reason " << reason << LL_ENDL;
-
-		// If viewer's concept of display name is out-of-date, the set request
-		// will fail with 409 Conflict.  If that happens, fetch up-to-date
-		// name information.
-		if (status == HTTP_CONFLICT)
-		{
-			LLUUID agent_id = gAgent.getID();
-			// Flush stale data
-			LLAvatarNameCache::erase( agent_id );
-			// Queue request for new data: nothing to do on callback though...
-			// Note: no need to disconnect the callback as it never gets out of scope
-			LLAvatarNameCache::get(agent_id, boost::bind(&LLViewerDisplayName::doNothing));
-			// Kill name tag, as it is wrong
-			LLVOAvatar::invalidateNameTag( agent_id );
-		}
-
-		// inform caller of result
-		LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content);
-		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
-	}
-};
-
-
-class LLDisplayNameUpdate : public LLHTTPNode
-{
-	/*virtual*/ void post(
-		LLHTTPNode::ResponsePtr response,
-		const LLSD& context,
-		const LLSD& input) const
-	{
-		LLSD body = input["body"];
-		LLUUID agent_id = body["agent_id"];
-		std::string old_display_name = body["old_display_name"];
-		// By convention this record is called "agent" in the People API
-		LLSD name_data = body["agent"];
-
-		// Inject the new name data into cache
-		LLAvatarName av_name;
-		av_name.fromLLSD( name_data );
-
-		LL_INFOS() << "name-update now " << LLDate::now()
-			<< " next_update " << LLDate(av_name.mNextUpdate)
-			<< LL_ENDL;
-
-		// Name expiration time may be provided in headers, or we may use a
-		// default value
-		// *TODO: get actual headers out of ResponsePtr
-		//LLSD headers = response->mHeaders;
-		LLSD headers;
-		av_name.mExpires = 
-			LLAvatarNameCache::nameExpirationFromHeaders(headers);
-
-		LLAvatarNameCache::insert(agent_id, av_name);
-
-		// force name tag to update
-		LLVOAvatar::invalidateNameTag(agent_id);
-
-		LLSD args;
-		args["OLD_NAME"] = old_display_name;
-		args["SLID"] = av_name.getUserName();
-		args["NEW_NAME"] = av_name.getDisplayName();
-		LLNotificationsUtil::add("DisplayNameUpdate", args);
-		if (agent_id == gAgent.getID())
-		{
-			LLViewerDisplayName::sNameChangedSignal();
-		}
-	}
-};
-
-LLHTTPRegistration<LLSetDisplayNameReply>
-    gHTTPRegistrationMessageSetDisplayNameReply(
-		"/message/SetDisplayNameReply");
-
-LLHTTPRegistration<LLDisplayNameUpdate>
-    gHTTPRegistrationMessageDisplayNameUpdate(
-		"/message/DisplayNameUpdate");
diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h
deleted file mode 100755
index 16d59ae43b2e04bd79cb3d70c4dd015997ac27a6..0000000000000000000000000000000000000000
--- a/indra/newview/llviewerdisplayname.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/** 
- * @file llviewerdisplayname.h
- * @brief Wrapper for display name functionality
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LLVIEWERDISPLAYNAME_H
-#define LLVIEWERDISPLAYNAME_H
-
-#include <boost/signals2.hpp>
-
-class LLSD;
-class LLUUID;
-
-namespace LLViewerDisplayName
-{
-	typedef boost::signals2::signal<
-		void (bool success, const std::string& reason, const LLSD& content)>
-			set_name_signal_t;
-	typedef set_name_signal_t::slot_type set_name_slot_t;
-	
-	typedef boost::signals2::signal<void (void)> name_changed_signal_t;
-	typedef name_changed_signal_t::slot_type name_changed_slot_t;
-
-	// Sends an update to the server to change a display name
-	// and call back when done.  May not succeed due to service
-	// unavailable or name not available.
-	void set(const std::string& display_name, const set_name_slot_t& slot); 
-	
-	void addNameChangedCallback(const name_changed_signal_t::slot_type& cb);
-}
-
-#endif // LLVIEWERDISPLAYNAME_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 1dad9dd506d5a2738d30d16169cb2ade0e2356a6..8627c848b5b83f32efba1d58e8b163ac596ffd77 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -56,7 +56,6 @@
 #include "llfloaterconversationpreview.h"
 #include "llfloaterdeleteenvpreset.h"
 #include "llfloaterdestinations.h"
-#include "llfloaterdisplayname.h"
 #include "llfloatereditdaycycle.h"
 #include "llfloatereditsky.h"
 #include "llfloatereditwater.h"
@@ -244,7 +243,6 @@ void LLViewerFloaterReg::registerFloaters()
 	LLInspectRemoteObjectUtil::registerFloater();
 	LLFloaterVoiceVolumeUtil::registerFloater();
 	LLNotificationsUI::registerFloater();
-	LLFloaterDisplayNameUtil::registerFloater();
 	
 	LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
 	LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index d1121180821c4abe08aa75fa88bdcc3897d15dbb..9a20dea2aa1874826ddd944c80a93d7043b4a636 100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1750,27 +1750,20 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
         return;
     }
 
-	// check capability to prevent a crash while LL_ERRS in LLCapabilityListener::capListener. See EXT-8459.
-	std::string url = viewer_region->getCapability("CopyInventoryFromNotecard");
-	if (url.empty())
-	{
-        LL_WARNS(LOG_NOTECARD) << "There is no 'CopyInventoryFromNotecard' capability"
-							   << " for region: " << viewer_region->getName()
-							   << LL_ENDL;
-		return;
-	}
-
-    LLSD request, body;
+    LLSD body;
     body["notecard-id"] = notecard_inv_id;
     body["object-id"] = object_id;
     body["item-id"] = src->getUUID();
 	body["folder-id"] = destination_id;
     body["callback-id"] = (LLSD::Integer)callback_id;
 
-    request["message"] = "CopyInventoryFromNotecard";
-    request["payload"] = body;
-
-    viewer_region->getCapAPI().post(request);
+    /// *TODO: RIDER: This posts the request under the agents policy.  
+    /// When I convert the inventory over this call should be moved under that 
+    /// policy as well.
+    if (!gAgent.requestPostCapability("CopyInventoryFromNotecard", body))
+    {
+        LL_WARNS() << "SIM does not have the capability to copy from notecard." << LL_ENDL;
+    }
 }
 
 void create_new_item(const std::string& name,
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 3eae0f8d86ca64d9d64ab29b43e0d91db409ed42..f332a4e98e6e3faa625a1ab44464052f56b1cb82 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -69,6 +69,7 @@
 #include "llwebprofile.h"
 #include "llwindow.h"
 #include "llvieweraudio.h"
+#include "llcorehttputil.h"
 
 #include "llfloaterwebcontent.h"	// for handling window close requests and geometry change requests in media browser windows.
 
@@ -152,190 +153,6 @@ LLViewerMediaObserver::~LLViewerMediaObserver()
 }
 
 
-// Move this to its own file.
-// helper class that tries to download a URL from a web site and calls a method
-// on the Panel Land Media and to discover the MIME type
-class LLMimeDiscoveryResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLMimeDiscoveryResponder);
-public:
-	LLMimeDiscoveryResponder( viewer_media_t media_impl)
-		: mMediaImpl(media_impl),
-		  mInitialized(false)
-	{
-		if(mMediaImpl->mMimeTypeProbe != NULL)
-		{
-			LL_ERRS() << "impl already has an outstanding responder" << LL_ENDL;
-		}
-		
-		mMediaImpl->mMimeTypeProbe = this;
-	}
-
-	~LLMimeDiscoveryResponder()
-	{
-		disconnectOwner();
-	}
-
-private:
-	/* virtual */ void httpCompleted()
-	{
-		if (!isGoodStatus())
-		{
-			LL_WARNS() << dumpResponse()
-					<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
-		}
-		const std::string& media_type = getResponseHeader(HTTP_IN_HEADER_CONTENT_TYPE);
-		std::string::size_type idx1 = media_type.find_first_of(";");
-		std::string mime_type = media_type.substr(0, idx1);
-
-		LL_DEBUGS() << "status is " << getStatus() << ", media type \"" << media_type << "\"" << LL_ENDL;
-		
-		// 2xx status codes indicate success.
-		// Most 4xx status codes are successful enough for our purposes.
-		// 499 is the error code for host not found, timeout, etc.
-		// 500 means "Internal Server error" but we decided it's okay to 
-		//     accept this and go past it in the MIME type probe
-		// 302 means the resource can be found temporarily in a different place - added this for join.secondlife.com
-		// 499 is a code specifc to join.secondlife.com apparently safe to ignore
-//		if(	((status >= 200) && (status < 300))	||
-//			((status >= 400) && (status < 499))	|| 
-//			(status == 500) ||
-//			(status == 302) ||
-//			(status == 499) 
-//			)
-		// We now no longer check the error code returned from the probe.
-		// If we have a mime type, use it.  If not, default to the web plugin and let it handle error reporting.
-		//if(1)
-		{
-			// The probe was successful.
-			if(mime_type.empty())
-			{
-				// Some sites don't return any content-type header at all.
-				// Treat an empty mime type as text/html.
-				mime_type = HTTP_CONTENT_TEXT_HTML;
-			}
-		}
-		//else
-		//{
-		//	LL_WARNS() << "responder failed with status " << dumpResponse() << LL_ENDL;
-		//
-		//	if(mMediaImpl)
-		//	{
-		//		mMediaImpl->mMediaSourceFailed = true;
-		//	}
-		//	return;
-		//}
-
-		// the call to initializeMedia may disconnect the responder, which will clear mMediaImpl.
-		// Make a local copy so we can call loadURI() afterwards.
-		LLViewerMediaImpl *impl = mMediaImpl;
-		
-		if(impl && !mInitialized && ! mime_type.empty())
-		{
-			if(impl->initializeMedia(mime_type))
-			{
-				mInitialized = true;
-				impl->loadURI();
-				disconnectOwner();
-			}
-		}
-	}
-	
-public:
-	void cancelRequest()
-	{
-		disconnectOwner();
-	}
-	
-private:
-	void disconnectOwner()
-	{
-		if(mMediaImpl)
-		{
-			if(mMediaImpl->mMimeTypeProbe != this)
-			{
-				LL_ERRS() << "internal error: mMediaImpl->mMimeTypeProbe != this" << LL_ENDL;
-			}
-
-			mMediaImpl->mMimeTypeProbe = NULL;
-		}
-		mMediaImpl = NULL;
-	}
-	
-	
-public:
-		LLViewerMediaImpl *mMediaImpl;
-		bool mInitialized;
-};
-
-class LLViewerMediaOpenIDResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLViewerMediaOpenIDResponder);
-public:
-	LLViewerMediaOpenIDResponder( )
-	{
-	}
-
-	~LLViewerMediaOpenIDResponder()
-	{
-	}
-
-	/* virtual */ void completedRaw(
-		const LLChannelDescriptors& channels,
-		const LLIOPipe::buffer_ptr_t& buffer)
-	{
-		// We don't care about the content of the response, only the Set-Cookie header.
-		LL_DEBUGS("MediaAuth") << dumpResponse() 
-				<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
-		const std::string& cookie = getResponseHeader(HTTP_IN_HEADER_SET_COOKIE);
-		
-		// *TODO: What about bad status codes?  Does this destroy previous cookies?
-		LLViewerMedia::openIDCookieResponse(cookie);
-	}
-
-};
-
-class LLViewerMediaWebProfileResponder : public LLHTTPClient::Responder
-{
-LOG_CLASS(LLViewerMediaWebProfileResponder);
-public:
-	LLViewerMediaWebProfileResponder(std::string host)
-	{
-		mHost = host;
-	}
-
-	~LLViewerMediaWebProfileResponder()
-	{
-	}
-
-	 void completedRaw(
-		const LLChannelDescriptors& channels,
-		const LLIOPipe::buffer_ptr_t& buffer)
-	{
-		// We don't care about the content of the response, only the set-cookie header.
-		LL_WARNS("MediaAuth") << dumpResponse() 
-				<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
-
-		LLSD stripped_content = getResponseHeaders();
-		// *TODO: Check that this works.
-		stripped_content.erase(HTTP_IN_HEADER_SET_COOKIE);
-		LL_WARNS("MediaAuth") << stripped_content << LL_ENDL;
-
-		const std::string& cookie = getResponseHeader(HTTP_IN_HEADER_SET_COOKIE);
-		LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL;
-
-		// *TODO: What about bad status codes?  Does this destroy previous cookies?
-		LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, mHost);
-
-		// Set cookie for snapshot publishing.
-		std::string auth_cookie = cookie.substr(0, cookie.find(";")); // strip path
-		LLWebProfile::setAuthCookie(auth_cookie);
-	}
-
-	std::string mHost;
-};
-
-
 LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;
 LLURL LLViewerMedia::sOpenIDURL;
 std::string LLViewerMedia::sOpenIDCookie;
@@ -1388,87 +1205,172 @@ LLSD LLViewerMedia::getHeaders()
 	return headers;
 }
 
+LLCore::HttpHeaders::ptr_t LLViewerMedia::getHttpHeaders()
+{
+    LLCore::HttpHeaders::ptr_t headers(new LLCore::HttpHeaders);
+
+    headers->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+    headers->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_XML);
+    headers->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie);
+    headers->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent());
+
+    return headers;
+}
+
 /////////////////////////////////////////////////////////////////////////////////////////
 // static
 void LLViewerMedia::setOpenIDCookie()
 {
 	if(!sOpenIDCookie.empty())
 	{
-		// The LLURL can give me the 'authority', which is of the form: [username[:password]@]hostname[:port]
-		// We want just the hostname for the cookie code, but LLURL doesn't seem to have a way to extract that.
-		// We therefore do it here.
-		std::string authority = sOpenIDURL.mAuthority;
-		std::string::size_type host_start = authority.find('@'); 
-		if(host_start == std::string::npos)
-		{
-			// no username/password
-			host_start = 0;
-		}
-		else
-		{
-			// Hostname starts after the @. 
-			// (If the hostname part is empty, this may put host_start at the end of the string.  In that case, it will end up passing through an empty hostname, which is correct.)
-			++host_start;
-		}
-		std::string::size_type host_end = authority.rfind(':'); 
-		if((host_end == std::string::npos) || (host_end < host_start))
-		{
-			// no port
-			host_end = authority.size();
-		}
-		
-		getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(host_start, host_end - host_start));
+        std::string profileUrl = getProfileURL("");
+
+        LLCoros::instance().launch("LLViewerMedia::getOpenIDCookieCoro",
+            boost::bind(&LLViewerMedia::getOpenIDCookieCoro, profileUrl));
+	}
+}
+
+/*static*/
+void LLViewerMedia::getOpenIDCookieCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getOpenIDCookieCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+    
+    httpOpts->setFollowRedirects(true);
+    httpOpts->setWantHeaders(true);
+
+    LLURL hostUrl(url.c_str());
+    std::string hostAuth = hostUrl.getAuthority();
+
+    // *TODO: Expand LLURL to split and extract this information better. 
+    // The structure of a URL is well defined and needing to retrieve parts of it are common.
+    // original comment:
+    // The LLURL can give me the 'authority', which is of the form: [username[:password]@]hostname[:port]
+    // We want just the hostname for the cookie code, but LLURL doesn't seem to have a way to extract that.
+    // We therefore do it here.
+    std::string authority = sOpenIDURL.mAuthority;
+    std::string::size_type hostStart = authority.find('@');
+    if (hostStart == std::string::npos)
+    {   // no username/password
+        hostStart = 0;
+    }
+    else
+    {   // Hostname starts after the @. 
+        // (If the hostname part is empty, this may put host_start at the end of the string.  In that case, it will end up passing through an empty hostname, which is correct.)
+        ++hostStart;
+    }
+    std::string::size_type hostEnd = authority.rfind(':');
+    if ((hostEnd == std::string::npos) || (hostEnd < hostStart))
+    {   // no port
+        hostEnd = authority.size();
+    }
 
-		// Do a web profile get so we can store the cookie 
-		LLSD headers = LLSD::emptyMap();
-		headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
-		headers[HTTP_OUT_HEADER_COOKIE] = sOpenIDCookie;
-		headers[HTTP_OUT_HEADER_USER_AGENT] = getCurrentUserAgent();
+    getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(hostStart, hostEnd - hostStart));
 
-		std::string profile_url = getProfileURL("");
-		LLURL raw_profile_url( profile_url.c_str() );
+    // Do a web profile get so we can store the cookie 
+    httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+    httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie);
+    httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent());
+
+
+    LL_DEBUGS("MediaAuth") << "Requesting " << url << LL_ENDL;
+    LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL;
+    
+    LLSD result = httpAdapter->getRawAndYield(httpRequest, url, httpOpts, httpHeaders);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("MediaAuth") << "Error getting web profile." << LL_ENDL;
+        return;
+    }
+
+    LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+    if (!resultHeaders.has(HTTP_IN_HEADER_SET_COOKIE))
+    {
+        LL_WARNS("MediaAuth") << "No cookie in response." << LL_ENDL;
+        return;
+    }
+
+    const std::string& cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asStringRef();
+    LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL;
+
+    // *TODO: What about bad status codes?  Does this destroy previous cookies?
+    LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, hostAuth);
+
+    // Set cookie for snapshot publishing.
+    std::string authCookie = cookie.substr(0, cookie.find(";")); // strip path
+    LLWebProfile::setAuthCookie(authCookie);
 
-		LL_DEBUGS("MediaAuth") << "Requesting " << profile_url << LL_ENDL;
-		LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL;
-		LLHTTPClient::get(profile_url,  
-			new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
-			headers);
-	}
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
 // static
-void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string &openid_token)
+void LLViewerMedia::openIDSetup(const std::string &openidUrl, const std::string &openidToken)
 {
-	LL_DEBUGS("MediaAuth") << "url = \"" << openid_url << "\", token = \"" << openid_token << "\"" << LL_ENDL;
+	LL_DEBUGS("MediaAuth") << "url = \"" << openidUrl << "\", token = \"" << openidToken << "\"" << LL_ENDL;
 
-	// post the token to the url 
-	// the responder will need to extract the cookie(s).
+    LLCoros::instance().launch("LLViewerMedia::openIDSetupCoro",
+        boost::bind(&LLViewerMedia::openIDSetupCoro, openidUrl, openidToken));
+}
 
-	// Save the OpenID URL for later -- we may need the host when adding the cookie.
-	sOpenIDURL.init(openid_url.c_str());
-	
-	// We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies.
-	sOpenIDCookie.clear();
+/*static*/
+void LLViewerMedia::openIDSetupCoro(std::string openidUrl, std::string openidToken)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("openIDSetupCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
 
-	LLSD headers = LLSD::emptyMap();
-	// Keep LLHTTPClient from adding an "Accept: application/llsd+xml" header
-	headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
-	// and use the expected content-type for a post, instead of the LLHTTPClient::postRaw() default of "application/octet-stream"
-	headers[HTTP_OUT_HEADER_CONTENT_TYPE] = "application/x-www-form-urlencoded";
-
-	// postRaw() takes ownership of the buffer and releases it later, so we need to allocate a new buffer here.
-	size_t size = openid_token.size();
-	U8 *data = new U8[size];
-	memcpy(data, openid_token.data(), size);
-
-	LLHTTPClient::postRaw( 
-		openid_url, 
-		data, 
-		size, 
-		new LLViewerMediaOpenIDResponder(),
-		headers);
-			
+    httpOpts->setWantHeaders(true);
+
+    // post the token to the url 
+    // the responder will need to extract the cookie(s).
+    // Save the OpenID URL for later -- we may need the host when adding the cookie.
+    sOpenIDURL.init(openidUrl.c_str());
+    // We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies.
+    sOpenIDCookie.clear();
+
+    httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+    httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded");
+
+    LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray);
+    LLCore::BufferArrayStream bas(rawbody.get());
+
+    bas << std::noskipws << openidToken;
+
+    LLSD result = httpAdapter->postRawAndYield(httpRequest, openidUrl, rawbody, httpOpts, httpHeaders);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("MediaAuth") << "Error getting Open ID cookie" << LL_ENDL;
+        return;
+    }
+
+    LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+    if (!resultHeaders.has(HTTP_IN_HEADER_SET_COOKIE))
+    {
+        LL_WARNS("MediaAuth") << "No cookie in response." << LL_ENDL;
+        return;
+    }
+
+    // We don't care about the content of the response, only the Set-Cookie header.
+    const std::string &cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE];
+
+    // *TODO: What about bad status codes?  Does this destroy previous cookies?
+    LLViewerMedia::openIDCookieResponse(cookie);
+    LL_DEBUGS("MediaAuth") << "OpenID cookie set." << LL_ENDL;
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -1661,7 +1563,6 @@ LLViewerMediaImpl::LLViewerMediaImpl(	  const LLUUID& texture_id,
 	mIsParcelMedia(false),
 	mProximity(-1),
 	mProximityDistance(0.0f),
-	mMimeTypeProbe(NULL),
 	mMediaAutoPlay(false),
 	mInNearbyMediaList(false),
 	mClearCache(false),
@@ -1671,8 +1572,10 @@ LLViewerMediaImpl::LLViewerMediaImpl(	  const LLUUID& texture_id,
 	mIsUpdated(false),
 	mTrustedBrowser(false),
 	mZoomFactor(1.0),
-    mCleanBrowser(false)
-{ 
+    mCleanBrowser(false),
+    mMimeProbe(),
+    mCanceling(false)
+{
 
 	// Set up the mute list observer if it hasn't been set up already.
 	if(!sViewerMediaMuteListObserverInitialized)
@@ -2610,7 +2513,8 @@ void LLViewerMediaImpl::navigateInternal()
 		return;
 	}
 	
-	if(mMimeTypeProbe != NULL)
+    
+    if (!mMimeProbe.expired())
 	{
 		LL_WARNS() << "MIME type probe already in progress -- bailing out." << LL_ENDL;
 		return;
@@ -2648,14 +2552,8 @@ void LLViewerMediaImpl::navigateInternal()
 
 		if(scheme.empty() || "http" == scheme || "https" == scheme)
 		{
-			// If we don't set an Accept header, LLHTTPClient will add one like this:
-			//    Accept: application/llsd+xml
-			// which is really not what we want.
-			LLSD headers = LLSD::emptyMap();
-			headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
-			// Allow cookies in the response, to prevent a redirect loop when accessing join.secondlife.com
-			headers[HTTP_OUT_HEADER_COOKIE] = "";
-			LLHTTPClient::getHeaderOnly( mMediaURL, new LLMimeDiscoveryResponder(this), headers, 10.0f);
+            LLCoros::instance().launch("LLViewerMediaImpl::mimeDiscoveryCoro",
+                boost::bind(&LLViewerMediaImpl::mimeDiscoveryCoro, this, mMediaURL));
 		}
 		else if("data" == scheme || "file" == scheme || "about" == scheme)
 		{
@@ -2685,6 +2583,66 @@ void LLViewerMediaImpl::navigateInternal()
 	}
 }
 
+void LLViewerMediaImpl::mimeDiscoveryCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("mimeDiscoveryCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+
+    mMimeProbe = httpAdapter;
+
+    httpOpts->setFollowRedirects(true);
+    httpOpts->setHeadersOnly(true);
+
+    httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+    httpHeaders->append(HTTP_OUT_HEADER_COOKIE, "");
+
+    LLSD result = httpAdapter->getRawAndYield(httpRequest, url, httpOpts, httpHeaders);
+
+    mMimeProbe.reset();
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS() << "Error retrieving media headers." << LL_ENDL;
+    }
+
+    LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+    
+    const std::string& mediaType = resultHeaders[HTTP_IN_HEADER_CONTENT_TYPE].asStringRef();
+
+    std::string::size_type idx1 = mediaType.find_first_of(";");
+    std::string mimeType = mediaType.substr(0, idx1);
+
+    // We now no longer need to check the error code returned from the probe.
+    // If we have a mime type, use it.  If not, default to the web plugin and let it handle error reporting.
+    // The probe was successful.
+    if (mimeType.empty())
+    {
+        // Some sites don't return any content-type header at all.
+        // Treat an empty mime type as text/html.
+        mimeType = HTTP_CONTENT_TEXT_HTML;
+    }
+
+    LL_DEBUGS() << "Media type \"" << mediaType << "\", mime type is \"" << mimeType << "\"" << LL_ENDL;
+
+    // the call to initializeMedia may disconnect the responder, which will clear mMediaImpl.
+    // Make a local copy so we can call loadURI() afterwards.
+
+    if (!mimeType.empty())
+    {
+        if (initializeMedia(mimeType))
+        {
+            loadURI();
+        }
+    }
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::navigateStop()
 {
@@ -2783,7 +2741,7 @@ void LLViewerMediaImpl::update()
 		{
 			// Don't load new instances that are at PRIORITY_SLIDESHOW or below.  They're just kept around to preserve state.
 		}
-		else if(mMimeTypeProbe != NULL)
+        else if (!mMimeProbe.expired())
 		{
 			// this media source is doing a MIME type probe -- don't try loading it again.
 		}
@@ -3673,18 +3631,10 @@ void LLViewerMediaImpl::setNavigateSuspended(bool suspend)
 
 void LLViewerMediaImpl::cancelMimeTypeProbe()
 {
-	if(mMimeTypeProbe != NULL)
-	{
-		// There doesn't seem to be a way to actually cancel an outstanding request.
-		// Simulate it by telling the LLMimeDiscoveryResponder not to write back any results.
-		mMimeTypeProbe->cancelRequest();
-		
-		// The above should already have set mMimeTypeProbe to NULL.
-		if(mMimeTypeProbe != NULL)
-		{
-			LL_ERRS() << "internal error: mMimeTypeProbe is not NULL after cancelling request." << LL_ENDL;
-		}
-	}
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t probeAdapter = mMimeProbe.lock();
+
+    if (probeAdapter)
+        probeAdapter->cancelYieldingOperation();
 }
 
 void LLViewerMediaImpl::addObject(LLVOVolume* obj) 
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 6803adfaa251bc986ff6a76aacebc9009f1f5e70..92d644c9008db5653149a7fde5adb6427e4b949f 100755
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -40,6 +40,9 @@
 #include "llnotificationptr.h"
 
 #include "llurl.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "llcorehttputil.h"
 
 class LLViewerMediaImpl;
 class LLUUID;
@@ -161,11 +164,15 @@ class LLViewerMedia
 	static void setOnlyAudibleMediaTextureID(const LLUUID& texture_id);
 
 	static LLSD getHeaders();
+    static LLCore::HttpHeaders::ptr_t getHttpHeaders();
 	
 private:
 	static void setOpenIDCookie();
 	static void onTeleportFinished();
-	
+
+    static void openIDSetupCoro(std::string openidUrl, std::string openidToken);
+    static void getOpenIDCookieCoro(std::string url);
+
 	static LLPluginCookieStore *sCookieStore;
 	static LLURL sOpenIDURL;
 	static std::string sOpenIDCookie;
@@ -180,7 +187,6 @@ class LLViewerMediaImpl
 public:
 	
 	friend class LLViewerMedia;
-	friend class LLMimeDiscoveryResponder;
 	
 	LLViewerMediaImpl(
 		const LLUUID& texture_id,
@@ -453,7 +459,6 @@ class LLViewerMediaImpl
 	S32 mProximity;
 	F64 mProximityDistance;
 	F64 mProximityCamera;
-	LLMimeDiscoveryResponder *mMimeTypeProbe;
 	bool mMediaAutoPlay;
 	std::string mMediaEntryURL;
 	bool mInNearbyMediaList;	// used by LLPanelNearbyMedia::refreshList() for performance reasons
@@ -470,6 +475,10 @@ class LLViewerMediaImpl
 	BOOL mIsUpdated ;
 	std::list< LLVOVolume* > mObjectList ;
 
+    void mimeDiscoveryCoro(std::string url);
+    LLCoreHttpUtil::HttpCoroutineAdapter::wptr_t mMimeProbe;
+    bool mCanceling;
+
 private:
 	LLViewerMediaTexture *updatePlaceholderImage();
 };
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index f8e50ba463e616fff5f09006fdd3eade1967affb..20fbfaf71abc89b56d9a383cb28fbb72a14f7a9a 100755
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -62,6 +62,8 @@
 #include "lluploaddialog.h"
 #include "lltrans.h"
 #include "llfloaterbuycurrency.h"
+#include "llcoproceduremanager.h"
+#include "llviewerassetupload.h"
 
 // linden libraries
 #include "llassetuploadresponders.h"
@@ -83,8 +85,9 @@ class LLFileEnableUpload : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
-		return new_value;
+        return true;
+// 		bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
+// 		return new_value;
 	}
 };
 
@@ -410,7 +413,6 @@ class LLFileUploadBulk : public view_listener_t
 		}
 
 		// TODO:
-		// Iterate over all files
 		// Check extensions for uploadability, cost
 		// Check user balance for entire cost
 		// Charge user entire cost
@@ -422,6 +424,34 @@ class LLFileUploadBulk : public view_listener_t
 		LLFilePicker& picker = LLFilePicker::instance();
 		if (picker.getMultipleOpenFiles())
 		{
+            std::string filename = picker.getFirstFile();
+            S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+
+            while (!filename.empty())
+            {
+                std::string name = gDirUtilp->getBaseFileName(filename, true);
+
+                std::string asset_name = name;
+                LLStringUtil::replaceNonstandardASCII( asset_name, '?' );
+                LLStringUtil::replaceChar(asset_name, '|', '?');
+                LLStringUtil::stripNonprintable(asset_name);
+                LLStringUtil::trim(asset_name);
+
+                NewResourceUploadInfo::ptr_t uploadInfo(new NewFileResourceUploadInfo(
+                    filename,
+                    asset_name,
+                    asset_name, 0,
+                    LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+                    LLFloaterPerms::getNextOwnerPerms("Uploads"),
+                    LLFloaterPerms::getGroupPerms("Uploads"),
+                    LLFloaterPerms::getEveryonePerms("Uploads"),
+                    expected_upload_cost));
+
+                upload_new_resource(uploadInfo, NULL, NULL);
+
+                filename = picker.getNextFile();
+            }
+#if 0
 			const std::string& filename = picker.getFirstFile();
 			std::string name = gDirUtilp->getBaseFileName(filename, true);
 			
@@ -453,6 +483,7 @@ class LLFileUploadBulk : public view_listener_t
 
 			// *NOTE: Ew, we don't iterate over the file list here,
 			// we handle the next files in upload_done_callback()
+#endif
 		}
 		else
 		{
@@ -621,6 +652,7 @@ void handle_compress_image(void*)
 	}
 }
 
+
 LLUUID upload_new_resource(
 	const std::string& src_filename,
 	std::string name,
@@ -636,6 +668,18 @@ LLUUID upload_new_resource(
 	S32 expected_upload_cost,
 	void *userdata)
 {	
+
+    NewResourceUploadInfo::ptr_t uploadInfo(new NewFileResourceUploadInfo(
+        src_filename,
+        name, desc, compression_info,
+        destination_folder_type, inv_type,
+        next_owner_perms, group_perms, everyone_perms,
+        expected_upload_cost));
+    upload_new_resource(uploadInfo, callback, userdata);
+
+    return LLUUID::null;
+
+#if 0
 	// Generate the temporary UUID.
 	std::string filename = gDirUtilp->getTempFilename();
 	LLTransactionID tid;
@@ -704,123 +748,6 @@ LLUUID upload_new_resource(
 			return LLUUID();
 		}
 	}
-	else if(exten == "tmp")	 	
-	{	 	
-		// This is a generic .lin resource file	 	
-         asset_type = LLAssetType::AT_OBJECT;	 	
-         LLFILE* in = LLFile::fopen(src_filename, "rb");		/* Flawfinder: ignore */	 	
-         if (in)	 	
-         {	 	
-                 // read in the file header	 	
-                 char buf[16384];		/* Flawfinder: ignore */ 	
-                 size_t readbytes;
-                 S32  version;	 	
-                 if (fscanf(in, "LindenResource\nversion %d\n", &version))	 	
-                 {	 	
-                         if (2 == version)	 	
-                         {
-								// *NOTE: This buffer size is hard coded into scanf() below.
-                                 char label[MAX_STRING];		/* Flawfinder: ignore */	 	
-                                 char value[MAX_STRING];		/* Flawfinder: ignore */	 	
-                                 S32  tokens_read;	 	
-                                 while (fgets(buf, 1024, in))	 	
-                                 {	 	
-                                         label[0] = '\0';	 	
-                                         value[0] = '\0';	 	
-                                         tokens_read = sscanf(	/* Flawfinder: ignore */
-											 buf,
-											 "%254s %254s\n",
-											 label, value);	 	
-
-                                         LL_INFOS() << "got: " << label << " = " << value	 	
-                                                         << LL_ENDL;	 	
-
-                                         if (EOF == tokens_read)	 	
-                                         {	 	
-                                                 fclose(in);	 	
-                                                 error_message = llformat("corrupt resource file: %s", src_filename.c_str());
-												 args["FILE"] = src_filename;
-												 upload_error(error_message, "CorruptResourceFile", filename, args);
-                                                 return LLUUID();
-                                         }	 	
-
-                                         if (2 == tokens_read)	 	
-                                         {	 	
-                                                 if (! strcmp("type", label))	 	
-                                                 {	 	
-                                                         asset_type = (LLAssetType::EType)(atoi(value));	 	
-                                                 }	 	
-                                         }	 	
-                                         else	 	
-                                         {	 	
-                                                 if (! strcmp("_DATA_", label))	 	
-                                                 {	 	
-                                                         // below is the data section	 	
-                                                         break;	 	
-                                                 }	 	
-                                         }	 	
-                                         // other values are currently discarded	 	
-                                 }	 	
-
-                         }	 	
-                         else	 	
-                         {	 	
-                                 fclose(in);	 	
-                                 error_message = llformat("unknown linden resource file version in file: %s", src_filename.c_str());
-								 args["FILE"] = src_filename;
-								 upload_error(error_message, "UnknownResourceFileVersion", filename, args);
-                                 return LLUUID();
-                         }	 	
-                 }	 	
-                 else	 	
-                 {	 	
-                         // this is an original binary formatted .lin file	 	
-                         // start over at the beginning of the file	 	
-                         fseek(in, 0, SEEK_SET);	 	
-
-                         const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256;	 	
-                         const S32 MAX_ASSET_NAME_LENGTH = 64;	 	
-                         S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH;	 	
-                         S16     type_num;	 	
-
-                         // read in and throw out most of the header except for the type	 	
-                         if (fread(buf, header_size, 1, in) != 1)
-						 {
-							 LL_WARNS() << "Short read" << LL_ENDL;
-						 }
-                         memcpy(&type_num, buf + 16, sizeof(S16));		/* Flawfinder: ignore */	 	
-                         asset_type = (LLAssetType::EType)type_num;	 	
-                 }	 	
-
-                 // copy the file's data segment into another file for uploading	 	
-                 LLFILE* out = LLFile::fopen(filename, "wb");		/* Flawfinder: ignore */	
-                 if (out)	 	
-                 {	 	
-                         while((readbytes = fread(buf, 1, 16384, in)))		/* Flawfinder: ignore */	 	
-                         {	 	
-							 if (fwrite(buf, 1, readbytes, out) != readbytes)
-							 {
-								 LL_WARNS() << "Short write" << LL_ENDL;
-							 }
-                         }	 	
-                         fclose(out);	 	
-                 }	 	
-                 else	 	
-                 {	 	
-                         fclose(in);	 	
-                         error_message = llformat( "Unable to create output file: %s", filename.c_str());
-						 args["FILE"] = filename;
-						 upload_error(error_message, "UnableToCreateOutputFile", filename, args);
-                         return LLUUID();
-                 }	 	
-
-                 fclose(in);	 	
-         }	 	
-         else	 	
-         {	 	
-                 LL_INFOS() << "Couldn't open .lin file " << src_filename << LL_ENDL;	 	
-         }	 	
-	}
 	else if (exten == "bvh")
 	{
 		error_message = llformat("We do not currently support bulk upload of animation files\n");
@@ -871,26 +798,15 @@ LLUUID upload_new_resource(
 
 	if (!error)
 	{
-		std::string t_disp_name = display_name;
-		if (t_disp_name.empty())
-		{
-			t_disp_name = src_filename;
-		}
-		upload_new_resource(
-			tid,
-			asset_type,
-			name,
-			desc,
-			compression_info, // tid
-			destination_folder_type,
-			inv_type,
-			next_owner_perms,
-			group_perms,
-			everyone_perms,
-			display_name,
-			callback,
-			expected_upload_cost,
-			userdata);
+        NewResourceUploadInfo::ptr_t uploadInfo(new NewResourceUploadInfo(
+            tid, asset_type,
+            name, desc, compression_info,
+            destination_folder_type, inv_type,
+            next_owner_perms, group_perms, everyone_perms,
+            expected_upload_cost));
+
+        upload_new_resource(uploadInfo, 
+                callback, userdata);
 	}
 	else
 	{
@@ -906,6 +822,7 @@ LLUUID upload_new_resource(
 	}
 
 	return uuid;
+#endif
 }
 
 void upload_done_callback(
@@ -1035,189 +952,64 @@ void upload_done_callback(
 	}
 }
 
-static LLAssetID upload_new_resource_prep(
-	const LLTransactionID& tid,
-	LLAssetType::EType asset_type,
-	LLInventoryType::EType& inventory_type,
-	std::string& name,
-	const std::string& display_name,
-	std::string& description)
-{
-	LLAssetID uuid = generate_asset_id_for_new_upload(tid);
-
-	increase_new_upload_stats(asset_type);
-
-	assign_defaults_and_show_upload_message(
-		asset_type,
-		inventory_type,
-		name,
-		display_name,
-		description);
-
-	return uuid;
-}
-
-LLSD generate_new_resource_upload_capability_body(
-	LLAssetType::EType asset_type,
-	const std::string& name,
-	const std::string& desc,
-	LLFolderType::EType destination_folder_type,
-	LLInventoryType::EType inv_type,
-	U32 next_owner_perms,
-	U32 group_perms,
-	U32 everyone_perms)
-{
-	LLSD body;
-
-	body["folder_id"] = gInventory.findCategoryUUIDForType(
-		(destination_folder_type == LLFolderType::FT_NONE) ?
-		(LLFolderType::EType) asset_type :
-		destination_folder_type);
-
-	body["asset_type"] = LLAssetType::lookup(asset_type);
-	body["inventory_type"] = LLInventoryType::lookup(inv_type);
-	body["name"] = name;
-	body["description"] = desc;
-	body["next_owner_mask"] = LLSD::Integer(next_owner_perms);
-	body["group_mask"] = LLSD::Integer(group_perms);
-	body["everyone_mask"] = LLSD::Integer(everyone_perms);
-
-	return body;
-}
-
 void upload_new_resource(
-	const LLTransactionID &tid,
-	LLAssetType::EType asset_type,
-	std::string name,
-	std::string desc,
-	S32 compression_info,
-	LLFolderType::EType destination_folder_type,
-	LLInventoryType::EType inv_type,
-	U32 next_owner_perms,
-	U32 group_perms,
-	U32 everyone_perms,
-	const std::string& display_name,
-	LLAssetStorage::LLStoreAssetCallback callback,
-	S32 expected_upload_cost,
-	void *userdata)
+    NewResourceUploadInfo::ptr_t &uploadInfo,
+    LLAssetStorage::LLStoreAssetCallback callback,
+    void *userdata)
 {
 	if(gDisconnected)
 	{
 		return ;
 	}
-	
-	LLAssetID uuid = 
-		upload_new_resource_prep(
-			tid,
-			asset_type,
-			inv_type,
-			name,
-			display_name,
-			desc);
-	
-	if( LLAssetType::AT_SOUND == asset_type )
-	{
-		add(LLStatViewer::UPLOAD_SOUND, 1);
-	}
-	else
-	if( LLAssetType::AT_TEXTURE == asset_type )
-	{
-		add(LLStatViewer::UPLOAD_TEXTURE, 1);
-	}
-	else
-	if( LLAssetType::AT_ANIMATION == asset_type)
-	{
-		add(LLStatViewer::ANIMATION_UPLOADS, 1);
-	}
 
-	if(LLInventoryType::IT_NONE == inv_type)
-	{
-		inv_type = LLInventoryType::defaultForAssetType(asset_type);
-	}
-	LLStringUtil::stripNonprintable(name);
-	LLStringUtil::stripNonprintable(desc);
-	if(name.empty())
-	{
-		name = "(No Name)";
-	}
-	if(desc.empty())
-	{
-		desc = "(No Description)";
-	}
-	
-	// At this point, we're ready for the upload.
-	std::string upload_message = "Uploading...\n\n";
-	upload_message.append(display_name);
-	LLUploadDialog::modalUploadDialog(upload_message);
-
-	LL_INFOS() << "*** Uploading: " << LL_ENDL;
-	LL_INFOS() << "Type: " << LLAssetType::lookup(asset_type) << LL_ENDL;
-	LL_INFOS() << "UUID: " << uuid << LL_ENDL;
-	LL_INFOS() << "Name: " << name << LL_ENDL;
-	LL_INFOS() << "Desc: " << desc << LL_ENDL;
-	LL_INFOS() << "Expected Upload Cost: " << expected_upload_cost << LL_ENDL;
-	LL_DEBUGS() << "Folder: " << gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(asset_type) : destination_folder_type) << LL_ENDL;
-	LL_DEBUGS() << "Asset Type: " << LLAssetType::lookup(asset_type) << LL_ENDL;
-
-	std::string url = gAgent.getRegion()->getCapability(
-		"NewFileAgentInventory");
+//     uploadInfo->setAssetType(assetType);
+//     uploadInfo->setTransactionId(tid);
+
+
+	std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
 
 	if ( !url.empty() )
 	{
-		LL_INFOS() << "New Agent Inventory via capability" << LL_ENDL;
-
-		LLSD body;
-		body = generate_new_resource_upload_capability_body(
-			asset_type,
-			name,
-			desc,
-			destination_folder_type,
-			inv_type,
-			next_owner_perms,
-			group_perms,
-			everyone_perms);
-
-		LLHTTPClient::post(
-			url,
-			body,
-			new LLNewAgentInventoryResponder(
-				body,
-				uuid,
-				asset_type));
+        LLCoprocedureManager::CoProcedure_t proc = boost::bind(&LLViewerAssetUpload::AssetInventoryUploadCoproc, _1, _2, url, uploadInfo);
+
+        LLCoprocedureManager::getInstance()->enqueueCoprocedure("LLViewerAssetUpload::AssetInventoryUploadCoproc", proc);
 	}
 	else
 	{
+        uploadInfo->prepareUpload();
+        uploadInfo->logPreparedUpload();
+
 		LL_INFOS() << "NewAgentInventory capability not found, new agent inventory via asset system." << LL_ENDL;
 		// check for adequate funds
 		// TODO: do this check on the sim
-		if (LLAssetType::AT_SOUND == asset_type ||
-			LLAssetType::AT_TEXTURE == asset_type ||
-			LLAssetType::AT_ANIMATION == asset_type)
+		if (LLAssetType::AT_SOUND == uploadInfo->getAssetType() ||
+            LLAssetType::AT_TEXTURE == uploadInfo->getAssetType() ||
+            LLAssetType::AT_ANIMATION == uploadInfo->getAssetType())
 		{
 			S32 balance = gStatusBar->getBalance();
-			if (balance < expected_upload_cost)
+			if (balance < uploadInfo->getExpectedUploadCost())
 			{
 				// insufficient funds, bail on this upload
 				LLStringUtil::format_map_t args;
-				args["NAME"] = name;
-				args["AMOUNT"] = llformat("%d", expected_upload_cost);
-				LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("UploadingCosts", args), expected_upload_cost );
+				args["NAME"] = uploadInfo->getName();
+                args["AMOUNT"] = llformat("%d", uploadInfo->getExpectedUploadCost());
+                LLBuyCurrencyHTML::openCurrencyFloater(LLTrans::getString("UploadingCosts", args), uploadInfo->getExpectedUploadCost());
 				return;
 			}
 		}
 
 		LLResourceData* data = new LLResourceData;
-		data->mAssetInfo.mTransactionID = tid;
-		data->mAssetInfo.mUuid = uuid;
-		data->mAssetInfo.mType = asset_type;
+		data->mAssetInfo.mTransactionID = uploadInfo->getTransactionId();
+		data->mAssetInfo.mUuid = uploadInfo->getAssetId();
+        data->mAssetInfo.mType = uploadInfo->getAssetType();
 		data->mAssetInfo.mCreatorID = gAgentID;
-		data->mInventoryType = inv_type;
-		data->mNextOwnerPerm = next_owner_perms;
-		data->mExpectedUploadCost = expected_upload_cost;
+		data->mInventoryType = uploadInfo->getInventoryType();
+		data->mNextOwnerPerm = uploadInfo->getNextOwnerPerms();
+		data->mExpectedUploadCost = uploadInfo->getExpectedUploadCost();
 		data->mUserData = userdata;
-		data->mAssetInfo.setName(name);
-		data->mAssetInfo.setDescription(desc);
-		data->mPreferredLocation = destination_folder_type;
+		data->mAssetInfo.setName(uploadInfo->getName());
+		data->mAssetInfo.setDescription(uploadInfo->getDescription());
+		data->mPreferredLocation = uploadInfo->getDestinationFolderType();
 
 		LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback;
 		if (callback)
@@ -1233,66 +1025,6 @@ void upload_new_resource(
 	}
 }
 
-LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid)
-{
-	if ( gDisconnected )
-	{	
-		LLAssetID rv;
-
-		rv.setNull();
-		return rv;
-	}
-
-	LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID());
-
-	return uuid;
-}
-
-void increase_new_upload_stats(LLAssetType::EType asset_type)
-{
-	if ( LLAssetType::AT_SOUND == asset_type )
-	{
-		add(LLStatViewer::UPLOAD_SOUND, 1);
-	}
-	else if ( LLAssetType::AT_TEXTURE == asset_type )
-	{
-		add(LLStatViewer::UPLOAD_TEXTURE, 1);
-	}
-	else if ( LLAssetType::AT_ANIMATION == asset_type )
-	{
-		add(LLStatViewer::ANIMATION_UPLOADS, 1);
-	}
-}
-
-void assign_defaults_and_show_upload_message(
-	LLAssetType::EType asset_type,
-	LLInventoryType::EType& inventory_type,
-	std::string& name,
-	const std::string& display_name,
-	std::string& description)
-{
-	if ( LLInventoryType::IT_NONE == inventory_type )
-	{
-		inventory_type = LLInventoryType::defaultForAssetType(asset_type);
-	}
-	LLStringUtil::stripNonprintable(name);
-	LLStringUtil::stripNonprintable(description);
-
-	if ( name.empty() )
-	{
-		name = "(No Name)";
-	}
-	if ( description.empty() )
-	{
-		description = "(No Description)";
-	}
-
-	// At this point, we're ready for the upload.
-	std::string upload_message = "Uploading...\n\n";
-	upload_message.append(display_name);
-	LLUploadDialog::modalUploadDialog(upload_message);
-}
-
 
 void init_menu_file()
 {
@@ -1315,3 +1047,349 @@ void init_menu_file()
 
 	// "File.SaveTexture" moved to llpanelmaininventory so that it can be properly handled.
 }
+
+LLSD NewResourceUploadInfo::prepareUpload()
+{
+    if (mAssetId.isNull())
+        generateNewAssetId();
+
+    incrementUploadStats();
+    assignDefaults();
+
+    return LLSD().with("success", LLSD::Boolean(true));
+}
+
+std::string NewResourceUploadInfo::getAssetTypeString() const
+{
+    return LLAssetType::lookup(mAssetType);
+}
+
+std::string NewResourceUploadInfo::getInventoryTypeString() const
+{
+    return LLInventoryType::lookup(mInventoryType);
+}
+
+LLSD NewResourceUploadInfo::generatePostBody()
+{
+    LLSD body;
+
+    body["folder_id"] = mFolderId;
+    body["asset_type"] = getAssetTypeString();
+    body["inventory_type"] = getInventoryTypeString();
+    body["name"] = mName;
+    body["description"] = mDescription;
+    body["next_owner_mask"] = LLSD::Integer(mNextOwnerPerms);
+    body["group_mask"] = LLSD::Integer(mGroupPerms);
+    body["everyone_mask"] = LLSD::Integer(mEveryonePerms);
+
+    return body;
+
+}
+
+void NewResourceUploadInfo::logPreparedUpload()
+{
+    LL_INFOS() << "*** Uploading: " << std::endl << 
+        "Type: " << LLAssetType::lookup(mAssetType) << std::endl <<
+        "UUID: " << mAssetId.asString() << std::endl << 
+        "Name: " << mName << std::endl << 
+        "Desc: " << mDescription << std::endl <<
+        "Expected Upload Cost: " << mExpectedUploadCost << std::endl <<
+        "Folder: " << mFolderId << std::endl <<
+        "Asset Type: " << LLAssetType::lookup(mAssetType) << LL_ENDL;
+}
+
+LLUUID NewResourceUploadInfo::finishUpload(LLSD &result)
+{
+    if (getFolderId().isNull())
+    {
+        return LLUUID::null;
+    }
+
+    U32 permsEveryone = PERM_NONE;
+    U32 permsGroup = PERM_NONE;
+    U32 permsNextOwner = PERM_ALL;
+
+    if (result.has("new_next_owner_mask"))
+    {
+        // The server provided creation perms so use them.
+        // Do not assume we got the perms we asked for in
+        // since the server may not have granted them all.
+        permsEveryone = result["new_everyone_mask"].asInteger();
+        permsGroup = result["new_group_mask"].asInteger();
+        permsNextOwner = result["new_next_owner_mask"].asInteger();
+    }
+    else
+    {
+        // The server doesn't provide creation perms
+        // so use old assumption-based perms.
+        if (getAssetTypeString() != "snapshot")
+        {
+            permsNextOwner = PERM_MOVE | PERM_TRANSFER;
+        }
+    }
+
+    LLPermissions new_perms;
+    new_perms.init(
+        gAgent.getID(),
+        gAgent.getID(),
+        LLUUID::null,
+        LLUUID::null);
+
+    new_perms.initMasks(
+        PERM_ALL,
+        PERM_ALL,
+        permsEveryone,
+        permsGroup,
+        permsNextOwner);
+
+    U32 flagsInventoryItem = 0;
+    if (result.has("inventory_flags"))
+    {
+        flagsInventoryItem = static_cast<U32>(result["inventory_flags"].asInteger());
+        if (flagsInventoryItem != 0)
+        {
+            LL_INFOS() << "inventory_item_flags " << flagsInventoryItem << LL_ENDL;
+        }
+    }
+    S32 creationDate = time_corrected();
+
+    LLUUID serverInventoryItem = result["new_inventory_item"].asUUID();
+    LLUUID serverAssetId = result["new_asset"].asUUID();
+
+    LLPointer<LLViewerInventoryItem> item = new LLViewerInventoryItem(
+        serverInventoryItem,
+        getFolderId(),
+        new_perms,
+        serverAssetId,
+        getAssetType(),
+        getInventoryType(),
+        getName(),
+        getDescription(),
+        LLSaleInfo::DEFAULT,
+        flagsInventoryItem,
+        creationDate);
+
+    gInventory.updateItem(item);
+    gInventory.notifyObservers();
+
+    return serverInventoryItem;
+}
+
+
+LLAssetID NewResourceUploadInfo::generateNewAssetId()
+{
+    if (gDisconnected)
+    {
+        LLAssetID rv;
+
+        rv.setNull();
+        return rv;
+    }
+    mAssetId = mTransactionId.makeAssetID(gAgent.getSecureSessionID());
+
+    return mAssetId;
+}
+
+void NewResourceUploadInfo::incrementUploadStats() const
+{
+    if (LLAssetType::AT_SOUND == mAssetType)
+    {
+        add(LLStatViewer::UPLOAD_SOUND, 1);
+    }
+    else if (LLAssetType::AT_TEXTURE == mAssetType)
+    {
+        add(LLStatViewer::UPLOAD_TEXTURE, 1);
+    }
+    else if (LLAssetType::AT_ANIMATION == mAssetType)
+    {
+        add(LLStatViewer::ANIMATION_UPLOADS, 1);
+    }
+}
+
+void NewResourceUploadInfo::assignDefaults()
+{
+    if (LLInventoryType::IT_NONE == mInventoryType)
+    {
+        mInventoryType = LLInventoryType::defaultForAssetType(mAssetType);
+    }
+    LLStringUtil::stripNonprintable(mName);
+    LLStringUtil::stripNonprintable(mDescription);
+
+    if (mName.empty())
+    {
+        mName = "(No Name)";
+    }
+    if (mDescription.empty())
+    {
+        mDescription = "(No Description)";
+    }
+
+    mFolderId = gInventory.findCategoryUUIDForType(
+        (mDestinationFolderType == LLFolderType::FT_NONE) ?
+        (LLFolderType::EType)mAssetType : mDestinationFolderType);
+
+}
+
+std::string NewResourceUploadInfo::getDisplayName() const
+{ 
+    return (mName.empty()) ? mAssetId.asString() : mName; 
+};
+
+
+NewFileResourceUploadInfo::NewFileResourceUploadInfo(
+        std::string fileName,
+        std::string name,
+        std::string description,
+        S32 compressionInfo,
+        LLFolderType::EType destinationType,
+        LLInventoryType::EType inventoryType,
+        U32 nextOWnerPerms,
+        U32 groupPerms,
+        U32 everyonePerms,
+        S32 expectedCost):
+    NewResourceUploadInfo(name, description, compressionInfo,
+        destinationType, inventoryType,
+        nextOWnerPerms, groupPerms, everyonePerms, expectedCost),
+    mFileName(fileName)
+{
+    LLTransactionID tid;
+    tid.generate();
+    setTransactionId(tid);
+}
+
+
+
+LLSD NewFileResourceUploadInfo::prepareUpload()
+{
+    generateNewAssetId();
+
+    LLSD result = exportTempFile();
+    if (result.has("error"))
+        return result;
+
+    return NewResourceUploadInfo::prepareUpload();
+}
+
+LLSD NewFileResourceUploadInfo::exportTempFile()
+{
+    std::string filename = gDirUtilp->getTempFilename();
+
+    std::string exten = gDirUtilp->getExtension(getFileName());
+    U32 codec = LLImageBase::getCodecFromExtension(exten);
+
+    LLAssetType::EType assetType = LLAssetType::AT_NONE;
+    std::string errorMessage;
+    std::string errorLabel;
+
+    bool error = false;
+
+    if (exten.empty())
+    {
+        std::string shortName = gDirUtilp->getBaseFileName(filename);
+
+        // No extension
+        errorMessage = llformat(
+            "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
+            shortName.c_str());
+        errorLabel = "NoFileExtension";
+        error = true;
+    }
+    else if (codec != IMG_CODEC_INVALID)
+    {
+        // It's an image file, the upload procedure is the same for all
+        assetType = LLAssetType::AT_TEXTURE;
+        if (!LLViewerTextureList::createUploadFile(getFileName(), filename, codec))
+        {
+            errorMessage = llformat("Problem with file %s:\n\n%s\n",
+                getFileName().c_str(), LLImage::getLastError().c_str());
+            errorLabel = "ProblemWithFile";
+            error = true;
+        }
+    }
+    else if (exten == "wav")
+    {
+        assetType = LLAssetType::AT_SOUND;  // tag it as audio
+        S32 encodeResult = 0;
+
+        LL_INFOS() << "Attempting to encode wav as an ogg file" << LL_ENDL;
+
+        encodeResult = encode_vorbis_file(getFileName(), filename);
+
+        if (LLVORBISENC_NOERR != encodeResult)
+        {
+            switch (encodeResult)
+            {
+            case LLVORBISENC_DEST_OPEN_ERR:
+                errorMessage = llformat("Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str());
+                errorLabel = "CannotOpenTemporarySoundFile";
+                break;
+
+            default:
+                errorMessage = llformat("Unknown vorbis encode failure on: %s\n", getFileName().c_str());
+                errorLabel = "UnknownVorbisEncodeFailure";
+                break;
+            }
+            error = true;
+        }
+    }
+    else if (exten == "bvh")
+    {
+        errorMessage = llformat("We do not currently support bulk upload of animation files\n");
+        errorLabel = "DoNotSupportBulkAnimationUpload";
+        error = true;
+    }
+    else if (exten == "anim")
+    {
+        assetType = LLAssetType::AT_ANIMATION;
+        filename = getFileName();
+    }
+    else
+    {
+        // Unknown extension
+        errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
+        errorLabel = "ErrorMessage";
+        error = TRUE;;
+    }
+
+    if (error)
+    {
+        LLSD errorResult(LLSD::emptyMap());
+
+        errorResult["error"] = LLSD::Binary(true);
+        errorResult["message"] = errorMessage;
+        errorResult["label"] = errorLabel;
+        return errorResult;
+    }
+
+    setAssetType(assetType);
+
+    // copy this file into the vfs for upload
+    S32 file_size;
+    LLAPRFile infile;
+    infile.open(filename, LL_APR_RB, NULL, &file_size);
+    if (infile.getFileHandle())
+    {
+        LLVFile file(gVFS, getAssetId(), assetType, LLVFile::WRITE);
+
+        file.setMaxSize(file_size);
+
+        const S32 buf_size = 65536;
+        U8 copy_buf[buf_size];
+        while ((file_size = infile.read(copy_buf, buf_size)))
+        {
+            file.write(copy_buf, file_size);
+        }
+    }
+    else
+    {
+        errorMessage = llformat("Unable to access output file: %s", filename.c_str());
+        LLSD errorResult(LLSD::emptyMap());
+
+        errorResult["error"] = LLSD::Binary(true);
+        errorResult["message"] = errorMessage;
+        return errorResult;
+    }
+
+    return LLSD();
+
+}
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 3034d00b22ef4202d7cf4dddf4036198269effe7..7ee50437772156fb4ce303ba53335ccbf918bfbc 100755
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -39,40 +39,172 @@ class LLTransactionID;
 
 void init_menu_file();
 
+class NewResourceUploadInfo
+{
+public:
+    typedef boost::shared_ptr<NewResourceUploadInfo> ptr_t;
+
+    NewResourceUploadInfo(
+            LLTransactionID transactId,
+            LLAssetType::EType assetType,
+            std::string name, 
+            std::string description, 
+            S32 compressionInfo,
+            LLFolderType::EType destinationType,
+            LLInventoryType::EType inventoryType,
+            U32 nextOWnerPerms, 
+            U32 groupPerms, 
+            U32 everyonePerms, 
+            S32 expectedCost) :
+        mTransactionId(transactId),
+        mAssetType(assetType),
+        mName(name),
+        mDescription(description),
+        mCompressionInfo(compressionInfo),
+        mDestinationFolderType(destinationType),
+        mInventoryType(inventoryType),
+        mNextOwnerPerms(nextOWnerPerms),
+        mGroupPerms(groupPerms),
+        mEveryonePerms(everyonePerms),
+        mExpectedUploadCost(expectedCost),
+        mFolderId(LLUUID::null),
+        mItemId(LLUUID::null),
+        mAssetId(LLAssetID::null)
+    { }
+
+    virtual ~NewResourceUploadInfo()
+    { }
+
+    virtual LLSD        prepareUpload();
+    virtual LLSD        generatePostBody();
+    virtual void        logPreparedUpload();
+    virtual LLUUID      finishUpload(LLSD &result);
+
+    //void                setAssetType(LLAssetType::EType assetType) { mAssetType = assetType; }
+    //void                setTransactionId(LLTransactionID transactionId) { mTransactionId = transactionId; }
+
+    LLTransactionID     getTransactionId() const { return mTransactionId; }
+    LLAssetType::EType  getAssetType() const { return mAssetType; }
+    std::string         getAssetTypeString() const;
+    std::string         getName() const { return mName; };
+    std::string         getDescription() const { return mDescription; };
+    S32                 getCompressionInfo() const { return mCompressionInfo; };
+    LLFolderType::EType getDestinationFolderType() const { return mDestinationFolderType; };
+    LLInventoryType::EType  getInventoryType() const { return mInventoryType; };
+    std::string         getInventoryTypeString() const;
+    U32                 getNextOwnerPerms() const { return mNextOwnerPerms; };
+    U32                 getGroupPerms() const { return mGroupPerms; };
+    U32                 getEveryonePerms() const { return mEveryonePerms; };
+    S32                 getExpectedUploadCost() const { return mExpectedUploadCost; };
+
+    virtual std::string getDisplayName() const;
+
+    LLUUID              getFolderId() const { return mFolderId; }
+    LLUUID              getItemId() const { return mItemId; }
+    LLAssetID           getAssetId() const { return mAssetId; }
+
+protected:
+    NewResourceUploadInfo(
+            std::string name,
+            std::string description,
+            S32 compressionInfo,
+            LLFolderType::EType destinationType,
+            LLInventoryType::EType inventoryType,
+            U32 nextOWnerPerms,
+            U32 groupPerms,
+            U32 everyonePerms,
+            S32 expectedCost) :
+        mName(name),
+        mDescription(description),
+        mCompressionInfo(compressionInfo),
+        mDestinationFolderType(destinationType),
+        mInventoryType(inventoryType),
+        mNextOwnerPerms(nextOWnerPerms),
+        mGroupPerms(groupPerms),
+        mEveryonePerms(everyonePerms),
+        mExpectedUploadCost(expectedCost),
+        mTransactionId(),
+        mAssetType(LLAssetType::AT_NONE),
+        mFolderId(LLUUID::null),
+        mItemId(LLUUID::null),
+        mAssetId(LLAssetID::null)
+    { }
+
+    void                setTransactionId(LLTransactionID tid) { mTransactionId = tid; }
+    void                setAssetType(LLAssetType::EType assetType) { mAssetType = assetType; }
+
+    LLAssetID           generateNewAssetId();
+    void                incrementUploadStats() const;
+    virtual void        assignDefaults();
+
+private:
+    LLTransactionID     mTransactionId;
+    LLAssetType::EType  mAssetType;
+    std::string         mName;
+    std::string         mDescription;
+    S32                 mCompressionInfo;
+    LLFolderType::EType mDestinationFolderType;
+    LLInventoryType::EType mInventoryType;
+    U32                 mNextOwnerPerms;
+    U32                 mGroupPerms;
+    U32                 mEveryonePerms;
+    S32                 mExpectedUploadCost;
+
+    LLUUID              mFolderId;
+    LLUUID              mItemId;
+    LLAssetID           mAssetId;
+};
+
+class NewFileResourceUploadInfo : public NewResourceUploadInfo
+{
+public:
+    NewFileResourceUploadInfo(
+        std::string fileName,
+        std::string name,
+        std::string description,
+        S32 compressionInfo,
+        LLFolderType::EType destinationType,
+        LLInventoryType::EType inventoryType,
+        U32 nextOWnerPerms,
+        U32 groupPerms,
+        U32 everyonePerms,
+        S32 expectedCost);
+
+    virtual LLSD        prepareUpload();
+
+    std::string         getFileName() const { return mFileName; };
+
+protected:
+
+    virtual LLSD        exportTempFile();
+
+private:
+    std::string         mFileName;
+
+};
+
+
 LLUUID upload_new_resource(
-	const std::string& src_filename, 
-	std::string name,
-	std::string desc, 
-	S32 compression_info,
-	LLFolderType::EType destination_folder_type,
-	LLInventoryType::EType inv_type,
-	U32 next_owner_perms,
-	U32 group_perms,
-	U32 everyone_perms,
-	const std::string& display_name,
-	LLAssetStorage::LLStoreAssetCallback callback,
-	S32 expected_upload_cost,
-	void *userdata);
+    const std::string& src_filename,
+    std::string name,
+    std::string desc,
+    S32 compression_info,
+    LLFolderType::EType destination_folder_type,
+    LLInventoryType::EType inv_type,
+    U32 next_owner_perms,
+    U32 group_perms,
+    U32 everyone_perms,
+    const std::string& display_name,
+    LLAssetStorage::LLStoreAssetCallback callback,
+    S32 expected_upload_cost,
+    void *userdata);
 
 void upload_new_resource(
-	const LLTransactionID &tid, 
-	LLAssetType::EType type,
-	std::string name,
-	std::string desc, 
-	S32 compression_info,
-	LLFolderType::EType destination_folder_type,
-	LLInventoryType::EType inv_type,
-	U32 next_owner_perms,
-	U32 group_perms,
-	U32 everyone_perms,
-	const std::string& display_name,
-	LLAssetStorage::LLStoreAssetCallback callback,
-	S32 expected_upload_cost,
-	void *userdata);
+    NewResourceUploadInfo::ptr_t &uploadInfo,
+    LLAssetStorage::LLStoreAssetCallback callback = NULL,
+    void *userdata = NULL);
 
 
-LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid);
-void increase_new_upload_stats(LLAssetType::EType asset_type);
 void assign_defaults_and_show_upload_message(
 	LLAssetType::EType asset_type,
 	LLInventoryType::EType& inventory_type,
@@ -80,16 +212,6 @@ void assign_defaults_and_show_upload_message(
 	const std::string& display_name,
 	std::string& description);
 
-LLSD generate_new_resource_upload_capability_body(
-	LLAssetType::EType asset_type,
-	const std::string& name,
-	const std::string& desc,
-	LLFolderType::EType destination_folder_type,
-	LLInventoryType::EType inv_type,
-	U32 next_owner_perms,
-	U32 group_perms,
-	U32 everyone_perms);
-
 void on_new_single_inventory_upload_complete(
 	LLAssetType::EType asset_type,
 	LLInventoryType::EType inventory_type,
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 7c36b30dd10dc3e0a339c160d601991300f967e4..2a009499d322e2dcb55abe345e94fdd456ba2446 100755
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -78,6 +78,7 @@
 #include "llappviewer.h"
 #include "llfloaterperms.h"
 #include "llvocache.h"
+#include "llcorehttputil.h"
 
 extern F32 gMinObjectDistance;
 extern BOOL gAnimateTextures;
@@ -795,190 +796,6 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
 	LLVOAvatar::cullAvatarsByPixelArea();
 }
 
-class LLObjectCostResponder : public LLCurl::Responder
-{
-	LOG_CLASS(LLObjectCostResponder);
-public:
-	LLObjectCostResponder(const LLSD& object_ids)
-		: mObjectIDs(object_ids)
-	{
-	}
-
-	// Clear's the global object list's pending
-	// request list for all objects requested
-	void clear_object_list_pending_requests()
-	{
-		// TODO*: No more hard coding
-		for (
-			LLSD::array_iterator iter = mObjectIDs.beginArray();
-			iter != mObjectIDs.endArray();
-			++iter)
-		{
-			gObjectList.onObjectCostFetchFailure(iter->asUUID());
-		}
-	}
-
-private:
-	/* virtual */ void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-
-		// TODO*: Error message to user
-		// For now just clear the request from the pending list
-		clear_object_list_pending_requests();
-	}
-
-	/* virtual */ void httpSuccess()
-	{
-		const LLSD& content = getContent();
-		if ( !content.isMap() || content.has("error") )
-		{
-			// Improper response or the request had an error,
-			// show an error to the user?
-			LL_WARNS()
-				<< "Application level error when fetching object "
-				<< "cost.  Message: " << content["error"]["message"].asString()
-				<< ", identifier: " << content["error"]["identifier"].asString()
-				<< LL_ENDL;
-
-			// TODO*: Adaptively adjust request size if the
-			// service says we've requested too many and retry
-
-			// TODO*: Error message if not retrying
-			clear_object_list_pending_requests();
-			return;
-		}
-
-		// Success, grab the resource cost and linked set costs
-		// for an object if one was returned
-		for (
-			LLSD::array_iterator iter = mObjectIDs.beginArray();
-			iter != mObjectIDs.endArray();
-			++iter)
-		{
-			LLUUID object_id = iter->asUUID();
-
-			// Check to see if the request contains data for the object
-			if ( content.has(iter->asString()) )
-			{
-				F32 link_cost =
-					content[iter->asString()]["linked_set_resource_cost"].asReal();
-				F32 object_cost =
-					content[iter->asString()]["resource_cost"].asReal();
-
-				F32 physics_cost = content[iter->asString()]["physics_cost"].asReal();
-				F32 link_physics_cost = content[iter->asString()]["linked_set_physics_cost"].asReal();
-
-				gObjectList.updateObjectCost(object_id, object_cost, link_cost, physics_cost, link_physics_cost);
-			}
-			else
-			{
-				// TODO*: Give user feedback about the missing data?
-				gObjectList.onObjectCostFetchFailure(object_id);
-			}
-		}
-	}
-
-private:
-	LLSD mObjectIDs;
-};
-
-
-class LLPhysicsFlagsResponder : public LLCurl::Responder
-{
-	LOG_CLASS(LLPhysicsFlagsResponder);
-public:
-	LLPhysicsFlagsResponder(const LLSD& object_ids)
-		: mObjectIDs(object_ids)
-	{
-	}
-
-	// Clear's the global object list's pending
-	// request list for all objects requested
-	void clear_object_list_pending_requests()
-	{
-		// TODO*: No more hard coding
-		for (
-			LLSD::array_iterator iter = mObjectIDs.beginArray();
-			iter != mObjectIDs.endArray();
-			++iter)
-		{
-			gObjectList.onPhysicsFlagsFetchFailure(iter->asUUID());
-		}
-	}
-
-private:
-	/* virtual */ void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-
-		// TODO*: Error message to user
-		// For now just clear the request from the pending list
-		clear_object_list_pending_requests();
-	}
-
-	/* virtual void */ void httpSuccess()
-	{
-		const LLSD& content = getContent();
-		if ( !content.isMap() || content.has("error") )
-		{
-			// Improper response or the request had an error,
-			// show an error to the user?
-			LL_WARNS()
-				<< "Application level error when fetching object "
-				<< "physics flags.  Message: " << content["error"]["message"].asString()
-				<< ", identifier: " << content["error"]["identifier"].asString()
-				<< LL_ENDL;
-
-			// TODO*: Adaptively adjust request size if the
-			// service says we've requested too many and retry
-
-			// TODO*: Error message if not retrying
-			clear_object_list_pending_requests();
-			return;
-		}
-
-		// Success, grab the resource cost and linked set costs
-		// for an object if one was returned
-		for (
-			LLSD::array_iterator iter = mObjectIDs.beginArray();
-			iter != mObjectIDs.endArray();
-			++iter)
-		{
-			LLUUID object_id = iter->asUUID();
-
-			// Check to see if the request contains data for the object
-			if ( content.has(iter->asString()) )
-			{
-				const LLSD& data = content[iter->asString()];
-
-				S32 shape_type = data["PhysicsShapeType"].asInteger();
-
-				gObjectList.updatePhysicsShapeType(object_id, shape_type);
-
-				if (data.has("Density"))
-				{
-					F32 density = data["Density"].asReal();
-					F32 friction = data["Friction"].asReal();
-					F32 restitution = data["Restitution"].asReal();
-					F32 gravity_multiplier = data["GravityMultiplier"].asReal();
-					
-					gObjectList.updatePhysicsProperties(object_id, 
-						density, friction, restitution, gravity_multiplier);
-				}
-			}
-			else
-			{
-				// TODO*: Give user feedback about the missing data?
-				gObjectList.onPhysicsFlagsFetchFailure(object_id);
-			}
-		}
-	}
-
-private:
-	LLSD mObjectIDs;
-};
-
 static LLTrace::BlockTimerStatHandle FTM_IDLE_COPY("Idle Copy");
 
 void LLViewerObjectList::update(LLAgent &agent)
@@ -1174,41 +991,8 @@ void LLViewerObjectList::fetchObjectCosts()
 
 			if (!url.empty())
 			{
-				LLSD id_list;
-				U32 object_index = 0;
-
-				for (
-					std::set<LLUUID>::iterator iter = mStaleObjectCost.begin();
-					iter != mStaleObjectCost.end();
-					)
-				{
-					// Check to see if a request for this object
-					// has already been made.
-					if ( mPendingObjectCost.find(*iter) ==
-						 mPendingObjectCost.end() )
-					{
-						mPendingObjectCost.insert(*iter);
-						id_list[object_index++] = *iter;
-					}
-
-					mStaleObjectCost.erase(iter++);
-
-					if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS)
-					{
-						break;
-					}
-				}
-									
-				if ( id_list.size() > 0 )
-				{
-					LLSD post_data = LLSD::emptyMap();
-
-					post_data["object_ids"] = id_list;
-					LLHTTPClient::post(
-						url,
-						post_data,
-						new LLObjectCostResponder(id_list));
-				}
+                LLCoros::instance().launch("LLViewerObjectList::fetchObjectCostsCoro",
+                    boost::bind(&LLViewerObjectList::fetchObjectCostsCoro, this, url));
 			}
 			else
 			{
@@ -1219,6 +1003,111 @@ void LLViewerObjectList::fetchObjectCosts()
 	}
 }
 
+/*static*/
+void LLViewerObjectList::reportObjectCostFailure(LLSD &objectList)
+{
+    // TODO*: No more hard coding
+    for (LLSD::array_iterator it = objectList.beginArray(); it != objectList.endArray(); ++it)
+    {
+        gObjectList.onObjectCostFetchFailure(it->asUUID());
+    }
+}
+
+
+void LLViewerObjectList::fetchObjectCostsCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD idList;
+    U32 objectIndex = 0;
+
+    for (std::set<LLUUID>::iterator it = mStaleObjectCost.begin(); it != mStaleObjectCost.end(); )
+    {
+        // Check to see if a request for this object
+        // has already been made.
+        if (mPendingObjectCost.find(*it) == mPendingObjectCost.end())
+        {
+            mPendingObjectCost.insert(*it);
+            idList[objectIndex++] = *it;
+        }
+
+        mStaleObjectCost.erase(it++);
+
+        if (objectIndex >= MAX_CONCURRENT_PHYSICS_REQUESTS)
+        {
+            break;
+        }
+    }
+
+    if (idList.size() < 1)
+    {
+        LL_INFOS() << "No outstanding object IDs to request." << LL_ENDL;
+        return;
+    }
+     
+    LLSD postData = LLSD::emptyMap();
+
+    postData["object_ids"] = idList;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status || result.has("error"))
+    {
+        if (result.has("error"))
+        {
+            LL_WARNS() << "Application level error when fetching object "
+                << "cost.  Message: " << result["error"]["message"].asString()
+                << ", identifier: " << result["error"]["identifier"].asString()
+                << LL_ENDL;
+
+            // TODO*: Adaptively adjust request size if the
+            // service says we've requested too many and retry
+        }
+        reportObjectCostFailure(idList);
+
+        return;
+    }
+
+    // Success, grab the resource cost and linked set costs
+    // for an object if one was returned
+    for (LLSD::array_iterator it = idList.beginArray(); it != idList.endArray(); ++it)
+    {
+        LLUUID objectId = it->asUUID();
+
+        // Check to see if the request contains data for the object
+        if (result.has(it->asString()))
+        {
+            const LLSD& data = result[it->asString()];
+
+            S32 shapeType = data["PhysicsShapeType"].asInteger();
+
+            gObjectList.updatePhysicsShapeType(objectId, shapeType);
+
+            if (data.has("Density"))
+            {
+                F32 density = data["Density"].asReal();
+                F32 friction = data["Friction"].asReal();
+                F32 restitution = data["Restitution"].asReal();
+                F32 gravityMult = data["GravityMultiplier"].asReal();
+
+                gObjectList.updatePhysicsProperties(objectId, density, friction, restitution, gravityMult);
+            }
+        }
+        else
+        {
+            // TODO*: Give user feedback about the missing data?
+            gObjectList.onPhysicsFlagsFetchFailure(objectId);
+        }
+    }
+
+}
+
 void LLViewerObjectList::fetchPhysicsFlags()
 {
 	// issue http request for stale object physics flags
@@ -1232,41 +1121,8 @@ void LLViewerObjectList::fetchPhysicsFlags()
 
 			if (!url.empty())
 			{
-				LLSD id_list;
-				U32 object_index = 0;
-
-				for (
-					std::set<LLUUID>::iterator iter = mStalePhysicsFlags.begin();
-					iter != mStalePhysicsFlags.end();
-					)
-				{
-					// Check to see if a request for this object
-					// has already been made.
-					if ( mPendingPhysicsFlags.find(*iter) ==
-						 mPendingPhysicsFlags.end() )
-					{
-						mPendingPhysicsFlags.insert(*iter);
-						id_list[object_index++] = *iter;
-					}
-
-					mStalePhysicsFlags.erase(iter++);
-					
-					if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS)
-					{
-						break;
-					}
-				}
-
-				if ( id_list.size() > 0 )
-				{
-					LLSD post_data = LLSD::emptyMap();
-
-					post_data["object_ids"] = id_list;
-					LLHTTPClient::post(
-						url,
-						post_data,
-						new LLPhysicsFlagsResponder(id_list));
-				}
+                LLCoros::instance().launch("LLViewerObjectList::fetchPhisicsFlagsCoro",
+                    boost::bind(&LLViewerObjectList::fetchPhisicsFlagsCoro, this, url));
 			}
 			else
 			{
@@ -1277,6 +1133,109 @@ void LLViewerObjectList::fetchPhysicsFlags()
 	}
 }
 
+/*static*/
+void LLViewerObjectList::reportPhysicsFlagFailure(LLSD &objectList)
+{
+    // TODO*: No more hard coding
+    for (LLSD::array_iterator it = objectList.beginArray(); it != objectList.endArray(); ++it)
+    {
+        gObjectList.onPhysicsFlagsFetchFailure(it->asUUID());
+    }
+}
+
+void LLViewerObjectList::fetchPhisicsFlagsCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD idList;
+    U32 objectIndex = 0;
+
+    for (std::set<LLUUID>::iterator it = mStalePhysicsFlags.begin(); it != mStalePhysicsFlags.end(); )
+    {
+        // Check to see if a request for this object
+        // has already been made.
+        if (mPendingPhysicsFlags.find(*it) == mPendingPhysicsFlags.end())
+        {
+            mPendingPhysicsFlags.insert(*it);
+            idList[objectIndex++] = *it;
+        }
+
+        mStalePhysicsFlags.erase(it++);
+
+        if (objectIndex >= MAX_CONCURRENT_PHYSICS_REQUESTS)
+        {
+            break;
+        }
+    }
+
+    if (idList.size() < 1)
+    {
+        LL_INFOS() << "No outstanding object physics flags to request." << LL_ENDL;
+        return;
+    }
+
+    LLSD postData = LLSD::emptyMap();
+
+    postData["object_ids"] = idList;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status || result.has("error"))
+    {
+        if (result.has("error"))
+        {
+            LL_WARNS() << "Application level error when fetching object "
+                << "physics flags.  Message: " << result["error"]["message"].asString()
+                << ", identifier: " << result["error"]["identifier"].asString()
+                << LL_ENDL;
+
+            // TODO*: Adaptively adjust request size if the
+            // service says we've requested too many and retry
+        }
+        reportPhysicsFlagFailure(idList);
+
+        return;
+    }
+
+    // Success, grab the resource cost and linked set costs
+    // for an object if one was returned
+    for (LLSD::array_iterator it = idList.beginArray(); it != idList.endArray(); ++it)
+    {
+        LLUUID objectId = it->asUUID();
+
+        // Check to see if the request contains data for the object
+        if (result.has(it->asString()))
+        {
+            const LLSD& data = result[it->asString()];
+
+            S32 shapeType = data["PhysicsShapeType"].asInteger();
+
+            gObjectList.updatePhysicsShapeType(objectId, shapeType);
+
+            if (data.has("Density"))
+            {
+                F32 density = data["Density"].asReal();
+                F32 friction = data["Friction"].asReal();
+                F32 restitution = data["Restitution"].asReal();
+                F32 gravityMult = data["GravityMultiplier"].asReal();
+
+                gObjectList.updatePhysicsProperties(objectId, density, 
+                    friction, restitution, gravityMult);
+            }
+        }
+        else
+        {
+            // TODO*: Give user feedback about the missing data?
+            gObjectList.onPhysicsFlagsFetchFailure(objectId);
+        }
+    }
+}
 
 void LLViewerObjectList::clearDebugText()
 {
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 594317cd9ff2b83829895470fe4b6789b0565b16..9ec7c4bc22e4199f0289824c166665d2c1d96d31 100755
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -36,6 +36,8 @@
 
 // project includes
 #include "llviewerobject.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 class LLCamera;
 class LLNetMap;
@@ -227,6 +229,14 @@ class LLViewerObjectList
 	std::set<LLViewerObject *> mSelectPickList;
 
 	friend class LLViewerObject;
+
+private:
+    static void reportObjectCostFailure(LLSD &objectList);
+    void fetchObjectCostsCoro(std::string url);
+
+    static void reportPhysicsFlagFailure(LLSD &obejectList);
+    void fetchPhisicsFlagsCoro(std::string url);
+
 };
 
 
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 37b249dddd14c2cbdb8ac373b8be136981d3bcde..828271da7a9b4462ce20e2f5a758109107cb8b38 100755
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -43,6 +43,7 @@
 //#include "llfirstuse.h"
 #include "llpluginclassmedia.h"
 #include "llviewertexture.h"
+#include "llcorehttputil.h"
 
 // Static Variables
 
@@ -457,6 +458,7 @@ void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void *
 }
 // Static
 /////////////////////////////////////////////////////////////////////////////////////////
+// *TODO: I can not find any active code where this method is called...
 void LLViewerParcelMedia::sendMediaNavigateMessage(const std::string& url)
 {
 	std::string region_url = gAgent.getRegion()->getCapability("ParcelNavigateMedia");
@@ -467,7 +469,9 @@ void LLViewerParcelMedia::sendMediaNavigateMessage(const std::string& url)
 		body["agent-id"] = gAgent.getID();
 		body["local-id"] = LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID();
 		body["url"] = url;
-		LLHTTPClient::post(region_url, body, new LLHTTPClient::Responder);
+
+        LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(region_url, body,
+            "Media Navigation sent to sim.", "Media Navigation failed to send to sim.");
 	}
 	else
 	{
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 59f57c218ee993db4c5efe6ad6de9abb25c15865..0fa6c432db717f42e5916b3e30273870759da625 100755
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -67,6 +67,7 @@
 #include "roles_constants.h"
 #include "llweb.h"
 #include "llvieweraudio.h"
+#include "llcorehttputil.h"
 
 const F32 PARCEL_COLLISION_DRAW_SECS = 1.f;
 
@@ -1286,10 +1287,13 @@ const std::string& LLViewerParcelMgr::getAgentParcelName() const
 
 void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region)
 {
-	if(!parcel) return;
+	if(!parcel) 
+        return;
 
 	LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
-	if (!region) return;
+	if (!region) 
+        return;
+
 	//LL_INFOS() << "found region: " << region->getName() << LL_ENDL;
 
 	LLSD body;
@@ -1302,7 +1306,9 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag
 		parcel->packMessage(body);
 		LL_INFOS() << "Sending parcel properties update via capability to: "
 			<< url << LL_ENDL;
-		LLHTTPClient::post(url, body, new LLHTTPClient::Responder());
+
+        LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+            "Parcel Properties sent to sim.", "Parcel Properties failed to send to sim.");
 	}
 	else
 	{
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index ec28461201bdcc72f19f0787b1974b4b96c90feb..b256482289945ceab000b17c76edceea15c2db40 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -48,7 +48,6 @@
 #include "llavatarrenderinfoaccountant.h"
 #include "llcallingcard.h"
 #include "llcaphttpsender.h"
-#include "llcapabilitylistener.h"
 #include "llcommandhandler.h"
 #include "lldir.h"
 #include "lleventpoll.h"
@@ -78,6 +77,9 @@
 #include "llviewerdisplay.h"
 #include "llviewerwindow.h"
 #include "llprogressview.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llcorehttputil.h"
 
 #ifdef LL_WINDOWS
 	#pragma warning(disable:4355)
@@ -92,7 +94,6 @@
 // We want to allow for seed cap retry, but its not useful after that 60 seconds.
 // Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up.
 const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;
-const F32 CAP_REQUEST_TIMEOUT = 18;
 // Even though we gave up on login, keep trying for caps after we are logged in:
 const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
 const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
@@ -105,31 +106,62 @@ typedef std::map<std::string, std::string> CapabilityMap;
 
 static void log_capabilities(const CapabilityMap &capmap);
 
-class LLViewerRegionImpl {
+// support for secondlife:///app/region/{REGION} SLapps
+// N.B. this is defined to work exactly like the classic secondlife://{REGION}
+// However, the later syntax cannot support spaces in the region name because
+// spaces (and %20 chars) are illegal in the hostname of an http URL. Some
+// browsers let you get away with this, but some do not (such as Qt's Webkit).
+// Hence we introduced the newer secondlife:///app/region alternative.
+class LLRegionHandler : public LLCommandHandler
+{
+public:
+    // requests will be throttled from a non-trusted browser
+    LLRegionHandler() : LLCommandHandler("region", UNTRUSTED_THROTTLE) {}
+       
+    bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+    {
+        // make sure that we at least have a region name
+        int num_params = params.size();
+        if (num_params < 1)
+        {
+            return false;
+        }
+           
+        // build a secondlife://{PLACE} SLurl from this SLapp
+        std::string url = "secondlife://";
+        for (int i = 0; i < num_params; i++)
+        {
+            if (i > 0)
+            {
+                url += "/";
+            }
+            url += params[i].asString();
+        }
+           
+        // Process the SLapp as if it was a secondlife://{PLACE} SLurl
+        LLURLDispatcher::dispatch(url, "clicked", web, true);
+        return true;
+    }
+       
+};
+LLRegionHandler gRegionHandler;
+
+
+class LLViewerRegionImpl 
+{
 public:
-	LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host)
-		:	mHost(host),
-			mCompositionp(NULL),
-			mEventPoll(NULL),
-			mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
-			mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
-			mSeedCapAttempts(0),
-			mHttpResponderID(0),
-		mLastCameraUpdate(0),
-		mLastCameraOrigin(),
-		mVOCachePartition(NULL),
-		mLandp(NULL),
-		    // I'd prefer to set the LLCapabilityListener name to match the region
-		    // name -- it's disappointing that's not available at construction time.
-		    // We could instead store an LLCapabilityListener*, making
-		    // setRegionNameAndZone() replace the instance. Would that pose
-		    // consistency problems? Can we even request a capability before calling
-		    // setRegionNameAndZone()?
-		    // For testability -- the new Michael Feathers paradigm --
-		    // LLCapabilityListener binds all the globals it expects to need at
-		    // construction time.
-		    mCapabilityListener(host.getString(), gMessageSystem, *region,
-		                        gAgent.getID(), gAgent.getSessionID())
+	LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host):   
+        mHost(host),
+        mCompositionp(NULL),
+        mEventPoll(NULL),
+        mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
+        mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
+        mSeedCapAttempts(0),
+        mHttpResponderID(0),
+        mLastCameraUpdate(0),
+        mLastCameraOrigin(),
+        mVOCachePartition(NULL),
+        mLandp(NULL)
 	{}
 
 	void buildCapabilityNames(LLSD& capabilityNames);
@@ -181,220 +213,284 @@ class LLViewerRegionImpl {
 
 	S32 mHttpResponderID;
 
-	/// Post an event to this LLCapabilityListener to invoke a capability message on
-	/// this LLViewerRegion's server
-	/// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
-	LLCapabilityListener mCapabilityListener;
-
 	//spatial partitions for objects in this region
 	std::vector<LLViewerOctreePartition*> mObjectPartition;
 
-	LLVector3 mLastCameraOrigin;
-	U32       mLastCameraUpdate;
-};
-
-// support for secondlife:///app/region/{REGION} SLapps
-// N.B. this is defined to work exactly like the classic secondlife://{REGION}
-// However, the later syntax cannot support spaces in the region name because
-// spaces (and %20 chars) are illegal in the hostname of an http URL. Some
-// browsers let you get away with this, but some do not (such as Qt's Webkit).
-// Hence we introduced the newer secondlife:///app/region alternative.
-class LLRegionHandler : public LLCommandHandler
-{
-public:
-	// requests will be throttled from a non-trusted browser
-	LLRegionHandler() : LLCommandHandler("region", UNTRUSTED_THROTTLE) {}
-
-	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
-	{
-		// make sure that we at least have a region name
-		int num_params = params.size();
-		if (num_params < 1)
-		{
-			return false;
-		}
-
-		// build a secondlife://{PLACE} SLurl from this SLapp
-		std::string url = "secondlife://";
-		for (int i = 0; i < num_params; i++)
-		{
-			if (i > 0)
-			{
-				url += "/";
-			}
-			url += params[i].asString();
-		}
+	LLVector3   mLastCameraOrigin;
+	U32         mLastCameraUpdate;
 
-		// Process the SLapp as if it was a secondlife://{PLACE} SLurl
-		LLURLDispatcher::dispatch(url, "clicked", web, true);
-		return true;
-	}
+    void        requestBaseCapabilitiesCoro(U64 regionHandle);
+    void        requestBaseCapabilitiesCompleteCoro(U64 regionHandle);
+    void        requestSimulatorFeatureCoro(std::string url, U64 regionHandle);
 };
-LLRegionHandler gRegionHandler;
 
-class BaseCapabilitiesComplete : public LLHTTPClient::Responder
+void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
 {
-	LOG_CLASS(BaseCapabilitiesComplete);
-public:
-	BaseCapabilitiesComplete(U64 region_handle, S32 id)
-		: mRegionHandle(region_handle), mID(id)
-	{ }
-	virtual ~BaseCapabilitiesComplete()
-	{ }
-
-	static BaseCapabilitiesComplete* build( U64 region_handle, S32 id )
-	{
-		return new BaseCapabilitiesComplete(region_handle, id);
-	}
-
-private:
-	/* virtual */void httpFailure()
-	{
-		LL_WARNS("AppInit", "Capabilities") << dumpResponse() << LL_ENDL;
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if (regionp)
-		{
-			regionp->failedSeedCapability();
-		}
-	}
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t 
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
 
-	/* virtual */ void httpSuccess()
-	{
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if(!regionp) //region was removed
-		{
-			LL_WARNS("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
-			return ;
-		}
-		if( mID != regionp->getHttpResponderID() ) // region is no longer referring to this responder
-		{
-			LL_WARNS("AppInit", "Capabilities") << "Received results for a stale http responder!" << LL_ENDL;
-			regionp->failedSeedCapability();
-			return ;
-		}
-
-		const LLSD& content = getContent();
-		if (!content.isMap())
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		LLSD::map_const_iterator iter;
-		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
-		{
-			regionp->setCapability(iter->first, iter->second);
+    LLSD result;
+    LLViewerRegion *regionp = NULL;
 
-			LL_DEBUGS("AppInit", "Capabilities")
-				<< "Capability '" << iter->first << "' is '" << iter->second << "'" << LL_ENDL;
-
-			/* HACK we're waiting for the ServerReleaseNotes */
-			if (iter->first == "ServerReleaseNotes" && regionp->getReleaseNotesRequested())
-			{
-				regionp->showReleaseNotes();
-			}
-		}
-
-		regionp->setCapabilitiesReceived(true);
+    // This loop is used for retrying a capabilities request.
+    do
+    {
+        regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+        if (!regionp) //region was removed
+        {
+            LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
+            return; // this error condition is not recoverable.
+        }
+
+        std::string url = regionp->getCapability("Seed");
+        if (url.empty())
+        {
+            LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+            return; // this error condition is not recoverable.
+        }
+
+        // After a few attempts, continue login.  But keep trying to get the caps:
+        if (mSeedCapAttempts >= mSeedCapMaxAttemptsBeforeLogin &&
+            STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
+        {
+            LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+        }
+
+        if (mSeedCapAttempts > mSeedCapMaxAttempts)
+        {
+            // *TODO: Give a user pop-up about this error?
+            LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities from '" << url << "' after " << mSeedCapAttempts << " attempts.  Giving up!" << LL_ENDL;
+            return;  // this error condition is not recoverable.
+        }
+
+        S32 id = ++mHttpResponderID;
+        ++mSeedCapAttempts;
+
+        LLSD capabilityNames = LLSD::emptyArray();
+        buildCapabilityNames(capabilityNames);
+
+        LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url 
+            << " (attempt #" << mSeedCapAttempts << ")" << LL_ENDL;
+
+        regionp = NULL;
+        result = httpAdapter->postAndYield(httpRequest, url, capabilityNames);
+
+        regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+        if (!regionp) //region was removed
+        {
+            LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
+            return; // this error condition is not recoverable.
+        }
+
+        if (id != mHttpResponderID) // region is no longer referring to this request
+        {
+            LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
+            // setup for retry.
+            continue;
+        }
+
+        LLSD httpResults = result["http_result"];
+        LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+        if (!status)
+        {
+            LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL;
+            // setup for retry.
+            continue;
+        }
+
+        // remove the http_result from the llsd
+        result.erase("http_result");
+
+        LLSD::map_const_iterator iter;
+        for (iter = result.beginMap(); iter != result.endMap(); ++iter)
+        {
+            regionp->setCapability(iter->first, iter->second);
+
+            LL_DEBUGS("AppInit", "Capabilities")
+                << "Capability '" << iter->first << "' is '" << iter->second << "'" << LL_ENDL;
+        }
+
+        regionp->setCapabilitiesReceived(true);
+
+        if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
+        {
+            LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+        }
+
+        break;
+    } 
+    while (true);
+
+    if (regionp && regionp->isCapabilityAvailable("ServerReleaseNotes") &&
+            regionp->getReleaseNotesRequested())
+    {   // *HACK: we're waiting for the ServerReleaseNotes
+        regionp->showReleaseNotes();
+    }
 
-		if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
-		{
-			LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
-		}
-	}
+}
 
-private:
-	U64 mRegionHandle;
-	S32 mID;
-};
 
-class BaseCapabilitiesCompleteTracker :  public LLHTTPClient::Responder
+void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
 {
-	LOG_CLASS(BaseCapabilitiesCompleteTracker);
-public:
-	BaseCapabilitiesCompleteTracker( U64 region_handle)
-	: mRegionHandle(region_handle)
-	{ }
-	
-	virtual ~BaseCapabilitiesCompleteTracker()
-	{ }
-
-	static BaseCapabilitiesCompleteTracker* build( U64 region_handle )
-	{
-		return new BaseCapabilitiesCompleteTracker( region_handle );
-	}
-
-private:
-	/* virtual */ void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-	}
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
 
-	/* virtual */ void httpSuccess()
-	{
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if( !regionp ) 
-		{
-			LL_WARNS("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
-			return ;
-		}
+    LLSD result;
+    LLViewerRegion *regionp = NULL;
 
-		const LLSD& content = getContent();
-		if (!content.isMap())
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		LLSD::map_const_iterator iter;
-		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
-		{
-			regionp->setCapabilityDebug(iter->first, iter->second);	
-			//LL_INFOS()<<"BaseCapabilitiesCompleteTracker New Caps "<<iter->first<<" "<< iter->second<<LL_ENDL;
-		}
-		
-		if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() )
-		{
-			LL_WARNS("AppInit", "Capabilities") 
-				<< "Sim sent duplicate base caps that differ in size from what we initially received - most likely content. "
-				<< "mCapabilities == " << regionp->getRegionImpl()->mCapabilities.size()
-				<< " mSecondCapabilitiesTracker == " << regionp->getRegionImpl()->mSecondCapabilitiesTracker.size()
-				<< LL_ENDL;
+    // This loop is used for retrying a capabilities request.
+    do
+    {
+        regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+        if (!regionp) //region was removed
+        {
+            LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
+            break; // this error condition is not recoverable.
+        }
+
+        std::string url = regionp->getCapabilityDebug("Seed");
+        if (url.empty())
+        {
+            LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+            break; // this error condition is not recoverable.
+        }
+
+        LLSD capabilityNames = LLSD::emptyArray();
+        buildCapabilityNames(capabilityNames);
+
+        LL_INFOS("AppInit", "Capabilities") << "Requesting second Seed from " << url << LL_ENDL;
+
+        regionp = NULL;
+        result = httpAdapter->postAndYield(httpRequest, url, capabilityNames);
+
+        LLSD httpResults = result["http_result"];
+        LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+        if (!status)
+        {
+            LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL;
+            break;  // no retry
+        }
+
+        regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+        if (!regionp) //region was removed
+        {
+            LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
+            break; // this error condition is not recoverable.
+        }
+
+        // remove the http_result from the llsd
+        result.erase("http_result");
+
+        LLSD::map_const_iterator iter;
+        for (iter = result.beginMap(); iter != result.endMap(); ++iter)
+        {
+            regionp->setCapabilityDebug(iter->first, iter->second);
+            //LL_INFOS()<<"BaseCapabilitiesCompleteTracker New Caps "<<iter->first<<" "<< iter->second<<LL_ENDL;
+        }
+
+        if (mCapabilities.size() != mSecondCapabilitiesTracker.size())
+        {
+            LL_WARNS("AppInit", "Capabilities")
+                << "Sim sent duplicate base caps that differ in size from what we initially received - most likely content. "
+                << "mCapabilities == " << mCapabilities.size()
+                << " mSecondCapabilitiesTracker == " << mSecondCapabilitiesTracker.size()
+                << LL_ENDL;
 #ifdef DEBUG_CAPS_GRANTS
-			LL_WARNS("AppInit", "Capabilities")
-				<< "Initial Base capabilities: " << LL_ENDL;
+            LL_WARNS("AppInit", "Capabilities")
+                << "Initial Base capabilities: " << LL_ENDL;
 
-			log_capabilities(regionp->getRegionImpl()->mCapabilities);
+            log_capabilities(mCapabilities);
 
-			LL_WARNS("AppInit", "Capabilities")
-							<< "Latest base capabilities: " << LL_ENDL;
+            LL_WARNS("AppInit", "Capabilities")
+                << "Latest base capabilities: " << LL_ENDL;
 
-			log_capabilities(regionp->getRegionImpl()->mSecondCapabilitiesTracker);
+            log_capabilities(mSecondCapabilitiesTracker);
 
 #endif
 
-			if (regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() > regionp->getRegionImpl()->mCapabilities.size() )
-			{
-				// *HACK Since we were granted more base capabilities in this grant request than the initial, replace
-				// the old with the new. This shouldn't happen i.e. we should always get the same capabilities from a
-				// sim. The simulator fix from SH-3895 should prevent it from happening, at least in the case of the
-				// inventory api capability grants.
-
-				// Need to clear a std::map before copying into it because old keys take precedence.
-				regionp->getRegionImplNC()->mCapabilities.clear();
-				regionp->getRegionImplNC()->mCapabilities = regionp->getRegionImpl()->mSecondCapabilitiesTracker;
-			}
-		}
-		else
-		{
-			LL_DEBUGS("CrossingCaps") << "Sim sent multiple base cap grants with matching sizes." << LL_ENDL;
-		}
-		regionp->getRegionImplNC()->mSecondCapabilitiesTracker.clear();
-	}
+            if (mSecondCapabilitiesTracker.size() > mCapabilities.size())
+            {
+                // *HACK Since we were granted more base capabilities in this grant request than the initial, replace
+                // the old with the new. This shouldn't happen i.e. we should always get the same capabilities from a
+                // sim. The simulator fix from SH-3895 should prevent it from happening, at least in the case of the
+                // inventory api capability grants.
 
+                // Need to clear a std::map before copying into it because old keys take precedence.
+                mCapabilities.clear();
+                mCapabilities = mSecondCapabilitiesTracker;
+            }
+        }
+        else
+        {
+            LL_DEBUGS("CrossingCaps") << "Sim sent multiple base cap grants with matching sizes." << LL_ENDL;
+        }
+        mSecondCapabilitiesTracker.clear();
+    } 
+    while (false);
 
-private:
-	U64 mRegionHandle;
-};
 
+}
+
+void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 regionHandle)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLViewerRegion *regionp = NULL;
+    S32 attemptNumber = 0;
+    // This loop is used for retrying a capabilities request.
+    do
+    {
+        ++attemptNumber;
+
+        if (attemptNumber > MAX_CAP_REQUEST_ATTEMPTS)
+        {
+            LL_WARNS("AppInit", "SimulatorFeatures") << "Retries count exceeded attempting to get Simulator feature from " 
+                << url << LL_ENDL;
+            break;
+        }
+
+        regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+        if (!regionp) //region was removed
+        {
+            LL_WARNS("AppInit", "SimulatorFeatures") << "Attempting to request Sim Feature for region that no longer exists!" << LL_ENDL;
+            break; // this error condition is not recoverable.
+        }
+
+        regionp = NULL;
+        LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+        LLSD httpResults = result["http_result"];
+        LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+        if (!status)
+        {
+            LL_WARNS("AppInit", "SimulatorFeatures") << "HttpStatus error retrying" << LL_ENDL;
+            continue;  
+        }
+
+        // remove the http_result from the llsd
+        result.erase("http_result");
+
+        regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+        if (!regionp) //region was removed
+        {
+            LL_WARNS("AppInit", "SimulatorFeatures") << "Attempting to set Sim Feature for region that no longer exists!" << LL_ENDL;
+            break; // this error condition is not recoverable.
+        }
+
+        regionp->setSimulatorFeatures(result);
+
+        break;
+    }
+    while (true);
+
+}
 
 LLViewerRegion::LLViewerRegion(const U64 &handle,
 							   const LLHost &host,
@@ -525,11 +621,6 @@ LLViewerRegion::~LLViewerRegion()
 	mImpl = NULL;
 }
 
-LLEventPump& LLViewerRegion::getCapAPI() const
-{
-	return mImpl->mCapabilityListener.getCapAPI();
-}
-
 /*virtual*/ 
 const LLHost&	LLViewerRegion::getHost() const				
 { 
@@ -2810,15 +2901,14 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	if (getCapability("Seed") == url)
     {	
 		setCapabilityDebug("Seed", url);
-		LL_DEBUGS("CrossingCaps") <<  "Received duplicate seed capability, posting to seed " <<
+		LL_WARNS("CrossingCaps") <<  "Received duplicate seed capability, posting to seed " <<
 				url	<< LL_ENDL;
 
 		//Instead of just returning we build up a second set of seed caps and compare them 
 		//to the "original" seed cap received and determine why there is problem!
-		LLSD capabilityNames = LLSD::emptyArray();
-		mImpl->buildCapabilityNames( capabilityNames );
-		LLHTTPClient::post( url, capabilityNames, BaseCapabilitiesCompleteTracker::build(getHandle() ),
-							LLSD(), CAP_REQUEST_TIMEOUT );
+        std::string coroname =
+            LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro",
+            boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, mImpl, getHandle()));
 		return;
     }
 	
@@ -2828,15 +2918,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	mImpl->mCapabilities.clear();
 	setCapability("Seed", url);
 
-	LLSD capabilityNames = LLSD::emptyArray();
-	mImpl->buildCapabilityNames(capabilityNames);
-
-	LL_INFOS() << "posting to seed " << url << LL_ENDL;
+    std::string coroname =
+        LLCoros::instance().launch("LLEnvironmentRequest::environmentRequestCoro",
+        boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, mImpl, getHandle()));
 
-	S32 id = ++mImpl->mHttpResponderID;
-	LLHTTPClient::post(url, capabilityNames, 
-						BaseCapabilitiesComplete::build(getHandle(), id),
-						LLSD(), CAP_REQUEST_TIMEOUT);
+    LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << LL_ENDL;
 }
 
 S32 LLViewerRegion::getNumSeedCapRetries()
@@ -2844,94 +2930,6 @@ S32 LLViewerRegion::getNumSeedCapRetries()
 	return mImpl->mSeedCapAttempts;
 }
 
-void LLViewerRegion::failedSeedCapability()
-{
-	// Should we retry asking for caps?
-	mImpl->mSeedCapAttempts++;
-	std::string url = getCapability("Seed");
-	if ( url.empty() )
-	{
-		LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url for retries!" << LL_ENDL;
-		return;
-	}
-	// After a few attempts, continue login.  We will keep trying once in-world:
-	if ( mImpl->mSeedCapAttempts >= mImpl->mSeedCapMaxAttemptsBeforeLogin &&
-		 STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState() )
-	{
-		LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
-	}
-
-	if ( mImpl->mSeedCapAttempts < mImpl->mSeedCapMaxAttempts)
-	{
-		LLSD capabilityNames = LLSD::emptyArray();
-		mImpl->buildCapabilityNames(capabilityNames);
-
-		LL_INFOS() << "posting to seed " << url << " (retry " 
-				<< mImpl->mSeedCapAttempts << ")" << LL_ENDL;
-
-		S32 id = ++mImpl->mHttpResponderID;
-		LLHTTPClient::post(url, capabilityNames, 
-						BaseCapabilitiesComplete::build(getHandle(), id),
-						LLSD(), CAP_REQUEST_TIMEOUT);
-	}
-	else
-	{
-		// *TODO: Give a user pop-up about this error?
-		LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities from '" << url << "' after " << mImpl->mSeedCapAttempts << " attempts.  Giving up!" << LL_ENDL;
-	}
-}
-
-class SimulatorFeaturesReceived : public LLHTTPClient::Responder
-{
-	LOG_CLASS(SimulatorFeaturesReceived);
-public:
-	SimulatorFeaturesReceived(const std::string& retry_url, U64 region_handle, 
-							  S32 attempt = 0, S32 max_attempts = MAX_CAP_REQUEST_ATTEMPTS)
-		: mRetryURL(retry_url), mRegionHandle(region_handle), mAttempt(attempt), mMaxAttempts(max_attempts)
-	{ }
-
-	/* virtual */ void httpFailure()
-	{
-		LL_WARNS("AppInit", "SimulatorFeatures") << dumpResponse() << LL_ENDL;
-		retry();
-	}
-
-	/* virtual */ void httpSuccess()
-	{
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if(!regionp) //region is removed or responder is not created.
-		{
-			LL_WARNS("AppInit", "SimulatorFeatures") 
-				<< "Received results for region that no longer exists!" << LL_ENDL;
-			return ;
-		}
-
-		const LLSD& content = getContent();
-		if (!content.isMap())
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		regionp->setSimulatorFeatures(content);
-	}
-
-	void retry()
-	{
-		if (mAttempt < mMaxAttempts)
-		{
-			mAttempt++;
-			LL_WARNS("AppInit", "SimulatorFeatures") << "Re-trying '" << mRetryURL << "'.  Retry #" << mAttempt << LL_ENDL;
-			LLHTTPClient::get(mRetryURL, new SimulatorFeaturesReceived(*this), LLSD(), CAP_REQUEST_TIMEOUT);
-		}
-	}
-
-	std::string mRetryURL;
-	U64 mRegionHandle;
-	S32 mAttempt;
-	S32 mMaxAttempts;
-};
-
-
 void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
 {
 	if(name == "EventQueueGet")
@@ -2947,7 +2945,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
 	else if (name == "SimulatorFeatures")
 	{
 		// kick off a request for simulator features
-		LLHTTPClient::get(url, new SimulatorFeaturesReceived(url, getHandle()), LLSD(), CAP_REQUEST_TIMEOUT);
+        std::string coroname =
+            LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
+            boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, mImpl, url, getHandle()));
+
+        LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << LL_ENDL;
 	}
 	else
 	{
@@ -2970,9 +2972,20 @@ void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::stri
 			mHttpUrl = url ;
 		}
 	}
+}
 
+std::string LLViewerRegion::getCapabilityDebug(const std::string& name) const
+{
+    CapabilityMap::const_iterator iter = mImpl->mSecondCapabilitiesTracker.find(name);
+    if (iter == mImpl->mSecondCapabilitiesTracker.end())
+    {
+        return "";
+    }
+
+    return iter->second;
 }
 
+
 bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
 {
 	return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index c14fa5aee805c62bf9322237b428a49de8711a97..8c4966369c35e78bc570dea45272f02b36074496 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -40,7 +40,6 @@
 #include "llweb.h"
 #include "llcapabilityprovider.h"
 #include "m4math.h"					// LLMatrix4
-#include "llhttpclient.h"
 #include "llframetimer.h"
 
 // Surface id's
@@ -62,7 +61,6 @@ class LLVOCache;
 class LLVOCacheEntry;
 class LLSpatialPartition;
 class LLEventPump;
-class LLCapabilityListener;
 class LLDataPacker;
 class LLDataPackerBinaryBuffer;
 class LLHost;
@@ -253,13 +251,14 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 
 	// Get/set named capability URLs for this region.
 	void setSeedCapability(const std::string& url);
-	void failedSeedCapability();
 	S32 getNumSeedCapRetries();
 	void setCapability(const std::string& name, const std::string& url);
 	void setCapabilityDebug(const std::string& name, const std::string& url);
 	bool isCapabilityAvailable(const std::string& name) const;
 	// implements LLCapabilityProvider
     virtual std::string getCapability(const std::string& name) const;
+    std::string getCapabilityDebug(const std::string& name) const;
+
 
 	// has region received its final (not seed) capability list?
 	bool capabilitiesReceived() const;
@@ -269,10 +268,6 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	static bool isSpecialCapabilityName(const std::string &name);
 	void logActiveCapabilities() const;
 
-    /// Get LLEventPump on which we listen for capability requests
-    /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
-    LLEventPump& getCapAPI() const;
-
     /// implements LLCapabilityProvider
 	/*virtual*/ const LLHost& getHost() const;
 	const U64 		&getHandle() const 			{ return mHandle; }
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index f60829e9e8def1169f7e95c9b47219c7a9383ce5..2c3067cd3ac2bff604dcf3de13f5b43f7a8c10fc 100755
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -60,6 +60,7 @@
 #include "llfeaturemanager.h"
 #include "llviewernetwork.h"
 #include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
+#include "llcorehttputil.h"
 
 namespace LLStatViewer
 {
@@ -410,24 +411,6 @@ void update_statistics()
 	}
 }
 
-class ViewerStatsResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(ViewerStatsResponder);
-public:
-	ViewerStatsResponder() { }
-
-private:
-	/* virtual */ void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-	}
-
-	/* virtual */ void httpSuccess()
-	{
-		LL_INFOS() << "OK" << LL_ENDL;
-	}
-};
-
 /*
  * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats.
  *
@@ -618,8 +601,8 @@ void send_stats()
 	body["MinimalSkin"] = false;
 	
 	LLViewerStats::getInstance()->addToMessage(body);
-	LLHTTPClient::post(url, body, new ViewerStatsResponder());
-
+    LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+        "Statistics posted to sim", "Failed to post statistics to sim");
 	LLViewerStats::instance().getRecording().resume();
 }
 
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 56997c928ad9a20d11bc8e94112533e0b251b3c2..7c460ce097d330bbb24ecb74488825caff389774 100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -64,6 +64,7 @@
 #include "llsdutil.h"
 #include "llstartup.h"
 #include "llsdserialize.h"
+#include "llcorehttputil.h"
 
 #if LL_MSVC
 // disable boost::lexical_cast warning
@@ -105,6 +106,9 @@ void selfClearPhases()
 
 using namespace LLAvatarAppearanceDefines;
 
+
+LLSD summarize_by_buckets(std::vector<LLSD> in_records, std::vector<std::string> by_fields, std::string val_field);
+
 /*********************************************************************************
  **                                                                             **
  ** Begin private LLVOAvatarSelf Support classes
@@ -127,25 +131,6 @@ struct LocalTextureData
 	LLTextureEntry *mTexEntry;
 };
 
-// TODO - this class doesn't really do anything, could just use a base
-// class responder if nothing else gets added.
-class LLHoverHeightResponder: public LLHTTPClient::Responder
-{
-public:
-	LLHoverHeightResponder(): LLHTTPClient::Responder() {}
-
-private:
-	void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-	}
-
-	void httpSuccess()
-	{
-		LL_INFOS() << dumpResponse() << LL_ENDL;
-	}
-};
-
 //-----------------------------------------------------------------------------
 // Callback data
 //-----------------------------------------------------------------------------
@@ -180,7 +165,9 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
 	mRegionCrossingCount(0),
 	// Value outside legal range, so will always be a mismatch the
 	// first time through.
-	mLastHoverOffsetSent(LLVector3(0.0f, 0.0f, -999.0f))
+	mLastHoverOffsetSent(LLVector3(0.0f, 0.0f, -999.0f)),
+    mInitialMetric(true),
+    mMetricSequence(0)
 {
 	mMotionController.mIsSelf = TRUE;
 
@@ -2203,43 +2190,76 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
 	return text;
 }
 
-class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
-{
-	LOG_CLASS(ViewerAppearanceChangeMetricsResponder);
-public:
-	ViewerAppearanceChangeMetricsResponder( S32 expected_sequence,
-											volatile const S32 & live_sequence,
-											volatile bool & reporting_started):
-		mExpectedSequence(expected_sequence),
-		mLiveSequence(live_sequence),
-		mReportingStarted(reporting_started)
-	{
-	}
-
-private:
-	/* virtual */ void httpSuccess()
-	{
-		LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
-
-		gPendingMetricsUploads--;
-		if (mLiveSequence == mExpectedSequence)
-		{
-			mReportingStarted = true;
-		}
-	}
-
-	/* virtual */ void httpFailure()
-	{
-		// if we add retry, this should be removed from the httpFailure case
-		LL_WARNS("Avatar") << dumpResponse() << LL_ENDL;
-		gPendingMetricsUploads--;
-	}
-
-private:
-	S32 mExpectedSequence;
-	volatile const S32 & mLiveSequence;
-	volatile bool & mReportingStarted;
-};
+void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("appearanceChangeMetrics", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+    S32 currentSequence = mMetricSequence;
+    if (S32_MAX == ++mMetricSequence)
+        mMetricSequence = 0;
+
+    LLSD msg;
+    msg["message"] = "ViewerAppearanceChangeMetrics";
+    msg["session_id"] = gAgentSessionID;
+    msg["agent_id"] = gAgentID;
+    msg["sequence"] = currentSequence;
+    msg["initial"] = mInitialMetric;
+    msg["break"] = false;
+    msg["duration"] = mTimeSinceLastRezMessage.getElapsedTimeF32();
+
+    // Status of our own rezzing.
+    msg["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
+
+    // Status of all nearby avs including ourself.
+    msg["nearby"] = LLSD::emptyArray();
+    std::vector<S32> rez_counts;
+    LLVOAvatar::getNearbyRezzedStats(rez_counts);
+    for (S32 rez_stat = 0; rez_stat < rez_counts.size(); ++rez_stat)
+    {
+        std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
+        msg["nearby"][rez_status_name] = rez_counts[rez_stat];
+    }
+
+    //	std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
+    std::vector<std::string> by_fields;
+    by_fields.push_back("timer_name");
+    by_fields.push_back("completed");
+    by_fields.push_back("grid_x");
+    by_fields.push_back("grid_y");
+    by_fields.push_back("is_using_server_bakes");
+    by_fields.push_back("is_self");
+    by_fields.push_back("central_bake_version");
+    LLSD summary = summarize_by_buckets(mPendingTimerRecords, by_fields, std::string("elapsed"));
+    msg["timers"] = summary;
+
+    mPendingTimerRecords.clear();
+
+    LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL;
+
+    gPendingMetricsUploads++;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, msg);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    gPendingMetricsUploads--;
+
+    if (!status)
+    {
+        LL_WARNS("Avatar") << "Unable to upload statistics" << LL_ENDL;
+        return;
+    }
+    else
+    {
+        LL_INFOS("Avatar") << "Statistics upload OK" << LL_ENDL;
+        mInitialMetric = false;
+    }
+}
 
 bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send)
 {
@@ -2317,51 +2337,7 @@ LLSD summarize_by_buckets(std::vector<LLSD> in_records,
 
 void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()
 {
-	static volatile bool reporting_started(false);
-	static volatile S32 report_sequence(0);
-
-	LLSD msg;
-	msg["message"] = "ViewerAppearanceChangeMetrics";
-	msg["session_id"] = gAgentSessionID;
-	msg["agent_id"] = gAgentID;
-	msg["sequence"] = report_sequence;
-	msg["initial"] = !reporting_started;
-	msg["break"] = false;
-	msg["duration"] = mTimeSinceLastRezMessage.getElapsedTimeF32();
-
-	// Status of our own rezzing.
-	msg["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
-
-	// Status of all nearby avs including ourself.
-	msg["nearby"] = LLSD::emptyArray();
-	std::vector<S32> rez_counts;
-	LLVOAvatar::getNearbyRezzedStats(rez_counts);
-	for (S32 rez_stat=0; rez_stat < rez_counts.size(); ++rez_stat)
-	{
-		std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
-		msg["nearby"][rez_status_name] = rez_counts[rez_stat];
-	}
-
-	//	std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
-	std::vector<std::string> by_fields;
-	by_fields.push_back("timer_name");
-	by_fields.push_back("completed");
-	by_fields.push_back("grid_x");
-	by_fields.push_back("grid_y");
-	by_fields.push_back("is_using_server_bakes");
-	by_fields.push_back("is_self");
-	by_fields.push_back("central_bake_version");
-	LLSD summary = summarize_by_buckets(mPendingTimerRecords, by_fields, std::string("elapsed"));
-	msg["timers"] = summary;
-
-	mPendingTimerRecords.clear();
-
-	// Update sequence number
-	if (S32_MAX == ++report_sequence)
-		report_sequence = 0;
-
-	LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL;
-	std::string	caps_url;
+    std::string	caps_url;
 	if (getRegion())
 	{
 		// runway - change here to activate.
@@ -2369,13 +2345,9 @@ void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()
 	}
 	if (!caps_url.empty())
 	{
-		gPendingMetricsUploads++;
-		LLCurlRequest::headers_t headers;
-		LLHTTPClient::post(caps_url,
-						   msg,
-						   new ViewerAppearanceChangeMetricsResponder(report_sequence,
-																	  report_sequence,
-																	  reporting_started));
+
+        LLCoros::instance().launch("LLVOAvatarSelf::appearanceChangeMetricsCoro",
+            boost::bind(&LLVOAvatarSelf::appearanceChangeMetricsCoro, this, caps_url));
 		mTimeSinceLastRezMessage.reset();
 	}
 }
@@ -2798,8 +2770,12 @@ void LLVOAvatarSelf::sendHoverHeight() const
 		update["hover_height"] = hover_offset[2];
 
 		LL_DEBUGS("Avatar") << avString() << "sending hover height value " << hover_offset[2] << LL_ENDL;
-		LLHTTPClient::post(url, update, new LLHoverHeightResponder);
 
+        // *TODO: - this class doesn't really do anything, could just use a base
+        // class responder if nothing else gets added. 
+        // (comment from removed Responder)
+        LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, update, 
+            "Hover hight sent to sim", "Hover hight not sent to sim");
 		mLastHoverOffsetSent = hover_offset;
 	}
 }
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index dc5e64d547888135f001e156bc49eeb290b7ad92..d32c959fb50c5f1947c627687a4c838972667a0a 100755
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -31,6 +31,8 @@
 #include "llviewertexture.h"
 #include "llvoavatar.h"
 #include <map>
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 struct LocalTextureData;
 class LLInventoryCallback;
@@ -400,6 +402,9 @@ class LLVOAvatarSelf :
 	F32 					mDebugBakedTextureTimes[LLAvatarAppearanceDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture
 	void					debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
 
+    void                    appearanceChangeMetricsCoro(std::string url);
+    bool                    mInitialMetric;
+    S32                     mMetricSequence;
 /**                    Diagnostics
  **                                                                            **
  *******************************************************************************/
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 426ca332e42ddaa24001e388717e7570a7c8fd42..192d50ae9bede4a5c40a02869e6db60f5e3b6290 100755
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -28,7 +28,6 @@
 
 #include "llagent.h"
 #include "llfloaterreg.h"
-#include "llhttpclient.h"
 #include "llimview.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
@@ -37,7 +36,7 @@
 #include "llviewercontrol.h"
 #include "llviewerregion.h"
 #include "llvoicechannel.h"
-
+#include "llcorehttputil.h"
 
 LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap;
 LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap;
@@ -52,71 +51,6 @@ BOOL LLVoiceChannel::sSuspended = FALSE;
 //
 const U32 DEFAULT_RETRIES_COUNT = 3;
 
-
-class LLVoiceCallCapResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLVoiceCallCapResponder);
-public:
-	LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {};
-
-protected:
-	// called with bad status codes
-	virtual void httpFailure();
-	virtual void httpSuccess();
-
-private:
-	LLUUID mSessionID;
-};
-
-
-void LLVoiceCallCapResponder::httpFailure()
-{
-	LL_WARNS("Voice") << dumpResponse() << LL_ENDL;
-	LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
-	if ( channelp )
-	{
-		if ( HTTP_FORBIDDEN == getStatus() )
-		{
-			//403 == no ability
-			LLNotificationsUtil::add(
-				"VoiceNotAllowed",
-				channelp->getNotifyArgs());
-		}
-		else
-		{
-			LLNotificationsUtil::add(
-				"VoiceCallGenericError",
-				channelp->getNotifyArgs());
-		}
-		channelp->deactivate();
-	}
-}
-
-void LLVoiceCallCapResponder::httpSuccess()
-{
-	LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
-	if (channelp)
-	{
-		//*TODO: DEBUG SPAM
-		const LLSD& content = getContent();
-		if (!content.isMap())
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		LLSD::map_const_iterator iter;
-		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
-		{
-			LL_DEBUGS("Voice") << "LLVoiceCallCapResponder::result got " 
-				<< iter->first << LL_ENDL;
-		}
-
-		channelp->setChannelInfo(
-			content["voice_credentials"]["channel_uri"].asString(),
-			content["voice_credentials"]["channel_credentials"].asString());
-	}
-}
-
 //
 // LLVoiceChannel
 //
@@ -545,12 +479,9 @@ void LLVoiceChannelGroup::getChannelInfo()
 	if (region)
 	{
 		std::string url = region->getCapability("ChatSessionRequest");
-		LLSD data;
-		data["method"] = "call";
-		data["session-id"] = mSessionID;
-		LLHTTPClient::post(url,
-						   data,
-						   new LLVoiceCallCapResponder(mSessionID));
+
+        LLCoros::instance().launch("LLVoiceChannelGroup::voiceCallCapCoro",
+            boost::bind(&LLVoiceChannelGroup::voiceCallCapCoro, this, url));
 	}
 }
 
@@ -673,6 +604,66 @@ void LLVoiceChannelGroup::setState(EState state)
 	}
 }
 
+void LLVoiceChannelGroup::voiceCallCapCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("voiceCallCapCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD postData;
+    postData["method"] = "call";
+    postData["session-id"] = mSessionID;
+
+    LL_INFOS("Voice", "voiceCallCapCoro") << "Generic POST for " << url << LL_ENDL;
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
+    if (!channelp)
+    {
+        LL_WARNS("Voice") << "Unable to retrieve channel with Id = " << mSessionID << LL_ENDL;
+        return;
+    }
+
+    if (!status)
+    {
+        if (status == LLCore::HttpStatus(HTTP_FORBIDDEN))
+        {
+            //403 == no ability
+            LLNotificationsUtil::add(
+                "VoiceNotAllowed",
+                channelp->getNotifyArgs());
+        }
+        else
+        {
+            LLNotificationsUtil::add(
+                "VoiceCallGenericError",
+                channelp->getNotifyArgs());
+        }
+        channelp->deactivate();
+        return;
+    }
+
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+
+    LLSD::map_const_iterator iter;
+    for (iter = result.beginMap(); iter != result.endMap(); ++iter)
+    {
+        LL_DEBUGS("Voice") << "LLVoiceCallCapResponder::result got "
+            << iter->first << LL_ENDL;
+    }
+
+    channelp->setChannelInfo(
+        result["voice_credentials"]["channel_uri"].asString(),
+        result["voice_credentials"]["channel_credentials"].asString());
+
+}
+
+
 //
 // LLVoiceChannelProximal
 //
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index fed44974fdee8d60548b086ca0327e465f831bc7..ef15b2c79ee2d5c184d7cf6e59df2802168e3ad7 100755
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -29,6 +29,8 @@
 
 #include "llhandle.h"
 #include "llvoiceclient.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 class LLPanel;
 
@@ -157,6 +159,8 @@ class LLVoiceChannelGroup : public LLVoiceChannel
 	virtual void setState(EState state);
 
 private:
+    void voiceCallCapCoro(std::string url);
+
 	U32 mRetries;
 	BOOL mIsRetrying;
 };
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index a6a7a35b03858d2279f13e245e5be2a79c879ada..f50ffdeae7b981e203117425fc31872cdf16358e 100755
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -64,6 +64,8 @@
 #include "llviewernetwork.h"
 #include "llnotificationsutil.h"
 
+#include "llcorehttputil.h"
+
 #include "stringize.h"
 
 // for base64 decoding
@@ -122,66 +124,6 @@ static int scale_speaker_volume(float volume)
 	
 }
 
-class LLVivoxVoiceAccountProvisionResponder :
-	public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLVivoxVoiceAccountProvisionResponder);
-public:
-	LLVivoxVoiceAccountProvisionResponder(int retries)
-	{
-		mRetries = retries;
-	}
-
-private:
-	/* virtual */ void httpFailure()
-	{
-		LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, "
-			<<  ( (mRetries > 0) ? "retrying" : "too many retries (giving up)" )
-			<< " " << dumpResponse() << LL_ENDL;
-
-		if ( mRetries > 0 )
-		{
-			LLVivoxVoiceClient::getInstance()->requestVoiceAccountProvision(mRetries - 1);
-		}
-		else
-		{
-			LLVivoxVoiceClient::getInstance()->giveUp();
-		}
-	}
-
-	/* virtual */ void httpSuccess()
-	{
-		std::string voice_sip_uri_hostname;
-		std::string voice_account_server_uri;
-		
-		LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << dumpResponse() << LL_ENDL;
-		
-		const LLSD& content = getContent();
-		if (!content.isMap())
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		if(content.has("voice_sip_uri_hostname"))
-			voice_sip_uri_hostname = content["voice_sip_uri_hostname"].asString();
-		
-		// this key is actually misnamed -- it will be an entire URI, not just a hostname.
-		if(content.has("voice_account_server_name"))
-			voice_account_server_uri = content["voice_account_server_name"].asString();
-		
-		LLVivoxVoiceClient::getInstance()->login(
-			content["username"].asString(),
-			content["password"].asString(),
-			voice_sip_uri_hostname,
-			voice_account_server_uri);
-	}
-
-private:
-	int mRetries;
-};
-
-
-
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
 class LLVivoxVoiceClientMuteListObserver : public LLMuteListObserver
@@ -194,59 +136,6 @@ static LLVivoxVoiceClientMuteListObserver mutelist_listener;
 static bool sMuteListListener_listening = false;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
-
-class LLVivoxVoiceClientCapResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLVivoxVoiceClientCapResponder);
-public:
-	LLVivoxVoiceClientCapResponder(LLVivoxVoiceClient::state requesting_state) : mRequestingState(requesting_state) {};
-
-private:
-	// called with bad status codes
-	/* virtual */ void httpFailure();
-	/* virtual */ void httpSuccess();
-
-	LLVivoxVoiceClient::state mRequestingState;  // state 
-};
-
-void LLVivoxVoiceClientCapResponder::httpFailure()
-{
-	LL_WARNS("Voice") << dumpResponse() << LL_ENDL;
-	LLVivoxVoiceClient::getInstance()->sessionTerminate();
-}
-
-void LLVivoxVoiceClientCapResponder::httpSuccess()
-{
-	LLSD::map_const_iterator iter;
-	
-	LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest response:" << dumpResponse() << LL_ENDL;
-
-	std::string uri;
-	std::string credentials;
-	
-	const LLSD& content = getContent();
-	if ( content.has("voice_credentials") )
-	{
-		LLSD voice_credentials = content["voice_credentials"];
-		if ( voice_credentials.has("channel_uri") )
-		{
-			uri = voice_credentials["channel_uri"].asString();
-		}
-		if ( voice_credentials.has("channel_credentials") )
-		{
-			credentials =
-				voice_credentials["channel_credentials"].asString();
-		}
-	}
-	
-	// set the spatial channel.  If no voice credentials or uri are 
-	// available, then we simply drop out of voice spatially.
-	if(LLVivoxVoiceClient::getInstance()->parcelVoiceInfoReceived(mRequestingState))
-	{
-		LLVivoxVoiceClient::getInstance()->setSpatialChannel(uri, credentials);
-	}
-}
-
 static LLProcessPtr sGatewayPtr;
 
 static bool isGatewayRunning()
@@ -556,16 +445,51 @@ void LLVivoxVoiceClient::requestVoiceAccountProvision(S32 retries)
 		
 		if ( !url.empty() ) 
 		{
-			LLHTTPClient::post(
-							   url,
-							   LLSD(),
-							   new LLVivoxVoiceAccountProvisionResponder(retries));
-		
+            LLCoros::instance().launch("LLVivoxVoiceClient::voiceAccountProvisionCoro",
+                boost::bind(&LLVivoxVoiceClient::voiceAccountProvisionCoro, this, url, retries));
 			setState(stateConnectorStart);		
 		}
 	}
 }
 
+void LLVivoxVoiceClient::voiceAccountProvisionCoro(std::string url, S32 retries)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("voiceAccountProvision", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+    httpOpts->setRetries(retries);
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, LLSD(), httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("Voice") << "Unable to provision voice account." << LL_ENDL;
+        giveUp();
+        return;
+    }
+
+    std::string voice_sip_uri_hostname;
+    std::string voice_account_server_uri;
+
+    //LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << dumpResponse() << LL_ENDL;
+
+    if (result.has("voice_sip_uri_hostname"))
+        voice_sip_uri_hostname = result["voice_sip_uri_hostname"].asString();
+
+    // this key is actually misnamed -- it will be an entire URI, not just a hostname.
+    if (result.has("voice_account_server_name"))
+        voice_account_server_uri = result["voice_account_server_name"].asString();
+
+    login(result["username"].asString(), result["password"].asString(),
+        voice_sip_uri_hostname, voice_account_server_uri);
+}
+
 void LLVivoxVoiceClient::login(
 	const std::string& account_name,
 	const std::string& password,
@@ -4003,14 +3927,60 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
 		LLSD data;
 		LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL;
 		
-		LLHTTPClient::post(
-						url,
-						data,
-						new LLVivoxVoiceClientCapResponder(getState()));
+        LLCoros::instance().launch("LLVivoxVoiceClient::parcelVoiceInfoRequestCoro",
+            boost::bind(&LLVivoxVoiceClient::parcelVoiceInfoRequestCoro, this, url));
 		return true;
 	}
 }
 
+void LLVivoxVoiceClient::parcelVoiceInfoRequestCoro(std::string url)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("parcelVoiceInfoRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    state requestingState = getState();
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, LLSD());
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("Voice") << "No voice on parcel" << LL_ENDL;
+        sessionTerminate();
+        return;
+    }
+
+    std::string uri;
+    std::string credentials;
+
+    if (result.has("voice_credentials"))
+    {
+        LLSD voice_credentials = result["voice_credentials"];
+        if (voice_credentials.has("channel_uri"))
+        {
+            uri = voice_credentials["channel_uri"].asString();
+        }
+        if (voice_credentials.has("channel_credentials"))
+        {
+            credentials =
+                voice_credentials["channel_credentials"].asString();
+        }
+    }
+
+    LL_INFOS("Voice") << "Voice URI is " << uri << LL_ENDL;
+
+    // set the spatial channel.  If no voice credentials or uri are 
+    // available, then we simply drop out of voice spatially.
+    if (parcelVoiceInfoReceived(requestingState))
+    {
+        setSpatialChannel(uri, credentials);
+    }
+
+}
+
 void LLVivoxVoiceClient::switchChannel(
 	std::string uri,
 	bool spatial,
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index a4ec9f2a69271e0f2a50781653b558722883ae07..b12ed80e41e03c6442c613294489a627157542c4 100755
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -37,6 +37,9 @@ class LLVivoxProtocolParser;
 #include "llframetimer.h"
 #include "llviewerregion.h"
 #include "llcallingcard.h"   // for LLFriendObserver
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include <queue>
 
 #ifdef LL_USESYSTEMLIBS
 # include "expat.h"
@@ -46,7 +49,6 @@ class LLVivoxProtocolParser;
 #include "llvoiceclient.h"
 
 class LLAvatarName;
-class LLVivoxVoiceAccountProvisionResponder;
 class LLVivoxVoiceClientMuteListObserver;
 
 
@@ -251,7 +253,6 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 	//////////////////////
 	// Vivox Specific definitions	
 	
-	friend class LLVivoxVoiceAccountProvisionResponder;
 	friend class LLVivoxVoiceClientMuteListObserver;
 	friend class LLVivoxVoiceClientFriendsObserver;	
 	
@@ -635,6 +636,10 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 	void accountGetTemplateFontsResponse(int statusCode, const std::string &statusString); 
 
 private:
+    
+    void voiceAccountProvisionCoro(std::string url, S32 retries);
+    void parcelVoiceInfoRequestCoro(std::string url);
+
 	LLVoiceVersionInfo mVoiceVersion;
 
 	/// Clean up objects created during a voice session.
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index ddb7f7bfce147daf0036ada23bc88734e1ceeacc..2033a5f36a371b53d7019ae9905eee517de6dc50 100755
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -30,14 +30,17 @@
 
 // libs
 #include "llbufferstream.h"
-#include "llhttpclient.h"
 #include "llimagepng.h"
 #include "llplugincookiestore.h"
 
+#include "llsdserialize.h"
+
 // newview
 #include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions
 #include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals
 
+#include "llcorehttputil.h"
+
 // third-party
 #include "reader.h" // JSON
 
@@ -54,139 +57,6 @@
  *    -> GET <redirect_url> via PostImageRedirectResponder
  */
 
-///////////////////////////////////////////////////////////////////////////////
-// LLWebProfileResponders::ConfigResponder
-
-class LLWebProfileResponders::ConfigResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLWebProfileResponders::ConfigResponder);
-
-public:
-	ConfigResponder(LLPointer<LLImageFormatted> imagep)
-	:	mImagep(imagep)
-	{
-	}
-
-	// *TODO: Check for 'application/json' content type, and parse json at the base class.
-	/*virtual*/ void completedRaw(
-		const LLChannelDescriptors& channels,
-		const LLIOPipe::buffer_ptr_t& buffer)
-	{
-		LLBufferStream istr(channels, buffer.get());
-		std::stringstream strstrm;
-		strstrm << istr.rdbuf();
-		const std::string body = strstrm.str();
-
-		if (getStatus() != HTTP_OK)
-		{
-			LL_WARNS() << "Failed to get upload config " << dumpResponse() << LL_ENDL;
-			LLWebProfile::reportImageUploadStatus(false);
-			return;
-		}
-
-		Json::Value root;
-		Json::Reader reader;
-		if (!reader.parse(body, root))
-		{
-			LL_WARNS() << "Failed to parse upload config: " << reader.getFormatedErrorMessages() << LL_ENDL;
-			LLWebProfile::reportImageUploadStatus(false);
-			return;
-		}
-
-		// *TODO: 404 = not supported by the grid
-		// *TODO: increase timeout or handle 499 Expired
-
-		// Convert config to LLSD.
-		const Json::Value data = root["data"];
-		const std::string upload_url = root["url"].asString();
-		LLSD config;
-		config["acl"]						= data["acl"].asString();
-		config["AWSAccessKeyId"]			= data["AWSAccessKeyId"].asString();
-		config["Content-Type"]				= data["Content-Type"].asString();
-		config["key"]						= data["key"].asString();
-		config["policy"]					= data["policy"].asString();
-		config["success_action_redirect"]	= data["success_action_redirect"].asString();
-		config["signature"]					= data["signature"].asString();
-		config["add_loc"]					= data.get("add_loc", "0").asString();
-		config["caption"]					= data.get("caption", "").asString();
-
-		// Do the actual image upload using the configuration.
-		LL_DEBUGS("Snapshots") << "Got upload config, POSTing image to " << upload_url << ", config=[" << config << "]" << LL_ENDL;
-		LLWebProfile::post(mImagep, config, upload_url);
-	}
-
-private:
-	LLPointer<LLImageFormatted> mImagep;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// LLWebProfilePostImageRedirectResponder
-class LLWebProfileResponders::PostImageRedirectResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLWebProfileResponders::PostImageRedirectResponder);
-
-public:
-	/*virtual*/ void completedRaw(
-		const LLChannelDescriptors& channels,
-		const LLIOPipe::buffer_ptr_t& buffer)
-	{
-		if (getStatus() != HTTP_OK)
-		{
-			LL_WARNS() << "Failed to upload image " << dumpResponse() << LL_ENDL;
-			LLWebProfile::reportImageUploadStatus(false);
-			return;
-		}
-
-		LLBufferStream istr(channels, buffer.get());
-		std::stringstream strstrm;
-		strstrm << istr.rdbuf();
-		const std::string body = strstrm.str();
-		LL_INFOS() << "Image uploaded." << LL_ENDL;
-		LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << body << "]" << LL_ENDL;
-		LLWebProfile::reportImageUploadStatus(true);
-	}
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// LLWebProfileResponders::PostImageResponder
-class LLWebProfileResponders::PostImageResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLWebProfileResponders::PostImageResponder);
-
-public:
-	/*virtual*/ void completedRaw(const LLChannelDescriptors& channels,
-								  const LLIOPipe::buffer_ptr_t& buffer)
-	{
-		// Viewer seems to fail to follow a 303 redirect on POST request
-		// (URLRequest Error: 65, Send failed since rewinding of the data stream failed).
-		// Handle it manually.
-		if (getStatus() == HTTP_SEE_OTHER)
-		{
-			LLSD headers = LLViewerMedia::getHeaders();
-			headers[HTTP_OUT_HEADER_COOKIE] = LLWebProfile::getAuthCookie();
-			const std::string& redir_url = getResponseHeader(HTTP_IN_HEADER_LOCATION);
-			if (redir_url.empty())
-			{
-				LL_WARNS() << "Received empty redirection URL " << dumpResponse() << LL_ENDL;
-				LL_DEBUGS("Snapshots") << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-				LLWebProfile::reportImageUploadStatus(false);
-			}
-			else
-			{
-				LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << LL_ENDL;
-				LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers);
-			}
-		}
-		else
-		{
-			LL_WARNS() << "Unexpected POST response " << dumpResponse() << LL_ENDL;
-			LL_DEBUGS("Snapshots") << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
-			LLWebProfile::reportImageUploadStatus(false);
-		}
-	}
-};
-
 ///////////////////////////////////////////////////////////////////////////////
 // LLWebProfile
 
@@ -196,15 +66,9 @@ LLWebProfile::status_callback_t LLWebProfile::mStatusCallback;
 // static
 void LLWebProfile::uploadImage(LLPointer<LLImageFormatted> image, const std::string& caption, bool add_location)
 {
-	// Get upload configuration data.
-	std::string config_url(getProfileURL(LLStringUtil::null) + "snapshots/s3_upload_config");
-	config_url += "?caption=" + LLURI::escape(caption);
-	config_url += "&add_loc=" + std::string(add_location ? "1" : "0");
-
-	LL_DEBUGS("Snapshots") << "Requesting " << config_url << LL_ENDL;
-	LLSD headers = LLViewerMedia::getHeaders();
-	headers[HTTP_OUT_HEADER_COOKIE] = getAuthCookie();
-	LLHTTPClient::get(config_url, new LLWebProfileResponders::ConfigResponder(image), headers);
+    LLCoros::instance().launch("LLWebProfile::uploadImageCoro",
+        boost::bind(&LLWebProfile::uploadImageCoro, image, caption, add_location));
+
 }
 
 // static
@@ -214,74 +78,178 @@ void LLWebProfile::setAuthCookie(const std::string& cookie)
 	sAuthCookie = cookie;
 }
 
-// static
-void LLWebProfile::post(LLPointer<LLImageFormatted> image, const LLSD& config, const std::string& url)
+
+/*static*/
+LLCore::HttpHeaders::ptr_t LLWebProfile::buildDefaultHeaders()
 {
-	if (dynamic_cast<LLImagePNG*>(image.get()) == 0)
-	{
-		LL_WARNS() << "Image to upload is not a PNG" << LL_ENDL;
-		llassert(dynamic_cast<LLImagePNG*>(image.get()) != 0);
-		return;
-	}
+    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+    LLSD headers = LLViewerMedia::getHeaders();
 
-	const std::string boundary = "----------------------------0123abcdefab";
+    for (LLSD::map_iterator it = headers.beginMap(); it != headers.endMap(); ++it)
+    {
+        httpHeaders->append((*it).first, (*it).second.asStringRef());
+    }
 
-	LLSD headers = LLViewerMedia::getHeaders();
-	headers[HTTP_OUT_HEADER_COOKIE] = getAuthCookie();
-	headers[HTTP_OUT_HEADER_CONTENT_TYPE] = "multipart/form-data; boundary=" + boundary;
+    return httpHeaders;
+}
 
-	std::ostringstream body;
 
-	// *NOTE: The order seems to matter.
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"key\"\r\n\r\n"
-			<< config["key"].asString() << "\r\n";
+/*static*/
+void LLWebProfile::uploadImageCoro(LLPointer<LLImageFormatted> image, std::string caption, bool addLocation)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+    LLCore::HttpHeaders::ptr_t httpHeaders;
 
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n"
-			<< config["AWSAccessKeyId"].asString() << "\r\n";
+    if (dynamic_cast<LLImagePNG*>(image.get()) == 0)
+    {
+        LL_WARNS() << "Image to upload is not a PNG" << LL_ENDL;
+        llassert(dynamic_cast<LLImagePNG*>(image.get()) != 0);
+        return;
+    }
 
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"acl\"\r\n\r\n"
-			<< config["acl"].asString() << "\r\n";
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
 
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n"
-			<< config["Content-Type"].asString() << "\r\n";
+    // Get upload configuration data.
+    std::string configUrl(getProfileURL(std::string()) + "snapshots/s3_upload_config");
+    configUrl += "?caption=" + LLURI::escape(caption);
+    configUrl += "&add_loc=" + std::string(addLocation ? "1" : "0");
 
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"policy\"\r\n\r\n"
-			<< config["policy"].asString() << "\r\n";
+    LL_DEBUGS("Snapshots") << "Requesting " << configUrl << LL_ENDL;
 
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"signature\"\r\n\r\n"
-			<< config["signature"].asString() << "\r\n";
+    httpHeaders = buildDefaultHeaders();
+    httpHeaders->append(HTTP_OUT_HEADER_COOKIE, getAuthCookie());
 
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n"
-			<< config["success_action_redirect"].asString() << "\r\n";
+    LLSD result = httpAdapter->getJsonAndYield(httpRequest, configUrl, httpOpts, httpHeaders);
 
-	body	<< "--" << boundary << "\r\n"
-			<< "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n"
-			<< "Content-Type: image/png\r\n\r\n";
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
 
-	// Insert the image data.
-	// *FIX: Treating this as a string will probably screw it up ...
-	U8* image_data = image->getData();
-	for (S32 i = 0; i < image->getDataSize(); ++i)
-	{
-		body << image_data[i];
-	}
+    if (!status)
+    {
+        LL_WARNS("Snapshots") << "Failed to get image upload config" << LL_ENDL;
+        LLWebProfile::reportImageUploadStatus(false);
+        return;
+    }
+
+    // Ready to build our image post body.
+
+    const LLSD &data = result["data"];
+    const std::string &uploadUrl = result["url"].asStringRef();
+    const std::string boundary = "----------------------------0123abcdefab";
+
+    // a new set of headers.
+    httpHeaders = LLWebProfile::buildDefaultHeaders();
+    httpHeaders->append(HTTP_OUT_HEADER_COOKIE, getAuthCookie());
+    httpHeaders->remove(HTTP_OUT_HEADER_CONTENT_TYPE);
+    httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "multipart/form-data; boundary=" + boundary);
+    
+    LLCore::BufferArray::ptr_t body = LLWebProfile::buildPostData(data, image, boundary);
+
+    result = httpAdapter->postAndYield(httpRequest, uploadUrl, body, httpOpts, httpHeaders);
+
+    body.reset();
+    httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
 
-	body <<	"\r\n--" << boundary << "--\r\n";
+    if (!status && (status != LLCore::HttpStatus(HTTP_SEE_OTHER)))
+    {
+        LL_WARNS("Snapshots") << "Failed to upload image data." << LL_ENDL;
+        LLWebProfile::reportImageUploadStatus(false);
+        return;
+    }
 
-	// postRaw() takes ownership of the buffer and releases it later.
-	size_t size = body.str().size();
-	U8 *data = new U8[size];
-	memcpy(data, body.str().data(), size);
+    LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
 
-	// Send request, successful upload will trigger posting metadata.
-	LLHTTPClient::postRaw(url, data, size, new LLWebProfileResponders::PostImageResponder(), headers);
+    httpHeaders = LLWebProfile::buildDefaultHeaders();
+    httpHeaders->append(HTTP_OUT_HEADER_COOKIE, getAuthCookie());
+
+    const std::string& redirUrl = resultHeaders[HTTP_IN_HEADER_LOCATION].asStringRef();
+
+    if (redirUrl.empty())
+    {
+        LL_WARNS("Snapshots") << "Received empty redirection URL in post image." << LL_ENDL;
+        LLWebProfile::reportImageUploadStatus(false);
+    }
+
+    LL_DEBUGS("Snapshots") << "Got redirection URL: " << redirUrl << LL_ENDL;
+
+    result = httpAdapter->getRawAndYield(httpRequest, redirUrl, httpOpts, httpHeaders);
+
+    httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (status != LLCore::HttpStatus(HTTP_OK))
+    {
+        LL_WARNS("Snapshots") << "Failed to upload image." << LL_ENDL;
+        LLWebProfile::reportImageUploadStatus(false);
+        return;
+    }
+
+    //LLSD raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW];
+
+    LL_INFOS("Snapshots") << "Image uploaded." << LL_ENDL;
+    //LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << raw.asString() << "]" << LL_ENDL;
+    LLWebProfile::reportImageUploadStatus(true);
+
+
+}
+
+/*static*/
+LLCore::BufferArray::ptr_t LLWebProfile::buildPostData(const LLSD &data, LLPointer<LLImageFormatted> &image, const std::string &boundary)
+{
+    LLCore::BufferArray::ptr_t body(new LLCore::BufferArray);
+    LLCore::BufferArrayStream bas(body.get());
+
+    // *NOTE: The order seems to matter.
+    bas << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"key\"\r\n\r\n"
+        << data["key"].asString() << "\r\n";
+
+    bas << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n"
+        << data["AWSAccessKeyId"].asString() << "\r\n";
+
+    bas << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"acl\"\r\n\r\n"
+        << data["acl"].asString() << "\r\n";
+
+    bas << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n"
+        << data["Content-Type"].asString() << "\r\n";
+
+    bas << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"policy\"\r\n\r\n"
+        << data["policy"].asString() << "\r\n";
+
+    bas << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"signature\"\r\n\r\n"
+        << data["signature"].asString() << "\r\n";
+
+    bas << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n"
+        << data["success_action_redirect"].asString() << "\r\n";
+
+    bas << "--" << boundary << "\r\n"
+        << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n"
+        << "Content-Type: image/png\r\n\r\n";
+
+    // Insert the image data.
+    //char *datap = (char *)(image->getData());
+    //bas.write(datap, image->getDataSize());
+    U8* image_data = image->getData();
+    for (S32 i = 0; i < image->getDataSize(); ++i)
+    {
+        bas << image_data[i];
+    }
+
+    bas << "\r\n--" << boundary << "--\r\n";
+
+    return body;
 }
 
 // static
diff --git a/indra/newview/llwebprofile.h b/indra/newview/llwebprofile.h
index 10279bffaccfe3c225c59bf81de225d39f0101c2..6227e00afeab80e7d872e2f76a256e4eb9545d83 100755
--- a/indra/newview/llwebprofile.h
+++ b/indra/newview/llwebprofile.h
@@ -28,6 +28,10 @@
 #define LL_LLWEBPROFILE_H
 
 #include "llimage.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "httpheaders.h"
+#include "bufferarray.h"
 
 namespace LLWebProfileResponders
 {
@@ -54,11 +58,11 @@ class LLWebProfile
 	static void setImageUploadResultCallback(status_callback_t cb) { mStatusCallback = cb; }
 
 private:
-	friend class LLWebProfileResponders::ConfigResponder;
-	friend class LLWebProfileResponders::PostImageResponder;
-	friend class LLWebProfileResponders::PostImageRedirectResponder;
+    static LLCore::HttpHeaders::ptr_t buildDefaultHeaders();
+
+    static void uploadImageCoro(LLPointer<LLImageFormatted> image, std::string caption, bool add_location);
+    static LLCore::BufferArray::ptr_t buildPostData(const LLSD &data, LLPointer<LLImageFormatted> &image, const std::string &boundary);
 
-	static void post(LLPointer<LLImageFormatted> image, const LLSD& config, const std::string& url);
 	static void reportImageUploadStatus(bool ok);
 	static std::string getAuthCookie();
 
diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index 3bedfbe502af09f22717da6c035bf5e8e7c47c96..ff15afa59848421c114257470f56d43edc481151 100755
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -32,6 +32,7 @@
 #include "llviewerregion.h"
 #include "llenvmanager.h"
 #include "llnotificationsutil.h"
+#include "llcorehttputil.h"
 
 /****
  * LLEnvironmentRequest
@@ -81,55 +82,62 @@ bool LLEnvironmentRequest::doRequest()
 		return false;
 	}
 
-	LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL;
-	LLHTTPClient::get(url, new LLEnvironmentRequestResponder());
-	return true;
-}
-
-/****
- * LLEnvironmentRequestResponder
- ****/
-int LLEnvironmentRequestResponder::sCount = 0; // init to 0
+    std::string coroname =
+        LLCoros::instance().launch("LLEnvironmentRequest::environmentRequestCoro",
+        boost::bind(&LLEnvironmentRequest::environmentRequestCoro, url));
 
-LLEnvironmentRequestResponder::LLEnvironmentRequestResponder()
-{
-	mID = ++sCount;
+    LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL;
+    return true;
 }
-/*virtual*/ void LLEnvironmentRequestResponder::httpSuccess()
-{
-	const LLSD& unvalidated_content = getContent();
-	LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL;
 
-	if (mID != sCount)
-	{
-		LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL;
-		return;
-	}
-
-	LLUUID regionId;
-	if( gAgent.getRegion() )
-	{
-		regionId = gAgent.getRegion()->getRegionID();
-	}
-	
-	if (unvalidated_content[0]["regionID"].asUUID() != regionId )
-	{
-		LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting "
-			<< regionId << " but got " << unvalidated_content[0]["regionID"].asUUID()
-			<< ") - ignoring..." << LL_ENDL;
-		return;
-	}
+S32 LLEnvironmentRequest::sLastRequest = 0;
 
-	LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content);
-}
-/*virtual*/
-void LLEnvironmentRequestResponder::httpFailure()
+//static 
+void LLEnvironmentRequest::environmentRequestCoro(std::string url)
 {
-	LL_WARNS("WindlightCaps") << "Got an error, not using region windlight... "
-			<< dumpResponse() << LL_ENDL;
-	LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    S32 requestId = ++LLEnvironmentRequest::sLastRequest;
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t 
+            httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EnvironmentRequest", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    if (requestId != LLEnvironmentRequest::sLastRequest)
+    {
+        LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL;
+        return;
+    }
+
+    LLSD httpResults = result["http_result"];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+    if (!status)
+    {
+        LL_WARNS("WindlightCaps") << "Got an error, not using region windlight... " << LL_ENDL;
+        LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
+        return;
+    }
+    result = result["content"];
+    LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL;
+
+    LLUUID regionId;
+    if (gAgent.getRegion())
+    {
+        regionId = gAgent.getRegion()->getRegionID();
+    }
+
+    if (result[0]["regionID"].asUUID() != regionId)
+    {
+        LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting "
+            << regionId << " but got " << result[0]["regionID"].asUUID()
+            << ") - ignoring..." << LL_ENDL;
+        return;
+    }
+
+    LLEnvManagerNew::getInstance()->onRegionSettingsResponse(result);
 }
 
+
 /****
  * LLEnvironmentApply
  ****/
@@ -161,53 +169,86 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
 		return false;
 	}
 
-	LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL;
-	LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL;
-	LLHTTPClient::post(url, content, new LLEnvironmentApplyResponder());
+    LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL;
+    LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL;
+
+    std::string coroname =
+        LLCoros::instance().launch("LLEnvironmentApply::environmentApplyCoro",
+        boost::bind(&LLEnvironmentApply::environmentApplyCoro, url, content));
 	return true;
 }
 
-/****
- * LLEnvironmentApplyResponder
- ****/
-/*virtual*/ void LLEnvironmentApplyResponder::httpSuccess()
-{
-	const LLSD& content = getContent();
-	if (!content.isMap() || !content.has("regionID"))
-	{
-		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-		return;
-	}
-	if (content["regionID"].asUUID() != gAgent.getRegion()->getRegionID())
-	{
-		LL_WARNS("WindlightCaps") << "No longer in the region where data was sent (currently "
-			<< gAgent.getRegion()->getRegionID() << ", reply is from " << content["regionID"].asUUID()
-			<< "); ignoring..." << LL_ENDL;
-		return;
-	}
-	else if (content["success"].asBoolean())
-	{
-		LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << content["regionID"].asUUID() << LL_ENDL;
-		LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true);
-	}
-	else
-	{
-		LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings!  " << dumpResponse() << LL_ENDL;
-		LLSD args(LLSD::emptyMap());
-		args["FAIL_REASON"] = content["fail_reason"].asString();
-		LLNotificationsUtil::add("WLRegionApplyFail", args);
-		LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
-	}
-}
-/*virtual*/
-void LLEnvironmentApplyResponder::httpFailure()
+void LLEnvironmentApply::environmentApplyCoro(std::string url, LLSD content)
 {
-	LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! "
-		<< dumpResponse() << LL_ENDL;
-
-	LLSD args(LLSD::emptyMap());
-	std::stringstream msg;
-	msg << getReason() << " (Code " << getStatus() << ")";
-	args["FAIL_REASON"] = msg.str();
-	LLNotificationsUtil::add("WLRegionApplyFail", args);
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EnvironmentApply", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD result = httpAdapter->postAndYield(httpRequest, url, content);
+
+    LLSD notify; // for error reporting.  If there is something to report to user this will be defined.
+    /*
+     * Expecting reply from sim in form of:
+     * {
+     *   regionID : uuid,
+     *   messageID: uuid,
+     *   success : true
+     * }
+     * or
+     * {
+     *   regionID : uuid,
+     *   success : false,
+     *   fail_reason : string
+     * }
+     */
+
+    do // while false.  
+    {  // Breaks from loop in the case of an error.
+
+        LLSD httpResults = result["http_result"];
+        LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+        if (!status)
+        {
+            LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! " << LL_ENDL;
+
+            std::stringstream msg;
+            msg << status.toString() << " (Code " << status.toTerseString() << ")";
+            notify = LLSD::emptyMap();
+            notify["FAIL_REASON"] = msg.str();
+            break;
+        }
+
+        if (!result.has("regionID"))
+        {
+            notify = LLSD::emptyMap();
+            notify["FAIL_REASON"] = "Missing regionID, malformed response";
+            break;
+        } 
+        else if (result["regionID"].asUUID() != gAgent.getRegion()->getRegionID())
+        {
+            // note that there is no report to the user in this failure case.
+            LL_WARNS("WindlightCaps") << "No longer in the region where data was sent (currently "
+                << gAgent.getRegion()->getRegionID() << ", reply is from " << result["regionID"].asUUID()
+                << "); ignoring..." << LL_ENDL;
+            break;
+        }
+        else if (!result["success"].asBoolean())
+        {
+            LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings!  " << LL_ENDL;
+            notify = LLSD::emptyMap();
+            notify["FAIL_REASON"] = result["fail_reason"].asString();
+            break;
+        }
+
+        LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << result["regionID"].asUUID() << LL_ENDL;
+        LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true);
+
+    } while (false);
+
+    if (!notify.isUndefined())
+    {
+        LLNotificationsUtil::add("WLRegionApplyFail", notify);
+        LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
+    }
 }
diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h
index 089c799da7cac21dd37228c41411fe0acd7854f4..eb2bbf9553596d85f38e1c4e9e31a4f64dc6c1fc 100755
--- a/indra/newview/llwlhandlers.h
+++ b/indra/newview/llwlhandlers.h
@@ -28,7 +28,7 @@
 #define LL_LLWLHANDLERS_H
 
 #include "llviewerprecompiledheaders.h"
-#include "llhttpclient.h"
+#include "llcoros.h"
 
 class LLEnvironmentRequest
 {
@@ -40,21 +40,10 @@ class LLEnvironmentRequest
 private:
 	static void onRegionCapsReceived(const LLUUID& region_id);
 	static bool doRequest();
-};
-
-class LLEnvironmentRequestResponder: public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLEnvironmentRequestResponder);
-private:
-	/* virtual */ void httpSuccess();
-	/* virtual */ void httpFailure();
 
-private:
-	friend class LLEnvironmentRequest;
+    static void environmentRequestCoro(std::string url);
 
-	LLEnvironmentRequestResponder();
-	static int sCount;
-	int mID;
+    static S32 sLastRequest;
 };
 
 class LLEnvironmentApply
@@ -67,35 +56,8 @@ class LLEnvironmentApply
 private:
 	static clock_t sLastUpdate;
 	static clock_t UPDATE_WAIT_SECONDS;
-};
 
-class LLEnvironmentApplyResponder: public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLEnvironmentApplyResponder);
-private:
-	/*
-	 * Expecting reply from sim in form of:
-	 * {
-	 *   regionID : uuid,
-	 *   messageID: uuid,
-	 *   success : true
-	 * }
-	 * or
-	 * {
-	 *   regionID : uuid,
-	 *   success : false,
-	 *   fail_reason : string
-	 * }
-	 */
-	/* virtual */ void httpSuccess();
-
-	// non-2xx errors only
-	/* virtual */ void httpFailure();
-
-private:
-	friend class LLEnvironmentApply;
-	
-	LLEnvironmentApplyResponder() {}
+    static void environmentApplyCoro(std::string url, LLSD content);
 };
 
 #endif // LL_LLWLHANDLERS_H
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index c12c2cc24c3639c8e020d0e6ec788246e61677b5..066970614a41cf2ca0c0d290208ee4e5be4a1196 100755
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -35,6 +35,11 @@
 #include "llxmlrpclistener.h"
 
 #include "llcurl.h"
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httpoptions.h"
+#include "httpheaders.h"
+#include "bufferarray.h"
 #include "llviewercontrol.h"
 
 // Have to include these last to avoid queue redefinition!
@@ -43,6 +48,13 @@
 #include "llappviewer.h"
 #include "lltrans.h"
 
+#include "boost/move/unique_ptr.hpp"
+
+namespace boost
+{
+	using ::boost::movelib::unique_ptr; // move unique_ptr into the boost namespace.
+}
+
 // Static instance of LLXMLRPCListener declared here so that every time we
 // bring in this code, we instantiate a listener. If we put the static
 // instance of LLXMLRPCListener into llxmlrpclistener.cpp, the linker would
@@ -155,55 +167,158 @@ XMLRPC_VALUE LLXMLRPCValue::getValue() const
 }
 
 
+class LLXMLRPCTransaction::Handler : public LLCore::HttpHandler
+{
+public: 
+	Handler(LLCore::HttpRequest::ptr_t &request, LLXMLRPCTransaction::Impl *impl);
+	virtual ~Handler();
+
+	virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+
+	typedef boost::unique_ptr<LLXMLRPCTransaction::Handler> ptr_t;
+
+private:
+
+	LLXMLRPCTransaction::Impl *mImpl;
+	LLCore::HttpRequest::ptr_t mRequest;
+};
+
 class LLXMLRPCTransaction::Impl
 {
 public:
 	typedef LLXMLRPCTransaction::EStatus	EStatus;
 
-	LLCurlEasyRequest* mCurlRequest;
+	LLCore::HttpRequest::ptr_t	mHttpRequest;
+
+
+	EStatus				mStatus;
+	CURLcode			mCurlCode;
+	std::string			mStatusMessage;
+	std::string			mStatusURI;
+	LLCore::HttpResponse::TransferStats::ptr_t	mTransferStats;
+	Handler::ptr_t		mHandler;
+	LLCore::HttpHandle	mPostH;
 
-	EStatus		mStatus;
-	CURLcode	mCurlCode;
-	std::string	mStatusMessage;
-	std::string	mStatusURI;
-	LLCurl::TransferInfo mTransferInfo;
-	
 	std::string			mURI;
-	char*				mRequestText;
-	int					mRequestTextSize;
-	
+
 	std::string			mProxyAddress;
 
 	std::string			mResponseText;
 	XMLRPC_REQUEST		mResponse;
 	std::string         mCertStore;
 	LLPointer<LLCertificate> mErrorCert;
-	
+
 	Impl(const std::string& uri, XMLRPC_REQUEST request, bool useGzip);
 	Impl(const std::string& uri,
-		 const std::string& method, LLXMLRPCValue params, bool useGzip);
+		const std::string& method, LLXMLRPCValue params, bool useGzip);
 	~Impl();
-	
+
 	bool process();
-	
-	void setStatus(EStatus code,
-				   const std::string& message = "", const std::string& uri = "");
-	void setCurlStatus(CURLcode);
+
+	void setStatus(EStatus code, const std::string& message = "", const std::string& uri = "");
+	void setHttpStatus(const LLCore::HttpStatus &status);
 
 private:
 	void init(XMLRPC_REQUEST request, bool useGzip);
-	static int _sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param);
-	static CURLcode _sslCtxFunction(CURL * curl, void *sslctx, void *param);
-	static size_t curlDownloadCallback(
-		char* data, size_t size, size_t nmemb, void* user_data);
 };
 
+LLXMLRPCTransaction::Handler::Handler(LLCore::HttpRequest::ptr_t &request, 
+		LLXMLRPCTransaction::Impl *impl) :
+	mImpl(impl),
+	mRequest(request)
+{
+}
+
+LLXMLRPCTransaction::Handler::~Handler()
+{
+}
+
+void LLXMLRPCTransaction::Handler::onCompleted(LLCore::HttpHandle handle, 
+	LLCore::HttpResponse * response)
+{
+	LLCore::HttpStatus status = response->getStatus();
+
+	if (!status)
+	{
+		if ((status.toULong() != CURLE_SSL_PEER_CERTIFICATE) &&
+			(status.toULong() != CURLE_SSL_CACERT))
+		{
+			// if we have a curl error that's not already been handled
+			// (a non cert error), then generate the error message as
+			// appropriate
+			mImpl->setHttpStatus(status);
+			LLCertificate *errordata = static_cast<LLCertificate *>(status.getErrorData());
+
+			if (errordata)
+			{
+				mImpl->mErrorCert = LLPointer<LLCertificate>(errordata);
+				status.setErrorData(NULL);
+				errordata->unref();
+			}
+
+			LL_WARNS() << "LLXMLRPCTransaction error "
+				<< status.toHex() << ": " << status.toString() << LL_ENDL;
+			LL_WARNS() << "LLXMLRPCTransaction request URI: "
+				<< mImpl->mURI << LL_ENDL;
+		}
+
+		return;
+	}
+
+	mImpl->setStatus(LLXMLRPCTransaction::StatusComplete);
+	mImpl->mTransferStats = response->getTransferStats();
+
+	// the contents of a buffer array are potentially noncontiguous, so we
+	// will need to copy them into an contiguous block of memory for XMLRPC.
+	LLCore::BufferArray *body = response->getBody();
+	char * bodydata = new char[body->size()];
+
+	body->read(0, bodydata, body->size());
+
+	mImpl->mResponse = XMLRPC_REQUEST_FromXML(bodydata, body->size(), 0);
+
+	delete[] bodydata;
+
+	bool		hasError = false;
+	bool		hasFault = false;
+	int			faultCode = 0;
+	std::string	faultString;
+
+	LLXMLRPCValue error(XMLRPC_RequestGetError(mImpl->mResponse));
+	if (error.isValid())
+	{
+		hasError = true;
+		faultCode = error["faultCode"].asInt();
+		faultString = error["faultString"].asString();
+	}
+	else if (XMLRPC_ResponseIsFault(mImpl->mResponse))
+	{
+		hasFault = true;
+		faultCode = XMLRPC_GetResponseFaultCode(mImpl->mResponse);
+		faultString = XMLRPC_GetResponseFaultString(mImpl->mResponse);
+	}
+
+	if (hasError || hasFault)
+	{
+		mImpl->setStatus(LLXMLRPCTransaction::StatusXMLRPCError);
+
+		LL_WARNS() << "LLXMLRPCTransaction XMLRPC "
+			<< (hasError ? "error " : "fault ")
+			<< faultCode << ": "
+			<< faultString << LL_ENDL;
+		LL_WARNS() << "LLXMLRPCTransaction request URI: "
+			<< mImpl->mURI << LL_ENDL;
+	}
+
+}
+
+//=========================================================================
+
 LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
 		XMLRPC_REQUEST request, bool useGzip)
-	: mCurlRequest(0),
+	: mHttpRequest(),
 	  mStatus(LLXMLRPCTransaction::StatusNotStarted),
 	  mURI(uri),
-	  mRequestText(0), 
 	  mResponse(0)
 {
 	init(request, useGzip);
@@ -212,10 +327,9 @@ LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
 
 LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
 		const std::string& method, LLXMLRPCValue params, bool useGzip)
-	: mCurlRequest(0),
+	: mHttpRequest(),
 	  mStatus(LLXMLRPCTransaction::StatusNotStarted),
 	  mURI(uri),
-	  mRequestText(0), 
 	  mResponse(0)
 {
 	XMLRPC_REQUEST request = XMLRPC_RequestNew();
@@ -231,127 +345,53 @@ LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
     XMLRPC_RequestFree(request, 1);
 }
 
-// _sslCertVerifyCallback
-// callback called when a cert verification is requested.
-// calls SECAPI to validate the context
-int LLXMLRPCTransaction::Impl::_sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
+void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
 {
-	LLXMLRPCTransaction::Impl *transaction = (LLXMLRPCTransaction::Impl *)param;
-	LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore(transaction->mCertStore);
-	LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
-	LLSD validation_params = LLSD::emptyMap();
-	LLURI uri(transaction->mURI);
-	validation_params[CERT_HOSTNAME] = uri.hostName();
-	try
-	{
-		// don't validate hostname.  Let libcurl do it instead.  That way, it'll handle redirects
-		store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params);
-	}
-	catch (LLCertValidationTrustException& cert_exception)
-	{
-		// this exception is is handled differently than the general cert
-		// exceptions, as we allow the user to actually add the certificate
-		// for trust.
-		// therefore we pass back a different error code
-		// NOTE: We're currently 'wired' to pass around CURL error codes.  This is
-		// somewhat clumsy, as we may run into errors that do not map directly to curl
-		// error codes.  Should be refactored with login refactoring, perhaps.
-		transaction->mCurlCode = CURLE_SSL_CACERT;
-		// set the status directly.  set curl status generates error messages and we want
-		// to use the fixed ones from the exceptions
-		transaction->setStatus(StatusCURLError, cert_exception.getMessage(), std::string());
-		// We should probably have a more generic way of passing information
-		// back to the error handlers.
-		transaction->mErrorCert = cert_exception.getCert();
-		return 0;		
-	}
-	catch (LLCertException& cert_exception)
-	{
-		transaction->mCurlCode = CURLE_SSL_PEER_CERTIFICATE;
-		// set the status directly.  set curl status generates error messages and we want
-		// to use the fixed ones from the exceptions
-		transaction->setStatus(StatusCURLError, cert_exception.getMessage(), std::string());
-		transaction->mErrorCert = cert_exception.getCert();
-		return 0;
-	}
-	catch (...)
-	{
-		// any other odd error, we just handle as a connect error.
-		transaction->mCurlCode = CURLE_SSL_CONNECT_ERROR;
-		transaction->setCurlStatus(CURLE_SSL_CONNECT_ERROR);
-		return 0;
-	}
-	return 1;
-}
+	LLCore::HttpOptions::ptr_t httpOpts;
+	LLCore::HttpHeaders::ptr_t httpHeaders;
 
-// _sslCtxFunction
-// Callback function called when an SSL Context is created via CURL
-// used to configure the context for custom cert validate(<, <#const & xs#>, <#T * #>, <#long #>)tion
-// based on SECAPI
-
-CURLcode LLXMLRPCTransaction::Impl::_sslCtxFunction(CURL * curl, void *sslctx, void *param)
-{
-	SSL_CTX * ctx = (SSL_CTX *) sslctx;
-	// disable any default verification for server certs
-	SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
-	// set the verification callback.
-	SSL_CTX_set_cert_verify_callback(ctx, _sslCertVerifyCallback, param);
-	// the calls are void
-	return CURLE_OK;
-	
-}
 
-void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
-{
-	if (!mCurlRequest)
+	if (!mHttpRequest)
 	{
-		mCurlRequest = new LLCurlEasyRequest();
+		mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest);
 	}
-	if(!mCurlRequest->isValid())
-	{
-		LL_WARNS() << "mCurlRequest is invalid." << LL_ENDL ;
 
-		delete mCurlRequest ;
-		mCurlRequest = NULL ;
-		return ;
-	}
+	// LLRefCounted starts with a 1 ref, so don't add a ref in the smart pointer
+	httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()); 
 
-	mErrorCert = NULL;
+	httpOpts->setTimeout(40L);
 
-//	mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // useful for debugging
-	mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
-	mCurlRequest->setWriteCallback(&curlDownloadCallback, (void*)this);
-	BOOL vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert");
+	bool vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert");
 	mCertStore = gSavedSettings.getString("CertStore");
-	mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, vefifySSLCert);
-	mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, vefifySSLCert ? 2 : 0);
-	// Be a little impatient about establishing connections.
-	mCurlRequest->setopt(CURLOPT_CONNECTTIMEOUT, 40L);
-	mCurlRequest->setSSLCtxCallback(_sslCtxFunction, (void *)this);
 
-	/* Setting the DNS cache timeout to -1 disables it completely.
-	   This might help with bug #503 */
-	mCurlRequest->setopt(CURLOPT_DNS_CACHE_TIMEOUT, -1);
+	httpOpts->setSSLVerifyPeer( vefifySSLCert );
+	httpOpts->setSSLVerifyHost( vefifySSLCert ? 2 : 0);
 
-    mCurlRequest->slist_append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
+	// LLRefCounted starts with a 1 ref, so don't add a ref in the smart pointer
+	httpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
 
-	if (useGzip)
-	{
-		mCurlRequest->setoptString(CURLOPT_ENCODING, "");
-	}
+	httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
+
+	///* Setting the DNS cache timeout to -1 disables it completely.
+	//This might help with bug #503 */
+	//httpOpts->setDNSCacheTimeout(-1);
+
+	LLCore::BufferArray::ptr_t body = LLCore::BufferArray::ptr_t(new LLCore::BufferArray());
+
+	// TODO: See if there is a way to serialize to a preallocated buffer I'm 
+	// not fond of the copy here.
+	int	requestSize(0);
+	char * requestText = XMLRPC_REQUEST_ToXML(request, &requestSize);
+
+	body->append(requestText, requestSize);
 	
-	mRequestText = XMLRPC_REQUEST_ToXML(request, &mRequestTextSize);
-	if (mRequestText)
-	{
-		mCurlRequest->setoptString(CURLOPT_POSTFIELDS, mRequestText);
-		mCurlRequest->setopt(CURLOPT_POSTFIELDSIZE, mRequestTextSize);
-	}
-	else
-	{
-		setStatus(StatusOtherError);
-	}
+	XMLRPC_Free(requestText);
+
+	mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler( mHttpRequest, this ));
+
+	mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, 0, 
+		mURI, body.get(), httpOpts.get(), httpHeaders.get(), mHandler.get());
 
-	mCurlRequest->sendRequest(mURI);
 }
 
 
@@ -361,28 +401,17 @@ LLXMLRPCTransaction::Impl::~Impl()
 	{
 		XMLRPC_RequestFree(mResponse, 1);
 	}
-	
-	if (mRequestText)
-	{
-		XMLRPC_Free(mRequestText);
-	}
-	
-	delete mCurlRequest;
-	mCurlRequest = NULL ;
 }
 
 bool LLXMLRPCTransaction::Impl::process()
 {
-	if(!mCurlRequest || !mCurlRequest->isValid())
+	if (!mPostH || !mHttpRequest)
 	{
-		LL_WARNS() << "transaction failed." << LL_ENDL ;
-
-		delete mCurlRequest ;
-		mCurlRequest = NULL ;
-		return true ; //failed, quit.
+		LL_WARNS() << "transaction failed." << LL_ENDL;
+		return true; //failed, quit.
 	}
 
-	switch(mStatus)
+	switch (mStatus)
 	{
 		case LLXMLRPCTransaction::StatusComplete:
 		case LLXMLRPCTransaction::StatusCURLError:
@@ -391,93 +420,25 @@ bool LLXMLRPCTransaction::Impl::process()
 		{
 			return true;
 		}
-		
+
 		case LLXMLRPCTransaction::StatusNotStarted:
 		{
 			setStatus(LLXMLRPCTransaction::StatusStarted);
 			break;
 		}
-		
+
 		default:
-		{
-			// continue onward
-		}
-	}
-		
-	if(!mCurlRequest->wait())
-	{
-		return false ;
+			break;
 	}
 
-	while(1)
-	{
-		CURLcode result;
-		bool newmsg = mCurlRequest->getResult(&result, &mTransferInfo);
-		if (newmsg)
-		{
-			if (result != CURLE_OK)
-			{
-				if ((result != CURLE_SSL_PEER_CERTIFICATE) &&
-					(result != CURLE_SSL_CACERT))
-				{
-					// if we have a curl error that's not already been handled
-					// (a non cert error), then generate the error message as
-					// appropriate
-					setCurlStatus(result);
-				
-					LL_WARNS() << "LLXMLRPCTransaction CURL error "
-					<< mCurlCode << ": " << mCurlRequest->getErrorString() << LL_ENDL;
-					LL_WARNS() << "LLXMLRPCTransaction request URI: "
-					<< mURI << LL_ENDL;
-				}
-					
-				return true;
-			}
-			
-			setStatus(LLXMLRPCTransaction::StatusComplete);
+	LLCore::HttpStatus status = mHttpRequest->update(0);
 
-			mResponse = XMLRPC_REQUEST_FromXML(
-					mResponseText.data(), mResponseText.size(), NULL);
-
-			bool		hasError = false;
-			bool		hasFault = false;
-			int			faultCode = 0;
-			std::string	faultString;
-
-			LLXMLRPCValue error(XMLRPC_RequestGetError(mResponse));
-			if (error.isValid())
-			{
-				hasError = true;
-				faultCode = error["faultCode"].asInt();
-				faultString = error["faultString"].asString();
-			}
-			else if (XMLRPC_ResponseIsFault(mResponse))
-			{
-				hasFault = true;
-				faultCode = XMLRPC_GetResponseFaultCode(mResponse);
-				faultString = XMLRPC_GetResponseFaultString(mResponse);
-			}
-
-			if (hasError || hasFault)
-			{
-				setStatus(LLXMLRPCTransaction::StatusXMLRPCError);
-				
-				LL_WARNS() << "LLXMLRPCTransaction XMLRPC "
-						<< (hasError ? "error " : "fault ")
-						<< faultCode << ": "
-						<< faultString << LL_ENDL;
-				LL_WARNS() << "LLXMLRPCTransaction request URI: "
-						<< mURI << LL_ENDL;
-			}
-			
-			return true;
-		}
-		else
-		{
-			break; // done
-		}
+	status = mHttpRequest->getStatus();
+	if (!status) 
+	{
+		return false;
 	}
-	
+
 	return false;
 }
 
@@ -516,64 +477,51 @@ void LLXMLRPCTransaction::Impl::setStatus(EStatus status,
 	}
 }
 
-void LLXMLRPCTransaction::Impl::setCurlStatus(CURLcode code)
+void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status)
 {
+	CURLcode code = static_cast<CURLcode>(status.toULong());
 	std::string message;
 	std::string uri = "http://secondlife.com/community/support.php";
-	
+	LLURI failuri(mURI);
+
+
 	switch (code)
 	{
-		case CURLE_COULDNT_RESOLVE_HOST:
-			message =
-				"DNS could not resolve the host name.\n"
-				"Please verify that you can connect to the www.secondlife.com\n"
-				"web site.  If you can, but continue to receive this error,\n"
-				"please go to the support section and report this problem.";
-			break;
-			
-		case CURLE_SSL_PEER_CERTIFICATE:
-			message =
-				"The login server couldn't verify itself via SSL.\n"
-				"If you continue to receive this error, please go\n"
-				"to the Support section of the SecondLife.com web site\n"
-				"and report the problem.";
-			break;
-			
-		case CURLE_SSL_CACERT:
-		case CURLE_SSL_CONNECT_ERROR:
-			message =
-				"Often this means that your computer\'s clock is set incorrectly.\n"
-				"Please go to Control Panels and make sure the time and date\n"
-				"are set correctly.\n"
-				"Also check that your network and firewall are set up correctly.\n"
-				"If you continue to receive this error, please go\n"
-				"to the Support section of the SecondLife.com web site\n"
-				"and report the problem.";
-			break;
-			
-		default:
-				break;
+	case CURLE_COULDNT_RESOLVE_HOST:
+		message =
+			std::string("DNS could not resolve the host name(") + failuri.hostName() + ").\n"
+			"Please verify that you can connect to the www.secondlife.com\n"
+			"web site.  If you can, but continue to receive this error,\n"
+			"please go to the support section and report this problem.";
+		break;
+
+	case CURLE_SSL_PEER_CERTIFICATE:
+		message =
+			"The login server couldn't verify itself via SSL.\n"
+			"If you continue to receive this error, please go\n"
+			"to the Support section of the SecondLife.com web site\n"
+			"and report the problem.";
+		break;
+
+	case CURLE_SSL_CACERT:
+	case CURLE_SSL_CONNECT_ERROR:
+		message =
+			"Often this means that your computer\'s clock is set incorrectly.\n"
+			"Please go to Control Panels and make sure the time and date\n"
+			"are set correctly.\n"
+			"Also check that your network and firewall are set up correctly.\n"
+			"If you continue to receive this error, please go\n"
+			"to the Support section of the SecondLife.com web site\n"
+			"and report the problem.";
+		break;
+
+	default:
+		break;
 	}
-	
+
 	mCurlCode = code;
 	setStatus(StatusCURLError, message, uri);
-}
-
-size_t LLXMLRPCTransaction::Impl::curlDownloadCallback(
-		char* data, size_t size, size_t nmemb, void* user_data)
-{
-	Impl& impl(*(Impl*)user_data);
-	
-	size_t n = size * nmemb;
 
-	impl.mResponseText.append(data, n);
-	
-	if (impl.mStatus == LLXMLRPCTransaction::StatusStarted)
-	{
-		impl.setStatus(LLXMLRPCTransaction::StatusDownloading);
-	}
-	
-	return n;
 }
 
 
@@ -645,11 +593,11 @@ F64 LLXMLRPCTransaction::transferRate()
 		return 0.0L;
 	}
 	
-	double rate_bits_per_sec = impl.mTransferInfo.mSpeedDownload * 8.0;
+	double rate_bits_per_sec = impl.mTransferStats->mSpeedDownload * 8.0;
 	
 	LL_INFOS("AppInit") << "Buffer size:   " << impl.mResponseText.size() << " B" << LL_ENDL;
-	LL_DEBUGS("AppInit") << "Transfer size: " << impl.mTransferInfo.mSizeDownload << " B" << LL_ENDL;
-	LL_DEBUGS("AppInit") << "Transfer time: " << impl.mTransferInfo.mTotalTime << " s" << LL_ENDL;
+	LL_DEBUGS("AppInit") << "Transfer size: " << impl.mTransferStats->mSizeDownload << " B" << LL_ENDL;
+	LL_DEBUGS("AppInit") << "Transfer time: " << impl.mTransferStats->mTotalTime << " s" << LL_ENDL;
 	LL_INFOS("AppInit") << "Transfer rate: " << rate_bits_per_sec / 1000.0 << " Kb/s" << LL_ENDL;
 
 	return rate_bits_per_sec;
diff --git a/indra/newview/llxmlrpctransaction.h b/indra/newview/llxmlrpctransaction.h
index f2589c7f411640aa7b5e8f2ff99b518cdd11c0a6..3a1c9c82b70ff9defc42fff2872f456262fe0bae 100755
--- a/indra/newview/llxmlrpctransaction.h
+++ b/indra/newview/llxmlrpctransaction.h
@@ -81,7 +81,7 @@ class LLXMLRPCValue
 
 
 class LLXMLRPCTransaction
-	// an asynchronous request and respones via XML-RPC
+	// an asynchronous request and responses via XML-RPC
 {
 public:
 	LLXMLRPCTransaction(const std::string& uri,
@@ -127,7 +127,9 @@ class LLXMLRPCTransaction
 		// only valid if StsatusComplete, otherwise 0.0
 		
 private:
+	class Handler;
 	class Impl;
+
 	Impl& impl;
 };
 
diff --git a/indra/newview/tests/llcapabilitylistener_test.cpp b/indra/newview/tests/llcapabilitylistener_test.cpp
deleted file mode 100755
index bde991a01e873531f0d6588c4a602b7a72247a54..0000000000000000000000000000000000000000
--- a/indra/newview/tests/llcapabilitylistener_test.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
- * @file   llcapabilitylistener_test.cpp
- * @author Nat Goodspeed
- * @date   2008-12-31
- * @brief  Test for llcapabilitylistener.cpp.
- * 
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-// Precompiled header
-#include "../llviewerprecompiledheaders.h"
-// Own header
-#include "../llcapabilitylistener.h"
-// STL headers
-#include <stdexcept>
-#include <map>
-#include <vector>
-// std headers
-// external library headers
-#include "boost/bind.hpp"
-// other Linden headers
-#include "../test/lltut.h"
-#include "../llcapabilityprovider.h"
-#include "lluuid.h"
-#include "tests/networkio.h"
-#include "tests/commtest.h"
-#include "tests/wrapllerrs.h"
-#include "message.h"
-#include "stringize.h"
-
-#if defined(LL_WINDOWS)
-#pragma warning(disable: 4355)      // using 'this' in base-class ctor initializer expr
-#endif
-
-/*****************************************************************************
-*   TestCapabilityProvider
-*****************************************************************************/
-struct TestCapabilityProvider: public LLCapabilityProvider
-{
-    TestCapabilityProvider(const LLHost& host):
-        mHost(host)
-    {}
-
-    std::string getCapability(const std::string& cap) const
-    {
-        CapMap::const_iterator found = mCaps.find(cap);
-        if (found != mCaps.end())
-            return found->second;
-        // normal LLViewerRegion lookup failure mode
-        return "";
-    }
-    void setCapability(const std::string& cap, const std::string& url)
-    {
-        mCaps[cap] = url;
-    }
-    const LLHost& getHost() const { return mHost; }
-    std::string getDescription() const { return "TestCapabilityProvider"; }
-
-    LLHost mHost;
-    typedef std::map<std::string, std::string> CapMap;
-    CapMap mCaps;
-};
-
-/*****************************************************************************
-*   Dummy LLMessageSystem methods
-*****************************************************************************/
-/*==========================================================================*|
-// This doesn't work because we're already linking in llmessage.a, and we get
-// duplicate-symbol errors from the linker. Perhaps if I wanted to go through
-// the exercise of providing dummy versions of every single symbol defined in
-// message.o -- maybe some day.
-typedef std::vector< std::pair<std::string, std::string> > StringPairVector;
-StringPairVector call_history;
-
-S32 LLMessageSystem::sendReliable(const LLHost& host)
-{
-    call_history.push_back(StringPairVector::value_type("sendReliable", stringize(host)));
-    return 0;
-}
-|*==========================================================================*/
-
-/*****************************************************************************
-*   TUT
-*****************************************************************************/
-namespace tut
-{
-    struct llcapears_data: public commtest_data
-    {
-        TestCapabilityProvider provider;
-        LLCapabilityListener regionListener;
-        LLEventPump& regionPump;
-
-        llcapears_data():
-            provider(host),
-            regionListener("testCapabilityListener", NULL, provider, LLUUID(), LLUUID()),
-            regionPump(regionListener.getCapAPI())
-        {
-            LLCurl::initClass();
-            provider.setCapability("good", server + "capability-test");
-            provider.setCapability("fail", server + "fail");
-        }
-    };
-    typedef test_group<llcapears_data> llcapears_group;
-    typedef llcapears_group::object llcapears_object;
-    llcapears_group llsdmgr("llcapabilitylistener");
-
-    template<> template<>
-    void llcapears_object::test<1>()
-    {
-        LLSD request, body;
-        body["data"] = "yes";
-        request["payload"] = body;
-        request["reply"] = replyPump.getName();
-        request["error"] = errorPump.getName();
-        std::string threw;
-        try
-        {
-            WrapLLErrs capture;
-            regionPump.post(request);
-        }
-        catch (const WrapLLErrs::FatalException& e)
-        {
-            threw = e.what();
-        }
-        ensure_contains("missing capability name", threw, "without 'message' key");
-    }
-
-    template<> template<>
-    void llcapears_object::test<2>()
-    {
-        LLSD request, body;
-        body["data"] = "yes";
-        request["message"] = "good";
-        request["payload"] = body;
-        request["reply"] = replyPump.getName();
-        request["error"] = errorPump.getName();
-        regionPump.post(request);
-        ensure("got response", netio.pump());
-        ensure("success response", success);
-        ensure_equals(result["reply"].asString(), "success");
-
-        body["status"] = 499;
-        body["reason"] = "custom error message";
-        request["message"] = "fail";
-        request["payload"] = body;
-        regionPump.post(request);
-        ensure("got response", netio.pump());
-        ensure("failure response", ! success);
-        ensure_equals(result["status"].asInteger(), body["status"].asInteger());
-        ensure_equals(result["reason"].asString(),  body["reason"].asString());
-    }
-
-    template<> template<>
-    void llcapears_object::test<3>()
-    {
-        LLSD request, body;
-        body["data"] = "yes";
-        request["message"] = "unknown";
-        request["payload"] = body;
-        request["reply"] = replyPump.getName();
-        request["error"] = errorPump.getName();
-        std::string threw;
-        try
-        {
-            WrapLLErrs capture;
-            regionPump.post(request);
-        }
-        catch (const WrapLLErrs::FatalException& e)
-        {
-            threw = e.what();
-        }
-        ensure_contains("bad capability name", threw, "unsupported capability");
-    }
-
-    struct TestMapper: public LLCapabilityListener::CapabilityMapper
-    {
-        // Instantiator gets to specify whether mapper expects a reply.
-        // I'd really like to be able to test CapabilityMapper::buildMessage()
-        // functionality, too, but -- even though LLCapabilityListener accepts
-        // the LLMessageSystem* that it passes to CapabilityMapper --
-        // LLMessageSystem::sendReliable(const LLHost&) isn't virtual, so it's
-        // not helpful to pass a subclass instance. I suspect that making any
-        // LLMessageSystem methods virtual would provoke howls of outrage,
-        // given how heavily it's used. Nor can I just provide a local
-        // definition of LLMessageSystem::sendReliable(const LLHost&) because
-        // we're already linking in the rest of message.o via llmessage.a, and
-        // that produces duplicate-symbol link errors.
-        TestMapper(const std::string& replyMessage = std::string()):
-            LLCapabilityListener::CapabilityMapper("test", replyMessage)
-        {}
-        virtual void buildMessage(LLMessageSystem* msg,
-                                  const LLUUID& agentID,
-                                  const LLUUID& sessionID,
-                                  const std::string& capabilityName,
-                                  const LLSD& payload) const
-        {
-            msg->newMessageFast(_PREHASH_SetStartLocationRequest);
-            msg->nextBlockFast( _PREHASH_AgentData);
-            msg->addUUIDFast(_PREHASH_AgentID, agentID);
-            msg->addUUIDFast(_PREHASH_SessionID, sessionID);
-            msg->nextBlockFast( _PREHASH_StartLocationData);
-            // corrected by sim
-            msg->addStringFast(_PREHASH_SimName, "");
-            msg->addU32Fast(_PREHASH_LocationID, payload["HomeLocation"]["LocationId"].asInteger());
-/*==========================================================================*|
-            msg->addVector3Fast(_PREHASH_LocationPos,
-                                ll_vector3_from_sdmap(payload["HomeLocation"]["LocationPos"]));
-            msg->addVector3Fast(_PREHASH_LocationLookAt,
-                                ll_vector3_from_sdmap(payload["HomeLocation"]["LocationLookAt"]));
-|*==========================================================================*/
-        }
-    };
-
-    template<> template<>
-    void llcapears_object::test<4>()
-    {
-        TestMapper testMapper("WantReply");
-        LLSD request, body;
-        body["data"] = "yes";
-        request["message"] = "test";
-        request["payload"] = body;
-        request["reply"] = replyPump.getName();
-        request["error"] = errorPump.getName();
-        std::string threw;
-        try
-        {
-            WrapLLErrs capture;
-            regionPump.post(request);
-        }
-        catch (const WrapLLErrs::FatalException& e)
-        {
-            threw = e.what();
-        }
-        ensure_contains("capability mapper wants reply", threw, "unimplemented support for reply message");
-    }
-
-    template<> template<>
-    void llcapears_object::test<5>()
-    {
-        TestMapper testMapper;
-        std::string threw;
-        try
-        {
-            TestMapper testMapper2;
-        }
-        catch (const std::runtime_error& e)
-        {
-            threw = e.what();
-        }
-        ensure_contains("no dup cap mapper", threw, "DupCapMapper");
-    }
-}
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 6f57daf1519a096c00057ddf7b6020a174d9f952..61120686e4c623df82742e14ef06dad812c093e8 100755
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -106,7 +106,7 @@ const char *DATA = _DATA(VALID_OBJECT_ID,"1.0","true");
 
 LLSD *gPostRecords = NULL;
 F64   gMinimumInterestLevel = (F64)0.0;
-
+#if 0
 // stubs:
 void LLHTTPClient::post(
 		const std::string& url,
@@ -140,6 +140,7 @@ void LLHTTPClient::post(
 	}
 	responder->successResult(result);
 }
+#endif
 
 const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
 
diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp
index c49b0350e9b279925145c3674de7861cbd8a9297..ea5014a59c2fa4c07319766567296d7204514a41 100755
--- a/indra/newview/tests/llremoteparcelrequest_test.cpp
+++ b/indra/newview/tests/llremoteparcelrequest_test.cpp
@@ -27,6 +27,7 @@
 #include "linden_common.h"
 
 #include "../test/lltut.h"
+#if 0
 
 #include "../llremoteparcelrequest.h"
 
@@ -134,3 +135,4 @@ namespace tut
 		processor.processParcelInfoReply(gMessageSystem, NULL);
 	}
 }
+#endif
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index b8408a6fb45bf5ec771382ffc376eff823c534b2..88415ff11ae47b685857eab6dd3d9d3f4ff47d6c 100755
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -107,9 +107,8 @@ class LLLogin::Impl
     }
 
     // In a coroutine's top-level function args, do NOT NOT NOT accept
-    // references (const or otherwise) to anything but the self argument! Pass
-    // by value only!
-    void login_(LLCoros::self& self, std::string uri, LLSD credentials);
+    // references (const or otherwise) to anything! Pass by value only!
+    void login_(std::string uri, LLSD credentials);
 
     LLEventStream mPump;
 	LLSD mAuthResponse, mValidAuthResponse;
@@ -123,11 +122,11 @@ void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params)
     // its first wait; at that point, return here.
     std::string coroname = 
         LLCoros::instance().launch("LLLogin::Impl::login_",
-                                   boost::bind(&Impl::login_, this, _1, uri, login_params));
+                                   boost::bind(&Impl::login_, this, uri, login_params));
     LL_DEBUGS("LLLogin") << " connected with  uri '" << uri << "', login_params " << login_params << LL_ENDL;	
 }
 
-void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_params)
+void LLLogin::Impl::login_(std::string uri, LLSD login_params)
 {
 	try
 	{
@@ -137,7 +136,7 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
 	//{
 	//	printable_params["params"]["passwd"] = "*******";
 	//}
-	LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self)
+	LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName()
                         << " with uri '" << uri << "', parameters " << printable_params << LL_ENDL;
 
 	// Arriving in SRVRequest state
@@ -176,7 +175,7 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
 		request["op"] = "rewriteURI";
 		request["uri"] = uri;
 		request["reply"] = replyPump.getName();
-		rewrittenURIs = postAndWait(self, request, srv_pump_name, filter);
+		rewrittenURIs = llcoro::postAndWait(request, srv_pump_name, filter);
 		// EXP-772: If rewrittenURIs fail, try original URI as a fallback.
 		rewrittenURIs.append(uri);
     } // we no longer need the filter
@@ -222,10 +221,10 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
             // returns. Subsequent responses, of course, must be awaited
             // without posting again.
             for (mAuthResponse = validateResponse(loginReplyPump.getName(),
-                                 postAndWait(self, request, xmlrpcPump, loginReplyPump, "reply"));
+                     llcoro::postAndWait(request, xmlrpcPump, loginReplyPump, "reply"));
                  mAuthResponse["status"].asString() == "Downloading";
                  mAuthResponse = validateResponse(loginReplyPump.getName(),
-                                     waitForEventOn(self, loginReplyPump)))
+                                                  llcoro::waitForEventOn(loginReplyPump)))
             {
                 // Still Downloading -- send progress update.
                 sendProgressEvent("offline", "downloading");
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index 61fd4220e0d310461ba59a1a2409781808dcad19..53e309290f613164302a284054232308ba755477 100755
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -9,12 +9,14 @@ endif(LL_TESTS)
 include(CMakeCopyIfDifferent)
 include(CURL)
 include(LLCommon)
+include(LLCoreHttp)
 include(LLMessage)
 include(LLPlugin)
 include(LLVFS)
 
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
+    ${LLCOREHTTP_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
     ${LLPLUGIN_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
@@ -59,6 +61,7 @@ add_library(llupdaterservice
 
 target_link_libraries(llupdaterservice
     ${LLCOMMON_LIBRARIES}
+    ${LLCOREHTTP_LIBRARIES}
     ${LLMESSAGE_LIBRARIES}
     ${LLPLUGIN_LIBRARIES}
     ${LLVFS_LIBRARIES}
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index 8da4f88905c51f9ad365c7e4007352480858268a..e889f83aa9fa69aae1d2735a79a1e1b83a3eb71e 100755
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -26,10 +26,10 @@
 #include "linden_common.h"
 #include <stdexcept>
 #include <boost/format.hpp>
-#include "llhttpclient.h"
 #include "llsd.h"
 #include "llupdatechecker.h"
 #include "lluri.h"
+#include "llcorehttputil.h"
 #if LL_DARWIN
 #include <CoreServices/CoreServices.h>
 #endif
@@ -53,15 +53,12 @@ class LLUpdateChecker::CheckError:
 
 // LLUpdateChecker
 //-----------------------------------------------------------------------------
-
-
 LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
 	mImplementation(new LLUpdateChecker::Implementation(client))
 {
 	; // No op.
 }
 
-
 void LLUpdateChecker::checkVersion(std::string const & urlBase, 
 								   std::string const & channel,
 								   std::string const & version,
@@ -74,11 +71,8 @@ void LLUpdateChecker::checkVersion(std::string const & urlBase,
 }
 
 
-
 // LLUpdateChecker::Implementation
 //-----------------------------------------------------------------------------
-
-
 const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.1";
 
 
@@ -121,57 +115,58 @@ void LLUpdateChecker::Implementation::checkVersion(std::string const & urlBase,
 
 		std::string checkUrl = buildUrl(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test);
 		LL_INFOS("UpdaterService") << "checking for updates at " << checkUrl << LL_ENDL;
-	
-		mHttpClient.get(checkUrl, this);
-	}
-	else
-	{
-		LL_WARNS("UpdaterService") << "attempting to restart a check when one is in progress; ignored" << LL_ENDL;
-	}
-}
 
-void LLUpdateChecker::Implementation::httpCompleted()
-{
-	mInProgress = false;	
+        LLCoros::instance().launch("LLUpdateChecker::Implementation::checkVersionCoro",
+            boost::bind(&Implementation::checkVersionCoro, this, checkUrl));
 
-	S32 status = getStatus();
-	const LLSD& content = getContent();
-	const std::string& reason = getReason();
-	if(status != 200)
-	{
-		std::string server_error;
-		if ( content.has("error_code") )
-		{
-			server_error += content["error_code"].asString();
-		}
-		if ( content.has("error_text") )
-		{
-			server_error += server_error.empty() ? "" : ": ";
-			server_error += content["error_text"].asString();
-		}
-
-		LL_WARNS("UpdaterService") << "response error " << status
-								   << " " << reason
-								   << " (" << server_error << ")"
-								   << LL_ENDL;
-		mClient.error(reason);
 	}
 	else
 	{
-		mClient.response(content);
+		LL_WARNS("UpdaterService") << "attempting to restart a check when one is in progress; ignored" << LL_ENDL;
 	}
 }
 
-
-void LLUpdateChecker::Implementation::httpFailure()
+void LLUpdateChecker::Implementation::checkVersionCoro(std::string url)
 {
-	const std::string& reason = getReason();
-	mInProgress = false;
-	LL_WARNS("UpdaterService") << "update check failed; " << reason << LL_ENDL;
-	mClient.error(reason);
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("checkVersionCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LL_INFOS("checkVersionCoro") << "Getting update information from " << url << LL_ENDL;
+
+    LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    mInProgress = false;
+
+    if (status != LLCore::HttpStatus(HTTP_OK))
+    {
+        std::string server_error;
+        if (result.has("error_code"))
+        {
+            server_error += result["error_code"].asString();
+        }
+        if (result.has("error_text"))
+        {
+            server_error += server_error.empty() ? "" : ": ";
+            server_error += result["error_text"].asString();
+        }
+
+        LL_WARNS("UpdaterService") << "response error " << status.getStatus()
+            << " " << status.toString()
+            << " (" << server_error << ")"
+            << LL_ENDL;
+        mClient.error(status.toString());
+        return;
+    }
+
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+    mClient.response(result);
 }
 
-
 std::string LLUpdateChecker::Implementation::buildUrl(std::string const & urlBase, 
 													  std::string const & channel,
 													  std::string const & version,
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
index 3163a6d53c517801c5d4509bb25809686678f2a9..d10ea4cf42e0d526699d5eb71060d245a110635c 100755
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -30,61 +30,27 @@
 #include <boost/shared_ptr.hpp>
 
 #include "llmd5.h"
-#include "llhttpclient.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
 
 //
 // Implements asynchronous checking for updates.
 //
 class LLUpdateChecker {
 public:
-	class Client;
-	class Implementation: public LLHTTPClient::Responder
-	{
-	public:
-		Implementation(Client & client);
-		~Implementation();
-		void checkVersion(std::string const & urlBase, 
-						  std::string const & channel,
-						  std::string const & version,
-						  std::string const & platform,
-						  std::string const & platform_version,
-						  unsigned char       uniqueid[MD5HEX_STR_SIZE],
-						  bool                willing_to_test
-						  );
-	
-    protected:
-		// Responder:
-		virtual void httpCompleted();
-		virtual void httpFailure();
-	
-	private:	
-		static const char * sLegacyProtocolVersion;
-		static const char * sProtocolVersion;
-		const char* mProtocol;
-		
-		Client & mClient;
-		LLHTTPClient mHttpClient;
-		bool         mInProgress;
-		std::string   mVersion;
-		std::string   mUrlBase;
-		std::string   mChannel;
-		std::string   mPlatform;
-		std::string   mPlatformVersion;
-		unsigned char mUniqueId[MD5HEX_STR_SIZE];
-		bool          mWillingToTest;
-		
-		std::string buildUrl(std::string const & urlBase, 
-							 std::string const & channel,
-							 std::string const & version,
-							 std::string const & platform,
-							 std::string const & platform_version,
-							 unsigned char       uniqueid[MD5HEX_STR_SIZE],
-							 bool                willing_to_test);
-
-		LOG_CLASS(LLUpdateChecker::Implementation);
-	};
+    //
+    // The client interface implemented by a requestor checking for an update.
+    //
+    class Client
+    {
+    public:
+        // An error occurred while checking for an update.
+        virtual void error(std::string const & message) = 0;
+
+        // A successful response was received from the viewer version manager
+        virtual void response(LLSD const & content) = 0;
+    };
 
-	
 	// An exception that may be raised on check errors.
 	class CheckError;
 	
@@ -100,25 +66,54 @@ class LLUpdateChecker {
 					  bool                willing_to_test);
 	
 private:
-	LLPointer<Implementation> mImplementation;
-};
+    class Implementation
+    {
+    public:
+        typedef boost::shared_ptr<Implementation> ptr_t;
 
+        Implementation(Client & client);
+        ~Implementation();
+        void checkVersion(std::string const & urlBase,
+            std::string const & channel,
+            std::string const & version,
+            std::string const & platform,
+            std::string const & platform_version,
+            unsigned char       uniqueid[MD5HEX_STR_SIZE],
+            bool                willing_to_test
+            );
 
-class LLURI; // From lluri.h
 
+    private:
+        static const char * sLegacyProtocolVersion;
+        static const char * sProtocolVersion;
+        const char* mProtocol;
 
-//
-// The client interface implemented by a requestor checking for an update.
-//
-class LLUpdateChecker::Client
-{
-public:
-	// An error occurred while checking for an update.
-	virtual void error(std::string const & message) = 0;
-	
-	// A successful response was received from the viewer version manager
-	virtual void response(LLSD const & content) = 0;
-};
+        Client & mClient;
+        bool         mInProgress;
+        std::string   mVersion;
+        std::string   mUrlBase;
+        std::string   mChannel;
+        std::string   mPlatform;
+        std::string   mPlatformVersion;
+        unsigned char mUniqueId[MD5HEX_STR_SIZE];
+        bool          mWillingToTest;
+
+        std::string buildUrl(std::string const & urlBase,
+            std::string const & channel,
+            std::string const & version,
+            std::string const & platform,
+            std::string const & platform_version,
+            unsigned char       uniqueid[MD5HEX_STR_SIZE],
+            bool                willing_to_test);
+
+        void checkVersionCoro(std::string url);
 
+        LOG_CLASS(LLUpdateChecker::Implementation);
+    };
+
+
+    Implementation::ptr_t       mImplementation;
+	//LLPointer<Implementation> mImplementation;
+};
 
 #endif
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index c6070020db4973d22e92d40adb2a7486327ce868..144d037a319e69436a60d2999adc836f1c23d920 100755
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -4,6 +4,7 @@ project(win_crash_logger)
 
 include(00-Common)
 include(LLCommon)
+include(LLCoreHttp)
 include(LLCrashLogger)
 include(LLMath)
 include(LLMessage)
@@ -13,8 +14,10 @@ include(LLXML)
 include(Linking)
 include(LLSharedLibs)
 include(GoogleBreakpad)
+include(Boost)
 
 include_directories(
+    ${LLCOREHTTP_INCLUDE_DIRS}
     ${LLCOMMON_INCLUDE_DIRS}
     ${LLCRASHLOGGER_INCLUDE_DIRS}
     ${LLMATH_INCLUDE_DIRS}
@@ -77,7 +80,10 @@ target_link_libraries(windows-crash-logger
     ${LLXML_LIBRARIES}
     ${LLMESSAGE_LIBRARIES}
     ${LLMATH_LIBRARIES}
+    ${LLCOREHTTP_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
+    ${BOOST_CONTEXT_LIBRARY}
+    ${BOOST_COROUTINE_LIBRARY}
     ${WINDOWS_LIBRARIES}
     ${DXGUID_LIBRARY}
     ${GOOGLE_PERFTOOLS_LIBRARIES}