diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 8ac55b2eb42b572c38e897e4850db5e6753852c6..97547208ecc058949a26614b73c35c964fbe8e3c 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -105,6 +105,7 @@ LLButton::Params::Params()
 	badge("badge"),
 	handle_right_mouse("handle_right_mouse"),
 	held_down_delay("held_down_delay"),
+	button_flash_enable("button_flash_enable", false),
 	button_flash_count("button_flash_count"),
 	button_flash_rate("button_flash_rate")
 {
@@ -170,15 +171,24 @@ LLButton::LLButton(const LLButton::Params& p)
 	mMouseUpSignal(NULL),
 	mHeldDownSignal(NULL),
 	mUseDrawContextAlpha(p.use_draw_context_alpha),
-	mHandleRightMouse(p.handle_right_mouse)
+	mHandleRightMouse(p.handle_right_mouse),
+	mFlashingTimer(NULL)
 {
-	// If optional parameter "p.button_flash_count" is not provided, LLFlashTimer will be
-	// used instead it a "default" value from gSavedSettings.getS32("FlashCount")).
-	// Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod").
-	// Note: flashing should be allowed in settings.xml (boolean key "EnableButtonFlashing").
-	S32 flash_count = p.button_flash_count.isProvided()? p.button_flash_count : 0;
-	F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0;
-	mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
+	if (p.button_flash_enable)
+	{
+		// If optional parameter "p.button_flash_count" is not provided, LLFlashTimer will be
+		// used instead it a "default" value from gSavedSettings.getS32("FlashCount")).
+		// Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod").
+		// Note: flashing should be allowed in settings.xml (boolean key "EnableButtonFlashing").
+		S32 flash_count = p.button_flash_count.isProvided()? p.button_flash_count : 0;
+		F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0;
+		mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
+	}
+	else
+	{
+		mButtonFlashCount = p.button_flash_count;
+		mButtonFlashRate = p.button_flash_rate;
+	}
 
 	static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
 	static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
@@ -273,7 +283,11 @@ LLButton::~LLButton()
 	delete mMouseDownSignal;
 	delete mMouseUpSignal;
 	delete mHeldDownSignal;
-	delete mFlashingTimer;
+
+	if (mFlashingTimer)
+	{
+		delete mFlashingTimer;
+	}
 }
 
 // HACK: Committing a button is the same as instantly clicking it.
@@ -599,10 +613,29 @@ void LLButton::draw()
 	static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
 	F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
 
-	mFlashing = mFlashingTimer->isFlashing();
-
-	bool flash = mFlashing &&
-	                 (!sEnableButtonFlashing || mFlashingTimer->isHighlight());
+	bool flash = false;
+	if (mFlashingTimer)
+	{
+		mFlashing = mFlashingTimer->isFlashingInProgress();
+		flash = mFlashing && (!sEnableButtonFlashing || mFlashingTimer->isCurrentlyHighlighted());
+	}
+	else 
+	{
+		if(mFlashing)
+		{
+			if ( sEnableButtonFlashing)
+			{
+				F32 elapsed = mFrameTimer.getElapsedTimeF32();
+				S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
+				// flash on or off?
+				flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
+			}
+			else
+			{ // otherwise just highlight button in flash color
+				flash = true;
+			}
+		}
+	}
 
 	bool pressed_by_keyboard = FALSE;
 	if (hasFocus())
@@ -945,19 +978,26 @@ void LLButton::setToggleState(BOOL b)
 	}
 }
 
-void LLButton::setFlashing( BOOL b )	
+void LLButton::setFlashing( bool b )	
 { 
-	if (b)
+	if (mFlashingTimer)
 	{
-		mFlashingTimer->startFlashing();
+		if (b)
+		{
+			mFlashingTimer->startFlashing();
+		}
+		else
+		{
+			mFlashingTimer->stopFlashing();
+		}
 	}
-	else
+	else if (b != mFlashing)
 	{
-		mFlashingTimer->stopFlashing();
+		mFlashing = b; 
+		mFrameTimer.reset();
 	}
 }
 
