diff --git a/doc/contributions.txt b/doc/contributions.txt
index 96ee446a0c2674db226aa215cf98730288ffc170..ee2dea7344347eee4e972343b790285e79cd224e 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -69,6 +69,7 @@ Aleric Inglewood
 	VWR-10759
 	VWR-10837
 	VWR-12691
+	VWR-12984
 	VWR-13996
 	VWR-14426
 	SNOW-84
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c0edd92bc117421a3501d71cd992f2f901c6cce8..096e8e07ab000d87d95b6c0c03e0c52599f83cc9 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -610,41 +610,46 @@ void LLGLManager::shutdownGL()
 void LLGLManager::initExtensions()
 {
 #if LL_MESA_HEADLESS
-# if GL_ARB_multitexture
+# ifdef GL_ARB_multitexture
 	mHasMultitexture = TRUE;
 # else
 	mHasMultitexture = FALSE;
 # endif
-# if GL_ARB_texture_env_combine
+# ifdef GL_ARB_texture_env_combine
 	mHasARBEnvCombine = TRUE;	
 # else
 	mHasARBEnvCombine = FALSE;
 # endif
-# if GL_ARB_texture_compression
+# ifdef GL_ARB_texture_compression
 	mHasCompressedTextures = TRUE;
 # else
 	mHasCompressedTextures = FALSE;
 # endif
-# if GL_ARB_vertex_buffer_object
+# ifdef GL_ARB_vertex_buffer_object
 	mHasVertexBufferObject = TRUE;
 # else
 	mHasVertexBufferObject = FALSE;
 # endif
-# if GL_EXT_framebuffer_object
+# ifdef GL_EXT_framebuffer_object
 	mHasFramebufferObject = TRUE;
 # else
 	mHasFramebufferObject = FALSE;
 # endif
-# if GL_EXT_framebuffer_multisample
+# ifdef GL_EXT_framebuffer_multisample
 	mHasFramebufferMultisample = TRUE;
 # else
 	mHasFramebufferMultisample = FALSE;
 # endif
-# if GL_ARB_draw_buffers
+# ifdef GL_ARB_draw_buffers
 	mHasDrawBuffers = TRUE;
 #else
 	mHasDrawBuffers = FALSE;
 # endif
+# if defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp)
+	mHasDepthClamp = TRUE;
+#else
+	mHasDepthClamp = FALSE;
+#endif
 # if GL_EXT_blend_func_separate
 	mHasBlendFuncSeparate = TRUE;
 #else
@@ -671,6 +676,7 @@ void LLGLManager::initExtensions()
 	mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
 	mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
 	mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
+	mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
 	// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
 	mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts)
 		&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
@@ -694,6 +700,7 @@ void LLGLManager::initExtensions()
 	if (getenv("LL_GL_NOEXT"))
 	{
 		//mHasMultitexture = FALSE; // NEEDED!
+		mHasDepthClamp = FALSE;
 		mHasARBEnvCombine = FALSE;
 		mHasCompressedTextures = FALSE;
 		mHasVertexBufferObject = FALSE;
@@ -755,6 +762,7 @@ void LLGLManager::initExtensions()
 		if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE;
 		if (strchr(blacklist,'t')) mHasTextureRectangle = FALSE;
 		if (strchr(blacklist,'u')) mHasBlendFuncSeparate = FALSE;//S
+		if (strchr(blacklist,'v')) mHasDepthClamp = FALSE;
 		
 	}
 #endif // LL_LINUX || LL_SOLARIS
@@ -2037,7 +2045,7 @@ void LLGLDepthTest::checkState()
 	}
 }
 
-LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P)
+LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P)
 {
 	for (U32 i = 0; i < 4; i++)
 	{
@@ -2050,7 +2058,7 @@ LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P)
 	glMatrixMode(GL_MODELVIEW);
 }
 
