diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index d3d75f78df06f7e2bbfd5f64b16a22b24ed83360..62476fd59d0b10a3009f4b2b4c242c879bcf8829 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -228,4 +228,4 @@ target_link_libraries(
 
 ADD_BUILD_TEST(lllazy llcommon)
 ADD_BUILD_TEST(lleventfilter llcommon)
-ADD_BUILD_TEST(coroutine llcommon)
+ADD_BUILD_TEST(lleventcoro llcommon)
diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cd39ac4df3ce5c65e7417bf2bedf13a539410bba
--- /dev/null
+++ b/indra/llcommon/tests/lleventcoro_test.cpp
@@ -0,0 +1,827 @@
+/**
+ * @file   coroutine_test.cpp
+ * @author Nat Goodspeed
+ * @date   2009-04-22
+ * @brief  Test for coroutine.
+ * 
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+/*****************************************************************************/
+//  test<1>() is cloned from a Boost.Coroutine example program whose copyright
+//  info is reproduced here:
+/*---------------------------------------------------------------------------*/
+//  Copyright (c) 2006, Giovanni P. Deretta
+//
+//  This code may be used under either of the following two licences:
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy 
+//  of this software and associated documentation files (the "Software"), to deal 
+//  in the Software without restriction, including without limitation the rights 
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+//  copies of the Software, and to permit persons to whom the Software is 
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in 
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
+//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
+//  THE SOFTWARE. OF SUCH DAMAGE.
+//
+//  Or:
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+/*****************************************************************************/
+
+// 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.
+#include <boost/coroutine/coroutine.hpp>
+// Normally, lleventcoro.h obviates future.hpp. We only include this because
+// we implement a "by hand" test of future functionality.
+#include <boost/coroutine/future.hpp>
+#include <boost/bind.hpp>
+#include <boost/range.hpp>
+#include <iostream>
+#include <string>
+
+#include "../test/lltut.h"
+#include "llsd.h"
+#include "llevents.h"
+#include "tests/wrapllerrs.h"
+#include "stringize.h"
+#include "lleventcoro.h"
+
+/*****************************************************************************
+*   Debugging stuff
+*****************************************************************************/
+// This class is intended to illuminate entry to a given block, exit from the
+// same block and checkpoints along the way. It also provides a convenient
+// place to turn std::cout output on and off.
+class Debug
+{
+public:
+    Debug(const std::string& block):
+        mBlock(block)
+    {
+        (*this)("entry");
+    }
+
+    ~Debug()
+    {
+        (*this)("exit");
+    }
+
+    void operator()(const std::string& status)
+    {
+//      std::cout << mBlock << ' ' << status << std::endl;
+    }
+
+private:
+    const std::string mBlock;
+};
+
+// It's often convenient to use the name of the enclosing function as the name
+// of the Debug block.
+#define DEBUG Debug debug(__FUNCTION__)
+
+// These BEGIN/END macros are specifically for debugging output -- please
+// don't assume you must use such for coroutines in general! They only help to
+// make control flow (as well as exception exits) explicit.
+#define BEGIN                                   \
+{                                               \
+    DEBUG;                                      \
+    try
+
+#define END                                             \
+    catch (...)                                         \
+    {                                                   \
+/*      std::cout << "*** exceptional " << std::flush; */    \
+        throw;                                          \
+    }                                                   \
+}
+
+/*****************************************************************************
+*   from the banana.cpp example program borrowed for test<1>()
+*****************************************************************************/
+namespace coroutines = boost::coroutines;
+using coroutines::coroutine;
+
+template<typename Iter>
+bool match(Iter first, Iter last, std::string match) {
+  std::string::iterator i = match.begin();
+  i != match.end();
+  for(; (first != last) && (i != match.end()); ++i) {
+    if (*first != *i)
+      return false;
+    ++first;
+  }
+  return i == match.end();
+}
+
+template<typename BidirectionalIterator> 
+BidirectionalIterator 
+match_substring(BidirectionalIterator begin, 
+		BidirectionalIterator end, 
+		std::string xmatch,
+		BOOST_DEDUCED_TYPENAME coroutine<BidirectionalIterator(void)>::self& self) { 
+  BidirectionalIterator begin_ = begin;
+  for(; begin != end; ++begin) 
+    if(match(begin, end, xmatch)) {
+      self.yield(begin);
+    }
+  return end;
+} 
+
+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::coroutines::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
+/// waitForEventOn().
+class ImmediateAPI
+{
+public:
+    ImmediateAPI():
+        mPump("immediate", true)
+    {
+        mPump.listen("API", boost::bind(&ImmediateAPI::operator(), this, _1));
+    }
+
+    LLEventPump& getPump() { return mPump; }
+
+    // Invoke this with an LLSD map containing:
+    // ["value"]: Integer value. We will reply with ["value"] + 1.
+    // ["reply"]: Name of LLEventPump on which to send success response.
+    // ["error"]: Name of LLEventPump on which to send error response.
+    // ["fail"]: Presence of this key selects ["error"], else ["success"] as
+    // the name of the pump on which to send the response.
+    bool operator()(const LLSD& event) const
+    {
+        LLSD::Integer value(event["value"]);
+        LLSD::String replyPumpName(event.has("fail")? "error" : "reply");
+        LLEventPumps::instance().obtain(event[replyPumpName]).post(value + 1);
+        return false;
+    }
+
+private:
+    LLEventStream mPump;
+};
+
+/*****************************************************************************
+*   TUT
+*****************************************************************************/
+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::coroutines::future<LLSD> future(self);
+                // tell the future what to wait for
+                LLTempBoundListener connection(
+                    LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::coroutines::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,
+                                     LLSD().insert("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,
+                                                    LLSD().insert("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,
+                                                    LLSD().insert("value", 18).insert("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, LLSD().insert("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();
+                WrapLL_ERRS capture;
+                try
+                {
+                    result = waiter.waitWithLog(self);
+                    debug("no exception");
+                }
+                catch (const WrapLL_ERRS::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, LLSD().insert("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, LLSD().insert("value", 23).insert("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, LLSD().insert("value", 8),
+                                                         immediateAPI.getPump(), "reply", "error");
+            }
+            END
+        }
+
+        void coroPumpsPostEx(coroutine_type::self& self)
+        {
+            BEGIN
+            {
+                LLCoroEventPumps waiter;
+                try
+                {
+                    result = waiter.postAndWaitWithException(self,
+                        LLSD().insert("value", 9).insert("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, LLSD().insert("value", 30),
+                                                   immediateAPI.getPump(), "reply", "error");
+            }
+            END
+        }
+
+        void coroPumpsPostLog(coroutine_type::self& self)
+        {
+            BEGIN
+            {
+                LLCoroEventPumps waiter;
+                WrapLL_ERRS capture;
+                try
+                {
+                    result = waiter.postAndWaitWithLog(self,
+                        LLSD().insert("value", 31).insert("fail", LLSD()),
+                        immediateAPI.getPump(), "reply", "error");
+                    debug("no exception");
+                }
+                catch (const WrapLL_ERRS::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;
+    };
+    typedef test_group<coroutine_data> coroutine_group;
+    typedef coroutine_group::object object;
+    coroutine_group coroutinegrp("coroutine");
+
+    template<> template<>
+    void object::test<1>()
+    {
+        set_test_name("From banana.cpp example program in Boost.Coroutine distro");
+        std::string buffer = "banananana"; 
+        std::string match = "nana"; 
+        std::string::iterator begin = buffer.begin();
+        std::string::iterator end = buffer.end();
+
+#if defined(BOOST_CORO_POSIX_IMPL)
+//      std::cout << "Using Boost.Coroutine " << BOOST_CORO_POSIX_IMPL << '\n';
+#else
+//      std::cout << "Using non-Posix Boost.Coroutine implementation" << std::endl;
+#endif
+
+        typedef std::string::iterator signature(std::string::iterator, 
+                                                std::string::iterator, 
+                                                std::string,
+                                                match_coroutine_type::self&);
+
+        coroutine<std::string::iterator(void)> matcher
+            (boost::bind(static_cast<signature*>(match_substring), 
+                         begin, 
+                         end, 
+                         match, 
+                         _1)); 
+
+        std::string::iterator i = matcher();
+/*==========================================================================*|
+        while(matcher && i != buffer.end()) {
+            std::cout <<"Match at: "<< std::distance(buffer.begin(), i)<<'\n'; 
+            i = matcher();
+        }
+|*==========================================================================*/
+        size_t matches[] = { 2, 4, 6 };
+        for (size_t *mi(boost::begin(matches)), *mend(boost::end(matches));
+             mi != mend; ++mi, i = matcher())
+        {
+            ensure("more", matcher);
+            ensure("found", i != buffer.end());
+            ensure_equals("value", std::distance(buffer.begin(), i), *mi);
+        }
+        ensure("done", ! matcher);
+    }
+
+    template<> template<>
+    void object::test<2>()
+    {
+        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));
+        // Start the coroutine
+        coro(std::nothrow);
+        // When the coroutine waits for the event pump, it returns here.
+        debug("about to send");
+        // Satisfy the wait.
+        LLEventPumps::instance().obtain("source").post("received");
+        // Now wait for the coroutine to complete.
+        ensure_done(coro);
+        // ensure the coroutine ran and woke up again with the intended result
+        ensure_equals(result.asString(), "received");
+    }
+
+    template<> template<>
+    void object::test<3>()
+    {
+        set_test_name("waitForEventOn1");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn1, this, _1));
+        coro(std::nothrow);
+        debug("about to send");
+        LLEventPumps::instance().obtain("source").post("received");
+        debug("back from send");
+        ensure_done(coro);
+        ensure_equals(result.asString(), "received");
+    }
+
+    template<> template<>
+    void object::test<4>()
+    {
+        set_test_name("waitForEventOn2 reply");
+        {
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1));
+        coro(std::nothrow);
+        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);
+    }
+
+    template<> template<>
+    void object::test<5>()
+    {
+        set_test_name("waitForEventOn2 error");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1));
+        coro(std::nothrow);
+        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);
+    }
+
+    template<> template<>
+    void object::test<6>()
+    {
+        set_test_name("coroPump");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPump, this, _1));
+        coro(std::nothrow);
+        debug("about to send");
+        LLEventPumps::instance().obtain(replyName).post("received");
+        debug("back from send");
+        ensure_done(coro);
+        ensure_equals(result.asString(), "received");
+    }
+
+    template<> template<>
+    void object::test<7>()
+    {
+        set_test_name("coroPumps reply");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1));
+        coro(std::nothrow);
+        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);
+    }
+
+    template<> template<>
+    void object::test<8>()
+    {
+        set_test_name("coroPumps error");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1));
+        coro(std::nothrow);
+        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);
+    }
+
+    template<> template<>
+    void object::test<9>()
+    {
+        set_test_name("coroPumpsNoEx");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoEx, this, _1));
+        coro(std::nothrow);
+        debug("about to send");
+        LLEventPumps::instance().obtain(replyName).post("received");
+        debug("back from send");
+        ensure_done(coro);
+        ensure_equals(result.asString(), "received");
+    }
+
+    template<> template<>
+    void object::test<10>()
+    {
+        set_test_name("coroPumpsEx");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsEx, this, _1));
+        coro(std::nothrow);
+        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");
+    }
+
+    template<> template<>
+    void object::test<11>()
+    {
+        set_test_name("coroPumpsNoLog");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoLog, this, _1));
+        coro(std::nothrow);
+        debug("about to send");
+        LLEventPumps::instance().obtain(replyName).post("received");
+        debug("back from send");
+        ensure_done(coro);
+        ensure_equals(result.asString(), "received");
+    }
+
+    template<> template<>
+    void object::test<12>()
+    {
+        set_test_name("coroPumpsLog");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsLog, this, _1));
+        coro(std::nothrow);
+        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");
+    }
+
+    template<> template<>
+    void object::test<13>()
+    {
+        set_test_name("postAndWait1");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::postAndWait1, this, _1));
+        coro(std::nothrow);
+        ensure_done(coro);
+        ensure_equals(result.asInteger(), 18);
+    }
+
+    template<> template<>
+    void object::test<14>()
+    {
+        set_test_name("postAndWait2");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::postAndWait2, this, _1));
+        coro(std::nothrow);
+        ensure_done(coro);
+        ensure_equals(result.asInteger(), 19);
+        ensure_equals(which, 0);
+    }
+
+    template<> template<>
+    void object::test<15>()
+    {
+        set_test_name("postAndWait2_1");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::postAndWait2_1, this, _1));
+        coro(std::nothrow);
+        ensure_done(coro);
+        ensure_equals(result.asInteger(), 19);
+        ensure_equals(which, 1);
+    }
+
+    template<> template<>
+    void object::test<16>()
+    {
+        set_test_name("coroPumpPost");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpPost, this, _1));
+        coro(std::nothrow);
+        ensure_done(coro);
+        ensure_equals(result.asInteger(), 18);
+    }
+
+    template<> template<>
+    void object::test<17>()
+    {
+        set_test_name("coroPumpsPost reply");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost, this, _1));
+        coro(std::nothrow);
+        ensure_done(coro);
+        ensure_equals(result.asInteger(), 24);
+        ensure_equals("which pump", which, 0);
+    }
+
+    template<> template<>
+    void object::test<18>()
+    {
+        set_test_name("coroPumpsPost error");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost_1, this, _1));
+        coro(std::nothrow);
+        ensure_done(coro);
+        ensure_equals(result.asInteger(), 24);
+        ensure_equals("which pump", which, 1);
+    }
+
+    template<> template<>
+    void object::test<19>()
+    {
+        set_test_name("coroPumpsPostNoEx");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoEx, this, _1));
+        coro(std::nothrow);
+        ensure_done(coro);
+        ensure_equals(result.asInteger(), 9);
+    }
+
+    template<> template<>
+    void object::test<20>()
+    {
+        set_test_name("coroPumpsPostEx");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostEx, this, _1));
+        coro(std::nothrow);
+        ensure_done(coro);
+        ensure("no result", result.isUndefined());
+        ensure_equals("got error", errordata.asInteger(), 10);
+    }
+
+    template<> template<>
+    void object::test<21>()
+    {
+        set_test_name("coroPumpsPostNoLog");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoLog, this, _1));
+        coro(std::nothrow);
+        ensure_done(coro);
+        ensure_equals(result.asInteger(), 31);
+    }
+
+    template<> template<>
+    void object::test<22>()
+    {
+        set_test_name("coroPumpsPostLog");
+        DEBUG;
+        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostLog, this, _1));
+        coro(std::nothrow);
+        ensure_done(coro);
+        ensure("no result", result.isUndefined());
+        ensure_contains("got error", threw, "32");
+    }
+} // namespace tut
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 388bf38d61d037be2c121139d42a968b7b517ef3..606f145d3b0543a6737511b5e92ede62920883c0 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -292,10 +292,9 @@ void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg)
 {
 	// store off config state, as we might quit soon
 	gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);	