-
 BOOL LLButton::toggleState()			
 {
     bool flipped = ! getToggleState();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 92548298f5046be6383aacdf07f866a5075d3859..060db59a8a6e088eb1661357961a7f4bf4317871 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -134,6 +134,7 @@ class LLButton
 
 		Optional<bool>				handle_right_mouse;
 
+		Optional<bool>				button_flash_enable;
 		Optional<S32>				button_flash_count;
 		Optional<F32>				button_flash_rate;
 
@@ -200,7 +201,7 @@ class LLButton
 	void			setToggleState(BOOL b);
 
 	void			setHighlight(bool b);
-	void			setFlashing( BOOL b );
+	void			setFlashing( bool b );
 	BOOL			getFlashing() const		{ return mFlashing; }
     LLFlashTimer*   getFlashTimer() {return mFlashingTimer;}
 
@@ -287,6 +288,8 @@ class LLButton
 
 	LLFrameTimer	mMouseDownTimer;
 	bool			mNeedsHighlight;
+	S32				mButtonFlashCount;
+	F32				mButtonFlashRate;
 
 	void			drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size);
 	void			resetMouseDownTimer();
@@ -373,7 +376,8 @@ class LLButton
 	bool						mForcePressedState;
 	bool						mDisplayPressedState;
 
-	LLFlashTimer*				mFlashingTimer;
+	LLFrameTimer				mFrameTimer;
+	LLFlashTimer *				mFlashingTimer;
 
 	bool						mHandleRightMouse;
 };
diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp
index 0e2f3f1961b784ebea0d731ceedca6403453c8ac..625fb8e87024c7cfc5f2a8d646737dabe181be76 100644
--- a/indra/llui/llcommandmanager.cpp
+++ b/indra/llui/llcommandmanager.cpp
@@ -63,6 +63,7 @@ LLCommand::Params::Params()
 	, is_running_parameters("is_running_parameters")
 	, is_starting_function("is_starting_function")
 	, is_starting_parameters("is_starting_parameters")
+	, is_flashing_allowed("is_flashing_allowed", false)
 {
 }
 
@@ -83,6 +84,7 @@ LLCommand::LLCommand(const LLCommand::Params& p)
 	, mIsRunningParameters(p.is_running_parameters)
 	, mIsStartingFunction(p.is_starting_function)
 	, mIsStartingParameters(p.is_starting_parameters)
+	, mIsFlashingAllowed(p.is_flashing_allowed)
 {
 }
 
diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h
index a7276a48aa5cb146e72d70020c57ccb2662b477f..ff5a8a325738b1c9a511cbd3df93b96683c357ca 100644
--- a/indra/llui/llcommandmanager.h
+++ b/indra/llui/llcommandmanager.h
@@ -111,6 +111,8 @@ class LLCommand
 		Optional<std::string>	is_starting_function;
 		Optional<LLSD>			is_starting_parameters;
 
+		Optional<bool>			is_flashing_allowed;
+
 		Params();
 	};
 
@@ -138,6 +140,8 @@ class LLCommand
 	const std::string& isStartingFunctionName() const { return mIsStartingFunction; }
 	const LLSD& isStartingParameters() const { return mIsStartingParameters; }
 
+	bool isFlashingAllowed() const { return mIsFlashingAllowed; }
+
 private:
 	LLCommandId mIdentifier;
 
@@ -161,6 +165,8 @@ class LLCommand
 
 	std::string mIsStartingFunction;
 	LLSD        mIsStartingParameters;
+
+	bool		mIsFlashingAllowed;
 };
 
 
diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp
index c572a83ff5f3d1bc2e3cc5fbb8fd071af1f6096e..2ad86b5751ec7080106be02b96c171df168c4256 100644
--- a/indra/llui/llflashtimer.cpp
+++ b/indra/llui/llflashtimer.cpp
@@ -33,15 +33,15 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
 		: LLEventTimer(period)
 		, mCallback(cb)
 		, mCurrentTickCount(0)
