diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6bb25969a6095ffb9fd8118c52e5c61bf3540df8..335998767cd084dd15ff72a1d94f6144ca5c1610 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2341,7 +2341,7 @@ void LLAppViewer::initUpdater()
 	std::string service_path = gSavedSettings.getString("UpdaterServicePath");
 	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
 
-	mUpdater->setParams(protocol_version, url, service_path, channel, version);
+	mUpdater->initialize(protocol_version, url, service_path, channel, version);
 	mUpdater->setCheckPeriod(check_period);
 	if(gSavedSettings.getBOOL("UpdaterServiceActive"))
 	{
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index 64a0f98c2a0cc4d1c8b5208fbdbb9d5814ad32db..980599dd48c3eb6cf5d93d55522aaa008d0b9a08 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -57,10 +57,13 @@ if(LL_TESTS)
       llupdaterservice.cpp
       )
 
-#  set_source_files_properties(
+# *NOTE:Mani - I was trying to use the preprocessor seam to mock out
+#              llifstream (and other) llcommon classes. I didn't work
+#              because of the windows declspec(dllimport)attribute.
+#set_source_files_properties(
 #    llupdaterservice.cpp
 #    PROPERTIES
-#      LL_TEST_ADDITIONAL_LIBRARIES "${PTH_LIBRARIES}"
+#      LL_TEST_ADDITIONAL_CFLAGS "-Dllifstream=llus_mock_llifstream"
 #    )
 
   LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}")
diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
index dc8ecc378adc872103e80f9d463002cf6d50ad91..fb628c99ebd56c0bd4872790f5cdd2e4e747f0e1 100644
--- a/indra/viewer_components/updater/llupdatedownloader.h
+++ b/indra/viewer_components/updater/llupdatedownloader.h
@@ -71,6 +71,11 @@ class LLUpdateDownloader::Client {
 public:
 	
 	// The download has completed successfully.
+	// data is a map containing the following items:
+	// url - source (remote) location
+	// hash - the md5 sum that should match the installer file.
+	// path - destination (local) location
+	// size - the size of the installer in bytes
 	virtual void downloadComplete(LLSD const & data) = 0;
 	
 	// The download failed.
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 4292da1528c3c6484d8e6d3071386a924ea7a74a..4eb317e668ea8d4cb295470143e81a285dd31fa4 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -33,12 +33,26 @@
 
 #include <boost/scoped_ptr.hpp>
 #include <boost/weak_ptr.hpp>
+#include "lldir.h"
+#include "llsdserialize.h"
+#include "llfile.h"
 
 #if LL_WINDOWS
 #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
 #endif
 
-boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
+
+namespace 
+{
+	boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
+
+	const std::string UPDATE_MARKER_FILENAME("SecondLifeUpdateReady.xml");
+	std::string update_marker_path()
+	{
+		return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, 
+											  UPDATE_MARKER_FILENAME);
+	}
+}
 
 class LLUpdaterServiceImpl : 
 	public LLUpdateChecker::Client,
@@ -59,7 +73,7 @@ class LLUpdaterServiceImpl :
 	LLUpdateDownloader mUpdateDownloader;
 	LLTimer mTimer;
 
-	void retry(void);
+	LLUpdaterService::app_exit_callback_t mAppExitCallback;
 	
 	LOG_CLASS(LLUpdaterServiceImpl);
 	
@@ -67,7 +81,7 @@ class LLUpdaterServiceImpl :
 	LLUpdaterServiceImpl();
 	virtual ~LLUpdaterServiceImpl();
 
-	void setParams(const std::string& protocol_version,
+	void initialize(const std::string& protocol_version,
 				   const std::string& url, 
 				   const std::string& path,
 				   const std::string& channel,
@@ -79,6 +93,11 @@ class LLUpdaterServiceImpl :
 	void stopChecking();
 	bool isChecking();
 	
+	void setAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) { mAppExitCallback = aecb;}
+
+	bool checkForInstall(); // Test if a local install is ready.
+	bool checkForResume(); // Test for resumeable d/l.
+
 	// LLUpdateChecker::Client:
 	virtual void error(std::string const & message);
 	virtual void optionalUpdate(std::string const & newVersion,
@@ -90,10 +109,14 @@ class LLUpdaterServiceImpl :
 	virtual void upToDate(void);
 	
 	// LLUpdateDownloader::Client
-	void downloadComplete(LLSD const & data) { retry(); }
-	void downloadError(std::string const & message) { retry(); }	
+	void downloadComplete(LLSD const & data);
+	void downloadError(std::string const & message);
 
 	bool onMainLoop(LLSD const & event);	
+
+private:
+	void retry(void);
+
 };
 
 const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl";
@@ -112,8 +135,8 @@ LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
 	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
 }
 
