diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 772f173f1748e9edabc3281e2ed6b43feb0803d0..b50ed2342d849e217252a3be828c9301b3836167 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -34,6 +34,7 @@ set(llui_SOURCE_FILES
     llbadgeholder.cpp
     llbadgeowner.cpp
     llbutton.cpp
+    llchatentry.cpp
     llcheckboxctrl.cpp
     llclipboard.cpp
     llcombobox.cpp
@@ -133,6 +134,7 @@ set(llui_HEADER_FILES
     llbadgeowner.h
     llbutton.h
     llcallbackmap.h
+    llchatentry.h
     llcheckboxctrl.h
     llclipboard.h
     llcombobox.h
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index c025cd7939e5443cd6581d24be2821d0fd199b80..43462bd2447687df1eb83b407eaa8fc12f63009f 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -184,7 +184,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitleFontStyle(std::string
 	if (mHeaderTextbox)
 	{
 		std::string text = mHeaderTextbox->getText();
-		mStyleParams.font(mHeaderTextbox->getDefaultFont());
+		mStyleParams.font(mHeaderTextbox->getFont());
 		mStyleParams.font.style(style);
 		mHeaderTextbox->setText(text, mStyleParams);
 	}
diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1da7900f59f881d71d0715847b9b95f0cd76ac42
--- /dev/null
+++ b/indra/llui/llchatentry.cpp
@@ -0,0 +1,198 @@
+/**
+ * @file llchatentry.cpp
+ * @brief LLChatEntry implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llchatentry.h"
+
+static LLDefaultChildRegistry::Register<LLChatEntry> r("text_editor");
+
+LLChatEntry::Params::Params()
+:	has_history("has_history", true),
+ 	is_expandable("is_expandable", false),
+ 	expand_lines_count("expand_lines_count", 1)
+{}
+
+LLChatEntry::LLChatEntry(const Params& p)
+:	LLTextEditor(p),
+ 	mTextExpandedSignal(NULL),
+ 	mHasHistory(p.has_history),
+ 	mIsExpandable(p.is_expandable),
+ 	mExpandLinesCount(p.expand_lines_count),
+ 	mPrevLinesCount(0)
+{
+	// Initialize current history line iterator
+	mCurrentHistoryLine = mLineHistory.begin();
+
+	mAutoIndent = false;
+}
+
+LLChatEntry::~LLChatEntry()
+{
+	delete mTextExpandedSignal;
+}
+
+void LLChatEntry::draw()
+{
+	LLTextEditor::draw();
+
+	if(mIsExpandable)
+	{
+		expandText();
+	}
+}
+
+void LLChatEntry::onCommit()
+{
+	updateHistory();
+	LLTextEditor::onCommit();
+}
+
+boost::signals2::connection LLChatEntry::setTextExpandedCallback(const commit_signal_t::slot_type& cb)
+{
+	if (!mTextExpandedSignal)
+	{
+		mTextExpandedSignal = new commit_signal_t();
+	}
+	return mTextExpandedSignal->connect(cb);
+}
+
+void LLChatEntry::expandText()
+{
+	int visible_lines_count = llabs(getVisibleLines(true).first - getVisibleLines(true).second);
+	bool can_expand = getLineCount() <= mExpandLinesCount;
+
+	// true if pasted text has more lines than expand height limit and expand limit is not reached yet
+	bool text_pasted = (getLineCount() > mExpandLinesCount) && (visible_lines_count < mExpandLinesCount);
+
+	if (mIsExpandable && (can_expand || text_pasted) && getLineCount() != mPrevLinesCount)
+	{
+		int lines_height = 0;
+		if (text_pasted)
+		{
+			// text is pasted and now mLineInfoList.size() > mExpandLineCounts and mLineInfoList is not empty,
+			// so lines_height is the sum of the last 'mExpandLinesCount' lines height
+			lines_height = (mLineInfoList.end() - mExpandLinesCount)->mRect.mTop - mLineInfoList.back().mRect.mBottom;
+		}
+		else
+		{
+			lines_height = mLineInfoList.begin()->mRect.mTop - mLineInfoList.back().mRect.mBottom;
+		}
+
+		int height = mVPad * 2 +  lines_height;
+
+		LLRect doc_rect = getRect();
+		doc_rect.setOriginAndSize(doc_rect.mLeft, doc_rect.mBottom, doc_rect.getWidth(), height);
+		setShape(doc_rect);
+
+		mPrevLinesCount = getLineCount();
+
+		if (mTextExpandedSignal)
+		{
+			(*mTextExpandedSignal)(this, LLSD() );
+		}
+	}
+}
+
+// line history support
+void LLChatEntry::updateHistory()
+{
+	// On history enabled, remember committed line and
+	// reset current history line number.
+	// Be sure only to remember lines that are not empty and that are
+	// different from the last on the list.
+	if (mHasHistory && getLength())
+	{
+		// Add text to history, ignoring duplicates
+		if (mLineHistory.empty() || getText() != mLineHistory.back())
+		{
+			mLineHistory.push_back(getText());
+		}
+
+		mCurrentHistoryLine = mLineHistory.end();
+	}
+}
+
+BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
+{
+	BOOL handled = FALSE;
+
+	LLTextEditor::handleSpecialKey(key, mask);
+
+	switch(key)
+	{
+	case KEY_RETURN:
+		if (MASK_NONE == mask)
+		{
+			needsReflow();
+		}
+		break;
+
+	case KEY_UP:
+		if (mHasHistory && MASK_CONTROL == mask)
+		{
+			if (!mLineHistory.empty() && mCurrentHistoryLine > mLineHistory.begin())
+			{
+				setText(*(--mCurrentHistoryLine));
+				endOfDoc();
+			}
+			else
+			{
+				LLUI::reportBadKeystroke();
+			}
+			handled = TRUE;
+		}
+		break;
+
+	case KEY_DOWN:
+		if (mHasHistory && MASK_CONTROL == mask)
+		{
+			if (!mLineHistory.empty() && ++mCurrentHistoryLine < mLineHistory.end())
+			{
+				setText(*mCurrentHistoryLine);
+				endOfDoc();
+			}
+			else if (!mLineHistory.empty() && mCurrentHistoryLine == mLineHistory.end())
+			{
+				std::string empty("");
+				setText(empty);
+				needsReflow();
+				endOfDoc();
+			}
+			else
+			{
+				LLUI::reportBadKeystroke();
+			}
+			handled = TRUE;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return handled;
+}
diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h
new file mode 100644
index 0000000000000000000000000000000000000000..10a4594e83f80b2e1537c98afa45ed0beb0a3d2e
--- /dev/null
+++ b/indra/llui/llchatentry.h
@@ -0,0 +1,98 @@
+/**
+ * @file llchatentry.h
+ * @author Paul Guslisty
+ * @brief Text editor widget which is used for user input
+ *
+ * Features:
+ *			Optional line history so previous entries can be recalled by CTRL UP/DOWN
+ *			Optional auto-resize behavior on input chat field
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLCHATENTRY_H_
+#define LLCHATENTRY_H_
+
+#include "lltexteditor.h"
+
+class LLChatEntry : public LLTextEditor
+{
+public:
+
+	struct Params : public LLInitParam::Block<Params, LLTextEditor::Params>
+	{
+		Optional<bool>		has_history,
+							is_expandable;
+
+		Optional<int>		expand_lines_count;
+
+		Params();
+	};
+
+	virtual ~LLChatEntry();
+
+protected:
+
+	friend class LLUICtrlFactory;
+	LLChatEntry(const Params& p);
+
+public:
+
+	virtual void	draw();
+	virtual	void	onCommit();
+
+	boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);
+
+private:
+
+	/**
+	 * Implements auto-resize behavior.
+	 * When user's typing reaches the right edge of the chat field
+	 * the chat field expands vertically by one line. The bottom of
+	 * the chat field remains bottom-justified. The chat field does
+	 * not expand beyond mExpandLinesCount.
+	 */
+	void	expandText();
+
+	/**
+	 * Implements line history so previous entries can be recalled by CTRL UP/DOWN
+	 */
+	void	updateHistory();
+
+	BOOL	handleSpecialKey(const KEY key, const MASK mask);
+
+
+	// Fired when text height expanded to mExpandLinesCount
+	commit_signal_t*			mTextExpandedSignal;
+
+	// line history support:
+	typedef std::vector<std::string>	line_history_t;
+	line_history_t::iterator			mCurrentHistoryLine;	// currently browsed history line
+	line_history_t						mLineHistory;			// line history storage
+	bool								mHasHistory;			// flag for enabled/disabled line history
+	bool								mIsExpandable;
+
+	int									mExpandLinesCount;
+	int									mPrevLinesCount;
+};
+
+#endif /* LLCHATENTRY_H_ */
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7aeeae298f754407abcf026372b21c6d6935ba8b..c112a7e477f78c1c55b903b9a6332e28956e3bf1 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -144,6 +144,7 @@ LLTextBase::Params::Params()
 :	cursor_color("cursor_color"),
 	text_color("text_color"),
 	text_readonly_color("text_readonly_color"),
+	text_tentative_color("text_tentative_color"),
 	bg_visible("bg_visible", false),
 	border_visible("border_visible", false),
 	bg_readonly_color("bg_readonly_color"),
@@ -177,7 +178,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 :	LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
 	mURLClickSignal(NULL),
 	mMaxTextByteLength( p.max_text_length ),
-	mDefaultFont(p.font),
+	mFont(p.font),
 	mFontShadow(p.font_shadow),
 	mPopupMenu(NULL),
 	mReadOnly(p.read_only),
@@ -185,6 +186,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 	mFgColor(p.text_color),
 	mBorderVisible( p.border_visible ),
 	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),
@@ -297,21 +299,21 @@ bool LLTextBase::truncate()
 	return did_truncate;
 }
 