-LLGLClampToFarClip::~LLGLClampToFarClip()
+LLGLSquashToFarClip::~LLGLSquashToFarClip()
 {
 	glMatrixMode(GL_PROJECTION);
 	glPopMatrix();
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 5e8965c06add464aa3d5bdedd1d39642ccf9b704..b0decc14999e3cd26b4a3435b3777ae3475da023 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -92,6 +92,7 @@ class LLGLManager
 	BOOL mHasOcclusionQuery;
 	BOOL mHasPointParameters;
 	BOOL mHasDrawBuffers;
+	BOOL mHasDepthClamp;
 	BOOL mHasTextureRectangle;
 
 	// Other extensions.
@@ -315,11 +316,11 @@ class LLGLUserClipPlane
   leaves this class.
   Does not stack.
 */
-class LLGLClampToFarClip
+class LLGLSquashToFarClip
 {
 public:
-	LLGLClampToFarClip(glh::matrix4f projection);
-	~LLGLClampToFarClip();
+	LLGLSquashToFarClip(glh::matrix4f projection);
+	~LLGLSquashToFarClip();
 };
 
 /*
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 5a34b46d0cd3fc2d49c6494c1fc948f69f8a8f5d..576969b81ae0f6eeab173375280d7fc91e103470 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -829,5 +829,15 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
 
 #endif // LL_MESA / LL_WINDOWS / LL_DARWIN
 
+// Even when GL_ARB_depth_clamp is available in the driver, the (correct)
+// headers, and therefore GL_DEPTH_CLAMP might not be defined.
+// In that case GL_DEPTH_CLAMP_NV should be defined, but why not just
+// use the known numeric.
+//
+// To avoid #ifdef's in the code. Just define this here.
+#ifndef GL_DEPTH_CLAMP
+// Probably (still) called GL_DEPTH_CLAMP_NV.
+#define GL_DEPTH_CLAMP 0x864F
+#endif
 
 #endif // LL_LLGLHEADERS_H
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 583bb541608ec7a66caa54b744921fd6d9b78f48..8106fada111b5aa02aceed2f091fafefbdc28e59 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -358,6 +358,7 @@ void LLDrawable::makeActive()
 	{
 		U32 pcode = mVObjp->getPCode();
 		if (pcode == LLViewerObject::LL_VO_WATER ||
+			pcode == LLViewerObject::LL_VO_VOID_WATER ||
 			pcode == LLViewerObject::LL_VO_SURFACE_PATCH ||
 			pcode == LLViewerObject::LL_VO_PART_GROUP ||
 			pcode == LLViewerObject::LL_VO_HUD_PART_GROUP ||
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index cb651f9d3a23773cfd4ff1105f2769c605ebe1fc..ba576ff97f260365af30c2b8c413c9d8f0d81319 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -89,6 +89,7 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
 	case POOL_SKY:
 		poolp = new LLDrawPoolSky();
 		break;
+	case POOL_VOIDWATER:
 	case POOL_WATER:
 		poolp = new LLDrawPoolWater();
 		break;
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index c69fee2bdf1ab8271d33e789742d38078fae6a7c..1d6f99d346eacc551f8e4486ee46f6e1a9d5e89c 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -57,6 +57,7 @@ class LLDrawPool
 		POOL_BUMP,
 		POOL_INVISIBLE, // see below *
 		POOL_AVATAR,
+		POOL_VOIDWATER,
 		POOL_WATER,
 		POOL_GLOW,
 		POOL_ALPHA,
diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index bb7c55e9317d547d49cb75248c9ebde546eb6433..ce07e62122de7d44ed340cd50344c9c485b84c09 100644
--- a/indra/newview/lldrawpoolground.cpp
+++ b/indra/newview/lldrawpoolground.cpp
@@ -68,7 +68,7 @@ void LLDrawPoolGround::render(S32 pass)
 
 	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
 
-	LLGLClampToFarClip far_clip(glh_get_current_projection());
+	LLGLSquashToFarClip far_clip(glh_get_current_projection());
 
 	F32 water_height = gAgent.getRegion()->getWaterHeight();
 	glPushMatrix();
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index 41ea8d73b372b91ee6e2593c1235a8b7123d1011..6b45c5abb0a57c7aa497ec64416e09b7c76d128c 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -97,7 +97,7 @@ void LLDrawPoolSky::render(S32 pass)
 
 	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
 
-	LLGLClampToFarClip far_clip(glh_get_current_projection());
+	LLGLSquashToFarClip far_clip(glh_get_current_projection());
 
 	LLGLEnable fog_enable( (mVertexShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0);
 
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index c20e1f9a263b5368687e383ebe7b07207c5a4af5..0ee70bcdd14525a810dd9c11461b4d8239a927b1 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -532,6 +532,7 @@ void LLDrawPoolWater::shade()
 	glColor4fv(water_color.mV);
 
 	{
+		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
 		LLGLDisable cullface(GL_CULL_FACE);
 		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 			iter != mDrawFace.end(); iter++)
@@ -548,30 +549,19 @@ void LLDrawPoolWater::shade()
 
 			sNeedsReflectionUpdate = TRUE;
 			
-			if (water->getUseTexture())
+			if (water->getUseTexture() || !water->getIsEdgePatch())
 			{
 				sNeedsDistortionUpdate = TRUE;
 				face->renderIndexed();
 			}
+			else if (gGLManager.mHasDepthClamp || deferred_render)
+			{
+				face->renderIndexed();
+			}
 			else
-			{ //smash background faces to far clip plane
-				if (water->getIsEdgePatch())
-				{
-					if (deferred_render)
-					{
-						face->renderIndexed();
-					}
-					else
-					{
-						LLGLClampToFarClip far_clip(glh_get_current_projection());
-						face->renderIndexed();
-					}
-				}
-				else
-				{
-					sNeedsDistortionUpdate = TRUE;
-					face->renderIndexed();
-				}
+			{
+				LLGLSquashToFarClip far_clip(glh_get_current_projection());
+				face->renderIndexed();
 			}
 		}
 	}
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 41a299151e1c08e55a2ea82f7847d38a2ec9fef2..eaa6aa7e37cbacc6199f5f31736e0b2661912a14 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -260,7 +260,7 @@ void LLDrawPoolWLSky::render(S32 pass)
 	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
 	LLGLDisable clip(GL_CLIP_PLANE0);
 
-	LLGLClampToFarClip far_clip(glh_get_current_projection());
+	LLGLSquashToFarClip far_clip(glh_get_current_projection());
 
 	renderSkyHaze(camHeightLocal);
 
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index 662e1c4f422c2df41a7e7dbd3ea96151e7d9a7f0..a34e0353ec5d9cd9593a20a858a5c54894b7050c 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -209,13 +209,6 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
 	llassert(msg);
 	if (!msg) return;
 
-	LLHost host = msg->getSender();
-	if (host != gAgent.getRegionHost())
-	{
-		// update is for a different region than the one we're in
-		return;
-	}
-
 	//const S32 SIM_NAME_BUF = 256;
 	U32 region_flags;
 	U8 sim_access;
@@ -233,6 +226,8 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
 	S32 redirect_grid_y;
 	LLUUID cache_id;
 
+	LLHost host = msg->getSender();
+
 	msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, sim_name);
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, estate_id);
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, parent_estate_id);
@@ -242,6 +237,15 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, object_bonus_factor);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, billable_factor);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
+
+	if (host != gAgent.getRegionHost())
+	{
+		// Update is for a different region than the one we're in.
+		// Just check for a waterheight change.
+		LLWorld::getInstance()->waterHeightRegionInfo(sim_name, water_height);
+		return;
+	}
+
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit);
 	msg->getS32Fast(_PREHASH_RegionInfo, _PREHASH_PricePerMeter, price_per_meter);
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 723689454266181e51eced97bfa1e9ec624fdf8a..ba0eb8a711c065f8cdca800c488d76f7e4af5335 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -635,7 +635,7 @@ void LLFloaterWorldMap::updateTeleportCoordsDisplay( const LLVector3d& pos )
 	// convert global specified position to a local one
 	F32 region_local_x = (F32)fmod( pos.mdV[VX], (F64)REGION_WIDTH_METERS );
 	F32 region_local_y = (F32)fmod( pos.mdV[VY], (F64)REGION_WIDTH_METERS );
-	F32 region_local_z = (F32)fmod( pos.mdV[VZ], (F64)REGION_WIDTH_METERS );
+	F32 region_local_z = (F32)llclamp( pos.mdV[VZ], 0.0, (F64)REGION_HEIGHT_METERS );
 
 	// write in the values
 	childSetValue("teleport_coordinate_x", region_local_x );
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index fb984a7c6289820a12a9fa3c143a670e1ec03f96..960e72ee421e9b3ac65de574fc0489ca81273c7a 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1555,7 +1555,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 {
 	if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1)
 	{
-		if (earlyFail(camera, this))
+		// Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension
+		if ((mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER && !gGLManager.mHasDepthClamp) ||
+			earlyFail(camera, this))
 		{
 			setOcclusionState(LLSpatialGroup::DISCARD_QUERY);
 			assert_states_valid(this);
@@ -1576,7 +1578,18 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 				{
 					buildOcclusion();
 				}
-
+				
+				// Depth clamp all water to avoid it being culled as a result of being
+				// behind the far clip plane, and in the case of edge water to avoid
+				// it being culled while still visible.
+				bool const use_depth_clamp = gGLManager.mHasDepthClamp &&
+											(mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER ||
+											mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER);
+				if (use_depth_clamp)
+				{
+					glEnable(GL_DEPTH_CLAMP);
+				}
+				
 				glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery[LLViewerCamera::sCurCameraID]);					
 				glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts);
 				if (camera->getOrigin().isExactlyZero())
@@ -1592,6 +1605,11 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 								GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0]));
 				}
 				glEndQueryARB(GL_SAMPLES_PASSED_ARB);
+				
+				if (use_depth_clamp)
+				{
+					glDisable(GL_DEPTH_CLAMP);
+				}
 			}
 
 			setOcclusionState(LLSpatialGroup::QUERY_PENDING);
@@ -2591,9 +2609,10 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
 						gGL.color4f(0.5f,0.5f,0.5f,1.0f);
 						break;
 				case LLViewerObject::LL_VO_PART_GROUP:
-			case LLViewerObject::LL_VO_HUD_PART_GROUP:
+				case LLViewerObject::LL_VO_HUD_PART_GROUP:
 						gGL.color4f(0,0,1,1);
 						break;
+				case LLViewerObject::LL_VO_VOID_WATER:
 				case LLViewerObject::LL_VO_WATER:
 						gGL.color4f(0,0.5f,1,1);
 						break;
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 1a25f3f85dee6e17f9dfbc0595fcef8b4fb3affd..2b9cf6c6300498ea17b122b1e259b73ef3cf8aa6 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -551,6 +551,13 @@ class LLWaterPartition : public LLSpatialPartition
 	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
 };
 
+//spatial partition for hole and edge water (implemented in LLVOWater.cpp)
+class LLVoidWaterPartition : public LLWaterPartition
+{
+public:
+	LLVoidWaterPartition();
+};
+
 //spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp)
 class LLTerrainPartition : public LLSpatialPartition
 {
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index af4d9fa7b950c3a14494d9fb3953dcd7e1979e44..6fc8153b7783585e12d785f7605e4d5d0ff698b5 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -1162,8 +1162,13 @@ void LLSurface::setWaterHeight(F32 height)
 	if (!mWaterObjp.isNull())
 	{
 		LLVector3 water_pos_region = mWaterObjp->getPositionRegion();
+		bool changed = water_pos_region.mV[VZ] != height;
 		water_pos_region.mV[VZ] = height;
 		mWaterObjp->setPositionRegion(water_pos_region);
+		if (changed)
+		{
+			LLWorld::getInstance()->updateWaterObjects();
+		}
 	}
 	else
 	{
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 6640e32cd21a9c2ace2c9d4a93d7f03453c924aa..d1cb9dabf1d5596426520b36c8dfb654a2bdad97 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -573,7 +573,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 
 		S32 water_clip = 0;
 		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) &&
-			 gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER))
+			 (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) || 
+			  gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)))
 		{
 			if (LLViewerCamera::getInstance()->cameraUnderWater())
 			{
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index a58b0d68de8d570dca43b817b54b53181d69e7bd..0e1553c421eaedf94121e79de7995ba819f16c71 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -168,8 +168,10 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
 	  res = new LLVOSurfacePatch(id, pcode, regionp); break;
 	case LL_VO_SKY:
 	  res = new LLVOSky(id, pcode, regionp); break;
+	case LL_VO_VOID_WATER:
+		res = new LLVOVoidWater(id, pcode, regionp); break;
 	case LL_VO_WATER:
-	  res = new LLVOWater(id, pcode, regionp); break;
+		res = new LLVOWater(id, pcode, regionp); break;
 	case LL_VO_GROUND:
 	  res = new LLVOGround(id, pcode, regionp); break;
 	case LL_VO_PART_GROUP:
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 7d697a4a5fd74aff5229b991bea78d13dba3930c..c2475c2709e6d13be27e983de0db30c3317b468d 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -131,7 +131,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 
 	typedef const child_list_t const_child_list_t;
 
-	LLViewerObject(const LLUUID &id, const LLPCode type, LLViewerRegion *regionp, BOOL is_global = FALSE);
+	LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global = FALSE);
 	MEM_TYPE_NEW(LLMemType::MTYPE_OBJECT);
 
 	virtual void markDead();				// Mark this object as dead, and clean up its references
@@ -518,14 +518,14 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	{
 		LL_VO_CLOUDS =				LL_PCODE_APP | 0x20,
 		LL_VO_SURFACE_PATCH =		LL_PCODE_APP | 0x30,
-		//LL_VO_STARS =				LL_PCODE_APP | 0x40,
+		LL_VO_WL_SKY =				LL_PCODE_APP | 0x40,
 		LL_VO_SQUARE_TORUS =		LL_PCODE_APP | 0x50,
 		LL_VO_SKY =					LL_PCODE_APP | 0x60,
-		LL_VO_WATER =				LL_PCODE_APP | 0x70,
-		LL_VO_GROUND =				LL_PCODE_APP | 0x80,
-		LL_VO_PART_GROUP =			LL_PCODE_APP | 0x90,
-		LL_VO_TRIANGLE_TORUS =		LL_PCODE_APP | 0xa0,
-		LL_VO_WL_SKY =				LL_PCODE_APP | 0xb0, // should this be moved to 0x40?
+		LL_VO_VOID_WATER =			LL_PCODE_APP | 0x70,
+		LL_VO_WATER =				LL_PCODE_APP | 0x80,
+		LL_VO_GROUND =				LL_PCODE_APP | 0x90,
+		LL_VO_PART_GROUP =			LL_PCODE_APP | 0xa0,
+		LL_VO_TRIANGLE_TORUS =		LL_PCODE_APP | 0xb0,
 		LL_VO_HUD_PART_GROUP =		LL_PCODE_APP | 0xc0,
 	} EVOType;
 
@@ -717,8 +717,8 @@ class LLViewerObjectMedia
 class LLAlphaObject : public LLViewerObject
 {
 public:
-	LLAlphaObject(const LLUUID &id, const LLPCode type, LLViewerRegion *regionp)
-	: LLViewerObject(id,type,regionp) 
+	LLAlphaObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
+	: LLViewerObject(id,pcode,regionp) 
 	{ mDepth = 0.f; }
 
 	virtual F32 getPartSize(S32 idx);
@@ -735,8 +735,8 @@ class LLAlphaObject : public LLViewerObject
 class LLStaticViewerObject : public LLViewerObject
 {
 public:
-	LLStaticViewerObject(const LLUUID& id, const LLPCode type, LLViewerRegion* regionp, BOOL is_global = FALSE)
-		: LLViewerObject(id,type,regionp, is_global)
+	LLStaticViewerObject(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp, BOOL is_global = FALSE)
+		: LLViewerObject(id,pcode,regionp, is_global)
 	{ }
 
 	virtual void updateDrawable(BOOL force_damped);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 7fb259e012bf48d781eb959f2c2657054dbb3b35..b684206960b329d900492b2f38d23fb8bb2d490f 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -266,6 +266,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	//MUST MATCH declaration of eObjectPartitions
 	mObjectPartition.push_back(new LLHUDPartition());		//PARTITION_HUD
 	mObjectPartition.push_back(new LLTerrainPartition());	//PARTITION_TERRAIN
+	mObjectPartition.push_back(new LLVoidWaterPartition());	//PARTITION_VOIDWATER
 	mObjectPartition.push_back(new LLWaterPartition());		//PARTITION_WATER
 	mObjectPartition.push_back(new LLTreePartition());		//PARTITION_TREE
 	mObjectPartition.push_back(new LLParticlePartition());	//PARTITION_PARTICLE
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 1ba025312b29462efbb899759147cbe3a838e0ec..8b71998f6054ddbaa7fccb8a1ee94ee317a5e093 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -73,6 +73,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	{
 		PARTITION_HUD=0,
 		PARTITION_TERRAIN,
+		PARTITION_VOIDWATER,
 		PARTITION_WATER,
 		PARTITION_TREE,
 		PARTITION_PARTICLE,
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index d078c153160eabfa54a62f52213620296b4a1495..c1abead36e4c9d10ae9fe4cad57cd4901f4d9eca 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -335,8 +335,8 @@ void LLViewerShaderMgr::setShaders()
 	}
 	else
 	{
-			LLPipeline::sRenderGlow = 
-			LLPipeline::sWaterReflections = FALSE;
+		LLPipeline::sRenderGlow = FALSE;
+		LLPipeline::sWaterReflections = FALSE;
 	}
 	
 	//hack to reset buffers that change behavior with shaders
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 0ee7a41378813cc5641f01f382df51b20c22712d..88d55cf14e732c18d237ae2ba30bd1f4b1d51765 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1404,6 +1404,11 @@ LLViewerWindow::LLViewerWindow(
 		gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
 	}
 
+	if (!gGLManager.mHasDepthClamp)
+	{
+		LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL;
+	}
+	
 	// If we crashed while initializng GL stuff last time, disable certain features
 	if (gSavedSettings.getBOOL("RenderInitError"))
 	{
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index eba600b50a30b87a95873b783662af4847fff869..2eb43984887adacb618d174a8eb69b04eef146aa 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -80,7 +80,7 @@ class LLVertexBufferTerrain : public LLVertexBuffer
 //============================================================================
 
 LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-	:	LLStaticViewerObject(id, LL_VO_SURFACE_PATCH, regionp),
+	:	LLStaticViewerObject(id, pcode, regionp),
 		mDirtiedPatch(FALSE),
 		mPool(NULL),
 		mBaseComp(0),
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 598938b710f4eff12dbc35cf13a0d6a58d8c2299..9280eb8fa48ded86450bab537fc1700b7d93c049 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -61,7 +61,8 @@ const F32 WAVE_STEP_INV	= (1. / WAVE_STEP);
 
 
 LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-:	LLStaticViewerObject(id, LL_VO_WATER, regionp)
+:	LLStaticViewerObject(id, pcode, regionp),
+	mRenderType(LLPipeline::RENDER_TYPE_WATER)
 {
 	// Terrain must draw during selection passes so it can block objects behind it.
 	mbCanSelect = FALSE;
@@ -114,7 +115,7 @@ LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline)
 {
 	pipeline->allocDrawable(this);
 	mDrawable->setLit(FALSE);
-	mDrawable->setRenderType(LLPipeline::RENDER_TYPE_WATER);
+	mDrawable->setRenderType(mRenderType);
 
 	LLDrawPoolWater *pool = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
 
@@ -268,6 +269,11 @@ U32 LLVOWater::getPartitionType() const
 	return LLViewerRegion::PARTITION_WATER; 
 }
 
+U32 LLVOVoidWater::getPartitionType() const
+{
+	return LLViewerRegion::PARTITION_VOIDWATER;
+}
+
 LLWaterPartition::LLWaterPartition()
 : LLSpatialPartition(0, FALSE, 0)
 {
@@ -275,3 +281,9 @@ LLWaterPartition::LLWaterPartition()
 	mDrawableType = LLPipeline::RENDER_TYPE_WATER;
 	mPartitionType = LLViewerRegion::PARTITION_WATER;
 }
+
+LLVoidWaterPartition::LLVoidWaterPartition()
+{
+	mDrawableType = LLPipeline::RENDER_TYPE_VOIDWATER;
+	mPartitionType = LLViewerRegion::PARTITION_VOIDWATER;
+}
diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h
index beefc3f17f186c79a0ff3f1304c5510c5868fd87..cb9584cabf6e7292da48f95dbabe00f9d0e638d2 100644
--- a/indra/newview/llvowater.h
+++ b/indra/newview/llvowater.h
@@ -29,6 +29,7 @@
 
 #include "llviewerobject.h"
 #include "llviewertexture.h"
+#include "pipeline.h"
 #include "v2math.h"
 
 const U32 N_RES	= 16; //32			// number of subdivisions of wave tile
@@ -77,6 +78,19 @@ class LLVOWater : public LLStaticViewerObject
 protected:
 	BOOL mUseTexture;
 	BOOL mIsEdgePatch;
+	S32  mRenderType; 
 };
 
+class LLVOVoidWater : public LLVOWater
+{
+public:
+	LLVOVoidWater(LLUUID const& id, LLPCode pcode, LLViewerRegion* regionp) : LLVOWater(id, pcode, regionp)
+	{
+		mRenderType = LLPipeline::RENDER_TYPE_VOIDWATER;
+	}
+
+	/*virtual*/ U32 getPartitionType() const;
+};
+
+
 #endif // LL_VOSURFACEPATCH_H
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 5760d04a084aff147368f0b11782df586570ced0..8731c9e1a7ef901ab4146651e7ef5ab6612fdda9 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -55,6 +55,11 @@
 #include "pipeline.h"
 #include "llappviewer.h"		// for do_disconnect()
 
