diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index e6feaae504995c1dc0cccf152480ff9e300ef4e4..06300141be52d63b0cf466f7428fa78514f95e1f 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -632,9 +632,6 @@ bool LLAppViewer::init()
 	if (!initConfiguration())
 		return false;
 
-	// Initialize updater service
-	initUpdater();
-
 	// write Google Breakpad minidump files to our log directory
 	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
 	logdir += gDirUtilp->getDirDelimiter();
@@ -980,7 +977,10 @@ bool LLAppViewer::mainLoop()
 	gServicePump = new LLPumpIO(gAPRPoolp);
 	LLHTTPClient::setPump(*gServicePump);
 	LLCurl::setCAFile(gDirUtilp->getCAFile());
-
+	
+	// Initialize updater service (now that we have an io pump)
+	initUpdater();
+	
 	// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
 
 	LLVoiceChannel::initClass();
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index 21467a2ab856146a27974ab38046146c02a657e0..8ccfdb071b663a0c5d73955c0c3dafef5f13976b 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -64,7 +64,7 @@ void LLTranslate::translateMessage(LLHTTPClient::ResponderPtr &result, const std
 	getTranslateUrl(url, from_lang, to_lang, mesg);
 
     std::string user_agent = llformat("%s %d.%d.%d (%d)",
-		LLVersionInfo::getChannel(),
+		LLVersionInfo::getChannel().c_str(),
 		LLVersionInfo::getMajor(),
 		LLVersionInfo::getMinor(),
 		LLVersionInfo::getPatch(),
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index a8a1d685f7c8037198084e7dfcaa1d26f506582a..2e77a7140a2d39fad8fe50af7babea32a6d41c98 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -18,10 +18,12 @@ include_directories(
 
 set(updater_service_SOURCE_FILES
     llupdaterservice.cpp
+    llupdatechecker.cpp
     )
 
 set(updater_service_HEADER_FILES
     llupdaterservice.h
+    llupdatechecker.h
     )
 
 set_source_files_properties(${updater_service_HEADER_FILES}
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a19b8be607c37ebbe6f57b0dbe54b206c5e93a8d
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -0,0 +1,131 @@
+/** 
+ * @file llupdaterservice.cpp
+ *
+ * $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 "linden_common.h"
+#include <boost/format.hpp>
+#include "llhttpclient.h"
+#include "llupdatechecker.h"
+
+
+class LLUpdateChecker::Implementation:
+	public LLHTTPClient::Responder
+{
+public:
+	
+	Implementation(Client & client);
+	void check(std::string const & host, std::string channel, std::string version);
+	
+	// Responder:
+	virtual void completed(U32 status,
+						   const std::string & reason,
+						   const LLSD& content);
+	virtual void error(U32 status, const std::string & reason);
+	
+private:
+	std::string buildUrl(std::string const & host, std::string channel, std::string version);
+	
+	Client & mClient;
+	LLHTTPClient mHttpClient;
+	bool mInProgress;
+	std::string mVersion;
+	
+	LOG_CLASS(LLUpdateChecker::Implementation);
+};
+
+
+
+// LLUpdateChecker
+//-----------------------------------------------------------------------------
+
+
+LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
+	mImplementation(new LLUpdateChecker::Implementation(client))
+{
+	; // No op.
+}
+
+
+void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version)
+{
+	mImplementation->check(host, channel, version);
+}
+
+
+
+// LLUpdateChecker::Implementation
+//-----------------------------------------------------------------------------
+
+
+LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client):
+	mClient(client),
+	mInProgress(false)
+{
+	; // No op.
+}
+
+
+void LLUpdateChecker::Implementation::check(std::string const & host, std::string channel, std::string version)
+{
+	llassert(!mInProgress);
+		
+	mInProgress = true;
+	mVersion = version;
+	std::string checkUrl = buildUrl(host, channel, version);
+	LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl;
+	mHttpClient.get(checkUrl, this);
+}
+
+void LLUpdateChecker::Implementation::completed(U32 status,
+							  const std::string & reason,
+							  const LLSD & content)
+{
+	mInProgress = false;
+	
+	if(status != 200) {
+		LL_WARNS("UpdateCheck") << "html error " << status << " (" << reason << ")" << llendl;
+	} else if(!content["valid"].asBoolean()) {
+		LL_INFOS("UpdateCheck") << "version invalid" << llendl;
+	} else if(content["latest_version"].asString() != mVersion) {
+		LL_INFOS("UpdateCheck") << "newer version " << content["latest_version"].asString() << " available" << llendl;
+	} else {
+		LL_INFOS("UpdateCheck") << "up to date" << llendl;
+	}
+}
+
+
+void LLUpdateChecker::Implementation::error(U32 status, const std::string & reason)
+{
+	mInProgress = false;
+	LL_WARNS("UpdateCheck") << "update check failed; " << reason << llendl;
+}
+
+
+std::string LLUpdateChecker::Implementation::buildUrl(std::string const & host, std::string channel, std::string version)
+{	
+	static boost::format urlFormat("%s/version/%s/%s");
+	urlFormat % host % channel % version;
+	return urlFormat.str();
+}
+
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
new file mode 100644
index 0000000000000000000000000000000000000000..d2ec848e14b10aed4fc833b2bc47af189a56e8ce
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -0,0 +1,69 @@
+/** 
+ * @file llupdatechecker.h
+ *
+ * $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 LL_UPDATERCHECKER_H
+#define LL_UPDATERCHECKER_H
+
+
+#include <boost/shared_ptr.hpp>
+
+
+//
+// Implements asynchronous checking for updates.
+//
+class LLUpdateChecker {
+public:
+	class Client;
+	class Implementation;
+	
+	LLUpdateChecker(Client & client);
+	
+	// Check status of current app on the given host for the channel and version provided.
+	void check(std::string const & hostUrl, std::string channel, std::string version);
+private:
+	boost::shared_ptr<Implementation> mImplementation;
+};
+
+
+//
+// The client interface implemented by a requestor checking for an update.
+//
+class LLUpdateChecker::Client
+{
+	// An error occurred while checking for an update.
+	virtual void error(std::string const & message) = 0;
+	
+	// A newer version is available, but the current version may still be used.
+	virtual void optionalUpdate(std::string const & newVersion) = 0;
+	
+	// A newer version is available, and the current version is no longer valid. 
+	virtual void requiredUpdate(std::string const & newVersion) = 0;
+	
+	// The checked version is up to date; no newer version exists.
+	virtual void upToDate(void) = 0;
+};
+
+
+#endif
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 28c942b5f21fd59127d438afa21464adc8489b57..e0f23722dd63daaab6f282bef95b17193ea1d668 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -26,6 +26,7 @@
 #include "linden_common.h"
 
 #include "llupdaterservice.h"
+#include "llupdatechecker.h"
 
 #include "llpluginprocessparent.h"
 #include <boost/scoped_ptr.hpp>
@@ -33,7 +34,9 @@
 
 boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
 
-class LLUpdaterServiceImpl : public LLPluginProcessParentOwner
+class LLUpdaterServiceImpl : 
+	public LLPluginProcessParentOwner,
+	public LLUpdateChecker::Client
 {
 	std::string mUrl;
 	std::string mChannel;
@@ -42,7 +45,9 @@ class LLUpdaterServiceImpl : public LLPluginProcessParentOwner
 	unsigned int mCheckPeriod;
 	bool mIsChecking;
 	boost::scoped_ptr<LLPluginProcessParent> mPlugin;
-
+	
+	LLUpdateChecker mUpdateChecker;
+	
 public:
 	LLUpdaterServiceImpl();
 	virtual ~LLUpdaterServiceImpl() {}
@@ -62,12 +67,21 @@ class LLUpdaterServiceImpl : public LLPluginProcessParentOwner
 	void startChecking();
 	void stopChecking();
 	bool isChecking();
+	
+	// LLUpdateChecker::Client:
+	virtual void error(std::string const & message);
+	virtual void optionalUpdate(std::string const & newVersion);
+	virtual void requiredUpdate(std::string const & newVersion);
+	virtual void upToDate(void);
+	
 };
 
+
 LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
 	mIsChecking(false),
 	mCheckPeriod(0),
-	mPlugin(0)
+	mPlugin(0),
+	mUpdateChecker(*this)
 {
 	// Create the plugin parent, this is the owner.
 	mPlugin.reset(new LLPluginProcessParent(this));
@@ -121,6 +135,8 @@ void LLUpdaterServiceImpl::startChecking()
 				"LLUpdaterService::startCheck().");
 		}
 		mIsChecking = true;
+		
+		mUpdateChecker.check(mUrl, mChannel, mVersion);
 	}
 }
 
@@ -137,6 +153,15 @@ bool LLUpdaterServiceImpl::isChecking()
 	return mIsChecking;
 }
 
+void LLUpdaterServiceImpl::error(std::string const & message) {}
+
+void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion) {}
+
+void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion) {}
+
+void LLUpdaterServiceImpl::upToDate(void) {}
+
+
 //-----------------------------------------------------------------------
 // Facade interface
 LLUpdaterService::LLUpdaterService()
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 73cf6ea6eb41e71a58194ac9464f03d567cbb699..d93a85cf7d294330de440734a366990e458385c7 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -28,6 +28,7 @@
 #include "linden_common.h"
 // associated header
 #include "../llupdaterservice.h"
+#include "../llupdatechecker.h"
 
 #include "../../../test/lltut.h"
 //#define DEBUG_ON
@@ -54,6 +55,11 @@ int LLPluginMessagePipeOwner::socketError(int) { return 0; }
 void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) {}
 void LLPluginMessagePipeOwner::setMessagePipe(class LLPluginMessagePipe *) {}
 LLPluginMessage::~LLPluginMessage() {}
+LLPluginMessage::LLPluginMessage(LLPluginMessage const&) {}
+
+LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
+{}
+void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version){}
 
 /*****************************************************************************
 *   TUT