diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp
index e0117eca06db45b469d77c47416979316b418e65..54fc167adfabd3015e5579b432b27de626b5880e 100644
--- a/indra/integration_tests/llui_libtest/llui_libtest.cpp
+++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp
@@ -41,6 +41,7 @@
 #include "lldir.h"
 #include "llerrorcontrol.h"
 #include "llfloater.h"
+#include "llfontfreetype.h"
 #include "llfontgl.h"
 #include "lltrans.h"
 #include "llui.h"
diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.cpp b/indra/integration_tests/llui_libtest/llwidgetreg.cpp
index 4e59971f29d5f9b601ed8a62597262f9ea09634b..5a97f2aefd1a7bd7570a60a904f3696d3c3f48f3 100644
--- a/indra/integration_tests/llui_libtest/llwidgetreg.cpp
+++ b/indra/integration_tests/llui_libtest/llwidgetreg.cpp
@@ -42,6 +42,7 @@
 #include "llmultisliderctrl.h"
 #include "llprogressbar.h"
 #include "llradiogroup.h"
+#include "llsearcheditor.h"
 #include "llscrollcontainer.h"
 #include "llscrollingpanellist.h"
 #include "llscrolllistctrl.h"
@@ -53,7 +54,7 @@
 #include "lltextbox.h"
 #include "lltexteditor.h"
 #include "llflyoutbutton.h"
-#include "llsearcheditor.h"
+#include "llfiltereditor.h"
 #include "lllayoutstack.h"
 
 void LLWidgetReg::initClass(bool register_widgets)
@@ -65,11 +66,11 @@ void LLWidgetReg::initClass(bool register_widgets)
 		LLDefaultChildRegistry::Register<LLButton> button("button");
 		LLDefaultChildRegistry::Register<LLCheckBoxCtrl> check_box("check_box");
 		LLDefaultChildRegistry::Register<LLComboBox> combo_box("combo_box");
+		LLDefaultChildRegistry::Register<LLFilterEditor> filter_editor("filter_editor");
 		LLDefaultChildRegistry::Register<LLFlyoutButton> flyout_button("flyout_button");
 		LLDefaultChildRegistry::Register<LLContainerView> container_view("container_view");
 		LLDefaultChildRegistry::Register<LLIconCtrl> icon("icon");
 		LLDefaultChildRegistry::Register<LLLineEditor> line_editor("line_editor");
-		LLDefaultChildRegistry::Register<LLSearchEditor> search_editor("search_editor");
 		LLDefaultChildRegistry::Register<LLMenuItemSeparatorGL> menu_item_separator("menu_item_separator");
 		LLDefaultChildRegistry::Register<LLMenuItemCallGL> menu_item_call_gl("menu_item_call");
 		LLDefaultChildRegistry::Register<LLMenuItemCheckGL> menu_item_check_gl("menu_item_check");
@@ -83,6 +84,7 @@ void LLWidgetReg::initClass(bool register_widgets)
 		LLDefaultChildRegistry::Register<LLProgressBar> progress_bar("progress_bar");
 		LLDefaultChildRegistry::Register<LLRadioGroup> radio_group("radio_group");
 		LLDefaultChildRegistry::Register<LLRadioCtrl> radio_item("radio_item");
+		LLDefaultChildRegistry::Register<LLSearchEditor> search_editor("search_editor");
 		LLDefaultChildRegistry::Register<LLScrollContainer> scroll_container("scroll_container");
 		LLDefaultChildRegistry::Register<LLScrollingPanelList> scrolling_panel_list("scrolling_panel_list");
 		LLDefaultChildRegistry::Register<LLScrollListCtrl> scroll_list("scroll_list");
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 0e0fc6ce6c3714e5966af19146cc616f09189925..aac650bec966cad18a658d09a4d3297c9ef55f35 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -26,7 +26,7 @@ include_directories(
 
 set(llrender_SOURCE_FILES
     llcubemap.cpp
-    llfont.cpp
+    llfontfreetype.cpp
     llfontgl.cpp
     llfontbitmapcache.cpp
     llfontregistry.cpp
@@ -45,7 +45,7 @@ set(llrender_HEADER_FILES
 
     llcubemap.h
     llfontgl.h
-    llfont.h
+    llfontfreetype.h
     llfontbitmapcache.h
     llfontregistry.h
     llgl.h
diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h
index 4beea0d0267de0de10520e33f477de4f151c96c1..4a57052b916c063d12cf66b4cc215688d62dc08f 100644
--- a/indra/llrender/llfontbitmapcache.h
+++ b/indra/llrender/llfontbitmapcache.h
@@ -36,7 +36,7 @@
 #include <vector>
 
 // Maintain a collection of bitmaps containing rendered glyphs.
-// Generalizes the single-bitmap logic from LLFont and LLFontGL.
+// Generalizes the single-bitmap logic from LLFontFreetype and LLFontGL.
 class LLFontBitmapCache: public LLRefCount
 {
 public:
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..91a95cdd25a3ff480ab34af18093e0570662baa4
--- /dev/null
+++ b/indra/llrender/llfontfreetype.cpp
@@ -0,0 +1,630 @@
+/** 
+ * @file llfontfreetype.cpp
+ * @brief Freetype font library wrapper
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ * 
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llfontfreetype.h"
+
+// Freetype stuff
+#include <ft2build.h>
+
+// For some reason, this won't work if it's not wrapped in the ifdef
+#ifdef FT_FREETYPE_H
+#include FT_FREETYPE_H
+#endif
+
+#include "llerror.h"
+#include "llimage.h"
+//#include "llimagej2c.h"
+#include "llmath.h"	// Linden math
+#include "llstring.h"
+//#include "imdebug.h"
+#include "llfontbitmapcache.h"
+#include "llgl.h"
+
+FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL;
+
+LLFontManager *gFontManagerp = NULL;
+
+FT_Library gFTLibrary = NULL;
+
+//static
+void LLFontManager::initClass()
+{
+	gFontManagerp = new LLFontManager;
+}
+
+//static
+void LLFontManager::cleanupClass()
+{
+	delete gFontManagerp;
+	gFontManagerp = NULL;
+}
+
+LLFontManager::LLFontManager()
+{
+	int error;
+	error = FT_Init_FreeType(&gFTLibrary);
+	if (error)
+	{
+		// Clean up freetype libs.
+		llerrs << "Freetype initialization failure!" << llendl;
+		FT_Done_FreeType(gFTLibrary);
+	}
+}
+
+LLFontManager::~LLFontManager()
+{
+	FT_Done_FreeType(gFTLibrary);
+}
+
+
+LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
+:	mGlyphIndex(index),
+	mXBitmapOffset(0), 	// Offset to the origin in the bitmap
+	mYBitmapOffset(0), 	// Offset to the origin in the bitmap
+	mXBearing(0),		// Distance from baseline to left in pixels
+	mYBearing(0),		// Distance from baseline to top in pixels
+	mWidth(0),			// In pixels
+	mHeight(0),			// In pixels
+	mXAdvance(0.f),		// In pixels
+	mYAdvance(0.f),		// In pixels
+	mIsRendered(FALSE),
+	mMetricsValid(FALSE)
+{
+}
+
+LLFontFreetype::LLFontFreetype()
+:	mFontBitmapCachep(new LLFontBitmapCache),
+	mValid(FALSE),
+	mAscender(0.f),
+	mDescender(0.f),
+	mLineHeight(0.f),
+	mIsFallback(FALSE),
+	mFTFace(NULL),
+	mRenderGlyphCount(0),
+	mAddGlyphCount(0),
+	mPointSize(0)
+{
+}
+
+
+LLFontFreetype::~LLFontFreetype()
+{
+	// Clean up freetype libs.
+	if (mFTFace)
+		FT_Done_Face(mFTFace);
+	mFTFace = NULL;
+
+	// Delete glyph info
+	std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
+
+	// mFontBitmapCachep will be cleaned up by LLPointer destructor.
+	// mFallbackFonts cleaned up by LLPointer destructor
+}
+
+BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
+{
+	// Don't leak face objects.  This is also needed to deal with
+	// changed font file names.
+	if (mFTFace)
+	{
+		FT_Done_Face(mFTFace);
+		mFTFace = NULL;
+	}
+
+	int error;
+
+	error = FT_New_Face( gFTLibrary,
+						 filename.c_str(),
+						 0,
+						 &mFTFace );
+
+    if (error)
+	{
+		return FALSE;
+	}
+
+	mIsFallback = is_fallback;
+	F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi
+
+	error = FT_Set_Char_Size(mFTFace,    /* handle to face object           */
+							0,       /* char_width in 1/64th of points  */
+							(S32)(point_size*64),   /* char_height in 1/64th of points */
+							(U32)horz_dpi,     /* horizontal device resolution    */
+							(U32)vert_dpi);   /* vertical device resolution      */
+
+	if (error)
+	{
+		// Clean up freetype libs.
+		FT_Done_Face(mFTFace);
+		mFTFace = NULL;
+		return FALSE;
+	}
+
+	F32 y_max, y_min, x_max, x_min;
+	F32 ems_per_unit = 1.f/ mFTFace->units_per_EM;
+	F32 pixels_per_unit = pixels_per_em * ems_per_unit;
+
+	// Get size of bbox in pixels
+	y_max = mFTFace->bbox.yMax * pixels_per_unit;
+	y_min = mFTFace->bbox.yMin * pixels_per_unit;
+	x_max = mFTFace->bbox.xMax * pixels_per_unit;
+	x_min = mFTFace->bbox.xMin * pixels_per_unit;
+	mAscender = mFTFace->ascender * pixels_per_unit;
+	mDescender = -mFTFace->descender * pixels_per_unit;
+	mLineHeight = mFTFace->height * pixels_per_unit;
+
+	S32 max_char_width = llround(0.5f + (x_max - x_min));
+	S32 max_char_height = llround(0.5f + (y_max - y_min));
+
+	mFontBitmapCachep->init(components, max_char_width, max_char_height);
+
+	if (!mFTFace->charmap)
+	{
+		//llinfos << " no unicode encoding, set whatever encoding there is..." << llendl;
+		FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]);
+	}
+
+	if (!mIsFallback)
+	{
+		// Add the default glyph
+		addGlyph(0, 0);
+	}
+
+	mName = filename;
+	mPointSize = point_size;
+
+	return TRUE;
+}
+
+void LLFontFreetype::setFallbackFonts(const font_vector_t &font)
+{
+	mFallbackFonts = font;
+}
+
+const LLFontFreetype::font_vector_t &LLFontFreetype::getFallbackFonts() const
+{
+	return mFallbackFonts;
+}
+
+F32 LLFontFreetype::getLineHeight() const
+{
+	return mLineHeight;
+}
+
+F32 LLFontFreetype::getAscenderHeight() const
+{
+	return mAscender;
+}
+
+F32 LLFontFreetype::getDescenderHeight() const
+{
+	return mDescender;
+}
+
+F32 LLFontFreetype::getXAdvance(llwchar wch) const
+{
+	if (mFTFace == NULL)
+		return 0.0;
+
+	llassert(!mIsFallback);
+	U32 glyph_index;
+
+	// Return existing info only if it is current
+	LLFontGlyphInfo* gi = getGlyphInfo(wch);
+	if (gi && gi->mMetricsValid)
+	{
+		return gi->mXAdvance;
+	}
+
+	const LLFontFreetype* fontp = this;
+	
+	// Initialize char to glyph map
+	glyph_index = FT_Get_Char_Index(mFTFace, wch);
+	if (glyph_index == 0)
+	{
+		font_vector_t::const_iterator iter;
+		for(iter = mFallbackFonts.begin(); (iter != mFallbackFonts.end()) && (glyph_index == 0); iter++)
+		{
+			glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
+			if(glyph_index)
+			{
+				fontp = *iter;
+			}
+		}
+	}
+	
+	if (glyph_index)
+	{
+		// This font has this glyph
+		fontp->renderGlyph(glyph_index);
+
+		// Create the entry if it's not there
+		char_glyph_info_map_t::iterator iter2 = mCharGlyphInfoMap.find(wch);
+		if (iter2 == mCharGlyphInfoMap.end())
+		{
+			gi = new LLFontGlyphInfo(glyph_index);
+			insertGlyphInfo(wch, gi);
+		}
+		else
+		{
+			gi = iter2->second;
+		}
+		
+		gi->mWidth = fontp->mFTFace->glyph->bitmap.width;
+		gi->mHeight = fontp->mFTFace->glyph->bitmap.rows;
+
+		// Convert these from 26.6 units to float pixels.
+		gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
+		gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
+		gi->mMetricsValid = TRUE;
+		return gi->mXAdvance;
+	}
+	else
+	{
+		gi = get_if_there(mCharGlyphInfoMap, (llwchar)0, (LLFontGlyphInfo*)NULL);
+		if (gi)
+		{
+			return gi->mXAdvance;
+		}
+	}
+
+	// Last ditch fallback - no glyphs defined at all.
+	return (F32)mFontBitmapCachep->getMaxCharWidth();
+}
+
+F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
+{
+	if (mFTFace == NULL)
+		return 0.0;
+
+	llassert(!mIsFallback);
+	LLFontGlyphInfo* left_glyph_info = get_if_there(mCharGlyphInfoMap, char_left, (LLFontGlyphInfo*)NULL);
+	U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
+	// Kern this puppy.
+	LLFontGlyphInfo* right_glyph_info = get_if_there(mCharGlyphInfoMap, char_right, (LLFontGlyphInfo*)NULL);
+	U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
+
+	FT_Vector  delta;
+
+	llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
+
+	return delta.x*(1.f/64.f);
+}
+
+BOOL LLFontFreetype::hasGlyph(llwchar wch) const
+{
+	llassert(!mIsFallback);
+	const LLFontGlyphInfo* gi = getGlyphInfo(wch);
+	if (gi && gi->mIsRendered)
+	{
+		return TRUE;
+	}
+	else
+	{
+		return FALSE;
+	}
+}
+
+BOOL LLFontFreetype::addChar(llwchar wch) const
+{
+	if (mFTFace == NULL)
+		return FALSE;
+
+	llassert(!mIsFallback);
+	//lldebugs << "Adding new glyph for " << wch << " to font" << llendl;
+
+	FT_UInt glyph_index;
+
+	// Initialize char to glyph map
+	glyph_index = FT_Get_Char_Index(mFTFace, wch);
+	if (glyph_index == 0)
+	{
+		//llinfos << "Trying to add glyph from fallback font!" << llendl
+		font_vector_t::const_iterator iter;
+		for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++)
+		{
+			glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
+			if (glyph_index)
+			{
+				addGlyphFromFont(*iter, wch, glyph_index);
+				return TRUE;
+			}
+		}
+	}
+	
+	char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
+	if (iter == mCharGlyphInfoMap.end() || !(iter->second->mIsRendered))
+	{
+		BOOL result = addGlyph(wch, glyph_index);
+		return result;
+	}
+	return FALSE;
+}
+
+BOOL LLFontFreetype::addGlyph(llwchar wch, U32 glyph_index) const
+{
+	return addGlyphFromFont(this, wch, glyph_index);
+}
+
+BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const
+{
+	if (mFTFace == NULL)
+		return FALSE;
+
+	llassert(!mIsFallback);
+	fontp->renderGlyph(glyph_index);
+	S32 width = fontp->mFTFace->glyph->bitmap.width;
+	S32 height = fontp->mFTFace->glyph->bitmap.rows;
+
+	S32 pos_x, pos_y;
+	S32 bitmap_num;
+	mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_num);
+	mAddGlyphCount++;
+
+	LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index);
+	gi->mXBitmapOffset = pos_x;
+	gi->mYBitmapOffset = pos_y;
+	gi->mBitmapNum = bitmap_num;
+	gi->mWidth = width;
+	gi->mHeight = height;
+	gi->mXBearing = fontp->mFTFace->glyph->bitmap_left;
+	gi->mYBearing = fontp->mFTFace->glyph->bitmap_top;
+	// Convert these from 26.6 units to float pixels.
+	gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
+	gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
+	gi->mIsRendered = TRUE;
+	gi->mMetricsValid = TRUE;
+
+	insertGlyphInfo(wch, gi);
+
+	llassert(fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO
+	    || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
+
+	if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO
+	    || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
+	{
+		U8 *buffer_data = fontp->mFTFace->glyph->bitmap.buffer;
+		S32 buffer_row_stride = fontp->mFTFace->glyph->bitmap.pitch;
+		U8 *tmp_graydata = NULL;
+
+		if (fontp->mFTFace->glyph->bitmap.pixel_mode
+		    == FT_PIXEL_MODE_MONO)
+		{
+			// need to expand 1-bit bitmap to 8-bit graymap.
+			tmp_graydata = new U8[width * height];
+			S32 xpos, ypos;
+			for (ypos = 0; ypos < height; ++ypos)
+			{
+				S32 bm_row_offset = buffer_row_stride * ypos;
+				for (xpos = 0; xpos < width; ++xpos)
+				{
+					U32 bm_col_offsetbyte = xpos / 8;
+					U32 bm_col_offsetbit = 7 - (xpos % 8);
+					U32 bit =
+					!!(buffer_data[bm_row_offset
+						       + bm_col_offsetbyte
+					   ] & (1 << bm_col_offsetbit) );
+					tmp_graydata[width*ypos + xpos] =
+						255 * bit;
+				}
+			}
+			// use newly-built graymap.
+			buffer_data = tmp_graydata;
+			buffer_row_stride = width;
+		}
+
+		switch (mFontBitmapCachep->getNumComponents())
+		{
+		case 1:
+			mFontBitmapCachep->getImageRaw(bitmap_num)->setSubImage(pos_x,
+																	pos_y,
+																	width,
+																	height,
+																	buffer_data,
+																	buffer_row_stride,
+																	TRUE);
+			break;
+		case 2:
+			setSubImageLuminanceAlpha(pos_x,	
+									  pos_y,
+									  bitmap_num,
+									  width,
+									  height,
+									  buffer_data,
+									  buffer_row_stride);
+			break;
+		default:
+			break;
+		}
+
+		if (tmp_graydata)
+			delete[] tmp_graydata;
+	} else {
+		// we don't know how to handle this pixel format from FreeType;
+		// omit it from the font-image.
+	}
+	
+	return TRUE;
+}
+
+LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch) const
+{
+	char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
+	if (iter != mCharGlyphInfoMap.end())
+	{
+		return iter->second;
+	}
+	return NULL;
+}
+
+void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
+{
+	char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
+	if (iter != mCharGlyphInfoMap.end())
+	{
+		delete iter->second;
+		iter->second = gi;
+	}
+	else
+	{
+		mCharGlyphInfoMap[wch] = gi;
+	}
+}
+
+void LLFontFreetype::renderGlyph(U32 glyph_index) const
+{
+	if (mFTFace == NULL)
+		return;
+
+	int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT );
+	llassert(!error);
+
+	error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode);
+
+	mRenderGlyphCount++;
+	
+	llassert(!error);
+}
+
+void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
+{
+	if (!mIsFallback)
+	{
+		// This is the head of the list - need to rebuild ourself and all fallbacks.
+		loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mFontBitmapCachep->getNumComponents(), mIsFallback);
+
+		if (mFallbackFonts.empty())
+		{
+			llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl;
+		}
+		else
+		{
+			for(font_vector_t::iterator it = mFallbackFonts.begin();
+				it != mFallbackFonts.end();
+				++it)
+			{
+				(*it)->reset(vert_dpi, horz_dpi);
+			}
+		}
+	}
+	resetBitmapCache(); 
+}
+
+void LLFontFreetype::resetBitmapCache()
+{
+	// Iterate through glyphs and clear the mIsRendered flag
+	for (char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.begin();
+		 iter != mCharGlyphInfoMap.end(); ++iter)
+	{
+		iter->second->mIsRendered = FALSE;
+		//FIXME: this is only strictly necessary when resetting the entire font, 
+		//not just flushing the bitmap
+		iter->second->mMetricsValid = FALSE;
+	}
+	mFontBitmapCachep->reset();
+
+	// Add the empty glyph`5
+	addGlyph(0, 0);
+}
+
+void LLFontFreetype::destroyGL()
+{
+	mFontBitmapCachep->destroyGL();
+}
+
+BOOL LLFontFreetype::getIsFallback() const
+{
+	return mIsFallback;
+}
+
+const std::string &LLFontFreetype::getName() const
+{
+	return mName;
+}
+
+F32 LLFontFreetype::getPointSize() const
+{
+	return mPointSize;
+}
+
+const LLPointer<LLFontBitmapCache> LLFontFreetype::getFontBitmapCache() const
+{
+	return mFontBitmapCachep;
+}
+
+void LLFontFreetype::setStyle(U8 style)
+{
+	mStyle = style;
+}
+
+U8 LLFontFreetype::getStyle() const
+{
+	return mStyle;
+}
+
+void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride) const
+{
+	LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);
+
+	llassert(!mIsFallback);
+	llassert(image_raw && (image_raw->getComponents() == 2));
+
+	
+	U8 *target = image_raw->getData();
+
+	if (!data)
+	{
+		return;
+	}
+
+	if (0 == stride)
+		stride = width;
+
+	U32 i, j;
+	U32 to_offset;
+	U32 from_offset;
+	U32 target_width = image_raw->getWidth();
+	for (i = 0; i < height; i++)
+	{
+		to_offset = (y + i)*target_width + x;
+		from_offset = (height - 1 - i)*stride;
+		for (j = 0; j < width; j++)
+		{
+			*(target + to_offset*2 + 1) = *(data + from_offset);
+			to_offset++;
+			from_offset++;
+		}
+	}
+}
+
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
new file mode 100644
index 0000000000000000000000000000000000000000..0520ef2cd642737be99410539e6920dbf67bf339
--- /dev/null
+++ b/indra/llrender/llfontfreetype.h
@@ -0,0 +1,380 @@
+/** 
+ * @file llfontfreetype.h
+ * @brief Font library wrapper
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ * 
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFONTFREETYPE_H
+#define LL_LLFONTFREETYPE_H
+
+#include <map>
+#include "llpointer.h"
+#include "llstl.h"
+
+#include "llimagegl.h"
+#include "llfontbitmapcache.h"
+
+// Hack.  FT_Face is just a typedef for a pointer to a struct,
+// but there's no simple forward declarations file for FreeType, 
+// and the main include file is 200K.  
+// We'll forward declare the struct here.  JC
+struct FT_FaceRec_;
+typedef struct FT_FaceRec_* LLFT_Face;
+
+class LLFontManager
+{
+public:
+	static void initClass();
+	static void cleanupClass();
+
+private:
+	LLFontManager();
+	~LLFontManager();
+};
+
+class LLFontGlyphInfo
+{
+public:
+	LLFontGlyphInfo(U32 index);
+
+	U32 mGlyphIndex;
+
+	// Metrics
+	S32 mWidth;			// In pixels
+	S32 mHeight;		// In pixels
+	F32 mXAdvance;		// In pixels
+	F32 mYAdvance;		// In pixels
+	BOOL mMetricsValid; // We have up-to-date metrics for this glyph
+
+	// Information for actually rendering
+	BOOL mIsRendered;	// We actually have rendered this glyph
+	S32 mXBitmapOffset; // Offset to the origin in the bitmap
+	S32 mYBitmapOffset; // Offset to the origin in the bitmap
+	S32 mXBearing;	// Distance from baseline to left in pixels
+	S32 mYBearing;	// Distance from baseline to top in pixels
+	S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph
+};
+
+extern LLFontManager *gFontManagerp;
+
+class LLFontFreetype : public LLRefCount
+{
+public:
+	LLFontFreetype();
+	~LLFontFreetype();
+
+	// is_fallback should be true for fallback fonts that aren't used
+	// to render directly (Unicode backup, primarily)
+	BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback);
+
+	typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t;
+
+	void setFallbackFonts(const font_vector_t &font);
+	const font_vector_t &getFallbackFonts() const;
+
+	// Global font metrics - in units of pixels
+	F32 getLineHeight() const;
+	F32 getAscenderHeight() const;
+	F32 getDescenderHeight() const;
+
+
+// For a lowercase "g":
+//
+//	------------------------------
+//	                     ^     ^
+//						 |     |
+//				xxx x    |Ascender
+//	           x   x     v     |
+//	---------   xxxx-------------- Baseline
+//	^		       x	       |
+//  | Descender    x           |
+//	v			xxxx           |LineHeight
+//  -----------------------    |
+//                             v
+//	------------------------------
+
+	enum
+	{
+		FIRST_CHAR = 32, 
+		NUM_CHARS = 127 - 32, 
+		LAST_CHAR_BASIC = 127,
+
+		// Need full 8-bit ascii range for spanish
+		NUM_CHARS_FULL = 255 - 32,
+		LAST_CHAR_FULL = 255
+	};
+
+	F32 getXAdvance(llwchar wc) const;
+	F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters
+
+	BOOL hasGlyph(llwchar wch) const;		// Has a glyph for this character
+	BOOL addChar(llwchar wch) const;		// Add a new character to the font if necessary
+	BOOL addGlyph(llwchar wch, U32 glyph_index) const;	// Add a new glyph to the existing font
+	BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const;	// Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
+
+	LLFontGlyphInfo* getGlyphInfo(llwchar wch) const;
+
+	void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;
+	void renderGlyph(U32 glyph_index) const;
+
+	void reset(F32 vert_dpi, F32 horz_dpi);
+	void resetBitmapCache();
+
+	void destroyGL();
+
+	BOOL getIsFallback() const;
+
+	const std::string& getName() const;
+
+	F32 getPointSize() const;
+
+	const LLPointer<LLFontBitmapCache> getFontBitmapCache() const;
+
+	void setStyle(U8 style);
+	U8 getStyle() const;
+
+private:
+	void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const;
+
+	std::string mName;
+
+	U8 mStyle;
+
+	F32 mPointSize;
+	F32 mAscender;			
+	F32 mDescender;
+	F32 mLineHeight;
+
+	LLFT_Face mFTFace;
+
+	BOOL mIsFallback;
+	font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
+
+	BOOL mValid;
+
+	typedef std::map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
+	mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
+
+	mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep;
+
+	mutable S32 mRenderGlyphCount;
+	mutable S32 mAddGlyphCount;
+};
+
+#endif // LL_FONTFREETYPE_H
+/** 
+ * @file llfontfreetype.h
+ * @brief Font library wrapper
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ * 
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFONTFREETYPE_H
+#define LL_LLFONTFREETYPE_H
+
+#include <map>
+#include "llpointer.h"
+#include "llstl.h"
+
+#include "llimagegl.h"
+#include "llfontbitmapcache.h"
+
+// Hack.  FT_Face is just a typedef for a pointer to a struct,
+// but there's no simple forward declarations file for FreeType, 
+// and the main include file is 200K.  
+// We'll forward declare the struct here.  JC
+struct FT_FaceRec_;
+typedef struct FT_FaceRec_* LLFT_Face;
+
+class LLFontManager
+{
+public:
+	static void initClass();
+	static void cleanupClass();
+
+private:
+	LLFontManager();
+	~LLFontManager();
+};
+
+class LLFontGlyphInfo
+{
+public:
+	LLFontGlyphInfo(U32 index);
+
+	U32 mGlyphIndex;
+
+	// Metrics
+	S32 mWidth;			// In pixels
+	S32 mHeight;		// In pixels
+	F32 mXAdvance;		// In pixels
+	F32 mYAdvance;		// In pixels
+	BOOL mMetricsValid; // We have up-to-date metrics for this glyph
+
+	// Information for actually rendering
+	BOOL mIsRendered;	// We actually have rendered this glyph
+	S32 mXBitmapOffset; // Offset to the origin in the bitmap
+	S32 mYBitmapOffset; // Offset to the origin in the bitmap
+	S32 mXBearing;	// Distance from baseline to left in pixels
+	S32 mYBearing;	// Distance from baseline to top in pixels
+	S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph
+};
+
+extern LLFontManager *gFontManagerp;
+
+class LLFontFreetype : public LLRefCount
+{
+public:
+	LLFontFreetype();
+	~LLFontFreetype();
+
+	// is_fallback should be true for fallback fonts that aren't used
+	// to render directly (Unicode backup, primarily)
+	BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback);
+
+	typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t;
+
+	void setFallbackFonts(const font_vector_t &font);
+	const font_vector_t &getFallbackFonts() const;
+
+	// Global font metrics - in units of pixels
+	F32 getLineHeight() const;
+	F32 getAscenderHeight() const;
+	F32 getDescenderHeight() const;
+
+
+// For a lowercase "g":
+//
+//	------------------------------
+//	                     ^     ^
+//						 |     |
+//				xxx x    |Ascender
+//	           x   x     v     |
+//	---------   xxxx-------------- Baseline
+//	^		       x	       |
+//  | Descender    x           |
+//	v			xxxx           |LineHeight
+//  -----------------------    |
+//                             v
+//	------------------------------
+
+	enum
+	{
+		FIRST_CHAR = 32, 
+		NUM_CHARS = 127 - 32, 
+		LAST_CHAR_BASIC = 127,
+
+		// Need full 8-bit ascii range for spanish
+		NUM_CHARS_FULL = 255 - 32,
+		LAST_CHAR_FULL = 255
+	};
+
+	F32 getXAdvance(llwchar wc) const;
+	F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters
+
+	BOOL hasGlyph(llwchar wch) const;		// Has a glyph for this character
+	BOOL addChar(llwchar wch) const;		// Add a new character to the font if necessary
+	BOOL addGlyph(llwchar wch, U32 glyph_index) const;	// Add a new glyph to the existing font
+	BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const;	// Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
+
+	LLFontGlyphInfo* getGlyphInfo(llwchar wch) const;
+
+	void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;
+	void renderGlyph(U32 glyph_index) const;
+
+	void reset(F32 vert_dpi, F32 horz_dpi);
+	void resetBitmapCache();
+
+	void destroyGL();
+
+	BOOL getIsFallback() const;
+
+	const std::string& getName() const;
+
+	F32 getPointSize() const;
+
+	const LLPointer<LLFontBitmapCache> getFontBitmapCache() const;
+
+	void setStyle(U8 style);
+	U8 getStyle() const;
+
+private:
+	void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const;
+
+	std::string mName;
+
+	U8 mStyle;
+
+	F32 mPointSize;
+	F32 mAscender;			
+	F32 mDescender;
+	F32 mLineHeight;
+
+	LLFT_Face mFTFace;
+
+	BOOL mIsFallback;
+	font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
+
+	BOOL mValid;
+
+	typedef std::map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
+	mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
+
+	mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep;
+
+	mutable S32 mRenderGlyphCount;
+	mutable S32 mAddGlyphCount;
+};
+
+#endif // LL_FONTFREETYPE_H
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 0b57d86c78a8100da990391f2fdb72fe0fdf2942..32a008047c0d53b48b67a510ad936ecb7984ad90 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -35,7 +35,7 @@
 #include "llfontgl.h"
 
 // Linden library includes
-#include "llfont.h"
+#include "llfontfreetype.h"
 #include "llfontbitmapcache.h"
 #include "llfontregistry.h"
 #include "llgl.h"
@@ -73,54 +73,25 @@ const F32 PIXEL_CORRECTION_DISTANCE = 0.01f;
 const F32 PAD_UVY = 0.5f; // half of vertical padding between glyphs in the glyph texture
 const F32 DROP_SHADOW_SOFT_STRENGTH = 0.3f;
 
-F32 llfont_round_x(F32 x)
+static F32 llfont_round_x(F32 x)
 {
 	//return llfloor((x-LLFontGL::sCurOrigin.mX)/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleX+LLFontGL::sCurOrigin.mX;
 	//return llfloor(x/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleY;
 	return x;
 }
 
-F32 llfont_round_y(F32 y)
+static F32 llfont_round_y(F32 y)
 {
 	//return llfloor((y-LLFontGL::sCurOrigin.mY)/LLFontGL::sScaleY+0.5f)*LLFontGL::sScaleY+LLFontGL::sCurOrigin.mY;
 	//return llfloor(y+0.5f);
 	return y;
 }
 
-// static
-U8 LLFontGL::getStyleFromString(const std::string &style)
-{
-	S32 ret = 0;
-	if (style.find("NORMAL") != style.npos)
-	{
-		ret |= NORMAL;
-	}
-	if (style.find("BOLD") != style.npos)
-	{
-		ret |= BOLD;
-	}
-	if (style.find("ITALIC") != style.npos)
-	{
-		ret |= ITALIC;
-	}
-	if (style.find("UNDERLINE") != style.npos)
-	{
-		ret |= UNDERLINE;
-	}
-	return ret;
-}
-
 LLFontGL::LLFontGL()
-	: LLFont()
 {
 	clearEmbeddedChars();
 }
 
-LLFontGL::LLFontGL(const LLFontGL &source)
-{
-	llerrs << "Not implemented!" << llendl;
-}
-
 LLFontGL::~LLFontGL()
 {
 	clearEmbeddedChars();
@@ -128,293 +99,26 @@ LLFontGL::~LLFontGL()
 
 void LLFontGL::reset()
 {
-	if (!mIsFallback)
-	{
-		// This is the head of the list - need to rebuild ourself and all fallbacks.
-		loadFace(mName,mPointSize,sVertDPI,sHorizDPI,mFontBitmapCachep->getNumComponents(),mIsFallback);
-		if (mFallbackFontp==NULL)
-		{
-			llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl;
-		}
-		else
-		{
-			for (LLFontList::iterator it = mFallbackFontp->begin();
-				 it != mFallbackFontp->end();
-				 ++it)
-			{
-				(*it)->reset();
-			}
-		}
-	}
-	resetBitmapCache(); 
-}
-
-// static 
-std::string LLFontGL::getFontPathSystem()
-{
-	std::string system_path;
-
-	// Try to figure out where the system's font files are stored.
-	char *system_root = NULL;
-#if LL_WINDOWS
-	system_root = getenv("SystemRoot");	/* Flawfinder: ignore */
-	if (!system_root)
-	{
-		llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl;
-	}
-#endif
-
-	if (system_root)
-	{
-		system_path = llformat("%s/fonts/", system_root);
-	}
-	else
-	{
-#if LL_WINDOWS
-		// HACK for windows 98/Me
-		system_path = "/WINDOWS/FONTS/";
-#elif LL_DARWIN
-		// HACK for Mac OS X
-		system_path = "/System/Library/Fonts/";
-#endif
-	}
-	return system_path;
-}
-
-
-// static 
-std::string LLFontGL::getFontPathLocal()
-{
-	std::string local_path;
-
-	// Backup files if we can't load from system fonts directory.
-	// We could store this in an end-user writable directory to allow
-	// end users to switch fonts.
-	if (LLFontGL::sAppDir.length())
-	{
-		// use specified application dir to look for fonts
-		local_path = LLFontGL::sAppDir + "/fonts/";
-	}
-	else
-	{
-		// assume working directory is executable directory
-		local_path = "./fonts/";
-	}
-	return local_path;
-}
-
-bool findOrCreateFont(LLFontGL*& fontp, const LLFontDescriptor& desc)
-{
-	// Don't delete existing fonts, if any, here, because they've
-	// already been deleted by LLFontRegistry::clear()
-	fontp = LLFontGL::getFont(desc);
-	return (fontp != NULL);
-}
-
-// static
-void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale,
-								const std::string& app_dir,
-								const std::vector<std::string>& xui_paths,
-								bool create_gl_textures)
-{
-	sVertDPI = (F32)llfloor(screen_dpi * y_scale);
-	sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
-	sScaleX = x_scale;
-	sScaleY = y_scale;
-	sAppDir = app_dir;
-
-	// Font registry init
-	if (!sFontRegistry)
-	{
-		sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures);
-		sFontRegistry->parseFontInfo("fonts.xml");
-	}
-	else
-	{
-		sFontRegistry->reset();
-	}
-}
-
-// Force standard fonts to get generated up front.
-// This is primarily for error detection purposes.
-// Don't do this during initClass because it can be slow and we want to get
-// the viewer window on screen first. JC
-// static
-bool LLFontGL::loadDefaultFonts()
-{
-	bool succ = true;
-	succ &= (NULL != getFontSansSerifSmall());
-	succ &= (NULL != getFontSansSerif());
-	succ &= (NULL != getFontSansSerifBig());
-	succ &= (NULL != getFontSansSerifHuge());
-	succ &= (NULL != getFontSansSerifBold());
-	succ &= (NULL != getFontMonospace());
-	succ &= (NULL != getFontExtChar());
-	return succ;
-}
-
-
-
-// static
-void LLFontGL::destroyDefaultFonts()
-{
-	// Remove the actual fonts.
-	delete sFontRegistry;
-	sFontRegistry = NULL;
-}
-
-//static 
-void LLFontGL::destroyAllGL()
-{
-	if (sFontRegistry)
-	{
-		sFontRegistry->destroyGL();
-	}
+	mFontFreetype->reset(sVertDPI, sHorizDPI);
 }
 
 void LLFontGL::destroyGL()
 {
-	mFontBitmapCachep->destroyGL();
-}
-
-
-
-LLFontGL &LLFontGL::operator=(const LLFontGL &source)
-{
-	llerrs << "Not implemented" << llendl;
-	return *this;
-}
-
-BOOL LLFontGL::loadFace(const std::string& filename,
-						const F32 point_size, const F32 vert_dpi, const F32 horz_dpi,
-						const S32 components, BOOL is_fallback)
-{
-	if (!LLFont::loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback))
-	{
-		return FALSE;
-	}
-	return TRUE;
-}
-
-//static
-LLFontGL* LLFontGL::getFontMonospace()
-{
-	return getFont(LLFontDescriptor("Monospace","Monospace",0));
-}
-
-//static
-LLFontGL* LLFontGL::getFontSansSerifSmall()
-{
-	return getFont(LLFontDescriptor("SansSerif","Small",0));
-}
-
-//static
-LLFontGL* LLFontGL::getFontSansSerif()
-{
-	return getFont(LLFontDescriptor("SansSerif","Medium",0));
-}
-
-//static
-LLFontGL* LLFontGL::getFontSansSerifBig()
-{
-	return getFont(LLFontDescriptor("SansSerif","Large",0));
-}
-
-//static 
-LLFontGL* LLFontGL::getFontSansSerifHuge()
-{
-	return getFont(LLFontDescriptor("SansSerif","Huge",0));
-}
-
-//static 
-LLFontGL* LLFontGL::getFontSansSerifBold()
-{
-	return getFont(LLFontDescriptor("SansSerif","Medium",BOLD));
-}
-
-//static
-LLFontGL* LLFontGL::getFontExtChar()
-{
-	return getFontSansSerif();
-}
-
-//static 
-LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc)
-{
-	return sFontRegistry->getFont(desc);
-}
-
-//static
-LLFontGL* LLFontGL::getFontByName(const std::string& name)
-{
-	// check for most common fonts first
-	if (name == "SANSSERIF")
-	{
-		return getFontSansSerif();
-	}
-	else if (name == "SANSSERIF_SMALL")
-	{
-		return getFontSansSerifSmall();
-	}
-	else if (name == "SANSSERIF_BIG")
-	{
-		return getFontSansSerifBig();
-	}
-	else if (name == "SMALL" || name == "OCRA")
-	{
-		// *BUG: Should this be "MONOSPACE"?  Do we use "OCRA" anymore?
-		// Does "SMALL" mean "SERIF"?
-		return getFontMonospace();
-	}
-	else
-	{
-		return NULL;
-	}
+	mFontFreetype->destroyGL();
 }
 