-const LLStyle::Params& LLTextBase::getDefaultStyleParams()
+const LLStyle::Params& LLTextBase::getStyleParams()
 {
 	//FIXME: convert mDefaultStyle to a flyweight http://www.boost.org/doc/libs/1_40_0/libs/flyweight/doc/index.html
 	//and eliminate color member values
 	if (mStyleDirty)
 	{
-		  mDefaultStyle
+		  mStyle
 				  .color(LLUIColor(&mFgColor))						// pass linked color instead of copy of mFGColor
 				  .readonly_color(LLUIColor(&mReadOnlyFgColor))
 				  .selected_color(LLUIColor(&mTextSelectedColor))
-				  .font(mDefaultFont)
+				  .font(mFont)
 				  .drop_shadow(mFontShadow);
 		  mStyleDirty = false;
 	}
-	return mDefaultStyle;
+	return mStyle;
 }
 
 void LLTextBase::onValueChange(S32 start, S32 end)
@@ -500,11 +502,17 @@ void LLTextBase::drawCursor()
 
 void LLTextBase::drawText()
 {
-	const S32 text_len = getLength();
-	if( text_len <= 0 )
+	S32 text_len = getLength();
+
+	if (text_len <= 0 && mLabel.empty())
 	{
 		return;
 	}
+	else if (text_len <= 0 && !mLabel.empty())
+	{
+		text_len = mLabel.length();
+	}
+
 	S32 selection_left = -1;
 	S32 selection_right = -1;
 	// Draw selection even if we don't have keyboard focus for search/replace
@@ -624,7 +632,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
 	else
 	{
 		// create default editable segment to hold new text
-		LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+		LLStyleConstSP sp(new LLStyle(getStyleParams()));
 		default_segment = new LLNormalTextSegment( sp, pos, pos + insert_len, *this);
 	}
 
@@ -749,7 +757,7 @@ void LLTextBase::createDefaultSegment()
 	// ensures that there is always at least one segment
 	if (mSegments.empty())
 	{
-		LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+		LLStyleConstSP sp(new LLStyle(getStyleParams()));
 		LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this);
 		mSegments.insert(default_segment);
 		default_segment->linkToDocument(this);
@@ -1103,6 +1111,22 @@ void LLTextBase::deselect()
 	mIsSelecting = FALSE;
 }
 