+	gSavedSkinSettings.saveToFile(gSavedSettings.getString("SkinningSettingsFile"), TRUE);
 
 	std::ostringstream message;
-
-	//*TODO:translate
 	std::string msg;
 	if (!auth_msg.empty())
 	{
@@ -409,6 +408,7 @@ bool LLLoginInstance::updateDialogCallback(const LLSD& notification, const LLSD&
 	query_map["userserver"] = LLViewerLogin::getInstance()->getGridLabel();
 	query_map["channel"] = gSavedSettings.getString("VersionChannelName");
 	// *TODO constantize this guy
+	// *NOTE: This URL is also used in win_setup/lldownloader.cpp
 	LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);
 	
 	if(LLAppViewer::sUpdaterInfo)
@@ -495,9 +495,7 @@ bool LLLoginInstance::updateDialogCallback(const LLSD& notification, const LLSD&
 	system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */
 
 #elif LL_LINUX || LL_SOLARIS
-	OSMessageBox("Automatic updating is not yet implemented for Linux.\n"
-		"Please download the latest version from www.secondlife.com.",
-		LLStringUtil::null, OSMB_OK);
+	OSMessageBox(LLTrans::getString("MBNoAutoUpdate"), LLStringUtil::null, OSMB_OK);
 #endif
 
 	// *REMOVE:Mani - Saving for reference...
@@ -520,13 +518,9 @@ std::string construct_start_string()
 						<< LLURLSimString::sInstance.mZ);
 		start = xml_escape_string(unescaped_start);
 	}
-	else if (gSavedSettings.getBOOL("LoginLastLocation"))
-	{
-		start = "last";
-	}
 	else
 	{
-		start = "home";
+		start = gSavedSettings.getString("LoginLocation");
 	}
 	return start;
 }
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 4cf94b5bc4a7b062c1b218689cefade6312abdac..eddc23b0c44e0f6fbbc825833f96f834f7f38278 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -55,7 +55,6 @@
 #include "llviewercontrol.h"
 #include "lldir.h"
 #include "llerrorcontrol.h"
-#include "llfiltersd2xmlrpc.h"
 #include "llfloaterreg.h"
 #include "llfocusmgr.h"
 #include "llhttpsender.h"
@@ -102,7 +101,6 @@
 #include "llfloaterhud.h"
 #include "llfloaterland.h"
 #include "llfloatertopobjects.h"
-#include "llfloatertos.h"
 #include "llfloaterworldmap.h"
 #include "llgesturemgr.h"
 #include "llgroupmgr.h"
@@ -114,6 +112,7 @@
 #include "llinventoryview.h"
 #include "llkeyboard.h"
 #include "llloginhandler.h"			// gLoginHandler, SLURL support
+#include "lllogininstance.h" // Host the login module.
 #include "llpanellogin.h"
 #include "llprefsim.h"
 #include "llmutelist.h"
@@ -134,7 +133,6 @@
 #include "llsecondlifeurls.h"
 #include "llselectmgr.h"
 #include "llsky.h"
-#include "llsrv.h"
 #include "llstatview.h"
 #include "lltrans.h"
 #include "llstatusbar.h"		// sendMoneyBalanceRequest(), owns L$ balance
@@ -147,7 +145,6 @@
 #include "llurlsimstring.h"
 #include "llurlhistory.h"
 #include "llurlwhitelist.h"
-#include "lluserauth.h"
 #include "llvieweraudio.h"
 #include "llviewerassetstorage.h"
 #include "llviewercamera.h"
@@ -188,6 +185,8 @@
 #include "llwearable.h"
 #include "llinventorybridge.h"
 
+#include "lllogin.h"
+
 #if LL_LIBXUL_ENABLED
 #include "llmozlib.h"
 #endif // LL_LIBXUL_ENABLED
@@ -201,12 +200,12 @@
 // exported globals
 //
 bool gAgentMovementCompleted = false;
-std::string gInitialOutfit;
-std::string gInitialOutfitGender;
 
 std::string SCREEN_HOME_FILENAME = "screen_home.bmp";
 std::string SCREEN_LAST_FILENAME = "screen_last.bmp";
 
+LLPointer<LLImageGL> gStartImageGL;
+
 //
 // Imported globals
 //
@@ -216,12 +215,6 @@ extern S32 gStartImageHeight;
 //
 // local globals
 //
-
-LLPointer<LLImageGL> gStartImageGL;
-
-static LLHost gAgentSimHost;
-static BOOL gSkipOptionalUpdate = FALSE;
-
 static bool gGotUseCircuitCodeAck = false;
 static std::string sInitialOutfit;
 static std::string sInitialOutfitGender;	// "male" or "female"
@@ -230,6 +223,17 @@ static bool gUseCircuitCallbackCalled = false;
 
 EStartupState LLStartUp::gStartupState = STATE_FIRST;
 
+// *NOTE:Mani - to reconcile with giab changes...
+static std::string gFirstname;
+static std::string gLastname;
+static std::string gPassword;
+
+static U64 gFirstSimHandle = 0;
+static LLHost gFirstSim;
+static std::string gFirstSimSeedCap;
+static LLVector3 gAgentStartLookAt(1.0f, 0.f, 0.f);
+static std::string gAgentStartLocation = "safe";
+
 
 //
 // local function declaration
@@ -242,8 +246,6 @@ void show_first_run_dialog();
 bool first_run_dialog_callback(const LLSD& notification, const LLSD& response);
 void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);
 bool login_alert_status(const LLSD& notification, const LLSD& response);
-void update_app(BOOL mandatory, const std::string& message);
-bool update_dialog_callback(const LLSD& notification, const LLSD& response);
 void login_packet_failed(void**, S32 result);
 void use_circuit_callback(void**, S32 result);
 void register_viewer_callbacks(LLMessageSystem* msg);
@@ -253,6 +255,7 @@ void init_start_screen(S32 location_id);
 void release_start_screen();
 void reset_login();
 void apply_udp_blacklist(const std::string& csv);
+bool process_login_success_response();
 
 void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group)
 {
@@ -309,9 +312,6 @@ void update_texture_fetch()
 	gImageList.updateImages(0.10f);
 }
 