-BOOL LLFontGL::addChar(const llwchar wch) const
+BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
 {
-	if (!LLFont::addChar(wch))
+	if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
 	{
-		return FALSE;
+		mFontFreetype = new LLFontFreetype;
 	}
 
-	stop_glerror();
-
-	LLFontGlyphInfo *glyph_info = getGlyphInfo(wch);
-	U32 bitmap_num = glyph_info->mBitmapNum;
-	LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_num);
-	LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);
-	image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight());
-	return TRUE;
-}
-
-
-S32 LLFontGL::renderUTF8(const std::string &text, const S32 offset, 
-					 const F32 x, const F32 y,
-					 const LLColor4 &color,
-					 const HAlign halign, const VAlign valign,
-					 U8 style,
-					 ShadowType shadow,
-					 const S32 max_chars, const S32 max_pixels,
-					 F32* right_x,
-					 BOOL use_ellipses) const
-{
-	LLWString wstr = utf8str_to_wstring(text);
-	return render(wstr, offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses);
+	return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback);
 }
 
-S32 LLFontGL::render(const LLWString &wstr, 
-					 const S32 begin_offset,
-					 const F32 x, const F32 y,
-					 const LLColor4 &color,
-					 const HAlign halign, const VAlign valign,
-					 U8 style,
-					 ShadowType shadow,
-					 const S32 max_chars, S32 max_pixels,
-					 F32* right_x,
-					 BOOL use_embedded,
-					 BOOL use_ellipses) const
+S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, 
+					 ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_embedded, BOOL use_ellipses) const
 {
 	if(!sDisplayFont) //do not display texts
 	{
@@ -430,8 +134,9 @@ S32 LLFontGL::render(const LLWString &wstr,
 
 	S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX);
 
-	// Strip off any style bits that are already accounted for by the font.
-	style = style & (~getFontDesc().getStyle());
+	// determine which style flags need to be added programmatically by striping off the
+	// style bits that are drawn by the underlying Freetype font
+	U8 style_to_add = (style | mFontDescriptor.getStyle()) & ~mFontFreetype->getStyle();
 
 	F32 drop_shadow_strength = 0.f;
 	if (shadow != NO_SHADOW)
@@ -483,13 +188,13 @@ S32 LLFontGL::render(const LLWString &wstr,
 	switch (valign)
 	{
 	case TOP:
-		cur_y -= mAscender;
+		cur_y -= mFontFreetype->getAscenderHeight();
 		break;
 	case BOTTOM:
-		cur_y += mDescender;
+		cur_y += mFontFreetype->getDescenderHeight();
 		break;
 	case VCENTER:
-		cur_y -= ((mAscender - mDescender)/2.f);
+		cur_y -= ((mFontFreetype->getAscenderHeight() - mFontFreetype->getDescenderHeight())/2.f);
 		break;
 	case BASELINE:
 		// Baseline, do nothing.
@@ -517,10 +222,12 @@ S32 LLFontGL::render(const LLWString &wstr,
 
 	F32 start_x = cur_x;
 
-	F32 inv_width = 1.f / mFontBitmapCachep->getBitmapWidth();
-	F32 inv_height = 1.f / mFontBitmapCachep->getBitmapHeight();
+	const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
 
-	const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL;
+	F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
+	F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
+
+	const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
 
 
 	BOOL draw_ellipses = FALSE;
@@ -576,11 +283,11 @@ S32 LLFontGL::render(const LLWString &wstr,
 
 			// snap origin to whole screen pixel
 			const F32 ext_x = (F32)llround(cur_render_x + (EXT_X_BEARING * sScaleX));
-			const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mAscender - mLineHeight));
+			const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mFontFreetype->getAscenderHeight() - mFontFreetype->getLineHeight()));
 
 			LLRectf uv_rect(0.f, 1.f, 1.f, 0.f);
 			LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y);
-			drawGlyph(screen_rect, uv_rect, LLColor4::white, style, shadow, drop_shadow_strength);
+			drawGlyph(screen_rect, uv_rect, LLColor4::white, style_to_add, shadow, drop_shadow_strength);
 
 			if (!label.empty())
 			{
@@ -609,19 +316,19 @@ S32 LLFontGL::render(const LLWString &wstr,
 		}
 		else
 		{
-			if (!hasGlyph(wch))
+			if (!mFontFreetype->hasGlyph(wch))
 			{
 				addChar(wch);
 			}
 
-			const LLFontGlyphInfo* fgi= getGlyphInfo(wch);
+			const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
 			if (!fgi)
 			{
 				llerrs << "Missing Glyph Info" << llendl;
 				break;
 			}
 			// Per-glyph bitmap texture.
-			LLImageGL *image_gl = mFontBitmapCachep->getImageGL(fgi->mBitmapNum);
+			LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum);
 			if (last_bound_texture != image_gl)
 			{
 				gGL.getTexUnit(0)->bind(image_gl);
@@ -646,7 +353,7 @@ S32 LLFontGL::render(const LLWString &wstr,
 					    llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
 					    llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
 			
-			drawGlyph(screen_rect, uv_rect, color, style, shadow, drop_shadow_strength);
+			drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength);
 
 			chars_drawn++;
 			cur_x += fgi->mXAdvance;
@@ -656,11 +363,11 @@ S32 LLFontGL::render(const LLWString &wstr,
 			if (next_char && (next_char < LAST_CHARACTER))
 			{
 				// Kern this puppy.
-				if (!hasGlyph(next_char))
+				if (!mFontFreetype->hasGlyph(next_char))
 				{
 					addChar(next_char);
 				}
-				cur_x += getXKerning(wch, next_char);
+				cur_x += mFontFreetype->getXKerning(wch, next_char);
 			}
 
 			// Round after kerning.
@@ -680,12 +387,14 @@ S32 LLFontGL::render(const LLWString &wstr,
 		*right_x = cur_x / sScaleX;
 	}
 
-	if (style & UNDERLINE)
+	if (style_to_add & UNDERLINE)
 	{
+		F32 descender = mFontFreetype->getDescenderHeight();
+
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.begin(LLRender::LINES);
-		gGL.vertex2f(start_x, cur_y - (mDescender));
-		gGL.vertex2f(cur_x, cur_y - (mDescender));
+		gGL.vertex2f(start_x, cur_y - (descender));
+		gGL.vertex2f(cur_x, cur_y - (descender));
 		gGL.end();
 	}
 
@@ -703,7 +412,7 @@ S32 LLFontGL::render(const LLWString &wstr,
 				cur_x / sScaleX, (F32)y,
 				color,
 				LEFT, valign,
-				style,
+				style_to_add,
 				shadow,
 				S32_MAX, max_pixels,
 				right_x,
@@ -716,8 +425,43 @@ S32 LLFontGL::render(const LLWString &wstr,
 	return chars_drawn;
 }
 
-
-S32 LLFontGL::getWidth(const std::string& utf8text) const
+S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const
+{
+	return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE, FALSE);
+}
+
+S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign,  VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels,  F32* right_x, BOOL use_ellipses) const
+{
+	return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses);
+}
+
+S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const
+{
+	return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
+}
+
+S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow) const
+{
+	return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow, S32_MAX, S32_MAX, NULL, FALSE);
+}
+
+// font metrics - override for LLFontFreetype that returns units of virtual pixels
+F32 LLFontGL::getLineHeight() const
+{ 
+	return (F32)llround(mFontFreetype->getLineHeight() / sScaleY); 
+}
+
+F32 LLFontGL::getAscenderHeight() const
+{ 
+	return (F32)llround(mFontFreetype->getAscenderHeight() / sScaleY); 
+}
+
+F32 LLFontGL::getDescenderHeight() const
+{ 
+	return (F32)llround(mFontFreetype->getDescenderHeight() / sScaleY); 
+}
+
+S32 LLFontGL::getWidth(const std::string& utf8text) const
 {
 	LLWString wtext = utf8str_to_wstring(utf8text);
 	return getWidth(wtext.c_str(), 0, S32_MAX);
@@ -728,13 +472,13 @@ S32 LLFontGL::getWidth(const llwchar* wchars) const
 	return getWidth(wchars, 0, S32_MAX);
 }
 
-S32 LLFontGL::getWidth(const std::string& utf8text, const S32 begin_offset, const S32 max_chars) const
+S32 LLFontGL::getWidth(const std::string& utf8text, S32 begin_offset, S32 max_chars) const
 {
 	LLWString wtext = utf8str_to_wstring(utf8text);
 	return getWidth(wtext.c_str(), begin_offset, max_chars);
 }
 
-S32 LLFontGL::getWidth(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
+S32 LLFontGL::getWidth(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const
 {
 	F32 width = getWidthF32(wchars, begin_offset, max_chars, use_embedded);
 	return llround(width);
@@ -751,15 +495,15 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars) const
 	return getWidthF32(wchars, 0, S32_MAX);
 }
 
-F32 LLFontGL::getWidthF32(const std::string& utf8text, const S32 begin_offset, const S32 max_chars ) const
+F32 LLFontGL::getWidthF32(const std::string& utf8text, S32 begin_offset, S32 max_chars ) const
 {
 	LLWString wtext = utf8str_to_wstring(utf8text);
 	return getWidthF32(wtext.c_str(), begin_offset, max_chars);
 }
 
-F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
+F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const
 {
-	const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL;
+	const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
 
 	F32 cur_x = 0;
 	const S32 max_index = begin_offset + max_chars;
@@ -783,7 +527,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
 		}
 		else
 		{
-			cur_x += getXAdvance(wch);
+			cur_x += mFontFreetype->getXAdvance(wch);
 			llwchar next_char = wchars[i+1];
 
 			if (((i + 1) < max_chars) 
@@ -791,7 +535,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
 				&& (next_char < LAST_CHARACTER))
 			{
 				// Kern this puppy.
-				cur_x += getXKerning(wch, next_char);
+				cur_x += mFontFreetype->getXKerning(wch, next_char);
 			}
 		}
 		// Round after kerning.
@@ -801,12 +545,8 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
 	return cur_x / sScaleX;
 }
 
-
-
 // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
-S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars,
-							   BOOL end_on_word_boundary, const BOOL use_embedded,
-							   F32* drawn_pixels) const
+S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, BOOL end_on_word_boundary, BOOL use_embedded, F32* drawn_pixels) const
 {
 	if (!wchars || !wchars[0] || max_chars == 0)
 	{
@@ -899,7 +639,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
 				}
 			}
 
-			cur_x += getXAdvance(wch);
+			cur_x += mFontFreetype->getXAdvance(wch);
 			
 			if (scaled_max_pixels < cur_x)
 			{
@@ -910,7 +650,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
 			if (((i+1) < max_chars) && wchars[i+1])
 			{
 				// Kern this puppy.
-				cur_x += getXKerning(wch, wchars[i+1]);
+				cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]);
 			}
 		}
 		// Round after kerning.
@@ -929,7 +669,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
 	return i;
 }
 
-
 S32	LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos, S32 max_chars) const
 {
 	if (!wchars || !wchars[0] || max_chars == 0)
@@ -948,7 +687,7 @@ S32	LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
 		llwchar wch = wchars[i];
 
 		const embedded_data_t* ext_data = getEmbeddedCharData(wch);
-		F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : getXAdvance(wch);
+		F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : mFontFreetype->getXAdvance(wch);
 
 		if( scaled_max_pixels < (total_width + char_width) )
 		{
@@ -966,7 +705,7 @@ S32	LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
 		if ( i > 0 )
 		{
 			// kerning
-			total_width += ext_data ? (EXT_KERNING * sScaleX) : getXKerning(wchars[i-1], wch);
+			total_width += ext_data ? (EXT_KERNING * sScaleX) : mFontFreetype->getXKerning(wchars[i-1], wch);
 		}
 
 		// Round after kerning.
@@ -976,8 +715,7 @@ S32	LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
 	return start_pos - drawable_chars;
 }
 
-
-S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const
+S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const
 {
 	if (!wchars || !wchars[0] || max_chars == 0)
 	{
@@ -1041,7 +779,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
 		}
 		else
 		{
-			F32 char_width = getXAdvance(wch);
+			F32 char_width = mFontFreetype->getXAdvance(wch);
 
 			if (round)
 			{
@@ -1070,7 +808,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
 			{
 				llwchar next_char = wchars[i + 1];
 				// Kern this puppy.
-				cur_x += getXKerning(wch, next_char);
+				cur_x += mFontFreetype->getXKerning(wch, next_char);
 			}
 
 			// Round after kerning.
@@ -1081,60 +819,370 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
 	return pos;
 }
 
+void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const
+{
+	LLWString wlabel = utf8str_to_wstring(label);
+	addEmbeddedChar(wc, image, wlabel);
+}
 
-const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(const llwchar wch) const
+void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const
 {
-	// Handle crappy embedded hack
-	embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch);
+	embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel);
+	mEmbeddedChars[wc] = ext_data;
+}
+
+void LLFontGL::removeEmbeddedChar(llwchar wc) const
+{
+	embedded_map_t::iterator iter = mEmbeddedChars.find(wc);
 	if (iter != mEmbeddedChars.end())
 	{
-		return iter->second;
+		delete iter->second;
+		mEmbeddedChars.erase(wc);
 	}
-	return NULL;
 }
 
+BOOL LLFontGL::addChar(llwchar wch) const
+{
+	if (!mFontFreetype->addChar(wch))
+	{
+		return FALSE;
+	}
 
-F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const
+	stop_glerror();
+
+	LLFontGlyphInfo *glyph_info = mFontFreetype->getGlyphInfo(wch);
+	U32 bitmap_num = glyph_info->mBitmapNum;
+
+	const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
+	LLImageGL *image_gl = font_bitmap_cache->getImageGL(bitmap_num);
+	LLImageRaw *image_raw = font_bitmap_cache->getImageRaw(bitmap_num);
+	image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight());
+	return TRUE;
+}
+
+const LLFontDescriptor& LLFontGL::getFontDesc() const
 {
-	const LLWString& label = ext_data->mLabel;
-	LLImageGL* ext_image = ext_data->mImage;
+	return mFontDescriptor;
+}
 
-	F32 ext_width = (F32)ext_image->getWidth();
-	if( !label.empty() )
+// static
+void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures)
+{
+	sVertDPI = (F32)llfloor(screen_dpi * y_scale);
+	sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
+	sScaleX = x_scale;
+	sScaleY = y_scale;
+	sAppDir = app_dir;
+
+	// Font registry init
+	if (!sFontRegistry)
 	{
-		ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX;
+		sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures);
+		sFontRegistry->parseFontInfo("fonts.xml");
+	}
+	else
+	{
+		sFontRegistry->reset();
 	}
+}
 
-	return (EXT_X_BEARING * sScaleX) + ext_width;
+// Force standard fonts to get generated up front.
+// This is primarily for error detection purposes.
+// Don't do this during initClass because it can be slow and we want to get
+// the viewer window on screen first. JC
+// static
+bool LLFontGL::loadDefaultFonts()
+{
+	bool succ = true;
+	succ &= (NULL != getFontSansSerifSmall());
+	succ &= (NULL != getFontSansSerif());
+	succ &= (NULL != getFontSansSerifBig());
+	succ &= (NULL != getFontSansSerifHuge());
+	succ &= (NULL != getFontSansSerifBold());
+	succ &= (NULL != getFontMonospace());
+	succ &= (NULL != getFontExtChar());
+	return succ;
 }
 
+// static
+void LLFontGL::destroyDefaultFonts()
+{
+	// Remove the actual fonts.
+	delete sFontRegistry;
+	sFontRegistry = NULL;
+}
 
-void LLFontGL::clearEmbeddedChars()
+//static 
+void LLFontGL::destroyAllGL()
 {
-	for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer());
-	mEmbeddedChars.clear();
+	if (sFontRegistry)
+	{
+		sFontRegistry->destroyGL();
+	}
 }
 
-void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const
+// static
+U8 LLFontGL::getStyleFromString(const std::string &style)
 {
-	LLWString wlabel = utf8str_to_wstring(label);
-	addEmbeddedChar(wc, image, wlabel);
+	S32 ret = 0;
+	if (style.find("NORMAL") != style.npos)
+	{
+		ret |= NORMAL;
+	}
+	if (style.find("BOLD") != style.npos)
+	{
+		ret |= BOLD;
+	}
+	if (style.find("ITALIC") != style.npos)
+	{
+		ret |= ITALIC;
+	}
+	if (style.find("UNDERLINE") != style.npos)
+	{
+		ret |= UNDERLINE;
+	}
+	return ret;
 }
 
-void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const
+// static
+std::string LLFontGL::nameFromFont(const LLFontGL* fontp)
 {
-	embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel);
-	mEmbeddedChars[wc] = ext_data;
+	return fontp->mFontDescriptor.getName();
 }
 
-void LLFontGL::removeEmbeddedChar( llwchar wc ) const
+// static
+std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align)
 {
-	embedded_map_t::iterator iter = mEmbeddedChars.find(wc);
+	if (align == LEFT)			return std::string("left");
+	else if (align == RIGHT)	return std::string("right");
+	else if (align == HCENTER)	return std::string("center");
+	else return std::string();
+}
+
+// static
+LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name)
+{
+	LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT;
+	if (name == "left")
+	{
+		gl_hfont_align = LLFontGL::LEFT;
+	}
+	else if (name == "right")
+	{
+		gl_hfont_align = LLFontGL::RIGHT;
+	}
+	else if (name == "center")
+	{
+		gl_hfont_align = LLFontGL::HCENTER;
+	}
+	//else leave left
+	return gl_hfont_align;
+}
+
+// static
+std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align)
+{
+	if (align == TOP)			return std::string("top");
+	else if (align == VCENTER)	return std::string("center");
+	else if (align == BASELINE)	return std::string("baseline");
+	else if (align == BOTTOM)	return std::string("bottom");
+	else return std::string();
+}
+
+// static
+LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name)
+{
+	LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE;
+	if (name == "top")
+	{
+		gl_vfont_align = LLFontGL::TOP;
+	}
+	else if (name == "center")
+	{
+		gl_vfont_align = LLFontGL::VCENTER;
+	}
+	else if (name == "baseline")
+	{
+		gl_vfont_align = LLFontGL::BASELINE;
+	}
+	else if (name == "bottom")
+	{
+		gl_vfont_align = LLFontGL::BOTTOM;
+	}
+	//else leave baseline
+	return gl_vfont_align;
+}
+
+//static
+LLFontGL* LLFontGL::getFontMonospace()
+{
+	return getFont(LLFontDescriptor("Monospace","Monospace",0));
+}
+
+//static
+LLFontGL* LLFontGL::getFontSansSerifSmall()
+{
+	return getFont(LLFontDescriptor("SansSerif","Small",0));
+}
+
+//static
+LLFontGL* LLFontGL::getFontSansSerif()
+{
+	return getFont(LLFontDescriptor("SansSerif","Medium",0));
+}
+
+//static
+LLFontGL* LLFontGL::getFontSansSerifBig()
+{
+	return getFont(LLFontDescriptor("SansSerif","Large",0));
+}
+
+//static 
+LLFontGL* LLFontGL::getFontSansSerifHuge()
+{
+	return getFont(LLFontDescriptor("SansSerif","Huge",0));
+}
+
+//static 
+LLFontGL* LLFontGL::getFontSansSerifBold()
+{
+	return getFont(LLFontDescriptor("SansSerif","Medium",BOLD));
+}
+
+//static
+LLFontGL* LLFontGL::getFontExtChar()
+{
+	return getFontSansSerif();
+}
+
+//static 
+LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc)
+{
+	return sFontRegistry->getFont(desc);
+}
+
+//static
+LLFontGL* LLFontGL::getFontByName(const std::string& name)
+{
+	// check for most common fonts first
+	if (name == "SANSSERIF")
+	{
+		return getFontSansSerif();
+	}
+	else if (name == "SANSSERIF_SMALL")
+	{
+		return getFontSansSerifSmall();
+	}
+	else if (name == "SANSSERIF_BIG")
+	{
+		return getFontSansSerifBig();
+	}
+	else if (name == "SMALL" || name == "OCRA")
+	{
+		// *BUG: Should this be "MONOSPACE"?  Do we use "OCRA" anymore?
+		// Does "SMALL" mean "SERIF"?
+		return getFontMonospace();
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+// static 
+std::string LLFontGL::getFontPathSystem()
+{
+	std::string system_path;
+
+	// Try to figure out where the system's font files are stored.
+	char *system_root = NULL;
+#if LL_WINDOWS
+	system_root = getenv("SystemRoot");	/* Flawfinder: ignore */
+	if (!system_root)
+	{
+		llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl;
+	}
+#endif
+
+	if (system_root)
+	{
+		system_path = llformat("%s/fonts/", system_root);
+	}
+	else
+	{
+#if LL_WINDOWS
+		// HACK for windows 98/Me
+		system_path = "/WINDOWS/FONTS/";
+#elif LL_DARWIN
+		// HACK for Mac OS X
+		system_path = "/System/Library/Fonts/";
+#endif
+	}
+	return system_path;
+}
+
+
+// static 
+std::string LLFontGL::getFontPathLocal()
+{
+	std::string local_path;
+
+	// Backup files if we can't load from system fonts directory.
+	// We could store this in an end-user writable directory to allow
+	// end users to switch fonts.
+	if (LLFontGL::sAppDir.length())
+	{
+		// use specified application dir to look for fonts
+		local_path = LLFontGL::sAppDir + "/fonts/";
+	}
+	else
+	{
+		// assume working directory is executable directory
+		local_path = "./fonts/";
+	}
+	return local_path;
+}
+
+LLFontGL::LLFontGL(const LLFontGL &source)
+{
+	llerrs << "Not implemented!" << llendl;
+}
+
+LLFontGL &LLFontGL::operator=(const LLFontGL &source)
+{
+	llerrs << "Not implemented" << llendl;
+	return *this;
+}
+
+const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(llwchar wch) const
+{
+	// Handle crappy embedded hack
+	embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch);
 	if (iter != mEmbeddedChars.end())
 	{
-		delete iter->second;
-		mEmbeddedChars.erase(wc);
+		return iter->second;
 	}
+	return NULL;
+}
+
+F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const
+{
+	const LLWString& label = ext_data->mLabel;
+	LLImageGL* ext_image = ext_data->mImage;
+
+	F32 ext_width = (F32)ext_image->getWidth();
+	if( !label.empty() )
+	{
+		ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX;
+	}
+
+	return (EXT_X_BEARING * sScaleX) + ext_width;
+}
+
+void LLFontGL::clearEmbeddedChars()
+{
+	for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer());
+	mEmbeddedChars.clear();
 }
 
 
@@ -1160,7 +1208,7 @@ void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F3
 void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
 {
 	F32 slant_offset;
-	slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f);
+	slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f);
 
 	gGL.begin(LLRender::QUADS);
 	{
@@ -1230,71 +1278,3 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con
 	}
 	gGL.end();
 }
-
-std::string LLFontGL::nameFromFont(const LLFontGL* fontp)
-{
-	return fontp->getFontDesc().getName();
-}
-
-// static
-std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align)
-{
-	if (align == LEFT)			return std::string("left");
-	else if (align == RIGHT)	return std::string("right");
-	else if (align == HCENTER)	return std::string("center");
-	else return std::string();
-}
-
-// static
-LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name)
-{
-	LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT;
-	if (name == "left")
-	{
-		gl_hfont_align = LLFontGL::LEFT;
-	}
-	else if (name == "right")
-	{
-		gl_hfont_align = LLFontGL::RIGHT;
-	}
-	else if (name == "center")
-	{
-		gl_hfont_align = LLFontGL::HCENTER;
-	}
-	//else leave left
-	return gl_hfont_align;
-}
-
-// static
-std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align)
-{
-	if (align == TOP)			return std::string("top");
-	else if (align == VCENTER)	return std::string("center");
-	else if (align == BASELINE)	return std::string("baseline");
-	else if (align == BOTTOM)	return std::string("bottom");
-	else return std::string();
-}
-
-// static
-LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name)
-{
-	LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE;
-	if (name == "top")
-	{
-		gl_vfont_align = LLFontGL::TOP;
-	}
-	else if (name == "center")
-	{
-		gl_vfont_align = LLFontGL::VCENTER;
-	}
-	else if (name == "baseline")
-	{
-		gl_vfont_align = LLFontGL::BASELINE;
-	}
-	else if (name == "bottom")
-	{
-		gl_vfont_align = LLFontGL::BOTTOM;
-	}
-	//else leave baseline
-	return gl_vfont_align;
-}
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 2298db0ef301003c7876191dec44c0178422e46a..42ed7a381fd104166ca53e0226bacf2ced0f3d5b 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -35,21 +35,21 @@
 #define LL_LLFONTGL_H
 
 #include "llcoord.h"
-#include "llfont.h"
 #include "llfontregistry.h"
+#include "llimagegl.h"
 #include "llpointer.h"
 #include "llrect.h"
 #include "v2math.h"
 
 class LLColor4;
-class LLImageGL;
 // Key used to request a font.
 class LLFontDescriptor;
+class LLFontFreetype;
 
 // Structure used to store previously requested fonts.
 class LLFontRegistry;
 
-class LLFontGL : public LLFont
+class LLFontGL
 {
 public:
 	enum HAlign
@@ -85,130 +85,72 @@ class LLFontGL : public LLFont
 		DROP_SHADOW,
 		DROP_SHADOW_SOFT
 	};
-	
-	// Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC"
-	static U8 getStyleFromString(const std::string &style);
 
 	LLFontGL();
-	LLFontGL(const LLFontGL &source);
 	~LLFontGL();
 
-	void init(); // Internal init, or reinitialization
-	void reset(); // Reset a font after GL cleanup.  ONLY works on an already loaded font.
 
-	LLFontGL &operator=(const LLFontGL &source);
-
-	static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale,
-								 const std::string& app_dir,
-								 const std::vector<std::string>& xui_paths,
-								 bool create_gl_textures = true);
+	void reset(); // Reset a font after GL cleanup.  ONLY works on an already loaded font.
 
-	// Load sans-serif, sans-serif-small, etc.
-	// Slow, requires multiple seconds to load fonts.
-	static bool loadDefaultFonts();
-	static void	destroyDefaultFonts();
-	static void destroyAllGL();
 	void destroyGL();
 
-	/* virtual*/ BOOL loadFace(const std::string& filename,
-							    const F32 point_size, const F32 vert_dpi, const F32 horz_dpi,
-							    const S32 components, BOOL is_fallback);
+	BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback);
 
+	S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign = LEFT,  VAlign valign = BASELINE, U8 style = NORMAL,
+	           ShadowType shadow = NO_SHADOW, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x=NULL, BOOL use_embedded = FALSE, BOOL use_ellipses = FALSE) const;
+	S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const;
 
-	S32 renderUTF8(const std::string &text, const S32 begin_offset,
-				   S32 x, S32 y,
-				   const LLColor4 &color) const
-	{
-		return renderUTF8(text, begin_offset, (F32)x, (F32)y, color,
-							LEFT, BASELINE, NORMAL, NO_SHADOW,
-							S32_MAX, S32_MAX, NULL, FALSE);
-	}
-	
-	S32 renderUTF8(const std::string &text, const S32 begin_offset,
-				   S32 x, S32 y,
-				   const LLColor4 &color,
-				   HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const
-	{
-		return renderUTF8(text, begin_offset, (F32)x, (F32)y, color,
-						  halign, valign, style, shadow,
-						  S32_MAX, S32_MAX, NULL, FALSE);
-	}
-	
 	// renderUTF8 does a conversion, so is slower!
-	S32 renderUTF8(const std::string &text,
-		S32 begin_offset,
-		F32 x, F32 y,
-		const LLColor4 &color,
-		HAlign halign, 
-		VAlign valign,
-		U8 style,
-		ShadowType shadow,
-		S32 max_chars,
-		S32 max_pixels, 
-		F32* right_x,
-		BOOL use_ellipses) const;
-
-	S32 render(const LLWString &text, const S32 begin_offset,
-			   F32 x, F32 y,
-			   const LLColor4 &color) const
-	{
-		return render(text, begin_offset, x, y, color,
-					  LEFT, BASELINE, NORMAL, NO_SHADOW,
-					  S32_MAX, S32_MAX, NULL, FALSE, FALSE);
-	}
-	
+	S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign,  VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels,  F32* right_x, BOOL use_ellipses) const;
+	S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const;
+	S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
 
