diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 48d49af58810e4e4eccc3a73072ddd2821a431ae..2e64be89faed4a4a33ba7151d9dce2507bfc9e0c 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -157,8 +157,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 	mHighlightColor(p.highlight_color()),
 	mPreeditBgColor(p.preedit_bg_color()),
 	mGLFont(p.font),
-	mContextMenuHandle(),
-	mAutoreplaceCallback()
+	mContextMenuHandle()
 {
 	llassert( mMaxLengthBytes > 0 );
 
@@ -971,12 +970,6 @@ void LLLineEditor::addChar(const llwchar uni_char)
 		LLUI::reportBadKeystroke();
 	}
 
-	if (!mReadOnly && mAutoreplaceCallback != NULL)
-	{
-		// call callback
-		mAutoreplaceCallback(mText, mCursorPos);
-	}
-
 	getWindow()->hideCursorUntilMouseMove();
 }
 
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 71dd53f60838a880fa47a1230017d849492a18eb..40f931ecc1e9b0d08fefa7d8a85c1f9b1f7e1b5d 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -189,9 +189,6 @@ class LLLineEditor
 	virtual BOOL	setTextArg( const std::string& key, const LLStringExplicit& text );
 	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
 
-	typedef boost::function<void(LLUIString&, S32&)> autoreplace_callback_t;
-	autoreplace_callback_t mAutoreplaceCallback;
-	void			setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
 	void			setLabel(const LLStringExplicit &new_label) { mLabel = new_label; }
 	const std::string& 	getLabel()	{ return mLabel.getString(); }
 
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index d42d6473ed585f60a13cecfdff9242cd69eeec88..562bbc7100a3f954e1b410d312af4282d33ee47e 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -247,6 +247,7 @@ LLTextEditor::Params::Params()
 
 LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
 	LLTextBase(p),
+	mAutoreplaceCallback(),
 	mBaseDocIsPristine(TRUE),
 	mPristineCmd( NULL ),
 	mLastCmd( NULL ),
@@ -1097,7 +1098,25 @@ void LLTextEditor::addChar(llwchar wc)
 	}
 
 	setCursorPos(mCursorPos + addChar( mCursorPos, wc ));
+
+	if (!mReadOnly && mAutoreplaceCallback != NULL)
+	{
+		// autoreplace the text, if necessary
+		S32 replacement_start;
+		S32 replacement_length;
+		LLWString replacement_string;
+		S32 new_cursor_pos = mCursorPos;
+		mAutoreplaceCallback(replacement_start, replacement_length, replacement_string, new_cursor_pos, getWText());
+
+		if (replacement_length > 0 || !replacement_string.empty())
+		{
+			remove(replacement_start, replacement_length, true);
+			insert(replacement_start, replacement_string, false, LLTextSegmentPtr());
+			setCursorPos(new_cursor_pos);
+		}
+	}
 }
+
 void LLTextEditor::addLineBreakChar()
 {
 	if( !getEnabled() )
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index f8f636b876cb2efa27bda774b3955254bfdcf063..5e189070faeb1788345cc15c84aaf3d807e01c86 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -157,6 +157,11 @@ class LLTextEditor :
 	BOOL			isPristine() const;
 	BOOL			allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
 
+	// Autoreplace (formerly part of LLLineEditor)
+	typedef boost::function<void(S32&, S32&, LLWString&, S32&, const LLWString&)> autoreplace_callback_t;
+	autoreplace_callback_t mAutoreplaceCallback;
+	void			setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
+
 	//
 	// Text manipulation
 	//
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 5e5aeefba179653f1f9738b8c66fe34b66771cae..f7bc19574a7a1bd77f67002291f6adb68be718e4 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -90,7 +90,8 @@ LLDir::LLDir()
 	mCAFile(""),
 	mTempDir(""),
 	mDirDelimiter("/"), // fallback to forward slash if not overridden
-	mLanguage("en")
+	mLanguage("en"),
+	mUserName("undefined")
 {
 }
 
@@ -814,6 +815,11 @@ void LLDir::setChatLogsDir(const std::string &path)
 	}
 }
 
+void LLDir::updatePerAccountChatLogsDir()
+{
+	mPerAccountChatLogsDir = add(getChatLogsDir(), mUserName);
+}
+
 void LLDir::setPerAccountChatLogsDir(const std::string &username)
 {
 	// if both first and last aren't set, assume we're grabbing the cached dir
@@ -824,13 +830,14 @@ void LLDir::setPerAccountChatLogsDir(const std::string &username)
 		std::string userlower(username);
 		LLStringUtil::toLower(userlower);
 		LLStringUtil::replaceChar(userlower, ' ', '_');
-		mPerAccountChatLogsDir = add(getChatLogsDir(), userlower);
+
+		mUserName = userlower;
+		updatePerAccountChatLogsDir();
 	}
 	else
 	{
 		llerrs << "NULL name for LLDir::setPerAccountChatLogsDir" << llendl;
 	}
-	
 }
 
 void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language)
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 300ff1eef6a21bc1cce9af91c1356c291e9f207b..95cab65149d1833adb8a6623285d6639eb3ff748 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -186,6 +186,7 @@ class LLDir
 	virtual std::string getSkinFolder() const;
 	virtual std::string getLanguage() const;
 	virtual bool setCacheDir(const std::string &path);
+	virtual void updatePerAccountChatLogsDir();
 
 	virtual void dumpCurrentDirectories();
 
@@ -243,6 +244,7 @@ class LLDir
 	std::vector<std::string> mSearchSkinDirs;
 	std::string mLanguage;              // Current viewer language
 	std::string mLLPluginDir;			// Location for plugins and plugin shell
+	std::string mUserName;				// Current user name
 };
 
 void dir_exists_or_crash(const std::string &dir_name);
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index fd4d1df894afb9c5ea771889dbf6b2227578bcf9..dd9a0100c0220119e45599b334dcf2a70c1987db 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4674,9 +4674,9 @@
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
-      <string>Boolean</string>
+      <string>S32</string>
       <key>Value</key>
-      <integer>1</integer>
+      <integer>2</integer>
     </map>
     <key>LandBrushSize</key>
     <map>
diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp
index d71cf290d6d3fb559076b866160720b8b63ea54a..1d72397cbc1d4d22c215b29c57bee20348876659 100644
--- a/indra/newview/llautoreplace.cpp
+++ b/indra/newview/llautoreplace.cpp
@@ -30,68 +30,60 @@
 #include "llviewercontrol.h"
 #include "llnotificationsutil.h"
 
-LLAutoReplace* LLAutoReplace::sInstance;
-
 const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml";
 
-LLAutoReplace::LLAutoReplace()
-{
-}
-
-LLAutoReplace::~LLAutoReplace()
+void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text)
 {
-	sInstance = NULL;
-}
+	// make sure these returned values are cleared in case there is no replacement
+	replacement_start = 0;
+	replacement_length = 0;
+	replacement_string.clear();
 
-void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
-{
 	static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace");
-	if(perform_autoreplace)
+	if (perform_autoreplace)
 	{
-		S32 wordEnd = cursorPos-1;
-		LLWString text = inputText.getWString();
+		S32 word_end = cursor_pos - 1;
 
-		bool atSpace  = (text[wordEnd] == ' ');
-		bool haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd]));
+		bool at_space  = (input_text[word_end] == ' ');
+		bool have_word = (LLWStringUtil::isPartOfWord(input_text[word_end]));
 
-		if (atSpace || haveWord)
+		if (at_space || have_word)
 		{
-			if (atSpace && wordEnd > 0)
+			if (at_space && word_end > 0)
 			{
 				// find out if this space immediately follows a word
-				wordEnd--;
-				haveWord  = (LLWStringUtil::isPartOfWord(text[wordEnd]));
+				word_end--;
+				have_word  = (LLWStringUtil::isPartOfWord(input_text[word_end]));
 			}
-			if (haveWord)
+			if (have_word)
 			{
-				// wordEnd points to the end of a word, now find the start of the word
+				// word_end points to the end of a word, now find the start of the word
 				std::string word;
-				S32 wordStart = wordEnd;
-				for ( S32 backOne = wordStart - 1;
-					  backOne >= 0 && LLWStringUtil::isPartOfWord(text[backOne]);
-					  backOne--
-					 )
+				S32 word_start = word_end;
+				for (S32 back_one = word_start - 1;
+					 back_one >= 0 && LLWStringUtil::isPartOfWord(input_text[back_one]);
+					 back_one--
+					)
 				{
-					wordStart--; // walk wordStart back to the beginning of the word
+					word_start--; // walk word_start back to the beginning of the word
 				}
-				LL_DEBUGS("AutoReplace")<<"wordStart: "<<wordStart<<" wordEnd: "<<wordEnd<<LL_ENDL;
-				std::string strText  = std::string(text.begin(), text.end());
-				std::string lastWord = strText.substr(wordStart, wordEnd-wordStart+1);
-				std::string replacementWord( mSettings.replaceWord( lastWord ) );
+				LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL;
+				std::string str_text  = std::string(input_text.begin(), input_text.end());
+				std::string last_word = str_text.substr(word_start, word_end - word_start + 1);
+				std::string replacement_word(mSettings.replaceWord(last_word));
 
-				if ( replacementWord != lastWord )
+				if (replacement_word != last_word)
 				{
 					// The last word is one for which we have a replacement
-					if (atSpace)
+					if (at_space)
 					{
-						// replace the last word in the input
-						LLWString strNew = utf8str_to_wstring(replacementWord);
-						LLWString strOld = utf8str_to_wstring(lastWord);
-						int size_change = strNew.size() - strOld.size();
-
-						text.replace(wordStart,lastWord.length(),strNew);
-						inputText = wstring_to_utf8str(text);
-						cursorPos+=size_change;
+						// return the replacement string
+						replacement_start = word_start;
+						replacement_length = last_word.length();
+						replacement_string = utf8str_to_wstring(replacement_word);
+						LLWString old_string = utf8str_to_wstring(last_word);
+						S32 size_change = replacement_string.size() - old_string.size();
+						cursor_pos += size_change;
 					}
 				}
 			}
@@ -99,16 +91,6 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
 	}
 }
 
