diff --git a/indra/newview/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp
index 4b0a70ffd862893145143b0bc145c51658c16d3a..a99047c163f23949c4901e1a315919c558627f32 100644
--- a/indra/newview/llcommunicationchannel.cpp
+++ b/indra/newview/llcommunicationchannel.cpp
@@ -67,12 +67,18 @@ void LLCommunicationChannel::clearHistory()
 	mHistory.clear();
 }
 
+void LLCommunicationChannel::removeItem(history_list_t::const_iterator itemToRemove)
+{
+    mHistory.erase(itemToRemove);
+}
+
 void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr)
 {
 	std::string notificationType = pNotificationPtr->getType();
 	if ((notificationType == "groupnotify")
 		|| (notificationType == "offer")
-		|| (notificationType == "notifytoast"))
+		|| (notificationType == "notifytoast")
+        && !pNotificationPtr->isCancelled())
 	{
 		mHistory.insert(std::make_pair<LLDate, LLNotificationPtr>(pNotificationPtr->getDate(), pNotificationPtr));
 	}
diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h
index 0e15e1cd1506083a1d72254321351ac258296afb..c07933118d8b33fb2c8770ffe1bebd1d69be6463 100644
--- a/indra/newview/llcommunicationchannel.h
+++ b/indra/newview/llcommunicationchannel.h
@@ -48,6 +48,7 @@ class LLCommunicationChannel : public LLNotificationChannel
 	history_list_t::const_iterator endHistory() const;
 	
 	void clearHistory();
+    void removeItem(history_list_t::const_iterator itemToRemove);
 
 protected:
 	virtual void onFilterFail(LLNotificationPtr pNotificationPtr);
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index ac41a3804ff6aa37a9a5e3d54e956b83cdfe4b2f..764da25b08c9a3931e33c54a8d95be3870c1978f 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -41,6 +41,8 @@
 #include "llsingleton.h"
 #include "lluuid.h"
 
+extern void useMostItrusiveIMNotification();
+
 LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
 	: LLSingleton<LLDoNotDisturbNotificationStorage>()
 	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
@@ -103,15 +105,22 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 	}
 	
 	LLNotifications& instance = LLNotifications::instance();
+    bool imToastExists = false;
 	
 	for (LLSD::array_const_iterator notification_it = data.beginArray();
 		 notification_it != data.endArray();
 		 ++notification_it)
 	{
 		LLSD notification_params = *notification_it;
+        const std::string notificationName = notification_params["name"].asString();
         const LLUUID& notificationID = notification_params["id"];
         LLNotificationPtr notification = instance.find(notificationID);
 		
+        if(notificationName == "IMToast")
+        {
+            imToastExists = true;
+        }
+
         //Notification already exists in notification pipeline (same instance of app running)
 		if (notification)
 		{
@@ -138,6 +147,11 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 		}
 	}
 
+    if(imToastExists)
+    {
+        useMostItrusiveIMNotification();
+    }
+
 	// Clear the communication channel history and rewrite the save file to empty it as well
 	LLNotificationChannelPtr channelPtr = getCommunicationChannel();
 	LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
@@ -154,6 +168,45 @@ LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChan
 	return channelPtr;
 }
 
+void LLDoNotDisturbNotificationStorage::removeIMNotification(const LLUUID& session_id)
+{
+    LLNotifications& instance = LLNotifications::instance();
+    LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+    LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+    LLNotificationPtr notification;
+    LLSD substitutions;
+    LLUUID notificationSessionID;
+    LLCommunicationChannel::history_list_t::const_iterator it;
+    std::vector<LLCommunicationChannel::history_list_t::const_iterator> itemsToRemove;
+
+    //Find notification with the matching session id
+    for (it = commChannel->beginHistory();
+        it != commChannel->endHistory(); 
+        ++it)
+    {
+        notification = it->second;
+        substitutions = notification->getSubstitutions();
+        notificationSessionID = substitutions["SESSION_ID"].asUUID();
+
+        if(session_id == notificationSessionID)
+        {
+            itemsToRemove.push_back(it);
+        }
+    }
+
+    //Remove the notification
+    while(itemsToRemove.size())
+    {
+        it = itemsToRemove.back();
+        notification = it->second;
+        commChannel->removeItem(it);
+        //instance.cancel triggers onChannelChanged to be called within LLNotificationChannelBase::updateItem (which save changes to the .xml file)
+        //but this means that saveNotifications write a file each time as well, BAD! Will find a way to prevent this.
+        instance.cancel(notification);
+        itemsToRemove.pop_back();
+    }
+}
+
 
 bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload)
 {
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index 60bcd89ec3dade90e201aaa5cbc4e58e4a2a3b9d..8edb8569b485fbaad7fd66c62a36e0bc5a440f2b 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -45,6 +45,7 @@ class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotif
 
 	void saveNotifications();
 	void loadNotifications();
+    void removeIMNotification(const LLUUID& session_id);
 
 protected:
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index a17b89af0dec3d712a60d19f5241c34a7035446c..376144951d3751e87ed80ffe6642ccceda65397f 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -39,6 +39,7 @@
 #include "llavatariconctrl.h"
 #include "llavatarnamecache.h"
 #include "llcallbacklist.h"
+#include "lldonotdisturbnotificationstorage.h"
 #include "llgroupactions.h"
 #include "llgroupiconctrl.h"
 #include "llflashtimer.h"
@@ -1291,6 +1292,10 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
     	if (widget && widget->getParentFolder())
     	{
     		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
+            if(gAgent.isDoNotDisturb())
+            {
+                LLDoNotDisturbNotificationStorage::getInstance()->removeIMNotification(session_id);
+            }
     	}
     }
 
