diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 305531b9ccf7b0d31ff600c5e911c445b0cb6816..829ea25e38fa9c14a1b19da963cbb8f4e53d290e 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -36,11 +36,23 @@
 #include "../llmath/llmath.h"
 #include "llformat.h"
 
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+#define NAME_UNNAMED_NAMESPACE
+#endif
+
+#ifdef NAME_UNNAMED_NAMESPACE
+namespace LLSDUnnamedNamespace {
+#else
 namespace {
+#endif
 	class ImplMap;
 	class ImplArray;
 }
 
+#ifdef NAME_UNNAMED_NAMESPACE
+using namespace LLSDUnnamedNamespace;
+#endif
+
 class LLSD::Impl
 	/**< This class is the abstract base class of the implementation of LLSD
 		 It provides the reference counting implementation, and the default
@@ -125,7 +137,11 @@ class LLSD::Impl
 	static U32 sOutstandingCount;
 };
 
+#ifdef NAME_UNNAMED_NAMESPACE
+namespace LLSDUnnamedNamespace {
+#else
 namespace {
+#endif
 	template<LLSD::Type T, class Data, class DataRef = Data>
 	class ImplBase : public LLSD::Impl
 		///< This class handles most of the work for a subclass of Impl
@@ -632,7 +648,11 @@ U32 LLSD::Impl::sOutstandingCount = 0;
 
 
 
+#ifdef NAME_UNNAMED_NAMESPACE
+namespace LLSDUnnamedNamespace {
+#else
 namespace {
+#endif
 	inline LLSD::Impl& safe(LLSD::Impl* impl)
 		{ return LLSD::Impl::safe(impl); }
 		
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 01976b12f1500cf578b59bff1255ebd708e1ff08..9b5e6cd4e65ea657cd017f10ef0d86cd50f0c481 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -367,6 +367,11 @@ LLCurl::getByteRange(const std::string& url, S32 offset, S32 length, ResponderPt
 	mainMulti()->getByteRange(url, offset, length, responder);
 }
 	
+void LLCurl::initClass()
+{
+    curl_global_init(CURL_GLOBAL_ALL);
+}
+
 void
 LLCurl::process()
 {
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index d21cdc4e47f09a9edf7a62ae4b6360ee59260c0f..53287c298883f5e08c4f5a808e3288eb20c8c675 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -130,8 +130,9 @@ class LLCurl
 	static void get(const std::string& url, ResponderPtr);
 	static void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr responder);
 	
+    static void initClass(); // *NOTE:Mani - not thread safe!
 	static void process();
-	static void cleanup();
+	static void cleanup(); // *NOTE:Mani - not thread safe!
 };
 
 namespace boost
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 36ccc3225501125ae1fb36b113e6d8fa0874f3df..26ce473e082610e7dfee68975f01a66f8ab7fb59 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -368,9 +368,6 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
 				(*mClickedCallback)( mCallbackUserData );
 			}			
 		}
-
-		mMouseDownTimer.stop();
-		mMouseDownTimer.reset();
 	}
 
 	return TRUE;
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index c0b0788c0b3d88e2ebfa08b07fc9b98adc0c3503..efd42455e5b836c31098c722badc4f8879aa0d5e 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -49,6 +49,9 @@ LLTextBox::LLTextBox(const LLString& name, const LLRect& rect, const LLString& t
 	mDisabledColor(		LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ),
 	mBackgroundColor(	LLUI::sColorsGroup->getColor( "DefaultBackgroundColor" ) ),
 	mBorderColor(		LLUI::sColorsGroup->getColor( "DefaultHighlightLight" ) ),
+	mHoverColor(		LLUI::sColorsGroup->getColor( "LabelSelectedColor" ) ),
+	mHoverActive( FALSE ),
+	mHasHover( FALSE ),
 	mBackgroundVisible( FALSE ),
 	mBorderVisible( FALSE ),
 	mFontStyle(LLFontGL::DROP_SHADOW_SOFT),
@@ -74,6 +77,9 @@ LLTextBox::LLTextBox(const LLString& name, const LLString& text, F32 max_width,
 	mDisabledColor(LLUI::sColorsGroup->getColor("LabelDisabledColor")),
 	mBackgroundColor(LLUI::sColorsGroup->getColor("DefaultBackgroundColor")),
 	mBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")),
+	mHoverColor( LLUI::sColorsGroup->getColor( "LabelSelectedColor" ) ),
+	mHoverActive( FALSE ),
+	mHasHover( FALSE ),
 	mBackgroundVisible(FALSE),
 	mBorderVisible(FALSE),
 	mFontStyle(LLFontGL::DROP_SHADOW_SOFT),
@@ -161,6 +167,16 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
 	return handled;
 }
 
+BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask)
+{
+	if(mHoverActive)
+	{
+		mHasHover = TRUE; // This should be set every frame during a hover.
+		return TRUE;
+	}
+	return FALSE;
+}
+
 void LLTextBox::setText(const LLStringExplicit& text)
 {
 	mText.assign(text);
@@ -334,7 +350,15 @@ void LLTextBox::draw()
 
 		if ( getEnabled() )
 		{
-			drawText( text_x, text_y, mTextColor );
+			if(mHasHover)
+			{
+				drawText( text_x, text_y, mHoverColor );
+			}
+			else
+			{
+				drawText( text_x, text_y, mTextColor );
+			}				
+
 		}
 		else
 		{
@@ -346,6 +370,8 @@ void LLTextBox::draw()
 			drawDebugRect();
 		}
 	}
+
+	mHasHover = FALSE; // This is reset every frame.
 }
 
 void LLTextBox::reshape(S32 width, S32 height, BOOL called_from_parent)
@@ -468,5 +494,20 @@ LLView* LLTextBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f
 		text_box->setColor(color);
 	}
 
+	if(node->hasAttribute("hover_color"))
+	{
+		LLColor4 color;
+		LLUICtrlFactory::getAttributeColor(node, "hover_color", color);
+		text_box->setHoverColor(color);
+		text_box->setHoverActive(true);
+	}
+
+	BOOL hover_active = FALSE;
+	if(node->getAttributeBOOL("hover", hover_active))
+	{
+		text_box->setHoverActive(hover_active);
+	}
+
+
 	return text_box;
 }
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 7e7018ac52e27e0f16b5af40143367274271fded..c7c79464a051dd2748b835dbd0aab95d68762a2a 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -66,11 +66,16 @@ class LLTextBox
 
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
+	virtual BOOL	handleHover(S32 x, S32 y, MASK mask);
 
 	void			setColor( const LLColor4& c )			{ mTextColor = c; }
 	void			setDisabledColor( const LLColor4& c)	{ mDisabledColor = c; }
 	void			setBackgroundColor( const LLColor4& c)	{ mBackgroundColor = c; }	
 	void			setBorderColor( const LLColor4& c)		{ mBorderColor = c; }	
+
+	void			setHoverColor( const LLColor4& c )		{ mHoverColor = c; }
+	void			setHoverActive( BOOL active )			{ mHoverActive = active; }
+
 	void			setText( const LLStringExplicit& text );
 	void			setWrappedText(const LLStringExplicit& text, F32 max_width = -1.0);
 						// default width means use existing control width
@@ -108,10 +113,12 @@ class LLTextBox
 	const LLFontGL*	mFontGL;
 	LLColor4		mTextColor;
 	LLColor4		mDisabledColor;
-
 	LLColor4		mBackgroundColor;
 	LLColor4		mBorderColor;
-	
+	LLColor4		mHoverColor;
+
+	BOOL			mHoverActive;	
+	BOOL			mHasHover;
 	BOOL			mBackgroundVisible;
 	BOOL			mBorderVisible;
 	
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index a19107dd9c598be9b4668750968dbd5b3e5e58c1..54f6741fee6127681a55a5aea95ff166b6c44b79 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -112,6 +112,7 @@
 #include "llviewerregion.h"
 #include "llviewerstats.h"
 #include "llviewerwindow.h"
+#include "llviewerdisplay.h"
 #include "llvoavatar.h"
 #include "llvoground.h"
 #include "llvosky.h"
@@ -121,7 +122,8 @@
 #include "llworldmap.h"
 #include "pipeline.h"
 #include "roles_constants.h"
-#include "viewer.h"
+#include "llviewercontrol.h"
+#include "llappviewer.h"
 #include "llvoiceclient.h"
 
 // Ventrella
@@ -130,7 +132,6 @@
 
 extern LLMenuBarGL* gMenuBarView;
 extern U8 gLastPickAlpha;
-extern F32 gFrameDTClamped;
 
 //drone wandering constants
 const F32 MAX_WANDER_TIME = 20.f;						// seconds
@@ -222,6 +223,9 @@ const LLUUID BAKED_TEXTURE_HASH[BAKED_TEXTURE_COUNT] =
 	LLUUID("ea800387-ea1a-14e0-56cb-24f2022f969a")
 };
 
+// The agent instance.
+LLAgent gAgent;
+
 //
 // Statics
 //
@@ -2545,8 +2549,8 @@ void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y)
 		LLVector3 headLookAxis;
 		LLCoordFrame frameCamera = *((LLCoordFrame*)gCamera);
 
-		F32 x_from_center = mouse_x_from_center( mouse_x );	// range from -0.5 to 0.5
-		F32 y_from_center = mouse_y_from_center( mouse_y );	// range from -0.5 to 0.5
+		F32 x_from_center = ((F32) mouse_x / (F32) gViewerWindow->getWindowWidth() ) - 0.5f;
+		F32 y_from_center = ((F32) mouse_y / (F32) gViewerWindow->getWindowHeight() ) - 0.5f;
 
 		if (cameraMouselook())
 		{
@@ -2811,7 +2815,7 @@ void LLAgent::endAnimationUpdateUI()
 
 		// HACK: If we're quitting, and we were in customize avatar, don't
 		// let the mini-map go visible again. JC
-		if (!gQuitRequested)
+        if (!LLAppViewer::instance()->quitRequested())
 		{
 			gFloaterMap->popVisible();
 		}
@@ -5828,7 +5832,7 @@ void LLAgent::requestEnterGodMode()
 	msg->addBOOLFast(_PREHASH_Godlike, TRUE);
 	msg->addUUIDFast(_PREHASH_Token, LLUUID::null);
 
-	// simulator and userserver need to know about your request
+	// simulators need to know about your request
 	sendReliableMessage();
 }
 
@@ -5843,7 +5847,7 @@ void LLAgent::requestLeaveGodMode()
 	msg->addBOOLFast(_PREHASH_Godlike, FALSE);
 	msg->addUUIDFast(_PREHASH_Token, LLUUID::null);
 
-	// simulator and userserver need to know about your request
+	// simulator needs to know about your request
 	sendReliableMessage();
 }
 
diff --git a/indra/newview/llagentpilot.cpp b/indra/newview/llagentpilot.cpp
index 9637c54a6d9b5d5247a746abefd66a087b6f1a38..f0bd452109fec7acb6be5cbc7ab71229aa97038b 100644
--- a/indra/newview/llagentpilot.cpp
+++ b/indra/newview/llagentpilot.cpp
@@ -38,7 +38,7 @@
 #include "llagentpilot.h"
 #include "llagent.h"
 #include "llframestats.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "llviewercontrol.h"
 
 LLAgentPilot gAgentPilot;
@@ -221,7 +221,7 @@ void LLAgentPilot::updateTarget()
 						else if (mQuitAfterRuns)
 						{
 							llinfos << "Done with all runs, quitting viewer!" << llendl;
-							app_force_quit(NULL);
+							LLAppViewer::instance()->forceQuit();
 						}
 						else
 						{
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c763ff928c637ed86024231e0fc4cc600375103b
--- /dev/null
+++ b/indra/newview/llappviewer.cpp
@@ -0,0 +1,3894 @@
+/** 
+ * @file llappviewer.cpp
+ * @brief The LLAppViewer class definitions
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+#include "llappviewer.h"
+
+#include "llversionviewer.h"
+#include "llfeaturemanager.h"
+#include "llvieweruictrlfactory.h"
+#include "llalertdialog.h"
+#include "llerrorcontrol.h"
+#include "llviewerimagelist.h"
+#include "llgroupmgr.h"
+#include "llagent.h"
+#include "llwindow.h"
+#include "llviewerstats.h"
+#include "llmd5.h"
+#include "llpumpio.h"
+#include "llfloateractivespeakers.h"
+#include "llimpanel.h"
+#include "llstartup.h"
+#include "llfocusmgr.h"
+#include "llviewerjoystick.h"
+#include "llcurl.h"
+#include "llfloatersnapshot.h"
+#include "llviewerwindow.h"
+#include "llviewerdisplay.h"
+#include "llviewermessage.h"
+#include "llviewerobjectlist.h"
+#include "llworldmap.h"
+#include "llmutelist.h"
+
+#include "llweb.h"
+#include "llsecondlifeurls.h"
+
+#if LL_WINDOWS
+	#include "llwindebug.h"
+#endif
+
+#if LL_WINDOWS
+#	include <share.h> // For _SH_DENYWR in initMarkerFile
+#else
+#   include <sys/file.h> // For initMarkerFile support
+#endif
+
+
+
+#include "llnotify.h"
+#include "llmediaengine.h"
+#include "llviewerkeyboard.h"
+#include "lllfsthread.h"
+#include "llworkerthread.h"
+#include "lltexturecache.h"
+#include "lltexturefetch.h"
+#include "llimageworker.h"
+
+// The files below handle dependencies from cleanup.
+#include "llkeyframemotion.h"
+#include "llworldmap.h"
+#include "llhudmanager.h"
+#include "lltoolmgr.h"
+#include "llassetstorage.h"
+#include "llpolymesh.h"
+#include "lleconomy.h"
+#include "llcachename.h"
+#include "audioengine.h"
+#include "llviewermenu.h"
+#include "llselectmgr.h"
+#include "lltracker.h"
+#include "llmozlib.h"
+#include "llviewerparcelmgr.h"
+#include "llworldmapview.h"
+
+#include "lldebugview.h"
+#include "llconsole.h"
+#include "llcontainerview.h"
+#include "llhoverview.h"
+
+#if LL_WINDOWS && LL_LCD_COMPILE
+	#include "lllcd.h"
+#endif
+
+#if LL_QUICKTIME_ENABLED
+	#if LL_DARWIN
+		#include <QuickTime/QuickTime.h>
+	#else
+		// quicktime specific includes
+		#include "MacTypes.h"
+		#include "QTML.h"
+		#include "Movies.h"
+		#include "FixMath.h"
+	#endif
+#endif
+
+#include "llworld.h"
+#include "llhudeffecttrail.h"
+#include "llvectorperfoptions.h"
+#include "llurlsimstring.h"
+
+// Included so that constants/settings might be initialized
+// in save_settings_to_globals()
+#include "llbutton.h"
+#include "llcombobox.h"
+#include "llstatusbar.h"
+#include "llsurface.h"
+#include "llvosky.h"
+#include "llvotree.h"
+#include "llvoavatar.h"
+#include "llfolderview.h"
+#include "lltoolbar.h"
+#include "llframestats.h"
+#include "llagentpilot.h"
+#include "llsrv.h"
+
+// includes for idle() idleShutdown()
+#include "llviewercontrol.h"
+#include "lleventnotifier.h"
+#include "llcallbacklist.h"
+#include "pipeline.h"
+#include "llgesturemgr.h"
+#include "llsky.h"
+#include "llvlmanager.h"
+#include "llviewercamera.h"
+#include "lldrawpoolbump.h"
+#include "llvieweraudio.h"
+#include "llimview.h"
+#include "llviewerthrottle.h"
+// 
+
+#include "llinventoryview.h"
+
+// *FIX: Remove these once the command line params thing is figured out.
+// Yuck!
+static int gTempArgC = 0;
+static char** gTempArgV;
+
+// *FIX: These extern globals should be cleaned up.
+// The globals either represent state/config/resource-storage of either 
+// this app, or another 'component' of the viewer. App globals should be 
+// moved into the app class, where as the other globals should be 
+// moved out of here.
+// If a global symbol reference seems valid, it will be included
+// via header files above.
+
+//----------------------------------------------------------------------------
+// llviewernetwork.h
+#include "llviewernetwork.h"
+// extern EGridInfo gGridChoice;
+
+//----------------------------------------------------------------------------
+// viewer.cpp - these are only used in viewer, should be easily moved.
+extern void disable_win_error_reporting();
+
+//#define APPLE_PREVIEW // Define this if you're doing a preview build on the Mac
+#if LL_RELEASE_FOR_DOWNLOAD
+// Default userserver for production builds is agni
+#ifndef APPLE_PREVIEW
+static EGridInfo GridDefaultChoice = GRID_INFO_AGNI;
+#else
+static EGridInfo GridDefaultChoice = GRID_INFO_ADITI;
+#endif
+#else
+// Default userserver for development builds is dmz
+static EGridInfo GridDefaultChoice = GRID_INFO_DMZ;
+#endif
+
+#if LL_WINDOWS
+extern void create_console();
+#endif
+
+
+#if LL_DARWIN
+#include <Carbon/Carbon.h>
+extern void init_apple_menu(const char* product);
+extern OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn);
+extern OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn);
+extern OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata);
+extern OSStatus DisplayReleaseNotes(void);
+#include <boost/tokenizer.hpp>
+#endif // LL_DARWIN
+
+
+#include "moviemaker.h"
+extern BOOL gbCapturing;
+
+#if !LL_SOLARIS
+	extern MovieMaker gMovieMaker;
+#endif
+
+extern BOOL gRandomizeFramerate;
+extern BOOL gPeriodicSlowFrame;
+
+#if LL_GSTREAMER_ENABLED
+void UnloadGStreamer();
+#endif
+
+extern void send_stats();
+////////////////////////////////////////////////////////////
+// All from the last globals push...
+bool gVerifySSLCert = true;
+BOOL gHandleKeysAsync = FALSE;
+
+BOOL gProbeHardware = TRUE; // Use DirectX 9 to probe for hardware
+
+S32 gYieldMS = 0; // set in parse_args, used in mainLoop
+BOOL gYieldTime = FALSE;
+
+const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard
+
+F32 gSimLastTime; // Used in LLAppViewer::init and send_stats()
+F32 gSimFrames;
+
+LLString gDisabledMessage; // Set in LLAppViewer::initConfiguration used in idle_startup
+
+BOOL gHideLinks = FALSE; // Set in LLAppViewer::initConfiguration, used externally
+
+BOOL gInProductionGrid	= FALSE; 
+
+BOOL				gAllowIdleAFK = TRUE;
+F32					gAFKTimeout = DEFAULT_AFK_TIMEOUT;
+BOOL				gShowObjectUpdates = FALSE;
+BOOL gLogMessages = FALSE;
+std::string gChannelName = LL_CHANNEL;
+BOOL gUseAudio = TRUE;
+LLString gCmdLineFirstName;
+LLString gCmdLineLastName;
+LLString gCmdLinePassword;
+
+BOOL				gAutoLogin = FALSE;
+
+const char*			DEFAULT_SETTINGS_FILE = "settings.xml";
+BOOL gRequestInventoryLibrary = TRUE;
+BOOL gGodConnect = FALSE;
+BOOL gAcceptTOS = FALSE;
+BOOL gAcceptCriticalMessage = FALSE;
+
+LLUUID				gViewerDigest;	// MD5 digest of the viewer's executable file.
+BOOL gLastExecFroze = FALSE;
+
+U32	gFrameCount = 0;
+U32 gForegroundFrameCount = 0; // number of frames that app window was in foreground
+LLPumpIO*			gServicePump = NULL;
+
+BOOL gPacificDaylightTime = FALSE;
+
+U64 gFrameTime = 0;
+F32 gFrameTimeSeconds = 0.f;
+F32 gFrameIntervalSeconds = 0.f;
+F32		gFPSClamped = 10.f;						// Pretend we start at target rate.
+F32		gFrameDTClamped = 0.f;					// Time between adjacent checks to network for packets
+U64	gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds
+
+LLTimer gRenderStartTime;
+LLFrameTimer gForegroundTime;
+LLTimer				gLogoutTimer;
+static const F32			LOGOUT_REQUEST_TIME = 6.f;  // this will be cut short by the LogoutReply msg.
+F32					gLogoutMaxTime = LOGOUT_REQUEST_TIME;
+
+LLUUID gInventoryLibraryOwner;
+LLUUID gInventoryLibraryRoot;
+
+BOOL				gDisableVoice = FALSE;
+BOOL				gDisconnected = FALSE;
+
+// Map scale in pixels per region
+F32 				gMapScale = 128.f;
+F32 				gMiniMapScale = 128.f;
+
+// used to restore texture state after a mode switch
+LLFrameTimer	gRestoreGLTimer;
+BOOL			gRestoreGL = FALSE;
+BOOL				gUseWireframe = FALSE;
+
+F32					gMouseSensitivity = 3.f;
+BOOL				gInvertMouse = FALSE;
+
+// VFS globals - see llappviewer.h
+LLVFS* gStaticVFS = NULL;
+
+LLMemoryInfo gSysMemory;
+
+bool gPreloadImages = true;
+bool gPreloadSounds = true;
+
+LLString gLastVersionChannel;
+
+LLVector3			gWindVec(3.0, 3.0, 0.0);
+LLVector3			gRelativeWindVec(0.0, 0.0, 0.0);
+
+U32		gPacketsIn = 0;
+
+BOOL				gPrintMessagesThisFrame = FALSE;
+
+BOOL gUseConsole = TRUE;
+
+BOOL gRandomizeFramerate = FALSE;
+BOOL gPeriodicSlowFrame = FALSE;
+
+BOOL gQAMode = FALSE;
+
+////////////////////////////////////////////////////////////
+// Internal globals... that should be removed.
+static F32 gQuitAfterSeconds = 0.f;
+static BOOL gRotateRight = FALSE;
+static BOOL gIgnorePixelDepth = FALSE;
+
+// Allow multiple viewers in ReleaseForDownload
+#if LL_RELEASE_FOR_DOWNLOAD
+static BOOL gMultipleViewersOK = FALSE;
+#else
+static BOOL gMultipleViewersOK = TRUE;
+#endif
+
+static std::map<std::string, std::string> gCommandLineSettings;
+static std::map<std::string, std::string> gCommandLineForcedSettings;
+
+static LLString gArgs;
+
+static LLString gOldSettingsFileName;
+static const char* LEGACY_DEFAULT_SETTINGS_FILE = "settings.ini";
+static BOOL gDoDisconnect = FALSE;
+static LLString gLaunchFileOnQuit;
+
+//----------------------------------------------------------------------------
+// File scope definitons
+const char *VFS_DATA_FILE_BASE = "data.db2.x.";
+const char *VFS_INDEX_FILE_BASE = "index.db2.x.";
+
+static LLString gSecondLife;
+static LLString gWindowTitle;
+#ifdef LL_WINDOWS
+	static char sWindowClass[] = "Second Life";
+#endif
+
+std::vector<std::string> gLoginURIs;
+static std::string gHelperURI;
+
+static const char USAGE[] = "\n"
+"usage:\tviewer [options]\n"
+"options:\n"
+" -login <first> <last> <password>     log in as a user\n"
+" -autologin                           log in as last saved user\n"
+" -loginuri <URI>                      login server and CGI script to use\n"
+" -helperuri <URI>                     helper web CGI prefix to use\n"
+" -settings <filename>                 specify the filename of a\n"
+"                                        configuration file\n"
+"                                        default is settings.xml\n"
+" -setdefault <variable> <value>       specify the value of a particular\n"
+"                                        configuration variable which can be\n"
+"                                        overridden by settings.xml\n"
+" -set <variable> <value>              specify the value of a particular\n"
+"                                        configuration variable that\n"
+"                                        overrides all other settings\n"
+" -user <user_server_ip>               specify userserver in dotted quad\n"
+#if !LL_RELEASE_FOR_DOWNLOAD
+" -sim <simulator_ip>                  specify the simulator ip address\n"
+#endif
+" -god		                           log in as god if you have god access\n"
+" -purge                               delete files in cache\n"
+" -safe                                reset preferences, run in safe mode\n"
+" -noutc                               logs in local time, not UTC\n"
+" -nothread                            run vfs in single thread\n"
+" -noinvlib                            Do not request inventory library\n"
+" -multiple                            allow multiple viewers\n"
+" -nomultiple                          block multiple viewers\n"
+" -novoice                             disable voice\n"
+" -ignorepixeldepth                    ignore pixel depth settings\n"
+" -cooperative [ms]                    yield some idle time to local host\n"
+" -skin                                ui/branding skin folder to use\n"
+#if LL_WINDOWS
+" -noprobe                             disable hardware probe\n"
+#endif
+" -noquicktime                         disable QuickTime movies, speeds startup\n"
+" -nopreload                           don't preload UI images or sounds, speeds startup\n"
+// these seem to be unused
+//" -noenv                               turn off environmental effects\n"
+//" -proxy <proxy_ip>                    specify the proxy ip address\n"
+"\n";
+
+void idle_afk_check()
+{
+	// check idle timers
+	if (gAllowIdleAFK && (gAwayTriggerTimer.getElapsedTimeF32() > gAFKTimeout))
+	{
+		gAgent.setAFK();
+	}
+}
+
+// A callback set in LLAppViewer::init()
+static void ui_audio_callback(const LLUUID& uuid)
+{
+	if (gAudiop)
+	{
+		F32 volume = gSavedSettings.getF32("AudioLevelUI");
+		gAudiop->triggerSound(uuid, gAgent.getID(), volume);
+	}
+}
+
+void request_initial_instant_messages()
+{
+	static BOOL requested = FALSE;
+	if (!requested
+		&& gMuteListp
+		&& gMuteListp->isLoaded()
+		&& gAgent.getAvatarObject())
+	{
+		// Auto-accepted inventory items may require the avatar object
+		// to build a correct name.  Likewise, inventory offers from
+		// muted avatars require the mute list to properly mute.
+		LLMessageSystem* msg = gMessageSystem;
+		msg->newMessageFast(_PREHASH_RetrieveInstantMessages);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		gAgent.sendReliableMessage();
+		requested = TRUE;
+	}
+}
+
+// Use these strictly for things that are constructed at startup,
+// or for things that are performance critical.  JC
+static void saved_settings_to_globals()
+{
+	LLBUTTON_H_PAD		= gSavedSettings.getS32("ButtonHPad");
+	LLBUTTON_V_PAD		= gSavedSettings.getS32("ButtonVPad");
+	BTN_HEIGHT_SMALL	= gSavedSettings.getS32("ButtonHeightSmall");
+	BTN_HEIGHT			= gSavedSettings.getS32("ButtonHeight");
+
+	MENU_BAR_HEIGHT		= gSavedSettings.getS32("MenuBarHeight");
+	MENU_BAR_WIDTH		= gSavedSettings.getS32("MenuBarWidth");
+	STATUS_BAR_HEIGHT	= gSavedSettings.getS32("StatusBarHeight");
+
+	LLCOMBOBOX_HEIGHT	= BTN_HEIGHT - 2;
+	LLCOMBOBOX_WIDTH	= 128;
+
+	LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
+
+	LLVOSky::sNighttimeBrightness		= gSavedSettings.getF32("RenderNightBrightness");
+	
+	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic");
+	LLVOVolume::sLODFactor				= gSavedSettings.getF32("RenderVolumeLODFactor");
+	LLVOVolume::sDistanceFactor			= 1.f-LLVOVolume::sLODFactor * 0.1f;
+	LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
+	LLVOTree::sTreeFactor				= gSavedSettings.getF32("RenderTreeLODFactor");
+	LLVOAvatar::sLODFactor				= gSavedSettings.getF32("RenderAvatarLODFactor");
+	LLVOAvatar::sMaxVisible				= gSavedSettings.getS32("RenderAvatarMaxVisible");
+	LLVOAvatar::sVisibleInFirstPerson	= gSavedSettings.getBOOL("FirstPersonAvatarVisible");
+	// clamp auto-open time to some minimum usable value
+	LLFolderView::sAutoOpenTime			= llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay"));
+	LLToolBar::sInventoryAutoOpenTime	= gSavedSettings.getF32("InventoryAutoOpenDelay");
+	LLSelectMgr::sRectSelectInclusive	= gSavedSettings.getBOOL("RectangleSelectInclusive");
+	LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections");
+	LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
+
+	gFrameStats.setTrackStats(gSavedSettings.getBOOL("StatsSessionTrackFrameStats"));
+	gAgentPilot.mNumRuns		= gSavedSettings.getS32("StatsNumRuns");
+	gAgentPilot.mQuitAfterRuns	= gSavedSettings.getBOOL("StatsQuitAfterRuns");
+	gAgent.mHideGroupTitle		= gSavedSettings.getBOOL("RenderHideGroupTitle");
+
+	gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
+	gAllowIdleAFK = gSavedSettings.getBOOL("AllowIdleAFK");
+	gAFKTimeout = gSavedSettings.getF32("AFKTimeout");
+	gMouseSensitivity = gSavedSettings.getF32("MouseSensitivity");
+	gInvertMouse = gSavedSettings.getBOOL("InvertMouse");
+	gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
+	gMapScale = gSavedSettings.getF32("MapScale");
+	gMiniMapScale = gSavedSettings.getF32("MiniMapScale");
+	gHandleKeysAsync = gSavedSettings.getBOOL("AsyncKeyboard");
+	LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips");
+
+#if LL_VECTORIZE
+	if (gSysCPU.hasAltivec())
+	{
+		gSavedSettings.setBOOL("VectorizeEnable", TRUE );
+		gSavedSettings.setU32("VectorizeProcessor", 0 );
+	}
+	else
+	if (gSysCPU.hasSSE2())
+	{
+		gSavedSettings.setBOOL("VectorizeEnable", TRUE );
+		gSavedSettings.setU32("VectorizeProcessor", 2 );
+	}
+	else
+	if (gSysCPU.hasSSE())
+	{
+		gSavedSettings.setBOOL("VectorizeEnable", TRUE );
+		gSavedSettings.setU32("VectorizeProcessor", 1 );
+	}
+	else
+	{
+		// Don't bother testing or running if CPU doesn't support it. JC
+		gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
+		gSavedSettings.setBOOL("VectorizeEnable", FALSE );
+		gSavedSettings.setU32("VectorizeProcessor", 0 );
+		gSavedSettings.setBOOL("VectorizeSkin", FALSE);
+	}
+#else
+	// This build target doesn't support SSE, don't test/run.
+	gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
+	gSavedSettings.setBOOL("VectorizeEnable", FALSE );
+	gSavedSettings.setU32("VectorizeProcessor", 0 );
+	gSavedSettings.setBOOL("VectorizeSkin", FALSE);
+#endif
+
+	// propagate push to talk preference to current status
+	gSavedSettings.setBOOL("PTTCurrentlyEnabled", gSavedSettings.getBOOL("EnablePushToTalk"));
+
+	settings_setup_listeners();
+
+	// gAgent.init() also loads from saved settings.
+}
+
+int parse_args(int argc, char **argv)
+{
+	// Sometimes IP addresses passed in on the command line have leading
+	// or trailing white space.  Use LLString to clean that up.
+	LLString ip_string;
+	S32 j;
+
+	for (j = 1; j < argc; j++) 
+	{
+		gArgs += argv[j];
+		gArgs += " ";
+
+		LLString argument = argv[j];
+		if ((!strcmp(argv[j], "-port")) && (++j < argc)) 
+		{
+			sscanf(argv[j], "%u", &(gAgent.mViewerPort));
+		}
+		else if ((!strcmp(argv[j], "-drop")) && (++j < argc)) 
+		{
+			sscanf(argv[j], "%f", &gPacketDropPercentage);
+		}
+		else if ((!strcmp(argv[j], "-inbw")) && (++j < argc))
+		{
+			sscanf(argv[j], "%f", &gInBandwidth);
+		}
+		else if ((!strcmp(argv[j], "-outbw")) && (++j < argc))
+		{
+			sscanf(argv[j], "%f", &gOutBandwidth);
+		}
+		else if (!strcmp(argv[j], "--aditi"))
+		{
+			gGridChoice = GRID_INFO_ADITI;
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--agni"))
+		{
+			gGridChoice = GRID_INFO_AGNI;
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--dmz"))
+		{
+			gGridChoice = GRID_INFO_DMZ;
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--siva"))
+		{
+			gGridChoice = GRID_INFO_SIVA;
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--shakti"))
+		{
+			gGridChoice = GRID_INFO_SHAKTI;
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--durga"))
+		{
+			gGridChoice = GRID_INFO_DURGA;
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--soma"))
+		{
+			gGridChoice = GRID_INFO_SOMA;
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--ganga"))
+		{
+			gGridChoice = GRID_INFO_GANGA;
+			sprintf(gGridName,"%s", gGridInfo[gGridChoice].mName);
+		}
+		else if (!strcmp(argv[j], "--vaak"))
+		{
+			gGridChoice = GRID_INFO_VAAK;
+			sprintf(gGridName,"%s", gGridInfo[gGridChoice].mName);
+		}
+		else if (!strcmp(argv[j], "--uma"))
+		{
+			gGridChoice = GRID_INFO_UMA;
+			sprintf(gGridName,"%s", gGridInfo[gGridChoice].mName);
+		}
+		else if (!strcmp(argv[j], "-user") && (++j < argc)) 
+		{
+			if (!strcmp(argv[j], "-"))
+			{
+				gGridChoice = GRID_INFO_LOCAL;
+				snprintf(gGridName, MAX_STRING, "%s", LOOPBACK_ADDRESS_STRING);		// Flawfinder: ignore
+			}
+			else
+			{
+				gGridChoice = GRID_INFO_OTHER;
+				ip_string.assign( argv[j] );
+				LLString::trim(ip_string);
+				snprintf(gGridName, MAX_STRING, "%s", ip_string.c_str());		// Flawfinder: ignore
+			}
+		}
+		else if (!strcmp(argv[j], "-loginuri") && (++j < argc))
+		{
+            LLAppViewer::instance()->addLoginURI(utf8str_trim(argv[j]));
+		}
+		else if (!strcmp(argv[j], "-helperuri") && (++j < argc))
+		{
+            LLAppViewer::instance()->setHelperURI(utf8str_trim(argv[j]));
+		}
+		else if (!strcmp(argv[j], "-debugviews"))
+		{
+			LLView::sDebugRects = TRUE;
+		}
+		else if (!strcmp(argv[j], "-skin") && (++j < argc))
+		{
+			std::string folder(argv[j]);
+			gDirUtilp->setSkinFolder(folder);
+		}
+		else if (!strcmp(argv[j], "-autologin") || !strcmp(argv[j], "--autologin")) // keep --autologin for compatibility
+		{
+			gAutoLogin = TRUE;
+		}
+		else if (!strcmp(argv[j], "-quitafter") && (++j < argc))
+		{
+			gQuitAfterSeconds = (F32)atof(argv[j]);
+		}
+		else if (!strcmp(argv[j], "-rotate"))
+		{
+			gRotateRight = TRUE;
+		}
+//		else if (!strcmp(argv[j], "-noenv")) 
+//		{
+			//turn OFF environmental effects for slow machines/video cards
+//			gRequestParaboloidMap = FALSE;
+//		}
+		else if (!strcmp(argv[j], "-noaudio"))
+		{
+			gUseAudio = FALSE;
+		}
+		else if (!strcmp(argv[j], "-nosound"))  // tends to be popular cmdline on Linux.
+		{
+			gUseAudio = FALSE;
+		}
+		else if (!strcmp(argv[j], "-noprobe"))
+		{
+			gProbeHardware = FALSE;
+		}
+		else if (!strcmp(argv[j], "-noquicktime"))
+		{
+			// Developers can log in faster if they don't load all the
+			// quicktime dlls.
+			gUseQuickTime = false;
+		}
+		else if (!strcmp(argv[j], "-nopreload"))
+		{
+			// Developers can log in faster if they don't decode sounds
+			// or images on startup, ~5 seconds faster.
+			gPreloadSounds = false;
+			gPreloadImages = false;
+		}
+		else if (!strcmp(argv[j], "-purge"))
+		{
+			LLAppViewer::instance()->purgeCache();
+		}
+		else if(!strcmp(argv[j], "-noinvlib"))
+		{
+			gRequestInventoryLibrary = FALSE;
+		}
+		else if (!strcmp(argv[j], "-log"))
+		{
+			gLogMessages = TRUE;
+			continue;
+		}
+		else if (!strcmp(argv[j], "-logfile") && (++j < argc)) 
+		{
+			// *NOTE: This buffer size is hard coded into scanf() below.
+			char logfile[256];	// Flawfinder: ignore
+			sscanf(argv[j], "%255s", logfile);	// Flawfinder: ignore
+			llinfos << "Setting log file to " << logfile << llendl;
+			LLFile::remove(logfile);
+			LLError::logToFile(logfile);
+		}
+		else if (!strcmp(argv[j], "-settings") && (++j < argc)) 
+		{
+			gSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, argv[j]);
+		}
+		else if (!strcmp(argv[j], "-setdefault") && (j + 2 < argc)) 
+		{
+			std::string control_name;
+			std::string control_value;
+			
+			j++;
+			if (argv[j]) control_name = std::string(argv[j]);
+
+			j++;
+			if (argv[j]) control_value = std::string(argv[j]);
+			
+			// grab control name and value
+			if (!control_name.empty())
+			{
+				gCommandLineSettings[control_name] = control_value;
+			}
+		}
+		else if (!strcmp(argv[j], "-set") && (j + 2 < argc)) 
+		{
+			std::string control_name;
+			std::string control_value;
+			
+			j++;
+			if (argv[j]) control_name = std::string(argv[j]);
+
+			j++;
+			if (argv[j]) control_value = std::string(argv[j]);
+			
+			// grab control name and value
+			if (!control_name.empty())
+			{
+				gCommandLineForcedSettings[control_name] = control_value;
+			}
+		}
+		else if (!strcmp(argv[j], "-login"))
+		{
+			if (j + 3 < argc)
+			{
+				j++;
+				gCmdLineFirstName = argv[j];
+				j++;
+				gCmdLineLastName = argv[j];
+				j++;
+				gCmdLinePassword = argv[j];
+			}
+			else
+			{
+				// only works if -login is last parameter on command line
+				llerrs << "Not enough parameters to -login. Did you mean -loginuri?" << llendl;
+			}
+		}
+		else if (!strcmp(argv[j], "-god"))
+		{
+			gGodConnect = TRUE;
+		}
+		else if (!strcmp(argv[j], "-noconsole"))
+		{
+			gUseConsole = FALSE;
+		}
+		else if (!strcmp(argv[j], "-safe"))
+		{
+			llinfos << "Setting viewer feature table to run in safe mode, resetting prefs" << llendl;
+			gFeatureManagerp->setSafe(TRUE);
+		}
+		else if (!strcmp(argv[j], "-multiple"))
+		{
+			gMultipleViewersOK = TRUE;
+		}
+		else if (!strcmp(argv[j], "-nomultiple"))
+		{
+			gMultipleViewersOK = FALSE;
+		}
+		else if (!strcmp(argv[j], "-novoice"))
+		{
+			gDisableVoice = TRUE;
+		}
+		else if (!strcmp(argv[j], "-nothread"))
+		{
+			LLVFile::ALLOW_ASYNC = FALSE;
+			llinfos << "Running VFS in nothread mode" << llendl;
+		}
+		// some programs don't respect the command line options in protocol handlers (I'm looking at you, Opera)
+		// so this allows us to parse the URL straight off the command line without a "-url" paramater
+		else if (!argument.compare(0, std::string( "secondlife://" ).length(), std::string("secondlife://")))
+		{
+			// *NOTE: After setting the url, bail. What can happen is
+			// that someone can use IE (or potentially other browsers)
+			// and do the rough equivalent of command injection and
+			// steal passwords. Phoenix. SL-55321
+			LLURLSimString::setString(argv[j]);
+			gArgs += argv[j];
+			return 0;
+		}
+		else if (!strcmp(argv[j], "-url") && (++j < argc)) 
+		{
+			// *NOTE: After setting the url, bail. What can happen is
+			// that someone can use IE (or potentially other browsers)
+			// and do the rough equivalent of command injection and
+			// steal passwords. Phoenix. SL-55321
+			LLURLSimString::setString(argv[j]);
+			gArgs += argv[j];
+			return 0;
+		}
+		else if (!strcmp(argv[j], "-ignorepixeldepth"))
+		{
+			gIgnorePixelDepth = TRUE;
+		}
+		else if (!strcmp(argv[j], "-cooperative"))
+		{
+			S32 ms_to_yield = 0;
+			if(++j < argc)
+			{
+				S32 rv = sscanf(argv[j], "%d", &ms_to_yield);
+				if(0 == rv)
+				{
+					--j;
+				}
+			}
+			else
+			{
+				--j;
+			}
+			gYieldMS = ms_to_yield;
+			gYieldTime = TRUE;
+		}
+		else if (!strcmp(argv[j], "-no-verify-ssl-cert"))
+		{
+			gVerifySSLCert = false;
+		}
+		else if ( (!strcmp(argv[j], "--channel") || !strcmp(argv[j], "-channel"))  && (++j < argc)) 
+		{
+			gChannelName = argv[j];
+		}
+#if LL_DARWIN
+		else if (!strncmp(argv[j], "-psn_", 5))
+		{
+			// this is the Finder passing the process session number
+			// we ignore this
+		}
+#endif
+		else if(!strncmp(argv[j], "-qa", 3))
+		{
+			gQAMode = TRUE;
+		}
+		else
+		{
+
+			// DBC - Mac OS X passes some stuff by default on the command line (e.g. psn).
+			// Second Life URLs are passed this way as well?
+			llwarns << "Possible unknown keyword " << argv[j] << llendl;
+
+			// print usage information
+			llinfos << USAGE << llendl;
+			// return 1;
+		}
+	}
+	return 0;
+}
+
+bool send_url_to_other_instance(const std::string& url)
+{
+#if LL_WINDOWS
+	wchar_t window_class[256]; /* Flawfinder: ignore */   // Assume max length < 255 chars.
+	mbstowcs(window_class, sWindowClass, 255);
+	window_class[255] = 0;
+	// Use the class instead of the window name.
+	HWND other_window = FindWindow(window_class, NULL);
+	if (other_window != NULL)
+	{
+		lldebugs << "Found other window with the name '" << gWindowTitle << "'" << llendl;
+		COPYDATASTRUCT cds;
+		const S32 SLURL_MESSAGE_TYPE = 0;
+		cds.dwData = SLURL_MESSAGE_TYPE;
+		cds.cbData = url.length() + 1;
+		cds.lpData = (void*)url.c_str();
+
+		LRESULT msg_result = SendMessage(other_window, WM_COPYDATA, NULL, (LPARAM)&cds);
+		lldebugs << "SendMessage(WM_COPYDATA) to other window '" 
+				 << gWindowTitle << "' returned " << msg_result << llendl;
+		return true;
+	}
+#endif
+	return false;
+}
+
+//----------------------------------------------------------------------------
+// LLAppViewer definition
+
+// Static members.
+// The single viewer app.
+LLAppViewer* LLAppViewer::sInstance = NULL;
+
+LLTextureCache* LLAppViewer::sTextureCache = NULL; 
+LLWorkerThread* LLAppViewer::sImageDecodeThread = NULL; 
+LLTextureFetch* LLAppViewer::sTextureFetch = NULL; 
+
+LLAppViewer::LLAppViewer() : 
+	mMarkerFile(NULL),
+	mLastExecFroze(false),
+	mDebugFile(NULL),
+	mCrashBehavior(CRASH_BEHAVIOR_ASK),
+	mReportedCrash(false),
+	mNumSessions(0),
+	mPurgeCache(false),
+    mPurgeOnExit(false),
+    mSecondInstance(false),
+	mSavedFinalSnapshot(false),
+    mQuitRequested(false),
+    mLogoutRequestSent(false)
+{
+	if(NULL != sInstance)
+	{
+		llerrs << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << llendl;
+	}
+
+	sInstance = this;
+}
+
+LLAppViewer::~LLAppViewer()
+{
+	// If we got to this destructor somehow, the app didn't hang.
+	removeMarkerFile();
+}
+
+bool LLAppViewer::tempStoreCommandOptions(int argc, char** argv)
+{
+	gTempArgC = argc;
+	gTempArgV = argv;
+	return true;
+}
+
+bool LLAppViewer::init()
+{
+    // *NOTE:Mani - LLCurl::initClass is not thread safe. 
+    // Called before threads are created.
+    LLCurl::initClass();
+
+    initThreads();
+
+	initEarlyConfiguration();
+
+	//
+	// Start of the application
+	//
+	// IMPORTANT! Do NOT put anything that will write
+	// into the log files during normal startup until AFTER
+	// we run the "program crashed last time" error handler below.
+	//
+
+	// Need to do this initialization before we do anything else, since anything
+	// that touches files should really go through the lldir API
+	gDirUtilp->initAppDirs("SecondLife");
+
+
+	initLogging();
+	
+	//
+	// OK to write stuff to logs now, we've now crash reported if necessary
+	//
+
+	// Set up some defaults...
+	gSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, DEFAULT_SETTINGS_FILE);
+	gOldSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, LEGACY_DEFAULT_SETTINGS_FILE);
+
+    initConfiguration();
+
+	//////////////////////////////////////////////////////////////////////////////
+	//////////////////////////////////////////////////////////////////////////////
+	//////////////////////////////////////////////////////////////////////////////
+	//////////////////////////////////////////////////////////////////////////////
+	// *FIX: The following code isn't grouped into functions yet.
+
+	//
+	// Write system information into the debug log (CPU, OS, etc.)
+	//
+	writeSystemInfo();
+
+	// Build a string representing the current version number.
+	gCurrentVersion = llformat("%d.%d.%d", LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH );
+	
+	//
+	// Load the feature tables
+	//
+	llinfos << "Loading feature tables." << llendl;
+	
+	gFeatureManagerp->loadFeatureTables();
+	gFeatureManagerp->initCPUFeatureMasks();
+
+	// Merge with the command line overrides
+	gSavedSettings.applyOverrides(gCommandLineSettings);
+
+	// Need to do this before calling parseAlerts
+	gUICtrlFactory = new LLViewerUICtrlFactory();
+	
+	// Pre-load alerts.xml to define the warnings settings (always loads from skins/xui/en-us/)
+	// Do this *before* loading the settings file
+	LLAlertDialog::parseAlerts("alerts.xml", &gSavedSettings, TRUE);
+	
+	// Overwrite default settings with user settings
+	llinfos << "Loading configuration file " << gSettingsFileName << llendl;
+	if (0 == gSavedSettings.loadFromFile(gSettingsFileName))
+	{
+		llinfos << "Failed to load settings from " << gSettingsFileName << llendl;
+		llinfos << "Loading legacy settings from " << gOldSettingsFileName << llendl;
+		gSavedSettings.loadFromFileLegacy(gOldSettingsFileName);
+	}
+
+	// need to do this here - need to have initialized global settings first
+	LLString nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
+	if ( nextLoginLocation.length() )
+	{
+		LLURLSimString::setString( nextLoginLocation.c_str() );
+	};
+
+	// Merge with the command line overrides
+	gSavedSettings.applyOverrides(gCommandLineForcedSettings);
+
+	gLastRunVersion = gSavedSettings.getString("LastRunVersion");
+
+	fixup_settings();
+	
+	// Get the single value from the crash settings file, if it exists
+	std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
+	gCrashSettings.loadFromFile(crash_settings_filename.c_str());
+
+	/////////////////////////////////////////////////
+	// OS-specific login dialogs
+	/////////////////////////////////////////////////
+#if LL_WINDOWS
+	/*
+	// Display initial login screen, comes up quickly. JC
+	{
+		LLSplashScreen::hide();
+
+		INT_PTR result = DialogBox(hInstance, L"CONNECTBOX", NULL, login_dialog_func);
+		if (result < 0)
+		{
+			llwarns << "Connect dialog box failed, returned " << result << llendl;
+			return 1;
+		}
+		// success, result contains which button user clicked
+		llinfos << "Connect dialog box clicked " << result << llendl;
+
+		LLSplashScreen::show();
+	}
+	*/
+#endif
+
+	// track number of times that app has run
+	mNumSessions = gSavedSettings.getS32("NumSessions");
+	mNumSessions++;
+	gSavedSettings.setS32("NumSessions", mNumSessions);
+
+	gSavedSettings.setString("HelpLastVisitedURL",gSavedSettings.getString("HelpHomeURL"));
+
+	if (gSavedSettings.getBOOL("VerboseLogs"))
+	{
+		LLError::setPrintLocation(true);
+	}
+
+#if !LL_RELEASE_FOR_DOWNLOAD
+	if (gGridChoice == GRID_INFO_NONE)
+	{
+		// Development version: load last server choice by default (overridden by cmd line args)
+		
+		S32 server = gSavedSettings.getS32("ServerChoice");
+		if (server != 0)
+			gGridChoice = (EGridInfo)llclamp(server, 0, (S32)GRID_INFO_COUNT - 1);
+		if (server == GRID_INFO_OTHER)
+		{
+			LLString custom_server = gSavedSettings.getString("CustomServer");
+			if (custom_server.empty())
+			{
+				snprintf(gGridName, MAX_STRING, "none");		/* Flawfinder: ignore */
+			}
+			else
+			{
+				snprintf(gGridName, MAX_STRING, "%s", custom_server.c_str());		/* Flawfinder: ignore */
+			}
+		}
+	}
+#endif
+
+	if (gGridChoice == GRID_INFO_NONE)
+	{
+		gGridChoice = GridDefaultChoice;
+	}
+	
+	// Load art UUID information, don't require these strings to be declared in code.
+	LLString viewer_art_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"viewerart.xml");
+	llinfos << "Loading art table from " << viewer_art_filename << llendl;
+	gViewerArt.loadFromFile(viewer_art_filename.c_str(), FALSE);
+	LLString textures_filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "textures", "textures.xml");
+	llinfos << "Loading art table from " << textures_filename << llendl;
+	gViewerArt.loadFromFile(textures_filename.c_str(), FALSE);
+
+	LLString colors_base_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors_base.xml");
+	llinfos << "Loading base colors from " << colors_base_filename << llendl;
+	gColors.loadFromFile(colors_base_filename.c_str(), FALSE, TYPE_COL4U);
+
+	// Load overrides from user colors file
+	LLString user_colors_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors.xml");
+	llinfos << "Loading user colors from " << user_colors_filename << llendl;
+	if (gColors.loadFromFile(user_colors_filename.c_str(), FALSE, TYPE_COL4U) == 0)
+	{
+		llinfos << "Failed to load user colors from " << user_colors_filename << llendl;
+		LLString user_legacy_colors_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors.ini");
+		llinfos << "Loading legacy colors from " << user_legacy_colors_filename << llendl;
+		gColors.loadFromFileLegacy(user_legacy_colors_filename.c_str(), FALSE, TYPE_COL4U);
+	}
+
+	// Widget construction depends on LLUI being initialized
+	LLUI::initClass(&gSavedSettings, 
+					&gColors, 
+					&gViewerArt,
+					&gImageList,
+					ui_audio_callback,
+					&LLUI::sGLScaleFactor);
+
+	gUICtrlFactory->setupPaths(); // update paths with correct language set
+	
+	/////////////////////////////////////////////////
+	//
+	// Load settings files
+	//
+	//
+	LLGroupMgr::parseRoleActions("role_actions.xml");
+
+	LLAgent::parseTeleportMessages("teleport_strings.xml");
+
+	mCrashBehavior = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING);
+
+	LLVectorPerformanceOptions::initClass();
+
+	// Move certain saved settings into global variables for speed
+	saved_settings_to_globals();
+
+
+	// Find partition serial number (Windows) or hardware serial (Mac)
+	mSerialNumber = generateSerialNumber();
+
+	if(false == initHardwareTest())
+	{
+		// Early out from user choice.
+		return false;
+	}
+
+	// Always fetch the Ethernet MAC address, needed both for login
+	// and password load.
+	LLUUID::getNodeID(gMACAddress);
+
+	// Prepare for out-of-memory situations, during which we will crash on
+	// purpose and save a dump.
+#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
+	MemSetErrorHandler(first_mem_error_handler);
+#endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
+
+	gViewerStats = new LLViewerStats();
+
+	//
+	// Initialize the VFS, and gracefully handle initialization errors
+	//
+
+	if (!initCache())
+	{
+		std::ostringstream msg;
+		msg <<
+			gSecondLife << " is unable to access a file that it needs.\n"
+			"\n"
+			"This can be because you somehow have multiple copies running, "
+			"or your system incorrectly thinks a file is open. "
+			"If this message persists, restart your computer and try again. "
+			"If it continues to persist, you may need to completely uninstall " <<
+			gSecondLife << " and reinstall it.";
+		OSMessageBox(
+			msg.str().c_str(),
+			NULL,
+			OSMB_OK);
+		return 1;
+	}
+	
+#if LL_DARWIN
+	// Display the release notes for the current version
+	if(!gHideLinks && gCurrentVersion != gLastRunVersion)
+	{
+		// Current version and last run version don't match exactly.  Display the release notes.
+		DisplayReleaseNotes();
+	}
+#endif
+
+	//
+	// Initialize the window
+	//
+	initWindow();
+
+	#if LL_WINDOWS && LL_LCD_COMPILE
+		// start up an LCD window on a logitech keyboard, if there is one
+		HINSTANCE hInstance = GetModuleHandle(NULL);
+		gLcdScreen = new llLCD(hInstance);
+		CreateLCDDebugWindows();
+	#endif
+
+	writeDebug(gGLManager.getGLInfoString());
+	llinfos << gGLManager.getGLInfoString() << llendl;
+
+	//load key settings
+	bind_keyboard_functions();
+
+	// Load Default bindings
+	if (!gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"keys.ini").c_str()))
+	{
+		llerrs << "Unable to open keys.ini" << llendl;
+	}
+	// Load Custom bindings (override defaults)
+	gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"custom_keys.ini").c_str());
+
+	// Calculate the digest for the executable (takes < 90ms on a fast machine).
+	FILE* app_file = LLFile::fopen( gDirUtilp->getExecutablePathAndName().c_str(), "rb" );		/* Flawfinder: ignore */
+	if( app_file )
+	{
+		LLMD5 app_md5;
+		app_md5.update( app_file ); // Automatically closes the file
+		app_md5.finalize();
+		app_md5.raw_digest( gViewerDigest.mData );
+	}
+	llinfos << "Viewer Digest: " << gViewerDigest << llendl;
+
+	// If we don't have the right GL requirements, exit.
+	// BUG: This should just be changed to a generic GL "Not good enough" flag
+	if (!gGLManager.mHasMultitexture && !gNoRender)
+	{
+		std::ostringstream msg;
+		msg <<
+			"You do not appear to have the proper hardware requirements "
+			"for " << gSecondLife << ". " << gSecondLife << " requires an OpenGL graphics "
+			"card that has multitexture support. If this is the case, "
+			"you may want to make sure that you have the latest drivers for "
+			"your graphics card, and service packs and patches for your "
+			"operating system.\n"
+			"If you continue to have problems, please go to: "
+			"www.secondlife.com/support ";
+		OSMessageBox(
+			msg.str().c_str(),
+			NULL,
+			OSMB_OK);
+		return 0;
+	}
+
+	// Save the current version to the prefs file
+	gSavedSettings.setString("LastRunVersion", gCurrentVersion);
+
+	gSimLastTime = gRenderStartTime.getElapsedTimeF32();
+	gSimFrames = (F32)gFrameCount;
+
+	return true;
+}
+
+bool LLAppViewer::mainLoop()
+{
+	//-------------------------------------------
+	// Run main loop until time to quit
+	//-------------------------------------------
+
+	// Create IO Pump to use for HTTP Requests.
+	gServicePump = new LLPumpIO(gAPRPoolp);
+	LLHTTPClient::setPump(*gServicePump);
+	LLHTTPClient::setCABundle(gDirUtilp->getCAFile());
+	
+	// initialize voice stuff here
+	gLocalSpeakerMgr = new LLLocalSpeakerMgr();
+	gActiveChannelSpeakerMgr = new LLActiveSpeakerMgr();
+
+	LLVoiceChannel::initClass();
+	LLVoiceClient::init(gServicePump);
+				
+	LLMemType mt1(LLMemType::MTYPE_MAIN);
+	LLTimer frameTimer,idleTimer;
+	LLTimer debugTime;
+	
+	// Handle messages
+	while (!LLApp::isExiting())
+	{
+		LLFastTimer::reset(); // Should be outside of any timer instances
+		{
+			LLFastTimer t(LLFastTimer::FTM_FRAME);
+
+			{
+				LLFastTimer t2(LLFastTimer::FTM_MESSAGES);
+			#if LL_WINDOWS
+				if (!LLWinDebug::setupExceptionHandler())
+				{
+					llwarns << " Someone took over my exception handler (post messagehandling)!" << llendl;
+				}
+			#endif
+
+				gViewerWindow->mWindow->gatherInput();
+			}
+
+#if 1 && !RELEASE_FOR_DOWNLOAD
+			// once per second debug info
+			if (debugTime.getElapsedTimeF32() > 1.f)
+			{
+				debugTime.reset();
+			}
+#endif
+			if (!LLApp::isExiting())
+			{
+				// Scan keyboard for movement keys.  Command keys and typing
+				// are handled by windows callbacks.  Don't do this until we're
+				// done initializing.  JC
+				if (gViewerWindow->mWindow->getVisible() 
+					&& gViewerWindow->getActive()
+					&& !gViewerWindow->mWindow->getMinimized()
+					&& LLStartUp::getStartupState() == STATE_STARTED
+					&& !gViewerWindow->getShowProgress()
+					&& !gFocusMgr.focusLocked())
+				{
+					gKeyboard->scanKeyboard();
+					LLViewerJoystick::scanJoystick();
+				}
+
+				// Update state based on messages, user input, object idle.
+				{
+					LLFastTimer t3(LLFastTimer::FTM_IDLE);
+					idle();
+					LLCurl::process();
+					// this pump is necessary to make the login screen show up
+					gServicePump->pump();
+					gServicePump->callback();
+				}
+
+				if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))
+				{
+					saveFinalSnapshot();
+					disconnectViewer();
+				}
+
+				// Render scene.
+				if (!LLApp::isExiting())
+				{
+					display();
+
+					LLFloaterSnapshot::update(); // take snapshots
+					
+#if !LL_SOLARIS
+					if (gbCapturing)
+					{
+						gMovieMaker.Snap();
+					}
+#endif
+#if LL_WINDOWS && LL_LCD_COMPILE
+					// update LCD Screen
+					gLcdScreen->UpdateDisplay();
+#endif
+				}
+
+			}
+
+			// Sleep and run background threads
+			{
+				LLFastTimer t2(LLFastTimer::FTM_SLEEP);
+				bool run_multiple_threads = gSavedSettings.getBOOL("RunMultipleThreads");
+
+				// yield some time to the os based on command line option
+				if(gYieldTime)
+				{
+					ms_sleep(gYieldMS);
+				}
+
+				// yield cooperatively when not running as foreground window
+				if (   gNoRender
+						|| !gViewerWindow->mWindow->getVisible()
+						|| !gFocusMgr.getAppHasFocus())
+				{
+					// Sleep if we're not rendering, or the window is minimized.
+					S32 milliseconds_to_sleep = llclamp(gSavedSettings.getS32("BackgroundYieldTime"), 0, 1000);
+					// don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads
+					// of equal priority on Windows
+					if (milliseconds_to_sleep > 0)
+					{
+						ms_sleep(milliseconds_to_sleep);
+						// also pause worker threads during this wait period
+						LLAppViewer::getTextureCache()->pause();
+						LLAppViewer::getImageDecodeThread()->pause();
+					}
+				}
+				
+				if (gRandomizeFramerate)
+				{
+					ms_sleep(rand() % 200);
+				}
+
+				if (gPeriodicSlowFrame
+					&& (gFrameCount % 10 == 0))
+				{
+					llinfos << "Periodic slow frame - sleeping 500 ms" << llendl;
+					ms_sleep(500);
+				}
+
+
+				const F64 min_frame_time = 0.0; //(.0333 - .0010); // max video frame rate = 30 fps
+				const F64 min_idle_time = 0.0; //(.0010); // min idle time = 1 ms
+				const F64 max_idle_time = run_multiple_threads ? min_idle_time : .005; // 5 ms
+				idleTimer.reset();
+				while(1)
+				{
+					S32 work_pending = 0;
+					S32 io_pending = 0;
+ 					work_pending += LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
+ 					work_pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
+ 					work_pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
+					io_pending += LLVFSThread::updateClass(1);
+					io_pending += LLLFSThread::updateClass(1);
+					if (io_pending > 1000)
+					{
+						ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up
+					}
+
+					F64 frame_time = frameTimer.getElapsedTimeF64();
+					F64 idle_time = idleTimer.getElapsedTimeF64();
+					if (frame_time >= min_frame_time &&
+						idle_time >= min_idle_time &&
+						(!work_pending || idle_time >= max_idle_time))
+					{
+						break;
+					}
+				}
+				frameTimer.reset();
+
+				 // Prevent the worker threads from running while rendering.
+				// if (LLThread::processorCount()==1) //pause() should only be required when on a single processor client...
+				if (run_multiple_threads == FALSE)
+				{
+					LLAppViewer::getTextureCache()->pause();
+					LLAppViewer::getImageDecodeThread()->pause();
+					// LLAppViewer::getTextureFetch()->pause(); // Don't pause the fetch (IO) thread
+				}
+				//LLVFSThread::sLocal->pause(); // Prevent the VFS thread from running while rendering.
+				//LLLFSThread::sLocal->pause(); // Prevent the LFS thread from running while rendering.
+			}
+						
+		}
+	}
+
+	// Save snapshot for next time, if we made it through initialization
+	if (STATE_STARTED == LLStartUp::getStartupState())
+	{
+		saveFinalSnapshot();
+	}
+	
+	delete gServicePump;
+
+	llinfos << "Exiting main_loop" << llendflush;
+
+	return true;
+}
+
+bool LLAppViewer::cleanup()
+{
+	//flag all elements as needing to be destroyed immediately
+	// to ensure shutdown order
+	LLMortician::setZealous(TRUE);
+
+	LLVoiceClient::terminate();
+	
+	disconnectViewer();
+
+	llinfos << "Viewer disconnected" << llendflush;
+
+	display_cleanup(); 
+
+	release_start_screen(); // just in case
+
+	LLError::logToFixedBuffer(NULL);
+
+	llinfos << "Cleaning Up" << llendflush;
+
+	LLKeyframeDataCache::clear();
+	
+	// Must clean up texture references before viewer window is destroyed.
+	LLHUDObject::cleanupHUDObjects();
+	llinfos << "HUD Objects cleaned up" << llendflush;
+
+ 	// End TransferManager before deleting systems it depends on (Audio, VFS, AssetStorage)
+#if 0 // this seems to get us stuck in an infinite loop...
+	gTransferManager.cleanup();
+#endif
+	
+	// Clean up map data storage
+	delete gWorldMap;
+	gWorldMap = NULL;
+
+	delete gHUDManager;
+	gHUDManager = NULL;
+
+	delete gToolMgr;
+	gToolMgr = NULL;
+
+	delete gAssetStorage;
+	gAssetStorage = NULL;
+
+	LLPolyMesh::freeAllMeshes();
+
+	delete gCacheName;
+	gCacheName = NULL;
+
+	delete gGlobalEconomy;
+	gGlobalEconomy = NULL;
+
+	delete gLocalSpeakerMgr;
+	gLocalSpeakerMgr = NULL;
+
+	LLNotifyBox::cleanup();
+
+	llinfos << "Global stuff deleted" << llendflush;
+
+#if !LL_RELEASE_FOR_DOWNLOAD
+	if (gAudiop)
+	{
+		gAudiop->shutdown();
+	}
+#else
+	// This hack exists because fmod likes to occasionally hang forever
+	// when shutting down for no apparent reason.
+	llwarns << "Hack, skipping audio engine cleanup" << llendflush;
+#endif
+
+
+	// moved to main application shutdown for now because it's non-trivial and only needs to be done once
+	// (even though it goes against the media framework design)
+
+	LLMediaEngine::cleanupClass();
+	
+#if LL_QUICKTIME_ENABLED
+	if (gQuickTimeInitialized)
+	{
+		// clean up media stuff
+		llinfos << "Cleaning up QuickTime" << llendl;
+		ExitMovies ();
+		#if LL_WINDOWS
+			// Only necessary/available on Windows.
+			TerminateQTML ();
+		#endif
+	}
+	llinfos << "Quicktime cleaned up" << llendflush;
+#endif
+
+#if LL_GSTREAMER_ENABLED
+	llinfos << "Cleaning up GStreamer" << llendl;
+	UnloadGStreamer();
+	llinfos << "GStreamer cleaned up" << llendflush;	
+#endif
+
+	llinfos << "Cleaning up feature manager" << llendflush;
+	delete gFeatureManagerp;
+	gFeatureManagerp = NULL;
+
+	// Patch up settings for next time
+	// Must do this before we delete the viewer window,
+	// such that we can suck rectangle information out of
+	// it.
+	cleanupSavedSettings();
+	llinfos << "Settings patched up" << llendflush;
+
+	delete gAudiop;
+	gAudiop = NULL;
+
+	// delete some of the files left around in the cache.
+	removeCacheFiles("*.wav");
+	removeCacheFiles("*.tmp");
+	removeCacheFiles("*.lso");
+	removeCacheFiles("*.out");
+	removeCacheFiles("*.dsf");
+	removeCacheFiles("*.bodypart");
+	removeCacheFiles("*.clothing");
+
+	llinfos << "Cache files removed" << llendflush;
+
+
+	cleanup_menus();
+
+	// Wait for any pending VFS IO
+	while (1)
+	{
+		S32 pending = LLVFSThread::updateClass(0);
+		pending += LLLFSThread::updateClass(0);
+		if (!pending)
+		{
+			break;
+		}
+		llinfos << "Waiting for pending IO to finish: " << pending << llendflush;
+		ms_sleep(100);
+	}
+	llinfos << "Shutting down." << llendflush;
+	
+	// Destroy Windows(R) window, and make sure we're not fullscreen
+	// This may generate window reshape and activation events.
+	// Therefore must do this before destroying the message system.
+	delete gViewerWindow;
+	gViewerWindow = NULL;
+	llinfos << "ViewerWindow deleted" << llendflush;
+
+	// viewer UI relies on keyboard so keep it aound until viewer UI isa gone
+	delete gKeyboard;
+	gKeyboard = NULL;
+
+	// Clean up selection managers after UI is destroyed, as UI
+	// may be observing them.
+	LLSelectMgr::cleanupGlobals();
+
+	LLViewerObject::cleanupVOClasses();
+		
+	LLTracker::cleanupInstance();
+	
+#if LL_LIBXUL_ENABLED
+	// this must be done after floater cleanup (delete gViewerWindow) since 
+	// floaters  potentially need the manager to destroy their contents.
+	LLMozLib::getInstance()->reset();
+#endif
+
+	// *FIX: This is handled in LLAppViewerWin32::cleanup().
+	// I'm keeping the comment to remember its order in cleanup,
+	// in case of unforseen dependency.
+//#if LL_WINDOWS
+//	gDXHardware.cleanup();
+//#endif // LL_WINDOWS
+
+#if LL_WINDOWS && LL_LCD_COMPILE
+	// shut down the LCD window on a logitech keyboard, if there is one
+	delete gLcdScreen;
+	gLcdScreen = NULL;
+#endif
+
+	if (!gVolumeMgr->cleanup())
+	{
+		llwarns << "Remaining references in the volume manager!" << llendflush;
+	}
+
+	LLViewerParcelMgr::cleanupGlobals();
+
+	delete gViewerStats;
+	gViewerStats = NULL;
+
+ 	//end_messaging_system();
+
+	LLFollowCamMgr::cleanupClass();
+	LLVolumeMgr::cleanupClass();
+	LLWorldMapView::cleanupClass();
+	LLUI::cleanupClass();
+	
+	//
+	// Shut down the VFS's AFTER the decode manager cleans up (since it cleans up vfiles).
+	// Also after viewerwindow is deleted, since it may have image pointers (which have vfiles)
+	// Also after shutting down the messaging system since it has VFS dependencies
+	//
+	LLVFile::cleanupClass();
+	llinfos << "VFS cleaned up" << llendflush;
+
+	// Store the time of our current logoff
+	gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
+
+	// Must do this after all panels have been deleted because panels that have persistent rects
+	// save their rects on delete.
+	gSavedSettings.saveToFile(gSettingsFileName, TRUE);
+	if (!gPerAccountSettingsFileName.empty())
+	{
+		gSavedPerAccountSettings.saveToFile(gPerAccountSettingsFileName, TRUE);
+	}
+	llinfos << "Saved settings" << llendflush;
+
+	std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
+	// save all settings, even if equals defaults
+	gCrashSettings.saveToFile(crash_settings_filename.c_str(), FALSE);
+
+	delete gUICtrlFactory;
+	gUICtrlFactory = NULL;
+
+	gSavedSettings.cleanup();
+	gViewerArt.cleanup();
+	gColors.cleanup();
+	gCrashSettings.cleanup();
+
+	if (gMuteListp)
+	{
+		// save mute list
+		gMuteListp->cache(gAgent.getID());
+
+		delete gMuteListp;
+		gMuteListp = NULL;
+	}
+
+	if (mPurgeOnExit)
+	{
+		llinfos << "Purging all cache files on exit" << llendflush;
+		char mask[LL_MAX_PATH];		/* Flawfinder: ignore */
+		snprintf(mask, LL_MAX_PATH, "%s*.*", gDirUtilp->getDirDelimiter().c_str());		/* Flawfinder: ignore */
+		gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"").c_str(),mask);
+	}
+
+	removeMarkerFile(); // Any crashes from here on we'll just have to ignore
+	
+	closeDebug();
+
+	// Let threads finish
+	LLTimer idleTimer;
+	idleTimer.reset();
+	const F64 max_idle_time = 5.f; // 5 seconds
+	while(1)
+	{
+		S32 pending = 0;
+		pending += LLAppViewer::getTextureCache()->update(1); // unpauses the worker thread
+		pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
+		pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
+		pending += LLVFSThread::updateClass(0);
+		pending += LLLFSThread::updateClass(0);
+		F64 idle_time = idleTimer.getElapsedTimeF64();
+		if (!pending || idle_time >= max_idle_time)
+		{
+			llwarns << "Quitting with pending background tasks." << llendl;
+			break;
+		}
+	}
+	
+	// Delete workers first
+	// shotdown all worker threads before deleting them in case of co-dependencies
+	sTextureCache->shutdown();
+	sTextureFetch->shutdown();
+	sImageDecodeThread->shutdown();
+	delete sTextureCache;
+    sTextureCache = NULL;
+	delete sTextureFetch;
+    sTextureFetch = NULL;
+	delete sImageDecodeThread;
+    sImageDecodeThread = NULL;
+
+	gImageList.shutdown(); // shutdown again in case a callback added something
+	
+	// This should eventually be done in LLAppViewer
+	LLImageJ2C::closeDSO();
+	LLImageFormatted::cleanupClass();
+	LLVFSThread::cleanupClass();
+	LLLFSThread::cleanupClass();
+
+	llinfos << "VFS Thread finished" << llendflush;
+
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+	llinfos << "Auditing VFS" << llendl;
+	gVFS->audit();
+#endif
+
+	// For safety, the LLVFS has to be deleted *after* LLVFSThread. This should be cleaned up.
+	// (LLVFS doesn't know about LLVFSThread so can't kill pending requests) -Steve
+	delete gStaticVFS;
+	gStaticVFS = NULL;
+	delete gVFS;
+	gVFS = NULL;
+	
+	end_messaging_system();
+
+    // *NOTE:Mani - The following call is not thread safe. 
+    LLCurl::cleanup();
+
+    // If we're exiting to launch an URL, do that here so the screen
+	// is at the right resolution before we launch IE.
+	if (!gLaunchFileOnQuit.empty())
+	{
+#if LL_WINDOWS
+		// Indicate an application is starting.
+		SetCursor(LoadCursor(NULL, IDC_WAIT));
+#endif
+
+		// HACK: Attempt to wait until the screen res. switch is complete.
+		ms_sleep(1000);
+
+		LLWeb::loadURLExternal( gLaunchFileOnQuit );
+	}
+
+
+    llinfos << "Goodbye" << llendflush;
+	// return 0;
+	return true;
+}
+
+bool LLAppViewer::initEarlyConfiguration()
+{
+	// *FIX: globals - This method sets a bunch of globals early in the init process.
+	int argc = gTempArgC;
+	char** argv = gTempArgV;
+
+	// HACK! We REALLY want to know what grid they were trying to connect to if they
+	// crashed hard.
+	// So we walk through the command line args ONLY looking for the
+	// userserver arguments first.  And we don't do ANYTHING but set
+	// the gGridName (which gets passed to the crash reporter).
+	// We're assuming that they're trying to log into the same grid as last
+	// time, which seems fairly reasonable.
+	snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GridDefaultChoice].mName);		// Flawfinder: ignore
+	S32 j;
+	for (j = 1; j < argc; j++) 
+	{
+		if (!strcmp(argv[j], "--aditi"))
+		{
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_ADITI].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--agni"))
+		{
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_AGNI].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--dmz"))
+		{
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_DMZ].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--siva"))
+		{
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_SIVA].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--shakti"))
+		{
+			sprintf(gGridName,"%s", gGridInfo[GRID_INFO_SHAKTI].mName);
+		}
+		else if (!strcmp(argv[j], "--durga"))
+		{
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_DURGA].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--soma"))
+		{
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_SOMA].mName);		// Flawfinder: ignore
+		}
+		else if (!strcmp(argv[j], "--ganga"))
+		{
+			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_GANGA].mName);		// Flawfinder: ignore 
+		}
+		else if (!strcmp(argv[j], "--vaak"))
+		{
+			sprintf(gGridName,"%s", gGridInfo[GRID_INFO_VAAK].mName);
+		}
+		else if (!strcmp(argv[j], "--uma"))
+		{
+			sprintf(gGridName,"%s", gGridInfo[GRID_INFO_UMA].mName);
+		}
+		else if (!strcmp(argv[j], "-user") && (++j < argc))
+		{
+			if (!strcmp(argv[j], "-"))
+			{
+				snprintf(gGridName, MAX_STRING, "%s", LOOPBACK_ADDRESS_STRING);		// Flawfinder: ignore 
+			}
+			else
+			{
+				snprintf(gGridName, MAX_STRING, "%s", argv[j]);		// Flawfinder: ignore 
+			}
+		}
+		else if (!strcmp(argv[j], "-multiple"))
+		{
+			// Hack to detect -multiple so we can disable the marker file check (which will always fail)
+			gMultipleViewersOK = TRUE;
+		}
+		else if (!strcmp(argv[j], "-novoice"))
+		{
+			// May need to know this early also
+			gDisableVoice = TRUE;
+		}
+		else if (!strcmp(argv[j], "-url") && (++j < argc)) 
+		{
+			LLURLSimString::setString(argv[j]);
+		}
+	}
+
+	return true;
+}
+
+bool LLAppViewer::initThreads()
+{
+#if MEM_TRACK_MEM
+	static const bool enable_threads = false;
+#else
+	static const bool enable_threads = true;
+#endif
+	LLVFSThread::initClass(enable_threads && true);
+	LLLFSThread::initClass(enable_threads && true);
+
+	// Image decoding
+	LLAppViewer::sImageDecodeThread = new LLWorkerThread("ImageDecode", enable_threads && true);
+	LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
+	LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), enable_threads && false);
+	LLImageWorker::initClass(LLAppViewer::getImageDecodeThread());
+	LLImageJ2C::openDSO();
+
+	// *FIX: no error handling here!
+	return true;
+}
+
+void errorCallback(const std::string &error_string)
+{
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+	OSMessageBox(error_string.c_str(), "Fatal Error", OSMB_OK);
+#endif
+	LLError::crashAndLoop(error_string);
+}
+
+bool LLAppViewer::initLogging()
+{
+	//
+	// Set up logging defaults for the viewer
+	//
+	LLError::initForApplication(
+				gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+	LLError::setFatalFunction(errorCallback);
+	
+	// Remove the last ".old" log file.
+	std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+							     "SecondLife.old");
+	LLFile::remove(old_log_file.c_str());
+
+	// Rename current log file to ".old"
+	std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+							     "SecondLife.log");
+	LLFile::rename(log_file.c_str(), old_log_file.c_str());
+
+	// Set the log file to SecondLife.log
+
+	LLError::logToFile(log_file);
+
+	// *FIX:Mani no error handling here!
+	return true;
+}
+
+bool LLAppViewer::initConfiguration()
+{
+	// Ye olde parse_args()...
+	if(!doConfigFromCommandLine())
+	{
+		return false;
+	}
+	
+	// XUI:translate
+	gSecondLife = "Second Life";
+
+	// Read skin/branding settings if specified.
+	if (! gDirUtilp->getSkinDir().empty() )
+	{
+		std::string skin_def_file = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "skin.xml");
+		LLXmlTree skin_def_tree;
+
+		if (!skin_def_tree.parseFile(skin_def_file))
+		{
+			llerrs << "Failed to parse skin definition." << llendl;
+		}
+
+		LLXmlTreeNode* rootp = skin_def_tree.getRoot();
+		LLXmlTreeNode* disabled_message_node = rootp->getChildByName("disabled_message");	
+		if (disabled_message_node)
+		{
+			gDisabledMessage = disabled_message_node->getContents();
+		}
+
+		static LLStdStringHandle hide_links_string = LLXmlTree::addAttributeString("hide_links");
+		rootp->getFastAttributeBOOL(hide_links_string, gHideLinks);
+
+		// Legacy string.  This flag really meant we didn't want to expose references to "Second Life".
+		// Just set gHideLinks instead.
+		static LLStdStringHandle silent_string = LLXmlTree::addAttributeString("silent_update");
+		BOOL silent_update;
+		rootp->getFastAttributeBOOL(silent_string, silent_update);
+		gHideLinks = (gHideLinks || silent_update);
+	}
+
+#if LL_DARWIN
+	// Initialize apple menubar and various callbacks
+	init_apple_menu(gSecondLife.c_str());
+
+#if __ppc__
+	// If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further.
+	// Only test PowerPC - all Intel Macs have SSE.
+	if(!gSysCPU.hasAltivec())
+	{
+		std::ostringstream msg;
+		msg << gSecondLife << " requires a processor with AltiVec (G4 or later).";
+		OSMessageBox(
+			msg.str().c_str(),
+			NULL,
+			OSMB_OK);
+		removeMarkerFile();
+		return false;
+	}
+#endif
+	
+#endif // LL_DARWIN
+
+	// Display splash screen.  Must be after above check for previous
+	// crash as this dialog is always frontmost.
+	std::ostringstream splash_msg;
+	splash_msg << "Loading " << gSecondLife << "...";
+	LLSplashScreen::show();
+	LLSplashScreen::update(splash_msg.str().c_str());
+
+	LLVolumeMgr::initClass();
+
+	// Initialize the feature manager
+	// The feature manager is responsible for determining what features
+	// are turned on/off in the app.
+	gFeatureManagerp = new LLFeatureManager;
+
+	gStartTime = totalTime();
+
+	////////////////////////////////////////
+	//
+	// Process ini files
+	//
+
+	// declare all possible setting variables
+	declare_settings();
+
+#if !LL_RELEASE_FOR_DOWNLOAD
+//	only write the defaults for non-release builds!
+	gSavedSettings.saveToFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings_default.xml").c_str(), FALSE);
+#endif
+
+	//
+	// Set the name of the window
+	//
+#if LL_RELEASE_FOR_DOWNLOAD
+	gWindowTitle = gSecondLife;
+#elif LL_DEBUG
+	gWindowTitle = gSecondLife + LLString(" [DEBUG] ") + gArgs;
+#else
+	gWindowTitle = gSecondLife + LLString(" ") + gArgs;
+#endif
+	LLString::truncate(gWindowTitle, 255);
+
+	if (!gMultipleViewersOK)
+	{
+	    //
+	    // Check for another instance of the app running
+	    //
+		//RN: if we received a URL, hand it off to the existing instance
+		// don't call anotherInstanceRunning() when doing URL handoff, as
+		// it relies on checking a marker file which will not work when running
+		// out of different directories
+		std::string slurl;
+		if (!LLStartUp::sSLURLCommand.empty())
+		{
+			slurl = LLStartUp::sSLURLCommand;
+		}
+		else if (LLURLSimString::parse())
+		{
+			slurl = LLURLSimString::getURL();
+		}
+		if (!slurl.empty())
+		{
+			if (send_url_to_other_instance(slurl))
+			{
+				// successfully handed off URL to existing instance, exit
+				return 1;
+			}
+		}
+		
+		mSecondInstance = anotherInstanceRunning();
+		
+		if (mSecondInstance)
+		{
+			std::ostringstream msg;
+			msg << 
+				gSecondLife << " is already running.\n"
+				"\n"
+				"Check your task bar for a minimized copy of the program.\n"
+				"If this message persists, restart your computer.",
+			OSMessageBox(
+				msg.str().c_str(),
+				NULL,
+				OSMB_OK);
+			return 1;
+		}
+
+		initMarkerFile();
+
+#if LL_SEND_CRASH_REPORTS
+		if (gLastExecFroze)
+		{
+			llinfos << "Last execution froze, requesting to send crash report." << llendl;
+			//
+			// Pop up a freeze or crash warning dialog
+			//
+			std::ostringstream msg;
+			msg << gSecondLife
+				<< " appears to have frozen or crashed on the previous run.\n"
+				<< "Would you like to send a crash report?";
+			std::string alert;
+			alert = gSecondLife;
+			alert += " Alert";
+			S32 choice = OSMessageBox(msg.str().c_str(),
+				alert.c_str(),
+				OSMB_YESNO);
+			if (OSBTN_YES == choice)
+			{
+				llinfos << "Sending crash report." << llendl;
+
+ 				removeMarkerFile();
+#if LL_WINDOWS
+				std::string exe_path = gDirUtilp->getAppRODataDir();
+				exe_path += gDirUtilp->getDirDelimiter();
+				exe_path += "win_crash_logger.exe";
+
+				std::string arg_string = "-previous -user ";
+				arg_string += gGridName;
+				arg_string += " -name \"";
+				arg_string += gSecondLife;
+				arg_string += "\"";
+				// Spawn crash logger.
+				// NEEDS to wait until completion, otherwise log files will get smashed.
+				_spawnl(_P_WAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL);
+#elif LL_DARWIN
+				std::string command_str;
+				command_str = "crashreporter.app/Contents/MacOS/crashreporter ";
+				command_str += "-previous -user ";
+				command_str += gGridName;
+				// XXX -- We need to exit fullscreen mode for this to work.
+				// XXX -- system() also doesn't wait for completion.  Hmm...
+				system(command_str.c_str());		/* Flawfinder: Ignore */
+#elif LL_LINUX || LL_SOLARIS
+				std::string cmd =gDirUtilp->getAppRODataDir();
+				cmd += gDirUtilp->getDirDelimiter();
+#if LL_LINUX
+				cmd += "linux-crash-logger.bin";
+#else // LL_SOLARIS
+				cmd += "bin/solaris-crash-logger";
+#endif
+				char* const cmdargv[] =
+					{(char*)cmd.c_str(),
+					 (char*)"-previous",
+					 (char*)"-user",
+					 (char*)gGridName,
+					 (char*)"-name",
+					 (char*)gSecondLife.c_str(),
+					 NULL};
+				pid_t pid = fork();
+				if (pid == 0)
+				{ // child
+					execv(cmd.c_str(), cmdargv);		/* Flawfinder: Ignore */
+					llwarns << "execv failure when trying to start " << cmd << llendl;
+					_exit(1); // avoid atexit()
+				} else {
+					if (pid > 0)
+					{
+						// wait for child proc to die
+						int childExitStatus;
+						waitpid(pid, &childExitStatus, 0);
+					} else {
+						llwarns << "fork failure." << llendl;
+					}
+				}
+#endif
+			}
+			else
+			{
+				llinfos << "Not sending crash report." << llendl;
+			}
+		}
+#endif // #if LL_SEND_CRASH_REPORTS
+	}
+	else
+	{
+		mSecondInstance = anotherInstanceRunning();
+		
+		if (mSecondInstance)
+		{
+			gDisableVoice = TRUE;
+			/* Don't start another instance if using -multiple
+			//RN: if we received a URL, hand it off to the existing instance
+		    if (LLURLSimString::parse())
+		    {
+			    LLURLSimString::send_to_other_instance();
+				return 1;
+			}
+			*/
+		}
+
+		initMarkerFile();
+	}
+
+	return true; // Config was successful.
+}
+
+bool LLAppViewer::doConfigFromCommandLine()
+{
+	// *FIX: This is what parse args used to do, minus the arg reading part.
+	// Now the arg parsing is handled by LLApp::parseCommandOptions() and this
+	// method need only interpret settings. Perhaps some day interested parties 
+	// can ask an app about a setting rather than have the app set 
+	// a gazzillion globals.
+	
+	/////////////////////////////////////////
+	//
+	// Process command line arguments
+	//
+	S32 args_result = 0;
+
+#if LL_DARWIN
+	{
+		// On the Mac, read in arguments.txt (if it exists) and process it for additional arguments.
+		LLString args;
+		if(_read_file_into_string(args, "arguments.txt"))		/* Flawfinder: ignore*/
+		{
+			// The arguments file exists.  
+			// It should consist of command line arguments separated by newlines.
+			// Split it into individual arguments and build a fake argv[] to pass to parse_args.
+			std::vector<std::string> arglist;
+			
+			arglist.push_back("newview");
+			
+			llinfos << "Reading additional command line arguments from arguments.txt..." << llendl;
+			
+			typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizer;
+			boost::escaped_list_separator<char> sep("\\", "\r\n ", "\"'");
+			tokenizer tokens(args, sep);
+			tokenizer::iterator token_iter;
+
+			for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
+			{
+				llinfos << "argument: '" << (token_iter->c_str()) << "'" << llendl;
+				
+				arglist.push_back(*token_iter);
+			}
+
+			char **fakeargv = new char*[arglist.size()];
+			int i;
+			for(i=0; i < arglist.size(); i++)
+				fakeargv[i] = const_cast<char*>(arglist[i].c_str());
+				
+			args_result = parse_args(arglist.size(), fakeargv);
+			delete[] fakeargv;
+		}
+		
+		// Get the user's preferred language string based on the Mac OS localization mechanism.
+		// To add a new localization:
+			// go to the "Resources" section of the project
+			// get info on "language.txt"
+			// in the "General" tab, click the "Add Localization" button
+			// create a new localization for the language you're adding
+			// set the contents of the new localization of the file to the string corresponding to our localization
+			//   (i.e. "en-us", "ja", etc.  Use the existing ones as a guide.)
+		CFURLRef url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("language"), CFSTR("txt"), NULL);
+		char path[MAX_PATH];
+		if(CFURLGetFileSystemRepresentation(url, false, (UInt8 *)path, sizeof(path)))
+		{
+			LLString lang;
+			if(_read_file_into_string(lang, path))		/* Flawfinder: ignore*/
+			{
+				gCommandLineForcedSettings["SystemLanguage"] = lang;
+			}
+		}
+		CFRelease(url);
+	}
+#endif
+
+	int argc = gTempArgC;
+	char** argv = gTempArgV;
+
+	//
+	// Parse the command line arguments
+	//
+	args_result |= parse_args(argc, argv);
+	if (args_result)
+	{
+		removeMarkerFile();
+		return false;
+	}
+	
+	if (!strcmp(gGridName, gGridInfo[GRID_INFO_AGNI].mName))
+	{
+		gInProductionGrid = TRUE;
+	}
+
+	return true;
+}
+
+bool LLAppViewer::initWindow()
+{
+	llinfos << "Initializing window..." << llendl;
+
+	// store setting in a global for easy access and modification
+	gNoRender = gSavedSettings.getBOOL("DisableRendering");
+
+	// Hide the splash screen
+	LLSplashScreen::hide();
+
+	// HACK: Need a non-const char * for stupid window name (propagated deep down)
+	char window_title_str[256];		/* Flawfinder: ignore */
+	strncpy(window_title_str, gWindowTitle.c_str(), sizeof(window_title_str) - 1);		/* Flawfinder: ignore */
+	window_title_str[sizeof(window_title_str) - 1] = '\0';
+
+	// always start windowed
+	gViewerWindow = new LLViewerWindow(window_title_str, "Second Life",
+		gSavedSettings.getS32("WindowX"), gSavedSettings.getS32("WindowY"),
+		gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"),
+		FALSE, gIgnorePixelDepth);
+		
+	if (gSavedSettings.getBOOL("FullScreen"))
+	{
+		gViewerWindow->toggleFullscreen(FALSE);
+			// request to go full screen... which will be delayed until login
+	}
+	
+	if (gSavedSettings.getBOOL("WindowMaximized"))
+	{
+		gViewerWindow->mWindow->maximize();
+		gViewerWindow->getWindow()->setNativeAspectRatio(gSavedSettings.getF32("FullScreenAspectRatio"));
+	}
+
+	LLUI::sWindow = gViewerWindow->getWindow();
+
+	LLAlertDialog::parseAlerts("alerts.xml");
+	LLNotifyBox::parseNotify("notify.xml");
+
+	LLMediaEngine::initClass();
+	
+	//
+	// Clean up the feature manager lookup table - settings were updated
+	// in the LLViewerWindow constructor
+	//
+	gFeatureManagerp->cleanupFeatureTables();
+
+	// Show watch cursor
+	gViewerWindow->setCursor(UI_CURSOR_WAIT);
+
+	// Finish view initialization
+	gViewerWindow->initBase();
+
+	// show viewer window
+	gViewerWindow->mWindow->show();
+	
+	return true;
+}
+
+void LLAppViewer::writeDebug(const char *str)
+{
+	if (!mDebugFile)
+	{
+		std::string debug_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log");
+		llinfos << "Opening debug file " << debug_filename << llendl;
+		mDebugFile = LLFile::fopen(debug_filename.c_str(), "w");		/* Flawfinder: ignore */
+        if (!mDebugFile)
+        {
+		    llinfos << "Opening debug file " << debug_filename << " failed. Using stderr." << llendl;
+            mDebugFile = stderr;
+        }
+	}
+	fputs(str, mDebugFile);
+	fflush(mDebugFile);
+}
+
+void LLAppViewer::closeDebug()
+{
+	if (mDebugFile)
+	{
+		fclose(mDebugFile);
+	}
+	mDebugFile = NULL;
+}
+
+void LLAppViewer::cleanupSavedSettings()
+{
+	gSavedSettings.setBOOL("MouseSun", FALSE);
+
+	gSavedSettings.setBOOL("FlyBtnState", FALSE);
+
+	gSavedSettings.setBOOL("FirstPersonBtnState", FALSE);
+	gSavedSettings.setBOOL("ThirdPersonBtnState", TRUE);
+	gSavedSettings.setBOOL("BuildBtnState", FALSE);
+
+	gSavedSettings.setBOOL("UseEnergy", TRUE);				// force toggle to turn off, since sends message to simulator
+
+	gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc);
+		
+	gSavedSettings.setBOOL("AllowIdleAFK", gAllowIdleAFK);
+	gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates);
+	
+	if (!gNoRender)
+	{
+		if (gDebugView)
+		{
+			gSavedSettings.setBOOL("ShowDebugConsole", gDebugView->mDebugConsolep->getVisible());
+			gSavedSettings.setBOOL("ShowDebugStats", gDebugView->mStatViewp->getVisible());
+		}
+	}
+
+	// save window position if not fullscreen
+	// as we don't track it in callbacks
+	BOOL fullscreen = gViewerWindow->mWindow->getFullscreen();
+	BOOL maximized = gViewerWindow->mWindow->getMaximized();
+	if (!fullscreen && !maximized)
+	{
+		LLCoordScreen window_pos;
+
+		if (gViewerWindow->mWindow->getPosition(&window_pos))
+		{
+			gSavedSettings.setS32("WindowX", window_pos.mX);
+			gSavedSettings.setS32("WindowY", window_pos.mY);
+		}
+	}
+
+	gSavedSettings.setF32("MapScale", gMapScale );
+	gSavedSettings.setF32("MiniMapScale", gMiniMapScale );
+	gSavedSettings.setBOOL("AsyncKeyboard", gHandleKeysAsync);
+	gSavedSettings.setBOOL("ShowHoverTips", LLHoverView::sShowHoverTips);
+
+	// Some things are cached in LLAgent.
+	if (gAgent.mInitialized)
+	{
+		gSavedSettings.setF32("RenderFarClip", gAgent.mDrawDistance);
+	}
+
+	// *REMOVE: This is now done via LLAppViewer::setCrashBehavior()
+	// Left vestigially in case I borked it.
+	// gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, gCrashBehavior);
+}
+
+void LLAppViewer::removeCacheFiles(const char* file_mask)
+{
+	char mask[LL_MAX_PATH];		/* Flawfinder: ignore */
+	snprintf(mask, LL_MAX_PATH, "%s%s", gDirUtilp->getDirDelimiter().c_str(), file_mask);		/* Flawfinder: ignore */
+	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "").c_str(), mask);
+}
+
+void LLAppViewer::writeSystemInfo()
+{
+	writeDebug("SL Log: ");
+	writeDebug(LLError::logFileName());
+	writeDebug("\n");
+
+	std::string tmp_str = gSecondLife
+		+ llformat(" version %d.%d.%d build %d",
+				   LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VERSION_BUILD);
+	writeDebug(tmp_str.c_str());
+	writeDebug("\n");
+	writeDebug(gSysCPU.getCPUString());
+	writeDebug("\n");
+	
+	tmp_str = llformat("RAM: %u KB\n", gSysMemory.getPhysicalMemoryKB());
+	writeDebug(tmp_str.c_str());
+	writeDebug("OS: ");
+	writeDebug(getOSInfo().getOSString().c_str());
+	writeDebug("\n");
+
+	// Dump some debugging info
+	llinfos << gSecondLife << " version "
+		<< LL_VERSION_MAJOR << "."
+		<< LL_VERSION_MINOR << "."
+		<< LL_VERSION_PATCH
+		<< llendl;
+
+	// Dump the local time and time zone
+	time_t now;
+	time(&now);
+	char tbuffer[256];		/* Flawfinder: ignore */
+	strftime(tbuffer, 256, "%Y-%m-%dT%H:%M:%S %Z", localtime(&now));
+	llinfos << "Local time: " << tbuffer << llendl;
+
+	// query some system information
+	llinfos << "CPU info:\n" << gSysCPU << llendl;
+	llinfos << "Memory info:\n" << gSysMemory << llendl;
+	llinfos << "OS info: " << getOSInfo() << llendl;
+}
+
+void LLAppViewer::handleViewerCrash()
+{
+	LLAppViewer* pApp = LLAppViewer::instance();
+	if (pApp->beingDebugged())
+	{
+		// This will drop us into the debugger.
+		abort();
+	}
+
+	// Returns whether a dialog was shown.
+	// Only do the logic in here once
+	if (pApp->mReportedCrash)
+	{
+		return;
+	}
+	pApp->mReportedCrash = TRUE;
+
+	BOOL do_crash_report = FALSE;
+
+	do_crash_report = TRUE;
+
+	pApp->writeDebug("Viewer exe: ");
+	pApp->writeDebug(gDirUtilp->getExecutablePathAndName().c_str());
+	pApp->writeDebug("\n");
+	pApp->writeDebug("Cur path: ");
+	pApp->writeDebug(gDirUtilp->getCurPath().c_str());
+	pApp->writeDebug("\n\n");
+
+	if (gMessageSystem && gDirUtilp)
+	{
+		std::string filename;
+		filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "stats.log");
+		llofstream file(filename.c_str(), llofstream::binary);
+		if(file.good())
+		{
+			gMessageSystem->summarizeLogs(file);
+		}
+	}
+
+	if (gMessageSystem)
+	{
+		pApp->writeDebug(gMessageSystem->getCircuitInfoString());
+		gMessageSystem->stopLogging();
+	}
+	pApp->writeDebug("\n");
+	if (gWorldp)
+	{
+		pApp->writeDebug(gWorldp->getInfoString());
+	}
+
+	// Close the debug file
+	pApp->closeDebug();
+	LLError::logToFile("");
+
+	// Close the SecondLife.log
+	//pApp->removeMarkerFile();
+
+	// Call to pure virtual, handled by platform specifc llappviewer instance.
+	pApp->handleCrashReporting(); 
+
+	return;
+}
+
+void LLAppViewer::setCrashBehavior(S32 cb) 
+{ 
+	mCrashBehavior = cb; 
+	gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, mCrashBehavior);
+} 
+
+bool LLAppViewer::anotherInstanceRunning()
+{
+		// We create a marker file when the program starts and remove the file when it finishes.
+	// If the file is currently locked, that means another process is already running.
+
+	std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker");
+	llinfos << "Checking marker file for lock..." << llendl;
+
+	// If file doesn't exist, we create it
+	// If file does exist, try to get writing privilages
+	FILE* fMarker = LLFile::fopen(marker_file.c_str(), "rb");		// Flawfinder: ignore
+	if (fMarker != NULL)
+	{
+		// File exists, try opening with write permissions
+		fclose(fMarker);
+		fMarker = LLFile::fopen(marker_file.c_str(), "wb");		// Flawfinder: ignore
+		if (fMarker == NULL)
+		{
+			llinfos << "Marker file is locked." << llendl;
+			return TRUE;
+		}
+
+		// *FIX:Mani - rather than have this exception here, 
+		// LLFile::fopen() have consistent behavior across platforms?
+#if LL_DARWIN
+		// Try to lock it. On Mac, this is the only way to test if it's actually locked.
+		if (flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1)
+		{
+			// Lock failed - somebody else has it.
+			fclose(fMarker);
+			llinfos << "Marker file is locked." << llendl;
+			return TRUE;
+		}
+#endif
+		fclose(fMarker);
+	}
+	llinfos << "Marker file isn't locked." << llendl;
+	return FALSE;
+
+}
+
+void LLAppViewer::initMarkerFile()
+{
+	// *FIX:Mani - an actually cross platform LLFile lib would be nice.
+
+#if LL_SOLARIS
+        struct flock fl;
+        fl.l_whence = SEEK_SET;
+        fl.l_start = 0;
+        fl.l_len = 1;
+#endif
+	// We create a marker file when the program starts and remove the file when it finishes.
+	// If the file is currently locked, that means another process is already running.
+	// If the file exists and isn't locked, we crashed on the last run.
+
+	std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker");
+	llinfos << "Checking marker file for lock..." << llendl;
+
+	FILE* fMarker = LLFile::fopen(marker_file.c_str(), "rb");		// Flawfinder: ignore
+	if (fMarker != NULL)
+	{
+		// File exists, try opening with write permissions
+		fclose(fMarker);
+		fMarker = LLFile::fopen(marker_file.c_str(), "wb");		// Flawfinder: ignxore
+		if (fMarker == NULL)
+		{
+			// Another instance is running. Skip the rest of these operations.
+			llinfos << "Marker file is locked." << llendl;
+			return;
+		}
+#if LL_DARWIN
+		// Try to lock it. On Mac, this is the only way to test if it's actually locked.
+		if (flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1)
+		{
+			// Lock failed - somebody else has it.
+			fclose(fMarker);
+			llinfos << "Marker file is locked." << llendl;
+			return;
+		}
+#endif
+
+		// No other instances; we'll lock this file now & delete on quit.
+		fclose(fMarker);
+		gLastExecFroze = TRUE;
+		llinfos << "Exec marker found: program froze on previous execution" << llendl;
+	}
+
+	// Create the marker file for this execution & lock it
+// 	FILE *fp_executing_marker;
+#if LL_WINDOWS
+	mMarkerFile = LLFile::_fsopen(marker_file.c_str(), "w", _SH_DENYWR);
+#else
+	mMarkerFile = LLFile::fopen(marker_file.c_str(), "w");		// Flawfinder: ignore
+	if (mMarkerFile)
+	{
+		int fd = fileno(mMarkerFile);
+		// Attempt to lock
+#if LL_SOLARIS
+		fl.l_type = F_WRLCK;
+		if (fcntl(fd, F_SETLK, &fl) == -1)
+#else
+		if (flock(fd, LOCK_EX | LOCK_NB) == -1)
+#endif
+		{
+			llinfos << "Failed to lock file." << llendl;
+		}
+	}
+#endif
+	if (mMarkerFile)
+	{
+		llinfos << "Marker file created." << llendl;
+	}
+	else
+	{
+		llinfos << "Failed to create marker file." << llendl;
+	}
+
+#if LL_WINDOWS
+	// Clean up SecondLife.dmp files, to avoid confusion
+	llinfos << "Removing SecondLife.dmp" << llendl;
+	std::string dmp_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.dmp");
+	LLFile::remove(dmp_filename.c_str());
+#endif
+
+	// This is to keep the crash reporter from constantly sending stale message logs
+	// We wipe the message file now.
+	llinfos << "Removing message.log" << llendl;
+	std::string message_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "message.log");
+	LLFile::remove(message_filename.c_str());
+
+	llinfos << "Exiting initMarkerFile()." << llendl;
+}
+
+void LLAppViewer::removeMarkerFile()
+{
+	llinfos << "removeMarkerFile()" << llendl;
+	if (mMarkerFile != NULL)
+	{
+		fclose(mMarkerFile);
+		mMarkerFile = NULL;
+	}
+	if( gDirUtilp )
+	{
+		LLString marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker");
+		ll_apr_file_remove( marker_file );
+	}
+}
+
+void LLAppViewer::forceQuit()
+{ 
+	LLApp::setQuitting(); 
+}
+
+void LLAppViewer::requestQuit()
+{
+	llinfos << "requestQuit" << llendl;
+
+	LLViewerRegion* region = gAgent.getRegion();
+	
+	if( (LLStartUp::getStartupState() < STATE_STARTED) || !region )
+	{
+		// Quit immediately
+		forceQuit();
+		return;
+	}
+
+	if (gHUDManager)
+	{
+		LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
+		effectp->setPositionGlobal(gAgent.getPositionGlobal());
+		effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+		gHUDManager->sendEffects();
+	}
+
+	// Attempt to close all floaters that might be
+	// editing things.
+	if (gFloaterView)
+	{
+		// application is quitting
+		gFloaterView->closeAllChildren(true);
+	}
+
+	send_stats();
+
+	gLogoutTimer.reset();
+	mQuitRequested = true;
+}
+
+static void finish_quit(S32 option, void *userdata)
+{
+	if (option == 0)
+	{
+		LLAppViewer::instance()->requestQuit();
+	}
+}
+
+void LLAppViewer::userQuit()
+{
+	gViewerWindow->alertXml("ConfirmQuit", finish_quit, NULL);
+}
+
+static void finish_early_exit(S32 option, void* userdata)
+{
+	LLAppViewer::instance()->forceQuit();
+}
+
+void LLAppViewer::earlyExit(const LLString& msg)
+{
+   	llwarns << "app_early_exit: " << msg << llendl;
+	gDoDisconnect = TRUE;
+// 	LLStringBase<char>::format_map_t args;
+// 	args["[MESSAGE]"] = mesg;
+// 	gViewerWindow->alertXml("AppEarlyExit", args, finish_early_exit);
+	LLAlertDialog::showCritical(msg, finish_early_exit, NULL);
+}
+
+void LLAppViewer::forceExit(S32 arg)
+{
+    removeMarkerFile();
+    
+    // *FIX:Mani - This kind of exit hardly seems appropriate.
+    exit(arg);
+}
+
+void LLAppViewer::abortQuit()
+{
+    llinfos << "abortQuit()" << llendl;
+	mQuitRequested = false;
+}
+
+bool LLAppViewer::initCache()
+{
+	mPurgeCache = false;
+	// Purge cache if user requested it
+	if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
+		gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
+	{
+		gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false);
+		mPurgeCache = true;
+	}
+	// Purge cache if it belongs to an old version
+	else
+	{
+		static const S32 cache_version = 5;
+		if (gSavedSettings.getS32("LocalCacheVersion") != cache_version)
+		{
+			mPurgeCache = true;
+			gSavedSettings.setS32("LocalCacheVersion", cache_version);
+		}
+	}
+	
+	// Setup and verify the cache location
+	LLString cache_location = gSavedSettings.getString("CacheLocation");
+	LLString new_cache_location = gSavedSettings.getString("NewCacheLocation");
+	if (new_cache_location != cache_location)
+	{
+		gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
+		purgeCache(); // purge old cache
+		gSavedSettings.setString("CacheLocation", new_cache_location);
+	}
+	
+	if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")))
+	{
+		llwarns << "Unable to set cache location" << llendl;
+		gSavedSettings.setString("CacheLocation", "");
+	}
+	
+	if (mPurgeCache)
+	{
+		LLSplashScreen::update("Clearing cache...");
+		purgeCache();
+	}
+
+	LLSplashScreen::update("Initializing Texture Cache...");
+	
+	// Init the texture cache
+	// Allocate 80% of the cache size for textures
+	BOOL read_only = mSecondInstance ? true : false;
+	const S32 MB = 1024*1024;
+	S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
+	const S64 MAX_CACHE_SIZE = 1024*MB;
+	cache_size = llmin(cache_size, MAX_CACHE_SIZE);
+	S64 texture_cache_size = ((cache_size * 8)/10);
+	S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, read_only);
+	texture_cache_size -= extra;
+
+	LLSplashScreen::update("Initializing VFS...");
+	
+	// Init the VFS
+	S64 vfs_size = cache_size - texture_cache_size;
+	const S64 MAX_VFS_SIZE = 1024 * MB; // 1 GB
+	vfs_size = llmin(vfs_size, MAX_VFS_SIZE);
+	vfs_size = (vfs_size / MB) * MB; // make sure it is MB aligned
+	U32 vfs_size_u32 = (U32)vfs_size;
+	U32 old_vfs_size = gSavedSettings.getU32("VFSOldSize") * MB;
+	bool resize_vfs = (vfs_size_u32 != old_vfs_size);
+	if (resize_vfs)
+	{
+		gSavedSettings.setU32("VFSOldSize", vfs_size_u32/MB);
+	}
+	llinfos << "VFS CACHE SIZE: " << vfs_size/(1024*1024) << " MB" << llendl;
+	
+	// This has to happen BEFORE starting the vfs
+	//time_t	ltime;
+	srand(time(NULL));		// Flawfinder: ignore
+	U32 old_salt = gSavedSettings.getU32("VFSSalt");
+	U32 new_salt;
+	char old_vfs_data_file[LL_MAX_PATH];		// Flawfinder: ignore
+	char old_vfs_index_file[LL_MAX_PATH];	// Flawfinder: ignore		
+	char new_vfs_data_file[LL_MAX_PATH];		// Flawfinder: ignore
+	char new_vfs_index_file[LL_MAX_PATH];	// Flawfinder: ignore
+	char static_vfs_index_file[LL_MAX_PATH];	// Flawfinder: ignore
+	char static_vfs_data_file[LL_MAX_PATH];	// Flawfinder: ignore
+
+	if (gMultipleViewersOK)
+	{
+		// don't mess with renaming the VFS in this case
+		new_salt = old_salt;
+	}
+	else
+	{
+		do
+		{
+			new_salt = rand();
+		} while( new_salt == old_salt );
+	}
+
+	snprintf(old_vfs_data_file,  LL_MAX_PATH, "%s%u",		// Flawfinder: ignore
+		gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE).c_str(),
+		old_salt);
+
+	// make sure this file exists
+	llstat s;
+	S32 stat_result = LLFile::stat(old_vfs_data_file, &s);
+	if (stat_result)
+	{
+		// doesn't exist, look for a data file
+		std::string mask;
+		mask = gDirUtilp->getDirDelimiter();
+		mask += VFS_DATA_FILE_BASE;
+		mask += "*";
+
+		std::string dir;
+		dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"");
+
+		std::string found_file;
+		if (gDirUtilp->getNextFileInDir(dir, mask, found_file, false))
+		{
+			snprintf(old_vfs_data_file, LL_MAX_PATH, "%s%s%s", dir.c_str(), gDirUtilp->getDirDelimiter().c_str(), found_file.c_str());		// Flawfinder: ignore
+
+			S32 start_pos;
+			S32 length = strlen(found_file.c_str());		/* Flawfinder: ignore*/
+			for (start_pos = length - 1; start_pos >= 0; start_pos--)
+			{
+				if (found_file[start_pos] == '.')
+				{
+					start_pos++;
+					break;
+				}
+			}
+			if (start_pos > 0)
+			{
+				sscanf(found_file.c_str() + start_pos, "%d", &old_salt);
+			}
+			llinfos << "Default vfs data file not present, found " << old_vfs_data_file << llendl;
+			llinfos << "Old salt: " << old_salt << llendl;
+		}
+	}
+
+	snprintf(old_vfs_index_file, LL_MAX_PATH, "%s%u",		// Flawfinder: ignore
+			gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_INDEX_FILE_BASE).c_str(),
+			old_salt);
+
+	stat_result = LLFile::stat(old_vfs_index_file, &s);
+	if (stat_result)
+	{
+		// We've got a bad/missing index file, nukem!
+		llwarns << "Bad or missing vfx index file " << old_vfs_index_file << llendl;
+		llwarns << "Removing old vfs data file " << old_vfs_data_file << llendl;
+		LLFile::remove(old_vfs_data_file);
+		LLFile::remove(old_vfs_index_file);
+		
+		// Just in case, nuke any other old cache files in the directory.
+		std::string dir;
+		dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"");
+
+		std::string mask;
+		mask = gDirUtilp->getDirDelimiter();
+		mask += VFS_DATA_FILE_BASE;
+		mask += "*";
+
+		gDirUtilp->deleteFilesInDir(dir, mask);
+
+		mask = gDirUtilp->getDirDelimiter();
+		mask += VFS_INDEX_FILE_BASE;
+		mask += "*";
+
+		gDirUtilp->deleteFilesInDir(dir, mask);
+	}
+
+	snprintf(new_vfs_data_file, LL_MAX_PATH, "%s%u",		// Flawfinder: ignore
+		gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE).c_str(),
+		new_salt);
+
+	snprintf(new_vfs_index_file, LL_MAX_PATH, "%s%u", gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_INDEX_FILE_BASE).c_str(),		// Flawfinder: ignore
+		new_salt);
+
+
+	strncpy(static_vfs_data_file, gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_data.db2").c_str(), LL_MAX_PATH -1);		// Flawfinder: ignore
+	static_vfs_data_file[LL_MAX_PATH -1] = '\0';
+	strncpy(static_vfs_index_file, gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_index.db2").c_str(), LL_MAX_PATH -1);		// Flawfinder: ignore
+	static_vfs_index_file[LL_MAX_PATH -1] = '\0';
+
+	if (resize_vfs)
+	{
+		llinfos << "Removing old vfs and re-sizing" << llendl;
+		
+		LLFile::remove(old_vfs_data_file);
+		LLFile::remove(old_vfs_index_file);
+	}
+	else if (old_salt != new_salt)
+	{
+		// move the vfs files to a new name before opening
+		llinfos << "Renaming " << old_vfs_data_file << " to " << new_vfs_data_file << llendl;
+		llinfos << "Renaming " << old_vfs_index_file << " to " << new_vfs_index_file << llendl;
+		LLFile::rename(old_vfs_data_file, new_vfs_data_file);
+		LLFile::rename(old_vfs_index_file, new_vfs_index_file);
+	}
+
+	// Startup the VFS...
+	gSavedSettings.setU32("VFSSalt", new_salt);
+
+	// Don't remove VFS after viewer crashes.  If user has corrupt data, they can reinstall. JC
+	gVFS = new LLVFS(new_vfs_index_file, new_vfs_data_file, false, vfs_size_u32, false);
+	if( VFSVALID_BAD_CORRUPT == gVFS->getValidState() )
+	{
+		// Try again with fresh files 
+		// (The constructor deletes corrupt files when it finds them.)
+		llwarns << "VFS corrupt, deleted.  Making new VFS." << llendl;
+		delete gVFS;
+		gVFS = new LLVFS(new_vfs_index_file, new_vfs_data_file, false, vfs_size_u32, false);
+	}
+
+	gStaticVFS = new LLVFS(static_vfs_index_file, static_vfs_data_file, true, 0, false);
+
+	BOOL success = gVFS->isValid() && gStaticVFS->isValid();
+	if( !success )
+	{
+		return false;
+	}
+	else
+	{
+		LLVFile::initClass();
+		return true;
+	}
+}
+
+void LLAppViewer::purgeCache()
+{
+	llinfos << "Purging Texture Cache..." << llendl;
+	LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
+	llinfos << "Purging Cache..." << llendl;
+	std::string mask = gDirUtilp->getDirDelimiter() + "*.*";
+	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"").c_str(),mask);
+}
+
+const LLString& LLAppViewer::getSecondLifeTitle() const
+{
+	return gSecondLife;
+}
+
+const LLString& LLAppViewer::getWindowTitle() const 
+{
+	return gWindowTitle;
+}
+
+void LLAppViewer::resetURIs() const
+{
+    // Clear URIs when picking a new server
+	gLoginURIs.clear();
+	gHelperURI.clear();
+}
+
+const std::vector<std::string>& LLAppViewer::getLoginURIs() const
+{
+	if (gLoginURIs.empty())
+	{
+		// not specified on the command line, use value from table
+		gLoginURIs = LLSRV::rewriteURI(gGridInfo[gGridChoice].mLoginURI);
+	}
+	return gLoginURIs;
+}
+
+const std::string& LLAppViewer::getHelperURI() const
+{
+	if (gHelperURI.empty())
+	{
+		// not specified on the command line, use value from table
+		gHelperURI = gGridInfo[gGridChoice].mHelperURI;
+	}
+	return gHelperURI;
+}
+
+void LLAppViewer::addLoginURI(const std::string& uri)
+{
+    gLoginURIs.push_back(uri);
+}
+
+void LLAppViewer::setHelperURI(const std::string& uri)
+{
+    gHelperURI = uri;
+}
+
+// Callback from a dialog indicating user was logged out.  
+void finish_disconnect(S32 option, void* userdata)
+{
+	if (1 == option)
+	{
+        LLAppViewer::instance()->forceQuit();
+	}
+}
+
+// Callback from an early disconnect dialog, force an exit
+void finish_forced_disconnect(S32 /* option */, void* /* userdata */)
+{
+	LLAppViewer::instance()->forceQuit();
+}
+
+
+void LLAppViewer::forceDisconnect(const LLString& mesg)
+{
+	if (gDoDisconnect)
+    {
+		// Already popped up one of these dialogs, don't
+		// do this again.
+		return;
+    }
+	
+	// Translate the message if possible
+	LLString big_reason = LLAgent::sTeleportErrorMessages[mesg];
+	if ( big_reason.size() == 0 )
+	{
+		big_reason = mesg;
+	}
+
+	LLStringBase<char>::format_map_t args;
+	gDoDisconnect = TRUE;
+
+	if (LLStartUp::getStartupState() < STATE_STARTED)
+	{
+		// Tell users what happened
+		args["[ERROR_MESSAGE]"] = big_reason;
+		gViewerWindow->alertXml("ErrorMessage", args, finish_forced_disconnect);
+	}
+	else
+	{
+		args["[MESSAGE]"] = big_reason;
+		gViewerWindow->alertXml("YouHaveBeenLoggedOut", args, finish_disconnect );
+	}
+}
+
+void LLAppViewer::badNetworkHandler()
+{
+	// Dump the packet
+	gMessageSystem->dumpPacketToLog();
+
+	// Flush all of our caches on exit in the case of disconnect due to
+	// invalid packets.
+
+	mPurgeOnExit = TRUE;
+
+#if LL_WINDOWS
+	// Generates the minidump.
+	LLWinDebug::handleException(NULL);
+#endif
+	LLAppViewer::handleViewerCrash();
+
+	std::ostringstream message;
+	message <<
+		"The viewer has detected mangled network data indicative\n"
+		"of a bad upstream network connection or an incomplete\n"
+		"local installation of " << LLAppViewer::instance()->getSecondLifeTitle() << ". \n"
+		" \n"
+		"Try uninstalling and reinstalling to see if this resolves \n"
+		"the issue. \n"
+		" \n"
+		"If the problem continues, see the Tech Support FAQ at: \n"
+		"www.secondlife.com/support";
+	forceDisconnect(message.str());
+}
+
+// This routine may get called more than once during the shutdown process.
+// This can happen because we need to get the screenshot before the window
+// is destroyed.
+void LLAppViewer::saveFinalSnapshot()
+{
+	if (!mSavedFinalSnapshot && !gNoRender)
+	{
+		gSavedSettings.setVector3d("FocusPosOnLogout", gAgent.calcFocusPositionTargetGlobal());
+		gSavedSettings.setVector3d("CameraPosOnLogout", gAgent.calcCameraPositionTargetGlobal());
+		gViewerWindow->setCursor(UI_CURSOR_WAIT);
+		gAgent.changeCameraToThirdPerson( FALSE );	// don't animate, need immediate switch
+		gSavedSettings.setBOOL("ShowParcelOwners", FALSE);
+		idle();
+
+		LLString snap_filename = gDirUtilp->getLindenUserDir();
+		snap_filename += gDirUtilp->getDirDelimiter();
+		snap_filename += SCREEN_LAST_FILENAME;
+		gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidth(), gViewerWindow->getWindowHeight(), FALSE, TRUE);
+		mSavedFinalSnapshot = TRUE;
+	}
+}
+
+void LLAppViewer::loadNameCache()
+{
+	if (!gCacheName) return;
+
+	std::string name_cache;
+	name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
+	FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "r");		// Flawfinder: ignore
+	if (name_cache_fp)
+	{
+		gCacheName->importFile(name_cache_fp);
+		fclose(name_cache_fp);
+	}
+}
+
+void LLAppViewer::saveNameCache()
+{
+	if (!gCacheName) return;
+
+	std::string name_cache;
+	name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
+	FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "w");		// Flawfinder: ignore
+	if (name_cache_fp)
+	{
+		gCacheName->exportFile(name_cache_fp);
+		fclose(name_cache_fp);
+	}
+}
+
+///////////////////////////////////////////////////////
+// idle()
+//
+// Called every time the window is not doing anything.
+// Receive packets, update statistics, and schedule a redisplay.
+///////////////////////////////////////////////////////
+void LLAppViewer::idle()
+{
+	// Update frame timers
+	static LLTimer idle_timer;
+
+	LLControlBase::updateAllListeners();
+
+	LLFrameTimer::updateFrameTime();
+	LLEventTimer::updateClass();
+	LLCriticalDamp::updateInterpolants();
+	LLMortician::updateClass();
+	F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
+
+	// Cap out-of-control frame times
+	// Too low because in menus, swapping, debugger, etc.
+	// Too high because idle called with no objects in view, etc.
+	const F32 MIN_FRAME_RATE = 1.f;
+	const F32 MAX_FRAME_RATE = 200.f;
+
+	F32 frame_rate_clamped = 1.f / dt_raw;
+	frame_rate_clamped = llclamp(frame_rate_clamped, MIN_FRAME_RATE, MAX_FRAME_RATE);
+	gFrameDTClamped = 1.f / frame_rate_clamped;
+
+	// Global frame timer
+	// Smoothly weight toward current frame
+	gFPSClamped = (frame_rate_clamped + (4.f * gFPSClamped)) / 5.f;
+
+	if (gQuitAfterSeconds > 0.f)
+	{
+		if (gRenderStartTime.getElapsedTimeF32() > gQuitAfterSeconds)
+		{
+			LLAppViewer::instance()->forceQuit();
+		}
+	}
+
+	// Must wait until both have avatar object and mute list, so poll
+	// here.
+	request_initial_instant_messages();
+
+	///////////////////////////////////
+	//
+	// Special case idle if still starting up
+	//
+
+	if (LLStartUp::getStartupState() < STATE_STARTED)
+	{
+		// Skip rest if idle startup returns false (essentially, no world yet)
+		if (!idle_startup())
+		{
+			return;
+		}
+	}
+
+	
+    F32 yaw = 0.f;				// radians
+
+	if (!gDisconnected)
+	{
+		LLFastTimer t(LLFastTimer::FTM_NETWORK);
+		
+	    // Update spaceserver timeinfo
+	    gWorldp->setSpaceTimeUSec(gWorldp->getSpaceTimeUSec() + (U32)(dt_raw * SEC_TO_MICROSEC));
+    
+    
+	    //////////////////////////////////////
+	    //
+	    // Update simulator agent state
+	    //
+
+		if (gRotateRight)
+		{
+			gAgent.moveYaw(-1.f);
+		}
+
+	    // Handle automatic walking towards points
+	    gAgentPilot.updateTarget();
+	    gAgent.autoPilot(&yaw);
+    
+	    static LLFrameTimer agent_update_timer;
+	    static U32 				last_control_flags;
+    
+	    //	When appropriate, update agent location to the simulator.
+	    F32 agent_update_time = agent_update_timer.getElapsedTimeF32();
+	    BOOL flags_changed = gAgent.controlFlagsDirty() || (last_control_flags != gAgent.getControlFlags());
+    
+	    if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
+	    {
+		    // Send avatar and camera info
+		    last_control_flags = gAgent.getControlFlags();
+		    send_agent_update(TRUE);
+		    agent_update_timer.reset();
+	    }
+	}
+
+	//////////////////////////////////////
+	//
+	// Manage statistics
+	//
+	//
+
+	{
+		static LLFrameTimer	viewer_stats_timer;
+		reset_statistics();
+
+		// Update session stats every large chunk of time
+		// *FIX: (???) SAMANTHA
+		if (viewer_stats_timer.getElapsedTimeF32() >= 300.f && !gDisconnected)
+		{
+			llinfos << "Transmitting sessions stats" << llendl;
+			send_stats();
+			viewer_stats_timer.reset();
+		}
+
+		// Print the object debugging stats
+		static LLFrameTimer object_debug_timer;
+		if (object_debug_timer.getElapsedTimeF32() > 5.f)
+		{
+			object_debug_timer.reset();
+			if (gObjectList.mNumDeadObjectUpdates)
+			{
+				llinfos << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << llendl;
+				gObjectList.mNumDeadObjectUpdates = 0;
+			}
+			if (gObjectList.mNumUnknownKills)
+			{
+				llinfos << "Kills on unknown objects: " << gObjectList.mNumUnknownKills << llendl;
+				gObjectList.mNumUnknownKills = 0;
+			}
+			if (gObjectList.mNumUnknownUpdates)
+			{
+				llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl;
+				gObjectList.mNumUnknownUpdates = 0;
+			}
+		}
+		gFrameStats.addFrameData();
+	}
+	
+	if (!gDisconnected)
+	{
+		LLFastTimer t(LLFastTimer::FTM_NETWORK);
+	
+	    ////////////////////////////////////////////////
+	    //
+	    // Network processing
+	    //
+	    // NOTE: Starting at this point, we may still have pointers to "dead" objects
+	    // floating throughout the various object lists.
+	    //
+    
+	    gFrameStats.start(LLFrameStats::IDLE_NETWORK);
+		idleNetwork();
+	    stop_glerror();
+	        
+	    gFrameStats.start(LLFrameStats::AGENT_MISC);
+
+		// Check for away from keyboard, kick idle agents.
+		idle_afk_check();
+
+		//  Update statistics for this frame
+		update_statistics(gFrameCount);
+
+		gViewerWindow->updateDebugText();
+	}
+
+	////////////////////////////////////////
+	//
+	// Handle the regular UI idle callbacks as well as
+	// hover callbacks
+	//
+
+	{
+// 		LLFastTimer t(LLFastTimer::FTM_IDLE_CB);
+
+		// Do event notifications if necessary.  Yes, we may want to move this elsewhere.
+		gEventNotifier.update();
+		
+		gIdleCallbacks.callFunctions();
+	}
+	
+	if (gDisconnected)
+    {
+		return;
+    }
+
+	gViewerWindow->handlePerFrameHover();
+
+	///////////////////////////////////////
+	// Agent and camera movement
+	//
+		LLCoordGL current_mouse = gViewerWindow->getCurrentMouse();
+
+// 		BOOL was_in_prelude = gAgent.inPrelude();
+
+	{
+		//LLFastTimer t(LLFastTimer::FTM_TEMP1);
+		
+		// After agent and camera moved, figure out if we need to
+		// deselect objects.
+		gSelectMgr->deselectAllIfTooFar();
+
+	}
+
+	{
+		LLFastTimer t(LLFastTimer::FTM_RESET_DRAWORDER);
+			
+		//////////////////////////////////////////////
+		//
+		// Clear draw orders
+		//
+		// Should actually be done after render, but handlePerFrameHover actually does a "render"
+		// to do its selection.
+		//
+
+		gPipeline.resetDrawOrders();
+	}
+	{
+		// Handle pending gesture processing
+		gGestureManager.update();
+
+		gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY);
+	}
+
+	{
+		LLFastTimer t(LLFastTimer::FTM_OBJECTLIST_UPDATE); // Actually "object update"
+		gFrameStats.start(LLFrameStats::OBJECT_UPDATE);
+		
+        if (!(logoutRequestSent() && hasSavedFinalSnapshot()))
+		{
+			gObjectList.update(gAgent, *gWorldp);
+		}
+	}
+	
+	{
+		LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY);	
+		gSky.updateSky();
+	}
+
+	//////////////////////////////////////
+	//
+	// Deletes objects...
+	// Has to be done after doing idleUpdates (which can kill objects)
+	//
+
+	{
+		LLFastTimer t(LLFastTimer::FTM_CLEANUP);
+		gFrameStats.start(LLFrameStats::CLEAN_DEAD);
+		gObjectList.cleanDeadObjects();
+		LLDrawable::cleanupDeadDrawables();
+	}
+	
+	//
+	// After this point, in theory we should never see a dead object
+	// in the various object/drawable lists.
+	//
+
+	//////////////////////////////////////
+	//
+	// Update/send HUD effects
+	//
+	// At this point, HUD effects may clean up some references to
+	// dead objects.
+	//
+
+	{
+		//LLFastTimer t(LLFastTimer::FTM_TEMP3);
+		
+		gFrameStats.start(LLFrameStats::UPDATE_EFFECTS);
+		gSelectMgr->updateEffects();
+		gHUDManager->cleanupEffects();
+		gHUDManager->sendEffects();
+	}
+
+	stop_glerror();
+
+	////////////////////////////////////////
+	//
+	// Unpack layer data that we've received
+	//
+
+	{
+		LLFastTimer t(LLFastTimer::FTM_NETWORK);
+		gVLManager.unpackData();
+	}
+	
+	/////////////////////////
+	//
+	// Update surfaces, and surface textures as well.
+	//
+
+	gWorldp->updateVisibilities();
+	{
+		const F32 max_region_update_time = .001f; // 1ms
+		LLFastTimer t(LLFastTimer::FTM_REGION_UPDATE);
+		gWorldp->updateRegions(max_region_update_time);
+	}
+	
+	/////////////////////////
+	//
+	// Update weather effects
+	//
+
+	if (!gNoRender)
+	{
+		gWorldp->updateClouds(gFrameDTClamped);
+		gSky.propagateHeavenlyBodies(gFrameDTClamped);				// moves sun, moon, and planets
+
+		// Update wind vector 
+		LLVector3 wind_position_region;
+		static LLVector3 average_wind;
+
+		LLViewerRegion *regionp;
+		regionp = gWorldp->resolveRegionGlobal(wind_position_region, gAgent.getPositionGlobal());	// puts agent's local coords into wind_position	
+		if (regionp)
+		{
+			gWindVec = regionp->mWind.getVelocity(wind_position_region);
+
+			// Compute average wind and use to drive motion of water
+			
+			average_wind = regionp->mWind.getAverage();
+			F32 cloud_density = regionp->mCloudLayer.getDensityRegion(wind_position_region);
+			
+			gSky.setCloudDensityAtAgent(cloud_density);
+			gSky.setWind(average_wind);
+			//LLVOWater::setWind(average_wind);
+		}
+		else
+		{
+			gWindVec.setVec(0.0f, 0.0f, 0.0f);
+		}
+	}
+	stop_glerror();
+	
+	//////////////////////////////////////
+	//
+	// Update images, using the image stats generated during object update/culling
+	//
+	// Can put objects onto the retextured list.
+	//
+	gFrameStats.start(LLFrameStats::IMAGE_UPDATE);
+
+	LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE);
+	
+	LLViewerImage::updateClass(gCamera->getVelocityStat()->getMean(),
+								gCamera->getAngularVelocityStat()->getMean());
+
+	gBumpImageList.updateImages();  // must be called before gImageList version so that it's textures are thrown out first.
+
+	const F32 max_image_decode_time = 0.005f; // 5 ms decode time
+	gImageList.updateImages(max_image_decode_time);
+	stop_glerror();
+
+	//////////////////////////////////////
+	//
+	// Sort and cull in the new renderer are moved to pipeline.cpp
+	// Here, particles are updated and drawables are moved.
+	//
+	
+	if (!gNoRender)
+	{
+		gFrameStats.start(LLFrameStats::UPDATE_MOVE);
+		gPipeline.updateMove();
+
+		gFrameStats.start(LLFrameStats::UPDATE_PARTICLES);
+		gWorldp->updateParticles();
+	}
+	stop_glerror();
+
+	if (!LLViewerJoystick::sOverrideCamera)
+	{
+		gAgent.updateCamera();
+	}
+	else
+	{
+		LLViewerJoystick::updateCamera();
+	}
+
+	// objects and camera should be in sync, do LOD calculations now
+	{
+		LLFastTimer t(LLFastTimer::FTM_LOD_UPDATE);
+		gObjectList.updateApparentAngles(gAgent);
+	}
+
+	{
+		gFrameStats.start(LLFrameStats::AUDIO);
+		LLFastTimer t(LLFastTimer::FTM_AUDIO_UPDATE);
+		
+		if (gAudiop)
+		{
+		    audio_update_volume(false);
+			audio_update_listener();
+			audio_update_wind(false);
+
+			// this line actually commits the changes we've made to source positions, etc.
+			const F32 max_audio_decode_time = 0.002f; // 2 ms decode time
+			gAudiop->idle(max_audio_decode_time);
+		}
+	}
+	
+	// Handle shutdown process, for example, 
+	// wait for floaters to close, send quit message,
+	// forcibly quit if it has taken too long
+	if (mQuitRequested)
+	{
+		idleShutdown();
+	}
+
+	stop_glerror();
+}
+
+void LLAppViewer::idleShutdown()
+{
+	// Wait for all modal alerts to get resolved
+	if (LLModalDialog::activeCount() > 0)
+	{
+		return;
+	}
+
+	// close IM interface
+	if(gIMMgr)
+	{
+		gIMMgr->disconnectAllSessions();
+	}
+	
+	// Wait for all floaters to get resolved
+	if (gFloaterView
+		&& !gFloaterView->allChildrenClosed())
+	{
+		return;
+	}
+
+	static bool saved_snapshot = false;
+	if (!saved_snapshot)
+	{
+		saved_snapshot = true;
+		saveFinalSnapshot();
+		return;
+	}
+
+	const F32 SHUTDOWN_UPLOAD_SAVE_TIME = 5.f;
+
+	S32 pending_uploads = gAssetStorage->getNumPendingUploads();
+	if (pending_uploads > 0
+		&& gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
+		&& !logoutRequestSent())
+	{
+		static S32 total_uploads = 0;
+		// Sometimes total upload count can change during logout.
+		total_uploads = llmax(total_uploads, pending_uploads);
+		gViewerWindow->setShowProgress(TRUE);
+		S32 finished_uploads = total_uploads - pending_uploads;
+		F32 percent = 100.f * finished_uploads / total_uploads;
+		gViewerWindow->setProgressPercent(percent);
+		char buffer[MAX_STRING];		// Flawfinder: ignore
+		snprintf(buffer, MAX_STRING, "Saving final data...");		// Flawfinder: ignore
+		gViewerWindow->setProgressString(buffer);
+		return;
+	}
+
+	// All floaters are closed.  Tell server we want to quit.
+	if( !logoutRequestSent() )
+	{
+		sendLogoutRequest();
+
+		// Wait for a LogoutReply message
+		gViewerWindow->setShowProgress(TRUE);
+		gViewerWindow->setProgressPercent(100.f);
+		gViewerWindow->setProgressString("Logging out...");
+		return;
+	}
+
+	// Make sure that we quit if we haven't received a reply from the server.
+	if( logoutRequestSent() 
+		&& gLogoutTimer.getElapsedTimeF32() > gLogoutMaxTime )
+	{
+		forceQuit();
+		return;
+	}
+}
+
+void LLAppViewer::sendLogoutRequest()
+{
+	if(!mLogoutRequestSent)
+	{
+		LLMessageSystem* msg = gMessageSystem;
+		msg->newMessageFast(_PREHASH_LogoutRequest);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		gAgent.sendReliableMessage();
+
+		gLogoutTimer.reset();
+		gLogoutMaxTime = LOGOUT_REQUEST_TIME;
+		mLogoutRequestSent = TRUE;
+		
+		gVoiceClient->leaveChannel();
+	}
+}
+
+//
+// Handle messages, and all message related stuff
+//
+
+#define TIME_THROTTLE_MESSAGES
+
+#ifdef TIME_THROTTLE_MESSAGES
+#define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!)
+static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
+#endif
+
+void LLAppViewer::idleNetwork()
+{
+	gObjectList.mNumNewObjects = 0;
+	S32 total_decoded = 0;
+
+	if (!gSavedSettings.getBOOL("SpeedTest"))
+	{
+		LLFastTimer t(LLFastTimer::FTM_IDLE_NETWORK); // decode
+		
+		// deal with any queued name requests and replies.
+		gCacheName->processPending();
+
+		LLTimer check_message_timer;
+		//  Read all available packets from network 
+		stop_glerror();
+		const S64 frame_count = gFrameCount;  // U32->S64
+		F32 total_time = 0.0f;
+   		while (gMessageSystem->checkAllMessages(frame_count, gServicePump)) 
+		{
+			if (gDoDisconnect)
+			{
+				// We're disconnecting, don't process any more messages from the server
+				// We're usually disconnecting due to either network corruption or a
+				// server going down, so this is OK.
+				break;
+			}
+			stop_glerror();
+
+			total_decoded++;
+			gPacketsIn++;
+
+			if (total_decoded > MESSAGE_MAX_PER_FRAME)
+			{
+				break;
+			}
+
+#ifdef TIME_THROTTLE_MESSAGES
+			// Prevent slow packets from completely destroying the frame rate.
+			// This usually happens due to clumps of avatars taking huge amount
+			// of network processing time (which needs to be fixed, but this is
+			// a good limit anyway).
+			total_time = check_message_timer.getElapsedTimeF32();
+			if (total_time >= CheckMessagesMaxTime)
+				break;
+#endif
+		}
+		// Handle per-frame message system processing.
+		gMessageSystem->processAcks();
+
+#ifdef TIME_THROTTLE_MESSAGES
+		if (total_time >= CheckMessagesMaxTime)
+		{
+			// Increase CheckMessagesMaxTime so that we will eventually catch up
+			CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
+		}
+		else
+		{
+			// Reset CheckMessagesMaxTime to default value
+			CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
+		}
+#endif
+		
+
+
+		// we want to clear the control after sending out all necessary agent updates
+		gAgent.resetControlFlags();
+		stop_glerror();
+
+		
+		// Decode enqueued messages...
+		S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded;
+
+		if( remaining_possible_decodes <= 0 )
+		{
+			llinfos << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << llendl;
+		}
+
+		if (gPrintMessagesThisFrame)
+		{
+			llinfos << "Decoded " << total_decoded << " msgs this frame!" << llendl;
+			gPrintMessagesThisFrame = FALSE;
+		}
+	}
+
+	gObjectList.mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
+
+	// Retransmit unacknowledged packets.
+	gXferManager->retransmitUnackedPackets();
+	gAssetStorage->checkForTimeouts();
+
+	gViewerThrottle.updateDynamicThrottle();
+}
+
+void LLAppViewer::disconnectViewer()
+{
+	if (gDisconnected)
+	{
+		return;
+	}
+	//
+	// Cleanup after quitting.
+	//	
+	// Save snapshot for next time, if we made it through initialization
+
+	llinfos << "Disconnecting viewer!" << llendl;
+
+	// Dump our frame statistics
+	gFrameStats.dump();
+
+	// Remember if we were flying
+	gSavedSettings.setBOOL("FlyingAtExit", gAgent.getFlying() );
+
+	// Un-minimize all windows so they don't get saved minimized
+	if (!gNoRender)
+	{
+		if (gFloaterView)
+		{
+			gFloaterView->restoreAll();
+		}
+	}
+
+	if (gSelectMgr)
+	{
+		gSelectMgr->deselectAll();
+	}
+
+	if (!gNoRender)
+	{
+		// save inventory if appropriate
+		gInventory.cache(gAgent.getInventoryRootID(), gAgent.getID());
+		if(gInventoryLibraryRoot.notNull() && gInventoryLibraryOwner.notNull())
+		{
+			gInventory.cache(gInventoryLibraryRoot, gInventoryLibraryOwner);
+		}
+	}
+
+	saveNameCache();
+
+	// close inventory interface, close all windows
+	LLInventoryView::cleanup();
+
+	// Also writes cached agent settings to gSavedSettings
+	gAgent.cleanup();
+
+	gObjectList.destroy();
+	delete gWorldp;
+	gWorldp = NULL;
+
+	cleanup_xfer_manager();
+	gDisconnected = TRUE;
+}
+
+void LLAppViewer::forceErrorLLError()
+{
+   	llerrs << "This is an llerror" << llendl;
+}
+
+void LLAppViewer::forceErrorBreakpoint()
+{
+#ifdef LL_WINDOWS
+    DebugBreak();
+#endif
+    return;
+}
+
+void LLAppViewer::forceErrorBadMemoryAccess()
+{
+    S32* crash = NULL;
+    *crash = 0xDEADBEEF;
+    return;
+}
+
+void LLAppViewer::forceErrorInifiniteLoop()
+{
+    while(true)
+    {
+        ;
+    }
+    return;
+}
+ 
+void LLAppViewer::forceErrorSoftwareException()
+{
+    // *FIX: Any way to insure it won't be handled?
+    throw; 
+}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
new file mode 100644
index 0000000000000000000000000000000000000000..227a27a8ac88cde055f7d9c55af3d6107446888a
--- /dev/null
+++ b/indra/newview/llappviewer.h
@@ -0,0 +1,298 @@
+/** 
+ * @file llappviewer.h
+ * @brief The LLAppViewer class declaration
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAPPVIEWER_H
+#define LL_LLAPPVIEWER_H
+
+class LLTextureCache;
+class LLWorkerThread;
+class LLTextureFetch;
+
+class LLAppViewer : public LLApp
+{
+public:
+	LLAppViewer();
+	virtual ~LLAppViewer();
+
+	// *NOTE:Mani - Don't use this!
+	// Having 
+	static LLAppViewer* instance() {return sInstance; } 
+
+	//
+	// Main application logic
+	//
+	virtual bool init();			// Override to do application initialization
+	virtual bool cleanup();			// Override to do application cleanup
+	virtual bool mainLoop(); // Override for the application main loop.  Needs to at least gracefully notice the QUITTING state and exit.
+
+	// Application control
+	void forceQuit(); // Puts the viewer into 'shutting down without error' mode.
+	void requestQuit(); // Request a quit. A kinder, gentler quit.
+	void userQuit(); // The users asks to quit. Confirm, then requestQuit()
+    void earlyExit(const LLString& msg); // Display an error dialog and forcibly quit.
+    void forceExit(S32 arg); // exit() immediately (after some cleanup).
+    void abortQuit();  // Called to abort a quit request.
+
+    bool quitRequested() { return mQuitRequested; }
+    bool logoutRequestSent() { return mLogoutRequestSent; }
+
+	// *FIX: This is meant to stay only until the command line issues are hashed out with repect to LLApp::parseCommandLine
+	// This version stores the argc and argv for later usage, make sure the params passed in last as long as this class.
+	bool tempStoreCommandOptions(int argc, char** argv);
+
+	// write string to "debug_info.log", used for crash reporting.
+	void writeDebug(const char *str); 
+	void writeDebug(const std::string& str) { writeDebug(str.c_str()); };
+	void closeDebug();
+
+	const LLOSInfo& getOSInfo() const { return mSysOSInfo; }
+
+	// Report true if under the control of a debugger. A null-op default.
+	virtual bool beingDebugged() { return false; } 
+
+	S32 getCrashBehavior() const { return mCrashBehavior; } 
+	void setCrashBehavior(S32 cb);
+	virtual void handleCrashReporting() = 0; // What to do with crash report?
+	static void handleViewerCrash(); // Hey! The viewer crashed. Do this.
+
+	// Thread accessors
+	static LLTextureCache* getTextureCache() { return sTextureCache; }
+	static LLWorkerThread* getImageDecodeThread() { return sImageDecodeThread; }
+	static LLTextureFetch* getTextureFetch() { return sTextureFetch; }
+
+	const std::string& getSerialNumber() { return mSerialNumber; }
+	
+	// *FIX:Mani purgeCache was made public for parse_args().
+	// If that beast is gone, make it private.
+	void purgeCache(); // Clear the local cache. 
+	bool getPurgeCache() const { return mPurgeCache; }
+	
+	const LLString& getSecondLifeTitle() const; // The Second Life title.
+	const LLString& getWindowTitle() const; // The window display name.
+
+    // Helpers for URIs
+    void addLoginURI(const std::string& uri);
+    void setHelperURI(const std::string& uri);
+    const std::vector<std::string>& getLoginURIs() const;
+    const std::string& getHelperURI() const;
+    void resetURIs() const;
+
+    void forceDisconnect(const LLString& msg); // Force disconnection, with a message to the user.
+    void badNetworkHandler(); // Cause a crash state due to bad network packet.
+
+	bool hasSavedFinalSnapshot() { return mSavedFinalSnapshot; }
+	void saveFinalSnapshot(); 
+
+    void loadNameCache();
+    void saveNameCache();
+
+    // LLAppViewer testing helpers.
+    // *NOTE: These will potentially crash the viewer. Only for debugging.
+    virtual void forceErrorLLError();
+    virtual void forceErrorBreakpoint();
+    virtual void forceErrorBadMemoryAccess();
+    virtual void forceErrorInifiniteLoop();
+    virtual void forceErrorSoftwareException();
+
+protected:
+	virtual bool initWindow(); // Initialize the viewer's window.
+	virtual bool initLogging(); // Initialize log files, logging system, return false on failure.
+	virtual bool initHardwareTest() { return true; } // A false result indicates the app should quit.
+	
+	virtual std::string generateSerialNumber() = 0; // Platforms specific classes generate this.
+
+
+private:
+
+	bool initEarlyConfiguration(); // Initialize setting needed by crash reporting.
+	bool initThreads(); // Initialize viewer threads, return false on failure.
+	bool initConfiguration(); // Initialize settings from the command line/config file.
+
+	bool initCache(); // Initialize local client cache.
+
+	bool doConfigFromCommandLine(); // calls parse args.
+
+	void cleanupSavedSettings(); // Sets some config data to current or default values during cleanup.
+	void removeCacheFiles(const char *filemask); // Deletes cached files the match the given wildcard.
+
+	void writeSystemInfo(); // Write system info to "debug_info.log"
+
+	bool anotherInstanceRunning(); 
+	void initMarkerFile(); 
+	void removeMarkerFile();
+    
+    void idle(); 
+    void idleShutdown();
+    void idleNetwork();
+
+    void sendLogoutRequest();
+    void disconnectViewer();
+
+	// *FIX: the app viewer class should be some sort of singleton, no?
+	// Perhaps its child class is the singleton and this should be an abstract base.
+	static LLAppViewer* sInstance; 
+
+    bool mSecondInstance; // Is this a second instance of the app?
+
+	FILE *mMarkerFile; // A file created to indicate the app is running.
+	bool mLastExecFroze; // Set on init if the marker file was found.
+
+	FILE* mDebugFile; // output stream written to via writeDebug()
+
+	LLOSInfo mSysOSInfo; 
+	S32 mCrashBehavior;
+	bool mReportedCrash;
+
+	// Thread objects.
+	static LLTextureCache* sTextureCache; 
+	static LLWorkerThread* sImageDecodeThread; 
+	static LLTextureFetch* sTextureFetch; 
+
+	S32 mNumSessions;
+
+	std::string mSerialNumber;
+	bool mPurgeCache;
+    bool mPurgeOnExit;
+
+	bool mSavedFinalSnapshot;
+
+    bool mQuitRequested;				// User wants to quit, may have modified documents open.
+    bool mLogoutRequestSent;			// Disconnect message sent to simulator, no longer safe to send messages to the sim.
+};
+
+// consts from viewer.h
+const S32 AGENT_UPDATES_PER_SECOND  = 10;
+
+// Globals with external linkage. From viewer.h
+// *NOTE:Mani - These will be removed as the Viewer App Cleanup project continues.
+//
+// "// llstartup" indicates that llstartup is the only client for this global.
+
+extern bool gVerifySSLCert; // parse_args setting used by llxmlrpctransaction.cpp
+extern BOOL gHandleKeysAsync; // gSavedSettings used by llviewerdisplay.cpp & llviewermenu.cpp
+extern BOOL gProbeHardware;
+extern LLString gDisabledMessage; // llstartup
+extern BOOL gHideLinks; // used by llpanellogin, lllfloaterbuycurrency, llstartup
+extern BOOL gInProductionGrid; 
+
+extern BOOL	gAllowIdleAFK;
+extern F32 gAFKTimeout;
+extern BOOL	gShowObjectUpdates;
+
+extern BOOL gLogMessages; // llstartup 
+extern std::string gChannelName;
+extern BOOL gUseAudio; // llstartup
+
+extern LLString gCmdLineFirstName; // llstartup
+extern LLString gCmdLineLastName;
+extern LLString gCmdLinePassword;
+
+extern BOOL gAutoLogin; // llstartup
+extern const char* DEFAULT_SETTINGS_FILE; // llstartup
+
+extern BOOL gRequestInventoryLibrary; // llstartup
+extern BOOL gGodConnect; // llstartup
+
+extern BOOL gAcceptTOS;
+extern BOOL gAcceptCriticalMessage;
+
+extern LLUUID	gViewerDigest;  // MD5 digest of the viewer's executable file.
+extern BOOL gLastExecFroze; // llstartup
+
+extern U32 gFrameCount;
+extern U32 gForegroundFrameCount;
+
+extern LLPumpIO* gServicePump;
+
+// Is the Pacific time zone (aka server time zone)
+// currently in daylight savings time?
+extern BOOL gPacificDaylightTime;
+
+extern U64      gFrameTime;					// The timestamp of the most-recently-processed frame
+extern F32		gFrameTimeSeconds;			// Loses msec precision after ~4.5 hours...
+extern F32		gFrameIntervalSeconds;		// Elapsed time between current and previous gFrameTimeSeconds
+extern F32		gFPSClamped;						// Frames per second, smoothed, weighted toward last frame
+extern F32		gFrameDTClamped;
+extern U64		gStartTime;
+
+extern LLTimer gRenderStartTime;
+extern LLFrameTimer gForegroundTime;
+
+extern F32 gLogoutMaxTime;
+extern LLTimer gLogoutTimer;
+
+extern F32 gSimLastTime; 
+extern F32 gSimFrames;
+
+extern LLUUID gInventoryLibraryOwner;
+extern LLUUID gInventoryLibraryRoot;
+
+extern BOOL		gDisconnected;
+extern BOOL		gDisableVoice;
+
+// Map scale in pixels per region
+extern F32 gMapScale;
+extern F32 gMiniMapScale;
+
+extern LLFrameTimer	gRestoreGLTimer;
+extern BOOL			gRestoreGL;
+extern BOOL		gUseWireframe;
+
+extern F32 gMouseSensitivity;
+extern BOOL gInvertMouse;
+
+// VFS globals - gVFS is for general use
+// gStaticVFS is read-only and is shipped w/ the viewer
+// it has pre-cache data like the UI .TGAs
+extern LLVFS	*gStaticVFS;
+
+extern LLMemoryInfo gSysMemory;
+
+extern bool gPreloadImages;
+extern bool gPreloadSounds;
+
+extern LLString gLastVersionChannel;
+
+extern LLVector3 gWindVec;
+extern LLVector3 gRelativeWindVec;
+extern U32	gPacketsIn;
+extern BOOL gPrintMessagesThisFrame;
+
+extern LLUUID gSunTextureID;
+extern LLUUID gMoonTextureID;
+
+extern BOOL gUseConsole; 
+
+extern BOOL gRandomizeFramerate;
+extern BOOL gPeriodicSlowFrame;
+
+extern BOOL gQAMode;
+#endif // LL_LLAPPVIEWER_H
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1993fd0a76e87df62b568d07ce9ebe09255a8201
--- /dev/null
+++ b/indra/newview/llappviewerlinux.cpp
@@ -0,0 +1,414 @@
+/**
+ * @file llappviewerlinux.cpp
+ * @brief The LLAppViewerWin32 class definitions
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */ 
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llmemtype.h"
+#include "llappviewerlinux.h"
+
+#include "llviewernetwork.h"
+#include "llmd5.h"
+
+  #if LL_LINUX
+  #	include <dlfcn.h>		// RTLD_LAZY
+  #     include <execinfo.h>            // backtrace - glibc only
+  #     ifndef LL_ELFBIN
+  #define LL_ELFBIN 1
+  #     endif // LL_ELFBIN
+  #     if LL_ELFBIN
+  #          include <cxxabi.h>         // for symbol demangling
+  #          include "ELFIO.h"          // for better backtraces
+  #     endif // LL_ELFBIN
+  #elif LL_SOLARIS
+  #     include <sys/types.h>
+  #     include <unistd.h>
+  #     include <fcntl.h>
+  #     include <ucontext.h>
+  #endif
+
+int main( int argc, char **argv ) 
+{
+	LLMemType mt1(LLMemType::MTYPE_STARTUP);
+
+#if LL_SOLARIS && defined(__sparc)
+	asm ("ta\t6");		 // NOTE:  Make sure memory alignment is enforced on SPARC
+#endif
+
+	LLAppViewer* viewer_app_ptr = new LLAppViewerLinux();
+
+	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
+
+	bool ok = viewer_app_ptr->tempStoreCommandOptions(argc, argv);
+	if(!ok)
+	{
+		llwarns << "Unable to parse command line." << llendl;
+		return -1;
+	}
+
+	ok = viewer_app_ptr->init();
+	if(!ok)
+	{
+		llwarns << "Application init failed." << llendl;
+		return -1;
+	}
+
+		// Run the application main loop
+	if(!LLApp::isQuitting()) 
+	{
+		viewer_app_ptr->mainLoop();
+	}
+
+	if (!LLApp::isError())
+	{
+		//
+		// We don't want to do cleanup here if the error handler got called -
+		// the assumption is that the error handler is responsible for doing
+		// app cleanup if there was a problem.
+		//
+		viewer_app_ptr->cleanup();
+	}
+	delete viewer_app_ptr;
+	viewer_app_ptr = NULL;
+	return 0;
+}
+
+#ifdef LL_SOLARIS
+static inline BOOL do_basic_glibc_backtrace()
+{
+	BOOL success = FALSE;
+
+	std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
+	llinfos << "Opening stack trace file " << strace_filename << llendl;
+	FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w");
+	if (!StraceFile)
+	{
+		llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl;
+		StraceFile = stderr;
+	}
+
+	printstack(fileno(StraceFile));
+
+	if (StraceFile != stderr)
+		fclose(StraceFile);
+
+	return success;
+}
+#else
+#define MAX_STACK_TRACE_DEPTH 40
+// This uses glibc's basic built-in stack-trace functions for a not very
+// amazing backtrace.
+static inline BOOL do_basic_glibc_backtrace()
+{
+	void *array[MAX_STACK_TRACE_DEPTH];
+	size_t size;
+	char **strings;
+	size_t i;
+	BOOL success = FALSE;
+
+	size = backtrace(array, MAX_STACK_TRACE_DEPTH);
+	strings = backtrace_symbols(array, size);
+
+	std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
+	llinfos << "Opening stack trace file " << strace_filename << llendl;
+	FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w");		// Flawfinder: ignore
+        if (!StraceFile)
+	{
+		llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl;
+		StraceFile = stderr;
+	}
+
+	if (size)
+	{
+		for (i = 0; i < size; i++)
+			fputs((std::string(strings[i])+"\n").c_str(),
+			      StraceFile);
+
+		success = TRUE;
+	}
+	
+	if (StraceFile != stderr)
+		fclose(StraceFile);
+
+	free (strings);
+	return success;
+}
+
+#if LL_ELFBIN
+// This uses glibc's basic built-in stack-trace functions together with
+// ELFIO's ability to parse the .symtab ELF section for better symbol
+// extraction without exporting symbols (which'd cause subtle, fatal bugs).
+static inline BOOL do_elfio_glibc_backtrace()
+{
+	void *array[MAX_STACK_TRACE_DEPTH];
+	size_t btsize;
+	char **strings;
+	BOOL success = FALSE;
+
+	std::string appfilename = gDirUtilp->getExecutablePathAndName();
+
+	std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
+	llinfos << "Opening stack trace file " << strace_filename << llendl;
+	FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w");		// Flawfinder: ignore
+        if (!StraceFile)
+	{
+		llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl;
+		StraceFile = stderr;
+	}
+
+	// get backtrace address list and basic symbol info
+	btsize = backtrace(array, MAX_STACK_TRACE_DEPTH);
+	strings = backtrace_symbols(array, btsize);
+
+	// create ELF reader for our app binary
+	IELFI* pReader;
+	const IELFISection* pSec = NULL;
+	IELFISymbolTable* pSymTbl = 0;
+	if (ERR_ELFIO_NO_ERROR != ELFIO::GetInstance()->CreateELFI(&pReader) ||
+	    ERR_ELFIO_NO_ERROR != pReader->Load(appfilename.c_str()) ||
+	    // find symbol table, create reader-object
+	    NULL == (pSec = pReader->GetSection( ".symtab" )) ||
+	    ERR_ELFIO_NO_ERROR != pReader->CreateSectionReader(IELFI::ELFI_SYMBOL, pSec, (void**)&pSymTbl) )
+	{
+		// Failed to open our binary and read its symbol table somehow
+		llinfos << "Could not initialize ELF symbol reading - doing basic backtrace." << llendl;
+		if (StraceFile != stderr)
+			fclose(StraceFile);
+		// note that we may be leaking some of the above ELFIO
+		// objects now, but it's expected that we'll be dead soon
+		// and we want to tread delicately until we get *some* kind
+		// of useful backtrace.
+		return do_basic_glibc_backtrace();
+	}
+
+	// iterate over trace and symtab, looking for plausible symbols
+	std::string   name;
+	Elf32_Addr    value;
+	Elf32_Word    ssize;
+	unsigned char bind;
+	unsigned char type;
+	Elf32_Half    section;
+	int nSymNo = pSymTbl->GetSymbolNum();
+	size_t btpos;
+	for (btpos = 0; btpos < btsize; ++btpos)
+	{
+		fprintf(StraceFile, "%d:\t", btpos);
+		int symidx;
+		for (symidx = 0; symidx < nSymNo; ++symidx)
+		{
+			if (ERR_ELFIO_NO_ERROR ==
+			    pSymTbl->GetSymbol(symidx, name, value, ssize,
+					       bind, type, section))
+			{
+				// check if trace address within symbol range
+				if (uintptr_t(array[btpos]) >= value &&
+				    uintptr_t(array[btpos]) < value+ssize)
+				{
+					char *demangled_str = NULL;
+					int demangle_result = 1;
+					demangled_str =
+						abi::__cxa_demangle
+						(name.c_str(), NULL, NULL,
+						 &demangle_result);
+					if (0 == demangle_result &&
+					    NULL != demangled_str) {
+						fprintf(StraceFile,
+							"ELF(%s", demangled_str);
+						free(demangled_str);
+					}
+					else // failed demangle; print it raw
+					{
+						fprintf(StraceFile,
+							"ELF(%s", name.c_str());
+					}
+					// print offset from symbol start
+					fprintf(StraceFile,
+						"+0x%lx) [%p]\n",
+						uintptr_t(array[btpos]) -
+						value,
+						array[btpos]);
+					goto got_sym; // early escape
+				}
+			}
+		}
+		// Fallback:
+		// Didn't find a suitable symbol in the binary - it's probably
+		// a symbol in a DSO; use glibc's idea of what it should be.
+		fprintf(StraceFile, "%s\n", strings[btpos]);
+	got_sym:;
+	}
+	
+	if (StraceFile != stderr)
+		fclose(StraceFile);
+
+	pSymTbl->Release();
+	pSec->Release();
+	pReader->Release();
+
+	free(strings);
+
+	llinfos << "Finished generating stack trace." << llendl;
+
+	success = TRUE;
+	return success;
+}
+#endif // LL_ELFBIN
+
+#endif // LL_SOLARIS
+
+
+LLAppViewerLinux::LLAppViewerLinux()
+{
+}
+
+LLAppViewerLinux::~LLAppViewerLinux()
+{
+}
+
+bool LLAppViewerLinux::init()
+{
+	return LLAppViewer::init();
+}
+
+void LLAppViewerLinux::handleCrashReporting()
+{
+
+	// Always generate the report, have the logger do the asking, and
+	// don't wait for the logger before exiting (-> total cleanup).
+	if (CRASH_BEHAVIOR_NEVER_SEND != LLAppViewer::instance()->getCrashBehavior())
+	{	
+		// This backtrace writes into stack_trace.log
+#  if LL_ELFBIN
+		do_elfio_glibc_backtrace(); // more useful backtrace
+#  else
+		do_basic_glibc_backtrace(); // only slightly useful backtrace
+#  endif // LL_ELFBIN
+		// launch the actual crash logger
+		char* ask_dialog = "-dialog";
+		if (CRASH_BEHAVIOR_ASK != LLAppViewer::instance()->getCrashBehavior())
+			ask_dialog = ""; // omit '-dialog' option
+		std::string cmd =gDirUtilp->getAppRODataDir();
+		cmd += gDirUtilp->getDirDelimiter();
+		cmd += "linux-crash-logger.bin";
+		char* const cmdargv[] =
+			{(char*)cmd.c_str(),
+			 ask_dialog,
+			 (char*)"-user",
+			 (char*)gGridName,
+			 (char*)"-name",
+			 (char*)LLAppViewer::instance()->getSecondLifeTitle().c_str(),
+			 NULL};
+		pid_t pid = fork();
+		if (pid == 0)
+		{ // child
+			execv(cmd.c_str(), cmdargv);		/* Flawfinder: ignore */
+			llwarns << "execv failure when trying to start " << cmd << llendl;
+			_exit(1); // avoid atexit()
+		} 
+		else
+		{
+			if (pid > 0)
+			{
+				// DO NOT wait for child proc to die; we want
+				// the logger to outlive us while we quit to
+				// free up the screen/keyboard/etc.
+				////int childExitStatus;
+				////waitpid(pid, &childExitStatus, 0);
+			} 
+			else
+			{
+				llwarns << "fork failure." << llendl;
+			}
+		}
+	}
+	// Sometimes signals don't seem to quit the viewer.  
+	// Make sure we exit so as to not totally confuse the user.
+	exit(1);
+}
+
+bool LLAppViewerLinux::beingDebugged()
+{
+	static enum {unknown, no, yes} debugged = unknown;
+	
+	if (debugged == unknown)
+	{
+		pid_t ppid = getppid();
+		char *name;
+		int ret;
+
+		ret = asprintf(&name, "/proc/%d/exe", ppid);
+		if (ret != -1)
+		{
+			char buf[1024];
+			ssize_t n;
+			
+			n = readlink(name, buf, sizeof(buf) - 1);
+			if (n != -1)
+			{
+				char *base = strrchr(buf, '/');
+				buf[n + 1] = '\0';
+				if (base == NULL)
+				{
+					base = buf;
+				} else {
+					base += 1;
+				}
+				
+				if (strcmp(base, "gdb") == 0)
+				{
+					debugged = yes;
+				}
+			}
+			free(name);
+		}
+	}
+
+	return debugged == yes;
+}
+
+bool LLAppViewerLinux::initLogging()
+{
+	// Remove the last stack trace, if any
+	std::string old_stack_file =
+		gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
+	LLFile::remove(old_stack_file.c_str());
+
+	return LLAppViewer::initLogging();
+}
+
+std::string LLAppViewerLinux::generateSerialNumber()
+{
+	char serial_md5[MD5HEX_STR_SIZE];
+	serial_md5[0] = 0;
+
+	// TODO
+
+	return serial_md5;
+}
diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h
new file mode 100644
index 0000000000000000000000000000000000000000..f38a64a8cdcbcbd0f9cc4399c979ead98fe99f8d
--- /dev/null
+++ b/indra/newview/llappviewerlinux.h
@@ -0,0 +1,59 @@
+/**
+ * @file llappviewerlinux.h
+ * @brief The LLAppViewerLinux class declaration
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */ 
+
+#ifndef LL_LLAPPVIEWERLINUX_H
+#define LL_LLAPPVIEWERLINUX_H
+
+#ifndef LL_LLAPPVIEWER_H
+#include "llappviewer.h"
+#endif
+
+class LLAppViewerLinux : public LLAppViewer
+{
+public:
+	LLAppViewerLinux();
+	virtual ~LLAppViewerLinux();
+
+	//
+	// Main application logic
+	//
+	virtual bool init();			// Override to do application initialization
+	std::string generateSerialNumber();
+
+protected:
+	virtual bool beingDebugged();
+
+	virtual void handleCrashReporting();
+
+	virtual bool initLogging();
+};
+
+#endif // LL_LLAPPVIEWERLINUX_H
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..63e7a6b129b492a427a4e85aee580c21891637c9
--- /dev/null
+++ b/indra/newview/llappviewermacosx.cpp
@@ -0,0 +1,388 @@
+/**
+ * @file llappviewermacosx.cpp
+ * @brief The LLAppViewerWin32 class definitions
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */ 
+
+#include "llviewerprecompiledheaders.h"
+
+#if !defined LL_DARWIN
+	#error "Use only with Mac OS X"
+#endif
+
+#include "llappviewermacosx.h"
+#include "llmemtype.h"
+
+#include "llviewernetwork.h"
+#include "llmd5.h"
+#include "llurlsimstring.h"
+#include "llfloaterworldmap.h"
+#include <Carbon/Carbon.h>
+
+
+int main( int argc, char **argv ) 
+{
+	LLMemType mt1(LLMemType::MTYPE_STARTUP);
+
+#if LL_SOLARIS && defined(__sparc)
+	asm ("ta\t6");		 // NOTE:  Make sure memory alignment is enforced on SPARC
+#endif
+
+	// Set the working dir to <bundle>/Contents/Resources
+	(void) chdir(gDirUtilp->getAppRODataDir().c_str());
+
+	LLAppViewerMacOSX* viewer_app_ptr = new LLAppViewerMacOSX();
+
+	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
+
+	bool ok = viewer_app_ptr->tempStoreCommandOptions(argc, argv);
+	if(!ok)
+	{
+		llwarns << "Unable to parse command line." << llendl;
+		return -1;
+	}
+
+	ok = viewer_app_ptr->init();
+	if(!ok)
+	{
+		llwarns << "Application init failed." << llendl;
+		return -1;
+	}
+
+		// Run the application main loop
+	if(!LLApp::isQuitting()) 
+	{
+		viewer_app_ptr->mainLoop();
+	}
+
+	if (!LLApp::isError())
+	{
+		//
+		// We don't want to do cleanup here if the error handler got called -
+		// the assumption is that the error handler is responsible for doing
+		// app cleanup if there was a problem.
+		//
+		viewer_app_ptr->cleanup();
+	}
+	delete viewer_app_ptr;
+	viewer_app_ptr = NULL;
+	return 0;
+}
+
+LLAppViewerMacOSX::LLAppViewerMacOSX()
+{
+}
+
+LLAppViewerMacOSX::~LLAppViewerMacOSX()
+{
+}
+
+bool LLAppViewerMacOSX::init()
+{
+	return LLAppViewer::init();
+}
+
+void LLAppViewerMacOSX::handleCrashReporting()
+{
+	// Macintosh
+	LLString command_str;
+	command_str = "crashreporter.app/Contents/MacOS/crashreporter ";
+	command_str += "-user ";
+	command_str += gGridName;
+	command_str += " &";	// This backgrounds the command so system() doesn't block until the crashreporter exits.
+	system(command_str.c_str());		/* Flawfinder: ignore */
+		
+	// Sometimes signals don't seem to quit the viewer.  
+	// Make sure we exit so as to not totally confuse the user.
+	exit(1);
+}
+
+std::string LLAppViewerMacOSX::generateSerialNumber()
+{
+	char serial_md5[MD5HEX_STR_SIZE];		// Flawfinder: ignore
+	serial_md5[0] = 0;
+
+	// JC: Sample code from http://developer.apple.com/technotes/tn/tn1103.html
+	CFStringRef serialNumber = NULL;
+	io_service_t    platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
+																 IOServiceMatching("IOPlatformExpertDevice"));
+	if (platformExpert) {
+		serialNumber = (CFStringRef) IORegistryEntryCreateCFProperty(platformExpert,
+																	 CFSTR(kIOPlatformSerialNumberKey),
+																	 kCFAllocatorDefault, 0);		
+		IOObjectRelease(platformExpert);
+	}
+	
+	if (serialNumber)
+	{
+		char buffer[MAX_STRING];		// Flawfinder: ignore
+		if (CFStringGetCString(serialNumber, buffer, MAX_STRING, kCFStringEncodingASCII))
+		{
+			LLMD5 md5( (unsigned char*)buffer );
+			md5.hex_digest(serial_md5);
+		}
+		CFRelease(serialNumber);
+	}
+
+	return serial_md5;
+}
+
+OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
+{
+	OSErr result = noErr;
+	DescType actualType;
+	char buffer[1024];		// Flawfinder: ignore
+	Size size;
+	
+	result = AEGetParamPtr (
+		messagein,
+		keyDirectObject,
+		typeCString,
+		&actualType,
+		(Ptr)buffer,
+		sizeof(buffer),
+		&size);	
+	
+	if(result == noErr)
+	{
+		// Got the URL out of the event.
+		// secondlife://
+
+		// Parse it and stash in globals.
+		LLURLSimString::setString(buffer);
+		
+		if(gFloaterWorldMap != NULL)
+		{
+			// If the viewer's already logged in, pass it along directly.
+			if (LLURLSimString::parse())
+			{
+				gFloaterWorldMap->trackURL(LLURLSimString::sInstance.mSimName,
+										   LLURLSimString::sInstance.mX,
+										   LLURLSimString::sInstance.mY,
+										   LLURLSimString::sInstance.mZ);
+				LLFloaterWorldMap::show(NULL, TRUE);
+			}
+		}
+	}
+	
+	return(result);
+}
+
+OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
+{
+	OSErr result = noErr;
+	
+	LLAppViewer::instance()->userQuit();
+	
+	return(result);
+}
+
+OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata)
+{
+	OSStatus result = eventNotHandledErr;
+	OSStatus err;
+	UInt32 evtClass = GetEventClass(event);
+	UInt32 evtKind = GetEventKind(event);
+	WindowRef window = (WindowRef)userdata;
+	
+	if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
+	{
+		HICommand cmd;
+		err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd);
+		
+		if(err == noErr)
+		{
+			switch(cmd.commandID)
+			{
+				case kHICommandOK:
+					QuitAppModalLoopForWindow(window);
+					result = noErr;
+				break;
+				
+				case kHICommandCancel:
+					QuitAppModalLoopForWindow(window);
+					result = userCanceledErr;
+				break;
+			}
+		}
+	}
+	
+	return(result);
+}
+
+OSStatus DisplayReleaseNotes(void)
+{
+	OSStatus err;
+	IBNibRef nib = NULL;
+	WindowRef window = NULL;
+	
+	err = CreateNibReference(CFSTR("SecondLife"), &nib);
+	
+	if(err == noErr)
+	{
+		CreateWindowFromNib(nib, CFSTR("Release Notes"), &window);
+	}
+		
+	if(err == noErr)
+	{
+		// Get the text view control
+		HIViewRef textView;
+		ControlID id;
+
+		id.signature = 'text';
+		id.id = 0;
+
+		LLString releaseNotesText;
+		
+		_read_file_into_string(releaseNotesText, "releasenotes.txt");		// Flawfinder: ignore
+
+		err = HIViewFindByID(HIViewGetRoot(window), id, &textView);
+		
+		if(err == noErr)
+		{
+			// Convert from the encoding used in the release notes.
+			CFStringRef str = CFStringCreateWithBytes(
+				NULL, 
+				(const UInt8*)releaseNotesText.c_str(), 
+				releaseNotesText.size(), 
+				kCFStringEncodingWindowsLatin1, 		// This matches the way the Windows version displays the release notes.
+				FALSE);
+			
+			if(str != NULL)
+			{
+				int size = CFStringGetLength(str);
+
+				if(size > 0)
+				{
+					UniChar *chars = new UniChar[size + 1];
+					CFStringGetCharacters(str, CFRangeMake(0, size), chars);
+				
+					err = TXNSetData(HITextViewGetTXNObject(textView), kTXNUnicodeTextData, chars, size * sizeof(UniChar), kTXNStartOffset, kTXNStartOffset);
+					
+					delete[] chars;
+				}
+				
+				CFRelease(str);
+			}
+			else
+			{
+				// Creating the string failed.  Probably an encoding problem.  Display SOMETHING...
+				err = TXNSetData(HITextViewGetTXNObject(textView), kTXNTextData, releaseNotesText.c_str(), releaseNotesText.size(), kTXNStartOffset, kTXNStartOffset);
+			}
+		}
+		
+		// Set the selection to the beginning of the text and scroll it into view.
+		if(err == noErr)
+		{
+			err = TXNSetSelection(HITextViewGetTXNObject(textView), kTXNStartOffset, kTXNStartOffset);
+		}
+		
+		if(err == noErr)
+		{
+			// This function returns void.
+			TXNShowSelection(HITextViewGetTXNObject(textView), false);
+		}
+	}
+
+	if(err == noErr)
+	{
+		ShowWindow(window);
+	}
+
+	if(err == noErr)
+	{
+		// Set up an event handler for the window.
+		EventHandlerRef handler = NULL;
+		EventTypeSpec handlerEvents[] = 
+		{
+			{ kEventClassCommand, kEventCommandProcess }
+		};
+
+		InstallWindowEventHandler(
+				window, 
+				NewEventHandlerUPP(simpleDialogHandler), 
+				GetEventTypeCount (handlerEvents), 
+				handlerEvents, 
+				(void*)window, 
+				&handler);
+	}
+			
+	if(err == noErr)
+	{
+		RunAppModalLoopForWindow(window);
+	}
+			
+	if(window != NULL)
+	{
+		DisposeWindow(window);
+	}
+	
+	if(nib != NULL)
+	{
+		DisposeNibReference(nib);
+	}
+
+	return(err);
+}
+
+void init_apple_menu(const char* product)
+{
+	// Load up a proper menu bar.
+	{
+		OSStatus err;
+		IBNibRef nib = NULL;
+		// NOTE: DO NOT translate or brand this string.  It's an internal name in the .nib file, and MUST match exactly.
+		err = CreateNibReference(CFSTR("SecondLife"), &nib);
+		
+		if(err == noErr)
+		{
+			// NOTE: DO NOT translate or brand this string.  It's an internal name in the .nib file, and MUST match exactly.
+			SetMenuBarFromNib(nib, CFSTR("MenuBar"));
+		}
+
+		if(nib != NULL)
+		{
+			DisposeNibReference(nib);
+		}
+	}
+	
+	// Install a handler for 'gurl' AppleEvents.  This is how secondlife:// URLs get passed to the viewer.
+	
+	if(AEInstallEventHandler('GURL', 'GURL', NewAEEventHandlerUPP(AEGURLHandler),0, false) != noErr)
+	{
+		// Couldn't install AppleEvent handler.  This error shouldn't be fatal.
+		llinfos << "Couldn't install 'GURL' AppleEvent handler.  Continuing..." << llendl;
+	}
+
+	// Install a handler for 'quit' AppleEvents.  This makes quitting the application from the dock work.
+	if(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler),0, false) != noErr)
+	{
+		// Couldn't install AppleEvent handler.  This error shouldn't be fatal.
+		llinfos << "Couldn't install Quit AppleEvent handler.  Continuing..." << llendl;
+	}
+}
diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c61e5a01cd16cf1f0578144be2b2f891b099fef
--- /dev/null
+++ b/indra/newview/llappviewermacosx.h
@@ -0,0 +1,56 @@
+/**
+ * @file llappviewermacosx.h
+ * @brief The LLAppViewerMacOSX class declaration
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */ 
+
+#ifndef LL_LLAPPVIEWERMACOSX_H
+#define LL_LLAPPVIEWERMACOSX_H
+
+#ifndef LL_LLAPPVIEWER_H
+#include "llappviewer.h"
+#endif
+
+class LLAppViewerMacOSX : public LLAppViewer
+{
+public:
+	LLAppViewerMacOSX();
+	virtual ~LLAppViewerMacOSX();
+
+	//
+	// Main application logic
+	//
+	virtual bool init();			// Override to do application initialization
+
+
+protected:
+	virtual void handleCrashReporting(); 
+	std::string generateSerialNumber();
+};
+
+#endif // LL_LLAPPVIEWERMACOSX_H
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d7a6690fc37f530d04a54701adc1b550cebba54
--- /dev/null
+++ b/indra/newview/llappviewerwin32.cpp
@@ -0,0 +1,454 @@
+/**
+ * @file llappviewerwin32.cpp
+ * @brief The LLAppViewerWin32 class definitions
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */ 
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llappviewerwin32.h"
+
+#include "llmemtype.h"
+
+#include "llwindowwin32.cpp" // *FIX: for setting gIconResource.
+#include "res/resource.h" // *FIX: for setting gIconResource.
+
+#include <fcntl.h>		//_O_APPEND
+#include <io.h>			//_open_osfhandle()
+#include <errorrep.h>	// for AddERExcludedApplicationA()
+#include <process.h>	// _spawnl()
+#include <tchar.h>		// For TCHAR support
+
+#include "llviewercontrol.h"
+#include "lldxhardware.h"
+
+#include "llweb.h"
+#include "llsecondlifeurls.h"
+
+#include "llwindebug.h"
+
+#include "llviewernetwork.h"
+#include "llmd5.h"
+
+void fill_args(int& argc, char** argv, const S32 max_args, LPSTR cmd_line)
+{
+	char *token = NULL;
+	if( cmd_line[0] == '\"' )
+	{
+		// Exe name is enclosed in quotes
+		token = strtok( cmd_line, "\"" );
+		argv[argc++] = token;
+		token = strtok( NULL, " \t," );
+	}
+	else
+	{
+		// Exe name is not enclosed in quotes
+		token = strtok( cmd_line, " \t," );
+	}
+
+	while( (token != NULL) && (argc < max_args) )
+	{
+		argv[argc++] = token;
+		/* Get next token: */
+		if (*(token + strlen(token) + 1) == '\"')		/* Flawfinder: ignore*/
+		{
+			token = strtok( NULL, "\"");
+		}
+		else
+		{
+			token = strtok( NULL, " \t," );
+		}
+	}
+}
+
+// *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
+LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop)
+{
+	// Translate the signals/exceptions into cross-platform stuff
+	// Windows implementation
+	llinfos << "Entering Windows Exception Handler..." << llendl;
+
+	// Make sure the user sees something to indicate that the app crashed.
+	LONG retval;
+
+	if (LLApp::isError())
+	{
+		llwarns << "Got another fatal signal while in the error handler, die now!" << llendl;
+		retval = EXCEPTION_EXECUTE_HANDLER;
+		return retval;
+	}
+
+	// Generate a minidump if we can.
+	// Before we wake the error thread...
+	// Which will start the crash reporting.
+	LLWinDebug::handleException(exception_infop);
+	
+	// Flag status to error, so thread_error starts its work
+	LLApp::setError();
+
+	// Block in the exception handler until the app has stopped
+	// This is pretty sketchy, but appears to work just fine
+	while (!LLApp::isStopped())
+	{
+		ms_sleep(10);
+	}
+
+	//
+	// At this point, we always want to exit the app.  There's no graceful
+	// recovery for an unhandled exception.
+	// 
+	// Just kill the process.
+	retval = EXCEPTION_EXECUTE_HANDLER;	
+	return retval;
+}
+
+int APIENTRY WinMain(HINSTANCE hInstance,
+                     HINSTANCE hPrevInstance,
+                     LPSTR     lpCmdLine,
+                     int       nCmdShow)
+{
+	LLMemType mt1(LLMemType::MTYPE_STARTUP);
+	
+	// *FIX: global
+	gIconResource = MAKEINTRESOURCE(IDI_LL_ICON);
+
+	// In Win32, we need to generate argc and argv ourselves...
+	// Note: GetCommandLine() returns a  potentially return a LPTSTR
+	// which can resolve to a LPWSTR (unicode string).
+	// (That's why it's different from lpCmdLine which is a LPSTR.)
+	// We don't currently do unicode, so call the non-unicode version
+	// directly.
+	LPSTR cmd_line_including_exe_name = GetCommandLineA();
+
+	const S32	MAX_ARGS = 100;
+	int argc = 0;
+	char* argv[MAX_ARGS];		/* Flawfinder: ignore */
+
+	fill_args(argc, argv, MAX_ARGS, cmd_line_including_exe_name);
+
+	LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32();
+
+	// *FIX:Mani This method is poorly named, since the exception
+	// is now handled by LLApp. 
+	bool ok = LLWinDebug::setupExceptionHandler(); 
+	
+	// Actually here's the exception setup.
+	LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
+	prev_filter = SetUnhandledExceptionFilter(viewer_windows_exception_handler);
+	if (!prev_filter)
+	{
+		llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with NULL!" << llendl;
+		ok = FALSE;
+	}
+	if (prev_filter != LLWinDebug::handleException)
+	{
+		llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with " << prev_filter << "!" << llendl;
+		ok = FALSE;
+	}
+
+	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
+
+	ok = viewer_app_ptr->tempStoreCommandOptions(argc, argv);
+	if(!ok)
+	{
+		llwarns << "Unable to parse command line." << llendl;
+		return -1;
+	}
+
+	ok = viewer_app_ptr->init();
+	if(!ok)
+	{
+		llwarns << "Application init failed." << llendl;
+		return -1;
+	}
+
+		// Run the application main loop
+	if(!LLApp::isQuitting()) 
+	{
+		viewer_app_ptr->mainLoop();
+	}
+
+	if (!LLApp::isError())
+	{
+		//
+		// We don't want to do cleanup here if the error handler got called -
+		// the assumption is that the error handler is responsible for doing
+		// app cleanup if there was a problem.
+		//
+		viewer_app_ptr->cleanup();
+	}
+	delete viewer_app_ptr;
+	viewer_app_ptr = NULL;
+	return 0;
+}
+
+void LLAppViewerWin32::disableWinErrorReporting()
+{
+	const char win_xp_string[] = "Microsoft Windows XP";
+	BOOL is_win_xp = ( getOSInfo().getOSString().substr(0, strlen(win_xp_string) ) == win_xp_string );		/* Flawfinder: ignore*/
+	if( is_win_xp )
+	{
+		// Note: we need to use run-time dynamic linking, because load-time dynamic linking will fail
+		// on systems that don't have the library installed (all non-Windows XP systems)
+		HINSTANCE fault_rep_dll_handle = LoadLibrary(L"faultrep.dll");		/* Flawfinder: ignore */
+		if( fault_rep_dll_handle )
+		{
+			pfn_ADDEREXCLUDEDAPPLICATIONA pAddERExcludedApplicationA  = (pfn_ADDEREXCLUDEDAPPLICATIONA) GetProcAddress(fault_rep_dll_handle, "AddERExcludedApplicationA");
+			if( pAddERExcludedApplicationA )
+			{
+
+				// Strip the path off the name
+				const char* executable_name = gDirUtilp->getExecutableFilename().c_str();
+
+				if( 0 == pAddERExcludedApplicationA( executable_name ) )
+				{
+					U32 error_code = GetLastError();
+					llinfos << "AddERExcludedApplication() failed with error code " << error_code << llendl;
+				}
+				else
+				{
+					llinfos << "AddERExcludedApplication() success for " << executable_name << llendl;
+				}
+			}
+			FreeLibrary( fault_rep_dll_handle );
+		}
+	}
+}
+
+const S32 MAX_CONSOLE_LINES = 500;
+
+void create_console()
+{
+	int h_con_handle;
+	long l_std_handle;
+
+	CONSOLE_SCREEN_BUFFER_INFO coninfo;
+	FILE *fp;
+
+	// allocate a console for this app
+	AllocConsole();
+
+	// set the screen buffer to be big enough to let us scroll text
+	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
+	coninfo.dwSize.Y = MAX_CONSOLE_LINES;
+	SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
+
+	// redirect unbuffered STDOUT to the console
+	l_std_handle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
+	h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
+	fp = _fdopen( h_con_handle, "w" );
+	*stdout = *fp;
+	setvbuf( stdout, NULL, _IONBF, 0 );
+
+	// redirect unbuffered STDIN to the console
+	l_std_handle = (long)GetStdHandle(STD_INPUT_HANDLE);
+	h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
+	fp = _fdopen( h_con_handle, "r" );
+	*stdin = *fp;
+	setvbuf( stdin, NULL, _IONBF, 0 );
+
+	// redirect unbuffered STDERR to the console
+	l_std_handle = (long)GetStdHandle(STD_ERROR_HANDLE);
+	h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
+	fp = _fdopen( h_con_handle, "w" );
+	*stderr = *fp;
+	setvbuf( stderr, NULL, _IONBF, 0 );
+}
+
+LLAppViewerWin32::LLAppViewerWin32()
+{
+}
+
+LLAppViewerWin32::~LLAppViewerWin32()
+{
+}
+
+bool LLAppViewerWin32::init()
+{
+	// Platform specific initialization.
+	
+	// Turn off Windows XP Error Reporting
+	// (Don't send our data to Microsoft--at least until we are Logo approved and have a way
+	// of getting the data back from them.)
+	//
+	llinfos << "Turning off Windows error reporting." << llendl;
+	disableWinErrorReporting();
+
+	return LLAppViewer::init();
+}
+
+bool LLAppViewerWin32::cleanup()
+{
+	bool result = LLAppViewer::cleanup();
+
+	gDXHardware.cleanup();
+
+	return result;
+}
+
+bool LLAppViewerWin32::initWindow()
+{
+	// pop up debug console if necessary
+	if (gUseConsole && gSavedSettings.getBOOL("ShowConsoleWindow"))
+	{
+		create_console();
+	}
+
+	return LLAppViewer::initWindow();
+}
+
+void write_debug_callback(const char* str)
+{
+	LLAppViewer::instance()->writeDebug(str);
+}
+
+bool LLAppViewerWin32::initHardwareTest()
+{
+	//
+	// Do driver verification and initialization based on DirectX
+	// hardware polling and driver versions
+	//
+	if (gProbeHardware)
+	{
+		BOOL vram_only = !gSavedSettings.getBOOL("ProbeHardwareOnStartup");
+
+		LLSplashScreen::update("Detecting hardware...");
+
+		llinfos << "Attempting to poll DirectX for hardware info" << llendl;
+		gDXHardware.setWriteDebugFunc(write_debug_callback);
+		BOOL probe_ok = gDXHardware.getInfo(vram_only);
+
+		if (!probe_ok
+			&& gSavedSettings.getWarning("AboutDirectX9"))
+		{
+			llinfos << "DirectX probe failed, alerting user." << llendl;
+
+			// Warn them that runnin without DirectX 9 will
+			// not allow us to tell them about driver issues
+			std::ostringstream msg;
+			msg << 
+				LLAppViewer::instance()->getSecondLifeTitle() << " is unable to detect DirectX 9.0b or greater.\n"
+				"\n" <<
+				LLAppViewer::instance()->getSecondLifeTitle() << " uses DirectX to detect hardware and/or\n"
+				"outdated drivers that can cause stability problems,\n"
+				"poor performance and crashes.  While you can run\n" <<
+				LLAppViewer::instance()->getSecondLifeTitle() << " without it, we highly recommend running\n"
+				"with DirectX 9.0b\n"
+				"\n"
+				"Do you wish to continue?\n";
+			S32 button = OSMessageBox(
+				msg.str().c_str(),
+				"Warning",
+				OSMB_YESNO);
+			if (OSBTN_NO== button)
+			{
+				llinfos << "User quitting after failed DirectX 9 detection" << llendl;
+				LLWeb::loadURLExternal(DIRECTX_9_URL);
+				return false;
+			}
+			gSavedSettings.setWarning("AboutDirectX9", FALSE);
+		}
+		llinfos << "Done polling DirectX for hardware info" << llendl;
+
+		// Only probe once after installation
+		gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
+
+		// Disable so debugger can work
+		std::ostringstream splash_msg;
+		splash_msg << "Loading " << LLAppViewer::instance()->getSecondLifeTitle() << "...";
+
+		LLSplashScreen::update(splash_msg.str().c_str());
+	}
+
+	if (!LLWinDebug::setupExceptionHandler())
+	{
+		llwarns << " Someone took over my exception handler (post hardware probe)!" << llendl;
+	}
+
+	gGLManager.mVRAM = gDXHardware.getVRAM();
+	llinfos << "Detected VRAM: " << gGLManager.mVRAM << llendl;
+
+	return true;
+}
+
+void LLAppViewerWin32::handleCrashReporting()
+{
+	// Windows only behaivor. Spawn win crash reporter.
+	std::string exe_path = gDirUtilp->getAppRODataDir();
+	exe_path += gDirUtilp->getDirDelimiter();
+	exe_path += "win_crash_logger.exe";
+
+	std::string arg_string = "-user ";
+	arg_string += gGridName;
+
+	switch(getCrashBehavior())
+	{
+	case CRASH_BEHAVIOR_ASK:
+	default:
+		arg_string += " -dialog ";
+		_spawnl(_P_NOWAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL);
+		break;
+
+	case CRASH_BEHAVIOR_ALWAYS_SEND:
+		_spawnl(_P_NOWAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL);
+		break;
+
+	case CRASH_BEHAVIOR_NEVER_SEND:
+		break;
+	}
+}
+
+std::string LLAppViewerWin32::generateSerialNumber()
+{
+	char serial_md5[MD5HEX_STR_SIZE];		// Flawfinder: ignore
+	serial_md5[0] = 0;
+
+	DWORD serial = 0;
+	DWORD flags = 0;
+	BOOL success = GetVolumeInformation(
+			L"C:\\",
+			NULL,		// volume name buffer
+			0,			// volume name buffer size
+			&serial,	// volume serial
+			NULL,		// max component length
+			&flags,		// file system flags
+			NULL,		// file system name buffer
+			0);			// file system name buffer size
+	if (success)
+	{
+		LLMD5 md5;
+		md5.update( (unsigned char*)&serial, sizeof(DWORD));
+		md5.finalize();
+		md5.hex_digest(serial_md5);
+	}
+	else
+	{
+		llwarns << "GetVolumeInformation failed" << llendl;
+	}
+	return serial_md5;
+}
\ No newline at end of file
diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h
new file mode 100644
index 0000000000000000000000000000000000000000..23e733761821d612b24e0d98a974503023d99c76
--- /dev/null
+++ b/indra/newview/llappviewerwin32.h
@@ -0,0 +1,63 @@
+/**
+ * @file llappviewerwin32.h
+ * @brief The LLAppViewerWin32 class declaration
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */ 
+
+#ifndef LL_LLAPPVIEWERWIN32_H
+#define LL_LLAPPVIEWERWIN32_H
+
+#ifndef LL_LLAPPVIEWER_H
+#include "llappviewer.h"
+#endif
+
+class LLAppViewerWin32 : public LLAppViewer
+{
+public:
+	LLAppViewerWin32();
+	virtual ~LLAppViewerWin32();
+
+	//
+	// Main application logic
+	//
+	virtual bool init(); // Override to do application initialization
+	virtual bool cleanup();
+
+protected:
+	virtual bool initWindow(); // Initialize the viewer's window.
+	virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.
+	virtual void handleCrashReporting(); 
+
+	std::string generateSerialNumber();
+
+private:
+	void disableWinErrorReporting();
+
+};
+
+#endif // LL_LLAPPVIEWERWIN32_H
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 866fa34038171b8bedf456c1d54c5bbc12b1827e..c3c892a572292fef5d0d3488246259259d930f5c 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -52,7 +52,6 @@
 #include "llviewerobjectlist.h"
 #include "llviewermenufile.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
 
 void dialog_refresh_all();
 
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index b80c2bb5e3affc4e6e6356411e8f7280fca5b54b..6d0244e55e455214bcefbf106adc1bf44fdf217c 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -466,7 +466,7 @@ void LLAvatarTracker::findAgent()
 	msg->nextBlockFast(_PREHASH_AgentBlock);
 	msg->addUUIDFast(_PREHASH_Hunter, gAgentID);
 	msg->addUUIDFast(_PREHASH_Prey, mTrackingData->mAvatarID);
-	msg->addU32Fast(_PREHASH_SpaceIP, 0); // will get filled in by userserver
+	msg->addU32Fast(_PREHASH_SpaceIP, 0); // will get filled in by simulator
 	msg->nextBlockFast(_PREHASH_LocationBlock);
 	const F64 NO_LOCATION = 0.0;
 	msg->addF64Fast(_PREHASH_GlobalX, NO_LOCATION);
diff --git a/indra/newview/llclassifiedinfo.cpp b/indra/newview/llclassifiedinfo.cpp
index a49af234266f65d38918ebb2575de39c58eceeb9..28d5f506c9090a758ef39c6b2e8cd13ae1b955d6 100644
--- a/indra/newview/llclassifiedinfo.cpp
+++ b/indra/newview/llclassifiedinfo.cpp
@@ -32,7 +32,6 @@
 #include "llviewerprecompiledheaders.h"
 #include "llclassifiedinfo.h"
 
-#include "viewer.h"	// for gPacificDaylightTime
 #include "lluuid.h"
 
 LLClassifiedInfo::cat_map LLClassifiedInfo::sCategories;
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index 1e97df0b8b9cb07b51d82cf779fef5a899c31fff..eeb970e38ba61c3f9af663ba1b5427fc8b4c96b8 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -44,8 +44,7 @@
 #include "lllineeditor.h"
 #include "llviewchildren.h"
 #include "llxmlrpctransaction.h"
-#include "viewer.h"
-
+#include "llappviewer.h"
 
 
 const F64 CURRENCY_ESTIMATE_FREQUENCY = 2.0;
@@ -239,7 +238,7 @@ void LLCurrencyUIManager::Impl::startTransaction(TransactionType type,
 	static std::string transactionURI;
 	if (transactionURI.empty())
 	{
-		transactionURI = getHelperURI() + "currency.php";
+		transactionURI = LLAppViewer::instance()->getHelperURI() + "currency.php";
 	}
 
 	delete mTransaction;
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index a63c687633c467465514f9356bbf10daa0e668dd..367293929df6041e5123e1e8a330251763f54532 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -32,7 +32,6 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "lldirpicker.h"
-//#include "viewer.h"
 //#include "llviewermessage.h"
 #include "llworld.h"
 #include "llviewerwindow.h"
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index c10c49cd2cd76ca775a5b6e6391d210cb1a1d4fc..52082ad5b5d14bfae4c334148ad2e117b64f2a1e 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -48,6 +48,7 @@
 #include "llstat.h"
 #include "llviewerobject.h"
 #include "llrect.h"
+#include "llappviewer.h" // for gFrameTimeSeconds
 
 class LLCamera;
 class LLDrawPool;
@@ -59,8 +60,6 @@ class LLSpatialPartition;
 class LLVOVolume;
 class LLViewerImage;
 
-extern F32 gFrameTimeSeconds;
-
 // Can have multiple silhouettes for each object
 const U32 SILHOUETTE_HIGHLIGHT = 0;
 
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 67a379d04d323df35f425d64fd9e94454e250244..9df9c115316c672e2f2e058cf1834e2d9525211c 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -45,13 +45,13 @@
 #include "noise.h"
 #include "pipeline.h"
 #include "llglslshader.h"
+#include "llappviewer.h"
 
 static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
 static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
 static U32 sShaderLevel = 0;
 static LLGLSLShader* sVertexProgram = NULL;
 
-extern F32 gFrameDTClamped;
 extern BOOL gUseGLPick;
 
 F32 CLOTHING_GRAVITY_EFFECT = 0.7f;
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 54a33f27a0754df217ebc9867acaede96560a6ce..4a7760f15cd53993dd6eb88e96f1a233cf47d689 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -50,7 +50,6 @@
 #include "llvowater.h"
 #include "llworld.h"
 #include "pipeline.h"
-#include "viewer.h"			// gSunTextureID, gMoonTextureID
 #include "llglslshader.h"
 
 const LLUUID WATER_TEST("2bfd3884-7e27-69b9-ba3a-3e673f680004");
diff --git a/indra/newview/lleventinfo.cpp b/indra/newview/lleventinfo.cpp
index 17b33f127c878f7be7c770a603d71d743908c814..0e698917316c1a082ca2cb7d66f2fcc21152ddf5 100644
--- a/indra/newview/lleventinfo.cpp
+++ b/indra/newview/lleventinfo.cpp
@@ -32,7 +32,7 @@
 #include "llviewerprecompiledheaders.h"
 #include "lleventinfo.h"
 
-#include "viewer.h"	// for gPacificDaylightTime
+#include "llappviewer.h"	// for gPacificDaylightTime
 #include "lluuid.h"
 #include "message.h"
 
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 424f47e9e4d3abc91213922f436799ef9978e58d..ee9177c18dff597451470fa02cdcef888dcd9d73 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -40,7 +40,7 @@
 #include "llmath.h"
 #include "llfontgl.h"
 
-#include "viewer.h"
+#include "llappviewer.h"
 #include "llviewerimagelist.h"
 #include "llui.h"
 #include "llviewercontrol.h"
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 6b6eacdefacddf355bf217dd5fadf3474a22bef6..1bcd1e1ab4a75fafd85a1b5dd88f3f519e32656b 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -58,8 +58,6 @@
 //
 extern LLMemoryInfo gSysMemory;
 extern LLCPUInfo gSysCPU;
-extern void write_debug(const char *str);
-extern void write_debug(const std::string& str);
 
 #if LL_DARWIN
 const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
@@ -493,8 +491,6 @@ void LLFeatureManager::initGraphicsFeatureMasks()
 	}
 }
 
-extern LLOSInfo gSysOS;
-
 void LLFeatureManager::applyRecommendedFeatures()
 {
 	// see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt
diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp
index 0782586ef2d2f36283e5b586ff86ae833b63ebe8..2772a134166e151e5245577d8e31f7e41025ac0e 100644
--- a/indra/newview/llfirstuse.cpp
+++ b/indra/newview/llfirstuse.cpp
@@ -41,7 +41,7 @@
 #include "llfloatervoicewizard.h"
 #include "llviewercontrol.h"
 #include "llui.h"
-#include "viewer.h"
+#include "llappviewer.h"
 
 // static
 std::set<LLString> LLFirstUse::sConfigVariables;
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 460b719094096d17bc42c1f0c9a32ed0883c7050..01e529078f76b7f99123c12fd663c1d10875571a 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -47,7 +47,7 @@
 #include "llversionviewer.h"
 #include "llviewerbuild.h"
 #include "llvieweruictrlfactory.h"
-#include "viewer.h"	// for gViewerDigest
+#include "llappviewer.h" 
 
 #if LL_LIBXUL_ENABLED
 #include "llmozlib.h"
@@ -57,7 +57,6 @@
 
 extern LLCPUInfo gSysCPU;
 extern LLMemoryInfo gSysMemory;
-extern LLOSInfo gSysOS;
 extern U32 gPacketsIn;
 
 ///----------------------------------------------------------------------------
@@ -78,13 +77,13 @@ LLFloaterAbout::LLFloaterAbout()
 
 	// Support for changing product name.
 	LLString title("About ");
-	title += gSecondLife;
+	title += LLAppViewer::instance()->getSecondLifeTitle();
 	setTitle(title);
 
 	LLString support;
 
 	// Version string
-	LLString version = gSecondLife
+	LLString version = LLAppViewer::instance()->getSecondLifeTitle()
 		+ llformat(" %d.%d.%d (%d) %s %s (%s)",
 				   LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VIEWER_BUILD,
 				   __DATE__, __TIME__,
@@ -133,7 +132,7 @@ LLFloaterAbout::LLFloaterAbout()
 	support.append(mem_text);
 
 	support.append("OS Version: ");
-	support.append( gSysOS.getOSString().c_str() );
+	support.append( LLAppViewer::instance()->getOSInfo().getOSString().c_str() );
 	support.append("\n");
 
 	support.append("Graphics Card Vendor: ");
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 71c221775e89ffdc512eb85e1342f0e2fe67f4a2..693ffe091b1f1bc18668af9f42bf57d5dbf51681 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -60,7 +60,6 @@
 #include "llviewermenufile.h"	// upload_new_resource()
 #include "llvoavatar.h"
 #include "pipeline.h"
-#include "viewer.h"
 #include "llvieweruictrlfactory.h"
 
 S32 LLFloaterAnimPreview::sUploadAmount = 10;
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index bc00565a28dad30072c1a3ed4cba4e2366f218d0..e044ead818d4e0f3441ba7b14b2389ba9d2919b8 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -50,7 +50,8 @@
 #include "llviewerregion.h"
 #include "llvieweruictrlfactory.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
+#include "llviewerdisplay.h"
+#include "llviewercontrol.h"
 #include "llui.h"
 
 ///----------------------------------------------------------------------------
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 50f7387777e353f8d36656ae55d3cb0ef9baf35c..a2ea8c2794e6d5132e4f07e842ff9ca279d69b62 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -42,7 +42,7 @@
 #include "llscrolllistctrl.h"
 #include "lltextbox.h"
 #include "llvieweruictrlfactory.h"
-#include "viewer.h"
+#include "llagent.h"
 
 const S32 MIN_WIDTH = 200;
 const S32 MIN_HEIGHT = 340;
@@ -265,13 +265,13 @@ void LLFloaterAvatarPicker::find()
 
 	msg->newMessage("AvatarPickerRequest");
 	msg->nextBlock("AgentData");
-	msg->addUUID("AgentID", agent_get_id());
-	msg->addUUID("SessionID", agent_get_session_id());
+	msg->addUUID("AgentID", gAgent.getID());
+	msg->addUUID("SessionID", gAgent.getSessionID());
 	msg->addUUID("QueryID", mQueryID);	// not used right now
 	msg->nextBlock("Data");
 	msg->addString("Name", text);
 
-	agent_send_reliable_message();
+	gAgent.sendReliableMessage();
 
 	if (mListNames)
 	{
@@ -309,7 +309,7 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
 	msg->getUUID("AgentData", "QueryID", query_id);
 
 	// Not for us
-	if (agent_id != agent_get_id()) return;
+	if (agent_id != gAgent.getID()) return;
 
 	// Dialog already closed
 	LLFloaterAvatarPicker *self = sInstance;
diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp
index e891bbe203d67fc3ccfe67f04617c557926c5003..abae92a854305e986be6431f05fdb1e6a563bb4a 100644
--- a/indra/newview/llfloaterbump.cpp
+++ b/indra/newview/llfloaterbump.cpp
@@ -37,7 +37,7 @@
 #include "llscrolllistctrl.h"
 
 #include "llvieweruictrlfactory.h"
-#include "viewer.h"		// gPacificDaylightTime
+#include "llappviewer.h"		// gPacificDaylightTime
 
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index a7233c310ad355c27f5052648dda8de5cc98dc77..4b5bb3548b20193a63eedcf2c134e146121b9524 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -43,7 +43,7 @@
 #include "llvieweruictrlfactory.h"
 #include "llweb.h"
 #include "llwindow.h"
-#include "viewer.h"
+#include "llappviewer.h"
 
 static const S32 STANDARD_BUY_AMOUNT = 1000;
 static const S32 MINIMUM_BALANCE_AMOUNT = 0;
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 9ae634c76fc6cf462a098e6f92504171387aa28e..12722b6d9544fd48a10bf810aa6d582b75885e6f 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -62,7 +62,7 @@
 #include "llwindow.h"
 #include "llworld.h"
 #include "llxmlrpctransaction.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "roles_constants.h"
 
 // NOTE: This is duplicated in lldatamoney.cpp ...
@@ -847,7 +847,7 @@ void LLFloaterBuyLandUI::startTransaction(TransactionType type,
 	static std::string transaction_uri;
 	if (transaction_uri.empty())
 	{
-		transaction_uri = getHelperURI() + "landtool.php";
+		transaction_uri = LLAppViewer::instance()->getHelperURI() + "landtool.php";
 	}
 	
 	const char* method;
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 03e3a2e967ce92a51a3d8337decc94a41a1bcc7a..324da688f8cd8cb5fbd765dd2a3460ebd4338bd9 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -46,7 +46,6 @@
 #include "v4coloru.h"
 #include "llbutton.h"
 #include "llviewercontrol.h"
-#include "viewer.h"
 #include "llvieweruictrlfactory.h"
 #include "llviewerwindow.h"
 #include "llgl.h"
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index c24d435132c61b1753029e1505d7c36aa08e8a17..53779b697095e2a83f8888f8d8faa95c943cdb0d 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -51,7 +51,6 @@
 #include "llviewerwindow.h"
 #include "llvoavatar.h"
 #include "pipeline.h"
-#include "viewer.h"
 #include "llvieweruictrlfactory.h"
 #include "llviewerimagelist.h"
 
diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp
index 399d0b684c9df78c06932f64975d1fe4ae128fa1..04a5cf6a243d294f7b19bd93ff74da3089965660 100644
--- a/indra/newview/llfloaterlagmeter.cpp
+++ b/indra/newview/llfloaterlagmeter.cpp
@@ -37,7 +37,8 @@
 #include "llviewerstats.h"
 #include "llviewerimage.h"
 #include "llviewercontrol.h"
-#include "viewer.h"
+#include "llappviewer.h"
+
 #include "lltexturefetch.h"
 
 #include "llbutton.h"
@@ -189,7 +190,7 @@ void LLFloaterLagMeter::determineClient()
 		{
 			mClientCause->setText( childGetText("client_draw_distance_cause_msg") );
 		}
-		else if(gTextureFetch->getNumRequests() > 2)
+		else if(LLAppViewer::instance()->getTextureFetch()->getNumRequests() > 2)
 		{
 			mClientCause->setText( childGetText("client_texture_loading_cause_msg") );
 		}
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index a158000da5e59c1886e53c7aabbfc017ae342176..ef628be47130e1d92a4c676cd7e495d8d7771cf2 100644
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -63,7 +63,7 @@
 #include "llviewerparceloverlay.h"
 #include "llviewerregion.h"
 #include "llviewerstats.h"
-#include "viewer.h"
+#include "llurlsimstring.h"
 
 #include "llglheaders.h"
 
@@ -178,7 +178,7 @@ void LLFloaterMap::onClose(bool app_quitting)
 
 BOOL LLFloaterMap::canClose()
 {
-	return !gQuit;
+	return !LLApp::isExiting();
 }
 
 
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index cab9d37cf7949718d17fe480eff0fbc2a73f43b1..a00f512515fd7a9e5e4bca11192d91d36dcbb6b9 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -60,7 +60,6 @@
 #include "llimagej2c.h"
 #include "llvfile.h"
 #include "llvfs.h"
-#include "viewer.h"
 
 #include "llassetuploadresponders.h"
 
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index a7cd2114e015426e678a4373f9826a938237fa10..bd5438e10f521f25c322252d9d11b44a04fd2ddd 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -81,7 +81,7 @@
 #include "llselectmgr.h"
 #include "llviewerbuild.h"
 #include "llvieweruictrlfactory.h"
-#include "viewer.h"
+#include "llappviewer.h"
 
 #include "llassetuploadresponders.h"
 
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 3bc172c83094fb583cfdd2cc67e5545d8cb7ed32..71e94cce93b94e37b8f4202bd8dfcace440e2e38 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -51,7 +51,6 @@
 #include "llsliderctrl.h"
 #include "llspinctrl.h"
 #include "llviewercontrol.h"
-#include "viewer.h"
 #include "llvieweruictrlfactory.h"
 #include "llviewerstats.h"
 #include "llviewercamera.h"
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 4f8ed08a690992a1cebc251837461250e4f42e42..22581c6576ae2c75682a484e9d83baa95ccd5b0e 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -76,7 +76,6 @@
 #include "llviewerparcelmgr.h"
 #include "llviewerwindow.h"
 #include "llviewercontrol.h"
-#include "viewer.h"
 
 #include "llvieweruictrlfactory.h"
 
@@ -752,7 +751,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
 BOOL LLFloaterTools::canClose()
 {
 	// don't close when quitting, so camera will stay put
-	return !gQuit;
+	return !LLApp::isExiting();
 }
 
 // virtual
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index 9e86c92befbc194b2fca5bf2536fef3251e0a91c..20f9e1ecd40c722ec797d416128066b478010121 100644
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -38,7 +38,7 @@
 #include "llvfile.h"
 #include "lltextbox.h"
 #include "llviewertexteditor.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "llstartup.h"
 #include "message.h"
 #include "llagent.h"
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index b411bb293f2a42ef6a4d85756ec000c6acccdeb6..53b43effeced187c7cdca56a937771bc079c6444 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -84,7 +84,7 @@
 #include "llworldmapview.h"
 #include "llurl.h"
 #include "llvieweruictrlfactory.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "llmapimagetype.h"
 #include "llweb.h"
 
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index c6a27103a8f1a59327fb1f7a9428a23bbb7abb99..eb9addcf5ce702891a36d8061c70e8b9293fddba 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -66,7 +66,7 @@
 // We need these because some of the code below relies on things like
 // gAgent root folder. Remove them once the abstraction leak is fixed.
 #include "llagent.h"
-#include "viewer.h"
+#include "llappviewer.h"
 
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 3e17ecf06e28cff14a873a36c7a59574f44c8841..537cadf1d198593b33d32d905b1251e14c69776f 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -55,7 +55,6 @@
 #include "llviewermessage.h"
 #include "llvoavatar.h"
 #include "llviewerstats.h"
-#include "viewer.h"
 
 LLGestureManager gGestureManager;
 
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index da3f7aad46fb472df8b0353d76a44f6aa4164db1..ba56d70c0a7deeaa5ee4280bd28bd20361058e85 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -56,7 +56,6 @@
 #include "llviewerobjectlist.h"
 #include "lltoolselectrect.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
 #include "llcompass.h"
 #include "llsurface.h"
 #include "llwind.h"
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index d1116b66e1b11b05f3e336d4cf602f7fbd63751e..c213d268481e86cf05b025c165b426ab3bb46319 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -47,7 +47,6 @@
 #include "roles_constants.h"
 #include "lltransactiontypes.h"
 #include "llstatusbar.h"
-#include "viewer.h"
 #include "lleconomy.h"
 #include "llviewerwindow.h"
 #include "llfloaterdirectory.h"
@@ -806,8 +805,7 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		llwarns << "Got group properties reply for another agent!"
-			<< " Probably a userserver bug!" << llendl;
+		llwarns << "Got group properties reply for another agent!" << llendl;
 		return;
 	}
 
@@ -895,8 +893,7 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		llwarns << "Got group properties reply for another agent!"
-			<< " Probably a userserver bug!" << llendl;
+		llwarns << "Got group properties reply for another agent!" << llendl;
 		return;
 	}
 
@@ -963,8 +960,7 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		llwarns << "Got group properties reply for another agent!"
-			<< " Probably a userserver bug!" << llendl;
+		llwarns << "Got group properties reply for another agent!" << llendl;
 		return;
 	}
 
@@ -1031,8 +1027,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		llwarns << "Got group properties reply for another agent!"
-			<< " Probably a userserver bug!" << llendl;
+		llwarns << "Got group properties reply for another agent!" << llendl;
 		return;
 	}
 
@@ -1142,8 +1137,7 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		llwarns << "Got group properties reply for another agent!"
-			<< " Probably a userserver bug!" << llendl;
+		llwarns << "Got group properties reply for another agent!" << llendl;
 		return;
 	}
 
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 1ebe813cf7bc0d6063dd9db4206eab7e0524ffe0..1d684412315afe4233592a192f6b38ddd4036291 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -48,7 +48,6 @@
 #include "llviewerobject.h"
 #include "llvovolume.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
 #include "llstatusbar.h"
 #include "llmenugl.h"
 #include "pipeline.h"
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index b259b801162853b363518b985164a57f67cd5b73..810d3a26a164e05b2a975a02d1c1c9178bbf2e3c 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -61,7 +61,7 @@
 #include "llviewertexteditor.h"
 #include "llviewermessage.h"
 #include "llviewerstats.h"
-#include "viewer.h"
+#include "llviewercontrol.h"
 #include "llvieweruictrlfactory.h"
 #include "lllogchat.h"
 #include "llfloaterhtml.h"
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a6e2a1393d5e128c1e9e43c7053ea6c1a948ad9a..9c37f1f33329a06e0e340ed600de88a9b0fcf082 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -55,7 +55,7 @@
 #include "llimpanel.h"
 #include "llresizebar.h"
 #include "lltabcontainer.h"
-#include "viewer.h"
+#include "llviewercontrol.h"
 #include "llfloater.h"
 #include "llmutelist.h"
 #include "llresizehandle.h"
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index f777e09813a5029666ae6b4932bafacd363ed8a4..12617efb673cf10a52a25395f60983aa7005805f 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -78,7 +78,6 @@
 #include "llviewerwindow.h"
 #include "llwearable.h"
 #include "llwearablelist.h"
-#include "viewer.h"
 #include "llviewermessage.h" 
 #include "llviewerregion.h"
 #include "lltabcontainer.h"
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 4e54e7843072f1bee876ea59d401a56c38d4c82d..ca65b879bc4339bbd155a99ce84421ff930ef01d 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -47,7 +47,7 @@
 #include "llviewerinventory.h"
 #include "llviewermessage.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "lldbstrings.h"
 #include "llviewerstats.h"
 #include "llmutelist.h"
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 8620446d4abe062fe728513521b360bbb82a7a93..d89ec791f1461767e0a78e3a95eb836e5cf65007 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -32,7 +32,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "lllogchat.h"
-#include "viewer.h"
+#include "llappviewer.h"
 	
 const S32 LOG_RECALL_SIZE = 2048;
 
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 953befcd30cb5f936f992df253d203f0dd03764b..44b919aa616cc1f31ea5b0af63199482390f3c88 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -55,7 +55,6 @@
 #include "llvoavatar.h"
 #include "llworld.h"		// for gWorldPointer
 #include "llresmgr.h"
-#include "viewer.h"			// for gFPS
 #include "pipeline.h"
 #include "llglheaders.h"
 
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index fb3de3ab56daf0c55f049f6590c83fb04d9cc1dc..2e4f66c9290555ca88b77ebb4ad72028a639366c 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -60,7 +60,6 @@
 #include "llviewerwindow.h"
 #include "llworld.h"
 #include "pipeline.h"
-#include "viewer.h"
 #include "lldrawable.h"
 #include "llglheaders.h"
 
@@ -513,8 +512,6 @@ LLVector3 LLManipRotate::projectToSphere( F32 x, F32 y, BOOL* on_sphere )
 	return LLVector3( x, y, z );
 }
 
-extern U32 gFrameCount;
-
 // Freeform rotation
 void LLManipRotate::drag( S32 x, S32 y )
 {
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 1963b1a8f5372a980d950f58735caa90a391ea41..36e3f9a5e909efc54e667e976c7f32ca4808c1aa 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -61,7 +61,6 @@
 #include "llviewerwindow.h"
 #include "llvoavatar.h"
 #include "llworld.h"
-#include "viewer.h"
 #include "llui.h"
 #include "pipeline.h"
 
diff --git a/indra/newview/llmemoryview.cpp b/indra/newview/llmemoryview.cpp
index 53582ac54b0ecd859a0fa08bea156250c9cb3561..a698c53f7f9b4de0345566e37e85d6b02e660efa 100644
--- a/indra/newview/llmemoryview.cpp
+++ b/indra/newview/llmemoryview.cpp
@@ -41,7 +41,6 @@
 #include "llfontgl.h"
 #include "llmemtype.h"
 
-#include "viewer.h"
 #include "llui.h"
 #include "llviewercontrol.h"
 #include "llstat.h"
diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp
index 92c7832e4fc9695f891c4ad0e016056fbf81211d..68bbe5309097d3d68a38092783c36484b76d4ef9 100644
--- a/indra/newview/llmenucommands.cpp
+++ b/indra/newview/llmenucommands.cpp
@@ -67,7 +67,6 @@
 #include "llviewerwindow.h"
 #include "llworld.h"
 #include "llworldmap.h"
-#include "viewer.h"
 #include "llfocusmgr.h"
 
 void handle_track_avatar(const LLUUID& agent_id, const std::string& name)
diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp
index d69968d7ea0bf182585284c139d1638b50a63cdb..81e677433b275196be5f81caf3b2ad3d31775e25 100644
--- a/indra/newview/llmorphview.cpp
+++ b/indra/newview/llmorphview.cpp
@@ -49,7 +49,6 @@
 #include "llvoavatar.h"
 #include "llviewerwindow.h"
 #include "pipeline.h"
-#include "viewer.h"
 
 LLMorphView *gMorphView = NULL;
 
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index e115f10d061f12219ca3ce9e57eef1534a0d9fac..4f1d7bb514182e58fa77d5512f49faa10f9a444e 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -39,7 +39,7 @@
 // Viewer includes
 #include "llagent.h"
 #include "llcallbacklist.h"
-#include "viewer.h"
+#include "llviewercontrol.h"
 #include "llfontgl.h"
 #include "llbutton.h"
 #include "llviewerwindow.h"
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 118fd4225b4c6ab0cbec6c13fd954b4e1b479b2d..f36e282ea0b8f5061e03e3254daed8ff4bc7ee9b 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -61,7 +61,6 @@
 #include "llfloatermute.h"
 #include "llviewergenericmessage.h"	// for gGenericDispatcher
 #include "llviewerwindow.h"
-#include "viewer.h"
 #include "llworld.h" //for particle system banning
 
 LLMuteList* gMuteListp = NULL;
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index edf2567c8c827e6bf31844d8af6c07185f47c27f..c3128652fef08734fdad467de6a1b69bb9a60a03 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -65,7 +65,7 @@
 #include "llvoavatar.h"
 #include "llworld.h"
 #include "llworldmapview.h"		// shared draw code
-#include "viewer.h"				// Only for constants!
+#include "llappviewer.h"				// Only for constants!
 
 #include "llglheaders.h"
 
diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp
index bcdb6c63f4b13f22a3d239ac208d797a801461a6..15c993e5525e0163046558a13114576d6803d6cd 100644
--- a/indra/newview/lloverlaybar.cpp
+++ b/indra/newview/lloverlaybar.cpp
@@ -57,7 +57,6 @@
 #include "llvoavatar.h"
 #include "llvoiceremotectrl.h"
 #include "llwebbrowserctrl.h"
-#include "viewer.h"
 
 //
 // Globals
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index dc2f14fcef61f412de4d160eccfe7054476cd608..706e05328cdca6024fe9aedf885fbae8ba7669b7 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -69,6 +69,7 @@
 #include "lltooldraganddrop.h"
 #include "lluiconstants.h"
 #include "llvoavatar.h"
+#include "llviewercontrol.h"
 #include "llviewermenu.h"		// *FIX: for is_agent_friend()
 #include "llviewergenericmessage.h"	// send_generic_message
 #include "llviewerobjectlist.h"
@@ -76,7 +77,6 @@
 #include "llviewborder.h"
 #include "llweb.h"
 #include "llinventorymodel.h"
-#include "viewer.h"				// for gUserServer
 #include "roles_constants.h"
 
 #define	kArraySize( _kArray ) ( sizeof( (_kArray) ) / sizeof( _kArray[0] ) )
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index cb75f1606ebe3acb80ae6bbb613e8ff1ef593a6d..821eaf1a72bff13737fda783ed26d291e278b66c 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -66,7 +66,7 @@
 #include "llviewergenericmessage.h"	// send_generic_message
 #include "llviewerregion.h"
 #include "llviewerwindow.h"	// for window width, height
-#include "viewer.h"	// app_abort_quit()
+#include "llappviewer.h"	// abortQuit()
 
 const S32 MINIMUM_PRICE_FOR_LISTING = 50;	// L$
 
@@ -314,7 +314,7 @@ void LLPanelClassified::saveCallback(S32 option, void* data)
 
 		case 2: // Cancel
 		default:
-			app_abort_quit();
+            LLAppViewer::instance()->abortQuit();
 			break;
 	}
 }
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 50ff7bd9eb9e08c26b6f81f9d00cf682f49eb2cc..fa7cdfbc97e7593d3d3789d999c35b159a446cd7 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -65,7 +65,6 @@
 #include "lltoolmgr.h"
 #include "lltoolcomp.h"
 #include "llpanelinventory.h"
-#include "viewer.h"
 
 //
 // Imported globals
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 99744c96535f2f51c67a5ea6d0c63882e72cde2e..76fbada56235d5da6bc3dd18517b226e250b5bfd 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -44,7 +44,7 @@
 #include "llviewermessage.h"
 #include "llvieweruictrlfactory.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
+#include "llappviewer.h"
 
 // static
 void* LLPanelGroupTab::createTab(void* data)
@@ -530,7 +530,7 @@ void LLPanelGroup::handleNotifyCallback(S32 option)
 	default:
 		// Do nothing.  The user is canceling the action.
 		// If we were quitting, we didn't really mean it.
-		app_abort_quit();
+		LLAppViewer::instance()->abortQuit();
 		break;
 	}
 }
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 4c12aa2218035f0cda0cf716559b6f2ef4cae67e..01529907981aed55793675595560ef974080f448 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -1115,8 +1115,7 @@ void LLPanelGroupLandMoney::processGroupAccountDetailsReply(LLMessageSystem* msg
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		llwarns << "Got group L$ history reply for another agent!"
-			<< " Probably a userserver bug!" << llendl;
+		llwarns << "Got group L$ history reply for another agent!" << llendl;
 		return;
 	}
 
@@ -1292,8 +1291,7 @@ void LLPanelGroupLandMoney::processGroupAccountTransactionsReply(LLMessageSystem
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		llwarns << "Got group L$ history reply for another agent!"
-			<< " Probably a userserver bug!" << llendl;
+		llwarns << "Got group L$ history reply for another agent!" << llendl;
 		return;
 	}
 
@@ -1463,8 +1461,7 @@ void LLPanelGroupLandMoney::processGroupAccountSummaryReply(LLMessageSystem* msg
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
 	if (gAgent.getID() != agent_id)
 	{
-		llwarns << "Got group L$ history reply for another agent!"
-			<< " Probably a userserver bug!" << llendl;
+		llwarns << "Got group L$ history reply for another agent!" << llendl;
 		return;
 	}
 
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 292f5c36f8284481fc393964130127d728cf27dc..fe0717552904e70a73a196421cde887569920f51 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -61,7 +61,8 @@
 #include "llviewernetwork.h"
 #include "llviewerwindow.h"			// to link into child list
 #include "llnotify.h"
-#include "viewer.h"					// for gHideLinks
+#include "llappviewer.h"					// for gHideLinks
+#include "llurlsimstring.h"
 #include "llvieweruictrlfactory.h"
 #include "llhttpclient.h"
 #include "llweb.h"
@@ -72,6 +73,7 @@
 
 #include "llglheaders.h"
 
+
 const S32 BLACK_BORDER_HEIGHT = 160;
 const S32 MAX_PASSWORD = 16;
 
@@ -155,7 +157,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 	mLogoImage = gImageList.getImage("startup_logo.tga", LLUUID::null, MIPMAP_FALSE, TRUE);
 
 	gUICtrlFactory->buildPanel(this, "panel_login.xml");
-	setRect(rect);
+	//setRect(rect);
 	reshape(rect.getWidth(), rect.getHeight());
 
 	childSetPrevalidate("first_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
@@ -214,26 +216,17 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 
 	childSetAction("quit_btn", onClickQuit, this);
 
-	LLTextBox* text = LLUICtrlFactory::getTextBoxByName(this, "version_text");
-	if (text)
+	LLTextBox* version_text = LLUICtrlFactory::getTextBoxByName(this, "version_text");
+	if (version_text)
 	{
 		LLString version = llformat("%d.%d.%d (%d)",
 			LL_VERSION_MAJOR,
 			LL_VERSION_MINOR,
 			LL_VERSION_PATCH,
 			LL_VIEWER_BUILD );
-		text->setText(version);
-		text->setClickedCallback(onClickVersion);
-		text->setCallbackUserData(this);
-
-		// HACK to move to the lower-right of the window
-		// replace/remove this logic when we have dynamic layouts
-		S32 right = getRect().mRight;
-		LLRect r = text->getRect();
-		const S32 PAD = 2;
-		r.setOriginAndSize( right - r.getWidth() - PAD, PAD, 
-			r.getWidth(), r.getHeight() );
-		text->setRect(r);
+		version_text->setText(version);
+		version_text->setClickedCallback(onClickVersion);
+		version_text->setCallbackUserData(this);
 	}
 
 	LLTextBox* channel_text = LLUICtrlFactory::getTextBoxByName(this, "channel_text");
@@ -242,25 +235,14 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 		channel_text->setText(gChannelName);
 		channel_text->setClickedCallback(onClickVersion);
 		channel_text->setCallbackUserData(this);
-
-		// HACK to move to the right of the window, above the version string,
-		// replace/remove this logic when we have dynamic layouts
-		S32 right = getRect().mRight;
-		LLRect r = channel_text->getRect();
-		const S32 PAD = 2;
-		S32 version_string_top = r.mTop;
-		if(text)
-		{
-			version_string_top = text->getRect().mTop;
-		}
-		r.setOriginAndSize( 
-			right - r.getWidth() - PAD,
-			version_string_top, 
-			r.getWidth(), 
-			r.getHeight());
-		channel_text->setRect(r);
 	}
 
+	LLTextBox* forgot_password_text = LLUICtrlFactory::getTextBoxByName(this, "forgot_password_text");
+	if (forgot_password_text)
+	{
+		forgot_password_text->setClickedCallback(onClickForgotPassword);
+	}
+    
 	// get the web browser control
 	#if LL_LIBXUL_ENABLED
 	LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html");
@@ -635,15 +617,15 @@ BOOL LLPanelLogin::getServer(LLString &server, S32 &domain_name)
 			{
 				domain_name = combo->getValue().asInteger();
 
-				if ((S32)USERSERVER_OTHER == domain_name)
+				if ((S32)GRID_INFO_OTHER == domain_name)
 				{
-					server = gUserServerName;
+					server = gGridName;
 				}
 			}
 			else
 			{
 				// no valid selection, return other
-				domain_name = (S32)USERSERVER_OTHER;
+				domain_name = (S32)GRID_INFO_OTHER;
 				server = combo_val.asString();
 			}
 			user_picked = combo->isDirty();
@@ -740,7 +722,7 @@ void LLPanelLogin::onClickConnect(void *)
 			if (combo)
 			{
 				S32 selected_server = combo->getValue();
-				if (selected_server == USERSERVER_NONE)
+				if (selected_server == GRID_INFO_NONE)
 				{
 					LLString custom_server = combo->getValue().asString();
 					gSavedSettings.setString("CustomServer", custom_server);
@@ -808,6 +790,15 @@ void LLPanelLogin::onClickVersion(void*)
 	LLFloaterAbout::show(NULL);
 }
 
+void LLPanelLogin::onClickForgotPassword(void*)
+{
+	if (sInstance )
+	{
+		LLWeb::loadURL(sInstance->childGetValue( "forgot_password_url" ).asString());
+	}
+}
+
+
 // static
 void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
 {
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 94e746eb69f5093c80e93e212c683b12bac634df..447b9ea01c0bb63da89122243eb0b1ac48d4fb8b 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -88,8 +88,9 @@ class LLPanelLogin
 	static void newAccountAlertCallback(S32 option, void*);
 	static void onClickQuit(void*);
 	static void onClickVersion(void*);
+	static void onClickForgotPassword(void*);
 	static void onPassKey(LLLineEditor* caller, void* user_data);
-
+	
 private:
 	LLPointer<LLViewerImage> mLogoImage;
 
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index cf507098f7a941cd6bbe1b303d0ae4a2747748d9..c3d949d3df4327bb66cfd8bc121570d6d6739e1b 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -68,7 +68,7 @@
 #include "llvovolume.h"
 #include "llworld.h"
 #include "pipeline.h"
-#include "viewer.h"
+#include "llviewercontrol.h"
 #include "llvieweruictrlfactory.h"
 #include "llfirstuse.h"
 
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 69e0fde823614fe6abf4d17843547aaeaf66bb05..c288c6aaedd501e410d258bc4a20ced05de4913e 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -72,7 +72,6 @@
 #include "llvovolume.h"
 #include "llworld.h"
 #include "pipeline.h"
-#include "viewer.h"
 
 #include "lldrawpool.h"
 #include "llvieweruictrlfactory.h"
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 720963cb0f5f30f294baf1cc9049facdcc8856a9..051e328a6bc2f980f93807ac9d9d74c4e21468d9 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -65,7 +65,7 @@
 #include "llviewerregion.h"
 #include "llviewerstats.h"
 #include "llviewerwindow.h"		// busycount
-#include "viewer.h"			// gVFS
+#include "llappviewer.h"			// gVFS
 
 #include "llresmgr.h"
 
@@ -342,7 +342,7 @@ void LLPreviewGesture::handleSaveChangesDialog(S32 option, void* data)
 	case 2: // "Cancel"
 	default:
 		// If we were quitting, we didn't really mean it.
-		app_abort_quit();
+		LLAppViewer::instance()->abortQuit();
 		break;
 	}
 }
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 620be8f8c65f6ed547bfbebf8e9e8a8176470bd2..dc56494d7fbbc6ffa525f7a44c68c90bca409070 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -55,7 +55,8 @@
 #include "lldir.h"
 //#include "llfloaterchat.h"
 #include "llviewerstats.h"
-#include "viewer.h"		// app_abort_quit()
+#include "llviewercontrol.h"		// gSavedSettings
+#include "llappviewer.h"		// app_abort_quit()
 #include "lllineeditor.h"
 #include "llvieweruictrlfactory.h"
 
@@ -636,7 +637,7 @@ void LLPreviewNotecard::handleSaveChangesDialog(S32 option, void* userdata)
 	case 2: // "Cancel"
 	default:
 		// If we were quitting, we didn't really mean it.
-		app_abort_quit();
+		LLAppViewer::instance()->abortQuit();
 		break;
 	}
 }
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 7eac589640c6d7892d81cf829ab3ef0fb32a977a..6c377009f275dfd6037658cb97ef765f21de712d 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -72,7 +72,6 @@
 #include "llscrolllistctrl.h"
 #include "lltextbox.h"
 #include "llslider.h"
-#include "viewer.h"
 #include "lldir.h"
 #include "llcombobox.h"
 //#include "llfloaterchat.h"
@@ -83,7 +82,8 @@
 #include "llwebbrowserctrl.h"
 #include "lluictrlfactory.h"
 
-#include "viewer.h"
+#include "llviewercontrol.h"
+#include "llappviewer.h"
 
 #include "llpanelinventory.h"
 
@@ -629,7 +629,7 @@ void LLScriptEdCore::handleSaveChangesDialog( S32 option, void* userdata )
 	case 2: // "Cancel"
 	default:
 		// If we were quitting, we didn't really mean it.
-		app_abort_quit();
+        LLAppViewer::instance()->abortQuit();
 		break;
 	}
 }
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index d855f7508e16681aa0694c99e88ee2ba5ddf67d5..cc9c3fa503aa4b799be24ca1c209e41af02453de 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -49,7 +49,7 @@
 #include "llviewercontrol.h"
 #include "llviewerimagelist.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
+#include "llappviewer.h"
 
 LLProgressView* LLProgressView::sInstance = NULL;
 
@@ -127,7 +127,7 @@ BOOL LLProgressView::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
 		// Suck up all keystokes except CTRL-Q.
 		if( ('Q' == key) && (MASK_CONTROL == mask) )
 		{
-			app_user_quit();
+			LLAppViewer::instance()->userQuit();
 		}
 		return TRUE;
 	}
@@ -228,7 +228,7 @@ void LLProgressView::draw()
 	F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
 	// background_color.mV[3] = background_color.mV[3]*alpha;
 
-	LLString top_line = gSecondLife;
+	LLString top_line = LLAppViewer::instance()->getSecondLifeTitle();
 
 	font->renderUTF8(top_line, 0,
 		line_x, line_one_y,
@@ -338,7 +338,7 @@ void LLProgressView::onCancelButtonClicked(void*)
 {
 	if (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE)
 	{
-		app_request_quit();
+		LLAppViewer::instance()->requestQuit();
 	}
 	else
 	{
diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp
index eadac8a9ebef01088abf6d1b8b808187db43b157..ee3890e50af0429024ed55dde2412a757f8d5e6e 100644
--- a/indra/newview/llsky.cpp
+++ b/indra/newview/llsky.cpp
@@ -64,6 +64,7 @@ extern LLPipeline gPipeline;
 F32 azimuth_from_vector(const LLVector3 &v);
 F32 elevation_from_vector(const LLVector3 &v);
 
+LLSky				gSky;
 // ---------------- LLSky ----------------
 
 //////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 6cd1aceeb752f55e4751a2e3140cbba60e668fa9..abb8d973aa3e41042d4a87997da205975b050fd9 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -38,7 +38,7 @@
 #include "llvovolume.h"
 #include "llviewercamera.h"
 #include "llface.h"
-#include "viewer.h"
+#include "llviewercontrol.h"
 #include "llagent.h"
 #include "llviewerregion.h"
 #include "llcamera.h"
diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp
index 332a5aa21826b19c3b03e14a2c214a6c5966bc45..827493d1b52e4b2724e779fd551830b66a1599b5 100644
--- a/indra/newview/llsprite.cpp
+++ b/indra/newview/llsprite.cpp
@@ -48,7 +48,6 @@
 #include "llface.h"
 #include "llviewercamera.h"
 #include "llviewerimagelist.h"
-#include "viewer.h"
 
 LLVector3 LLSprite::sCameraUp(0.0f,0.0f,1.0f);
 LLVector3 LLSprite::sCameraRight(1.0f,0.0f,0.0f);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index dad8046e501bddfb9172fc481c3dfe38f7de2138..0111676a97ec240a16f0cdec48b8166546f8bd0a 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -134,6 +134,7 @@
 #include "llurlsimstring.h"
 #include "llurlwhitelist.h"
 #include "lluserauth.h"
+#include "llvieweraudio.h"
 #include "llviewerassetstorage.h"
 #include "llviewercamera.h"
 #include "llviewerdisplay.h"
@@ -155,12 +156,16 @@
 #include "llworldmap.h"
 #include "llxfermanager.h"
 #include "pipeline.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "llmediaengine.h"
 #include "llfasttimerview.h"
 #include "llfloatermap.h"
 #include "llweb.h"
 #include "llvoiceclient.h"
+#include "llnamelistctrl.h"
+#include "llnamebox.h"
+#include "llnameeditor.h"
+#include "llurlsimstring.h"
 
 #if LL_LIBXUL_ENABLED
 #include "llmozlib.h"
@@ -186,13 +191,7 @@
 //
 // exported globals
 //
-
-// HACK: Allow server to change sun and moon IDs.
-// I can't figure out how to pass the appropriate
-// information into the LLVOSky constructor.  JC
-LLUUID gSunTextureID = IMG_SUN;
-LLUUID gMoonTextureID = IMG_MOON;
-LLUUID gCloudTextureID = IMG_CLOUD_POOF;
+BOOL gAgentMovementCompleted = FALSE;
 
 const char* SCREEN_HOME_FILENAME = "screen_home.bmp";
 const char* SCREEN_LAST_FILENAME = "screen_last.bmp";
@@ -202,7 +201,6 @@ const char* SCREEN_LAST_FILENAME = "screen_last.bmp";
 //
 extern S32 gStartImageWidth;
 extern S32 gStartImageHeight;
-extern std::string gSerialNumber;
 
 //
 // local globals
@@ -250,6 +248,17 @@ void init_start_screen(S32 location_id);
 void release_start_screen();
 void reset_login();
 
+void callback_cache_name(const LLUUID& id, const char* firstname, const char* lastname, BOOL is_group, void* data)
+{
+	LLNameListCtrl::refreshAll(id, firstname, lastname, is_group);
+	LLNameBox::refreshAll(id, firstname, lastname, is_group);
+	LLNameEditor::refreshAll(id, firstname, lastname, is_group);
+	
+	// TODO: Actually be intelligent about the refresh.
+	// For now, just brute force refresh the dialogs.
+	dialog_refresh_all();
+}
+
 //
 // exported functionality
 //
@@ -288,9 +297,9 @@ class LLGestureInventoryFetchObserver : public LLInventoryFetchObserver
 
 void update_texture_fetch()
 {
-	gTextureCache->update(1); // unpauses the texture cache thread
-	gImageDecodeThread->update(1); // unpauses the image thread
-	gTextureFetch->update(1); // unpauses the texture fetch thread
+	LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
+	LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
+	LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
 	gImageList.updateImages(0.10f);
 }
 
@@ -372,7 +381,7 @@ BOOL idle_startup()
 
 		/////////////////////////////////////////////////
 		//
-		// Initialize stuff that doesn't need data from userserver/simulators
+		// Initialize stuff that doesn't need data from simulators
 		//
 
 		if (gFeatureManagerp->isSafe())
@@ -412,7 +421,7 @@ BOOL idle_startup()
 			// *TODO:translate (maybe - very unlikely error message)
 			// Note: alerts.xml may be invalid - if this gets translated it will need to be in the code
 			LLString bad_xui_msg = "An error occured while updating Second Life. Please download the latest version from www.secondlife.com.";
-			app_early_exit(bad_xui_msg);
+            LLAppViewer::instance()->earlyExit(bad_xui_msg);
 		}
 		//
 		// Statistics stuff
@@ -465,13 +474,13 @@ BOOL idle_startup()
 				   std::string()))
 			{
 				std::string msg = llformat("Unable to start networking, error %d", gMessageSystem->getErrorCode());
-				app_early_exit(msg);
+				LLAppViewer::instance()->earlyExit(msg);
 			}
 			LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
 		}
 		else
 		{
-			app_early_exit("Unable to initialize communications.");
+			LLAppViewer::instance()->earlyExit("Unable to initialize communications.");
 		}
 
 		if(gMessageSystem && gMessageSystem->isOK())
@@ -651,7 +660,7 @@ BOOL idle_startup()
 		else
 		{
 			// if not automatically logging in, display login dialog
-			// until a valid userserver is selected
+			// a valid grid is selected
 			firstname = gSavedSettings.getString("FirstName");
 			lastname = gSavedSettings.getString("LastName");
 			password = load_password_from_disk();
@@ -731,11 +740,11 @@ BOOL idle_startup()
 			gSavedSettings.setString("LastName", lastname);
 
 			llinfos << "Attempting login as: " << firstname << " " << lastname << llendl;
-			write_debug("Attempting login as: ");
-			write_debug(firstname);
-			write_debug(" ");
-			write_debug(lastname);
-			write_debug("\n");
+			LLAppViewer::instance()->writeDebug("Attempting login as: ");
+			LLAppViewer::instance()->writeDebug(firstname);
+			LLAppViewer::instance()->writeDebug(" ");
+			LLAppViewer::instance()->writeDebug(lastname);
+			LLAppViewer::instance()->writeDebug("\n");
 		}
 
 		// create necessary directories
@@ -783,17 +792,17 @@ BOOL idle_startup()
 			LLString server_label;
 			S32 domain_name_index;
 			BOOL user_picked_server = LLPanelLogin::getServer( server_label, domain_name_index );
-			gUserServerChoice = (EUserServerDomain) domain_name_index;
-			gSavedSettings.setS32("ServerChoice", gUserServerChoice);
-			if (gUserServerChoice == USERSERVER_OTHER)
+			gGridChoice = (EGridInfo) domain_name_index;
+			gSavedSettings.setS32("ServerChoice", gGridChoice);
+			if (gGridChoice == GRID_INFO_OTHER)
 			{
-				snprintf(gUserServerName, MAX_STRING, "%s", server_label.c_str());			/* Flawfinder: ignore */
+				snprintf(gGridName, MAX_STRING, "%s", server_label.c_str());			/* Flawfinder: ignore */
 			}
 
 			if ( user_picked_server )
-			{	// User picked a grid from the popup, so clear the stored urls and they will be re-generated from gUserServerChoice
+			{	// User picked a grid from the popup, so clear the stored urls and they will be re-generated from gGridChoice
 				sAuthUris.clear();
-				resetURIs();
+                LLAppViewer::instance()->resetURIs();
 			}
 
 			LLString location;
@@ -908,12 +917,12 @@ BOOL idle_startup()
 		}
 		if (sAuthUris.empty())
 		{
-			sAuthUris = getLoginURIs();
+			sAuthUris = LLAppViewer::instance()->getLoginURIs();
 		}
 		sAuthUriNum = 0;
 		auth_method = "login_to_simulator";
 		auth_desc = "Logging in.  ";
-		auth_desc += gSecondLife;
+		auth_desc += LLAppViewer::instance()->getSecondLifeTitle();
 		auth_desc += " may appear frozen.  Please wait.";
 		LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
 	}
@@ -966,7 +975,7 @@ BOOL idle_startup()
 			gLastExecFroze,
 			requested_options,
 			hashed_mac_string,
-			gSerialNumber);
+			LLAppViewer::instance()->getSerialNumber());
 		// reset globals
 		gAcceptTOS = FALSE;
 		gAcceptCriticalMessage = FALSE;
@@ -1167,7 +1176,7 @@ BOOL idle_startup()
 		default:
 			if (sAuthUriNum >= (int) sAuthUris.size() - 1)
 			{
-				emsg << "Unable to connect to " << gSecondLife << ".\n";
+				emsg << "Unable to connect to " << LLAppViewer::instance()->getSecondLifeTitle() << ".\n";
 				emsg << gUserAuthp->errorMessage();
 			} else {
 				sAuthUriNum++;
@@ -1187,7 +1196,7 @@ BOOL idle_startup()
 		{
 			delete gUserAuthp;
 			gUserAuthp = NULL;
-			app_force_quit(NULL);
+			LLAppViewer::instance()->forceQuit();
 			return FALSE;
 		}
 
@@ -1202,15 +1211,15 @@ BOOL idle_startup()
 			const char* text;
 			text = gUserAuthp->getResponse("agent_id");
 			if(text) gAgentID.set(text);
-			write_debug("AgentID: ");
-			write_debug(text);
-			write_debug("\n");
+			LLAppViewer::instance()->writeDebug("AgentID: ");
+			LLAppViewer::instance()->writeDebug(text);
+			LLAppViewer::instance()->writeDebug("\n");
 			
 			text = gUserAuthp->getResponse("session_id");
 			if(text) gAgentSessionID.set(text);
-			write_debug("SessionID: ");
-			write_debug(text);
-			write_debug("\n");
+			LLAppViewer::instance()->writeDebug("SessionID: ");
+			LLAppViewer::instance()->writeDebug(text);
+			LLAppViewer::instance()->writeDebug("\n");
 			
 			text = gUserAuthp->getResponse("secure_session_id");
 			if(text) gAgent.mSecureSessionID.set(text);
@@ -1238,7 +1247,6 @@ BOOL idle_startup()
 			}
 			gSavedSettings.setBOOL("RememberPassword", remember_password);
 			gSavedSettings.setBOOL("LoginLastLocation", gSavedSettings.getBOOL("LoginLastLocation"));
-			gSavedSettings.setBOOL("LoggedIn", TRUE);
 
 			text = gUserAuthp->getResponse("agent_access");
 			if(text && (text[0] == 'M'))
@@ -1587,7 +1595,7 @@ BOOL idle_startup()
 			gCacheName->addObserver(callback_cache_name);
 	
 			// Load stored cache if possible
-			load_name_cache();
+            LLAppViewer::instance()->loadNameCache();
 		}
 
 		// Data storage for map of world.
@@ -1985,22 +1993,8 @@ BOOL idle_startup()
 		gAgent.sendReliableMessage();
 
 		// request all group information
-		// *FIX: This will not do the right thing if the message
-		// gets there before the requestuserserverconnection
-		// circuit is completed.
 		gAgent.sendAgentDataUpdateRequest();
 
-
-		// NOTE: removed as part of user-privacy
-		// enhancements. this information should be available from
-		// login. 2006-10-16 Phoenix.
-		// get the users that have been granted modify powers
-		//msg->newMessageFast(_PREHASH_RequestGrantedProxies);
-		//msg->nextBlockFast(_PREHASH_AgentData);
-		//msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		//msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		//gAgent.sendReliableMessage();
-
 		BOOL shown_at_exit = gSavedSettings.getBOOL("ShowInventory");
 
 		// Create the inventory views
@@ -2136,7 +2130,6 @@ BOOL idle_startup()
 		//msg->setHandlerFuncFast(_PREHASH_AttachedSoundCutoffRadius,	process_attached_sound_cutoff_radius);
 
 		llinfos << "Initialization complete" << llendl;
-		gInitializationComplete = TRUE;
 
 		gRenderStartTime.reset();
 		gForegroundTime.reset();
@@ -2352,27 +2345,27 @@ void login_show()
 	
 	llinfos << "Setting Servers" << llendl;
 	
-	if( USERSERVER_OTHER == gUserServerChoice )
+	if( GRID_INFO_OTHER == gGridChoice )
 	{
-		LLPanelLogin::addServer( gUserServerName, USERSERVER_OTHER );
+		LLPanelLogin::addServer( gGridName, GRID_INFO_OTHER );
 	}
 	else
 	{
-		LLPanelLogin::addServer( gUserServerDomainName[gUserServerChoice].mLabel, gUserServerChoice );
+		LLPanelLogin::addServer( gGridInfo[gGridChoice].mLabel, gGridChoice );
 	}
 
 	// Arg!  We hate loops!
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_DMZ].mLabel,	USERSERVER_DMZ );
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_LOCAL].mLabel,	USERSERVER_LOCAL );
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_AGNI].mLabel,	USERSERVER_AGNI );
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_ADITI].mLabel,	USERSERVER_ADITI );
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SIVA].mLabel,	USERSERVER_SIVA );
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_DURGA].mLabel,	USERSERVER_DURGA );
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SHAKTI].mLabel,	USERSERVER_SHAKTI );
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_GANGA].mLabel,	USERSERVER_GANGA );
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_UMA].mLabel,	USERSERVER_UMA );
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SOMA].mLabel,	USERSERVER_SOMA );
-	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_VAAK].mLabel,	USERSERVER_VAAK );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_DMZ].mLabel,	GRID_INFO_DMZ );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_LOCAL].mLabel,	GRID_INFO_LOCAL );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_AGNI].mLabel,	GRID_INFO_AGNI );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_ADITI].mLabel,	GRID_INFO_ADITI );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_SIVA].mLabel,	GRID_INFO_SIVA );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_DURGA].mLabel,	GRID_INFO_DURGA );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_SHAKTI].mLabel,	GRID_INFO_SHAKTI );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_GANGA].mLabel,	GRID_INFO_GANGA );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_UMA].mLabel,	GRID_INFO_UMA );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_SOMA].mLabel,	GRID_INFO_SOMA );
+	LLPanelLogin::addServer( gGridInfo[GRID_INFO_VAAK].mLabel,	GRID_INFO_VAAK );
 }
 
 // Callback for when login screen is closed.  Option 0 = connect, option 1 = quit.
@@ -2405,7 +2398,7 @@ void login_callback(S32 option, void *userdata)
 		LLPanelLogin::close();
 
 		// Next iteration through main loop should shut down the app cleanly.
-		gQuit = TRUE;
+		LLAppViewer::instance()->userQuit(); // gQuit = TRUE;
 
 		return;
 	}
@@ -2660,7 +2653,7 @@ void update_dialog_callback(S32 option, void *userdata)
 		// ...user doesn't want to do it
 		if (mandatory)
 		{
-			app_force_quit();
+			LLAppViewer::instance()->forceQuit();
 			// Bump them back to the login screen.
 			//reset_login();
 		}
@@ -2680,7 +2673,9 @@ void update_dialog_callback(S32 option, void *userdata)
 #elif LL_LINUX
 	query_map["os"] = "lnx";
 #endif
-	query_map["userserver"] = gUserServerName;
+	// *TODO change userserver to be grid on both viewer and sim, since
+	// userserver no longer exists.
+	query_map["userserver"] = gGridName;
 	query_map["channel"] = gChannelName;
 	// *TODO constantize this guy
 	LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);
@@ -2691,7 +2686,7 @@ void update_dialog_callback(S32 option, void *userdata)
 	{
 		// We're hosed, bail
 		llwarns << "LLDir::getTempFilename() failed" << llendl;
-		app_force_quit(NULL);
+		LLAppViewer::instance()->forceQuit();
 		return;
 	}
 
@@ -2709,7 +2704,7 @@ void update_dialog_callback(S32 option, void *userdata)
 	if (!CopyFileA(updater_source.c_str(), update_exe_path.c_str(), FALSE))
 	{
 		llinfos << "Unable to copy the updater!" << llendl;
-		app_force_quit(NULL);
+		LLAppViewer::instance()->forceQuit();
 		return;
 	}
 
@@ -2742,13 +2737,14 @@ void update_dialog_callback(S32 option, void *userdata)
 			program_name = "SecondLife";
 		}
 
-		params << " -silent -name \"" << gSecondLife << "\"";
+		params << " -silent -name \"" << LLAppViewer::instance()->getSecondLifeTitle() << "\"";
 		params << " -program \"" << program_name << "\"";
 	}
 
 	llinfos << "Calling updater: " << update_exe_path << " " << params.str() << llendl;
 
- 	remove_marker_file(); // In case updater fails
+	// *REMOVE:Mani The following call is handled through ~LLAppViewer.
+ 	// remove_marker_file(); // In case updater fails
 	
 	// Use spawn() to run asynchronously
 	int retval = _spawnl(_P_NOWAIT, update_exe_path.c_str(), update_exe_path.c_str(), params.str().c_str(), NULL);
@@ -2767,13 +2763,14 @@ void update_dialog_callback(S32 option, void *userdata)
 	update_exe_path += "/AutoUpdater.app/Contents/MacOS/AutoUpdater' -url \"";
 	update_exe_path += update_url.asString();
 	update_exe_path += "\" -name \"";
-	update_exe_path += gSecondLife;
+	update_exe_path += LLAppViewer::instance()->getSecondLifeTitle();
 	update_exe_path += "\" &";
 
 	llinfos << "Calling updater: " << update_exe_path << llendl;
-
- 	remove_marker_file(); // In case updater fails
 	
+	// *REMOVE:Mani The following call is handled through ~LLAppViewer.
+ 	// remove_marker_file(); // In case updater fails
+
 	// Run the auto-updater.
 	system(update_exe_path.c_str());		/* Flawfinder: ignore */
 	
@@ -2781,16 +2778,18 @@ void update_dialog_callback(S32 option, void *userdata)
 	OSMessageBox("Automatic updating is not yet implemented for Linux.\n"
 		"Please download the latest version from www.secondlife.com.",
 		NULL, OSMB_OK);
-	remove_marker_file();
+
+	// *REMOVE:Mani The following call is handled through ~LLAppViewer.
+	// remove_marker_file();
 	
 #endif
-	app_force_quit(NULL);
+	LLAppViewer::instance()->forceQuit();
 }
 
 void use_circuit_callback(void**, S32 result)
 {
 	// bail if we're quitting.
-	if(gQuit) return;
+	if(LLApp::isExiting()) return;
 	if( !gUseCircuitCallbackCalled )
 	{
 		gUseCircuitCallbackCalled = true;
@@ -3689,3 +3688,8 @@ bool LLStartUp::dispatchURL()
 	}
 	return false;
 }
+
+void login_alert_done(S32 option, void* user_data)
+{
+	LLPanelLogin::giveFocus();
+}
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index ad27b28a2137882b335dc1b6bf7e864c29e89020..08f2f6002ce5a63e28f7efea449dbf257f25f00d 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -36,9 +36,9 @@
 
 // functions
 BOOL idle_startup();
-void cleanup_app();
 LLString load_password_from_disk();
 void release_start_screen();
+void login_alert_done(S32 option, void* user_data);
 
 // constants, variables,  & enumerations
 extern const char* SCREEN_HOME_FILENAME;
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 8c50eca9af8cd84c6e3474b45505ea90df4383e5..27081d15dcadacabb885b1a28d123b909e4056a9 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -78,7 +78,7 @@
 
 #include "lltoolmgr.h"
 #include "llfocusmgr.h"
-#include "viewer.h"
+#include "llappviewer.h"
 
 //#include "llfirstuse.h"
 
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index e9643ebe26c034fc903b210382cc6302e34786cc..e9aa9b0232bafbf7a577dd2dd919a84dbaba79f1 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -41,7 +41,7 @@
 #include "llviewerobjectlist.h"
 #include "llregionhandle.h"
 #include "llagent.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "llworld.h"
 #include "llviewercontrol.h"
 #include "llviewerimage.h"
@@ -67,8 +67,6 @@ S32 LLSurface::sTexelsUpdated = 0;
 F32 LLSurface::sTextureUpdateTime = 0.f;
 LLStat LLSurface::sTexelsUpdatedPerSecStat;
 
-extern void bad_network_handler();
-
 // ---------------- LLSurface:: Public Members ---------------
 
 LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) :
@@ -776,7 +774,7 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL
 				<< " quant_wbits " << (S32)ph.quant_wbits
 				<< " patchids " << (S32)ph.patchids
 				<< llendl;
-			bad_network_handler();
+            LLAppViewer::instance()->badNetworkHandler();
 			return;
 		}
 
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 097682fa13a366da7b3cb81b325d686e1c695179..5330e8dfac6fb39e2e9e3a1cc0526f16205af574 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -52,7 +52,6 @@
 #include "llxmltree.h"
 #include "pipeline.h"
 #include "v4coloru.h"
-#include "viewer.h"
 
 //#include "../tools/imdebug/imdebug.h"
 
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 7d5e6ab185fffa985734381bd841397597bc99bf..ae42ec60d36bdccd8d1acf6e6a2bc88ca7453129 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -46,7 +46,6 @@
 #include "llviewerimagelist.h"
 #include "llviewerimage.h"
 #include "llviewerregion.h"
-#include "viewer.h"
 
 //////////////////////////////////////////////////////////////////////////////
 
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 4df5444d66078da34bc7adcf6a5a192c0e360db4..06a4ea097fb554ba5f6b8496c82d016050af0f58 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -49,7 +49,7 @@
 #include "llviewerobject.h"
 #include "llviewerimage.h"
 #include "llviewerimagelist.h"
-#include "viewer.h"
+#include "llappviewer.h"
 
 extern F32 texmem_lower_bound_scale;
 
@@ -145,7 +145,7 @@ void LLTextureBar::draw()
 	}
 
 	LLColor4 color;
-	if (mImagep->getID() == gTextureFetch->mDebugID)
+	if (mImagep->getID() == LLAppViewer::getTextureFetch()->mDebugID)
 	{
 		color = LLColor4::cyan2;
 	}
@@ -347,7 +347,7 @@ BOOL LLTextureBar::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	if ((mask & (MASK_CONTROL|MASK_SHIFT|MASK_ALT)) == MASK_ALT)
 	{
-		gTextureFetch->mDebugID = mImagep->getID();
+		LLAppViewer::getTextureFetch()->mDebugID = mImagep->getID();
 		return TRUE;
 	}
 	return LLView::handleMouseDown(x,y,mask);
@@ -469,9 +469,9 @@ void LLGLTexMemBar::draw()
 	
 	text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d",
 					gImageList.getNumImages(),
-					gTextureFetch->getNumRequests(), gTextureFetch->getNumDeletes(),
-					gTextureFetch->mPacketCount, gTextureFetch->mBadPacketCount, 
-					gTextureCache->getNumReads(), gTextureCache->getNumWrites(),
+					LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(),
+					LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, 
+					LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),
 					LLLFSThread::sLocal->getPending(),
 					LLImageWorker::sCount, LLImageWorker::getWorkerThread()->getNumDeletes(),
 					LLImageRaw::sRawImageCount);
@@ -480,7 +480,7 @@ void LLGLTexMemBar::draw()
 									 text_color, LLFontGL::LEFT, LLFontGL::TOP);
 	
 	S32 dx1 = 0;
-	if (gTextureFetch->mDebugPause)
+	if (LLAppViewer::getTextureFetch()->mDebugPause)
 	{
 		LLFontGL::sMonospace->renderUTF8("!", 0, title_x1, line_height,
 										 text_color, LLFontGL::LEFT, LLFontGL::TOP);
@@ -781,7 +781,7 @@ BOOL LLTextureView::handleMouseDown(S32 x, S32 y, MASK mask)
 	}
 	if ((mask & (MASK_CONTROL|MASK_SHIFT|MASK_ALT)) == (MASK_CONTROL|MASK_SHIFT))
 	{
-		gTextureFetch->mDebugPause = !gTextureFetch->mDebugPause;
+		LLAppViewer::getTextureFetch()->mDebugPause = !LLAppViewer::getTextureFetch()->mDebugPause;
 		return TRUE;
 	}
 	if (mask & MASK_SHIFT)
diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp
index 71e8aec78d532c2558ba829c6ecb3dd0a22dcdba..e7a5445ef631d12a918c9d62f8c62291ce6b5bb8 100644
--- a/indra/newview/lltoolbar.cpp
+++ b/indra/newview/lltoolbar.cpp
@@ -59,7 +59,6 @@
 #include "llviewerparcelmgr.h"
 #include "llvieweruictrlfactory.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
 #include "lltoolgrab.h"
 
 #if LL_DARWIN
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp
index a56bf42ceefbdd8710faa7721e3eb8b24756447d..189996e8710937d06469bf8607f53efb70b147d8 100644
--- a/indra/newview/lltoolbrush.cpp
+++ b/indra/newview/lltoolbrush.cpp
@@ -53,7 +53,7 @@
 #include "llviewerregion.h"
 #include "llviewerwindow.h"
 #include "llworld.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "llparcel.h"
 
 #include "llglheaders.h"
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 1f607def5851d9e34e4633d6805ee864e0268fd6..e6eca31cd0b600376f30d9c74d6925b66b068495 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -63,7 +63,6 @@
 #include "llvolume.h"
 #include "llworld.h"
 #include "object_flags.h"
-#include "viewer.h"
 
 LLToolDragAndDrop *gToolDragAndDrop = NULL;
 
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index 2ac2b339458df748a5fb26a5d4b5ea0056878f74..43c8e1a8d13714d08b3a8b2ee932bbf76ab090b4 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -55,7 +55,6 @@
 #include "llviewercamera.h"
 #include "llviewerobject.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
 #include "llvoavatar.h"
 #include "llmorphview.h"
 
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index 13977ee3ac30cc43c734bdec5f833a165faffd43..3f19ed43307d03a448b0ab25e943f3fb478a7496 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -62,7 +62,6 @@
 #include "llviewerwindow.h"
 #include "llvoavatar.h"
 #include "llworld.h"
-#include "viewer.h"
 
 const S32 SLOP_DIST_SQ = 4;
 
diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp
index c7e598ecb289757c4b872b7f7da4a2898cc413df..ebe22fc43c4bc6ac71b75bbcf68304bd2fea0ae3 100644
--- a/indra/newview/lltoolgun.cpp
+++ b/indra/newview/lltoolgun.cpp
@@ -37,7 +37,6 @@
 #include "llagent.h"
 #include "llviewercontrol.h"
 #include "llsky.h"
-#include "viewer.h"
 #include "llresmgr.h"
 #include "llfontgl.h"
 #include "llui.h"
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index d3cd997e74f109cdd26ca7b0962dd67a9aa5a2da..3a56a9fd63780b7c1a23243128416aaad9f2c8af 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -62,7 +62,6 @@
 #include "llviewerwindow.h"
 #include "llvoavatar.h"
 #include "pipeline.h"
-#include "viewer.h"
 
 //LLToolMorph *gToolMorph = NULL;
 
diff --git a/indra/newview/lltoolobjpicker.cpp b/indra/newview/lltoolobjpicker.cpp
index 8e8abfe3d17d90a518072e6effcab719ca43468b..a8876da1318f065e66564fe2e824a76ae32fb5de 100644
--- a/indra/newview/lltoolobjpicker.cpp
+++ b/indra/newview/lltoolobjpicker.cpp
@@ -38,7 +38,6 @@
 #include "llagent.h"
 #include "llselectmgr.h"
 #include "llworld.h"
-#include "viewer.h"				// for gFPSClamped, pie menus
 #include "llviewercontrol.h"
 #include "llmenugl.h"
 #include "lltoolmgr.h"
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index ee5d08f128d347a6ad72f569732f1e04ea1350ce..d26bdab921be969c58809c6fa2e855451a290c98 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -50,9 +50,22 @@
 #include "llviewerregion.h"
 #include "llviewerwindow.h"
 #include "llworld.h"
-#include "viewer.h"
 #include "llui.h"
 
+//Headers added for functions moved from viewer.cpp
+#include "llvograss.h"
+#include "llvotree.h"
+#include "llvolumemessage.h"
+#include "llhudmanager.h"
+#include "llagent.h"
+#include "audioengine.h"
+#include "llhudeffecttrail.h"
+#include "llviewerobjectlist.h"
+#include "llviewercamera.h"
+#include "llviewerstats.h"
+
+const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f);
+
 //static 
 LLPCode	LLToolPlacer::sObjectType = LL_PCODE_CUBE;
 
@@ -61,9 +74,366 @@ LLToolPlacer::LLToolPlacer()
 {
 }
 
+BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj, S32* hit_face, 
+							 BOOL* b_hit_land, LLVector3* ray_start_region, LLVector3* ray_end_region, LLViewerRegion** region )
+{
+	F32 max_dist_from_camera = gSavedSettings.getF32( "MaxSelectDistance" ) - 1.f;
+
+	// Viewer-side pick to find the right sim to create the object on.  
+	// First find the surface the object will be created on.
+	gViewerWindow->hitObjectOrLandGlobalImmediate(x, y, NULL, FALSE);
+	
+	// Note: use the frontmost non-flora version because (a) plants usually have lots of alpha and (b) pants' Havok
+	// representations (if any) are NOT the same as their viewer representation.
+	*hit_obj = gObjectList.findObject( gLastHitNonFloraObjectID );
+	*hit_face = gLastHitNonFloraObjectFace;
+	*b_hit_land = !(*hit_obj) && !gLastHitNonFloraPosGlobal.isExactlyZero();
+	LLVector3d land_pos_global = gLastHitNonFloraPosGlobal;
+
+	// Make sure there's a surface to place the new object on.
+	BOOL bypass_sim_raycast = FALSE;
+	LLVector3d	surface_pos_global;
+	if (*b_hit_land)
+	{
+		surface_pos_global = land_pos_global; 
+		bypass_sim_raycast = TRUE;
+	}
+	else 
+	if (*hit_obj)
+	{
+		surface_pos_global = (*hit_obj)->getPositionGlobal();
+	}
+	else
+	{
+		return FALSE;
+	}
+
+	// Make sure the surface isn't too far away.
+	LLVector3d ray_start_global = gAgent.getCameraPositionGlobal();
+	F32 dist_to_surface_sq = (F32)((surface_pos_global - ray_start_global).magVecSquared());
+	if( dist_to_surface_sq > (max_dist_from_camera * max_dist_from_camera) )
+	{
+		return FALSE;
+	}
+
+	// Find the sim where the surface lives.
+	LLViewerRegion *regionp = gWorldp->getRegionFromPosGlobal(surface_pos_global);
+	if (!regionp)
+	{
+		llwarns << "Trying to add object outside of all known regions!" << llendl;
+		return FALSE;
+	}
+
+	// Find the simulator-side ray that will be used to place the object accurately
+	LLVector3d		mouse_direction;
+	mouse_direction.setVec( gViewerWindow->mouseDirectionGlobal( x, y ) );
+
+	*region = regionp;
+	*ray_start_region =	regionp->getPosRegionFromGlobal( ray_start_global );
+	F32 near_clip = gCamera->getNear() + 0.01f;  // Include an epsilon to avoid rounding issues.
+	*ray_start_region += gCamera->getAtAxis() * near_clip;
+
+	if( bypass_sim_raycast )
+	{
+		// Hack to work around Havok's inability to ray cast onto height fields
+		*ray_end_region = regionp->getPosRegionFromGlobal( surface_pos_global );  // ray end is the viewer's intersection point
+	}
+	else
+	{
+		LLVector3d		ray_end_global = ray_start_global + (1.f + max_dist_from_camera) * mouse_direction;  // add an epsilon to the sim version of the ray to avoid rounding problems.
+		*ray_end_region = regionp->getPosRegionFromGlobal( ray_end_global );
+	}
+
+	return TRUE;
+}
+
+
+BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
+{
+	LLVector3 ray_start_region;
+	LLVector3 ray_end_region;
+	LLViewerRegion* regionp = NULL;
+	BOOL b_hit_land = FALSE;
+	S32 hit_face = -1;
+	LLViewerObject* hit_obj = NULL;
+	U8 state = 0;
+	BOOL success = raycastForNewObjPos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, &regionp );
+	if( !success )
+	{
+		return FALSE;
+	}
+
+	if( hit_obj && (hit_obj->isAvatar() || hit_obj->isAttachment()) )
+	{
+		// Can't create objects on avatars or attachments
+		return FALSE;
+	}
+
+	if (NULL == regionp)
+	{
+		llwarns << "regionp was NULL; aborting function." << llendl;
+		return FALSE;
+	}
+
+	if (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX)
+	{
+		LLFirstUse::useSandbox();
+	}
+
+	// Set params for new object based on its PCode.
+	LLQuaternion	rotation;
+	LLVector3		scale = DEFAULT_OBJECT_SCALE;
+	U8				material = LL_MCODE_WOOD;
+	BOOL			create_selected = FALSE;
+	LLVolumeParams	volume_params;
+	
+	switch (pcode) 
+	{
+	case LL_PCODE_LEGACY_GRASS:
+		//  Randomize size of grass patch 
+		scale.setVec(10.f + ll_frand(20.f), 10.f + ll_frand(20.f),  1.f + ll_frand(2.f));
+		state = rand() % LLVOGrass::sMaxGrassSpecies;
+		break;
+
+
+	case LL_PCODE_LEGACY_TREE:
+	case LL_PCODE_TREE_NEW:
+		state = rand() % LLVOTree::sMaxTreeSpecies;
+		break;
+
+	case LL_PCODE_SPHERE:
+	case LL_PCODE_CONE:
+	case LL_PCODE_CUBE:
+	case LL_PCODE_CYLINDER:
+	case LL_PCODE_TORUS:
+	case LLViewerObject::LL_VO_SQUARE_TORUS:
+	case LLViewerObject::LL_VO_TRIANGLE_TORUS:
+	default:
+		create_selected = TRUE;
+		break;
+	}
+
+	// Play creation sound
+	if (gAudiop)
+	{
+		F32 volume = gSavedSettings.getF32("AudioLevelUI");
+		gAudiop->triggerSound( LLUUID(gSavedSettings.getString("UISndObjectCreate")), gAgent.getID(), volume);
+	}
+
+	gMessageSystem->newMessageFast(_PREHASH_ObjectAdd);
+	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
+	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+	gMessageSystem->addU8Fast(_PREHASH_Material,	material);
+
+	U32 flags = 0;		// not selected
+	if (use_physics)
+	{
+		flags |= FLAGS_USE_PHYSICS;
+	}
+	if (create_selected)
+	{
+		flags |= FLAGS_CREATE_SELECTED;
+	}
+	gMessageSystem->addU32Fast(_PREHASH_AddFlags, flags );
+
+	LLPCode volume_pcode;	// ...PCODE_VOLUME, or the original on error
+	switch (pcode)
+	{
+	case LL_PCODE_SPHERE:
+		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);
+
+		volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE );
+		volume_params.setBeginAndEndS( 0.f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 1, 1 );
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LL_PCODE_TORUS:
+		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);
+
+		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE );
+		volume_params.setBeginAndEndS( 0.f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 1.f, 0.25f );	// "top size"
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LLViewerObject::LL_VO_SQUARE_TORUS:
+		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);
+
+		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_CIRCLE );
+		volume_params.setBeginAndEndS( 0.f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 1.f, 0.25f );	// "top size"
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LLViewerObject::LL_VO_TRIANGLE_TORUS:
+		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);
+
+		volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_CIRCLE );
+		volume_params.setBeginAndEndS( 0.f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 1.f, 0.25f );	// "top size"
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LL_PCODE_SPHERE_HEMI:
+		volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE );
+		//volume_params.setBeginAndEndS( 0.5f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 0.5f );
+		volume_params.setRatio	( 1, 1 );
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LL_PCODE_CUBE:
+		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE );
+		volume_params.setBeginAndEndS( 0.f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 1, 1 );
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LL_PCODE_PRISM:
+		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE );
+		volume_params.setBeginAndEndS( 0.f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 0, 1 );
+		volume_params.setShear	( -0.5f, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LL_PCODE_PYRAMID:
+		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE );
+		volume_params.setBeginAndEndS( 0.f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 0, 0 );
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LL_PCODE_TETRAHEDRON:
+		volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_LINE );
+		volume_params.setBeginAndEndS( 0.f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 0, 0 );
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LL_PCODE_CYLINDER:
+		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
+		volume_params.setBeginAndEndS( 0.f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 1, 1 );
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LL_PCODE_CYLINDER_HEMI:
+		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
+		volume_params.setBeginAndEndS( 0.25f, 0.75f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 1, 1 );
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LL_PCODE_CONE:
+		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
+		volume_params.setBeginAndEndS( 0.f, 1.f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 0, 0 );
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	case LL_PCODE_CONE_HEMI:
+		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
+		volume_params.setBeginAndEndS( 0.25f, 0.75f );
+		volume_params.setBeginAndEndT( 0.f, 1.f );
+		volume_params.setRatio	( 0, 0 );
+		volume_params.setShear	( 0, 0 );
+		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
+		volume_pcode = LL_PCODE_VOLUME;
+		break;
+
+	default:
+		LLVolumeMessage::packVolumeParams(0, gMessageSystem);
+		volume_pcode = pcode;
+		break;
+	}
+	gMessageSystem->addU8Fast(_PREHASH_PCode, volume_pcode);
+
+	gMessageSystem->addVector3Fast(_PREHASH_Scale,			scale );
+	gMessageSystem->addQuatFast(_PREHASH_Rotation,			rotation );
+	gMessageSystem->addVector3Fast(_PREHASH_RayStart,		ray_start_region );
+	gMessageSystem->addVector3Fast(_PREHASH_RayEnd,			ray_end_region );
+	gMessageSystem->addU8Fast(_PREHASH_BypassRaycast,		(U8)b_hit_land );
+	gMessageSystem->addU8Fast(_PREHASH_RayEndIsIntersection, (U8)FALSE );
+	gMessageSystem->addU8Fast(_PREHASH_State, state);
+
+	// Limit raycast to a single object.  
+	// Speeds up server raycast + avoid problems with server ray hitting objects
+	// that were clipped by the near plane or culled on the viewer.
+	LLUUID ray_target_id;
+	if( hit_obj )
+	{
+		ray_target_id = hit_obj->getID();
+	}
+	else
+	{
+		ray_target_id.setNull();
+	}
+	gMessageSystem->addUUIDFast(_PREHASH_RayTargetID,			ray_target_id );
+	
+	// Pack in name value pairs
+	gMessageSystem->sendReliable(regionp->getHost());
+
+	// Spawns a message, so must be after above send
+	if (create_selected)
+	{
+		gSelectMgr->deselectAll();
+		gViewerWindow->getWindow()->incBusyCount();
+	}
+
+	// VEFFECT: AddObject
+	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
+	effectp->setSourceObject((LLViewerObject*)gAgent.getAvatarObject());
+	effectp->setPositionGlobal(regionp->getPosGlobalFromRegion(ray_end_region));
+	effectp->setDuration(LL_HUD_DUR_SHORT);
+	effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+
+	gViewerStats->incStat(LLViewerStats::ST_CREATE_COUNT);
+
+	return TRUE;
+}
+
 // Used by the placer tool to add copies of the current selection.
 // Inspired by add_object().  JC
-BOOL add_duplicate(S32 x, S32 y)
+BOOL LLToolPlacer::addDuplicate(S32 x, S32 y)
 {
 	LLVector3 ray_start_region;
 	LLVector3 ray_end_region;
@@ -71,7 +441,7 @@ BOOL add_duplicate(S32 x, S32 y)
 	BOOL b_hit_land = FALSE;
 	S32 hit_face = -1;
 	LLViewerObject* hit_obj = NULL;
-	BOOL success = raycast_for_new_obj_pos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, &regionp );
+	BOOL success = raycastForNewObjPos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, &regionp );
 	if( !success )
 	{
 		make_ui_sound("UISndInvalidOp");
@@ -123,11 +493,11 @@ BOOL LLToolPlacer::placeObject(S32 x, S32 y, MASK mask)
 	
 	if (gSavedSettings.getBOOL("CreateToolCopySelection"))
 	{
-		added = add_duplicate(x, y);
+		added = addDuplicate(x, y);
 	}
 	else
 	{
-		added = add_object( sObjectType, x, y, NO_PHYSICS );
+		added = addObject( sObjectType, x, y, FALSE );
 	}
 
 	// ...and go back to the default tool
diff --git a/indra/newview/lltoolplacer.h b/indra/newview/lltoolplacer.h
index d6d21cbf708633dd012399d50769e72f6d5fb2a9..b0164701297fe3b41be5728b745459c0d22da826 100644
--- a/indra/newview/lltoolplacer.h
+++ b/indra/newview/lltoolplacer.h
@@ -37,6 +37,7 @@
 #include "lltool.h"
 
 class LLButton;
+class LLViewerRegion;
 
 ////////////////////////////////////////////////////
 // LLToolPlacer
@@ -57,6 +58,12 @@ class LLToolPlacer
 
 protected:
 	static LLPCode	sObjectType;
+
+private:
+	BOOL addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics );
+	BOOL raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj, S32* hit_face, 
+							  BOOL* b_hit_land, LLVector3* ray_start_region, LLVector3* ray_end_region, LLViewerRegion** region );
+	BOOL addDuplicate(S32 x, S32 y);
 };
 
 ////////////////////////////////////////////////////
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index f77202f1bca2b945c91483d685021e4c5c984d86..37c8b00ed222c80e3f80c3e910e5f66432e8e1ca 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -49,7 +49,6 @@
 #include "llviewerwindow.h"
 #include "llvoavatar.h"
 #include "llworld.h"
-#include "viewer.h"				// for gFPSClamped, pie menus
 
 // Globals
 LLToolSelect		*gToolSelect = NULL;
diff --git a/indra/newview/lltoolselectland.cpp b/indra/newview/lltoolselectland.cpp
index dae82888101e0cc80a6928f4380753b27b940946..bbbda58cf054a3d0ce881e5f39e97271f9f06c51 100644
--- a/indra/newview/lltoolselectland.cpp
+++ b/indra/newview/lltoolselectland.cpp
@@ -45,7 +45,6 @@
 #include "lltoolview.h"
 #include "llviewerparcelmgr.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
 
 // Globals
 LLToolSelectLand *gToolParcel = NULL;
diff --git a/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp
index 505039d3d3c078791ab6486ac60f60be1156069b..dd1a01f8dd681c6247a9a5796c3aa125f2d8245a 100644
--- a/indra/newview/lltoolselectrect.cpp
+++ b/indra/newview/lltoolselectrect.cpp
@@ -48,7 +48,6 @@
 #include "llviewerobjectlist.h"
 #include "llviewerwindow.h"
 #include "llviewercamera.h"
-#include "viewer.h"
 
 #include "llglheaders.h"
 
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index a35d7b5c080a14b14376009c5ced2ee018feb004..4bab92269cdb7d7500fbd8081dd3673502b91001 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -45,7 +45,7 @@
 #include "v4color.h"
 
 // viewer includes
-#include "viewer.h"
+#include "llappviewer.h"
 #include "lltracker.h"
 #include "llagent.h"
 #include "llcallingcard.h"
@@ -62,6 +62,7 @@
 #include "llviewerinventory.h"
 #include "llworld.h"
 #include "llworldmapview.h"
+#include "llviewercontrol.h"
 
 const F32 DESTINATION_REACHED_RADIUS    = 3.0f;
 const F32 DESTINATION_VISITED_RADIUS    = 6.0f;
diff --git a/indra/newview/llvectorperfoptions.cpp b/indra/newview/llvectorperfoptions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0952e8b3149de361f3ebc28faf8b61ef4a92482b
--- /dev/null
+++ b/indra/newview/llvectorperfoptions.cpp
@@ -0,0 +1,108 @@
+/** 
+ * @file llvectorperfoptions.cpp
+ * @brief Control of vector perfomance options.
+ *
+ * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llvectorperfoptions.h"
+#include "llviewerjointmesh.h"
+#include "llviewercontrol.h"
+
+// Initially, we test the performance of the vectorization code, then
+// turn it off if it ends up being slower. JC
+BOOL	gVectorizePerfTest	= TRUE;
+BOOL	gVectorizeEnable	= FALSE;
+U32		gVectorizeProcessor	= 0;
+BOOL	gVectorizeSkin		= FALSE;
+
+void update_vector_performances(void)
+{
+	char *vp;
+	
+	switch(gVectorizeProcessor)
+	{
+		case 2: vp = "SSE2"; break;					// *TODO: replace the magic #s
+		case 1: vp = "SSE"; break;
+		default: vp = "COMPILER DEFAULT"; break;
+	}
+	llinfos << "Vectorization         : " << ( gVectorizeEnable ? "ENABLED" : "DISABLED" ) << llendl ;
+	llinfos << "Vector Processor      : " << vp << llendl ;
+	llinfos << "Vectorized Skinning   : " << ( gVectorizeSkin ? "ENABLED" : "DISABLED" ) << llendl ;
+	
+	if(gVectorizeEnable && gVectorizeSkin)
+	{
+		switch(gVectorizeProcessor)
+		{
+			case 2:
+				LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometrySSE2;
+				break;
+			case 1:
+				LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometrySSE;
+				break;
+			default:
+				LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometryVectorized;
+				break;
+		}
+	}
+	else
+	{
+		LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometryOriginal;
+	}
+}
+
+
+class LLVectorizationEnableListener: public LLSimpleListener
+{
+	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+	{
+		gVectorizeEnable = event->getValue().asBoolean();
+		update_vector_performances();
+		return true;
+	}
+};
+static LLVectorizationEnableListener vectorization_enable_listener;
+
+class LLVectorizeSkinListener: public LLSimpleListener
+{
+	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+	{
+		gVectorizeSkin = event->getValue().asBoolean();
+		update_vector_performances();
+		return true;
+	}
+};
+static LLVectorizeSkinListener vectorize_skin_listener;
+
+class LLVectorProcessorListener: public LLSimpleListener
+{
+	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+	{
+		gVectorizeProcessor = event->getValue().asInteger();
+		update_vector_performances();
+		return true;
+	}
+};
+static LLVectorProcessorListener vector_processor_listener;
+
+void LLVectorPerformanceOptions::initClass()
+{
+	gVectorizePerfTest = gSavedSettings.getBOOL("VectorizePerfTest");
+	gVectorizeEnable = gSavedSettings.getBOOL("VectorizeEnable");
+	gVectorizeProcessor = gSavedSettings.getU32("VectorizeProcessor");
+	gVectorizeSkin = gSavedSettings.getBOOL("VectorizeSkin");
+	update_vector_performances();
+
+	// these are currently static in this file, so they can't move to settings_setup_listeners
+	gSavedSettings.getControl("VectorizeEnable")->addListener(&vectorization_enable_listener);
+	gSavedSettings.getControl("VectorizeProcessor")->addListener(&vector_processor_listener);
+	gSavedSettings.getControl("VectorizeSkin")->addListener(&vectorize_skin_listener);
+}
+
+void LLVectorPerformanceOptions::cleanupClass()
+{
+}
+
diff --git a/indra/newview/llvectorperfoptions.h b/indra/newview/llvectorperfoptions.h
new file mode 100644
index 0000000000000000000000000000000000000000..ebd1f8248d85d77ab56fd680b3952415f16065b9
--- /dev/null
+++ b/indra/newview/llvectorperfoptions.h
@@ -0,0 +1,18 @@
+/** 
+ * @file llvectorperfoptions.h
+ * @brief Control of vector performance options
+ *
+ * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_VECTORPERFOPTIONS_H
+#define LL_VECTORPERFOPTIONS_H
+
+namespace LLVectorPerformanceOptions
+{
+	void initClass(); // Run after configuration files are read.
+	void cleanupClass();
+};
+
+#endif
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ac90a06a570156683afce9d54c2a33014a40f87d
--- /dev/null
+++ b/indra/newview/llvieweraudio.cpp
@@ -0,0 +1,215 @@
+/** 
+ * @file llvieweraudio.cpp
+ * @brief Audio functions moved from viewer.cpp
+ *
+ * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llvieweraudio.h"
+#include "audioengine.h"
+#include "llviewercontrol.h"
+#include "llmediaengine.h"
+#include "llagent.h"
+#include "llappviewer.h"
+#include "llvoiceclient.h"
+#include "llviewerwindow.h"
+#include "llviewercamera.h"
+
+/////////////////////////////////////////////////////////
+
+void init_audio() 
+{
+	if (!gAudiop) 
+	{
+		llwarns << "Failed to create an appropriate Audio Engine" << llendl;
+		return;
+	}
+	LLVector3d lpos_global = gAgent.getCameraPositionGlobal();
+	LLVector3 lpos_global_f;
+
+	lpos_global_f.setVec(lpos_global);
+					
+	gAudiop->setListener(lpos_global_f,
+						  LLVector3::zero,	// gCamera->getVelocity(),    // !!! BUG need to replace this with smoothed velocity!
+						  gCamera->getUpAxis(),
+						  gCamera->getAtAxis());
+
+// load up our initial set of sounds we'll want so they're in memory and ready to be played
+
+	BOOL mute_audio = gSavedSettings.getBOOL("MuteAudio");
+
+	if (!mute_audio && gPreloadSounds)
+	{
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndAlert")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndBadKeystroke")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndChatFromObject")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndClick")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndClickRelease")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndHealthReductionF")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndHealthReductionM")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndIncomingChat")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndIncomingIM")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInvApplyToObject")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInvalidOp")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInventoryCopyToInv")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndMoneyChangeDown")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndMoneyChangeUp")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectCopyToInv")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectCreate")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectDelete")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezIn")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezOut")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuAppear")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuHide")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight0")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight1")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight2")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight3")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight4")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight5")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight6")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight7")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndSnapshot")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartAutopilot")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartFollowpilot")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartIM")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStopAutopilot")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTeleportOut")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTextureApplyToObject")));
+		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTextureCopyToInv")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTyping")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowClose")));
+		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen")));
+	}
+
+	audio_update_volume(true);
+}
+
+void audio_update_volume(bool force_update)
+{
+	F32 master_volume = gSavedSettings.getF32("AudioLevelMaster");
+	BOOL mute_audio = gSavedSettings.getBOOL("MuteAudio");
+	if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized")))
+	{
+		mute_audio = TRUE;
+	}
+	F32 mute_volume = mute_audio ? 0.0f : 1.0f;
+
+	// Sound Effects
+	if (gAudiop) 
+	{
+		gAudiop->setMasterGain ( master_volume );
+
+		gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
+		gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance")); 
+		gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
+#ifdef kAUDIO_ENABLE_WIND
+		gAudiop->enableWind(!mute_audio);
+#endif
+
+		gAudiop->setMuted(mute_audio);
+		
+		if (force_update)
+		{
+			audio_update_wind(true);
+		}
+	}
+
+	// Streaming Music
+	if (gAudiop) 
+	{		
+		F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
+		music_volume = mute_volume * master_volume * (music_volume*music_volume);
+		gAudiop->setInternetStreamGain ( music_volume );
+	}
+
+	// Streaming Media
+	if(LLMediaEngine::getInstance())
+	{
+		F32 media_volume = gSavedSettings.getF32("AudioLevelMedia");
+		media_volume = mute_volume * master_volume * (media_volume*media_volume);
+		LLMediaEngine::getInstance()->setVolume(media_volume);
+	}
+
+	// Voice
+	if (gVoiceClient)
+	{
+		F32 voice_volume = gSavedSettings.getF32("AudioLevelVoice");
+		voice_volume = mute_volume * master_volume * voice_volume;
+		gVoiceClient->setVoiceVolume(voice_volume);
+		gVoiceClient->setMicGain(gSavedSettings.getF32("AudioLevelMic"));
+
+		if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized")))
+		{
+			gVoiceClient->setMuteMic(true);
+		}
+		else
+		{
+			gVoiceClient->setMuteMic(false);
+		}
+	}
+}
+
+void audio_update_listener()
+{
+	if (gAudiop)
+	{
+		// update listener position because agent has moved	
+		LLVector3d lpos_global = gAgent.getCameraPositionGlobal();		
+		LLVector3 lpos_global_f;
+		lpos_global_f.setVec(lpos_global);
+	
+		gAudiop->setListener(lpos_global_f,
+							 // gCameraVelocitySmoothed, 
+							 // LLVector3::zero,	
+							 gAgent.getVelocity(),    // !!! *TODO: need to replace this with smoothed velocity!
+							 gCamera->getUpAxis(),
+							 gCamera->getAtAxis());
+	}
+}
+
+void audio_update_wind(bool force_update)
+{
+#ifdef kAUDIO_ENABLE_WIND
+	//
+	//  Extract height above water to modulate filter by whether above/below water 
+	// 
+	LLViewerRegion* region = gAgent.getRegion();
+	if (region)
+	{
+		static F32 last_camera_water_height = -1000.f;
+		LLVector3 camera_pos = gAgent.getCameraPositionAgent();
+		F32 camera_water_height = camera_pos.mV[VZ] - region->getWaterHeight();
+		
+		//
+		//  Don't update rolloff factor unless water surface has been crossed
+		//
+		if (force_update || (last_camera_water_height * camera_water_height) < 0.f)
+		{
+			if (camera_water_height < 0.f)
+			{
+				gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff") * LL_ROLLOFF_MULTIPLIER_UNDER_WATER);
+			}
+			else 
+			{
+				gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
+			}
+		}
+		// this line rotates the wind vector to be listener (agent) relative
+		// unfortunately we have to pre-translate to undo the translation that
+		// occurs in the transform call
+		gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal(gWindVec - gAgent.getVelocity());
+
+		// don't use the setter setMaxWindGain() because we don't
+		// want to screw up the fade-in on startup by setting actual source gain
+		// outside the fade-in.
+		gAudiop->mMaxWindGain = gSavedSettings.getF32("AudioLevelAmbient");
+		
+		last_camera_water_height = camera_water_height;
+		gAudiop->updateWind(gRelativeWindVec, camera_water_height);
+	}
+#endif
+}
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
new file mode 100644
index 0000000000000000000000000000000000000000..4aba50ec7454eb0dbe995e812f46bd56b9a7ee14
--- /dev/null
+++ b/indra/newview/llvieweraudio.h
@@ -0,0 +1,17 @@
+/** 
+ * @file llvieweraudio.h
+ * @brief Audio functions originally in viewer.cpp
+ *
+ * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_VIEWERAUDIO_H
+#define LL_VIEWERAUDIO_H
+
+void init_audio();
+void audio_update_volume(bool force_update = true);
+void audio_update_listener();
+void audio_update_wind(bool force_update = true);
+
+#endif //LL_VIEWER_H
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index a5b7b6fc8f1a8db8564fd13c4ba3a88e1ed3baf7..5a655cba1a363fce4646d2ce63991ccc995c9b98 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -47,6 +47,9 @@ const F32 OGL_TO_CFR_ROTATION[16] = {  0.f,  0.f, -1.f,  0.f, 	// -Z becomes X
 									   0.f,  1.f,  0.f,  0.f,	//  Y becomes Z
 									   0.f,  0.f,  0.f,  1.f };
 
+const BOOL FOR_SELECTION = TRUE;
+const BOOL NOT_FOR_SELECTION = FALSE;
+
 class LLViewerCamera : public LLCamera
 {
 public:
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 79ec70fb1c9101dc80b5dd0ad0e2161ee44b209f..250b250a7a609d179f1abcdd5e79f5d63d9cad95 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -50,6 +50,10 @@
 #include "llspinctrl.h"
 #include "llcolorswatch.h"
 
+#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+BOOL 				gHackGodmode = FALSE;
+#endif
+
 LLFloaterSettingsDebug* LLFloaterSettingsDebug::sInstance = NULL;
 
 LLControlGroup gSavedSettings;	// saved at end of session
diff --git a/indra/newview/llviewercontrol.h b/indra/newview/llviewercontrol.h
index 3151261ec3bd8f5bb166f8b8eb204c06b6d88bce..8a3191d3bb5e0188108a7bf7e81f63989bef1fe5 100644
--- a/indra/newview/llviewercontrol.h
+++ b/indra/newview/llviewercontrol.h
@@ -36,6 +36,13 @@
 #include "llfloater.h"
 #include "lltexteditor.h"
 
+// Enabled this definition to compile a 'hacked' viewer that
+// allows a hacked godmode to be toggled on and off.
+#define TOGGLE_HACKED_GODLIKE_VIEWER 
+#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+extern BOOL gHackGodmode;
+#endif
+
 class LLFloaterSettingsDebug : public LLFloater
 {
 public:
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 24b8105916013f4817b39c534e247046fdd123e1..60184312a7fc6ef0987886cc8dcd73743e1d4dcb 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -62,7 +62,7 @@
 #include "llvograss.h"
 #include "llworld.h"
 #include "pipeline.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "llstartup.h"
 #include "llfasttimer.h"
 #include "llfloatertools.h"
@@ -72,14 +72,11 @@
 #include "llviewerregion.h"
 #include "lldrawpoolwater.h"
 
-extern U32 gFrameCount;
 extern LLPointer<LLImageGL> gStartImageGL;
-extern LLPointer<LLImageGL> gDisconnectedImagep;
-extern BOOL gLogoutRequestSent;
-extern LLTimer gLogoutTimer;
-extern BOOL gHaveSavedSnapshot;
 extern BOOL gDisplaySwapBuffers;
 
+LLPointer<LLImageGL> gDisconnectedImagep = NULL;
+
 // used to toggle renderer back on after teleport
 const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain
 const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
@@ -99,7 +96,7 @@ void render_ui_3d();
 void render_ui_2d();
 void render_disconnected_background();
 
-void process_keystrokes_async(); // in viewer.cpp
+void process_keystrokes_async();
 
 void display_startup()
 {
@@ -331,7 +328,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)
 			break;
 		}
 	}
-	else if(gLogoutRequestSent)
+    else if(LLAppViewer::instance()->logoutRequestSent())
 	{
 		F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime;
 		if (percent_done > 100.f)
@@ -339,7 +336,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)
 			percent_done = 100.f;
 		}
 
-		if( gQuit )
+		if( LLApp::isExiting() )
 		{
 			percent_done = 100.f;
 		}
@@ -358,7 +355,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)
 		else
 		{
 
-			if( gQuit )
+			if( LLApp::isExiting() )
 			{
 				percent_done = 100.f;
 			}
@@ -554,7 +551,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)
 	//	glPopMatrix();
 	//}
 
-	if (!(gLogoutRequestSent && gHaveSavedSnapshot) 
+	if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) 
 			&& !gRestoreGL
 			&& !gDisconnected)
 	{
@@ -745,6 +742,74 @@ void render_ui_and_swap()
 	}
 }
 
+void renderCoordinateAxes()
+{
+	LLGLSNoTexture gls_no_texture;
+	glBegin(GL_LINES);
+		glColor3f(1.0f, 0.0f, 0.0f);   // i direction = X-Axis = red
+		glVertex3f(0.0f, 0.0f, 0.0f);
+		glVertex3f(2.0f, 0.0f, 0.0f);
+		glVertex3f(3.0f, 0.0f, 0.0f);
+		glVertex3f(5.0f, 0.0f, 0.0f);
+		glVertex3f(6.0f, 0.0f, 0.0f);
+		glVertex3f(8.0f, 0.0f, 0.0f);
+		// Make an X
+		glVertex3f(11.0f, 1.0f, 1.0f);
+		glVertex3f(11.0f, -1.0f, -1.0f);
+		glVertex3f(11.0f, 1.0f, -1.0f);
+		glVertex3f(11.0f, -1.0f, 1.0f);
+
+		glColor3f(0.0f, 1.0f, 0.0f);   // j direction = Y-Axis = green
+		glVertex3f(0.0f, 0.0f, 0.0f);
+		glVertex3f(0.0f, 2.0f, 0.0f);
+		glVertex3f(0.0f, 3.0f, 0.0f);
+		glVertex3f(0.0f, 5.0f, 0.0f);
+		glVertex3f(0.0f, 6.0f, 0.0f);
+		glVertex3f(0.0f, 8.0f, 0.0f);
+		// Make a Y
+		glVertex3f(1.0f, 11.0f, 1.0f);
+		glVertex3f(0.0f, 11.0f, 0.0f);
+		glVertex3f(-1.0f, 11.0f, 1.0f);
+		glVertex3f(0.0f, 11.0f, 0.0f);
+		glVertex3f(0.0f, 11.0f, 0.0f);
+		glVertex3f(0.0f, 11.0f, -1.0f);
+
+		glColor3f(0.0f, 0.0f, 1.0f);   // Z-Axis = blue
+		glVertex3f(0.0f, 0.0f, 0.0f);
+		glVertex3f(0.0f, 0.0f, 2.0f);
+		glVertex3f(0.0f, 0.0f, 3.0f);
+		glVertex3f(0.0f, 0.0f, 5.0f);
+		glVertex3f(0.0f, 0.0f, 6.0f);
+		glVertex3f(0.0f, 0.0f, 8.0f);
+		// Make a Z
+		glVertex3f(-1.0f, 1.0f, 11.0f);
+		glVertex3f(1.0f, 1.0f, 11.0f);
+		glVertex3f(1.0f, 1.0f, 11.0f);
+		glVertex3f(-1.0f, -1.0f, 11.0f);
+		glVertex3f(-1.0f, -1.0f, 11.0f);
+		glVertex3f(1.0f, -1.0f, 11.0f);
+	glEnd();
+}
+
+
+void draw_axes() 
+{
+	LLGLSUIDefault gls_ui;
+	LLGLSNoTexture gls_no_texture;
+	// A vertical white line at origin
+	LLVector3 v = gAgent.getPositionAgent();
+	glBegin(GL_LINES);
+		glColor3f(1.0f, 1.0f, 1.0f); 
+		glVertex3f(0.0f, 0.0f, 0.0f);
+		glVertex3f(0.0f, 0.0f, 40.0f);
+	glEnd();
+	// Some coordinate axes
+	glPushMatrix();
+		glTranslatef( v.mV[VX], v.mV[VY], v.mV[VZ] );
+		renderCoordinateAxes();
+	glPopMatrix();
+}
+
 void render_ui_3d()
 {
 	LLGLSPipeline gls_pipeline;
@@ -841,73 +906,6 @@ void render_ui_2d()
 	LLFontGL::sCurOrigin.set(0, 0);
 }
 
-void renderCoordinateAxes()
-{
-	LLGLSNoTexture gls_no_texture;
-	glBegin(GL_LINES);
-		glColor3f(1.0f, 0.0f, 0.0f);   // i direction = X-Axis = red
-		glVertex3f(0.0f, 0.0f, 0.0f);
-		glVertex3f(2.0f, 0.0f, 0.0f);
-		glVertex3f(3.0f, 0.0f, 0.0f);
-		glVertex3f(5.0f, 0.0f, 0.0f);
-		glVertex3f(6.0f, 0.0f, 0.0f);
-		glVertex3f(8.0f, 0.0f, 0.0f);
-		// Make an X
-		glVertex3f(11.0f, 1.0f, 1.0f);
-		glVertex3f(11.0f, -1.0f, -1.0f);
-		glVertex3f(11.0f, 1.0f, -1.0f);
-		glVertex3f(11.0f, -1.0f, 1.0f);
-
-		glColor3f(0.0f, 1.0f, 0.0f);   // j direction = Y-Axis = green
-		glVertex3f(0.0f, 0.0f, 0.0f);
-		glVertex3f(0.0f, 2.0f, 0.0f);
-		glVertex3f(0.0f, 3.0f, 0.0f);
-		glVertex3f(0.0f, 5.0f, 0.0f);
-		glVertex3f(0.0f, 6.0f, 0.0f);
-		glVertex3f(0.0f, 8.0f, 0.0f);
-		// Make a Y
-		glVertex3f(1.0f, 11.0f, 1.0f);
-		glVertex3f(0.0f, 11.0f, 0.0f);
-		glVertex3f(-1.0f, 11.0f, 1.0f);
-		glVertex3f(0.0f, 11.0f, 0.0f);
-		glVertex3f(0.0f, 11.0f, 0.0f);
-		glVertex3f(0.0f, 11.0f, -1.0f);
-
-		glColor3f(0.0f, 0.0f, 1.0f);   // Z-Axis = blue
-		glVertex3f(0.0f, 0.0f, 0.0f);
-		glVertex3f(0.0f, 0.0f, 2.0f);
-		glVertex3f(0.0f, 0.0f, 3.0f);
-		glVertex3f(0.0f, 0.0f, 5.0f);
-		glVertex3f(0.0f, 0.0f, 6.0f);
-		glVertex3f(0.0f, 0.0f, 8.0f);
-		// Make a Z
-		glVertex3f(-1.0f, 1.0f, 11.0f);
-		glVertex3f(1.0f, 1.0f, 11.0f);
-		glVertex3f(1.0f, 1.0f, 11.0f);
-		glVertex3f(-1.0f, -1.0f, 11.0f);
-		glVertex3f(-1.0f, -1.0f, 11.0f);
-		glVertex3f(1.0f, -1.0f, 11.0f);
-	glEnd();
-}
-
-void draw_axes() 
-{
-	LLGLSUIDefault gls_ui;
-	LLGLSNoTexture gls_no_texture;
-	// A vertical white line at origin
-	LLVector3 v = gAgent.getPositionAgent();
-	glBegin(GL_LINES);
-		glColor3f(1.0f, 1.0f, 1.0f); 
-		glVertex3f(0.0f, 0.0f, 0.0f);
-		glVertex3f(0.0f, 0.0f, 40.0f);
-	glEnd();
-	// Some coordinate axes
-	glPushMatrix();
-		glTranslatef( v.mV[VX], v.mV[VY], v.mV[VZ] );
-		renderCoordinateAxes();
-	glPopMatrix();
-}
-
 
 void render_disconnected_background()
 {
@@ -984,3 +982,48 @@ void render_disconnected_background()
 		glPopMatrix();
 	}
 }
+
+void display_cleanup()
+{
+	gDisconnectedImagep = NULL;
+}
+
+void process_keystrokes_async()
+{
+#if LL_WINDOWS
+	MSG			msg;
+	// look through all input messages, leaving them in the event queue
+	while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD))
+	{
+		// on first mouse message, break out
+		if (msg.message >= WM_MOUSEFIRST && 
+			msg.message <= WM_MOUSELAST ||
+			msg.message == WM_QUIT)
+		{
+			break;
+		}
+
+		// this is a message we want to handle now, so remove it from the event queue
+		PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE | PM_NOYIELD);
+		//		if (msg.message == WM_KEYDOWN)
+		//		{
+		//			llinfos << "Process async key down " << (U32)msg.wParam << llendl;
+		//		}
+		TranslateMessage(&msg);
+		DispatchMessage(&msg);
+	}
+
+	// Scan keyboard for movement keys.  Command keys and typing
+	// are handled by windows callbacks.  Don't do this until we're
+	// done initializing.  JC
+	if (gViewerWindow->mWindow->getVisible() 
+		&& gViewerWindow->getActive()
+		&& !gViewerWindow->mWindow->getMinimized()
+		&& LLStartUp::getStartupState() == STATE_STARTED
+		&& !gViewerWindow->getShowProgress()
+		&& !gFocusMgr.focusLocked())
+	{
+		gKeyboard->scanKeyboard();
+	}
+#endif
+}
diff --git a/indra/newview/llviewerdisplay.h b/indra/newview/llviewerdisplay.h
index b42c6e9bda4526803198a825e798e7b24bf5ebe1..2bf784c575d4edf7e34565a32fb9777f1b0bb93a 100644
--- a/indra/newview/llviewerdisplay.h
+++ b/indra/newview/llviewerdisplay.h
@@ -33,8 +33,13 @@
 #define LL_LLVIEWERDISPLAY_H
 
 void display_startup();
+void display_cleanup();
 
-extern BOOL gDisplaySwapBuffers;
+void display(BOOL rebuild = TRUE, F32 zoom_factor = 1.f, int subfield = 0);
 
+extern BOOL gDisplaySwapBuffers;
+extern BOOL	gTeleportDisplay;
+extern LLFrameTimer	gTeleportDisplayTimer;
+extern BOOL			gForceRenderLandFence;
 
 #endif // LL_LLVIEWERDISPLAY_H
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index b43646541b2b190c6cd4eae36824dbba80031265..43e858917611764cd2eaae8a616f585b38548627 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -41,7 +41,6 @@
 #include "llinventorymodel.h"
 #include "llnotify.h"
 #include "llimview.h"
-#include "viewer.h"
 #include "llgesturemgr.h"
 
 #include "llinventoryview.h"
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index c3c504f672f0a3d83c3668de3739bf65be55ec17..27e71c23c935e1493490adedd0320d8037515f48 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -34,7 +34,7 @@
 #include "llviewerwindow.h"
 #include "llviewercamera.h"
 #include "llviewerjoystick.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "llkeyboard.h"
 
 static LLQuaternion sFlycamRotation;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index d344f687d40c6a92369a9c289ade0e44316dafb8..c052d18f0b91fa31d48b0b73f66d9f18901e8fd9 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -191,7 +191,7 @@
 #include "llworldmap.h"
 #include "object_flags.h"
 #include "pipeline.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "roles_constants.h"
 #include "llviewerjoystick.h"
 
@@ -218,8 +218,6 @@ LLVOAvatar* find_avatar_from_object( const LLUUID& object_id );
 
 void handle_test_load_url(void*);
 
-extern void disconnect_viewer(void *);
-
 //
 // Evil hackish imported globals
 //
@@ -227,8 +225,6 @@ extern BOOL	gRenderLightGlows;
 extern BOOL gRenderAvatar;
 extern BOOL	gHideSelectedObjects;
 extern BOOL gShowOverlayTitle;
-extern BOOL gRandomizeFramerate;
-extern BOOL gPeriodicSlowFrame;
 extern BOOL gOcclusionCull;
 extern BOOL gAllowSelectAvatar;
 
@@ -408,11 +404,16 @@ void handle_claim_public_land(void*);
 void handle_god_request_havok(void *);
 void handle_god_request_avatar_geometry(void *);	// Hack for easy testing of new avatar geometry
 void reload_personal_settings_overrides(void *);
-void force_breakpoint(void *);
 void reload_vertex_shader(void *);
 void slow_mo_animations(void *);
 void handle_disconnect_viewer(void *);
 
+void force_error_breakpoint(void *);
+void force_error_llerror(void *);
+void force_error_bad_memory_access(void *);
+void force_error_infinite_loop(void *);
+void force_error_software_exception(void *);
+
 void handle_stopall(void*);
 //void handle_hinge(void*);
 //void handle_ptop(void*);
@@ -422,6 +423,7 @@ void handle_stopall(void*);
 BOOL enable_dehinge(void*);
 void handle_force_delete(void*);
 void print_object_info(void*);
+void print_agent_nvpairs(void*);
 void show_debug_menus();
 void toggle_debug_menus(void*);
 void toggle_map( void* user_data );
@@ -446,7 +448,6 @@ void handle_force_unlock(void*);
 void handle_selected_texture_info(void*);
 void handle_dump_image_list(void*);
 
-void handle_fullscreen_debug(void*);
 void handle_crash(void*);
 void handle_dump_followcam(void*);
 void handle_toggle_flycam(void*);
@@ -1061,16 +1062,18 @@ void init_client_menu(LLMenuGL* menu)
 										&menu_check_control,
 										(void*)"ShowConsoleWindow"));
 
-#ifndef LL_RELEASE_FOR_DOWNLOAD
+	if(gQAMode && !gInProductionGrid)
 	{
 		LLMenuGL* sub = NULL;
 		sub = new LLMenuGL("Debugging");
-		sub->append(new LLMenuItemCallGL("Force Breakpoint", &force_breakpoint, NULL, NULL, 'B', MASK_CONTROL | MASK_ALT));
-		sub->append(new LLMenuItemCallGL("LLError And Crash", &handle_crash));
+        sub->append(new LLMenuItemCallGL("Force Breakpoint", &force_error_breakpoint, NULL, NULL, 'B', MASK_CONTROL | MASK_ALT));
+		sub->append(new LLMenuItemCallGL("Force LLError And Crash", &force_error_llerror));
+        sub->append(new LLMenuItemCallGL("Force Bad Memory Access", &force_error_bad_memory_access));
+		sub->append(new LLMenuItemCallGL("Force Infinite Loop", &force_error_infinite_loop));
+		// *NOTE:Mani this isn't handled yet... sub->append(new LLMenuItemCallGL("Force Software Exception", &force_error_unhandled_exception)); 
 		sub->createJumpKeys();
 		menu->appendMenu(sub);
 	}
-#endif	
 
 	// TomY Temporary menu item so we can test this floater
 	menu->append(new LLMenuItemCheckGL("Clothing...", 
@@ -2372,7 +2375,6 @@ void callback_leave_group(S32 option, void *userdata)
 		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 		msg->nextBlockFast(_PREHASH_GroupData);
 		msg->addUUIDFast(_PREHASH_GroupID, gAgent.mGroupID );
-		//msg->sendReliable( gUserServer );
 		gAgent.sendReliableMessage();
 	}
 }
@@ -4689,6 +4691,24 @@ void print_object_info(void*)
 	gSelectMgr->selectionDump();
 }
 
+void print_agent_nvpairs(void*)
+{
+	LLViewerObject *objectp;
+
+	llinfos << "Agent Name Value Pairs" << llendl;
+
+	objectp = gObjectList.findObject(gAgentID);
+	if (objectp)
+	{
+		objectp->printNameValuePairs();
+	}
+	else
+	{
+		llinfos << "Can't find agent object" << llendl;
+	}
+
+	llinfos << "Camera at " << gAgent.getCameraPositionGlobal() << llendl;
+}
 
 void show_debug_menus()
 {
@@ -5174,18 +5194,6 @@ void handle_force_unlock(void*)
 	gSelectMgr->getSelection()->applyToObjects(&func);
 }
 
-// Fullscreen debug stuff
-void handle_fullscreen_debug(void*)
-{
-	llinfos << "Width " << gViewerWindow->getWindowWidth() << " Height " << gViewerWindow->getWindowHeight() << llendl;
-	llinfos << "mouse_x_from_center(100) " << mouse_x_from_center(100) << " y " << mouse_y_from_center(100) << llendl;
-}
-
-void handle_crash(void*)
-{
-	llerrs << "This is an llerror" << llendl;
-}
-
 class LLWorldForceSun : public view_listener_t
 {
 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -6811,13 +6819,6 @@ void reload_personal_settings_overrides(void *)
 	gSavedSettings.loadFromFile(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,"overrides.xml"));
 }
 
-void force_breakpoint(void *)
-{
-#if LL_WINDOWS // Forcing a breakpoint
-	DebugBreak();
-#endif
-}
-
 void reload_vertex_shader(void *)
 {
 	//THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought	- DaveP
@@ -6994,9 +6995,33 @@ void handle_disconnect_viewer(void *)
 
 	snprintf(message, sizeof(message), "Testing viewer disconnect");		/* Flawfinder: ignore */
 
-	do_disconnect(message);
+	LLAppViewer::instance()->forceDisconnect(message);
 }
 
+void force_error_breakpoint(void *)
+{
+    LLAppViewer::instance()->forceErrorBreakpoint();
+}
+
+void force_error_llerror(void *)
+{
+    LLAppViewer::instance()->forceErrorLLError();
+}
+
+void force_error_bad_memory_access(void *)
+{
+    LLAppViewer::instance()->forceErrorBadMemoryAccess();
+}
+
+void force_error_infinite_loop(void *)
+{
+    LLAppViewer::instance()->forceErrorInifiniteLoop();
+}
+
+void force_error_software_exception(void *)
+{
+    LLAppViewer::instance()->forceErrorSoftwareException();
+}
 
 class LLToolsUseSelectionForGrid : public view_listener_t
 {
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 97b11fde8bbb2e3eb8cd067ec994330a1cce68db..ac4ac77f0c4248b8fc6895c460e40a37dc71747d 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -52,7 +52,8 @@
 #include "llviewerregion.h"
 #include "llviewerstats.h"
 #include "llviewerwindow.h"
-#include "viewer.h"	// app_request_quit()
+#include "llappviewer.h"
+
 
 // linden libraries
 #include "llassetuploadresponders.h"
@@ -439,7 +440,7 @@ class LLFileQuit : public view_listener_t
 {
 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
 	{
-		app_user_quit();
+		LLAppViewer::instance()->userQuit();
 		return true;
 	}
 };
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index bd959b9dead7dc07824ad6e5da30276a9a8a9660..ce3a3f1ae9bfe2a9b283420205768f20a89b95e0 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -129,8 +129,9 @@
 #include "llweb.h"
 #include "llworld.h"
 #include "pipeline.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "llfloaterworldmap.h"
+#include "llviewerdisplay.h"
 
 #include <boost/tokenizer.hpp>
 
@@ -146,8 +147,6 @@ const F32 SIT_DISTANCE_FROM_TARGET = 0.25f;
 static const F32 LOGOUT_REPLY_TIME = 3.f;	// Wait this long after LogoutReply before quitting.
 extern BOOL gDebugClicks;
 
-extern void bad_network_handler();
-
 // function prototypes
 void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
 void friendship_offer_callback(S32 option, void* user_data);
@@ -202,8 +201,8 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessageFast(_PREHASH_MoneyTransferRequest);
 		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, agent_get_id());
-		msg->addUUIDFast(_PREHASH_SessionID, agent_get_session_id());
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+        msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 		msg->nextBlockFast(_PREHASH_MoneyData);
 		msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID() );
 		msg->addUUIDFast(_PREHASH_DestID, uuid);
@@ -241,7 +240,7 @@ void process_logout_reply(LLMessageSystem* msg, void**)
 	msg->getUUID("AgentData", "AgentID", agent_id);
 	LLUUID session_id;
 	msg->getUUID("AgentData", "SessionID", session_id);
-	if((agent_id != agent_get_id()) || (session_id != agent_get_session_id()))
+	if((agent_id != gAgent.getID()) || (session_id != gAgent.getSessionID()))
 	{
 		llwarns << "Bogus Logout Reply" << llendl;
 	}
@@ -278,7 +277,7 @@ void process_logout_reply(LLMessageSystem* msg, void**)
 		gInventory.accountForUpdate(parents);
 		gInventory.notifyObservers();
 	}
-	app_force_quit(NULL);
+    LLAppViewer::instance()->forceQuit();
 }
 
 void process_layer_data(LLMessageSystem *mesgsys, void **user_data)
@@ -782,7 +781,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)
 				// Use the name of the last item giver, who is probably the person
 				// spamming you. JC
 				std::ostringstream message;
-				message << gSecondLife;
+				message << LLAppViewer::instance()->getSecondLifeTitle();
 				if (!from_name.empty())
 				{
 					message << ": Items coming in too fast from " << from_name;
@@ -2708,7 +2707,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 			<< x << ":" << y 
 			<< " current pos " << gAgent.getPositionGlobal()
 			<< llendl;
-		do_disconnect("You were sent to an invalid region.");
+		LLAppViewer::instance()->forceDisconnect("You were sent to an invalid region.");
 		return;
 
 	}
@@ -2888,7 +2887,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 	}
 
 	// We have already requested to log out.  Don't send agent updates.
-	if(gLogoutRequestSent)
+	if(LLAppViewer::instance()->logoutRequestSent())
 	{
 		return;
 	}
@@ -3235,10 +3234,13 @@ void process_time_synch(LLMessageSystem *mesgsys, void **user_data)
 	F32 phase;
 	U64	space_time_usec;
 
+    U32 seconds_per_day;
+    U32 seconds_per_year;
+
 	// "SimulatorViewerTimeMessage"
 	mesgsys->getU64Fast(_PREHASH_TimeInfo, _PREHASH_UsecSinceStart, space_time_usec);
-	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerDay, gSecondsPerDay);
-	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerYear, gSecondsPerYear);
+	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerDay, seconds_per_day);
+	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerYear, seconds_per_year);
 
 	// This should eventually be moved to an "UpdateHeavenlyBodies" message
 	mesgsys->getF32Fast(_PREHASH_TimeInfo, _PREHASH_SunPhase, phase);
@@ -3923,7 +3925,7 @@ void process_kick_user(LLMessageSystem *msg, void** /*user_data*/)
 
 	msg->getStringFast(_PREHASH_UserInfo, _PREHASH_Reason, 2048, message);
 
-	do_disconnect(message);
+	LLAppViewer::instance()->forceDisconnect(message);
 }
 
 
@@ -5337,7 +5339,7 @@ void invalid_message_callback(LLMessageSystem* msg,
 								   void*,
 								   EMessageException exception)
 {
-	bad_network_handler();
+    LLAppViewer::instance()->badNetworkHandler();
 }
 
 // Please do not add more message handlers here. This file is huge.
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 046f1f6c4f42573920304073a08992bb61c35649..caa61d64185048a70cbe807caf20c73b6903cf8f 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -34,47 +34,47 @@
 
 #include "llviewernetwork.h"
 
-LLUserServerData gUserServerDomainName[USERSERVER_COUNT] = 
+LLGridData gGridInfo[GRID_INFO_COUNT] = 
 {
 	{ "None", "", "", ""},
 	{ "Aditi", 
-	  "userserver.aditi.lindenlab.com", 
+	  "util.aditi.lindenlab.com", 
 	  "https://login.aditi.lindenlab.com/cgi-bin/login.cgi",
 	  "http://aditi-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Agni", 
-	  "userserver.agni.lindenlab.com", 
+	  "util.agni.lindenlab.com", 
 	  "https://login.agni.lindenlab.com/cgi-bin/login.cgi",
 	  "https://secondlife.com/helpers/" },
 	{ "DMZ",  
-	  "userserver.dmz.lindenlab.com", 
+	  "util.dmz.lindenlab.com", 
 	  "https://login.dmz.lindenlab.com/cgi-bin/login.cgi",
 	  "http://dmz-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Siva", 
-	  "userserver.siva.lindenlab.com",
+	  "util.siva.lindenlab.com",
 	  "https://login.siva.lindenlab.com/cgi-bin/login.cgi",
 	  "http://siva-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Durga",
-	  "userserver.durga.lindenlab.com",
+	  "util.durga.lindenlab.com",
 	  "https://login.durga.lindenlab.com/cgi-bin/login.cgi",
 	  "http://durga-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Shakti",
-	  "userserver.shakti.lindenlab.com",
+	  "util.shakti.lindenlab.com",
 	  "https://login.shakti.lindenlab.com/cgi-bin/login.cgi",
 	  "http://shakti-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Soma",
-	  "userserver.soma.lindenlab.com",
+	  "util.soma.lindenlab.com",
 	  "https://login.soma.lindenlab.com/cgi-bin/login.cgi",
 	  "http://soma-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Ganga",
-	  "userserver.ganga.lindenlab.com",
+	  "util.ganga.lindenlab.com",
 	  "https://login.ganga.lindenlab.com/cgi-bin/login.cgi",
 	  "http://ganga-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Vaak",
-	  "userserver.vaak.lindenlab.com",
+	  "util.vaak.lindenlab.com",
 	  "https://login.vaak.lindenlab.com/cgi-bin/login.cgi",
 	  "http://vaak-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Uma",
-	  "userserver.uma.lindenlab.com",
+	  "util.uma.lindenlab.com",
 	  "https://login.uma.lindenlab.com/cgi-bin/login.cgi",
 	  "http://uma-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Local", 
@@ -89,10 +89,8 @@ LLUserServerData gUserServerDomainName[USERSERVER_COUNT] =
 
 // Use this to figure out which domain name and login URI to use.
 
-EUserServerDomain gUserServerChoice = USERSERVER_NONE;
-char gUserServerName[MAX_STRING];		/* Flawfinder: ignore */
-
-LLHost gUserServer;
+EGridInfo gGridChoice = GRID_INFO_NONE;
+char gGridName[MAX_STRING];		/* Flawfinder: ignore */
 
 F32 gPacketDropPercentage = 0.f;
 F32 gInBandwidth = 0.f;
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index 1f73fe29673849d1bd7e06f1e1be6c1af767ab8e..118897aebcf78e8b0d4c75d1ab0b76d3d90620df 100644
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -35,26 +35,26 @@
 
 class LLHost;
 
-enum EUserServerDomain
+enum EGridInfo
 {
-	USERSERVER_NONE,
-	USERSERVER_ADITI,
-	USERSERVER_AGNI,
-	USERSERVER_DMZ,
-	USERSERVER_SIVA,
-	USERSERVER_DURGA,
-	USERSERVER_SHAKTI,
-	USERSERVER_SOMA,
-	USERSERVER_GANGA,
-	USERSERVER_VAAK,
-	USERSERVER_UMA,
-	USERSERVER_LOCAL,
-	USERSERVER_OTHER, // IP address set via -user or other command line option
-	USERSERVER_COUNT
+	GRID_INFO_NONE,
+	GRID_INFO_ADITI,
+	GRID_INFO_AGNI,
+	GRID_INFO_DMZ,
+	GRID_INFO_SIVA,
+	GRID_INFO_DURGA,
+	GRID_INFO_SHAKTI,
+	GRID_INFO_SOMA,
+	GRID_INFO_GANGA,
+	GRID_INFO_VAAK,
+	GRID_INFO_UMA,
+	GRID_INFO_LOCAL,
+	GRID_INFO_OTHER, // IP address set via -user or other command line option
+	GRID_INFO_COUNT
 };
 
 
-struct LLUserServerData
+struct LLGridData
 {
 	const char* mLabel;
 	const char* mName;
@@ -65,9 +65,9 @@ struct LLUserServerData
 extern F32 gPacketDropPercentage;
 extern F32 gInBandwidth;
 extern F32 gOutBandwidth;
-extern EUserServerDomain gUserServerChoice;
-extern LLUserServerData gUserServerDomainName[];
-extern char gUserServerName[MAX_STRING];		/* Flawfinder: ignore */
+extern EGridInfo gGridChoice;
+extern LLGridData gGridInfo[];
+extern char gGridName[MAX_STRING];		/* Flawfinder: ignore */
 
 const S32 MAC_ADDRESS_BYTES = 6;
 extern unsigned char gMACAddress[MAC_ADDRESS_BYTES];		/* Flawfinder: ignore */
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 0c9ca0152fcff431f9f35d721018cd3c5648b8f3..4c6f27944f3c4e20358c3b1fbf47baa4f0aaa71f 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -95,13 +95,12 @@
 #include "llworld.h"
 #include "llui.h"
 #include "pipeline.h"
-#include "viewer.h"
+#include "llappviewer.h"
 
 //#define DEBUG_UPDATE_TYPE
 
-extern BOOL		gVelocityInterpolate;
-extern BOOL		gPingInterpolate;
-extern U32		gFrameCount;
+BOOL gVelocityInterpolate = TRUE;
+BOOL gPingInterpolate = TRUE; 
 
 U32			LLViewerObject::sNumZombieObjects = 0;
 S32			LLViewerObject::sNumObjects = 0;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 9ce417d0e6ce63008aa87eda4de780008351897b..b30bf7e1b87c95ea26373502f6c006a447cb23f1 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -692,4 +692,7 @@ class LLStaticViewerObject : public LLViewerObject
 	virtual void updateDrawable(BOOL force_damped);
 };
 
+extern BOOL gVelocityInterpolate;
+extern BOOL gPingInterpolate;
+
 #endif
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 967f018f0d4fa5a11e077bc42b1ae2c9c35a4a17..38efb5de110f557220aac9c5f3919e81f6f178ff 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -42,7 +42,6 @@
 #include "llvoavatar.h"
 #include "llviewerobject.h"
 #include "llviewerwindow.h"
-#include "viewer.h"
 #include "llnetmap.h"
 #include "llagent.h"
 #include "pipeline.h"
@@ -71,11 +70,9 @@
 #endif
 #include "object_flags.h"
 
-extern BOOL gVelocityInterpolate;
-extern BOOL gPingInterpolate;
+#include "llappviewer.h"
+
 extern F32 gMinObjectDistance;
-extern U32 gFrameCount;
-extern LLTimer gRenderStartTime;
 extern BOOL gAnimateTextures;
 
 void dialog_refresh_all();
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 5e17ff0a5730bd51b6980c0b72d5ec1d3664a464..95a1db12dfbc5ed69fbf6a1869067cede30abefe 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -63,7 +63,6 @@
 #include "llvocache.h"
 #include "llvoclouds.h"
 #include "llworld.h"
-#include "viewer.h"
 
 // Viewer object cache version, change if object update
 // format changes. JC
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 96f52a1382feaf2d0cfccc49d79e4021b4d00def..81c10d161ccd9487cfe432549fdbfe8871c6067a 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -37,10 +37,28 @@
 #include "message.h"
 #include "lltimer.h"
 
-LLViewerStats *gViewerStats = NULL;
+#include "llappviewer.h"
+
+#include "pipeline.h" 
+#include "llviewerobjectlist.h" 
+#include "llviewerimagelist.h" 
+#include "lltexlayer.h"
+#include "llsurface.h"
+#include "llvlmanager.h"
+#include "llagent.h"
+#include "llviewercontrol.h"
+#include "llfloatertools.h"
+#include "lldebugview.h"
+#include "llfasttimerview.h"
+#include "llviewerregion.h"
+#include "llfloaterhtmlhelp.h"
+#include "llworld.h"
+#include "llfeaturemanager.h"
+#if LL_WINDOWS && LL_LCD_COMPILE
+	#include "lllcd.h"
+#endif
 
-extern U32 gFrameCount;
-extern LLTimer gRenderStartTime;
+LLViewerStats *gViewerStats = NULL;
 
 class StatAttributes
 {
@@ -323,3 +341,399 @@ const char *LLViewerStats::statTypeToText(EStatType type)
 		return "Unknown statistic";
 	}
 }
+
+// *NOTE:Mani The following methods used to exist in viewer.cpp
+// Moving them here, but not merging them into LLViewerStats yet.
+void reset_statistics()
+{
+	gPipeline.resetFrameStats();	// Reset per-frame statistics.
+	if (LLSurface::sTextureUpdateTime)
+	{
+		LLSurface::sTexelsUpdatedPerSecStat.addValue(0.001f*(LLSurface::sTexelsUpdated / LLSurface::sTextureUpdateTime));
+		LLSurface::sTexelsUpdated = 0;
+		LLSurface::sTextureUpdateTime = 0.f;
+	}
+}
+
+
+void output_statistics(void*)
+{
+	llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl;
+	llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl;
+	llinfos << "Num images: " << gImageList.getNumImages() << llendl;
+	llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemory << llendl;
+	llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemory << llendl;
+	llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl;
+	llinfos << "Formatted usage: " << LLImageFormatted::sGlobalFormattedMemory << llendl;
+	llinfos << "Zombie Viewer Objects: " << LLViewerObject::getNumZombieObjects() << llendl;
+	llinfos << "Number of lights: " << gPipeline.getLightCount() << llendl;
+
+	llinfos << "Memory Usage:" << llendl;
+	llinfos << "--------------------------------" << llendl;
+	llinfos << "Pipeline:" << llendl;
+	llinfos << llendl;
+
+#if LL_SMARTHEAP
+	llinfos << "--------------------------------" << llendl;
+	{
+		llinfos << "sizeof(LLVOVolume) = " << sizeof(LLVOVolume) << llendl;
+
+		U32 total_pool_size = 0;
+		U32 total_used_size = 0;
+		MEM_POOL_INFO pool_info;
+		MEM_POOL_STATUS pool_status;
+		U32 pool_num = 0;
+		for(pool_status = MemPoolFirst( &pool_info, 1 ); 
+			pool_status != MEM_POOL_END; 
+			pool_status = MemPoolNext( &pool_info, 1 ) )
+		{
+			llinfos << "Pool #" << pool_num << llendl;
+			if( MEM_POOL_OK != pool_status )
+			{
+				llwarns << "Pool not ok" << llendl;
+				continue;
+			}
+
+			llinfos << "Pool blockSizeFS " << pool_info.blockSizeFS
+				<< " pageSize " << pool_info.pageSize
+				<< llendl;
+
+			U32 pool_count = MemPoolCount(pool_info.pool);
+			llinfos << "Blocks " << pool_count << llendl;
+
+			U32 pool_size = MemPoolSize( pool_info.pool );
+			if( pool_size == MEM_ERROR_RET )
+			{
+				llinfos << "MemPoolSize() failed (" << pool_num << ")" << llendl;
+			}
+			else
+			{
+				llinfos << "MemPool Size " << pool_size / 1024 << "K" << llendl;
+			}
+
+			total_pool_size += pool_size;
+
+			if( !MemPoolLock( pool_info.pool ) )
+			{
+				llinfos << "MemPoolLock failed (" << pool_num << ") " << llendl;
+				continue;
+			}
+
+			U32 used_size = 0; 
+			MEM_POOL_ENTRY entry;
+			entry.entry = NULL;
+			while( MemPoolWalk( pool_info.pool, &entry ) == MEM_POOL_OK )
+			{
+				if( entry.isInUse )
+				{
+					used_size += entry.size;
+				}
+			}
+
+			MemPoolUnlock( pool_info.pool );
+
+			llinfos << "MemPool Used " << used_size/1024 << "K" << llendl;
+			total_used_size += used_size;
+			pool_num++;
+		}
+		
+		llinfos << "Total Pool Size " << total_pool_size/1024 << "K" << llendl;
+		llinfos << "Total Used Size " << total_used_size/1024 << "K" << llendl;
+
+	}
+#endif
+
+	llinfos << "--------------------------------" << llendl;
+	llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl;
+	gTexStaticImageList.dumpByteCount();
+	LLVOAvatar::dumpScratchTextureByteCount();
+	LLTexLayerSetBuffer::dumpTotalByteCount();
+	LLVOAvatar::dumpTotalLocalTextureByteCount();
+	LLTexLayerParamAlpha::dumpCacheByteCount();
+	LLVOAvatar::dumpBakedStatus();
+
+	llinfos << llendl;
+
+	llinfos << "Object counts:" << llendl;
+	S32 i;
+	S32 obj_counts[256];
+//	S32 app_angles[256];
+	for (i = 0; i < 256; i++)
+	{
+		obj_counts[i] = 0;
+	}
+	for (i = 0; i < gObjectList.getNumObjects(); i++)
+	{
+		LLViewerObject *objectp = gObjectList.getObject(i);
+		if (objectp)
+		{
+			obj_counts[objectp->getPCode()]++;
+		}
+	}
+	for (i = 0; i < 256; i++)
+	{
+		if (obj_counts[i])
+		{
+			llinfos << LLPrimitive::pCodeToString(i) << ":" << obj_counts[i] << llendl;
+		}
+	}
+}
+
+
+U32		gTotalLandIn = 0, gTotalLandOut = 0;
+U32		gTotalWaterIn = 0, gTotalWaterOut = 0;
+
+F32		gAveLandCompression = 0.f, gAveWaterCompression = 0.f;
+F32		gBestLandCompression = 1.f, gBestWaterCompression = 1.f;
+F32		gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f;
+
+
+
+U32		gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0;
+U32		gObjectBits = 0;
+F32		gAvgSimPing = 0.f;
+
+
+extern U32  gVisCompared;
+extern U32  gVisTested;
+
+std::map<S32,LLFrameTimer> gDebugTimers;
+
+void update_statistics(U32 frame_count)
+{
+	gTotalWorldBytes += gVLManager.getTotalBytes();
+	gTotalObjectBytes += gObjectBits / 8;
+	gTotalTextureBytes += LLViewerImageList::sTextureBits / 8;
+
+	// make sure we have a valid time delta for this frame
+	if (gFrameIntervalSeconds > 0.f)
+	{
+		if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+		{
+			gViewerStats->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds);
+		}
+		else if (gAgent.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
+		{
+			gViewerStats->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds);
+		}
+		else if (gFloaterTools && gFloaterTools->getVisible())
+		{
+			gViewerStats->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
+		}
+	}
+	gViewerStats->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
+	gViewerStats->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail"));
+	gViewerStats->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
+	gViewerStats->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
+#if 0 // 1.9.2
+	gViewerStats->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject"));
+	gViewerStats->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar"));
+	gViewerStats->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment"));
+#endif
+	gViewerStats->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_FRAME));
+	F64 idle_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IDLE);
+	F64 network_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_NETWORK);
+	gViewerStats->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
+	gViewerStats->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
+	gViewerStats->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IMAGE_UPDATE));
+	gViewerStats->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_REBUILD));
+	gViewerStats->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_RENDER_GEOMETRY));
+		
+	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
+	if (cdp)
+	{
+		gViewerStats->mSimPingStat.addValue(cdp->getPingDelay());
+		gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);
+		gSimPingCount++;
+	}
+	else
+	{
+		gViewerStats->mSimPingStat.addValue(10000);
+	}
+
+	gViewerStats->mFPSStat.addValue(1);
+	F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
+	gViewerStats->mLayersKBitStat.addValue(layer_bits/1024.f);
+	gViewerStats->mObjectKBitStat.addValue(gObjectBits/1024.f);
+	gViewerStats->mTextureKBitStat.addValue(LLViewerImageList::sTextureBits/1024.f);
+	gViewerStats->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
+	gViewerStats->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
+	gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
+
+	static S32 tex_bits_idle_count = 0;
+	if (LLViewerImageList::sTextureBits == 0)
+	{
+		if (++tex_bits_idle_count >= 30)
+			gDebugTimers[0].pause();
+	}
+	else
+	{
+		tex_bits_idle_count = 0;
+		gDebugTimers[0].unpause();
+	}
+	
+	gViewerStats->mTexturePacketsStat.addValue(LLViewerImageList::sTexturePackets);
+
+	// log when the LibXUL (aka Mozilla) widget is used and opened so we can monitor framerate changes
+	#if LL_LIBXUL_ENABLED
+	{
+		BOOL result = gViewerHtmlHelp.getFloaterOpened();
+		gViewerStats->setStat(LLViewerStats::ST_LIBXUL_WIDGET_USED, (F64)result);
+	}
+	#endif
+
+	{
+		static F32 visible_avatar_frames = 0.f;
+		static F32 avg_visible_avatars = 0;
+		F32 visible_avatars = (F32)LLVOAvatar::sNumVisibleAvatars;
+		if (visible_avatars > 0.f)
+		{
+			visible_avatar_frames = 1.f;
+			avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;
+		}
+		gViewerStats->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
+	}
+	gWorldp->updateNetStats();
+	gWorldp->requestCacheMisses();
+	
+	// Reset all of these values.
+	gVLManager.resetBitCounts();
+	gObjectBits = 0;
+//	gDecodedBits = 0;
+
+	LLViewerImageList::sTextureBits = 0;
+	LLViewerImageList::sTexturePackets = 0;
+
+#if LL_WINDOWS && LL_LCD_COMPILE
+	bool LCDenabled = gLcdScreen->Enabled();
+	gViewerStats->setStat(LLViewerStats::ST_LOGITECH_LCD, LCDenabled);
+#else
+	gViewerStats->setStat(LLViewerStats::ST_LOGITECH_LCD, false);
+#endif
+}
+
+class ViewerStatsResponder : public LLHTTPClient::Responder
+{
+public:
+    ViewerStatsResponder() { }
+
+    void error(U32 statusNum, const std::string& reason)
+    {
+		llinfos << "ViewerStatsResponder::error " << statusNum << " "
+				<< reason << llendl;
+    }
+
+    void result(const LLSD& content)
+    {
+		llinfos << "ViewerStatsResponder::result" << llendl;
+	}
+};
+
+/*
+ * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats.
+ *
+ * There's also a compatibility shim for the old fixed-format sim
+ * stats in newsim/llagentinfo.cpp:processViewerStats.
+ *
+ * If you move stats around here, make the corresponding changes in
+ * those locations, too.
+ */
+void send_stats()
+{
+	// IW 9/23/02 I elected not to move this into LLViewerStats
+	// because it depends on too many viewer.cpp globals.
+	// Someday we may want to merge all our stats into a central place
+	// but that day is not today.
+
+	// Only send stats if the agent is connected to a region.
+	if (!gAgent.getRegion() || gNoRender)
+	{
+		return;
+	}
+
+	LLSD body;
+	std::string url = gAgent.getRegion()->getCapability("ViewerStats");
+
+	if (url.empty()) {
+		llwarns << "Could not get ViewerStats capability" << llendl;
+		return;
+	}
+	
+	body["session_id"] = gAgentSessionID;
+	
+	LLSD &agent = body["agent"];
+	
+	time_t ltime;
+	time(&ltime);
+	F32 run_time = F32(LLFrameTimer::getElapsedSeconds());
+
+	agent["start_time"] = ltime - run_time;
+	agent["run_time"] = run_time;
+	// send fps only for time app spends in foreground
+	agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
+	agent["version"] = gCurrentVersion;
+	
+	agent["sim_fps"] = ((F32) gFrameCount - gSimFrames) /
+		(F32) (gRenderStartTime.getElapsedTimeF32() - gSimLastTime);
+
+	gSimLastTime = gRenderStartTime.getElapsedTimeF32();
+	gSimFrames   = (F32) gFrameCount;
+
+	agent["agents_in_view"] = LLVOAvatar::sNumVisibleAvatars;
+	agent["ping"] = gAvgSimPing;
+	agent["meters_traveled"] = gAgent.getDistanceTraveled();
+	agent["regions_visited"] = gAgent.getRegionsVisited();
+	agent["mem_use"] = getCurrentRSS() / 1024.0;
+
+	LLSD &system = body["system"];
+	
+	system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB();
+	system["os"] = LLAppViewer::instance()->getOSInfo().getOSString();
+	system["cpu"] = gSysCPU.getCPUString();
+
+	std::string gpu_desc = llformat(
+		"%-6s Class %d ",
+		gGLManager.mGLVendorShort.substr(0,6).c_str(),
+		gFeatureManagerp->getGPUClass())
+		+ gFeatureManagerp->getGPUString();
+
+	system["gpu"] = gpu_desc;
+	system["gpu_class"] = gFeatureManagerp->getGPUClass();
+	system["gpu_vendor"] = gGLManager.mGLVendorShort;
+	system["gpu_version"] = gGLManager.mDriverVersionVendorString;
+
+	LLSD &download = body["downloads"];
+
+	download["world_kbytes"] = gTotalWorldBytes / 1024.0;
+	download["object_kbytes"] = gTotalObjectBytes / 1024.0;
+	download["texture_kbytes"] = gTotalTextureBytes / 1024.0;
+
+	LLSD &in = body["stats"]["net"]["in"];
+
+	in["kbytes"] = gMessageSystem->mTotalBytesIn / 1024.0;
+	in["packets"] = (S32) gMessageSystem->mPacketsIn;
+	in["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsIn;
+	in["savings"] = (gMessageSystem->mUncompressedBytesIn -
+					 gMessageSystem->mCompressedBytesIn) / 1024.0;
+	
+	LLSD &out = body["stats"]["net"]["out"];
+	
+	out["kbytes"] = gMessageSystem->mTotalBytesOut / 1024.0;
+	out["packets"] = (S32) gMessageSystem->mPacketsOut;
+	out["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsOut;
+	out["savings"] = (gMessageSystem->mUncompressedBytesOut -
+					  gMessageSystem->mCompressedBytesOut) / 1024.0;
+
+	LLSD &fail = body["stats"]["failures"];
+
+	fail["send_packet"] = (S32) gMessageSystem->mSendPacketFailureCount;
+	fail["dropped"] = (S32) gMessageSystem->mDroppedPackets;
+	fail["resent"] = (S32) gMessageSystem->mResentPackets;
+	fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets;
+	fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets;
+	fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets;
+
+	gViewerStats->addToMessage(body);
+
+	LLHTTPClient::post(url, body, new ViewerStatsResponder());
+}
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 3c959a53507ebdcb97bde76d0b5f00f855345b04..735da591502fb73b7e9478b185da387af7f9fea6 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -94,7 +94,6 @@ class LLViewerStats
 
 
 	LLStat mSimPingStat;
-	LLStat mUserserverPingStat;
 
 	void resetStats();
 public:
@@ -188,4 +187,10 @@ class LLViewerStats
 
 extern LLViewerStats *gViewerStats;
 
+// The following are from (older?) statistics code found in appviewer.
+void reset_statistics();
+void output_statistics(void*);
+void update_statistics(U32 frame_count);
+
+extern std::map<S32,LLFrameTimer> gDebugTimers;
 #endif // LL_LLVIEWERSTATS_H
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 1e75e421a14716ce9856fae141810fb617b42bcd..81de1eb9a8c0fde9b7c02e3e86dd3cb03a8a0799 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -58,7 +58,7 @@
 #include "llmemorystream.h"
 #include "llmenugl.h"
 
-extern BOOL gPacificDaylightTime;
+#include "llappviewer.h" // for gPacificDaylightTime
 
 ///----------------------------------------------------------------------------
 /// Class LLEmbeddedNotecardOpener
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 7aaf9c0652ed802bf905a3f3dd57c6c63c0bcfeb..e7e2151353fdd557ece89338e6762508640571e1 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -161,6 +161,7 @@
 #include "llvieweruictrlfactory.h"
 #include "lluploaddialog.h"
 #include "llurldispatcher.h"		// SLURL from other app instance
+#include "llvieweraudio.h"
 #include "llviewercamera.h"
 #include "llviewergesture.h"
 #include "llviewerimagelist.h"
@@ -178,7 +179,9 @@
 #include "llworldmapview.h"
 #include "moviemaker.h"
 #include "pipeline.h"
-#include "viewer.h"
+#include "llappviewer.h"
+#include "llurlsimstring.h"
+#include "llviewerdisplay.h"
 
 #if LL_WINDOWS
 #include "llwindebug.h"
@@ -240,6 +243,12 @@ BOOL			gbCapturing = FALSE;
 MovieMaker		gMovieMaker;
 #endif
 
+// HUD display lines in lower right
+BOOL				gDisplayWindInfo = FALSE;
+BOOL				gDisplayCameraPos = FALSE;
+BOOL				gDisplayNearestWater = FALSE;
+BOOL				gDisplayFOV = FALSE;
+
 S32 CHAT_BAR_HEIGHT = 28; 
 S32 OVERLAY_BAR_HEIGHT = 20;
 
@@ -1192,14 +1201,14 @@ BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)
 {
 	// User has indicated they want to close, but we may need to ask
 	// about modified documents.
-	app_user_quit();
+	LLAppViewer::instance()->userQuit();
 	// Don't quit immediately
 	return FALSE;
 }
 
 void LLViewerWindow::handleQuit(LLWindow *window)
 {
-	app_force_quit(NULL);
+	LLAppViewer::instance()->forceQuit();
 }
 
 void LLViewerWindow::handleResize(LLWindow *window,  S32 width,  S32 height)
@@ -1315,7 +1324,7 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
 		gAgent.clearAFK();
 		if (mWindow->getFullscreen() && !mIgnoreActivate)
 		{
-			if (!gQuit)
+			if (!LLApp::isExiting() )
 			{
 				if (LLStartUp::getStartupState() >= STATE_STARTED)
 				{
@@ -1505,7 +1514,7 @@ LLViewerWindow::LLViewerWindow(
 		llwarns << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
 				<< llendl;
 #endif
-		app_force_exit(1);
+        LLAppViewer::instance()->forceExit(1);
 	}
 	
 	// Get the real window rect the window was created with (since there are various OS-dependent reasons why
@@ -2107,7 +2116,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
 	// reshape messages.  We don't care about these, and we
 	// don't want to send messages because the message system
 	// may have been destructed.
-	if (!gQuit)
+	if (!LLApp::isExiting())
 	{
 		if (gNoRender)
 		{
@@ -4715,9 +4724,9 @@ void LLViewerWindow::stopGL(BOOL save_state)
 		llinfos << "Shutting down GL..." << llendl;
 
 		// Pause texture decode threads (will get unpaused during main loop)
-		gTextureCache->pause();
-		gImageDecodeThread->pause();
-		gTextureFetch->pause();
+		LLAppViewer::getTextureCache()->pause();
+		LLAppViewer::getImageDecodeThread()->pause();
+		LLAppViewer::getTextureFetch()->pause();
 		
 		gSky.destroyGL();
 		stop_glerror();
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index fcd15974f61892b2aa094efa43a8477dd6d716e3..faab518879974f850567a052e9fe73d385e34595 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -416,4 +416,10 @@ extern BOOL				gPickTransparent;
 
 extern BOOL				gDebugFastUIRender;
 extern S32 CHAT_BAR_HEIGHT; 
+
+extern BOOL			gDisplayCameraPos;
+extern BOOL			gDisplayWindInfo;
+extern BOOL			gDisplayNearestWater;
+extern BOOL			gDisplayFOV;
+
 #endif
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 4905ff82b912704763f1f5db2266e7f5ff2edccd..7a225c8a12bee5b78160d07fcaacb97e3e3fdadf 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -114,7 +114,7 @@
 #include "llworld.h"
 #include "pipeline.h"
 #include "llglslshader.h"
-#include "viewer.h"
+#include "llappviewer.h"
 #include "lscript_byteformat.h"
 
 //#include "vtune/vtuneapi.h"
@@ -1622,7 +1622,6 @@ BOOL LLVOAvatar::buildSkeleton(LLVOAvatarSkeletonInfo *info)
 // LLVOAvatar::buildCharacter()
 // Deferred initialization and rebuild of the avatar.
 //-----------------------------------------------------------------------------
-extern BOOL gPrintMessagesThisFrame;
 void LLVOAvatar::buildCharacter()
 {
 	LLMemType mt(LLMemType::MTYPE_AVATAR);
@@ -7439,7 +7438,7 @@ void LLVOAvatar::onCustomizeEnd()
 
 		avatar->updateMeshTextures();
 
-		if( !gQuit )
+		if( !LLApp::isExiting())
 		{
 			avatar->requestLayerSetUploads();
 		}
diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp
index 07cfcea8bce00903b10bc3bb6a919c8f9f4a3192..7a2ba609e87c56270f30238b9d7409dacf5ebd93 100644
--- a/indra/newview/llvoclouds.cpp
+++ b/indra/newview/llvoclouds.cpp
@@ -49,7 +49,9 @@
 #include "llvosky.h"
 #include "llworld.h"
 #include "pipeline.h"
-#include "viewer.h"
+
+LLUUID gCloudTextureID = IMG_CLOUD_POOF;
+
 
 LLVOClouds::LLVOClouds(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
 :	LLAlphaObject(id, LL_VO_CLOUDS, regionp)
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index f6f7ce7d5b561559c5dec2876fda9ba2e2a9329f..cf6b13e74ca9f605f0f93ec698689accacf22bae 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -42,12 +42,12 @@
 #include "expat/expat.h"
 #include "llcallbacklist.h"
 #include "llviewerregion.h"
-#include "llviewernetwork.h"		// for gUserServerChoice
+#include "llviewernetwork.h"		// for gGridChoice
 #include "llfloateractivespeakers.h"	// for LLSpeakerMgr
 #include "llbase64.h"
 #include "llviewercontrol.h"
 #include "llkeyboard.h"
-#include "viewer.h"	// for gDisconnected, gDisableVoice
+#include "llappviewer.h"	// for gDisconnected, gDisableVoice
 #include "llmutelist.h"  // to check for muted avatars
 #include "llagent.h"
 #include "llcachename.h"
@@ -1052,10 +1052,10 @@ void LLVoiceClient::userAuthorized(const std::string& firstName, const std::stri
 
 	llinfos << "name \"" << mAccountDisplayName << "\" , ID " << agentID << llendl;
 
-	std::string userserver = gUserServerName;
-	LLString::toLower(userserver);
-	if((gUserServerChoice == USERSERVER_AGNI) || 
-		((gUserServerChoice == USERSERVER_OTHER) && (userserver.find("agni") != std::string::npos)))
+	std::string gridname = gGridName;
+	LLString::toLower(gridname);
+	if((gGridChoice == GRID_INFO_AGNI) || 
+		((gGridChoice == GRID_INFO_OTHER) && (gridname.find("agni") != std::string::npos)))
 	{
 		sConnectingToAgni = true;
 	}
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index d3c24a6e727a7b6cfecd3991648fbd54d4382dfe..b8d994d095b3c96a64ca41bdbc09bf3d916485fa 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -53,7 +53,6 @@
 #include "llviewerregion.h"
 #include "llworld.h"
 #include "pipeline.h"
-#include "viewer.h"		// for gSunTextureID
 
 const S32 NUM_TILES_X = 8;
 const S32 NUM_TILES_Y = 4;
@@ -72,6 +71,10 @@ const LLVector2 TEX01 = LLVector2(0.f, 1.f);
 const LLVector2 TEX10 = LLVector2(1.f, 0.f);
 const LLVector2 TEX11 = LLVector2(1.f, 1.f);
 
+// Exported globals
+LLUUID gSunTextureID = IMG_SUN;
+LLUUID gMoonTextureID = IMG_MOON;
+
 //static 
 LLColor3 LLHaze::sAirScaSeaLevel;
 
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 4020114ce5ab4f15b705dec2b5f40d242450d925..f3bceb065327c4977d7b684f7018b7033db439ac 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -69,6 +69,12 @@ const F32 fsigma	= (6.f + 3.f * sigma) / (6.f-7.f*sigma);
 const F64 Ndens		= 2.55e25;
 const F64 Ndens2	= Ndens*Ndens;
 
+// HACK: Allow server to change sun and moon IDs.
+// I can't figure out how to pass the appropriate
+// information into the LLVOSky constructor.  JC
+extern LLUUID gSunTextureID;
+extern LLUUID gMoonTextureID;
+
 
 LL_FORCE_INLINE LLColor3 color_div(const LLColor3 &col1, const LLColor3 &col2)
 {
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index 4222e843b28aef3113b1d3a81662b64492b23f97..b4e79109ace47b7a58d688c439d3248b0f6c8ea5 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -48,9 +48,6 @@
 #include "llvoavatar.h"
 #include "llwearable.h"
 
-//#include "viewer.h"
-//#include "llvfs.h"
-
 // static
 S32 LLWearable::sCurrentDefinitionVersion = 1;
 
diff --git a/indra/newview/llwind.cpp b/indra/newview/llwind.cpp
index b04299b924f554d03b29635cfea7696d51b5030a..96a985f69407a71c01de7fb5bbce57e967705713 100644
--- a/indra/newview/llwind.cpp
+++ b/indra/newview/llwind.cpp
@@ -48,7 +48,6 @@
 // viewer
 #include "noise.h"
 #include "v4color.h"
-#include "viewer.h"
 #include "llagent.h"
 #include "llworld.h"
 
diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp
index b65262c15cad82903bed21276deb0a48f50cb2fb..88ba5822eb423232524940e28e7f9a7699c390ba 100644
--- a/indra/newview/llwindebug.cpp
+++ b/indra/newview/llwindebug.cpp
@@ -37,12 +37,8 @@
 #include "llviewercontrol.h"
 #include "lldir.h"
 
-// From viewer.h
-extern BOOL gInProductionGrid;
+#include "llappviewer.h"
 
-extern void (*gCrashCallback)(void);
-extern void write_debug(const char *str);
-extern void write_debug(const std::string &str);
 
 // based on dbghelp.h
 typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,
@@ -123,7 +119,7 @@ BOOL LLWinDebug::setupExceptionHandler()
 			msg += local_dll_name;
 			msg += "!\n";
 
-			write_debug(msg.c_str());
+			LLAppViewer::instance()->writeDebug(msg.c_str());
 
 			ok = FALSE;
 		}
@@ -133,7 +129,7 @@ BOOL LLWinDebug::setupExceptionHandler()
 
 			if (!f_mdwp)
 			{
-				write_debug("No MiniDumpWriteDump!\n");
+				LLAppViewer::instance()->writeDebug("No MiniDumpWriteDump!\n");
 				FreeLibrary(hDll);
 				hDll = NULL;
 				ok = FALSE;
@@ -143,25 +139,29 @@ BOOL LLWinDebug::setupExceptionHandler()
 		gEmergencyMemoryReserve.reserve();
 	}
 
-	LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
-	prev_filter = SetUnhandledExceptionFilter(LLWinDebug::handleException);
+	// *REMOVE: LLApp now handles the exception handing. 
+	//            LLAppViewerWin32 calls SetUnhandledExceptionFilter()
+
+	//LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
+	//prev_filter = SetUnhandledExceptionFilter(LLWinDebug::handleException);
+
+	//if (s_first_run)
+	//{
+	//	// We're fine, this is the first run.
+	//	s_first_run = FALSE;
+	//	return ok;
+	//}
+	//if (!prev_filter)
+	//{
+	//	llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with NULL!" << llendl;
+	//	ok = FALSE;
+	//}
+	//if (prev_filter != LLWinDebug::handleException)
+	//{
+	//	llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with " << prev_filter << "!" << llendl;
+	//	ok = FALSE;
+	//}
 
-	if (s_first_run)
-	{
-		// We're fine, this is the first run.
-		s_first_run = FALSE;
-		return ok;
-	}
-	if (!prev_filter)
-	{
-		llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with NULL!" << llendl;
-		ok = FALSE;
-	}
-	if (prev_filter != LLWinDebug::handleException)
-	{
-		llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with " << prev_filter << "!" << llendl;
-		ok = FALSE;
-	}
 	return ok;
 #else
 	// Internal builds don't mess with exception handling.
@@ -173,11 +173,11 @@ void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMAT
 {
 	if(f_mdwp == NULL) 
 	{
-		write_debug("No way to generate a minidump, no MiniDumpWriteDump function!\n");
+		LLAppViewer::instance()->writeDebug("No way to generate a minidump, no MiniDumpWriteDump function!\n");
 	}
 	else if(gDirUtilp == NULL)
 	{
-		write_debug("No way to generate a minidump, no gDirUtilp!\n");
+		LLAppViewer::instance()->writeDebug("No way to generate a minidump, no gDirUtilp!\n");
 	}
 	else
 	{
@@ -212,6 +212,8 @@ void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMAT
 // static
 LONG LLWinDebug::handleException(struct _EXCEPTION_POINTERS *exception_infop)
 {
+	// *NOTE:Mani - This method is no longer the initial exception handler.
+	// It is called from viewer_windows_exception_handler() and other places.
 
 	// 
 	// Let go of a bunch of reserved memory to give library calls etc
@@ -256,15 +258,6 @@ LONG LLWinDebug::handleException(struct _EXCEPTION_POINTERS *exception_infop)
 		return EXCEPTION_CONTINUE_SEARCH;
 	}
 
-	//
-	// Call the newview crash callback, which will spawn the crash
-	// reporter.  It may or may not spawn a dialog.
-	//
-	if (gCrashCallback)
-	{
-		gCrashCallback();
-	}
-
 	//
 	// At this point, we always want to exit the app.  There's no graceful
 	// recovery for an unhandled exception.
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index dd3223ce78ee6a1bf866f97c2f7c6be9813cbe43..36be05fe7f4594a4714da4081c88cfa537e56c41 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -56,7 +56,7 @@
 #include "llvowater.h"
 #include "message.h"
 #include "pipeline.h"
-#include "viewer.h"		// for do_disconnect()
+#include "llappviewer.h"		// for do_disconnect()
 
 //
 // Globals
@@ -248,7 +248,7 @@ void LLWorld::removeRegion(const LLHost &host)
 		llwarns << "gFrameTimeSeconds " << gFrameTimeSeconds << llendl;
 
 		llwarns << "Disabling region " << regionp->getName() << " that agent is in!" << llendl;
-		do_disconnect("You have been disconnected from the region you were in.");
+		LLAppViewer::instance()->forceDisconnect("You have been disconnected from the region you were in.");
 		return;
 	}
 
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 6ba10ea0a9129bc4a8a588387fbd1c4f5e5c2b13..50c9ceeb0a335fbf6edab3212f8e0debd995963c 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -36,7 +36,7 @@
 #include "llregionhandle.h"
 #include "message.h"
 
-#include "viewer.h"	// for gPacificDaylightTime
+#include "llappviewer.h"	// for gPacificDaylightTime
 #include "llagent.h"
 #include "llmapresponders.h"
 #include "llviewercontrol.h"
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index dc689102f353ec96148d7cf5a28dd6e541685c04..dac693885f2d58cbe8257c7adfbc428190efb553 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -61,7 +61,7 @@
 #include "llviewerwindow.h"
 #include "llworld.h"
 #include "llworldmap.h"
-#include "viewer.h"				// Only for constants!
+#include "llappviewer.h"				// Only for constants!
 
 #include "llglheaders.h"
 
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 905e35cb225b25da2acce02f28c7128fb171c33e..3df2073c6a7e3bdde715955f18dee084817d17ae 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -39,7 +39,7 @@
 #include <curl/curl.h>
 #include <xmlrpc-epi/xmlrpc.h>
 
-#include "viewer.h"
+#include "llappviewer.h"
 
 LLXMLRPCValue LLXMLRPCValue::operator[](const char* id) const
 {
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 758455df6ae4df0445db9e2b435597be6e1e4ea3..559db5fc892c0da2cf292705b4994b76acddb0aa 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -91,11 +91,11 @@
 #include "llvotree.h"
 #include "llvopartgroup.h"
 #include "llworld.h"
-#include "viewer.h"
 #include "llcubemap.h"
 #include "lldebugmessagebox.h"
 #include "llglslshader.h"
 #include "llviewerjoystick.h"
+#include "llviewerdisplay.h"
 
 #ifdef _DEBUG
 // Debug indices is disabled for now for debug performance - djs 4/24/02
@@ -135,6 +135,8 @@ S32		gTrivialAccepts = 0;
 
 BOOL	gRenderForSelect = FALSE;
 
+LLPipeline gPipeline;
+
 //----------------------------------------
 
 void stamp(F32 x, F32 y, F32 xs, F32 ys)