-static std::vector<std::string> sAuthUris;
-static S32 sAuthUriNum = -1;
-
 // Returns false to skip other idle processing. Should only return
 // true when all initialization done.
 bool idle_startup()
@@ -330,23 +330,11 @@ bool idle_startup()
 	// auth/transform loop will do.
 	static F32 progress = 0.10f;
 
-	static std::string auth_method;
 	static std::string auth_desc;
 	static std::string auth_message;
-	static std::string firstname;
-	static std::string lastname;
-	static LLUUID web_login_key;
-	static std::string password;
-	static std::vector<const char*> requested_options;
-
-	static U64 first_sim_handle = 0;
-	static LLHost first_sim;
-	static std::string first_sim_seed_cap;
 
 	static LLVector3 initial_sun_direction(1.f, 0.f, 0.f);
 	static LLVector3 agent_start_position_region(10.f, 10.f, 10.f);		// default for when no space server
-	static LLVector3 agent_start_look_at(1.0f, 0.f, 0.f);
-	static std::string agent_start_location = "safe";
 
 	// last location by default
 	static S32  agent_location_id = START_LOCATION_ID_LAST;
@@ -354,7 +342,7 @@ bool idle_startup()
 
 	static bool show_connect_box = true;
 
-	static bool stipend_since_login = false;
+	//static bool stipend_since_login = false;
 
 	// HACK: These are things from the main loop that usually aren't done
 	// until initialization is complete, but need to be done here for things
@@ -375,12 +363,7 @@ bool idle_startup()
 
 	LLStringUtil::setLocale (LLTrans::getString(system));
 
-	if (gNoRender)
-	{
-		// HACK, skip optional updates if you're running drones
-		gSkipOptionalUpdate = TRUE;
-	}
-	else
+	if (!gNoRender)
 	{
 		// Update images?
 		gImageList.updateImages(0.01f);
@@ -675,24 +658,23 @@ bool idle_startup()
 			|| !gLoginHandler.getWebLoginKey().isNull() )
 		{
 			// We have at least some login information on a SLURL
-			firstname = gLoginHandler.getFirstName();
-			lastname = gLoginHandler.getLastName();
-			web_login_key = gLoginHandler.getWebLoginKey();
+			gFirstname = gLoginHandler.getFirstName();
+			gLastname = gLoginHandler.getLastName();
 
 			// Show the login screen if we don't have everything
 			show_connect_box = 
-				firstname.empty() || lastname.empty() || web_login_key.isNull();
+				gFirstname.empty() || gLastname.empty();
 		}
         else if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
         {
             LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo");
-			firstname = cmd_line_login[0].asString();
-			lastname = cmd_line_login[1].asString();
+			gFirstname = cmd_line_login[0].asString();
+			gLastname = cmd_line_login[1].asString();
 
 			LLMD5 pass((unsigned char*)cmd_line_login[2].asString().c_str());
 			char md5pass[33];               /* Flawfinder: ignore */
 			pass.hex_digest(md5pass);
-			password = md5pass;
+			gPassword = md5pass;
 			
 #ifdef USE_VIEWER_AUTH
 			show_connect_box = true;
@@ -703,9 +685,9 @@ bool idle_startup()
         }
 		else if (gSavedSettings.getBOOL("AutoLogin"))
 		{
-			firstname = gSavedSettings.getString("FirstName");
-			lastname = gSavedSettings.getString("LastName");
-			password = LLStartUp::loadPasswordFromDisk();
+			gFirstname = gSavedSettings.getString("FirstName");
+			gLastname = gSavedSettings.getString("LastName");
+			gPassword = LLStartUp::loadPasswordFromDisk();
 			gSavedSettings.setBOOL("RememberPassword", TRUE);
 			
 #ifdef USE_VIEWER_AUTH
@@ -718,9 +700,9 @@ bool idle_startup()
 		{
 			// if not automatically logging in, display login dialog
 			// a valid grid is selected
-			firstname = gSavedSettings.getString("FirstName");
-			lastname = gSavedSettings.getString("LastName");
-			password = LLStartUp::loadPasswordFromDisk();
+			gFirstname = gSavedSettings.getString("FirstName");
+			gLastname = gSavedSettings.getString("LastName");
+			gPassword = LLStartUp::loadPasswordFromDisk();
 			show_connect_box = true;
 		}
 
@@ -757,7 +739,7 @@ bool idle_startup()
 			// Load all the name information out of the login view
 			// NOTE: Hits "Attempted getFields with no login view shown" warning, since we don't
 			// show the login view until login_show() is called below.  
-			// LLPanelLogin::getFields(firstname, lastname, password);
+			// LLPanelLogin::getFields(gFirstname, gLastname, gPassword);
 
 			if (gNoRender)
 			{
@@ -769,7 +751,7 @@ bool idle_startup()
 			// Show the login dialog
 			login_show();
 			// connect dialog is already shown, so fill in the names
-			LLPanelLogin::setFields( firstname, lastname, password);
+			LLPanelLogin::setFields( gFirstname, gLastname, gPassword);
 
 			LLPanelLogin::giveFocus();
 
@@ -826,37 +808,29 @@ bool idle_startup()
 
 	if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
 	{
-		//reset the values that could have come in from a slurl
-		if (!gLoginHandler.getWebLoginKey().isNull())
-		{
-			firstname = gLoginHandler.getFirstName();
-			lastname = gLoginHandler.getLastName();
-			web_login_key = gLoginHandler.getWebLoginKey();
-		}
-				
 		if (show_connect_box)
 		{
 			// TODO if not use viewer auth
 			// Load all the name information out of the login view
-			LLPanelLogin::getFields(&firstname, &lastname, &password);
+			LLPanelLogin::getFields(&gFirstname, &gLastname, &gPassword);
 			// end TODO
 	 
 			// HACK: Try to make not jump on login
 			gKeyboard->resetKeys();
 		}
 
-		if (!firstname.empty() && !lastname.empty())
+		if (!gFirstname.empty() && !gLastname.empty())
 		{
-			gSavedSettings.setString("FirstName", firstname);
-			gSavedSettings.setString("LastName", lastname);
+			gSavedSettings.setString("FirstName", gFirstname);
+			gSavedSettings.setString("LastName", gLastname);
 
-			LL_INFOS("AppInit") << "Attempting login as: " << firstname << " " << lastname << LL_ENDL;
-			gDebugInfo["LoginName"] = firstname + " " + lastname;	
+			LL_INFOS("AppInit") << "Attempting login as: " << gFirstname << " " << gLastname << LL_ENDL;
+			gDebugInfo["LoginName"] = gFirstname + " " + gLastname;	
 		}
 
 		// create necessary directories
 		// *FIX: these mkdir's should error check
-		gDirUtilp->setLindenUserDir(firstname, lastname);
+		gDirUtilp->setLindenUserDir(gFirstname, gLastname);
     	LLFile::mkdir(gDirUtilp->getLindenUserDir());
 
         // Set PerAccountSettingsFile to the default value.
@@ -887,7 +861,7 @@ bool idle_startup()
 			gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath"));		
 		}
 		
-		gDirUtilp->setPerAccountChatLogsDir(firstname, lastname);
+		gDirUtilp->setPerAccountChatLogsDir(gFirstname, gLastname);
 
 		LLFile::mkdir(gDirUtilp->getChatLogsDir());
 		LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
@@ -908,13 +882,6 @@ bool idle_startup()
 
 		if (show_connect_box)
 		{
-			if ( LLPanelLogin::isGridComboDirty() )
-			{
-				// User picked a grid from the popup, so clear the 
-				// stored uris and they will be reacquired from the grid choice.
-				sAuthUris.clear();
-			}
-			
 			std::string location;
 			LLPanelLogin::getLocation( location );
 			LLURLSimString::setString( location );
@@ -944,7 +911,7 @@ bool idle_startup()
 			agent_location_id = START_LOCATION_ID_URL;
 
 			// doesn't really matter what location_which is, since
-			// agent_start_look_at will be overwritten when the
+			// gAgentStartLookAt will be overwritten when the
 			// UserLoginLocationReply arrives
 			location_which = START_LOCATION_ID_LAST;
 		}
@@ -977,594 +944,115 @@ bool idle_startup()
 
 		gVFS->pokeFiles();
 
-		// skipping over STATE_UPDATE_CHECK because that just waits for input
 		LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
 
 		return FALSE;
 	}
 
-	if (STATE_UPDATE_CHECK == LLStartUp::getStartupState())
-	{
-		// wait for user to give input via dialog box
-		return FALSE;
-	}
-
 	if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())
 	{
-//#define LL_MINIMIAL_REQUESTED_OPTIONS
 		gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel();
 
-		// *Note: this is where gUserAuth used to be created.
-		requested_options.clear();
-		requested_options.push_back("inventory-root");
-		requested_options.push_back("inventory-skeleton");
-		//requested_options.push_back("inventory-meat");
-		//requested_options.push_back("inventory-skel-targets");
-#if (!defined LL_MINIMIAL_REQUESTED_OPTIONS)
-		if(FALSE == gSavedSettings.getBOOL("NoInventoryLibrary"))
-		{
-			requested_options.push_back("inventory-lib-root");
-			requested_options.push_back("inventory-lib-owner");
-			requested_options.push_back("inventory-skel-lib");
-		//	requested_options.push_back("inventory-meat-lib");
-		}
-
-		requested_options.push_back("initial-outfit");
-		requested_options.push_back("gestures");
-		requested_options.push_back("event_categories");
-		requested_options.push_back("event_notifications");
-		requested_options.push_back("classified_categories");
-		//requested_options.push_back("inventory-targets");
-		requested_options.push_back("buddy-list");
-		requested_options.push_back("ui-config");
-#endif
-		requested_options.push_back("tutorial_setting");
-		requested_options.push_back("login-flags");
-		requested_options.push_back("global-textures");
-		if(gSavedSettings.getBOOL("ConnectAsGod"))
-		{
-			gSavedSettings.setBOOL("UseDebugMenus", TRUE);
-			requested_options.push_back("god-connect");
-		}
-		std::vector<std::string> uris;
-		LLViewerLogin::getInstance()->getLoginURIs(uris);
-		std::vector<std::string>::const_iterator iter, end;
-		for (iter = uris.begin(), end = uris.end(); iter != end; ++iter)
-		{
-			std::vector<std::string> rewritten;
-			rewritten = LLSRV::rewriteURI(*iter);
-			sAuthUris.insert(sAuthUris.end(),
-							 rewritten.begin(), rewritten.end());
-		}
-		sAuthUriNum = 0;
-		auth_method = "login_to_simulator";
-		
+		// Update progress status and the display loop.
 		auth_desc = LLTrans::getString("LoginInProgress");
-		LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
-	}
-
-	if (STATE_LOGIN_AUTHENTICATE == LLStartUp::getStartupState())
-	{
-		LL_DEBUGS("AppInit") << "STATE_LOGIN_AUTHENTICATE" << LL_ENDL;
 		set_startup_status(progress, auth_desc, auth_message);
 		progress += 0.02f;
 		display_startup();
-		
-		std::stringstream start;
-		if (LLURLSimString::parse())
-		{
-			// a startup URL was specified
-			std::stringstream unescaped_start;
-			unescaped_start << "uri:" 
-							<< LLURLSimString::sInstance.mSimName << "&" 
-							<< LLURLSimString::sInstance.mX << "&" 
-							<< LLURLSimString::sInstance.mY << "&" 
-							<< LLURLSimString::sInstance.mZ;
-			start << xml_escape_string(unescaped_start.str());
-			
-		}
-		else
-		{
-			start << gSavedSettings.getString("LoginLocation");
-		}
-
-		char hashed_mac_string[MD5HEX_STR_SIZE];		/* Flawfinder: ignore */
-		LLMD5 hashed_mac;
-		hashed_mac.update( gMACAddress, MAC_ADDRESS_BYTES );
-		hashed_mac.finalize();
-		hashed_mac.hex_digest(hashed_mac_string);
-
-		// TODO if statement here to use web_login_key
-		sAuthUriNum = llclamp(sAuthUriNum, 0, (S32)sAuthUris.size()-1);
-		LLUserAuth::getInstance()->authenticate(
-			sAuthUris[sAuthUriNum],
-			auth_method,
-			firstname,
-			lastname,			
-			password, // web_login_key,
-			start.str(),
-			gSkipOptionalUpdate,
-			gAcceptTOS,
-			gAcceptCriticalMessage,
-			gLastExecEvent,
-			requested_options,
-			hashed_mac_string,
-			LLAppViewer::instance()->getSerialNumber());
-
-		// reset globals
-		gAcceptTOS = FALSE;
-		gAcceptCriticalMessage = FALSE;
-		LLStartUp::setStartupState( STATE_LOGIN_NO_DATA_YET );
-		return FALSE;
-	}
 