+#include <deque>
+#include <queue>
+#include <map>
+#include <cstring>
+
 //
 // Globals
 //
@@ -834,10 +839,69 @@ F32 LLWorld::getLandFarClip() const
 
 void LLWorld::setLandFarClip(const F32 far_clip)
 {
+	static S32 const rwidth = (S32)REGION_WIDTH_U32;
+	S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth;
+	S32 const n2 = (llceil(far_clip) - 1) / rwidth;
+	bool need_water_objects_update = n1 != n2;
+
 	mLandFarClip = far_clip;
+
+	if (need_water_objects_update)
+	{
+		updateWaterObjects();
+	}
 }
 
+// Some region that we're connected to, but not the one we're in, gave us
+// a (possibly) new water height. Update it in our local copy.
+void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_height)
+{
+	for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter)
+	{
+		if ((*iter)->getName() == sim_name)
+		{
+			(*iter)->setWaterHeight(water_height);
+			break;
+		}
+	}
+}
 
+// There are three types of water objects:
+// Region water objects: the water in a region.
+// Hole water objects: water in the void but within current draw distance.
+// Edge water objects: the water outside the draw distance, up till the horizon.
+//
+// For example:
+//
+// -----------------------horizon-------------------------
+// |                 |                 |                 |
+// |  Edge Water     |                 |                 |
+// |                 |                 |                 |
+// |                 |                 |                 |
+// |                 |                 |                 |
+// |                 |                 |                 |
+// |                 |      rwidth     |                 |
+// |                 |     <----->     |                 |
+// -------------------------------------------------------
+// |                 |Hole |other|     |                 |
+// |                 |Water|reg. |     |                 |
+// |                 |-----------------|                 |
+// |                 |other|cur. |<--> |                 |
+// |                 |reg. | reg.|  \__|_ draw distance  |
+// |                 |-----------------|                 |
+// |                 |     |     |<--->|                 |
+// |                 |     |     |  \__|_ range          |
+// -------------------------------------------------------
+// |                 |<----width------>|<--horizon ext.->|
+// |                 |                 |                 |
+// |                 |                 |                 |
+// |                 |                 |                 |
+// |                 |                 |                 |
+// |                 |                 |                 |
+// |                 |                 |                 |
+// |                 |                 |                 |
+// -------------------------------------------------------
+//
 void LLWorld::updateWaterObjects()
 {
 	if (!gAgent.getRegion())
@@ -850,128 +914,265 @@ void LLWorld::updateWaterObjects()
 		return;
 	}
 