-	S32 render(const LLWString &text,
-		S32 begin_offset,
-		F32 x, F32 y,
-		const LLColor4 &color,
-		HAlign halign = LEFT, 
-		VAlign valign = BASELINE,
-		U8 style = NORMAL,
-		ShadowType shadow = NO_SHADOW,
-		S32 max_chars = S32_MAX,
-		S32 max_pixels = S32_MAX, 
-		F32* right_x=NULL,
-		BOOL use_embedded = FALSE,
-		BOOL use_ellipses = FALSE) const;
-
-	// font metrics - override for LLFont that returns units of virtual pixels
-	/*virtual*/ F32 getLineHeight() const		{ return (F32)llround(mLineHeight / sScaleY); }
-	/*virtual*/ F32 getAscenderHeight() const	{ return (F32)llround(mAscender / sScaleY); }
-	/*virtual*/ F32 getDescenderHeight() const	{ return (F32)llround(mDescender / sScaleY); }
-	
-	virtual S32 getWidth(const std::string& utf8text) const;
-	virtual S32 getWidth(const llwchar* wchars) const;
-	virtual S32 getWidth(const std::string& utf8text, const S32 offset, const S32 max_chars ) const;
-	virtual S32 getWidth(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE) const;
+	// font metrics - override for LLFontFreetype that returns units of virtual pixels
+	F32 getLineHeight() const;
+	F32 getAscenderHeight() const;
+	F32 getDescenderHeight() const;
 
-	virtual F32 getWidthF32(const std::string& utf8text) const;
-	virtual F32 getWidthF32(const llwchar* wchars) const;
-	virtual F32 getWidthF32(const std::string& text, const S32 offset, const S32 max_chars ) const;
-	virtual F32 getWidthF32(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE ) const;
+	S32 getWidth(const std::string& utf8text) const;
+	S32 getWidth(const llwchar* wchars) const;
+	S32 getWidth(const std::string& utf8text, S32 offset, S32 max_chars ) const;
+	S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE) const;
+
+	F32 getWidthF32(const std::string& utf8text) const;
+	F32 getWidthF32(const llwchar* wchars) const;
+	F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars ) const;
+	F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE ) const;
 
 	// The following are called often, frequently with large buffers, so do not use a string interface
 	
 	// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
-	virtual S32	maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX,
-								 BOOL end_on_word_boundary = FALSE, const BOOL use_embedded = FALSE,
-								 F32* drawn_pixels = NULL) const;
+	S32	maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, BOOL end_on_word_boundary = FALSE, BOOL use_embedded = FALSE, F32* drawn_pixels = NULL) const;
 
 	// Returns the index of the first complete characters from text that can be drawn in max_pixels
 	// given that the character at start_pos should be the last character (or as close to last as possible).
-	virtual S32	firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const;
+	S32	firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const;
 
 	// Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars)
-	virtual S32 charFromPixelOffset(const llwchar* wchars, const S32 char_offset,
-									F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX,
-									BOOL round = TRUE, BOOL use_embedded = FALSE) const;
+	S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE, BOOL use_embedded = FALSE) const;
+
+	void addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const;
+	void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const;
+	void removeEmbeddedChar( llwchar wc ) const;
 
+	BOOL addChar(const llwchar wch) const;
 
-	LLImageGL *getImageGL() const;
+	const LLFontDescriptor& getFontDesc() const;
 
-	void	   addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const;
-	void	   addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const;
-	void	   removeEmbeddedChar( llwchar wc ) const;
+
+	static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures = true);
+
+	// Load sans-serif, sans-serif-small, etc.
+	// Slow, requires multiple seconds to load fonts.
+	static bool loadDefaultFonts();
+	static void	destroyDefaultFonts();
+	static void destroyAllGL();
+
+	// Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC"
+	static U8 getStyleFromString(const std::string &style);
 
 	static std::string nameFromFont(const LLFontGL* fontp);
 
@@ -218,28 +160,7 @@ class LLFontGL : public LLFont
 	static std::string nameFromVAlign(LLFontGL::VAlign align);
 	static LLFontGL::VAlign vAlignFromName(const std::string& name);
 
-	static void setFontDisplay(BOOL flag) { sDisplayFont = flag ; }
-
-protected:
-	struct embedded_data_t
-	{
-		embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {}
-		LLPointer<LLImageGL> mImage;
-		LLWString			 mLabel;
-	};
-	const embedded_data_t* getEmbeddedCharData(const llwchar wch) const;
-	F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const;
-	void clearEmbeddedChars();
-	void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const;
-	void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
-
-public:
-	static F32 sVertDPI;
-	static F32 sHorizDPI;
-	static F32 sScaleX;
-	static F32 sScaleY;
-	static BOOL     sDisplayFont ;
-	static std::string sAppDir;			// For loading fonts
+	static void setFontDisplay(BOOL flag) { sDisplayFont = flag; }
 		
 	static LLFontGL* getFontMonospace();
 	static LLFontGL* getFontSansSerifSmall();
@@ -252,32 +173,50 @@ class LLFontGL : public LLFont
 	// Use with legacy names like "SANSSERIF_SMALL" or "OCRA"
 	static LLFontGL* getFontByName(const std::string& name);
 
+	static std::string getFontPathLocal();
+	static std::string getFontPathSystem();
+
+	static LLCoordFont sCurOrigin;
+	static std::vector<LLCoordFont> sOriginStack;
+
 	static LLColor4 sShadowColor;
 
+	static F32 sVertDPI;
+	static F32 sHorizDPI;
+	static F32 sScaleX;
+	static F32 sScaleY;
+	static BOOL sDisplayFont ;
+	static std::string sAppDir;			// For loading fonts
+
+private:
+	friend class LLFontRegistry;
 	friend class LLTextBillboard;
 	friend class LLHUDText;
 
-protected:
-	/*virtual*/ BOOL addChar(const llwchar wch) const;
+	LLFontGL(const LLFontGL &source);
+	LLFontGL &operator=(const LLFontGL &source);
 
-protected:
-	typedef std::map<llwchar,embedded_data_t*> embedded_map_t;
-	mutable embedded_map_t mEmbeddedChars;
-	
 	LLFontDescriptor mFontDescriptor;
+	LLPointer<LLFontFreetype> mFontFreetype;
 
-	// Registry holds all instantiated fonts.
-	static LLFontRegistry* sFontRegistry;
+	struct embedded_data_t
+	{
+		embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {}
+		LLPointer<LLImageGL> mImage;
+		LLWString			 mLabel;
+	};
 
-public:
-	static std::string getFontPathLocal();
-	static std::string getFontPathSystem();
+	typedef std::map<llwchar,embedded_data_t*> embedded_map_t;
+	mutable embedded_map_t mEmbeddedChars;
 
-	static LLCoordFont sCurOrigin;
-	static std::vector<LLCoordFont> sOriginStack;
+	const embedded_data_t* getEmbeddedCharData(llwchar wch) const;
+	F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const;
+	void clearEmbeddedChars();
+	void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const;
+	void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
 
-	const LLFontDescriptor &getFontDesc() const { return mFontDescriptor; }
-	void setFontDesc(const LLFontDescriptor& font_desc) { mFontDescriptor = font_desc; }
+	// Registry holds all instantiated fonts.
+	static LLFontRegistry* sFontRegistry;
 };
 
 #endif
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 3b5c62a5ea6f194de3d38b8b6f49609b7d875412..553e7b8f9dcf49890d557610c915e7d3be45ed32 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -33,8 +33,9 @@
 
 #include "linden_common.h"
 #include "llgl.h"
-#include "llfontregistry.h"
+#include "llfontfreetype.h"
 #include "llfontgl.h"
+#include "llfontregistry.h"
 #include <boost/tokenizer.hpp>
 #include "llcontrol.h"
 #include "lldir.h"
@@ -382,7 +383,14 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
 	if (it != mFontMap.end())
 	{
 		llinfos << "-- matching font exists: " << nearest_exact_desc.getName() << " size " << nearest_exact_desc.getSize() << " style " << ((S32) nearest_exact_desc.getStyle()) << llendl;
-		return it->second;
+		
+		// copying underlying Freetype font, and storing in LLFontGL with requested font descriptor
+		LLFontGL *font = new LLFontGL;
+		font->mFontDescriptor = desc;
+		font->mFontFreetype = it->second->mFontFreetype;
+		mFontMap[desc] = font;
+
+		return font;
 	}
 
 	// Build list of font names to look for.
@@ -410,10 +418,11 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
 		llwarns << "createFont failed, no file names specified" << llendl;
 		return NULL;
 	}
-	LLFontList *fontlistp = new LLFontList;
+
+	LLFontFreetype::font_vector_t fontlist;
 	LLFontGL *result = NULL;
 
-	// Snarf all fonts we can into fontlistp.  First will get pulled
+	// Snarf all fonts we can into fontlist.  First will get pulled
 	// off the list and become the "head" font, set to non-fallback.
 	// Rest will consitute the fallback list.
 	BOOL is_first_found = TRUE;
@@ -455,23 +464,28 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
 				is_first_found = false;
 			}
 			else
-				fontlistp->addAtEnd(fontp);
+			{
+				fontlist.push_back(fontp->mFontFreetype);
+			}
 		}
 	}
-	if (result && !fontlistp->empty())
+
+	if (result && !fontlist.empty())
 	{
-		result->setFallbackFont(fontlistp);
+		result->mFontFreetype->setFallbackFonts(fontlist);
 	}
 
-	norm_desc.setStyle(match_desc->getStyle());
 	if (result)
-		result->setFontDesc(norm_desc);
-
-	if (!result)
+	{
+		result->mFontFreetype->setStyle(match_desc->getStyle());
+		result->mFontDescriptor = desc;
+	}
+	else
 	{
 		llwarns << "createFont failed in some way" << llendl;
 	}
-	mFontMap[norm_desc] = result;
+
+	mFontMap[desc] = result;
 	return result;
 }
 
@@ -511,21 +525,19 @@ void LLFontRegistry::destroyGL()
 	}
 }
 
-LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& orig_desc)
+LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& desc)
 {
-	LLFontDescriptor norm_desc = orig_desc.normalize();
-
-	font_reg_map_t::iterator it = mFontMap.find(norm_desc);
+	font_reg_map_t::iterator it = mFontMap.find(desc);
 	if (it != mFontMap.end())
 		return it->second;
 	else
 	{
-		LLFontGL *fontp = createFont(orig_desc);
+		LLFontGL *fontp = createFont(desc);
 		if (!fontp)
 		{
-			llwarns << "getFont failed, name " << orig_desc.getName()
-					<<" style=[" << ((S32) orig_desc.getStyle()) << "]"
-					<< " size=[" << orig_desc.getSize() << "]" << llendl;
+			llwarns << "getFont failed, name " << desc.getName()
+					<<" style=[" << ((S32) desc.getStyle()) << "]"
+					<< " size=[" << desc.getSize() << "]" << llendl;
 		}
 		return fontp;
 	}
@@ -653,3 +665,8 @@ void LLFontRegistry::dump()
 		}
 	}
 }
+
+const string_vec_t& LLFontRegistry::getUltimateFallbackList() const 
+{ 
+	return mUltimateFallbackList;
+}
diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h
index 198ca0b9205ce91a9d323b8d5f1cd74c14ea3d45..4da4ca48bb2aa927cf883d13959d67fb961ef576 100644
--- a/indra/llrender/llfontregistry.h
+++ b/indra/llrender/llfontregistry.h
@@ -98,7 +98,7 @@ class LLFontRegistry
 
 	void dump();
 	
-	const string_vec_t& getUltimateFallbackList() const { return mUltimateFallbackList; }
+	const string_vec_t& getUltimateFallbackList() const;
 
 private:
 	LLFontGL *createFont(const LLFontDescriptor& desc);
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index e62d875a01ae44165319f57c155f8a08ac2f5bf9..edd3fe2beb23ad2130807c5d5fac67c054273aa6 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -37,6 +37,7 @@ set(llui_SOURCE_FILES
     lldraghandle.cpp
     lleditmenuhandler.cpp
     llf32uictrl.cpp
+    llfiltereditor.cpp
     llfloater.cpp
     llfloaterreg.cpp
     llflyoutbutton.cpp 
@@ -59,6 +60,7 @@ set(llui_SOURCE_FILES
     llresizebar.cpp
     llresizehandle.cpp
     llresmgr.cpp
+    llrngwriter.cpp
     llscrollbar.cpp
     llscrollcontainer.cpp
     llscrollingpanellist.cpp
@@ -67,7 +69,7 @@ set(llui_SOURCE_FILES
     llscrolllistctrl.cpp
     llscrolllistitem.cpp
     llsdparam.cpp
-    llsearcheditor.cpp 
+    llsearcheditor.cpp
     llslider.cpp
     llsliderctrl.cpp
     llspinctrl.cpp
@@ -109,11 +111,13 @@ set(llui_HEADER_FILES
     lldraghandle.h
     lleditmenuhandler.h
     llf32uictrl.h
+    llfiltereditor.h 
     llfloater.h
     llfloaterreg.h
     llflyoutbutton.h 
     llfocusmgr.h
     llfunctorregistry.h
+    llhandle.h
     llhtmlhelp.h
     lliconctrl.h
     llinitparam.h
@@ -134,6 +138,7 @@ set(llui_HEADER_FILES
     llresizebar.h
     llresizehandle.h
     llresmgr.h
+    llrngwriter.h
     llsearcheditor.h 
     llscrollbar.h
     llscrollcontainer.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 9ad27e7c4153ca30f4d1a5738ca1efc4317b2b99..fc3af34951c77961bc391e70245925f1d320a725 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -62,7 +62,7 @@ S32 BTN_HEIGHT		= 0;
 
 LLButton::Params::Params()
 :	label_selected("label_selected"),				// requires is_toggle true
-	label_dropshadow("label_shadow", true),
+	label_shadow("label_shadow", true),
 	auto_resize("auto_resize", false),
 	image_unselected("image_unselected"),
 	image_selected("image_selected"),
@@ -133,7 +133,7 @@ LLButton::LLButton(const LLButton::Params& p)
 	mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)),
 	mIsToggle(p.is_toggle),
 	mScaleImage(p.scale_image),
-	mDropShadowedText(p.label_dropshadow),
+	mDropShadowedText(p.label_shadow),
 	mAutoResize(p.auto_resize),
 	mHAlign(p.font_halign),
 	mLeftHPad(p.pad_left),
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 3fa62cc35165188db50ba28601f9a24e323f5ad9..e387c91a177e1ebed477c32aec382a4b0d910a3f 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -74,7 +74,7 @@ class LLButton
 	{
 		// text label
 		Optional<std::string>	label_selected;
-		Optional<bool>			label_dropshadow;
+		Optional<bool>			label_shadow;
 		Optional<bool>			auto_resize;
 
 		// images
@@ -105,9 +105,9 @@ class LLButton
 		
 		// callbacks
 		Optional<CommitCallbackParam>	click_callback, // alias -> commit_callback
-															mouse_down_callback,
-															mouse_up_callback,
-															mouse_held_callback;
+										mouse_down_callback,
+										mouse_up_callback,
+										mouse_held_callback;
 		
 		// misc
 		Optional<bool>			is_toggle,
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 5caad1919af096fb7c935e1b7e9d786973c2ad4f..51f9d6bd1862ae84cb320ef5482568c1fc902620 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -141,7 +141,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
 		LLScrollListItem::Params item_params = *it;
 		if (it->label.isProvided())
 		{
-			item_params.cells.add().value(it->label());
+			item_params.columns.add().value(it->label());
 		}
 
 		mList->addRow(item_params);
diff --git a/indra/llui/llconsole.h b/indra/llui/llconsole.h
index 65149b217f69c49372782776c918eabae0fefcdb..56e1614948be7e0337efd5338f2d2adc462b995a 100644
--- a/indra/llui/llconsole.h
+++ b/indra/llui/llconsole.h
@@ -58,7 +58,8 @@ class LLConsole : public LLFixedBuffer, public LLView
 		Optional<S32>	font_size_index;
 		Params()
 		:	max_lines("max_lines", LLUI::sSettingGroups["config"]->getS32("ConsoleMaxLines")),
-			persist_time("persist_time", 0.f) // forever
+			persist_time("persist_time", 0.f), // forever
+			font_size_index("font_size_index")
 		{
 			mouse_opaque(false);
 		}
diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp
index 8ecbdb98e1d1b50240892038e534eee54f1f0451..6e8e37ded37a0c3113018ddc55c24be30f56f551 100644
--- a/indra/llui/lldraghandle.cpp
+++ b/indra/llui/lldraghandle.cpp
@@ -317,6 +317,23 @@ BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask)
 		S32 delta_x = screen_x - mDragLastScreenX;
 		S32 delta_y = screen_y - mDragLastScreenY;
 
+		// if dragging a docked floater we want to undock
+		if (((LLFloater*)getParent())->isDocked())
+		{
+			const S32 SLOP = 12;
+
+			if (delta_y <= -SLOP || 
+				delta_y >= SLOP)
+			{
+				((LLFloater*)getParent())->setDocked(false, false);
+				return TRUE;
+			}
+			else
+			{
+				return FALSE;
+			}
+		}
+
 		LLRect original_rect = getParent()->getRect();
 		LLRect translated_rect = getParent()->getRect();
 		translated_rect.translate(delta_x, delta_y);
diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h
index 86eef7c42c232355f1e355e26a5746b702d7f017..88ec1d21f81ce22dc1cdea50ba30e4cab9012fc2 100644
--- a/indra/llui/lldraghandle.h
+++ b/indra/llui/lldraghandle.h
@@ -53,7 +53,8 @@ class LLDragHandle : public LLView
 		Optional<LLUIColor> drag_shadow_color;
 		
 		Params() 
-		:	drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")),
+		:	label("label"),	
+			drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")),
 			drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark"))
 		{
 			mouse_opaque(true);
diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0f36483fc2c93520719c78c7bb6b7a949de64849
--- /dev/null
+++ b/indra/llui/llfiltereditor.cpp
@@ -0,0 +1,110 @@
+/** 
+ * @file llfiltereditor.cpp
+ * @brief LLFilterEditor implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Text editor widget to let users enter a single line.
+
+#include "linden_common.h"
+ 
+#include "llfiltereditor.h"
+
+LLFilterEditor::LLFilterEditor(const LLFilterEditor::Params& p)
+:	LLUICtrl(p)
+{
+	LLLineEditor::Params line_editor_p(p);
+	line_editor_p.name("filter edit box");
+	line_editor_p.rect(getLocalRect());
+	line_editor_p.follows.flags(FOLLOWS_ALL);
+	line_editor_p.text_pad_right(getRect().getHeight());
+	line_editor_p.keystroke_callback(boost::bind(&LLUICtrl::onCommit, this));
+
+	mFilterEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_p);
+	addChild(mFilterEditor);
+
+	S32 btn_width = getRect().getHeight(); // button is square, and as tall as search editor
+	LLRect clear_btn_rect(getRect().getWidth() - btn_width, getRect().getHeight(), getRect().getWidth(), 0);
+	LLButton::Params button_params(p.clear_filter_button);
+	button_params.name(std::string("clear filter"));
+	button_params.rect(clear_btn_rect) ;
+	button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
+	button_params.tab_stop(false);
+	button_params.click_callback.function(boost::bind(&LLFilterEditor::onClearFilter, this, _2));
+
+	mClearFilterButton = LLUICtrlFactory::create<LLButton>(button_params);
+	mFilterEditor->addChild(mClearFilterButton);
+}
+
+//virtual
+void LLFilterEditor::setValue(const LLSD& value )
+{
+	mFilterEditor->setValue(value);
+}
+
+//virtual
+LLSD LLFilterEditor::getValue() const
+{
+	return mFilterEditor->getValue();
+}
+
+//virtual
+BOOL LLFilterEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
+{
+	return mFilterEditor->setTextArg(key, text);
+}
+
+//virtual
+BOOL LLFilterEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
+{
+	return mFilterEditor->setLabelArg(key, text);
+}
+
+//virtual
+void LLFilterEditor::clear()
+{
+	if (mFilterEditor)
+	{
+		mFilterEditor->clear();
+	}
+}
+
+void LLFilterEditor::draw()
+{
+	mClearFilterButton->setVisible(!mFilterEditor->getWText().empty());
+
+	LLUICtrl::draw();
+}
+
+void LLFilterEditor::onClearFilter(const LLSD& data)
+{
+	setText(LLStringUtil::null);
+	onCommit();
+}
+
diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h
new file mode 100644
index 0000000000000000000000000000000000000000..4240fd770c9bd3e8282efc1f892adc7a6f37af68
--- /dev/null
+++ b/indra/llui/llfiltereditor.h
@@ -0,0 +1,86 @@
+/** 
+ * @file llfiltereditor.h
+ * @brief Text editor widget that represents a filter operation
+ *
+ * Features: 
+ *		Text entry of a single line (text, delete, left and right arrow, insert, return).
+ *		Callbacks either on every keystroke or just on the return key.
+ *		Focus (allow multiple text entry widgets)
+ *		Clipboard (cut, copy, and paste)
+ *		Horizontal scrolling to allow strings longer than widget size allows 
+ *		Pre-validation (limit which keys can be used)
+ *		Optional line history so previous entries can be recalled by CTRL UP/DOWN
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FILTEREDITOR_H
+#define LL_FILTEREDITOR_H
+
+#include "lllineeditor.h"
+#include "llbutton.h"
+
+class LLFilterEditor : public LLUICtrl
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLLineEditor::Params>
+	{
+		Optional<LLButton::Params> clear_filter_button;
+
+		Params()
+		: clear_filter_button("clear_filter_button")
+		{
+			name = "filter_editor";
+		}
+	};
+
+protected:
+	LLFilterEditor(const Params&);
+	friend class LLUICtrlFactory;
+public:
+	virtual ~LLFilterEditor() {}
+
+	/*virtual*/ void	draw();
+
+	void setText(const LLStringExplicit &new_text) { mFilterEditor->setText(new_text); }
+
+	// LLUICtrl interface
+	virtual void	setValue(const LLSD& value );
+	virtual LLSD	getValue() const;
+	virtual BOOL	setTextArg( const std::string& key, const LLStringExplicit& text );
+	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
+	virtual void	clear();
+
+private:
+	void onClearFilter(const LLSD& data);
+
+	LLLineEditor* mFilterEditor;
+	LLButton* mClearFilterButton;
+};
+
+#endif  // LL_FILTEREDITOR_H
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 153e025385bf2acc4c5613fad207a4279f4ccbac..a397278a2bb9993941f8d4776d99fd3eb7591973 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -71,15 +71,8 @@ std::string	LLFloater::sButtonActiveImageNames[BUTTON_COUNT] =
 	"minimize.tga",	//BUTTON_MINIMIZE
 	"tearoffbox.tga",	//BUTTON_TEAR_OFF
 	"closebox.tga",		//BUTTON_EDIT
-};
-
-std::string	LLFloater::sButtonInactiveImageNames[BUTTON_COUNT] = 
-{
-	"close_inactive_blue.tga",	//BUTTON_CLOSE
-	"restore_inactive.tga",	//BUTTON_RESTORE
-	"minimize_inactive.tga",	//BUTTON_MINIMIZE
-	"tearoffbox.tga",	//BUTTON_TEAR_OFF
-	"close_inactive_blue.tga",	//BUTTON_EDIT
+	"Icon_Dock_Foreground",
+	"Icon_Undock_Foreground"
 };
 
 std::string	LLFloater::sButtonPressedImageNames[BUTTON_COUNT] = 
@@ -89,6 +82,8 @@ std::string	LLFloater::sButtonPressedImageNames[BUTTON_COUNT] =
 	"minimize_pressed.tga",	//BUTTON_MINIMIZE
 	"tearoff_pressed.tga",	//BUTTON_TEAR_OFF
 	"close_in_blue.tga",		//BUTTON_EDIT
+	"Icon_Dock_Press",
+	"Icon_Undock_Press"
 };
 
 std::string	LLFloater::sButtonNames[BUTTON_COUNT] = 
@@ -98,6 +93,8 @@ std::string	LLFloater::sButtonNames[BUTTON_COUNT] =
 	"llfloater_minimize_btn",	//BUTTON_MINIMIZE
 	"llfloater_tear_off_btn",	//BUTTON_TEAR_OFF
 	"llfloater_edit_btn",		//BUTTON_EDIT
+	"llfloater_dock_btn",
+	"llfloater_undock_btn"
 };
 
 std::string LLFloater::sButtonToolTips[BUTTON_COUNT] = {};
@@ -114,6 +111,8 @@ std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]=
 	"BUTTON_MINIMIZE",//LLTrans::getString("BUTTON_MINIMIZE"),	//"Minimize",	//BUTTON_MINIMIZE
 	"BUTTON_TEAR_OFF",//LLTrans::getString("BUTTON_TEAR_OFF"),	//"Tear Off",	//BUTTON_TEAR_OFF
 	"BUTTON_EDIT", //LLTrans::getString("BUTTON_EDIT"), //	"Edit",		//BUTTON_EDIT
+	"BUTTON_DOCK",
+	"BUTTON_UNDOCK"
 };
 
 LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
@@ -123,6 +122,8 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
 	LLFloater::onClickMinimize, //BUTTON_MINIMIZE
 	LLFloater::onClickTearOff,	//BUTTON_TEAR_OFF
 	LLFloater::onClickEdit,	//BUTTON_EDIT
+	LLFloater::onClickDock,
+	LLFloater::onClickDock
 };
 
 LLMultiFloater* LLFloater::sHostp = NULL;
@@ -189,6 +190,29 @@ bool LLFloater::KeyCompare::equate(const LLSD& a, const LLSD& b)
 
 //************************************
 
+LLFloater::Params::Params()
+:	title("title"),
+	short_title("short_title"),
+	single_instance("single_instance", false),
+	auto_tile("auto_tile", false),
+	can_resize("can_resize", false),
+	can_minimize("can_minimize", true),
+	can_close("can_close", true),
+	can_drag_on_left("can_drag_on_left", false),
+	can_tear_off("can_tear_off", true),
+	save_rect("save_rect", false),
+	save_visibility("save_visibility", false),
+	open_callback("open_callback"),
+	close_callback("close_callback"),
+	can_dock("can_dock", false)
+{
+	name = "floater";
+	// defaults that differ from LLPanel:
+	background_visible = true;
+	visible = false;
+}
+
+
 //static 
 const LLFloater::Params& LLFloater::getDefaultParams()
 {
@@ -217,6 +241,8 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
 		mEditing(FALSE),
 		mButtonScale(1.0f),
 		mAutoFocus(TRUE), // automatically take focus when opened
+		mCanDock(false),
+		mDocked(false),
 		mHasBeenDraggedWhileMinimized(FALSE),
 		mPreviousMinimizedBottom(0),
 		mPreviousMinimizedLeft(0),
@@ -289,6 +315,11 @@ void LLFloater::initFloater()
 		mButtonsEnabled[BUTTON_MINIMIZE] = TRUE;
 	}
 
+	if(mCanDock)
+	{
+		mButtonsEnabled[BUTTON_DOCK] = TRUE;
+	}
+
 	buildButtons();
 
 	// Floaters are created in the invisible state	
@@ -1305,6 +1336,36 @@ void LLFloater::setFrontmost(BOOL take_focus)
 	}
 }
 
+void LLFloater::setCanDock(bool b)
+{
+	if(b != mCanDock)
+	{
+		mCanDock = b;
+		if(mCanDock)
+		{
+			mButtonsEnabled[BUTTON_DOCK] = !mDocked;
+			mButtonsEnabled[BUTTON_UNDOCK] = mDocked;
+		}
+		else
+		{
+			mButtonsEnabled[BUTTON_DOCK] = FALSE;
+			mButtonsEnabled[BUTTON_UNDOCK] = FALSE;
+		}
+	}
+	updateButtons();
+}
+
+void LLFloater::setDocked(bool docked, bool pop_on_undock)
+{
+	if(docked != mDocked && mCanDock)
+	{
+		mDocked = docked;
+		mButtonsEnabled[BUTTON_DOCK] = !mDocked;
+		mButtonsEnabled[BUTTON_UNDOCK] = mDocked;
+		updateButtons();
+	}
+}
+
 //static
 void LLFloater::setEditModeEnabled(BOOL enable)
 {
@@ -1381,6 +1442,15 @@ void LLFloater::onClickEdit(LLFloater* self)
 	self->mEditing = self->mEditing ? FALSE : TRUE;
 }
 
+// static
+void LLFloater::onClickDock(LLFloater* self)
+{
+	if(self && self->mCanDock)
+	{
+		self->setDocked(!self->mDocked, true);
+	}
+}
+
 // static 
 LLFloater* LLFloater::getClosableFloaterFromFocus()
 {
@@ -2522,6 +2592,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
 	setCanTearOff(p.can_tear_off);
 	setCanMinimize(p.can_minimize);
 	setCanClose(p.can_close);
+	setCanDock(p.can_dock);
 	
 	mDragOnLeft = p.can_drag_on_left;
 	mResizable = p.can_resize;
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index b1d33f48e9dec8e4b9005af9693fee46be38063f..f6c6dcf27722766fb27dffaf44a5577a6c09dfc0 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -102,6 +102,8 @@ friend class LLMultiFloater;
 		BUTTON_MINIMIZE,
 		BUTTON_TEAR_OFF,
 		BUTTON_EDIT,
+		BUTTON_DOCK,
+		BUTTON_UNDOCK,
 		BUTTON_COUNT
 	};
 	
@@ -120,7 +122,7 @@ friend class LLMultiFloater;
 	{
 		Optional<close_callback_t> function;
 	};
-	 	
+
 	struct Params 
 	:	public LLInitParam::Block<Params, LLPanel::Params>
 	{
@@ -135,31 +137,13 @@ friend class LLMultiFloater;
 								can_drag_on_left,
 								can_tear_off,
 								save_rect,
-								save_visibility;
+								save_visibility,
+								can_dock;
 		
 		Optional<OpenCallbackParam> open_callback;
 		Optional<CloseCallbackParam> close_callback;
 		
-		Params() :
-			title("title"),
-			short_title("short_title"),
-			single_instance("single_instance", false),
-			auto_tile("auto_tile", false),
-			can_resize("can_resize", false),
-			can_minimize("can_minimize", true),
-			can_close("can_close", true),
-			can_drag_on_left("can_drag_on_left", false),
-			can_tear_off("can_tear_off", true),
-			save_rect("save_rect", false),
-			save_visibility("save_visibility", false),
-		    open_callback("open_callback"),
-			close_callback("close_callback")
-		{
-			name = "floater";
-			// defaults that differ from LLPanel:
-			background_visible = true;
-			visible = false;
-		}
+		Params();
 	};
 	
 	// use this to avoid creating your own default LLFloater::Param instance
@@ -267,6 +251,12 @@ friend class LLMultiFloater;
 	const LLSD& 	getKey() { return mKey; }
 	BOOL		 	matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); }
 
+	bool            isDockable() const { return mCanDock; }
+	void            setCanDock(bool b);
+
+	bool            isDocked() const { return mDocked; }
+	virtual void    setDocked(bool docked, bool pop_on_undock = true);
+
 	// Return a closeable floater, if any, given the current focus.
 	static LLFloater* getClosableFloaterFromFocus(); 
 
@@ -283,6 +273,7 @@ friend class LLMultiFloater;
 	static void		onClickMinimize(LLFloater* floater);
 	static void		onClickTearOff(LLFloater* floater);
 	static void		onClickEdit(LLFloater* floater);
+	static void     onClickDock(LLFloater* floater);
 
 	static void		setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }
 	static void		setEditModeEnabled(BOOL enable);
@@ -378,11 +369,13 @@ friend class LLMultiFloater;
 	LLHandle<LLFloater> mHostHandle;
 	LLHandle<LLFloater> mLastHostHandle;
 
+	bool            mCanDock;
+	bool            mDocked;
+
 	static LLMultiFloater* sHostp;
 	static BOOL		sEditModeEnabled;
 	static BOOL		sQuitting;
 	static std::string	sButtonActiveImageNames[BUTTON_COUNT];
-	static std::string	sButtonInactiveImageNames[BUTTON_COUNT];
 	static std::string	sButtonPressedImageNames[BUTTON_COUNT];
 	static std::string	sButtonNames[BUTTON_COUNT];
 	static std::string	sButtonToolTips[BUTTON_COUNT];
diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h
new file mode 100644
index 0000000000000000000000000000000000000000..10a7fd454420e273081850dc558658747123da53
--- /dev/null
+++ b/indra/llui/llhandle.h
@@ -0,0 +1,171 @@
+/** 
+* @file llhandle.h
+* @brief "Handle" to an object (usually a floater) whose lifetime you don't
+* control.
+*
+* $LicenseInfo:firstyear=2001&license=viewergpl$
+* 
+* Copyright (c) 2001-2009, Linden Research, Inc.
+* 
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab.  Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+* 
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+* 
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+* 
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+#ifndef LLHANDLE_H
+#define LLHANDLE_H
+
+#include "llpointer.h"
+
+template <typename T>
+class LLTombStone : public LLRefCount
+{
+public:
+	LLTombStone(T* target = NULL) : mTarget(target) {}
+
+	void setTarget(T* target) { mTarget = target; }
+	T* getTarget() const { return mTarget; }
+private:
+	T* mTarget;
+};
+
+//	LLHandles are used to refer to objects whose lifetime you do not control or influence.  
+//	Calling get() on a handle will return a pointer to the referenced object or NULL, 
+//	if the object no longer exists.  Note that during the lifetime of the returned pointer, 
+//	you are assuming that the object will not be deleted by any action you perform, 
+//	or any other thread, as normal when using pointers, so avoid using that pointer outside of
+//	the local code block.
+// 
+//  https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
+
+template <typename T>
+class LLHandle
+{
+public:
+	LLHandle() : mTombStone(sDefaultTombStone) {}
+	const LLHandle<T>& operator =(const LLHandle<T>& other)  
+	{ 
+		mTombStone = other.mTombStone;
+		return *this; 
+	}
+
+	bool isDead() const 
+	{ 
+		return mTombStone->getTarget() == NULL; 
+	}
+
+	void markDead() 
+	{ 
+		mTombStone = sDefaultTombStone; 
+	}
+
+	T* get() const
+	{
+		return mTombStone->getTarget();
+	}
+
+	friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+	{
+		return lhs.mTombStone == rhs.mTombStone;
+	}
+	friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+	{
+		return !(lhs == rhs);
+	}
+	friend bool	operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+	{
+		return lhs.mTombStone < rhs.mTombStone;
+	}
+	friend bool	operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+	{
+		return lhs.mTombStone > rhs.mTombStone;
+	}
+protected:
+
+protected:
+	LLPointer<LLTombStone<T> > mTombStone;
+
+private:
+	static LLPointer<LLTombStone<T> > sDefaultTombStone;
+};
+
+// initialize static "empty" tombstone pointer
+template <typename T> LLPointer<LLTombStone<T> > LLHandle<T>::sDefaultTombStone = new LLTombStone<T>();
+
+
+template <typename T>
+class LLRootHandle : public LLHandle<T>
+{
+public:
+	LLRootHandle(T* object) { bind(object); }
+	LLRootHandle() {};
+	~LLRootHandle() { unbind(); }
+
+	// this is redundant, since a LLRootHandle *is* an LLHandle
+	LLHandle<T> getHandle() { return LLHandle<T>(*this); }
+
+	void bind(T* object) 
+	{ 
+		// unbind existing tombstone
+		if (LLHandle<T>::mTombStone.notNull())
+		{
+			if (LLHandle<T>::mTombStone->getTarget() == object) return;
+			LLHandle<T>::mTombStone->setTarget(NULL);
+		}
+		// tombstone reference counted, so no paired delete
+		LLHandle<T>::mTombStone = new LLTombStone<T>(object);
+	}
+
+	void unbind() 
+	{
+		LLHandle<T>::mTombStone->setTarget(NULL);
+	}
+
+	//don't allow copying of root handles, since there should only be one
+private:
+	LLRootHandle(const LLRootHandle& other) {};
+};
+
+// Use this as a mixin for simple classes that need handles and when you don't
+// want handles at multiple points of the inheritance hierarchy
+template <typename T>
+class LLHandleProvider
+{
+protected:
+	typedef LLHandle<T> handle_type_t;
+	LLHandleProvider() 
+	{
+		// provided here to enforce T deriving from LLHandleProvider<T>
+	} 
+
+	LLHandle<T> getHandle() 
+	{ 
+		// perform lazy binding to avoid small tombstone allocations for handle
+		// providers whose handles are never referenced
+		mHandle.bind(static_cast<T*>(this)); 
+		return mHandle; 
+	}
+
+private:
+	LLRootHandle<T> mHandle;
+};
+
+#endif
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index f1e7d791d434133030c05a7039a30eb0ba706eca..702d8e4a39c5d742ab6847d6f33a9c2423bc8971 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -120,7 +120,8 @@ struct LLLayoutStack::LayoutPanel
 
 LLLayoutStack::Params::Params()
 :	orientation("orientation", std::string("vertical")),
-	animate("animate", TRUE),
+	animate("animate", true),
+	clip("clip", true),
 	border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0))
 {
 	name="stack";
@@ -132,7 +133,8 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)
 	mMinHeight(0),
 	mPanelSpacing(p.border_size),
 	mOrientation((p.orientation() == "vertical") ? VERTICAL : HORIZONTAL),
-	mAnimate(p.animate)
+	mAnimate(p.animate),
+	mClip(p.clip)
 {}
 
 LLLayoutStack::~LLLayoutStack()
@@ -163,7 +165,7 @@ void LLLayoutStack::draw()
 
 		LLPanel* panelp = (*panel_it)->mPanel;
 
-		LLLocalClipRect clip(clip_rect);
+		LLLocalClipRect clip(clip_rect, mClip);
 		// only force drawing invisible children if visible amount is non-zero
 		drawChild(panelp, 0, 0, !clip_rect.isNull());
 	}
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index 480bdb5c17be7d69a805f6d0367a92a70887dcdb..9459b9990cdd99fc3b00622f69d0e48a7342ce0c 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -43,7 +43,8 @@ class LLLayoutStack : public LLView
 	{
 		Optional<std::string>	orientation;
 		Optional<S32>			border_size;
-		Optional<bool>	animate;
+		Optional<bool>			animate;
+		Optional<bool>			clip;
 		// mMinWidth and mMinHeight are calculated, not set in XML
 
 		Params();
@@ -100,6 +101,7 @@ class LLLayoutStack : public LLView
 	S32 mPanelSpacing;
 
 	bool mAnimate;
+	bool mClip;
 }; // end class LLLayoutStack
 
 #endif
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 43c22cbf5d722fc1315e05865a5d2d6f6c9e3186..f94eb7fcc3cae9ffb800375c8b71ed78f3b56107 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -91,7 +91,11 @@ void LLLineEditor::PrevalidateNamedFuncs::declareValues()
 
 LLLineEditor::Params::Params()
 :	max_length_bytes("max_length", 254),
+    keystroke_callback("keystroke_callback"),
+	prevalidate_callback("prevalidate_callback"),
 	background_image("background_image"),
+	background_image_disabled("background_image_disabled"),
+	background_image_focused("background_image_focused"),
 	select_on_focus("select_on_focus", false),
 	handle_edit_keys_directly("handle_edit_keys_directly", false),
 	commit_on_focus_lost("commit_on_focus_lost", true),
@@ -100,9 +104,8 @@ LLLineEditor::Params::Params()
 	text_color("text_color"),
 	text_readonly_color("text_readonly_color"),
 	text_tentative_color("text_tentative_color"),
-	bg_readonly_color("bg_readonly_color"),
-	bg_writeable_color("bg_writeable_color"),
-	bg_focus_color("bg_focus_color"),
+	highlight_color("highlight_color"),
+	preedit_bg_color("preedit_bg_color"),
 	border(""),
 	is_unicode("is_unicode"),
 	drop_shadow_visible("drop_shadow_visible"),
@@ -145,18 +148,18 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 	mSelectAllonFocusReceived( p.select_on_focus ),
 	mPassDelete(FALSE),
 	mReadOnly(FALSE),
-	mImage( NULL ),
+	mBgImage( p.background_image ),
+	mBgImageDisabled( p.background_image_disabled ),
+	mBgImageFocused( p.background_image_focused ),
 	mReplaceNewlinesWithSpaces( TRUE ),
 	mLabel(p.label),
 	mCursorColor(p.cursor_color()),
 	mFgColor(p.text_color()),
 	mReadOnlyFgColor(p.text_readonly_color()),
 	mTentativeFgColor(p.text_tentative_color()),
-	mWriteableBgColor(p.bg_writeable_color()),
-	mReadOnlyBgColor(p.bg_readonly_color()),
-	mFocusBgColor(p.bg_focus_color()),
-	mGLFont(p.font),
-	mGLFontStyle(LLFontGL::getStyleFromString(p.font.style))
+	mHighlightColor(p.highlight_color()),
+	mPreeditBgColor(p.preedit_bg_color()),
+	mGLFont(p.font)
 {
 	llassert( mMaxLengthBytes > 0 );
 
@@ -183,11 +186,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 	mBorder = LLUICtrlFactory::create<LLViewBorder>(border_p);
 	addChild( mBorder );
 
-	if(p.background_image.isProvided())
-	{
-		mImage = p.background_image;
-	}
-
 	// clamp text padding to current editor size
 	updateTextPadding();
 	setCursor(mText.length());
@@ -237,6 +235,7 @@ void LLLineEditor::onFocusLost()
 	LLUICtrl::onFocusLost();
 }
 
+// virtual
 void LLLineEditor::onCommit()
 {
 	// put current line into the line history
@@ -247,6 +246,33 @@ void LLLineEditor::onCommit()
 	selectAll();
 }
 
+// Returns TRUE if user changed value at all
+// virtual
+BOOL LLLineEditor::isDirty() const
+{
+	return mText.getString() != mPrevText;
+}
+
+// Clear dirty state
+// virtual
+void LLLineEditor::resetDirty()
+{
+	mPrevText = mText.getString();
+}		
+
+// assumes UTF8 text
+// virtual
+void LLLineEditor::setValue(const LLSD& value )
+{
+	setText(value.asString());
+}
+
+//virtual
+LLSD LLLineEditor::getValue() const
+{
+	return LLSD(getText());
+}
+
 
 // line history support
 void LLLineEditor::updateHistory()
@@ -1497,6 +1523,33 @@ void LLLineEditor::doDelete()
 }
 
 
+void LLLineEditor::drawBackground()
+{
+	bool has_focus = hasFocus();
+	LLUIImage* image;
+	if ( mReadOnly )
+	{
+		image = mBgImageDisabled;
+	}
+	else if ( has_focus )
+	{
+		image = mBgImageFocused;
+	}
+	else
+	{
+		image = mBgImage;
+	}
+	
+	// optionally draw programmatic border
+	if (has_focus)
+	{
+		image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(),
+						  gFocusMgr.getFocusColor(),
+						  gFocusMgr.getFocusFlashWidth());
+	}
+	image->draw(getLocalRect());
+}
+
 void LLLineEditor::draw()
 {
 	S32 text_len = mText.length();
@@ -1527,34 +1580,8 @@ void LLLineEditor::draw()
 	LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 );
 	background.stretch( -mBorderThickness );
 
-	LLColor4 bg_color = mReadOnlyBgColor.get();
-
-#if 1 // for when we're ready for image art.
-	if( hasFocus())
-	{
-		mImage->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
-	}
-	mImage->draw(getLocalRect());
-#else // the old programmer art.
-	// drawing solids requires texturing be disabled
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		// draw background for text
-		if( !mReadOnly )
-		{
-			if( gFocusMgr.getKeyboardFocus() == this )
-			{
-				bg_color = mFocusBgColor.get();
-			}
-			else
-			{
-				bg_color = mWriteableBgColor.get();
-			}
-		}
-		gl_rect_2d(background, bg_color);
-	}
-#endif
-
+	drawBackground();
+	
 	// draw text
 
 	// With viewer-2 art files, input region is 2 pixels up
@@ -1600,7 +1627,8 @@ void LLLineEditor::draw()
 						background.mBottom + preedit_standout_position,
 						preedit_pixels_right - preedit_standout_gap - 1,
 						background.mBottom + preedit_standout_position - preedit_standout_thickness,
-						(text_color * preedit_standout_brightness + bg_color * (1 - preedit_standout_brightness)).setAlpha(1.0f));
+						(text_color * preedit_standout_brightness 
+						 + mPreeditBgColor * (1 - preedit_standout_brightness)).setAlpha(1.0f));
 				}
 				else
 				{
@@ -1608,7 +1636,8 @@ void LLLineEditor::draw()
 						background.mBottom + preedit_marker_position,
 						preedit_pixels_right - preedit_marker_gap - 1,
 						background.mBottom + preedit_marker_position - preedit_marker_thickness,
-						(text_color * preedit_marker_brightness + bg_color * (1 - preedit_marker_brightness)).setAlpha(1.0f));
+						(text_color * preedit_marker_brightness
+						 + mPreeditBgColor * (1 - preedit_marker_brightness)).setAlpha(1.0f));
 				}
 			}
 		}
@@ -1641,7 +1670,7 @@ void LLLineEditor::draw()
 				rendered_pixels_right, text_bottom,
 				text_color,
 				LLFontGL::LEFT, LLFontGL::BOTTOM,
-				mGLFontStyle,
+				0,
 				LLFontGL::NO_SHADOW,
 				select_left - mScrollHPos,
 				mMaxHPixels - llround(rendered_pixels_right),
@@ -1650,7 +1679,7 @@ void LLLineEditor::draw()
 		
 		if( (rendered_pixels_right < (F32)mMaxHPixels) && (rendered_text < text_len) )
 		{
-			LLColor4 color(1.f - bg_color.mV[0], 1.f - bg_color.mV[1], 1.f - bg_color.mV[2], 1.f);
+			LLColor4 color = mHighlightColor;
 			// selected middle
 			S32 width = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos + rendered_text, select_right - mScrollHPos - rendered_text);
 			width = llmin(width, mMaxHPixels - llround(rendered_pixels_right));
@@ -1661,7 +1690,7 @@ void LLLineEditor::draw()
 				rendered_pixels_right, text_bottom,
 				LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ),
 				LLFontGL::LEFT, LLFontGL::BOTTOM,
-				mGLFontStyle,
+				0,
 				LLFontGL::NO_SHADOW,
 				select_right - mScrollHPos - rendered_text,
 				mMaxHPixels - llround(rendered_pixels_right),
@@ -1676,7 +1705,7 @@ void LLLineEditor::draw()
 				rendered_pixels_right, text_bottom,
 				text_color,
 				LLFontGL::LEFT, LLFontGL::BOTTOM,
-				mGLFontStyle,
+				0,
 				LLFontGL::NO_SHADOW,
 				S32_MAX,
 				mMaxHPixels - llround(rendered_pixels_right),
@@ -1690,7 +1719,7 @@ void LLLineEditor::draw()
 			rendered_pixels_right, text_bottom,
 			text_color,
 			LLFontGL::LEFT, LLFontGL::BOTTOM,
-			mGLFontStyle,
+			0,
 			LLFontGL::NO_SHADOW,
 			S32_MAX,
 			mMaxHPixels - llround(rendered_pixels_right),
@@ -1728,7 +1757,7 @@ void LLLineEditor::draw()
 					mGLFont->render(mText, getCursor(), (F32)(cursor_left + lineeditor_cursor_thickness / 2), text_bottom, 
 						LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ),
 						LLFontGL::LEFT, LLFontGL::BOTTOM,
-						mGLFontStyle,
+						0,
 						LLFontGL::NO_SHADOW,
 						1);
 				}
@@ -1754,7 +1783,7 @@ void LLLineEditor::draw()
 							label_color,
 							LLFontGL::LEFT,
 							LLFontGL::BOTTOM,
-							mGLFontStyle,
+							0,
 							LLFontGL::NO_SHADOW,
 							S32_MAX,
 							mMaxHPixels - llround(rendered_pixels_right),
@@ -1779,7 +1808,7 @@ void LLLineEditor::draw()
 							label_color,
 							LLFontGL::LEFT,
 							LLFontGL::BOTTOM,
-							mGLFontStyle,
+							0,
 							LLFontGL::NO_SHADOW,
 							S32_MAX,
 							mMaxHPixels - llround(rendered_pixels_right),
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 4362cff2fecda0754a779aaa1e51650bae6c3904..0986ce5a870404b9b12ee2ccb621cd06806da8be 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -84,7 +84,9 @@ class LLLineEditor
 		
 		Optional<LLViewBorder::Params>	border;
 
-		Optional<LLUIImage*>			background_image;
+		Optional<LLUIImage*>			background_image,
+										background_image_disabled,
+										background_image_focused;
 
 		Optional<bool>					select_on_focus,
 										handle_edit_keys_directly,
@@ -96,10 +98,9 @@ class LLLineEditor
 										text_color,
 										text_readonly_color,
 										text_tentative_color,
-										bg_readonly_color,
-										bg_writeable_color,
-										bg_focus_color;
-
+										highlight_color,
+										preedit_bg_color;
+		
 		Optional<S32>					text_pad_left,
 										text_pad_right;
 
@@ -107,7 +108,7 @@ class LLLineEditor
 										drop_shadow_visible,	
 										border_drop_shadow_visible,
 										bg_visible;
-
+		
 		Params();
 	};
 protected:
@@ -163,12 +164,12 @@ class LLLineEditor
 	virtual void 	setRect(const LLRect& rect);
 	virtual BOOL	acceptsTextInput() const;
 	virtual void	onCommit();
-	virtual BOOL	isDirty() const { return mText.getString() != mPrevText; }	// Returns TRUE if user changed value at all
-	virtual void	resetDirty() { mPrevText = mText.getString(); }		// Clear dirty state
+	virtual BOOL	isDirty() const;	// Returns TRUE if user changed value at all
+	virtual void	resetDirty();		// Clear dirty state
 
 	// assumes UTF8 text
-	virtual void	setValue(const LLSD& value ) { setText(value.asString()); }
-	virtual LLSD	getValue() const { return LLSD(getText()); }
+	virtual void	setValue(const LLSD& value );
+	virtual LLSD	getValue() const;
 	virtual BOOL	setTextArg( const std::string& key, const LLStringExplicit& text );
 	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
 
@@ -197,16 +198,10 @@ class LLLineEditor
 	void setFgColor( const LLColor4& c )			{ mFgColor = c; }
 	void setReadOnlyFgColor( const LLColor4& c )	{ mReadOnlyFgColor = c; }
 	void setTentativeFgColor(const LLColor4& c)		{ mTentativeFgColor = c; }
-	void setWriteableBgColor( const LLColor4& c )	{ mWriteableBgColor = c; }
-	void setReadOnlyBgColor( const LLColor4& c )	{ mReadOnlyBgColor = c; }
-	void setFocusBgColor(const LLColor4& c)			{ mFocusBgColor = c; }
 
 	const LLColor4& getFgColor() const			{ return mFgColor.get(); }
 	const LLColor4& getReadOnlyFgColor() const	{ return mReadOnlyFgColor.get(); }
 	const LLColor4& getTentativeFgColor() const { return mTentativeFgColor.get(); }
-	const LLColor4& getWriteableBgColor() const	{ return mWriteableBgColor.get(); }
-	const LLColor4& getReadOnlyBgColor() const	{ return mReadOnlyBgColor.get(); }
-	const LLColor4& getFocusBgColor() const		{ return mFocusBgColor.get(); }
 
 	void			setIgnoreArrowKeys(BOOL b)		{ mIgnoreArrowKeys = b; }
 	void			setIgnoreTab(BOOL b)			{ mIgnoreTab = b; }
@@ -266,6 +261,9 @@ class LLLineEditor
 	BOOL			handleControlKey(KEY key, MASK mask);
 	S32				handleCommitKey(KEY key, MASK mask);
 	void			updateTextPadding();
+	
+	// Draw the background image depending on enabled/focused state.
+	void			drawBackground();
 
 	//
 	// private data members
@@ -294,7 +292,6 @@ class LLLineEditor
 
 	LLViewBorder* mBorder;
 	const LLFontGL*	mGLFont;
-	U8          mGLFontStyle;
 	S32			mMaxLengthBytes;			// Max length of the UTF8 string in bytes
 	S32			mCursorPos;					// I-beam is just after the mCursorPos-th character.
 	S32			mScrollHPos;				// Horizontal offset from the start of mText.  Used for scrolling.
@@ -326,9 +323,8 @@ class LLLineEditor
 	LLUIColor	mFgColor;
 	LLUIColor	mReadOnlyFgColor;
 	LLUIColor	mTentativeFgColor;
-	LLUIColor	mWriteableBgColor;
-	LLUIColor	mReadOnlyBgColor;
-	LLUIColor	mFocusBgColor;
+	LLUIColor	mHighlightColor;		// background for selected text
+	LLUIColor	mPreeditBgColor;		// preedit marker background color
 
 	S32			mBorderThickness;
 
@@ -349,7 +345,9 @@ class LLLineEditor
 
 private:
 	// Instances that by default point to the statics but can be overidden in XML.
-	LLPointer<LLUIImage> mImage;
+	LLPointer<LLUIImage> mBgImage;
+	LLPointer<LLUIImage> mBgImageDisabled;
+	LLPointer<LLUIImage> mBgImageFocused;
 
 	BOOL        mReplaceNewlinesWithSpaces; // if false, will replace pasted newlines with paragraph symbol.
 
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index ade88d27148f6b58b1c20b9773f0c24eea80ae46..fdb4bdd5c1ed909585d773132ff4d55e803c634a 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -49,12 +49,12 @@
 #include "llmath.h"
 #include "llrender.h"
 #include "llfocusmgr.h"
-#include "llfont.h"
 #include "llcoord.h"
 #include "llwindow.h"
 #include "llcriticaldamp.h"
 #include "lluictrlfactory.h"
 
+#include "llbutton.h"
 #include "llfontgl.h"
 #include "llresmgr.h"
 #include "llui.h"
@@ -1453,6 +1453,7 @@ void LLMenuItemBranchDownGL::draw( void )
 	setHover(FALSE);
 }
 
+
 class LLMenuScrollItem : public LLMenuItemCallGL
 {
 public:
@@ -1461,10 +1462,18 @@ class LLMenuScrollItem : public LLMenuItemCallGL
 		ARROW_DOWN,
 		ARROW_UP
 	};
+	struct ArrowTypes : public LLInitParam::TypeValuesHelper<EArrowType, ArrowTypes>
+	{
+		static void declareValues()
+		{
+			declare("up", ARROW_UP);
+			declare("down", ARROW_DOWN);
+		}
+	};
 
 	struct Params : public LLInitParam::Block<Params, LLMenuItemCallGL::Params>
 	{
-		Optional<EArrowType> arrow_type;
+		Optional<EArrowType, ArrowTypes> arrow_type;
 		Optional<CommitCallbackParam> scroll_callback;
 	};
 
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 7d5cc25e1e88068b234eef6f8190750b07a02cbc..262f75f1e106cc367f0c91c6b12a4dab93494850 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -380,6 +380,7 @@ class LLMenuGL
 
 		Params()
 		:	jump_key("jump_key", KEY_NONE),
+			horizontal_layout("horizontal_layout"),
 			can_tear_off("tear_off", false),
 			drop_shadow("drop_shadow", true),
 			bg_visible("bg_visible", true),
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 50fee41029437007732ea11a8931125553d93d5f..2b6ae1f67e7a9974ecf51189f38d7c7cc5842bc0 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -384,7 +384,7 @@ LLNotificationTemplate::LLNotificationTemplate() :
 }
 
 LLNotification::LLNotification(const LLNotification::Params& p) : 
-	mTimestamp(p.timestamp), 
+	mTimestamp(p.time_stamp), 
 	mSubstitutions(p.substitutions),
 	mPayload(p.payload),
 	mExpiresAt(0),
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 512886790cab1f42a9fa0045465e243b4df00853..63eae7278f4eb7a5e1ffe5436669cac6ff399f4a 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -294,7 +294,7 @@ friend class LLNotifications;
 		Optional<LLSD>							payload;
 		Optional<ENotificationPriority>			priority;
 		Optional<LLSD>							form_elements;
-		Optional<LLDate>						timestamp;
+		Optional<LLDate>						time_stamp;
 		Optional<LLNotificationContext*>		context;
 
 		struct Functor : public LLInitParam::Choice<Functor>
@@ -312,19 +312,23 @@ friend class LLNotifications;
 		Params()
 		:	name("name"),
 			priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
-			timestamp("time_stamp")
+			time_stamp("time_stamp"),
+			payload("payload"),
+			form_elements("form_elements")
 		{
-			timestamp = LLDate::now();
+			time_stamp = LLDate::now();
 		}
 
 		Params(const std::string& _name) 
-			:	name("name"),
-				priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
-				timestamp("time_stamp")
+		:	name("name"),
+			priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
+			time_stamp("time_stamp"),
+			payload("payload"),
+			form_elements("form_elements")
 		{
 			functor.name = _name;
 			name = _name;
-			timestamp = LLDate::now();
+			time_stamp = LLDate::now();
 		}
 	};
 
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 116096b7b33311bdfd697b9e90f88e5b35c96d28..9fb38bc31674c6e8fa0179a93c36a03d8c81dd28 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -43,6 +43,7 @@
 #include "llerror.h"
 #include "lltimer.h"
 
+#include "llbutton.h"
 #include "llmenugl.h"
 //#include "llstatusbar.h"
 #include "llui.h"
@@ -53,7 +54,6 @@
 #include "lluictrl.h"
 #include "lluictrlfactory.h"
 #include "llviewborder.h"
-#include "llbutton.h"
 #include "lltabcontainer.h"
 
 static LLDefaultChildRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML);
@@ -65,6 +65,7 @@ const LLPanel::Params& LLPanel::getDefaultParams()
 
 LLPanel::Params::Params()
 :	has_border("border", false),
+	border(""),
 	bg_opaque_color("bg_opaque_color"),
 	bg_alpha_color("bg_alpha_color"),
 	background_visible("background_visible", false),
@@ -430,7 +431,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
 		it != p.strings().end();
 		++it)
 	{
-		mUIStrings[it->name] = it->text;
+		mUIStrings[it->name] = it->value;
 	}
 
 	setLabel(p.label());
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 381cba2db38aeb70629260dcd5644785e1b8b707..4140e3aa93854a84e6faa7bac3eec956642a7285 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -37,8 +37,6 @@
 
 #include "llcallbackmap.h"
 #include "lluictrl.h"
-#include "llbutton.h"
-#include "lllineeditor.h"
 #include "llviewborder.h"
 #include "lluistring.h"
 #include "v4color.h"
@@ -49,6 +47,7 @@ const S32 LLPANEL_BORDER_WIDTH = 1;
 const BOOL BORDER_YES = TRUE;
 const BOOL BORDER_NO = FALSE;
 
+class LLButton;
 
 /*
  * General purpose concrete view base class.
@@ -62,11 +61,11 @@ class LLPanel : public LLUICtrl
 	struct LocalizedString : public LLInitParam::Block<LocalizedString>
 	{
 		Mandatory<std::string>	name;
-		Mandatory<std::string>	text;
+		Mandatory<std::string>	value;
 		
 		LocalizedString()
 		:	name("name"),
-			text("value")
+			value("value")
 		{}
 	};
 
diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp
index 7a34cc67929c27718c22bc07991a8ac7dabf6004..c8b6e814e13dfb4970fac5132d079d67bab57eb7 100644
--- a/indra/llui/llprogressbar.cpp
+++ b/indra/llui/llprogressbar.cpp
@@ -50,10 +50,7 @@ static LLDefaultChildRegistry::Register<LLProgressBar> r("progress_bar");
 LLProgressBar::Params::Params()
 :	image_bar("image_bar"),
 	image_fill("image_fill"),
-	image_shadow("image_shadow"),
 	color_bar("color_bar"),
-	color_bar2("color_bar2"),
-	color_shadow("color_shadow"),
 	color_bg("color_bg")
 {}
 
@@ -61,12 +58,9 @@ LLProgressBar::Params::Params()
 LLProgressBar::LLProgressBar(const LLProgressBar::Params& p) 
 :	LLView(p),
 	mImageBar(p.image_bar),
-	mImageShadow(p.image_shadow),
 	mImageFill(p.image_fill),
 	mColorBackground(p.color_bg()),
 	mColorBar(p.color_bar()),
-	mColorBar2(p.color_bar2()),
-	mColorShadow(p.color_shadow()),
 	mPercentDone(0.f)
 {}
 
@@ -85,10 +79,10 @@ void LLProgressBar::draw()
 
 	F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
 	LLColor4 bar_color = mColorBar.get();
-	bar_color.mV[3] = alpha;
+	bar_color.mV[VALPHA] *= alpha; // modulate alpha
 	LLRect progress_rect = getLocalRect();
 	progress_rect.mRight = llround(getRect().getWidth() * (mPercentDone / 100.f));
-	mImageFill->draw(progress_rect);
+	mImageFill->draw(progress_rect, bar_color);
 }
 
 void LLProgressBar::setPercent(const F32 percent)
diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h
index 5c2f73ef9e08319a88b23824391eae3e6c4cf2dd..b6a5b0400d09a6ae78117c9baea82cd96669505b 100644
--- a/indra/llui/llprogressbar.h
+++ b/indra/llui/llprogressbar.h
@@ -43,12 +43,9 @@ class LLProgressBar
 	struct Params : public LLInitParam::Block<Params, LLView::Params>
 	{
 		Optional<LLUIImage*>	image_bar,
-								image_fill,
-								image_shadow;
+								image_fill;
 
 		Optional<LLUIColor>		color_bar,
-								color_bar2,
-								color_shadow,
 								color_bg;
 
 		Params();
@@ -65,10 +62,7 @@ class LLProgressBar
 
 	LLPointer<LLUIImage>	mImageBar;
 	LLUIColor	mColorBar;
-	LLUIColor	mColorBar2;
 
-	LLPointer<LLUIImage>	mImageShadow;
-	LLUIColor    mColorShadow;
 	LLUIColor    mColorBackground;
 	
 	LLPointer<LLUIImage>	mImageFill;
diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp
index 90f51b9919da304a2b04107c39db7dc8cded4d61..7449c339a0dfacdd5deed2ab1d2c0dfa4295a325 100644
--- a/indra/llui/llresizehandle.cpp
+++ b/indra/llui/llresizehandle.cpp
@@ -45,7 +45,9 @@
 const S32 RESIZE_BORDER_WIDTH = 3;
 
 LLResizeHandle::Params::Params()
-:	corner("corner")
+:	corner("corner"),
+	min_width("min_width"),
+	min_height("min_height")
 {
 	name = "resize_handle";
 }
diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cf23e3af15a6bd28ccb06de929271b1a141cf2b0
--- /dev/null
+++ b/indra/llui/llrngwriter.cpp
@@ -0,0 +1,315 @@
+/** 
+ * @file llrngwriter.cpp
+ * @brief Generates Relax NG schema from param blocks
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ * 
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llrngwriter.h"
+#include "lluicolor.h"
+#include "lluictrlfactory.h"
+
+//
+// LLRNGWriter - writes Relax NG schema files based on a param block
+//
+LLRNGWriter::LLRNGWriter()
+{
+	// register various callbacks for inspecting the contents of a param block
+	registerInspectFunc<bool>(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4));
+	registerInspectFunc<std::string>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+	registerInspectFunc<U8>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedByte", _1, _2, _3, _4));
+	registerInspectFunc<S8>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedByte", _1, _2, _3, _4));
+	registerInspectFunc<U16>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedShort", _1, _2, _3, _4));
+	registerInspectFunc<S16>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedShort", _1, _2, _3, _4));
+	registerInspectFunc<U32>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedInt", _1, _2, _3, _4));
+	registerInspectFunc<S32>(boost::bind(&LLRNGWriter::writeAttribute, this, "integer", _1, _2, _3, _4));
+	registerInspectFunc<F32>(boost::bind(&LLRNGWriter::writeAttribute, this, "float", _1, _2, _3, _4));
+	registerInspectFunc<F64>(boost::bind(&LLRNGWriter::writeAttribute, this, "double", _1, _2, _3, _4));
+	registerInspectFunc<LLColor4>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+	registerInspectFunc<LLUIColor>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+	registerInspectFunc<LLUUID>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+	registerInspectFunc<LLSD>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+}
+
+void LLRNGWriter::writeRNG(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace)
+{
+	mGrammarNode = node;
+	mGrammarNode->setName("grammar");
+	mGrammarNode->createChild("xmlns", true)->setStringValue("http://relaxng.org/ns/structure/1.0");
+	mGrammarNode->createChild("datatypeLibrary", true)->setStringValue("http://www.w3.org/2001/XMLSchema-datatypes");
+	mGrammarNode->createChild("ns", true)->setStringValue(xml_namespace);
+
+	node = mGrammarNode->createChild("start", false);
+	node = node->createChild("ref", false);
+	node->createChild("name", true)->setStringValue(type_name);
+
+	addDefinition(type_name, block);
+}
+
+void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block)
+{
+	if (mDefinedElements.find(type_name) != mDefinedElements.end()) return;
+	mDefinedElements.insert(type_name);
+
+	LLXMLNodePtr node = mGrammarNode->createChild("define", false);
+	node->createChild("name", true)->setStringValue(type_name);
+
+	mElementNode = node->createChild("element", false);
+	mElementNode->createChild("name", true)->setStringValue(type_name);
+	mChildrenNode = mElementNode->createChild("zeroOrMore", false)->createChild("choice", false);
+
+	mAttributesWritten.first = mElementNode;
+	mAttributesWritten.second.clear();
+	mElementsWritten.clear();
+
+	block.inspectBlock(*this);
+
+	// add includes for all possible children
+	const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name);
+	const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type);
+	
+	// add include declarations for all valid children
+	for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
+		it != widget_registryp->currentRegistrar().endItems();
+		++it)
+	{
+		std::string child_name = it->first;
+		if (child_name == type_name)
+		{
+			continue;
+		}
+		
+		LLXMLNodePtr old_element_node = mElementNode;
+		LLXMLNodePtr old_child_node = mChildrenNode;
+		addDefinition(child_name, (*LLDefaultParamBlockRegistry::instance().getValue(type))());
+		mElementNode = old_element_node;
+		mChildrenNode = old_child_node;
+
+		mChildrenNode->createChild("ref", false)->createChild("name", true)->setStringValue(child_name);
+	}
+
+	if (mChildrenNode->mChildren.isNull())
+	{
+		// remove unused children node
+		mChildrenNode->mParent->mParent->deleteChild(mChildrenNode->mParent);
+	}
+}
+
+void LLRNGWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values)
+{
+	if (max_count == 0) return;
+
+	name_stack_t non_empty_names;
+	std::string attribute_name;
+	for (name_stack_t::const_iterator it = stack.begin();
+		it != stack.end();
+		++it)
+	{
+		const std::string& name = it->first;
+		if (!name.empty())
+		{
+			non_empty_names.push_back(*it);
+		}
+	}
+
+	if (non_empty_names.empty()) return;
+
+	for (name_stack_t::const_iterator it = non_empty_names.begin();
+		it != non_empty_names.end();
+		++it)
+	{
+		if (!attribute_name.empty())
+		{
+			attribute_name += ".";
+		}
+		attribute_name += it->first;
+	}
+
+	// singular attribute, e.g. <foo bar="1"/>
+	if (non_empty_names.size() == 1 && max_count == 1)
+	{
+		if (mAttributesWritten.second.find(attribute_name) == mAttributesWritten.second.end())
+		{
+			LLXMLNodePtr node = createCardinalityNode(mElementNode, min_count, max_count)->createChild("attribute", false);
+			node->createChild("name", true)->setStringValue(attribute_name);
+			node->createChild("data", false)->createChild("type", true)->setStringValue(type);
+
+			mAttributesWritten.second.insert(attribute_name);
+		}
+	}
+	// compound attribute
+	else
+	{
+		std::string element_name;
+
+		// traverse all but last element, leaving that as an attribute name
+		name_stack_t::const_iterator end_it = non_empty_names.end();
+		end_it--;
+
+		for (name_stack_t::const_iterator it = non_empty_names.begin();
+			it != end_it;
+			++it)
+		{
+			if (it != non_empty_names.begin())
+			{
+				element_name += ".";
+			}
+			element_name += it->first;
+		}
+
+		elements_map_t::iterator found_it = mElementsWritten.find(element_name);
+		// <choice>
+		//   <group>
+		//     <optional>
+		//	     <attribute name="foo.bar"><data type="string"/></attribute>
+		//     </optional>
+		//     <optional>
+		//       <attribute name="foo.baz"><data type="integer"/></attribute>
+		//     </optional>
+		//   </group>
+		//   <element name="foo">
+		//     <optional>
+		//       <attribute name="bar"><data type="string"/></attribute>
+		//     </optional>
+		//     <optional>
+		//       <attribute name="baz"><data type="string"/></attribute>
+		//     </optional>
+		//   </element>
+		//   <element name="outer.foo">
+		//     <ref name="foo"/>
+		//   </element>
+		// </choice>
+
+		if (found_it != mElementsWritten.end())
+		{
+			// reuse existing element
+			LLXMLNodePtr choice_node = found_it->second.first;
+
+			// attribute with this name not already written?
+			if (found_it->second.second.find(attribute_name) == found_it->second.second.end())
+			{
+				// append to <group>
+				LLXMLNodePtr node = choice_node->mChildren->head;
+				node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+				node->createChild("name", true)->setStringValue(attribute_name);
+				addTypeNode(node, type, possible_values);
+
+				// append to <element>
+				node = choice_node->mChildren->head->mNext->mChildren->head;
+				node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+				node->createChild("name", true)->setStringValue(non_empty_names.back().first);
+				addTypeNode(node, type, possible_values);
+
+				// append to <element>
+				//node = choice_node->mChildren->head->mNext->mNext->mChildren->head;
+				//node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+				//node->createChild("name", true)->setStringValue(non_empty_names.back().first);
+				//addTypeNode(node, type, possible_values);
+
+				found_it->second.second.insert(attribute_name);
+			}
+		}
+		else
+		{
+			LLXMLNodePtr choice_node = mElementNode->createChild("choice", false);
+
+			LLXMLNodePtr node = choice_node->createChild("group", false);
+			node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+			node->createChild("name", true)->setStringValue(attribute_name);
+			addTypeNode(node, type, possible_values);
+
+			node = choice_node->createChild("optional", false);
+			node = node->createChild("element", false);
+			node->createChild("name", true)->setStringValue(element_name);
+			node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+			node->createChild("name", true)->setStringValue(non_empty_names.back().first);
+			addTypeNode(node, type, possible_values);
+			
+			//node = choice_node->createChild("optional", false);
+			//node = node->createChild("element", false);
+			//node->createChild("name", true)->setStringValue(mDefinitionName + "." + element_name);
+			//node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+			//node->createChild("name", true)->setStringValue(non_empty_names.back().first);
+			//addTypeNode(node, type, possible_values);
+
+			attribute_data_t& attribute_data = mElementsWritten[element_name];
+			attribute_data.first = choice_node;
+			attribute_data.second.insert(attribute_name);
+		}
+	}
+}
+
+void LLRNGWriter::addTypeNode(LLXMLNodePtr parent_node, const std::string& type, const std::vector<std::string>* possible_values)
+{
+	if (possible_values)
+	{
+		LLXMLNodePtr enum_node = parent_node->createChild("choice", false);
+		for (std::vector<std::string>::const_iterator it = possible_values->begin();
+			it != possible_values->end();
+			++it)
+		{
+			enum_node->createChild("value", false)->setStringValue(*it);
+		}
+	}
+	else
+	{
+		parent_node->createChild("data", false)->createChild("type", true)->setStringValue(type);
+	}
+}
+
+LLXMLNodePtr LLRNGWriter::createCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count)
+{
+	// unlinked by default, meaning this attribute is forbidden
+	LLXMLNodePtr count_node = new LLXMLNode();
+	if (min_count == 0)
+	{
+		if (max_count == 1)
+		{
+			count_node = parent_node->createChild("optional", false);
+		}
+		else if (max_count > 1)
+		{
+			count_node = parent_node->createChild("zeroOrMore", false);
+		}	
+	}
+	else if (min_count >= 1)
+	{
+		if (max_count == 1 && min_count == 1)
+		{
+			// just add raw element, will count as 1 and only 1
+			count_node = parent_node;
+		}
+		else
+		{
+			count_node = parent_node->createChild("oneOrMore", false);
+		}
+	}
+	return count_node;
+}
diff --git a/indra/llui/llrngwriter.h b/indra/llui/llrngwriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..66807577b50e817baa72bd8e445ce88eb67f50fe
--- /dev/null
+++ b/indra/llui/llrngwriter.h
@@ -0,0 +1,69 @@
+/** 
+ * @file llrngwriter.h
+ * @brief Generates Relax NG schema files from a param block
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ * 
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLRNGWRITER_H
+#define LLRNGWRITER_H
+
+#include "llinitparam.h"
+#include "llxmlnode.h"
+
+class LLRNGWriter : public LLInitParam::Parser
+{
+	LOG_CLASS(LLRNGWriter);
+public:
+	void writeRNG(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace);
+	void addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block);
+
+	/*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; }
+
+	LLRNGWriter();
+
+private:
+	LLXMLNodePtr createCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count);
+	void addTypeNode(LLXMLNodePtr parent_node, const std::string& type, const std::vector<std::string>* possible_values);
+
+	void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values);
+	LLXMLNodePtr	mElementNode;
+	LLXMLNodePtr	mChildrenNode;
+	LLXMLNodePtr	mGrammarNode;
+	std::string		mDefinitionName;
+
+	typedef std::pair<LLXMLNodePtr, std::set<std::string> >  attribute_data_t;
+	typedef std::map<std::string, attribute_data_t> elements_map_t;
+	typedef std::set<std::string> defined_elements_t;
+
+	defined_elements_t	mDefinedElements;
+	attribute_data_t	mAttributesWritten;
+	elements_map_t		mElementsWritten;
+};
+
+#endif //LLRNGWRITER_H
diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index 4e6de24160dbea741d94d40a11b78785c921700e..cd43e194d299ebb436f8531c37f2d57289582f3d 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -177,7 +177,6 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
 	mFont(p.font),
 	mColor(p.color),
 	mUseColor(p.color.isProvided()),
-	mFontStyle(LLFontGL::NORMAL),
 	mFontAlignment(p.font_halign),
 	mVisible(p.visible),
 	mHighlightCount( 0 ),
@@ -240,6 +239,13 @@ void LLScrollListText::setText(const LLStringExplicit& text)
 	mText = text;
 }
 
+void LLScrollListText::setFontStyle(const U8 font_style)
+{
+	LLFontDescriptor new_desc(mFont->getFontDesc());
+	new_desc.setStyle(font_style);
+	mFont = LLFontGL::getFont(new_desc);
+}
+
 //virtual
 void LLScrollListText::setValue(const LLSD& text)
 {
@@ -308,7 +314,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
 						display_color,
 						mFontAlignment,
 						LLFontGL::BOTTOM, 
-						mFontStyle,
+						0,
 						LLFontGL::NO_SHADOW,
 						string_chars, 
 						getWidth(),
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index 2ab13f76188f45afe051c77d0c5ee5e29d90ceb6..9d3fa65f64859951fe2b19f54349ee1b51b44bc4 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -145,14 +145,13 @@ class LLScrollListText : public LLScrollListCell
 	/*virtual*/ BOOL	isText() const;
 
 	void			setText(const LLStringExplicit& text);