-	if(STATE_LOGIN_NO_DATA_YET == LLStartUp::getStartupState())
-	{
-		LL_DEBUGS("AppInit") << "STATE_LOGIN_NO_DATA_YET" << LL_ENDL;
-		// If we get here we have gotten past the potential stall
-		// in curl, so take "may appear frozen" out of progress bar. JC
-		auth_desc = LLTrans::getString("LoginInProgressNoFrozen");
-		set_startup_status(progress, auth_desc, auth_message);
-		// Process messages to keep from dropping circuit.
-		LLMessageSystem* msg = gMessageSystem;
-		while (msg->checkAllMessages(gFrameCount, gServicePump))
+		// Setting initial values...
+		if(gNoRender)
 		{
+			// HACK, skip optional updates if you're running drones
+			LLLoginInstance::getInstance()->setSkipOptionalUpdate(true);
 		}
-		msg->processAcks();
-		LLUserAuth::UserAuthcode error = LLUserAuth::getInstance()->authResponse();
-		if(LLUserAuth::E_NO_RESPONSE_YET == error)
-		{
-			LL_DEBUGS("AppInit") << "waiting..." << LL_ENDL;
-			return FALSE;
-		}
-		LLStartUp::setStartupState( STATE_LOGIN_DOWNLOADING );
-		progress += 0.01f;
-		set_startup_status(progress, auth_desc, auth_message);
-		return FALSE;
-	}
 
-	if(STATE_LOGIN_DOWNLOADING == LLStartUp::getStartupState())
-	{
-		LL_DEBUGS("AppInit") << "STATE_LOGIN_DOWNLOADING" << LL_ENDL;
-		// Process messages to keep from dropping circuit.
-		LLMessageSystem* msg = gMessageSystem;
-		while (msg->checkAllMessages(gFrameCount, gServicePump))
-		{
-		}
-		msg->processAcks();
-		LLUserAuth::UserAuthcode error = LLUserAuth::getInstance()->authResponse();
-		if(LLUserAuth::E_DOWNLOADING == error)
-		{
-			LL_DEBUGS("AppInit") << "downloading..." << LL_ENDL;
-			return FALSE;
-		}
+		LLLoginInstance::getInstance()->setUserInteraction(show_connect_box);
+
+		// This call to LLLoginInstance::connect() starts the 
+		// authentication process.
+		LLSD credentials;
+		credentials["first"] = gFirstname;
+		credentials["last"] = gLastname;
+		credentials["passwd"] = gPassword;
+		LLLoginInstance::getInstance()->connect(credentials);
+
 		LLStartUp::setStartupState( STATE_LOGIN_PROCESS_RESPONSE );
-		progress += 0.01f;
-		set_startup_status(progress, LLTrans::getString("LoginProcessingResponse"), auth_message);
 		return FALSE;
 	}
 
-	if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState())
+	if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState()) 
 	{
-		LL_DEBUGS("AppInit") << "STATE_LOGIN_PROCESS_RESPONSE" << LL_ENDL;
+		bool transitionBackToLoginPanel = false;
 		std::ostringstream emsg;
-		bool quit = false;
-		bool update = false;
-		std::string login_response;
-		std::string reason_response;
-		std::string message_response;
-		bool successful_login = false;
-		LLUserAuth::UserAuthcode error = LLUserAuth::getInstance()->authResponse();
-		// reset globals
-		gAcceptTOS = FALSE;
-		gAcceptCriticalMessage = FALSE;
-		switch(error)
-		{
-		case LLUserAuth::E_OK:
-			login_response = LLUserAuth::getInstance()->getResponse("login");
-			if(login_response == "true")
-			{
-				// Yay, login!
-				successful_login = true;
-			}
-			else if(login_response == "indeterminate")
+		if(LLLoginInstance::getInstance()->authFailure())
+		{
+			// Still have error conditions that may need some 
+			// sort of handling.
+			emsg << "Login failed.\n";
+			std::string reason_response = LLLoginInstance::getInstance()->getResponse("reason");
+			std::string message_response = LLLoginInstance::getInstance()->getResponse("message");
+	
+			if(!message_response.empty())
 			{
-				LL_INFOS("AppInit") << "Indeterminate login..." << LL_ENDL;
-				sAuthUris = LLSRV::rewriteURI(LLUserAuth::getInstance()->getResponse("next_url"));
-				sAuthUriNum = 0;
-				auth_method = LLUserAuth::getInstance()->getResponse("next_method");
-				auth_message = LLUserAuth::getInstance()->getResponse("message");
-				if(auth_method.substr(0, 5) == "login")
+				// XUI: fix translation for strings returned during login
+				// We need a generic table for translations
+				std::string big_reason = LLAgent::sTeleportErrorMessages[ message_response ];
+				if ( big_reason.size() == 0 )
 				{
-					auth_desc.assign(LLTrans::getString("LoginAuthenticating"));
+					emsg << message_response;
 				}
 				else
 				{
-					auth_desc.assign(LLTrans::getString("LoginMaintenance"));
-				}
-				// ignoring the duration & options array for now.
-				// Go back to authenticate.
-				LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
-				return FALSE;
-			}
-			else
-			{
-				emsg << "Login failed.\n";
-				reason_response = LLUserAuth::getInstance()->getResponse("reason");
-				message_response = LLUserAuth::getInstance()->getResponse("message");
-
-				if (!message_response.empty())
-				{
-					// XUI: fix translation for strings returned during login
-					// We need a generic table for translations
-					std::string big_reason = LLAgent::sTeleportErrorMessages[ message_response ];
-					if ( big_reason.size() == 0 )
-					{
-						emsg << message_response;
-					}
-					else
-					{
-						emsg << big_reason;
-					}
-				}
-
-				if(reason_response == "tos")
-				{
-					if (show_connect_box)
-					{
-						LL_DEBUGS("AppInit") << "Need tos agreement" << LL_ENDL;
-						LLStartUp::setStartupState( STATE_UPDATE_CHECK );
-						LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_TOS,
-																	message_response);
-						tos_dialog->startModal();
-						// LLFloaterTOS deletes itself.
-						return false;
-					}
-					else
-					{
-						quit = true;
-					}
-				}
-				if(reason_response == "critical")
-				{
-					if (show_connect_box)
-					{
-						LL_DEBUGS("AppInit") << "Need critical message" << LL_ENDL;
-						LLStartUp::setStartupState( STATE_UPDATE_CHECK );
-						LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_CRITICAL_MESSAGE,
-																	message_response);
-						tos_dialog->startModal();
-						// LLFloaterTOS deletes itself.
-						return false;
-					}
-					else
-					{
-						quit = true;
-					}
-				}
-				if(reason_response == "key")
-				{
-					// Couldn't login because user/password is wrong
-					// Clear the password
-					password = "";
-				}
-				if(reason_response == "update")
-				{
-					auth_message = LLUserAuth::getInstance()->getResponse("message");
-					update = true;
-				}
-				if(reason_response == "optional")
-				{
-					LL_DEBUGS("AppInit") << "Login got optional update" << LL_ENDL;
-					auth_message = LLUserAuth::getInstance()->getResponse("message");
-					if (show_connect_box)
-					{
-						update_app(FALSE, auth_message);
-						LLStartUp::setStartupState( STATE_UPDATE_CHECK );
-						gSkipOptionalUpdate = TRUE;
-						return false;
-					}
+					emsg << big_reason;
 				}
 			}
-			break;
-		case LLUserAuth::E_COULDNT_RESOLVE_HOST:
-		case LLUserAuth::E_SSL_PEER_CERTIFICATE:
-		case LLUserAuth::E_UNHANDLED_ERROR:
-		case LLUserAuth::E_SSL_CACERT:
-		case LLUserAuth::E_SSL_CONNECT_ERROR:
-		default:
-			if (sAuthUriNum >= (int) sAuthUris.size() - 1)
-			{
-				emsg << "Unable to connect to " << LLAppViewer::instance()->getSecondLifeTitle() << ".\n";
-				emsg << LLUserAuth::getInstance()->errorMessage();
-			} else {
-				sAuthUriNum++;
-				std::ostringstream s;
-				LLStringUtil::format_map_t args;
-				args["[NUMBER]"] = llformat("%d", sAuthUriNum + 1);
-				auth_desc = LLTrans::getString("LoginAttempt", args);
-				LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
-				return FALSE;
-			}
-			break;
-		}
-
-		if (update || gSavedSettings.getBOOL("ForceMandatoryUpdate"))
-		{
-			gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE);
-			update_app(TRUE, auth_message);
-			LLStartUp::setStartupState( STATE_UPDATE_CHECK );
-			return false;
-		}
-
-		// Version update and we're not showing the dialog
-		if(quit)
-		{
-			LLUserAuth::getInstance()->reset();
-			LLAppViewer::instance()->forceQuit();
-			return false;
-		}
 