-	// First, determine the min and max "box" of water objects
-	S32 min_x = 0;
-	S32 min_y = 0;
-	S32 max_x = 0;
-	S32 max_y = 0;
+	// Region width in meters.
+	S32 const rwidth = (S32)REGION_WIDTH_U32;
+
+	// The distance we might see into the void
+	// when standing on the edge of a region, in meters.
+	S32 const draw_distance = llceil(mLandFarClip);
+
+	// We can only have "holes" in the water (where there no region) if we
+	// can have existing regions around it. Taking into account that this
+	// code is only executed when we enter a region, and not when we walk
+	// around in it, we (only) need to take into account regions that fall
+	// within the draw_distance.
+	//
+	// Set 'range' to draw_distance, rounded up to the nearest multiple of rwidth.
+	S32 const nsims = (draw_distance + rwidth - 1) / rwidth;
+	S32 const range = nsims * rwidth;
+
+	// Get South-West corner of current region.
+	LLViewerRegion const* regionp = gAgent.getRegion();
 	U32 region_x, region_y;
-
-	S32 rwidth = 256;
-
-	// We only want to fill in water for stuff that's near us, say, within 256 or 512m
-	S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256;
-
-	LLViewerRegion* regionp = gAgent.getRegion();
 	from_region_handle(regionp->getHandle(), &region_x, &region_y);
 
-	min_x = (S32)region_x - range;
-	min_y = (S32)region_y - range;
-	max_x = (S32)region_x + range;
-	max_y = (S32)region_y + range;
+	// The min. and max. coordinates of the South-West corners of the Hole water objects.
+	S32 const min_x = (S32)region_x - range;
+	S32 const min_y = (S32)region_y - range;
+	S32 const max_x = (S32)region_x + range;
+	S32 const max_y = (S32)region_y + range;
+
+	// Attempt to determine a sensible water height for all the
+	// Hole Water objects.
+	//
+	// It make little sense to try to guess what the best water
+	// height should be when that isn't completely obvious: if it's
+	// impossible to satisfy every region's water height without
+	// getting a jump in the water height.
+	//
+	// In order to keep the reasoning simple, we assume something
+	// logical as a group of connected regions, where the coastline
+	// is at the outer edge. Anything more complex that would "break"
+	// under such an assumption would probably break anyway (would
+	// depend on terrain editing and existing mega prims, say, if
+	// anything would make sense at all).
+	//
+	// So, what we do is find all connected regions within the
+	// draw distance that border void, and then pick the lowest
+	// water height of those (coast) regions.
+	S32 const n = 2 * nsims + 1;
+	S32 const origin = nsims + nsims * n;
+	std::vector<F32> water_heights(n * n);
+	std::vector<U8> checked(n * n, 0);		// index = nx + ny * n + origin;
+	U8 const region_bit = 1;
+	U8 const hole_bit = 2;
+	U8 const bordering_hole_bit = 4;
+	U8 const bordering_edge_bit = 8;
+	// Use the legacy waterheight for the Edge water in the case
+	// that we don't find any Hole water at all.
+	F32 water_height = DEFAULT_WATER_HEIGHT;
+	int max_count = 0;
+	LL_DEBUGS("WaterHeight") << "Current region: " << regionp->getName() << "; water height: " << regionp->getWaterHeight() << " m." << LL_ENDL;
+	std::map<S32, int> water_height_counts;
+	typedef std::queue<std::pair<S32, S32>, std::deque<std::pair<S32, S32> > > nxny_pairs_type;
+	nxny_pairs_type nxny_pairs;
+	nxny_pairs.push(nxny_pairs_type::value_type(0, 0));
+	water_heights[origin] = regionp->getWaterHeight();
+	checked[origin] = region_bit;
+	// For debugging purposes.
+	int number_of_connected_regions = 1;
+	int uninitialized_regions = 0;
+	int bordering_hole = 0;
+	int bordering_edge = 0;
+	while(!nxny_pairs.empty())
+	{
+		S32 const nx = nxny_pairs.front().first;
+		S32 const ny = nxny_pairs.front().second;
+		LL_DEBUGS("WaterHeight") << "nx,ny = " << nx << "," << ny << LL_ENDL;
+		S32 const index = nx + ny * n + origin;
+		nxny_pairs.pop();
+		for (S32 dir = 0; dir < 4; ++dir)
+		{
+			S32 const cnx = nx + gDirAxes[dir][0];
+			S32 const cny = ny + gDirAxes[dir][1];
+			LL_DEBUGS("WaterHeight") << "dir = " << dir << "; cnx,cny = " << cnx << "," << cny << LL_ENDL;
+			S32 const cindex = cnx + cny * n + origin;
+			bool is_hole = false;
+			bool is_edge = false;
+			LLViewerRegion* new_region_found = NULL;
+			if (cnx < -nsims || cnx > nsims ||
+			    cny < -nsims || cny > nsims)
+			{
+				LL_DEBUGS("WaterHeight") << "  Edge Water!" << LL_ENDL;
+				// Bumped into Edge water object.
+				is_edge = true;
+			}
+			else if (checked[cindex])
+			{
+				LL_DEBUGS("WaterHeight") << "  Already checked before!" << LL_ENDL;
+				// Already checked.
+				is_hole = (checked[cindex] & hole_bit);
+			}
+			else
+			{
+				S32 x = (S32)region_x + cnx * rwidth;
+				S32 y = (S32)region_y + cny * rwidth;
+				U64 region_handle = to_region_handle(x, y);
+				new_region_found = getRegionFromHandle(region_handle);
+				is_hole = !new_region_found;
+				checked[cindex] = is_hole ? hole_bit : region_bit;
+			}
+			if (is_hole)
+			{
+				// This was a region that borders at least one 'hole'.
+				// Count the found coastline.
+				F32 new_water_height = water_heights[index];
+				LL_DEBUGS("WaterHeight") << "  This is void; counting coastline with water height of " << new_water_height << LL_ENDL;
+				S32 new_water_height_cm = llround(new_water_height * 100);
+				int count = (water_height_counts[new_water_height_cm] += 1);
+				// Just use the lowest water height: this is mainly about the horizon water,
+				// and whatever we do, we don't want it to be possible to look under the water
+				// when looking in the distance: it is better to make a step downwards in water
+				// height when going away from the avie than a step upwards. However, since
+				// everyone is used to DEFAULT_WATER_HEIGHT, don't allow a single region
+				// to drag the water level below DEFAULT_WATER_HEIGHT on it's own.
+				if (bordering_hole == 0 ||			// First time we get here.
+				    (new_water_height >= DEFAULT_WATER_HEIGHT &&
+					 new_water_height < water_height) ||
+				    (new_water_height < DEFAULT_WATER_HEIGHT &&
+					 count > max_count)
+				   )
+				{
+					water_height = new_water_height;
+				}
+				if (count > max_count)
+				{
+					max_count = count;
+				}
+				if (!(checked[index] & bordering_hole_bit))
+				{
+					checked[index] |= bordering_hole_bit;
+					++bordering_hole;
+				}
+			}
+			else if (is_edge && !(checked[index] & bordering_edge_bit))
+			{
+				checked[index] |= bordering_edge_bit;
+				++bordering_edge;
+			}
+			if (!new_region_found)
+			{
+				// Dead end, there is no region here.
+				continue;
+			}
+			// Found a new connected region.
+			++number_of_connected_regions;
+			if (new_region_found->getName().empty())
+			{
+				// Uninitialized LLViewerRegion, don't use it's water height.
+				LL_DEBUGS("WaterHeight") << "  Uninitialized region." << LL_ENDL;
+				++uninitialized_regions;
+				continue;
+			}
+			nxny_pairs.push(nxny_pairs_type::value_type(cnx, cny));
+			water_heights[cindex] = new_region_found->getWaterHeight();
+			LL_DEBUGS("WaterHeight") << "  Found a new region (name: " << new_region_found->getName() << "; water height: " << water_heights[cindex] << " m)!" << LL_ENDL;
+		}
+	}
+	llinfos << "Number of connected regions: " << number_of_connected_regions << " (" << uninitialized_regions <<
+		" uninitialized); number of regions bordering Hole water: " << bordering_hole <<
+		"; number of regions bordering Edge water: " << bordering_edge << llendl;
+	llinfos << "Coastline count (height, count): ";
+	bool first = true;
+	for (std::map<S32, int>::iterator iter = water_height_counts.begin(); iter != water_height_counts.end(); ++iter)
+	{
+		if (!first) llcont << ", ";
+		llcont << "(" << (iter->first / 100.f) << ", " << iter->second << ")";
+		first = false;
+	}
+	llcont << llendl;
+	llinfos << "Water height used for Hole and Edge water objects: " << water_height << llendl;
 