-void LLUpdaterServiceImpl::setParams(const std::string& protocol_version,
-									 const std::string& url, 
+void LLUpdaterServiceImpl::initialize(const std::string& protocol_version,
+									  const std::string& url, 
 									 const std::string& path,
 									 const std::string& channel,
 									 const std::string& version)
@@ -129,6 +152,12 @@ void LLUpdaterServiceImpl::setParams(const std::string& protocol_version,
 	mPath = path;
 	mChannel = channel;
 	mVersion = version;
+
+	// Check to see if an install is ready.
+	if(!checkForInstall())
+	{
+		checkForResume();
+	}	
 }
 
 void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds)
@@ -146,7 +175,7 @@ void LLUpdaterServiceImpl::startChecking()
 				"LLUpdaterService::startCheck().");
 		}
 		mIsChecking = true;
-		
+	
 		mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
 	}
 }
@@ -164,6 +193,45 @@ bool LLUpdaterServiceImpl::isChecking()
 	return mIsChecking;
 }
 
+bool LLUpdaterServiceImpl::checkForInstall()
+{
+	bool result = false; // return true if install is found.
+
+	llifstream update_marker(update_marker_path(), 
+							 std::ios::in | std::ios::binary);
+
+	if(update_marker.is_open())
+	{
+		// Found an update info - now lets see if its valid.
+		LLSD update_info;
+		LLSDSerialize::fromXMLDocument(update_info, update_marker);
+
+		// Get the path to the installer file.
+		LLSD path = update_info.get("path");
+		if(path.isDefined() && !path.asString().empty())
+		{
+			// install!
+		}
+
+		update_marker.close();
+		LLFile::remove(update_marker_path());
+		result = true;
+	}
+	return result;
+}
+
+bool LLUpdaterServiceImpl::checkForResume()
+{
+	bool result = false;
+	llstat stat_info;
+	if(0 == LLFile::stat(mUpdateDownloader.downloadMarkerPath(), &stat_info))
+	{
+		mUpdateDownloader.resume();
+		result = true;
+	}
+	return false;
+}
+
 void LLUpdaterServiceImpl::error(std::string const & message)
 {
 	retry();
@@ -188,6 +256,24 @@ void LLUpdaterServiceImpl::upToDate(void)
 	retry();
 }
 