-		if(successful_login)
-		{
-			std::string text;
-			text = LLUserAuth::getInstance()->getResponse("udp_blacklist");
-			if(!text.empty())
-			{
-				apply_udp_blacklist(text);
-			}
-
-			// unpack login data needed by the application
-			text = LLUserAuth::getInstance()->getResponse("agent_id");
-			if(!text.empty()) gAgentID.set(text);
-			gDebugInfo["AgentID"] = text;
-			
-			text = LLUserAuth::getInstance()->getResponse("session_id");
-			if(!text.empty()) gAgentSessionID.set(text);
-			gDebugInfo["SessionID"] = text;
-			
-			text = LLUserAuth::getInstance()->getResponse("secure_session_id");
-			if(!text.empty()) gAgent.mSecureSessionID.set(text);
-
-			text = LLUserAuth::getInstance()->getResponse("first_name");
-			if(!text.empty()) 
+			if(reason_response == "key")
 			{
-				// Remove quotes from string.  Login.cgi sends these to force
-				// names that look like numbers into strings.
-				firstname.assign(text);
-				LLStringUtil::replaceChar(firstname, '"', ' ');
-				LLStringUtil::trim(firstname);
+				// Couldn't login because user/password is wrong
+				// Clear the password
+				gPassword = "";
 			}
-			text = LLUserAuth::getInstance()->getResponse("last_name");
-			if(!text.empty()) lastname.assign(text);
-			gSavedSettings.setString("FirstName", firstname);
-			gSavedSettings.setString("LastName", lastname);
 
-			if (gSavedSettings.getBOOL("RememberPassword"))
+			if(reason_response == "update" 
+				|| reason_response == "optional")
 			{
-				// Successful login means the password is valid, so save it.
-				LLStartUp::savePasswordToDisk(password);
+				// In the case of a needed update, quit.
+				// Its either downloading or declined.
+				// If optional was skipped this case shouldn't 
+				// be reached.
+				LLLoginInstance::getInstance()->disconnect();
+				LLAppViewer::instance()->forceQuit();
 			}
 			else
 			{
-				// Don't leave password from previous session sitting around
-				// during this login session.
-				LLStartUp::deletePasswordFromDisk();
-			}
-
-			// this is their actual ability to access content
-			text = LLUserAuth::getInstance()->getResponse("agent_access_max");
-			if (!text.empty())
-			{
-				// agent_access can be 'A', 'M', and 'PG'.
-				gAgent.setMaturity(text[0]);
-			}
-			
-			// this is the value of their preference setting for that content
-			// which will always be <= agent_access_max
-			text = LLUserAuth::getInstance()->getResponse("agent_region_access");
-			if (!text.empty())
-			{
-				int preferredMaturity = LLAgent::convertTextToMaturity(text[0]);
-				gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
-			}
-			// During the AO transition, this flag will be true. Then the flag will
-			// go away. After the AO transition, this code and all the code that
-			// uses it can be deleted.
-			text = LLUserAuth::getInstance()->getResponse("ao_transition");
-			if (!text.empty())
-			{
-				if (text == "1")
-				{
-					gAgent.setAOTransition();
-				}
-			}
-
-			text = LLUserAuth::getInstance()->getResponse("start_location");
-			if(!text.empty()) agent_start_location.assign(text);
-			text = LLUserAuth::getInstance()->getResponse("circuit_code");
-			if(!text.empty())
-			{
-				gMessageSystem->mOurCircuitCode = strtoul(text.c_str(), NULL, 10);
-			}
-			std::string sim_ip_str = LLUserAuth::getInstance()->getResponse("sim_ip");
-			std::string sim_port_str = LLUserAuth::getInstance()->getResponse("sim_port");
-			if(!sim_ip_str.empty() && !sim_port_str.empty())
-			{
-				U32 sim_port = strtoul(sim_port_str.c_str(), NULL, 10);
-				first_sim.set(sim_ip_str, sim_port);
-				if (first_sim.isOk())
-				{
-					gMessageSystem->enableCircuit(first_sim, TRUE);
-				}
-			}
-			std::string region_x_str = LLUserAuth::getInstance()->getResponse("region_x");
-			std::string region_y_str = LLUserAuth::getInstance()->getResponse("region_y");
-			if(!region_x_str.empty() && !region_y_str.empty())
-			{
-				U32 region_x = strtoul(region_x_str.c_str(), NULL, 10);
-				U32 region_y = strtoul(region_y_str.c_str(), NULL, 10);
-				first_sim_handle = to_region_handle(region_x, region_y);
-			}
-			
-			const std::string look_at_str = LLUserAuth::getInstance()->getResponse("look_at");
-			if (!look_at_str.empty())
-			{
-				size_t len = look_at_str.size();
-				LLMemoryStream mstr((U8*)look_at_str.c_str(), len);
-				LLSD sd = LLSDSerialize::fromNotation(mstr, len);
-				agent_start_look_at = ll_vector3_from_sd(sd);
-			}
-
-			text = LLUserAuth::getInstance()->getResponse("seed_capability");
-			if (!text.empty()) first_sim_seed_cap = text;
-						
-			text = LLUserAuth::getInstance()->getResponse("seconds_since_epoch");
-			if(!text.empty())
-			{
-				U32 server_utc_time = strtoul(text.c_str(), NULL, 10);
-				if(server_utc_time)
-				{
-					time_t now = time(NULL);
-					gUTCOffset = (server_utc_time - now);
-				}
-			}
-
-			std::string home_location = LLUserAuth::getInstance()->getResponse("home");
-			if(!home_location.empty())
-			{
-				size_t len = home_location.size();
-				LLMemoryStream mstr((U8*)home_location.c_str(), len);
-				LLSD sd = LLSDSerialize::fromNotation(mstr, len);
-				S32 region_x = sd["region_handle"][0].asInteger();
-				S32 region_y = sd["region_handle"][1].asInteger();
-				U64 region_handle = to_region_handle(region_x, region_y);
-				LLVector3 position = ll_vector3_from_sd(sd["position"]);
-				gAgent.setHomePosRegion(region_handle, position);
-			}
-
-			gAgent.mMOTD.assign(LLUserAuth::getInstance()->getResponse("message"));
-			LLUserAuth::options_t options;
-			if(LLUserAuth::getInstance()->getOptions("inventory-root", options))
-			{
-				LLUserAuth::response_t::iterator it;
-				it = options[0].find("folder_id");
-				if(it != options[0].end())
-				{
-					gAgent.mInventoryRootID.set((*it).second);
-					//gInventory.mock(gAgent.getInventoryRootID());
-				}
-			}
-
-			options.clear();
-			if(LLUserAuth::getInstance()->getOptions("login-flags", options))
-			{
-				LLUserAuth::response_t::iterator it;
-				LLUserAuth::response_t::iterator no_flag = options[0].end();
-				it = options[0].find("ever_logged_in");
-				if(it != no_flag)
-				{
-					if((*it).second == "N") gAgent.setFirstLogin(TRUE);
-					else gAgent.setFirstLogin(FALSE);
-				}
-				it = options[0].find("stipend_since_login");
-				if(it != no_flag)
-				{
-					if((*it).second == "Y") stipend_since_login = true;
-				}
-				it = options[0].find("gendered");
-				if(it != no_flag)
-				{
-					if((*it).second == "Y") gAgent.setGenderChosen(TRUE);
-				}
-				it = options[0].find("daylight_savings");
-				if(it != no_flag)
-				{
-					if((*it).second == "Y")  gPacificDaylightTime = TRUE;
-					else gPacificDaylightTime = FALSE;
-				}
-
-				//setup map of datetime strings to codes and slt & local time offset from utc
-				LLStringOps::setupDatetimeInfo (gPacificDaylightTime);
+				transitionBackToLoginPanel = true;
 			}
-			options.clear();
-			if (LLUserAuth::getInstance()->getOptions("initial-outfit", options)
-				&& !options.empty())
-			{
-				LLUserAuth::response_t::iterator it;
-				LLUserAuth::response_t::iterator it_end = options[0].end();
-				it = options[0].find("folder_name");
-				if(it != it_end)
-				{
-					// Initial outfit is a folder in your inventory,
-					// must be an exact folder-name match.
-					sInitialOutfit = (*it).second;
-				}
-				it = options[0].find("gender");
-				if (it != it_end)
-				{
-					sInitialOutfitGender = (*it).second;
-				}
-			}
-
-			options.clear();
-			if(LLUserAuth::getInstance()->getOptions("global-textures", options))
-			{
-				// Extract sun and moon texture IDs.  These are used
-				// in the LLVOSky constructor, but I can't figure out
-				// how to pass them in.  JC
-				LLUserAuth::response_t::iterator it;
-				LLUserAuth::response_t::iterator no_texture = options[0].end();
-				it = options[0].find("sun_texture_id");
-				if(it != no_texture)
-				{
-					gSunTextureID.set((*it).second);
-				}
-				it = options[0].find("moon_texture_id");
-				if(it != no_texture)
-				{
-					gMoonTextureID.set((*it).second);
-				}
-				it = options[0].find("cloud_texture_id");
-				if(it != no_texture)
-				{
-					gCloudTextureID.set((*it).second);
-				}
-			}
-
-
-			// JC: gesture loading done below, when we have an asset system
-			// in place.  Don't delete/clear user_credentials until then.
-
-			if(gAgentID.notNull()
-			   && gAgentSessionID.notNull()
-			   && gMessageSystem->mOurCircuitCode
-			   && first_sim.isOk()
-			   && gAgent.mInventoryRootID.notNull())
+		}
+		else if(LLLoginInstance::getInstance()->authSuccess())
+		{
+			if(process_login_success_response())
 			{
-				LLStartUp::setStartupState( STATE_WORLD_INIT );
+				// Pass the user information to the voice chat server interface.
+				gVoiceClient->userAuthorized(gFirstname, gLastname, gAgentID);
+				LLStartUp::setStartupState( STATE_WORLD_INIT);
 			}
 			else
 			{
-				if (gNoRender)
-				{
-					LL_WARNS("AppInit") << "Bad login - missing return values" << LL_ENDL;
-					LL_WARNS("AppInit") << emsg << LL_ENDL;
-					exit(0);
-				}
-				// Bounce back to the login screen.
-				LLSD args;
-				args["ERROR_MESSAGE"] = emsg.str();
-				LLNotifications::instance().add("ErrorMessage", args, LLSD(), login_alert_done);
-				reset_login();
-				gSavedSettings.setBOOL("AutoLogin", FALSE);
-				show_connect_box = true;
+				transitionBackToLoginPanel = false;
 			}
-			
-			// Pass the user information to the voice chat server interface.
-			gVoiceClient->userAuthorized(firstname, lastname, gAgentID);
 		}