-	F32 height = 0.f;
-	
-	for (region_list_t::iterator iter = mRegionList.begin();
-		 iter != mRegionList.end(); ++iter)
+	// Update all Region water objects.
+	for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter)
 	{
 		LLViewerRegion* regionp = *iter;
 		LLVOWater* waterp = regionp->getLand().getWaterObj();
-		height += regionp->getWaterHeight();
 		if (waterp)
 		{
 			gObjectList.updateActive(waterp);
 		}
 	}
 
+	// Clean up all existing Hole water objects.
 	for (std::list<LLVOWater*>::iterator iter = mHoleWaterObjects.begin();
-		 iter != mHoleWaterObjects.end(); ++ iter)
+		 iter != mHoleWaterObjects.end(); ++iter)
 	{
 		LLVOWater* waterp = *iter;
 		gObjectList.killObject(waterp);
 	}
 	mHoleWaterObjects.clear();
 
-	// Now, get a list of the holes
-	S32 x, y;
-	for (x = min_x; x <= max_x; x += rwidth)
+	// Let the Edge and Hole water boxes be 1024 meter high so that they
+	// are never too small to be drawn (A LL_VO_*_WATER box has water
+	// rendered on it's bottom surface only), and put their bottom at
+	// the current regions water height.
+	F32 const box_height = 1024;
+	F32 const water_center_z = water_height + box_height / 2;
+
+	// Create new Hole water objects within 'range' where there is no region.
+	for (S32 x = min_x; x <= max_x; x += rwidth)
 	{
-		for (y = min_y; y <= max_y; y += rwidth)
+		for (S32 y = min_y; y <= max_y; y += rwidth)
 		{
 			U64 region_handle = to_region_handle(x, y);
 			if (!getRegionFromHandle(region_handle))
 			{
-				LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion());
+				LLVOWater* waterp = (LLVOWater*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, gAgent.getRegion());
 				waterp->setUseTexture(FALSE);
-				waterp->setPositionGlobal(LLVector3d(x + rwidth/2,
-													 y + rwidth/2,
-													 256.f+DEFAULT_WATER_HEIGHT));
-				waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f));
+				waterp->setPositionGlobal(LLVector3d(x + rwidth / 2, y + rwidth / 2, water_center_z));
+				waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, box_height));
 				gPipeline.createObject(waterp);
 				mHoleWaterObjects.push_back(waterp);
 			}
 		}
 	}
 
-	// Update edge water objects
-	S32 wx, wy;
-	S32 center_x, center_y;
-	wx = (max_x - min_x) + rwidth;
-	wy = (max_y - min_y) + rwidth;
-	center_x = min_x + (wx >> 1);
-	center_y = min_y + (wy >> 1);
-
-	S32 add_boundary[4] = {
-		512 - (max_x - region_x),
-		512 - (max_y - region_y),
-		512 - (region_x - min_x),
-		512 - (region_y - min_y) };
+	// Center of the region.
+	S32 const center_x = region_x + rwidth / 2;
+	S32 const center_y = region_y + rwidth / 2;
+	// Width of the area with Hole water objects.
+	S32 const width = rwidth + 2 * range;
+	S32 const horizon_extend = 2048 + 512 - range;	// Legacy value.
+	// The overlap is needed to get rid of sky pixels being visible between the
+	// Edge and Hole water object at greater distances (due to floating point
+	// round off errors).
+	S32 const edge_hole_overlap = 1;		// Twice the actual overlap.
 		
-	S32 dir;
-	for (dir = 0; dir < 8; dir++)
+	for (S32 dir = 0; dir < 8; ++dir)
 	{
-		S32 dim[2] = { 0 };
-		switch (gDirAxes[dir][0])
-		{
-		case -1: dim[0] = add_boundary[2]; break;
-		case  0: dim[0] = wx; break;
-		default: dim[0] = add_boundary[0]; break;
-		}
-		switch (gDirAxes[dir][1])
-		{
-		case -1: dim[1] = add_boundary[3]; break;
-		case  0: dim[1] = wy; break;
-		default: dim[1] = add_boundary[1]; break;
-		}
+		// Size of the Edge water objects.
+		S32 const dim_x = (gDirAxes[dir][0] == 0) ? width : (horizon_extend + edge_hole_overlap);
+		S32 const dim_y = (gDirAxes[dir][1] == 0) ? width : (horizon_extend + edge_hole_overlap);
+		// And their position.
+		S32 const water_center_x = center_x + (width + horizon_extend) / 2 * gDirAxes[dir][0];
+		S32 const water_center_y = center_y + (width + horizon_extend) / 2 * gDirAxes[dir][1];
 
-		// Resize and reshape the water objects
-		const S32 water_center_x = center_x + llround((wx + dim[0]) * 0.5f * gDirAxes[dir][0]);
-		const S32 water_center_y = center_y + llround((wy + dim[1]) * 0.5f * gDirAxes[dir][1]);
-		
 		LLVOWater* waterp = mEdgeWaterObjects[dir];
 		if (!waterp || waterp->isDead())
 		{
 			// The edge water objects can be dead because they're attached to the region that the
 			// agent was in when they were originally created.
-			mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER,
-																				 gAgent.getRegion());
+			mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, gAgent.getRegion());
 			waterp = mEdgeWaterObjects[dir];
 			waterp->setUseTexture(FALSE);
-			waterp->setIsEdgePatch(TRUE);
+			waterp->setIsEdgePatch(TRUE);		// Mark that this is edge water and not hole water.
 			gPipeline.createObject(waterp);
 		}
 
 		waterp->setRegion(gAgent.getRegion());
-		LLVector3d water_pos(water_center_x, water_center_y, 
-			DEFAULT_WATER_HEIGHT+256.f);
-		LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f);
-
-		//stretch out to horizon
-		water_scale.mV[0] += fabsf(2048.f * gDirAxes[dir][0]);
-		water_scale.mV[1] += fabsf(2048.f * gDirAxes[dir][1]);
-
-		water_pos.mdV[0] += 1024.f * gDirAxes[dir][0];
-		water_pos.mdV[1] += 1024.f * gDirAxes[dir][1];
+		LLVector3d water_pos(water_center_x, water_center_y, water_center_z);
+		LLVector3 water_scale((F32) dim_x, (F32) dim_y, box_height);
 
 		waterp->setPositionGlobal(water_pos);
 		waterp->setScale(water_scale);
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index 4465fde210885eb77890928f1540c0e4955a86b3..c60dc8dc292aaa1e2ca621ca72398b02bdc695f8 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -137,6 +137,7 @@ class LLWorld : public LLSingleton<LLWorld>
 
 	LLViewerTexture *getDefaultWaterTexture();
 	void updateWaterObjects();
+	void waterHeightRegionInfo(std::string const& sim_name, F32 water_height);
 	void shiftRegions(const LLVector3& offset);
 
 	void setSpaceTimeUSec(const U64 space_time_usec);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 45e6ba996fde422fa05695440ff0fc5f65e07cdb..37c8f48de9f3ae361dc5d8c910bf5f90d7b0f5ad 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -628,14 +628,14 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 //static
 void LLPipeline::updateRenderDeferred()
 {
-	BOOL deferred = (gSavedSettings.getBOOL("RenderDeferred") && 
-		LLRenderTarget::sUseFBO &&
-			 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
-		gSavedSettings.getBOOL("VertexShaderEnable") && 
-		gSavedSettings.getBOOL("RenderAvatarVP") &&
-			 (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) &&
-		!gUseWireframe;
-	
+	BOOL deferred = ((gSavedSettings.getBOOL("RenderDeferred") && 
+					 LLRenderTarget::sUseFBO &&
+					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+					 gSavedSettings.getBOOL("VertexShaderEnable") && 
+					 gSavedSettings.getBOOL("RenderAvatarVP") &&
+					 gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) &&
+					!gUseWireframe;
+
 	sRenderDeferred = deferred;			
 }
 
@@ -1637,20 +1637,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
 
 	camera.disableUserClipPlane();
 
-	if (gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull())
+	if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) && 
+		gSky.mVOSkyp.notNull() && 
+		gSky.mVOSkyp->mDrawable.notNull())
 	{
-		// Hack for sky - always visible.
-		if (hasRenderType(LLPipeline::RENDER_TYPE_SKY)) 
-		{
-			gSky.mVOSkyp->mDrawable->setVisible(camera);
-			sCull->pushDrawable(gSky.mVOSkyp->mDrawable);
-			gSky.updateCull();
-			stop_glerror();
-		}
-	}
-	else
-	{
-		llinfos << "No sky drawable!" << llendl;
+		gSky.mVOSkyp->mDrawable->setVisible(camera);
+		sCull->pushDrawable(gSky.mVOSkyp->mDrawable);
+		gSky.updateCull();
+		stop_glerror();
 	}
 
 	if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) && 