+void LLTextBase::onFocusReceived()
+{
+	if (!getLength() && !mLabel.empty())
+	{
+		// delete label which is LLLabelTextSegment
+		clearSegments();
+	}
+}
+
+void LLTextBase::onFocusLost()
+{
+	if (!getLength() && !mLabel.empty())
+	{
+		resetLabel();
+	}
+}
 
 // Sets the scrollbar from the cursor position
 void LLTextBase::updateScrollFromCursor()
@@ -1688,7 +1712,7 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name)
 void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params)
 {
 	LLStyle::Params style_params(input_params);
-	style_params.fillFrom(getDefaultStyleParams());
+	style_params.fillFrom(getStyleParams());
 
 	S32 part = (S32)LLTextParser::WHOLE;
 	if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358).
@@ -1770,6 +1794,39 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
 	appendTextImpl(new_text,input_params);
 }
 
+void LLTextBase::setLabel(const LLStringExplicit& label)
+{
+	mLabel = label;
+	resetLabel();
+}
+
+BOOL LLTextBase::setLabelArg(const std::string& key, const LLStringExplicit& text )
+{
+	mLabel.setArg(key, text);
+	return TRUE;
+}
+
+void LLTextBase::resetLabel()
+{
+	if (!getLength() && !mLabel.empty() && !hasFocus())
+	{
+		clearSegments();
+
+		LLStyle* style = new LLStyle(getStyleParams());
+		style->setColor(mTentativeFgColor);
+		LLStyleConstSP sp(style);
+
+		LLTextSegmentPtr label = new LLLabelTextSegment(sp, 0, getLabel().length() + 1, *this);
+		insertSegment(label);
+	}
+}
+
+void LLTextBase::setFont(const LLFontGL* font)
+{
+	mFont = font;
+	mStyleDirty = true;
+}
+
 void LLTextBase::needsReflow(S32 index)
 {
 	lldebugs << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << llendl;
@@ -2160,7 +2217,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
 	{ 
 		// return default height rect in upper left
 		local_rect = content_window_rect;
-		local_rect.mBottom = local_rect.mTop - mDefaultFont->getLineHeight();
+		local_rect.mBottom = local_rect.mTop - mFont->getLineHeight();
 		return local_rect;
 	}
 
@@ -2665,7 +2722,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
 {
 	F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
 
-	const LLWString &text = mEditor.getWText();
+	const LLWString &text = getWText();
 
 	F32 right_x = rect.mLeft;
 	if (!mStyle->isVisible())
@@ -2828,7 +2885,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
 	if (num_chars > 0)
 	{
 		height = mFontHeight;
-		const LLWString &text = mEditor.getWText();
+		const LLWString &text = getWText();
 		// if last character is a newline, then return true, forcing line break
 		width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
 	}
@@ -2837,7 +2894,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
 
 S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
 {
-	const LLWString &text = mEditor.getWText();
+	const LLWString &text = getWText();
 	return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset,
 											   (F32)segment_local_x_coord,
 											   F32_MAX,
@@ -2847,7 +2904,7 @@ S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset,
 
 S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
 {
-	const LLWString &text = mEditor.getWText();
+	const LLWString &text = getWText();
 
 	LLUIImagePtr image = mStyle->getImage();
 	if( image.notNull())
@@ -2883,7 +2940,7 @@ S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 	S32 last_char_in_run = mStart + segment_offset + num_chars;
 	// check length first to avoid indexing off end of string
 	if (last_char_in_run < mEnd 
-		&& (last_char_in_run >= mEditor.getLength() ))
+		&& (last_char_in_run >= getLength()))
 	{
 		num_chars++;
 	}
@@ -2901,6 +2958,39 @@ void LLNormalTextSegment::dump() const
 		llendl;
 }
 
+/*virtual*/
+const LLWString& LLNormalTextSegment::getWText()	const
+{
+	return mEditor.getWText();
+}
+
+/*virtual*/
+const S32 LLNormalTextSegment::getLength() const
+{
+	return mEditor.getLength();
+}
+
+LLLabelTextSegment::LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor )
+:	LLNormalTextSegment(style, start, end, editor)
+{
+}
+
+LLLabelTextSegment::LLLabelTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible)
+:	LLNormalTextSegment(color, start, end, editor, is_visible)
+{
+}
+
+/*virtual*/
+const LLWString& LLLabelTextSegment::getWText()	const
+{
+	return mEditor.getWlabel();
+}
+/*virtual*/
+const S32 LLLabelTextSegment::getLength() const
+{
+	return mEditor.getLabel().length();
+}
+
 //
 // LLOnHoverChangeableTextSegment
 //
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 0549141b72a20531d5b10af3601bbf36eeb52bf9..412272b3522998139d406ea2fb46b9f2a73211de 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -105,7 +105,7 @@ class LLNormalTextSegment : public LLTextSegment
 public:
 	LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
 	LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