-LLAutoReplace* LLAutoReplace::getInstance()
-{
-	if(!sInstance)
-	{
-		sInstance = new LLAutoReplace();
-		sInstance->loadFromSettings();
-	}
-	return sInstance;
-}
-
 std::string LLAutoReplace::getUserSettingsFileName()
 {
 	std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
@@ -147,6 +129,15 @@ void LLAutoReplace::setSettings(const LLAutoReplaceSettings& newSettings)
 	saveToUserSettings();
 }
 
+LLAutoReplace::LLAutoReplace()
+{
+}
+
+void LLAutoReplace::initSingleton()
+{
+    loadFromSettings();
+}
+
 void LLAutoReplace::loadFromSettings()
 {
 	std::string filename=getUserSettingsFileName();
@@ -220,7 +211,7 @@ void LLAutoReplace::saveToUserSettings()
 	std::string filename=getUserSettingsFileName();
 	llofstream file;
 	file.open(filename.c_str());
-	LLSDSerialize::toPrettyXML(mSettings.getAsLLSD(), file);
+	LLSDSerialize::toPrettyXML(mSettings.asLLSD(), file);
 	file.close();
 	LL_INFOS("AutoReplace") << "settings saved to '" << filename << "'" << LL_ENDL;
 }
@@ -801,7 +792,7 @@ LLSD LLAutoReplaceSettings::getExampleLLSD()
 	return example;
 }
 
-const LLSD& LLAutoReplaceSettings::getAsLLSD()
+const LLSD& LLAutoReplaceSettings::asLLSD()
 {
 	return mLists;
 }
diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h
index f720cc4edaf0a164fbc0e709f993f0b7756e6332..9eecc2d9814911608793d5195a72a7e202e1cdaf 100644
--- a/indra/newview/llautoreplace.h
+++ b/indra/newview/llautoreplace.h
@@ -132,7 +132,7 @@ class LLAutoReplaceSettings
 	LLSD getExampleLLSD();
 
 	/// Get the actual settings as LLSD
-	const LLSD& getAsLLSD();
+	const LLSD& asLLSD();
 	///< @note for use only in AutoReplace::saveToUserSettings
 	
   private:
@@ -183,49 +183,45 @@ class LLAutoReplaceSettings
  * When the end of a word is detected (defined as any punctuation character,
  * or any whitespace except newline or return), the preceding word is used
  * as a lookup key in an ordered list of maps.  If a match is found in any
- * map, the keyword is replaced by the associated value from the map.
+ * map, the replacement start index and length are returned along with the
+ * new replacement string.
  *
  * See the autoreplaceCallback method for how to add autoreplace functionality
  * to a text entry tool.
  */
 class LLAutoReplace : public LLSingleton<LLAutoReplace>
 {
-  public:
-	LLAutoReplace();
-	~LLAutoReplace();
-
-	/// @return a pointer to the active instance
-	static LLAutoReplace* getInstance();
+public:
+    /// Callback that provides the hook for use in text entry methods
+    void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text);
 
-	/// Callback that provides the hook for use in text entry methods
-	void autoreplaceCallback(LLUIString& inputText, S32& cursorPos);
+    /// Get a copy of the current settings
+    LLAutoReplaceSettings getSettings();
 
-	/// Get a copy of the current settings
-	LLAutoReplaceSettings getSettings();
+    /// Commit new settings after making changes
+    void setSettings(const LLAutoReplaceSettings& settings);
 
-	/// Commit new settings after making changes
-	void setSettings(const LLAutoReplaceSettings& settings);
-
-  private:
-	friend class LLSingleton<LLAutoReplace>;
-	static LLAutoReplace* sInstance; ///< the active settings instance
+private:
+    friend class LLSingleton<LLAutoReplace>;
+    LLAutoReplace();
+    /*virtual*/ void initSingleton();
 
-	LLAutoReplaceSettings mSettings; ///< configuration information
+    LLAutoReplaceSettings mSettings; ///< configuration information
 	
-	/// Read settings from persistent storage
-	void loadFromSettings();
+    /// Read settings from persistent storage
+    void loadFromSettings();
 
-	/// Make the newSettings active and write them to user storage
-	void saveToUserSettings();
+    /// Make the newSettings active and write them to user storage
+    void saveToUserSettings();
 
-	/// Compute the user settings file name
-	std::string getUserSettingsFileName();
+    /// Compute the user settings file name
+    std::string getUserSettingsFileName();
 
-	/// Compute the (read-ony) application settings file name
-	std::string getAppSettingsFileName();
+    /// Compute the (read-ony) application settings file name
+    std::string getAppSettingsFileName();
 
-	/// basename for the settings files
-	static const char* SETTINGS_FILE_NAME;
+    /// basename for the settings files
+    static const char* SETTINGS_FILE_NAME;
 };
 
 #endif /* LLAUTOREPLACE_H */
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index ff1f819d7d9804db920f09ef89feea30f0567f0a..8de041f983a2f4c7773c0a5e1495595b0dbdb625 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -28,13 +28,14 @@
 #include "llagent.h"
 #include "llavatarnamecache.h"
 #include "llconversationlog.h"
+#include "llnotificationsutil.h"
 #include "lltrans.h"
 
 const int CONVERSATION_LIFETIME = 30; // lifetime of LLConversation is 30 days by spec
 
-struct Conversation_params
+struct ConversationParams
 {
-	Conversation_params(time_t time)
+	ConversationParams(time_t time)
 	:	mTime(time),
 		mTimestamp(LLConversation::createTimestamp(time))
 	{}
@@ -53,7 +54,7 @@ struct Conversation_params
 /*             LLConversation implementation                            */
 /************************************************************************/
 
-LLConversation::LLConversation(const Conversation_params& params)
+LLConversation::LLConversation(const ConversationParams& params)
 :	mTime(params.mTime),
 	mTimestamp(params.mTimestamp),
 	mConversationType(params.mConversationType),
@@ -188,33 +189,24 @@ void LLConversationLogFriendObserver::changed(U32 mask)
 LLConversationLog::LLConversationLog() :
 	mAvatarNameCacheConnection()
 {
-	LLControlVariable* log_instant_message = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
-	LLControlVariable* keep_convers_log = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
-	bool is_log_message = false;
-	bool is_keep_log = false;
+	LLControlVariable * keep_log_ctrlp = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
+	S32 log_mode = keep_log_ctrlp->getValue();
 
-	if (log_instant_message)
+	if (log_mode > 0)
 	{
-		log_instant_message->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
-		is_log_message = log_instant_message->getValue().asBoolean();
+		keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+		enableLogging(log_mode);
 	}
-	if (keep_convers_log)
-	{
-		keep_convers_log->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
-		is_keep_log = keep_convers_log->getValue().asBoolean();
-	}
-
-	enableLogging(is_log_message && is_keep_log);
 }
 
-void LLConversationLog::enableLogging(bool enable)
+void LLConversationLog::enableLogging(S32 log_mode)
 {
-	if (enable)
+	if (log_mode > 0)
 	{
 		loadFromFile(getFileName());
 
 		LLIMMgr::instance().addSessionObserver(this);
-		newMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
+		mNewMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
 
 		mFriendObserver = new LLConversationLogFriendObserver;
 		LLAvatarTracker::instance().addObserver(mFriendObserver);
@@ -224,7 +216,7 @@ void LLConversationLog::enableLogging(bool enable)
 		saveToFile(getFileName());
 
 		LLIMMgr::instance().removeSessionObserver(this);
-		newMessageSignalConnection.disconnect();
+		mNewMessageSignalConnection.disconnect();
 		LLAvatarTracker::instance().removeObserver(mFriendObserver);
 		mConversations.clear();
 	}
@@ -377,7 +369,7 @@ void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string
 
 void LLConversationLog::cache()
 {
-	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+	if (gSavedSettings.getS32("KeepConversationLogTranscripts") > 0)
 	{
 		saveToFile(getFileName());
 	}
@@ -450,9 +442,9 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 	char part_id_buffer[MAX_STRING];
 	char conv_id_buffer[MAX_STRING];
 	char history_file_name[MAX_STRING];
-	int has_offline_ims;
-	int stype;
-	time_t time;
+	S32 has_offline_ims;
+	S32 stype;
+	S64 time;
 	// before CHUI-348 it was a flag of conversation voice state
 	int prereserved_unused;
 
@@ -462,7 +454,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 		part_id_buffer[0]	= '\0';
 		conv_id_buffer[0]	= '\0';
 
-		sscanf(buffer, "[%ld] %d %d %d %[^|]| %s %s %[^|]|",
+		sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|",
 				&time,
 				&stype,
 				&prereserved_unused,
@@ -472,7 +464,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 				conv_id_buffer,
 				history_file_name);
 
-		Conversation_params params(time);
+		ConversationParams params((time_t)time);
 		params.mConversationType = (SessionType)stype;
 		params.mHasOfflineIMs = has_offline_ims;
 		params.mConversationName = std::string(conv_name_buffer);
@@ -530,3 +522,17 @@ void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LL
 	mAvatarNameCacheConnection.disconnect();
 	updateConversationName(session, av_name.getCompleteName());
 }
+
+void LLConversationLog::onClearLog()
+{
+	LLNotificationsUtil::add("PreferenceChatClearLog", LLSD(), LLSD(), boost::bind(&LLConversationLog::onClearLogResponse, this, _1, _2));
+}
+
+void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD& response)
+{
+	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+	{
+		mConversations.clear();
+		notifyObservers();
+	}
+}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 35462ec3a4b3e2c7ce8d56b398cc3d6667636d28..65a18c02e5dcb4b3587565388b386024a88f103a 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -31,7 +31,7 @@
 #include "llimview.h"
 
 class LLConversationLogObserver;
-struct Conversation_params;
+struct ConversationParams;
 
 typedef LLIMModel::LLIMSession::SType SessionType;
 
@@ -43,7 +43,7 @@ class LLConversation
 {
 public:
 
-	LLConversation(const Conversation_params& params);
+	LLConversation(const ConversationParams& params);
 	LLConversation(const LLIMModel::LLIMSession& session);
 	LLConversation(const LLConversation& conversation);
 
@@ -138,6 +138,9 @@ class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObse
 	 */
 	void cache();
 
+	void onClearLog();
+	void onClearLogResponse(const LLSD& notification, const LLSD& response);
+
 private:
 
 	LLConversationLog();
@@ -149,7 +152,7 @@ class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObse
 		}
 	}
 	