@@ -2220,6 +2214,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
 					  LLPipeline::RENDER_TYPE_TERRAIN,
 					  LLPipeline::RENDER_TYPE_TREE,
 					  LLPipeline::RENDER_TYPE_SKY,
+					  LLPipeline::RENDER_TYPE_VOIDWATER,
 					  LLPipeline::RENDER_TYPE_WATER,
 					  LLPipeline::END_RENDER_TYPES))
 	{
@@ -4832,6 +4827,10 @@ void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light)
 void LLPipeline::toggleRenderType(U32 type)
 {
 	gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type];
+	if (type == LLPipeline::RENDER_TYPE_WATER)
+	{
+		gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER] = !gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER];
+	}
 }
 
 //static
@@ -7159,6 +7158,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 				gPipeline.pushRenderTypeMask();
 
 				clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
+									LLPipeline::RENDER_TYPE_VOIDWATER,
 									LLPipeline::RENDER_TYPE_GROUND,
 									LLPipeline::RENDER_TYPE_SKY,
 									LLPipeline::RENDER_TYPE_CLOUDS,
@@ -7211,6 +7211,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 		{
 			camera.setFar(camera_in.getFar());
 			clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
+								LLPipeline::RENDER_TYPE_VOIDWATER,
 								LLPipeline::RENDER_TYPE_GROUND,
 								END_RENDER_TYPES);	
 			stop_glerror();
@@ -7727,6 +7728,7 @@ void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<L
 								 LLPipeline::RENDER_TYPE_TREE, 
 								 LLPipeline::RENDER_TYPE_TERRAIN,
 								 LLPipeline::RENDER_TYPE_WATER,
+								 LLPipeline::RENDER_TYPE_VOIDWATER,
 								 LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW,
 								 LLPipeline::RENDER_TYPE_AVATAR,
 								 LLPipeline::RENDER_TYPE_PASS_SIMPLE,
@@ -7910,6 +7912,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 					LLPipeline::RENDER_TYPE_TREE, 
 					LLPipeline::RENDER_TYPE_TERRAIN,
 					LLPipeline::RENDER_TYPE_WATER,
+					LLPipeline::RENDER_TYPE_VOIDWATER,
 					LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW,
 					LLPipeline::RENDER_TYPE_PASS_SIMPLE,
 					LLPipeline::RENDER_TYPE_PASS_BUMP,
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 397d64aa1d0abd210ed0f530be8b3f2f16dc0990..3f785a99fef3f178e8ea1fa4ed5f90173630dd56 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -358,6 +358,7 @@ class LLPipeline
 		RENDER_TYPE_AVATAR						= LLDrawPool::POOL_AVATAR,
 		RENDER_TYPE_TREE						= LLDrawPool::POOL_TREE,
 		RENDER_TYPE_INVISIBLE					= LLDrawPool::POOL_INVISIBLE,
+		RENDER_TYPE_VOIDWATER					= LLDrawPool::POOL_VOIDWATER,
 		RENDER_TYPE_WATER						= LLDrawPool::POOL_WATER,
  		RENDER_TYPE_ALPHA						= LLDrawPool::POOL_ALPHA,
 		RENDER_TYPE_GLOW						= LLDrawPool::POOL_GLOW,
diff --git a/indra/newview/skins/default/xui/en/alert_line_editor.xml b/indra/newview/skins/default/xui/en/alert_line_editor.xml
index 82bf5fc8dad1463c5487051a29d0a955114eabf3..54dbc698c830f7313e2c6ef5762acc45f2b23f33 100644
--- a/indra/newview/skins/default/xui/en/alert_line_editor.xml
+++ b/indra/newview/skins/default/xui/en/alert_line_editor.xml
@@ -4,7 +4,7 @@
   revert_on_esc="true"
   commit_on_focus_lost="true"
   ignore_tab="true"
-  max_length="254"
+  max_length_bytes="254"
   text_pad_right="0"
   text_pad_left="2"
   mouse_opaque="true"/>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 89ed16e7c2060c48d17b040572cc3a6dbf5d9e92..0a27cc7bc92734ae4c638e28ccfe0d1b0df8ee7f 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -128,7 +128,7 @@
              height="23"
              layout="topleft"
              left_pad="2"
-             max_length="63"
+             max_length_bytes="63"
              name="Name"
              top_delta="0"
              width="365" />
@@ -1081,7 +1081,7 @@ Leyla Linden               </text>
              follows="left|top"
              height="23"
              layout="topleft"
-             max_length="6"
+             max_length_bytes="6"
              name="clean other time"
              left_pad="0"
              width="46"
@@ -1625,7 +1625,7 @@ Only large parcels can be listed in search.
              height="23"
              layout="topleft"
              left_pad="0"
-             max_length="255"
+             max_length_bytes="255"
              name="media_url"
              select_on_focus="true"
              width="300"
@@ -1666,7 +1666,7 @@ Only large parcels can be listed in search.
              height="20"
              layout="topleft"
              left="110"
-             max_length="255"
+             max_length_bytes="255"
              name="url_description"
              select_on_focus="true"
              tool_tip="Text displayed next to play/load button"
@@ -1821,7 +1821,7 @@ Only large parcels can be listed in search.
              height="23"
              layout="topleft"
              left="100"
-             max_length="255"
+             max_length_bytes="255"
              name="music_url"
              top_delta="0"
              right="-15"
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
index 637f9f55d400b741501b25bf3f830e681f28b120..cd5922a9a29a4bbd1d96d8f1df1f6ee3931853ee 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
@@ -114,7 +114,7 @@
     </text>
     <line_editor
      type="string"
-     max_length="10"
+     max_length_bytes="10"
      halign="right"
      font="SansSerifMedium"
      select_on_focus="true"
diff --git a/indra/newview/skins/default/xui/en/floater_god_tools.xml b/indra/newview/skins/default/xui/en/floater_god_tools.xml
index dfe3cf44858abd578e494c8f5843325de7a59e44..e7131e20cbd05c92f83f82abd815a184c50c85b4 100644
--- a/indra/newview/skins/default/xui/en/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_god_tools.xml
@@ -73,7 +73,7 @@
              height="20"
              layout="topleft"
              left_pad="0"
-             max_length="63"
+             max_length_bytes="63"
              name="region name"
              top_delta="0"
              width="250">
@@ -236,7 +236,7 @@
              height="16"
              layout="topleft"
              left_delta="108"
-             max_length="10"
+             max_length_bytes="10"
              name="estate"
              top_delta="0"
              width="50" />
@@ -260,7 +260,7 @@
              height="16"
              layout="topleft"
              left_delta="108"
-             max_length="10"
+             max_length_bytes="10"
              name="parentestate"
              tool_tip="This is the parent estate for this region"
              top_delta="0"
@@ -287,7 +287,7 @@
              height="16"
              layout="topleft"
              left_delta="88"
-             max_length="10"
+             max_length_bytes="10"
              name="gridposx"
              tool_tip="This is the grid x position for this region"
              top_delta="0"
@@ -302,7 +302,7 @@
              height="16"
              layout="topleft"
              left_pad="10"
-             max_length="10"
+             max_length_bytes="10"
              name="gridposy"
              tool_tip="This is the grid y position for this region"
              top_delta="0"
@@ -329,7 +329,7 @@
              height="16"
              layout="topleft"
              left_pad="0"
-             max_length="10"
+             max_length_bytes="10"
              name="redirectx"
              width="50">
 			       <line_editor.commit_callback
@@ -342,7 +342,7 @@
              height="16"
              layout="topleft"
              left_pad="10"
-             max_length="10"
+             max_length_bytes="10"
              name="redirecty"
              top_delta="0"
              width="40">
@@ -754,7 +754,7 @@
              height="22"
              layout="topleft"
              left_pad="10"
-             max_length="63"
+             max_length_bytes="63"
              name="parameter"
              top_delta="0"
              width="290" />
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
index 2ef52bf5391daa614eabd01cb7c38e8e84098680..29f09dd0b27862d4b9498d270d5573113344b5ea 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
@@ -58,7 +58,7 @@
      height="16"
      layout="topleft"
      left_delta="78"
-     max_length="63"
+     max_length_bytes="63"
      name="LabelItemName"
      top_delta="0"
      width="252" />
@@ -81,7 +81,7 @@
      height="16"
      layout="topleft"
      left_delta="78"
-     max_length="127"
+     max_length_bytes="127"
      name="LabelItemDesc"
      top_delta="0"
      width="252" />
@@ -348,7 +348,7 @@
      height="16"
      layout="topleft"
      left_pad="5"
-     max_length="25"
+     max_length_bytes="25"
      name="EditPrice"
      top_delta="0"
      width="242" /-->