-        , mIsFlashing(false)
+        , mIsFlashingInProgress(false)
 {
 	mEventTimer.stop();
 
 	// By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
 	// Due to Timer is implemented as derived class from EventTimer it is impossible to change period
 	// in runtime. So, both settings are made as required restart.
-	mFlashCount = 2 * ((count>0)? count : gSavedSettings.getS32("FlashCount"));
-	if (mPeriod<=0)
+	mFlashCount = 2 * ((count > 0) ? count : gSavedSettings.getS32("FlashCount"));
+	if (mPeriod <= 0)
 	{
 		mPeriod = gSavedSettings.getF32("FlashPeriod");
 	}
@@ -49,15 +49,18 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
 
 BOOL LLFlashTimer::tick()
 {
-	mIsHighlight = !(mCurrentTickCount % 2);
+	mIsCurrentlyHighlighted = !mIsCurrentlyHighlighted;
+
 	if (mCallback)
 	{
-		mCallback(mIsHighlight);
+		mCallback(mIsCurrentlyHighlighted);
 	}
 
 	if (++mCurrentTickCount >= mFlashCount)
 	{
 		mEventTimer.stop();
+		mCurrentTickCount = 0;
+		mIsFlashingInProgress = false;
 	}
 
 	return FALSE;
@@ -65,15 +68,14 @@ BOOL LLFlashTimer::tick()
 
 void LLFlashTimer::startFlashing()
 {
-	mCurrentTickCount = 0;
-	mIsFlashing = true;
+	mIsFlashingInProgress = true;
 	mEventTimer.start();
 }
 
 void LLFlashTimer::stopFlashing()
 {
-	mIsFlashing = false;
-	mIsHighlight = false;
+	mIsFlashingInProgress = false;
+	mIsCurrentlyHighlighted = false;
 	mEventTimer.stop();
 }
 
diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h
index 2ef6ebcc8ac6eff65cacd58cbefec6ff7f24ba37..538ee0fcca602ee4cd15b82bee089ea4257bbe49 100644
--- a/indra/llui/llflashtimer.h
+++ b/indra/llui/llflashtimer.h
@@ -50,8 +50,8 @@ class LLFlashTimer : public LLEventTimer
 	void startFlashing();
 	void stopFlashing();
 
-	bool isFlashing() {return mIsFlashing;}
-	bool isHighlight() {return mIsHighlight;}
+	bool isFlashingInProgress() {return mIsFlashingInProgress;}
+	bool isCurrentlyHighlighted() {return mIsCurrentlyHighlighted;}
 
 private:
 	callback_t		mCallback;
@@ -60,8 +60,8 @@ class LLFlashTimer : public LLEventTimer
 	 */
 	S32 mFlashCount;
 	S32 mCurrentTickCount;
-	bool mIsHighlight;
-	bool mIsFlashing;
+	bool mIsCurrentlyHighlighted;
+	bool mIsFlashingInProgress;
 };
 
 #endif /* LL_FLASHTIMER_H */
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index d65f53cd4daab121d7c93261a89b5abb0bd79d9e..95407d2364356e24a4368b58480fbea114cb977f 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -145,8 +145,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
     mArrowSize(p.arrow_size),
     mMaxFolderItemOverlap(p.max_folder_item_overlap)
 {
-	mFlashTimer = new LLFlashTimer();
-
 	sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
 	sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
 	sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
@@ -168,7 +166,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 // Destroys the object
 LLFolderViewItem::~LLFolderViewItem()
 {
-	delete mFlashTimer;
 	mViewModelItem = NULL;
 }
 
@@ -671,6 +668,16 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L
 	}
 }
 