-		else // if(successful_login)
+		else
+		{
+			// Still waiting for response.
+			// *TODO:Mani - Actually check for login progress.
+			// If we get here we have gotten past the potential stall
+			// in curl, so take "may appear frozen" out of progress bar. JC
+			auth_desc = LLTrans::getString("LoginInProgressNoFrozen");
+			set_startup_status(progress, auth_desc, auth_message);
+		}
+
+		if(transitionBackToLoginPanel)
 		{
 			if (gNoRender)
 			{
@@ -1572,11 +1060,12 @@ bool idle_startup()
 				LL_WARNS("AppInit") << emsg << LL_ENDL;
 				exit(0);
 			}
+
 			// Bounce back to the login screen.
 			LLSD args;
 			args["ERROR_MESSAGE"] = emsg.str();
 			LLNotifications::instance().add("ErrorMessage", args, LLSD(), login_alert_done);
-			reset_login();
+			reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );
 			gSavedSettings.setBOOL("AutoLogin", FALSE);
 			show_connect_box = true;
 		}
@@ -1640,14 +1129,14 @@ bool idle_startup()
 		// This is necessary because creating objects before this is set will result in a
 		// bad mPositionAgent cache.
 
-		gAgent.initOriginGlobal(from_region_handle(first_sim_handle));
+		gAgent.initOriginGlobal(from_region_handle(gFirstSimHandle));
 
-		LLWorld::getInstance()->addRegion(first_sim_handle, first_sim);
+		LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim);
 
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(first_sim_handle);
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(gFirstSimHandle);
 		LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL;
 		
-		regionp->setSeedCapability(first_sim_seed_cap);
+		regionp->setSeedCapability(gFirstSimSeedCap);
 		LL_DEBUGS("AppInit") << "Waiting for seed grant ...." << LL_ENDL;
 		
 		// Set agent's initial region to be the one we just created.
@@ -1818,7 +1307,7 @@ bool idle_startup()
 		// the coordinates handed to us to fit in the local region.
 
 		gAgent.setPositionAgent(agent_start_position_region);
-		gAgent.resetAxes(agent_start_look_at);
+		gAgent.resetAxes(gAgentStartLookAt);
 		gAgent.stopCameraAnimation();
 		gAgent.resetCamera();
 
@@ -1857,18 +1346,18 @@ bool idle_startup()
 			LL_WARNS("AppInit") << "Attempting to connect to simulator with a zero circuit code!" << LL_ENDL;
 		}
 
-		gUseCircuitCallbackCalled = FALSE;
+		gUseCircuitCallbackCalled = false;
 
-		msg->enableCircuit(first_sim, TRUE);
+		msg->enableCircuit(gFirstSim, TRUE);
 		// now, use the circuit info to tell simulator about us!
-		LL_INFOS("AppInit") << "viewer: UserLoginLocationReply() Enabling " << first_sim << " with code " << msg->mOurCircuitCode << LL_ENDL;
+		LL_INFOS("AppInit") << "viewer: UserLoginLocationReply() Enabling " << gFirstSim << " with code " << msg->mOurCircuitCode << LL_ENDL;
 		msg->newMessageFast(_PREHASH_UseCircuitCode);
 		msg->nextBlockFast(_PREHASH_CircuitCode);
 		msg->addU32Fast(_PREHASH_Code, msg->mOurCircuitCode);
 		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 		msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
 		msg->sendReliable(
-			first_sim,
+			gFirstSim,
 			MAX_TIMEOUT_COUNT,
 			FALSE,
 			TIMEOUT_SECONDS,
@@ -1979,122 +1468,113 @@ bool idle_startup()
 		LLAgentLanguage::update();
 
 		// unpack thin inventory
-		LLUserAuth::options_t options;
-		options.clear();
+		LLSD response = LLLoginInstance::getInstance()->getResponse();
 		//bool dump_buffer = false;
-		
-		if(LLUserAuth::getInstance()->getOptions("inventory-lib-root", options)
-			&& !options.empty())
+
+		LLSD inv_lib_root = response["inventory-lib-root"];
+		if(inv_lib_root.isDefined())
 		{
 			// should only be one
-			LLUserAuth::response_t::iterator it;
-			it = options[0].find("folder_id");
-			if(it != options[0].end())
+			LLSD id = inv_lib_root[0]["folder_id"];
+			if(id.isDefined())
 			{
-				gInventoryLibraryRoot.set((*it).second);
+				gInventoryLibraryRoot = id.asUUID();
 			}
 		}
- 		options.clear();
-		if(LLUserAuth::getInstance()->getOptions("inventory-lib-owner", options)
-			&& !options.empty())
+ 		
+		LLSD inv_lib_owner = response["inventory-lib-owner"];
+		if(inv_lib_owner.isDefined())
 		{
 			// should only be one
-			LLUserAuth::response_t::iterator it;
-			it = options[0].find("agent_id");
-			if(it != options[0].end())
+			LLSD id = inv_lib_owner[0]["agent_id"];
+			if(id.isDefined())
 			{
-				gInventoryLibraryOwner.set((*it).second);
+				gInventoryLibraryOwner = id.asUUID();
 			}
 		}
- 		options.clear();
- 		if(LLUserAuth::getInstance()->getOptions("inventory-skel-lib", options)
-			&& gInventoryLibraryOwner.notNull())
+
+		LLSD inv_skel_lib = response["inventory-skel-lib"];
+ 		if(inv_skel_lib.isDefined() && gInventoryLibraryOwner.notNull())
  		{
- 			if(!gInventory.loadSkeleton(options, gInventoryLibraryOwner))
+ 			if(!gInventory.loadSkeleton(inv_skel_lib, gInventoryLibraryOwner))
  			{
  				LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
  			}
  		}
- 		options.clear();
- 		if(LLUserAuth::getInstance()->getOptions("inventory-skeleton", options))
+
+		LLSD inv_skeleton = response["inventory-skeleton"];
+ 		if(inv_skeleton.isDefined())
  		{
- 			if(!gInventory.loadSkeleton(options, gAgent.getID()))
+ 			if(!gInventory.loadSkeleton(inv_skeleton, gAgent.getID()))
  			{
  				LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
  			}
  		}
 
-		options.clear();
- 		if(LLUserAuth::getInstance()->getOptions("buddy-list", options))
+		LLSD buddy_list = response["buddy-list"];
+ 		if(buddy_list.isDefined())
  		{
-			LLUserAuth::options_t::iterator it = options.begin();
-			LLUserAuth::options_t::iterator end = options.end();
 			LLAvatarTracker::buddy_map_t list;
 			LLUUID agent_id;
 			S32 has_rights = 0, given_rights = 0;
-			for (; it != end; ++it)
+			for(LLSD::array_const_iterator it = buddy_list.beginArray(),
+				end = buddy_list.endArray(); it != end; ++it)
 			{
-				LLUserAuth::response_t::const_iterator option_it;
-				option_it = (*it).find("buddy_id");
-				if(option_it != (*it).end())
+				LLSD buddy_id = (*it)["buddy_id"];
+				if(buddy_id.isDefined())
 				{
-					agent_id.set((*option_it).second);
+					agent_id = buddy_id.asUUID();
 				}
-				option_it = (*it).find("buddy_rights_has");
-				if(option_it != (*it).end())
+
+				LLSD buddy_rights_has = (*it)["buddy_rights_has"];
+				if(buddy_rights_has.isDefined())
 				{
-					has_rights = atoi((*option_it).second.c_str());
+					has_rights = buddy_rights_has.asInteger();
 				}
-				option_it = (*it).find("buddy_rights_given");
-				if(option_it != (*it).end())
+
+				LLSD buddy_rights_given = (*it)["buddy_rights_given"];
+				if(buddy_rights_given.isDefined())
 				{
-					given_rights = atoi((*option_it).second.c_str());
+					given_rights = buddy_rights_given.asInteger();
 				}
+
 				list[agent_id] = new LLRelationship(given_rights, has_rights, false);
 			}
 			LLAvatarTracker::instance().addBuddyList(list);
  		}
 
-		options.clear();
- 		if(LLUserAuth::getInstance()->getOptions("ui-config", options))
+		LLSD ui_config = response["ui-config"];
+ 		if(ui_config.isDefined())
  		{
-			LLUserAuth::options_t::iterator it = options.begin();
-			LLUserAuth::options_t::iterator end = options.end();
-			for (; it != end; ++it)
+			for(LLSD::array_const_iterator it = ui_config.beginArray(),
+				end = ui_config.endArray(); it != end; ++it)
 			{
-				LLUserAuth::response_t::const_iterator option_it;
-				option_it = (*it).find("allow_first_life");
-				if(option_it != (*it).end())
+				LLSD allow_first_life = (*it)["allow_first_life"];
+				if(allow_first_life.asString() == "Y")
 				{
-					if (option_it->second == "Y")
-					{
-						LLPanelAvatar::sAllowFirstLife = TRUE;
-					}
+					LLPanelAvatar::sAllowFirstLife = TRUE;
 				}
 			}
  		}
-		options.clear();
+
 		bool show_hud = false;
-		if(LLUserAuth::getInstance()->getOptions("tutorial_setting", options))
+		LLSD tutorial_setting = response["tutorial_setting"];
+		if(tutorial_setting.isDefined())
 		{
-			LLUserAuth::options_t::iterator it = options.begin();
-			LLUserAuth::options_t::iterator end = options.end();
-			for (; it != end; ++it)
+			for(LLSD::array_const_iterator it = tutorial_setting.beginArray(),
+				end = tutorial_setting.endArray(); it != end; ++it)
 			{
-				LLUserAuth::response_t::const_iterator option_it;
-				option_it = (*it).find("tutorial_url");
-				if(option_it != (*it).end())
+				LLSD tutorial_url = (*it)["tutorial_url"];
+				if(tutorial_url.isDefined())
 				{
 					// Tutorial floater will append language code
-					gSavedSettings.setString("TutorialURL", option_it->second);
+					gSavedSettings.setString("TutorialURL", tutorial_url.asString());
 				}
-				option_it = (*it).find("use_tutorial");
-				if(option_it != (*it).end())
+				
+				LLSD use_tutorial = (*it)["use_tutorial"];
+				if(use_tutorial.asString() == "true")
 				{
-					if (option_it->second == "true")
-					{
-						show_hud = true;
-					}
+					show_hud = true;
 				}
 			}
 		}
@@ -2107,19 +1587,22 @@ bool idle_startup()
 			LLFloaterHUD::showHUD();
 		}
 