diff --git a/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml
index 1d73d516d0bc6508597f397216462d61e5d67249..068737494f30a34af05f8f04a23782e425659bf3 100644
--- a/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml
@@ -50,7 +50,7 @@ as a new Outfit:
      left_delta="0"
      show_text_as_tentative="false"
      top_pad="0"
-     max_length="63"
+     max_length_bytes="63"
      name="name ed"
      width="200">
         [DESC] (new)
diff --git a/indra/newview/skins/default/xui/en/floater_pay.xml b/indra/newview/skins/default/xui/en/floater_pay.xml
index 7ab565313ea6cd55a00d4f0ffebd5e02ade23225..41a7134b1de1bb812a1b585eb27df5fc8373b054 100644
--- a/indra/newview/skins/default/xui/en/floater_pay.xml
+++ b/indra/newview/skins/default/xui/en/floater_pay.xml
@@ -84,7 +84,7 @@
      top_pad="0"
      layout="topleft"
      left="130"
-     max_length="9"
+     max_length_bytes="9"
      name="amount"
      width="80" />
     <button
diff --git a/indra/newview/skins/default/xui/en/floater_pay_object.xml b/indra/newview/skins/default/xui/en/floater_pay_object.xml
index d8cfed7b09ad11f9bbd85ddd60721579408c93bd..d3a35c205171ac2047f4e64e6d7670d3a954dbc8 100644
--- a/indra/newview/skins/default/xui/en/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_pay_object.xml
@@ -117,7 +117,7 @@
      top_pad="0"
      layout="topleft"
      left="120"
-     max_length="9"
+     max_length_bytes="9"
      name="amount"
      width="80" />
     <button
diff --git a/indra/newview/skins/default/xui/en/floater_post_process.xml b/indra/newview/skins/default/xui/en/floater_post_process.xml
index 05559adf89b26933dddb8144418be649807a01db..05943a10d382f0694ad3b1a67d6a727f311a3394 100644
--- a/indra/newview/skins/default/xui/en/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/en/floater_post_process.xml
@@ -416,7 +416,7 @@
              label="Effect Name"
              layout="topleft"
              left_delta="0"
-             max_length="40"
+             max_length_bytes="40"
              name="PPEffectNameEditor"
              tab_group="1"
              top_pad="22"
diff --git a/indra/newview/skins/default/xui/en/floater_postcard.xml b/indra/newview/skins/default/xui/en/floater_postcard.xml
index 6f78363b2535c62556ed02e535402005abd1459d..b4ecedd9815d3bf0fcea79701d3ef0ccabcc9e44 100644
--- a/indra/newview/skins/default/xui/en/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/en/floater_postcard.xml
@@ -78,7 +78,7 @@
      height="20"
      layout="topleft"
      left_delta="108"
-     max_length="100"
+     max_length_bytes="100"
      name="name_form"
      top_delta="-4"
      width="150" />
@@ -99,7 +99,7 @@
      label="Type your subject here."
      layout="topleft"
      left_delta="108"
-     max_length="100"
+     max_length_bytes="100"
      name="subject_form"
      top_delta="-4"
      width="150" />
diff --git a/indra/newview/skins/default/xui/en/floater_preview_animation.xml b/indra/newview/skins/default/xui/en/floater_preview_animation.xml
index 6dc073728b84f1ba94fbc024d8e7c6fb2ce0ea26..65efc46c7173470a8a77183d1374184589451a8b 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_animation.xml
@@ -32,7 +32,7 @@
      height="19"
      layout="topleft"
      left_delta="95"
-     max_length="127"
+     max_length_bytes="127"
      name="desc"
      top="19"
      width="170" />
diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
index 19034019883ae0a3ee79985c64710aa492a66e56..a17cf8eea8ba43df2b56bc8ad507f8356cc9758c 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
@@ -80,7 +80,7 @@
      height="20"
      layout="topleft"
      left_delta="89"
-     max_length="31"
+     max_length_bytes="31"
      name="trigger_editor"
      top_delta="-4"
      width="175" />
@@ -104,7 +104,7 @@
      height="20"
      layout="topleft"
      left_delta="99"
-     max_length="31"
+     max_length_bytes="31"
      name="replace_editor"
      tool_tip="Replace the trigger word(s) with these words. For example, trigger &apos;hello&apos; replace with &apos;howdy&apos; will turn the chat &apos;I wanted to say hello&apos; into &apos;I wanted to say howdy&apos; as well as playing the gesture"
      top_delta="-4"
@@ -263,7 +263,7 @@
      height="20"
      layout="topleft"
      left_delta="0"
-     max_length="127"
+     max_length_bytes="127"
      name="chat_editor"
      top="330"
      width="100" />
@@ -316,7 +316,7 @@
      height="20"
      layout="topleft"
      left_pad="10"
-     max_length="15"
+     max_length_bytes="15"
      name="wait_time_editor"
      top_delta="1"
      width="50" />
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index e5a5fab9b9321f8294681324b9fd0895c5506fac..8c9e1d52b33fd39a32dacfab781ac672e8ea4afe 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -56,7 +56,7 @@
      height="22"
      layout="topleft"
      left_pad="0"
-     max_length="127"
+     max_length_bytes="127"
      name="desc"
      width="296" />
     <text_editor
diff --git a/indra/newview/skins/default/xui/en/floater_preview_sound.xml b/indra/newview/skins/default/xui/en/floater_preview_sound.xml
index f3be8c4131fb2c93d638d643a4b6a520932ca81e..62ef4c3097e8cca9a82c10b3a04b43c3ddfe48ab 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_sound.xml
@@ -32,7 +32,7 @@
      height="19"
      layout="topleft"
      left_pad="0"
-     max_length="127"
+     max_length_bytes="127"
      name="desc"
      width="170" />
     <button
diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
index 7fd7eab867599964950d0d1ec348f55bb3d66848..a79d2f63cb346e1419ac5a87b081adae4d74a8cd 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
@@ -40,7 +40,7 @@
      height="19"
      layout="topleft"
      left_pad="0"
-     max_length="127"
+     max_length_bytes="127"
      name="desc"
      width="190" />
     <text
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index 47383c80101db97dbcbb0517ee18523b2dfc76c6..e6d749a3f01a93b7f47f0c5964fb9766d117737f 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -416,7 +416,7 @@
      height="23"
      layout="topleft"
      left="10"
-     max_length="256"
+     max_length_bytes="256"
      name="abuse_location_edit"
      top_pad="0"
      width="313" />
@@ -441,7 +441,7 @@
      height="23"
      layout="topleft"
      left_delta="0"
-     max_length="64"
+     max_length_bytes="64"
      name="summary_edit"
      top_pad="0"
      width="313" />
diff --git a/indra/newview/skins/default/xui/en/floater_script_preview.xml b/indra/newview/skins/default/xui/en/floater_script_preview.xml
index d0cd00d14715b3f3fe9881cefdcf79325b6a1398..8c03b560400a755999f184eb508d9b1cd1987915 100644
--- a/indra/newview/skins/default/xui/en/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_script_preview.xml
@@ -55,7 +55,7 @@
      height="19"
      layout="topleft"
      left_delta="80"
-     max_length="127"
+     max_length_bytes="127"
      name="desc"
      top_delta="0"
      width="394" />
diff --git a/indra/newview/skins/default/xui/en/floater_sound_preview.xml b/indra/newview/skins/default/xui/en/floater_sound_preview.xml
index ca54ee66049019ea9478b12e82be91260d31e5ce..af791466b6bf55e17289f871ea464e7cd1c24028 100644
--- a/indra/newview/skins/default/xui/en/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_sound_preview.xml
@@ -27,7 +27,7 @@
      height="19"
      layout="topleft"
      left_delta="0"
-     max_length="63"
+     max_length_bytes="63"
      name="name_form"
      top_pad="0"
      width="280" />
@@ -51,7 +51,7 @@
      height="19"
      layout="topleft"
      left_delta="0"
-     max_length="127"
+     max_length_bytes="127"
      name="description_form"
      top_pad="0"
      width="280" />
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 4c508035be42ed9e1b3c12cae79c3d85c7d8f402..d5be64192be5098f75a698185e869a0d86713e15 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -831,7 +831,7 @@
              follows="left|top|right"
              height="19"
              left_pad="0"
-             max_length="63"
+             max_length_bytes="63"
              name="Object Name"
              select_on_focus="true"
              top_delta="0"
@@ -849,7 +849,7 @@
              follows="left|top|right"
              height="19"
              left_pad="0"
-             max_length="127"
+             max_length_bytes="127"
              name="Object Description"
              select_on_focus="true"
              top_delta="0"
@@ -2554,7 +2554,7 @@ even though the user gets a free copy.
              height="16"
              layout="topleft"
              left="10"
-             max_length="63"
+             max_length_bytes="63"
              name="Home Url"
              select_on_focus="true"
              top="134"
diff --git a/indra/newview/skins/default/xui/en/floater_ui_preview.xml b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
index 3b10a57c500268e0a487a273451d90a1030d853e..12c45617530885b9677f4c40f7920e35f816b5db 100644
--- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
@@ -241,7 +241,7 @@
              height="20"
              layout="topleft"
              left_delta="100"