-	void enableLogging(bool enable);
+	void enableLogging(S32 log_mode);
 
 	/**
 	 * adds conversation to the conversation list and notifies observers
@@ -182,7 +185,7 @@ class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObse
 
 	LLFriendObserver* mFriendObserver;		// Observer of the LLAvatarTracker instance
 
-	boost::signals2::connection newMessageSignalConnection;
+	boost::signals2::connection mNewMessageSignalConnection;
 	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index a8da4908ced660dafd194f546e8d1ed3ae844adf..7184a70db51e629b397be7282f265bbb0a3135db 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -35,6 +35,7 @@
 #include "llsdutil.h"
 #include "llconversationmodel.h"
 #include "llimview.h" //For LLIMModel
+#include "lltrans.h"
 
 //
 // Conversation items : common behaviors
@@ -461,6 +462,7 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display
 	LLConversationItem(display_name,uuid,root_view_model),
 	mIsMuted(false),
 	mIsModerator(false),
+	mDisplayModeratorLabel(false),
 	mDistToAgent(-1.0)
 {
 	mDisplayName = display_name;
@@ -471,6 +473,7 @@ LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid,
 	LLConversationItem(uuid,root_view_model),
 	mIsMuted(false),
 	mIsModerator(false),
+	mDisplayModeratorLabel(false),
 	mDistToAgent(-1.0)
 {
 	mConvType = CONV_PARTICIPANT;
@@ -503,6 +506,12 @@ void LLConversationItemParticipant::updateName(const LLAvatarName& av_name)
 {
 	mName = av_name.getUserName();
 	mDisplayName = av_name.getDisplayName();
+	
+	if (mDisplayModeratorLabel)
+	{
+		mDisplayName += " " + LLTrans::getString("IM_moderator_label");
+	}
+	
 	renameItem(mDisplayName);
 	if (mParent != NULL)
 	{
@@ -541,6 +550,15 @@ void LLConversationItemParticipant::dumpDebugData()
 	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", display name = " << mDisplayName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
 }
 
+void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole)
+{ 
+	if (displayRole != mDisplayModeratorLabel)
+	{
+		mDisplayModeratorLabel = displayRole;
+		updateName();
+	}
+}
+
 //
 // LLConversationSort
 // 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 6aaea041e4f1a600d11c8cb6ab1374c4ed2058ed..c907d1d6d2170da75f5ad4f2e835239fa50aa982 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -205,13 +205,15 @@ class LLConversationItemParticipant : public LLConversationItem
 
 	void dumpDebugData();
 	void setModeratorOptionsVisible(bool visible) { mDisplayModeratorOptions = visible; }
+	void setDisplayModeratorRole(bool displayRole);
 
 private:
 	void onAvatarNameCache(const LLAvatarName& av_name);	// callback used by fetchAvatarName
 	void updateName(const LLAvatarName& av_name);
 
-	bool mIsMuted;		// default is false
-	bool mIsModerator;	// default is false
+	bool mIsMuted;		         // default is false
+	bool mIsModerator;	         // default is false
+	bool mDisplayModeratorLabel; // default is false
 	std::string mDisplayName;
 	F64  mDistToAgent;  // Distance to the agent. A negative (meaningless) value means the distance has not been set.
 	boost::signals2::connection mAvatarNameCacheConnection;
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index a40a000babfd396316ad9840e1f9ec8050413639..a44ebcf6ab615a9052f1ee94bbf8673d8690c84c 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -63,13 +63,9 @@ BOOL LLFloaterConversationLog::postBuild()
 
 	getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2));
 
-	LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
-	if (ctrl)
-	{
-		ctrl->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2));
-		onCallLoggingEnabledDisabled(ctrl->getValue().asBoolean()
-				&& gSavedSettings.getBOOL("KeepConversationLogTranscripts"));
-	}
+	LLControlVariable * keep_log_ctrlp = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
+	keep_log_ctrlp->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2));
+	onCallLoggingEnabledDisabled(keep_log_ctrlp->getValue());
 
 	return LLFloater::postBuild();
 }
@@ -139,8 +135,8 @@ bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
 	return false;
 }
 
-void LLFloaterConversationLog::onCallLoggingEnabledDisabled(bool enabled)
+void LLFloaterConversationLog::onCallLoggingEnabledDisabled(S32 log_mode)
 {
-	std::string no_items_msg = enabled ? "" : getString("logging_calls_disabled");
+	std::string no_items_msg = log_mode > 0 ? "" : getString("logging_calls_disabled");
 	mConversationLogList->setNoItemsCommentText(no_items_msg);
 }
diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h
index 9e79cbd7d8eb2c31a1650d644aa77af24be364b0..aa0f480aae6a45dfed41927a85075c12f67ec7d1 100644
--- a/indra/newview/llfloaterconversationlog.h
+++ b/indra/newview/llfloaterconversationlog.h
@@ -49,7 +49,7 @@ class LLFloaterConversationLog : public LLFloater
 	bool isActionEnabled(const LLSD& userdata);
 	bool isActionChecked(const LLSD& userdata);
 
-	void onCallLoggingEnabledDisabled(bool enabled);
+	void onCallLoggingEnabledDisabled(S32 log_mode);
 
 	LLConversationLogList* mConversationLogList;
 };
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index ff6234fa27bd260a46cc6b1646ea61772545d609..54e50854903f68bf5667244b73d77b844cfe9dc9 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -224,7 +224,7 @@ BOOL LLFloaterIMContainer::postBuild()
 
 	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
 	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
-	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate));
+	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
 	mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));
 	if (! mMessagesPane->isCollapsed())
 	{
@@ -1086,7 +1086,10 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command,
         }
         else
         {
-            doToParticipants(command, selectedIDS);
+        	if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+        	{
+        		doToParticipants(command, selectedIDS);
+        	}
         }
     }
 }
@@ -1139,7 +1142,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 
 	if ("conversation_log" == item)
 	{
-		return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
+		return gSavedSettings.getS32("KeepConversationLogTranscripts") > 0;
 	}
 
 	//Enable Chat history item for ad-hoc and group conversations
@@ -1790,7 +1793,7 @@ void LLFloaterIMContainer::updateSpeakBtnState()
 
 bool LLFloaterIMContainer::isConversationLoggingAllowed()
 {
-	return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
+	return gSavedSettings.getS32("KeepConversationLogTranscripts") > 0;
 }
 
 void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 797d590e1f7840df0ce1d5e13e99247587f63a0b..a2dd93e10ddba9f918657cd767bd916fa4b6db50 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -66,6 +66,7 @@
 #include "llrootview.h"
 #include "llviewerchat.h"
 #include "lltranslate.h"
+#include "llautoreplace.h"
 
 S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0;
 
@@ -111,7 +112,8 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 {
     setIsSingleInstance(TRUE);
     BOOL result = LLFloaterIMSessionTab::postBuild();
-	
+
+	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
 	mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
 	mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this));
 	mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this));
@@ -148,8 +150,14 @@ void LLFloaterIMNearbyChat::refresh()
 	}
 }
 
-void LLFloaterIMNearbyChat::reloadMessages()
+void LLFloaterIMNearbyChat::reloadMessages(bool clean_messages/* = false*/)
 {
+	if (clean_messages)
+	{
+		mMessageArchive.clear();
+		loadHistory();
+	}
+
 	mChatHistory->clear();
 
 	LLSD do_not_log;
@@ -174,11 +182,11 @@ void LLFloaterIMNearbyChat::loadHistory()
 	{
 		const LLSD& msg = *it;
 
-		std::string from = msg[IM_FROM];
+		std::string from = msg[LL_IM_FROM];
 		LLUUID from_id;
-		if (msg[IM_FROM_ID].isDefined())
+		if (msg[LL_IM_FROM_ID].isDefined())
 		{
-			from_id = msg[IM_FROM_ID].asUUID();
+			from_id = msg[LL_IM_FROM_ID].asUUID();
 		}
 		else
  		{
@@ -189,8 +197,8 @@ void LLFloaterIMNearbyChat::loadHistory()
 		LLChat chat;
 		chat.mFromName = from;
 		chat.mFromID = from_id;
-		chat.mText = msg[IM_TEXT].asString();
-		chat.mTimeStr = msg[IM_TIME].asString();
+		chat.mText = msg[LL_IM_TEXT].asString();
+		chat.mTimeStr = msg[LL_IM_TIME].asString();
 		chat.mChatStyle = CHAT_STYLE_HISTORY;
 
 		chat.mSourceType = CHAT_SOURCE_AGENT;
@@ -519,20 +527,21 @@ void LLFloaterIMNearbyChat::sendChat( EChatType type )
 	}
 }
 
-void	LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
+void LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
 {
 	appendMessage(chat, args);
 
 	if(archive)
 	{
 		mMessageArchive.push_back(chat);
-		if(mMessageArchive.size()>200)
+		if(mMessageArchive.size() > 200)
+		{
 			mMessageArchive.erase(mMessageArchive.begin());
+		}
 	}
 
 	// logging
-	if (!args["do_not_log"].asBoolean()
-			&& gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
+	if (!args["do_not_log"].asBoolean() && gSavedSettings.getS32("KeepConversationLogTranscripts") > 1)
 	{
 		std::string from_name = chat.mFromName;
 
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index f4213eda5a8cd7120ba78825405776aca090c1c1..14c7d01ecdcb44f3d1cdf5f48ed80c3fe3122f42 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -56,7 +56,7 @@ class LLFloaterIMNearbyChat
 	/*virtual*/ void setVisible(BOOL visible);
 
 	void loadHistory();
-    void reloadMessages();
+    void reloadMessages(bool clean_messages = false);
 	void removeScreenChat();
 
 	void show();
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a09dc1914f3308641c23ab5c33cf7cba690a637e..f754853b82080976419119662cfa06eb2cd8d683 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -162,7 +162,7 @@ void LLFloaterIMSession::newIMCallback(const LLSD& data)
 		LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
 
         // update if visible, otherwise will be updated when opened
-		if (floater && (floater->getHost()? floater->hasFocus() : floater->getVisible()))
+		if (floater && floater->isInVisibleChain())
 		{
 			floater->updateMessages();
 		}
@@ -332,13 +332,7 @@ BOOL LLFloaterIMSession::postBuild()
 	BOOL result = LLFloaterIMSessionTab::postBuild();
 
 	mInputEditor->setMaxTextLength(1023);
-	// enable line history support for instant message bar
-	// XXX stinson TODO : resolve merge by adding autoreplace to text editors
-#if 0
-	// *TODO Establish LineEditor with autoreplace callback
-	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
-#endif
-	
+	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
 	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
 	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
 	mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
@@ -853,8 +847,18 @@ void LLFloaterIMSession::updateMessages()
 	}
 }
 
-void LLFloaterIMSession::reloadMessages()
+void LLFloaterIMSession::reloadMessages(bool clean_messages/* = false*/)
 {
+	if (clean_messages)
+	{
+		LLIMModel::LLIMSession * sessionp = LLIMModel::instance().findIMSession(mSessionID);
+
+		if (NULL != sessionp)
+		{
+			sessionp->loadHistory();
+		}
+	}
+
 	mChatHistory->clear();
 	mLastMessageIndex = -1;
 	updateMessages();
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 2049cedfd7906557957195386afbe2d507e6642a..e7fd6f9ff32355737652a5c64c1dd49195b7acbb 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -86,7 +86,7 @@ class LLFloaterIMSession
 
 	// get new messages from LLIMModel
 	/*virtual*/ void updateMessages();
-	void reloadMessages();
+	void reloadMessages(bool clean_messages = false);
 	static void onSendMsg(LLUICtrl*, void*);
 	void sendMsgFromInputEditor();
 	void sendMsg(const std::string& msg);
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 37404ab7168008767d76749e294a6db0d7de0d8f..f52cf3b8f01b4eae1a9ef55094540b7e8fa682c7 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -497,6 +497,28 @@ void LLFloaterIMSessionTab::refreshConversation()
 		}
 		updateSessionName(session_name);
 	}
+
+	LLParticipantList* participant_list = getParticipantList();
+	if (participant_list)
+	{
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = participant_list->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = participant_list->getChildrenEnd();
+		LLIMSpeakerMgr *speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+			if (speaker_mgr && participant_model)
+			{
+				LLSpeaker *participant_speaker = speaker_mgr->findSpeaker(participant_model->getUUID());
+				LLSpeaker *agent_speaker = speaker_mgr->findSpeaker(gAgentID);
+				if (participant_speaker && agent_speaker)
+				{
+					participant_model->setDisplayModeratorRole(agent_speaker->mIsModerator && participant_speaker->mIsModerator);
+				}
+			}
+			current_participant_model++;
+		}
+	}
 	
 	mConversationViewModel.requestSortAll();
 	if(mConversationsRoot != NULL)