-	void			setFontStyle(const U8 font_style) { mFontStyle = font_style; }
+	void			setFontStyle(const U8 font_style);
 
 private:
 	LLUIString		mText;
 	const LLFontGL*	mFont;
 	LLColor4		mColor;
 	U8				mUseColor;
-	U8				mFontStyle;
 	LLFontGL::HAlign mFontAlignment;
 	BOOL			mVisible;
 	S32				mHighlightCount;
diff --git a/indra/llui/llscrolllistcolumn.h b/indra/llui/llscrolllistcolumn.h
index 712ea564548fdd8f8e5da0652462225a6a9d12b8..23318fd7c4e6792b1cf4ceda85bd52e815ef05db 100644
--- a/indra/llui/llscrolllistcolumn.h
+++ b/indra/llui/llscrolllistcolumn.h
@@ -121,7 +121,7 @@ class LLScrollListColumn
 			Alternative<F32>		relative_width;
 
 			Width()
-			:	dynamic_width("dynamicwidth", false),
+			:	dynamic_width("dynamic_width", false),
 				pixel_width("width"),
 				relative_width("relative_width", -1.f)
 			{
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 84a725ce02ed8cfb28762687dce4ae1a0f6fa3e0..e8627586eaa86bacd4c946358b54dc94691a0b65 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -102,11 +102,11 @@ struct SortScrollListItem
 //---------------------------------------------------------------------------
 
 LLScrollListCtrl::Contents::Contents()
-:	columns("columns"),
-	rows("rows")
+:	columns("column"),
+	rows("row")
 {
-	addSynonym(columns, "column");
-	addSynonym(rows, "row");
+	addSynonym(columns, "columns");
+	addSynonym(rows, "rows");
 }
 
 LLScrollListCtrl::Params::Params()
@@ -126,10 +126,11 @@ LLScrollListCtrl::Params::Params()
 	bg_selected_color("bg_selected_color"),
 	fg_disable_color("fg_disable_color"),
 	bg_writeable_color("bg_writeable_color"),
-	bg_read_only_color("bg_read_only_color"),
+	bg_readonly_color("bg_readonly_color"),
 	bg_stripe_color("bg_stripe_color"),
 	hovered_color("hovered_color"),
-	highlighted_color("highlighted_color")
+	highlighted_color("highlighted_color"),
+	contents("")
 {
 	name = "scroll_list";
 	mouse_opaque = true;
@@ -170,7 +171,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	mBackgroundVisible(p.background_visible),
 	mDrawStripes(p.draw_stripes),
 	mBgWriteableColor(p.bg_writeable_color()),
-	mBgReadOnlyColor(p.bg_read_only_color()),
+	mBgReadOnlyColor(p.bg_readonly_color()),
 	mBgSelectedColor(p.bg_selected_color()),
 	mBgStripeColor(p.bg_stripe_color()),
 	mFgSelectedColor(p.fg_selected_color()),
@@ -1082,12 +1083,12 @@ LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos)
 {
 	LLScrollListItem::Params separator_params;
 	separator_params.enabled(false);
-	LLScrollListCell::Params cell_params;
-	cell_params.type = "icon";
-	cell_params.value = "menu_separator";
-	cell_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f);
-	cell_params.font_halign = LLFontGL::HCENTER;
-	separator_params.cells.add(cell_params);
+	LLScrollListCell::Params column_params;
+	column_params.type = "icon";
+	column_params.value = "menu_separator";
+	column_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f);
+	column_params.font_halign = LLFontGL::HCENTER;
+	separator_params.columns.add(column_params);
 	return addRow( separator_params, pos );
 }
 
@@ -1249,7 +1250,7 @@ LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const std::string& item_te
 		LLScrollListItem::Params item_p;
 		item_p.enabled(enabled);
 		item_p.value(id);
-		item_p.cells.add().value(item_text).type("text");
+		item_p.columns.add().value(item_text).type("text");
 
 		return addRow( item_p, pos );
 	}
@@ -2635,8 +2636,8 @@ LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_
 	// Add any columns we don't already have
 	S32 col_index = 0;
 
-	for(LLInitParam::ParamIterator<LLScrollListCell::Params>::const_iterator itor = item_p.cells().begin();
-		itor != item_p.cells().end();
+	for(LLInitParam::ParamIterator<LLScrollListCell::Params>::const_iterator itor = item_p.columns().begin();
+		itor != item_p.columns().end();
 		++itor)
 	{
 		LLScrollListCell::Params cell_p = *itor;
@@ -2687,7 +2688,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_
 		col_index++;
 	}
 
-	if (item_p.cells().empty())
+	if (item_p.columns().empty())
 	{
 		if (mColumns.empty())
 		{
@@ -2742,7 +2743,7 @@ LLScrollListItem* LLScrollListCtrl::addSimpleElement(const std::string& value, E
 
 	LLScrollListItem::Params item_params;
 	item_params.value(entry_id);
-	item_params.cells.add()
+	item_params.columns.add()
 		.value(value)
 		.font(LLFontGL::getFontSansSerifSmall());
 	
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 60cd9239e2ebaaf11a6c6cbb3a7896ca0d7d767b..c1800419be94a9be14e6a43c58bb10d9f18e68ba 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -99,7 +99,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 							bg_selected_color,
 							fg_disable_color,
 							bg_writeable_color,
-							bg_read_only_color,
+							bg_readonly_color,
 							bg_stripe_color,
 							hovered_color,
 							highlighted_color;
diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h
index 4237d5b304eabf0e6a84e56b2b1339e4fac55415..c2b7effbc7dfd5ca6588491655557961ab4d6a77 100644
--- a/indra/llui/llscrolllistitem.h
+++ b/indra/llui/llscrolllistitem.h
@@ -68,7 +68,7 @@ class LLScrollListItem
 		Ignored				type; 
 		Ignored				length; 
 
-		Multiple<LLScrollListCell::Params> cells;
+		Multiple<LLScrollListCell::Params> columns;
 
 		Params()
 		:	enabled("enabled", true),
@@ -76,9 +76,9 @@ class LLScrollListItem
 			name("name"),
 			type("type"),
 			length("length"),
-			cells("columns")
+			columns("columns")
 		{
-			addSynonym(cells, "column");
+			addSynonym(columns, "column");
 			addSynonym(value, "id");
 		}
 	};
diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp
index 64583071a62a53008cf652d86a3869da5989ae96..3516712dc965aa20db7a46eaacad686635148071 100644
--- a/indra/llui/llsearcheditor.cpp
+++ b/indra/llui/llsearcheditor.cpp
@@ -1,6 +1,6 @@
 /** 
- * @file lllineeditor.cpp
- * @brief LLLineEditor base class
+ * @file llsearcheditor.cpp
+ * @brief LLSearchEditor implementation
  *
  * $LicenseInfo:firstyear=2001&license=viewergpl$
  * 
@@ -36,89 +36,63 @@
  
 #include "llsearcheditor.h"
 
-//static LLDefaultChildRegistry::Register<LLSearchEditor> r2("search_editor");
-
 LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
 :	LLUICtrl(p)
 {
-	LLLineEditor::Params line_editor_p(p);
-	line_editor_p.name("search edit box");
-	line_editor_p.rect(getLocalRect());
-	line_editor_p.follows.flags(FOLLOWS_ALL);
-	line_editor_p.text_pad_right(getRect().getHeight());
-	line_editor_p.keystroke_callback(boost::bind(&LLSearchEditor::onSearchEdit, this, _1));
-
-	mSearchEdit = LLUICtrlFactory::create<LLLineEditor>(line_editor_p);
-	addChild(mSearchEdit);
-
-	S32 btn_width = getRect().getHeight(); // button is square, and as tall as search editor
-	LLRect clear_btn_rect(getRect().getWidth() - btn_width, getRect().getHeight(), getRect().getWidth(), 0);
-	LLButton::Params button_params(p.clear_search_button);
-	button_params.name(std::string("clear search"));
-	button_params.rect(clear_btn_rect) ;
+	const S32 fudge = 2;
+	S32 btn_height = getRect().getHeight() - (fudge * 2);
+
+	LLLineEditor::Params line_editor_params(p);
+	line_editor_params.name("filter edit box");
+	line_editor_params.rect(getLocalRect());
+	line_editor_params.follows.flags(FOLLOWS_ALL);
+	line_editor_params.text_pad_left(btn_height + fudge);
+	line_editor_params.commit_callback.function(boost::bind(&LLUICtrl::onCommit, this));
+
+	mSearchEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_params);
+	addChild(mSearchEditor);
+
+	LLRect search_btn_rect(fudge, fudge + btn_height, fudge + btn_height, fudge);
+	LLButton::Params button_params(p.search_button);
+	button_params.name(std::string("clear filter"));
+	button_params.rect(search_btn_rect) ;
 	button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
 	button_params.tab_stop(false);
-	button_params.click_callback.function(boost::bind(&LLSearchEditor::onClearSearch, this, _2));
+	button_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this));
 
-	mClearSearchButton = LLUICtrlFactory::create<LLButton>(button_params);
-	mSearchEdit->addChild(mClearSearchButton);
+	mSearchButton = LLUICtrlFactory::create<LLButton>(button_params);
+	mSearchEditor->addChild(mSearchButton);
 }
 
 //virtual
 void LLSearchEditor::setValue(const LLSD& value )
 {
-	mSearchEdit->setValue(value);
+	mSearchEditor->setValue(value);
 }
 
 //virtual
 LLSD LLSearchEditor::getValue() const
 {
-	return mSearchEdit->getValue();
+	return mSearchEditor->getValue();
 }
 
 //virtual
 BOOL LLSearchEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
 {
-	return mSearchEdit->setTextArg(key, text);
+	return mSearchEditor->setTextArg(key, text);
 }
 
 //virtual
 BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
 {
-	return mSearchEdit->setLabelArg(key, text);
+	return mSearchEditor->setLabelArg(key, text);
 }
 
 //virtual
 void LLSearchEditor::clear()
 {
-	if (mSearchEdit)
+	if (mSearchEditor)
 	{
-		mSearchEdit->clear();
+		mSearchEditor->clear();
 	}
 }
-
-void LLSearchEditor::draw()
-{
-	mClearSearchButton->setVisible(!mSearchEdit->getWText().empty());
-
-	LLUICtrl::draw();
-}
-
-
-void LLSearchEditor::onSearchEdit(LLLineEditor* caller )
-{
-	if (mSearchCallback)
-	{
-		mSearchCallback(caller->getText());
-	}
-}
-
-void LLSearchEditor::onClearSearch(const LLSD& data)
-{
-	setText(LLStringUtil::null);
-	if (mSearchCallback)
-	{
-		mSearchCallback(LLStringUtil::null);
-	}
-}
-
diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h
index d8c5093fbf67592ef11d12ca49bd97c50c9c4452..368b68baa3ee2993fbe6d050bd141885237d10c3 100644
--- a/indra/llui/llsearcheditor.h
+++ b/indra/llui/llsearcheditor.h
@@ -39,28 +39,21 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_LLSEARCHEDITOR_H
-#define LL_LLSEARCHEDITOR_H
+#ifndef LL_SEARCHEDITOR_H
+#define LL_SEARCHEDITOR_H
 
 #include "lllineeditor.h"
 #include "llbutton.h"
 
-#include <boost/function.hpp>
-
-/*
- * @brief A line editor with a button to clear it and a callback to call on every edit event.
- */
 class LLSearchEditor : public LLUICtrl
 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLLineEditor::Params>
 	{
-		Optional<boost::function<void(const std::string&, void*)> > search_callback;
-		
-		Optional<LLButton::Params> clear_search_button;
+		Optional<LLButton::Params> search_button;
 
 		Params()
-		: clear_search_button("clear_search_button")
+		: search_button("search_button")
 		{
 			name = "search_editor";
 		}
@@ -69,15 +62,11 @@ class LLSearchEditor : public LLUICtrl
 protected:
 	LLSearchEditor(const Params&);
 	friend class LLUICtrlFactory;
+
 public:
 	virtual ~LLSearchEditor() {}
 
-	/*virtual*/ void	draw();
-
-	void setText(const LLStringExplicit &new_text) { mSearchEdit->setText(new_text); }
-
-	typedef boost::function<void (const std::string& search_string)> search_callback_t;
-	void setSearchCallback(search_callback_t cb) { mSearchCallback = cb; }
+	void setText(const LLStringExplicit &new_text) { mSearchEditor->setText(new_text); }
 
 	// LLUICtrl interface
 	virtual void	setValue(const LLSD& value );
@@ -87,12 +76,8 @@ class LLSearchEditor : public LLUICtrl
 	virtual void	clear();
 
 private:
-	void onSearchEdit(LLLineEditor* caller );
-	void onClearSearch(const LLSD& data);
-
-	LLLineEditor* mSearchEdit;
-	LLButton* mClearSearchButton;
-	search_callback_t mSearchCallback;
+	LLLineEditor* mSearchEditor;
+	LLButton* mSearchButton;
 };
 
-#endif  // LL_LLSEARCHEDITOR_H
+#endif  // LL_SEARCHEDITOR_H
diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h
index 1a94fcf2c6b128aaf0d7de1922b00f8415d12420..32ddded2c8666fdbf19d191609207bc4d4e5f53e 100644
--- a/indra/llui/llstyle.h
+++ b/indra/llui/llstyle.h
@@ -34,7 +34,6 @@
 #define LL_LLSTYLE_H
 
 #include "v4color.h"
-#include "llfont.h"
 #include "llui.h"
 
 class LLFontGL;
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 3d5b5caead7ad4aff0960d6da781a21bdc7e6c8b..29c30004ef3bced313c063b70b94c2abc9db3bc2 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -108,6 +108,7 @@ LLTabContainer::Params::Params()
 	tab_min_width("tab_min_width"),
 	tab_max_width("tab_max_width"),
 	hide_tabs("hide_tabs", false),
+	tab_padding_right("tab_padding_right"),
 	tab_top_image_unselected("tab_top_image_unselected"),
 	tab_top_image_selected("tab_top_image_selected"),
 	tab_bottom_image_unselected("tab_bottom_image_unselected"),
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index ac8232bbb1b587e5533b3b0d4c0fc5c4f73a23b4..78592a0f9a2f8b34d2b1909a624ce5023fd2f98b 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -122,6 +122,10 @@ class LLTabContainer : public LLPanel
 
 		TabPanelParams()
 		:	panel("panel", NULL),
+			label("label"),
+			select_tab("select_tab"),
+			is_placeholder("is_placeholder"),
+			indent("indent"),
 			insert_at("insert_at", END)
 		{}
 	};
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 56019171e1bf3ea0a44b7c381a589f8c7922ecfd..3dd8d21f6bdcdefa5e0d69af0031f69d2cb026b6 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -82,8 +82,7 @@ LLTextBox::LLTextBox(const LLTextBox::Params& p)
 	mHAlign(p.font_halign),
 	mLineSpacing(p.line_spacing),
 	mWordWrap( p.word_wrap ),
-	mDidWordWrap(FALSE),
-	mFontStyle(LLFontGL::getStyleFromString(p.font.style))
+	mDidWordWrap(FALSE)
 {
 	setText( p.text() );
 }
@@ -382,7 +381,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color )
 	{
 		mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color,
 						mHAlign, mVAlign, 
-						mFontStyle,
+						0,
 						mShadowType,
 						S32_MAX, getRect().getWidth(), NULL, TRUE, mUseEllipses);
 	}
@@ -395,7 +394,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color )
 			S32 line_length = *iter;
 			mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color,
 							mHAlign, mVAlign,
-							mFontStyle,
+							0,
 							mShadowType,
 							line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses );
 			cur_pos += line_length + 1;
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 53d57ff785bbc8c35a2f87d3d237c801aefef73c..d807fe7639425a3cdd5b4a45c3024e940c2dafb8 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -143,7 +143,6 @@ class LLTextBox
 	BOOL			mWordWrap;
 	BOOL            mDidWordWrap;
 	
-	U8				mFontStyle; // style bit flags for font
 	LLFontGL::ShadowType mShadowType;
 	BOOL			mBorderDropShadowVisible;
 	BOOL			mUseEllipses;
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 421ba321688829f070d9bf12c3d2720b1d853050..adeaf0a2791652cd1cf2c5702836e3ff4d6101c5 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -36,6 +36,7 @@
 
 #include "lltexteditor.h"
 
+#include "llfontfreetype.h" // for LLFontFreetype::FIRST_CHAR
 #include "llfontgl.h"
 #include "llrender.h"
 #include "llui.h"
@@ -227,6 +228,29 @@ class LLTextEditor::LLTextCmdRemove : public LLTextEditor::LLTextCmd
 
 
 ///////////////////////////////////////////////////////////////////
+LLTextEditor::Params::Params()
+:	default_text("default_text"),
+	max_text_length("max_length", 255),
+	read_only("read_only", false),
+	embedded_items("embedded_items", false),
+	hide_scrollbar("hide_scrollbar", false),
+	hide_border("hide_border", false),
+	word_wrap("word_wrap", false),
+	ignore_tab("ignore_tab", true),
+	track_bottom("track_bottom", false),
+	takes_non_scroll_clicks("takes_non_scroll_clicks", true),
+	cursor_color("cursor_color"),
+	default_color("default_color"),
+	text_color("text_color"),
+	text_readonly_color("text_readonly_color"),
+	bg_readonly_color("bg_readonly_color"),
+	bg_writeable_color("bg_writeable_color"),
+	bg_focus_color("bg_focus_color"),
+	length("length"),		// ignored
+	type("type"),			// ignored
+	is_unicode("is_unicode")// ignored
+{}
+
 LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)
 	:	LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
 	mMaxTextByteLength( p.max_text_length ),
@@ -254,7 +278,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)
 	mHideScrollbarForShortDocs( FALSE ),
 	mTakesNonScrollClicks( p.takes_non_scroll_clicks ),
 	mTrackBottom( p.track_bottom ),
-	mAllowEmbeddedItems( p.allow_embedded_items ),
+	mAllowEmbeddedItems( p.embedded_items ),
 	mHandleEditKeysDirectly( FALSE ),
 	mMouseDownX(0),
 	mMouseDownY(0),
@@ -263,8 +287,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)
 	mScrollNeeded(FALSE),
 	mLastSelectionY(-1),
 	mTabsToNextField(p.ignore_tab),
-	mGLFont(p.font),
-	mGLFontStyle(LLFontGL::getStyleFromString(p.font.style))
+	mGLFont(p.font)
 {
 	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
 
@@ -1930,7 +1953,7 @@ void LLTextEditor::pasteHelper(bool is_primary)
 		for( S32 i = 0; i < len; i++ )
 		{
 			llwchar wc = clean_string[i];
-			if( (wc < LLFont::FIRST_CHAR) && (wc != LF) )
+			if( (wc < LLFontFreetype::FIRST_CHAR) && (wc != LF) )
 			{
 				clean_string[i] = LL_UNKNOWN_CHAR;
 			}
@@ -3101,7 +3124,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32
 		S32 start = seg_start;
 		S32 end = llmin( selection_left, seg_end );
 		S32 length =  end - start;
-		font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems);
+		font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems);
 	}
 	x = *right_x;
 	
@@ -3114,7 +3137,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32
 
 		font->render(text, start, x, y_top,
 					 LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ),
-					 LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems);
+					 LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems);
 	}
 	x = *right_x;
 	if( selection_right < seg_end )
@@ -3123,7 +3146,7 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32
 		S32 start = llmax( selection_right, seg_start );
 		S32 end = seg_end;
 		S32 length = end - start;
-		font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, mGLFontStyle, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems);
+		font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems);
 	}
  }
 
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 5e423f854894faf68730ef527847e327e500c0ef..4da91cc1d7fbbfe75d7f79042c7d4b9ea18c2d41 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -63,7 +63,7 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 		Optional<S32>			max_text_length;
 
 		Optional<bool>			read_only,
-								allow_embedded_items,
+								embedded_items,
 								hide_scrollbar,
 								word_wrap,
 								ignore_tab,
@@ -86,30 +86,7 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 								length,
 								is_unicode;
 
-
-		Params()
-		:	max_text_length("max_length", 255),
-			read_only("read_only", false),
-			allow_embedded_items("embedded_items", false),
-			hide_scrollbar("hide_scrollbar", false),
-			hide_border("hide_border", false),
-			word_wrap("word_wrap", false),
-			ignore_tab("ignore_tab", true),
-			track_bottom("track_bottom", false),
-			takes_non_scroll_clicks("takes_non_scroll_clicks", true),
-			cursor_color("cursor_color"),
-			default_color("default_color"),
-			text_color("text_color"),
-			text_readonly_color("text_readonly_color"),
-			bg_readonly_color("bg_readonly_color"),
-			bg_writeable_color("bg_writeable_color"),
-			bg_focus_color("bg_focus_color"),
-			length("length"),
-			type("type"),
-			is_unicode("is_unicode")
-		{}
-			
-			
+		Params();
 	};
 
 	void initFromParams(const Params&);
@@ -524,7 +501,6 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	S32				mMaxTextByteLength;		// Maximum length mText is allowed to be in bytes
 
 	const LLFontGL*	mGLFont;
-	U8              mGLFontStyle; // the font style from xml
 
 	class LLViewBorder*	mBorder;
 
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 7eaa118222b4fe06687ef79cfa6d82321928d3aa..6906f0befb3ed7b6d99ce4d2860138b3e6b583c9 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -58,8 +58,9 @@
 #include "llwindow.h"
 
 // for registration
-#include "llsearcheditor.h"
+#include "llfiltereditor.h"
 #include "llflyoutbutton.h"
+#include "llsearcheditor.h"
 
 // for XUIParse
 #include "llquaternion.h"
@@ -88,9 +89,10 @@ std::list<std::string> gUntranslated;
 
 /*static*/ std::vector<std::string> LLUI::sXUIPaths;
 
-// register searcheditor here
-static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("search_editor");
+// register filtereditor here
+static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor");
 static LLDefaultChildRegistry::Register<LLFlyoutButton> register_flyout_button("flyout_button");
+static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("search_editor");
 
 
 //
@@ -1963,6 +1965,17 @@ namespace LLInitParam
 		declare("blue", LLColor4::blue);
 	}
 
+	template<>
+	class ParamCompare<const LLFontGL*>
+	{
+	public:
+		static bool equals(const LLFontGL* a, const LLFontGL* b)
+		{
+			return !(a->getFontDesc() < b->getFontDesc())
+				&& !(b->getFontDesc() < a->getFontDesc());
+		}
+	};
+
 	TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
 	:	super_t(descriptor, name, value, func, min_count, max_count),
 		name(""),
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 9399eff2ab9a9b66f131749f409e704417322fb6..413733a50bf1f1c2a254889e8c9bd09924b90f7e 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -39,7 +39,6 @@
 #include "llrect.h"
 #include "llcontrol.h"
 #include "llcoord.h"
-//#include "llhtmlhelp.h"
 #include "llgl.h"			// *TODO: break this dependency
 #include <stack>
 #include "lluiimage.h"		// *TODO: break this dependency, need to add #include "lluiimage.h" to all widgets that hold an Optional<LLUIImage*> in their paramblocks
@@ -49,6 +48,8 @@
 #include "lluicolortable.h"
 #include <boost/signals2.hpp>
 #include "lllazyvalue.h"
+#include "llhandle.h"		// *TODO: remove this dependency, added as a 
+							// convenience when LLHandle moved to llhandle.h
 
 // LLUIFactory
 #include "llsd.h"
@@ -433,139 +434,7 @@ class LLLocalClipRect : public LLScreenClipRect
 	LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE);
 };
 
-template <typename T>
-class LLTombStone : public LLRefCount
-{
-public:
-	LLTombStone(T* target = NULL) : mTarget(target) {}
-	
-	void setTarget(T* target) { mTarget = target; }
-	T* getTarget() const { return mTarget; }
-private:
-	T* mTarget;
-};
-
-//	LLHandles are used to refer to objects whose lifetime you do not control or influence.  
-//	Calling get() on a handle will return a pointer to the referenced object or NULL, 
-//	if the object no longer exists.  Note that during the lifetime of the returned pointer, 
-//	you are assuming that the object will not be deleted by any action you perform, 
-//	or any other thread, as normal when using pointers, so avoid using that pointer outside of
-//	the local code block.
-// 
-//  https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
-
-template <typename T>
-class LLHandle
-{
-public:
-	LLHandle() : mTombStone(sDefaultTombStone) {}
-	const LLHandle<T>& operator =(const LLHandle<T>& other)  
-	{ 
-		mTombStone = other.mTombStone;
-		return *this; 
-	}
-
-	bool isDead() const 
-	{ 
-		return mTombStone->getTarget() == NULL; 
-	}
-
-	void markDead() 
-	{ 
-		mTombStone = sDefaultTombStone; 
-	}
-
-	T* get() const
-	{
-		return mTombStone->getTarget();
-	}
-
-	friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
-	{
-		return lhs.mTombStone == rhs.mTombStone;
-	}
-	friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
-	{
-		return !(lhs == rhs);
-	}
-	friend bool	operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
-	{
-		return lhs.mTombStone < rhs.mTombStone;
-	}
-	friend bool	operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
-	{
-		return lhs.mTombStone > rhs.mTombStone;
-	}
-protected:
-
-protected:
-	LLPointer<LLTombStone<T> > mTombStone;
-
-private:
-	static LLPointer<LLTombStone<T> > sDefaultTombStone;
-};
-
-// initialize static "empty" tombstone pointer
-template <typename T> LLPointer<LLTombStone<T> > LLHandle<T>::sDefaultTombStone = new LLTombStone<T>();
-
-
-template <typename T>
-class LLRootHandle : public LLHandle<T>
-{
-public:
-	LLRootHandle(T* object) { bind(object); }
-	LLRootHandle() {};
-	~LLRootHandle() { unbind(); }
-
-	// this is redundant, since a LLRootHandle *is* an LLHandle
-	LLHandle<T> getHandle() { return LLHandle<T>(*this); }
-
-	void bind(T* object) 
-	{ 
-		// unbind existing tombstone
-		if (LLHandle<T>::mTombStone.notNull())
-		{
-			if (LLHandle<T>::mTombStone->getTarget() == object) return;
-			LLHandle<T>::mTombStone->setTarget(NULL);
-		}
-		// tombstone reference counted, so no paired delete
-		LLHandle<T>::mTombStone = new LLTombStone<T>(object);
-	}
-
-	void unbind() 
-	{
-		LLHandle<T>::mTombStone->setTarget(NULL);
-	}
-
-	//don't allow copying of root handles, since there should only be one
-private:
-	LLRootHandle(const LLRootHandle& other) {};
-};
-
-// Use this as a mixin for simple classes that need handles and when you don't
-// want handles at multiple points of the inheritance hierarchy
-template <typename T>
-class LLHandleProvider
-{
-protected:
-	typedef LLHandle<T> handle_type_t;
-	LLHandleProvider() 
-	{
-		// provided here to enforce T deriving from LLHandleProvider<T>
-	} 
-
-	LLHandle<T> getHandle() 
-	{ 
-		// perform lazy binding to avoid small tombstone allocations for handle
-		// providers whose handles are never referenced
-		mHandle.bind(static_cast<T*>(this)); 
-		return mHandle; 
-	}
-
-private:
-	LLRootHandle<T> mHandle;
-};
-
+// Moved all LLHandle-related code to llhandle.h
 
 //RN: maybe this needs to moved elsewhere?
 class LLImageProviderInterface
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index ebf594ff6649bd8201e3d3371ea6310ce1c24c68..aae4a86d870715bf66397fd13b14cd1b73de9867 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -43,7 +43,7 @@ static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl");
 LLUICtrl::Params::Params()
 :	tab_stop("tab_stop", true),
 	label("label"),