-             max_length="300"
+             max_length_bytes="300"
              name="executable_path_field"
              select_on_focus="true"
              tool_tip="The full path to an editor (executable) to edit floater XML files (quotes not necessary)"
@@ -280,7 +280,7 @@
              height="20"
              layout="topleft"
              left_delta="100"
-             max_length="300"
+             max_length_bytes="300"
              name="executable_args_field"
              select_on_focus="true"
              tool_tip="Command-line arguments to the editor; use &apos;%FILE%&apos; to refer to the target file; &apos;YourProgram.exe FileName.xml&apos; will be run if this field is empty"
@@ -321,7 +321,7 @@
              height="20"
              layout="topleft"
              left_delta="65"
-             max_length="300"
+             max_length_bytes="300"
              name="vlt_diff_path_field"
              select_on_focus="true"
              tool_tip="The full path to an XML D0 or D1 localization difference file generated by the Viewer Localization Toolkit"
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index 20629018e2e86086de1f601eafbb874d4405821f..019e7cd032a5e84c9b0ed5c878c98eb23ba60299 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -541,7 +541,7 @@
       halign="right"
       height="16"
       layout="topleft"
-      left="25"
+      left="15"
       name="events_label"
       top_pad="16"
       width="70">
@@ -574,7 +574,8 @@
         left_delta="47"
         max_val="255"
         min_val="0"
-        name="teleport_coordinate_y" >
+        name="teleport_coordinate_y"
+        width="44" >
         <spinner.commit_callback
           function="WMap.Coordinates" />
       </spinner>
@@ -584,12 +585,13 @@
         follows="right|bottom"
         height="23"
         increment="1"
-        initial_value="128"
+        initial_value="23"
         layout="topleft"
         left_delta="47"
-        max_val="255"
+        max_val="4096"
         min_val="0"
-        name="teleport_coordinate_z">
+        name="teleport_coordinate_z"
+        width="55" >
         <spinner.commit_callback
           function="WMap.Coordinates" />
       </spinner>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
index 5934956559bb680362785a699e1b71f344b8f749..ce0438fbc98f16832ea3a6705163d48b469246af 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
@@ -119,7 +119,7 @@
          layout="topleft"
          left="10"
          top_pad="2"
-         max_length="30"
+         max_length_bytes="30"
          name="classified_name"
          prevalidate_callback="ascii"
          text_color="black"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index c4b831b71c4f4319c562520ddcaa58b79deebef5..a284d3ccc029c846290f6fc567514aa6d4b92c41 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -104,7 +104,7 @@
          layout="topleft"
          left="10"
          top_pad="2"
-         max_length="63"
+         max_length_bytes="63"
          name="pick_name"
          text_color="black"
          width="273" />
diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
index b8ef612c6ca8b65edf66f680fea50d4ec7abd1ba..b3e9586ee9347ce30347082e409c33cba3c1dd4b 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
@@ -241,7 +241,7 @@
          height="23"
          layout="topleft"
          left="10"
-         max_length="63"
+         max_length_bytes="63"
          name="description"
          prevalidate_callback="ascii"
          select_on_focus="true"
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index 3ded5c6678c16c0e53fd5f6424e11a87a6177555..0347d2feec5e540a038751245893cf536325cacf 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -71,7 +71,7 @@ background_visible="true"
      label="Type your new group name here"
      layout="topleft"
      left_delta="10"
-     max_length="35"
+     max_length_bytes="35"
      name="group_name_editor"
      top_delta="5"
      width="270"
diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
index 2e57c85d6f71201e567f10577bb4b2564ab0d2a9..1270a21710bfafc03a7b9c1be88f51588cc414e8 100644
--- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
@@ -184,7 +184,7 @@
      height="19"
      layout="topleft"
      left_pad="5"
-     max_length="10"
+     max_length_bytes="10"
      name="your_contribution_line_editor"
      top_delta="0"
      width="80" />
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 41f2b28004ad97a98051403d73bfd6347c4cdaf8..600b0e3b71ddac9cf9b6dc38b7179dfc6ae43865 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -138,7 +138,7 @@ Maximum 200 per group daily
          height="16"
          layout="topleft"
          left_pad="3"
-         max_length="63"
+         max_length_bytes="63"
          name="create_subject"
          prevalidate_callback="ascii"
          width="220" />
@@ -180,7 +180,7 @@ Maximum 200 per group daily
          enabled="false"
          height="19"
          layout="topleft"
-         max_length="90"
+         max_length_bytes="90"
          mouse_opaque="false"
          name="create_inventory_name"
          top_pad="2"
@@ -307,7 +307,7 @@ Maximum 200 per group daily
          height="20"
          layout="topleft"
          left_pad="3"
-         max_length="63"
+         max_length_bytes="63"
          name="view_subject"
          top_delta="-1"
          visible="false"
@@ -341,7 +341,7 @@ Maximum 200 per group daily
          height="20"
          layout="topleft"
          left="5"
-         max_length="63"
+         max_length_bytes="63"
          mouse_opaque="false"
          name="view_inventory_name"
          top_pad="8"
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 074e9bf5e5813d041c9f2720a133d6ea3e1d1fd6..a7178dc28864d56fb5aae93571ee6431e6d5d396 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -390,7 +390,7 @@ things in this group. There&apos;s a broad variety of Abilities.
          left="0"
          follows="left|top|right"
          right="-1"
-         max_length="20"
+         max_length_bytes="20"
          name="role_name"
          top_pad="0"
          width="300">
@@ -413,7 +413,7 @@ things in this group. There&apos;s a broad variety of Abilities.
          left="0"
          follows="left|top|right"
          right="-1"
-         max_length="20"
+         max_length_bytes="20"
          name="role_title"
          top_pad="0"
          width="300">
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index f8635b9edbdbf03fa8405341a24b181377450c0a..6ee2abc70fe233329979d1809f99dca8e33c345d 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -252,7 +252,7 @@
                  height="22"
                  layout="topleft"
                  left="0"
-                 max_length="63"
+                 max_length_bytes="63"
                  name="title_editor"
                  prevalidate_callback="ascii"
                  text_readonly_color="white"
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index a5d730711c4b4cbc0be088413779769ed093b30d..b181ca3bbad8db1defeb8ea60aceacf2e4d1ac28 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -69,7 +69,7 @@ follows="left|bottom"
 height="22"
 label="bobsmith12 or Steller Sunshine"
 left_delta="0"
-max_length="63"
+max_length_bytes="63"
 name="username_edit"
 prevalidate_callback="ascii" 
 select_on_focus="true"
@@ -89,7 +89,7 @@ top="20"
 <line_editor
 follows="left|bottom"
   height="22"
-  max_length="16"
+  max_length_bytes="16"
 name="password_edit"
 select_on_focus="true"
   top_pad="0"
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 55df70eb71009f68c73952c8291b911be9e78747..5871eb06540206df6e97c633b4ae6d26c1bef293 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -17,7 +17,7 @@
      layout="topleft"
      left_delta="3"
      left="0"
-     max_length="1024"
+     max_length_bytes="1023"
      name="chat_box"
      text_pad_left="5"
      text_pad_right="25"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 7d9bd1bf2aafc336bd157341b77a2035c2778299..9d496575c9782492ceea67b4196acf14f5af00e4 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -280,7 +280,7 @@ Automatic position for:
      enabled_control="EnableVoiceChat"
      height="23"
      left="80"
-     max_length="200"
+     max_length_bytes="200"
      name="modifier_combo"
      label="Push-to-Speak trigger"
      top_pad="5"
diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
index b25fd695c96cc6151f36cff0b567a9c48a990812..273c2524742b21ede2e5d50feec5021b124d450a 100644
--- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
@@ -319,7 +319,7 @@
 		min_width="90">
 	  <line_editor 
 		  name="media_address_url"
-		  max_length="1024"
+		  max_length_bytes="1023"
 		  follows="top|left|right" 
 		  height="22"
 		  top="0"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index 8760c911dcfb039220de9250574dcb5533e3e3f7..6940d1549ba249b9ccdb397810dc3312ceb5fc9d 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -118,7 +118,7 @@
                  height="20"
                  layout="topleft"
                  left_delta="78"
-                 max_length="63"
+                 max_length_bytes="63"
                  name="LabelItemName"
                  top_delta="0"
                  width="210" />
@@ -141,7 +141,7 @@
                  height="23"
                  layout="topleft"
                  left_delta="78"
-                 max_length="127"
+                 max_length_bytes="127"
                  name="LabelItemDesc"
                  top_delta="-5"
                  width="210" />
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index a2f7edb1675f5a91d911ccbd8dfae64ec44b5119..ca63d2df3962f8fe89ac06b57d2d497c7ea92cc5 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -118,7 +118,7 @@
 		     height="20"
 		     layout="topleft"
 	    	 left_delta="78"
-		     max_length="63"
+		     max_length_bytes="63"
              name="Object Name"
 	    	 top_delta="0"
 		     width="225" />
@@ -143,7 +143,7 @@
              name="Object Description"
              select_on_focus="true"
     		 left_delta="78"
-		     max_length="127"
+		     max_length_bytes="127"
 	    	 top_delta="-5"
 	    	 width="225"/>
 	    <text