@@ -1312,6 +1317,11 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 				// Switch to the conversation floater that is being selected
 				selectFloater(session_floater);
 			}
+
+            if(gAgent.isDoNotDisturb())
+            {
+                LLDoNotDisturbNotificationStorage::getInstance()->removeIMNotification(session_id);
+            }
 		}
 
 		// Set the focus on the selected floater
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3d4a1c44d88cbf78269d1901240c006c759e9d0a..9c836489f3e0881bc12640c3915cbec1493fcfd8 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1624,6 +1624,36 @@ void LLFloaterPreference::selectChatPanel()
 	selectPanel("chat");
 }
 
+S32 LLFloaterPreference::getHighestNotificationIndex() //change this name
+{
+    static const S32 comboBoxNamesLength = 5;
+    static std::string comboBoxNames[comboBoxNamesLength] = {"NearbyChatOptions",
+                                            "FriendIMOptions",
+                                            "NonFriendIMOptions",
+                                            "ConferenceIMOptions",
+                                            "GroupChatOptions"};
+    S32 selectedIndex;
+    S32 priorityindex = 3;
+    LLComboBox * comboBox;
+
+    for(S32 i = 0; i < comboBoxNamesLength; ++i)
+    {
+        comboBox = getChild<LLComboBox>(comboBoxNames[i]);
+
+        if(comboBox)
+        {
+            selectedIndex = comboBox->getCurrentIndex();
+
+            if(selectedIndex < priorityindex)
+            {
+                priorityindex = selectedIndex;
+            }
+        }
+    }
+
+    return priorityindex;
+}
+
 //------------------------------Updater---------------------------------------
 
 static bool handleBandwidthChanged(const LLSD& newvalue)
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 37a531e99e6995bbe3ad2dfc493ce157856bdf79..3d5d49294eab019f473d673cfe84c9da871c31a3 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -86,6 +86,7 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 	void saveAvatarProperties( void );
 	void selectPrivacyPanel();
 	void selectChatPanel();
+    S32 getHighestNotificationIndex();
 
 protected:	
 	void		onBtnOK();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 067f0d199301d6d403f49a6878eb75801fe69406..e513d2e6d1e340dd7da9704de3cf549f276a712d 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -52,6 +52,7 @@
 #include "llchat.h"
 #include "llfloaterimsession.h"
 #include "llfloaterimcontainer.h"
+#include "llfloaterpreference.h"
 #include "llgroupiconctrl.h"
 #include "llmd5.h"
 #include "llmutelist.h"
@@ -128,11 +129,46 @@ void process_dnd_im(const LLSD& notification)
             false, 
             false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
     }
-
-    //Flash toolbar button for now, eventually the user's preference will be taken into account
-    gToolBarView->flashCommand(LLCommandId("chat"), true);
 }
 
+void useMostItrusiveIMNotification()
+{
+    LLFloaterPreference * instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+    if (instance)
+    {    
+        LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+
+        //conv. floater is closed
+        bool conversation_floater_is_closed =
+            !(  im_box
+            && im_box->isInVisibleChain()
+            && !im_box->isMinimized());
+
+        //conversation floater not focused (visible or not)
+        bool conversation_floater_not_focused =
+            conversation_floater_is_closed || !im_box->hasFocus();
+
+        switch(instance->getHighestNotificationIndex())
+        {
+            //Highest priority to lowest (cases correspond to options in drop down box inside Preferences->Chat)
+
+            //open conversation floater
+            case 0:
+                    LLFloaterReg::showInstance("im_container");
+                break;
+            //pop up message
+            case 1:
+            //flash toolbar button
+            case 2:
+                if(conversation_floater_not_focused)
+                {
+                    gToolBarView->flashCommand(LLCommandId("chat"), true);
+                }
+                break;
+        }
+    }
+
+}
 
 static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 									   const LLAvatarName& av_name,