@@ -680,7 +702,7 @@ void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
 }
 
 // static
-void LLFloaterIMSessionTab::processChatHistoryStyleUpdate()
+void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/* = false*/)
 {
 	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
 	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
@@ -689,14 +711,14 @@ void LLFloaterIMSessionTab::processChatHistoryStyleUpdate()
 		LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter);
 		if (floater)
 		{
-			floater->reloadMessages();
+			floater->reloadMessages(clean_messages);
 		}
 	}
 
 	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 	if (nearby_chat)
 	{
-             nearby_chat->reloadMessages();
+             nearby_chat->reloadMessages(clean_messages);
 	}
 }
 
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index beaffc14a667fb523ce3c21700306bdbe6b02391..e90fcbb8060a9b5130f6708184ae475a270d5e17 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -53,7 +53,7 @@ class LLFloaterIMSessionTab
 	~LLFloaterIMSessionTab();
 
 	// reload all message with new settings of visual modes
-	static void processChatHistoryStyleUpdate();
+	static void processChatHistoryStyleUpdate(bool clean_messages = false);
 
 	/**
 	 * Returns true if chat is displayed in multi tabbed floater
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3d4a1c44d88cbf78269d1901240c006c759e9d0a..7742e5b3c3b04803f090255c6578535be065e801 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -306,7 +306,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mAvatarDataInitialized(false),
 	mClickActionDirty(false)
 {
-	
+	LLConversationLog::instance().addObserver(this);
+
 	//Build Floater is now Called from 	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
 	
 	static bool registered_dialog = false;
@@ -329,8 +330,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.VoiceSetKey",			boost::bind(&LLFloaterPreference::onClickSetKey, this));
 	mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse",	boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this));
 	mCommitCallbackRegistrar.add("Pref.SetSounds",				boost::bind(&LLFloaterPreference::onClickSetSounds, this));
-//	mCommitCallbackRegistrar.add("Pref.ClickSkipDialogs",		boost::bind(&LLFloaterPreference::onClickSkipDialogs, this));
-//	mCommitCallbackRegistrar.add("Pref.ClickResetDialogs",		boost::bind(&LLFloaterPreference::onClickResetDialogs, this));
 	mCommitCallbackRegistrar.add("Pref.ClickEnablePopup",		boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
 	mCommitCallbackRegistrar.add("Pref.ClickDisablePopup",		boost::bind(&LLFloaterPreference::onClickDisablePopup, this));	
 	mCommitCallbackRegistrar.add("Pref.LogPath",				boost::bind(&LLFloaterPreference::onClickLogPath, this));
@@ -351,13 +350,16 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 
 	sSkin = gSavedSettings.getString("SkinCurrent");
 
-	mCommitCallbackRegistrar.add("Pref.ClickActionChange",				boost::bind(&LLFloaterPreference::onClickActionChange, this));
+	mCommitCallbackRegistrar.add("Pref.ClickActionChange",		boost::bind(&LLFloaterPreference::onClickActionChange, this));
 
 	gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged,  _2));
 	
 	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
+
+	mCommitCallbackRegistrar.add("Pref.ClearLog",				boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
+	mCommitCallbackRegistrar.add("Pref.DeleteTranscripts",      boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
 }
 
 void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
@@ -425,7 +427,7 @@ void LLFloaterPreference::saveAvatarProperties( void )
 
 BOOL LLFloaterPreference::postBuild()
 {
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate));
+	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
 
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
 
@@ -455,9 +457,24 @@ BOOL LLFloaterPreference::postBuild()
 		gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
 	}
 
+	// set 'enable' property for 'Clear log...' button
+	changed();
+
+	// set 'enable' property for 'Delete transcripts...' button
+	updateDeleteTranscriptsButton();
+
+	LLLogChat::setSaveHistorySignal(boost::bind(&LLFloaterPreference::onLogChatHistorySaved, this));
+
 	return TRUE;
 }
 
+void LLFloaterPreference::updateDeleteTranscriptsButton()
+{
+	std::vector<std::string> list_of_transcriptions_file_names;
+	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names);
+	getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0);
+}
+
 void LLFloaterPreference::onDoNotDisturbResponseChanged()
 {
 	// set "DoNotDisturbResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
@@ -476,6 +493,8 @@ LLFloaterPreference::~LLFloaterPreference()
 	{
 		ctrl_window_size->setCurrentByIndex(i);
 	}
+
+	LLConversationLog::instance().removeObserver(this);
 }
 
 void LLFloaterPreference::draw()
@@ -833,12 +852,12 @@ void LLFloaterPreference::onBtnCancel()
 }
 
 // static 
-void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email)
 {
 	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
 	if (instance)
 	{
-		instance->setPersonalInfo(visibility, im_via_email, email);	
+		instance->setPersonalInfo(visibility, im_via_email);	
 	}
 }
 
@@ -1425,10 +1444,21 @@ void LLFloaterPreference::onClickLogPath()
 		return; //Canceled!
 	}
 
-	gSavedPerAccountSettings.setString("InstantMessageLogPath", picker.getDirName());
+	std::string dir_name = picker.getDirName();
+	gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
+	
+	gDirUtilp->setChatLogsDir(dir_name);
+	gDirUtilp->updatePerAccountChatLogsDir();
+	LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
+
+	// refresh IM floaters with new logs from files from new selected directory
+	LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+
+	// enable/disable 'Delete transcripts button
+	updateDeleteTranscriptsButton();
 }
 
-void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email)
 {
 	mGotPersonalInfo = true;
 	mOriginalIMViaEmail = im_via_email;
@@ -1450,32 +1480,14 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
 	}
 	
 	getChild<LLUICtrl>("online_searchresults")->setEnabled(TRUE);
-
-	getChildView("include_im_in_chat_history")->setEnabled(TRUE);
-	getChildView("show_timestamps_check_im")->setEnabled(TRUE);
 	getChildView("friends_online_notify_checkbox")->setEnabled(TRUE);
-	
 	getChild<LLUICtrl>("online_visibility")->setValue(mOriginalHideOnlineStatus); 	 
 	getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility);
 	getChildView("send_im_to_email")->setEnabled(TRUE);
 	getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email);
-	getChildView("log_instant_messages")->setEnabled(TRUE);
-//	getChildView("log_chat")->setEnabled(TRUE);
-//	getChildView("log_instant_messages_timestamp")->setEnabled(TRUE);
-//	getChildView("log_chat_timestamp")->setEnabled(TRUE);
-	getChildView("log_chat_IM")->setEnabled(TRUE);
-	getChildView("log_date_timestamp")->setEnabled(TRUE);
-	
 	getChildView("favorites_on_login_check")->setEnabled(TRUE);
-	getChildView("log_nearby_chat")->setEnabled(TRUE);
-	getChildView("log_instant_messages")->setEnabled(TRUE);
-	getChildView("show_timestamps_check_im")->setEnabled(TRUE);
 	getChildView("log_path_string")->setEnabled(FALSE);// LineEditor becomes readonly in this case.
 	getChildView("log_path_button")->setEnabled(TRUE);
-	childEnable("logfile_name_datestamp");	
-	std::string display_email(email);
-	getChild<LLUICtrl>("email_address")->setValue(display_email);
-
 }
 
 void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name)
@@ -1566,6 +1578,35 @@ void LLFloaterPreference::onClickActionChange()
 	mClickActionDirty = true;
 }
 
+void LLFloaterPreference::onDeleteTranscripts()
+{
+	LLNotificationsUtil::add("PreferenceChatDeleteTranscripts", LLSD(), LLSD(), boost::bind(&LLFloaterPreference::onDeleteTranscriptsResponse, this, _1, _2));
+}
+
+void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response)
+{
+	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+	{
+		gDirUtilp->deleteFilesInDir(gDirUtilp->getPerAccountChatLogsDir(), "*." + LL_TRANSCRIPT_FILE_EXTENSION);
+
+		std::vector<std::string> list_of_transcriptions_file_names;
+		LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names);
+		getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0);
+
+		LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+	}
+}
+
+void LLFloaterPreference::onLogChatHistorySaved()
+{
+	LLButton * delete_transcripts_buttonp = getChild<LLButton>("delete_transcripts");
+
+	if (!delete_transcripts_buttonp->getEnabled())
+	{
+		delete_transcripts_buttonp->setEnabled(true);
+	}
+}
+
 void LLFloaterPreference::updateClickActionSettings()
 {
 	const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
@@ -1624,6 +1665,11 @@ void LLFloaterPreference::selectChatPanel()
 	selectPanel("chat");
 }
 
+void LLFloaterPreference::changed()
+{
+	getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0);
+}
+
 //------------------------------Updater---------------------------------------
 
 static bool handleBandwidthChanged(const LLSD& newvalue)
@@ -1717,11 +1763,6 @@ BOOL LLPanelPreference::postBuild()
 
 	}
 
-	if (hasChild("online_visibility") && hasChild("send_im_to_email"))
-	{
-		getChild<LLUICtrl>("email_address")->setValue(getString("log_in_to_change") );
-	}
-	
 	//////////////////////PanelPrivacy ///////////////////
 	if (hasChild("media_enabled"))
 	{
@@ -1898,7 +1939,7 @@ class LLPanelPreferencePrivacy : public LLPanelPreference
 			for (control_values_map_t::iterator it = mSavedValues.begin(); it != mSavedValues.end(); )
 			{
 				const std::string setting = it->first->getName();
-				if (std::find(mAccountIndependentSettings.begin(),
+				if (find(mAccountIndependentSettings.begin(),
 					mAccountIndependentSettings.end(), setting) == mAccountIndependentSettings.end())
 				{
 					mSavedValues.erase(it++);
@@ -2187,4 +2228,4 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings()
 		otherHttpProxy->selectFirstItem();
 	}
 
-};
+}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 37a531e99e6995bbe3ad2dfc493ce157856bdf79..f9f1d5224428c2891880a8d36e1364f1345c653f 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -35,7 +35,9 @@
 
 #include "llfloater.h"
 #include "llavatarpropertiesprocessor.h"
+#include "llconversationlog.h"
 
+class LLConversationLogObserver;
 class LLPanelPreference;
 class LLPanelLCD;
 class LLPanelDebug;
@@ -58,7 +60,7 @@ typedef enum
 
 
 // Floater to control preferences (display, audio, bandwidth, general.
-class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
+class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver, public LLConversationLogObserver
 {
 public: 
 	LLFloaterPreference(const LLSD& key);
@@ -70,9 +72,11 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/	void onClose(bool app_quitting);
+	/*virtual*/ void changed();
+	/*virtual*/ void changed(const LLUUID& session_id, U32 mask) {};
 
 	// static data update, called from message handler