-		options.clear();
-		if(LLUserAuth::getInstance()->getOptions("event_categories", options))
+		LLSD event_categories = response["event_categories"];
+		if(event_categories.isDefined())
 		{
-			LLEventInfo::loadCategories(options);
+			LLEventInfo::loadCategories(event_categories);
 		}
-		if(LLUserAuth::getInstance()->getOptions("event_notifications", options))
+
+		LLSD event_notifications = response["event_notifications"];
+		if(event_notifications.isDefined())
 		{
-			gEventNotifier.load(options);
+			gEventNotifier.load(event_notifications);
 		}
-		options.clear();
-		if(LLUserAuth::getInstance()->getOptions("classified_categories", options))
+
+		LLSD classified_categories = response["classified_categories"];
+		if(classified_categories.isDefined())
 		{
-			LLClassifiedInfo::loadCategories(options);
+			LLClassifiedInfo::loadCategories(classified_categories);
 		}
 
 
@@ -2176,7 +1659,7 @@ bool idle_startup()
 			// This is actually a pessimistic computation, because TCP may not have enough
 			// time to ramp up on the (small) default inventory file to truly measure max
 			// bandwidth. JC
-			F64 rate_bps = LLUserAuth::getInstance()->getLastTransferRateBPS();
+			F64 rate_bps = LLLoginInstance::getInstance()->getLastTransferRateBPS();
 			const F32 FAST_RATE_BPS = 600.f * 1024.f;
 			const F32 FASTER_RATE_BPS = 750.f * 1024.f;
 			F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
@@ -2223,34 +1706,20 @@ bool idle_startup()
 			// JC: Initialize "active" gestures.  This may also trigger
 			// many gesture downloads, if this is the user's first
 			// time on this machine or -purge has been run.
-			LLUserAuth::options_t gesture_options;
-			if (LLUserAuth::getInstance()->getOptions("gestures", gesture_options))
+			LLSD gesture_options 
+				= LLLoginInstance::getInstance()->getResponse("gestures");
+			if (gesture_options.isDefined())
 			{
 				LL_DEBUGS("AppInit") << "Gesture Manager loading " << gesture_options.size()
 					<< LL_ENDL;
 				std::vector<LLUUID> item_ids;
-				LLUserAuth::options_t::iterator resp_it;
-				for (resp_it = gesture_options.begin();
-					 resp_it != gesture_options.end();
-					 ++resp_it)
+				for(LLSD::array_const_iterator resp_it = gesture_options.beginArray(),
+					end = gesture_options.endArray(); resp_it != end; ++resp_it)
 				{
-					const LLUserAuth::response_t& response = *resp_it;
-					LLUUID item_id;
-					LLUUID asset_id;
-					LLUserAuth::response_t::const_iterator option_it;
-
-					option_it = response.find("item_id");
-					if (option_it != response.end())
-					{
-						const std::string& uuid_string = (*option_it).second;
-						item_id.set(uuid_string);
-					}
-					option_it = response.find("asset_id");
-					if (option_it != response.end())
-					{
-						const std::string& uuid_string = (*option_it).second;
-						asset_id.set(uuid_string);
-					}
+					// If the id is not specifed in the LLSD,
+					// the LLSD operator[]() will return a null LLUUID. 
+					LLUUID item_id = (*resp_it)["item_id"];
+					LLUUID asset_id = (*resp_it)["asset_id"];
 
 					if (item_id.notNull() && asset_id.notNull())
 					{
@@ -2306,8 +1775,8 @@ bool idle_startup()
 		if (!gAgent.isFirstLogin())
 		{
 			bool url_ok = LLURLSimString::sInstance.parse();
-			if ((url_ok && agent_start_location == "url") ||
-				(!url_ok && ((agent_start_location == gSavedSettings.getString("LoginLocation")))))
+			if ((url_ok && gAgentStartLocation == "url") ||
+				(!url_ok && ((gAgentStartLocation == gSavedSettings.getString("LoginLocation")))))
 			{
 				// Start location is OK
 				// Disabled code to restore camera location and focus if logging in to default location
@@ -2518,8 +1987,10 @@ bool idle_startup()
 		// then the data is cached for the viewer's lifetime)
 		LLProductInfoRequestManager::instance();
 		
+		// *FIX:Mani - What do I do here?
+		// Need we really clear the Auth response data?
 		// Clean up the userauth stuff.
-		LLUserAuth::getInstance()->reset();
+		// LLUserAuth::getInstance()->reset();
 
 		LLStartUp::setStartupState( STATE_STARTED );
 
@@ -2804,194 +2275,6 @@ bool login_alert_status(const LLSD& notification, const LLSD& response)
 	return false;
 }
 
-void update_app(BOOL mandatory, const std::string& auth_msg)
-{
-	// store off config state, as we might quit soon
-	gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);	
-	gSavedSkinSettings.saveToFile(gSavedSettings.getString("SkinningSettingsFile"), TRUE);
-	std::ostringstream message;
-
-	std::string msg;
-	if (!auth_msg.empty())
-	{
-		msg = "("+ auth_msg + ") \n";
-	}
-
-	LLSD args;
-	args["MESSAGE"] = msg;
-	
-	LLSD payload;
-	payload["mandatory"] = mandatory;
-
-/*
- We're constructing one of the following 6 strings here:
-	 "DownloadWindowsMandatory"
-	 "DownloadWindowsReleaseForDownload"
-	 "DownloadWindows"
-	 "DownloadMacMandatory"
-	 "DownloadMacReleaseForDownload"
-	 "DownloadMac"
- 
- I've called them out explicitly in this comment so that they can be grepped for.
- 
- Also, we assume that if we're not Windows we're Mac. If we ever intend to support 
- Linux with autoupdate, this should be an explicit #elif LL_DARWIN, but 
- we'd rather deliver the wrong message than no message, so until Linux is supported
- we'll leave it alone.
- */
-	std::string notification_name = "Download";
-	
-#if LL_WINDOWS
-	notification_name += "Windows";
-#else
-	notification_name += "Mac";
-#endif
-	
-	if (mandatory)
-	{
-		notification_name += "Mandatory";
-	}
-	else
-	{
-#if LL_RELEASE_FOR_DOWNLOAD
-		notification_name += "ReleaseForDownload";
-#endif
-	}
-	
-	LLNotifications::instance().add(notification_name, args, payload, update_dialog_callback);
-	
-}
-
-bool update_dialog_callback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotification::getSelectedOption(notification, response);
-	std::string update_exe_path;
-	bool mandatory = notification["payload"]["mandatory"].asBoolean();
-
-#if !LL_RELEASE_FOR_DOWNLOAD
-	if (option == 2)
-	{
-		LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); 
-		return false;
-	}
-#endif
-
-	if (option == 1)
-	{
-		// ...user doesn't want to do it
-		if (mandatory)
-		{
-			LLAppViewer::instance()->forceQuit();
-			// Bump them back to the login screen.
-			//reset_login();
-		}
-		else
-		{
-			LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
-		}
-		return false;
-	}
-	
-	LLSD query_map = LLSD::emptyMap();
-	// *TODO place os string in a global constant
-#if LL_WINDOWS  
-	query_map["os"] = "win";
-#elif LL_DARWIN
-	query_map["os"] = "mac";
-#elif LL_LINUX
-	query_map["os"] = "lnx";
-#elif LL_SOLARIS
-	query_map["os"] = "sol";
-#endif
-	// *TODO change userserver to be grid on both viewer and sim, since
-	// userserver no longer exists.
-	query_map["userserver"] = LLViewerLogin::getInstance()->getGridLabel();
-	query_map["channel"] = gSavedSettings.getString("VersionChannelName");
-	// *TODO constantize this guy
-	// *NOTE: This URL is also used in win_setup/lldownloader.cpp
-	LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);
-	
-	if(LLAppViewer::sUpdaterInfo)
-	{
-		delete LLAppViewer::sUpdaterInfo ;
-	}
-	LLAppViewer::sUpdaterInfo = new LLAppViewer::LLUpdaterInfo() ;
-	
-#if LL_WINDOWS
-	LLAppViewer::sUpdaterInfo->mUpdateExePath = gDirUtilp->getTempFilename();
-	if (LLAppViewer::sUpdaterInfo->mUpdateExePath.empty())
-	{
-		delete LLAppViewer::sUpdaterInfo ;
-		LLAppViewer::sUpdaterInfo = NULL ;
-
-		// We're hosed, bail
-		LL_WARNS("AppInit") << "LLDir::getTempFilename() failed" << LL_ENDL;
-		LLAppViewer::instance()->forceQuit();
-		return false;
-	}
-
-	LLAppViewer::sUpdaterInfo->mUpdateExePath += ".exe";
-
-	std::string updater_source = gDirUtilp->getAppRODataDir();
-	updater_source += gDirUtilp->getDirDelimiter();
-	updater_source += "updater.exe";
-
-	LL_DEBUGS("AppInit") << "Calling CopyFile source: " << updater_source
-			<< " dest: " << LLAppViewer::sUpdaterInfo->mUpdateExePath
-			<< LL_ENDL;
-
-
-	if (!CopyFileA(updater_source.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), FALSE))
-	{
-		delete LLAppViewer::sUpdaterInfo ;
-		LLAppViewer::sUpdaterInfo = NULL ;
-
-		LL_WARNS("AppInit") << "Unable to copy the updater!" << LL_ENDL;
-		LLAppViewer::instance()->forceQuit();
-		return false;
-	}
-
-	// if a sim name was passed in via command line parameter (typically through a SLURL)
-	if ( LLURLSimString::sInstance.mSimString.length() )
-	{
-		// record the location to start at next time
-		gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString ); 
-	};
-
-	LLAppViewer::sUpdaterInfo->mParams << "-url \"" << update_url.asString() << "\"";
-
-	LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL;
-
-	//Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird.
-	LLAppViewer::instance()->removeMarkerFile(); // In case updater fails
-	
-#elif LL_DARWIN
-	// if a sim name was passed in via command line parameter (typically through a SLURL)
-	if ( LLURLSimString::sInstance.mSimString.length() )
-	{
-		// record the location to start at next time
-		gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString ); 
-	};
-	
-	LLAppViewer::sUpdaterInfo->mUpdateExePath = "'";
-	LLAppViewer::sUpdaterInfo->mUpdateExePath += gDirUtilp->getAppRODataDir();
-	LLAppViewer::sUpdaterInfo->mUpdateExePath += "/mac-updater.app/Contents/MacOS/mac-updater' -url \"";
-	LLAppViewer::sUpdaterInfo->mUpdateExePath += update_url.asString();
-	LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -name \"";
-	LLAppViewer::sUpdaterInfo->mUpdateExePath += LLAppViewer::instance()->getSecondLifeTitle();
-	LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" &";
-
-	LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL;
-
-	// Run the auto-updater.
-	system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */
-
-#elif LL_LINUX || LL_SOLARIS
-	OSMessageBox(LLTrans::getString("MBNoAutoUpdate"), LLStringUtil::null, OSMB_OK);
-#endif
-	LLAppViewer::instance()->forceQuit();
-	return false;
-}
 
 void use_circuit_callback(void**, S32 result)
 {
@@ -3348,11 +2631,7 @@ std::string LLStartUp::startupStateToString(EStartupState state)
 		RTNENUM( STATE_LOGIN_SHOW );
 		RTNENUM( STATE_LOGIN_WAIT );
 		RTNENUM( STATE_LOGIN_CLEANUP );
-		RTNENUM( STATE_UPDATE_CHECK );
 		RTNENUM( STATE_LOGIN_AUTH_INIT );
-		RTNENUM( STATE_LOGIN_AUTHENTICATE );
-		RTNENUM( STATE_LOGIN_NO_DATA_YET );
-		RTNENUM( STATE_LOGIN_DOWNLOADING );
 		RTNENUM( STATE_LOGIN_PROCESS_RESPONSE );
 		RTNENUM( STATE_WORLD_INIT );
 		RTNENUM( STATE_SEED_GRANTED_WAIT );
@@ -3493,3 +2772,252 @@ void apply_udp_blacklist(const std::string& csv)
 	
 }
 