-	~LLNormalTextSegment();
+	virtual ~LLNormalTextSegment();
 
 	/*virtual*/ bool				getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
 	/*virtual*/ S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
@@ -130,6 +130,9 @@ class LLNormalTextSegment : public LLTextSegment
 protected:
 	F32					drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRect rect);
 
+	virtual		const LLWString&	getWText()	const;
+	virtual		const S32			getLength()	const;
+
 protected:
 	class LLTextBase&	mEditor;
 	LLStyleConstSP		mStyle;
@@ -139,6 +142,21 @@ class LLNormalTextSegment : public LLTextSegment
 	boost::signals2::connection mImageLoadedConnection;
 };
 
+// This text segment is the same as LLNormalTextSegment, the only difference
+// is that LLNormalTextSegment draws value of LLTextBase (LLTextBase::getWText()),
+// but LLLabelTextSegment draws label of the LLTextBase (LLTextBase::mLabel)
+class LLLabelTextSegment : public LLNormalTextSegment
+{
+public:
+	LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
+	LLLabelTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
+
+protected:
+
+	/*virtual*/	const LLWString&	getWText()	const;
+	/*virtual*/	const S32			getLength()	const;
+};
+
 // Text segment that changes it's style depending of mouse pointer position ( is it inside or outside segment)
 class LLOnHoverChangeableTextSegment : public LLNormalTextSegment
 {
@@ -249,6 +267,7 @@ class LLTextBase
 		Optional<LLUIColor>		cursor_color,
 								text_color,
 								text_readonly_color,
+								text_tentative_color,
 								bg_readonly_color,
 								bg_writeable_color,
 								bg_focus_color,
@@ -311,6 +330,9 @@ class LLTextBase
 	/*virtual*/ BOOL		canDeselect() const;
 	/*virtual*/ void		deselect();
 
+	virtual void	onFocusReceived();
+	virtual void	onFocusLost();
+
 	// used by LLTextSegment layout code
 	bool					getWordWrap() { return mWordWrap; }
 	bool					getUseEllipses() { return mUseEllipses; }
@@ -330,6 +352,21 @@ class LLTextBase
 	const LLWString&       	getWText() const;
 
 	void					appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
+
+	void					setLabel(const LLStringExplicit& label);
+	virtual BOOL			setLabelArg(const std::string& key, const LLStringExplicit& text );
+
+	const	std::string& 	getLabel()	{ return mLabel.getString(); }
+	const	LLWString&		getWlabel() { return mLabel.getWString();}
+
+	/**
+	 * If label is set, draws text label (which is LLLabelTextSegment)
+	 * that is visible when no user text provided and has no focus
+	 */
+	void					resetLabel();
+
+	void					setFont(const LLFontGL* font);
+
 	// force reflow of text
 	void					needsReflow(S32 index = 0);
 
@@ -369,7 +406,7 @@ class LLTextBase
 	bool					scrolledToStart();
 	bool					scrolledToEnd();
 
-	const LLFontGL*			getDefaultFont() const					{ return mDefaultFont; }
+	const LLFontGL*			getFont() const					{ return mFont; }
 
 	virtual void			appendLineBreakSegment(const LLStyle::Params& style_params);
 	virtual void			appendImageSegment(const LLStyle::Params& style_params);
@@ -469,7 +506,7 @@ class LLTextBase
 	void							createDefaultSegment();
 	virtual void					updateSegments();
 	void							insertSegment(LLTextSegmentPtr segment_to_insert);
-	const LLStyle::Params&			getDefaultStyleParams();
+	const LLStyle::Params&			getStyleParams();
 
 	//  manage lines
 	S32								getLineStart( S32 line ) const;
@@ -514,15 +551,16 @@ class LLTextBase
 	LLRect						mTextBoundingRect;
 
 	// default text style
-	LLStyle::Params				mDefaultStyle;
+	LLStyle::Params				mStyle;
 	bool						mStyleDirty;
-	const LLFontGL* const		mDefaultFont;		// font that is used when none specified, can only be set by constructor
-	const LLFontGL::ShadowType	mFontShadow;		// shadow style, can only be set by constructor
+	const LLFontGL*				mFont;
+	const LLFontGL::ShadowType	mFontShadow;
 
 	// colors
 	LLUIColor					mCursorColor;
 	LLUIColor					mFgColor;
 	LLUIColor					mReadOnlyFgColor;
+	LLUIColor					mTentativeFgColor;
 	LLUIColor					mWriteableBgColor;
 	LLUIColor					mReadOnlyBgColor;
 	LLUIColor					mFocusBgColor;
@@ -558,6 +596,7 @@ class LLTextBase
 	bool						mClip;				// clip text to widget rect
 	bool						mClipPartial;		// false if we show lines that are partially inside bounding rect
 	bool						mPlainText;			// didn't use Image or Icon segments
+	bool						mAutoIndent;
 	S32							mMaxTextByteLength;	// Maximum length mText is allowed to be in bytes
 
 	// support widgets
@@ -573,6 +612,7 @@ class LLTextBase
 	// Fired when a URL link is clicked
 	commit_signal_t*			mURLClickSignal;
 
+	LLUIString					mLabel;	// text label that is visible when no user text provided
 };
 
 #endif
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 9720dded6c658e5844fe04a949a5997b4060d742..4fa6ea085e74ddb37eeed365540f998518003303 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -235,6 +235,7 @@ LLTextEditor::Params::Params()
 	embedded_items("embedded_items", false),
 	ignore_tab("ignore_tab", true),
 	show_line_numbers("show_line_numbers", false),