-	static void updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+	static void updateUserInfo(const std::string& visibility, bool im_via_email);
 
 	// refresh all the graphics preferences menus
 	static void refreshEnabledGraphics();
@@ -134,15 +138,13 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 	void setKey(KEY key);
 	void onClickSetMiddleMouse();
 	void onClickSetSounds();
-//	void onClickSkipDialogs();
-//	void onClickResetDialogs();
 	void onClickEnablePopup();
 	void onClickDisablePopup();	
 	void resetAllIgnored();
 	void setAllIgnored();
 	void onClickLogPath();	
 	void enableHistory();
-	void setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+	void setPersonalInfo(const std::string& visibility, bool im_via_email);
 	void refreshEnabledState();
 	void disableUnavailableSettings();
 	void onCommitWindowedMode();
@@ -166,12 +168,17 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 	void onClickSpellChecker();
 	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
 	void getUIColor(LLUICtrl* ctrl, const LLSD& param);
-	
+	void onLogChatHistorySaved();	
 	void buildPopupLists();
 	static void refreshSkin(void* data);
 	void selectPanel(const LLSD& name);
 
 private:
+
+	void onDeleteTranscripts();
+	void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);
+	void updateDeleteTranscriptsButton();
+
 	static std::string sSkin;
 	notifications_map mNotificationOptions;
 	bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 433ddad35d88b92888f27eeb28dce1ba0c8dd74e..8f010850f708a9688ef536c1d3491f76abd1b3c5 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -237,7 +237,7 @@ void on_new_message(const LLSD& msg)
                     LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
                 }
             }
-        }
+		}
     }
 
     else if ("flash" == action)
@@ -273,9 +273,9 @@ void on_new_message(const LLSD& msg)
 
             if(!gAgent.isDoNotDisturb())
             {
-            //Surface conversations floater
-            LLFloaterReg::showInstance("im_container");
-        }
+				//Surface conversations floater
+				LLFloaterReg::showInstance("im_container");
+			}
 
             //If in DND mode, allow notification to be stored so upon DND exit 
             //useMostItrusiveIMNotification will be called to notify user a message exists
@@ -284,8 +284,8 @@ void on_new_message(const LLSD& msg)
                 && gAgent.isDoNotDisturb())
             {
                 LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
-    }
-}
+			}
+		}
     }
 }
 
@@ -378,15 +378,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 	}
 
 	buildHistoryFileName();
-
-	if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
-	{
-		std::list<LLSD> chat_history;
-
-		//involves parsing of a chat history
-		LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
-		addMessagesFromHistory(chat_history);
-	}
+	loadHistory();
 
 	// Localizing name of ad-hoc session. STORM-153
 	// Changing name should happen here- after the history file was created, so that
@@ -579,11 +571,11 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
 	{
 		const LLSD& msg = *it;
 
-		std::string from = msg[IM_FROM];
+		std::string from = msg[LL_IM_FROM];
 		LLUUID from_id;
-		if (msg[IM_FROM_ID].isDefined())
+		if (msg[LL_IM_FROM_ID].isDefined())
 		{
-			from_id = msg[IM_FROM_ID].asUUID();
+			from_id = msg[LL_IM_FROM_ID].asUUID();
 		}
 		else
 		{
@@ -592,8 +584,8 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
  			gCacheName->getUUID(legacy_name, from_id);
 		}
 
-		std::string timestamp = msg[IM_TIME];
-		std::string text = msg[IM_TEXT];
+		std::string timestamp = msg[LL_IM_TIME];
+		std::string text = msg[LL_IM_TEXT];
 
 		addMessage(from, from_id, text, timestamp, true);
 
@@ -617,6 +609,20 @@ void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const
 	}
 }
 
+void LLIMModel::LLIMSession::loadHistory()
+{
+	mMsgs.clear();
+
+	if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
+	{
+		std::list<LLSD> chat_history;
+
+		//involves parsing of a chat history
+		LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
+		addMessagesFromHistory(chat_history);
+	}
+}
+
 LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
 {
 	return get_if_there(mId2SessionMap, session_id,
@@ -921,8 +927,7 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
 
 bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
 {
-	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")
-			&& gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
+	if (gSavedSettings.getS32("KeepConversationLogTranscripts") > 1)
 	{	
 		std::string from_name = from;
 
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 8578fa8c06da7c1e3643659db8fe5fa34367441e..da6039a3ae339e291499462b3c35343c4ddeb4d0 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -101,6 +101,8 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 		/** ad-hoc sessions involve sophisticated chat history file naming schemes */
 		void buildHistoryFileName();
 
+		void loadHistory();
+
 		LLUUID mSessionID;
 		std::string mName;
 		EInstantMessage mType;
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 3692658e9e651aa4b4a4408a2770768e8725a053..545b44ef925f4d93f3d220ce9ea3ca00a2767510 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -58,10 +58,11 @@
 
 const S32 LOG_RECALL_SIZE = 2048;
 
-const std::string IM_TIME("time");
-const std::string IM_TEXT("message");
-const std::string IM_FROM("from");
-const std::string IM_FROM_ID("from_id");
+const std::string LL_IM_TIME("time");
+const std::string LL_IM_TEXT("message");
+const std::string LL_IM_FROM("from");
+const std::string LL_IM_FROM_ID("from_id");
+const std::string LL_TRANSCRIPT_FILE_EXTENSION("ll.txt");
 
 const static std::string IM_SEPARATOR(": ");
 const static std::string NEW_LINE("\n");
@@ -116,6 +117,15 @@ const static int IDX_TEXT = 3;
 using namespace boost::posix_time;
 using namespace boost::gregorian;
 
+void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
+{
+	if (!messages.size()) return;
+
+	std::string im_text = messages.back()[LL_IM_TEXT].asString();
+	im_text.append(line);
+	messages.back()[LL_IM_TEXT] = im_text;
+}
+
 class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
 {
 public:
@@ -191,15 +201,17 @@ class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
 	std::stringstream mTimeStream;
 };
 
+LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL;
+
 //static
 std::string LLLogChat::makeLogFileName(std::string filename)
 {
 	/**
-	* Testing for in bound and out bound ad-hoc file names
-	* if it is then skip date stamping.
-	**/
-	//LL_INFOS("") << "Befor:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-    boost::match_results<std::string::const_iterator> matches;
+	 * Testing for in bound and out bound ad-hoc file names
+	 * if it is then skip date stamping.
+	 **/
+
+	boost::match_results<std::string::const_iterator> matches;
 	bool inboundConf = boost::regex_match(filename, matches, INBOUND_CONFERENCE);
 	bool outboundConf = boost::regex_match(filename, matches, OUTBOUND_CONFERENCE);
 	if (!(inboundConf || outboundConf))
@@ -220,17 +232,17 @@ std::string LLLogChat::makeLogFileName(std::string filename)
 			filename += dbuffer;
 		}
 	}
-	//LL_INFOS("") << "After:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+
 	filename = cleanFileName(filename);
-	filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS,filename);
-	filename += ".txt";
-	//LL_INFOS("") << "Full:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+	filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename);
+	filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+
 	return filename;
 }
 
 std::string LLLogChat::cleanFileName(std::string filename)
 {
-    std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
+	std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
 	std::string::size_type position = filename.find_first_of(invalidChars);
 	while (position != filename.npos)
 	{
@@ -242,27 +254,24 @@ std::string LLLogChat::cleanFileName(std::string filename)
 
 std::string LLLogChat::timestamp(bool withdate)
 {
-	time_t utc_time;
-	utc_time = time_corrected();
-
 	std::string timeStr;
-	LLSD substitution;
-	substitution["datetime"] = (S32) utc_time;
-
 	if (withdate)
 	{
-		timeStr = "["+LLTrans::getString ("TimeYear")+"]/["
-		          +LLTrans::getString ("TimeMonth")+"]/["
-				  +LLTrans::getString ("TimeDay")+"] ["
-				  +LLTrans::getString ("TimeHour")+"]:["
-				  +LLTrans::getString ("TimeMin")+"]";
+		timeStr = "[" + LLTrans::getString ("TimeYear") + "]/["
+				  + LLTrans::getString ("TimeMonth") + "]/["
+				  + LLTrans::getString ("TimeDay") + "] ["
+				  + LLTrans::getString ("TimeHour") + "]:["
+				  + LLTrans::getString ("TimeMin") + "]";
 	}
 	else
 	{
 		timeStr = "[" + LLTrans::getString("TimeHour") + "]:["
-			      + LLTrans::getString ("TimeMin")+"]";
+				  + LLTrans::getString ("TimeMin")+"]";
 	}
 
+	LLSD substitution;
+	substitution["datetime"] = (S32)time_corrected();
+
 	LLStringUtil::format (timeStr, substitution);
 	return timeStr;
 }
@@ -270,9 +279,9 @@ std::string LLLogChat::timestamp(bool withdate)
 
 //static
 void LLLogChat::saveHistory(const std::string& filename,
-			    const std::string& from,
-			    const LLUUID& from_id,
-			    const std::string& line)
+							const std::string& from,
+							const LLUUID& from_id,
+							const std::string& line)
 {
 	std::string tmp_filename = filename;
 	LLStringUtil::trim(tmp_filename);
@@ -312,6 +321,11 @@ void LLLogChat::saveHistory(const std::string& filename,
 	file << LLChatLogFormatter(item) << std::endl;
 
 	file.close();
+
+	if (NULL != sSaveHistorySignal)
+	{
+		(*sSaveHistorySignal)();
+	}
 }
 
 void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLineType, const LLSD&, void*), void* userdata)
@@ -321,7 +335,7 @@ void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLi
 		llwarns << "Filename is Empty!" << llendl;
 		return ;
 	}