+bool process_login_success_response()
+{
+	LLSD response = LLLoginInstance::getInstance()->getResponse();
+
+	std::string text(response["udp_blacklist"]);
+	if(!text.empty())
+	{
+		apply_udp_blacklist(text);
+	}
+
+	// unpack login data needed by the application
+	text = response["agent_id"].asString();
+	if(!text.empty()) gAgentID.set(text);
+	gDebugInfo["AgentID"] = text;
+	
+	text = response["session_id"].asString();
+	if(!text.empty()) gAgentSessionID.set(text);
+	gDebugInfo["SessionID"] = text;
+	
+	text = response["secure_session_id"].asString();
+	if(!text.empty()) gAgent.mSecureSessionID.set(text);
+
+	text = response["first_name"].asString();
+	if(!text.empty()) 
+	{
+		// Remove quotes from string.  Login.cgi sends these to force
+		// names that look like numbers into strings.
+		gFirstname.assign(text);
+		LLStringUtil::replaceChar(gFirstname, '"', ' ');
+		LLStringUtil::trim(gFirstname);
+	}
+	text = response["last_name"].asString();
+	if(!text.empty()) 
+	{
+		gLastname.assign(text);
+	}
+	gSavedSettings.setString("FirstName", gFirstname);
+	gSavedSettings.setString("LastName", gLastname);
+
+	if (gSavedSettings.getBOOL("RememberPassword"))
+	{
+		// Successful login means the password is valid, so save it.
+		LLStartUp::savePasswordToDisk(gPassword);
+	}
+	else
+	{
+		// Don't leave password from previous session sitting around
+		// during this login session.
+		LLStartUp::deletePasswordFromDisk();
+	}
+
+	// this is their actual ability to access content
+	text = response["agent_access_max"].asString();
+	if (!text.empty())
+	{
+		// agent_access can be 'A', 'M', and 'PG'.
+		gAgent.setMaturity(text[0]);
+	}
+	
+	// this is the value of their preference setting for that content
+	// which will always be <= agent_access_max
+	text = response["agent_region_access"].asString();
+	if (!text.empty())
+	{
+		int preferredMaturity = LLAgent::convertTextToMaturity(text[0]);
+		gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
+	}
+	// During the AO transition, this flag will be true. Then the flag will
+	// go away. After the AO transition, this code and all the code that
+	// uses it can be deleted.
+	text = response["ao_transition"].asString();
+	if (!text.empty())
+	{
+		if (text == "1")
+		{
+			gAgent.setAOTransition();
+		}
+	}
+
+	text = response["start_location"].asString();
+	if(!text.empty()) 
+	{
+		gAgentStartLocation.assign(text);
+	}
+
+	text = response["circuit_code"].asString();
+	if(!text.empty())
+	{
+		gMessageSystem->mOurCircuitCode = strtoul(text.c_str(), NULL, 10);
+	}
+	std::string sim_ip_str = response["sim_ip"];
+	std::string sim_port_str = response["sim_port"];
+	if(!sim_ip_str.empty() && !sim_port_str.empty())
+	{
+		U32 sim_port = strtoul(sim_port_str.c_str(), NULL, 10);
+		gFirstSim.set(sim_ip_str, sim_port);
+		if (gFirstSim.isOk())
+		{
+			gMessageSystem->enableCircuit(gFirstSim, TRUE);
+		}
+	}
+	std::string region_x_str = response["region_x"];
+	std::string region_y_str = response["region_y"];
+	if(!region_x_str.empty() && !region_y_str.empty())
+	{
+		U32 region_x = strtoul(region_x_str.c_str(), NULL, 10);
+		U32 region_y = strtoul(region_y_str.c_str(), NULL, 10);
+		gFirstSimHandle = to_region_handle(region_x, region_y);
+	}
+	
+	const std::string look_at_str = response["look_at"];
+	if (!look_at_str.empty())
+	{
+		size_t len = look_at_str.size();
+		LLMemoryStream mstr((U8*)look_at_str.c_str(), len);
+		LLSD sd = LLSDSerialize::fromNotation(mstr, len);
+		gAgentStartLookAt = ll_vector3_from_sd(sd);
+	}
+
+	text = response["seed_capability"].asString();
+	if (!text.empty()) gFirstSimSeedCap = text;
+				
+	text = response["seconds_since_epoch"].asString();
+	if(!text.empty())
+	{
+		U32 server_utc_time = strtoul(text.c_str(), NULL, 10);
+		if(server_utc_time)
+		{
+			time_t now = time(NULL);
+			gUTCOffset = (server_utc_time - now);
+		}
+	}
+
+	std::string home_location = response["home"];
+	if(!home_location.empty())
+	{
+		size_t len = home_location.size();
+		LLMemoryStream mstr((U8*)home_location.c_str(), len);
+		LLSD sd = LLSDSerialize::fromNotation(mstr, len);
+		S32 region_x = sd["region_handle"][0].asInteger();
+		S32 region_y = sd["region_handle"][1].asInteger();
+		U64 region_handle = to_region_handle(region_x, region_y);
+		LLVector3 position = ll_vector3_from_sd(sd["position"]);
+		gAgent.setHomePosRegion(region_handle, position);
+	}
+
+	gAgent.mMOTD.assign(response["message"]);
+
+	// Options...
+	// Each 'option' is an array of submaps. 
+	// It appears that we only ever use the first element of the array.
+	LLUUID inv_root_folder_id = response["inventory-root"][0]["folder_id"];
+	if(inv_root_folder_id.notNull())
+	{
+		gAgent.mInventoryRootID = inv_root_folder_id;
+		//gInventory.mock(gAgent.getInventoryRootID());
+	}
+
+	LLSD login_flags = response["login-flags"][0];
+	if(login_flags.size())
+	{
+		std::string flag = login_flags["ever_logged_in"];
+		if(!flag.empty())
+		{
+			gAgent.setFirstLogin((flag == "N") ? TRUE : FALSE);
+		}
+
+		/*  Flag is currently ignored by the viewer.
+		flag = login_flags["stipend_since_login"];
+		if(flag == "Y") 
+		{
+			stipend_since_login = true;
+		}
+		*/
+
+		flag = login_flags["gendered"].asString();
+		if(flag == "Y")
+		{
+			gAgent.setGenderChosen(TRUE);
+		}
+		
+		flag = login_flags["daylight_savings"].asString();
+		if(flag == "Y")
+		{
+			gPacificDaylightTime  = (flag == "Y") ? TRUE : FALSE;
+		}
+
+		//setup map of datetime strings to codes and slt & local time offset from utc
+		LLStringOps::setupDatetimeInfo (gPacificDaylightTime);
+	}
+
+	LLSD initial_outfit = response["initial-outfit"][0];
+	if(initial_outfit.size())
+	{
+		std::string flag = initial_outfit["folder_name"];
+		if(!flag.empty())
+		{
+			// Initial outfit is a folder in your inventory,
+			// must be an exact folder-name match.
+			sInitialOutfit = flag;
+		}
+
+		flag = initial_outfit["gender"].asString();
+		if(!flag.empty())
+		{
+			sInitialOutfitGender = flag;
+		}
+	}
+
+	LLSD global_textures = response["global-textures"][0];
+	if(global_textures.size())
+	{
+		// Extract sun and moon texture IDs.  These are used
+		// in the LLVOSky constructor, but I can't figure out
+		// how to pass them in.  JC
+		LLUUID id = global_textures["sun_texture_id"];
+		if(id.notNull())
+		{
+			gSunTextureID = id;
+		}
+
+		id = global_textures["moon_texture_id"];
+		if(id.notNull())
+		{
+			gMoonTextureID = id;
+		}
+
+		id = global_textures["cloud_texture_id"];
+		if(id.notNull())
+		{
+			gCloudTextureID = id;
+		}
+	}
+
+
+	bool success = false;
+	// JC: gesture loading done below, when we have an asset system
+	// in place.  Don't delete/clear user_credentials until then.
+	if(gAgentID.notNull()
+	   && gAgentSessionID.notNull()
+	   && gMessageSystem->mOurCircuitCode
+	   && gFirstSim.isOk()
+	   && gAgent.mInventoryRootID.notNull())
+	{
+		success = true;
+	}
+
+	return success;
+}
diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp
index 0c1ee42ffcd16d1322a315940f1283e338682c83..c94ba0a3e89032e2d22cb5f1b8839d3449b45957 100644
--- a/indra/newview/tests/llxmlrpclistener_test.cpp
+++ b/indra/newview/tests/llxmlrpclistener_test.cpp
@@ -26,7 +26,7 @@
 #include "llcontrol.h"
 #include "tests/wrapllerrs.h"
 
-LLControlGroup gSavedSettings;
+LLControlGroup gSavedSettings("Global");
 
 /*****************************************************************************
 *   TUT