diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 6ea63809f85e65b8318ce18f03652acf0a2eb7fd..c86c89fa9b30eba2f8933b1014bb74abe70d71bb 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -57,9 +57,12 @@
 BOOL gDebugSession = FALSE;
 BOOL gDebugGL = FALSE;
 BOOL gClothRipple = FALSE;
-BOOL gNoRender = FALSE;
+BOOL gHeadlessClient = FALSE;
 BOOL gGLActive = FALSE;
 
+static const std::string HEADLESS_VENDOR_STRING("Linden Lab");
+static const std::string HEADLESS_RENDERER_STRING("Headless");
+static const std::string HEADLESS_VERSION_STRING("1.0");
 
 std::ofstream gFailLog;
 
@@ -538,9 +541,19 @@ void LLGLManager::setToDebugGPU()
 
 void LLGLManager::getGLInfo(LLSD& info)
 {
-	info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
-	info["GLInfo"]["GLRenderer"] = std::string((const char *)glGetString(GL_RENDERER));
-	info["GLInfo"]["GLVersion"] = std::string((const char *)glGetString(GL_VERSION));
+	if (gHeadlessClient)
+	{
+		info["GLInfo"]["GLVendor"] = HEADLESS_VENDOR_STRING;
+		info["GLInfo"]["GLRenderer"] = HEADLESS_RENDERER_STRING;
+		info["GLInfo"]["GLVersion"] = HEADLESS_VERSION_STRING;
+		return;
+	}
+	else
+	{
+		info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
+		info["GLInfo"]["GLRenderer"] = std::string((const char *)glGetString(GL_RENDERER));
+		info["GLInfo"]["GLVersion"] = std::string((const char *)glGetString(GL_VERSION));
+	}
 
 #if !LL_MESA_HEADLESS
 	std::string all_exts = ll_safe_string((const char *)gGLHExts.mSysExts);
@@ -556,14 +569,22 @@ void LLGLManager::getGLInfo(LLSD& info)
 std::string LLGLManager::getGLInfoString()
 {
 	std::string info_str;
-	std::string all_exts, line;
 
-	info_str += std::string("GL_VENDOR      ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
-	info_str += std::string("GL_RENDERER    ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
-	info_str += std::string("GL_VERSION     ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
+	if (gHeadlessClient)
+	{
+		info_str += std::string("GL_VENDOR      ") + HEADLESS_VENDOR_STRING + std::string("\n");
+		info_str += std::string("GL_RENDERER    ") + HEADLESS_RENDERER_STRING + std::string("\n");
+		info_str += std::string("GL_VERSION     ") + HEADLESS_VERSION_STRING + std::string("\n");
+	}
+	else
+	{
+		info_str += std::string("GL_VENDOR      ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
+		info_str += std::string("GL_RENDERER    ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
+		info_str += std::string("GL_VERSION     ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
+	}
 
 #if !LL_MESA_HEADLESS 
-	all_exts = (const char *)gGLHExts.mSysExts;
+	std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
 	LLStringUtil::replaceChar(all_exts, ' ', '\n');
 	info_str += std::string("GL_EXTENSIONS:\n") + all_exts + std::string("\n");
 #endif
@@ -573,15 +594,21 @@ std::string LLGLManager::getGLInfoString()
 
 void LLGLManager::printGLInfoString()
 {
-	std::string info_str;
-	std::string all_exts, line;
-	
-	LL_INFOS("RenderInit") << "GL_VENDOR:     " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
-	LL_INFOS("RenderInit") << "GL_RENDERER:   " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
-	LL_INFOS("RenderInit") << "GL_VERSION:    " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
+	if (gHeadlessClient)
+	{
+		LL_INFOS("RenderInit") << "GL_VENDOR:     " << HEADLESS_VENDOR_STRING << LL_ENDL;
+		LL_INFOS("RenderInit") << "GL_RENDERER:   " << HEADLESS_RENDERER_STRING << LL_ENDL;
+		LL_INFOS("RenderInit") << "GL_VERSION:    " << HEADLESS_VERSION_STRING << LL_ENDL;
+	}
+	else
+	{
+		LL_INFOS("RenderInit") << "GL_VENDOR:     " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
+		LL_INFOS("RenderInit") << "GL_RENDERER:   " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
+		LL_INFOS("RenderInit") << "GL_VERSION:    " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
+	}
 
 #if !LL_MESA_HEADLESS
-	all_exts = std::string(gGLHExts.mSysExts);
+	std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
 	LLStringUtil::replaceChar(all_exts, ' ', '\n');
 	LL_DEBUGS("RenderInit") << "GL_EXTENSIONS:\n" << all_exts << LL_ENDL;
 #endif
@@ -590,7 +617,14 @@ void LLGLManager::printGLInfoString()
 std::string LLGLManager::getRawGLString()
 {
 	std::string gl_string;
-	gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
+	if (gHeadlessClient)
+	{
+		gl_string = HEADLESS_VENDOR_STRING + " " + HEADLESS_RENDERER_STRING;
+	}
+	else
+	{
+		gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
+	}
 	return gl_string;
 }
 
@@ -614,47 +648,47 @@ void LLGLManager::initExtensions()
 	mHasMultitexture = TRUE;
 # else
 	mHasMultitexture = FALSE;
-# endif
+# endif // GL_ARB_multitexture
 # ifdef GL_ARB_texture_env_combine
 	mHasARBEnvCombine = TRUE;	
 # else
 	mHasARBEnvCombine = FALSE;
-# endif
+# endif // GL_ARB_texture_env_combine
 # ifdef GL_ARB_texture_compression
 	mHasCompressedTextures = TRUE;
 # else
 	mHasCompressedTextures = FALSE;
-# endif
+# endif // GL_ARB_texture_compression
 # ifdef GL_ARB_vertex_buffer_object
 	mHasVertexBufferObject = TRUE;
 # else
 	mHasVertexBufferObject = FALSE;
-# endif
+# endif // GL_ARB_vertex_buffer_object
 # ifdef GL_EXT_framebuffer_object
 	mHasFramebufferObject = TRUE;
 # else
 	mHasFramebufferObject = FALSE;
-# endif
+# endif // GL_EXT_framebuffer_object
 # ifdef GL_EXT_framebuffer_multisample
 	mHasFramebufferMultisample = TRUE;
 # else
 	mHasFramebufferMultisample = FALSE;
-# endif
+# endif // GL_EXT_framebuffer_multisample
 # ifdef GL_ARB_draw_buffers
 	mHasDrawBuffers = TRUE;
 #else
 	mHasDrawBuffers = FALSE;
-# endif
+# endif // GL_ARB_draw_buffers
 # if defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp)
 	mHasDepthClamp = TRUE;
 #else
 	mHasDepthClamp = FALSE;
-#endif
+#endif // defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp)
 # if GL_EXT_blend_func_separate
 	mHasBlendFuncSeparate = TRUE;
 #else
 	mHasBlendFuncSeparate = FALSE;
-# endif
+# endif // GL_EXT_blend_func_separate
 	mHasMipMapGeneration = FALSE;
 	mHasSeparateSpecularColor = FALSE;
 	mHasAnisotropic = FALSE;
@@ -1145,7 +1179,7 @@ void assert_glerror()
 		}
 	}
 
-	if (!gNoRender && gDebugGL) 
+	if (gDebugGL) 
 	{
 		do_assert_glerror();
 	}
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 85fab7a0f82cfc1a3b0b80aa31f751c3b3caa886..684fd508834329eec9843d4ca74e8e70bb9931b5 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -415,7 +415,7 @@ void set_binormals(const S32 index, const U32 stride, const LLVector3 *binormals
 void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific );
 
 extern BOOL gClothRipple;
-extern BOOL gNoRender;
+extern BOOL gHeadlessClient;
 extern BOOL gGLActive;
 
 #endif // LL_LLGL_H
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index e8e98211f1c1db2e2380bfa848712946f5be6afc..d4ffd6f88e630cd94a32274606e2e06569f193dc 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -967,12 +967,14 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
 	}
 	if (mTexName == 0)
 	{
-		llwarns << "Setting subimage on image without GL texture" << llendl;
+		// *TODO: Re-enable warning?  Ran into thread locking issues? DK 2011-02-18
+		//llwarns << "Setting subimage on image without GL texture" << llendl;
 		return FALSE;
 	}
 	if (datap == NULL)
 	{
-		llwarns << "Setting subimage on image with NULL datap" << llendl;
+		// *TODO: Re-enable warning?  Ran into thread locking issues? DK 2011-02-18
+		//llwarns << "Setting subimage on image with NULL datap" << llendl;
 		return FALSE;
 	}
 	
@@ -1100,6 +1102,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
 //the texture is assiciate with some image by calling glTexImage outside LLImageGL
 BOOL LLImageGL::createGLTexture()
 {
+	if (gHeadlessClient) return FALSE;
 	if (gGLManager.mIsDisabled)
 	{
 		llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@@ -1128,6 +1131,7 @@ BOOL LLImageGL::createGLTexture()
 
 BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
 {
+	if (gHeadlessClient) return FALSE;
 	if (gGLManager.mIsDisabled)
 	{
 		llwarns << "Trying to create a texture while GL is disabled!" << llendl;
diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp
index 35398f1c099a628fb08b6528a711bebf899608bd..2e811ab23fa3bb97c4d21d48be64f3a9e3cad62e 100644
--- a/indra/llwindow/llwindowheadless.cpp
+++ b/indra/llwindow/llwindowheadless.cpp
@@ -28,6 +28,7 @@
 #include "indra_constants.h"
 
 #include "llwindowheadless.h"
+#include "llgl.h"
 
 //
 // LLWindowHeadless
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ced46c72949ce04ab40d9d66f62b08af05091d4e..603fddbccd5ee4b1b3532fbc3d54025ae51fbd36 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2612,10 +2612,10 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>DisableRendering</key>
+    <key>HeadlessClient</key>
     <map>
       <key>Comment</key>
-      <string>Disable GL rendering and GUI (load testing)</string>
+      <string>Run in headless mode by disabling GL rendering, keyboard, etc</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 7d908df5ceed5469064c52543e304114be028dc7..7d491a777489c0e025c8e0ebc66b0bea377cecd8 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1119,12 +1119,6 @@ void LLAgent::resetControlFlags()
 //-----------------------------------------------------------------------------
 void LLAgent::setAFK()
 {
-	// Drones can't go AFK
-	if (gNoRender)
-	{
-		return;
-	}
-
 	if (!gAgent.getRegion())
 	{
 		// Don't set AFK if we're not talking to a region yet.
@@ -1684,11 +1678,6 @@ void LLAgent::clearRenderState(U8 clearstate)
 //-----------------------------------------------------------------------------
 U8 LLAgent::getRenderState()
 {
-	if (gNoRender || gKeyboard == NULL)
-	{
-		return 0;
-	}
-
 	// *FIX: don't do stuff in a getter!  This is infinite loop city!
 	if ((mTypingTimer.getElapsedTimeF32() > TYPING_TIMEOUT_SECS) 
 		&& (mRenderState & AGENT_STATE_TYPING))
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index f01d5ff1f539121e87b6c3ce373b9fbdb6e2e2d5..6c5c3bcdab1b54242d4435d2c019eb87b2b60366 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -282,25 +282,22 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
 		gAgent.stopAutoPilot(TRUE);
 	}
 
-	if (!gNoRender)
-	{
-		LLSelectMgr::getInstance()->unhighlightAll();
+	LLSelectMgr::getInstance()->unhighlightAll();
 
-		// By popular request, keep land selection while walking around. JC
-		// LLViewerParcelMgr::getInstance()->deselectLand();
+	// By popular request, keep land selection while walking around. JC
+	// LLViewerParcelMgr::getInstance()->deselectLand();
 
-		// force deselect when walking and attachment is selected
-		// this is so people don't wig out when their avatar moves without animating
-		if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
-		{
-			LLSelectMgr::getInstance()->deselectAll();
-		}
+	// force deselect when walking and attachment is selected
+	// this is so people don't wig out when their avatar moves without animating
+	if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
+	{
+		LLSelectMgr::getInstance()->deselectAll();
+	}
 
-		if (gMenuHolder != NULL)
-		{
-			// Hide all popup menus
-			gMenuHolder->hideMenus();
-		}
+	if (gMenuHolder != NULL)
+	{
+		// Hide all popup menus
+		gMenuHolder->hideMenus();
 	}
 
 	if (change_camera && !gSavedSettings.getBOOL("FreezeTime"))
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6a9dfaf21b6cbe21e3ade86ecc8983f129a04e04..25bdaed0c9085b94d46e3e8a9871e4923ff1a540 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -881,7 +881,7 @@ bool LLAppViewer::init()
 	}
 
 	// If we don't have the right GL requirements, exit.
-	if (!gGLManager.mHasRequirements && !gNoRender)
+	if (!gGLManager.mHasRequirements)
 	{	
 		// can't use an alert here since we're exiting and
 		// all hell breaks lose.
@@ -1171,7 +1171,8 @@ bool LLAppViewer::mainLoop()
 				}
 
 				// Render scene.
-				if (!LLApp::isExiting())
+				// *TODO: Should we run display() even during gHeadlessClient?  DK 2011-02-18
+				if (!LLApp::isExiting() && !gHeadlessClient)
 				{
 					pingMainloopTimeout("Main:Display");
 					gGLActive = TRUE;
@@ -1199,8 +1200,7 @@ bool LLAppViewer::mainLoop()
 				}
 
 				// yield cooperatively when not running as foreground window
-				if (   gNoRender
-					   || (gViewerWindow && !gViewerWindow->mWindow->getVisible())
+				if (   (gViewerWindow && !gViewerWindow->mWindow->getVisible())
 						|| !gFocusMgr.getAppHasFocus())
 				{
 					// Sleep if we're not rendering, or the window is minimized.
@@ -2640,7 +2640,8 @@ bool LLAppViewer::initWindow()
 	LL_INFOS("AppInit") << "Initializing window..." << LL_ENDL;
 
 	// store setting in a global for easy access and modification
-	gNoRender = gSavedSettings.getBOOL("DisableRendering");
+	gHeadlessClient = gSavedSettings.getBOOL("DisableRendering") 
+				   || gSavedSettings.getBOOL("HeadlessClient");
 
 	// always start windowed
 	BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth");
@@ -2676,28 +2677,25 @@ bool LLAppViewer::initWindow()
 		gViewerWindow->mWindow->maximize();
 	}
 
-	if (!gNoRender)
+	//
+	// Initialize GL stuff
+	//
+
+	if (mForceGraphicsDetail)
 	{
-		//
-		// Initialize GL stuff
-		//
+		LLFeatureManager::getInstance()->setGraphicsLevel(gSavedSettings.getU32("RenderQualityPerformance"), false);
+	}
+			
+	// Set this flag in case we crash while initializing GL
+	gSavedSettings.setBOOL("RenderInitError", TRUE);
+	gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
 
-		if (mForceGraphicsDetail)
-		{
-			LLFeatureManager::getInstance()->setGraphicsLevel(gSavedSettings.getU32("RenderQualityPerformance"), false);
-		}
-				
-		// Set this flag in case we crash while initializing GL
-		gSavedSettings.setBOOL("RenderInitError", TRUE);
-		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
-	
-		gPipeline.init();
-		stop_glerror();
-		gViewerWindow->initGLDefaults();
+	gPipeline.init();
+	stop_glerror();
+	gViewerWindow->initGLDefaults();
 
-		gSavedSettings.setBOOL("RenderInitError", FALSE);
-		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
-	}
+	gSavedSettings.setBOOL("RenderInitError", FALSE);
+	gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
 
 	//If we have a startup crash, it's usually near GL initialization, so simulate that.
 	if(gCrashOnStartup)
@@ -2739,12 +2737,9 @@ void LLAppViewer::cleanupSavedSettings()
 		
 	gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates);
 	
-	if (!gNoRender)
+	if (gDebugView)
 	{
-		if (gDebugView)
-		{
-			gSavedSettings.setBOOL("ShowDebugConsole", gDebugView->mDebugConsolep->getVisible());
-		}
+		gSavedSettings.setBOOL("ShowDebugConsole", gDebugView->mDebugConsolep->getVisible());
 	}
 
 	// save window position if not maximized
@@ -3711,7 +3706,7 @@ void LLAppViewer::badNetworkHandler()
 // is destroyed.
 void LLAppViewer::saveFinalSnapshot()
 {
-	if (!mSavedFinalSnapshot && !gNoRender)
+	if (!mSavedFinalSnapshot)
 	{
 		gSavedSettings.setVector3d("FocusPosOnLogout", gAgentCamera.calcFocusPositionTargetGlobal());
 		gSavedSettings.setVector3d("CameraPosOnLogout", gAgentCamera.calcCameraPositionTargetGlobal());
@@ -4115,34 +4110,31 @@ void LLAppViewer::idle()
 	//
 	// Update weather effects
 	//
-	if (!gNoRender)
-	{
-		LLWorld::getInstance()->updateClouds(gFrameDTClamped);
-		gSky.propagateHeavenlyBodies(gFrameDTClamped);				// moves sun, moon, and planets
+	LLWorld::getInstance()->updateClouds(gFrameDTClamped);
+	gSky.propagateHeavenlyBodies(gFrameDTClamped);				// moves sun, moon, and planets
 
-		// Update wind vector 
-		LLVector3 wind_position_region;
-		static LLVector3 average_wind;
+	// Update wind vector 
+	LLVector3 wind_position_region;
+	static LLVector3 average_wind;
 
-		LLViewerRegion *regionp;
-		regionp = LLWorld::getInstance()->resolveRegionGlobal(wind_position_region, gAgent.getPositionGlobal());	// puts agent's local coords into wind_position	
-		if (regionp)
-		{
-			gWindVec = regionp->mWind.getVelocity(wind_position_region);
+	LLViewerRegion *regionp;
+	regionp = LLWorld::getInstance()->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);
-		}
+		// 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);
 	}
 	
 	//////////////////////////////////////
@@ -4151,13 +4143,10 @@ void LLAppViewer::idle()
 	// Here, particles are updated and drawables are moved.
 	//
 	
-	if (!gNoRender)
-	{
-		LLFastTimer t(FTM_WORLD_UPDATE);
-		gPipeline.updateMove();
+	LLFastTimer t(FTM_WORLD_UPDATE);
+	gPipeline.updateMove();
 
-		LLWorld::getInstance()->updateParticles();
-	}
+	LLWorld::getInstance()->updateParticles();
 
 	if (LLViewerJoystick::getInstance()->getOverrideCamera())
 	{
@@ -4523,12 +4512,9 @@ void LLAppViewer::disconnectViewer()
 	gSavedSettings.setBOOL("FlyingAtExit", gAgent.getFlying() );
 
 	// Un-minimize all windows so they don't get saved minimized
-	if (!gNoRender)
+	if (gFloaterView)
 	{
-		if (gFloaterView)
-		{
-			gFloaterView->restoreAll();
-		}
+		gFloaterView->restoreAll();
 	}
 
 	if (LLSelectMgr::getInstance())
diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp
index 61cf4dad93a762a7cd7b9b463e649c50b4db7075..eeb81085bbbf017855e1c63eaffabfba95fd6ed1 100644
--- a/indra/newview/llfloaterbump.cpp
+++ b/indra/newview/llfloaterbump.cpp
@@ -38,13 +38,11 @@
 ///----------------------------------------------------------------------------
 /// Class LLFloaterBump
 ///----------------------------------------------------------------------------
-extern BOOL gNoRender;
 
 // Default constructor
 LLFloaterBump::LLFloaterBump(const LLSD& key) 
 :	LLFloater(key)
 {
-	if(gNoRender) return;
 }
 
 
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index 8cf7d23f88fd6e7e460ee7403fccd047cd2ca364..72f64752d6fa9bde666755a3768148507e410456 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -587,11 +587,6 @@ void LLHUDEffectLookAt::update()
  */
 bool LLHUDEffectLookAt::calcTargetPosition()
 {
-	if (gNoRender)
-	{
-		return false;
-	}
-
 	LLViewerObject *target_obj = (LLViewerObject *)mTargetObject;
 	LLVector3 local_offset;
 	
diff --git a/indra/newview/llhudmanager.cpp b/indra/newview/llhudmanager.cpp
index 5f3178b95553b0ba7c2ba3bcb19837901c3df574..8f14b53db0a14bcc37bfccac9fa5b918502469e5 100644
--- a/indra/newview/llhudmanager.cpp
+++ b/indra/newview/llhudmanager.cpp
@@ -38,8 +38,6 @@
 #include "llviewercontrol.h"
 #include "llviewerobjectlist.h"
 
-extern BOOL gNoRender;
-
 // These are loaded from saved settings.
 LLColor4 LLHUDManager::sParentColor;
 LLColor4 LLHUDManager::sChildColor;
@@ -150,11 +148,6 @@ LLHUDEffect *LLHUDManager::createViewerEffect(const U8 type, BOOL send_to_sim, B
 //static
 void LLHUDManager::processViewerEffect(LLMessageSystem *mesgsys, void **user_data)
 {
-	if (gNoRender)
-	{
-		return;
-	}
-
 	LLHUDEffect *effectp = NULL;
 	LLUUID effect_id;
 	U8 effect_type = 0;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 9623554200f4675e0e23997595f2c53c0d360169..060ad17c02e9fb46dce74a9d4ed5e82d7950a24a 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -3174,10 +3174,6 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 			//just like a normal IM
 			//this is just replicated code from process_improved_im
 			//and should really go in it's own function -jwolk
-			if (gNoRender)
-			{
-				return;
-			}
 			LLChat chat;
 
 			std::string message = message_params["message"].asString();
@@ -3254,11 +3250,6 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 		} //end if invitation has instant message
 		else if ( input["body"].has("voice") )
 		{
-			if (gNoRender)
-			{
-				return;
-			}
-			
 			if(!LLVoiceClient::getInstance()->voiceEnabled() || !LLVoiceClient::getInstance()->isVoiceWorking())
 			{
 				// Don't display voice invites unless the user has voice enabled.
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index da891d1c51526a8fa1bfd68178289db8d3d70029..81f4dd802aa751d5ebb84f253093b9760735d996 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -516,17 +516,15 @@ BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id)
 {
 	BOOL object_found = FALSE;
 	LLTool *tool = NULL;
-	if (!gNoRender)
-	{
-		tool = LLToolMgr::getInstance()->getCurrentTool();
 
-		// It's possible that the tool is editing an object that is not selected
-		LLViewerObject* tool_editing_object = tool->getEditingObject();
-		if( tool_editing_object && tool_editing_object->mID == id)
-		{
-			tool->stopEditing();
-			object_found = TRUE;
-		}
+	tool = LLToolMgr::getInstance()->getCurrentTool();
+
+	// It's possible that the tool is editing an object that is not selected
+	LLViewerObject* tool_editing_object = tool->getEditingObject();
+	if( tool_editing_object && tool_editing_object->mID == id)
+	{
+		tool->stopEditing();
+		object_found = TRUE;
 	}
 
 	// Iterate through selected objects list and kill the object
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 0eac7d5e2a7464127611cdf6225ba387b32fb14a..34a79bcde326168df0230122dd567b69875ae6f1 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -354,11 +354,8 @@ bool idle_startup()
 
 	LLStringUtil::setLocale (LLTrans::getString(system));
 
-	if (!gNoRender)
-	{
-		//note: Removing this line will cause incorrect button size in the login screen. -- bao.
-		gTextureList.updateImages(0.01f) ;
-	}
+	//note: Removing this line will cause incorrect button size in the login screen. -- bao.
+	gTextureList.updateImages(0.01f) ;
 
 	if ( STATE_FIRST == LLStartUp::getStartupState() )
 	{
@@ -673,6 +670,7 @@ bool idle_startup()
 		{
 			gUserCredential = gLoginHandler.initializeLoginInfo();
 		}
+		// Previous initialÃzeLoginInfo may have generated user credentials.  Re-check them.
 		if (gUserCredential.isNull())
 		{
 			show_connect_box = TRUE;
@@ -731,9 +729,9 @@ bool idle_startup()
 			{                                                                                                      
 				gUserCredential = gLoginHandler.initializeLoginInfo();                 
 			}     
-			if (gNoRender)
+			if (gHeadlessClient)
 			{
-				LL_ERRS("AppInit") << "Need to autologin or use command line with norender!" << LL_ENDL;
+				LL_WARNS("AppInit") << "Waiting at connection box in headless client.  Did you mean to add autologin params?" << LL_ENDL;
 			}
 			// Make sure the process dialog doesn't hide things
 			gViewerWindow->setShowProgress(FALSE);
@@ -941,10 +939,7 @@ bool idle_startup()
 
 		gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
 
-		if (!gNoRender)
-		{
-			init_start_screen(agent_location_id);
-		}
+		init_start_screen(agent_location_id);
 
 		// Display the startup progress bar.
 		gViewerWindow->setShowProgress(TRUE);
@@ -975,11 +970,6 @@ bool idle_startup()
 		// Setting initial values...
 		LLLoginInstance* login = LLLoginInstance::getInstance();
 		login->setNotificationsInterface(LLNotifications::getInstance());
-		if(gNoRender)
-		{
-			// HACK, skip optional updates if you're running drones
-			login->setSkipOptionalUpdate(true);
-		}
 
 		login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());
 		login->setLastExecEvent(gLastExecEvent);
@@ -1265,14 +1255,11 @@ bool idle_startup()
 		gLoginMenuBarView->setVisible( FALSE );
 		gLoginMenuBarView->setEnabled( FALSE );
 
-		if (!gNoRender)
-		{
-			// direct logging to the debug console's line buffer
-			LLError::logToFixedBuffer(gDebugView->mDebugConsolep);
-			
-			// set initial visibility of debug console
-			gDebugView->mDebugConsolep->setVisible(gSavedSettings.getBOOL("ShowDebugConsole"));
-		}
+		// direct logging to the debug console's line buffer
+		LLError::logToFixedBuffer(gDebugView->mDebugConsolep);
+		
+		// set initial visibility of debug console
+		gDebugView->mDebugConsolep->setVisible(gSavedSettings.getBOOL("ShowDebugConsole"));
 
 		//
 		// Set message handlers
@@ -1300,7 +1287,7 @@ bool idle_startup()
 
 		//gCacheName is required for nearby chat history loading
 		//so I just moved nearby history loading a few states further
-		if (!gNoRender && gSavedPerAccountSettings.getBOOL("LogShowHistory"))
+		if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
 		{
 			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
 			if (nearby_chat) nearby_chat->loadHistory();
@@ -1352,18 +1339,15 @@ bool idle_startup()
 		gAgentCamera.resetCamera();
 
 		// Initialize global class data needed for surfaces (i.e. textures)
-		if (!gNoRender)
-		{
-			LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL;
-			// Initialize all of the viewer object classes for the first time (doing things like texture fetches.
-			LLGLState::checkStates();
-			LLGLState::checkTextureChannels();
+		LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL;
+		// Initialize all of the viewer object classes for the first time (doing things like texture fetches.
+		LLGLState::checkStates();
+		LLGLState::checkTextureChannels();
 
-			gSky.init(initial_sun_direction);
+		gSky.init(initial_sun_direction);
 
-			LLGLState::checkStates();
-			LLGLState::checkTextureChannels();
-		}
+		LLGLState::checkStates();
+		LLGLState::checkTextureChannels();
 
 		LL_DEBUGS("AppInit") << "Decoding images..." << LL_ENDL;
 		// For all images pre-loaded into viewer cache, decode them.
@@ -1726,46 +1710,43 @@ bool idle_startup()
 			LLUIColorTable::instance().saveUserSettings();
 		};
 
-		if (!gNoRender)
-		{
-			// JC: Initializing audio requests many sounds for download.
-			init_audio();
-
-			// JC: Initialize "active" gestures.  This may also trigger
-			// many gesture downloads, if this is the user's first
-			// time on this machine or -purge has been run.
-			LLSD gesture_options 
-				= LLLoginInstance::getInstance()->getResponse("gestures");
-			if (gesture_options.isDefined())
+		// JC: Initializing audio requests many sounds for download.
+		init_audio();
+
+		// JC: Initialize "active" gestures.  This may also trigger
+		// many gesture downloads, if this is the user's first
+		// time on this machine or -purge has been run.
+		LLSD gesture_options 
+			= LLLoginInstance::getInstance()->getResponse("gestures");
+		if (gesture_options.isDefined())
+		{
+			LL_DEBUGS("AppInit") << "Gesture Manager loading " << gesture_options.size()
+				<< LL_ENDL;
+			uuid_vec_t item_ids;
+			for(LLSD::array_const_iterator resp_it = gesture_options.beginArray(),
+				end = gesture_options.endArray(); resp_it != end; ++resp_it)
 			{
-				LL_DEBUGS("AppInit") << "Gesture Manager loading " << gesture_options.size()
-					<< LL_ENDL;
-				uuid_vec_t item_ids;
-				for(LLSD::array_const_iterator resp_it = gesture_options.beginArray(),
-					end = gesture_options.endArray(); resp_it != end; ++resp_it)
-				{
-					// If the id is not specifed in the LLSD,
-					// the LLSD operator[]() will return a null LLUUID. 
-					LLUUID item_id = (*resp_it)["item_id"];
-					LLUUID asset_id = (*resp_it)["asset_id"];
+				// If the id is not specifed in the LLSD,
+				// the LLSD operator[]() will return a null LLUUID. 
+				LLUUID item_id = (*resp_it)["item_id"];
+				LLUUID asset_id = (*resp_it)["asset_id"];
 
-					if (item_id.notNull() && asset_id.notNull())
-					{
-						// Could schedule and delay these for later.
-						const BOOL no_inform_server = FALSE;
-						const BOOL no_deactivate_similar = FALSE;
-						LLGestureMgr::instance().activateGestureWithAsset(item_id, asset_id,
-											 no_inform_server,
-											 no_deactivate_similar);
-						// We need to fetch the inventory items for these gestures
-						// so we have the names to populate the UI.
-						item_ids.push_back(item_id);
-					}
+				if (item_id.notNull() && asset_id.notNull())
+				{
+					// Could schedule and delay these for later.
+					const BOOL no_inform_server = FALSE;
+					const BOOL no_deactivate_similar = FALSE;
+					LLGestureMgr::instance().activateGestureWithAsset(item_id, asset_id,
+										 no_inform_server,
+										 no_deactivate_similar);
+					// We need to fetch the inventory items for these gestures
+					// so we have the names to populate the UI.
+					item_ids.push_back(item_id);
 				}
-				// no need to add gesture to inventory observer, it's already made in constructor 
-				LLGestureMgr::instance().setFetchIDs(item_ids);
-				LLGestureMgr::instance().startFetch();
 			}
+			// no need to add gesture to inventory observer, it's already made in constructor 
+			LLGestureMgr::instance().setFetchIDs(item_ids);
+			LLGestureMgr::instance().startFetch();
 		}
 		gDisplaySwapBuffers = TRUE;
 
@@ -1786,13 +1767,6 @@ bool idle_startup()
 		// JC - 7/20/2002
 		gViewerWindow->sendShapeToSim();
 
-		
-		// Ignore stipend information for now.  Money history is on the web site.
-		// if needed, show the L$ history window
-		//if (stipend_since_login && !gNoRender)
-		//{
-		//}
-
 		// The reason we show the alert is because we want to
 		// reduce confusion for when you log in and your provided
 		// location is not your expected location. So, if this is
@@ -3218,7 +3192,7 @@ bool process_login_success_response()
 
 void transition_back_to_login_panel(const std::string& emsg)
 {
-	if (gNoRender)
+	if (gHeadlessClient && gSavedSettings.getBOOL("AutoLogin"))
 	{
 		LL_WARNS("AppInit") << "Failed to login!" << LL_ENDL;
 		LL_WARNS("AppInit") << emsg << LL_ENDL;
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index 6fc8153b7783585e12d785f7605e4d5d0ff698b5..bccabe21a8521bc3d317e2f0ebf3446138a8ac9f 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -340,11 +340,6 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 	S32 i;
 	LLSurfacePatch *patchp, *neighbor_patchp;
 
-	if (gNoRender)
-	{
-		return;
-	}
-
 	mNeighbors[direction] = neighborp;
 	neighborp->mNeighbors[gDirOpposite[direction]] = this;
 
diff --git a/indra/newview/lltexturestats.cpp b/indra/newview/lltexturestats.cpp
index dd35d5cf83309a055d5e5f392588c7f8aa8b849e..f820ae65df01713ab075b7ff682e3164b0af8f04 100644
--- a/indra/newview/lltexturestats.cpp
+++ b/indra/newview/lltexturestats.cpp
@@ -37,7 +37,7 @@ void send_texture_stats_to_sim(const LLSD &texture_stats)
 {
 	LLSD texture_stats_report;
 	// Only send stats if the agent is connected to a region.
-	if (!gAgent.getRegion() || gNoRender)
+	if (!gAgent.getRegion())
 	{
 		return;
 	}
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index ddb11829dfe0ead5d2447a8f25b56ea59c68ee2b..3e13537113e34fed2c05b39d7f8cfc0836fab0f7 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -115,8 +115,7 @@ void display_startup()
 {
 	if (   !gViewerWindow->getActive()
 		|| !gViewerWindow->mWindow->getVisible() 
-		|| gViewerWindow->mWindow->getMinimized()
-		|| gNoRender )
+		|| gViewerWindow->mWindow->getMinimized() )
 	{
 		return; 
 	}
@@ -294,7 +293,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 	// Logic for forcing window updates if we're in drone mode.
 	//
 
-	if (gNoRender) 
+	// *TODO: Investigate running display() during gHeadlessClient.  See if this early exit is needed DK 2011-02-18
+	if (gHeadlessClient) 
 	{
 #if LL_WINDOWS
 		static F32 last_update_time = 0.f;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 6fc85a39449ac2b44bc13747dd1106802b18bc4d..7e8fbf7345fdccfa3203b3cfd15f1e25be502df0 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -343,12 +343,6 @@ void process_layer_data(LLMessageSystem *mesgsys, void **user_data)
 {
 	LLViewerRegion *regionp = LLWorld::getInstance()->getRegion(mesgsys->getSender());
 
-	if (!regionp || gNoRender)
-	{
-		return;
-	}
-
-
 	S32 size;
 	S8 type;
 
@@ -2163,10 +2157,6 @@ void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string m
 
 void process_improved_im(LLMessageSystem *msg, void **user_data)
 {
-	if (gNoRender)
-	{
-		return;
-	}
 	LLUUID from_id;
 	BOOL from_group;
 	LLUUID to_id;
@@ -3936,7 +3926,14 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 	// LBUTTON and ML_LBUTTON so that using the camera (alt-key) doesn't
 	// trigger a control event.
 	U32 control_flags = gAgent.getControlFlags();
-	MASK	key_mask = gKeyboard->currentMask(TRUE);
+
+	MASK	key_mask = MASK_NONE;
+	// *TODO: Create a headless gKeyboard DK 2011-02-18
+	if (gKeyboard)
+	{
+		key_mask = gKeyboard->currentMask(TRUE);
+	}
+
 	if (key_mask & MASK_ALT || key_mask & MASK_CONTROL)
 	{
 		control_flags &= ~(	AGENT_CONTROL_LBUTTON_DOWN |
@@ -4255,7 +4252,7 @@ void process_time_synch(LLMessageSystem *mesgsys, void **user_data)
 
 	gSky.setSunPhase(phase);
 	gSky.setSunTargetDirection(sun_direction, sun_ang_velocity);
-	if (!gNoRender && !(gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || gSky.getOverrideSun()))
+	if ( !(gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || gSky.getOverrideSun()) )
 	{
 		gSky.setSunDirection(sun_direction, sun_ang_velocity);
 	}
@@ -5517,21 +5514,12 @@ time_t								gLastDisplayedTime = 0;
 
 void handle_show_mean_events(void *)
 {
-	if (gNoRender)
-	{
-		return;
-	}
 	LLFloaterReg::showInstance("bumps");
 	//LLFloaterBump::showInstance();
 }
 
 void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_group)
 {
-	if (gNoRender)
-	{
-		return;
-	}
-
 	static const U32 max_collision_list_size = 20;
 	if (gMeanCollisionList.size() > max_collision_list_size)
 	{
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 090d3cadd491f90404e9463aa13c3a7f9e816818..c60bdf31c960b1a8c002808ece23b4f342457598 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -469,11 +469,6 @@ void LLViewerObject::initVOClasses()
 	// Initialized shared class stuff first.
 	LLVOAvatar::initClass();
 	LLVOTree::initClass();
-	if (gNoRender)
-	{
-		// Don't init anything else in drone mode
-		return;
-	}
 	llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl;
 	LLVOGrass::initClass();
 	LLVOWater::initClass();
@@ -2151,12 +2146,6 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 		}
 	}
 
-	if (gNoRender)
-	{
-		// Skip drawable stuff if not rendering.
-		return TRUE;
-	}
-
 	updateDrawable(FALSE);
 
 	return TRUE;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 970cc2e2a784837f282350e5c489cd2bab83e352..d112b3490e0be6fe86baf1139b2f4d018f3ec3ae 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -636,19 +636,16 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
 	}
 
 
-	if (!gNoRender)
+	// Slam priorities for textures that we care about (hovered, selected, and focused)
+	// Hovered
+	// Assumes only one level deep of parenting
+	LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
+	if (nodep)
 	{
-		// Slam priorities for textures that we care about (hovered, selected, and focused)
-		// Hovered
-		// Assumes only one level deep of parenting
-		LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
-		if (nodep)
+		objectp = nodep->getObject();
+		if (objectp)
 		{
-			objectp = nodep->getObject();
-			if (objectp)
-			{
-				objectp->boostTexturePriority();
-			}
+			objectp->boostTexturePriority();
 		}
 	}
 
@@ -1099,7 +1096,7 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
 	// We need to update many object caches, I'll document this more as I dig through the code
 	// cleaning things out...
 
-	if (gNoRender || 0 == offset.magVecSquared())
+	if (0 == offset.magVecSquared())
 	{
 		return;
 	}
@@ -1505,11 +1502,6 @@ void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip
 
 void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
 {
-	if (gNoRender)
-	{
-		return;
-	}
-
 	if (objectp->isDead())
 	{
 		llwarns << "Trying to find orphans for dead obj " << objectp->mID 
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index fccd1156d3f613821459969a6a74566615572461..e84e4a859a04df99b7130a4e0bca63aa63a9b0e8 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1383,11 +1383,6 @@ void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos)
 // static
 void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user)
 {
-	if (gNoRender)
-	{
-		return;
-	}
-
 	// Extract the packed overlay information
 	S32 packed_overlay_size = msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_Data);
 
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 23b7b921b8ce1ca94a74b0c2953d8ac4cc8ae67d..8e0373c79e0eb6d0f93892d8e4d0eaae8264193c 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -72,8 +72,6 @@
 	#pragma warning(disable:4355)
 #endif
 
-extern BOOL gNoRender;
-
 const F32 WATER_TEXTURE_SCALE = 8.f;			//  Number of times to repeat the water texture across a region
 const S16 MAX_MAP_DIST = 10;
 
@@ -234,28 +232,19 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	updateRenderMatrix();
 
 	mLandp = new LLSurface('l', NULL);
-	if (!gNoRender)
-	{
-		// Create the composition layer for the surface
-		mCompositionp = new LLVLComposition(mLandp, grids_per_region_edge, region_width_meters/grids_per_region_edge);
-		mCompositionp->setSurface(mLandp);
-
-		// Create the surfaces
-		mLandp->setRegion(this);
-		mLandp->create(grids_per_region_edge,
-						grids_per_patch_edge,
-						mOriginGlobal,
-						mWidth);
-	}
 
-	if (!gNoRender)
-	{
-		mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
-	}
-	else
-	{
-		mParcelOverlay = NULL;
-	}
+	// Create the composition layer for the surface
+	mCompositionp = new LLVLComposition(mLandp, grids_per_region_edge, region_width_meters/grids_per_region_edge);
+	mCompositionp->setSurface(mLandp);
+
+	// Create the surfaces
+	mLandp->setRegion(this);
+	mLandp->create(grids_per_region_edge,
+					grids_per_patch_edge,
+					mOriginGlobal,
+					mWidth);
+
+	mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
 
 	setOriginGlobal(from_region_handle(handle));
 	calculateCenterGlobal();
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 546ee9a334b05646dae5492aa8aa71b01326d187..e29370dfa4771819efe183ca8e737a3b9f16bd5f 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -711,7 +711,7 @@ void send_stats()
 	// but that day is not today.
 
 	// Only send stats if the agent is connected to a region.
-	if (!gAgent.getRegion() || gNoRender)
+	if (!gAgent.getRegion())
 	{
 		return;
 	}
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index cd16b15e3ef56cc38e4ef5fb8d2aff053eba8d7b..16e73da79bd320fd4e3256c18a0cd3c9866fd9c0 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1415,61 +1415,59 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 // 						mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
 // 			<< mID.getString() << llendl;
 	BOOL res = TRUE;
-	if (!gNoRender)
-	{
-		// store original size only for locally-sourced images
-		if (mUrl.compare(0, 7, "file://") == 0)
-		{
-			mOrigWidth = mRawImage->getWidth();
-			mOrigHeight = mRawImage->getHeight();
 
-			// leave black border, do not scale image content
-			mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
-			
-			mFullWidth = mRawImage->getWidth();
-			mFullHeight = mRawImage->getHeight();
-			setTexelsPerImage();
-		}
-		else
-		{
-			mOrigWidth = mFullWidth;
-			mOrigHeight = mFullHeight;
-		}
+	// store original size only for locally-sourced images
+	if (mUrl.compare(0, 7, "file://") == 0)
+	{
+		mOrigWidth = mRawImage->getWidth();
+		mOrigHeight = mRawImage->getHeight();
 
-		bool size_okay = true;
+		// leave black border, do not scale image content
+		mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
 		
-		U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel;
-		U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel;
-		if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE )
-		{
-			llinfos << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << llendl;
-			size_okay = false;
-		}
-		
-		if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
-		{
-			// A non power-of-two image was uploaded (through a non standard client)
-			llinfos << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << llendl;
-			size_okay = false;
-		}
-		
-		if( !size_okay )
-		{
-			// An inappropriately-sized image was uploaded (through a non standard client)
-			// We treat these images as missing assets which causes them to
-			// be renderd as 'missing image' and to stop requesting data
-			setIsMissingAsset();
-			destroyRawImage();
-			return FALSE;
-		}
-		
-		if(!(res = insertToAtlas()))
-		{
-			res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
-			resetFaceAtlas() ;
-		}
-		setActive() ;
+		mFullWidth = mRawImage->getWidth();
+		mFullHeight = mRawImage->getHeight();
+		setTexelsPerImage();
+	}
+	else
+	{
+		mOrigWidth = mFullWidth;
+		mOrigHeight = mFullHeight;
+	}
+
+	bool size_okay = true;
+	
+	U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel;
+	U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel;
+	if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE )
+	{
+		llinfos << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << llendl;
+		size_okay = false;
+	}
+	
+	if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
+	{
+		// A non power-of-two image was uploaded (through a non standard client)
+		llinfos << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << llendl;
+		size_okay = false;
+	}
+	
+	if( !size_okay )
+	{
+		// An inappropriately-sized image was uploaded (through a non standard client)
+		// We treat these images as missing assets which causes them to
+		// be renderd as 'missing image' and to stop requesting data
+		setIsMissingAsset();
+		destroyRawImage();
+		return FALSE;
+	}
+	
+	if(!(res = insertToAtlas()))
+	{
+		res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+		resetFaceAtlas() ;
 	}
+	setActive() ;
 
 	if (!mForceToSaveRawImage)
 	{
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 10126219f8b943f1e2da0c55d780da9e8af89070..06f6ff23c23cd49063bc4300de39ee2c757f2d59 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -91,11 +91,6 @@ void LLViewerTextureList::init()
 	sNumImages = 0;
 	mMaxResidentTexMemInMegaBytes = 0;
 	mMaxTotalTextureMemInMegaBytes = 0 ;
-	if (gNoRender)
-	{
-		// Don't initialize GL stuff if we're not rendering.
-		return;
-	}
 	
 	mUpdateStats = TRUE;
 	
@@ -345,13 +340,6 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
 												   LLGLenum primary_format, 
 												   const LLUUID& force_id)
 {
-	if (gNoRender)
-	{
-		// Never mind that this ignores image_set_id;
-		// getImage() will handle that later.
-		return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI);
-	}
-
 	// generate UUID based on hash of filename
 	LLUUID new_id;
 	if (force_id.notNull())
@@ -741,7 +729,7 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create Images");
 
 F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
 {
-	if (gNoRender || gGLManager.mIsDisabled) return 0.0f;
+	if (gGLManager.mIsDisabled) return 0.0f;
 	
 	//
 	// Create GL textures for all textures that need them (images which have been
@@ -876,7 +864,6 @@ void LLViewerTextureList::updateImagesUpdateStats()
 void LLViewerTextureList::decodeAllImages(F32 max_time)
 {
 	LLTimer timer;
-	if(gNoRender) return;
 	
 	// Update texture stats and priorities
 	std::vector<LLPointer<LLViewerFetchedTexture> > image_list;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 166b11041279a1d55109971ab61e8a4d59e77bf5..435da72622ea12bb71a5d485b1f0cd719f42d471 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1225,8 +1225,9 @@ void LLViewerWindow::handleMenuSelect(LLWindow *window,  S32 menu_item)
 
 BOOL LLViewerWindow::handlePaint(LLWindow *window,  S32 x,  S32 y, S32 width,  S32 height)
 {
+	// *TODO: Enable similar information output for other platforms?  DK 2011-02-18
 #if LL_WINDOWS
-	if (gNoRender)
+	if (gHeadlessClient)
 	{
 		HWND window_handle = (HWND)window->getPlatformWindow();
 		PAINTSTRUCT ps; 
@@ -1256,7 +1257,7 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window,  S32 x,  S32 y, S32 width,  S
 		len = temp_str.length();
 		TextOutA(hdc, 0, 25, temp_str.c_str(), len); 
 
-		TextOutA(hdc, 0, 50, "Set \"DisableRendering FALSE\" in settings.ini file to reenable", 61);
+		TextOutA(hdc, 0, 50, "Set \"HeadlessClient FALSE\" in settings.ini file to reenable", 61);
 		EndPaint(window_handle, &ps); 
 		return TRUE;
 	}
@@ -1404,9 +1405,9 @@ LLViewerWindow::LLViewerWindow(
 	mWindow = LLWindowManager::createWindow(this,
 		title, name, x, y, width, height, 0,
 		fullscreen, 
-		gNoRender,
+		gHeadlessClient,
 		gSavedSettings.getBOOL("DisableVerticalSync"),
-		!gNoRender,
+		!gHeadlessClient,
 		ignore_pixel_depth,
 		gSavedSettings.getBOOL("RenderUseFBO") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled
 
@@ -1862,11 +1863,8 @@ void LLViewerWindow::shutdownGL()
 	LLVertexBuffer::cleanupClass();
 
 	llinfos << "Stopping GL during shutdown" << llendl;
-	if (!gNoRender)
-	{
-		stopGL(FALSE);
-		stop_glerror();
-	}
+	stopGL(FALSE);
+	stop_glerror();
 
 	gGL.shutdown();
 }
@@ -1930,11 +1928,6 @@ void LLViewerWindow::reshape(S32 width, S32 height)
 	// may have been destructed.
 	if (!LLApp::isExiting())
 	{
-		if (gNoRender)
-		{
-			return;
-		}
-
 		gWindowResized = TRUE;
 
 		// update our window rectangle
@@ -2575,11 +2568,12 @@ void LLViewerWindow::updateUI()
 
 	S32 x = mCurrentMousePoint.mX;
 	S32 y = mCurrentMousePoint.mY;
-	MASK mask = gKeyboard->currentMask(TRUE);
 
-	if (gNoRender)
+	MASK	mask = MASK_NONE;
+	// *TODO: Create a headless gKeyboard DK 2011-02-18
+	if (gKeyboard)
 	{
-		return;
+		mask = gKeyboard->currentMask(TRUE);
 	}
 
 	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
@@ -3410,11 +3404,6 @@ BOOL LLViewerWindow::clickPointOnSurfaceGlobal(const S32 x, const S32 y, LLViewe
 
 void LLViewerWindow::pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& info), BOOL pick_transparent)
 {
-	if (gNoRender)
-	{
-		return;
-	}
-	
 	BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
 	if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
 	{
@@ -3450,11 +3439,6 @@ void LLViewerWindow::schedulePick(LLPickInfo& pick_info)
 
 void LLViewerWindow::performPick()
 {
-	if (gNoRender)
-	{
-		return;
-	}
-
 	if (!mPicks.empty())
 	{
 		std::vector<LLPickInfo>::iterator pick_it;
@@ -3486,11 +3470,6 @@ void LLViewerWindow::returnEmptyPicks()
 // Performs the GL object/land pick.
 LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_transparent)
 {
-	if (gNoRender)
-	{
-		return LLPickInfo();
-	}
-
 	BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
 	if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
 	{
@@ -3500,7 +3479,13 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_trans
 	}
 
 	// shortcut queueing in mPicks and just update mLastPick in place
-	mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), gKeyboard->currentMask(TRUE), pick_transparent, TRUE, NULL);
+	MASK	key_mask = MASK_NONE;
+	// *TODO: Create a headless gKeyboard DK 2011-02-18
+	if (gKeyboard)
+	{
+		key_mask = gKeyboard->currentMask(TRUE);
+	}
+	mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, TRUE, NULL);
 	mLastPick.fetchResults();
 
 	return mLastPick;
@@ -4774,12 +4759,9 @@ bool LLViewerWindow::onAlert(const LLSD& notify)
 {
 	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
 
-	if (gNoRender)
+	if (gHeadlessClient)
 	{
 		llinfos << "Alert: " << notification->getName() << llendl;
-		notification->respond(LLSD::emptyMap());
-		LLNotifications::instance().cancel(notification);
-		return false;
 	}
 
 	// If we're in mouselook, the mouse is hidden and so the user can't click 
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index fd89044995aab28a4d7107f698ed147bfcec6581..26b595c92319eed05324385227be1d3cd611a147 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1295,18 +1295,8 @@ void LLVOAvatar::initInstance(void)
 		
 	}
 	
-	if (gNoRender)
-	{
-		return;
-	}
-	
 	buildCharacter();
 	
-	if (gNoRender)
-	{
-		return;
-	}
-	
 	// preload specific motions here
 	createMotion( ANIM_AGENT_CUSTOMIZE);
 	createMotion( ANIM_AGENT_CUSTOMIZE_DONE);
@@ -1747,12 +1737,6 @@ void LLVOAvatar::buildCharacter()
 	BOOL status = loadAvatar();
 	stop_glerror();
 
-	if (gNoRender)
-	{
-		// Still want to load the avatar skeleton so visual parameters work.
-		return;
-	}
-
 // 	gPrintMessagesThisFrame = TRUE;
 	lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl;
 
@@ -2223,7 +2207,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 	setPixelAreaAndAngle(gAgent);
 
 	// force asynchronous drawable update
-	if(mDrawable.notNull() && !gNoRender)
+	if(mDrawable.notNull())
 	{	
 		LLFastTimer t(FTM_JOINT_UPDATE);
 	
@@ -2280,11 +2264,6 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 	LLVector3 root_pos_last = mRoot.getWorldPosition();
 	BOOL detailed_update = updateCharacter(agent);
 
-	if (gNoRender)
-	{
-		return TRUE;
-	}
-
 	static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false);
 	bool voice_enabled = (visualizers_in_calls || LLVoiceClient::getInstance()->inProximalChannel()) &&
 						 LLVoiceClient::getInstance()->getVoiceEnabled(mID);
@@ -3257,17 +3236,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		}
 	}
 
-	if (gNoRender)
-	{
-		// Hack if we're running drones...
-		if (isSelf())
-		{
-			gAgent.setPositionAgent(getPositionAgent());
-		}
-		return FALSE;
-	}
-
-
 	LLVector3d root_pos_global;
 
 	if (!mIsBuilt)
@@ -4194,7 +4162,7 @@ void LLVOAvatar::updateTextures()
 {
 	BOOL render_avatar = TRUE;
 
-	if (mIsDummy || gNoRender)
+	if (mIsDummy)
 	{
 		return;
 	}
@@ -4468,11 +4436,6 @@ void LLVOAvatar::processAnimationStateChanges()
 {
 	LLMemType mt(LLMemType::MTYPE_AVATAR);
 	
-	if (gNoRender)
-	{
-		return;
-	}
-
 	if ( isAnyAnimationSignaled(AGENT_WALK_ANIMS, NUM_AGENT_WALK_ANIMS) )
 	{
 		startMotion(ANIM_AGENT_WALK_ADJUST);
@@ -4867,7 +4830,7 @@ void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_age
 	LLVector3d z_vec(0.0f, 0.0f, 1.0f);
 	LLVector3d p0_global, p1_global;
 
-	if (gNoRender || mIsDummy)
+	if (mIsDummy)
 	{
 		outNorm.setVec(z_vec);
 		out_pos_agent = in_pos_agent;
@@ -5439,11 +5402,6 @@ BOOL LLVOAvatar::loadLayersets()
 //-----------------------------------------------------------------------------
 void LLVOAvatar::updateVisualParams()
 {
-	if (gNoRender)
-	{
-		return;
-	}
-
 	setSex( (getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE );
 
 	LLCharacter::updateVisualParams();
@@ -6174,8 +6132,6 @@ LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const
 void LLVOAvatar::updateMeshTextures()
 {
     // llinfos << "updateMeshTextures" << llendl;
-	if (gNoRender) return;
-
 	// if user has never specified a texture, assign the default
 	for (U32 i=0; i < getNumTEs(); i++)
 	{
@@ -6831,11 +6787,6 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 		}
 	}
 
-	if (gNoRender)
-	{
-		return;
-	}
-
 	ESex old_sex = getSex();
 
 //	llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl;
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 5f9e34390702fb4d874706603d0fcfb29c9161cc..c74b60f7e77349a2a03fd9c88bf42cb03dc23382 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -2506,10 +2506,6 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
 //------------------------------------------------------------------------
 BOOL LLVOAvatarSelf::needsRenderBeam()
 {
-	if (gNoRender)
-	{
-		return FALSE;
-	}
 	LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
 
 	BOOL is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing());
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 399442e5c43d966fe0e1c606775c91a0330403b2..7f3a8deb47c5bd3f445dead597f12efdb166e525 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -98,11 +98,6 @@ LLWorld::LLWorld() :
 		mEdgeWaterObjects[i] = NULL;
 	}
 
-	if (gNoRender)
-	{
-		return;
-	}
-
 	LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,4);
 	U8 *default_texture = raw->getData();
 	*(default_texture++) = MAX_WATER_COLOR.mV[0];
@@ -622,10 +617,7 @@ void LLWorld::updateVisibilities()
 		if (LLViewerCamera::getInstance()->sphereInFrustum(regionp->getCenterAgent(), radius))
 		{
 			regionp->calculateCameraDistance();
-			if (!gNoRender)
-			{
-				regionp->getLand().updatePatchVisibilities(gAgent);
-			}
+			regionp->getLand().updatePatchVisibilities(gAgent);
 		}
 		else
 		{
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 59b526059b367b06c948977cbbc7114db09440e1..b4ea4553181a5875f203d0105217052a6d25ccfa 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1227,10 +1227,6 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
 U32 LLPipeline::addObject(LLViewerObject *vobj)
 {
 	LLMemType mt_ao(LLMemType::MTYPE_PIPELINE_ADD_OBJECT);
-	if (gNoRender)
-	{
-		return 0;
-	}
 
 	if (gSavedSettings.getBOOL("RenderDelayCreation"))
 	{