-        
+		
 	LLFILE* fptr = LLFile::fopen(makeLogFileName(filename), "r");		/*Flawfinder: ignore*/
 	if (!fptr)
 	{
@@ -377,15 +391,6 @@ void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLi
 	}
 }
 
-void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
-{
-	if (!messages.size()) return;
-
-	std::string im_text = messages.back()[IM_TEXT].asString();
-	im_text.append(line);
-	messages.back()[IM_TEXT] = im_text;
-}
-
 // static
 void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
 {
@@ -397,19 +402,16 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 
 	bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
 
-	//LL_INFOS("") << "Loading:" << file_name << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-	//LL_INFOS("") << "Current:" << makeLogFileName(file_name) << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
 	LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
 	if (!fptr)
-    {
+	{
 		fptr = LLFile::fopen(oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
-        if (!fptr)
-        {
-			if (!fptr) return;      //No previous conversation with this name.
-        }
+		if (!fptr)
+		{
+			return;						//No previous conversation with this name.
+		}
 	}
  
-    //LL_INFOS("") << "Reading:" << file_name << LL_ENDL;
 	char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
 	char *bptr;
 	S32 len;
@@ -454,7 +456,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 			LLSD item;
 			if (!LLChatLogParser::parse(line, item, load_params))
 			{
-				item[IM_TEXT] = line;
+				item[LL_IM_TEXT] = line;
 			}
 			messages.push_back(item);
 		}
@@ -462,9 +464,78 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 	fclose(fptr);
 }
 
+// static
+std::string LLLogChat::oldLogFileName(std::string filename)
+{
+	// get Users log directory
+	std::string directory = gDirUtilp->getPerAccountChatLogsDir();
+
+	// add final OS dependent delimiter
+	directory += gDirUtilp->getDirDelimiter();
+
+	// lest make sure the file name has no invalid characters before making the pattern
+	filename = cleanFileName(filename);
+
+	// create search pattern
+	std::string pattern = filename + ( filename == "chat" ? "-???\?-?\?-??.txt" : "-???\?-??.txt");
+
+	std::vector<std::string> allfiles;
+	LLDirIterator iter(directory, pattern);
+	std::string scanResult;
+
+	while (iter.next(scanResult))
+	{
+		allfiles.push_back(scanResult);
+	}
+
+	if (allfiles.size() == 0)  // if no result from date search, return generic filename
+	{
+		scanResult = directory + filename + '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+	}
+	else 
+	{
+		sort(allfiles.begin(), allfiles.end());
+		scanResult = directory + allfiles.back();
+		// this file is now the most recent version of the file.
+	}
+
+	return scanResult;
+}
+
+// static
+void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_transcriptions)
+{
+	// get Users log directory
+	std::string directory = gDirUtilp->getPerAccountChatLogsDir();
+
+	// add final OS dependent delimiter
+	directory += gDirUtilp->getDirDelimiter();
+
+	// create search pattern
+	std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION;
+
+	LLDirIterator iter(directory, pattern);
+	std::string scanResult;
+	while (iter.next(scanResult))
+	{
+		list_of_transcriptions.push_back(scanResult);
+	}
+}
+
+//static
+boost::signals2::connection LLLogChat::setSaveHistorySignal(const save_history_signal_t::slot_type& cb)
+{
+	if (NULL == sSaveHistorySignal)
+	{
+		sSaveHistorySignal = new save_history_signal_t();
+	}
+
+	return sSaveHistorySignal->connect(cb);
+}
+
 //*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
 //which are more strict by its nature (only firstname and secondname)
-//Example, an object's name can be writen like "Object <actual_object's_name>"
+//Example, an object's name can be written like "Object <actual_object's_name>"
 void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 {
 	if (!im.isMap())
@@ -473,19 +544,19 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 		return;
 	}
 
-	if (im[IM_TIME].isDefined())
+	if (im[LL_IM_TIME].isDefined())
 {
-		std::string timestamp = im[IM_TIME].asString();
+		std::string timestamp = im[LL_IM_TIME].asString();
 		boost::trim(timestamp);
 		ostr << '[' << timestamp << ']' << TWO_SPACES;
 	}
 	
 	//*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
 	//which are more strict by its nature (only firstname and secondname)
-	//Example, an object's name can be writen like "Object <actual_object's_name>"
-	if (im[IM_FROM].isDefined())
+	//Example, an object's name can be written like "Object <actual_object's_name>"
+	if (im[LL_IM_FROM].isDefined())
 	{
-		std::string from = im[IM_FROM].asString();
+		std::string from = im[LL_IM_FROM].asString();
 		boost::trim(from);
 		if (from.size())
 		{
@@ -493,9 +564,9 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 		}
 	}
 
-	if (im[IM_TEXT].isDefined())
+	if (im[LL_IM_TEXT].isDefined())
 	{
-		std::string im_text = im[IM_TEXT].asString();
+		std::string im_text = im[LL_IM_TEXT].asString();
 
 		//multilined text will be saved with prepended spaces
 		boost::replace_all(im_text, NEW_LINE, NEW_LINE_SPACE_PREFIX);
@@ -528,12 +599,12 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 			LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
 		}
 
-		im[IM_TIME] = timestamp;
+		im[LL_IM_TIME] = timestamp;
 	}
 	else
 	{
 		//timestamp is optional
-		im[IM_TIME] = "";
+		im[LL_IM_TIME] = "";
 	}
 
 	bool has_stuff = matches[IDX_STUFF].matched;
@@ -559,8 +630,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 	if (!has_name || name == SYSTEM_FROM)
 	{
 		//name is optional too
-		im[IM_FROM] = SYSTEM_FROM;
-		im[IM_FROM_ID] = LLUUID::null;
+		im[LL_IM_FROM] = SYSTEM_FROM;
+		im[LL_IM_FROM_ID] = LLUUID::null;
 	}
 
 	//possibly a case of complex object names consisting of 3+ words
@@ -569,8 +640,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 		U32 divider_pos = stuff.find(NAME_TEXT_DIVIDER);
 		if (divider_pos != std::string::npos && divider_pos < (stuff.length() - NAME_TEXT_DIVIDER.length()))
 		{
-			im[IM_FROM] = stuff.substr(0, divider_pos);
-			im[IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
+			im[LL_IM_FROM] = stuff.substr(0, divider_pos);
+			im[LL_IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
 			return true;
 		}
 	}
@@ -578,7 +649,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 	if (!has_name)
 	{
 		//text is mandatory
-		im[IM_TEXT] = stuff;
+		im[LL_IM_TEXT] = stuff;
 		return true; //parse as a message from Second Life
 	}
 	
@@ -590,45 +661,15 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 	{
 		std::string agent_name;
 		LLAgentUI::buildFullname(agent_name);
-		im[IM_FROM] = agent_name;
-		im[IM_FROM_ID] = gAgentID;
+		im[LL_IM_FROM] = agent_name;
+		im[LL_IM_FROM_ID] = gAgentID;
 	}
 	else
 	{
-		im[IM_FROM] = name;
+		im[LL_IM_FROM] = name;
 	}
 	
 
-	im[IM_TEXT] = name_and_text[IDX_TEXT];
+	im[LL_IM_TEXT] = name_and_text[IDX_TEXT];
 	return true;  //parsed name and message text, maybe have a timestamp too
 }