+/*virtual*/ bool LLFolderViewItem::isHighlightAllowed()
+{
+	return mIsSelected;
+}
+
+/*virtual*/ bool LLFolderViewItem::isHighlightActive()
+{
+	return mIsCurSelection;
+}
+
 void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, 
                                                         const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)
 {
@@ -683,16 +690,13 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
     const S32 focus_bottom = getRect().getHeight() - mItemHeight;
     const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
     const S32 FOCUS_LEFT = 1;
-    bool flashing = mFlashTimer->isFlashing();
-
-    if (flashing? mFlashTimer->isHighlight() : mIsSelected) // always render "current" item (only render other selected items if
-    	             // mShowSingleSelection is FALSE) or flashing item
 
+    if (isHighlightAllowed())	// always render "current" item (only render other selected items if
+    							// mShowSingleSelection is FALSE) or flashing item
     {
         gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
         LLColor4 bg_color = bgColor;
-        bool selection = flashing? mFlashTimer->isHighlight() : mIsCurSelection;
-        if (!selection)
+        if (!isHighlightActive())
         {
             // do time-based fade of extra objects
             F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
@@ -712,7 +716,7 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
             getRect().getWidth() - 2,
             focus_bottom,
             bg_color, hasKeyboardFocus);
-        if (selection)
+        if (isHighlightActive())
         {
             gl_rect_2d(FOCUS_LEFT, 
                 focus_top, 
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index c8d6c37b0403365bb36d0c0a327605a0e4f2540d..c5d6d26e843d2ed7d8a24a4b7705063049596947 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -135,6 +135,8 @@ class LLFolderViewItem : public LLView
 	// no-op at this level, but reimplemented in derived classes.
 	virtual void addItem(LLFolderViewItem*) { }
 	virtual void addFolder(LLFolderViewFolder*) { }
+	virtual bool isHighlightAllowed();
+	virtual bool isHighlightActive();
 
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
@@ -163,7 +165,6 @@ class LLFolderViewItem : public LLView
     S32 getIconPad();
     S32 getTextPad();
 
-    LLFlashTimer* getFlashTimer() {return mFlashTimer;}
 	// If 'selection' is 'this' then note that otherwise ignore.
 	// Returns TRUE if this item ends up being selected.
 	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
@@ -274,8 +275,6 @@ class LLFolderViewItem : public LLView
 
 private:
 	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
-	LLFlashTimer* mFlashTimer;
-
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index d1f77830a64bf0a3f7136835c5ac98aaec19f897..3c1dfc118441671ffdfa885e34ff147f5813d834 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -506,8 +506,8 @@ void LLTabContainer::draw()
 		}
 	}
 
-	mPrevArrowBtn->getFlashTimer()->stopFlashing();
-	mNextArrowBtn->getFlashTimer()->stopFlashing();
+	mPrevArrowBtn->setFlashing(false);
+	mNextArrowBtn->setFlashing(false);
 }
 
 
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 81ea0ebf0ca603099532841ee5cbf50e1ce75f1c..1aa46806c3ad7dd521fb2ecd2f427c5aa97d1e8a 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -914,6 +914,7 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
 	button_p.label = LLTrans::getString(commandp->labelRef());
 	button_p.tool_tip = LLTrans::getString(commandp->tooltipRef());
 	button_p.image_overlay = LLUI::getUIImage(commandp->icon());
+	button_p.button_flash_enable = commandp->isFlashingAllowed();
 	button_p.overwriteFrom(mButtonParams[mButtonType]);
 	LLToolBarButton* button = LLUICtrlFactory::create<LLToolBarButton>(button_p);
 
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index d4bbd84d0f6dd9c761c262c7bbe0f1b11e1d959b..4659673333b945cd68e064b9b63c5de1d8b3a419 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -44,6 +44,7 @@
            />
   <command name="chat"
            available_in_toybox="true"
+		   is_flashing_allowed="true"
            icon="Command_Chat_Icon"
            label_ref="Command_Chat_Label"
            tooltip_ref="Command_Conversations_Tooltip"
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index b9d62e85c46aee8df4dee3f4429effcb6870f2e1..e40d57c318701033315c43b314004babc09471c4 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -82,6 +82,7 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
 	mVoiceClientObserver(NULL),
 	mMinimizedMode(false)
 {
+	mFlashTimer = new LLFlashTimer();
 }
 
 LLConversationViewSession::~LLConversationViewSession()
@@ -92,6 +93,18 @@ LLConversationViewSession::~LLConversationViewSession()
 	{
 		LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
 	}
+
+	delete mFlashTimer;
+}
+
+bool LLConversationViewSession::isHighlightAllowed()
+{
+	return mFlashTimer->isFlashingInProgress() || mIsSelected;
+}
+
+bool LLConversationViewSession::isHighlightActive()
+{
+	return mFlashTimer->isFlashingInProgress() ? mFlashTimer->isCurrentlyHighlighted() : mIsCurSelection;
 }
 
 BOOL LLConversationViewSession::postBuild()
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 8156b746b21e13fa70115830ef9cebc81435b301..acd7128b7d7db154d248dd863214b251a59b66f2 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -55,7 +55,10 @@ class LLConversationViewSession : public LLFolderViewFolder
 protected:
 	friend class LLUICtrlFactory;
 	LLConversationViewSession( const Params& p );
-	
+
+	/*virtual*/ bool isHighlightAllowed();
+	/*virtual*/ bool isHighlightActive();
+
 	LLFloaterIMContainer* mContainer;
 	
 public:
@@ -82,6 +85,8 @@ class LLConversationViewSession : public LLFolderViewFolder
 
 	virtual void refresh();
 
+	LLFlashTimer * getFlashTimer() { return mFlashTimer; }
+
 private:
 
 	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
@@ -90,6 +95,7 @@ class LLConversationViewSession : public LLFolderViewFolder
 	LLPanel*				mCallIconLayoutPanel;
 	LLTextBox*				mSessionTitle;
 	LLOutputMonitorCtrl*	mSpeakingIndicator;
+	LLFlashTimer*			mFlashTimer;
 
 	bool					mMinimizedMode;
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index bcc7e77116bf36e0c42ff183d87b000dc0dba35b..304fb78260900c09f41490455b6cff004ef2486b 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1611,7 +1611,7 @@ void LLFloaterIMContainer::reSelectConversation()
 
 void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
 {
-	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
+	LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id));
 	if (widget)
 	{
 		if (is_flashes)