+	auto_indent("auto_indent", true),
 	default_color("default_color"),
     commit_on_focus_lost("commit_on_focus_lost", false),
 	show_context_menu("show_context_menu")
@@ -249,6 +250,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
 	mLastCmd( NULL ),
 	mDefaultColor(		p.default_color() ),
 	mShowLineNumbers ( p.show_line_numbers ),
+	mAutoIndent(p.auto_indent),
 	mCommitOnFocusLost( p.commit_on_focus_lost),
 	mAllowEmbeddedItems( p.embedded_items ),
 	mMouseDownX(0),
@@ -256,7 +258,8 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
 	mTabsToNextField(p.ignore_tab),
 	mPrevalidateFunc(p.prevalidate_callback()),
 	mContextMenu(NULL),
-	mShowContextMenu(p.show_context_menu)
+	mShowContextMenu(p.show_context_menu),
+	mPassDelete(FALSE)
 {
 	mSourceID.generate();
 
@@ -1606,7 +1609,10 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask)
 			{
 				deleteSelection(FALSE);
 			}
-			autoIndent(); // TODO: make this optional
+			if (mAutoIndent)
+			{
+				autoIndent();
+			}
 		}
 		else
 		{
@@ -1746,7 +1752,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
 // virtual
 BOOL LLTextEditor::canDoDelete() const
 {
-	return !mReadOnly && ( hasSelection() || (mCursorPos < getLength()) );
+	return !mReadOnly && ( !mPassDelete || ( hasSelection() || (mCursorPos < getLength())) );
 }
 
 void LLTextEditor::doDelete()
@@ -1984,7 +1990,7 @@ void LLTextEditor::drawPreeditMarker()
 		return;
 	}
 		
-	const S32 line_height = mDefaultFont->getLineHeight();
+	const S32 line_height = mFont->getLineHeight();
 
 	S32 line_start = getLineStart(cur_line);
 	S32 line_y = mVisibleTextRect.mTop - line_height;
@@ -2023,16 +2029,16 @@ void LLTextEditor::drawPreeditMarker()
 				S32 preedit_left = mVisibleTextRect.mLeft;
 				if (left > line_start)
 				{
-					preedit_left += mDefaultFont->getWidth(text, line_start, left - line_start);
+					preedit_left += mFont->getWidth(text, line_start, left - line_start);
 				}
 				S32 preedit_right = mVisibleTextRect.mLeft;
 				if (right < line_end)
 				{
-					preedit_right += mDefaultFont->getWidth(text, line_start, right - line_start);
+					preedit_right += mFont->getWidth(text, line_start, right - line_start);
 				}
 				else
 				{
-					preedit_right += mDefaultFont->getWidth(text, line_start, line_end - line_start);
+					preedit_right += mFont->getWidth(text, line_start, line_end - line_start);
 				}
 
 				if (mPreeditStandouts[i])
@@ -2707,11 +2713,11 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
 
     const LLWString textString(getWText());
 	const llwchar * const text = textString.c_str();