-std::string LLLogChat::oldLogFileName(std::string filename)
-{
-    std::string scanResult;
-	std::string directory = gDirUtilp->getPerAccountChatLogsDir();/* get Users log directory */
-	directory += gDirUtilp->getDirDelimiter();/* add final OS dependent delimiter */
-	filename=cleanFileName(filename);/* lest make shure the file name has no invalad charecters befor making the pattern */
-	std::string pattern = (filename+(( filename == "chat" ) ? "-???\?-?\?-??.txt" : "-???\?-??.txt"));/* create search pattern*/
-	//LL_INFOS("") << "Checking:" << directory << " for " << pattern << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-	std::vector<std::string> allfiles;
-
-	LLDirIterator iter(directory, pattern);
-	while (iter.next(scanResult))
-    {
-		//LL_INFOS("") << "Found   :" << scanResult << LL_ENDL;
-        allfiles.push_back(scanResult);
-    }
-
-    if (allfiles.size() == 0)  // if no result from date search, return generic filename
-    {
-        scanResult = directory + filename + ".txt";
-    }
-    else 
-    {
-        std::sort(allfiles.begin(), allfiles.end());
-        scanResult = directory + allfiles.back();
-        // thisfile is now the most recent version of the file.
-    }
-	//LL_INFOS("") << "Reading:" << scanResult << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-    return scanResult;
-}
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index d3e9adcc37ad15b2bf69a02fb8d0fd97d96d6ec9..b35a94b4b32c9f9865929a11ce6fd2717a4e160c 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -49,6 +49,7 @@ class LLLogChat
 				const std::string& from,
 				const LLUUID& from_id,
 				const std::string& line);
+	static void getListOfTranscriptFiles(std::vector<std::string>& list);
 
 	/** @deprecated @see loadChatHistory() */
 	static void loadHistory(const std::string& filename, 
@@ -56,8 +57,13 @@ class LLLogChat
 							void* userdata);
 
 	static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
+
+	typedef boost::signals2::signal<void ()> save_history_signal_t;
+	static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
+
 private:
 	static std::string cleanFileName(std::string filename);