-	initial_value("initial_value"),
+	initial_value("value"),
 	init_callback("init_callback"),
 	commit_callback("commit_callback"),
 	validate_callback("validate_callback"),
@@ -52,9 +52,7 @@ LLUICtrl::Params::Params()
 	mouseleave_callback("mouseleave_callback"),
 	control_name("control_name")
 {
-	addSynonym(initial_value, "initial_val");
-	// this is the canonical name for text contents of an xml node
-	addSynonym(initial_value, "value");
+	addSynonym(initial_value, "initial_value");
 }
 
 LLFocusableElement::LLFocusableElement()
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 16fbbf79ea33fbb912113bf4e45318f6e4d55545..cf6634f370674e290e0c97ed85aabf5b8f7e00ac 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -108,7 +108,7 @@ class LLUICtrl
 	{
 		Optional<commit_callback_t> function;
 	};
-	
+
 	struct EnableCallbackParam : public LLInitParam::Block<EnableCallbackParam, CallbackParam >
 	{
 		Optional<enable_callback_t> function;
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 9df22e39b4c0cec268078e95af2e1dc4bd434e81..3b2b56d48e5ba95629e907b20a9c52b792fcab42 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -77,6 +77,7 @@ const S32 HPAD = 4;
 const S32 VPAD = 4;
 const S32 FLOATER_H_MARGIN = 15;
 const S32 MIN_WIDGET_HEIGHT = 10;
+const S32 MAX_STRING_ATTRIBUTE_SIZE = 40;
 
 LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION("Widget Construction");
 LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS("Widget InitFromParams");
@@ -449,177 +450,6 @@ void LLUICtrlFactory::popFactoryFunctions()
 	}
 }
 
-
-//
-// LLRNGWriter - writes Relax NG schema files based on a param block
-//
-LLRNGWriter::LLRNGWriter()
-{
-	// register various callbacks for inspecting the contents of a param block
-	registerInspectFunc<bool>(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4));
-	registerInspectFunc<std::string>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
-	registerInspectFunc<U8>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedByte", _1, _2, _3, _4));
-	registerInspectFunc<S8>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedByte", _1, _2, _3, _4));
-	registerInspectFunc<U16>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedShort", _1, _2, _3, _4));
-	registerInspectFunc<S16>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedShort", _1, _2, _3, _4));
-	registerInspectFunc<U32>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedInt", _1, _2, _3, _4));
-	registerInspectFunc<S32>(boost::bind(&LLRNGWriter::writeAttribute, this, "integer", _1, _2, _3, _4));
-	registerInspectFunc<F32>(boost::bind(&LLRNGWriter::writeAttribute, this, "float", _1, _2, _3, _4));
-	registerInspectFunc<F64>(boost::bind(&LLRNGWriter::writeAttribute, this, "double", _1, _2, _3, _4));
-	registerInspectFunc<LLColor4>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
-	registerInspectFunc<LLUIColor>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
-	registerInspectFunc<LLUUID>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
-	registerInspectFunc<LLSD>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
-}
-
-void LLRNGWriter::writeRNG(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace)
-{
-	mGrammarNode = node;
-	mGrammarNode->setName("grammar");
-	mGrammarNode->createChild("xmlns", true)->setStringValue("http://relaxng/ns/structure/1.0");
-	mGrammarNode->createChild("datatypeLibrary", true)->setStringValue("http://www.w3.org/2001/XMLSchema-datatypes");
-	mGrammarNode->createChild("ns", true)->setStringValue(xml_namespace);
-
-	node = mGrammarNode->createChild("start", false);
-	node = node->createChild("ref", false);
-	node->createChild("name", true)->setStringValue(type_name);
-	
-	node = mGrammarNode->createChild("define", false);
-	node->createChild("name", true)->setStringValue(type_name);
-
-	mElementNode = node->createChild("element", false);
-	mElementNode->createChild("name", true)->setStringValue(type_name);
-
-	block.inspectBlock(*this);
-}
-
-void LLRNGWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values)
-{
-	name_stack_t non_empty_names;
-	std::string attribute_name;
-	for (name_stack_t::const_iterator it = stack.begin();
-		it != stack.end();
-		++it)
-	{
-		const std::string& name = it->first;
-		if (!name.empty())
-		{
-			non_empty_names.push_back(*it);
-		}
-	}
-
-	if (non_empty_names.empty()) return;
-
-	for (name_stack_t::const_iterator it = non_empty_names.begin();
-		it != non_empty_names.end();
-		++it)
-	{
-		if (!attribute_name.empty())
-		{
-			attribute_name += ".";
-		}
-		attribute_name += it->first;
-	}
-
-	// singular attribute
-	if (non_empty_names.size() == 1)
-	{
-		if (max_count == 1)
-		{
-			LLXMLNodePtr node = getCardinalityNode(mElementNode, min_count, max_count)->createChild("attribute", false);
-			node->createChild("name", true)->setStringValue(attribute_name);
-			node->createChild("data", false)->createChild("type", true)->setStringValue(type);
-		}
-	}
-	// compound attribute
-	else
-	{
-		std::string element_name;
-
-		// traverse all but last element, leaving that as an attribute name
-		name_stack_t::const_iterator end_it = non_empty_names.end();
-		end_it--;
-
-		for (name_stack_t::const_iterator it = non_empty_names.begin();
-			it != end_it;
-			++it)
-		{
-			if (it != non_empty_names.begin())
-			{
-				element_name += ".";
-			}
-			element_name += it->first;
-		}
-
-		elements_map_t::iterator found_it = mElementsWritten.find(element_name);
-		if (found_it != mElementsWritten.end())
-		{
-			// reuse existing element
-			LLXMLNodePtr choice_node = found_it->second;
-
-			LLXMLNodePtr node = choice_node->mChildren->head;
-			node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
-			node->createChild("name", true)->setStringValue(attribute_name);
-			node->createChild("data", false)->createChild("type", true)->setStringValue(type);
-
-			node = choice_node->mChildren->head->mNext->mChildren->head;
-			node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
-			node->createChild("name", true)->setStringValue(non_empty_names.back().first);
-			node->createChild("data", false)->createChild("type", true)->setStringValue(type);
-		}
-		else
-		{
-			LLXMLNodePtr choice_node = mElementNode->createChild("choice", false);
-
-			LLXMLNodePtr node = choice_node->createChild("group", false);
-			node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
-			node->createChild("name", true)->setStringValue(attribute_name);
-			node->createChild("data", false)->createChild("type", true)->setStringValue(type);
-
-			node = choice_node->createChild("element", false);
-			node->createChild("name", true)->setStringValue(element_name);
-			node = getCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
-			node->createChild("name", true)->setStringValue(non_empty_names.back().first);
-			node->createChild("data", false)->createChild("type", true)->setStringValue(type);
-			
-			node = choice_node->createChild("element", false);
-			node->createChild("name", true)->setStringValue(type + "." + element_name);
-			node->createChild("ref", true)->createChild("name", true)->setStringValue(element_name);
-
-			mElementsWritten[element_name] = choice_node;
-		}
-	}
-}
-
-LLXMLNodePtr LLRNGWriter::getCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count)
-{
-	// unlinked by default, meaning this attribute is forbidden
-	LLXMLNodePtr count_node = new LLXMLNode();
-	if (min_count >= 1)
-	{
-		if (max_count == 1 && min_count == 1)
-		{
-			// just add raw element, will count as 1 and only 1
-			count_node = mElementNode;
-		}
-		else
-		{
-			count_node = mElementNode->createChild("oneOrMore", false);
-		}
-	}
-	else
-	{
-		if (max_count == 1)
-		{
-			count_node = mElementNode->createChild("optional", false);
-		}
-		else if (max_count > 1)
-		{
-			count_node = mElementNode->createChild("zeroOrMore", false);
-		}
-	}
-	return count_node;
-}
 //
 // LLXSDWriter
 //
@@ -811,7 +641,7 @@ void LLXSDWriter::addAttributeToSchema(LLXMLNodePtr type_declaration_node, const
 
 		string_set_t& attributes_written = mAttributesWritten[type_declaration_node];
 
-		string_set_t::iterator found_it = std::lower_bound(attributes_written.begin(), attributes_written.end(), attribute_name);
+		string_set_t::iterator found_it = attributes_written.lower_bound(attribute_name);
 
 		// attribute not yet declared
 		if (found_it == attributes_written.end() || attributes_written.key_comp()(attribute_name, *found_it))
@@ -997,142 +827,6 @@ void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, bool
 	}
 }
 
-void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block)
-{
-	mLastWriteGeneration = -1;
-	mWriteRootNode = node;
-	block.serializeBlock(*this, Parser::name_stack_t(), diff_block);
-}
-
-// go from a stack of names to a specific XML node
-LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack)
-{
-	name_stack_t name_stack;
-
-	for (name_stack_t::const_iterator it = stack.begin();
-		it != stack.end();
-		++it)
-	{
-		if (!it->first.empty())
-		{
-			name_stack.push_back(*it);
-		}
-	}
-
-	if (name_stack.empty() || mWriteRootNode.isNull()) return NULL;
-
-	std::string attribute_name = name_stack.front().first;
-
-	// heuristic to make font always attribute of parent node
-	bool is_font = (attribute_name == "font");
-	// XML spec says that attributes have their whitespace normalized
-	// on parse: http://www.w3.org/TR/REC-xml/#AVNormalize
-	// Therefore text-oriented widgets that might have carriage returns
-	// have their values serialized as text contents, not the
-	// initial_value attribute. JC
-	if (attribute_name == "initial_value")
-	{
-		const char* root_node_name = mWriteRootNode->getName()->mString;
-		if (!strcmp(root_node_name, "text")		// LLTextBox
-			|| !strcmp(root_node_name, "text_editor") 
-			|| !strcmp(root_node_name, "line_editor")) // for consistency
-		{
-			// writeStringValue will write to this node
-			return mWriteRootNode;
-		}
-	}
-
-	for (name_stack_t::const_iterator it = ++name_stack.begin();
-		it != name_stack.end();
-		++it)
-	{
-		attribute_name += ".";
-		attribute_name += it->first;
-	}
-
-	// *NOTE: <string> elements for translation need to have whitespace
-	// preserved like "initial_value" above, however, the <string> node
-	// becomes an attribute of the containing floater or panel.
-	// Because all <string> elements must have a "name" attribute, and
-	// "name" is parsed first, just put the value into the last written
-	// child.
-	if (attribute_name == "string.value")
-	{
-		// The caller of will shortly call writeStringValue(), which sets
-		// this node's type to string, but we don't want to export type="string".
-		// Set the default for this node to suppress the export.
-		static LLXMLNodePtr default_node;
-		if (default_node.isNull())
-		{
-			default_node = new LLXMLNode();
-			// Force the node to have a string type
-			default_node->setStringValue( std::string() );
-		}
-		mLastWrittenChild->setDefault(default_node);
-		// mLastWrittenChild is the "string" node part of "string.value",
-		// so the caller will call writeStringValue() into that node,
-		// setting the node text contents.
-		return mLastWrittenChild;
-	}
-
-	LLXMLNodePtr attribute_node;
-
-	const char* attribute_cstr = attribute_name.c_str();
-	if (name_stack.size() != 1
-		&& !is_font)
-	{
-		std::string child_node_name(mWriteRootNode->getName()->mString);
-		child_node_name += ".";
-		child_node_name += name_stack.front().first;
-
-		LLXMLNodePtr child_node;
-
-		if (mLastWriteGeneration == name_stack.front().second)
-		{
-			child_node = mLastWrittenChild;
-		}
-		else
-		{
-			mLastWriteGeneration = name_stack.front().second;
-			child_node = mWriteRootNode->createChild(child_node_name.c_str(), false);
-		}
-
-		mLastWrittenChild = child_node;
-
-		name_stack_t::const_iterator it = ++name_stack.begin();
-		std::string short_attribute_name(it->first);
-
-		for (++it;
-			it != name_stack.end();
-			++it)
-		{
-			short_attribute_name += ".";
-			short_attribute_name += it->first;
-		}
-
-		if (child_node->hasAttribute(short_attribute_name.c_str()))
-		{
-			llerrs << "Attribute " << short_attribute_name << " already exists!" << llendl;
-		}
-
-		attribute_node = child_node->createChild(short_attribute_name.c_str(), true);
-	}
-	else
-	{
-		if (mWriteRootNode->hasAttribute(attribute_cstr))
-		{
-			mWriteRootNode->getAttribute(attribute_cstr, attribute_node);
-		}
-		else
-		{
-			attribute_node = mWriteRootNode->createChild(attribute_name.c_str(), true);
-		}
-	}
-
-	return attribute_node;
-}
-
-
 bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLInitParam::BaseBlock& block)
 {
 	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
@@ -1152,8 +846,15 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLIn
 		// child nodes are not necessarily valid parameters (could be a child widget)
 		// so don't complain once we've recursed
 		bool silent = mCurReadDepth > 0;
-		block.submitValue(mNameStack, *this, silent);
-		mNameStack.pop_back();
+		if (!block.submitValue(mNameStack, *this, true))
+		{
+			mNameStack.pop_back();
+			block.submitValue(mNameStack, *this, silent);
+		}
+		else
+		{
+			mNameStack.pop_back();
+		}
 	}
 
 	// then traverse children
@@ -1271,6 +972,62 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo
 	return any_parsed;
 }
 
+void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block)
+{
+	mWriteRootNode = node;
+	block.serializeBlock(*this, Parser::name_stack_t(), diff_block);
+	mOutNodes.clear();
+}
+
+// go from a stack of names to a specific XML node
+LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack)
+{
+	name_stack_t name_stack;
+	for (name_stack_t::const_iterator it = stack.begin();
+		it != stack.end();
+		++it)
+	{
+		if (!it->first.empty())
+		{
+			name_stack.push_back(*it);
+		}
+	}
+
+	LLXMLNodePtr out_node = mWriteRootNode;
+
+	name_stack_t::const_iterator next_it = name_stack.begin();
+	for (name_stack_t::const_iterator it = name_stack.begin();
+		it != name_stack.end();
+		it = next_it)
+	{
+		++next_it;
+		if (it->first.empty())
+		{
+			continue;
+		}
+
+		out_nodes_t::iterator found_it = mOutNodes.lower_bound(it->second);
+
+		// node with this name not yet written
+		if (found_it == mOutNodes.end() || mOutNodes.key_comp()(found_it->first, it->second))
+		{
+			// make an attribute if we are the last element on the name stack
+			bool is_attribute = next_it == name_stack.end();
+			LLXMLNodePtr new_node = new LLXMLNode(it->first.c_str(), is_attribute);
+			out_node->addChild(new_node);
+			mOutNodes.insert(found_it, std::make_pair(it->second, new_node));
+			out_node = new_node;
+		}
+		else
+		{
+			out_node = found_it->second;
+		}
+	}
+
+	return (out_node == mWriteRootNode ? LLXMLNodePtr(NULL) : out_node);
+}
+
+
 bool LLXUIParser::readBoolValue(void* val_ptr)
 {
 	S32 value;
@@ -1301,7 +1058,27 @@ bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stac
 	LLXMLNodePtr node = getNode(stack);
 	if (node.notNull())
 	{
-		node->setStringValue(*((std::string*)val_ptr));
+		const std::string* string_val = reinterpret_cast<const std::string*>(val_ptr);
+		if (string_val->find('\n') != std::string::npos 
+			|| string_val->size() > MAX_STRING_ATTRIBUTE_SIZE)
+		{
+			// don't write strings with newlines into attributes
+			std::string attribute_name = node->getName()->mString;
+			LLXMLNodePtr parent_node = node->mParent;
+			parent_node->deleteChild(node);
+			// write results in text contents of node
+			if (attribute_name == "value")
+			{
+				// "value" is implicit, just write to parent
+				node = parent_node;
+			}
+			else
+			{
+				// create a child that is not an attribute, but with same name
+				node = parent_node->createChild(attribute_name.c_str(), false);
+			}
+		}
+		node->setStringValue(*string_val);
 		return true;
 	}
 	return false;
@@ -1538,7 +1315,26 @@ bool LLXUIParser::writeSDValue(const void* val_ptr, const name_stack_t& stack)
 	LLXMLNodePtr node = getNode(stack);
 	if (node.notNull())
 	{
-		node->setStringValue(((LLSD*)val_ptr)->asString());
+		std::string string_val = ((LLSD*)val_ptr)->asString();
+		if (string_val.find('\n') != std::string::npos || string_val.size() > MAX_STRING_ATTRIBUTE_SIZE)
+		{
+			// don't write strings with newlines into attributes
+			std::string attribute_name = node->getName()->mString;
+			LLXMLNodePtr parent_node = node->mParent;
+			parent_node->deleteChild(node);
+			// write results in text contents of node
+			if (attribute_name == "value")
+			{
+				// "value" is implicit, just write to parent
+				node = parent_node;
+			}
+			else
+			{
+				node = parent_node->createChild(attribute_name.c_str(), false);
+			}
+		}
+
+		node->setStringValue(string_val);
 		return true;
 	}
 	return false;
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 894c77888ca5274ee4d2c8fdef2045d9873d2afb..6374018ca691d34146cc5b634d76760707767daf 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -47,28 +47,6 @@ class LLPanel;
 class LLFloater;
 class LLView;
 
-class LLRNGWriter : public LLInitParam::Parser
-{
-	LOG_CLASS(LLRNGWriter);
-public:
-	void writeRNG(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace);
-
-	/*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; }
-
-	LLRNGWriter();
-
-private:
-	LLXMLNodePtr getCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count);
-
-	void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values);
-	LLXMLNodePtr mElementNode;
-	LLXMLNodePtr mGrammarNode;
-
-	typedef std::map<std::string, LLXMLNodePtr> elements_map_t;
-	elements_map_t	mElementsWritten;
-};
-
-
 class LLXSDWriter : public LLInitParam::Parser
 {
 	LOG_CLASS(LLXSDWriter);
@@ -161,6 +139,9 @@ LOG_CLASS(LLXUIParser);
 	LLXMLNodePtr					mCurReadNode;
 	// Root of the widget XML sub-tree, for example, "line_editor"
 	LLXMLNodePtr					mWriteRootNode;
+	
+	typedef std::map<S32, LLXMLNodePtr>	out_nodes_t;
+	out_nodes_t						mOutNodes;
 	S32								mLastWriteGeneration;
 	LLXMLNodePtr					mLastWrittenChild;
 	S32								mCurReadDepth;
@@ -489,7 +470,7 @@ LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreator
 }
 
 
-typedef boost::function<LLPanel* (void)> LLPannelClassCreatorFunc;
+typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc;
 
 // local static instance for registering a particular panel class
 
@@ -498,15 +479,15 @@ class LLRegisterPanelClass
 {
 public:
 	// reigister with either the provided builder, or the generic templated builder
-	void addPanelClass(const std::string& tag,LLPannelClassCreatorFunc func)
+	void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func)
 	{
-		mPannelClassesNames[tag] = func;
+		mPanelClassesNames[tag] = func;
 	}
 
 	LLPanel* createPanelClass(const std::string& tag)
 	{
-		param_name_map_t::iterator iT =  mPannelClassesNames.find(tag);
-		if(iT == mPannelClassesNames.end())
+		param_name_map_t::iterator iT =  mPanelClassesNames.find(tag);
+		if(iT == mPanelClassesNames.end())
 			return 0;
 		return iT->second();
 	}
@@ -518,9 +499,9 @@ class LLRegisterPanelClass
 	}
 
 private:
-	typedef std::map< std::string, LLPannelClassCreatorFunc> param_name_map_t;
+	typedef std::map< std::string, LLPanelClassCreatorFunc> param_name_map_t;
 	
-	param_name_map_t mPannelClassesNames;
+	param_name_map_t mPanelClassesNames;
 };
 
 
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 5d43ac11e465d87e4d7a9630920762c9a6c64ace..07cc612a0aa24d709f1c138002ea68df7abc1812 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -922,7 +922,7 @@ void LLXMLNode::writeHeaderToFile(LLFILE *out_file)
 	fprintf(out_file, "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n");
 }
 
-void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent)
+void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent, bool use_type_decorations)
 {
 	if (isFullyDefault())
 	{
@@ -931,7 +931,7 @@ void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent)
 	}
 
 	std::ostringstream ostream;
-	writeToOstream(ostream, indent);
+	writeToOstream(ostream, indent, use_type_decorations);
 	std::string outstring = ostream.str();
 	size_t written = fwrite(outstring.c_str(), 1, outstring.length(), out_file);
 	if (written != outstring.length())
@@ -940,7 +940,7 @@ void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent)
 	}
 }
 
-void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent)
+void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent, bool use_type_decorations)
 {
 	if (isFullyDefault())
 	{
@@ -956,77 +956,80 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
 	// stream the name
 	output_stream << indent << "<" << mName->mString << "\n";
 
-	// ID
-	if (mID != "")
+	if (use_type_decorations)
 	{
-		output_stream << indent << " id=\"" << mID << "\"\n";
-	}
+		// ID
+		if (mID != "")
+		{
+			output_stream << indent << " id=\"" << mID << "\"\n";
+		}
 
-	// Type
-	if (!has_default_type)
-	{
-		switch (mType)
+		// Type
+		if (!has_default_type)
 		{
-		case TYPE_BOOLEAN:
-			output_stream << indent << " type=\"boolean\"\n";
-			break;
-		case TYPE_INTEGER:
-			output_stream << indent << " type=\"integer\"\n";
-			break;
-		case TYPE_FLOAT:
-			output_stream << indent << " type=\"float\"\n";
-			break;
-		case TYPE_STRING:
-			output_stream << indent << " type=\"string\"\n";
-			break;
-		case TYPE_UUID:
-			output_stream << indent << " type=\"uuid\"\n";
-			break;
-		case TYPE_NODEREF:
-			output_stream << indent << " type=\"noderef\"\n";
-			break;
-		default:
-			// default on switch(enum) eliminates a warning on linux
-			break;
-		};
-	}
+			switch (mType)
+			{
+			case TYPE_BOOLEAN:
+				output_stream << indent << " type=\"boolean\"\n";
+				break;
+			case TYPE_INTEGER:
+				output_stream << indent << " type=\"integer\"\n";
+				break;
+			case TYPE_FLOAT:
+				output_stream << indent << " type=\"float\"\n";
+				break;
+			case TYPE_STRING:
+				output_stream << indent << " type=\"string\"\n";
+				break;
+			case TYPE_UUID:
+				output_stream << indent << " type=\"uuid\"\n";
+				break;
+			case TYPE_NODEREF:
+				output_stream << indent << " type=\"noderef\"\n";
+				break;
+			default:
+				// default on switch(enum) eliminates a warning on linux
+				break;
+			};
+		}
 
-	// Encoding
-	if (!has_default_encoding)
-	{
-		switch (mEncoding)
+		// Encoding
+		if (!has_default_encoding)
 		{
-		case ENCODING_DECIMAL:
-			output_stream << indent << " encoding=\"decimal\"\n";
-			break;
-		case ENCODING_HEX:
-			output_stream << indent << " encoding=\"hex\"\n";
-			break;
-		/*case ENCODING_BASE32:
-			output_stream << indent << " encoding=\"base32\"\n";
-			break;*/
-		default:
-			// default on switch(enum) eliminates a warning on linux
-			break;
-		};
-	}
+			switch (mEncoding)
+			{
+			case ENCODING_DECIMAL:
+				output_stream << indent << " encoding=\"decimal\"\n";
+				break;
+			case ENCODING_HEX:
+				output_stream << indent << " encoding=\"hex\"\n";
+				break;
+			/*case ENCODING_BASE32:
+				output_stream << indent << " encoding=\"base32\"\n";
+				break;*/
+			default:
+				// default on switch(enum) eliminates a warning on linux
+				break;
+			};
+		}
 
-	// Precision
-	if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT))
-	{
-		output_stream << indent << " precision=\"" << mPrecision << "\"\n";
-	}
+		// Precision
+		if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT))
+		{
+			output_stream << indent << " precision=\"" << mPrecision << "\"\n";
+		}
 
-	// Version
-	if (mVersionMajor > 0 || mVersionMinor > 0)
-	{
-		output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\n";
-	}
+		// Version
+		if (mVersionMajor > 0 || mVersionMinor > 0)
+		{
+			output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\n";
+		}
 
-	// Array length
-	if (!has_default_length && mLength > 0)
-	{
-		output_stream << indent << " length=\"" << mLength << "\"\n";
+		// Array length
+		if (!has_default_length && mLength > 0)
+		{
+			output_stream << indent << " length=\"" << mLength << "\"\n";
+		}
 	}
 
 	{
@@ -1039,12 +1042,13 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
 			if (child->mDefault.isNull() || child->mDefault->mValue != child->mValue)
 			{
 				std::string attr = child->mName->mString;
-				if (attr == "id" ||
-					attr == "type" ||
-					attr == "encoding" ||
-					attr == "precision" ||
-					attr == "version" ||
-					attr == "length")
+				if (use_type_decorations
+					&& (attr == "id" ||
+						attr == "type" ||
+						attr == "encoding" ||
+						attr == "precision" ||
+						attr == "version" ||
+						attr == "length"))
 				{
 					continue; // skip built-in attributes
 				}
@@ -1074,7 +1078,7 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
 			std::string next_indent = indent + "    ";
 			for (LLXMLNode* child = getFirstChild(); child; child = child->getNextSibling())
 			{
-				child->writeToOstream(output_stream, next_indent);
+				child->writeToOstream(output_stream, next_indent, use_type_decorations);
 			}
 		}
 		if (!mValue.empty())
diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h
index cc9e5cb351e2ca6a65ea19e158694a04259e5b25..818d774f73f5194b7a84e538bf36bb0980996f9d 100644
--- a/indra/llxml/llxmlnode.h
+++ b/indra/llxml/llxmlnode.h
@@ -165,8 +165,8 @@ class LLXMLNode : public LLThreadSafeRefCount
 	
 	// Write XML to file with one attribute per line.
 	// XML escapes values as they are written.
-    void writeToFile(LLFILE *out_file, const std::string& indent = std::string());
-    void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string());
+    void writeToFile(LLFILE *out_file, const std::string& indent = std::string(), bool use_type_decorations=true);
+    void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string(), bool use_type_decorations=true);
 
     // Utility
     void findName(const std::string& name, LLXMLNodeList &results);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d06571fb7ab6144fc0df888a6dd39566fed13660..2e29a56e79c86c31989ad6992a9b6a351eddbf17 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -299,6 +299,7 @@ set(viewer_SOURCE_FILES
     llpanelgroupnotices.cpp
     llpanelgrouproles.cpp
     llpanelinventory.cpp
+    llpanelimcontrolpanel.cpp
     llpanelland.cpp
     llpanellandmarks.cpp
     llpanellandmedia.cpp
@@ -734,6 +735,7 @@ set(viewer_HEADER_FILES
     llpanelgroupnotices.h
     llpanelgrouproles.h
     llpanelinventory.h
+    llpanelimcontrolpanel.h
     llpanelland.h
     llpanellandmarks.h
     llpanellandmedia.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index cb30cada7000c2b7341a0b2e7912a65e7bfdda45..ab9b0181509dd28a2b799ab6bd3e065306070fa7 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8091,7 +8091,7 @@
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <real>1</real>
+      <integer>4</integer>
     </map>
     <key>UIPreeditMarkerThickness</key>
     <map>
@@ -8135,7 +8135,7 @@
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <real>2</real>
+      <integer>4</integer>
     </map>
     <key>UIPreeditStandoutThickness</key>
     <map>
@@ -8146,7 +8146,7 @@
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <real>2</real>
+      <integer>2</integer>
     </map>
     <key>UIResizeBarHeight</key>
     <map>
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index cb1e9584ba5884e30a89bc375af23bb80d838b5f..e34f2ff47419a3d76b6c87aac8417c9d37212bfb 100644
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -46,9 +46,10 @@ class LLAvatarIconCtrl
 		Optional <LLUUID> avatar_id;
 		Optional <bool> draw_tooltip;
 		Params()
+		:	avatar_id("avatar_id"),
+			draw_tooltip("draw_tooltip", true)
 		{
 			name = "avatar_icon";
-			draw_tooltip = TRUE;
 		}
 	};
 protected:
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 5835a4c6b4bb6aa5696f2b75d1f239acd29e68c9..dc73f187a7658c6ba9a4e9ca9d39f0a44ca8c938 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -57,7 +57,9 @@ class LLAvatarListItem : public LLPanel
 			{};
 		} buttons;
 
-        Params() : avatar_icon("avatar_icon",LLUUID()), user_name("user_name","")
+        Params() 
+		:	avatar_icon("avatar_icon"), 
+			user_name("user_name")
         {};
 	};
 
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index d84dd09812f4e6ba978aa53842ca4ff866c2d49b..963946e888851b46889145bdb0f308a92624699d 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -32,11 +32,14 @@
 
 #include "llviewerprecompiledheaders.h" // must be first include
 #include "llbottomtray.h"
+
 #include "llagent.h"
 #include "llchiclet.h"
 #include "llfloaterreg.h"
 #include "llflyoutbutton.h"
+#include "llimpanel.h"
 #include "llkeyboard.h"
+#include "lllineeditor.h"
 #include "llgesturemgr.h"
 #include "llanimationstates.h"
 #include "llmultigesture.h"
@@ -233,7 +236,13 @@ void LLBottomTray::onChicletClick(LLUICtrl* ctrl)
 	LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl);
 	if (chiclet)
 	{
+		// Until you can type into an IM Window and have a conversation,
+		// still show the old communicate window
 		LLFloaterReg::showInstance("communicate", chiclet->getSessionId());
+		// DISABLED IN VIEWER-2 BRANCH UNTIL FEATURE IS DONE -- James
+		//// Show after comm window so it is frontmost (and hence will not
+		//// auto-hide)
+		//LLIMFloater::show(chiclet->getSessionId());
 	}
 }
 
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 330afeb6478bb221883fcff68d2f93116b4cc517..08f5cb91d803d02c91a876c4adc62354af31d5ee 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -40,6 +40,7 @@
 #include "llcombobox.h"
 
 class LLChicletPanel;
+class LLLineEditor;
 class LLNotificationChiclet;
 class LLTalkButton;
 
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 27ebccfe25e32b8ed455876fe3f05df65884c49d..bb31b7f2e8f344a9669a2c8905f0c653cbcefc9a 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -367,7 +367,7 @@ void	LLChatItemsContainerCtrl::updateLayout				(S32 width, S32 height)
 	}
 
 
-	//set sizes for first pannels and dragbars
+	//set sizes for first panels and dragbars
 	for(size_t i=0;i<mItems.size();++i)
 	{
 		LLRect panel_rect = mItems[i]->getRect();
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 38a7494b5b7d84ec3c491bac9b86c94181310e8f..bfa4e06d2e2f256085a8c35f844878f7d0f413b5 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -37,7 +37,7 @@
 #include "llbottomtray.h"
 #include "llgroupactions.h"
 #include "lliconctrl.h"
-#include "llimpanel.h"
+#include "llimpanel.h"				// LLFloaterIMPanel
 #include "llimview.h"
 #include "llfloatergroupinfo.h"
 #include "llmenugl.h"
@@ -203,6 +203,7 @@ LLIMChiclet::LLIMChiclet(const Params& p)
 , mSpeakerCtrl(NULL)
 , mShowSpeaker(p.show_speaker)
 , mPopupMenu(NULL)
+, mDockTongueVisible(false)
 {
 	LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
 	mAvatarCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
@@ -227,6 +228,11 @@ LLIMChiclet::~LLIMChiclet()
 
 }
 
+void LLIMChiclet::setDockTongueVisible(bool visible)
+{
+	mDockTongueVisible = visible;
+}
+
 void LLIMChiclet::setCounter(S32 counter)
 {
 	mCounterCtrl->setCounter(counter);
@@ -321,6 +327,13 @@ void LLIMChiclet::draw()
 {
 	LLUICtrl::draw();
 	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE);
+
+	if (mDockTongueVisible)
+	{
+		LLUIImagePtr flyout_tongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
+		// was previously AVATAR_WIDTH-16 and CHICLET_HEIGHT-6
+		flyout_tongue->draw( getRect().getWidth()-31, getRect().getHeight()-5);
+	}
 }
 
 BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
@@ -552,14 +565,6 @@ void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param)
 
 void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD&param)
 {
-	LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl);
-	if (chiclet)
-	{
-		S32 x, y;
-		LLRect rect = getRect();
-		localPointToScreen(rect.getCenterX(), 0, &x, &y);
-		LLIMFloater::show(chiclet->getSessionId(), x);
-	}
 	mCommitSignal(ctrl,param);
 }
 