+void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) 
+{ 
+	// Save out the download data to the SecondLifeUpdateReady
+	// marker file.
+	llofstream update_marker(update_marker_path());
+	LLSDSerialize::toPrettyXML(data, update_marker);
+
+	// Stop checking.
+	stopChecking();
+
+	// Wait for restart...?
+}
+
+void LLUpdaterServiceImpl::downloadError(std::string const & message) 
+{ 
+	retry(); 
+}
+
 void LLUpdaterServiceImpl::retry(void)
 {
 	LL_INFOS("UpdaterService") << "will check for update again in " << 
@@ -233,13 +319,13 @@ LLUpdaterService::~LLUpdaterService()
 {
 }
 
-void LLUpdaterService::setParams(const std::string& protocol_version,
+void LLUpdaterService::initialize(const std::string& protocol_version,
 								 const std::string& url, 
 								 const std::string& path,
 								 const std::string& channel,
 								 const std::string& version)
 {
-	mImpl->setParams(protocol_version, url, path, channel, version);
+	mImpl->initialize(protocol_version, url, path, channel, version);
 }
 
 void LLUpdaterService::setCheckPeriod(unsigned int seconds)
@@ -261,3 +347,8 @@ bool LLUpdaterService::isChecking()
 {
 	return mImpl->isChecking();
 }
+
+void LLUpdaterService::setImplAppExitCallback(LLUpdaterService::app_exit_callback_t aecb)
+{
+	return mImpl->setAppExitCallback(aecb);
+}
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 04adf461b6b3b3321a2240d4375ddb8145017565..42ec3a2cab3efbc381c9d2b75489373cdda19a87 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -27,6 +27,7 @@
 #define LL_UPDATERSERVICE_H
 
 #include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
 
 class LLUpdaterServiceImpl;
 
@@ -42,11 +43,11 @@ class LLUpdaterService
 	LLUpdaterService();
 	~LLUpdaterService();
 
-	void setParams(const std::string& protocol_version,
-				   const std::string& url, 
-				   const std::string& path,
-				   const std::string& channel,
-				   const std::string& version);
+	void initialize(const std::string& protocol_version,
+				    const std::string& url, 
+				    const std::string& path,
+				    const std::string& channel,
+				    const std::string& version);
 
 	void setCheckPeriod(unsigned int seconds);
 	
@@ -54,8 +55,17 @@ class LLUpdaterService
 	void stopChecking();
 	bool isChecking();
 
+	typedef boost::function<void (void)> app_exit_callback_t;
+	template <typename F>
+	void setAppExitCallback(F const &callable) 
+	{ 
+		app_exit_callback_t aecb = callable;
+		setImplAppExitCallback(aecb);
+	}
+
 private:
 	boost::shared_ptr<LLUpdaterServiceImpl> mImpl;
+	void setImplAppExitCallback(app_exit_callback_t aecb);
 };
 
 #endif // LL_UPDATERSERVICE_H
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 7f45ae51fb5997dd60d925ea7c745c8d5bb1f70d..57732ad0a56c981829a982cb36ce684ca3bf46ee 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -36,6 +36,7 @@
 #include "../../../test/debug.h"
 
 #include "llevents.h"
+#include "lldir.h"
 
 /*****************************************************************************
 *   MOCK'd
@@ -48,6 +49,70 @@ void LLUpdateChecker::check(std::string const & protocolVersion, std::string con
 LLUpdateDownloader::LLUpdateDownloader(Client & ) {}
 void LLUpdateDownloader::download(LLURI const & , std::string const &){}
 
+class LLDir_Mock : public LLDir
+{
+	void initAppDirs(const std::string &app_name, 
+		   			 const std::string& app_read_only_data_dir = "") {}
+	U32 countFilesInDir(const std::string &dirname, const std::string &mask) 
+	{
+		return 0;
+	}
+
+	BOOL getNextFileInDir(const std::string &dirname, 
+						  const std::string &mask, 
+						  std::string &fname, BOOL wrap) 
+	{
+		return false;
+	}
+	void getRandomFileInDir(const std::string &dirname, 
+							const std::string &mask, 
+							std::string &fname) {}
+	std::string getCurPath() { return ""; }
+	BOOL fileExists(const std::string &filename) const { return false; }
+	std::string getLLPluginLauncher() { return ""; }
+	std::string getLLPluginFilename(std::string base_name) { return ""; }
+
+} gDirUtil;
+LLDir* gDirUtilp = &gDirUtil;
+LLDir::LLDir() {}
+LLDir::~LLDir() {}
+S32 LLDir::deleteFilesInDir(const std::string &dirname, 
+							const std::string &mask)
+{ return 0; }
+
+void LLDir::setChatLogsDir(const std::string &path){}		
+void LLDir::setPerAccountChatLogsDir(const std::string &username){}
+void LLDir::setLindenUserDir(const std::string &username){}		
+void LLDir::setSkinFolder(const std::string &skin_folder){}
+bool LLDir::setCacheDir(const std::string &path){ return true; }
+void LLDir::dumpCurrentDirectories() {}
+
+std::string LLDir::getExpandedFilename(ELLPath location, 
+									   const std::string &filename) const 
+{
+	return "";
+}
+
+std::string LLUpdateDownloader::downloadMarkerPath(void)
+{
+	return "";
+}
+
+void LLUpdateDownloader::resume(void) {}
+
+/*
+#pragma warning(disable: 4273)
+llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename,
+										   ios_base::openmode _Mode,
+										   int _Prot) :
+	std::basic_istream<char,std::char_traits< char > >(NULL,true)
+{}
+
+llus_mock_llifstream::~llus_mock_llifstream() {}
+bool llus_mock_llifstream::is_open() const {return true;}
+void llus_mock_llifstream::close() {}
+*/
+
 /*****************************************************************************
 *   TUT
 *****************************************************************************/
@@ -96,9 +161,9 @@ namespace tut
 		bool got_usage_error = false;
 		try
 		{
-			updater.setParams("1.0",test_url, "update" ,test_channel, test_version);
+			updater.initialize("1.0",test_url, "update" ,test_channel, test_version);
 			updater.startChecking();
-			updater.setParams("1.0", "other_url", "update", test_channel, test_version);
+			updater.initialize("1.0", "other_url", "update", test_channel, test_version);
 		}
 		catch(LLUpdaterService::UsageError)
 		{
@@ -112,7 +177,7 @@ namespace tut
     {
         DEBUG;
 		LLUpdaterService updater;
-		updater.setParams("1.0", test_url, "update", test_channel, test_version);
+		updater.initialize("1.0", test_url, "update", test_channel, test_version);
 		updater.startChecking();
 		ensure(updater.isChecking());
 		updater.stopChecking();