+	static save_history_signal_t * sSaveHistorySignal;
 };
 
 /**
@@ -113,9 +119,10 @@ class LLChatLogParser
 };
 
 // LLSD map lookup constants
-extern const std::string IM_TIME; //("time");
-extern const std::string IM_TEXT; //("message");
-extern const std::string IM_FROM; //("from");
-extern const std::string IM_FROM_ID; //("from_id");
+extern const std::string LL_IM_TIME; //("time");
+extern const std::string LL_IM_TEXT; //("message");
+extern const std::string LL_IM_FROM; //("from");
+extern const std::string LL_IM_FROM_ID; //("from_id");
+extern const std::string LL_TRANSCRIPT_FILE_EXTENSION; //("ll.txt");
 
 #endif
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 8489e92d1595439bd9cd001bb8179d05b34ad81b..f141419c438bf6b038b175f446cc2d89f9aae3b5 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -6943,7 +6943,7 @@ void process_user_info_reply(LLMessageSystem* msg, void**)
 	std::string dir_visibility;
 	msg->getString( "UserData", "DirectoryVisibility", dir_visibility);
 
-	LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email);
+	LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email);
 	LLFloaterSnapshot::setAgentEmail(email);
 }
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6a464ccdc44933ba667ca88be21802871fa2e567..9c3687314162bcb10c84a8992322d4bcb1e8772c 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -8316,4 +8316,30 @@ Attempt cancelled.
      yestext="Yes"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="PreferenceChatClearLog"
+   type="alertmodal">
+    This will delete the log of previous conversations, and all transcripts of those conversations. Proceed?
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Confirm before I delete the log of previous conversations."
+     name="okcancelignore"
+     notext="Cancel"
+     yestext="OK"/>
+  </notification>
+    
+  <notification
+   icon="alertmodal.tga"
+   name="PreferenceChatDeleteTranscripts"
+   type="alertmodal">
+    This will delete transcripts for all previous conversations. The list of conversations will not be affected. Proceed?
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Confirm before I delete transcripts."
+     name="okcancelignore"
+     notext="Cancel"
+     yestext="OK"/>
+  </notification>
+
 </notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 37bfbae9918fd1a41950795c6c06127f277ccc84..4f33699aa6a17a671df4f572fcafe2de81255b5e 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
     border="true"
-    follows="left|top|right|bottom"
+    has_border="true"
     height="408"
     label="Text Chat"
     layout="topleft"
@@ -12,8 +12,7 @@
 
   <panel
       border="false"
-      follows="left|top"
-      height="90"
+      height="60"
       layout="topleft"
       top="10"
       left="13"
@@ -27,7 +26,9 @@
         layout="topleft"
         top="0"
         name="play_typing_animation"
-        width="330" />
+        width="330">
+    </check_box>
+
     <check_box
         enabled="false"
         height="16"
@@ -35,26 +36,21 @@
         layout="topleft"
         name="send_im_to_email"
         top_pad="6"
-        width="330" />
-    <check_box
-        control_name="KeepConversationLogTranscripts"
-        height="16"
-        label="Keep a conversation log and transcripts"
-        layout="topleft"
-        name="keep_convo_log_and_transcripts"
-        top_pad="6"
-        width="330" />
+        width="330">
+    </check_box>
+
     <check_box
-        control_name="UseChatBubbles"
-        follows="left|top"
+        control_name="VoiceCallsFriendsOnly"
         height="16"
-        label="Bubble Chat"
+        label="Only friends and groups can call or IM me"
         layout="topleft"
+        name="voice_call_friends_only_check"
         top_pad="6"
-        name="bubble_text_chat"
-        width="330" />
+        width="350">
+      <check_box.label_text text_color="White" />
+    </check_box>
+
     <text
-        follows="left|top"
         layout="topleft"
         left="345"
         height="12"
@@ -63,67 +59,65 @@
         top="0">
       Font size:
     </text>
-    <radio_group
-        height="90"
-        layout="topleft"
-        left="352"
+
+    <combo_box
         control_name="ChatFontSize"
+        height="23"
+        layout="topleft"
+        left="341"
         name="chat_font_size"
-        top_pad="0"
-        width="50">
-      <radio_item
-          height="16"
+        top_pad="5"
+        width="100">
+      <item
           label="Small"
-          layout="topleft"
-          name="radio"
-          value="0"
-          top="10"
-          width="125" />
-      <radio_item
-          height="16"
+          name="Small"
+          value="0"/>
+      <item
           label="Medium"
-          layout="topleft"
-          name="radio2"
-          value="1"
-          top_pad="6"
-          width="125" />
-      <radio_item
-          height="16"
+          name="Medium"
+          value="1"/>
+      <item
           label="Large"
-          layout="topleft"
-          name="radio3"
-          value="2"
-          top_pad="6"
-          width="125" />
-    </radio_group>    
-    
-  </panel>  
+          name="Large"
+          value="2"/>
+      <combo_box.drop_down_button label_color="White" />
+    </combo_box>
+
+    <check_box
+        control_name="UseChatBubbles"
+        height="16"
+        label="Bubble Chat"
+        layout="topleft"
+        top_pad="4"
+        name="bubble_text_chat"
+        width="330">
+    </check_box>
+      
+  </panel>
 
   <panel
       border="false"
-      follows="left|top"
-      height="198"
+      height="165"
       layout="topleft"
       left="13"
       width="517">
 
     <text
-        follows="left|top"
         layout="topleft"
         height="12"
         name="notifications"
         left="0"
+        text_color="White"
         width="120">
-      Notifications:
+      Notifications
     </text>
     <text
-        follows="left|top"
         layout="topleft"
         height="12"
         name="friend_ims"
         width="145"
         left="0"
-        top_pad="15">
+        top_pad="13">
       Friend IMs:
     </text>
     <combo_box
@@ -134,31 +128,30 @@
         top_delta="-6"
         name="FriendIMOptions"
         width="223">
-      <combo_box.item
+      <item
           label="Open Conversations window"
           name="OpenConversationsWindow"
           value="openconversations"/>      
-      <combo_box.item
+      <item
           label="Pop up the message"
           name="PopUpMessage"
           value="toast"/>
-      <combo_box.item
+      <item
           label="Flash toolbar button"
           name="FlashToolbarButton"
           value="flash"/>
-      <combo_box.item
+      <item
           label="None"
           name="None"
           value="none"/>
     </combo_box>
     <text
-        follows="left|top"
         layout="topleft"
         height="12"
         name="non_friend_ims"
         width="145"
         left="0"
-        top_pad="15">
+        top_pad="9">
       Non-friend IMs:
     </text>
     <combo_box
@@ -169,31 +162,30 @@
         top_delta="-6"
         name="NonFriendIMOptions"
         width="223">
-      <combo_box.item
+      <item
           label="Open Conversations window"
           name="OpenConversationsWindow"
           value="openconversations"/>
-      <combo_box.item
+      <item
           label="Pop up the message"
           name="PopUpMessage"
           value="toast"/>
-      <combo_box.item
+      <item
           label="Flash toolbar button"
           name="FlashToolbarButton"
           value="flash"/>
-      <combo_box.item
+      <item
           label="None"
           name="None"
           value="none"/>
     </combo_box>
     <text
-        follows="left|top"
         layout="topleft"
         left="0"
         height="13"
         name="conference_ims"
         width="145"
-        top_pad="14">
+        top_pad="9">
       Conference IMs:
     </text>
     <combo_box
@@ -204,31 +196,30 @@
         top_delta="-6"
         name="ConferenceIMOptions"
         width="223">
-      <combo_box.item
+      <item
           label="Open Conversations window"
           name="OpenConversationsWindow"
           value="openconversations"/>
-      <combo_box.item
+      <item
           label="Pop up the message"
           name="PopUpMessage"
           value="toast"/>
-      <combo_box.item
+      <item
           label="Flash toolbar button"
           name="FlashToolbarButton"
           value="flash"/>
-      <combo_box.item
+      <item
           label="None"
           name="None"
           value="none"/>
     </combo_box>
     <text
-        follows="left|top"
         layout="topleft"
         left="0"
         height="13"
         name="group_chat"
         width="145"
-        top_pad="14">
+        top_pad="9">
       Group chat:
     </text>
     <combo_box
@@ -239,31 +230,30 @@
         top_delta="-6"
         name="GroupChatOptions"
         width="223">
-      <combo_box.item
+      <item
           label="Open Conversations window"
           name="OpenConversationsWindow"
           value="openconversations"/>
-      <combo_box.item
+      <item
           label="Pop up the message"
           name="PopUpMessage"
           value="toast"/>
-      <combo_box.item
+      <item
           label="Flash toolbar button"
           name="FlashToolbarButton"
           value="flash"/>
-      <combo_box.item
+      <item
           label="None"
           name="None"
           value="none"/>
     </combo_box>
     <text
-        follows="left|top"
         layout="topleft"
         left="0"
         height="12"
         name="nearby_chat"
         width="145"
-        top_pad="14">
+        top_pad="9">
       Nearby chat:
     </text>
     <combo_box
@@ -274,31 +264,30 @@
         top_delta="-6"
         name="NearbyChatOptions"
         width="223">
-      <combo_box.item
+      <item
           label="Open Conversations window"
           name="OpenConversationsWindow"
           value="openconversations"/>
-      <combo_box.item
+      <item
           label="Pop up the message"
           name="PopUpMessage"
           value="toast"/>
-      <combo_box.item
+      <item
           label="Flash toolbar button"
           name="FlashToolBarButton"
           value="flash"/>
-      <combo_box.item
+      <item
           label="None"
           name="None"
           value="none"/>
     </combo_box>
     <text
-        follows="left|top"
         layout="topleft"
         left="0"
         height="13"
         name="notifications_alert"
         width="500"
-        top_pad="11"
+        top_pad="9"
         visible="true"
         text_color="DrYellow">
       To temporarily stop all notifications, use Communicate &gt; Do Not Disturb.
@@ -308,14 +297,13 @@
 
   <panel
       border="false"
-      follows="left|top"
-      height="67"
+      height="50"
       layout="topleft"
       left="13"
+      top_pad="10"
       width="517">
 
     <text
-        follows="left|top"
         layout="topleft"
         left="0"
         name="play_sound"
@@ -360,9 +348,123 @@
         width="150" />
 
   </panel>
+
+  <view_border
+      bevel_style="none"
+      height="0"
+      layout="topleft"
+      left="13"
+      name="cost_text_border"
+      top_pad="5"
+      width="495"/>
+
+  <panel
+      height="50"
+      layout="topleft"
+      left="13"
+      top_pad="10"
+      width="505">
+
+    <text
+        layout="topleft"
+        left="0"
+        text_color="White"
+        height="12"
+        top="5"
+        width="55">
+        Save:
+    </text>
+
+    <combo_box
+        control_name="KeepConversationLogTranscripts"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        name="chat_font_size"
+        top="0"
+        width="165">
+        <item
+            label="Log and transcripts"
+            value="2"/>
+        <item
+            label="Log only"
+            value="1"/>
+        <item
+            label="No log or transcripts"
+            value="0"/>
+        <drop_down_button label_color="White" />
+    </combo_box>
+
+    <button
+        enabled="false"
+        height="23"
+        label="Clear log..."
+        label_color="White"
+        layout="topleft"
+        left_pad="5"
+        top="0"
+        name="clear_log"
+        width="110">
+        <commit_callback
+            function="Pref.ClearLog" />
+    </button>
+  
+    <button
+        enabled="false"
+        height="23"
+        label="Delete transcripts..."
+        label_color="White"
+        layout="topleft"
+        left_pad="5"
+        top="0"
+        name="delete_transcripts"
+        width="147">
+        <button.commit_callback
+            function="Pref.DeleteTranscripts" />
+    </button>
+  
+    <text
+        layout="topleft"
+        left="0"
+        text_color="White"
+        height="12"
+        top_pad="15"
+        width="55">
+        Location:
+    </text>
+  
+    <line_editor
+        control_name="InstantMessageLogPath"
+        border_style="line"
+        border_thickness="1"
+        font="SansSerif"
+        height="23"
+        layout="topleft"
+        left_pad="55"
+        max_length="4096"
+        name="log_path_string"
+        top_delta="-5"
+        width="185">
+    </line_editor>
+  
+    <button
+        enabled="false"
+        follows="left|top"
+        height="23"
+        label="Browse..."
+        label_color="White"
+        label_selected="Browse"
+        layout="topleft"
+        left_pad="5"
+        name="log_path_button"
+        top_delta="0"
+        width="112">
+      <commit_callback function="Pref.LogPath" />
+    </button>
+
+  </panel>
   
   <button
-      follows="left|top"
       height="23"
       label="Translation..."
       layout="topleft"
@@ -370,11 +472,10 @@
       name="ok_btn"
       top="-29"
       width="170">
-    <button.commit_callback
+    <commit_callback
         function="Pref.TranslationSettings" />
   </button>
   <button
-      follows="top|left"
       height="23"
       layout="topleft"
       top_pad="-23"
@@ -385,7 +486,6 @@
       width="150">
   </button>
   <button
-      follows="top|left"
       height="23"
       layout="topleft"
       top_pad="-23"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index 587c461bee96ebc9e6c20682973bcd746d6df0c7..78743d26bbe74593b60b4b9d8a70ff174428cc51 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -1,72 +1,69 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
- border="true"
- follows="left|top|right|bottom"
- height="408"
- label="Communication"
- layout="topleft"
- left="102"
- name="im"
- top="1"
- width="517">
-    <panel.string
-     name="log_in_to_change">
-        log in to change
-    </panel.string>
-    <button
-     follows="left|bottom"
-     height="23"
-     label="Clear History"
-     tool_tip="Clear login image, last location, teleport history, web, and texture cache"
-     layout="topleft"
-     left="30"
-     name="clear_cache"
-     top="10"
-     width="145">
-        <button.commit_callback
-         function="Pref.WebClearCache" />
-    </button>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="10"
-     mouse_opaque="false"
-     name="cache_size_label_l"
-     top_delta="3"
-     text_color="LtGray_50"
-     width="300">
-       (Locations, images, web, search history)
-    </text>
-    <check_box
-	 height="16"
-     enabled="false"
-     label="Show me in Search results"
-     layout="topleft"
-     left="30"
-     name="online_searchresults"
-     top_pad="20"
-     width="350" />
-    <check_box
-	 height="16"
-	 enabled="false"
-     label="Only friends and groups know I'm online"
-     layout="topleft"
-     left="30"
-     name="online_visibility"
-     top_pad="30"
-     width="350" />
-    <check_box
-     control_name="VoiceCallsFriendsOnly"
-     height="16"
-     label="Only friends and groups can call or IM me"
-     layout="topleft"
-     left="30"
-     name="voice_call_friends_only_check"
-     top_pad="10"
-     width="350" />
+    border="true"
+    follows="left|top|right|bottom"
+    height="408"
+    label="Communication"
+    layout="topleft"
+    left="102"
+    name="im"
+    top="1"
+    width="517">
+
+  <panel.string
+      name="log_in_to_change">
+    log in to change
+  </panel.string>
+
+  <button
+      follows="left|bottom"
+      height="23"
+      label="Clear History"
+      tool_tip="Clear login image, last location, teleport history, web, and texture cache"
+      layout="topleft"
+      left="30"
+      name="clear_cache"
+      top="10"
+      width="145">
+    <button.commit_callback
+        function="Pref.WebClearCache" />
+  </button>
+
+  <text
+      type="string"
+      length="1"
+      follows="left|top"
+      height="10"
+      layout="topleft"
+      left_pad="10"
+      mouse_opaque="false"
+      name="cache_size_label_l"
+      top_delta="3"
+      text_color="LtGray_50"
+      width="300">
+    (Locations, images, web, search history)
+  </text>
+
+  <check_box
+      height="16"
+      enabled="false"
+      label="Show me in Search results"
+      layout="topleft"
+      left="30"
+      name="online_searchresults"
+      top_pad="20"
+      width="350" />
+
+  <check_box
+      height="16"
+      enabled="false"
+      label="Only friends and groups know I'm online"
+      layout="topleft"
+      left="30"
+      name="online_visibility"
+      top_pad="30"
+      width="350" />
+    
     <check_box
      enabled_control="EnableVoiceChat"
      control_name="AutoDisengageMic"
@@ -87,100 +84,7 @@
      name="favorites_on_login_check"
      top_pad="10"
      width="350" />
-	<text
-      type="string"
-    length="1"
-    follows="left|top"
-     height="10"
-     layout="topleft"
-     left="30"
-     mouse_opaque="false"
-     name="Logs:"
-     top_pad="20"
-     width="350">
-        Chat Logs:
-    </text>
-    <check_box
-	 enabled="false"
-     control_name="LogNearbyChat"
-     height="16"
-     label="Save nearby chat logs on my computer"
-     layout="topleft"
-     left="30"
-     name="log_nearby_chat"
-     top_pad="10"
-     width="350">
-    </check_box>
-    <check_box
-	 enabled="false"
-     control_name="LogInstantMessages"
-     height="16"
-     label="Save IM logs on my computer"
-     layout="topleft"
-     left="30"
-     name="log_instant_messages"
-     top_pad="10"
-     width="350">
-    </check_box>
-    <check_box
-     control_name="LogTimestamp"
-	 enabled="false"
-     height="16"
-     label="Add timestamp to each line in chat log"
-     layout="topleft"
-     left_delta="0"
-     name="show_timestamps_check_im"
-     top_pad="10"
-     width="237" />
-	<check_box
-     control_name="LogFileNamewithDate"
-     enabled="false"
-     height="16"
-     label="Add datestamp to log file name."
-     layout="topleft"
-     left_delta="5"
-     name="logfile_name_datestamp"
-     top_pad="10"
-     width="350"/>
-	<text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_delta="0"
-     mouse_opaque="false"
-     name="log_path_desc"
-     top_pad="30"
-     width="128">
-        Location of logs:
-    </text>    
-    <line_editor
-     bottom="366"
-     control_name="InstantMessageLogPath"
-     follows="top|left|right"
-     halign="right"
-     height="23"
-     layout="topleft"
-     left_delta="0"
-     mouse_opaque="false"
-     name="log_path_string"
-     top_pad="5"
-     width="250"/>
-    <button
-	 enabled="false"
-     follows="right|bottom"
-     height="23"
-     label="Browse"
-     label_selected="Browse"
-     layout="topleft"
-     left_pad="5"
-     name="log_path_button"
-     top_delta="0"
-     width="145">
-        <button.commit_callback
-         function="Pref.LogPath" />
-    </button>
+
     <button
      follows="left|bottom"
      height="23"
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index a49bc4161e2cdc4558a7d633d878d471b35ee963..de07beee7c8ebe2ab9fa7e116e4257faba8cb443 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -83,6 +83,7 @@ std::string LLDir::getSkinFolder() const { return "default"; }
 std::string LLDir::getLanguage() const { return "en"; }
 bool LLDir::setCacheDir(const std::string &path){ return true; }
 void LLDir::dumpCurrentDirectories() {}
+void LLDir::updatePerAccountChatLogsDir() {}
 
 std::string LLDir::getExpandedFilename(ELLPath location, 
 									   const std::string &filename) const