@@ -653,7 +658,7 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )
 		width, height - scroll_button_rect.getHeight()));
 
 	mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD,
-		height + 1, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
+		height + 7, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
 
 	trimChiclets();
 
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index e467ec012a7d67694e157b3b5fc28bdfc0304d1a..415ae59ca276f1509a6685c27d42aed5fe15f60a 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -34,6 +34,7 @@
 #define LL_LLCHICLET_H
 
 #include "llavatariconctrl.h"
+#include "llbutton.h"
 #include "llpanel.h"
 #include "lltextbox.h"
 #include "lloutputmonitorctrl.h"
@@ -266,6 +267,8 @@ class LLIMChiclet : public LLChiclet
 	*/
 	virtual void setShowSpeaker(bool show);
 
+	void setDockTongueVisible(bool visible);
+
 	/*
 	 * Returns voice chat status control visibility.
 	*/
@@ -332,6 +335,7 @@ class LLIMChiclet : public LLChiclet
 	LLMenuGL* mPopupMenu;
 
 	bool mShowSpeaker;
+	bool mDockTongueVisible;
 };
 
 /*
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
index d05a32dc88b9bb9158a6d3bab0de897698f72a79..cf78d7d34f96f55092879e1dad84355bedc6d416 100644
--- a/indra/newview/llfloaterinventory.cpp
+++ b/indra/newview/llfloaterinventory.cpp
@@ -42,7 +42,7 @@
 #include "llcallingcard.h"
 #include "llfloaterreg.h"
 #include "llsdserialize.h"
-#include "llsearcheditor.h"
+#include "llfiltereditor.h"
 #include "llspinctrl.h"
 #include "llui.h"
 #include "message.h"
@@ -530,10 +530,10 @@ BOOL LLFloaterInventory::postBuild()
 	}
 
 
-	mSearchEditor = getChild<LLSearchEditor>("inventory search editor");
-	if (mSearchEditor)
+	mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
+	if (mFilterEditor)
 	{
-		mSearchEditor->setSearchCallback(boost::bind(&LLFloaterInventory::onSearchEdit, this, _1));
+		mFilterEditor->setCommitCallback(boost::bind(&LLFloaterInventory::onFilterEdit, this, _2));
 	}
 
 	// *TODO:Get the cost info from the server
@@ -598,9 +598,9 @@ void LLFloaterInventory::draw()
 		title << mFilterText;
 		setTitle(title.str());
 	}
-	if (mActivePanel && mSearchEditor)
+	if (mActivePanel && mFilterEditor)
 	{
-		mSearchEditor->setText(mActivePanel->getFilterSubString());
+		mFilterEditor->setText(mActivePanel->getFilterSubString());
 	}
 	LLFloater::draw();
 }
@@ -673,9 +673,9 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder)
 void LLFloaterInventory::startSearch()
 {
 	// this forces focus to line editor portion of search editor
-	if (mSearchEditor)
+	if (mFilterEditor)
 	{
-		mSearchEditor->focusFirstItem(TRUE);
+		mFilterEditor->focusFirstItem(TRUE);
 	}
 }
 
@@ -715,8 +715,8 @@ BOOL LLFloaterInventory::handleKeyHere(KEY key, MASK mask)
 	if (root_folder)
 	{
 		// first check for user accepting current search results
-		if (mSearchEditor 
-			&& mSearchEditor->hasFocus()
+		if (mFilterEditor 
+			&& mFilterEditor->hasFocus()
 		    && (key == KEY_RETURN 
 		    	|| key == KEY_DOWN)
 		    && mask == MASK_NONE)
@@ -966,7 +966,7 @@ void LLFloaterInventory::onClearSearch()
 	}
 }
 
-void LLFloaterInventory::onSearchEdit(const std::string& search_string )
+void LLFloaterInventory::onFilterEdit(const std::string& search_string )
 {
 	if (search_string == "")
 	{
diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h
index cd604075072ca10b01f46359986a74f5301bb24a..35ac1ab3802be6d4a499fb1e9a05eb8ac8804972 100644
--- a/indra/newview/llfloaterinventory.h
+++ b/indra/newview/llfloaterinventory.h
@@ -64,7 +64,7 @@ class LLScrollContainer;
 class LLTextBox;
 class LLIconCtrl;
 class LLSaveFolderState;
-class LLSearchEditor;
+class LLFilterEditor;
 class LLTabContainer;
 
 class LLInventoryPanel : public LLPanel
@@ -267,7 +267,7 @@ friend class LLFloaterInventoryFinder;
 	void onClearSearch();
 	static void onFoldersByName(void *user_data);
 	static BOOL checkFoldersByName(void *user_data);
-	void onSearchEdit(const std::string& search_string );
+	void onFilterEdit(const std::string& search_string );
 	static BOOL incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward);
 	void onFilterSelected();
 
@@ -291,7 +291,7 @@ friend class LLFloaterInventoryFinder;
 	LLFloaterInventoryFinder* getFinder() { return (LLFloaterInventoryFinder*)mFinderHandle.get(); }
 
 protected:
-	LLSearchEditor*				mSearchEditor;
+	LLFilterEditor*				mFilterEditor;
 	LLTabContainer*				mFilterTabs;
 	LLHandle<LLFloater>			mFinderHandle;
 	LLInventoryPanel*			mActivePanel;
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 08a042707d0d5d3550d1e5ebca523276aefa16c5..149df61b35c70e3b441dd3ca069af21c6d2e655d 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1490,26 +1490,26 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo
 
 		if (is_group_owned)
 		{
-			item_params.cells.add().type("icon").value(self->mIconGroup->getName()).column("type");
-			item_params.cells.add().value(OWNER_GROUP).font(FONT).column("online_status");
+			item_params.columns.add().type("icon").value(self->mIconGroup->getName()).column("type");
+			item_params.columns.add().value(OWNER_GROUP).font(FONT).column("online_status");
 		}
 		else if (is_online)
 		{
-			item_params.cells.add().type("icon").value(self->mIconAvatarOnline->getName()).column("type");
-			item_params.cells.add().value(OWNER_ONLINE).font(FONT).column("online_status");
+			item_params.columns.add().type("icon").value(self->mIconAvatarOnline->getName()).column("type");
+			item_params.columns.add().value(OWNER_ONLINE).font(FONT).column("online_status");
 		}
 		else  // offline
 		{
-			item_params.cells.add().type("icon").value(self->mIconAvatarOffline->getName()).column("type");
-			item_params.cells.add().value(OWNER_OFFLINE).font(FONT).column("online_status");
+			item_params.columns.add().type("icon").value(self->mIconAvatarOffline->getName()).column("type");
+			item_params.columns.add().value(OWNER_OFFLINE).font(FONT).column("online_status");
 		}
 
 		// Placeholder for name.
-		item_params.cells.add().font(FONT).column("name");
+		item_params.columns.add().font(FONT).column("name");
 
 		object_count_str = llformat("%d", object_count);
-		item_params.cells.add().value(object_count_str).font(FONT).column("count");
-		item_params.cells.add().value(formatted_time((time_t)most_recent_time)).font(FONT).column("mostrecent");
+		item_params.columns.add().value(object_count_str).font(FONT).column("count");
+		item_params.columns.add().value(formatted_time((time_t)most_recent_time)).font(FONT).column("mostrecent");
 
 		self->mOwnerList->addRow(item_params);
 
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 41e9ee3ccd6c6874665cd5b0a63705f8f4f81009..4870494b20f96e85e1c2c40b6eff46a2be394da5 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -57,6 +57,7 @@
 #include "lldraghandle.h"
 #include "lllayoutstack.h"
 #include "llviewermenu.h"
+#include "llrngwriter.h"
 
 // Boost (for linux/unix command-line execv)
 #include <boost/tokenizer.hpp>
@@ -354,6 +355,7 @@ void LLFloaterUIPreview::onLanguageComboSelect(LLUICtrl* ctrl)
 
 void LLFloaterUIPreview::onClickExportSchema()
 {
+	gViewerWindow->setCursor(UI_CURSOR_WAIT);
 	std::string template_path = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "xui", "schema");
 
 	typedef LLWidgetTypeRegistry::Registrar::registry_map_t::const_iterator registry_it;
@@ -373,10 +375,12 @@ void LLFloaterUIPreview::onClickExportSchema()
 		LLFILE* rng_file = LLFile::fopen(file_name.c_str(), "w");
 		{
 			LLXMLNode::writeHeaderToFile(rng_file);
-			root_nodep->writeToFile(rng_file);
+			const bool use_type_decorations = false;
+			root_nodep->writeToFile(rng_file, std::string(), use_type_decorations);
 		}
 		fclose(rng_file);
 	}
+	gViewerWindow->setCursor(UI_CURSOR_ARROW);
 }
 
 
@@ -625,7 +629,8 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
 				std::string full_filename = append_new_to_xml_filename(path);
 				LLFILE* floater_temp = LLFile::fopen(full_filename.c_str(), "w");
 				LLXMLNode::writeHeaderToFile(floater_temp);
-				floater_write->writeToFile(floater_temp);
+				const bool use_type_decorations = false;
+				floater_write->writeToFile(floater_temp, std::string(), use_type_decorations);
 				fclose(floater_temp);
 			}
 		}
@@ -647,7 +652,8 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
 				std::string full_filename = append_new_to_xml_filename(path);
 				LLFILE* menu_temp = LLFile::fopen(full_filename.c_str(), "w");
 				LLXMLNode::writeHeaderToFile(menu_temp);
-				menu_write->writeToFile(menu_temp);
+				const bool use_type_decorations = false;
+				menu_write->writeToFile(menu_temp, std::string(), use_type_decorations);
 				fclose(menu_temp);
 			}
 
@@ -671,7 +677,8 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
 				std::string full_filename = append_new_to_xml_filename(path);
 				LLFILE* panel_temp = LLFile::fopen(full_filename.c_str(), "w");
 				LLXMLNode::writeHeaderToFile(panel_temp);
-				panel_write->writeToFile(panel_temp);
+				const bool use_type_decorations = false;
+				panel_write->writeToFile(panel_temp, std::string(), use_type_decorations);
 				fclose(panel_temp);
 			}
 		}
diff --git a/indra/newview/llfloateruipreview.h b/indra/newview/llfloateruipreview.h
index 1307d606897369f71e5b1c0a66b1b0b86e3af790..eca8c0a141d67f9e86861c0e2077193ffa52bfbd 100644
--- a/indra/newview/llfloateruipreview.h
+++ b/indra/newview/llfloateruipreview.h
@@ -49,6 +49,7 @@ class LLColor;
 class LLScrollListCtrl;
 class LLComboBox;
 class LLButton;
+class LLLineEditor;
 class LLXmlTreeNode;
 class LLFloaterUIPreview;
 class LLFadeEventTimer;
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 5c1760ce22bf14aed76284ab6c89d0af56561116..d52079fc06ea2446237fd3c4f2154d55840cc600 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -49,6 +49,7 @@ class LLFriendObserver;
 class LLInventoryModel;
 class LLInventoryObserver;
 class LLItemInfo;
+class LLLineEditor;
 class LLTabContainer;
 
 class LLFloaterWorldMap : public LLFloater
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 43f3ea8d8f3b27bb43fc3db2f866824b798323fa..a6a8da2a7655ac27b7e90b9fca51cd66c6761fb3 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -81,8 +81,9 @@ void LLFolderViewItem::cleanupClass()
 
 // NOTE: Optimize this, we call it a *lot* when opening a large inventory
 LLFolderViewItem::Params::Params()
-:	folder_arrow_image("", LLUI::getUIImage("folder_arrow.tga")),
-	selection_image("", LLUI::getUIImage("rounded_square.tga"))
+:	icon("icon"),
+	folder_arrow_image("folder_arrow_image", LLUI::getUIImage("folder_arrow.tga")),
+	selection_image("selection_image", LLUI::getUIImage("rounded_square.tga"))
 {
 	mouse_opaque(true);
 	follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_RIGHT);
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 5b4f71109994369dd60c89833df7887c31ccf64d..248a8dbc4cceab4e0ac8bf40068acc4da2714081 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -45,8 +45,10 @@
 
 #include "llagent.h"
 #include "llbutton.h"
+#include "llbottomtray.h"
 #include "llcallingcard.h"
 #include "llchat.h"
+#include "llchiclet.h"
 #include "llconsole.h"
 #include "llfloater.h"
 #include "llfloatercall.h"
@@ -57,9 +59,12 @@
 #include "llinventorymodel.h"
 #include "llfloaterinventory.h"
 #include "llfloaterchat.h"
+#include "lliconctrl.h"
+#include "llimview.h"                  // for LLIMModel to get other avatar id in chat
 #include "llkeyboard.h"
 #include "lllineeditor.h"
 #include "llnotify.h"
+#include "llpanelimcontrolpanel.h"
 #include "llrecentpeople.h"
 #include "llresmgr.h"
 #include "lltrans.h"
@@ -2040,7 +2045,7 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const
 	}
 	return false;
 }
-
+	
 
 std::map<LLUUID, LLIMFloater*> LLIMFloater::sIMFloaterMap;
 
@@ -2048,23 +2053,183 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id,
 					 const std::string title,
 					 EInstantMessage dialog)
 :	mSessionID(session_id),
-	mIndex(0)
+	mLastMessageIndex(-1),
+	mDialog(dialog)
 {
 	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml");
 	sIMFloaterMap[mSessionID] = this;
 
+	LLPanelIMControlPanel* im_control_panel = getChild<LLPanelIMControlPanel>("panel_im_control_panel");
+
+	LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, session_id, (LLIMModel::LLIMSession*)NULL);
+	if(session)
+	{
+		mOtherParticipantUUID = session->mOtherParticipantID;
+		im_control_panel->setAvatarId(session->mOtherParticipantID);
+	}
+
+	LLButton* slide_left = getChild<LLButton>("slide_left_btn");
+	slide_left->setVisible(im_control_panel->getVisible());
+	slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
+
+	LLButton* slide_right = getChild<LLButton>("slide_right_btn");
+	slide_right->setVisible(!im_control_panel->getVisible());
+	slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
+
 	setTitle(title);
+	setDocked(true);
+
+	mInputEditor = getChild<LLLineEditor>("chat_editor");
+
+	
+	mInputEditor->setMaxTextLength(1023);
+	// enable line history support for instant message bar
+	mInputEditor->setEnableLineHistory(TRUE);
+	
+	mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
+	mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
+	mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
+	mInputEditor->setCommitOnFocusLost( FALSE );
+	mInputEditor->setRevertOnEsc( FALSE );
+	mInputEditor->setReplaceNewlinesWithSpaces( FALSE );
+
+	childSetCommitCallback("chat_editor", onSendMsg, this);
+}
+
+/* static */
+void LLIMFloater::newIMCallback(const LLSD& data){
+	
+	if (data["num_unread"].asInteger() > 0)
+	{
+		LLUUID session_id = data["session_id"].asUUID();
+
+		LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL);
+		
+		if (floater == NULL)
+		{
+			llwarns << "new_im_callback for non-existent session_id " << session_id << llendl;
+			return;
+		}
+
+        // update if visible, otherwise will be updated when opened
+		if (floater->getVisible())
+		{
+			floater->updateMessages();
+		}
+	}
+}
+
+void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
+{
+	LLIMFloater* self = (LLIMFloater*) userdata;
+	self->sendMsg();
 }
 
+void LLIMFloater::sendMsg()
+{
+	if (!gAgent.isGodlike() 
+		&& (mDialog == IM_NOTHING_SPECIAL)
+		&& mOtherParticipantUUID.isNull())
+	{
+		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
+		return;
+	}
+
+	if (mInputEditor)
+	{
+		LLWString text = mInputEditor->getConvertedText();
+		if(!text.empty())
+		{
+			// Truncate and convert to UTF8 for transport
+			std::string utf8_text = wstring_to_utf8str(text);
+			utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
+			
+			LLIMModel::sendMessage(utf8_text,
+								mSessionID,
+								mOtherParticipantUUID,
+								mDialog);
+
+			mInputEditor->setText(LLStringUtil::null);
+
+			updateMessages();
+		}
+	}
+}
+
+
+
 LLIMFloater::~LLIMFloater()
 {
 	sIMFloaterMap.erase(mSessionID);
 }
 
+//virtual
+BOOL LLIMFloater::postBuild()
+{
+	mHistoryEditor = getChild<LLViewerTextEditor>("im_text", true, false);
+	mChiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(mSessionID);
+
+	if (!mChiclet)
+	{
+		llwarns << "No chiclet found for the IMFloter" << llendl;
+	}
+	setDocked(false);
+	return TRUE;
+}
+
+const U32 UNDOCK_LEAP_HEIGHT = 12;
+const U32 DOCK_ICON_HEIGHT = 6;
 
-void LLIMFloater::show(const LLUUID& session_id, S32 center_x)
+//virtual
+void LLIMFloater::onFocusLost()
 {
+	// spec says close if docked to bottom tray and user has clicked away
+	// (hence we are no longer focused)
+	if (isDocked())
+	{
+		// app not quitting
+		closeFloater(false);
+	}
+}
+
 
+//virtual
+void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
+{
+	LLFloater::setDocked(docked);
+	mChiclet->setDockTongueVisible(docked);
+	if (docked)
+	{
+		S32 x, y;
+		mChiclet->localPointToScreen((mChiclet->getRect().getWidth())/2, 0, &x, &y);
+		translate(x - getRect().getCenterX(), DOCK_ICON_HEIGHT - getRect().mBottom);	
+	}
+	else if (pop_on_undock)
+	{
+		// visually pop up a little bit to emphasize the undocking
+		translate(0, UNDOCK_LEAP_HEIGHT);
+	}
+}
+
+
+void LLIMFloater::onClose(bool app_quitting)
+{
+	mChiclet->setDockTongueVisible(false);
+	LLFloater::onClose(app_quitting);
+}
+
+void LLIMFloater::onSlide()
+{
+	LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
+	im_control_panel->setVisible(!im_control_panel->getVisible());
+
+	getChild<LLButton>("slide_left_btn")->setVisible(im_control_panel->getVisible());
+	getChild<LLButton>("slide_right_btn")->setVisible(!im_control_panel->getVisible());
+}
+
+//static
+LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
+{
 	LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL);
 	
 	if (floater == NULL)
@@ -2078,28 +2243,25 @@ void LLIMFloater::show(const LLUUID& session_id, S32 center_x)
 	{
 		LLIMFloater* floater = (*iter).second;
 		floater->setVisible(false);
+		floater->mChiclet->setDockTongueVisible(false);
+	
 	}
 
-	//floater->setVisibleAndFrontmost(true);
+	floater->setVisibleAndFrontmost(true);
 
-	floater->updateMessages(session_id);
-
-	floater->translate(center_x - floater->getRect().getCenterX(), gFloaterView->getRect().mBottom - floater->getRect().mBottom);
+	if (floater->isDocked()) 
+	{
+		floater->mChiclet->setDockTongueVisible(true);
+	}
 
+	floater->updateMessages();
+	return floater;
 }
 
-void LLIMFloater::updateMessages(const LLUUID& session_id)
+void LLIMFloater::updateMessages()
 {
 
-	LLTextEditor* text_editor = getChild<LLTextEditor>("im_text", true, false);
-
-	if (!text_editor) 
-	{
-		llwarns << "Text editor not found! " << llendl;
-		return;
-	}
-
-	std::list<LLSD> messages = LLIMModel::instance().getMessages(mSessionID, mIndex);
+	std::list<LLSD> messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1);
 
 	if (messages.size())
 	{
@@ -2112,10 +2274,45 @@ void LLIMFloater::updateMessages(const LLUUID& session_id)
 			
 			message << msg["from"].asString() << " : " << msg["time"].asString() << "\n   " << msg["message"].asString() << "\n"; 
 			
-			mIndex = msg["index"].asInteger();
+			mLastMessageIndex = msg["index"].asInteger();
 		}
 
-		text_editor->setText(message.str());
+		mHistoryEditor->appendText(message.str(), false, false);
+		mHistoryEditor->setCursorAndScrollToEnd();
 	}
 
 }
+// static
+void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
+{
+	LLIMFloater* self= (LLIMFloater*) userdata;
+	self->mHistoryEditor->setCursorAndScrollToEnd();
+}
+
+// static
+void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
+{
+	LLIMFloater* self = (LLIMFloater*) userdata;
+	self->setTyping(FALSE);
+}
+
+// static
+void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
+{
+	LLIMFloater* self = (LLIMFloater*)userdata;
+	std::string text = self->mInputEditor->getText();
+	if (!text.empty())
+	{
+		self->setTyping(TRUE);
+	}
+	else
+	{
+		// Deleting all text counts as stopping typing.
+		self->setTyping(FALSE);
+	}
+}
+
+//just a stub for now
+void LLIMFloater::setTyping(BOOL typing)
+{
+}
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index 88f21864b551cd16c66daad0a09155ee643669d0..e6bde5c93a199ee113c17707d52ec0cf3f874c35 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -47,6 +47,7 @@ class LLInventoryItem;
 class LLInventoryCategory;
 class LLIMSpeakerMgr;
 class LLPanelActiveSpeakers;
+class LLIMChiclet;
 
 class LLVoiceChannel : public LLVoiceClientStatusObserver
 {
@@ -359,6 +360,8 @@ class LLFloaterIMPanel : public LLFloater
 };
 
 
+// Individual IM window that appears at the bottom of the screen,
+// optionally "docked" to the bottom tray.
 class LLIMFloater : public LLFloater
 {
 public:
@@ -367,14 +370,49 @@ class LLIMFloater : public LLFloater
 			  EInstantMessage dialog);
 
 	virtual ~LLIMFloater();
+	
+	// LLView overrides
+	/*virtual*/ BOOL postBuild();
+
+	// Floater should close when user clicks away to other UI area,
+	// hence causing focus loss.
+	/*virtual*/ void onFocusLost();
+
+	// LLFloater overrides
+	/*virtual*/ void setDocked(bool docked,  bool pop_on_undock = true);
+
+	static LLIMFloater* show(const LLUUID& session_id);
+	void onClose(bool app_quitting);
 
-	static void show(const LLUUID& session_id, S32 center_x);
-	void updateMessages(const LLUUID& session_id);
+	// get new messages from LLIMModel
+	void updateMessages();
+	static void onSendMsg( LLUICtrl*, void*);
+	void sendMsg();
 
+	// callback for LLIMModel on new messages
+	// route to specific floater if it is visible
+	static void newIMCallback(const LLSD& data);
+	
 	static std::map<LLUUID, LLIMFloater*> sIMFloaterMap;
+	
+
+private:
+	
+	static void		onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
+	static void		onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
+	static void		onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
+	void			setTyping(BOOL typing);
 
+	void onSlide();
+	
 	LLUUID mSessionID;
-	U32 mIndex;
+	S32 mLastMessageIndex;
+	EInstantMessage mDialog;
+	LLIMChiclet* mChiclet;
+	LLUUID mOtherParticipantUUID;
+	LLViewerTextEditor* mHistoryEditor;
+	LLLineEditor* mInputEditor;
+
 };
 
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 38335fe68f4c8d68e6e1b87447bb34ab997263f6..0505baac41f1ae9ece6235cc9a7c107133edc48d 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -113,14 +113,16 @@ void toast_callback(const LLSD& msg){
 LLIMModel::LLIMModel() 
 {
 	addChangedCallback(toast_callback);
+	addChangedCallback(LLIMFloater::newIMCallback);
 }
 
 
 void LLIMModel::testMessages()
 {
-	static LLUUID bot1_id, bot1_session_id;
-	if (bot1_id.isNull()) bot1_id.generate();
-	std::string from = "Bot1 TestLinden";
+	LLUUID bot1_id("d0426ec6-6535-4c11-a5d9-526bb0c654d9");
+	LLUUID bot1_session_id;
+	std::string from = "IM Tester";
+
 	bot1_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot1_id);
 	newSession(bot1_session_id, from, IM_NOTHING_SPECIAL, bot1_id);
 	addMessage(bot1_session_id, from, "Test Message: Hi from testerbot land!");
@@ -158,7 +160,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage
 
 }
 
-std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int index)
+std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
 {
 	std::list<LLSD> return_list;
 
@@ -170,7 +172,7 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int index)
 		return return_list;
 	}
 
-	int i = session->mMsgs.size() - index;
+	int i = session->mMsgs.size() - start_index;
 
 	for (std::list<LLSD>::iterator iter = session->mMsgs.begin(); 
 		iter != session->mMsgs.end() && i > 0;
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 6a354dfe926622cf46b0d246397428654eb5690c..b3b821f2ac53bca9e3d07841ec0a97a85a6a8de2 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -53,11 +53,11 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	struct LLIMSession
 	{
 		LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id) 
-			:mName(name), mType(type), mNumUnread(0), mOtherPraticipantID(other_participant_id) {}
+			:mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id) {}
 		
 		std::string mName;
 		EInstantMessage mType;
-		LLUUID mOtherPraticipantID;
+		LLUUID mOtherParticipantID;
 		S32 mNumUnread;
 		std::list<LLSD> mMsgs;
 	};
@@ -70,7 +70,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb );
 
 	bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id);
-	std::list<LLSD> getMessages(LLUUID session_id, int index = 0);
+	std::list<LLSD> getMessages(LLUUID session_id, int start_index = 0);
 	bool addMessage(LLUUID session_id, std::string from, std::string utf8_text);
 	bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text); 
     //used to get the name of the session, for use as the title
diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp
index 0c652621f48f488b132b297c311bf097dd0907bb..cfcb3319123771ae8fcf32b49a8ae6c4ef5d8f59 100644
--- a/indra/newview/llmenucommands.cpp
+++ b/indra/newview/llmenucommands.cpp
@@ -51,6 +51,7 @@
 #include "llfloaterworldmap.h"
 #include "llgivemoney.h"
 #include "llfloaterinventory.h"
+#include "lllineeditor.h"
 #include "llnotify.h"
 #include "llstatusbar.h"
 #include "llimview.h"
diff --git a/indra/newview/llnameeditor.h b/indra/newview/llnameeditor.h
index f9cabb5831e580bd1e533748986a588556635f08..99e03a11662a53f0993ebb929533a5c235592bf3 100644
--- a/indra/newview/llnameeditor.h
+++ b/indra/newview/llnameeditor.h
@@ -50,6 +50,11 @@ class LLNameEditor
 	{
 		Optional<bool>		is_group;
 		Optional<LLUUID>	name_id;
+
+		Params()
+		:	is_group("is_group"),
+			name_id("name_id")
+		{}
 	};
 
 protected:
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index d7066cb1401680865022bb2f631fc901a5c95089..ffc3b2f37a4727e8d40368d01cb9064b6f082f90 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -169,7 +169,7 @@ LLScrollListItem* LLNameListCtrl::addRow(const LLNameListCtrl::NameItem& name_it
 	if (!item) return NULL;
 
 	// use supplied name by default
-	std::string fullname = name_item.display_name;
+	std::string fullname = name_item.name;
 	switch(name_item.target)
 	{
 	case GROUP:
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index 6692d4cff9093ab1f824fd09be1857e9900b4f6b..80feaea8812d5aa0277174d799c091efa82115f3 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -57,11 +57,11 @@ class LLNameListCtrl
 
 	struct NameItem : public LLInitParam::Block<NameItem, LLScrollListItem::Params>
 	{
-		Optional<std::string>				display_name;
+		Optional<std::string>				name;
 		Optional<ENameType, NameTypeNames>	target;
 
 		NameItem()
-		:	display_name("name"),
+		:	name("name"),
 			target("target", INDIVIDUAL)
 		{}		
 	};
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index fbeff2d628ac27257be9b054415ad7d0cf07c381..c0bddd101e8bc316ed2441489e0584ef0c61cfa3 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -45,6 +45,7 @@
 #include "lllocationhistory.h"
 #include "lllocationinputctrl.h"
 #include "llteleporthistory.h"
+#include "llsearcheditor.h"
 #include "llslurl.h"
 #include "llurlsimstring.h"
 #include "llviewerinventory.h"
@@ -204,12 +205,10 @@ BOOL LLNavigationBar::postBuild()
 	mBtnHelp	= getChild<LLButton>("help_btn");
 	
 	mCmbLocation= getChild<LLLocationInputCtrl>("location_combo"); 
-	mLeSearch	= getChild<LLLineEditor>("search_input");
-	
-	LLButton* search_btn = getChild<LLButton>("search_btn");
+	mLeSearch	= getChild<LLSearchEditor>("search_input");
 
 	if (!mBtnBack || !mBtnForward || !mBtnHome || !mBtnHelp ||
-		!mCmbLocation || !mLeSearch || !search_btn)
+		!mCmbLocation || !mLeSearch)
 	{
 		llwarns << "Malformed navigation bar" << llendl;
 		return FALSE;
@@ -229,7 +228,6 @@ BOOL LLNavigationBar::postBuild()
 	mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));
 	
 	mLeSearch->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));
-	search_btn->setClickedCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));
 
 	// Load the location field context menu
 	mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
@@ -306,7 +304,7 @@ void LLNavigationBar::onHelpButtonClicked()
 
 void LLNavigationBar::onSearchCommit()
 {
-	invokeSearch(mLeSearch->getText());
+	invokeSearch(mLeSearch->getValue().asString());
 }
 
 void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 846040e506025b3ed98089105dae0a7e6867c09d..a82dfc73ffdcb61bb20034a5424a7dcfb1d859a5 100644
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -40,7 +40,7 @@ extern S32 NAVIGATION_BAR_HEIGHT;
 class LLButton;
 class LLLocationInputCtrl;
 class LLMenuGL;