-	const S32 line_height = mDefaultFont->getLineHeight();
+	const S32 line_height = mFont->getLineHeight();
 
 	if (coord)
 	{
-		const S32 query_x = mVisibleTextRect.mLeft + mDefaultFont->getWidth(text, current_line_start, query - current_line_start);
+		const S32 query_x = mVisibleTextRect.mLeft + mFont->getWidth(text, current_line_start, query - current_line_start);
 		const S32 query_y = mVisibleTextRect.mTop - (current_line - first_visible_line) * line_height - line_height / 2;
 		S32 query_screen_x, query_screen_y;
 		localPointToScreen(query_x, query_y, &query_screen_x, &query_screen_y);
@@ -2723,17 +2729,17 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
 		S32 preedit_left = mVisibleTextRect.mLeft;
 		if (preedit_left_position > current_line_start)
 		{
-			preedit_left += mDefaultFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
+			preedit_left += mFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
 		}
 
 		S32 preedit_right = mVisibleTextRect.mLeft;
 		if (preedit_right_position < current_line_end)
 		{
-			preedit_right += mDefaultFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
+			preedit_right += mFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
 		}
 		else
 		{
-			preedit_right += mDefaultFont->getWidth(text, current_line_start, current_line_end - current_line_start);
+			preedit_right += mFont->getWidth(text, current_line_start, current_line_end - current_line_start);
 		}
 
 		const S32 preedit_top = mVisibleTextRect.mTop - (current_line - first_visible_line) * line_height;
@@ -2810,7 +2816,7 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)
 
 S32 LLTextEditor::getPreeditFontSize() const
 {
-	return llround((F32)mDefaultFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+	return llround((F32)mFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
 }
 
 BOOL LLTextEditor::isDirty() const
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 40821ae9fbc58f994a81f58e03ca1522bcc5b46a..f8f636b876cb2efa27bda774b3955254bfdcf063 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -64,7 +64,8 @@ class LLTextEditor :
 								ignore_tab,
 								show_line_numbers,
 								commit_on_focus_lost,
-								show_context_menu;
+								show_context_menu,
+								auto_indent;
 
 		//colors
 		Optional<LLUIColor>		default_color;
@@ -202,6 +203,8 @@ class LLTextEditor :
 	void			setShowContextMenu(bool show) { mShowContextMenu = show; }
 	bool			getShowContextMenu() const { return mShowContextMenu; }
 
+	void			setPassDelete(BOOL b) { mPassDelete = b; }
+
 protected:
 	void			showContextMenu(S32 x, S32 y);
 	void			drawPreeditMarker();
@@ -214,8 +217,8 @@ class LLTextEditor :
 	S32				indentLine( S32 pos, S32 spaces );
 	void			unindentLineBeforeCloseBrace();
 
+	virtual	BOOL	handleSpecialKey(const KEY key, const MASK mask);
 	BOOL			handleNavigationKey(const KEY key, const MASK mask);
-	BOOL			handleSpecialKey(const KEY key, const MASK mask);
 	BOOL			handleSelectionKey(const KEY key, const MASK mask);
 	BOOL			handleControlKey(const KEY key, const MASK mask);
 
@@ -279,6 +282,7 @@ class LLTextEditor :
 	LLUIColor			mDefaultColor;
 
 	BOOL				mShowLineNumbers;
+	bool				mAutoIndent;
 
 	/*virtual*/ void	updateSegments();
 	void				updateLinkSegments();
@@ -321,6 +325,7 @@ class LLTextEditor :
 	BOOL			mAllowEmbeddedItems;
 	bool			mShowContextMenu;
 	bool			mParseOnTheFly;
+	bool			mPassDelete;
 
 	LLUUID			mSourceID;
 
diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index 935dcb74b0f8370c8df57fb3c0db77862f5ddb76..a50184460b74f65cb04b42cc6b32553fdbf4ce21 100644
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -150,7 +150,7 @@ void LLExpandableTextBox::LLTextBoxEx::showExpandText()
 		std::pair<S32, S32> visible_lines = getVisibleLines(true);
 		S32 last_line = visible_lines.second - 1;
 
-		LLStyle::Params expander_style(getDefaultStyleParams());
+		LLStyle::Params expander_style(getStyleParams());
 		expander_style.font.style = "UNDERLINE";
 		expander_style.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
 		LLExpanderSegment* expanderp = new LLExpanderSegment(new LLStyle(expander_style), getLineStart(last_line), getLength() + 1, mExpanderLabel, *this);
@@ -166,7 +166,7 @@ void LLExpandableTextBox::LLTextBoxEx::hideExpandText()
 	if (mExpanderVisible)
 	{
 		// this will overwrite the expander segment and all text styling with a single style
-		LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+		LLStyleConstSP sp(new LLStyle(getStyleParams()));
 		LLNormalTextSegment* segmentp = new LLNormalTextSegment(sp, 0, getLength() + 1, *this);
 		insertSegment(segmentp);
 		
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 2de891565caaf59717f094d00b2fd1aa033b39fb..aba3d74d878152478e2354ab87a9cb479682f8a1 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -406,7 +406,7 @@ void LLGroupListItem::setActive(bool active)
 	// *BUG: setName() overrides the style params.
 
 	// Active group should be bold.
-	LLFontDescriptor new_desc(mGroupNameBox->getDefaultFont()->getFontDesc());
+	LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
 
 	// *NOTE dzaporozhan
 	// On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font 
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 3e2b208874aedbbd943c2cda108e0bed0535a347..ead87e3ed523b6f7b04a194b9a9f7699f6f7ca15 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -236,6 +236,13 @@ void LLIMConversation::updateHeaderAndToolbar()
 	mCloseBtn->setVisible(is_hosted);
 
 	enableDisableCallBtn();
+
+	showTranslationCheckbox();
+}
+
+void LLIMConversation::showTranslationCheckbox(BOOL show)
+{
+	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(mIsNearbyChat? show : FALSE);
 }
 
 // static
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index d31ae0808abe9a8edfa2c4ee84c1474f458e40e2..66401b9a3ce23e1498835e3d42acc614e78e9084 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -56,6 +56,9 @@ class LLIMConversation
 	 */
 	static bool isChatMultiTab();
 
+	// show/hide the translation check box
+	void showTranslationCheckbox(const BOOL visible = FALSE);
+
 	// LLFloater overrides
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 14fcd602fc9a61e183a9a5815dcab9296d7e1233..882637151d9850df9f32aa43b3829826de366b8a 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -44,7 +44,7 @@
 #include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
 #include "llinventoryfunctions.h"
 //#include "lllayoutstack.h"
-#include "lllineeditor.h"
+#include "llchatentry.h"
 #include "lllogchat.h"
 #include "llscreenchannel.h"
 #include "llsyswellwindow.h"
@@ -64,6 +64,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mLastMessageIndex(-1),
 	mDialog(IM_NOTHING_SPECIAL),
 	mInputEditor(NULL),
+	mInputEditorTopPad(0),
 	mSavedTitle(),
 	mTypingStart(),
 	mShouldSendTypingState(false),
@@ -200,7 +201,9 @@ void LLIMFloater::sendMsg()
 	{
 		if (mInputEditor)
 		{
-			LLWString text = mInputEditor->getConvertedText();
+			LLWString text = mInputEditor->getWText();
+			LLWStringUtil::trim(text);
+			LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
 			if(!text.empty())
 			{
 				// Truncate and convert to UTF8 for transport
@@ -297,26 +300,26 @@ BOOL LLIMFloater::postBuild()
 {
 	LLIMConversation::postBuild();
 
-	mInputEditor = getChild<LLLineEditor>("chat_editor");
+	mInputEditor = getChild<LLChatEntry>("chat_editor");
 	mInputEditor->setMaxTextLength(1023);
 	// enable line history support for instant message bar
-	mInputEditor->setEnableLineHistory(TRUE);
 
 	LLFontGL* font = LLViewerChat::getChatFont();
 	mInputEditor->setFont(font);	
 	
 	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
 	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
-	mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
+	mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
 	mInputEditor->setCommitOnFocusLost( FALSE );
-	mInputEditor->setRevertOnEsc( FALSE );
-	mInputEditor->setReplaceNewlinesWithSpaces( FALSE );
 	mInputEditor->setPassDelete( TRUE );
 
-	childSetCommitCallback("chat_editor", onSendMsg, this);
+	mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this));
+	mInputEditor->setTextExpandedCallback(boost::bind(&LLIMFloater::reshapeChatHistory, this));
 	
 	mChatHistory = getChild<LLChatHistory>("chat_history");
 
+	mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop;
+
 	setDocked(true);
 
 	mTypingStart = LLTrans::getString("IM_typing_start_string");
@@ -890,7 +893,7 @@ void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userd
 }
 
 // static
-void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
+void LLIMFloater::onInputEditorKeystroke(LLTextEditor* caller, void* userdata)
 {
 	LLIMFloater* self = (LLIMFloater*) userdata;
 	std::string text = self->mInputEditor->getText();
@@ -1087,7 +1090,7 @@ class LLSessionInviteResponder: public LLHTTPClient::Responder
 BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
 {
 	LLViewerRegion* region = gAgent.getRegion();
-	bool is_region_exist = !!region;
+	bool is_region_exist = region != NULL;
 
 	if (is_region_exist)
 	{
@@ -1168,6 +1171,17 @@ void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
 	}
 }
 
+void LLIMFloater::reshapeChatHistory()
+{
+	LLRect chat_rect  = mChatHistory->getRect();
+	LLRect input_rect = mInputEditor->getRect();
+
+	int delta_height = chat_rect.mBottom - (input_rect.mTop + mInputEditorTopPad);
+
+	chat_rect.setLeftTopAndSize(chat_rect.mLeft, chat_rect.mTop, chat_rect.getWidth(), chat_rect.getHeight() + delta_height);
+	mChatHistory->setShape(chat_rect);
+}
+
 // static
 void LLIMFloater::closeHiddenIMToasts()
 {
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 333340c696268b32039ab1c2a2a8968c73d30e0b..1992bd930c1b82a511bbe73d78dfc9fe2c4df88b 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -37,7 +37,9 @@
 
 class LLAvatarName;
 class LLButton;
-class LLLineEditor;
+class LLChatEntry;
+class LLTextEditor;
+class LLPanelChatControlPanel;
 class LLChatHistory;
 class LLInventoryItem;
 class LLInventoryCategory;
@@ -142,7 +144,7 @@ class LLIMFloater
 	void appendMessage(const LLChat& chat, const LLSD &args = 0);
 	static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata );
 	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
-	static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
+	static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata);
 	void setTyping(bool typing);
 	void onAddButtonClicked();
 	void onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names);
@@ -161,6 +163,13 @@ class LLIMFloater
 	// Remove the "User is typing..." indicator.
 	void removeTypingIndicator(const LLIMInfo* im_info = NULL);
 
+	/**
+	 * Adjusts chat history height to fit vertically with input chat field
+	 * and avoid overlapping, since input chat field can be vertically expanded.
+	 * Implementation: chat history bottom "follows" top+top_pad of input chat field
+	 */
+	void reshapeChatHistory();
+
 	static void closeHiddenIMToasts();
 
 	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
@@ -171,9 +180,11 @@ class LLIMFloater
 
 	LLChatHistory* mChatHistory;
 
+	int mInputEditorTopPad; // padding between input field and chat history
+
 	EInstantMessage mDialog;
 	LLUUID mOtherParticipantUUID;
-	LLLineEditor* mInputEditor;
+	LLChatEntry* mInputEditor;
 	bool mPositioned;
 
 	std::string mSavedTitle;
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 04fb2f3b9a13ee0160b974b291d38709864d7118..10188febab1a1d18061ecb752cf7621368055dfc 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -96,8 +96,7 @@ void LLIMFloaterContainer::onOpen(const LLSD& key)
 		// If there's *no* conversation open so far, we force the opening of the nearby chat conversation
 		// *TODO: find a way to move this to XML as a default panel or something like that
 		LLSD name("chat_bar");
-		LLSD key("");
-		LLFloaterReg::toggleInstanceOrBringToFront(name,key);
+		LLFloaterReg::toggleInstanceOrBringToFront(name);
 	}
 	/*
 	if (key.isDefined())
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index fbaf45141247426fa4b1121ebd2300f85f6ff86b..1b2d9b68013777183721c115b3d0a9d2d1f79b82 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -130,6 +130,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key)
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
 {
+	mKey = LLSD();
 	mIsNearbyChat = true;
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
 }
@@ -382,11 +383,6 @@ LLNearbyChat* LLNearbyChat::getInstance()
 	return LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar");
 }
 
-//static
-//LLNearbyChat* LLNearbyChat::findInstance()
-//{
-//	return LLFloaterReg::findTypedInstance<LLNearbyChat>("chat_bar");
-//}
 
 void LLNearbyChat::showHistory()
 {
@@ -397,10 +393,6 @@ void LLNearbyChat::showHistory()
 	storeRectControl();
 }
 
-void LLNearbyChat::showTranslationCheckbox(BOOL show)
-{
-	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(show);
-}
 
 BOOL LLNearbyChat::tick()
 {
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index bc0e54de15d352cda6517154391996dfe1d1fa6c..3dc94ce0dabf140a284759174ca596640f0cca7e 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -87,7 +87,6 @@ class LLNearbyChat
 	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
 
 	void showHistory();
-	void showTranslationCheckbox(BOOL show);
 
 protected:
 	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp
index 280cc11179670ea84450245460433d7890a1cf7f..854deb00d0417e0b78f77889d1f5103cfe12b849 100644
--- a/indra/newview/llpaneltopinfobar.cpp
+++ b/indra/newview/llpaneltopinfobar.cpp
@@ -230,7 +230,7 @@ void LLPanelTopInfoBar::buildLocationString(std::string& loc_str, bool show_coor
 void LLPanelTopInfoBar::setParcelInfoText(const std::string& new_text)
 {
 	LLRect old_rect = getRect();
-	const LLFontGL* font = mParcelInfoText->getDefaultFont();
+	const LLFontGL* font = mParcelInfoText->getFont();
 	S32 new_text_width = font->getWidth(new_text);
 
 	mParcelInfoText->setText(new_text);
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 707d2d9765d33487ed6babb3a0afaf3c05b90b9f..ed350ea1444ae4718394fe029939a228d6f88ae7 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -112,7 +112,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
 		style.font = date_font;
 	pMessageText->appendText(timeStr + "\n", TRUE, style);
 	
-	style.font = pMessageText->getDefaultFont();
+	style.font = pMessageText->getFont();
 	pMessageText->appendText(message, TRUE, style);
 
 	//attachment
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index e20d516392c4f53849383f53178e4ff143a1382b..09f8dcf83c3122a059ec9ea6178e3d8f5f97e365 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -68,7 +68,7 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
 	if (message->getVisible())
 	{
 		S32 heightDelta = 0;
-		S32 maxTextHeight = message->getDefaultFont()->getLineHeight() * maxLineCount;
+		S32 maxTextHeight = message->getFont()->getLineHeight() * maxLineCount;
 
 		LLRect messageRect = message->getRect();
 		S32 oldTextHeight = messageRect.getHeight();
diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp
index 2529ec865a9b937f6dd4c96a3c91bd7909d5cfca..45fbabad59ecfc2358c5be25f76620077c244ce8 100644
--- a/indra/newview/lltoastscripttextbox.cpp
+++ b/indra/newview/lltoastscripttextbox.cpp
@@ -65,7 +65,7 @@ LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification
 	pMessageText->clear();
 
 	LLStyle::Params style;
-	style.font = pMessageText->getDefaultFont();
+	style.font = pMessageText->getFont();
 	pMessageText->appendText(message, TRUE, style);
 
 	//submit button
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 7f14e021fdd3ac59d18d72e061c666f2ddebf9d6..016da1d994aafd447a44a37dbfd4db9345fc4335 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2555,7 +2555,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && 
 		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
 	{
-		LLLineEditor* chat_editor = LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar")->getChatBox();
+		LLLineEditor* chat_editor = LLNearbyChat::getInstance()->getChatBox();
 		if (chat_editor)
 		{
 			// passing NULL here, character will be added later when it is handled by character handler.
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 a4695b8c097765b67b734a18d410064a52ef317a..f6d5b20a659924bb112f9c443e3fba036243470c 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -242,18 +242,21 @@
              bottom="-1" 
              follows="left|right|bottom" 
              tab_group="1">    
-            	<line_editor
+            	<text_editor
              		bottom="0"
+             		expand_lines_count="5"
              		follows="left|right|bottom"
 	         		font="SansSerifSmall"
 	         		visible="true"
              		height="20"
+             		is_expandable="true"
              		label="To"
              		layout="bottomleft"
              		name="chat_editor"
              		tab_group="3"
-             		width="220">
-            	</line_editor>
+             		width="240"
+             		wrap="true">
+            	</text_editor>
               </panel>
     </layout_panel>
   </layout_stack>
diff --git a/indra/newview/skins/default/xui/en/widgets/text.xml b/indra/newview/skins/default/xui/en/widgets/text.xml
index 134f2d75229719c15a16315adf11c8e609b1354f..210207467435b44ab7231f00ef05c95906f79649 100644
--- a/indra/newview/skins/default/xui/en/widgets/text.xml
+++ b/indra/newview/skins/default/xui/en/widgets/text.xml
@@ -9,6 +9,7 @@
       h_pad="0" 
       allow_scroll="false"
       text_readonly_color="LabelTextColor"
+      text_tentative_color="TextFgTentativeColor"
       bg_writeable_color="FloaterDefaultBackgroundColor" 
       use_ellipses="false"
       bg_visible="false"