-class LLLineEditor;
+class LLSearchEditor;
 
 /**
  * Web browser-like navigation bar.
@@ -97,7 +97,7 @@ class LLNavigationBar
 	LLButton*				mBtnForward;
 	LLButton*				mBtnHome;
 	LLButton*				mBtnHelp;
-	LLLineEditor*			mLeSearch;
+	LLSearchEditor*			mLeSearch;
 	LLLocationInputCtrl*	mCmbLocation;
 	bool					mPurgeTPHistoryItems;
 };
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 340cb8187d737f449bbc7787dfc2c7746cc0c551..955f50caf51a00955c179170ead3a7d9a5836377 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -52,7 +52,8 @@ LLColor4	LLOutputMonitorCtrl::sColorBound;
 //F32			LLOutputMonitorCtrl::sRectHeightRatio	= 0.f;
 
 LLOutputMonitorCtrl::Params::Params()
-:	image_mute("image_mute"),
+:	draw_border("draw_border"),
+	image_mute("image_mute"),
 	image_off("image_off"),
 	image_on("image_on"),
 	image_level_1("image_level_1"),
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 868d4d9200c8e19821dd7ba2452d378b1cb03ec9..bf6ecd6bf45b4b5390e4639a1bc51d74d9c8e77f 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -61,6 +61,7 @@ class LLDropTarget : public LLView
 	{
 		Optional<LLUUID> agent_id;
 		Params()
+		:	agent_id("agent_id")
 		{
 			mouse_opaque(false);
 			follows.flags(FOLLOWS_ALL);
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..45fe625a13ee3131247d812a63047dd54270a387
--- /dev/null
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -0,0 +1,87 @@
+/** 
+ * @file llpanelavatar.cpp
+ * @brief LLPanelAvatar and related class implementations
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ * 
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelimcontrolpanel.h"
+
+#include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llbutton.h"
+
+static LLRegisterPanelClassWrapper<LLPanelIMControlPanel> t_im_control_panel("panel_im_control_panel");
+
+LLPanelIMControlPanel::LLPanelIMControlPanel()
+: LLPanel()
+{
+}
+
+LLPanelIMControlPanel::~LLPanelIMControlPanel()
+{
+}
+
+BOOL LLPanelIMControlPanel::postBuild()
+{
+	childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this));
+	childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this));
+	childSetAction("call_btn", boost::bind(&LLPanelIMControlPanel::onCallButtonClicked, this));
+	childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this));
+
+	return TRUE;
+}
+
+void LLPanelIMControlPanel::onViewProfileButtonClicked()
+{
+	LLAvatarActions::showProfile(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId());
+}
+
+void LLPanelIMControlPanel::onAddFriendButtonClicked()
+{
+	LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+	std::string full_name = avatar_icon->getFirstName() + " " + avatar_icon->getLastName();
+	LLAvatarActions::requestFriendshipDialog(avatar_icon->getAvatarId(), full_name);
+}
+
+void LLPanelIMControlPanel::onCallButtonClicked()
+{
+	// *TODO: Implement
+}
+
+void LLPanelIMControlPanel::onShareButtonClicked()
+{
+	// *TODO: Implement
+}
+
+void LLPanelIMControlPanel::setAvatarId(const LLUUID& avatar_id)
+{
+	getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(avatar_id);
+}
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
new file mode 100644
index 0000000000000000000000000000000000000000..be3b2d31304533e21dd371a0f6cfc10eb63aea11
--- /dev/null
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -0,0 +1,55 @@
+/** 
+ * @file llpanelimcontrolpanel.h
+ * @brief LLPanelIMControlPanel and related class definitions
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ * 
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELIMCONTROLPANEL_H
+#define LL_LLPANELIMCONTROLPANEL_H
+
+#include "llpanel.h"
+
+class LLPanelIMControlPanel : public LLPanel
+{
+public:
+	LLPanelIMControlPanel();
+	~LLPanelIMControlPanel();
+
+	BOOL postBuild();
+
+	void setAvatarId(const LLUUID& avatar_id);
+
+private:
+	void onViewProfileButtonClicked();
+	void onAddFriendButtonClicked();
+	void onCallButtonClicked();
+	void onShareButtonClicked();
+};
+
+#endif // LL_LLPANELIMCONTROLPANEL_H
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 453183ad74132e65875f52ff746d4c1c25f8512c..0cbf10f7c2e34f8e01711da8716d45ff67196e7d 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -33,6 +33,7 @@
 
 #include "llpanellandmarks.h"
 
+#include "llbutton.h"
 #include "llfloaterreg.h"
 #include "lllandmark.h"
 
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 540f93805344356f85e63afe9b0d00cb766403db..83a31eecda1c8d2255086601709de4e33a2083d6 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -37,6 +37,7 @@
 #include "llpointer.h"			// LLPointer<>
 #include "llwebbrowserctrl.h"	// LLWebBrowserCtrlObserver
 
+class LLLineEditor;
 class LLUIImage;
 
 
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index d2879a675f7102c2aef5deb124cdd4ed7783eb1d..d947003109ab28b81f2f44128522e6a60ae23654 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -35,7 +35,7 @@
 // libs
 #include "llfloaterreg.h"
 #include "llmenugl.h"
-#include "llsearcheditor.h"
+#include "llfiltereditor.h"
 #include "lltabcontainer.h"
 #include "lluictrlfactory.h"
 
@@ -306,7 +306,7 @@ class LLGroupListUpdater : public LLPanelPeople::Updater, public LLSimpleListene
 LLPanelPeople::LLPanelPeople()
 	:	LLPanel(),
 		mFilterSubString(LLStringUtil::null),
-		mSearchEditor(NULL),
+		mFilterEditor(NULL),
 		mTabContainer(NULL),
 		mFriendList(NULL),
 		mNearbyList(NULL),
@@ -330,8 +330,8 @@ LLPanelPeople::~LLPanelPeople()
 
 BOOL LLPanelPeople::postBuild()
 {
-	mSearchEditor = getChild<LLSearchEditor>("filter_input");
-	mSearchEditor->setSearchCallback(boost::bind(&LLPanelPeople::onSearchEdit, this, _1));
+	mFilterEditor = getChild<LLFilterEditor>("filter_input");
+	mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
 
 	mTabContainer = getChild<LLTabContainer>("tabs");
 	mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2));
@@ -609,7 +609,7 @@ void LLPanelPeople::reSelectedCurrentTab()
 	mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex());
 }
 
-void LLPanelPeople::onSearchEdit(const std::string& search_string)
+void LLPanelPeople::onFilterEdit(const std::string& search_string)
 {
 	if (mFilterSubString == search_string)
 		return;
@@ -618,7 +618,7 @@ void LLPanelPeople::onSearchEdit(const std::string& search_string)
 
 	LLStringUtil::toUpper(mFilterSubString);
 	LLStringUtil::trimHead(mFilterSubString);
-	mSearchEditor->setText(mFilterSubString);
+	mFilterEditor->setText(mFilterSubString);
 
 	// Apply new filter to all tabs.
 	filterNearbyList();
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 11317901062f70be25f45fc72aec5aaa0139b457..6c3b5e0664ef3f89295e517963a0e15dae9804c0 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -37,7 +37,7 @@
 
 #include "llcallingcard.h" // for avatar tracker
 
-class LLSearchEditor;
+class LLFilterEditor;
 class LLTabContainer;
 class LLAvatarList;
 class LLGroupList;
@@ -77,7 +77,7 @@ class LLPanelPeople : public LLPanel
 	void					reSelectedCurrentTab();
 
 	// UI callbacks
-	void					onSearchEdit(const std::string& search_string);
+	void					onFilterEdit(const std::string& search_string);
 	void					onTabSelected(const LLSD& param);
 	void					onViewProfileButtonClicked();
 	void					onAddFriendButtonClicked();
@@ -104,7 +104,7 @@ class LLPanelPeople : public LLPanel
 								const std::vector<LLUUID>& ids,
 								void*);
 
-	LLSearchEditor*			mSearchEditor;
+	LLFilterEditor*			mFilterEditor;
 	LLTabContainer*			mTabContainer;
 	LLAvatarList*			mFriendList;
 	LLAvatarList*			mNearbyList;
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 961c54d667c2f36507724fef244432030a31e3ca..cda1a9e7e75f0e006b90dc98ca72aa7e94da65e3 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -38,6 +38,7 @@
 #include "llpanel.h"
 #include "message.h"
 #include "llagent.h"
+#include "llbutton.h"
 #include "llparcel.h"
 #include "llviewerparcelmgr.h"
 #include "lltexturectrl.h"
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index c162a9ba337a553de2744a5477c816d10061c928..57c633dd74b5322f380621a94b414caa5f9b5d67 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -32,7 +32,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llfloaterreg.h"
-#include "llsearcheditor.h"
+#include "llfiltereditor.h"
 #include "lltabcontainer.h"
 #include "lluictrlfactory.h"
 
@@ -67,7 +67,7 @@ LLPanelPlaces::LLPanelPlaces()
 	:	LLPanel(),
 		mFilterSubString(LLStringUtil::null),
 		mActivePanel(NULL),
-		mSearchEditor(NULL),
+		mFilterEditor(NULL),
 		mPlaceInfo(NULL)
 {
 	gInventory.addObserver(this);
@@ -92,10 +92,10 @@ BOOL LLPanelPlaces::postBuild()
 		mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this));
 	}
 
-	mSearchEditor = getChild<LLSearchEditor>("Filter");
-	if (mSearchEditor)
+	mFilterEditor = getChild<LLFilterEditor>("Filter");
+	if (mFilterEditor)
 	{
-		mSearchEditor->setSearchCallback(boost::bind(&LLPanelPlaces::onSearchEdit, this, _1));
+		mFilterEditor->setCommitCallback(boost::bind(&LLPanelPlaces::onFilterEdit, this, _2));
 	}
 
 	mPlaceInfo = getChild<LLPanelPlaceInfo>("panel_place_info", TRUE, FALSE);
@@ -187,7 +187,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 	}
 }
 
-void LLPanelPlaces::onSearchEdit(const std::string& search_string)
+void LLPanelPlaces::onFilterEdit(const std::string& search_string)
 {
 	if (mFilterSubString != search_string)
 	{
@@ -196,7 +196,7 @@ void LLPanelPlaces::onSearchEdit(const std::string& search_string)
 		LLStringUtil::toUpper(mFilterSubString);
 		LLStringUtil::trimHead(mFilterSubString);
 
-		mSearchEditor->setText(mFilterSubString);
+		mFilterEditor->setText(mFilterSubString);
 
 		mActivePanel->onSearchEdit(mFilterSubString);
 	}
@@ -208,7 +208,7 @@ void LLPanelPlaces::onTabSelected()
 	if (!mActivePanel)
 		return;
 
-	onSearchEdit(mFilterSubString);	
+	onFilterEdit(mFilterSubString);	
 	mActivePanel->updateVerbs();
 }
 
@@ -274,7 +274,7 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
 		return;
 
 	mPlaceInfo->setVisible(visible);
-	mSearchEditor->setVisible(!visible);
+	mFilterEditor->setVisible(!visible);
 	mTabContainer->setVisible(!visible);
 	
 	// Enable overflow button only for the information about agent's current location.
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 6fbb7562c910db89b8d6b3e3cf721d9ecface6a6..e2ba4f39cd17b38c9d8765e346deef55555e0f87 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -42,7 +42,7 @@
 #include "llpanelplaceinfo.h"
 
 class LLPanelPlacesTab;
-class LLSearchEditor;
+class LLFilterEditor;
 class LLTabContainer;
 
 class LLPanelPlaces : public LLPanel, LLInventoryObserver
@@ -55,7 +55,7 @@ class LLPanelPlaces : public LLPanel, LLInventoryObserver
 	/*virtual*/ void changed(U32 mask);
 	/*virtual*/ void onOpen(const LLSD& key);
 
-	void onSearchEdit(const std::string& search_string);
+	void onFilterEdit(const std::string& search_string);
 	void onTabSelected();
 	//void onAddLandmarkButtonClicked();
 	//void onCopySLURLButtonClicked();
@@ -68,7 +68,7 @@ class LLPanelPlaces : public LLPanel, LLInventoryObserver
 	void onAgentParcelChange();
 
 private:
-	LLSearchEditor*			mSearchEditor;
+	LLFilterEditor*			mFilterEditor;
 	LLPanelPlacesTab*		mActivePanel;
 	LLTabContainer*			mTabContainer;
 	LLPanelPlaceInfo*		mPlaceInfo;
diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp
index dc9119d2e32e8ff0dc291c8532c9cd48d97566c2..e5b1f040644ce1706a95f75157e3f80591110291 100644
--- a/indra/newview/llpanelplacestab.cpp
+++ b/indra/newview/llpanelplacestab.cpp
@@ -31,12 +31,14 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llpanelplacestab.h"
+
 #include "llwindow.h"
 
 #include "llnotifications.h"
 
+#include "llbutton.h"
 #include "llslurl.h"
-#include "llpanelplacestab.h"
 #include "llworldmap.h"
 
 void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel)
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 37262b736eac80b241d3dab69b4bafc158e658d6..abcff7cfb17735be3e108615a0440e96afeea54a 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -118,7 +118,7 @@ LLSideTrayTab::LLSideTrayTab(const Params& params):mAccordionCtrl(0)
 {
 	mImagePath = params.image_path;
 	mTabTitle = params.tab_title;
-	mDescription = params.tab_description;
+	mDescription = params.description;
 }
 LLSideTrayTab::~LLSideTrayTab()
 {
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index 7487c71bfc707a64a747278f1570368b1eafc2b9..7b1f4aee04a89c356ba4e1eae61b6ba5163d7078 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -51,10 +51,11 @@ class LLSideTrayTab: public LLPanel
 		// image name
 		Optional<std::string>		image_path;
 		Optional<std::string>		tab_title;
-		Optional<std::string>		tab_description;
-		Params():image_path("image","")
-				,tab_title("tab_title","no title")
-				,tab_description("description","no description")
+		Optional<std::string>		description;
+		Params()
+		:	image_path("image"),
+			tab_title("tab_title","no title"),
+			description("description","no description")
 		{};
 	};
 protected:
@@ -109,14 +110,14 @@ class LLSideTray : public LLPanel
 		Optional<S32>				default_button_height;
 		Optional<S32>				default_button_margin;
 		
-		Params():
-			collapsed("collapsed",false)
-			,tab_btn_image_normal("tab_btn_image","sidebar_tab_left.tga")
-			,tab_btn_image_selected("tab_btn_image_selected","button_enabled_selected_32x128.tga")
-			,default_button_width("tab_btn_width",32)
-			,default_button_height("tab_btn_height",32)
-			,default_button_margin("tab_btn_margin",0)
-			{};
+		Params()
+		:	collapsed("collapsed",false),
+			tab_btn_image_normal("tab_btn_image","sidebar_tab_left.tga"),
+			tab_btn_image_selected("tab_btn_image_selected","button_enabled_selected_32x128.tga"),
+			default_button_width("tab_btn_width",32),
+			default_button_height("tab_btn_height",32),
+			default_button_margin("tab_btn_margin",0)
+		{};
 	};
 
 	static LLSideTray*	getInstance		();
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 211a441d64adbd945623d43aad25d540ffed8f3a..d792b972bb882c80025e76c6b9c9487dd565b6de 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -60,7 +60,7 @@
 #include "llscrollcontainer.h"
 #include "lltoolmgr.h"
 #include "lltoolpipette.h"
-#include "llsearcheditor.h"
+#include "llfiltereditor.h"
 
 #include "lltool.h"
 #include "llviewerwindow.h"
@@ -130,7 +130,7 @@ class LLFloaterTexturePicker : public LLFloater
 	void updateFilterPermMask();
 	void commitIfImmediateSet();
 	
-	void onSearchEdit(const std::string& search_string );
+	void onFilterEdit(const std::string& search_string );
 	
 	static void		onBtnSetToDefault( void* userdata );
 	static void		onBtnSelect( void* userdata );
@@ -164,7 +164,7 @@ class LLFloaterTexturePicker : public LLFloater
 	std::string			mPendingName;
 	BOOL				mActive;
 
-	LLSearchEditor*		mSearchEdit;
+	LLFilterEditor*		mFilterEdit;
 	LLInventoryPanel*	mInventoryPanel;
 	PermissionMask		mImmediateFilterPermMask;
 	PermissionMask		mNonImmediateFilterPermMask;
@@ -191,7 +191,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
 	mTentativeLabel(NULL),
 	mResolutionLabel(NULL),
 	mActive( TRUE ),
-	mSearchEdit(NULL),
+	mFilterEdit(NULL),
 	mImmediateFilterPermMask(immediate_filter_perm_mask),
 	mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
 	mContextConeOpacity(0.f)
@@ -335,9 +335,9 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
 {
 	LLFolderView* root_folder = mInventoryPanel->getRootFolder();
 
-	if (root_folder && mSearchEdit)
+	if (root_folder && mFilterEdit)
 	{
-		if (mSearchEdit->hasFocus() 
+		if (mFilterEdit->hasFocus() 
 			&& (key == KEY_RETURN || key == KEY_DOWN) 
 			&& mask == MASK_NONE)
 		{
@@ -362,7 +362,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
 		
 		if (mInventoryPanel->hasFocus() && key == KEY_UP)
 		{
-			mSearchEdit->focusFirstItem(TRUE);
+			mFilterEdit->focusFirstItem(TRUE);
 		}
 	}
 
@@ -404,8 +404,8 @@ BOOL LLFloaterTexturePicker::postBuild()
 	childSetCommitCallback("show_folders_check", onShowFolders, this);
 	childSetVisible("show_folders_check", FALSE);
 
-	mSearchEdit = getChild<LLSearchEditor>("inventory search editor");
-	mSearchEdit->setSearchCallback(boost::bind(&LLFloaterTexturePicker::onSearchEdit, this, _1));
+	mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
+	mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
 
 	mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
 
@@ -524,7 +524,7 @@ void LLFloaterTexturePicker::draw()
 	childSetValue("Pipette", LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
 
 	//RN: reset search bar to reflect actual search query (all caps, for example)
-	mSearchEdit->setText(mInventoryPanel->getFilterSubString());
+	mFilterEdit->setText(mInventoryPanel->getFilterSubString());
 
 	//BOOL allow_copy = FALSE;
 	if( mOwner ) 
@@ -797,7 +797,7 @@ void LLFloaterTexturePicker::updateFilterPermMask()
 	//mInventoryPanel->setFilterPermMask( getFilterPermMask() );  Commented out due to no-copy texture loss.
 }
 
-void LLFloaterTexturePicker::onSearchEdit(const std::string& search_string )
+void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
 {
 	std::string upper_case_search_string = search_string;
 	LLStringUtil::toUpper(upper_case_search_string);
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index e30cdb2e973ccb1594f5f60b56cca50732c0cb66..0b232da62b547284bdf4d67dc69d5d03748ec351 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -84,7 +84,7 @@ class LLTextureCtrl
 
 		Params()
 		:	image_id("image"),
-			default_image_id("default_image"),
+			default_image_id("default_image_id"),
 			default_image_name("default_image_name"),
 			allow_no_texture("allow_no_texture"),
 			can_apply_immediately("can_apply_immediately"),
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 954418f7fb7ee66b5996381ceb17c14c2dc301ef..9144f9c3e07fdd8cce790722b62e2196730ffb57 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -32,9 +32,11 @@
 
 #include "llviewerprecompiledheaders.h" // must be first include
 
-#include "llfocusmgr.h"
 #include "lltoast.h"
 
+#include "llbutton.h"
+#include "llfocusmgr.h"
+
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index c43618d33050fdd5953ceb3457f8292d5c63527e..a7b57802c1d28439da8552af011e6c90572a1831 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -174,7 +174,7 @@ LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : LLToas
 		params.max_text_length(MAX_LENGTH);
 		params.default_text(mMessage);
 		params.font(sFont);
-		params.allow_embedded_items(false);
+		params.embedded_items(false);
 		params.word_wrap(true);
 		params.tab_stop(false);
 		params.mouse_opaque(false);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 8f1b105ba603076ac3a0b17bebab7f74d8432eba..74ded991246bf532740cb8b12bc0123e74a2a0cf 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1719,7 +1719,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				LLSD args;
 				args["SUBJECT"] = subj;
 				args["MESSAGE"] = mes;
-				LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).timestamp(timestamp));
+				LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(timestamp));
 			}
 
 			// Also send down the old path for now.
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 24479485efc2f3b19eb9ee0deed9762869013954..3e86f48cc56c6d980dd0b97a84b71535041e005a 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -107,6 +107,7 @@
 #include "llfloatertools.h"
 #include "llfloaterworldmap.h"
 #include "llfocusmgr.h"
+#include "llfontfreetype.h"
 #include "llgesturemgr.h"
 #include "llglheaders.h"
 #include "llhoverview.h"
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 7703211c3d91b431644af386b95e5b9c6ba47391..dc5936a4357f23a748ebb87bb2d0631f9c20ce3a 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -1,4 +1,5 @@
 <textures version="101">
+  <!-- Please add new files alphabetically to prevent merge conflicts. JC -->
 
   <texture name="ScrollThumb_Horiz" file_name="widgets/ScrollThumb_Horiz.png" preload="true" scale.left="4" scale.top="10" scale.bottom="53" scale.right="4" />
   <texture name="ScrollThumb_Vert" file_name="widgets/ScrollThumb_Vert.png" preload="true" scale.left="4" scale.top="53" scale.bottom="10" scale.right="4" />
@@ -469,7 +470,6 @@
   <texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="true"/>
   <texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="true"/>
   <texture name="Icon_Gear_Press" file_name="windows/Icon_Gear_Press.png" preload="true"/>
-  
   <texture name="Stepper_Down_Disabled" file_name="widgets/Stepper_Down_Disabled.png" preload="true"/>
   <texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="true"/>
   <texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="true"/>
@@ -477,4 +477,5 @@
   <texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="true"/>
   <texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="true"/>
 
+  <!-- Please add new files alphabetically to prevent merge conflicts. JC -->
 </textures>
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 1fb09424615c44a30f5586fd237699e120ffe997..cb3388ccbc24356caae84f20350a32ca092fc648 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1147,7 +1147,7 @@ Go to World menu &gt; About Land or select another parcel to show its details.
                  name="online_status"
                  width="-1" />
                 <name_list.columns
-                 dynamicwidth="true"
+                 dynamic_width="true"
                  label="Name"
                  name="name" />
                 <name_list.columns
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 0856a787f39c7b87e67d8f7972fc360465145c8e..44c56e420742b89d225eeb0313a6c2ee79236478 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -2,25 +2,66 @@
 <floater
  background_visible="true"
  follows="left|top|right|bottom"
- height="200"
+ height="250"
  layout="topleft"
  left="0"
  name="panel_im"
  top="0"
+ can_dock="true"
+ can_minimize="false"
  visible="false" 
- width="300">
-  <text_editor
-   enabled="false"
-   type="string"
-   length="1"
-   top="20" 
-   follows="left|top|right"
-   font="SansSerif"
-   height="175"
-   layout="topleft"
-   left="5"
-   name="im_text"
-   width="290"
-   word_wrap="true">
-  </text_editor>
+ width="315">
+  <layout_stack follows="left|top|right|bottom"
+                height="235"
+                width="315"
+                layout="topleft"
+                orientation="horizontal"
+                name="im_panels"
+                top="16"
+                left="2">
+    <layout_panel
+      class="panel_im_control_panel"
+      name="panel_im_control_panel"
+      filename="panel_im_control_panel.xml"
+      layout="topleft"
+      top_delta="-3"
+      min_width="96" 
+      width="96"
+      height="225"
+      label="IM Control Panel"
+      user_resize="false" />
+    <layout_panel height="235"
+                  width="200"
+                  left_delta="96" 
+                  top="0"
+                  user_resize="false">
+      <button height="12"
+              top="8" 
+              label="&lt;&lt;"
+              layout="topleft"
+              width="35"
+              name="slide_left_btn" />
+      <button height="12"
+              top="8"
+              label="&gt;&gt;"
+              layout="topleft"
+              width="35"
+              name="slide_right_btn" />
+      <text_editor
+       enabled="false"
+       type="string"
+       length="1"
+       follows="left|top|right"
+       font="SansSerif"
+       height="185"
+       layout="topleft"
+       max_length="2147483647"
+       name="im_text"
+       width="195"
+       word_wrap="true">
+      </text_editor>
+      <line_editor name="chat_editor" height="20" layout="topleft" width="190">
+      </line_editor>
+    </layout_panel>
+  </layout_stack>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inspect.xml b/indra/newview/skins/default/xui/en/floater_inspect.xml
index b11b3e4df568bfd458c23315c68f3cdafb09be22..b43cdca0d10a680b704a099a555688beda47951f 100644
--- a/indra/newview/skins/default/xui/en/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/en/floater_inspect.xml
@@ -25,15 +25,15 @@
      tool_tip="Select an object from this list to highlight it in-world"
      top="20">
         <scroll_list.columns
-         dynamicwidth="true"
+         dynamic_width="true"
          label="Object Name"
          name="object_name" />
         <scroll_list.columns
-         dynamicwidth="true"
+         dynamic_width="true"
          label="Owner Name"
          name="owner_name" />
         <scroll_list.columns
-         dynamicwidth="true"
+         dynamic_width="true"
          label="Creator Name"
          name="creator_name" />
         <scroll_list.columns
diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml
index eb05fe18834ae7729834f0ec082e29df4e01a9b6..6a54c187cb7de40ab57371020e0dbd82d960532d 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory.xml
@@ -23,7 +23,7 @@
      name="Fetched">
         Fetched
     </floater.string>
-    <search_editor
+    <filter_editor
      follows="left|top|right"
      height="16"
      label="Type here to search"
diff --git a/indra/newview/skins/default/xui/en/floater_test_widgets.xml b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
index c6b158fe6f8f0551083cb4e6367f3da079d49569..c6c561b4978dde52684ab81a7a02f40ca50c3242 100644
--- a/indra/newview/skins/default/xui/en/floater_test_widgets.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
@@ -156,9 +156,9 @@
    width="200">
     Line Editor Sample Text
   </line_editor>
-  <!-- "search_editor" is a specialized line_editor that shows read-only
+  <!-- "filter_editor" is a specialized line_editor that shows read-only
        help text until the user clicks in the widget. -->
-  <search_editor
+  <filter_editor
    follows="left|top|right"
    height="20"
    label="Type here to search"
@@ -230,11 +230,11 @@
    tool_tip="scroll list" 
    layout="topleft">
     <scroll_list.columns
-     dynamicwidth="true"
+     dynamic_width="true"
      name="first_column"
      label="Column A"/>
     <scroll_list.columns
-     dynamicwidth="true"
+     dynamic_width="true"
      name="second_column"
      label="Column B"/>
   </scroll_list>
diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
index 8d855196103bc8c224044b9abdd2f293c787b530..dc048eb352cf7b2493e2781294554dbb818fa082 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -86,7 +86,7 @@
      name="show_folders_check"
      top="20"
      width="201" />
-    <search_editor
+    <filter_editor
      follows="left|top|right"
      height="16"
      label="Type here to search"
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 6934fad49581f6b9bd5cc11aaa773fc5fe7bb651..bbb17dfb8fb1cf125c97dcb2994416641106ae26 100644
--- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
@@ -163,6 +163,15 @@
          tool_tip="Closes the currently-displayed floater, if one exists"
          top_delta="0"
          width="85" />
+        <button
+         follows="left|top"
+         height="25"
+         label="Export Schema"
+         layout="topleft"
+         left_pad="10"
+         name="export_schema"
+         top_delta="0"
+         width="120" />
         <scroll_list
          bottom="525"
          column_padding="0"
@@ -185,7 +194,7 @@
              name="file_column"
              width="150" />
             <scroll_list.columns
-             dynamicwidth="true"
+             dynamic_width="true"
              label="Top-Level Node"
              name="top_level_node_column" />
         </scroll_list>
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 7ac068df4bacbe96f8cf563c1e17287f763feafe..bbef5a889295ce52a99ad9c591b4dcbac4e5f31c 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -13,6 +13,7 @@
  width="1000">
     <layout_stack
      border_size="0"
+     clip="false" 
      follows="left|right|bottom|top"
      height="28"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_friends.xml b/indra/newview/skins/default/xui/en/panel_friends.xml
index a151eed20f87aec840011b7f8d93f2bf6038b51b..3a35465df27f7c79c40d01a6ec332d7ad8a6e5a1 100644
--- a/indra/newview/skins/default/xui/en/panel_friends.xml
+++ b/indra/newview/skins/default/xui/en/panel_friends.xml
@@ -29,7 +29,7 @@
          tool_tip="Online status"
          width="20" />
         <scroll_list.columns
-         dynamicwidth="true"
+         dynamic_width="true"
          label="Name"
          name="friend_name"
          tool_tip="Name" />
diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5067b4c1d89078c8cf82fc62930eeeedbbc3d13b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="panel_im_control_panel"
+       width="96"
+       height="215"
+       border="false">
+
+  <avatar_icon name="avatar_icon"
+               width="96"
+               height="96" />
+
+  <button name="view_profile_btn"
+          label="View Profile"
+          left_delta="3"
+          width="90"
+		  height="20" />
+
+  <button name="add_friend_btn"
+          label="Add Friend"
+          width="90"
+          height="20" />
+
+  <button name="call_btn"
+          label="Call"
+          width="90"
+          height="20" />
+
+  <button name="share_btn"
+          label="Share"
+          width="90"
+          height="20" />
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 9d4c411201b3d8cf4e1171fe5b457412dcaf2d2c..c9a0b6bc38f32deb0540cc5528c59bee2236d38d 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -101,37 +101,21 @@
 <!--      top_delta="0" -->
 <!--      width="168" /> -->
     
-    <button
-     follows="right|top"
-     height="16"
-     image_disabled="Search"
-     image_disabled_selected="Search"
-     image_selected="Search"
-     image_unselected="Search"
-     layout="topleft"
-     left_pad="5"
-     name="search_btn"
-     picture_style="true"
-     scale_image="false"
-     tool_tip="Search"
-     top_delta="2"
-     width="16" />
-    
-    <line_editor
+    <search_editor
      bevel_style="none"
      border_style="line"
      border.border_thickness="0"
      commit_on_focus_lost="false"
      follows="right|top"
      halign="right"
-     height="18"
+     height="20"
      label="Search All"
      layout="topleft"
-     left_pad="2"
+     left_pad="5"
      mouse_opaque="false"
      name="search_input"
      tool_tip="Search All"
-     top_delta="-1"
+     top_delta="0"
      width="135" /> 
     
     <button
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 4fc47d1c425b56ce76cee2cec1a76ce0ad59e3ef..29f5d3aee8acb2758483e0b9d369d0f4f2b728a8 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -7,9 +7,10 @@
   height="465"
   follows="left|top|right|bottom"  
   background_visible="true"
+  bg_alpha_color="0.3 0.3 0.3 1"
   label="People"
   name="people_panel">
- <search_editor
+  <filter_editor
     layout="topleft"
     top="3"
     left="15"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index 61b0ac9b7272cd6fb0cd1ac8fd9fe48575294167..c91cb2394cd5584fff1da87a176d6465e020c1a8 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -19,7 +19,7 @@
      name="teleport_history_tab_title">
         Teleport History
     </panel.string>
-    <search_editor
+    <filter_editor
      follows="left|top|right"
      height="20"
      label="Filter"
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
index 330bc362d2ecf352cebea2889ac57e0e1c24f2ad..05ebcbb50b4c348c4b8fa57bd8a2a30541460fdb 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -6,7 +6,7 @@
 	     multi_select="false" name="history_items" search_column="1"
 	     sort_column="1" height="326" width="380" >
 		<column name="landmark_icon" width="20" />
-		<column dynamicwidth="true" label="Region" name="region" />
+		<column dynamic_width="true" label="Region" name="region" />
 		<column name="index" width="0" />
 	</scroll_list>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index c6ee2ce364b2214b59799676ecbed76f61bc74e2..149da313a2609b776d1d5f1e70ff92d75f7997c1 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -82,6 +82,8 @@
 	<string name="BUTTON_MINIMIZE">Minimize</string>
 	<string name="BUTTON_TEAR_OFF">Tear Off</string>
 	<string name="BUTTON_EDIT">Edit</string>
+  <string name="BUTTON_DOCK">Dock</string>
+  <string name="BUTTON_UNDOCK">Undock</string>
 
 	<!-- searching - generic -->
 	<string name="Searching">Searching...</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f77aa396ec00329e7ed336f68d6a60aa737a8ba8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<filter_editor select_on_focus="true"
+               background="TextField_Search_Off" >
+  <clear_filter_button label="" 
+                       image_unselected="Icon_Close_Foreground"
+                       image_selected="Icon_Close_Press" />
+</filter_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/line_editor.xml b/indra/newview/skins/default/xui/en/widgets/line_editor.xml
index 168609d5d7a34d2229794615fa71db7fb7b68c44..08205cacbcf582f3cb10009466c4a10d06406914 100644
--- a/indra/newview/skins/default/xui/en/widgets/line_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/line_editor.xml
@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<line_editor background_image="TextField_Off"
+<line_editor
+  background_image="TextField_Off"
+  background_image_disabled="TextField_Disabled"
+  background_image_focused="TextField_Active"
              select_on_focus="false"
              handle_edit_keys_directly="false"
              commit_on_focus_lost="true"
@@ -8,9 +11,8 @@
              text_color="TextFgColor"
              text_readonly_color="Green"
              text_tentative_color="TextFgTentativeColor"
-             bg_readonly_color="TextBgReadOnlyColor"
-             bg_writeable_color="TextBgWriteableColor"
-             bg_focus_color="TextBgFocusColor"
+			 highlight_color="EmphasisColor"
+			 preedit_bg_color="White"
              mouse_opaque="true"
              name="line_editor"
              font="SansSerifSmall">
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
index 9e2c52accaa224c346f06c817a05619fecbf6584..e3a53eee4dce9e3e61f81c70dc70aa18ec9da822 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
@@ -4,7 +4,7 @@
              bg_selected_color="ScrollSelectedBGColor"
              fg_disable_color="ScrollDisabledColor"
              bg_writeable_color="ScrollBgWriteableColor"
-             bg_read_only_color="ScrollBgReadOnlyColor"
+             bg_readonly_color="ScrollBgReadOnlyColor"
              bg_stripe_color="ScrollBGStripeColor"
              hovered_color="ScrollHoveredColor"
              highlighted_color="ScrollHighlightedColor"
diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
index 67588d76ca22ba23ec8dccd83ab709b7c6845b87..6f557e239d9bfa7ed0fbf03b458aa38fdc97d86d 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<search_editor select_on_focus="true">
-  <clear_search_button image_unselected="TextField_Search_Off"
-                       image_selected="TextField_Search_Active"
-                       image_disabled="TextField_Search_Disabled"
-                       image_color="TextFgTentativeColor"/>
+<search_editor
+  select_on_focus="true"
+  background_image="TextField_Search_Off"
+  background_image_disabled="TextField_Search_Disabled"
+  background_image_focused="TextField_Search_Active" >
+  <search_button label=""
+	  image_unselected="Search"
+	  image_selected="Search" />
 </search_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
index b39c2991a04e7f23fcd6c53452a62391ef8f99f5..960c4e81e5e224ae25b66f3d222b417a70f64c1b 100644
--- a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
@@ -1,11 +1,23 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<simple_text_editor cursor_color="TextCursorColor"
-                    default_color="TextDefaultColor"
-                    text_color="TextFgColor"
-                    text_readonly_color="TextFgReadOnlyColor"
-                    bg_readonly_color="TextBgReadOnlyColor"
-                    bg_writeable_color="TextBgWriteableColor"
-                    bg_focus_color="TextBgFocusColor"
-                    hide_border="true"
-                    hide_scrollbar="false"
-                    font="SansSerif"/>
+<simple_text_editor
+  mouse_opaque="true"
+  font="SansSerifSmall"
+  max_length="255" 
+  embedded_items="false" 
+  hide_scrollbar="false"
+  hide_border="true"
+  word_wrap="false" 
+  ignore_tab="true"
+  track_bottom="false" 
+  takes_non_scroll_clicks="true" 
+  cursor_color="TextCursorColor"
+  default_color="TextDefaultColor"
+  text_color="TextFgColor"
+  text_readonly_color="TextFgReadOnlyColor"
+  bg_readonly_color="TextBgReadOnlyColor"
+  bg_writeable_color="TextBgWriteableColor"
+  bg_focus_color="TextBgFocusColor">
+  <simple_text_editor.border
+    bevel_style="in"
+    follows="all" />
+</simple_text_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/text_editor.xml b/indra/newview/skins/default/xui/en/widgets/text_editor.xml
index a613c43f907b0aab02e48a5fe4b649af6d84e1ef..deaade04f86eae59b4300e7322a64d602cc7e991 100644
--- a/indra/newview/skins/default/xui/en/widgets/text_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/text_editor.xml
@@ -1,19 +1,4 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<line_editor background_image="TextField_Off"
-             select_on_focus="false"
-             handle_edit_keys_directly="false"
-             commit_on_focus_lost="true"
-             ignore_tab="true"
-             cursor_color="TextCursorColor"
-             text_color="TextFgColor"
-             text_readonly_color="TextFgReadOnlyColor"
-             text_tentative_color="TextFgTentativeColor"
-             bg_readonly_color="TextBgReadOnlyColor"
-             bg_writeable_color="TextBgWriteableColor"
-             bg_focus_color="TextBgFocusColor"
-             mouse_opaque="true"
-             name="line_editor"
-             font="SansSerifSmall">
-  <line_editor.border bevel_style="in"
-                      follows="all" />
-</line_editor>
+<!-- Core parameters are in simple_text_editor.xml -->
+<text_editor
+  allow_html="false" />